From 6b86da716eae7cbf5894b463da3c856e687866d5 Mon Sep 17 00:00:00 2001 From: Stephen Lombardo Date: Wed, 22 Apr 2020 11:11:26 -0400 Subject: [PATCH] Snapshot of upstream SQLite 3.31.0 --- Makefile.in | 12 +- Makefile.msc | 24 +- VERSION | 2 +- autoconf/Makefile.msc | 16 +- autoconf/configure.ac | 2 +- autoconf/tea/configure.ac | 2 +- autoconf/tea/win/makefile.vc | 49 ++- configure | 67 +-- configure.ac | 16 +- doc/trusted-schema.md | 142 ++++++ ext/expert/sqlite3expert.h | 6 +- ext/fts3/fts3.c | 137 ++++-- ext/fts3/fts3Int.h | 18 +- ext/fts3/fts3_snippet.c | 40 +- ext/fts3/fts3_tokenizer.c | 6 +- ext/fts3/fts3_write.c | 153 ++++--- ext/fts5/fts5.h | 6 +- ext/fts5/fts5Int.h | 10 + ext/fts5/fts5_config.c | 7 +- ext/fts5/fts5_expr.c | 4 +- ext/fts5/fts5_index.c | 70 ++- ext/fts5/fts5_main.c | 33 +- ext/fts5/fts5_storage.c | 17 +- ext/fts5/test/fts5content.test | 31 +- ext/fts5/test/fts5corrupt3.test | 335 ++++++++++++++- ext/fts5/test/fts5eb.test | 19 +- ext/fts5/test/fts5full.test | 2 +- ext/fts5/test/fts5integrity.test | 72 ++++ ext/fts5/test/fts5matchinfo.test | 26 ++ ext/fts5/test/fts5misc.test | 216 ++++++++++ ext/fts5/test/fts5savepoint.test | 85 ++++ ext/icu/icu.c | 27 +- ext/misc/amatch.c | 1 + ext/misc/completion.c | 1 + ext/misc/compress.c | 10 +- ext/misc/csv.c | 9 + ext/misc/eval.c | 6 +- ext/misc/fileio.c | 7 +- ext/misc/fossildelta.c | 8 +- ext/misc/fuzzer.c | 2 + ext/misc/ieee754.c | 6 +- ext/misc/json1.c | 115 ++++- ext/misc/nextchar.c | 9 +- ext/misc/noop.c | 68 +++ ext/misc/percentile.c | 3 +- ext/misc/prefixes.c | 1 + ext/misc/regexp.c | 6 +- ext/misc/rot13.c | 5 +- ext/misc/series.c | 1 + ext/misc/sha1.c | 21 +- ext/misc/shathree.c | 20 +- ext/misc/spellfix.c | 1 + ext/misc/sqlar.c | 6 +- ext/misc/totype.c | 10 +- ext/misc/urifuncs.c | 209 +++++++++ ext/misc/uuid.c | 233 ++++++++++ ext/misc/wholenumber.c | 1 + ext/misc/zipfile.c | 46 +- ext/rbu/sqlite3rbu.c | 31 +- ext/rtree/geopoly.c | 20 +- ext/rtree/rtree.c | 98 +++-- ext/rtree/rtree1.test | 74 +++- ext/rtree/rtree2.test | 3 +- ext/rtree/rtreeC.test | 2 +- ext/rtree/rtreeH.test | 23 + ext/rtree/rtreeI.test | 74 ++++ ext/session/sqlite3session.h | 14 +- ext/userauth/userauth.c | 2 +- main.mk | 6 +- manifest | 481 +++++++++++---------- manifest.uuid | 2 +- src/alter.c | 183 ++++---- src/analyze.c | 37 +- src/attach.c | 14 +- src/btree.c | 135 ++++-- src/btree.h | 6 +- src/btreeInt.h | 2 + src/build.c | 386 +++++++++++++---- src/callback.c | 141 +++--- src/date.c | 2 +- src/dbpage.c | 1 + src/dbstat.c | 348 ++++++++++----- src/delete.c | 11 +- src/expr.c | 666 +++++++++++++++++++++-------- src/fkey.c | 36 +- src/func.c | 27 +- src/global.c | 14 +- src/hwtime.h | 24 +- src/insert.c | 713 ++++++++++++++++++++++++------- src/loadext.c | 6 + src/main.c | 143 ++++++- src/malloc.c | 188 ++++++-- src/os.c | 2 +- src/os_unix.c | 27 +- src/pager.c | 142 ++++-- src/pager.h | 2 +- src/parse.y | 15 +- src/pcache1.c | 4 +- src/pragma.c | 120 +++++- src/pragma.h | 154 ++++--- src/prepare.c | 80 ++-- src/resolve.c | 197 ++++++--- src/select.c | 209 ++++++--- src/shell.c.in | 101 +++-- src/sqlite.h.in | 515 +++++++++++++++------- src/sqlite3ext.h | 12 + src/sqliteInt.h | 361 ++++++++++++---- src/status.c | 13 + src/tclsqlite.c | 30 +- src/test1.c | 53 ++- src/test_vfs.c | 2 + src/tokenize.c | 4 +- src/treeview.c | 58 ++- src/trigger.c | 10 +- src/update.c | 111 ++++- src/upsert.c | 3 +- src/utf.c | 16 +- src/util.c | 14 +- src/vdbe.c | 436 +++++++++++++------ src/vdbe.h | 10 +- src/vdbeInt.h | 8 +- src/vdbeapi.c | 4 +- src/vdbeaux.c | 170 +++++++- src/vdbemem.c | 49 ++- src/vdbesort.c | 11 +- src/vtab.c | 50 ++- src/wal.c | 18 +- src/walker.c | 2 +- src/where.c | 223 ++++++---- src/whereInt.h | 55 ++- src/wherecode.c | 233 +++++++--- src/whereexpr.c | 54 +-- src/window.c | 81 +++- test/alter.test | 4 +- test/alter3.test | 4 +- test/alter4.test | 2 +- test/altercol.test | 4 +- test/altertab.test | 32 +- test/altertab2.test | 11 +- test/altertab3.test | 207 ++++++++- test/atof1.test | 24 ++ test/attach4.test | 20 + test/cast.test | 12 + test/check.test | 71 ++- test/collate1.test | 31 ++ test/conflict.test | 22 + test/conflict3.test | 13 +- test/corruptC.test | 2 +- test/corruptE.test | 2 +- test/corruptL.test | 68 +++ test/date2.test | 53 ++- test/descidx1.test | 17 +- test/descidx2.test | 3 +- test/descidx3.test | 3 +- test/distinct.test | 25 ++ test/distinct2.test | 1 - test/e_expr.test | 16 +- test/enc2.test | 14 +- test/exclusive.test | 24 ++ test/expr.test | 20 + test/filter1.test | 21 +- test/fkey2.test | 12 +- test/format4.test | 3 +- test/fts3atoken.test | 23 + test/fts3auto.test | 7 + test/fts3corrupt.test | 15 + test/fts3corrupt4.test | 315 +++++++++++++- test/fts3cov.test | 4 +- test/fts3misc.test | 76 ++++ test/fts3snippet.test | 14 + test/fts4aa.test | 57 +++ test/fts4content.test | 36 ++ test/fts4langid.test | 15 + test/fts4merge.test | 15 + test/func.test | 29 +- test/fuzz_common.tcl | 1 + test/fuzzcheck.c | 84 ++-- test/fuzzdata1.db | Bin 4398080 -> 4419584 bytes test/fuzzdata8.db | Bin 1357824 -> 1741824 bytes test/gencol1.test | 563 ++++++++++++++++++++++++ test/in4.test | 26 ++ test/index6.test | 21 +- test/indexexpr1.test | 2 +- test/indexexpr2.test | 1 - test/insert.test | 130 +++++- test/insert4.test | 2 +- test/instrfault.test | 2 +- test/join.test | 120 ++++++ test/join2.test | 14 + test/journal3.test | 5 +- test/json101.test | 15 + test/json105.test | 118 +++++ test/minmax2.test | 2 +- test/normalize.test | 30 ++ test/nulls1.test | 52 ++- test/orderby1.test | 4 + test/ossfuzz.c | 3 + test/pragma3.test | 29 ++ test/pragma4.test | 1 - test/pragma5.test | 10 +- test/rowvalue.test | 74 ++++ test/rowvaluevtab.test | 95 ++++ test/select1.test | 36 ++ test/skipscan1.test | 21 + test/stat.test | 48 ++- test/symlink.test | 21 +- test/symlink2.test | 116 +++++ test/tabfunc01.test | 9 + test/tclsqlite.test | 11 +- test/tester.tcl | 12 +- test/tkt-18458b1a.test | 1 - test/tkt-a7debbe0.test | 1 - test/tkt3292.test | 2 +- test/trigger1.test | 45 ++ test/trigger2.test | 17 +- test/triggerG.test | 16 + test/trustschema1.test | 251 +++++++++++ test/update.test | 89 ++++ test/upsert1.test | 20 + test/walvfs.test | 1 + test/whereG.test | 12 +- test/whereL.test | 23 + test/window1.test | 360 ++++++++++++++++ test/window2.tcl | 41 ++ test/window2.test | 43 ++ test/window9.test | 1 - test/windowfault.test | 19 +- test/with1.test | 31 ++ test/with3.test | 34 +- test/without_rowid1.test | 22 + test/without_rowid3.test | 12 +- test/zipfile.test | 48 +++ tool/GetFile.cs | 37 +- tool/dbhash.c | 15 - tool/lemon.c | 132 +++++- tool/lempar.c | 13 +- tool/mkkeywordhash.c | 324 +++++++------- tool/mkmsvcmin.tcl | 2 +- tool/mkpragmatab.tcl | 15 +- tool/mksourceid.c | 18 - tool/omittest.tcl | 11 +- tool/showdb.c | 2 +- 242 files changed, 11787 insertions(+), 2925 deletions(-) create mode 100644 doc/trusted-schema.md create mode 100644 ext/fts5/test/fts5savepoint.test create mode 100644 ext/misc/noop.c create mode 100644 ext/misc/urifuncs.c create mode 100644 ext/misc/uuid.c create mode 100644 ext/rtree/rtreeI.test create mode 100644 test/gencol1.test create mode 100644 test/json105.test create mode 100644 test/rowvaluevtab.test create mode 100644 test/symlink2.test create mode 100644 test/trustschema1.test diff --git a/Makefile.in b/Makefile.in index cadc2eda..e4b82436 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1052,7 +1052,7 @@ parse.h: parse.c parse.c: $(TOP)/src/parse.y lemon$(BEXE) cp $(TOP)/src/parse.y . - ./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) parse.y + ./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) $(TOP)/VERSION $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h @@ -1177,10 +1177,10 @@ FTS5_SRC = \ $(TOP)/ext/fts5/fts5_varint.c \ $(TOP)/ext/fts5/fts5_vocab.c \ -fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon +fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon$(BEXE) cp $(TOP)/ext/fts5/fts5parse.y . rm -f fts5parse.h - ./lemon$(BEXE) $(OPTS) fts5parse.y + ./lemon$(BEXE) $(OPTS) -S fts5parse.y fts5parse.h: fts5parse.c @@ -1242,10 +1242,6 @@ fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuz ./fuzzcheck$(TEXE) $(FUZZDATA) ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db -fastfuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db - ./fuzzcheck$(TEXE) --limit-mem 100M $(FUZZDATA) - ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db - valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA) valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db @@ -1263,7 +1259,7 @@ quicktest: ./testfixture$(TEXE) # This is the common case. Run many tests that do not take too long, # including fuzzcheck, sqlite3_analyzer, and sqldiff tests. # -test: fastfuzztest sourcetest $(TESTPROGS) tcltest +test: fuzztest sourcetest $(TESTPROGS) tcltest # Run a test using valgrind. This can take a really long time # because valgrind is so much slower than a native machine. diff --git a/Makefile.msc b/Makefile.msc index 01d20d2d..d0b7860d 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -248,6 +248,12 @@ OPTIMIZATIONS = 2 SESSION = 0 !ENDIF +# Set this to non-0 to enable support for the rbu extension. +# +!IFNDEF RBU +RBU = 0 +!ENDIF + # Set the source code file to be used by executables and libraries when # they need the amalgamation. # @@ -364,6 +370,13 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1 !ENDIF +# Should the rbu extension be enabled? If so, add compilation options +# to enable it. +# +!IF $(RBU)!=0 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RBU=1 +!ENDIF + # These are the "extended" SQLite compilation options used when compiling for # the Windows 10 platform. # @@ -1742,7 +1755,7 @@ $(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP) sqlite3.def: libsqlite3.lib echo EXPORTS > sqlite3.def dumpbin /all libsqlite3.lib \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset|changegroup|rebaser)?_[^@]*)(?:@\d+)?$$" \1 \ + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset|changegroup|rebaser|rbu)?_[^@]*)(?:@\d+)?$$" \1 \ | sort >> sqlite3.def # <> @@ -2141,7 +2154,7 @@ parse.h: parse.c parse.c: $(TOP)\src\parse.y lemon.exe del /Q parse.y parse.h parse.h.temp 2>NUL copy $(TOP)\src\parse.y . - .\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) parse.y + .\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) -S parse.y $(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest mksourceid.exe $(TOP)\VERSION $(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > $(SQLITE3H) $(MKSQLITE3H_ARGS) @@ -2301,7 +2314,7 @@ LSM1_SRC = \ fts5parse.c: $(TOP)\ext\fts5\fts5parse.y lemon.exe copy $(TOP)\ext\fts5\fts5parse.y . del /Q fts5parse.h 2>NUL - .\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) fts5parse.y + .\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) -S fts5parse.y fts5parse.h: fts5parse.c @@ -2404,9 +2417,6 @@ queryplantest: testfixture.exe shell fuzztest: fuzzcheck.exe .\fuzzcheck.exe $(FUZZDATA) -fastfuzztest: fuzzcheck.exe - .\fuzzcheck.exe --limit-mem 100M $(FUZZDATA) - # Minimal testing that runs in less than 3 minutes (on a fast machine) # quicktest: testfixture.exe sourcetest @@ -2416,7 +2426,7 @@ quicktest: testfixture.exe sourcetest # This is the common case. Run many tests that do not take too long, # including fuzzcheck, sqlite3_analyzer, and sqldiff tests. # -test: $(TESTPROGS) sourcetest fastfuzztest +test: $(TESTPROGS) sourcetest fuzztest @set PATH=$(LIBTCLPATH);$(PATH) .\testfixture.exe $(TOP)\test\veryquick.test $(TESTOPTS) diff --git a/VERSION b/VERSION index 72bde0ab..d9351e58 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.30.1 +3.31.0 diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index 2a7042ef..37a3c1b1 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -210,6 +210,12 @@ OPTIMIZATIONS = 2 SESSION = 0 !ENDIF +# Set this to non-0 to enable support for the rbu extension. +# +!IFNDEF RBU +RBU = 0 +!ENDIF + # Set the source code file to be used by executables and libraries when # they need the amalgamation. # @@ -282,7 +288,6 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1 -OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1 !ENDIF OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1 @@ -296,6 +301,13 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1 !ENDIF +# Should the rbu extension be enabled? If so, add compilation options +# to enable it. +# +!IF $(RBU)!=0 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RBU=1 +!ENDIF + # These are the "extended" SQLite compilation options used when compiling for # the Windows 10 platform. # @@ -978,7 +990,7 @@ Replace.exe: sqlite3.def: Replace.exe $(LIBOBJ) echo EXPORTS > sqlite3.def dumpbin /all $(LIBOBJ) \ - | .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \ + | .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser|rbu)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \ | sort >> sqlite3.def $(SQLITE3EXE): shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H) diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 82ab43df..167626d5 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -161,7 +161,7 @@ AC_ARG_ENABLE(rtree, [AS_HELP_STRING( [--enable-rtree], [include rtree support [default=yes]])], [], [enable_rtree=yes]) if test x"$enable_rtree" = "xyes"; then - BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE" + BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_GEOPOLY" fi #----------------------------------------------------------------------- diff --git a/autoconf/tea/configure.ac b/autoconf/tea/configure.ac index 7fca05b2..f6bea0f8 100644 --- a/autoconf/tea/configure.ac +++ b/autoconf/tea/configure.ac @@ -19,7 +19,7 @@ dnl to configure the system for the local environment. # so you can encode the package version directly into the source files. #----------------------------------------------------------------------- -AC_INIT([sqlite], [3.7.4]) +AC_INIT([sqlite], [3.31.0]) #-------------------------------------------------------------------- # Call TEA_INIT as the first TEA_ macro to set up initial vars. diff --git a/autoconf/tea/win/makefile.vc b/autoconf/tea/win/makefile.vc index a5e46277..88b66f17 100644 --- a/autoconf/tea/win/makefile.vc +++ b/autoconf/tea/win/makefile.vc @@ -153,7 +153,7 @@ Please `cd` to its location first. # #------------------------------------------------------------------------- -PROJECT = sqlite3 +PROJECT = tclsqlite3 !include "rules.vc" # nmakehelp -V will search the file for tag, skips until a @@ -162,18 +162,15 @@ PROJECT = sqlite3 !if [echo REM = This file is generated from Makefile.vc > versions.vc] !endif -# get project version from row "AC_INIT([sqlite], [3.7.14])" +# get project version from row "AC_INIT([sqlite], [3.x.y])" !if [echo DOTVERSION = \>> versions.vc] \ - && [nmakehlp -V ..\configure.in AC_INIT >> versions.vc] + && [nmakehlp -V ..\configure.ac AC_INIT >> versions.vc] !endif !include "versions.vc" VERSION = $(DOTVERSION:.=) STUBPREFIX = $(PROJECT)stub -DLLOBJS = \ - $(TMP_DIR)\tclsqlite3.obj - #------------------------------------------------------------------------- # Target names and paths ( shouldn't need changing ) #------------------------------------------------------------------------- @@ -182,7 +179,7 @@ BINROOT = . ROOT = .. PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib -PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT) +PRJLIBNAME = $(PROJECT).$(EXT) PRJLIB = $(OUT_DIR)\$(PRJLIBNAME) PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib @@ -204,6 +201,17 @@ DOCDIR = $(ROOT)\doc TOOLSDIR = $(ROOT)\tools COMPATDIR = $(ROOT)\compat +### Figure out where the primary source code file(s) is/are. +!if exist("$(ROOT)\..\..\sqlite3.c") && exist("$(ROOT)\..\..\src\tclsqlite.c") +SQL_INCLUDES = -I"$(ROOT)\..\.." +SQLITE_SRCDIR = $(ROOT)\..\.. +TCLSQLITE_SRCDIR = $(ROOT)\..\..\src +DLLOBJS = $(TMP_DIR)\sqlite3.obj $(TMP_DIR)\tclsqlite.obj +!else +TCLSQLITE_SRCDIR = $(ROOT)\generic +DLLOBJS = $(TMP_DIR)\tclsqlite3.obj +!endif + #--------------------------------------------------------------------- # Compile flags #--------------------------------------------------------------------- @@ -223,7 +231,7 @@ cdebug = -Z7 -WX -Od -GZ !endif ### Declarations common to all compiler options -cflags = -nologo -c -W3 -YX -Fp$(TMP_DIR)^\ +cflags = -nologo -c -W3 -D_CRT_SECURE_NO_WARNINGS -YX -Fp$(TMP_DIR)^\ !if $(MSVCRT) !if $(DEBUG) @@ -239,8 +247,8 @@ crt = -MT !endif !endif -INCLUDES = $(TCL_INCLUDES) -I"$(WINDIR)" -I"$(GENERICDIR)" \ - -I"$(ROOT)\.." +INCLUDES = $(SQL_INCLUDES) $(TCL_INCLUDES) -I"$(WINDIR)" \ + -I"$(GENERICDIR)" -I"$(ROOT)\.." BASE_CLFAGS = $(cflags) $(cdebug) $(crt) $(INCLUDES) \ -DSQLITE_3_SUFFIX_ONLY=1 -DSQLITE_ENABLE_RTREE=1 \ -DSQLITE_ENABLE_FTS3=1 -DSQLITE_OMIT_DEPRECATED=1 @@ -341,20 +349,17 @@ $(PRJSTUBLIB): $(PRJSTUBOBJS) # Implicit rules #--------------------------------------------------------------------- -{$(WINDIR)}.c{$(TMP_DIR)}.obj:: - $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<< -$< -<< +$(TMP_DIR)\sqlite3.obj: $(SQLITE_SRCDIR)\sqlite3.c + $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ \ + -c $(SQLITE_SRCDIR)\sqlite3.c -{$(GENERICDIR)}.c{$(TMP_DIR)}.obj:: - $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<< -$< -<< +$(TMP_DIR)\tclsqlite.obj: $(TCLSQLITE_SRCDIR)\tclsqlite.c + $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ \ + -c $(TCLSQLITE_SRCDIR)\tclsqlite.c -{$(COMPATDIR)}.c{$(TMP_DIR)}.obj:: - $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<< -$< -<< +$(TMP_DIR)\tclsqlite3.obj: $(TCLSQLITE_SRCDIR)\tclsqlite3.c + $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ \ + -c $(TCLSQLITE_SRCDIR)\tclsqlite3.c {$(WINDIR)}.rc{$(TMP_DIR)}.res: $(rc32) -fo $@ -r -i "$(GENERICDIR)" -D__WIN32__ \ diff --git a/configure b/configure index dce4f6cc..1d1a5d24 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for sqlite 3.30.1. +# Generated by GNU Autoconf 2.69 for sqlite 3.31.0. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -726,8 +726,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.30.1' -PACKAGE_STRING='sqlite 3.30.1' +PACKAGE_VERSION='3.31.0' +PACKAGE_STRING='sqlite 3.31.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -906,6 +906,7 @@ enable_amalgamation enable_load_extension enable_memsys5 enable_memsys3 +enable_all enable_fts3 enable_fts4 enable_fts5 @@ -1466,7 +1467,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sqlite 3.30.1 to adapt to many kinds of systems. +\`configure' configures sqlite 3.31.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1531,7 +1532,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.30.1:";; + short | recursive ) echo "Configuration of sqlite 3.31.0:";; esac cat <<\_ACEOF @@ -1559,6 +1560,7 @@ Optional Features: Disable loading of external extensions --enable-memsys5 Enable MEMSYS5 --enable-memsys3 Enable MEMSYS3 + --enable-all Enable FTS4, FTS5, Geopoly, JSON, RTree, Sessions --enable-fts3 Enable the FTS3 extension --enable-fts4 Enable the FTS4 extension --enable-fts5 Enable the FTS5 extension @@ -1657,7 +1659,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.30.1 +sqlite configure 3.31.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2076,7 +2078,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sqlite $as_me 3.30.1, which was +It was created by sqlite $as_me 3.31.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3934,13 +3936,13 @@ if ${lt_cv_nm_interface+:} false; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3937: $ac_compile\"" >&5) + (eval echo "\"\$as_me:3939: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:3940: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:3942: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:3943: output\"" >&5) + (eval echo "\"\$as_me:3945: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -5146,7 +5148,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5149 "configure"' > conftest.$ac_ext + echo '#line 5151 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -6671,11 +6673,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6674: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6676: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6678: \$? = $ac_status" >&5 + echo "$as_me:6680: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7010,11 +7012,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7013: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7015: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7017: \$? = $ac_status" >&5 + echo "$as_me:7019: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7115,11 +7117,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7118: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7120: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7122: \$? = $ac_status" >&5 + echo "$as_me:7124: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7170,11 +7172,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7173: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7175: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7177: \$? = $ac_status" >&5 + echo "$as_me:7179: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9550,7 +9552,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9553 "configure" +#line 9555 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9646,7 +9648,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9649 "configure" +#line 9651 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11450,6 +11452,15 @@ else $as_echo "no" >&6; } fi +######## +# The --enable-extensions argument is short-hand to enable +# multiple extensions. +# Check whether --enable-all was given. +if test "${enable_all+set}" = set; then : + enableval=$enable_all; +fi + + ######### # See whether we should enable Full Text Search extensions # Check whether --enable-fts3 was given. @@ -11465,7 +11476,7 @@ if test "${enable_fts4+set}" = set; then : enableval=$enable_fts4; fi -if test "${enable_fts4}" = "yes" ; then +if test "${enable_fts4}" = "yes" -o "${enable_all}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5 $as_echo_n "checking for library containing log... " >&6; } @@ -11529,7 +11540,7 @@ if test "${enable_fts5+set}" = set; then : enableval=$enable_fts5; fi -if test "${enable_fts5}" = "yes" ; then +if test "${enable_fts5}" = "yes" -o "${enable_all}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5 $as_echo_n "checking for library containing log... " >&6; } @@ -11596,7 +11607,7 @@ if test "${enable_json1+set}" = set; then : enableval=$enable_json1; fi -if test "${enable_json1}" = "yes" ; then +if test "${enable_json1}" = "yes" -o "${enable_all}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1" fi @@ -11621,7 +11632,7 @@ else enable_geopoly=no fi -if test "${enable_geopoly}" = "yes" ; then +if test "${enable_geopoly}" = "yes" -o "${enable_all}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY" enable_rtree=yes fi @@ -11644,7 +11655,7 @@ if test "${enable_session+set}" = set; then : enableval=$enable_session; fi -if test "${enable_session}" = "yes" ; then +if test "${enable_session}" = "yes" -o "${enable_all}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION" OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK" fi @@ -12232,7 +12243,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sqlite $as_me 3.30.1, which was +This file was extended by sqlite $as_me 3.31.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12298,7 +12309,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sqlite config.status 3.30.1 +sqlite config.status 3.31.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 9cf87adc..ef70a4f0 100644 --- a/configure.ac +++ b/configure.ac @@ -613,6 +613,12 @@ else AC_MSG_RESULT([no]) fi +######## +# The --enable-extensions argument is short-hand to enable +# multiple extensions. +AC_ARG_ENABLE(all, AC_HELP_STRING([--enable-all], + [Enable FTS4, FTS5, Geopoly, JSON, RTree, Sessions])) + ######### # See whether we should enable Full Text Search extensions AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3], @@ -622,13 +628,13 @@ if test "${enable_fts3}" = "yes" ; then fi AC_ARG_ENABLE(fts4, AC_HELP_STRING([--enable-fts4], [Enable the FTS4 extension])) -if test "${enable_fts4}" = "yes" ; then +if test "${enable_fts4}" = "yes" -o "${enable_all}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4" AC_SEARCH_LIBS([log],[m]) fi AC_ARG_ENABLE(fts5, AC_HELP_STRING([--enable-fts5], [Enable the FTS5 extension])) -if test "${enable_fts5}" = "yes" ; then +if test "${enable_fts5}" = "yes" -o "${enable_all}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5" AC_SEARCH_LIBS([log],[m]) fi @@ -636,7 +642,7 @@ fi ######### # See whether we should enable JSON1 AC_ARG_ENABLE(json1, AC_HELP_STRING([--enable-json1],[Enable the JSON1 extension])) -if test "${enable_json1}" = "yes" ; then +if test "${enable_json1}" = "yes" -o "${enable_all}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1" fi @@ -654,7 +660,7 @@ fi AC_ARG_ENABLE(geopoly, AC_HELP_STRING([--enable-geopoly], [Enable the GEOPOLY extension]), [enable_geopoly=yes],[enable_geopoly=no]) -if test "${enable_geopoly}" = "yes" ; then +if test "${enable_geopoly}" = "yes" -o "${enable_all}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY" enable_rtree=yes fi @@ -671,7 +677,7 @@ fi # See whether we should enable the SESSION extension AC_ARG_ENABLE(session, AC_HELP_STRING([--enable-session], [Enable the SESSION extension])) -if test "${enable_session}" = "yes" ; then +if test "${enable_session}" = "yes" -o "${enable_all}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION" OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK" fi diff --git a/doc/trusted-schema.md b/doc/trusted-schema.md new file mode 100644 index 00000000..d431fd49 --- /dev/null +++ b/doc/trusted-schema.md @@ -0,0 +1,142 @@ +# The new-security-options branch + +## The problem that the [new-security-options](/timeline?r=new-security-options) branch tries to solve + +An attacker might modify the schema of an SQLite database by adding +structures that cause code to run when some other application opens and +reads the database. For example, the attacker might replace a table +definition with a view. Or the attacker might add triggers to tables +or views, or add new CHECK constraints or generated columns or indexes +with expressions in the index list or in the WHERE clause. If the +added features invoke SQL functions or virtual tables with side effects, +that might cause harm to the system if run by a high-privilege victim. +Or, the added features might exfiltrate information if the database is +read by a high-privilege victim. + +The changes in this branch strive to make it easier for high-privilege +applications to safely read SQLite database files that might have been +maliciously corrupted by an attacker. + +## Overview of changes in [new-security-options](/timeline?r=new-security-options) + +The basic idea is to tag every SQL function and virtual table with one +of three risk levels: + + 1. Innocuous + 2. Normal + 3. Direct-Only + +Innocuous functions/vtabs are safe and can be used at any time. +Direct-only elements, in contrast, might have cause side-effects and +should only be used from top-level SQL, not from within triggers or views nor +in elements of the schema such as CHECK constraint, DEFAULT values, +generated columns, index expressions, or in the WHERE clause of a +partial index that are potentially under the control of an attacker. +Normal elements behave like Innocuous if TRUSTED\_SCHEMA=on +and behave like direct-only if TRUSTED\_SCHEMA=off. + +Application-defined functions and virtual tables go in as Normal unless +the application takes deliberate steps to change the risk level. + +For backwards compatibility, the default is TRUSTED\_SCHEMA=on. Documentation +will be updated to recommend applications turn TRUSTED\_SCHEMA to off. + +An innocuous function or virtual table is one that can only read content +from the database file in which it resides, and can only alter the database +in which it resides. Most SQL functions are innocuous. For example, there +is no harm in an attacker running the abs() function. + +Direct-only elements that have side-effects that go outside the database file +in which it lives, or return information from outside of the database file. +Examples of direct-only elements include: + + 1. The fts3\_tokenizer() function + 2. The writefile() function + 3. The readfile() function + 4. The zipvfs virtual table + 5. The csv virtual table + +We do not want an attacker to be able to add these kinds of things to +the database schema and possibly trick a high-privilege application +from performing any of these actions. Therefore, functions and vtabs +with side-effects are marked as Direct-Only. + +Legacy applications might add other risky functions or vtabs. Those will +go in as "Normal" by default. For optimal security, we want those risky +app-defined functions and vtabs to be direct-only, but making that the +default might break some legacy applications. Hence, all app-defined +functions and vtabs go in as Normal, but the application can switch them +over to "Direct-Only" behavior using a single pragma. + +The restrictions on the use of functions and virtual tables do not apply +to TEMP. A TEMP VIEW or a TEMP TRIGGER can use any valid SQL function +or virtual table. The idea is that TEMP views and triggers must be +directly created by the application and are thus under the control of the +application. TEMP views and triggers cannot be created by an attacker who +corrupts the schema of a persistent database file. Hence TEMP views and +triggers are safe. + +## Specific changes + + 1. New sqlite3\_db\_config() option SQLITE\_DBCONFIG\_TRUSTED\_SCHEMA for + turning TRUSTED\_SCHEMA on and off. It defaults to ON. + + 2. Compile-time option -DSQLITE\_TRUSTED\_SCHEMA=0 causes the default + TRUSTED\_SCHEMA setting to be off. + + 3. New pragma "PRAGMA trusted\_schema=(ON\|OFF);". This provides access + to the TRUSTED_SCHEMA setting for application coded using scripting + languages or other secondary languages where they are unable to make + calls to sqlite3\_db\_config(). + + 4. New options for the "enc" parameter to sqlite3\_create\_function() and + its kin: +
    +
  1. _SQLITE\_INNOCUOUS_ → tags the new functions as Innocuous +
  2. _SQLITE\_DIRECTONLY_ → tags the new functions as Direct-Only +
+ + 5. New options to sqlite3\_vtab\_config(): +
    +
  1. _SQLITE\_VTAB\_INNOCUOUS_ → tags the vtab as Innocuous +
  2. _SQLITE\_VTAB\_DIRECTONLY_ → tags the vtab as Direct-Only +
+ + 6. Change many of the functions and virtual tables in the SQLite source + tree to use one of the tags above. + + 7. Enhanced PRAGMA function\_list and virtual-table "pragma\_function\_list" + with additional columns. The columns now are: +
    +
  • _name_ → Name of the function +
  • _builtin_ → 1 for built-in functions. 0 otherwise. +
  • _type_ → 's'=Scalar, 'a'=Aggregate, 'w'=Window +
  • _enc_ → 'utf8', 'utf16le', or 'utf16be' +
  • _narg_ → number of argument +
  • _flags_ → Bitmask of SQLITE\_INNOCUOUS, SQLITE\_DIRECTONLY, + SQLITE\_DETERMINISTIC, SQLITE\_SUBTYPE, and + SQLITE\_FUNC\_INTERNAL flags. +
+

The last four columns are new. + + 8. The function\_list PRAGMA now also shows all entries for each function. + So, for example, if a function can take either 2 or 3 arguments, + there are separate rows for the 2-argument and 3-argument versions of + the function. + +## Additional Notes + +The function_list enhancements allow the application to query the set +of SQL functions that meet various criteria. For example, to see all +SQL functions that are never allowed to be used in the schema or in +trigger or views: + +~~~ + SELECT DISTINCT name FROM pragma_function_list + WHERE (flags & 0x80000)!=0 + ORDER BY name; +~~~ + +Doing the same is not possible for virtual tables, as a virtual table +might be Innocuous, Normal, or Direct-Only depending on the arguments +passed into the xConnect method. diff --git a/ext/expert/sqlite3expert.h b/ext/expert/sqlite3expert.h index 39135dc2..60481372 100644 --- a/ext/expert/sqlite3expert.h +++ b/ext/expert/sqlite3expert.h @@ -10,8 +10,8 @@ ** ************************************************************************* */ - - +#if !defined(SQLITEEXPERT_H) +#define SQLITEEXPERT_H 1 #include "sqlite3.h" typedef struct sqlite3expert sqlite3expert; @@ -165,4 +165,4 @@ const char *sqlite3_expert_report(sqlite3expert*, int iStmt, int eReport); */ void sqlite3_expert_destroy(sqlite3expert*); - +#endif /* !defined(SQLITEEXPERT_H) */ diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 2e19d688..77738eb5 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -308,18 +308,6 @@ SQLITE_EXTENSION_INIT1 #endif -/* -** The following are copied from sqliteInt.h. -** -** Constants for the largest and smallest possible 64-bit signed integers. -** These macros are designed to work correctly on both 32-bit and 64-bit -** compilers. -*/ -#ifndef SQLITE_AMALGAMATION -# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) -# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) -#endif - static int fts3EvalNext(Fts3Cursor *pCsr); static int fts3EvalStart(Fts3Cursor *pCsr); static int fts3TermSegReaderCursor( @@ -364,12 +352,7 @@ int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){ v = (*ptr++); \ if( (v & mask2)==0 ){ var = v; return ret; } -/* -** Read a 64-bit variable-length integer from memory starting at p[0]. -** Return the number of bytes read, or 0 on error. -** The value is stored in *v. -*/ -int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){ +int sqlite3Fts3GetVarintU(const char *pBuf, sqlite_uint64 *v){ const unsigned char *p = (const unsigned char*)pBuf; const unsigned char *pStart = p; u32 a; @@ -391,6 +374,41 @@ int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){ return (int)(p - pStart); } +/* +** Read a 64-bit variable-length integer from memory starting at p[0]. +** Return the number of bytes read, or 0 on error. +** The value is stored in *v. +*/ +int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){ + return sqlite3Fts3GetVarintU(pBuf, (sqlite3_uint64*)v); +} + +/* +** Read a 64-bit variable-length integer from memory starting at p[0] and +** not extending past pEnd[-1]. +** Return the number of bytes read, or 0 on error. +** The value is stored in *v. +*/ +int sqlite3Fts3GetVarintBounded( + const char *pBuf, + const char *pEnd, + sqlite_int64 *v +){ + const unsigned char *p = (const unsigned char*)pBuf; + const unsigned char *pStart = p; + const unsigned char *pX = (const unsigned char*)pEnd; + u64 b = 0; + int shift; + for(shift=0; shift<=63; shift+=7){ + u64 c = pnNodeSize = p->nPgsz-35; +#if defined(SQLITE_DEBUG)||defined(SQLITE_TEST) + p->nMergeCount = FTS3_MERGE_COUNT; +#endif + /* Declare the table schema to SQLite. */ fts3DeclareVtab(&rc, p); @@ -1581,6 +1603,10 @@ static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ int iDocidLe = -1; /* Index of docid<=x constraint, if present */ int iIdx; + if( p->bLock ){ + return SQLITE_ERROR; + } + /* By default use a full table scan. This is an expensive option, ** so search through the constraints to see if a more efficient ** strategy is possible. @@ -1779,7 +1805,11 @@ static int fts3CursorSeekStmt(Fts3Cursor *pCsr){ }else{ zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist); if( !zSql ) return SQLITE_NOMEM; - rc = sqlite3_prepare_v3(p->db, zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0); + p->bLock++; + rc = sqlite3_prepare_v3( + p->db, zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0 + ); + p->bLock--; sqlite3_free(zSql); } if( rc==SQLITE_OK ) pCsr->bSeekStmt = 1; @@ -1797,11 +1827,15 @@ static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){ if( pCsr->isRequireSeek ){ rc = fts3CursorSeekStmt(pCsr); if( rc==SQLITE_OK ){ + Fts3Table *pTab = (Fts3Table*)pCsr->base.pVtab; + pTab->bLock++; sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId); pCsr->isRequireSeek = 0; if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){ + pTab->bLock--; return SQLITE_OK; }else{ + pTab->bLock--; rc = sqlite3_reset(pCsr->pStmt); if( rc==SQLITE_OK && ((Fts3Table *)pCsr->base.pVtab)->zContentTbl==0 ){ /* If no row was found and no error has occurred, then the %_content @@ -1973,7 +2007,7 @@ static int fts3SelectLeaf( fts3GetVarint32(zNode, &iHeight); rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2); - assert( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) ); + assert_fts3_nc( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) ); if( rc==SQLITE_OK && iHeight>1 ){ char *zBlob = 0; /* Blob read from %_segments table */ @@ -1993,7 +2027,13 @@ static int fts3SelectLeaf( rc = sqlite3Fts3ReadBlock(p, piLeaf?*piLeaf:*piLeaf2, &zBlob, &nBlob, 0); } if( rc==SQLITE_OK ){ - rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, piLeaf2); + int iNewHeight = 0; + fts3GetVarint32(zBlob, &iNewHeight); + if( iNewHeight>=iHeight ){ + rc = FTS_CORRUPT_VTAB; + }else{ + rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, piLeaf2); + } } sqlite3_free(zBlob); } @@ -2448,12 +2488,12 @@ static void fts3GetDeltaVarint3( if( *pp>=pEnd ){ *pp = 0; }else{ - sqlite3_int64 iVal; - *pp += sqlite3Fts3GetVarint(*pp, &iVal); + u64 iVal; + *pp += sqlite3Fts3GetVarintU(*pp, &iVal); if( bDescIdx ){ - *pVal -= iVal; + *pVal = (i64)((u64)*pVal - iVal); }else{ - *pVal += iVal; + *pVal = (i64)((u64)*pVal + iVal); } } } @@ -2480,15 +2520,16 @@ static void fts3PutDeltaVarint3( int *pbFirst, /* IN/OUT: True after first int written */ sqlite3_int64 iVal /* Write this value to the list */ ){ - sqlite3_int64 iWrite; + sqlite3_uint64 iWrite; if( bDescIdx==0 || *pbFirst==0 ){ - iWrite = iVal - *piPrev; + assert_fts3_nc( *pbFirst==0 || iVal>=*piPrev ); + iWrite = (u64)iVal - (u64)*piPrev; }else{ - iWrite = *piPrev - iVal; + assert_fts3_nc( *piPrev>=iVal ); + iWrite = (u64)*piPrev - (u64)iVal; } assert( *pbFirst || *piPrev==0 ); assert_fts3_nc( *pbFirst==0 || iWrite>0 ); - assert( *pbFirst==0 || iWrite>=0 ); *pp += sqlite3Fts3PutVarint(*pp, iWrite); *piPrev = iVal; *pbFirst = 1; @@ -2504,7 +2545,8 @@ static void fts3PutDeltaVarint3( ** Using this makes it easier to write code that can merge doclists that are ** sorted in either ascending or descending order. */ -#define DOCID_CMP(i1, i2) ((bDescDoclist?-1:1) * (i1-i2)) +/* #define DOCID_CMP(i1, i2) ((bDescDoclist?-1:1) * (i64)((u64)i1-i2)) */ +#define DOCID_CMP(i1, i2) ((bDescDoclist?-1:1) * (i1>i2?1:((i1==i2)?0:-1))) /* ** This function does an "OR" merge of two doclists (output contains all @@ -2918,7 +2960,7 @@ static int fts3SegReaderCursor( ** Fts3SegReaderPending might segfault, as the data structures used by ** fts4aux are not completely populated. So it's easiest to filter these ** calls out here. */ - if( iLevel<0 && p->aIndex ){ + if( iLevel<0 && p->aIndex && p->iPrevLangid==iLangid ){ Fts3SegReader *pSeg = 0; rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg); if( rc==SQLITE_OK && pSeg ){ @@ -3181,6 +3223,8 @@ static int fts3NextMethod(sqlite3_vtab_cursor *pCursor){ int rc; Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; if( pCsr->eSearch==FTS3_DOCID_SEARCH || pCsr->eSearch==FTS3_FULLSCAN_SEARCH ){ + Fts3Table *pTab = (Fts3Table*)pCursor->pVtab; + pTab->bLock++; if( SQLITE_ROW!=sqlite3_step(pCsr->pStmt) ){ pCsr->isEof = 1; rc = sqlite3_reset(pCsr->pStmt); @@ -3188,6 +3232,7 @@ static int fts3NextMethod(sqlite3_vtab_cursor *pCursor){ pCsr->iPrevId = sqlite3_column_int64(pCsr->pStmt, 0); rc = SQLITE_OK; } + pTab->bLock--; }else{ rc = fts3EvalNext((Fts3Cursor *)pCursor); } @@ -3248,6 +3293,10 @@ static int fts3FilterMethod( UNUSED_PARAMETER(idxStr); UNUSED_PARAMETER(nVal); + if( p->bLock ){ + return SQLITE_ERROR; + } + eSearch = (idxNum & 0x0000FFFF); assert( eSearch>=0 && eSearch<=(FTS3_FULLTEXT_SEARCH+p->nColumn) ); assert( p->pSegments==0 ); @@ -3319,7 +3368,11 @@ static int fts3FilterMethod( ); } if( zSql ){ - rc = sqlite3_prepare_v3(p->db,zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0); + p->bLock++; + rc = sqlite3_prepare_v3( + p->db,zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0 + ); + p->bLock--; sqlite3_free(zSql); }else{ rc = SQLITE_NOMEM; @@ -4336,7 +4389,7 @@ static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){ int bIncrOk = (bOptOk && pCsr->bDesc==pTab->bDescIdx && p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0 -#ifdef SQLITE_TEST +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) && pTab->bNoIncrDoclist==0 #endif ); @@ -4478,15 +4531,16 @@ static void fts3EvalDlPhraseNext( u8 *pbEof ){ char *pIter; /* Used to iterate through aAll */ - char *pEnd = &pDL->aAll[pDL->nAll]; /* 1 byte past end of aAll */ + char *pEnd; /* 1 byte past end of aAll */ if( pDL->pNextDocid ){ pIter = pDL->pNextDocid; + assert( pDL->aAll!=0 || pIter==0 ); }else{ pIter = pDL->aAll; } - if( pIter>=pEnd ){ + if( pIter==0 || pIter>=(pEnd = pDL->aAll + pDL->nAll) ){ /* We have already reached the end of this doclist. EOF. */ *pbEof = 1; }else{ @@ -4858,12 +4912,13 @@ static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){ rc = sqlite3Fts3SelectDoctotal(p, &pStmt); if( rc!=SQLITE_OK ) return rc; a = sqlite3_column_blob(pStmt, 0); - assert( a ); - - pEnd = &a[sqlite3_column_bytes(pStmt, 0)]; - a += sqlite3Fts3GetVarint(a, &nDoc); - while( anMergeCount) +#else +# define MergeCount(P) FTS3_MERGE_COUNT +#endif + /* ** When the core wants to read from the virtual table, it creates a ** virtual table cursor (an instance of the following structure) using @@ -567,6 +581,8 @@ int sqlite3Fts3Incrmerge(Fts3Table*,int,int); void sqlite3Fts3ErrMsg(char**,const char*,...); int sqlite3Fts3PutVarint(char *, sqlite3_int64); int sqlite3Fts3GetVarint(const char *, sqlite_int64 *); +int sqlite3Fts3GetVarintU(const char *, sqlite_uint64 *); +int sqlite3Fts3GetVarintBounded(const char*,const char*,sqlite3_int64*); int sqlite3Fts3GetVarint32(const char *, int *); int sqlite3Fts3VarintLen(sqlite3_uint64); void sqlite3Fts3Dequote(char *); diff --git a/ext/fts3/fts3_snippet.c b/ext/fts3/fts3_snippet.c index 6db3fd7d..2b20ba10 100644 --- a/ext/fts3/fts3_snippet.c +++ b/ext/fts3/fts3_snippet.c @@ -560,7 +560,7 @@ static int fts3BestSnippet( /* Set the *pmSeen output variable. */ for(i=0; ipEnd ){ + return FTS_CORRUPT_VTAB; + } + *pnDoc = nDoc; if( paLen ) *paLen = a; + if( ppEnd ) *ppEnd = pEnd; return SQLITE_OK; } @@ -1237,7 +1249,7 @@ static int fts3MatchinfoValues( case FTS3_MATCHINFO_NDOC: if( bGlobal ){ sqlite3_int64 nDoc = 0; - rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0); + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0, 0); pInfo->aMatchinfo[0] = (u32)nDoc; } break; @@ -1246,14 +1258,19 @@ static int fts3MatchinfoValues( if( bGlobal ){ sqlite3_int64 nDoc; /* Number of rows in table */ const char *a; /* Aggregate column length array */ + const char *pEnd; /* First byte past end of length array */ - rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, &a); + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, &a, &pEnd); if( rc==SQLITE_OK ){ int iCol; for(iCol=0; iColnCol; iCol++){ u32 iVal; sqlite3_int64 nToken; a += sqlite3Fts3GetVarint(a, &nToken); + if( a>pEnd ){ + rc = SQLITE_CORRUPT_VTAB; + break; + } iVal = (u32)(((u32)(nToken&0xffffffff)+nDoc/2)/nDoc); pInfo->aMatchinfo[iCol] = iVal; } @@ -1267,9 +1284,14 @@ static int fts3MatchinfoValues( if( rc==SQLITE_OK ){ int iCol; const char *a = sqlite3_column_blob(pSelectDocsize, 0); + const char *pEnd = a + sqlite3_column_bytes(pSelectDocsize, 0); for(iCol=0; iColnCol; iCol++){ sqlite3_int64 nToken; - a += sqlite3Fts3GetVarint(a, &nToken); + a += sqlite3Fts3GetVarintBounded(a, pEnd, &nToken); + if( a>pEnd ){ + rc = SQLITE_CORRUPT_VTAB; + break; + } pInfo->aMatchinfo[iCol] = (u32)nToken; } } @@ -1300,7 +1322,7 @@ static int fts3MatchinfoValues( if( rc!=SQLITE_OK ) break; if( bGlobal ){ if( pCsr->pDeferred ){ - rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc, 0); + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc,0,0); if( rc!=SQLITE_OK ) break; } rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo); diff --git a/ext/fts3/fts3_tokenizer.c b/ext/fts3/fts3_tokenizer.c index 0196f0f2..eab3f513 100644 --- a/ext/fts3/fts3_tokenizer.c +++ b/ext/fts3/fts3_tokenizer.c @@ -390,7 +390,9 @@ int queryTokenizer( sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); if( SQLITE_ROW==sqlite3_step(pStmt) ){ - if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){ + if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB + && sqlite3_column_bytes(pStmt, 0)==sizeof(*pp) + ){ memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp)); } } @@ -479,7 +481,7 @@ int sqlite3Fts3InitHashTable( ){ int rc = SQLITE_OK; void *p = (void *)pHash; - const int any = SQLITE_ANY; + const int any = SQLITE_UTF8|SQLITE_DIRECTONLY; #ifdef SQLITE_TEST char *zTest = 0; diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index 6960c31b..197aebdd 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -23,7 +23,7 @@ #include #include #include - +#include #define FTS_MAX_APPENDABLE_HEIGHT 16 @@ -67,7 +67,7 @@ int test_fts3_node_chunk_threshold = (4*1024)*4; #endif /* -** The two values that may be meaningfully bound to the :1 parameter in +** The values that may be meaningfully bound to the :1 parameter in ** statements SQL_REPLACE_STAT and SQL_SELECT_STAT. */ #define FTS_STAT_DOCTOTAL 0 @@ -335,7 +335,7 @@ static int fts3SqlStmt( ** returns zero rows. */ /* 28 */ "SELECT level, count(*) AS cnt FROM %Q.'%q_segdir' " " GROUP BY level HAVING cnt>=?" - " ORDER BY (level %% 1024) ASC LIMIT 1", + " ORDER BY (level %% 1024) ASC, 2 DESC LIMIT 1", /* Estimate the upper limit on the number of leaf nodes in a new segment ** created by merging the oldest :2 segments from absolute level :1. See @@ -696,7 +696,7 @@ static int fts3PendingListAppend( assert( !p || p->iLastDocid<=iDocid ); if( !p || p->iLastDocid!=iDocid ){ - sqlite3_int64 iDelta = iDocid - (p ? p->iLastDocid : 0); + u64 iDelta = (u64)iDocid - (u64)(p ? p->iLastDocid : 0); if( p ){ assert( p->nDatanSpace ); assert( p->aData[p->nData]==0 ); @@ -1153,7 +1153,7 @@ static int fts3AllocateSegdirIdx( ** segment and allocate (newly freed) index 0 at level iLevel. Otherwise, ** if iNext is less than FTS3_MERGE_COUNT, allocate index iNext. */ - if( iNext>=FTS3_MERGE_COUNT ){ + if( iNext>=MergeCount(p) ){ fts3LogMerge(16, getAbsoluteLevel(p, iLangid, iIndex, iLevel)); rc = fts3SegmentMerge(p, iLangid, iIndex, iLevel); *piIdx = 0; @@ -1237,6 +1237,8 @@ int sqlite3Fts3ReadBlock( } *paBlob = aByte; } + }else if( rc==SQLITE_ERROR ){ + rc = FTS_CORRUPT_VTAB; } return rc; @@ -1379,7 +1381,7 @@ static int fts3SegReaderNext( pNext += fts3GetVarint32(pNext, &nSuffix); if( nSuffix<=0 || (&pReader->aNode[pReader->nNode] - pNext)pReader->nTermAlloc + || nPrefix>pReader->nTerm ){ return FTS_CORRUPT_VTAB; } @@ -1529,18 +1531,18 @@ static int fts3SegReaderNextDocid( }else{ rc = fts3SegReaderRequire(pReader, p, FTS3_VARINT_MAX); if( rc==SQLITE_OK ){ - sqlite3_int64 iDelta; - pReader->pOffsetList = p + sqlite3Fts3GetVarint(p, &iDelta); + u64 iDelta; + pReader->pOffsetList = p + sqlite3Fts3GetVarintU(p, &iDelta); if( pTab->bDescIdx ){ - pReader->iDocid -= iDelta; + pReader->iDocid = (i64)((u64)pReader->iDocid - iDelta); }else{ - pReader->iDocid += iDelta; + pReader->iDocid = (i64)((u64)pReader->iDocid + iDelta); } } } } - return SQLITE_OK; + return rc; } @@ -2030,6 +2032,11 @@ static int fts3NodeAddTerm( nPrefix = fts3PrefixCompress(pTree->zTerm, pTree->nTerm, zTerm, nTerm); nSuffix = nTerm-nPrefix; + /* If nSuffix is zero or less, then zTerm/nTerm must be a prefix of + ** pWriter->zTerm/pWriter->nTerm. i.e. must be equal to or less than when + ** compared with BINARY collation. This indicates corruption. */ + if( nSuffix<=0 ) return FTS_CORRUPT_VTAB; + nReq += sqlite3Fts3VarintLen(nPrefix)+sqlite3Fts3VarintLen(nSuffix)+nSuffix; if( nReq<=p->nNodeSize || !pTree->zTerm ){ @@ -2274,6 +2281,7 @@ static int fts3SegWriterAdd( int rc; /* The current leaf node is full. Write it out to the database. */ + if( pWriter->iFree==LARGEST_INT64 ) return FTS_CORRUPT_VTAB; rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, nData); if( rc!=SQLITE_OK ) return rc; p->nLeafAdd++; @@ -2323,9 +2331,11 @@ static int fts3SegWriterAdd( /* Append the prefix-compressed term and doclist to the buffer. */ nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nPrefix); nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nSuffix); + assert( nSuffix>0 ); memcpy(&pWriter->aData[nData], &zTerm[nPrefix], nSuffix); nData += nSuffix; nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nDoclist); + assert( nDoclist>0 ); memcpy(&pWriter->aData[nData], aDoclist, nDoclist); pWriter->nData = nData + nDoclist; @@ -2345,6 +2355,7 @@ static int fts3SegWriterAdd( pWriter->zTerm = zNew; } assert( pWriter->zTerm==pWriter->zMalloc ); + assert( nTerm>0 ); memcpy(pWriter->zTerm, zTerm, nTerm); }else{ pWriter->zTerm = (char *)zTerm; @@ -2653,6 +2664,7 @@ static int fts3MsrBufferData( pMsr->aBuffer = pNew; } + assert( nList>0 ); memcpy(pMsr->aBuffer, pList, nList); return SQLITE_OK; } @@ -2966,14 +2978,12 @@ int sqlite3Fts3SegReaderStep( ** doclist. */ sqlite3_int64 iDelta; if( p->bDescIdx && nDoclist>0 ){ - iDelta = iPrev - iDocid; + if( iPrev<=iDocid ) return FTS_CORRUPT_VTAB; + iDelta = (i64)((u64)iPrev - (u64)iDocid); }else{ - iDelta = iDocid - iPrev; + if( nDoclist>0 && iPrev>=iDocid ) return FTS_CORRUPT_VTAB; + iDelta = (i64)((u64)iDocid - (u64)iPrev); } - if( iDelta<=0 && (nDoclist>0 || iDelta!=iDocid) ){ - return FTS_CORRUPT_VTAB; - } - assert( nDoclist>0 || iDelta==iDocid ); nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0); if( nDoclist+nByte>pCsr->nBuffer ){ @@ -3255,7 +3265,7 @@ static int fts3SegmentMerge( csr.zTerm, csr.nTerm, csr.aDoclist, csr.nDoclist); } if( rc!=SQLITE_OK ) goto finished; - assert( pWriter || bIgnoreEmpty ); + assert_fts3_nc( pWriter || bIgnoreEmpty ); if( iLevel!=FTS3_SEGCURSOR_PENDING ){ rc = fts3DeleteSegdir( @@ -3482,7 +3492,10 @@ static int fts3DoOptimize(Fts3Table *p, int bReturnDone){ int rc; sqlite3_stmt *pAllLangid = 0; - rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); + rc = sqlite3Fts3PendingTermsFlush(p); + if( rc==SQLITE_OK ){ + rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); + } if( rc==SQLITE_OK ){ int rc2; sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid); @@ -3503,7 +3516,6 @@ static int fts3DoOptimize(Fts3Table *p, int bReturnDone){ } sqlite3Fts3SegmentsClose(p); - sqlite3Fts3PendingTermsClear(p); return (rc==SQLITE_OK && bReturnDone && bSeenDone) ? SQLITE_DONE : rc; } @@ -3841,6 +3853,7 @@ static int fts3IncrmergePush( ** be added to. */ nPrefix = fts3PrefixCompress(pNode->key.a, pNode->key.n, zTerm, nTerm); nSuffix = nTerm - nPrefix; + if(nSuffix<=0 ) return FTS_CORRUPT_VTAB; nSpace = sqlite3Fts3VarintLen(nPrefix); nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; @@ -4235,6 +4248,10 @@ static int fts3IncrmergeLoad( pWriter->bNoLeafData = (pWriter->nLeafData==0); nRoot = sqlite3_column_bytes(pSelect, 4); aRoot = sqlite3_column_blob(pSelect, 4); + if( aRoot==0 ){ + sqlite3_reset(pSelect); + return nRoot ? SQLITE_NOMEM : FTS_CORRUPT_VTAB; + } }else{ return sqlite3_reset(pSelect); } @@ -4270,6 +4287,10 @@ static int fts3IncrmergeLoad( int i; int nHeight = (int)aRoot[0]; NodeWriter *pNode; + if( nHeight<1 || nHeight>FTS_MAX_APPENDABLE_HEIGHT ){ + sqlite3_reset(pSelect); + return FTS_CORRUPT_VTAB; + } pWriter->nLeafEst = (int)((iEnd - iStart) + 1)/FTS_MAX_APPENDABLE_HEIGHT; pWriter->iStart = iStart; @@ -4830,13 +4851,17 @@ static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){ const int nHint = pHint->n; int i; - i = pHint->n-2; + i = pHint->n-1; + if( (pHint->a[i] & 0x80) ) return FTS_CORRUPT_VTAB; while( i>0 && (pHint->a[i-1] & 0x80) ) i--; + if( i==0 ) return FTS_CORRUPT_VTAB; + i--; while( i>0 && (pHint->a[i-1] & 0x80) ) i--; pHint->n = i; i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); i += fts3GetVarint32(&pHint->a[i], pnInput); + assert( i<=nHint ); if( i!=nHint ) return FTS_CORRUPT_VTAB; return SQLITE_OK; @@ -4906,8 +4931,14 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ rc = fts3IncrmergeHintPop(&hint, &iHintAbsLevel, &nHintSeg); if( nSeg<0 || (iAbsLevel % nMod) >= (iHintAbsLevel % nMod) ){ + /* Based on the scan in the block above, it is known that there + ** are no levels with a relative level smaller than that of + ** iAbsLevel with more than nSeg segments, or if nSeg is -1, + ** no levels with more than nMin segments. Use this to limit the + ** value of nHintSeg to avoid a large memory allocation in case the + ** merge-hint is corrupt*/ iAbsLevel = iHintAbsLevel; - nSeg = nHintSeg; + nSeg = MIN(MAX(nMin,nSeg), nHintSeg); bUseHint = 1; bDirtyHint = 1; }else{ @@ -4920,7 +4951,7 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ /* If nSeg is less that zero, then there is no level with at least ** nMin segments and no hint in the %_stat table. No work to do. ** Exit early in this case. */ - if( nSeg<0 ) break; + if( nSeg<=0 ) break; /* Open a cursor to iterate through the contents of the oldest nSeg ** indexes of absolute level iAbsLevel. If this cursor is opened using @@ -4948,8 +4979,15 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ } if( SQLITE_OK==rc && pCsr->nSegment==nSeg && SQLITE_OK==(rc = sqlite3Fts3SegReaderStart(p, pCsr, pFilter)) - && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, pCsr)) ){ + int bEmpty = 0; + rc = sqlite3Fts3SegReaderStep(p, pCsr); + if( rc==SQLITE_OK ){ + bEmpty = 1; + }else if( rc!=SQLITE_ROW ){ + sqlite3Fts3SegReaderFinish(pCsr); + break; + } if( bUseHint && iIdx>0 ){ const char *zKey = pCsr->zTerm; int nKey = pCsr->nTerm; @@ -4960,11 +4998,13 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ if( rc==SQLITE_OK && pWriter->nLeafEst ){ fts3LogMerge(nSeg, iAbsLevel); - do { - rc = fts3IncrmergeAppend(p, pWriter, pCsr); - if( rc==SQLITE_OK ) rc = sqlite3Fts3SegReaderStep(p, pCsr); - if( pWriter->nWork>=nRem && rc==SQLITE_ROW ) rc = SQLITE_OK; - }while( rc==SQLITE_ROW ); + if( bEmpty==0 ){ + do { + rc = fts3IncrmergeAppend(p, pWriter, pCsr); + if( rc==SQLITE_OK ) rc = sqlite3Fts3SegReaderStep(p, pCsr); + if( pWriter->nWork>=nRem && rc==SQLITE_ROW ) rc = SQLITE_OK; + }while( rc==SQLITE_ROW ); + } /* Update or delete the input segments */ if( rc==SQLITE_OK ){ @@ -5029,7 +5069,7 @@ static int fts3DoIncrmerge( const char *zParam /* Nul-terminated string containing "A,B" */ ){ int rc; - int nMin = (FTS3_MERGE_COUNT / 2); + int nMin = (MergeCount(p) / 2); int nMerge = 0; const char *z = zParam; @@ -5074,7 +5114,7 @@ static int fts3DoAutoincrmerge( int rc = SQLITE_OK; sqlite3_stmt *pStmt = 0; p->nAutoincrmerge = fts3Getint(&zParam); - if( p->nAutoincrmerge==1 || p->nAutoincrmerge>FTS3_MERGE_COUNT ){ + if( p->nAutoincrmerge==1 || p->nAutoincrmerge>MergeCount(p) ){ p->nAutoincrmerge = 8; } if( !p->bHasStat ){ @@ -5157,12 +5197,12 @@ static u64 fts3ChecksumIndex( i64 iDocid = 0; i64 iCol = 0; - i64 iPos = 0; + u64 iPos = 0; pCsr += sqlite3Fts3GetVarint(pCsr, &iDocid); while( pCsrbDescIdx ){ + iDocid = (i64)((u64)iDocid - iVal); + }else{ + iDocid = (i64)((u64)iDocid + iVal); + } } }else{ iPos += (iVal - 2); @@ -5244,10 +5288,9 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){ for(iCol=0; rc==SQLITE_OK && iColnColumn; iCol++){ if( p->abNotindexed[iCol]==0 ){ const char *zText = (const char *)sqlite3_column_text(pStmt, iCol+1); - int nText = sqlite3_column_bytes(pStmt, iCol+1); sqlite3_tokenizer_cursor *pT = 0; - rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, nText,&pT); + rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, -1, &pT); while( rc==SQLITE_OK ){ char const *zToken; /* Buffer containing token */ int nToken = 0; /* Number of bytes in token */ @@ -5332,7 +5375,7 @@ static int fts3DoIntegrityCheck( ** meaningful value to insert is the text 'optimize'. */ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ - int rc; /* Return Code */ + int rc = SQLITE_ERROR; /* Return Code */ const char *zVal = (const char *)sqlite3_value_text(pVal); int nVal = sqlite3_value_bytes(pVal); @@ -5348,21 +5391,27 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ rc = fts3DoIncrmerge(p, &zVal[6]); }else if( nVal>10 && 0==sqlite3_strnicmp(zVal, "automerge=", 10) ){ rc = fts3DoAutoincrmerge(p, &zVal[10]); -#ifdef SQLITE_TEST - }else if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){ - p->nNodeSize = atoi(&zVal[9]); - rc = SQLITE_OK; - }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){ - p->nMaxPendingData = atoi(&zVal[11]); - rc = SQLITE_OK; - }else if( nVal>21 && 0==sqlite3_strnicmp(zVal, "test-no-incr-doclist=", 21) ){ - p->bNoIncrDoclist = atoi(&zVal[21]); - rc = SQLITE_OK; -#endif +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) }else{ - rc = SQLITE_ERROR; + int v; + if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){ + v = atoi(&zVal[9]); + if( v>=24 && v<=p->nPgsz-35 ) p->nNodeSize = v; + rc = SQLITE_OK; + }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){ + v = atoi(&zVal[11]); + if( v>=64 && v<=FTS3_MAX_PENDING_DATA ) p->nMaxPendingData = v; + rc = SQLITE_OK; + }else if( nVal>21 && 0==sqlite3_strnicmp(zVal,"test-no-incr-doclist=",21) ){ + p->bNoIncrDoclist = atoi(&zVal[21]); + rc = SQLITE_OK; + }else if( nVal>11 && 0==sqlite3_strnicmp(zVal,"mergecount=",11) ){ + v = atoi(&zVal[11]); + if( v>=4 && v<=FTS3_MERGE_COUNT && (v&1)==0 ) p->nMergeCount = v; + rc = SQLITE_OK; + } +#endif } - return rc; } diff --git a/ext/fts5/fts5.h b/ext/fts5/fts5.h index 9d71d3fb..081e534f 100644 --- a/ext/fts5/fts5.h +++ b/ext/fts5/fts5.h @@ -159,7 +159,7 @@ struct Fts5PhraseIter { ** ** xSetAuxdata(pFts5, pAux, xDelete) ** -** Save the pointer passed as the second argument as the extension functions +** Save the pointer passed as the second argument as the extension function's ** "auxiliary data". The pointer may then be retrieved by the current or any ** future invocation of the same fts5 extension function made as part of ** the same MATCH query using the xGetAuxdata() API. @@ -401,8 +401,8 @@ struct Fts5ExtensionApi { ** ** There are several ways to approach this in FTS5: ** -**

  1. By mapping all synonyms to a single token. In this case, the -** In the above example, this means that the tokenizer returns the +**
    1. By mapping all synonyms to a single token. In this case, using +** the above example, this means that the tokenizer returns the ** same token for inputs "first" and "1st". Say that token is in ** fact "first", so that when the user inserts the document "I won ** 1st place" entries are added to the index for tokens "i", "won", diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index c29b42b7..e0287d16 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -61,6 +61,11 @@ typedef sqlite3_uint64 u64; */ #define FTS5_MAX_PREFIX_INDEXES 31 +/* +** Maximum segments permitted in a single index +*/ +#define FTS5_MAX_SEGMENT 2000 + #define FTS5_DEFAULT_NEARDIST 10 #define FTS5_DEFAULT_RANK "bm25" @@ -417,6 +422,11 @@ int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch); */ void sqlite3Fts5IterClose(Fts5IndexIter*); +/* +** Close the reader blob handle, if it is open. +*/ +void sqlite3Fts5IndexCloseReader(Fts5Index*); + /* ** This interface is used by the fts5vocab module. */ diff --git a/ext/fts5/fts5_config.c b/ext/fts5/fts5_config.c index 4e1707b3..ddd23179 100644 --- a/ext/fts5/fts5_config.c +++ b/ext/fts5/fts5_config.c @@ -23,7 +23,7 @@ #define FTS5_DEFAULT_HASHSIZE (1024*1024) /* Maximum allowed page size */ -#define FTS5_MAX_PAGE_SIZE (128*1024) +#define FTS5_MAX_PAGE_SIZE (64*1024) static int fts5_iswhitespace(char x){ return (x==' '); @@ -150,7 +150,7 @@ static int fts5Dequote(char *z){ assert( q=='[' || q=='\'' || q=='"' || q=='`' ); if( q=='[' ) q = ']'; - while( ALWAYS(z[iIn]) ){ + while( z[iIn] ){ if( z[iIn]==q ){ if( z[iIn+1]!=q ){ /* Character iIn was the close quote. */ @@ -828,7 +828,7 @@ int sqlite3Fts5ConfigSetValue( if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ pgsz = sqlite3_value_int(pVal); } - if( pgsz<=0 || pgsz>FTS5_MAX_PAGE_SIZE ){ + if( pgsz<32 || pgsz>FTS5_MAX_PAGE_SIZE ){ *pbBadkey = 1; }else{ pConfig->pgsz = pgsz; @@ -881,6 +881,7 @@ int sqlite3Fts5ConfigSetValue( *pbBadkey = 1; }else{ if( nCrisisMerge<=1 ) nCrisisMerge = FTS5_DEFAULT_CRISISMERGE; + if( nCrisisMerge>=FTS5_MAX_SEGMENT ) nCrisisMerge = FTS5_MAX_SEGMENT-1; pConfig->nCrisisMerge = nCrisisMerge; } } diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index ce462af0..d9de1c81 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -2516,10 +2516,12 @@ static void fts5ExprFunction( azConfig[1] = "main"; azConfig[2] = "tbl"; for(i=3; iArgpReader ){ sqlite3_blob *pReader = p->pReader; p->pReader = 0; @@ -648,7 +643,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ assert( p->pReader==0 ); p->pReader = pBlob; if( rc!=SQLITE_OK ){ - fts5CloseReader(p); + sqlite3Fts5IndexCloseReader(p); } if( rc==SQLITE_ABORT ) rc = SQLITE_OK; } @@ -5209,7 +5204,7 @@ int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){ int sqlite3Fts5IndexSync(Fts5Index *p){ assert( p->rc==SQLITE_OK ); fts5IndexFlush(p); - fts5CloseReader(p); + sqlite3Fts5IndexCloseReader(p); return fts5IndexReturn(p); } @@ -5220,7 +5215,7 @@ int sqlite3Fts5IndexSync(Fts5Index *p){ ** records must be invalidated. */ int sqlite3Fts5IndexRollback(Fts5Index *p){ - fts5CloseReader(p); + sqlite3Fts5IndexCloseReader(p); fts5IndexDiscardData(p); fts5StructureInvalidate(p); /* assert( p->rc==SQLITE_OK ); */ @@ -5235,6 +5230,7 @@ int sqlite3Fts5IndexRollback(Fts5Index *p){ int sqlite3Fts5IndexReinit(Fts5Index *p){ Fts5Structure s; fts5StructureInvalidate(p); + fts5IndexDiscardData(p); memset(&s, 0, sizeof(Fts5Structure)); fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0); fts5StructureWrite(p, &s); @@ -5322,9 +5318,13 @@ int sqlite3Fts5IndexCharlenToBytelen( for(i=0; i=nByte ) return 0; /* Input contains fewer than nChar chars */ if( (unsigned char)p[n++]>=0xc0 ){ + if( n>=nByte ) return 0; while( (p[n] & 0xc0)==0x80 ){ n++; - if( n>=nByte ) break; + if( n>=nByte ){ + if( i+1==nChar ) break; + return 0; + } } } } @@ -5460,7 +5460,7 @@ int sqlite3Fts5IndexQuery( if( p->rc ){ sqlite3Fts5IterClose((Fts5IndexIter*)pRet); pRet = 0; - fts5CloseReader(p); + sqlite3Fts5IndexCloseReader(p); } *ppIter = (Fts5IndexIter*)pRet; @@ -5533,7 +5533,7 @@ void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5Index *pIndex = pIter->pIndex; fts5MultiIterFree(pIter); - fts5CloseReader(pIndex); + sqlite3Fts5IndexCloseReader(pIndex); } } @@ -5726,6 +5726,37 @@ static int fts5QueryCksum( return rc; } +/* +** Check if buffer z[], size n bytes, contains as series of valid utf-8 +** encoded codepoints. If so, return 0. Otherwise, if the buffer does not +** contain valid utf-8, return non-zero. +*/ +static int fts5TestUtf8(const char *z, int n){ + assert_nc( n>0 ); + int i = 0; + while( i=n || (z[i+1] & 0xC0)!=0x80 ) return 1; + i += 2; + }else + if( (z[i] & 0xF0)==0xE0 ){ + if( i+2>=n || (z[i+1] & 0xC0)!=0x80 || (z[i+2] & 0xC0)!=0x80 ) return 1; + i += 3; + }else + if( (z[i] & 0xF8)==0xF0 ){ + if( i+3>=n || (z[i+1] & 0xC0)!=0x80 || (z[i+2] & 0xC0)!=0x80 ) return 1; + if( (z[i+2] & 0xC0)!=0x80 ) return 1; + i += 3; + }else{ + return 1; + } + } + + return 0; +} /* ** This function is also purely an internal test. It does not contribute to @@ -5766,8 +5797,14 @@ static void fts5TestTerm( ** This check may only be performed if the hash table is empty. This ** is because the hash table only supports a single scan query at ** a time, and the multi-iter loop from which this function is called - ** is already performing such a scan. */ - if( p->nPendingData==0 ){ + ** is already performing such a scan. + ** + ** Also only do this if buffer zTerm contains nTerm bytes of valid + ** utf-8. Otherwise, the last part of the buffer contents might contain + ** a non-utf-8 sequence that happens to be a prefix of a valid utf-8 + ** character stored in the main fts index, which will cause the + ** test to fail. */ + if( p->nPendingData==0 && 0==fts5TestUtf8(zTerm, nTerm) ){ if( iIdx>0 && rc==SQLITE_OK ){ int f = flags|FTS5INDEX_QUERY_TEST_NOIDX; ck2 = 0; @@ -5890,7 +5927,8 @@ static void fts5IndexIntegrityCheckSegment( if( pSeg->pgnoFirst==0 ) return; fts5IndexPrepareStmt(p, &pStmt, sqlite3_mprintf( - "SELECT segid, term, (pgno>>1), (pgno&1) FROM %Q.'%q_idx' WHERE segid=%d", + "SELECT segid, term, (pgno>>1), (pgno&1) FROM %Q.'%q_idx' WHERE segid=%d " + "ORDER BY 1, 2", pConfig->zDb, pConfig->zName, pSeg->iSegid )); @@ -5899,8 +5937,8 @@ static void fts5IndexIntegrityCheckSegment( i64 iRow; /* Rowid for this leaf */ Fts5Data *pLeaf; /* Data for this leaf */ + const char *zIdxTerm = (const char*)sqlite3_column_blob(pStmt, 1); int nIdxTerm = sqlite3_column_bytes(pStmt, 1); - const char *zIdxTerm = (const char*)sqlite3_column_text(pStmt, 1); int iIdxLeaf = sqlite3_column_int(pStmt, 2); int bIdxDlidx = sqlite3_column_int(pStmt, 3); diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index fc4ec0c4..347bf7f2 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -289,7 +289,10 @@ static void fts5CheckTransactionState(Fts5FullTable *p, int op, int iSavepoint){ case FTS5_ROLLBACKTO: assert( p->ts.eState==1 ); assert( iSavepoint>=-1 ); - assert( iSavepoint<=p->ts.iSavepoint ); + /* The following assert() can fail if another vtab strikes an error + ** within an xSavepoint() call then SQLite calls xRollbackTo() - without + ** having called xSavepoint() on this vtab. */ + /* assert( iSavepoint<=p->ts.iSavepoint ); */ p->ts.iSavepoint = iSavepoint; break; } @@ -744,6 +747,7 @@ static void fts5FreeCursorComponents(Fts5Cursor *pCsr){ sqlite3_free(pCsr->zRankArgs); } + sqlite3Fts5IndexCloseReader(pTab->p.pIndex); memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan - (u8*)pCsr)); } @@ -894,15 +898,24 @@ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){ break; } - default: + default: { + Fts5Config *pConfig = ((Fts5Table*)pCursor->pVtab)->pConfig; + pConfig->bLock++; rc = sqlite3_step(pCsr->pStmt); + pConfig->bLock--; if( rc!=SQLITE_ROW ){ CsrFlagSet(pCsr, FTS5CSR_EOF); rc = sqlite3_reset(pCsr->pStmt); + if( rc!=SQLITE_OK ){ + pCursor->pVtab->zErrMsg = sqlite3_mprintf( + "%s", sqlite3_errmsg(pConfig->db) + ); + } }else{ rc = SQLITE_OK; } break; + } } } @@ -1187,6 +1200,13 @@ static int fts5FilterMethod( int iIdxStr = 0; Fts5Expr *pExpr = 0; + if( pConfig->bLock ){ + pTab->p.base.zErrMsg = sqlite3_mprintf( + "recursively defined fts5 content table" + ); + return SQLITE_ERROR; + } + if( pCsr->ePlan ){ fts5FreeCursorComponents(pCsr); memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr)); @@ -1407,10 +1427,13 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){ } if( rc==SQLITE_OK && CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) ){ + Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); assert( pCsr->pExpr ); sqlite3_reset(pCsr->pStmt); sqlite3_bind_int64(pCsr->pStmt, 1, fts5CursorRowid(pCsr)); + pTab->pConfig->bLock++; rc = sqlite3_step(pCsr->pStmt); + pTab->pConfig->bLock--; if( rc==SQLITE_ROW ){ rc = SQLITE_OK; CsrFlagClear(pCsr, FTS5CSR_REQUIRE_CONTENT); @@ -1418,6 +1441,10 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){ rc = sqlite3_reset(pCsr->pStmt); if( rc==SQLITE_OK ){ rc = FTS5_CORRUPT; + }else if( pTab->pConfig->pzErrmsg ){ + *pTab->pConfig->pzErrmsg = sqlite3_mprintf( + "%s", sqlite3_errmsg(pTab->pConfig->db) + ); } } } @@ -2433,10 +2460,12 @@ static int fts5ColumnMethod( } } }else if( !fts5IsContentless(pTab) ){ + pConfig->pzErrmsg = &pTab->p.base.zErrMsg; rc = fts5SeekCursor(pCsr, 1); if( rc==SQLITE_OK ){ sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1)); } + pConfig->pzErrmsg = 0; } return rc; } diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index 960c1805..22f90c0e 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -560,6 +560,8 @@ int sqlite3Fts5StorageDeleteAll(Fts5Storage *p){ Fts5Config *pConfig = p->pConfig; int rc; + p->bTotalsValid = 0; + /* Delete the contents of the %_data and %_docsize tables. */ rc = fts5ExecPrintf(pConfig->db, 0, "DELETE FROM %Q.'%q_data';" @@ -611,10 +613,11 @@ int sqlite3Fts5StorageRebuild(Fts5Storage *p){ for(ctx.iCol=0; rc==SQLITE_OK && ctx.iColnCol; ctx.iCol++){ ctx.szCol = 0; if( pConfig->abUnindexed[ctx.iCol]==0 ){ + const char *zText = (const char*)sqlite3_column_text(pScan, ctx.iCol+1); + int nText = sqlite3_column_bytes(pScan, ctx.iCol+1); rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, - (const char*)sqlite3_column_text(pScan, ctx.iCol+1), - sqlite3_column_bytes(pScan, ctx.iCol+1), + zText, nText, (void*)&ctx, fts5StorageInsertCallback ); @@ -736,10 +739,11 @@ int sqlite3Fts5StorageIndexInsert( for(ctx.iCol=0; rc==SQLITE_OK && ctx.iColnCol; ctx.iCol++){ ctx.szCol = 0; if( pConfig->abUnindexed[ctx.iCol]==0 ){ + const char *zText = (const char*)sqlite3_value_text(apVal[ctx.iCol+2]); + int nText = sqlite3_value_bytes(apVal[ctx.iCol+2]); rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, - (const char*)sqlite3_value_text(apVal[ctx.iCol+2]), - sqlite3_value_bytes(apVal[ctx.iCol+2]), + zText, nText, (void*)&ctx, fts5StorageInsertCallback ); @@ -908,10 +912,11 @@ int sqlite3Fts5StorageIntegrity(Fts5Storage *p){ rc = sqlite3Fts5TermsetNew(&ctx.pTermset); } if( rc==SQLITE_OK ){ + const char *zText = (const char*)sqlite3_column_text(pScan, i+1); + int nText = sqlite3_column_bytes(pScan, i+1); rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, - (const char*)sqlite3_column_text(pScan, i+1), - sqlite3_column_bytes(pScan, i+1), + zText, nText, (void*)&ctx, fts5StorageIntegrityCallback ); diff --git a/ext/fts5/test/fts5content.test b/ext/fts5/test/fts5content.test index bd510a55..74a74e2a 100644 --- a/ext/fts5/test/fts5content.test +++ b/ext/fts5/test/fts5content.test @@ -257,16 +257,41 @@ do_execsql_test 6.2 { # Check that an fts5 table cannot be its own content table. # reset_db -do_execsql_test 7.1 { +do_execsql_test 7.1.1 { CREATE VIRTUAL TABLE t1 USING fts5(a, c=t1 ); INSERT INTO t1( a ) VALUES('abc'); } -do_catchsql_test 7.2 { +do_catchsql_test 7.1.2 { SELECT * FROM t1; } {1 {recursively defined fts5 content table}} -do_catchsql_test 7.3 { +do_catchsql_test 7.1.3 { SELECT * FROM t1('abc'); } {1 {recursively defined fts5 content table}} +do_catchsql_test 7.1.4 { + SELECT count(*) FROM t1; +} {1 {recursively defined fts5 content table}} +do_catchsql_test 7.1.5 { + SELECT * FROM t1('abc') ORDER BY rank; +} {1 {recursively defined fts5 content table}} + +reset_db +do_execsql_test 7.2.1 { + CREATE VIRTUAL TABLE t1 USING fts5(a, c=t2 ); + CREATE VIRTUAL TABLE t2 USING fts5(a, c=t1 ); + INSERT INTO t1( a ) VALUES('abc'); +} +do_catchsql_test 7.2.2 { + SELECT * FROM t1; +} {1 {recursively defined fts5 content table}} +do_catchsql_test 7.2.3 { + SELECT * FROM t1('abc'); +} {1 {recursively defined fts5 content table}} +do_catchsql_test 7.2.4 { + SELECT count(*) FROM t1; +} {1 {recursively defined fts5 content table}} +do_catchsql_test 7.2.5 { + SELECT * FROM t1('abc') ORDER BY rank; +} {1 {recursively defined fts5 content table}} finish_test diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index bab61e80..4e0ae64a 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -4484,7 +4484,7 @@ do_test 36.0 { do_catchsql_test 36.1 { INSERT INTO t1(b) VALUES( x'78de3fa24af3733ca8769291a0fee3669f9fddefc5cba913e4225d4b6ce2b04f26b87fad3ee6f9b7d90a1ea62a169bf41e5d32707a6ca5c3d05e4bde05c9d89eaaa8c50e74333d2e9fcd7dfe95528a3a016aac1102d825c5cd70cf99d8a88e0ea7f798d4334386518b7ad359beb168b93aba059a2a3bd93112d65b44c12b9904ea786b204d80531cdf0504bf9b203dbe927061974caf7b9f30cbc3397b61f802e732012a6663d41c3607d6f1c0dbcfd489adac05ca500c0b04439d894cd93a840159225ef73b627e178b9f84b3ffe66cf22a963a8368813ff7961fc47f573211ccec95e0220dcbb3bf429f4a50ba54d7a53784ac51bfef346e6a'); -} {1 {database disk image is malformed}} +} {0 {}} #------------------------------------------------------------------------- reset_db @@ -9774,6 +9774,339 @@ do_catchsql_test 66.1 { INSERT INTO t1(t1) VALUES('integrity-check'); } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +# +reset_db +do_test 67.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 24576 pagesize 4096 filename crash-43ed0ad79c0194.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........ +| 96: 00 00 00 00 0d 00 00 00 06 0d e2 00 0f c4 0f 6a ...............j +| 112: 0e fc 0e 9d 0e 3d 0d e2 01 00 00 00 00 00 00 00 .....=.......... +| 3552: 00 00 59 06 06 17 21 21 01 7f 74 61 62 6c 65 74 ..Y...!!..tablet +| 3568: 74 74 5f 63 6f 6e 66 69 67 74 74 74 5f 63 6f 6e tt_configttt_con +| 3584: 66 69 67 06 43 52 45 41 54 45 20 54 41 42 4c 45 fig.CREATE TABLE +| 3600: 20 27 74 74 74 5f 63 6f 6e 66 69 67 27 28 6b 20 'ttt_config'(k +| 3616: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 PRIMARY KEY, v) +| 3632: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5e 05 07 WITHOUT ROWID^.. +| 3648: 17 23 23 01 81 03 74 61 62 6c 65 74 74 74 5f 64 .##...tablettt_d +| 3664: 6f 63 73 69 7a 65 74 74 74 5f 64 6f 63 73 69 7a ocsizettt_docsiz +| 3680: 65 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 e.CREATE TABLE ' +| 3696: 74 74 74 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 ttt_docsize'(id +| 3712: 49 4e 54 45 47 45 52 20 51 52 49 4d 41 52 59 20 INTEGER QRIMARY +| 3728: 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 29 5d 04 07 KEY, sz BLOB)].. +| 3744: 17 23 23 01 81 01 74 61 62 6c 65 74 74 74 5f 63 .##...tablettt_c +| 3760: 6f 6e 74 65 6e 74 74 74 74 5f 63 6f 6e 74 65 6e ontentttt_conten +| 3776: 74 04 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 t.CREATE TABLE ' +| 3792: 74 74 74 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20 ttt_content'(id +| 3808: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 f1 59 20 INTEGER PRIMA.Y +| 3824: 4b 45 59 2c 20 63 30 2c 20 63 31 29 6c 03 07 17 KEY, c0, c1)l... +| 3840: 1b 1b 01 81 2f 74 61 62 6c 65 74 74 74 5f 69 64 ..../tablettt_id +| 3856: 78 74 74 74 5f 69 64 78 03 43 52 45 41 54 45 20 xttt_idx.CREATE +| 3872: 54 41 42 4c 45 20 27 74 74 74 5f 69 64 78 27 28 TABLE 'ttt_idx'( +| 3888: 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 67 6e segid, term, pgn +| 3904: 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 73 o, PRIMARY KEY(s +| 3920: 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 54 egid, term)) WIT +| 3936: 48 4f 55 54 20 52 4f 57 49 44 58 02 07 17 1d 1d HOUT ROWIDX..... +| 3952: 01 81 03 74 61 62 6c 65 74 74 74 5f 64 61 74 61 ...tablettt_data +| 3968: 74 74 74 5f 64 61 74 61 02 43 52 45 41 54 45 20 ttt_data.CREATE +| 3984: 54 41 42 4c 45 20 27 74 74 74 5f 64 61 74 61 27 TABLE 'ttt_data' +| 4000: 28 69 64 20 49 4e 54 45 47 55 52 20 50 52 49 4d (id INTEGUR PRIM +| 4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 ARY KEY, block B +| 4032: 4c 50 42 29 3a 02 06 17 13 13 08 5f 74 61 62 6c LPB):......_tabl +| 4048: 65 74 74 74 74 74 74 43 52 45 41 54 45 20 56 49 ettttttCREATE VI +| 4064: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 74 74 20 RTUAL TABLE ttt +| 4080: 55 53 49 4e 47 20 66 74 73 35 28 61 2c 20 62 29 USING fts5(a, b) +| page 2 offset 4096 +| 0: 0d 0f 44 00 05 0e 71 00 0f e7 0e 81 0f af 0f 58 ..D...q........X +| 16: 0e 98 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3712: 00 15 0a 03 00 30 00 00 00 00 01 03 03 00 03 01 .....0.......... +| 3728: 01 01 02 01 01 03 01 01 81 24 8c 80 80 80 80 01 .........$...... +| 3744: 04 00 82 4c 00 00 00 9b 02 30 65 03 1a 12 05 05 ...L.....0e..... +| 3760: 07 05 01 01 04 03 03 08 04 03 01 2e 02 05 f7 07 ................ +| 3776: 01 e6 f5 07 05 01 01 04 03 03 01 22 03 18 03 03 ................ +| 3792: 08 03 03 02 01 65 03 1e 03 05 05 04 05 05 01 01 .....e.......... +| 3808: 03 06 03 f4 06 04 03 00 36 03 ff 05 04 05 05 04 ........6....... +| 3824: 05 05 04 05 04 f1 01 03 06 04 04 06 04 04 06 04 ................ +| 3840: 04 07 04 03 03 01 65 03 14 04 05 07 05 05 01 01 ......e......... +| 3856: 02 08 a5 01 20 04 05 01 94 f7 05 07 05 05 01 01 .... ........... +| 3872: 02 08 0a 0a 0a 04 01 65 03 02 0a 00 06 0a 0a 0a .......e........ +| 3888: 05 01 65 03 06 a7 01 0a 01 0a 01 01 0a 0a 0a 04 ..e............. +| 3904: 2b 31 21 0b 0f ef 00 14 2a 00 00 00 00 01 02 02 +1!.....*....... +| 3920: 00 02 01 01 01 02 11 01 50 88 80 80 80 80 01 04 ........P....... +| 3936: 00 81 24 00 00 00 47 02 30 65 02 1a 02 05 05 07 ..$...G.0e...... +| 3952: 05 e6 01 07 aa e3 08 03 03 02 01 65 02 1e 03 05 ...........e.... +| 3968: 05 05 04 f5 01 01 03 06 04 04 06 04 13 03 01 65 ...............e +| 3984: 02 14 04 05 07 05 05 01 f7 f2 08 0a 04 01 65 02 ..............e. +| 4000: 02 0a 05 01 65 02 06 00 f1 0a 04 12 14 0f 06 31 ....e..........1 +| 4016: 84 80 80 80 80 01 03 00 68 00 00 00 2b 02 30 65 ........h...+.0e +| 4032: 01 10 02 05 05 00 01 04 03 03 02 01 65 01 12 03 ............e... +| 4048: 05 05 01 01 03 06 04 03 03 01 65 01 0e 04 05 04 ..........e..... +| 4064: 01 01 02 08 04 0d 0e 06 01 03 00 12 04 4c 4c 00 .............LL. +| 4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 02 ...$............ +| page 3 offset 8192 +| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| page 4 offset 12288 +| 3600: 00 00 00 00 00 00 00 00 00 00 81 52 04 06 00 81 ...........R.... +| 3616: 5d 81 55 65 20 65 65 20 65 65 65 20 65 20 65 65 ].Ue ee eee e ee +| 3632: 20 65 65 65 28 15 20 65 65 20 65 65 65 65 20 65 eee(. ee eeee e +| 3648: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65 e eee e ee eee e +| 3664: 20 65 65 20 65 65 65 65 20 65 66 20 65 65 55 20 ee eeee ef eeU +| 3680: 65 20 65 55 20 65 65 65 20 65 20 65 65 20 65 65 e eU eee e ee ee +| 3696: 65 64 20 65 61 c0 65 65 65 20 65 20 65 65 20 65 ed ea.eee e ee e +| 3712: 65 65 20 79 20 65 65 20 65 65 65 65 65 65 20 65 ee y ee eeeeee e +| 3728: 65 1f 65 20 65 20 65 20 65 65 20 65 65 65 20 65 e.e e e ee eee e +| 3744: 65 20 65 65 65 65 65 20 65 65 20 65 20 65 20 65 e eeeee ee e e e +| 3760: 20 65 65 20 65 65 65 20 6b 85 20 65 65 65 66 65 ee eee k. eeefe +| 3776: 20 65 65 10 65 20 65 20 65 20 65 65 20 65 65 65 ee.e e e ee eee +| 3792: 20 65 65 20 65 65 65 65 65 20 65 65 20 65 20 65 ee eeeee ee e e +| 3808: 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65 6a e ee eee ee eej +| 3824: 03 04 00 75 71 65 20 65 65 20 65 65 65 20 65 30 ...uqe ee eee e0 +| 3840: 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65 65 ee eee e ee eeee +| 3856: 20 65 65 20 65 65 65 20 65 1f 65 65 20 65 65 65 ee eee e.ee eee +| 3872: 20 65 20 65 65 20 65 65 65 65 65 66 20 65 65 20 e ee eeeeef ee +| 3888: 65 21 27 20 65 20 55 65 20 66 65 64 20 65 65 00 e!' e Ue fed ee. +| page 5 offset 16384 +| 4064: 00 00 00 00 05 04 03 00 10 11 20 05 03 03 00 10 .......... ..... +| 4080: 11 11 05 02 03 00 00 11 11 05 01 03 00 10 09 09 ................ +| page 6 offset 20480 +| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 01 00 00 00 00 ................ +| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. +| end crash-43ed0ad79c0194.db +}]} {} + +do_catchsql_test 67.1 { + SELECT snippet(ttt, null,null, + EXISTS(SELECT 1 FROM ttt('e NuOT ee*e*ÏNuOY ee*') ) , '', + (SELECT 1 FROM ttt('eu NuOT ee*e* NuOY ee*')) + ), * FROM ttt('e') +} {1 {database disk image is malformed}} + +#------------------------------------------------------------------------- +# +reset_db +do_test 68.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 32768 pagesize 4096 filename crash-41234e232809e7.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 08 .....@ ........ +| 32: 00 00 00 02 00 00 00 01 00 00 00 09 00 00 00 04 ................ +| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6 +| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 0d 92 00 00 00 00 ...k............ +| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet +| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE +| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta +| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c +| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB +| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k +| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v) +| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[. +| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d +| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize +| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't +| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN +| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE +| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...! +| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont +| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR +| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c +| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG +| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY, +| 3776: 63 30 2c 20 63 31 2c 20 63 32 29 69 04 07 17 19 c0, c1, c2)i.... +| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt +| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB +| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi +| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P +| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid +| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT +| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t +| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da +| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE +| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT +| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY +| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8.. +| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR +| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB +| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5 +| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c)......... +| page 3 offset 8192 +| 0: 0d 00 00 00 03 0c 94 00 0f e6 0f ef 0c 94 00 00 ................ +| 16: 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J.......... +| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00......... +| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 30 31 36 30 ...........20160 +| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 00 01 34 01 609...........4. +| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 04 01 02 ..........5..... +| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 04 ......0000000... +| 3312: 01 02 04 01 02 03 f1 06 62 69 6e 62 72 79 03 06 ........binbry.. +| 3328: 01 02 02 03 06 01 02 02 03 06 01 02 01 03 16 01 ................ +| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ +| 3376: 03 04 71 02 02 03 06 11 02 02 01 08 63 6f 6d 70 ..q.........comp +| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d +| 3408: 62 73 74 61 74 07 02 03 01 02 03 01 02 03 02 04 bstat........... +| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 06 65 ebug...........e +| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable........... +| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 03 02 ................ +| 3472: 00 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................ +| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................ +| 3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02 ......xtension.. +| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4... +| 3536: 01 02 03 01 02 03 04 01 35 0d 02 03 01 02 03 01 ........5....... +| 3552: 02 03 01 03 66 63 63 01 02 03 01 02 03 01 02 03 ....fcc......... +| 3568: 02 06 65 6f 70 6f 6c 79 10 02 03 01 02 03 01 02 ..eopoly........ +| 3584: 03 01 05 6a 73 6f 5e 31 13 02 03 01 02 03 01 02 ...jso^1........ +| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load......... +| 3616: 01 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05 ..max........... +| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory........... +| 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n +| 3664: 6f 63 61 73 65 02 06 01 02 02 03 06 01 02 02 03 ocase........... +| 3680: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 13 06 ................ +| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02 ...omit......... +| 3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03 ..rtree......... +| 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 12 02 03 06 ..im............ +| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ +| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe.... +| 3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab..... +| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x......... +| 3872: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................ +| 3888: 01 06 01 01 02 01 06 01 01 02 01 05 f1 01 02 01 ................ +| 3904: 06 01 01 02 01 06 01 5b 02 01 06 01 01 02 01 06 .......[........ +| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................ +| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................ +| 3952: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................ +| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................ +| 3984: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................ +| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................ +| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................ +| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................ +| 4048: 12 44 13 11 0f 47 13 0f 0c 0e 11 10 0f 0e 10 0f .D...G.......... +| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$. +| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............ +| page 4 offset 12288 +| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0b 01 02 ................ +| page 5 offset 16384 +| 0: 0d 00 00 00 24 0c 0a 00 0f d8 0f af 0f 86 0f 74 ....$..........t +| 16: 0f 61 0f 4e 0f 2f 0f 0f 0e ef 0e d7 0e be 0e a5 .a.N./.......... +| 32: 0e 8d 0e 74 0e 5b 0e 40 0e 24 0e 08 0d ef 0d d5 ...t.[.@.$...... +| 48: 0d bb 0d a0 0d 84 0d 68 0d 4f 0d 35 0d 1b 0c fb .......h.O.5.... +| 64: 0c da 0c b9 0c 99 0c 78 0c 57 0c 3e 0c 24 0c 0a .......x.W.>.$.. +| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%. +| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI +| 3104: 4f 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 OARY.#..%..THREA +| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 22 DSAFE=0XNOCASE.. +| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d ..%..THREADSAFE= +| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM +| 3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 4f IT LOAD EXTENSIO +| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O +| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI +| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3.. +| 3232: 4f 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMIT LOAD EXTENS +| 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 0f 19 IONXRTRIM....3.. +| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX MEMORY=50000 +| 3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f 000XBINARY....3. +| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000 +| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 33 0000XNOCASE....3 +| 3328: 0f 17 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 ..MAX MEMORY=500 +| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....% +| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB +| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3392: 4c 45 20 52 54 52 46 45 58 4e 4f 43 41 53 45 17 LE RTRFEXNOCASE. +| 3408: 19 05 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 ...%..ENABLE RTR +| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E +| 3440: 49 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 IABLE MEMSYS5XBI +| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL +| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE +| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME +| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 00 25 MSYS5XRTRIM....% +| 3520: 0f 19 45 4e 41 42 4c 45 20 4a 53 4f 4e 31 58 42 ..ENABLE JSON1XB +| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3552: 4c 45 20 4a 53 4f 4e 31 58 4e 4f 43 41 53 45 17 LE JSON1XNOCASE. +| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO +| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E +| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 57 42 49 NABLE GEOPOLYWBI +| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL +| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 42 41 53 45 E GEOPOLYXNOBASE +| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE +| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....# +| 3680: 0f 19 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49 ..ENABLE FTS5XBI +| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL +| 3712: 45 20 46 54 53 35 58 4e 4f 43 41 53 45 16 0d 05 E FTS5XNOCASE... +| 3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X +| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB +| 3760: 4c 45 20 46 54 53 34 58 42 49 4e 41 52 59 17 0b LE FTS4XBINARY.. +| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4 +| 3792: 58 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e XNOCASE....#..EN +| 3808: 41 42 4c 45 20 46 54 53 34 58 52 54 52 49 4d 1e ABLE FTS4XRTRIM. +| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY. +| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE. +| 3888: 07 05 00 31 0f 17 b7 4e 41 42 4c 45 20 44 42 53 ...1...NABLE DBS +| 3904: 54 41 54 20 66 54 41 42 58 52 54 52 49 4d 11 06 TAT fTABXRTRIM.. +| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52 .....DEBUGXBINAR +| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO +| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG +| 3968: 58 62 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XbTRIM'...C..COM +| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0 +| 4000: 32 30 31 36 30 36 30 39 52 02 4a 4e 41 52 59 27 20160609R.JNARY' +| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3d 67 ...C..COMPILER=g +| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060 +| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XNOCASE&...C..C +| 4064: 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e OMPILER=gcc-5.4. +| 4080: 30 20 32 30 31 36 30 36 30 39 58 52 54 52 49 4d 0 20160609XRTRIM +| page 6 offset 20480 +| 0: 0d 00 00 00 24 0e e0 00 0f f8 0f f0 0f e8 0f e0 ....$........... +| 16: 0f d8 0f d0 0f c8 0f c0 0f b8 0f b0 0f a8 0f a0 ................ +| 32: 0f 98 0f 90 0f 88 0f 80 0f 78 0f 70 0f 68 0f 60 .........x.p.h.` +| 48: 0f 58 0f 50 0f 48 0f 40 0f 38 0f 30 0f 28 0f 20 .X.P.H.@.8.0.(. +| 64: 0f 18 0f 10 0f 08 0f 00 0e f8 0e f0 0e e8 0e e0 ................ +| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#...... +| 3824: 06 22 03 00 12 02 01 01 06 21 03 00 12 03 01 01 .........!...... +| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 01 01 . .............. +| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................ +| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................ +| 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................ +| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................ +| 3920: 06 16 03 00 12 02 01 01 06 15 03 00 12 02 01 01 ................ +| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................ +| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................ +| 3968: 06 10 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................ +| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................ +| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01 ................ +| 4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01 ................ +| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................ +| 4048: 06 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01 ................ +| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................ +| 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................ +| page 7 offset 24576 +| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. +| page 8 offset 28672 +| 0: 0d 00 00 00 03 0f d6 00 0f f4 0f e9 0f d6 00 00 ................ +| 4048: 00 00 00 00 00 00 11 04 02 2b 69 6e 74 65 67 72 .........+integr +| 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb +| 4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 5d 69 71 a5 uild....opti]iq. +| end crash-41234e232809e7.db +.testctrl prng_seed 1 db +}]} {} + +do_catchsql_test 68.1 { + PRAGMA reverse_unordered_selects=ON; + INSERT INTO t1(t1) SELECT x FROM t2; +} {1 {database disk image is malformed}} sqlite3_fts5_may_be_corrupt 0 diff --git a/ext/fts5/test/fts5eb.test b/ext/fts5/test/fts5eb.test index dd66decb..9d6f251e 100644 --- a/ext/fts5/test/fts5eb.test +++ b/ext/fts5/test/fts5eb.test @@ -59,10 +59,27 @@ do_catchsql_test 2.1 { SELECT fts5_expr() } {1 {wrong number of arguments to function fts5_expr}} -do_catchsql_test 2.1 { +do_catchsql_test 2.2 { SELECT fts5_expr_tcl() } {1 {wrong number of arguments to function fts5_expr_tcl}} +do_catchsql_test 2.3 { + SELECT fts5_expr('') +} {1 {fts5: syntax error near ""}} + +do_catchsql_test 2.4 { + SELECT fts5_expr(NULL) +} {1 {fts5: syntax error near ""}} + +do_catchsql_test 2.5 { + SELECT fts5_expr(NULL, NULL) +} {1 {parse error in ""}} + +for {set i 0} {$i < 255} {incr i} { + do_test 2.6.$i { + lindex [catchsql {sELECT fts5_expr(NULL, char($i));}] 0 + } 1 +} do_execsql_test 3.0 { CREATE VIRTUAL TABLE e1 USING fts5(text, tokenize = 'porter unicode61'); diff --git a/ext/fts5/test/fts5full.test b/ext/fts5/test/fts5full.test index 91ded37d..751e874c 100644 --- a/ext/fts5/test/fts5full.test +++ b/ext/fts5/test/fts5full.test @@ -36,7 +36,7 @@ do_test 1.1 { execsql { INSERT INTO x8 VALUES( rnddoc(5) ); } } } msg] $msg -} {1 {database or disk is full}} +} {0 {}} finish_test diff --git a/ext/fts5/test/fts5integrity.test b/ext/fts5/test/fts5integrity.test index 25c72773..38dff21f 100644 --- a/ext/fts5/test/fts5integrity.test +++ b/ext/fts5/test/fts5integrity.test @@ -210,4 +210,76 @@ foreach {tn pgsz} { } {1000} } +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 7.0 { + PRAGMA encoding = 'UTF-16'; + CREATE VIRTUAL TABLE vt0 USING fts5(c0); + INSERT INTO vt0 VALUES (x'46f0'); + SELECT quote(c0) FROM vt0; +} {X'46F0'} +do_execsql_test 7.1 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} +do_execsql_test 7.2 { + INSERT INTO vt0(vt0) VALUES('rebuild'); +} +do_execsql_test 7.3 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} +do_execsql_test 7.4 { + UPDATE vt0 SET c0=''; +} +do_execsql_test 7.5 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} + +#------------------------------------------------------------------------- +# Ticket 7a458c2a5f4 +# +reset_db +do_execsql_test 8.0 { + PRAGMA locking_mode = EXCLUSIVE; + PRAGMA journal_mode = PERSIST; + CREATE VIRTUAL TABLE vt0 USING fts5(c0); +} {exclusive persist} +do_execsql_test 8.1 { + PRAGMA data_version +} {1} +do_execsql_test 8.2 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); + PRAGMA data_version; +} {1} +do_execsql_test 8.1 { + INSERT INTO vt0(vt0, rank) VALUES('usermerge', 2); +} + +#------------------------------------------------------------------------- +# Ticket [771fe617] +# +reset_db +do_execsql_test 9.0 { + PRAGMA encoding = 'UTF16'; + CREATE VIRTUAL TABLE vt0 USING fts5(c0); +} + +#explain_i { SELECT quote(SUBSTR(x'37', 0)); } +#execsql { PRAGMA vdbe_trace = 1 } +do_execsql_test 9.1.1 { + SELECT quote(SUBSTR(x'37', 0)); +} {X'37'} +do_execsql_test 9.1.2 { + SELECT quote(x'37'); +} {X'37'} + +breakpoint +do_execsql_test 9.2 { + INSERT INTO vt0 VALUES (SUBSTR(x'37', 0)); +-- INSERT INTO vt0 VALUES (x'37'); +} +do_execsql_test 9.3 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} + finish_test diff --git a/ext/fts5/test/fts5matchinfo.test b/ext/fts5/test/fts5matchinfo.test index 4dc04b78..d8d8d84e 100644 --- a/ext/fts5/test/fts5matchinfo.test +++ b/ext/fts5/test/fts5matchinfo.test @@ -491,4 +491,30 @@ do_catchsql_test 14.2 { SELECT matchinfo(x1, 'd') FROM x1('a b c'); } {1 {unrecognized matchinfo flag: d}} +#------------------------------------------------------------------------- +# Test using matchinfo() and similar on a non-full-text query +# +do_execsql_test 15.0 { + CREATE VIRTUAL TABLE t1 USING fts5(x, y); + INSERT INTO t1 VALUES('a', 'b'); + INSERT INTO t1 VALUES('c', 'd'); +} + +do_execsql_test 15.1 { + SELECT quote(matchinfo(t1, 'n')) FROM t1 LIMIT 1; +} {X'02000000'} + +do_execsql_test 15.2 { + DELETE FROM t1_content WHERE rowid=1; + SELECT quote(matchinfo(t1, 'n')) FROM t1 LIMIT 1; +} {X'02000000'} + +fts5_aux_test_functions db +do_execsql_test 15.3 { + SELECT fts5_test_all(t1) FROM t1 LIMIT 1; +} { + {columnsize {0 0} columntext {c d} columntotalsize {2 2} poslist {} tokenize {c d} rowcount 2} +} + finish_test + diff --git a/ext/fts5/test/fts5misc.test b/ext/fts5/test/fts5misc.test index 8d374241..9abc92b2 100644 --- a/ext/fts5/test/fts5misc.test +++ b/ext/fts5/test/fts5misc.test @@ -106,6 +106,222 @@ do_execsql_test 2.2.5 { INSERT INTO vt0(vt0) VALUES('integrity-check'); } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE vt0 USING fts5(a); + PRAGMA reverse_unordered_selects = true; + INSERT INTO vt0 VALUES('365062398'), (0), (0); + INSERT INTO vt0(vt0, rank) VALUES('pgsz', '38'); +} +do_execsql_test 3.1 { + UPDATE vt0 SET a = 399905135; -- unexpected: database disk image is malformed +} +do_execsql_test 3.2 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 4.0 { + CREATE VIRTUAL TABLE vt0 USING fts5(c0); + INSERT INTO vt0(c0) VALUES ('xyz'); +} + +do_execsql_test 4.1 { + BEGIN; + INSERT INTO vt0(c0) VALUES ('abc'); + INSERT INTO vt0(vt0) VALUES('rebuild'); + COMMIT; +} + +do_execsql_test 4.2 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} + +do_execsql_test 4.3 { + BEGIN; + INSERT INTO vt0(vt0) VALUES('rebuild'); + INSERT INTO vt0(vt0) VALUES('rebuild'); + COMMIT; +} + +do_execsql_test 4.4 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} + +#------------------------------------------------------------------------- +# Ticket [81a7f7b9]. +# +reset_db +do_execsql_test 5.0 { + CREATE VIRTUAL TABLE vt0 USING fts5(c0, c1); + INSERT INTO vt0(vt0, rank) VALUES('pgsz', '65536'); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1236 + ) + INSERT INTO vt0(c0) SELECT '0' FROM s; +} {} + +do_execsql_test 5.1 { + UPDATE vt0 SET c1 = 'T,D&p^y/7#3*v='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); +#ifdef SQLITE_EBCDIC + h += 9*(1&~(h>>4)); +#else + h += 9*(1&(h>>6)); +#endif + return (u8)(h & 0xf); +} + +/* +** Convert a 4-byte hex string into an integer +*/ +static u32 jsonHexToInt4(const char *z){ + u32 v; + assert( safe_isxdigit(z[0]) ); + assert( safe_isxdigit(z[1]) ); + assert( safe_isxdigit(z[2]) ); + assert( safe_isxdigit(z[3]) ); + v = (jsonHexToInt(z[0])<<12) + + (jsonHexToInt(z[1])<<8) + + (jsonHexToInt(z[2])<<4) + + jsonHexToInt(z[3]); + return v; +} + /* ** Make the JsonNode the return value of the function. */ @@ -615,15 +646,8 @@ static void jsonReturn( }else{ c = z[++i]; if( c=='u' ){ - u32 v = 0, k; - for(k=0; k<4; i++, k++){ - assert( i>6)); zOut[j++] = 0x80 | (v&0x3f); }else{ - zOut[j++] = (char)(0xe0 | (v>>12)); - zOut[j++] = 0x80 | ((v>>6)&0x3f); - zOut[j++] = 0x80 | (v&0x3f); + u32 vlo; + if( (v&0xfc00)==0xd800 + && i>18); + zOut[j++] = 0x80 | ((v>>12)&0x3f); + zOut[j++] = 0x80 | ((v>>6)&0x3f); + zOut[j++] = 0x80 | (v&0x3f); + }else{ + zOut[j++] = 0xe0 | (v>>12); + zOut[j++] = 0x80 | ((v>>6)&0x3f); + zOut[j++] = 0x80 | (v&0x3f); + } } }else{ if( c=='b' ){ @@ -1136,18 +1176,49 @@ static JsonNode *jsonLookupStep( } return pNode; } - }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){ - if( pRoot->eType!=JSON_ARRAY ) return 0; + }else if( zPath[0]=='[' ){ i = 0; j = 1; while( safe_isdigit(zPath[j]) ){ i = i*10 + zPath[j] - '0'; j++; } - if( zPath[j]!=']' ){ - *pzErr = zPath; - return 0; + if( j<2 || zPath[j]!=']' ){ + if( zPath[1]=='#' ){ + JsonNode *pBase = pRoot; + int iBase = iRoot; + if( pRoot->eType!=JSON_ARRAY ) return 0; + for(;;){ + while( j<=pBase->n ){ + if( (pBase[j].jnFlags & JNODE_REMOVE)==0 ) i++; + j += jsonNodeSize(&pBase[j]); + } + if( (pBase->jnFlags & JNODE_APPEND)==0 ) break; + iBase += pBase->u.iAppend; + pBase = &pParse->aNode[iBase]; + j = 1; + } + j = 2; + if( zPath[2]=='-' && safe_isdigit(zPath[3]) ){ + unsigned int x = 0; + j = 3; + do{ + x = x*10 + zPath[j] - '0'; + j++; + }while( safe_isdigit(zPath[j]) ); + if( x>i ) return 0; + i -= x; + } + if( zPath[j]!=']' ){ + *pzErr = zPath; + return 0; + } + }else{ + *pzErr = zPath; + return 0; + } } + if( pRoot->eType!=JSON_ARRAY ) return 0; zPath += j + 1; j = 1; for(;;){ @@ -2020,6 +2091,7 @@ static int jsonEachConnect( pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); if( pNew==0 ) return SQLITE_NOMEM; memset(pNew, 0, sizeof(*pNew)); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); } return rc; } @@ -2510,16 +2582,19 @@ int sqlite3Json1Init(sqlite3 *db){ { "json_tree", &jsonTreeModule }, }; #endif + static const int enc = + SQLITE_UTF8 | + SQLITE_DETERMINISTIC | + SQLITE_INNOCUOUS; for(i=0; i +#include + +/* +** Implementation of the noop() function. +** +** The function returns its argument, unchanged. +*/ +static void noopfunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==1 ); + sqlite3_result_value(context, argv[0]); +} + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_noop_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); + (void)pzErrMsg; /* Unused parameter */ + rc = sqlite3_create_function(db, "noop", 1, + SQLITE_UTF8 | SQLITE_DETERMINISTIC, + 0, noopfunc, 0, 0); + if( rc ) return rc; + rc = sqlite3_create_function(db, "noop_i", 1, + SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS, + 0, noopfunc, 0, 0); + if( rc ) return rc; + rc = sqlite3_create_function(db, "noop_do", 1, + SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_DIRECTONLY, + 0, noopfunc, 0, 0); + if( rc ) return rc; + rc = sqlite3_create_function(db, "noop_nd", 1, + SQLITE_UTF8, + 0, noopfunc, 0, 0); + return rc; +} diff --git a/ext/misc/percentile.c b/ext/misc/percentile.c index 88fc5a96..d83bc5b8 100644 --- a/ext/misc/percentile.c +++ b/ext/misc/percentile.c @@ -213,7 +213,8 @@ int sqlite3_percentile_init( int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "percentile", 2, SQLITE_UTF8, 0, + rc = sqlite3_create_function(db, "percentile", 2, + SQLITE_UTF8|SQLITE_INNOCUOUS, 0, 0, percentStep, percentFinal); return rc; } diff --git a/ext/misc/prefixes.c b/ext/misc/prefixes.c index 3aa579b8..3f053b7f 100644 --- a/ext/misc/prefixes.c +++ b/ext/misc/prefixes.c @@ -79,6 +79,7 @@ static int prefixesConnect( *ppVtab = (sqlite3_vtab*)pNew; if( pNew==0 ) return SQLITE_NOMEM; memset(pNew, 0, sizeof(*pNew)); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); } return rc; } diff --git a/ext/misc/regexp.c b/ext/misc/regexp.c index 3359109a..03bbeb97 100644 --- a/ext/misc/regexp.c +++ b/ext/misc/regexp.c @@ -156,7 +156,7 @@ static unsigned re_next_char(ReInput *p){ && (p->z[p->i+1]&0xc0)==0x80 ){ c = (c&0x0f)<<12 | ((p->z[p->i]&0x3f)<<6) | (p->z[p->i+1]&0x3f); p->i += 2; - if( c<=0x3ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd; + if( c<=0x7ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd; }else if( (c&0xf8)==0xf0 && p->i+3mx && (p->z[p->i]&0xc0)==0x80 && (p->z[p->i+1]&0xc0)==0x80 && (p->z[p->i+2]&0xc0)==0x80 ){ c = (c&0x07)<<18 | ((p->z[p->i]&0x3f)<<12) | ((p->z[p->i+1]&0x3f)<<6) @@ -754,7 +754,7 @@ int sqlite3_regexp_init( ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); - rc = sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8, 0, - re_sql_func, 0, 0); + rc = sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8|SQLITE_INNOCUOUS, + 0, re_sql_func, 0, 0); return rc; } diff --git a/ext/misc/rot13.c b/ext/misc/rot13.c index 2e9dd21c..05b4a188 100644 --- a/ext/misc/rot13.c +++ b/ext/misc/rot13.c @@ -105,8 +105,9 @@ int sqlite3_rot_init( int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "rot13", 1, SQLITE_UTF8, 0, - rot13func, 0, 0); + rc = sqlite3_create_function(db, "rot13", 1, + SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, + 0, rot13func, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3_create_collation(db, "rot13", SQLITE_UTF8, 0, rot13CollFunc); } diff --git a/ext/misc/series.c b/ext/misc/series.c index 86309dd7..ac93f1fc 100644 --- a/ext/misc/series.c +++ b/ext/misc/series.c @@ -126,6 +126,7 @@ static int seriesConnect( pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); if( pNew==0 ) return SQLITE_NOMEM; memset(pNew, 0, sizeof(*pNew)); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); } return rc; } diff --git a/ext/misc/sha1.c b/ext/misc/sha1.c index 886b1db7..0050fdfb 100644 --- a/ext/misc/sha1.c +++ b/ext/misc/sha1.c @@ -39,25 +39,9 @@ struct SHA1Context { unsigned char buffer[64]; }; - -#if __GNUC__ && (defined(__i386__) || defined(__x86_64__)) -/* - * GCC by itself only generates left rotates. Use right rotates if - * possible to be kinder to dinky implementations with iterative rotate - * instructions. - */ -#define SHA_ROT(op, x, k) \ - ({ unsigned int y; asm(op " %1,%0" : "=r" (y) : "I" (k), "0" (x)); y; }) -#define rol(x,k) SHA_ROT("roll", x, k) -#define ror(x,k) SHA_ROT("rorl", x, k) - -#else -/* Generic C equivalent */ #define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r)) #define rol(x,k) SHA_ROT(x,k,32-(k)) #define ror(x,k) SHA_ROT(x,32-(k),k) -#endif - #define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \ |(rol(block[i],8)&0x00FF00FF)) @@ -397,10 +381,11 @@ int sqlite3_sha_init( int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "sha1", 1, SQLITE_UTF8, 0, + rc = sqlite3_create_function(db, "sha1", 1, SQLITE_UTF8|SQLITE_INNOCUOUS, 0, sha1Func, 0, 0); if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "sha1_query", 1, SQLITE_UTF8, 0, + rc = sqlite3_create_function(db, "sha1_query", 1, + SQLITE_UTF8|SQLITE_DIRECTONLY, 0, sha1QueryFunc, 0, 0); } return rc; diff --git a/ext/misc/shathree.c b/ext/misc/shathree.c index e35fa494..56eba564 100644 --- a/ext/misc/shathree.c +++ b/ext/misc/shathree.c @@ -696,19 +696,23 @@ int sqlite3_shathree_init( int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "sha3", 1, SQLITE_UTF8, 0, - sha3Func, 0, 0); + rc = sqlite3_create_function(db, "sha3", 1, + SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, + 0, sha3Func, 0, 0); if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "sha3", 2, SQLITE_UTF8, 0, - sha3Func, 0, 0); + rc = sqlite3_create_function(db, "sha3", 2, + SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, + 0, sha3Func, 0, 0); } if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "sha3_query", 1, SQLITE_UTF8, 0, - sha3QueryFunc, 0, 0); + rc = sqlite3_create_function(db, "sha3_query", 1, + SQLITE_UTF8 | SQLITE_DIRECTONLY, + 0, sha3QueryFunc, 0, 0); } if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "sha3_query", 2, SQLITE_UTF8, 0, - sha3QueryFunc, 0, 0); + rc = sqlite3_create_function(db, "sha3_query", 2, + SQLITE_UTF8 | SQLITE_DIRECTONLY, + 0, sha3QueryFunc, 0, 0); } return rc; } diff --git a/ext/misc/spellfix.c b/ext/misc/spellfix.c index 81bef139..3b78d9f0 100644 --- a/ext/misc/spellfix.c +++ b/ext/misc/spellfix.c @@ -2069,6 +2069,7 @@ static int spellfix1Init( if( pNew->zTableName==0 ){ rc = SQLITE_NOMEM; }else{ + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); rc = sqlite3_declare_vtab(db, "CREATE TABLE x(word,rank,distance,langid, " "score, matchlen, phonehash HIDDEN, " diff --git a/ext/misc/sqlar.c b/ext/misc/sqlar.c index e812d70c..8b90f9d1 100644 --- a/ext/misc/sqlar.c +++ b/ext/misc/sqlar.c @@ -111,10 +111,12 @@ int sqlite3_sqlar_init( int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "sqlar_compress", 1, SQLITE_UTF8, 0, + rc = sqlite3_create_function(db, "sqlar_compress", 1, + SQLITE_UTF8|SQLITE_INNOCUOUS, 0, sqlarCompressFunc, 0, 0); if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "sqlar_uncompress", 2, SQLITE_UTF8, 0, + rc = sqlite3_create_function(db, "sqlar_uncompress", 2, + SQLITE_UTF8|SQLITE_INNOCUOUS, 0, sqlarUncompressFunc, 0, 0); } return rc; diff --git a/ext/misc/totype.c b/ext/misc/totype.c index 5dc99f3d..50d7f05d 100644 --- a/ext/misc/totype.c +++ b/ext/misc/totype.c @@ -502,11 +502,13 @@ int sqlite3_totype_init( int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "tointeger", 1, SQLITE_UTF8, 0, - tointegerFunc, 0, 0); + rc = sqlite3_create_function(db, "tointeger", 1, + SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS, 0, + tointegerFunc, 0, 0); if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "toreal", 1, SQLITE_UTF8, 0, - torealFunc, 0, 0); + rc = sqlite3_create_function(db, "toreal", 1, + SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS, 0, + torealFunc, 0, 0); } return rc; } diff --git a/ext/misc/urifuncs.c b/ext/misc/urifuncs.c new file mode 100644 index 00000000..9697b724 --- /dev/null +++ b/ext/misc/urifuncs.c @@ -0,0 +1,209 @@ +/* +** 2020-01-11 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This SQLite extension implements various SQL functions used to access +** the following SQLite C-language APIs: +** +** sqlite3_uri_parameter() +** sqlite3_uri_boolean() +** sqlite3_uri_int64() +** sqlite3_uri_key() +** sqlite3_filename_database() +** sqlite3_filename_journal() +** sqlite3_filename_wal() +** sqlite3_db_filename() +** +** These SQL functions are for testing and demonstration purposes only. +** +** +*/ +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 +#include +#include + +/* +** SQL function: sqlite3_db_filename(SCHEMA) +** +** Return the filename corresponding to SCHEMA. +*/ +static void func_db_filename( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zSchema = (const char*)sqlite3_value_text(argv[0]); + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zFile = sqlite3_db_filename(db, zSchema); + sqlite3_result_text(context, zFile, -1, SQLITE_TRANSIENT); +} + +/* +** SQL function: sqlite3_uri_parameter(SCHEMA,NAME) +** +** Return the value of the NAME query parameter to the database for SCHEMA +*/ +static void func_uri_parameter( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zSchema = (const char*)sqlite3_value_text(argv[0]); + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zName = (const char*)sqlite3_value_text(argv[1]); + const char *zFile = sqlite3_db_filename(db, zSchema); + const char *zRes = sqlite3_uri_parameter(zFile, zName); + sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT); +} + +/* +** SQL function: sqlite3_uri_boolean(SCHEMA,NAME,DEFAULT) +** +** Return the boolean value of the NAME query parameter to +** the database for SCHEMA +*/ +static void func_uri_boolean( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zSchema = (const char*)sqlite3_value_text(argv[0]); + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zName = (const char*)sqlite3_value_text(argv[1]); + const char *zFile = sqlite3_db_filename(db, zSchema); + int iDflt = sqlite3_value_int(argv[2]); + int iRes = sqlite3_uri_boolean(zFile, zName, iDflt); + sqlite3_result_int(context, iRes); +} + +/* +** SQL function: sqlite3_uri_key(SCHEMA,N) +** +** Return the name of the Nth query parameter +*/ +static void func_uri_key( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zSchema = (const char*)sqlite3_value_text(argv[0]); + sqlite3 *db = sqlite3_context_db_handle(context); + int N = sqlite3_value_int(argv[1]); + const char *zFile = sqlite3_db_filename(db, zSchema); + const char *zRes = sqlite3_uri_key(zFile, N); + sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT); +} + +/* +** SQL function: sqlite3_uri_int64(SCHEMA,NAME,DEFAULT) +** +** Return the int64 value of the NAME query parameter to +** the database for SCHEMA +*/ +static void func_uri_int64( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zSchema = (const char*)sqlite3_value_text(argv[0]); + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zName = (const char*)sqlite3_value_text(argv[1]); + const char *zFile = sqlite3_db_filename(db, zSchema); + sqlite3_int64 iDflt = sqlite3_value_int64(argv[2]); + sqlite3_int64 iRes = sqlite3_uri_int64(zFile, zName, iDflt); + sqlite3_result_int64(context, iRes); +} + +/* +** SQL function: sqlite3_filename_database(SCHEMA) +** +** Return the database filename for SCHEMA +*/ +static void func_filename_database( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zSchema = (const char*)sqlite3_value_text(argv[0]); + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zFile = sqlite3_db_filename(db, zSchema); + const char *zRes = zFile ? sqlite3_filename_database(zFile) : 0; + sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT); +} + +/* +** SQL function: sqlite3_filename_journal(SCHEMA) +** +** Return the rollback journal filename for SCHEMA +*/ +static void func_filename_journal( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zSchema = (const char*)sqlite3_value_text(argv[0]); + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zFile = sqlite3_db_filename(db, zSchema); + const char *zRes = zFile ? sqlite3_filename_journal(zFile) : 0; + sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT); +} + +/* +** SQL function: sqlite3_filename_wal(SCHEMA) +** +** Return the WAL filename for SCHEMA +*/ +static void func_filename_wal( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zSchema = (const char*)sqlite3_value_text(argv[0]); + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zFile = sqlite3_db_filename(db, zSchema); + const char *zRes = zFile ? sqlite3_filename_wal(zFile) : 0; + sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT); +} + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_urifuncs_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + static const struct { + const char *zFuncName; + int nArg; + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); + } aFunc[] = { + { "sqlite3_db_filename", 1, func_db_filename }, + { "sqlite3_uri_parameter", 2, func_uri_parameter }, + { "sqlite3_uri_boolean", 3, func_uri_boolean }, + { "sqlite3_uri_int64", 3, func_uri_int64 }, + { "sqlite3_uri_key", 2, func_uri_key }, + { "sqlite3_filename_database", 1, func_filename_database }, + { "sqlite3_filename_journal", 1, func_filename_journal }, + { "sqlite3_filename_wal", 1, func_filename_wal }, + }; + int rc = SQLITE_OK; + int i; + SQLITE_EXTENSION_INIT2(pApi); + (void)pzErrMsg; /* Unused parameter */ + for(i=0; rc==SQLITE_OK && i +#include +#include + +#if !defined(SQLITE_ASCII) && !defined(SQLITE_EBCDIC) +# define SQLITE_ASCII 1 +#endif + +/* +** Translate a single byte of Hex into an integer. +** This routine only works if h really is a valid hexadecimal +** character: 0..9a..fA..F +*/ +static unsigned char sqlite3UuidHexToInt(int h){ + assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); +#ifdef SQLITE_ASCII + h += 9*(1&(h>>6)); +#endif +#ifdef SQLITE_EBCDIC + h += 9*(1&~(h>>4)); +#endif + return (unsigned char)(h & 0xf); +} + +/* +** Convert a 16-byte BLOB into a well-formed RFC-4122 UUID. The output +** buffer zStr should be at least 37 bytes in length. The output will +** be zero-terminated. +*/ +static void sqlite3UuidBlobToStr( + const unsigned char *aBlob, /* Input blob */ + unsigned char *zStr /* Write the answer here */ +){ + static const char zDigits[] = "0123456789abcdef"; + int i, k; + unsigned char x; + k = 0; + for(i=0, k=0x550; i<16; i++, k=k>>1){ + if( k&1 ){ + zStr[0] = '-'; + zStr++; + } + x = aBlob[i]; + zStr[0] = zDigits[x>>4]; + zStr[1] = zDigits[x&0xf]; + zStr += 2; + } + *zStr = 0; +} + +/* +** Attempt to parse a zero-terminated input string zStr into a binary +** UUID. Return 0 on success, or non-zero if the input string is not +** parsable. +*/ +static int sqlite3UuidStrToBlob( + const unsigned char *zStr, /* Input string */ + unsigned char *aBlob /* Write results here */ +){ + int i; + if( zStr[0]=='{' ) zStr++; + for(i=0; i<16; i++){ + if( zStr[0]=='-' ) zStr++; + if( isxdigit(zStr[0]) && isxdigit(zStr[1]) ){ + aBlob[i] = (sqlite3UuidHexToInt(zStr[0])<<4) + + sqlite3UuidHexToInt(zStr[1]); + zStr += 2; + }else{ + return 1; + } + } + if( zStr[0]=='}' ) zStr++; + return zStr[0]!=0; +} + +/* +** Render sqlite3_value pIn as a 16-byte UUID blob. Return a pointer +** to the blob, or NULL if the input is not well-formed. +*/ +static const unsigned char *sqlite3UuidInputToBlob( + sqlite3_value *pIn, /* Input text */ + unsigned char *pBuf /* output buffer */ +){ + switch( sqlite3_value_type(pIn) ){ + case SQLITE_TEXT: { + const unsigned char *z = sqlite3_value_text(pIn); + if( sqlite3UuidStrToBlob(z, pBuf) ) return 0; + return pBuf; + } + case SQLITE_BLOB: { + int n = sqlite3_value_bytes(pIn); + return n==16 ? sqlite3_value_blob(pIn) : 0; + } + default: { + return 0; + } + } +} + +/* Implementation of uuid() */ +static void sqlite3UuidFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + unsigned char aBlob[16]; + unsigned char zStr[37]; + (void)argc; + (void)argv; + sqlite3_randomness(16, aBlob); + aBlob[6] = (aBlob[6]&0x0f) + 0x40; + aBlob[8] = (aBlob[8]&0x3f) + 0x80; + sqlite3UuidBlobToStr(aBlob, zStr); + sqlite3_result_text(context, (char*)zStr, 36, SQLITE_TRANSIENT); +} + +/* Implementation of uuid_str() */ +static void sqlite3UuidStrFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + unsigned char aBlob[16]; + unsigned char zStr[37]; + const unsigned char *pBlob; + (void)argc; + pBlob = sqlite3UuidInputToBlob(argv[0], aBlob); + if( pBlob==0 ) return; + sqlite3UuidBlobToStr(pBlob, zStr); + sqlite3_result_text(context, (char*)zStr, 36, SQLITE_TRANSIENT); +} + +/* Implementation of uuid_blob() */ +static void sqlite3UuidBlobFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + unsigned char aBlob[16]; + const unsigned char *pBlob; + (void)argc; + pBlob = sqlite3UuidInputToBlob(argv[0], aBlob); + if( pBlob==0 ) return; + sqlite3_result_blob(context, pBlob, 16, SQLITE_TRANSIENT); +} + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_uuid_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); + (void)pzErrMsg; /* Unused parameter */ + rc = sqlite3_create_function(db, "uuid", 0, SQLITE_UTF8|SQLITE_INNOCUOUS, 0, + sqlite3UuidFunc, 0, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "uuid_str", 1, + SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, + 0, sqlite3UuidStrFunc, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "uuid_blob", 1, + SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, + 0, sqlite3UuidBlobFunc, 0, 0); + } + return rc; +} diff --git a/ext/misc/wholenumber.c b/ext/misc/wholenumber.c index 63369c6a..5643f9cf 100644 --- a/ext/misc/wholenumber.c +++ b/ext/misc/wholenumber.c @@ -50,6 +50,7 @@ static int wholenumberConnect( pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); if( pNew==0 ) return SQLITE_NOMEM; sqlite3_declare_vtab(db, "CREATE TABLE x(value)"); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); memset(pNew, 0, sizeof(*pNew)); return SQLITE_OK; } diff --git a/ext/misc/zipfile.c b/ext/misc/zipfile.c index 0b14917c..a35a26f4 100644 --- a/ext/misc/zipfile.c +++ b/ext/misc/zipfile.c @@ -369,6 +369,7 @@ static int zipfileConnect( zipfileDequote(pNew->zFile); } } + sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); *ppVtab = (sqlite3_vtab*)pNew; return rc; } @@ -981,25 +982,25 @@ static int zipfileDeflate( u8 **ppOut, int *pnOut, /* Output */ char **pzErr /* OUT: Error message */ ){ - sqlite3_int64 nAlloc = compressBound(nIn); - u8 *aOut; int rc = SQLITE_OK; + sqlite3_int64 nAlloc; + z_stream str; + u8 *aOut; + memset(&str, 0, sizeof(str)); + str.next_in = (Bytef*)aIn; + str.avail_in = nIn; + deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); + + nAlloc = deflateBound(&str, nIn); aOut = (u8*)sqlite3_malloc64(nAlloc); if( aOut==0 ){ rc = SQLITE_NOMEM; }else{ int res; - z_stream str; - memset(&str, 0, sizeof(str)); - str.next_in = (Bytef*)aIn; - str.avail_in = nIn; str.next_out = aOut; str.avail_out = nAlloc; - - deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); res = deflate(&str, Z_FINISH); - if( res==Z_STREAM_END ){ *ppOut = aOut; *pnOut = (int)str.total_out; @@ -1308,10 +1309,10 @@ static int zipfileBestIndex( idx = i; } } + pIdxInfo->estimatedCost = 1000.0; if( idx>=0 ){ pIdxInfo->aConstraintUsage[idx].argvIndex = 1; pIdxInfo->aConstraintUsage[idx].omit = 1; - pIdxInfo->estimatedCost = 1000.0; pIdxInfo->idxNum = 1; }else if( unusable ){ return SQLITE_CONSTRAINT; @@ -1433,8 +1434,8 @@ static int zipfileGetMode( ** identical, ignoring any trailing '/' character in either path. */ static int zipfileComparePath(const char *zA, const char *zB, int nB){ int nA = (int)strlen(zA); - if( zA[nA-1]=='/' ) nA--; - if( zB[nB-1]=='/' ) nB--; + if( nA>0 && zA[nA-1]=='/' ) nA--; + if( nB>0 && zB[nB-1]=='/' ) nB--; if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0; return 1; } @@ -1444,6 +1445,10 @@ static int zipfileBegin(sqlite3_vtab *pVtab){ int rc = SQLITE_OK; assert( pTab->pWriteFd==0 ); + if( pTab->zFile==0 || pTab->zFile[0]==0 ){ + pTab->base.zErrMsg = sqlite3_mprintf("zipfile: missing filename"); + return SQLITE_ERROR; + } /* Open a write fd on the file. Also load the entire central directory ** structure into memory. During the transaction any new file data is @@ -1618,6 +1623,7 @@ static int zipfileUpdate( if( rc==SQLITE_OK ){ zPath = (const char*)sqlite3_value_text(apVal[2]); + if( zPath==0 ) zPath = ""; nPath = (int)strlen(zPath); mTime = zipfileGetTime(apVal[4]); } @@ -1627,11 +1633,15 @@ static int zipfileUpdate( ** '/'. This appears to be required for compatibility with info-zip ** (the unzip command on unix). It does not create directories ** otherwise. */ - if( zPath[nPath-1]!='/' ){ + if( nPath<=0 || zPath[nPath-1]!='/' ){ zFree = sqlite3_mprintf("%s/", zPath); - if( zFree==0 ){ rc = SQLITE_NOMEM; } zPath = (const char*)zFree; - nPath++; + if( zFree==0 ){ + rc = SQLITE_NOMEM; + nPath = 0; + }else{ + nPath = (int)strlen(zPath); + } } } @@ -2024,19 +2034,19 @@ void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){ ** at the end of the path. Or, if this is not a directory and the path ** ends in '/' it is an error. */ if( bIsDir==0 ){ - if( zName[nName-1]=='/' ){ + if( nName>0 && zName[nName-1]=='/' ){ zErr = sqlite3_mprintf("non-directory name must not end with /"); rc = SQLITE_ERROR; goto zipfile_step_out; } }else{ - if( zName[nName-1]!='/' ){ + if( nName==0 || zName[nName-1]!='/' ){ zName = zFree = sqlite3_mprintf("%s/", zName); - nName++; if( zName==0 ){ rc = SQLITE_NOMEM; goto zipfile_step_out; } + nName = (int)strlen(zName); }else{ while( nName>1 && zName[nName-2]=='/' ) nName--; } diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 5c2ae954..8e82cd8b 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -4936,33 +4936,6 @@ static int rbuVfsShmUnmap(sqlite3_file *pFile, int delFlag){ return rc; } -/* -** A main database named zName has just been opened. The following -** function returns a pointer to a buffer owned by SQLite that contains -** the name of the *-wal file this db connection will use. SQLite -** happens to pass a pointer to this buffer when using xAccess() -** or xOpen() to operate on the *-wal file. -*/ -static const char *rbuMainToWal(const char *zName, int flags){ - int n = (int)strlen(zName); - const char *z = &zName[n]; - if( flags & SQLITE_OPEN_URI ){ - int odd = 0; - while( 1 ){ - if( z[0]==0 ){ - odd = 1 - odd; - if( odd && z[1]==0 ) break; - } - z++; - } - z += 2; - }else{ - while( *z==0 ) z++; - } - z += (n + 8 + 1); - return z; -} - /* ** Open an rbu file handle. */ @@ -5011,7 +4984,7 @@ static int rbuVfsOpen( ** the name of the *-wal file this db connection will use. SQLite ** happens to pass a pointer to this buffer when using xAccess() ** or xOpen() to operate on the *-wal file. */ - pFd->zWal = rbuMainToWal(zName, flags); + pFd->zWal = sqlite3_filename_wal(zName); } else if( flags & SQLITE_OPEN_WAL ){ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0); @@ -5026,7 +4999,7 @@ static int rbuVfsOpen( char *zCopy; if( rbuIsVacuum(pDb->pRbu) ){ zBase = sqlite3_db_filename(pDb->pRbu->dbRbu, "main"); - zBase = rbuMainToWal(zBase, SQLITE_OPEN_URI); + zBase = sqlite3_filename_wal(zBase); } nCopy = strlen(zBase); zCopy = sqlite3_malloc64(nCopy+2); diff --git a/ext/rtree/geopoly.c b/ext/rtree/geopoly.c index fa58838a..14facad5 100644 --- a/ext/rtree/geopoly.c +++ b/ext/rtree/geopoly.c @@ -1345,17 +1345,11 @@ static int geopolyFilter( RtreeNode *pRoot = 0; int rc = SQLITE_OK; int iCell = 0; - sqlite3_stmt *pStmt; rtreeReference(pRtree); /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ - freeCursorConstraints(pCsr); - sqlite3_free(pCsr->aPoint); - pStmt = pCsr->pReadAux; - memset(pCsr, 0, sizeof(RtreeCursor)); - pCsr->base.pVtab = (sqlite3_vtab*)pRtree; - pCsr->pReadAux = pStmt; + resetCursor(pCsr); pCsr->iStrategy = idxNum; if( idxNum==1 ){ @@ -1792,14 +1786,20 @@ static int sqlite3_geopoly_init(sqlite3 *db){ }; int i; for(i=0; ibase.pVtab); + int ii; + sqlite3_stmt *pStmt; if( pCsr->aConstraint ){ int i; /* Used to iterate through constraint array */ for(i=0; inConstraint; i++){ @@ -1073,6 +1083,13 @@ static void freeCursorConstraints(RtreeCursor *pCsr){ sqlite3_free(pCsr->aConstraint); pCsr->aConstraint = 0; } + for(ii=0; iiaNode[ii]); + sqlite3_free(pCsr->aPoint); + pStmt = pCsr->pReadAux; + memset(pCsr, 0, sizeof(RtreeCursor)); + pCsr->base.pVtab = (sqlite3_vtab*)pRtree; + pCsr->pReadAux = pStmt; + } /* @@ -1080,13 +1097,10 @@ static void freeCursorConstraints(RtreeCursor *pCsr){ */ static int rtreeClose(sqlite3_vtab_cursor *cur){ Rtree *pRtree = (Rtree *)(cur->pVtab); - int ii; RtreeCursor *pCsr = (RtreeCursor *)cur; assert( pRtree->nCursor>0 ); - freeCursorConstraints(pCsr); + resetCursor(pCsr); sqlite3_finalize(pCsr->pReadAux); - sqlite3_free(pCsr->aPoint); - for(ii=0; iiaNode[ii]); sqlite3_free(pCsr); pRtree->nCursor--; nodeBlobReset(pRtree); @@ -1244,9 +1258,12 @@ static void rtreeNonleafConstraint( pCellData += 8 + 4*(p->iCoord&0xfe); assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE - || p->op==RTREE_GT || p->op==RTREE_EQ ); + || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE + || p->op==RTREE_FALSE ); assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */ switch( p->op ){ + case RTREE_TRUE: return; /* Always satisfied */ + case RTREE_FALSE: break; /* Never satisfied */ case RTREE_LE: case RTREE_LT: case RTREE_EQ: @@ -1284,16 +1301,19 @@ static void rtreeLeafConstraint( RtreeDValue xN; /* Coordinate value converted to a double */ assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE - || p->op==RTREE_GT || p->op==RTREE_EQ ); + || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE + || p->op==RTREE_FALSE ); pCellData += 8 + p->iCoord*4; assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */ RTREE_DECODE_COORD(eInt, pCellData, xN); switch( p->op ){ - case RTREE_LE: if( xN <= p->u.rValue ) return; break; - case RTREE_LT: if( xN < p->u.rValue ) return; break; - case RTREE_GE: if( xN >= p->u.rValue ) return; break; - case RTREE_GT: if( xN > p->u.rValue ) return; break; - default: if( xN == p->u.rValue ) return; break; + case RTREE_TRUE: return; /* Always satisfied */ + case RTREE_FALSE: break; /* Never satisfied */ + case RTREE_LE: if( xN <= p->u.rValue ) return; break; + case RTREE_LT: if( xN < p->u.rValue ) return; break; + case RTREE_GE: if( xN >= p->u.rValue ) return; break; + case RTREE_GT: if( xN > p->u.rValue ) return; break; + default: if( xN == p->u.rValue ) return; break; } *peWithin = NOT_WITHIN; } @@ -1786,17 +1806,11 @@ static int rtreeFilter( int ii; int rc = SQLITE_OK; int iCell = 0; - sqlite3_stmt *pStmt; rtreeReference(pRtree); /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ - freeCursorConstraints(pCsr); - sqlite3_free(pCsr->aPoint); - pStmt = pCsr->pReadAux; - memset(pCsr, 0, sizeof(RtreeCursor)); - pCsr->base.pVtab = (sqlite3_vtab*)pRtree; - pCsr->pReadAux = pStmt; + resetCursor(pCsr); pCsr->iStrategy = idxNum; if( idxNum==1 ){ @@ -1805,7 +1819,15 @@ static int rtreeFilter( RtreeSearchPoint *p; /* Search point for the leaf */ i64 iRowid = sqlite3_value_int64(argv[0]); i64 iNode = 0; - rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); + int eType = sqlite3_value_numeric_type(argv[0]); + if( eType==SQLITE_INTEGER + || (eType==SQLITE_FLOAT && sqlite3_value_double(argv[0])==iRowid) + ){ + rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); + }else{ + rc = SQLITE_OK; + pLeaf = 0; + } if( rc==SQLITE_OK && pLeaf!=0 ){ p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0); assert( p!=0 ); /* Always returns pCsr->sPoint */ @@ -1835,6 +1857,7 @@ static int rtreeFilter( || (idxStr && (int)strlen(idxStr)==argc*2) ); for(ii=0; iiaConstraint[ii]; + int eType = sqlite3_value_numeric_type(argv[ii]); p->op = idxStr[ii*2]; p->iCoord = idxStr[ii*2+1]-'0'; if( p->op>=RTREE_MATCH ){ @@ -1849,12 +1872,21 @@ static int rtreeFilter( p->pInfo->nCoord = pRtree->nDim2; p->pInfo->anQueue = pCsr->anQueue; p->pInfo->mxLevel = pRtree->iDepth + 1; - }else{ + }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ #ifdef SQLITE_RTREE_INT_ONLY p->u.rValue = sqlite3_value_int64(argv[ii]); #else p->u.rValue = sqlite3_value_double(argv[ii]); #endif + }else{ + p->u.rValue = RTREE_ZERO; + if( eType==SQLITE_NULL ){ + p->op = RTREE_FALSE; + }else if( p->op==RTREE_LT || p->op==RTREE_LE ){ + p->op = RTREE_TRUE; + }else{ + p->op = RTREE_FALSE; + } } } } @@ -3631,6 +3663,14 @@ static int getNodeSize( return rc; } +/* +** Return the length of a token +*/ +static int rtreeTokenLength(const char *z){ + int dummy = 0; + return sqlite3GetToken((const unsigned char*)z,&dummy); +} + /* ** This function is the implementation of both the xConnect and xCreate ** methods of the r-tree virtual table. @@ -3667,8 +3707,8 @@ static int rtreeInit( }; assert( RTREE_MAX_AUX_COLUMN<256 ); /* Aux columns counted by a u8 */ - if( argc>RTREE_MAX_AUX_COLUMN+3 ){ - *pzErr = sqlite3_mprintf("%s", aErrMsg[3]); + if( argc<6 || argc>RTREE_MAX_AUX_COLUMN+3 ){ + *pzErr = sqlite3_mprintf("%s", aErrMsg[2 + (argc>=6)]); return SQLITE_ERROR; } @@ -3696,16 +3736,18 @@ static int rtreeInit( ** the r-tree table schema. */ pSql = sqlite3_str_new(db); - sqlite3_str_appendf(pSql, "CREATE TABLE x(%s", argv[3]); + sqlite3_str_appendf(pSql, "CREATE TABLE x(%.*s INT", + rtreeTokenLength(argv[3]), argv[3]); for(ii=4; iinAux++; - sqlite3_str_appendf(pSql, ",%s", argv[ii]+1); + sqlite3_str_appendf(pSql, ",%.*s", rtreeTokenLength(zArg+1), zArg+1); }else if( pRtree->nAux>0 ){ break; }else{ pRtree->nDim2++; - sqlite3_str_appendf(pSql, ",%s", argv[ii]); + sqlite3_str_appendf(pSql, ",%.*s NUM", rtreeTokenLength(zArg), zArg); } } sqlite3_str_appendf(pSql, ");"); diff --git a/ext/rtree/rtree1.test b/ext/rtree/rtree1.test index 77494573..447ef5da 100644 --- a/ext/rtree/rtree1.test +++ b/ext/rtree/rtree1.test @@ -112,6 +112,9 @@ for {set nCol 1} {$nCol<[llength $cols]} {incr nCol} { catchsql { DROP TABLE t1 } } +do_catchsql_test rtree-1.3.1000 { + CREATE VIRTUAL TABLE t1000 USING rtree; +} {1 {Too few columns for an rtree table}} # Like execsql except display output as integer where that can be # done without loss of information. @@ -374,13 +377,43 @@ do_test rtree-8.1.1 { INSERT INTO t6 VALUES(2, 4, 6); } } {} -do_test rtree-8.1.2 { execsql { SELECT ii FROM t6 WHERE x1>2 } } {1 2} -do_test rtree-8.1.3 { execsql { SELECT ii FROM t6 WHERE x1>3 } } {2} -do_test rtree-8.1.4 { execsql { SELECT ii FROM t6 WHERE x1>4 } } {} -do_test rtree-8.1.5 { execsql { SELECT ii FROM t6 WHERE x1>5 } } {} -do_test rtree-8.1.6 { execsql { SELECT ii FROM t6 WHERE x1<3 } } {} -do_test rtree-8.1.7 { execsql { SELECT ii FROM t6 WHERE x1<4 } } {1} -do_test rtree-8.1.8 { execsql { SELECT ii FROM t6 WHERE x1<5 } } {1 2} +do_test rtree-8.1.2 { execsql { SELECT ii FROM t6 WHERE x1>2 } } {1 2} +do_test rtree-8.1.3 { execsql { SELECT ii FROM t6 WHERE x1>3 } } {2} +do_test rtree-8.1.4 { execsql { SELECT ii FROM t6 WHERE x1>4 } } {} +do_test rtree-8.1.5 { execsql { SELECT ii FROM t6 WHERE x1>5 } } {} +do_test rtree-8.1.6 { execsql { SELECT ii FROM t6 WHERE x1>''} } {} +do_test rtree-8.1.7 { execsql { SELECT ii FROM t6 WHERE x1>null}} {} +do_test rtree-8.1.8 { execsql { SELECT ii FROM t6 WHERE x1>'2'} } {1 2} +do_test rtree-8.1.9 { execsql { SELECT ii FROM t6 WHERE x1>'3'} } {2} +do_test rtree-8.2.2 { execsql { SELECT ii FROM t6 WHERE x1>=2 } } {1 2} +do_test rtree-8.2.3 { execsql { SELECT ii FROM t6 WHERE x1>=3 } } {1 2} +do_test rtree-8.2.4 { execsql { SELECT ii FROM t6 WHERE x1>=4 } } {2} +do_test rtree-8.2.5 { execsql { SELECT ii FROM t6 WHERE x1>=5 } } {} +do_test rtree-8.2.6 { execsql { SELECT ii FROM t6 WHERE x1>=''} } {} +do_test rtree-8.2.7 { execsql { SELECT ii FROM t6 WHERE x1>=null}} {} +do_test rtree-8.2.8 { execsql { SELECT ii FROM t6 WHERE x1>='4'} } {2} +do_test rtree-8.2.9 { execsql { SELECT ii FROM t6 WHERE x1>='5'} } {} +do_test rtree-8.3.2 { execsql { SELECT ii FROM t6 WHERE x1<2 } } {} +do_test rtree-8.3.3 { execsql { SELECT ii FROM t6 WHERE x1<3 } } {} +do_test rtree-8.3.4 { execsql { SELECT ii FROM t6 WHERE x1<4 } } {1} +do_test rtree-8.3.5 { execsql { SELECT ii FROM t6 WHERE x1<5 } } {1 2} +do_test rtree-8.3.6 { execsql { SELECT ii FROM t6 WHERE x1<''} } {1 2} +do_test rtree-8.3.7 { execsql { SELECT ii FROM t6 WHERE x1 '-1'; + SELECT rt0.c1 > '-1' FROM rt0; +} {9 1} + + expand_all_sql db finish_test diff --git a/ext/rtree/rtree2.test b/ext/rtree/rtree2.test index 853737b9..31c19148 100644 --- a/ext/rtree/rtree2.test +++ b/ext/rtree/rtree2.test @@ -33,12 +33,13 @@ if {[info exists G(isquick)] && $G(isquick)} { } foreach module {rtree_i32 rtree} { + if {$module=="rtree_i32"} {set etype INT} {set etype REAL} for {set nDim 1} {$nDim <= 5} {incr nDim} { do_test rtree2-$module.$nDim.1 { set cols [list] foreach c [list c0 c1 c2 c3 c4 c5 c6 c7 c8 c9] { - lappend cols "$c REAL" + lappend cols "$c $etype" } set cols [join [lrange $cols 0 [expr {$nDim*2-1}]] ", "] execsql " diff --git a/ext/rtree/rtreeC.test b/ext/rtree/rtreeC.test index 19a1f7fe..47ca3ad7 100644 --- a/ext/rtree/rtreeC.test +++ b/ext/rtree/rtreeC.test @@ -177,7 +177,7 @@ do_execsql_test 4.3 { # reset_db do_execsql_test 5.1 { - CREATE TABLE t1(x PRIMARY KEY, y); + CREATE TABLE t1(x INT PRIMARY KEY, y); CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2, +d1); INSERT INTO t1(x) VALUES(1); diff --git a/ext/rtree/rtreeH.test b/ext/rtree/rtreeH.test index bff765d5..e26107f0 100644 --- a/ext/rtree/rtreeH.test +++ b/ext/rtree/rtreeH.test @@ -43,10 +43,33 @@ do_execsql_test rtreeH-101 { do_execsql_test rtreeH-102 { SELECT * FROM t1 WHERE rowid=5; } {5 40.0 60.0 40.0 60.0 center {}} +do_execsql_test rtreeH-102b { + SELECT * FROM t1 WHERE rowid=5.0; +} {5 40.0 60.0 40.0 60.0 center {}} +do_execsql_test rtreeH-102c { + SELECT * FROM t1 WHERE rowid='5'; +} {5 40.0 60.0 40.0 60.0 center {}} +do_execsql_test rtreeH-102d { + SELECT * FROM t1 WHERE rowid='0005'; +} {5 40.0 60.0 40.0 60.0 center {}} +do_execsql_test rtreeH-102e { + SELECT * FROM t1 WHERE rowid='+5.0e+0'; +} {5 40.0 60.0 40.0 60.0 center {}} do_execsql_test rtreeH-103 { SELECT * FROM t1 WHERE label='center'; } {5 40.0 60.0 40.0 60.0 center {}} +do_execsql_test rtreeH-104 { + SELECT * FROM t1 WHERE rowid='+5.0e+0x'; +} {} +do_execsql_test rtreeH-105 { + SELECT * FROM t1 WHERE rowid=x'35'; +} {} +do_execsql_test rtreeH-106 { + SELECT * FROM t1 WHERE rowid=null; +} {} + + do_rtree_integrity_test rtreeH-110 t1 do_execsql_test rtreeH-120 { diff --git a/ext/rtree/rtreeI.test b/ext/rtree/rtreeI.test new file mode 100644 index 00000000..0bc910e0 --- /dev/null +++ b/ext/rtree/rtreeI.test @@ -0,0 +1,74 @@ +# 2019-12-05 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# Additional test cases + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] rtree_util.tcl] +source $testdir/tester.tcl +ifcapable !rtree { finish_test ; return } + +# The following is a test of rowvalue handling on virtual tables that +# deal with inequalities and that set the OMIT flag on terms of the +# WHERE clause. This is not specific to rtree. We just use rtree because +# it is a convenient test platform since it has all the right +# characteristics. +# +do_execsql_test rtreeI-1.10 { + CREATE TABLE t1(a); + INSERT INTO t1 VALUES(2); + CREATE VIRTUAL TABLE t2 USING rtree(id,x0,x1); + INSERT INTO t2(id,x0,x1) VALUES(1,2,3); +} {} +do_execsql_test rtreeI-1.20 { + SELECT 123 FROM t1, t2 WHERE (a,0)>(x0,0); +} {} +do_execsql_test rtreeI-1.21 { + SELECT 123 FROM t1, t2 WHERE (a,0.1)>(x0,0); +} {123} +do_execsql_test rtreeI-1.22 { + SELECT 123 FROM t1, t2 WHERE (a,0)>=(x0,0); +} {123} +do_execsql_test rtreeI-1.23 { + SELECT 123 FROM t1, t2 WHERE (a,0)<=(x0,0); +} {123} +do_execsql_test rtreeI-1.24 { + SELECT 123 FROM t1, t2 WHERE (a,0)<(x0,0); +} {} +do_execsql_test rtreeI-1.30 { + SELECT 123 FROM t1, t2 WHERE (x0,0)<(a,0); +} {} +do_execsql_test rtreeI-1.31 { + SELECT 123 FROM t1, t2 WHERE (x0,0)<(a,0.1); +} {123} +do_execsql_test rtreeI-1.40 { + SELECT 123 FROM t1, t2 WHERE x1<5 AND id<99 AND (a,0)>(x0,0); +} {} +do_execsql_test rtreeI-1.41 { + SELECT 123 FROM t1, t2 WHERE x1<5 AND id<99 AND (a,0.5)>(x0,0); +} {123} +do_execsql_test rtreeI-1.42 { + SELECT 123 FROM t1, t2 WHERE x1<5 AND id<99 AND (a,0)>=(x0,0); +} {123} +do_execsql_test rtreeI-1.43 { + SELECT 123 FROM t1, t2 WHERE x1<5 AND id<99 AND (a,0)<(x0,0); +} {} +do_execsql_test rtreeI-1.50 { + SELECT 123 FROM t1, t2 WHERE 5>x1 AND 99>id AND (x0,0)<(a,0); +} {} +do_execsql_test rtreeI-1.51 { + SELECT 123 FROM t1, t2 WHERE 5>x1 AND 99>id AND (x0,0)<(a,0.5); +} {123} + + + +finish_test diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 2f9ee9cd..1ed3b550 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -200,7 +200,7 @@ int sqlite3session_attach( ** The second argument (xFilter) is the "filter callback". For changes to rows ** in tables that are not attached to the Session object, the filter is called ** to determine whether changes to the table's rows should be tracked or not. -** If xFilter returns 0, changes is not tracked. Note that once a table is +** If xFilter returns 0, changes are not tracked. Note that once a table is ** attached, xFilter will not be called again. */ void sqlite3session_table_filter( @@ -374,7 +374,7 @@ int sqlite3session_changeset( ** It an error if database zFrom does not exist or does not contain the ** required compatible table. ** -** If the operation successful, SQLITE_OK is returned. Otherwise, an SQLite +** If the operation is successful, SQLITE_OK is returned. Otherwise, an SQLite ** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg ** may be set to point to a buffer containing an English language error ** message. It is the responsibility of the caller to free this buffer using @@ -511,7 +511,7 @@ int sqlite3changeset_start_v2( ** CAPI3REF: Advance A Changeset Iterator ** METHOD: sqlite3_changeset_iter ** -** This function may only be used with iterators created by function +** This function may only be used with iterators created by the function ** [sqlite3changeset_start()]. If it is called on an iterator passed to ** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE ** is returned and the call has no effect. @@ -927,8 +927,8 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp); ** case, this function fails with SQLITE_SCHEMA. If the input changeset ** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is ** returned. Or, if an out-of-memory condition occurs during processing, this -** function returns SQLITE_NOMEM. In all cases, if an error occurs the -** final contents of the changegroup is undefined. +** function returns SQLITE_NOMEM. In all cases, if an error occurs the state +** of the final contents of the changegroup is undefined. ** ** If no error occurs, SQLITE_OK is returned. */ @@ -1103,7 +1103,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*); ** ** It is safe to execute SQL statements, including those that write to the ** table that the callback related to, from within the xConflict callback. -** This can be used to further customize the applications conflict +** This can be used to further customize the application's conflict ** resolution strategy. ** ** All changes made by these functions are enclosed in a savepoint transaction. @@ -1413,7 +1413,7 @@ int sqlite3rebaser_configure( ** ** Argument pIn must point to a buffer containing a changeset nIn bytes ** in size. This function allocates and populates a buffer with a copy -** of the changeset rebased rebased according to the configuration of the +** of the changeset rebased according to the configuration of the ** rebaser object passed as the first argument. If successful, (*ppOut) ** is set to point to the new buffer containing the rebased changeset and ** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the diff --git a/ext/userauth/userauth.c b/ext/userauth/userauth.c index a8ed01ae..fa708516 100644 --- a/ext/userauth/userauth.c +++ b/ext/userauth/userauth.c @@ -40,7 +40,7 @@ static sqlite3_stmt *sqlite3UserAuthPrepare( char *zSql; int rc; va_list ap; - int savedFlags = db->flags; + u64 savedFlags = db->flags; va_start(ap, zFormat); zSql = sqlite3_vmprintf(zFormat, ap); diff --git a/main.mk b/main.mk index 54622920..cbf14f06 100644 --- a/main.mk +++ b/main.mk @@ -934,10 +934,6 @@ fuzztest: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz- ./fuzzcheck$(EXE) $(FUZZDATA) ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db -fastfuzztest: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db - ./fuzzcheck$(EXE) --limit-mem 100M $(FUZZDATA) - ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db - valgrindfuzz: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA) valgrind ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db @@ -955,7 +951,7 @@ quicktest: ./testfixture$(EXE) # The default test case. Runs most of the faster standard TCL tests, # and fuzz tests, and sqlite3_analyzer and sqldiff tests. -test: fastfuzztest sourcetest $(TESTPROGS) tcltest +test: fuzztest sourcetest $(TESTPROGS) tcltest # Run a test using valgrind. This can take a really long time # because valgrind is so much slower than a native machine. diff --git a/manifest b/manifest index db99853c..927e64b1 100644 --- a/manifest +++ b/manifest @@ -1,13 +1,13 @@ -C Version\s3.30.1 -D 2019-10-10T20:19:45.339 +C Version\s3.31.0 +D 2020-01-22T18:38:59.573 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 578f123620087ea459aa08fa872810a25ca7c0aaf16331de985bfcddb5f1e747 +F Makefile.in 9dfc7936f675785309b74d09202bb656732325e65df889e5aaa18cc8932e5b0c F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 -F Makefile.msc a463dca3c50d8a36094fe5c8c39077907f530b54edfc5388c66c85e2cfc8dc04 +F Makefile.msc fab23c6b10cb6f06a7e9c407fc2e35cb184a6d653f1b793bda87fcee2eafa4f6 F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a -F VERSION 396c1094b353e5533180a7498086557a9c50c76f2bfb62cc5fb69cfba07d562c +F VERSION 081500f0aeaadc989d85aafbc717af45512018aebc73d89e5c2368fe62a600ff F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 @@ -15,31 +15,32 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am e14b629addaa1ce372b72043f28f40de2e32b7e211b6e0fc18dbb87989197e40 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac -F autoconf/Makefile.msc 3804b004efb6abd2d2e0f5f887dfc6ade3d1661f39335c0531df96e1ab61a062 +F autoconf/Makefile.msc 1d1e4af61289c62b94aa65a93afcd3dfa4b53e4195908980e0b138203e71e1c9 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 -F autoconf/configure.ac 308de24343e76ecfbe9a67f8fcd4c5216b790d230c5d9ce10210b7d5965d6192 +F autoconf/configure.ac 3cd933b959fe514eebd1ca1717dfddbf2c9b825b6bc2c5f744deaf5d63af9288 F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 -F autoconf/tea/configure.ac 8aa16e3f0a5ca7959d4af198f46934ec187d395f +F autoconf/tea/configure.ac 6f379dfd46ace5caa97791acae07675eff62cada9800fc7bb36c789ecb7f17ac F autoconf/tea/doc/sqlite3.n e1fe45d4f5286ee3d0ccc877aca2a0def488e9bb F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523 F autoconf/tea/pkgIndex.tcl.in 3ef61715cf1c7bdcff56947ffadb26bc991ca39d F autoconf/tea/tclconfig/install-sh bdd5e293591621ae60d9824d86a4b1c5f22c3d00 F autoconf/tea/tclconfig/tcl.m4 66ddf0a5d5e4b1d29bff472c0985fd7fa89d0fb5 -F autoconf/tea/win/makefile.vc f89d0184d0eee5f7e356ea407964dcd139939928 +F autoconf/tea/win/makefile.vc 71915591c07cd5137711dc40ba3e127deb3f4531b9aad220b724cf5b451362bd F autoconf/tea/win/nmakehlp.c 247538ad8e8c508f33c03ec1fbd67d3a07ef6291 F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559 -F configure be1e3b2af2355720ff01c2f35fb450ba78488832afffa47452d7c305f333dfa1 x -F configure.ac 3552d3aecade98a9d4b64bceb48ffb7726cbc85902efde956812942f060fbd0a +F configure aae28230005acf833d466c8a160bd4c70cf42984f5a6756fa327e15e7f473477 x +F configure.ac 798a24cee2879325ca5b688a618199eb32cc77ed8136edbaa43d9137b470d54e F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd F doc/lemon.html 24956ab2995e55fe171e55bdd04f22b553957dc8bb43501dbb9311e30187e0d3 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 +F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91 @@ -49,7 +50,7 @@ F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633ca F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4 F ext/expert/expert1.test e2afc53a27610e8251e44c7f961806607a5490ff204b3db342740d558e052662 F ext/expert/sqlite3expert.c 3da865f2286433588260f41e796422c611bceaca3a0bbf9139a619cf7d062c19 -F ext/expert/sqlite3expert.h af6354f8ee5c9e025024e63fec3bd640a802afcc3099a44d804752cf0791d811 +F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72 F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b @@ -81,25 +82,25 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c a01da95e840a6ddb14d0a14b35c9017a8b034b08511ca97af716f00df102fb3f +F ext/fts3/fts3.c 52c09f459364732b5df73eff0373f991fd6af8f0f60fcdbb4b649205e88a7568 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe -F ext/fts3/fts3Int.h 74384e28b778a057f1467529715668b98f3f12f52eeb564fd6ae1e894125c00c +F ext/fts3/fts3Int.h f091030b976045e7df91af2337935952b477cdbd9f48058c44c965684484cb50 F ext/fts3/fts3_aux.c 96708c8b3a7d9b8ca1b68ea2b7e503e283f20e95f145becadedfad096dbd0f34 F ext/fts3/fts3_expr.c b132af223e90e35b9f9efa9fe63d6ae737d34153a3b6066736086df8abc78a1f F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6bdb48b7 F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116 F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009 -F ext/fts3/fts3_snippet.c 7963dd25ec81013c31f3c61697d0a1f3d06be21af3565774645c08d3dedf1fa7 +F ext/fts3/fts3_snippet.c 052b35ad746349ffb53820379bacdb23ff3ac60d3cc13d986e56d42822ef5a9a F ext/fts3/fts3_term.c f45a1e7c6ef464abb1231245d123dae12266b69e05cc56e14045b76591ae92d1 F ext/fts3/fts3_test.c 73b16e229e517c1b1f0fb8e1046182a4e5dbc8dbe6eea8a5d4353fcce7dbbf39 F ext/fts3/fts3_tokenize_vtab.c 1de9a61acfa2a0445ed989310c31839c57f6b6086dd9d5c97177ae734a17fd8b -F ext/fts3/fts3_tokenizer.c 8034a5604c31559493fef0fed432cb251a566c46043c0b2c11b92c740e6f036f +F ext/fts3/fts3_tokenizer.c 6d8fc150c48238955d5182bf661498db0dd473c8a2a80e00c16994a646fa96e7 F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 F ext/fts3/fts3_unicode.c 4b9af6151c29b35ed09574937083cece7c31e911f69615e168a39677569b684d F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f -F ext/fts3/fts3_write.c 13582783abedf905e6946ce95edff7103c07810fb03a9c3b40212d21a3efa09c +F ext/fts3/fts3_write.c 6f9dd5d774003ea81b8b32daa7d0819f9aaf01bf2b5f33498a69aab096094ed3 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73 @@ -109,16 +110,16 @@ F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7 F ext/fts3/unicode/mkunicode.tcl bf7fcaa6d68e6d38223467983785d054f1cff4d9e3905dd51f6ed8801bb590d5 F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 -F ext/fts5/fts5.h 7c9da96f2b9dcfa4dd94081fb2d87ec418d8cdb35b25df56756c334b6b558fd7 -F ext/fts5/fts5Int.h 0ec19a906a54c0e53f8a380c0ff70f11a866aa259490bc13aa39f8d2491800fd +F ext/fts5/fts5.h c132a9323f22a972c4c93a8d5a3d901113a6e612faf30ca8e695788438c5ca2a +F ext/fts5/fts5Int.h d7cbc214ee167496f70905667e18f73ea0402f7ef09236ce305e117e0efc866a F ext/fts5/fts5_aux.c dcc627d8b6e3fc773db528ff67b39955dab7b51628f9dba8e15849e5bedfd7fa F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70 -F ext/fts5/fts5_config.c 606a29f2962a8f4508923e6ad833974b32a3ab4093f63fd6de0fb33a87eed54c -F ext/fts5/fts5_expr.c 5661fe64f4f5a499710df9561075de84b743f01e808af46df4130a9ec343a0fd +F ext/fts5/fts5_config.c b447948f35ad3354e8fe5e242e0a7e7b5b941555400b9404259944e3aa570037 +F ext/fts5/fts5_expr.c 2be456484786333d559dc2987a00f2750981fab91d52db8452a8046278c5f22e F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75 -F ext/fts5/fts5_index.c 6601d085d8e8cf4750ee49e2e1d18907582cc0aab78233d3b21bc240ba76a199 -F ext/fts5/fts5_main.c bf637030722badf06667d28f7159e4c209dbafd7aa76c33f387104b78ad147e1 -F ext/fts5/fts5_storage.c 801b4e3cd33786a60a07b6b01f86d0fbdf7e68325054e08d17176293a8081e99 +F ext/fts5/fts5_index.c e3573c88ce8238f7a5892c777a9ddf646c1355012780337d783fb2dfc3dca650 +F ext/fts5/fts5_main.c e881a2ea0bf01b3a3ff0bc1b31373c58fd54b6c9f3c43ea3d431bea4e5d4025e +F ext/fts5/fts5_storage.c 3ecda8edadc1f62a355d6789776be0da609f8658c50d72e422674093ab7e1528 F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee F ext/fts5/fts5_test_tok.c f96c6e193c466711d6d7828d5f190407fe7ab897062d371426dd3036f01258e7 @@ -154,10 +155,10 @@ F ext/fts5/test/fts5columnsize.test 45459ce4dd9fd853b6044cdc9674921bff89e3d840f3 F ext/fts5/test/fts5config.test 60094712debc59286c59aef0e6cf511c37d866802776a825ce437d26afe0817f F ext/fts5/test/fts5conflict.test 655925678e630d3cdf145d18725a558971806416f453ac8410ca8c04d934238d F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c073e19b3ae9126b2f4 -F ext/fts5/test/fts5content.test 9517cc527a8e8a33949652d5c7b5e251f8c3d5ae3f23f01d4320e30f29a0336b +F ext/fts5/test/fts5content.test 213506436fb2c87567b8e31f6d43ab30aab99354cec74ed679f22aad0cdbf283 F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f -F ext/fts5/test/fts5corrupt3.test e188a43cecb3ff53b6236f862f82b2ec36962b9e39f20cb620dfa07aed70afa4 +F ext/fts5/test/fts5corrupt3.test fab4ea761b2df254fb3909423989320772a3a757de4d151ddcfa2a40a3b93328 F ext/fts5/test/fts5corrupt4.test ea805c4d7c68b5f185b9db5d2060a7ae5875339738dd48203c92162f41e7ca91 F ext/fts5/test/fts5delete.test cbf87e3b8867c4d5cfcaed975c7475fd3f99d072bce2075fcedf43d1f82af775 F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e @@ -165,7 +166,7 @@ F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3 F ext/fts5/test/fts5dlidx.test b90852c55881b29dbac6380b274de27beae623ac4b6d567c6c8fb9cdc315a86e F ext/fts5/test/fts5doclist.test e39a6001495f1dc68e20323586ac965787986c2bf6f515b9b0285627b089d9e6 F ext/fts5/test/fts5ea.test b01e3a18cdfabbff8104a96a5242a06a68a998a0 -F ext/fts5/test/fts5eb.test e5fe57b4141db456f06094afca45541fb0c13b30032eccae05100b4dbec11955 +F ext/fts5/test/fts5eb.test 239bb2f02571f8cccfc7018d08f502df1cd8cc6a69b65ed1dde5f6a070e3f669 F ext/fts5/test/fts5fault1.test d28a65caee75db6897c3cf1358c5230d3bb2a3bf7fb31062c19c7e5382b3d2bd F ext/fts5/test/fts5fault2.test 69c8fdbef830cd0d450908d4504d5bb86609e255af99c421c20a0756251fe344 F ext/fts5/test/fts5fault3.test da2f9e3e56ff5740d68ebdd6877c97089e7ed28ddff28a0da87a6afea27e5522 @@ -179,17 +180,17 @@ F ext/fts5/test/fts5faultA.test be4487576bff8c22cee6597d1893b312f306504a8c6ccd3c F ext/fts5/test/fts5faultB.test d606bdb8e81aaeb6f41de3fc9fc7ae315733f0903fbff05cf54f5b045b729ab5 F ext/fts5/test/fts5faultD.test cc5d1225556e356615e719c612e845d41bff7d5a F ext/fts5/test/fts5first.test 3fcf2365c00a15fc9704233674789a3b95131d12de18a9b996159f6909dc8079 -F ext/fts5/test/fts5full.test 49b565da02918c06e58f51f0b953b0302b96f155aa68baba24782b81570685e2 +F ext/fts5/test/fts5full.test e1701a112354e0ff9a1fdffb0c940c576530c33732ee20ac5e8361777070d717 F ext/fts5/test/fts5fuzz1.test 238d8c45f3b81342aa384de3e581ff2fa330bf922a7b69e484bbc06051a1080e F ext/fts5/test/fts5hash.test a4cf51acad99bfc43c16fb74f9d22495dc221ae0701fc5e908ca963a9b26a02b -F ext/fts5/test/fts5integrity.test 4317561cd25eca7df16aa1f7d1a700ee958059fa639785f94aba0a84df9ab17b +F ext/fts5/test/fts5integrity.test 8ffabcd91b058d812aba3e3e0a06f76ce165ba402a18cca20e34204a7feec92e F ext/fts5/test/fts5interrupt.test 09613247b273a99889808ef852898177e671406fe71fdde7ea00e78ea283d227 F ext/fts5/test/fts5lastrowid.test be98fe3e03235296585b72daad7aed5717ba0062bae5e5c18dd6e04e194c6b28 F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc2782680740513c4d1fc114b43d4ad -F ext/fts5/test/fts5matchinfo.test 79129ff6c9a2d86943b287a5a8caa7ee639f6dcf004d8975d15c279374e82e35 +F ext/fts5/test/fts5matchinfo.test 50d86da66ec5b27603dcd90ba0227f5d9deb10351cbc52974a88e24f6fc9b076 F ext/fts5/test/fts5merge.test e92a8db28b45931e7a9c7b1bbd36101692759d00274df74d83fd29d25d53b3a6 F ext/fts5/test/fts5merge2.test 3ebad1a59d6ad3fb66eff6523a09e95dc6367cbefb3cd73196801dea0425c8e2 -F ext/fts5/test/fts5misc.test 9a7263add42d55b8e22fc6ebbee2904390e923f4aa11d05fffaf617032f95db5 +F ext/fts5/test/fts5misc.test 088ac5f0f5de1ad45b0f83197ab5263bcae8130156cdc901bff2375ff2b8af86 F ext/fts5/test/fts5multi.test a15bc91cdb717492e6e1b66fec1c356cb57386b980c7ba5af1915f97fe878581 F ext/fts5/test/fts5multiclient.test 5ff811c028d6108045ffef737f1e9f05028af2458e456c0937c1d1b8dea56d45 F ext/fts5/test/fts5near.test 211477940142d733ac04fad97cb24095513ab2507073a99c2765c3ddd2ef58bd @@ -205,6 +206,7 @@ F ext/fts5/test/fts5rank.test c9fd4a1e36b4fa92d572ec13d846469b97da249d1c2f7fd3ee F ext/fts5/test/fts5rebuild.test 55d6f17715cddbf825680dd6551efbc72ed916d8cf1cde40a46fc5d785b451e7 F ext/fts5/test/fts5restart.test 835ecc8f449e3919f72509ab58056d0cedca40d1fe04108ccf8ac4c2ba41f415 F ext/fts5/test/fts5rowid.test b8790ec170a8dc1942a15aef3db926a5f3061b1ff171013003d8297203a20ad6 +F ext/fts5/test/fts5savepoint.test fc02929f238d02a22df4172625704e029f7c1e0e92e332d654375690f8e6e43f F ext/fts5/test/fts5simple.test a298670508c1458b88ce6030440f26a30673931884eb5f4094ac1773b3ba217b F ext/fts5/test/fts5simple2.test 258a1b0c590409bfa5271e872c79572b319d2a56554d0585f68f146a0da603f0 F ext/fts5/test/fts5simple3.test d5c74a9d3ca71bd5dd5cacb7c55b86ea12cdddfc8b1910e3de2995206898380f @@ -229,7 +231,7 @@ F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt a295e91db742b153e8dce8f7efd31d28ad1eea4df31ef4daa3eedc85be2f5138 -F ext/icu/icu.c c2c7592574c08cd1270d909b8fb8797f6ea1f49e931e71dbcc25506b9b224580 +F ext/icu/icu.c 7adfe8a72dd4f54b47684dc9b88523399c6ef119d733b73e17371445f7428dd1 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/lsm1/Makefile a553b728bba6c11201b795188c5708915cc4290f02b7df6ba7e8c4c943fd5cd9 F ext/lsm1/Makefile.msc f8c878b467232226de288da320e1ac71c131f5ec91e08b21f502303347260013 @@ -277,53 +279,56 @@ F ext/lsm1/test/lsm1_common.tcl 5ed4bab07c93be2e4f300ebe46007ecf4b3e20bc5fbe1ded F ext/lsm1/test/lsm1_simple.test a04d08e8661ae6fc53786c67f0bd102c6692f003e859dde03ed9ac3f12e066e5 F ext/lsm1/tool/mklsm1c.tcl f31561bbee5349f0a554d1ad7236ac1991fc09176626f529f6078e07335398b0 F ext/misc/README.md d6dd0fe1d8af77040216798a6a2b0c46c73054d2f0ea544fbbcdccf6f238c240 -F ext/misc/amatch.c 50a9ef2d38dabfa371f8c1904097d493271e63d58ccb0e9b79a4fa4a94e66660 +F ext/misc/amatch.c e3ad5532799cee9a97647f483f67f43b38796b84b5a8c60594fe782a4338f358 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb F ext/misc/appendvfs.c 3777f22ec1057dc4e5fd89f2fbddcc7a29fbeef1ad038c736c54411bb1967af7 F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a F ext/misc/btreeinfo.c 4f0ebf278f46e68e6306c667917766cebc5550fd35d5de17847988e22892d4d2 F ext/misc/carray.c 91e9a7f512fda934894bed30464552fffa7d3073b5be04189ae0bd0c59f26bfd F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243 -F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f -F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 -F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb +F ext/misc/completion.c a0efe03edfdc4f717c61e6c9b0bfe2708ff7878010dae3174980a68fdf76aabc +F ext/misc/compress.c 3354c77a7c8e86e07d849916000cdac451ed96500bfb5bd83b20eb61eee012c9 +F ext/misc/csv.c 3ed979c1eb35e35a98b30ef545a2facf62994594217681d9138b4b75faf6b0d7 F ext/misc/dbdata.c e316fba936571584e55abd5b974a32a191727a6b746053a0c9d439bd2cf93940 F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336 -F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e +F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1 F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f -F ext/misc/fileio.c 288e7230e0fe464d71b0694e2d8bdd3a353118ac2e31da3964b95f460f09915f -F ext/misc/fossildelta.c 7708651072eb5620ab21bbfb518d184f27b2c29c0131b09b9a2d8852a8016430 -F ext/misc/fuzzer.c c4e27daf41433a64cad5265cd27dbcb891147e9994d0422200ce81ce9a54b625 -F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c 66ccdfa63283adb2c015019b431eeee1f5af40a78d9aad10afd22c2c6db0e3b0 +F ext/misc/fileio.c bfa11a207da4eed8e5f84a1e3954608492f25f8850f9f00d0d2076f4648d7608 +F ext/misc/fossildelta.c 1240b2d3e52eab1d50c160c7fe1902a9bd210e052dc209200a750bbf885402d5 +F ext/misc/fuzzer.c eae560134f66333e9e1ca4c8ffea75df42056e2ce8456734565dbe1c2a92bf3d +F ext/misc/ieee754.c eaffd9b364d7c8371727e9c43fc8bec38cdacc4d11fc26beffaa3ca05a0ea9d6 +F ext/misc/json1.c 2d44e3fa37f958b42cbcd41651f9f0a0eaaf3bac3f1f4b8eb456431623cb3bd8 F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567 F ext/misc/mmapwarm.c 8c5fe90d807a23e44a8b93e96e8b812b19b300d5fd8c1d40a4fd1d8224e33f46 -F ext/misc/nextchar.c 279f80fe8ef5ba413242e2704e246503ac601f005eefb180d19e6c920338a0ba +F ext/misc/nextchar.c 7877914c2a80c2f181dd04c3dbef550dfb54c93495dc03da2403b5dd58f34edd +F ext/misc/noop.c 81efe4cad9ec740e64388b14281cb983e6e2c223fed43eb77ab3e34946e0c1ab F ext/misc/normalize.c b4290464f542bae7a97b43f15bd197949b833ffd668b7c313631bd5d4610212c -F ext/misc/percentile.c 148dd07286b16e50f232bb638a47850085ad37d51f270429905bd865e595d1ca -F ext/misc/prefixes.c 7be86d17525cfae6ed462fc3c519efc44488ac329890f77491c8f82871f57e17 -F ext/misc/regexp.c 653b6ab5e89bcb5d45f9ebe0747d7f8f3f5706cac963fcbc9a3ddbe5fdc1efa2 +F ext/misc/percentile.c b9086e223d583bdaf8cb73c98a6539d501a2fc4282654adbfea576453d82e691 +F ext/misc/prefixes.c 0f4f8cff5aebc00a7e3ac4021fd59cfe1a8e17c800ceaf592859ecb9cbc38196 +F ext/misc/regexp.c 246244c714267f303df76acf73dcf110cf2eaf076896aaaba8db6d6d21a129db F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c -F ext/misc/rot13.c 540a169cb0d74f15522a8930b0cccdcb37a4fd071d219a5a083a319fc6e8db77 +F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c F ext/misc/scrub.c db9fff56fed322ca587d73727c6021b11ae79ce3f31b389e1d82891d144f22ad -F ext/misc/series.c 0c97f63378fddc9f425e82ba139b9aaf902211f24ced115c2b6ae12b425f7334 -F ext/misc/sha1.c df0a667211baa2c0612d8486acbf6331b9f8633fd4d605c17c7cccd26d59c6bd -F ext/misc/shathree.c 22ba7ca84a433d6466a7d05dcc876910b435a715da8cc462517db9351412b8c8 +F ext/misc/series.c 4057dda3579b38ff88b2d3b13b4dd92dbd9d6f90dac2b55c19b0a8ed87ee4959 +F ext/misc/sha1.c 1190aec0d9d886d9f5ffdf891142a626812327d11472c0cade3489db3b7b140a +F ext/misc/shathree.c 135b7c145db4a09b1650c3e7aff9cb538763a9a361e834c015dd1aaf8d5c9a00 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 -F ext/misc/spellfix.c f88ecb2c0294453ce8b7704b211f5350c41b085b38c8e056852e3a08b0f5e484 -F ext/misc/sqlar.c 57d5bc45cd5492208e451f697404be88f8612527d64c9d42f96b325b64983d74 +F ext/misc/spellfix.c 94df9bbfa514a563c1484f684a2df3d128a2f7209a84ca3ca100c68a0163e29f +F ext/misc/sqlar.c c9e5d58544e1506135806a1e0f525f92d4bb6bb125348dce469d778fb334fbce F ext/misc/stmt.c 8a8dc4675042e4551e4afe99b8d0cc7a4a2fc1a8dacc0a9ce1b1bbff145da93d F ext/misc/templatevtab.c 8a16a91a5ceaccfcbd6aaaa56d46828806e460dd194965b3f77bf38f14b942c4 -F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 +F ext/misc/totype.c fa4aedeb07f66169005dffa8de3b0a2b621779fd44f85c103228a42afa71853b F ext/misc/unionvtab.c 36237f0607ca954ac13a4a0e2d2ac40c33bc6e032a5f55f431713061ef1625f9 +F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917b9c751 +F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf F ext/misc/vfslog.c 3b25c2f56ba60788db247287be6ab024b53c4afffd412b4876db563389be0d35 F ext/misc/vfsstat.c 77b5b4235c9f7f11eddf82487c0a422944ac2f132dafd5af3be7a68a057b1cdb F ext/misc/vtablog.c 5538acd0c8ddaae372331bee11608d76973436b77d6a91e8635cfc9432fba5ae F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd -F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 -F ext/misc/zipfile.c c1ca8f52330b4564207036b978edac8141c737bf612659bf6f7bee3ddd563a03 +F ext/misc/wholenumber.c 520f34c3099e5b7d546f13708607dc2fa173c46b68952eecf0d19cd675fec85e +F ext/misc/zipfile.c d1be54ea83ac9ad71b8b6ffc4b60db8946ce2ceacdf6bff063fcd9489f41bb49 F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64 F ext/rbu/rbu.c 8681f6157db6adc82c34af24b14ea8a3be0146ad2a3b6c1d5da6cb8a5796c8ce F ext/rbu/rbu1.test 221d9c18a5e600ac9ac6b1810d99d9f99163a7909ba61597876ab6e4d4beb3d6 @@ -365,7 +370,7 @@ F ext/rbu/rbuvacuum.test 55e101e90168c2b31df6c9638fe73dc7f7cc666b6142266d1563697 F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc F ext/rbu/rbuvacuum4.test a78898e438a44803eb2bc897ba3323373c9f277418e2d6d76e90f2f1dbccfd10 -F ext/rbu/sqlite3rbu.c f3a3e09f575157052813be667d6ab3b54f47fb02e6e1c9f767ad7bb8f1fb90b3 +F ext/rbu/sqlite3rbu.c 77a47f3231f5f363b2c584dba3e310a7efdaf073ad8c18728ab846b38de2879c F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812 F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 @@ -378,11 +383,11 @@ F ext/repair/test/checkfreelist01.test 3e8aa6aeb4007680c94a8d07b41c339aa635cc782 F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c335096108c12c01bddbadcec F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/geopoly.c c591164125808f8bba9659e92665b78412cd263e654b6f05294f3a8da7cdd9fb -F ext/rtree/rtree.c f8d9ea7d988c1002bff5acfac77d188f2f5d9eb025f24d5038a3d70a9c3f3d9d +F ext/rtree/geopoly.c cac70b5502742bd0ba8877a1329a74e86a379c78567546a2a18cf5f9c3787f73 +F ext/rtree/rtree.c 84b939a9a558edd0461bb976b98f60012e3e574b3b17a0f44533d6f2a9aa2f2e F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412 -F ext/rtree/rtree1.test 7573134f1b4f59df36c1b0a6de51268fd3b9c714d91f3811482263e734e416ea -F ext/rtree/rtree2.test 5f25b01acd03470067a2d52783b2eb0a50bf836803d4342d20ca39e541220fe2 +F ext/rtree/rtree1.test 4092a8bd2b5eafc4fafe4fe9024249c12b13e4bab23c2c3eaff57412fdf805fa +F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d F ext/rtree/rtree3.test 4ee5d7df86040efe3d8d84f141f2962a7745452200a7cba1db06f86d97050499 F ext/rtree/rtree4.test 304de65d484540111b896827e4261815e5dca4ce28eeecd58be648cd73452c4b F ext/rtree/rtree5.test 49c9041d713d54560b315c2c7ef7207ee287eba1b20f8266968a06f2e55d3142 @@ -392,12 +397,13 @@ F ext/rtree/rtree8.test 2d99006a1386663978c9e1df167554671e4f711c419175b39f332719 F ext/rtree/rtree9.test c646f12c8c1c68ef015c6c043d86a0c42488e2e68ed1bb1b0771a7ca246cbabf F ext/rtree/rtreeA.test ed2f1be9c06dde0b1ab93a95dd9e87eeaa02db2d30bcb4b9179b69ee3dc3319b F ext/rtree/rtreeB.test 4cec297f8e5c588654bbf3c6ed0903f10612be8a2878055dd25faf8c71758bc9 -F ext/rtree/rtreeC.test 128928549d22b65c381ab1366760d08703cd75e34f6a7a506ece38f9330b7282 +F ext/rtree/rtreeC.test 6aa87eba4d9a3003b941a1ba77db259c5cabc3fd92fc5a6360f5369520eb9a4d F ext/rtree/rtreeD.test fe46aa7f012e137bd58294409b16c0d43976c3bb92c8f710481e577c4a1100dc F ext/rtree/rtreeE.test e65d3fc625da1800b412fc8785817327d43ccfec5f5973912d8c9e471928caa9 F ext/rtree/rtreeF.test 81ffa7ef51c4e4618d497a57328c265bf576990c7070633b623b23cd450ed331 F ext/rtree/rtreeG.test 1b9ca6e3effb48f4161edaa463ddeaa8fca4b2526d084f9cbf5dbe4e0184939c -F ext/rtree/rtreeH.test aa08cc4fa8005b4c67446c7110205055b4d6da90e760e6f44b82dfa4cdf8d87a +F ext/rtree/rtreeH.test 0885151ee8429242625600ae47142cca935332c70a06737f35af53a7bd7aaf90 +F ext/rtree/rtreeI.test 608e77f7fde9be5a12eae316baef640fffaafcfa90a3d67443e78123e19c4ca4 F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 F ext/rtree/rtree_util.tcl db734b4c5e75fed6acc56d9701f2235345acfdec750b5fc7b587936f5f6bceed F ext/rtree/rtreecheck.test d67d5b3e9e45bfa8cd90734e8e9302144ac415b8e9176c6f02d4f92892ee8a35 @@ -439,15 +445,15 @@ F ext/session/sessionrebase.test ccfa716b23bd1d3b03217ee58cfd90c78d4b99f53e6a9a2 F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5 F ext/session/sessionwor.test 67b5ab91d4f93ce65ff1f58240ac5ddf73f8670facc1ffa49cef56293d52818d F ext/session/sqlite3session.c a4dfb372f270df93422b0dc7666fd46849e6979b62a152f11287c21eed4ac21b -F ext/session/sqlite3session.h 919be6649d39d6413ce7a63fc3e3bca3270e18bc2d57ad4040a70007b9e54397 +F ext/session/sqlite3session.h a2db5b72b938d12c727b4b4ec632254ca493670a9c0de597af3271a7f774fc57 F ext/session/test_session.c 98797aba475a799376c9a42214f2d1debf2d0c3cb657d9c8bbf4f70bf3fb4aec F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 -F ext/userauth/userauth.c f81aa5a3ecacf406f170c62a144405858f6f6de51dbdc0920134e629edbe2648 +F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 09716d345766a55b25ed157b14786526cf67c761c61d99c53e117196fb3b391a +F main.mk 7ce055f3df31a4f7d21e38f493f907c21db1f673863a573e231f55e2ab005023 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -459,38 +465,38 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 5773b28684a001dcab45adcefa3cbf5e846335c0c8fee0da8a3770cb0123bba8 -F src/analyze.c a3f4ea45cdb4e9df78d4ea7beb87ec8a7a46f494173b641cd28512a40a97bff2 -F src/attach.c 3ca19504849c2d9be10fc5899d6811f9d6e848665d1a41ffb53df0cd6e7c13ed +F src/alter.c f48a4423c8f198d7f1ae4940f74b606707d05384ac79fb219be8e3323af2a2de +F src/analyze.c b3ceec3fc052df8a96ca8a8c858d455dc5029ba681b4be98bb5c5a9162cfa58c +F src/attach.c df0ead9091042c68964856ecc08dba55d5403ad5f3ca865d9d396d71528c511a F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c fdc4389b271bca30138db27dc2dfb9f52c2a7baaa44845aaf31a3c54663d837f -F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 -F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f -F src/build.c 4814d55abb5553ac82763f6df9e185503d913f912cc0abea00965bb02912cc2d -F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73 +F src/btree.c 7af5ff0f88ba856c2681f6eeb457590b24f787e994f18cbdb44c2de2d33f757e +F src/btree.h 6111552f19ed7a40f029cf4b33badc6fef9880314fffd80a945f0b7f43ab7471 +F src/btreeInt.h 6794084fad08c9750b45145743c0e3e5c27c94dee89f26dd8df7073314934fd2 +F src/build.c 2394d2c853088106dfc1cf485d609f20e6421d7c84892b795824e454f78e50ad +F src/callback.c c547d00963ae28100117b4fb1f0f32242109b5804374ee3bfe01138a54da7f76 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251 -F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 -F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 -F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 -F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 18974550063a6a1c8eef69e63d2ad88ceb4395ef139a60cc0d0a28632f41d553 +F src/date.c 6c408fdd2e9ddf6e8431aba76315a2d061bea2cec8fbb75e25d7c1ba08274712 +F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a +F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da +F src/delete.c a5c59b9c0251cf7682bc52af0d64f09b1aefc6781a63592c8f1136f7b73c66e4 +F src/expr.c 003c59158b33d7f3b198122cb0d1e13c06517cc3932e56b42283eb0e96696d66 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e -F src/func.c ed33e38cd642058182a31a3f518f2e34f4bbe53aa483335705c153c4d3e50b12 -F src/global.c a1a8d698762ddd9a1543aac26c1e0029b20fcc3fcb56bfa41ec8cea2368f2798 +F src/fkey.c 92a248ec0fa4ed8ab60c98d9b188ce173aaf218f32e7737ba77deb2a684f9847 +F src/func.c 92249abc3fd7e52b249ca8eb2d15a617f70819d2fa4c777a4a33552b89bfb322 +F src/global.c 59601d885a0dbbfbd22ed2d030424a5e7f1b9809a17ca46686058bbc4a55e980 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 -F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da +F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 40557ebd69f4115e7a273f9304a8ab637a47ce44f3c6923396928f023967b5e8 +F src/insert.c 2fe4d7f67078a68650f16e4efe73207899e21702e6b9d2e8ad1894c76dcad352 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa -F src/loadext.c 4ddc65ae13c0d93db0ceedc8b14a28c8c260513448b0eb8c5a2ac375e3b6a85d -F src/main.c 3851950717170ade4f6d718c18c6c7400ef5994c2a654679af2cff2ffd0fb2b9 -F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990 +F src/loadext.c 8cd803f1747c03a50b32fe87ebfb5851998d0cdafefe02737daa95e0616b42bb +F src/main.c 430db07f140a2455784b504af1a56fe49134a79dd479a203370490031708d48f +F src/malloc.c eaa4dc9602ce28b077f7de2eb275db2be270c5cc56d7fec5466301bd9b80e2f5 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -505,37 +511,37 @@ F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4 F src/mutex_unix.c aaf9ebc3f89df28483c52208497a99a02cc3650011422fc9d4c57e4392f7fe58 F src/mutex_w32.c 7670d770c94bbfe8289bec9d7f1394c5a00a57c37f892aab6b6612d085255235 F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7 -F src/os.c 20f7b32c1e8839999fa7e79756a6cdc3041b44d7fc635c25a1b9399180d1fbd9 +F src/os.c 669cc3839cc35d20f81faf0be1ab6d4581cea35e9d8f3a9d48a98d6571f7c285 F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 -F src/os_unix.c a76a75f179cb233d54e505c3e0c84832224cfe5dfb3ee470bdcaf1ed29da57ab +F src/os_unix.c ad7640c04eed946052a3b12856362a773d0a717696707313037186df0e2b59f2 F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 422fd8cfa59fb9173eff36a95878904a0eeb0dcc62ba49350acc8b1e51c4dc7b -F src/pager.h 217921e81eb5fe455caa5cda96061959706bcdd29ddb57166198645ef7822ac3 -F src/parse.y 50bfcb34be7320dd0cb875021a93ae6451c8f0b083f21b71934a1a3a9108015a +F src/pager.c 302a18da8b247881808cd65009e1ac7c8b6e5cefb22ed9a1c330ed47b73e94ab +F src/pager.h 71fe1d5016ec54d0cc5d344cd474e563450b438c59f535e8c1ec8a13b1373f14 +F src/parse.y c8d2de64db469fd56e0fa24da46cd8ec8523eb98626567d2708df371b47fdc3f F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 -F src/pcache1.c 62714cbd1b7299a6e6a27a587b66b4fd3a836a84e1181e7f96f5c34a50917848 -F src/pragma.c b47bc7db02ab13d04c680aee424466b4e34f4ef5aa7b2e464876ec005806f98f -F src/pragma.h 40962d65b645bb3f08c1f4c456effd01c6e7f073f68ea25177e0c95e181cff75 -F src/prepare.c 132484635a30f873ee7eccd47f93ed1932503863b93b28423b42332d81adffaf +F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a +F src/pragma.c 0d49d43b22d66397aa026db505457f6683d8a66cd0a4f9db2e6776156bda716c +F src/pragma.h 9f86a3a3a0099e651189521c8ad03768df598974e7bbdc21c7f9bb6125592fbd +F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c e021be0c1c4a2125fa38aabcd8dbb764bf5b2c889a948c30d3708430ec6ccd00 +F src/resolve.c f0781c9e180028b279bc4ff079ad54f4727223d470c8d2343643fcaf79b67740 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c b3d64a7a3342471ce078251c5ba132f8ec66f994534f1070dda025b354a09a62 -F src/shell.c.in d70bcf630c4073eaa994fa74be98886c781918e794cb8b562be8df10f018e274 -F src/sqlite.h.in 5725a6b20190a1e8d662077a1c1c8ea889ad7be90dd803f914c2de226f5fe6ab +F src/select.c 3f7aecf64b08b018b89e4fe16ea621cc9a0e3f3801e9e5638cfe1a6035fa1581 +F src/shell.c.in c2e20c43a44fb5588a6c27ce60589538fbf4794fd7686f5b2598eca22eaae1fa +F src/sqlite.h.in 75d0304247a2154122d6d06f12219c1e29291d72304f0eeef4c1ec6b1409b443 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31 -F src/sqliteInt.h b8cabe8fcef93b7251422db41903c04abb4052df015eacb886dabd496fc3e0e8 +F src/sqlite3ext.h b0f776a0d042b23b6bcbb6b0943e8a3768c7f0b438a275e7168f0204e223a4db +F src/sqliteInt.h 7a29ba700a51eeb925731749a570cf3859f6a58ed94797ecf47508875b0ba279 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b -F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e +F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 -F src/tclsqlite.c 50c93be3e1c03b4e6cf6756e5197afcfe7f5cd0497d83a7ac317cde09e19b290 -F src/test1.c 17e1395cbddeb9226b756d723a7566b45b43b99a5f9f55afb4ff70888de6ad6f +F src/tclsqlite.c 97590069efaba5a4928ecffb606e3771dd93ee8e6bf248a62a6507c37a2b2e46 +F src/test1.c 4d0ab2f67053a4fff87d1d3586ecc0e5322a1fc45dd4119ab11dc96de44f17a1 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb @@ -582,40 +588,40 @@ F src/test_tclsh.c eeafce33ad2136d57e5dec10f1e9a4347447eb72ffd504a1c7b9c6bfe2e71 F src/test_tclvar.c 33ff42149494a39c5fbb0df3d25d6fafb2f668888e41c0688d07273dcb268dfc F src/test_thread.c 911d15fb14e19c0c542bdc8aabf981c2f10a4858 F src/test_vdbecov.c f60c6f135ec42c0de013a1d5136777aa328a776d33277f92abac648930453d43 -F src/test_vfs.c 32618cbd953963278804bb47e97be7085d9e0d8755b1e734c3e54e9b9e115277 +F src/test_vfs.c 36822d696789535bdd0260f07d2c9a46546082fea8bb1d0a7354c7f9366e37ea F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_windirent.c a895e2c068a06644eef91a7f0a32182445a893b9a0f33d0cdb4283dca2486ac1 F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a90484215 F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e -F src/treeview.c fddeb413159c3eeeaea3f496172f121cf3695606c461dc4e6dcee51417952df5 -F src/trigger.c 845ccc08f60716c58aa28fe6470385c18ef8c4e1d88c93dcf449bc13d464eb2e -F src/update.c 7f05fad5e145248a00048aeb0bac78b8fdb4ed17216e14a6eb24c55596e87ee7 -F src/upsert.c 710c91bb13e3c3fed5b6fe17cb13e09560bdd003ad8b8c51e6b16c80cfc48b10 -F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 -F src/util.c fffdfa627be74d69ef425f92db124e7148af449bb8a3286e79577c42bca84061 +F src/tokenize.c 7b17f6e2f20f6cbcb0b215025a86b7457c38451fc7622f705e553d7a488c572d +F src/treeview.c 438c1000587b33faba35e87596bebcf7f40638d98f33781cdd9e04711b18b09c +F src/trigger.c a40d50e88bd3355f1d2a73f0a3b2d6b42eae26ca4219001b82ef0d064439badc +F src/update.c 9ad19af96aff95dc02a923a99f97c1bc0b909009a29a2914b796f786b9ac0c60 +F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78 +F src/utf.c 736ff76753236ffbc8b5b939f5e0607f28aeaa7c780b3a56b419228f0a81c87b +F src/util.c d035b09df9cecbc0e8f07c34b815acbf0d43c8adc8d2c540e3dc92eecb27855a F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c da4030a71acf42be18001b9b7067d6d34ffb76610603ce6fafa52854b9e52936 -F src/vdbe.h 3f2b571e702e77e6bf031f0236e554aedfae643e991f69000320f481408455cf -F src/vdbeInt.h e95de5129124d77f01439e6635012adfaf23c0017bff47296126143cf18bd0c6 -F src/vdbeapi.c 95001d0f84ee3cda344fed98ca0d7961deb4fc836b83495630d0af1f7cc4789e -F src/vdbeaux.c d17dfbf1e03ef706cad9e2076c7f2354882c191a84e73e00c69c50bb7823e5ce +F src/vdbe.c e3dd230ece613409507523e68436764cc20638bb77ba2f416097de5b37235ce1 +F src/vdbe.h defd693289c7bb8d325f109be9490c77138061211a116827da7244b6015a4934 +F src/vdbeInt.h 30d3e8b991547cdf39025e416a0a737b0416d46747af70ae058f60e2e0466fe7 +F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02 +F src/vdbeaux.c ff690e6c9314ef281de7c06f8c8c33393f0afca80aabb1fe69836dcf2d60b0bf F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 -F src/vdbemem.c d8e10d1773806105e62094c4ede0a4684f46caaf07667a45e6d461e94306b530 -F src/vdbesort.c da75f505aba230060ce6472605a4aa6494f73eeb1071e1cc2643c3d4035e671b +F src/vdbemem.c 6200af702c87105d5b00d8ac5f5fa2c6d8f796aa974dbe2d15dcd95379ba1fa7 +F src/vdbesort.c a3be032cc3fee0e3af31773af4a7a6f931b7230a34f53282ccf1d9a2a72343be F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 -F src/vtab.c 5a0b7193d586991b3db30e343d6b59959906bfe8658a6a0a85709b20ca50bb49 +F src/vtab.c 7b704a90515a239c6cdba6a66b1bb3a385e62326cceb5ecb05ec7a091d6b8515 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d +F src/wal.c dbc77159e6734c2d64343cb8624ad245d89dd79a5010750fce8118b3fa7be2e8 F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a -F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c 9f3f23efc45934e7b7ea6c0c1042420b73053e7c3264feef6faf9ce6fbd5df61 -F src/whereInt.h 2c6bae136a7c0be6ff75dc36950d1968c67d005c8e51d7a9d77cb996bb4843d9 -F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b -F src/whereexpr.c 05c283d26aa9c3f5d1bf13a5f6a573b43295b9db280eff18e26f97d7d7f119b4 -F src/window.c 064f251451c8e2a1c76b6269229d911a651e119c6a5f522b6eaebf8dc8714041 +F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d +F src/where.c 2005d0511e05e5f7b6fb3be514b44f264f23d45f3b0cc5e150c63e3006a003e5 +F src/whereInt.h 9157228db086f436a574589f8cc5749bd971e94017c552305ad9ec472ed2e098 +F src/wherecode.c ec8870d6fe79668dd12d7edc65ae9771828d6cdfe478348c8abd872a89fdbadd +F src/whereexpr.c 4b34be1434183e7bb8a05d4bf42bd53ea53021b0b060936fbd12062b4ff6b396 +F src/window.c f8ba2ee12a19b51d3ba42c16277c74185ee9215306bc0d5a03974ade8b5bc98f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -623,19 +629,19 @@ F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 12106f0748e8e9bfc1a8e6840e203e051eae06a26ed13fc9fd5db108a8d6db54 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13 -F test/alter.test 16ed8d2470193f34bc711e51506ff1211ebfab8025ca3b9510ff2aef139874cb +F test/alter.test 77f0092d137dd9470fc683b64ed92868e188462e713e52f48deae8902ea60b96 F test/alter2.test a966ccfcddf9ce0a4e0e6ff1aca9e6e7948e0e242cd7e43fc091948521807687 -F test/alter3.test 4d79934d812eaeacc6f22781a080f8cfe012fdc3 -F test/alter4.test 7e93a21fe131e1dfeb317e90056856f96b10381fc7fe3a05e765569a23400433 +F test/alter3.test 9351a9f0c59ff9dddecccaaa2f777ffee5369870c63d30d3a74add815254ec0f +F test/alter4.test 74b22251c5e9c48093cfc4921ed9c11b59df84634aeeb00e501773320beb8424 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 F test/alterauth2.test c0a1ddf5b93d93cb0d15ba7acaf0c5c6fb515bbe861ede75b2d3fabad33b6499 -F test/altercol.test 54374d2ba18af25bb24e23acf18a60270d4ec120b7ec0558078b59d5aa1a31ad +F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f117ddf F test/alterlegacy.test 82022721ce0de29cedc9a7af63bc9fcc078b0ee000f8283b4b6ea9c3eab2f44b F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b -F test/altertab.test b2004ac589207fed7e19877bc3f1ad65142be482f269c176ee407e3b4a65f1a0 -F test/altertab2.test 8883693952f6d7fb5f754dbf1d694ed780aa883027bef04cb1fb99a3b88c9272 -F test/altertab3.test c755ef31f8a61911331b46d71e43f6f3ef94af05c56314b168e47520355fa18e +F test/altertab.test bd61e5b73d495ec4707133db91b07f09d57e339d988de5ec5a76d34a2198e8f2 +F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b +F test/altertab3.test 155b8dc225ce484454a7fb4c8ba745680b6fa0fc3e08919cbbc19f9309d128ff F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f F test/analyze.test 547bb700f903107b38611b014ca645d6b5bb819f5210d7bf39c40802aafeb7d7 F test/analyze3.test 01f0b122e3e54ad2544f14f7cc7dcb4c2cb8753cad5e88c6b8d49615b3fd6a2b @@ -655,14 +661,14 @@ F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7 F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a F test/async5.test 383ab533fdb9f7ad228cc99ee66e1acb34cc0dc0 -F test/atof1.test ff0b0156fd705b67c506e1f2bfe9e26102bea9bd +F test/atof1.test 1ccfc96a6888566597b83d882c81b3c04258dc39317e8c1cec89ba481eaa2fba F test/atomic.test 065a453dde33c77ff586d91ccaa6ed419829d492dbb1a5694b8a09f3f9d7d061 F test/atomic2.test b6863b4aa552543874f80b42fb3063f1c8c2e3d8e56b6562f00a3cc347b5c1da F test/atrc.c ec92d56d8fbed9eb3e11aaf1ab98cf7dd59e69dae31f128013f1d97e54e7dfed F test/attach.test 21bce8681f780a8d631a5ec7ecd0d849bfe84611257b038ae4ffeccc609d8a4e F test/attach2.test 256bd240da1835fb8408dd59fb7ef71f8358c7a756c46662434d11d07ba3a0ce F test/attach3.test c59d92791070c59272e00183b7353eeb94915976 -F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c +F test/attach4.test aa05b1d8218b24eba5a7cccf4f224f514ba57ba705c9267f09d2bb63fed0eea1 F test/attachmalloc.test 12c4f028e570acf9e0a4b0b7fe6f536e21f3d5ebddcece423603d0569beaf438 F test/auth.test 2154625c05bc79f0e0ea72cb2358395a8041243caa0fd7ce7617d50da4331794 F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1 @@ -724,15 +730,15 @@ F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 F test/capi3c.test 54e2dc0c8fd7c34ad1590d1be6864397da2438c95a9f5aee2f8fbc60c112e44b F test/capi3d.test aba917805573a03deed961a21f07a5a84505ad0a616f7e3fc1508844a15bccc4 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe -F test/cast.test 3619f0c58c2e4b2a94aa86e75607e497d34ef40ab74418e71aef7b4ca5155895 +F test/cast.test 2906ccab6a3ebd147ffa63304b635be903ce58264110d0a0eb4fd9939422bb53 F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef -F test/check.test 4b57ecbbb300336382ca21ef983dfa70b291a70ae430690494d13f1629f45a38 +F test/check.test b21a76546c2115af2674280566a8eba577e72adfec330c3d9a8a466d41f8eb0d F test/checkfault.test da6cb3d50247169efcb20bdf57863a3ccfa1d27d9e55cd324f0680096970f014 F test/chunksize.test 427d87791743486cbf0c3b8c625002f3255cb3a89c6eba655a98923b1387b760 F test/close.test eccbad8ecd611d974cbf47278c3d4e5874faf02d811338d5d348af42d56d647c F test/closure01.test 9905883f1b171a4638f98fc764879f154e214a306d3d8daf412a15e7f3a9b1e0 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 -F test/collate1.test f9b653f515ef3324a0c4e3c6adbf136bb1903622af678d482a60c11c9c054e6c +F test/collate1.test 532b4992f78e91dd80c2e3c7bd944fada8cbe3d6c0ded0b20f7182b4dfca0006 F test/collate2.test 9aaa410a00734e48bcb27f3872617d6f69b2a621 F test/collate3.test 89defc49983ddfbf0a0555aca8c0521a676f56a5 F test/collate4.test c953715fb498b87163e3e73dd94356bff1f317bd @@ -745,9 +751,9 @@ F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6 F test/collateB.test 1e68906951b846570f29f20102ed91d29e634854ee47454d725f2151ecac0b95 F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1 F test/colname.test 87ad5458bb8709312dac0d6755fd30e8e4ca83298d0a9ef6e5c24277a3c3390e -F test/conflict.test c7cc007e2af151516ddf38f7412fe10d473a694f55e3df437e2c7b31c2590e8d +F test/conflict.test 58857e2533fb9f2e0358ea7cb191215657846be1dd9da3b3d6df3e750c02ae03 F test/conflict2.test bb0b94cf7196c64a3cbd815c66d3ee98c2fecd9c -F test/conflict3.test 56d18aedfa521a7ebffadb8254cfff10caf4e49cd8659cb54da39513aed478ba +F test/conflict3.test 81865d9599609aca394fb3b9cd5f561d4729ea5b176bece3644f6ecb540f88ac F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4 F test/corrupt.test d7cb0300e4a297147b6a05e92a1684bc8973635c3bcaa3d66e983c9cbdbf47a3 F test/corrupt2.test bb50042cf9a1f1023d73af325d47eb02a6bb11e3c52f8812644b220c5d4bca35 @@ -760,16 +766,16 @@ F test/corrupt8.test 2399dfe40d2c0c63af86706e30f3e6302a8d0516 F test/corrupt9.test 730a3db08d4ab9aa43392ea30d9c2b4879cbff85 F test/corruptA.test 112f4b2ae0b95ebf3ea63718642fb969a93acea557ace3a307234d19c245989b F test/corruptB.test 73a8d6c0b9833697ecf16b63e3c5c05c945b5dec -F test/corruptC.test 776f43eb7df750f6d00b8b59c36c3b690822b2880ddbd80d22bf44e9f66acf5c +F test/corruptC.test 74d4498fd25759618b393f1e9cde111de828b88c1848ab320f6c179fd52b5a60 F test/corruptD.test 33a37ce3ed56a20093ceee778cd2d7109c7085a59f3213d2baede11d952e8e50 -F test/corruptE.test 82ccf4f8f543fdbedd4aa42c709cb077f7374c62 +F test/corruptE.test 4143791f2dfb443aec5b7fabfa5821e6063eccc3b49b06f212c2f014715fd476 F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4 F test/corruptG.test adf79b669cbfd19e28c8191a610d083ae53a6d51 F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454 F test/corruptI.test a17bbf54fdde78d43cf3cc34b0057719fd4a173a3d824285b67dc5257c064c7b F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4 F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af -F test/corruptL.test dfad96373bf9264d73039315ea6013994b90bf6776847adc7ec06b6fad3c04b2 +F test/corruptL.test 4f28fbef85a6f27489542bb915ab7938dcd68f896e8f62a7d23de02b32489e5d F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067 F test/cost.test 51f4fcaae6e78ad5a57096831259ed6c760e2ac6876836e91c00030fad385b34 F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c @@ -793,7 +799,7 @@ F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8 F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373 -F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10 +F test/date2.test 5ef8265c71460cda6b1698bf18f4bb0ffb40ac08c5092f6afe84d398c2feb5be F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603 F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e F test/dbfuzz001.test 42aad1dcef6219fbee86a9b7d08832c9bbb2e41508f6f128ae91745927276292 @@ -808,12 +814,12 @@ F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab F test/delete4.test 6aa279f459f4aa792cc251435c3809415c1ecaf9f27dce91675e26f05b503db3 F test/delete_db.test 096d828493c7907f9ea11a7098ea6a0f73edba89406487d5d6cc2228dc4ab8b0 -F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240 -F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d -F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2 +F test/descidx1.test edc8adee58d491b06c7157c50364eaf1c3605c9c19f8093cb1ea2b6184f3ac13 +F test/descidx2.test a0ba347037ff3b811f4c6ceca5fd0f9d5d72e74e59f2d9de346a9d2f6ad78298 +F test/descidx3.test 953c831df7ea219c73826dfbf2f6ee02d95040725aa88ccb4fa43d1a1999b926 F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e -F test/distinct.test a1783b960ad8c15a77cd9f207be072898db1026c -F test/distinct2.test b854b442111bf362328981f55d39d0df13140383b112057f6e046e311f14e5c3 +F test/distinct.test 8b6c652f0b2d477f0830884736f2a1cd2e8f7fc10a04aa6d571a401fa13ed88b +F test/distinct2.test 11b0594c932098e969d084ba45ab81d5040f4d4e766db65d49146705a305ed98 F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 F test/e_blobbytes.test 439a945953b35cb6948a552edaec4dc31fd70a05 F test/e_blobclose.test 4b3c8c60c2171164d472059c73e9f3c1844bb66d @@ -824,7 +830,7 @@ F test/e_createtable.test 1c602347e73ab80b11b9fa083f47155861aaafcff8054aac9e0b76 F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 F test/e_dropview.test 21ce09c361227ddbc9819a5608ee2700c276bdd5 -F test/e_expr.test e6048fe3901241799c4315bdd625f39dae790ff089c454979ca85f03b644dc6f +F test/e_expr.test 328d2d7c84f8e53e942a13eac771b337bcdfcf4c3569324001868b5639f3c857 F test/e_fkey.test 2febb2084aef9b0186782421c07bc9d377abf067c9cb4efd49d9647ae31f5afe F test/e_fts3.test 17ba7c373aba4d4f5696ba147ee23fd1a1ef70782af050e03e262ca187c5ee07 F test/e_insert.test f02f7f17852b2163732c6611d193f84fc67bc641fb4882c77a464076e5eba80e @@ -842,29 +848,29 @@ F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0 F test/e_walhook.test 01b494287ba9e60b70f6ebf3c6c62e0ffe01788e344a4846b08e5de0b344cb66 F test/emptytable.test a38110becbdfa6325cd65cb588dca658cd885f62 F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea -F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473 +F test/enc2.test 848bf05f15b011719f478dddb7b5e9aea35e39e457493cba4c4eef75d849a5ec F test/enc3.test 6807f7a7740a00361ca8d0ccd66bc60c8dc5f2b6 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 F test/eqp.test 84879b63e3110552bf8ce648a3507dc3ceb72109ecec83c2aef0db37a27f6382 F test/errmsg.test eae9f091eb39ce7e20305de45d8e5d115b68fa856fba4ea6757b6ca3705ff7f9 F test/eval.test a64c9105d6ff163df7cf09d6ac29cdad5922078c -F test/exclusive.test 1206b87e192497d78c7f35552e86a9d05421498da300fb1cce5ca5351ccde3c3 +F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650bf0747 F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac -F test/expr.test 7cb55e80aeb41d65fec968c08212505123063fea60bdc355d764d747670e9eea +F test/expr.test 26cd01e8485bc48c8aa6a1add598e9ce1e706b4eb4f3f554e0b0223022e8c2cf F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8 F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9 F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79 F test/fallocate.test 37a62e396a68eeede8f8d2ecf23573a80faceb630788d314d0a073d862616717 F test/filectrl.test 6e871c2d35dead1d9a88e176e8d2ca094fec6bb3 F test/filefmt.test f393e80c4b8d493b7a7f8f3809a8425bbf4292af1f5140f01cb1427798a2bbd4 -F test/filter1.test edd797ab2ef38de16064c9e3945efd941cba72d27e8f070c349501ff95d2727d +F test/filter1.test 8a6f047a000ef391db2ca17b6beecc0006f4e0f9ca8bbe272b2443c7316e66b1 F test/filter2.tcl 44e525497ce07382915f01bd29ffd0fa49dab3adb87253b5e5103ba8f93393e8 F test/filter2.test 485cf95d1f6d6ceee5632201ca52a71868599836f430cdee42e5f7f14666e30a F test/filterfault.test c08fb491d698e8df6c122c98f7db1c65ffcfcad2c1ab0e07fa8a5be1b34eaa8b F test/fkey1.test d11dbb8a93ead9b5c46ae5d02da016d61245d47662fb2d844c99214f6163f768 -F test/fkey2.test d35d1c81e7569bdd2b872e91750f7098117d2e8291369f70b7e3d50a0e523dc2 +F test/fkey2.test 65c86b11127c11f80c0f450b3480321e0f087edea3031b9daa1978e3c020c91b F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49 F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d F test/fkey5.test 24dd28eb3d9f1b5a174f47e9899ace5facb08373a4223593c8c631e6cf9f7d5a @@ -873,7 +879,7 @@ F test/fkey7.test 64fb28da03da5dfe3cdef5967aa7e832c2507bf7fb8f0780cacbca1f2338d0 F test/fkey8.test 48ef829d63f5f7b37aabd4df9363ac05f65539d1da8c4a44251631769d920579 F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749 F test/fordelete.test eb93a2f34137bb87bdab88fcab06c0bd92719aff -F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb +F test/format4.test eeae341953db8b6bda7f549044797c3278a6cc345d11ada81471671b654f8ef4 F test/fts-9fd058691.test 78b887e30ae6816df0e1fed6259de4b5a64ad33c F test/fts1a.test 46090311f85da51bb33bd5ce84f7948359c6d8d7 F test/fts1b.test 5d8a01aefbecc8b7442b36c94c05eb7a845462d5 @@ -926,20 +932,20 @@ F test/fts3al.test 07d64326e79bbdbab20ee87fc3328fbf01641c9f F test/fts3am.test 218aa6ba0dfc50c7c16b2022aac5c6be593d08d8 F test/fts3an.test a49ccadc07a2f7d646ec1b81bc09da2d85a85b18 F test/fts3ao.test 266989148fec6d9f1bb6c5382f7aa3dcea0e9cd444576e28dd2b9287ac7dd220 -F test/fts3atoken.test bef8a163490098a6b8a6ec5f5407269a3a15b9902c0fcf5e962825a81675b3a0 -F test/fts3auto.test 19097050a3ca7ab7a43b2be967cb3dfd8ddf841dfdc4eac88deb172ad2f209f2 +F test/fts3atoken.test dc2078ce464914efe3a8dfc545dd034a0fc14f2ab425c240471d5a5f1c721400 +F test/fts3auto.test 649aa4c198d7acc5cd6355e19ee073d051c40d9e88a43fc3d88af46bdf3e99d5 F test/fts3aux1.test 7a170e172afdbceb67f5baa05941fd4fbf56af42f61daa3d140f4b4bf4cb68f6 F test/fts3aux2.test 2459e7fa3e22734aed237d1e2ae192f5541c4d8b218956ad2d90754977bf907f F test/fts3b.test c15c4a9d04e210d0be67e54ce6a87b927168fbf9c1e3faec8c1a732c366fd491 F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958 F test/fts3comp1.test a0f5b16a2df44dd0b15751787130af2183167c0c F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f5a76b -F test/fts3corrupt.test 46b9ddda7f6588fd5a5b1f4bb4fc0618dc45010e7dddb8a3a188baf3197177ae +F test/fts3corrupt.test ce7f7b5eaeee5f1804584d061b978d85e64abf2af9adaa7577589fac6f7eae01 F test/fts3corrupt2.test bf55c3fa0b0dc8ea1c0fe5543623bd27714585da6a129038fd6999fe3b0d25f3 F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f -F test/fts3corrupt4.test 545c50e70d1fe922b6efef12019a92829832f52993c5421086489ce72bde2251 +F test/fts3corrupt4.test e407c7b4f4cd3335080833aff3a8855d520e531b79f84dcc77be4623af2342d4 F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5 -F test/fts3cov.test cb932743da52a1c79a1ab8983e26c8121cf02263d6ff16e1f642e6f9b8348338 +F test/fts3cov.test 7eacdbefd756cfa4dc2241974e3db2834e9b372ca215880e00032222f32194cf F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f F test/fts3defer.test f4c20e4c7153d20a98ee49ee5f3faef624fefc9a067f8d8d629db380c4d9f1de F test/fts3defer2.test 3da52ca2114e300e9971eee2f0cc1a2e5f27e6a9ee67957d49e63e41fdfcc0e7 @@ -958,7 +964,7 @@ F test/fts3fuzz001.test e3c7b0ce9b04cc02281dcc96812a277f02df03cd7dc082055d87e11e F test/fts3join.test 949b4f5ae3ae9cc2423cb865d711e32476bdb205ab2be923fdf48246e4a44166 F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6 F test/fts3matchinfo.test aa66cc50615578b30f6df9984819ae5b702511cf8a94251ec7c594096a703a4a -F test/fts3misc.test 0b20083efab36a42804bf8017a003f72f963c46163403dae7256493367d2f9d3 +F test/fts3misc.test c47d2c1ea1351c51c32c688545b02c8180a3f22156d1aedc206a8c09b9d95905 F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905 F test/fts3offsets.test b85fd382abdc78ebce721d8117bd552dfb75094c F test/fts3prefix.test fa794eaab0bdae466494947b0b153d7844478ab2 @@ -967,21 +973,21 @@ F test/fts3query.test ca033ff2ebcc22c69d89032fb0bc1850997d31e7e60ecd26440796ba16 F test/fts3rank.test cd99bc83a3c923c8d52afd90d86979cf05fc41849f892faeac3988055ef37b99 F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0 F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e -F test/fts3snippet.test 430bb5ace2b31ccd99de4d71775d956da832c114c4b3e39589748f114458647c +F test/fts3snippet.test d9b9f4b717584040fb56df1dacab53acd474958e9c1d00b073d10726695cea0c F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca F test/fts3tok1.test a663f4cac22a9505400bc22aacb818d7055240409c28729669ea7d4cc2120d15 F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d F test/fts3varint.test 0b84a3fd4eba8a39f3687523804d18f3b322e6d4539a55bf342079c3614f2ada -F test/fts4aa.test 10aac8e9d62c7357590acfabe3fad01e9a9ce1cb +F test/fts4aa.test 4338ea7a67f7e19269bf6e6fb4a291352aa32296e7daed87f9823d57016a1ef7 F test/fts4check.test 6259f856604445d7b684c9b306b2efb6346834c3f50e8fc4a59a2ca6d5319ad0 -F test/fts4content.test 1518195a9f92b711d94419f76409a31cc78755854fb0abb1da2b74b9e0cf843e +F test/fts4content.test 73bbb123420d2c46ef2fb3b24761e9acdb78b0877179d3a5d7d57aada08066f6 F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01 F test/fts4growth.test 289833c34ad45a5e6e6133b53b6a71647231fb89d36ddcb8d9c87211b6721d7f F test/fts4growth2.test 13ad4e76451af6e6906c95cdc725d01b00044269 F test/fts4incr.test 4e353a0bd886ea984e56fce9e77724fc923b8d0d -F test/fts4langid.test 2168ba330af34f8a1c8832de0aab4c4b6fa195a16419c9c0c8aad59ceb6ff714 +F test/fts4langid.test 89e623218935507bca69d076ca254a7a8969dfc681c282b6374feaea8c7de784 F test/fts4lastrowid.test 185835895948d5325c7710649824042373b2203149abe8024a9319d25234dfd7 -F test/fts4merge.test 1096e30b58ad616bd502141bfe5bfe4c3a518df89e958d41a5ed1ce322369b9c +F test/fts4merge.test e2b2ec21e287d54ec09824ccfb41e66896eeca568fc818ba0e0eb2efd94c35d2 F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891 F test/fts4merge3.test 8d9ccb4a3d41c4c617a149d6c4b13ad02de797d0 F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b @@ -994,7 +1000,7 @@ F test/fts4rename.test 15fd9985c2bce6dea20da2245b22029ec89bd4710ed317c4c53abbe3c F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f757380429 F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d -F test/func.test 0889128141b99b38aa9ce78445acfc4c1f9fbe9aa4f51d4c6aff88ae43cf125b +F test/func.test b7f1a706d1bb8de103a24bd0c30c9e3dc3eedf0df24aabc54b0a4f6e08742622 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func3.test 2bb0f31ab7baaed690b962a88544d7be6b34fa389364bc36a44e441ed3e3f1e6 F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f @@ -1005,21 +1011,22 @@ F test/fuzz.test 96083052bf5765e4518c1ba686ce2bab785670d1 F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c31 F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634 -F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b +F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830 F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2 -F test/fuzzcheck.c 3ad76298a80cda31d270dc5e4f31194fa38d507d3e9b3f355cf1c283895cd5a5 -F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664 +F test/fuzzcheck.c a9746aa49843827f960bc875cc70e04b0cfcd3e10e6676e3abc402ad190e165f +F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e42ed2 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 F test/fuzzdata7.db e7a86fd83dda151d160445d542e32e5c6019c541b3a74c2a525b6ac640639711 -F test/fuzzdata8.db c75b0fd1d28c262f9c3a9428393ff9c420ea5bdbe0b33c557a971915a94bab71 +F test/fuzzdata8.db 8bd41f8e1b9c61af011bf5cf16a85fb7f718fdd3348e476b78ba36adab872653 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c +F test/gencol1.test e89eafdf03245e2609ddf6e9b0add37a17ce229095836c409131764c3a5282a5 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/having.test e4098a4b8962f9596035c3b87a8928a10648acc509f1bb8d6f96413bbf79a1b3 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 @@ -1032,7 +1039,7 @@ F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 F test/in.test 3e9bd58597a444123a40a9ac94cae0fec8897e17e9f519b02fc370bcf5ba5175 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 -F test/in4.test 0f77b0ff371549e6a119d0356be10bdba72258162e9701e83527a560482f5e98 +F test/in4.test 65460600d48933adba4283c6ebd089aae173d16136ab9d01f74c89089090c5a5 F test/in5.test b32ce7f4a93f44c5dee94af16886d922cc16ebe33c8e1765c73d4049d0f4b40f F test/in6.test 62d943a02f722948f4410ee0b53c3cb39acd7c41afb083df8d7004238fe90a20 F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822 @@ -1051,23 +1058,23 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407 F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7 -F test/index6.test 4d1dd3cab97fba2ddf30bb70afc82eab35bd6e61788b3ac941e55263f81ef7e9 +F test/index6.test f172653b35b20233e59200e8b92a76db61bf7285437bf777b93b306ba26a47e7 F test/index7.test 1d764c0cca45f5a76150b08e127ccc8d52492cfa788b5fafed4be784a351b020 F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 F test/indexedby.test a52c8c6abfae4fbfb51d99440de4ca1840dbacc606b05e29328a2a8ba7cd914e -F test/indexexpr1.test c26c8b352311c1deb30642cd0379e5cb94e416c7e9e0885e92d9e01554df2db9 -F test/indexexpr2.test b580f378423bca443ffab47ada677203cfcf8a60f48a8aa20065f27c8f7739b5 +F test/indexexpr1.test 284e119999d132cc8bf37735a928c9859b28e8e295d02b7a6a4f93977c7f9ba5 +F test/indexexpr2.test dba11dbb0a58fcba4cd694f46b4004976123b81b0501f525d43c9be59f0207b1 F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811 F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 -F test/insert.test 72004f6a900a25bd3f1ce9a72e73d02749644666a8ce6d6d2dba061137e5aa63 +F test/insert.test 4e3f0de67aac3c5be1f4aaedbcea11638f1b5cdc9a3115be14d19aa9db7623c6 F test/insert2.test 4d14b8f1b810a41995f6286b64a6943215d52208 F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30 -F test/insert4.test 7802ada6ba8738661b9f6c0e26858d3375b40cc7180289fd350644cd7a08fec9 +F test/insert4.test fb9e0f752c75f453555990250b449f6d123ae6a3ebf054d14e4470de4498dce3 F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/insertfault.test ac63d14ea3b49c573673a572f4014b9117383a03e497c58f308b5c776e4a7f74 F test/instr.test 107df2b9b74a4b59315916b575590a08f2a714de0754abe541f10a0971d0a2a4 -F test/instrfault.test 0f870b218ea17cd477bb19ed330eecdb460dd53a +F test/instrfault.test 95e28efade652e6d51ae11b377088fe523a581a07ec428009e152a4dd0e0f44c F test/intarray.test bb976b0b3df0ebb6a2eddfb61768280440e672beba5460ed49679ea984ccf440 F test/interrupt.test 16ea879ec728cb76414c148c5f24afd5d1f91054 F test/interrupt2.test e4408ca770a6feafbadb0801e54a0dcd1a8d108d @@ -1081,22 +1088,23 @@ F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b F test/istrue.test 75327829744e65cc8700e69340b8e6c192e10e39dfae7ccb0e970d3c4f49090a -F test/join.test 7610c1818f8921618279ab633fc03c93d54f6c8fb9e9e7e96b252319ece346d4 -F test/join2.test 10f7047e723ebd68b2f47189be8eed20451a6f665d8bf46f1774c640d1062417 +F test/join.test bca044589e94bb466e4c1e91fb6fecdc3f3326ca6b3f590f555f1958156eb321 +F test/join2.test 659bc6193f5c3fe20fa444dd2c91713db8c33e376b098b860644e175e87b8dbc F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 3a96dc62f0b45402d7207e22d1993fe0c2fce1c57644a11439891dd62b990eb7 F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 -F test/journal3.test 939a3578396dffa0cdaa9b2685088c5a1a644db90d61aca08bd7e19d33932c00 +F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e F test/jrnlmode.test 9b5bc01dac22223cb60ec2d5f97acf568d73820794386de5634dcadbea9e1946 F test/jrnlmode2.test 8759a1d4657c064637f8b079592651530db738419e1d649c6df7048cd724363d F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa -F test/json101.test 8f8977b00ba02f9a26c1d1f52f29f540f6d5eb162cbd5eb78bb805366d4ab26d +F test/json101.test bb71538005f2d9e18620bdd3b76839a93ca0be61903eb8d751a64e78cf99b8fb F test/json102.test eeb54efa221e50b74a2d6fb9259963b48d7414dca3ce2fdfdeed45cb28487bc1 F test/json103.test aff6b7a4c17d5a20b487a7bc1a274bfdc63b829413bdfb83bedac42ec7f67e3b F test/json104.test 317f4ec4b2d87afbba4d2460cf5be297aea76f2285eb618d276dbcd40a50950f +F test/json105.test 45f7d6a9a54c85f8a9589b68d3e7a1f42d02f2359911a8cdbad1f9988f571173 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff F test/kvtest.c 94da54bb66aae7a54e47cf7e4ea4acecc0f217560f79ad3abfcc0361d6d557ba F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 @@ -1152,7 +1160,7 @@ F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 F test/memsubsys1.test 9e7555a22173b8f1c96c281ce289b338fcba2abe8b157f8798ca195bbf1d347e F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08 F test/minmax.test 6751e87b409fe11b02e70a306d846fa544e25a41 -F test/minmax2.test dae92964ac87c1d2ef978c582e81a95e11c00f1cbef68980bfb2abaf10315063 +F test/minmax2.test 1edf66901ddfab26ae1e04165e8da834c8d3284e2b20aefb26b80ef217962eab F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354 F test/minmax4.test 272ca395257f05937dc96441c9dde4bc9fbf116a8d4fa02baeb0d13d50e36c87 F test/misc1.test 7ce84b25df9872e7d7878613a96815d2ba5bc974ac4e15a50118dde8f3917599 @@ -1180,13 +1188,13 @@ F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test 437d40e6d0778b050d7750726c0cbd2c9936b81962926e8f8c48ca698f00f4d1 F test/nockpt.test 8c43b25af63b0bd620cf1b003529e37b6f1dc53bd22690e96a1bd73f78dde53a F test/nolock.test f196cf8b8fbea4e2ca345140a2b3f3b0da45c76e -F test/normalize.test 422027884ffb67ebba32bb78487c67cf67643496d19c077b07044bdba071a3f6 +F test/normalize.test f23b6c5926c59548635fcf39678ac613e726121e073dd902a3062fbb83903b72 F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934 F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18 F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3 -F test/nulls1.test 725fb4d99db2ddcce59ca6bf847cd92db8f1af861785918892f84ac3bcd4223d +F test/nulls1.test fe4153fd59a3786b4b9f3663a3e65a3aa43a318c7b4d7dcb3f6c3ed5652c9095 F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823 F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2 @@ -1194,7 +1202,7 @@ F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394 F test/optfuzz-db01.c a0c256905c8ac79f9a5de2f374a3d9f757bef0dca2a238dc7c10cc8a38031834 F test/optfuzz-db01.txt 21f6bdeadc701cf11528276e2a55c70bfcb846ba42df327f979bd9e7b6ce7041 F test/optfuzz.c 50e330304eb1992e15ddd11f3daaad9bcc0d9aaad09cb2bcc77f9515df2e88b1 -F test/orderby1.test e4501f54721f804ca56922e253403ac6775f88e9f07569994ce99212b3ca5b10 +F test/orderby1.test 6bf0ce45cbfb1cf4779dd418ac5e8cf66abfa04de2c1d2edf1e0e85f1520d8f3 F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04 F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99 F test/orderby4.test 4d39bfbaaa3ae64d026ca2ff166353d2edca4ba4 @@ -1205,7 +1213,7 @@ F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3 F test/orderbyA.test df608e59efc2ef50c1eddf1a773b272de3252e9401bfec86d04b52fd973866d5 F test/oserror.test 1fc9746b83d778e70d115049747ba19c7fba154afce7cc165b09feb6ca6abbc5 -F test/ossfuzz.c 18af635fa73d12a109b305faca727a734c1fa28a421b161d9d15c5a84a4998a2 +F test/ossfuzz.c 9636dad2092a05a32110df0ca06713038dd0c43dd89a77dabe4b8b0d71096715 F test/ossshell.c f125c5bd16e537a2549aa579b328dd1c59905e7ab1338dfc210e755bb7b69f17 F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f F test/pager1.test 1e9ee778bdeaf4f7f09997d029cdaca6a42dfc2092edafe4f5e590acbf1eab13 @@ -1225,9 +1233,9 @@ F test/permutations.test 8587800fe1a0eb01456a3f4500b821e54e3347e78acf11dbf05f499 F test/pg_common.tcl 222a1bad1c41c308fa366313cd7b51b3be7e9b21c8736a421b974ac941693b54 F test/pragma.test 59becdfd720b80d463ab750f69f7118fde10dfd556aa5d554f3bf6b7e5ea7533 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f -F test/pragma3.test 8300aa9c63cff1027006ca34bf413a148abbd6dcd471fa9a1ded322fe18c0df9 -F test/pragma4.test 1cb4b32f1a304ed9e291d7c4d49c91c2c8dc1b9450e6d2c1198b2cc895d40d77 -F test/pragma5.test 2be6a44c91e8585ccb4c71c5f221ccebe0692a49557215a912916ed391188959 +F test/pragma3.test 92a46bbea12322dd94a404f49edcfbfc913a2c98115f0d030a7459bb4712ef31 +F test/pragma4.test 10c624e45a83c0096a82a7579a5ff658542391d3b77355192da6572c8c17c00b +F test/pragma5.test 7b33fc43e2e41abf17f35fb73f71b49671a380ea92a6c94b6ce530a25f8d9102 F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8 F test/prefixes.test b524a1c44bffec225b9aec98bd728480352aa8532ac4c15771fb85e8beef65d9 F test/printf.test 0300699733e53101b2ce48800518427249edd4053bb50fa0621c6607482f0fdb @@ -1260,7 +1268,7 @@ F test/round1.test 768018b04522ca420b1aba8a24bd76091d269f3bce3902af3ec6ebcee41ab F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test bfbd7b97d9267660be3c8f28507c4ed7f205196b8877c0db42df347c2e8845e3 -F test/rowvalue.test a3e729d5c1f32da03bba15af1e3128218d2ba3c40d4f4ed5fa0497a713df68ea +F test/rowvalue.test 8964f95b253d3b5cc8dc1cfd0cdb7529bce3ecc6b6259e23c5f829f80f4d51cd F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256 F test/rowvalue4.test 02e35f7762371c2f57ebd856aa056eac56cb27ef7715a0bb31eac1895a745356 @@ -1270,6 +1278,7 @@ F test/rowvalue7.test c1cbdbf407029db01f87764097c6ac02a1c5a37efd2776eff32a9cdfdf F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0 F test/rowvalue9.test d8dd2c6ecac432dadaa79e41dc2434f007be1b6b F test/rowvaluefault.test 7cd9ccc6c2fbdd881672984087aad0491bb75504 +F test/rowvaluevtab.test cd9747bb3f308086944c07968f547ad6b05022e698d80b9ffbdfe09ce0b8da6f F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 F test/savepoint.test 1f8a6b1aea9a0d05837adc463d4bf47bd9d0f1c842f1c2a9caccd639baf34bf9 @@ -1289,7 +1298,7 @@ F test/schema6.test e4bd1f23d368695eb9e7b51ef6e02ca0642ea2ab4a52579959826b5e7dce F test/schemafault.test 1936bceca55ac82c5efbcc9fc91a1933e45c8d1e1d106b9a7e56c972a5a2a51e F test/securedel.test 2f70b2449186a1921bd01ec9da407fbfa98c3a7a5521854c300c194b2ff09384 F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5 -F test/select1.test 703154cbf66d0a9fbbd5b771dc3d2c4d3700121d133d695958d4a9c5a33251e8 +F test/select1.test 009a6d8eacd9684d046302b8d13b50846a87e39d6f08e92178aa13e95ea29a2d F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 F test/select3.test 3905450067c28766bc83ee397f6d87342de868baa60f2bcfd00f286dfbd62cb9 F test/select4.test 5389d9895968d1196c457d59b3ee6515d771d328 @@ -1334,7 +1343,7 @@ F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 F test/shrink.test 1b4330b1fd9e818c04726d45cb28db73087535ce F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329 -F test/skipscan1.test 2a64ca7b3e6246bb86b47c9051bfd324603b1b60675fe606513535267713e080 +F test/skipscan1.test ed524bc86f27646b3a297f45d6557b55db338977b6838f8064b196b35848b31b F test/skipscan2.test 3eb703ce794f139e7b83567911046298bcde29606116727f9b700ce34f559d2d F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 @@ -1370,7 +1379,7 @@ F test/spellfix4.test 51c7c26514ade169855c66bcf130bd5acfb4d7fd090cc624645ab275ae F test/sqldiff1.test 28cd737cf1b0078b1ec1bbf425e674c47785835e F test/sqllimits1.test 264f4b0f941800ba139d25e33ee919c5d95fea06dfbe8ac291d6811a30984ca5 F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a -F test/stat.test f8f1279ffffabe6df825723af18cc6e0ae70a893 +F test/stat.test 423257dc36e5865fb9dd1d9051ac985763b6fba1daec134932f37772d5ed1e64 F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1 F test/stmt.test 54ed2cc0764bf3e48a058331813c3dbd19fc1d0827c3d8369914a5d8f564ec75 F test/stmtvtab1.test 6873dfb24f8e79cbb5b799b95c2e4349060eb7a3b811982749a84b359468e2d5 @@ -1385,16 +1394,17 @@ F test/swarmvtab.test 9a3fd5ab3e9b3c976ad1b3d7646aab725114f2ac26b59395d0778b33ba F test/swarmvtab2.test c948cb2fdfc5b01d85e8f6d6504854202dc1a0782ab2a0ed61538f27cbd0aa5c F test/swarmvtab3.test 247aa38b6ebd2b99db2075847ae47e789ac34f1c2ab5c720dfcffd990004c544 F test/swarmvtabfault.test 8a67a9f27c61073a47990829e92bc0c64420a807cb642b15a25f6c788210ed95 -F test/symlink.test 0d816670325536b8973ec08d32b45136baddb80bd45fd178e0ce7a9e8153f3e7 +F test/symlink.test 72b22238d4405ba34df8e60b335d290a3b1129fd5c260835c944c1e4e77288a9 +F test/symlink2.test 9531f475a53d8781c4f81373f87faf2e2aff4f5fb2102ec6386e0c827916a670 F test/sync.test 89539f4973c010eda5638407e71ca7fddbcd8e0594f4c9980229f804d4333092 F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef2039 F test/syscall.test a39d9a36f852ae6e4800f861bc2f2e83f68bbc2112d9399931ecfadeabd2d69d F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 -F test/tabfunc01.test 20e98ffe55f35d8d33fd834ca8bf9d4b637e560af8fcd00464b4154d90a4db45 +F test/tabfunc01.test 5ca6d004157a3e886a55a9387b960cc0db41acd88753eb597ff409ec6cfb1be0 F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132 F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 -F test/tclsqlite.test f9acb83122be0a7c4997ab7f17742507874dced95144c20217c2428553f110bb +F test/tclsqlite.test 79a473f5797e317c08f2c4f8192edb3eea6a67329b1087453328b66a7cb31070 F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08 F test/tempdb2.test 353864e96fd3ae2f70773d0ffbf8b1fe48589b02c2ec05013b540879410c3440 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 @@ -1402,7 +1412,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test d2940417496e2b9548e01d09990763fbe88c316504033256d51493e1f1a5ce6a F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc -F test/tester.tcl 64ac253a411db1af7649438f674213a45876ca70609570310a8652edf23e5d77 +F test/tester.tcl abba168acd7f01dbfa3ffdbf402d151eb97e8a824d9208e845ab34c194441483 F test/thread001.test b61a29dd87cf669f5f6ac96124a7c97d71b0c80d9012746072055877055cf9ef F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1417,7 +1427,7 @@ F test/threadtest3.c 38a612ea62854349ed66372f330a40d73c5cf956 F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925 F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90 F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c -F test/tkt-18458b1a.test c543c4b8e8c7c2200579a635e72c15bc374a92d44eddb1d588d4fdeca9cca532 +F test/tkt-18458b1a.test 6a62cb1ee50fa3c620da59e3a6f531eb38fceaf7e2166203816b724524e6f1d6 F test/tkt-26ff0c2d1e.test c15bec890c4d226c0da2f35ff30f9e84c169cfef90e73a8cb5cec11d723dfa96 F test/tkt-2a5629202f.test 0521bd25658428baa26665aa53ffed9367d33af2 F test/tkt-2d1a5c67d.test be1326f3061caec85085f4c9ee4490561ca037c0 @@ -1453,7 +1463,7 @@ F test/tkt-9a8b09f8e6.test b2ef151d0984b2ebf237760dbeaa50724e5a0667 F test/tkt-9d68c883.test 16f7cb96781ba579bc2e19bb14b4ad609d9774b6 F test/tkt-9f2eb3abac.test cb6123ac695a08b4454c3792fbe85108f67fabf8 F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4 -F test/tkt-a7debbe0.test 65a647034e3416d068f81e7d86fffc07edfae371c70b8761714edb56ec1c7521 +F test/tkt-a7debbe0.test e295fa83cd4416a8ca37b354eb5fadefc5e81fb55253db538d35261fe9c95067 F test/tkt-a8a0d2996a.test 002e1cde8fc30c39611b52cf981c88200b858765748556822da72e0d32fac73e F test/tkt-b1d3a2e531.test 8f7576e41ca179289ee1a8fee28386fd8e4b0550 F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0 @@ -1517,7 +1527,7 @@ F test/tkt3080.test 1bca7579260920a66b4dd7e196e807c0f25ff804 F test/tkt3093.test fbdbc5b4969244ad11f540759003e361fcaf391f F test/tkt3121.test 536df66a02838c26a12fe98639354ca1290ca68b F test/tkt3201.test f1500ccecc0d578dc4cde7d3242008297c4d59b3 -F test/tkt3292.test 962465a0984a3b8c757efe59c2c59144871ee1dd +F test/tkt3292.test 7bad4423cf5eb075dbb58511d66d46fe816744754c9f0050ae60157f71a4fca7 F test/tkt3298.test 20fd8773b825cb602e033aa04f8602e1ebdcd93c F test/tkt3334.test 9756631e3c4aa3c416362c279e3c0953a83b7ca8274cb81a13264bb56296d8b0 F test/tkt3346.test 6f67c3ed7db94dfc5df4f5f0b63809a1f611e01a @@ -1568,8 +1578,8 @@ F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94 F test/transitive1.test 293300f46916569f08875cdb2fe2134be2c27677 -F test/trigger1.test 6be279c9d48b25320eab68c30fd5268ab787955679f4c584128f71800247fb50 -F test/trigger2.test 5cd7d69a7ba1143ee045e4ae2963ff32ae4c87a6 +F test/trigger1.test d30cd09ae8ac365a088f09daba583cc5c0b8fc7d4e1d70809d0b4be3bf6ae2ab +F test/trigger2.test d15da46f7012832faf3e0c536b47024409d5fb1722d2bb77e29c06d96d704bb1 F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945 F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359 F test/trigger5.test 619391a3e9fc194081d22cefd830d811e7badf83 @@ -1583,7 +1593,8 @@ F test/triggerC.test 29f5a28d0fe39e6e2c01f6e1f53f08c0955170ae10a63ad023e33cb0a16 F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650 F test/triggerE.test ede2e4bce4ba802337bd69d39447fa04a938e06d84a8bfc53c76850fc36ed86d F test/triggerF.test 5d76f0a8c428ff87a4d5ed52da06f6096a2c787a1e21b846111dfac4123de3ad -F test/triggerG.test d5caeef6144ede2426dd13211fd72248241ff2ebc68e12a4c0bf30f5faa21499 +F test/triggerG.test 2b816093c91ba73c733cfa8aedcc210ad819d72a98b1da30768a3c56505233e9 +F test/trustschema1.test 4e970aef0bfe0cee139703cc7209d0e0f07725d999b180ba50770f49edef1494 F test/tt3_checkpoint.c 9e75cf7c1c364f52e1c47fd0f14c4340a9db0fe1 F test/tt3_index.c 39eec10a35f57672225be4d182862152896dee4a F test/tt3_lookaside1.c 0377e202c3c2a50d688cb65ba203afeda6fafeb9 @@ -1598,9 +1609,9 @@ F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264 F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2 F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97 F test/unordered.test ffeea7747d5ba962a8009a20b7e53d68cbae05b063604c68702c5998eb50c981 -F test/update.test 1148de8d913e9817717990603aadeca07aab9ddbb10a30f167cbfd8d3a3ccb60 +F test/update.test e906ca7cb1dc6f52af1ea243e08f727edfa79f924c2691f2f9e72481f847310d F test/update2.test 67455bc61fcbcf96923c45b3bc4f87bc72be7d67575ad35f134906148c7b06d3 -F test/upsert1.test 9b115320149e6d72db64511a373c522746c2a2156efdbdb52add33504f66c989 +F test/upsert1.test 88f9e258c6a0eeeb85937b08831e8daad440ba41f125af48439e9d33f266fb18 F test/upsert2.test 9c3cdbb1a890227f6504ce4b0e3de68f4cdfa16bb21d8641208a9239896c5a09 F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3179c F test/upsert4.test 25d2a1da92f149331ae0c51ca6e3eee78189577585eab92de149900d62994fa5 @@ -1675,7 +1686,7 @@ F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cf F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417 F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747 -F test/walvfs.test f1accd66c876e3a0f6b4bef5b18d13411062d0ff0a0016e32bb41570474e99fc +F test/walvfs.test ca81c9f427e0e5434076dfa948fd1d8e6d5ddd192b2fb6991635d81da5f3f5d4 F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec F test/wapptest.tcl 3cca775aede0591756a1fc0da55bbb3715d8c363873fd2cfdd4d555b0a4af57d x F test/where.test 19c709c9f0f6ed12c23f909f6592aa55fba34269d5a2898537aa27a22b9ce650 @@ -1693,12 +1704,12 @@ F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6 F test/whereD.test 711d4df58d6d4fb9b3f5ce040b818564198be002 F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f F test/whereF.test 3d9412b1199d3e2bed34fcb76b4c48d0bf4df95d27e3f8dd27b6f8b4716d0d89 -F test/whereG.test 4cda56de49f0c7d9a4f2590a3ddc5f79a7f2a03d2229d0f5bb5d3981ce57f293 +F test/whereG.test c9378b285828754377ef47fbece7264018c0a3743e7eb686e89917bb9df10885 F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 F test/whereI.test a2874062140ed4aba9ffae76e6190a3df6fc73d1373fdfa8fd632945082a5364 F test/whereJ.test 88287550f6ee604422403b053455b1ad894eeaa5c35d348532dfa1439286cb9a F test/whereK.test f8e3cf26a8513ecc7f514f54df9f0572c046c42b -F test/whereL.test 0a19fc44cd1122040f56c934f1b14d0ca85bde28f270268a428dd9796ea0634c +F test/whereL.test 976f100f412ce2f39bf923eb57794cdc39fc0a3fec8fab025d51706a7cc4845b F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864 F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3 F test/wherelimit.test 592081800806d297dd7449b1030c863d2883d6d42901837ccd2e5a9bd962edb0 @@ -1707,9 +1718,9 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2 F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc -F test/window1.test 453bb9dcb1b447eddbb4777c97620f02543a4375359723b7372ff09dcf847045 -F test/window2.tcl 66db96fd9fd202bc31ee7f8ce7904cb469564864cff3f74e009bfef8102333f4 -F test/window2.test af2a001ded703bb8f2474fb0edfef170d5aba00f5c1f2aa9f65935b5da13df90 +F test/window1.test cec56b9a0a2e7ca4bd63b30590c7b049dce9acfd87478e2597e13b67152bd821 +F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476 +F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03 F test/window3.test e9959a993c8a71e96433be8daaa1827d78b8921e4f12debd7bdbeb3c856ef3cb F test/window4.tcl d732df0e81beedc0ba8a563ade68611d322d27303ad0c0c8e4444107c39e84ec @@ -1720,20 +1731,20 @@ F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d761 F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd F test/window8.tcl f2711aa3571e4e6b0dad98db8d95fd6cb8d9db0c92bbdf535f153b07606a1ce2 F test/window8.test c4331b27a6f66d69fa8f8bab10cc731db1a81d293ae108a68f7c3487fa94e65b -F test/window9.test ae8be07be05a5a4c8ead1818ac5d45f278b8dd456e589d67f24270b0070c35a0 +F test/window9.test b63f6f74d730547e63e78946f951f5d1a7d4e99f91f6d5906305469043d92a15 F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be F test/windowB.test 7a983ea1cc1cf72be7f378e4b32f6cb2d73014c5cd8b25aaee825164cd4269e5 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b -F test/windowfault.test a90b397837209f15e54afa62e8be39b2759a0101fae04e05a08bcc50e243a452 -F test/with1.test d32792084dcb5f6c047d77bb8a032822ef9fe050ade07d0aeffa37753a05e3c9 +F test/windowfault.test 8e3b69abe0eea9595ba3940afd9c63644e11966ed8815734b67f1479a8e9891a +F test/with1.test 584580a5ae79868a91873863f8cb2d00040006dc1e4c332ef1d8642f2815dc6e F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab -F test/with3.test b5f1372097690c6ef84db2f13fc7e64a88c7263c3f88493605f90597e8a68d45 +F test/with3.test 13b3336739da648a9e4dfa11bb04e73a920c97620041007c5f75d5d14084c346 F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205 F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64 -F test/without_rowid1.test 0abe18762b74714580c1d4d00a8e540e58966d3e46aae41ddb1a1d2c88c9277d +F test/without_rowid1.test 9cfb83705c506e3849fa7efc88a3c9a15f9a50bf9b1516b41757a7cef9bba8c3 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 -F test/without_rowid3.test ea4b59dd1b0d7f5f5e4b7cca978cdb905752a9d7c57dc4344a591dba765a3691 +F test/without_rowid3.test 392e6e12f275d11d931a8bc4580e573342f391639c87ffb631010a7b3cedfdc0 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a F test/without_rowid5.test 89b1c587bd92a0590e440da33e7666bf4891572a F test/without_rowid6.test 8463b20098e9f75a501a9f17dfb42fffc79068eac0b2775fe56ef2281d2df45e @@ -1742,17 +1753,17 @@ F test/wordcount.c d721a4b6fae93e6e33449700bce1686bc23257c27425bc3ef1599dc912ade F test/writecrash.test f1da7f7adfe8d7f09ea79b42e5ca6dcc41102f27f8e334ad71539501ddd910cc F test/zeroblob.test 07a5b11ab591d1f26c626945fb7f228f68b993533b2ada77273edf6ee29db174 F test/zerodamage.test 9c41628db7e8d9e8a0181e59ea5f189df311a9f6ce99cc376dc461f66db6f8dc -F test/zipfile.test b3b558639f7a103e095713ad0f57fec1fce1b7d60c8054df5789b98f7547a395 +F test/zipfile.test 429cb81c518487fa1b644b6b04b6e9af704a4fa767bd1a110204c5f03b2e8616 F test/zipfile2.test 9903388a602a3834189857a985106ff95c3bba6a3969e0134127df991889db5d F test/zipfilefault.test 44d4d7a7f7cca7521d569d7f71026b241d65a6b1757aa409c1a168827edbbc2c -F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 +F tool/GetFile.cs 47852aa0d806fe47ed1ac5138bdce7f000fe87aaa7f28107d0cb1e26682aeb44 F tool/GetTclKit.bat 8995df40c4209808b31f24de0b58f90930239a234f7591e3675d45bfbb990c5d F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 F tool/build-all-msvc.bat c12328d06c45fec8baada5949e3d5af54bf8c887 x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/cg_anno.tcl c1f875f5a4c9caca3d59937b16aff716f8b1883935f1b4c9ae23124705bc8099 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 -F tool/dbhash.c a06228aa21ebc4e6ea8daa486601d938499238a5 +F tool/dbhash.c 19560c9a2aa2b269b6a5108259b93d26d12f8f0877c31fe9f8f61dfbd219ba63 F tool/dbtotxt.c b2221864a20fb391c46bd31bc1fbdc4a96f5c8a89bef58f421eb9b9c36b1702c F tool/dbtotxt.md c9a57af8739957ef36d2cfad5c4b1443ff3688ed33e4901ee200c8b651f43f3c F tool/extract-sqlite3h.tcl 069ceab0cee26cba99952bfa08c0b23e35941c837acabe143f0c355d96c9e2eb x @@ -1765,8 +1776,8 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c 9ec344d29cbeb03fdc0fce668eedfb7495792170de933adf95cf8d6904a166ad F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f -F tool/lemon.c 61d5f0af1eff8f754b75ddca668c9897fd30759e389bfffb42ce9e4d38fd4746 -F tool/lempar.c eb2841e2a7fd484cf44b1f526b06e7ab0f216d2f41818bf9485e8f38e3d1db19 +F tool/lemon.c a361b85fa230560b783006ac002a6a8bad214c3b9d7fa48980aecc2b691ddcad +F tool/lempar.c e8899b28488f060d0ff931539ea6311b16b22dce068c086c788a06d5e8d01ab7 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1774,14 +1785,14 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/mkautoconfamal.sh 422fc365358a2e92876ffc62971a0ff28ed472fc8bcf9de0df921c736fdeca5e F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x F tool/mkctimec.tcl dd183b73ae1c28249669741c250525f0407e579a70482371668fd5f130d9feb3 -F tool/mkkeywordhash.c bc5bcc92ebcaf15345346be7cf2204b83ed649b5208234adb5e543c061209bbf -F tool/mkmsvcmin.tcl cad0c7b54d7dd92bc87d59f36d4cc4f070eb2e625f14159dc2f5c4204e6a13ea +F tool/mkkeywordhash.c 27ffc6f6e7e3ecbfc5bca1f1f11a09fc5badf6d67557a5fb2d3b069dbed90617 +F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a895ab33 F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21 F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa -F tool/mkpragmatab.tcl f115d63ada8171f9da28dc8e34e043a1a159692d46b89f66b6e681140bc4683d +F tool/mkpragmatab.tcl ca12b1c718ececdab2d3aacb437bc3c81ebf68467f19d7974e17f18844a3a48f F tool/mkshellc.tcl 70a9978e363b0f3280ca9ce1c46d72563ff479c1930a12a7375e3881b7325712 -F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b +F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f F tool/mksqlite3c.tcl 5fed3d75069d8f66f202d3b5200b0cea4aa7108481acd06732a06fdd42eb83a2 @@ -1789,14 +1800,14 @@ F tool/mksqlite3h.tcl 080873e3856eceb9d289a08a00c4b30f875ea3feadcbece796bd509b15 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 -F tool/omittest.tcl 27f9413c3343bac200a28d81e8234adb0f5e141c4771893cb19b40235a91f1e0 +F tool/omittest.tcl 6616fbf384f0f630113eab27d41d4530435dd94e2883307759988b45f0604a3b F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b F tool/replace.tcl 60f91e8dd06ab81f74d213ecbd9c9945f32ac048 F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5 F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076 -F tool/showdb.c 97d14a1ce32d5edda84081a5c939bd8975abd89568a773b288940e67e4c7e3ad +F tool/showdb.c 9b2dbb4b7a00afaf8fc1719f0d775775effa5b135ac1a2c23f1c3f5d670c4e15 F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818 F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68 F tool/showshm.c a0ab6ec32dd1f11218ca2a4018f8fb875b59414801ab8ceed8b2e69b7b45a809 @@ -1846,11 +1857,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c6cc2390e91097a32992d11c74af8e77a6a42862ec8a936b549e156250629407 -R 9b77b3da995b6a235a01d1e768df1101 +P 4daf94d83319231e42243625c804d5db2d14f10fa5ea1a1f358c3603c47b955b +R 5a98666c879217368b8f21c26d062d92 T +bgcolor * #d0c0ff T +sym-release * -T +sym-version-3.30.1 * +T +sym-version-3.31.0 * U drh -Z 6b715002b9e76fa6c3cf0c09f9813287 +Z 51c630793e0eec473e1274a795f77643 # Remove this line to create a well-formed manifest. diff --git a/manifest.uuid b/manifest.uuid index 6238afad..b885b0a7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -18db032d058f1436ce3dea84081f4ee5a0f2259ad97301d43c426bc7f3df1b0b +f6affdd41608946fcfcea914ece149038a8b25a62bbe719ed2561c649b86d824 diff --git a/src/alter.c b/src/alter.c index 9d02d383..ee193d18 100644 --- a/src/alter.c +++ b/src/alter.c @@ -31,9 +31,8 @@ static int isAlterableTable(Parse *pParse, Table *pTab){ if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) #ifndef SQLITE_OMIT_VIRTUALTABLE - || ( (pTab->tabFlags & TF_Shadow) - && (pParse->db->flags & SQLITE_Defensive) - && pParse->db->nVdbeExec==0 + || ( (pTab->tabFlags & TF_Shadow)!=0 + && sqlite3ReadOnlyShadowTables(pParse->db) ) #endif ){ @@ -298,14 +297,6 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ } #endif - /* If the default value for the new column was specified with a - ** literal NULL, then set pDflt to 0. This simplifies checking - ** for an SQL NULL default below. - */ - assert( pDflt==0 || pDflt->op==TK_SPAN ); - if( pDflt && pDflt->pLeft->op==TK_NULL ){ - pDflt = 0; - } /* Check that the new column is not specified as PRIMARY KEY or UNIQUE. ** If there is a NOT NULL constraint, then the default value for the @@ -319,35 +310,49 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column"); return; } - if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){ - sqlite3ErrorMsg(pParse, - "Cannot add a REFERENCES column with non-NULL default value"); - return; - } - if( pCol->notNull && !pDflt ){ - sqlite3ErrorMsg(pParse, - "Cannot add a NOT NULL column with default value NULL"); + if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){ + /* If the default value for the new column was specified with a + ** literal NULL, then set pDflt to 0. This simplifies checking + ** for an SQL NULL default below. + */ + assert( pDflt==0 || pDflt->op==TK_SPAN ); + if( pDflt && pDflt->pLeft->op==TK_NULL ){ + pDflt = 0; + } + if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){ + sqlite3ErrorMsg(pParse, + "Cannot add a REFERENCES column with non-NULL default value"); + return; + } + if( pCol->notNull && !pDflt ){ + sqlite3ErrorMsg(pParse, + "Cannot add a NOT NULL column with default value NULL"); + return; + } + + /* Ensure the default expression is something that sqlite3ValueFromExpr() + ** can handle (i.e. not CURRENT_TIME etc.) + */ + if( pDflt ){ + sqlite3_value *pVal = 0; + int rc; + rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + if( rc!=SQLITE_OK ){ + assert( db->mallocFailed == 1 ); + return; + } + if( !pVal ){ + sqlite3ErrorMsg(pParse,"Cannot add a column with non-constant default"); + return; + } + sqlite3ValueFree(pVal); + } + }else if( pCol->colFlags & COLFLAG_STORED ){ + sqlite3ErrorMsg(pParse, "cannot add a STORED column"); return; } - /* Ensure the default expression is something that sqlite3ValueFromExpr() - ** can handle (i.e. not CURRENT_TIME etc.) - */ - if( pDflt ){ - sqlite3_value *pVal = 0; - int rc; - rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal); - assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); - if( rc!=SQLITE_OK ){ - assert( db->mallocFailed == 1 ); - return; - } - if( !pVal ){ - sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default"); - return; - } - sqlite3ValueFree(pVal); - } /* Modify the CREATE TABLE statement. */ zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n); @@ -692,12 +697,14 @@ void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){ RenameToken *pNew; assert( pPtr || pParse->db->mallocFailed ); renameTokenCheckAll(pParse, pPtr); - pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken)); - if( pNew ){ - pNew->p = pPtr; - pNew->t = *pToken; - pNew->pNext = pParse->pRename; - pParse->pRename = pNew; + if( pParse->eParseMode!=PARSE_MODE_UNMAP ){ + pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken)); + if( pNew ){ + pNew->p = pPtr; + pNew->t = *pToken; + pNew->pNext = pParse->pRename; + pParse->pRename = pNew; + } } return pPtr; @@ -728,17 +735,39 @@ static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){ return WRC_Continue; } +/* +** Iterate through the Select objects that are part of WITH clauses attached +** to select statement pSelect. +*/ +static void renameWalkWith(Walker *pWalker, Select *pSelect){ + With *pWith = pSelect->pWith; + if( pWith ){ + int i; + for(i=0; inCte; i++){ + Select *p = pWith->a[i].pSelect; + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pWalker->pParse; + sqlite3SelectPrep(sNC.pParse, p, &sNC); + sqlite3WalkSelect(pWalker, p); + sqlite3RenameExprlistUnmap(pWalker->pParse, pWith->a[i].pCols); + } + } +} + /* ** Walker callback used by sqlite3RenameExprUnmap(). */ static int renameUnmapSelectCb(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; int i; + if( pParse->nErr ) return WRC_Abort; + if( NEVER(p->selFlags & SF_View) ) return WRC_Prune; if( ALWAYS(p->pEList) ){ ExprList *pList = p->pEList; for(i=0; inExpr; i++){ - if( pList->a[i].zName ){ - sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zName); + if( pList->a[i].zEName && pList->a[i].eEName==ENAME_NAME ){ + sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zEName); } } } @@ -746,8 +775,11 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){ SrcList *pSrc = p->pSrc; for(i=0; inSrc; i++){ sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName); + if( sqlite3WalkExpr(pWalker, pSrc->a[i].pOn) ) return WRC_Abort; } } + + renameWalkWith(pWalker, p); return WRC_Continue; } @@ -755,12 +787,15 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){ ** Remove all nodes that are part of expression pExpr from the rename list. */ void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){ + u8 eMode = pParse->eParseMode; Walker sWalker; memset(&sWalker, 0, sizeof(Walker)); sWalker.pParse = pParse; sWalker.xExprCallback = renameUnmapExprCb; sWalker.xSelectCallback = renameUnmapSelectCb; + pParse->eParseMode = PARSE_MODE_UNMAP; sqlite3WalkExpr(&sWalker, pExpr); + pParse->eParseMode = eMode; } /* @@ -776,7 +811,9 @@ void sqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){ sWalker.xExprCallback = renameUnmapExprCb; sqlite3WalkExprList(&sWalker, pEList); for(i=0; inExpr; i++){ - sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zName); + if( ALWAYS(pEList->a[i].eEName==ENAME_NAME) ){ + sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zEName); + } } } } @@ -814,30 +851,13 @@ static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){ } } -/* -** Iterate through the Select objects that are part of WITH clauses attached -** to select statement pSelect. -*/ -static void renameWalkWith(Walker *pWalker, Select *pSelect){ - if( pSelect->pWith ){ - int i; - for(i=0; ipWith->nCte; i++){ - Select *p = pSelect->pWith->a[i].pSelect; - NameContext sNC; - memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pWalker->pParse; - sqlite3SelectPrep(sNC.pParse, p, &sNC); - sqlite3WalkSelect(pWalker, p); - } - } -} - /* ** This is a Walker select callback. It does nothing. It is only required ** because without a dummy callback, sqlite3WalkExpr() and similar do not ** descend into sub-select statements. */ static int renameColumnSelectCb(Walker *pWalker, Select *p){ + if( p->selFlags & SF_View ) return WRC_Prune; renameWalkWith(pWalker, p); return WRC_Continue; } @@ -931,8 +951,11 @@ static void renameColumnElistNames( if( pEList ){ int i; for(i=0; inExpr; i++){ - char *zName = pEList->a[i].zName; - if( 0==sqlite3_stricmp(zName, zOld) ){ + char *zName = pEList->a[i].zEName; + if( ALWAYS(pEList->a[i].eEName==ENAME_NAME) + && ALWAYS(zName!=0) + && 0==sqlite3_stricmp(zName, zOld) + ){ renameTokenFind(pParse, pCtx, (void*)zName); } } @@ -968,7 +991,6 @@ static void renameColumnIdlistNames( static int renameParseSql( Parse *p, /* Memory to use for Parse object */ const char *zDb, /* Name of schema SQL belongs to */ - int bTable, /* 1 -> RENAME TABLE, 0 -> RENAME COLUMN */ sqlite3 *db, /* Database handle */ const char *zSql, /* SQL to parse */ int bTemp /* True if SQL is from temp schema */ @@ -982,7 +1004,7 @@ static int renameParseSql( ** occurs and the parse does not result in a new table, index or ** trigger object, the database must be corrupt. */ memset(p, 0, sizeof(Parse)); - p->eParseMode = (bTable ? PARSE_MODE_RENAME_TABLE : PARSE_MODE_RENAME_COLUMN); + p->eParseMode = PARSE_MODE_RENAME; p->db = db; p->nQueryLoop = 1; rc = sqlite3RunParser(p, zSql, &zErr); @@ -1289,7 +1311,7 @@ static void renameColumnFunc( #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = 0; #endif - rc = renameParseSql(&sParse, zDb, 0, db, zSql, bTemp); + rc = renameParseSql(&sParse, zDb, db, zSql, bTemp); /* Find tokens that need to be replaced. */ memset(&sWalker, 0, sizeof(Walker)); @@ -1303,8 +1325,9 @@ static void renameColumnFunc( if( sParse.pNewTable ){ Select *pSelect = sParse.pNewTable->pSelect; if( pSelect ){ + pSelect->selFlags &= ~SF_View; sParse.rc = SQLITE_OK; - sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, 0); + sqlite3SelectPrep(&sParse, pSelect, 0); rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); if( rc==SQLITE_OK ){ sqlite3WalkSelect(&sWalker, pSelect); @@ -1331,6 +1354,11 @@ static void renameColumnFunc( sqlite3WalkExprList(&sWalker, pIdx->aColExpr); } } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + for(i=0; inCol; i++){ + sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt); + } +#endif for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){ for(i=0; inCol; i++){ @@ -1416,6 +1444,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ int i; RenameCtx *p = pWalker->u.pRename; SrcList *pSrc = pSelect->pSrc; + if( pSelect->selFlags & SF_View ) return WRC_Prune; if( pSrc==0 ){ assert( pWalker->pParse->db->mallocFailed ); return WRC_Abort; @@ -1486,7 +1515,7 @@ static void renameTableFunc( sWalker.xSelectCallback = renameTableSelectCb; sWalker.u.pRename = &sCtx; - rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp); + rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); if( rc==SQLITE_OK ){ int isLegacy = (db->flags & SQLITE_LegacyAlter); @@ -1495,13 +1524,19 @@ static void renameTableFunc( if( pTab->pSelect ){ if( isLegacy==0 ){ + Select *pSelect = pTab->pSelect; NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = &sParse; + assert( pSelect->selFlags & SF_View ); + pSelect->selFlags &= ~SF_View; sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC); - if( sParse.nErr ) rc = sParse.rc; - sqlite3WalkSelect(&sWalker, pTab->pSelect); + if( sParse.nErr ){ + rc = sParse.rc; + }else{ + sqlite3WalkSelect(&sWalker, pTab->pSelect); + } } }else{ /* Modify any FK definitions to point to the new table. */ @@ -1622,7 +1657,7 @@ static void renameTableTest( if( zDb && zInput ){ int rc; Parse sParse; - rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp); + rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); if( rc==SQLITE_OK ){ if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){ NameContext sNC; diff --git a/src/analyze.c b/src/analyze.c index 1904b9be..2a071ef1 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -916,18 +916,17 @@ static const FuncDef statGetFuncdef = { {0} }; -static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){ - assert( regOut!=regStat4 && regOut!=regStat4+1 ); +static void callStatGet(Parse *pParse, int regStat4, int iParam, int regOut){ #ifdef SQLITE_ENABLE_STAT4 - sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1); + sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat4+1); #elif SQLITE_DEBUG assert( iParam==STAT_GET_STAT1 ); #else UNUSED_PARAMETER( iParam ); #endif - sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4, regOut, - (char*)&statGetFuncdef, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, 1 + IsStat4); + assert( regOut!=regStat4 && regOut!=regStat4+1 ); + sqlite3VdbeAddFunctionCall(pParse, 0, regStat4, regOut, 1+IsStat4, + &statGetFuncdef, 0); } /* @@ -1095,9 +1094,8 @@ static void analyzeOneTable( #endif sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1); sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2); - sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4+1, regStat4, - (char*)&statInitFuncdef, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, 2+IsStat4); + sqlite3VdbeAddFunctionCall(pParse, 0, regStat4+1, regStat4, 2+IsStat4, + &statInitFuncdef, 0); /* Implementation of the following: ** @@ -1182,7 +1180,7 @@ static void analyzeOneTable( int j, k, regKey; regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol); for(j=0; jnKeyCol; j++){ - k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]); + k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]); assert( k>=0 && knColumn ); sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j); VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName)); @@ -1192,13 +1190,12 @@ static void analyzeOneTable( } #endif assert( regChng==(regStat4+1) ); - sqlite3VdbeAddOp4(v, OP_Function0, 1, regStat4, regTemp, - (char*)&statPushFuncdef, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, 2+IsStat4); + sqlite3VdbeAddFunctionCall(pParse, 1, regStat4, regTemp, 2+IsStat4, + &statPushFuncdef, 0); sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); /* Add the entry to the stat1 table. */ - callStatGet(v, regStat4, STAT_GET_STAT1, regStat1); + callStatGet(pParse, regStat4, STAT_GET_STAT1, regStat1); assert( "BBB"[0]==SQLITE_AFF_TEXT ); sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); @@ -1224,12 +1221,12 @@ static void analyzeOneTable( pParse->nMem = MAX(pParse->nMem, regCol+nCol); addrNext = sqlite3VdbeCurrentAddr(v); - callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid); + callStatGet(pParse, regStat4, STAT_GET_ROWID, regSampleRowid); addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid); VdbeCoverage(v); - callStatGet(v, regStat4, STAT_GET_NEQ, regEq); - callStatGet(v, regStat4, STAT_GET_NLT, regLt); - callStatGet(v, regStat4, STAT_GET_NDLT, regDLt); + callStatGet(pParse, regStat4, STAT_GET_NEQ, regEq); + callStatGet(pParse, regStat4, STAT_GET_NLT, regLt); + callStatGet(pParse, regStat4, STAT_GET_NDLT, regDLt); sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0); VdbeCoverage(v); for(i=0; ilookaside.bDisable++; + DisableLookaside; rc = loadStat4(db, sInfo.zDatabase); - db->lookaside.bDisable--; + EnableLookaside; } for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); diff --git a/src/attach.c b/src/attach.c index 1dcb407e..fdd71854 100644 --- a/src/attach.c +++ b/src/attach.c @@ -401,11 +401,8 @@ static void codeAttach( assert( v || db->mallocFailed ); if( v ){ - sqlite3VdbeAddOp4(v, OP_Function0, 0, regArgs+3-pFunc->nArg, regArgs+3, - (char *)pFunc, P4_FUNCDEF); - assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg ); - sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg)); - + sqlite3VdbeAddFunctionCall(pParse, 0, regArgs+3-pFunc->nArg, regArgs+3, + pFunc->nArg, pFunc, 0); /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this ** statement only). For DETACH, set it to false (expire all existing ** statements). @@ -480,7 +477,7 @@ void sqlite3FixInit( pFix->pSchema = db->aDb[iDb].pSchema; pFix->zType = zType; pFix->pName = pName; - pFix->bVarOnly = (iDb==1); + pFix->bTemp = (iDb==1); } /* @@ -508,7 +505,7 @@ int sqlite3FixSrcList( if( NEVER(pList==0) ) return 0; zDb = pFix->zDb; for(i=0, pItem=pList->a; inSrc; i++, pItem++){ - if( pFix->bVarOnly==0 ){ + if( pFix->bTemp==0 ){ if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){ sqlite3ErrorMsg(pFix->pParse, "%s %T cannot reference objects in database %s", @@ -518,6 +515,7 @@ int sqlite3FixSrcList( sqlite3DbFree(pFix->pParse->db, pItem->zDatabase); pItem->zDatabase = 0; pItem->pSchema = pFix->pSchema; + pItem->fg.fromDDL = 1; } #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; @@ -573,7 +571,7 @@ int sqlite3FixExpr( Expr *pExpr /* The expression to be fixed to one database */ ){ while( pExpr ){ - ExprSetProperty(pExpr, EP_Indirect); + if( !pFix->bTemp ) ExprSetProperty(pExpr, EP_FromDDL); if( pExpr->op==TK_VARIABLE ){ if( pFix->pParse->db->init.busy ){ pExpr->op = TK_NULL; diff --git a/src/btree.c b/src/btree.c index 7ff91e66..be5d639b 100644 --- a/src/btree.c +++ b/src/btree.c @@ -699,6 +699,9 @@ static int saveCursorPosition(BtCursor *pCur){ assert( 0==pCur->pKey ); assert( cursorHoldsMutex(pCur) ); + if( pCur->curFlags & BTCF_Pinned ){ + return SQLITE_CONSTRAINT_PINNED; + } if( pCur->eState==CURSOR_SKIPNEXT ){ pCur->eState = CURSOR_VALID; }else{ @@ -1446,7 +1449,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ int sz2 = 0; int sz = get2byte(&data[iFree+2]); int top = get2byte(&data[hdr+5]); - if( top>=iFree ){ + if( NEVER(top>=iFree) ){ return SQLITE_CORRUPT_PAGE(pPage); } if( iFree2 ){ @@ -1455,7 +1458,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage); memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); sz += sz2; - }else if( iFree+sz>usableSize ){ + }else if( NEVER(iFree+sz>usableSize) ){ return SQLITE_CORRUPT_PAGE(pPage); } @@ -1647,8 +1650,10 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ if( (data[hdr+2] || data[hdr+1]) && gap+2<=top ){ u8 *pSpace = pageFindSlot(pPage, nByte, &rc); if( pSpace ){ + int g2; assert( pSpace+nByte<=data+pPage->pBt->usableSize ); - if( (*pIdx = (int)(pSpace-data))<=gap ){ + *pIdx = g2 = (int)(pSpace-data); + if( NEVER(g2<=gap) ){ return SQLITE_CORRUPT_PAGE(pPage); }else{ return SQLITE_OK; @@ -1726,12 +1731,12 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ }else{ while( (iFreeBlk = get2byte(&data[iPtr]))pPage->pBt->usableSize-4 ){ + if( iFreeBlk>pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */ return SQLITE_CORRUPT_PAGE(pPage); } assert( iFreeBlk>iPtr || iFreeBlk==0 ); @@ -1746,7 +1751,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ nFrag = iFreeBlk - iEnd; if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PAGE(pPage); iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]); - if( iEnd > pPage->pBt->usableSize ){ + if( NEVER(iEnd > pPage->pBt->usableSize) ){ return SQLITE_CORRUPT_PAGE(pPage); } iSize = iEnd - iStart; @@ -1774,7 +1779,8 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ /* The new freeblock is at the beginning of the cell content area, ** so just extend the cell content area rather than create another ** freelist entry */ - if( iStart0 ){ u32 next, size; - if( pcnPage & 0x80000000)==0 || CORRUPT_DB ); return pBt->nPage; } u32 sqlite3BtreeLastPage(Btree *p){ assert( sqlite3BtreeHoldsMutex(p) ); - assert( ((p->pBt->nPage)&0x80000000)==0 ); - return btreePagecount(p->pBt); + return btreePagecount(p->pBt) & 0x7fffffff; } /* @@ -2403,9 +2409,13 @@ int sqlite3BtreeOpen( rc = sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); if( rc ){ - sqlite3_free(zFullPathname); - sqlite3_free(p); - return rc; + if( rc==SQLITE_OK_SYMLINK ){ + rc = SQLITE_OK; + }else{ + sqlite3_free(zFullPathname); + sqlite3_free(p); + return rc; + } } } #if SQLITE_THREADSAFE @@ -4365,8 +4375,9 @@ static int btreeCursor( /* The following assert statements verify that if this is a sharable ** b-tree database, the connection is holding the required table locks, ** and that no other connection has any open cursor that conflicts with - ** this lock. */ - assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2:1)) ); + ** this lock. The iTable<1 term disables the check for corrupt schemas. */ + assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2:1)) + || iTable<1 ); assert( wrFlag==0 || !hasReadConflicts(p, iTable) ); /* Assert that the caller has opened the required transaction. */ @@ -4379,9 +4390,13 @@ static int btreeCursor( allocateTempSpace(pBt); if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM_BKPT; } - if( iTable==1 && btreePagecount(pBt)==0 ){ - assert( wrFlag==0 ); - iTable = 0; + if( iTable<=1 ){ + if( iTable<1 ){ + return SQLITE_CORRUPT_BKPT; + }else if( btreePagecount(pBt)==0 ){ + assert( wrFlag==0 ); + iTable = 0; + } } /* Now that no other errors can occur, finish filling in the BtCursor @@ -4406,6 +4421,19 @@ static int btreeCursor( pCur->eState = CURSOR_INVALID; return SQLITE_OK; } +static int btreeCursorWithLock( + Btree *p, /* The btree */ + int iTable, /* Root page of table to open */ + int wrFlag, /* 1 to write. 0 read-only */ + struct KeyInfo *pKeyInfo, /* First arg to comparison function */ + BtCursor *pCur /* Space for new cursor */ +){ + int rc; + sqlite3BtreeEnter(p); + rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur); + sqlite3BtreeLeave(p); + return rc; +} int sqlite3BtreeCursor( Btree *p, /* The btree */ int iTable, /* Root page of table to open */ @@ -4413,15 +4441,11 @@ int sqlite3BtreeCursor( struct KeyInfo *pKeyInfo, /* First arg to xCompare() */ BtCursor *pCur /* Write new cursor here */ ){ - int rc; - if( iTable<1 ){ - rc = SQLITE_CORRUPT_BKPT; + if( p->sharable ){ + return btreeCursorWithLock(p, iTable, wrFlag, pKeyInfo, pCur); }else{ - sqlite3BtreeEnter(p); - rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur); - sqlite3BtreeLeave(p); + return btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur); } - return rc; } /* @@ -4544,6 +4568,18 @@ i64 sqlite3BtreeIntegerKey(BtCursor *pCur){ return pCur->info.nKey; } +/* +** Pin or unpin a cursor. +*/ +void sqlite3BtreeCursorPin(BtCursor *pCur){ + assert( (pCur->curFlags & BTCF_Pinned)==0 ); + pCur->curFlags |= BTCF_Pinned; +} +void sqlite3BtreeCursorUnpin(BtCursor *pCur){ + assert( (pCur->curFlags & BTCF_Pinned)!=0 ); + pCur->curFlags &= ~BTCF_Pinned; +} + #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC /* ** Return the offset into the database file for the start of the @@ -5700,8 +5736,11 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ ** to be invalid here. This can only occur if a second cursor modifies ** the page while cursor pCur is holding a reference to it. Which can ** only happen if the database is corrupt in such a way as to link the - ** page into more than one b-tree structure. */ - testcase( idx>pPage->nCell ); + ** page into more than one b-tree structure. + ** + ** Update 2019-12-23: appears to long longer be possible after the + ** addition of anotherValidCursor() condition on balance_deeper(). */ + harmless( idx>pPage->nCell ); if( idx>=pPage->nCell ){ if( !pPage->leaf ){ @@ -6900,7 +6939,7 @@ static int rebuildPage( assert( i(u32)usableSize ){ j = 0; } + if( NEVER(j>(u32)usableSize) ){ j = 0; } memcpy(&pTmp[j], &aData[j], usableSize - j); for(k=0; pCArray->ixNx[k]<=i && ALWAYS(kxCellSize(pPg, pCell) || CORRUPT_DB ); - testcase( sz!=pPg->xCellSize(pPg,pCell) ); + testcase( sz!=pPg->xCellSize(pPg,pCell) ) i++; if( i>=iEnd ) break; if( pCArray->ixNx[k]<=i ){ @@ -8290,6 +8329,30 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){ return SQLITE_OK; } +/* +** Return SQLITE_CORRUPT if any cursor other than pCur is currently valid +** on the same B-tree as pCur. +** +** This can if a database is corrupt with two or more SQL tables +** pointing to the same b-tree. If an insert occurs on one SQL table +** and causes a BEFORE TRIGGER to do a secondary insert on the other SQL +** table linked to the same b-tree. If the secondary insert causes a +** rebalance, that can change content out from under the cursor on the +** first SQL table, violating invariants on the first insert. +*/ +static int anotherValidCursor(BtCursor *pCur){ + BtCursor *pOther; + for(pOther=pCur->pBt->pCursor; pOther; pOther=pOther->pNext){ + if( pOther!=pCur + && pOther->eState==CURSOR_VALID + && pOther->pPage==pCur->pPage + ){ + return SQLITE_CORRUPT_BKPT; + } + } + return SQLITE_OK; +} + /* ** The page that pCur currently points to has just been modified in ** some way. This function figures out if this modification means the @@ -8317,7 +8380,7 @@ static int balance(BtCursor *pCur){ if( pPage->nOverflow==0 && pPage->nFree<=nMin ){ break; }else if( (iPage = pCur->iPage)==0 ){ - if( pPage->nOverflow ){ + if( pPage->nOverflow && (rc = anotherValidCursor(pCur))==SQLITE_OK ){ /* The root page of the b-tree is overfull. In this case call the ** balance_deeper() function to create a new child for the root-page ** and copy the current contents of the root-page to it. The @@ -8613,7 +8676,6 @@ int sqlite3BtreeInsert( if( flags & BTREE_SAVEPOSITION ){ assert( pCur->curFlags & BTCF_ValidNKey ); assert( pX->nKey==pCur->info.nKey ); - assert( pCur->info.nSize!=0 ); assert( loc==0 ); } #endif @@ -8688,7 +8750,9 @@ int sqlite3BtreeInsert( } } - assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) ); + assert( pCur->eState==CURSOR_VALID + || (pCur->eState==CURSOR_INVALID && loc) + || CORRUPT_DB ); pPage = pCur->pPage; assert( pPage->intKey || pX->nKey>=0 ); @@ -9459,7 +9523,7 @@ int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){ ** Otherwise, if an error is encountered (i.e. an IO error or database ** corruption) an SQLite error code is returned. */ -int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ +int sqlite3BtreeCount(sqlite3 *db, BtCursor *pCur, i64 *pnEntry){ i64 nEntry = 0; /* Value to return in *pnEntry */ int rc; /* Return code */ @@ -9472,7 +9536,7 @@ int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ /* Unless an error occurs, the following loop runs one iteration for each ** page in the B-Tree structure (not including overflow pages). */ - while( rc==SQLITE_OK ){ + while( rc==SQLITE_OK && !db->u1.isInterrupted ){ int iIdx; /* Index of child node in parent */ MemPage *pPage; /* Current page of the b-tree */ @@ -9598,6 +9662,7 @@ static int checkRef(IntegrityCk *pCheck, Pgno iPage){ checkAppendMsg(pCheck, "2nd reference to page %d", iPage); return 1; } + if( pCheck->db->u1.isInterrupted ) return 1; setPageReferenced(pCheck, iPage); return 0; } @@ -10041,6 +10106,7 @@ end_of_check: ** returned. If a memory allocation error occurs, NULL is returned. */ char *sqlite3BtreeIntegrityCheck( + sqlite3 *db, /* Database connection that is running the check */ Btree *p, /* The btree to be checked */ int *aRoot, /* An array of root pages numbers for individual trees */ int nRoot, /* Number of entries in aRoot[] */ @@ -10058,6 +10124,7 @@ char *sqlite3BtreeIntegrityCheck( assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE ); VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) ); assert( nRef>=0 ); + sCheck.db = db; sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; sCheck.nPage = btreePagecount(sCheck.pBt); diff --git a/src/btree.h b/src/btree.h index ed228c22..4bd41f7f 100644 --- a/src/btree.h +++ b/src/btree.h @@ -306,6 +306,8 @@ int sqlite3BtreeNext(BtCursor*, int flags); int sqlite3BtreeEof(BtCursor*); int sqlite3BtreePrevious(BtCursor*, int flags); i64 sqlite3BtreeIntegerKey(BtCursor*); +void sqlite3BtreeCursorPin(BtCursor*); +void sqlite3BtreeCursorUnpin(BtCursor*); #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC i64 sqlite3BtreeOffset(BtCursor*); #endif @@ -314,7 +316,7 @@ const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt); u32 sqlite3BtreePayloadSize(BtCursor*); sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*); -char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); +char *sqlite3BtreeIntegrityCheck(sqlite3*,Btree*,int*aRoot,int nRoot,int,int*); struct Pager *sqlite3BtreePager(Btree*); i64 sqlite3BtreeRowCountEst(BtCursor*); @@ -335,7 +337,7 @@ int sqlite3BtreeCursorIsValid(BtCursor*); int sqlite3BtreeCursorIsValidNN(BtCursor*); #ifndef SQLITE_OMIT_BTREECOUNT -int sqlite3BtreeCount(BtCursor *, i64 *); +int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*); #endif #ifdef SQLITE_TEST diff --git a/src/btreeInt.h b/src/btreeInt.h index ddd374ef..7687a0f1 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -542,6 +542,7 @@ struct BtCursor { #define BTCF_AtLast 0x08 /* Cursor is pointing ot the last entry */ #define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */ #define BTCF_Multiple 0x20 /* Maybe another cursor on the same btree */ +#define BTCF_Pinned 0x40 /* Cursor is busy and cannot be moved */ /* ** Potential values for BtCursor.eState. @@ -685,6 +686,7 @@ struct IntegrityCk { int v1, v2; /* Values for up to two %d fields in zPfx */ StrAccum errMsg; /* Accumulate the error message text here */ u32 *heap; /* Min-heap used for analyzing cell coverage */ + sqlite3 *db; /* Database connection running the check */ }; /* diff --git a/src/build.c b/src/build.c index a3d1abf0..a7dc36ff 100644 --- a/src/build.c +++ b/src/build.c @@ -856,13 +856,14 @@ int sqlite3CheckObjectName( } } }else{ - if( pParse->nested==0 - && 0==sqlite3StrNICmp(zName, "sqlite_", 7) + if( (pParse->nested==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7)) + || (sqlite3ReadOnlyShadowTables(db) && sqlite3ShadowTableName(db, zName)) ){ sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName); return SQLITE_ERROR; } + } return SQLITE_OK; } @@ -877,10 +878,12 @@ Index *sqlite3PrimaryKeyIndex(Table *pTab){ } /* -** Return the column of index pIdx that corresponds to table -** column iCol. Return -1 if not found. +** Convert an table column number into a index column number. That is, +** for the column iCol in the table (as defined by the CREATE TABLE statement) +** find the (first) offset of that column in index pIdx. Or return -1 +** if column iCol is not used in index pIdx. */ -i16 sqlite3ColumnOfIndex(Index *pIdx, i16 iCol){ +i16 sqlite3TableColumnToIndex(Index *pIdx, i16 iCol){ int i; for(i=0; inColumn; i++){ if( iCol==pIdx->aiColumn[i] ) return i; @@ -888,6 +891,84 @@ i16 sqlite3ColumnOfIndex(Index *pIdx, i16 iCol){ return -1; } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +/* Convert a storage column number into a table column number. +** +** The storage column number (0,1,2,....) is the index of the value +** as it appears in the record on disk. The true column number +** is the index (0,1,2,...) of the column in the CREATE TABLE statement. +** +** The storage column number is less than the table column number if +** and only there are VIRTUAL columns to the left. +** +** If SQLITE_OMIT_GENERATED_COLUMNS, this routine is a no-op macro. +*/ +i16 sqlite3StorageColumnToTable(Table *pTab, i16 iCol){ + if( pTab->tabFlags & TF_HasVirtual ){ + int i; + for(i=0; i<=iCol; i++){ + if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) iCol++; + } + } + return iCol; +} +#endif + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +/* Convert a table column number into a storage column number. +** +** The storage column number (0,1,2,....) is the index of the value +** as it appears in the record on disk. Or, if the input column is +** the N-th virtual column (zero-based) then the storage number is +** the number of non-virtual columns in the table plus N. +** +** The true column number is the index (0,1,2,...) of the column in +** the CREATE TABLE statement. +** +** If the input column is a VIRTUAL column, then it should not appear +** in storage. But the value sometimes is cached in registers that +** follow the range of registers used to construct storage. This +** avoids computing the same VIRTUAL column multiple times, and provides +** values for use by OP_Param opcodes in triggers. Hence, if the +** input column is a VIRTUAL table, put it after all the other columns. +** +** In the following, N means "normal column", S means STORED, and +** V means VIRTUAL. Suppose the CREATE TABLE has columns like this: +** +** CREATE TABLE ex(N,S,V,N,S,V,N,S,V); +** -- 0 1 2 3 4 5 6 7 8 +** +** Then the mapping from this function is as follows: +** +** INPUTS: 0 1 2 3 4 5 6 7 8 +** OUTPUTS: 0 1 6 2 3 7 4 5 8 +** +** So, in other words, this routine shifts all the virtual columns to +** the end. +** +** If SQLITE_OMIT_GENERATED_COLUMNS then there are no virtual columns and +** this routine is a no-op macro. If the pTab does not have any virtual +** columns, then this routine is no-op that always return iCol. If iCol +** is negative (indicating the ROWID column) then this routine return iCol. +*/ +i16 sqlite3TableColumnToStorage(Table *pTab, i16 iCol){ + int i; + i16 n; + assert( iColnCol ); + if( (pTab->tabFlags & TF_HasVirtual)==0 || iCol<0 ) return iCol; + for(i=0, n=0; iaCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) n++; + } + if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ){ + /* iCol is a virtual column itself */ + return pTab->nNVCol + i - n; + }else{ + /* iCol is a normal or stored column */ + return n; + } +} +#endif + /* ** Begin constructing a new table representation in memory. This is ** the first of several action routines that get called in response @@ -1178,6 +1259,7 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ pCol->colFlags |= COLFLAG_HASTYPE; } p->nCol++; + p->nNVCol++; pParse->constraintName.n = 0; } @@ -1322,10 +1404,17 @@ void sqlite3AddDefaultValue( sqlite3 *db = pParse->db; p = pParse->pNewTable; if( p!=0 ){ + int isInit = db->init.busy && db->init.iDb!=1; pCol = &(p->aCol[p->nCol-1]); - if( !sqlite3ExprIsConstantOrFunction(pExpr, db->init.busy) ){ + if( !sqlite3ExprIsConstantOrFunction(pExpr, isInit) ){ sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", pCol->zName); +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + }else if( pCol->colFlags & COLFLAG_GENERATED ){ + testcase( pCol->colFlags & COLFLAG_VIRTUAL ); + testcase( pCol->colFlags & COLFLAG_STORED ); + sqlite3ErrorMsg(pParse, "cannot use DEFAULT on a generated column"); +#endif }else{ /* A copy of pExpr is used instead of the original, as pExpr contains ** tokens that point to volatile memory. @@ -1371,6 +1460,21 @@ static void sqlite3StringToId(Expr *p){ } } +/* +** Tag the given column as being part of the PRIMARY KEY +*/ +static void makeColumnPartOfPrimaryKey(Parse *pParse, Column *pCol){ + pCol->colFlags |= COLFLAG_PRIMKEY; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( pCol->colFlags & COLFLAG_GENERATED ){ + testcase( pCol->colFlags & COLFLAG_VIRTUAL ); + testcase( pCol->colFlags & COLFLAG_STORED ); + sqlite3ErrorMsg(pParse, + "generated columns cannot be part of the PRIMARY KEY"); + } +#endif +} + /* ** Designate the PRIMARY KEY for the table. pList is a list of names ** of columns that form the primary key. If pList is NULL, then the @@ -1410,7 +1514,7 @@ void sqlite3AddPrimaryKey( if( pList==0 ){ iCol = pTab->nCol - 1; pCol = &pTab->aCol[iCol]; - pCol->colFlags |= COLFLAG_PRIMKEY; + makeColumnPartOfPrimaryKey(pParse, pCol); nTerm = 1; }else{ nTerm = pList->nExpr; @@ -1423,7 +1527,7 @@ void sqlite3AddPrimaryKey( for(iCol=0; iColnCol; iCol++){ if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){ pCol = &pTab->aCol[iCol]; - pCol->colFlags |= COLFLAG_PRIMKEY; + makeColumnPartOfPrimaryKey(pParse, pCol); break; } } @@ -1444,6 +1548,7 @@ void sqlite3AddPrimaryKey( assert( autoInc==0 || autoInc==1 ); pTab->tabFlags |= autoInc*TF_Autoincrement; if( pList ) pParse->iPkSortOrder = pList->a[0].sortFlags; + (void)sqlite3HasExplicitNulls(pParse, pList); }else if( autoInc ){ #ifndef SQLITE_OMIT_AUTOINCREMENT sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an " @@ -1520,41 +1625,58 @@ void sqlite3AddCollateType(Parse *pParse, Token *pToken){ } } -/* -** This function returns the collation sequence for database native text -** encoding identified by the string zName, length nName. -** -** If the requested collation sequence is not available, or not available -** in the database native encoding, the collation factory is invoked to -** request it. If the collation factory does not supply such a sequence, -** and the sequence is available in another text encoding, then that is -** returned instead. -** -** If no versions of the requested collations sequence are available, or -** another error occurs, NULL is returned and an error message written into -** pParse. -** -** This routine is a wrapper around sqlite3FindCollSeq(). This routine -** invokes the collation factory if the named collation cannot be found -** and generates an error message. -** -** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq() +/* Change the most recently parsed column to be a GENERATED ALWAYS AS +** column. */ -CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){ - sqlite3 *db = pParse->db; - u8 enc = ENC(db); - u8 initbusy = db->init.busy; - CollSeq *pColl; - - pColl = sqlite3FindCollSeq(db, enc, zName, initbusy); - if( !initbusy && (!pColl || !pColl->xCmp) ){ - pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName); +void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){ +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + u8 eType = COLFLAG_VIRTUAL; + Table *pTab = pParse->pNewTable; + Column *pCol; + if( pTab==0 ){ + /* generated column in an CREATE TABLE IF NOT EXISTS that already exists */ + goto generated_done; } + pCol = &(pTab->aCol[pTab->nCol-1]); + if( IN_DECLARE_VTAB ){ + sqlite3ErrorMsg(pParse, "virtual tables cannot use computed columns"); + goto generated_done; + } + if( pCol->pDflt ) goto generated_error; + if( pType ){ + if( pType->n==7 && sqlite3StrNICmp("virtual",pType->z,7)==0 ){ + /* no-op */ + }else if( pType->n==6 && sqlite3StrNICmp("stored",pType->z,6)==0 ){ + eType = COLFLAG_STORED; + }else{ + goto generated_error; + } + } + if( eType==COLFLAG_VIRTUAL ) pTab->nNVCol--; + pCol->colFlags |= eType; + assert( TF_HasVirtual==COLFLAG_VIRTUAL ); + assert( TF_HasStored==COLFLAG_STORED ); + pTab->tabFlags |= eType; + if( pCol->colFlags & COLFLAG_PRIMKEY ){ + makeColumnPartOfPrimaryKey(pParse, pCol); /* For the error message */ + } + pCol->pDflt = pExpr; + pExpr = 0; + goto generated_done; - return pColl; +generated_error: + sqlite3ErrorMsg(pParse, "error in generated column \"%s\"", + pCol->zName); +generated_done: + sqlite3ExprDelete(pParse->db, pExpr); +#else + /* Throw and error for the GENERATED ALWAYS AS clause if the + ** SQLITE_OMIT_GENERATED_COLUMNS compile-time option is used. */ + sqlite3ErrorMsg(pParse, "generated columns not supported"); + sqlite3ExprDelete(pParse->db, pExpr); +#endif } - /* ** Generate code that will increment the schema cookie. ** @@ -1812,15 +1934,24 @@ static int isDupColumn(Index *pIdx, int nKey, Index *pPk, int iCol){ ** high-order bit of colNotIdxed is always 1. All unindexed columns ** of the table have a 1. ** +** 2019-10-24: For the purpose of this computation, virtual columns are +** not considered to be covered by the index, even if they are in the +** index, because we do not trust the logic in whereIndexExprTrans() to be +** able to find all instances of a reference to the indexed table column +** and convert them into references to the index. Hence we always want +** the actual table at hand in order to recompute the virtual column, if +** necessary. +** ** The colNotIdxed mask is AND-ed with the SrcList.a[].colUsed mask ** to determine if the index is covering index. */ static void recomputeColumnsNotIndexed(Index *pIdx){ Bitmask m = 0; int j; + Table *pTab = pIdx->pTable; for(j=pIdx->nColumn-1; j>=0; j--){ int x = pIdx->aiColumn[j]; - if( x>=0 ){ + if( x>=0 && (pTab->aCol[x].colFlags & COLFLAG_VIRTUAL)==0 ){ testcase( x==BMS-1 ); testcase( x==BMS-2 ); if( xaCol[i].notNull = OE_Abort; } } + pTab->tabFlags |= TF_HasNotNull; } /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY @@ -1978,11 +2110,14 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ */ nExtra = 0; for(i=0; inCol; i++){ - if( !hasColumn(pPk->aiColumn, nPk, i) ) nExtra++; + if( !hasColumn(pPk->aiColumn, nPk, i) + && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) nExtra++; } if( resizeIndexObject(db, pPk, nPk+nExtra) ) return; for(i=0, j=nPk; inCol; i++){ - if( !hasColumn(pPk->aiColumn, j, i) ){ + if( !hasColumn(pPk->aiColumn, j, i) + && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 + ){ assert( jnColumn ); pPk->aiColumn[j] = i; pPk->azColl[j] = sqlite3StrBINARY; @@ -1990,7 +2125,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ } } assert( pPk->nColumn==j ); - assert( pTab->nCol<=j ); + assert( pTab->nNVCol<=j ); recomputeColumnsNotIndexed(pPk); } @@ -2002,7 +2137,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ ** zName is temporarily modified while this routine is running, but is ** restored to its original value prior to this routine returning. */ -static int isShadowTableName(sqlite3 *db, char *zName){ +int sqlite3ShadowTableName(sqlite3 *db, const char *zName){ char *zTail; /* Pointer to the last "_" in zName */ Table *pTab; /* Table that zName is a shadow of */ Module *pMod; /* Module for the virtual table */ @@ -2020,8 +2155,6 @@ static int isShadowTableName(sqlite3 *db, char *zName){ if( pMod->pModule->xShadowName==0 ) return 0; return pMod->pModule->xShadowName(zTail+1); } -#else -# define isShadowTableName(x,y) 0 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ /* @@ -2063,7 +2196,7 @@ void sqlite3EndTable( p = pParse->pNewTable; if( p==0 ) return; - if( pSelect==0 && isShadowTableName(db, p->zName) ){ + if( pSelect==0 && sqlite3ShadowTableName(db, p->zName) ){ p->tabFlags |= TF_Shadow; } @@ -2099,12 +2232,11 @@ void sqlite3EndTable( } if( (p->tabFlags & TF_HasPrimaryKey)==0 ){ sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName); - }else{ - p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid; - convertToWithoutRowidTable(pParse, p); + return; } + p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid; + convertToWithoutRowidTable(pParse, p); } - iDb = sqlite3SchemaToIndex(db, p->pSchema); #ifndef SQLITE_OMIT_CHECK @@ -2112,8 +2244,45 @@ void sqlite3EndTable( */ if( p->pCheck ){ sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck); + if( pParse->nErr ){ + /* If errors are seen, delete the CHECK constraints now, else they might + ** actually be used if PRAGMA writable_schema=ON is set. */ + sqlite3ExprListDelete(db, p->pCheck); + p->pCheck = 0; + } } #endif /* !defined(SQLITE_OMIT_CHECK) */ +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( p->tabFlags & TF_HasGenerated ){ + int ii, nNG = 0; + testcase( p->tabFlags & TF_HasVirtual ); + testcase( p->tabFlags & TF_HasStored ); + for(ii=0; iinCol; ii++){ + u32 colFlags = p->aCol[ii].colFlags; + if( (colFlags & COLFLAG_GENERATED)!=0 ){ + Expr *pX = p->aCol[ii].pDflt; + testcase( colFlags & COLFLAG_VIRTUAL ); + testcase( colFlags & COLFLAG_STORED ); + if( sqlite3ResolveSelfReference(pParse, p, NC_GenCol, pX, 0) ){ + /* If there are errors in resolving the expression, change the + ** expression to a NULL. This prevents code generators that operate + ** on the expression from inserting extra parts into the expression + ** tree that have been allocated from lookaside memory, which is + ** illegal in a schema and will lead to errors or heap corruption + ** when the database connection closes. */ + sqlite3ExprDelete(db, pX); + p->aCol[ii].pDflt = sqlite3ExprAlloc(db, TK_NULL, 0, 0); + } + }else{ + nNG++; + } + } + if( nNG==0 ){ + sqlite3ErrorMsg(pParse, "must have at least one non-generated column"); + return; + } + } +#endif /* Estimate the average row size for the table and for all implied indices */ estimateTableWidth(p); @@ -2190,7 +2359,7 @@ void sqlite3EndTable( pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect, SQLITE_AFF_BLOB); if( pSelTab==0 ) return; assert( p->aCol==0 ); - p->nCol = pSelTab->nCol; + p->nCol = p->nNVCol = pSelTab->nCol; p->aCol = pSelTab->aCol; pSelTab->nCol = 0; pSelTab->aCol = 0; @@ -2263,7 +2432,6 @@ void sqlite3EndTable( sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName)); } - /* Add the table to the in-memory representation of the database. */ if( db->init.busy ){ @@ -2334,6 +2502,7 @@ void sqlite3CreateView( ** allocated rather than point to the input string - which means that ** they will persist after the current sqlite3_exec() call returns. */ + pSelect->selFlags |= SF_View; if( IN_RENAME_OBJECT ){ p->pSelect = pSelect; pSelect = 0; @@ -2447,7 +2616,7 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ n = pParse->nTab; sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; - db->lookaside.bDisable++; + DisableLookaside; #ifndef SQLITE_OMIT_AUTHORIZATION xAuth = db->xAuth; db->xAuth = 0; @@ -2457,7 +2626,10 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE); #endif pParse->nTab = n; - if( pTable->pCheck ){ + if( pSelTab==0 ){ + pTable->nCol = 0; + nErr++; + }else if( pTable->pCheck ){ /* CREATE VIEW name(arglist) AS ... ** The names of the columns in the table are taken from ** arglist which is stored in pTable->pCheck. The pCheck field @@ -2473,7 +2645,7 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel, SQLITE_AFF_NONE); } - }else if( pSelTab ){ + }else{ /* CREATE VIEW name AS... without an argument list. Construct ** the column names from the SELECT statement that defines the view. */ @@ -2483,13 +2655,11 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ pSelTab->nCol = 0; pSelTab->aCol = 0; assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); - }else{ - pTable->nCol = 0; - nErr++; } + pTable->nNVCol = pTable->nCol; sqlite3DeleteTable(db, pSelTab); sqlite3SelectDelete(db, pSel); - db->lookaside.bDisable--; + EnableLookaside; #ifndef SQLITE_OMIT_ALTERTABLE pParse->eParseMode = eParseMode; #endif @@ -2746,6 +2916,37 @@ void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){ sqliteViewResetAll(db, iDb); } +/* +** Return TRUE if shadow tables should be read-only in the current +** context. +*/ +int sqlite3ReadOnlyShadowTables(sqlite3 *db){ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( (db->flags & SQLITE_Defensive)!=0 + && db->pVtabCtx==0 + && db->nVdbeExec==0 + ){ + return 1; + } +#endif + return 0; +} + +/* +** Return true if it is not allowed to drop the given table +*/ +static int tableMayNotBeDropped(sqlite3 *db, Table *pTab){ + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ + if( sqlite3StrNICmp(pTab->zName+7, "stat", 4)==0 ) return 0; + if( sqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0; + return 1; + } + if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){ + return 1; + } + return 0; +} + /* ** This routine is called to do the work of a DROP TABLE statement. ** pName is the name of the table to be dropped. @@ -2815,9 +3016,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ } } #endif - if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 - && sqlite3StrNICmp(pTab->zName+7, "stat", 4)!=0 - && sqlite3StrNICmp(pTab->zName+7, "parameters", 10)!=0 ){ + if( tableMayNotBeDropped(db, pTab) ){ sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); goto exit_drop_table; } @@ -2909,7 +3108,7 @@ void sqlite3CreateForeignKey( nByte = sizeof(*pFKey) + (nCol-1)*sizeof(pFKey->aCol[0]) + pTo->n + 1; if( pToCol ){ for(i=0; inExpr; i++){ - nByte += sqlite3Strlen30(pToCol->a[i].zName) + 1; + nByte += sqlite3Strlen30(pToCol->a[i].zEName) + 1; } } pFKey = sqlite3DbMallocZero(db, nByte ); @@ -2934,7 +3133,7 @@ void sqlite3CreateForeignKey( for(i=0; inCol; j++){ - if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zName)==0 ){ + if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zEName)==0 ){ pFKey->aCol[i].iFrom = j; break; } @@ -2942,22 +3141,22 @@ void sqlite3CreateForeignKey( if( j>=p->nCol ){ sqlite3ErrorMsg(pParse, "unknown column \"%s\" in foreign key definition", - pFromCol->a[i].zName); + pFromCol->a[i].zEName); goto fk_end; } if( IN_RENAME_OBJECT ){ - sqlite3RenameTokenRemap(pParse, &pFKey->aCol[i], pFromCol->a[i].zName); + sqlite3RenameTokenRemap(pParse, &pFKey->aCol[i], pFromCol->a[i].zEName); } } } if( pToCol ){ for(i=0; ia[i].zName); + int n = sqlite3Strlen30(pToCol->a[i].zEName); pFKey->aCol[i].zCol = z; if( IN_RENAME_OBJECT ){ - sqlite3RenameTokenRemap(pParse, z, pToCol->a[i].zName); + sqlite3RenameTokenRemap(pParse, z, pToCol->a[i].zEName); } - memcpy(z, pToCol->a[i].zName, n); + memcpy(z, pToCol->a[i].zEName, n); z[n] = 0; z += n+1; } @@ -3488,8 +3687,13 @@ void sqlite3CreateIndex( assert( j<=0x7fff ); if( j<0 ){ j = pTab->iPKey; - }else if( pTab->aCol[j].notNull==0 ){ - pIndex->uniqNotNull = 0; + }else{ + if( pTab->aCol[j].notNull==0 ){ + pIndex->uniqNotNull = 0; + } + if( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ){ + pIndex->bHasVCol = 1; + } } pIndex->aiColumn[i] = (i16)j; } @@ -3544,13 +3748,13 @@ void sqlite3CreateIndex( /* If this index contains every column of its table, then mark ** it as a covering index */ assert( HasRowid(pTab) - || pTab->iPKey<0 || sqlite3ColumnOfIndex(pIndex, pTab->iPKey)>=0 ); + || pTab->iPKey<0 || sqlite3TableColumnToIndex(pIndex, pTab->iPKey)>=0 ); recomputeColumnsNotIndexed(pIndex); if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){ pIndex->isCovering = 1; for(j=0; jnCol; j++){ if( j==pTab->iPKey ) continue; - if( sqlite3ColumnOfIndex(pIndex,j)>=0 ) continue; + if( sqlite3TableColumnToIndex(pIndex,j)>=0 ) continue; pIndex->isCovering = 0; break; } @@ -3725,26 +3929,9 @@ void sqlite3CreateIndex( sqlite3VdbeJumpHere(v, pIndex->tnum); } } - - /* When adding an index to the list of indices for a table, make - ** sure all indices labeled OE_Replace come after all those labeled - ** OE_Ignore. This is necessary for the correct constraint check - ** processing (in sqlite3GenerateConstraintChecks()) as part of - ** UPDATE and INSERT statements. - */ if( db->init.busy || pTblName==0 ){ - if( onError!=OE_Replace || pTab->pIndex==0 - || pTab->pIndex->onError==OE_Replace){ - pIndex->pNext = pTab->pIndex; - pTab->pIndex = pIndex; - }else{ - Index *pOther = pTab->pIndex; - while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){ - pOther = pOther->pNext; - } - pIndex->pNext = pOther->pNext; - pOther->pNext = pIndex; - } + pIndex->pNext = pTab->pIndex; + pTab->pIndex = pIndex; pIndex = 0; } else if( IN_RENAME_OBJECT ){ @@ -3756,6 +3943,21 @@ void sqlite3CreateIndex( /* Clean up before exiting */ exit_create_index: if( pIndex ) sqlite3FreeIndex(db, pIndex); + if( pTab ){ /* Ensure all REPLACE indexes are at the end of the list */ + Index **ppFrom = &pTab->pIndex; + Index *pThis; + for(ppFrom=&pTab->pIndex; (pThis = *ppFrom)!=0; ppFrom=&pThis->pNext){ + Index *pNext; + if( pThis->onError!=OE_Replace ) continue; + while( (pNext = pThis->pNext)!=0 && pNext->onError!=OE_Replace ){ + *ppFrom = pNext; + pThis->pNext = pNext->pNext; + pNext->pNext = pThis; + ppFrom = &pNext->pNext; + } + break; + } + } sqlite3ExprDelete(db, pPIWhere); sqlite3ExprListDelete(db, pList); sqlite3SrcListDelete(db, pTblName); diff --git a/src/callback.c b/src/callback.c index ad53bd4d..3d991901 100644 --- a/src/callback.c +++ b/src/callback.c @@ -65,51 +65,6 @@ static int synthCollSeq(sqlite3 *db, CollSeq *pColl){ return SQLITE_ERROR; } -/* -** This function is responsible for invoking the collation factory callback -** or substituting a collation sequence of a different encoding when the -** requested collation sequence is not available in the desired encoding. -** -** If it is not NULL, then pColl must point to the database native encoding -** collation sequence with name zName, length nName. -** -** The return value is either the collation sequence to be used in database -** db for collation type name zName, length nName, or NULL, if no collation -** sequence can be found. If no collation is found, leave an error message. -** -** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq() -*/ -CollSeq *sqlite3GetCollSeq( - Parse *pParse, /* Parsing context */ - u8 enc, /* The desired encoding for the collating sequence */ - CollSeq *pColl, /* Collating sequence with native encoding, or NULL */ - const char *zName /* Collating sequence name */ -){ - CollSeq *p; - sqlite3 *db = pParse->db; - - p = pColl; - if( !p ){ - p = sqlite3FindCollSeq(db, enc, zName, 0); - } - if( !p || !p->xCmp ){ - /* No collation sequence of this type for this encoding is registered. - ** Call the collation factory to see if it can supply us with one. - */ - callCollNeeded(db, enc, zName); - p = sqlite3FindCollSeq(db, enc, zName, 0); - } - if( p && !p->xCmp && synthCollSeq(db, p) ){ - p = 0; - } - assert( !p || p->xCmp ); - if( p==0 ){ - sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); - pParse->rc = SQLITE_ERROR_MISSING_COLLSEQ; - } - return p; -} - /* ** This routine is called on a collation sequence before it is used to ** check that it is defined. An undefined collation sequence exists when @@ -202,10 +157,10 @@ static CollSeq *findCollSeqEntry( ** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq() */ CollSeq *sqlite3FindCollSeq( - sqlite3 *db, - u8 enc, - const char *zName, - int create + sqlite3 *db, /* Database connection to search */ + u8 enc, /* Desired text encoding */ + const char *zName, /* Name of the collating sequence. Might be NULL */ + int create /* True to create CollSeq if doesn't already exist */ ){ CollSeq *pColl; if( zName ){ @@ -219,6 +174,85 @@ CollSeq *sqlite3FindCollSeq( return pColl; } +/* +** This function is responsible for invoking the collation factory callback +** or substituting a collation sequence of a different encoding when the +** requested collation sequence is not available in the desired encoding. +** +** If it is not NULL, then pColl must point to the database native encoding +** collation sequence with name zName, length nName. +** +** The return value is either the collation sequence to be used in database +** db for collation type name zName, length nName, or NULL, if no collation +** sequence can be found. If no collation is found, leave an error message. +** +** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq() +*/ +CollSeq *sqlite3GetCollSeq( + Parse *pParse, /* Parsing context */ + u8 enc, /* The desired encoding for the collating sequence */ + CollSeq *pColl, /* Collating sequence with native encoding, or NULL */ + const char *zName /* Collating sequence name */ +){ + CollSeq *p; + sqlite3 *db = pParse->db; + + p = pColl; + if( !p ){ + p = sqlite3FindCollSeq(db, enc, zName, 0); + } + if( !p || !p->xCmp ){ + /* No collation sequence of this type for this encoding is registered. + ** Call the collation factory to see if it can supply us with one. + */ + callCollNeeded(db, enc, zName); + p = sqlite3FindCollSeq(db, enc, zName, 0); + } + if( p && !p->xCmp && synthCollSeq(db, p) ){ + p = 0; + } + assert( !p || p->xCmp ); + if( p==0 ){ + sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); + pParse->rc = SQLITE_ERROR_MISSING_COLLSEQ; + } + return p; +} + +/* +** This function returns the collation sequence for database native text +** encoding identified by the string zName. +** +** If the requested collation sequence is not available, or not available +** in the database native encoding, the collation factory is invoked to +** request it. If the collation factory does not supply such a sequence, +** and the sequence is available in another text encoding, then that is +** returned instead. +** +** If no versions of the requested collations sequence are available, or +** another error occurs, NULL is returned and an error message written into +** pParse. +** +** This routine is a wrapper around sqlite3FindCollSeq(). This routine +** invokes the collation factory if the named collation cannot be found +** and generates an error message. +** +** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq() +*/ +CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){ + sqlite3 *db = pParse->db; + u8 enc = ENC(db); + u8 initbusy = db->init.busy; + CollSeq *pColl; + + pColl = sqlite3FindCollSeq(db, enc, zName, initbusy); + if( !initbusy && (!pColl || !pColl->xCmp) ){ + pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName); + } + + return pColl; +} + /* During the search for the best function definition, this procedure ** is called to test how well the function passed as the first argument ** matches the request for a function with nArg arguments in a system @@ -254,12 +288,13 @@ static int matchQuality( u8 enc /* Desired text encoding */ ){ int match; - - /* nArg of -2 is a special case */ - if( nArg==(-2) ) return (p->xSFunc==0) ? 0 : FUNC_PERFECT_MATCH; + assert( p->nArg>=-1 ); /* Wrong number of arguments means "no match" */ - if( p->nArg!=nArg && p->nArg>=0 ) return 0; + if( p->nArg!=nArg ){ + if( nArg==(-2) ) return (p->xSFunc==0) ? 0 : FUNC_PERFECT_MATCH; + if( p->nArg>=0 ) return 0; + } /* Give a better score to a function with a specific number of arguments ** than to function that accepts any number of arguments. */ diff --git a/src/date.c b/src/date.c index e2712106..6a8defc6 100644 --- a/src/date.c +++ b/src/date.c @@ -688,7 +688,7 @@ static int parseModifier( r = p->s*1000.0 + 210866760000000.0; if( r>=0.0 && r<464269060800000.0 ){ clearYMD_HMS_TZ(p); - p->iJD = (sqlite3_int64)r; + p->iJD = (sqlite3_int64)(r + 0.5); p->validJD = 1; p->rawS = 0; rc = 0; diff --git a/src/dbpage.c b/src/dbpage.c index 27c962d1..c4f0b539 100644 --- a/src/dbpage.c +++ b/src/dbpage.c @@ -73,6 +73,7 @@ static int dbpageConnect( DbpageTable *pTab = 0; int rc = SQLITE_OK; + sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); rc = sqlite3_declare_vtab(db, "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)"); if( rc==SQLITE_OK ){ diff --git a/src/dbstat.c b/src/dbstat.c index 9b72fb14..2fea48ce 100644 --- a/src/dbstat.c +++ b/src/dbstat.c @@ -12,7 +12,7 @@ ** ** This file contains an implementation of the "dbstat" virtual table. ** -** The dbstat virtual table is used to extract low-level formatting +** The dbstat virtual table is used to extract low-level storage ** information from an SQLite database in order to implement the ** "sqlite3_analyzer" utility. See the ../tool/spaceanal.tcl script ** for an example implementation. @@ -56,27 +56,30 @@ ** ** '/1c2/000/' // Left-most child of 451st child of root */ -#define VTAB_SCHEMA \ - "CREATE TABLE xx( " \ - " name TEXT, /* Name of table or index */" \ - " path TEXT, /* Path to page from root */" \ - " pageno INTEGER, /* Page number */" \ - " pagetype TEXT, /* 'internal', 'leaf' or 'overflow' */" \ - " ncell INTEGER, /* Cells on page (0 for overflow) */" \ - " payload INTEGER, /* Bytes of payload on this page */" \ - " unused INTEGER, /* Bytes of unused space on this page */" \ - " mx_payload INTEGER, /* Largest payload size of all cells */" \ - " pgoffset INTEGER, /* Offset of page in file */" \ - " pgsize INTEGER, /* Size of the page */" \ - " schema TEXT HIDDEN /* Database schema being analyzed */" \ - ");" - +static const char zDbstatSchema[] = + "CREATE TABLE x(" + " name TEXT," /* 0 Name of table or index */ + " path TEXT," /* 1 Path to page from root (NULL for agg) */ + " pageno INTEGER," /* 2 Page number (page count for aggregates) */ + " pagetype TEXT," /* 3 'internal', 'leaf', 'overflow', or NULL */ + " ncell INTEGER," /* 4 Cells on page (0 for overflow) */ + " payload INTEGER," /* 5 Bytes of payload on this page */ + " unused INTEGER," /* 6 Bytes of unused space on this page */ + " mx_payload INTEGER," /* 7 Largest payload size of all cells */ + " pgoffset INTEGER," /* 8 Offset of page in file (NULL for agg) */ + " pgsize INTEGER," /* 9 Size of the page (sum for aggregate) */ + " schema TEXT HIDDEN," /* 10 Database schema being analyzed */ + " aggregate BOOLEAN HIDDEN" /* 11 aggregate info for each table */ + ")" +; +/* Forward reference to data structured used in this module */ typedef struct StatTable StatTable; typedef struct StatCursor StatCursor; typedef struct StatPage StatPage; typedef struct StatCell StatCell; +/* Size information for a single cell within a btree page */ struct StatCell { int nLocal; /* Bytes of local payload */ u32 iChildPg; /* Child node (or 0 if this is a leaf) */ @@ -86,10 +89,11 @@ struct StatCell { int iOvfl; /* Iterates through aOvfl[] */ }; +/* Size information for a single btree page */ struct StatPage { - u32 iPgno; - DbPage *pPg; - int iCell; + u32 iPgno; /* Page number */ + DbPage *pPg; /* Page content */ + int iCell; /* Current cell */ char *zPath; /* Path to this page */ @@ -99,34 +103,38 @@ struct StatPage { int nUnused; /* Number of unused bytes on page */ StatCell *aCell; /* Array of parsed cells */ u32 iRightChildPg; /* Right-child page number (or 0) */ - int nMxPayload; /* Largest payload of any cell on this page */ + int nMxPayload; /* Largest payload of any cell on the page */ }; +/* The cursor for scanning the dbstat virtual table */ struct StatCursor { - sqlite3_vtab_cursor base; + sqlite3_vtab_cursor base; /* base class. MUST BE FIRST! */ sqlite3_stmt *pStmt; /* Iterates through set of root pages */ - int isEof; /* After pStmt has returned SQLITE_DONE */ + u8 isEof; /* After pStmt has returned SQLITE_DONE */ + u8 isAgg; /* Aggregate results for each table */ int iDb; /* Schema used for this query */ - StatPage aPage[32]; + StatPage aPage[32]; /* Pages in path to current page */ int iPage; /* Current entry in aPage[] */ /* Values to return. */ + u32 iPageno; /* Value of 'pageno' column */ char *zName; /* Value of 'name' column */ char *zPath; /* Value of 'path' column */ - u32 iPageno; /* Value of 'pageno' column */ char *zPagetype; /* Value of 'pagetype' column */ + int nPage; /* Number of pages in current btree */ int nCell; /* Value of 'ncell' column */ - int nPayload; /* Value of 'payload' column */ - int nUnused; /* Value of 'unused' column */ int nMxPayload; /* Value of 'mx_payload' column */ + i64 nUnused; /* Value of 'unused' column */ + i64 nPayload; /* Value of 'payload' column */ i64 iOffset; /* Value of 'pgOffset' column */ - int szPage; /* Value of 'pgSize' column */ + i64 szPage; /* Value of 'pgSize' column */ }; +/* An instance of the DBSTAT virtual table */ struct StatTable { - sqlite3_vtab base; - sqlite3 *db; + sqlite3_vtab base; /* base class. MUST BE FIRST! */ + sqlite3 *db; /* Database connection that owns this vtab */ int iDb; /* Index of database to analyze */ }; @@ -135,7 +143,7 @@ struct StatTable { #endif /* -** Connect to or create a statvfs virtual table. +** Connect to or create a new DBSTAT virtual table. */ static int statConnect( sqlite3 *db, @@ -159,7 +167,8 @@ static int statConnect( }else{ iDb = 0; } - rc = sqlite3_declare_vtab(db, VTAB_SCHEMA); + sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); + rc = sqlite3_declare_vtab(db, zDbstatSchema); if( rc==SQLITE_OK ){ pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable)); if( pTab==0 ) rc = SQLITE_NOMEM_BKPT; @@ -177,7 +186,7 @@ static int statConnect( } /* -** Disconnect from or destroy a statvfs virtual table. +** Disconnect from or destroy the DBSTAT virtual table. */ static int statDisconnect(sqlite3_vtab *pVtab){ sqlite3_free(pVtab); @@ -185,14 +194,20 @@ static int statDisconnect(sqlite3_vtab *pVtab){ } /* -** There is no "best-index". This virtual table always does a linear -** scan. However, a schema=? constraint should cause this table to -** operate on a different database schema, so check for it. +** Compute the best query strategy and return the result in idxNum. ** -** idxNum is normally 0, but will be 1 if a schema=? constraint exists. +** idxNum-Bit Meaning +** ---------- ---------------------------------------------- +** 0x01 There is a schema=? term in the WHERE clause +** 0x02 There is a name=? term in the WHERE clause +** 0x04 There is an aggregate=? term in the WHERE clause +** 0x08 Output should be ordered by name and path */ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int i; + int iSchema = -1; + int iName = -1; + int iAgg = -1; /* Look for a valid schema=? constraint. If found, change the idxNum to ** 1 and request the value of that constraint be sent to xFilter. And @@ -200,16 +215,40 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ ** used. */ for(i=0; inConstraint; i++){ - if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue; - if( pIdxInfo->aConstraint[i].usable==0 ) return SQLITE_CONSTRAINT; if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; - pIdxInfo->idxNum = 1; - pIdxInfo->estimatedCost = 1.0; - pIdxInfo->aConstraintUsage[i].argvIndex = 1; - pIdxInfo->aConstraintUsage[i].omit = 1; - break; + if( pIdxInfo->aConstraint[i].usable==0 ){ + /* Force DBSTAT table should always be the right-most table in a join */ + return SQLITE_CONSTRAINT; + } + switch( pIdxInfo->aConstraint[i].iColumn ){ + case 0: { /* name */ + iName = i; + break; + } + case 10: { /* schema */ + iSchema = i; + break; + } + case 11: { /* aggregate */ + iAgg = i; + break; + } + } } - + i = 0; + if( iSchema>=0 ){ + pIdxInfo->aConstraintUsage[iSchema].argvIndex = ++i; + pIdxInfo->idxNum |= 0x01; + } + if( iName>=0 ){ + pIdxInfo->aConstraintUsage[iName].argvIndex = ++i; + pIdxInfo->idxNum |= 0x02; + } + if( iAgg>=0 ){ + pIdxInfo->aConstraintUsage[iAgg].argvIndex = ++i; + pIdxInfo->idxNum |= 0x04; + } + pIdxInfo->estimatedCost = 1.0; /* Records are always returned in ascending order of (name, path). ** If this will satisfy the client, set the orderByConsumed flag so that @@ -227,13 +266,14 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ ) ){ pIdxInfo->orderByConsumed = 1; + pIdxInfo->idxNum |= 0x08; } return SQLITE_OK; } /* -** Open a new statvfs cursor. +** Open a new DBSTAT cursor. */ static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ StatTable *pTab = (StatTable *)pVTab; @@ -283,8 +323,18 @@ static void statResetCsr(StatCursor *pCsr){ pCsr->isEof = 0; } +/* Resize the space-used counters inside of the cursor */ +static void statResetCounts(StatCursor *pCsr){ + pCsr->nCell = 0; + pCsr->nMxPayload = 0; + pCsr->nUnused = 0; + pCsr->nPayload = 0; + pCsr->szPage = 0; + pCsr->nPage = 0; +} + /* -** Close a statvfs cursor. +** Close a DBSTAT cursor. */ static int statClose(sqlite3_vtab_cursor *pCursor){ StatCursor *pCsr = (StatCursor *)pCursor; @@ -294,11 +344,15 @@ static int statClose(sqlite3_vtab_cursor *pCursor){ return SQLITE_OK; } -static void getLocalPayload( +/* +** For a single cell on a btree page, compute the number of bytes of +** content (payload) stored on that page. That is to say, compute the +** number of bytes of content not found on overflow pages. +*/ +static int getLocalPayload( int nUsable, /* Usable bytes per page */ u8 flags, /* Page flags */ - int nTotal, /* Total record (payload) size */ - int *pnLocal /* OUT: Bytes stored locally */ + int nTotal /* Total record (payload) size */ ){ int nLocal; int nMinLocal; @@ -314,9 +368,12 @@ static void getLocalPayload( nLocal = nMinLocal + (nTotal - nMinLocal) % (nUsable - 4); if( nLocal>nMaxLocal ) nLocal = nMinLocal; - *pnLocal = nLocal; + return nLocal; } +/* Populate the StatPage object with information about the all +** cells found on the page currently under analysis. +*/ static int statDecodePage(Btree *pBt, StatPage *p){ int nUnused; int iOff; @@ -387,7 +444,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){ iOff += sqlite3GetVarint(&aData[iOff], &dummy); } if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload; - getLocalPayload(nUsable, p->flags, nPayload, &nLocal); + nLocal = getLocalPayload(nUsable, p->flags, nPayload); if( nLocal<0 ) goto statPageIsCorrupt; pCell->nLocal = nLocal; assert( nPayload>=(u32)nLocal ); @@ -437,23 +494,25 @@ static void statSizeAndOffset(StatCursor *pCsr){ sqlite3_file *fd; sqlite3_int64 x[2]; - /* The default page size and offset */ - pCsr->szPage = sqlite3BtreeGetPageSize(pBt); - pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1); - - /* If connected to a ZIPVFS backend, override the page size and - ** offset with actual values obtained from ZIPVFS. + /* If connected to a ZIPVFS backend, find the page size and + ** offset from ZIPVFS. */ fd = sqlite3PagerFile(pPager); x[0] = pCsr->iPageno; if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){ pCsr->iOffset = x[0]; - pCsr->szPage = (int)x[1]; + pCsr->szPage += x[1]; + }else{ + /* Not ZIPVFS: The default page size and offset */ + pCsr->szPage += sqlite3BtreeGetPageSize(pBt); + pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1); } } /* -** Move a statvfs cursor to the next entry in the file. +** Move a DBSTAT cursor to the next entry. Normally, the next +** entry will be the next page, but in aggregated mode (pCsr->isAgg!=0), +** the next entry is the next btree. */ static int statNext(sqlite3_vtab_cursor *pCursor){ int rc; @@ -469,6 +528,8 @@ static int statNext(sqlite3_vtab_cursor *pCursor){ statNextRestart: if( pCsr->aPage[0].pPg==0 ){ + /* Start measuring space on the next btree */ + statResetCounts(pCsr); rc = sqlite3_step(pCsr->pStmt); if( rc==SQLITE_ROW ){ int nPage; @@ -481,44 +542,47 @@ statNextRestart: rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg, 0); pCsr->aPage[0].iPgno = iRoot; pCsr->aPage[0].iCell = 0; - pCsr->aPage[0].zPath = z = sqlite3_mprintf("/"); + if( !pCsr->isAgg ){ + pCsr->aPage[0].zPath = z = sqlite3_mprintf("/"); + if( z==0 ) rc = SQLITE_NOMEM_BKPT; + } pCsr->iPage = 0; - if( z==0 ) rc = SQLITE_NOMEM_BKPT; + pCsr->nPage = 1; }else{ pCsr->isEof = 1; return sqlite3_reset(pCsr->pStmt); } }else{ - - /* Page p itself has already been visited. */ + /* Continue analyzing the btree previously started */ StatPage *p = &pCsr->aPage[pCsr->iPage]; - + if( !pCsr->isAgg ) statResetCounts(pCsr); while( p->iCellnCell ){ StatCell *pCell = &p->aCell[p->iCell]; - if( pCell->iOvflnOvfl ){ - int nUsable; + while( pCell->iOvflnOvfl ){ + int nUsable, iOvfl; sqlite3BtreeEnter(pBt); nUsable = sqlite3BtreeGetPageSize(pBt) - sqlite3BtreeGetReserveNoMutex(pBt); sqlite3BtreeLeave(pBt); - pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0); - pCsr->iPageno = pCell->aOvfl[pCell->iOvfl]; - pCsr->zPagetype = "overflow"; - pCsr->nCell = 0; - pCsr->nMxPayload = 0; - pCsr->zPath = z = sqlite3_mprintf( - "%s%.3x+%.6x", p->zPath, p->iCell, pCell->iOvfl - ); - if( pCell->iOvflnOvfl-1 ){ - pCsr->nUnused = 0; - pCsr->nPayload = nUsable - 4; - }else{ - pCsr->nPayload = pCell->nLastOvfl; - pCsr->nUnused = nUsable - 4 - pCsr->nPayload; - } - pCell->iOvfl++; + pCsr->nPage++; statSizeAndOffset(pCsr); - return z==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK; + if( pCell->iOvflnOvfl-1 ){ + pCsr->nPayload += nUsable - 4; + }else{ + pCsr->nPayload += pCell->nLastOvfl; + pCsr->nUnused += nUsable - 4 - pCell->nLastOvfl; + } + iOvfl = pCell->iOvfl; + pCell->iOvfl++; + if( !pCsr->isAgg ){ + pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0); + pCsr->iPageno = pCell->aOvfl[iOvfl]; + pCsr->zPagetype = "overflow"; + pCsr->zPath = z = sqlite3_mprintf( + "%s%.3x+%.6x", p->zPath, p->iCell, iOvfl + ); + return z==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK; + } } if( p->iRightChildPg ) break; p->iCell++; @@ -526,8 +590,13 @@ statNextRestart: if( !p->iRightChildPg || p->iCell>p->nCell ){ statClearPage(p); - if( pCsr->iPage==0 ) return statNext(pCursor); - pCsr->iPage--; + if( pCsr->iPage>0 ){ + pCsr->iPage--; + }else if( pCsr->isAgg ){ + /* label-statNext-done: When computing aggregate space usage over + ** an entire btree, this is the exit point from this function */ + return SQLITE_OK; + } goto statNextRestart; /* Tail recursion */ } pCsr->iPage++; @@ -543,10 +612,13 @@ statNextRestart: p[1].iPgno = p->aCell[p->iCell].iChildPg; } rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg, 0); + pCsr->nPage++; p[1].iCell = 0; - p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell); + if( !pCsr->isAgg ){ + p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell); + if( z==0 ) rc = SQLITE_NOMEM_BKPT; + } p->iCell++; - if( z==0 ) rc = SQLITE_NOMEM_BKPT; } @@ -576,16 +648,23 @@ statNextRestart: pCsr->zPagetype = "corrupted"; break; } - pCsr->nCell = p->nCell; - pCsr->nUnused = p->nUnused; - pCsr->nMxPayload = p->nMxPayload; - pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath); - if( z==0 ) rc = SQLITE_NOMEM_BKPT; + pCsr->nCell += p->nCell; + pCsr->nUnused += p->nUnused; + if( p->nMxPayload>pCsr->nMxPayload ) pCsr->nMxPayload = p->nMxPayload; + if( !pCsr->isAgg ){ + pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath); + if( z==0 ) rc = SQLITE_NOMEM_BKPT; + } nPayload = 0; for(i=0; inCell; i++){ nPayload += p->aCell[i].nLocal; } - pCsr->nPayload = nPayload; + pCsr->nPayload += nPayload; + + /* If computing aggregate space usage by btree, continue with the + ** next page. The loop will exit via the return at label-statNext-done + */ + if( pCsr->isAgg ) goto statNextRestart; } } @@ -597,6 +676,10 @@ static int statEof(sqlite3_vtab_cursor *pCursor){ return pCsr->isEof; } +/* Initialize a cursor according to the query plan idxNum using the +** arguments in argv[0]. See statBestIndex() for a description of the +** meaning of the bits in idxNum. +*/ static int statFilter( sqlite3_vtab_cursor *pCursor, int idxNum, const char *idxStr, @@ -604,29 +687,52 @@ static int statFilter( ){ StatCursor *pCsr = (StatCursor *)pCursor; StatTable *pTab = (StatTable*)(pCursor->pVtab); - char *zSql; - int rc = SQLITE_OK; + sqlite3_str *pSql; /* Query of btrees to analyze */ + char *zSql; /* String value of pSql */ + int iArg = 0; /* Count of argv[] parameters used so far */ + int rc = SQLITE_OK; /* Result of this operation */ + const char *zName = 0; /* Only provide analysis of this table */ - if( idxNum==1 ){ - const char *zDbase = (const char*)sqlite3_value_text(argv[0]); + statResetCsr(pCsr); + sqlite3_finalize(pCsr->pStmt); + pCsr->pStmt = 0; + if( idxNum & 0x01 ){ + /* schema=? constraint is present. Get its value */ + const char *zDbase = (const char*)sqlite3_value_text(argv[iArg++]); pCsr->iDb = sqlite3FindDbName(pTab->db, zDbase); if( pCsr->iDb<0 ){ - sqlite3_free(pCursor->pVtab->zErrMsg); - pCursor->pVtab->zErrMsg = sqlite3_mprintf("no such schema: %s", zDbase); - return pCursor->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM_BKPT; + pCsr->iDb = 0; + pCsr->isEof = 1; + return SQLITE_OK; } }else{ pCsr->iDb = pTab->iDb; } - statResetCsr(pCsr); - sqlite3_finalize(pCsr->pStmt); - pCsr->pStmt = 0; - zSql = sqlite3_mprintf( - "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type" - " UNION ALL " - "SELECT name, rootpage, type" - " FROM \"%w\".sqlite_master WHERE rootpage!=0" - " ORDER BY name", pTab->db->aDb[pCsr->iDb].zDbSName); + if( idxNum & 0x02 ){ + /* name=? constraint is present */ + zName = (const char*)sqlite3_value_text(argv[iArg++]); + } + if( idxNum & 0x04 ){ + /* aggregate=? constraint is present */ + pCsr->isAgg = sqlite3_value_double(argv[iArg++])!=0.0; + }else{ + pCsr->isAgg = 0; + } + pSql = sqlite3_str_new(pTab->db); + sqlite3_str_appendf(pSql, + "SELECT * FROM (" + "SELECT 'sqlite_master' AS name,1 AS rootpage,'table' AS type" + " UNION ALL " + "SELECT name,rootpage,type" + " FROM \"%w\".sqlite_master WHERE rootpage!=0)", + pTab->db->aDb[pCsr->iDb].zDbSName); + if( zName ){ + sqlite3_str_appendf(pSql, "WHERE name=%Q", zName); + } + if( idxNum & 0x08 ){ + sqlite3_str_appendf(pSql, " ORDER BY name"); + } + zSql = sqlite3_str_finish(pSql); if( zSql==0 ){ return SQLITE_NOMEM_BKPT; }else{ @@ -651,13 +757,21 @@ static int statColumn( sqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_TRANSIENT); break; case 1: /* path */ - sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT); + if( !pCsr->isAgg ){ + sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT); + } break; case 2: /* pageno */ - sqlite3_result_int64(ctx, pCsr->iPageno); + if( pCsr->isAgg ){ + sqlite3_result_int64(ctx, pCsr->nPage); + }else{ + sqlite3_result_int64(ctx, pCsr->iPageno); + } break; case 3: /* pagetype */ - sqlite3_result_text(ctx, pCsr->zPagetype, -1, SQLITE_STATIC); + if( !pCsr->isAgg ){ + sqlite3_result_text(ctx, pCsr->zPagetype, -1, SQLITE_STATIC); + } break; case 4: /* ncell */ sqlite3_result_int(ctx, pCsr->nCell); @@ -672,17 +786,23 @@ static int statColumn( sqlite3_result_int(ctx, pCsr->nMxPayload); break; case 8: /* pgoffset */ - sqlite3_result_int64(ctx, pCsr->iOffset); + if( !pCsr->isAgg ){ + sqlite3_result_int64(ctx, pCsr->iOffset); + } break; case 9: /* pgsize */ sqlite3_result_int(ctx, pCsr->szPage); break; - default: { /* schema */ + case 10: { /* schema */ sqlite3 *db = sqlite3_context_db_handle(ctx); int iDb = pCsr->iDb; sqlite3_result_text(ctx, db->aDb[iDb].zDbSName, -1, SQLITE_STATIC); break; } + default: { /* aggregate */ + sqlite3_result_int(ctx, pCsr->isAgg); + break; + } } return SQLITE_OK; } diff --git a/src/delete.c b/src/delete.c index e3a0abc2..0a83f1b6 100644 --- a/src/delete.c +++ b/src/delete.c @@ -70,11 +70,7 @@ static int tabIsReadOnly(Parse *pParse, Table *pTab){ return sqlite3WritableSchema(db)==0 && pParse->nested==0; } assert( pTab->tabFlags & TF_Shadow ); - return (db->flags & SQLITE_Defensive)!=0 -#ifndef SQLITE_OMIT_VIRTUALTABLE - && db->pVtabCtx==0 -#endif - && db->nVdbeExec==0; + return sqlite3ReadOnlyShadowTables(db); } /* @@ -737,7 +733,8 @@ void sqlite3GenerateRowDelete( testcase( mask!=0xffffffff && iCol==31 ); testcase( mask!=0xffffffff && iCol==32 ); if( mask==0xffffffff || (iCol<=31 && (mask & MASKBIT32(iCol))!=0) ){ - sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+iCol+1); + int kk = sqlite3TableColumnToStorage(pTab, iCol); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+kk+1); } } @@ -917,6 +914,8 @@ int sqlite3GenerateIndexKey( sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, SQLITE_JUMPIFNULL); pParse->iSelfTab = 0; + pPrior = 0; /* Ticket a9efb42811fa41ee 2019-11-02; + ** pPartIdxWhere may have corrupted regPrior registers */ }else{ *piPartIdxLabel = 0; } diff --git a/src/expr.c b/src/expr.c index 2cc2d337..d82ef8b8 100644 --- a/src/expr.c +++ b/src/expr.c @@ -70,6 +70,9 @@ char sqlite3ExprAffinity(Expr *pExpr){ pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr ); } + if( op==TK_VECTOR ){ + return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); + } return pExpr->affExpr; } @@ -172,6 +175,10 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ p = p->pLeft; continue; } + if( op==TK_VECTOR ){ + p = p->x.pList->a[0].pExpr; + continue; + } if( op==TK_COLLATE ){ pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); break; @@ -183,12 +190,12 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ Expr *pNext = p->pRight; /* The Expr.x union is never used at the same time as Expr.pRight */ assert( p->x.pList==0 || p->pRight==0 ); - /* p->flags holds EP_Collate and p->pLeft->flags does not. And - ** p->x.pSelect cannot. So if p->x.pLeft exists, it must hold at - ** least one EP_Collate. Thus the following two ALWAYS. */ - if( p->x.pList!=0 && ALWAYS(!ExprHasProperty(p, EP_xIsSelect)) ){ + if( p->x.pList!=0 + && !db->mallocFailed + && ALWAYS(!ExprHasProperty(p, EP_xIsSelect)) + ){ int i; - for(i=0; ALWAYS(ix.pList->nExpr); i++){ + for(i=0; ix.pList->nExpr; i++){ if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){ pNext = p->x.pList->a[i].pExpr; break; @@ -336,6 +343,22 @@ CollSeq *sqlite3BinaryCompareCollSeq( return pColl; } +/* Expresssion p is a comparison operator. Return a collation sequence +** appropriate for the comparison operator. +** +** This is normally just a wrapper around sqlite3BinaryCompareCollSeq(). +** However, if the OP_Commuted flag is set, then the order of the operands +** is reversed in the sqlite3BinaryCompareCollSeq() call so that the +** correct collating sequence is found. +*/ +CollSeq *sqlite3ExprCompareCollSeq(Parse *pParse, Expr *p){ + if( ExprHasProperty(p, EP_Commuted) ){ + return sqlite3BinaryCompareCollSeq(pParse, p->pRight, p->pLeft); + }else{ + return sqlite3BinaryCompareCollSeq(pParse, p->pLeft, p->pRight); + } +} + /* ** Generate code for a comparison operator. */ @@ -346,13 +369,19 @@ static int codeCompare( int opcode, /* The comparison opcode */ int in1, int in2, /* Register holding operands */ int dest, /* Jump here if true. */ - int jumpIfNull /* If true, jump if either operand is NULL */ + int jumpIfNull, /* If true, jump if either operand is NULL */ + int isCommuted /* The comparison has been commuted */ ){ int p5; int addr; CollSeq *p4; - p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); + if( pParse->nErr ) return 0; + if( isCommuted ){ + p4 = sqlite3BinaryCompareCollSeq(pParse, pRight, pLeft); + }else{ + p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); + } p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, (void*)p4, P4_COLLSEQ); @@ -563,7 +592,9 @@ static void codeVectorCompare( int regRight = 0; u8 opx = op; int addrDone = sqlite3VdbeMakeLabel(pParse); + int isCommuted = ExprHasProperty(pExpr,EP_Commuted); + if( pParse->nErr ) return; if( nLeft!=sqlite3ExprVectorSize(pRight) ){ sqlite3ErrorMsg(pParse, "row value misused"); return; @@ -592,7 +623,7 @@ static void codeVectorCompare( assert( i>=0 && ifuncFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 ); + if( ExprHasProperty(pExpr, EP_FromDDL) ){ + if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0 + || (pParse->db->flags & SQLITE_TrustedSchema)==0 + ){ + /* Functions prohibited in triggers and views if: + ** (1) tagged with SQLITE_DIRECTONLY + ** (2) not tagged with SQLITE_INNOCUOUS (which means it + ** is tagged with SQLITE_FUNC_UNSAFE) and + ** SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning + ** that the schema is possibly tainted). + */ + sqlite3ErrorMsg(pParse, "unsafe use of %s()", pDef->zName); + } + } +} + /* ** Assign a variable number to an expression that encodes a wildcard ** in the original SQL statement. @@ -1407,12 +1474,11 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ pNewExpr->pLeft = pPriorSelectCol; } } - pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); - pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); + pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName); pItem->sortFlags = pOldItem->sortFlags; + pItem->eEName = pOldItem->eEName; pItem->done = 0; pItem->bNulls = pOldItem->bNulls; - pItem->bSpanIsTab = pOldItem->bSpanIsTab; pItem->bSorterRef = pOldItem->bSorterRef; pItem->u = pOldItem->u; } @@ -1579,9 +1645,9 @@ ExprList *sqlite3ExprListAppend( pList = pNew; } pItem = &pList->a[pList->nExpr++]; - assert( offsetof(struct ExprList_item,zName)==sizeof(pItem->pExpr) ); + assert( offsetof(struct ExprList_item,zEName)==sizeof(pItem->pExpr) ); assert( offsetof(struct ExprList_item,pExpr)==0 ); - memset(&pItem->zName,0,sizeof(*pItem)-offsetof(struct ExprList_item,zName)); + memset(&pItem->zEName,0,sizeof(*pItem)-offsetof(struct ExprList_item,zEName)); pItem->pExpr = pExpr; return pList; @@ -1638,7 +1704,7 @@ ExprList *sqlite3ExprListAppendVector( pList = sqlite3ExprListAppend(pParse, pList, pSubExpr); if( pList ){ assert( pList->nExpr==iFirst+i+1 ); - pList->a[pList->nExpr-1].zName = pColumns->a[i].zName; + pList->a[pList->nExpr-1].zEName = pColumns->a[i].zName; pColumns->a[i].zName = 0; } } @@ -1698,7 +1764,7 @@ void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int eNulls){ } /* -** Set the ExprList.a[].zName element of the most recently added item +** Set the ExprList.a[].zEName element of the most recently added item ** on the expression list. ** ** pList might be NULL following an OOM error. But pName should never be @@ -1716,11 +1782,12 @@ void sqlite3ExprListSetName( struct ExprList_item *pItem; assert( pList->nExpr>0 ); pItem = &pList->a[pList->nExpr-1]; - assert( pItem->zName==0 ); - pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n); - if( dequote ) sqlite3Dequote(pItem->zName); + assert( pItem->zEName==0 ); + assert( pItem->eEName==ENAME_NAME ); + pItem->zEName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n); + if( dequote ) sqlite3Dequote(pItem->zEName); if( IN_RENAME_OBJECT ){ - sqlite3RenameTokenMap(pParse, (void*)pItem->zName, pName); + sqlite3RenameTokenMap(pParse, (void*)pItem->zEName, pName); } } } @@ -1744,8 +1811,10 @@ void sqlite3ExprListSetSpan( if( pList ){ struct ExprList_item *pItem = &pList->a[pList->nExpr-1]; assert( pList->nExpr>0 ); - sqlite3DbFree(db, pItem->zSpan); - pItem->zSpan = sqlite3DbSpanDup(db, zStart, zEnd); + if( pItem->zEName==0 ){ + pItem->zEName = sqlite3DbSpanDup(db, zStart, zEnd); + pItem->eEName = ENAME_SPAN; + } } } @@ -1775,8 +1844,7 @@ static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){ assert( pList->nExpr>0 ); do{ sqlite3ExprDelete(db, pItem->pExpr); - sqlite3DbFree(db, pItem->zName); - sqlite3DbFree(db, pItem->zSpan); + sqlite3DbFree(db, pItem->zEName); pItem++; }while( --i>0 ); sqlite3DbFreeNN(db, pList); @@ -1814,19 +1882,34 @@ int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){ return WRC_Abort; } +/* +** Check the input string to see if it is "true" or "false" (in any case). +** +** If the string is.... Return +** "true" EP_IsTrue +** "false" EP_IsFalse +** anything else 0 +*/ +u32 sqlite3IsTrueOrFalse(const char *zIn){ + if( sqlite3StrICmp(zIn, "true")==0 ) return EP_IsTrue; + if( sqlite3StrICmp(zIn, "false")==0 ) return EP_IsFalse; + return 0; +} + + /* ** If the input expression is an ID with the name "true" or "false" ** then convert it into an TK_TRUEFALSE term. Return non-zero if ** the conversion happened, and zero if the expression is unaltered. */ int sqlite3ExprIdToTrueFalse(Expr *pExpr){ + u32 v; assert( pExpr->op==TK_ID || pExpr->op==TK_STRING ); if( !ExprHasProperty(pExpr, EP_Quoted) - && (sqlite3StrICmp(pExpr->u.zToken, "true")==0 - || sqlite3StrICmp(pExpr->u.zToken, "false")==0) + && (v = sqlite3IsTrueOrFalse(pExpr->u.zToken))!=0 ){ pExpr->op = TK_TRUEFALSE; - ExprSetProperty(pExpr, pExpr->u.zToken[4]==0 ? EP_IsTrue : EP_IsFalse); + ExprSetProperty(pExpr, v); return 1; } return 0; @@ -1888,10 +1971,11 @@ Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){ ** In all cases, the callbacks set Walker.eCode=0 and abort if the expression ** is found to not be a constant. ** -** The sqlite3ExprIsConstantOrFunction() is used for evaluating expressions -** in a CREATE TABLE statement. The Walker.eCode value is 5 when parsing -** an existing schema and 4 when processing a new statement. A bound -** parameter raises an error for new statements, but is silently converted +** The sqlite3ExprIsConstantOrFunction() is used for evaluating DEFAULT +** expressions in a CREATE TABLE statement. The Walker.eCode value is 5 +** when parsing an existing schema out of the sqlite_master table and 4 +** when processing a new CREATE TABLE statement. A bound parameter raises +** an error for new statements, but is silently converted ** to NULL for existing schemas. This allows sqlite_master tables that ** contain a bound parameter because they were generated by older versions ** of SQLite to be parsed by newer versions of SQLite without raising a @@ -1912,7 +1996,10 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ ** and either pWalker->eCode==4 or 5 or the function has the ** SQLITE_FUNC_CONST flag. */ case TK_FUNCTION: - if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc) ){ + if( (pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc)) + && !ExprHasProperty(pExpr, EP_WinFunc) + ){ + if( pWalker->eCode==5 ) ExprSetProperty(pExpr, EP_FromDDL); return WRC_Continue; }else{ pWalker->eCode = 0; @@ -2076,9 +2163,21 @@ int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){ } /* -** Walk an expression tree. Return non-zero if the expression is constant -** or a function call with constant arguments. Return and 0 if there -** are any variables. +** Walk an expression tree for the DEFAULT field of a column definition +** in a CREATE TABLE statement. Return non-zero if the expression is +** acceptable for use as a DEFAULT. That is to say, return non-zero if +** the expression is constant or a function call with constant arguments. +** Return and 0 if there are any variables. +** +** isInit is true when parsing from sqlite_master. isInit is false when +** processing a new CREATE TABLE statement. When isInit is true, parameters +** (such as ? or $abc) in the expression are converted into NULL. When +** isInit is false, parameters raise an error. Parameters should not be +** allowed in a CREATE TABLE statement, but some legacy versions of SQLite +** allowed it, so we need to support it when reading sqlite_master for +** backwards compatibility. +** +** If isInit is true, set EP_FromDDL on every TK_FUNCTION node. ** ** For the purposes of this function, a double-quoted string (ex: "abc") ** is considered a variable but a single-quoted string (ex: 'abc') is @@ -2175,7 +2274,9 @@ int sqlite3ExprCanBeNull(const Expr *p){ case TK_COLUMN: return ExprHasProperty(p, EP_CanBeNull) || p->y.pTab==0 || /* Reference to column of index on expression */ - (p->iColumn>=0 && p->y.pTab->aCol[p->iColumn].notNull==0); + (p->iColumn>=0 + && ALWAYS(p->y.pTab->aCol!=0) /* Defense against OOM problems */ + && p->y.pTab->aCol[p->iColumn].notNull==0); default: return 1; } @@ -2652,8 +2753,10 @@ static char *exprINAffinity(Parse *pParse, Expr *pExpr){ ** "sub-select returns N columns - expected M" */ void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){ - const char *zFmt = "sub-select returns %d columns - expected %d"; - sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect); + if( pParse->nErr==0 ){ + const char *zFmt = "sub-select returns %d columns - expected %d"; + sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect); + } } #endif @@ -3154,19 +3257,25 @@ static void sqlite3ExprCodeIN( if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){ sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull); } + sqlite3ReleaseTempReg(pParse, regToFree); if( iinExpr-1 || destIfNull!=destIfFalse ){ - sqlite3VdbeAddOp4(v, OP_Eq, rLhs, labelOk, r2, + int op = rLhs!=r2 ? OP_Eq : OP_NotNull; + sqlite3VdbeAddOp4(v, op, rLhs, labelOk, r2, (void*)pColl, P4_COLLSEQ); - VdbeCoverageIf(v, iinExpr-1); - VdbeCoverageIf(v, ii==pList->nExpr-1); + VdbeCoverageIf(v, iinExpr-1 && op==OP_Eq); + VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_Eq); + VdbeCoverageIf(v, iinExpr-1 && op==OP_NotNull); + VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_NotNull); sqlite3VdbeChangeP5(v, zAff[0]); }else{ + int op = rLhs!=r2 ? OP_Ne : OP_IsNull; assert( destIfNull==destIfFalse ); - sqlite3VdbeAddOp4(v, OP_Ne, rLhs, destIfFalse, r2, - (void*)pColl, P4_COLLSEQ); VdbeCoverage(v); + sqlite3VdbeAddOp4(v, op, rLhs, destIfFalse, r2, + (void*)pColl, P4_COLLSEQ); + VdbeCoverageIf(v, op==OP_Ne); + VdbeCoverageIf(v, op==OP_IsNull); sqlite3VdbeChangeP5(v, zAff[0] | SQLITE_JUMPIFNULL); } - sqlite3ReleaseTempReg(pParse, regToFree); } if( regCkNull ){ sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v); @@ -3186,6 +3295,7 @@ static void sqlite3ExprCodeIN( }else{ destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse); } + if( pParse->nErr ) goto sqlite3ExprCodeIN_finished; for(i=0; ipLeft, i); if( sqlite3ExprCanBeNull(p) ){ @@ -3367,16 +3477,45 @@ void sqlite3ExprCodeLoadIndexColumn( } } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +/* +** Generate code that will compute the value of generated column pCol +** and store the result in register regOut +*/ +void sqlite3ExprCodeGeneratedColumn( + Parse *pParse, + Column *pCol, + int regOut +){ + int iAddr; + Vdbe *v = pParse->pVdbe; + assert( v!=0 ); + assert( pParse->iSelfTab!=0 ); + if( pParse->iSelfTab>0 ){ + iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut); + }else{ + iAddr = 0; + } + sqlite3ExprCode(pParse, pCol->pDflt, regOut); + if( pCol->affinity>=SQLITE_AFF_TEXT ){ + sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1); + } + if( iAddr ) sqlite3VdbeJumpHere(v, iAddr); +} +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + /* ** Generate code to extract the value of the iCol-th column of a table. */ void sqlite3ExprCodeGetColumnOfTable( - Vdbe *v, /* The VDBE under construction */ + Vdbe *v, /* Parsing context */ Table *pTab, /* The table containing the value */ int iTabCur, /* The table cursor. Or the PK cursor for WITHOUT ROWID */ int iCol, /* Index of the column to extract */ int regOut /* Extract the value into this register */ ){ + Column *pCol; + assert( v!=0 ); if( pTab==0 ){ sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut); return; @@ -3384,14 +3523,36 @@ void sqlite3ExprCodeGetColumnOfTable( if( iCol<0 || iCol==pTab->iPKey ){ sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); }else{ - int op = IsVirtual(pTab) ? OP_VColumn : OP_Column; - int x = iCol; - if( !HasRowid(pTab) && !IsVirtual(pTab) ){ - x = sqlite3ColumnOfIndex(sqlite3PrimaryKeyIndex(pTab), iCol); + int op; + int x; + if( IsVirtual(pTab) ){ + op = OP_VColumn; + x = iCol; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + }else if( (pCol = &pTab->aCol[iCol])->colFlags & COLFLAG_VIRTUAL ){ + Parse *pParse = sqlite3VdbeParser(v); + if( pCol->colFlags & COLFLAG_BUSY ){ + sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pCol->zName); + }else{ + int savedSelfTab = pParse->iSelfTab; + pCol->colFlags |= COLFLAG_BUSY; + pParse->iSelfTab = iTabCur+1; + sqlite3ExprCodeGeneratedColumn(pParse, pCol, regOut); + pParse->iSelfTab = savedSelfTab; + pCol->colFlags &= ~COLFLAG_BUSY; + } + return; +#endif + }else if( !HasRowid(pTab) ){ + testcase( iCol!=sqlite3TableColumnToStorage(pTab, iCol) ); + x = sqlite3TableColumnToIndex(sqlite3PrimaryKeyIndex(pTab), iCol); + op = OP_Column; + }else{ + x = sqlite3TableColumnToStorage(pTab,iCol); + testcase( x!=iCol ); + op = OP_Column; } sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut); - } - if( iCol>=0 ){ sqlite3ColumnDefault(v, pTab, iCol, regOut); } } @@ -3411,11 +3572,11 @@ int sqlite3ExprCodeGetColumn( int iReg, /* Store results here */ u8 p5 /* P5 value for OP_Column + FLAGS */ ){ - Vdbe *v = pParse->pVdbe; - assert( v!=0 ); - sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg); + assert( pParse->pVdbe!=0 ); + sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pTab, iTable, iColumn, iReg); if( p5 ){ - sqlite3VdbeChangeP5(v, p5); + VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1); + if( pOp->opcode==OP_Column ) pOp->p5 = p5; } return iReg; } @@ -3425,7 +3586,6 @@ int sqlite3ExprCodeGetColumn( ** over to iTo..iTo+nReg-1. */ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ - assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo ); sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg); } @@ -3477,6 +3637,109 @@ static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){ return iResult; } +/* +** Generate code to implement special SQL functions that are implemented +** in-line rather than by using the usual callbacks. +*/ +static int exprCodeInlineFunction( + Parse *pParse, /* Parsing context */ + ExprList *pFarg, /* List of function arguments */ + int iFuncId, /* Function ID. One of the INTFUNC_... values */ + int target /* Store function result in this register */ +){ + int nFarg; + Vdbe *v = pParse->pVdbe; + assert( v!=0 ); + assert( pFarg!=0 ); + nFarg = pFarg->nExpr; + assert( nFarg>0 ); /* All in-line functions have at least one argument */ + switch( iFuncId ){ + case INLINEFUNC_coalesce: { + /* Attempt a direct implementation of the built-in COALESCE() and + ** IFNULL() functions. This avoids unnecessary evaluation of + ** arguments past the first non-NULL argument. + */ + int endCoalesce = sqlite3VdbeMakeLabel(pParse); + int i; + assert( nFarg>=2 ); + sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target); + for(i=1; ia[i].pExpr, target); + } + if( sqlite3VdbeGetOp(v, -1)->opcode==OP_Copy ){ + sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergable */ + } + sqlite3VdbeResolveLabel(v, endCoalesce); + break; + } + + default: { + /* The UNLIKELY() function is a no-op. The result is the value + ** of the first argument. + */ + assert( nFarg==1 || nFarg==2 ); + target = sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target); + break; + } + + /*********************************************************************** + ** Test-only SQL functions that are only usable if enabled + ** via SQLITE_TESTCTRL_INTERNAL_FUNCTIONS + */ + case INLINEFUNC_expr_compare: { + /* Compare two expressions using sqlite3ExprCompare() */ + assert( nFarg==2 ); + sqlite3VdbeAddOp2(v, OP_Integer, + sqlite3ExprCompare(0,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1), + target); + break; + } + + case INLINEFUNC_expr_implies_expr: { + /* Compare two expressions using sqlite3ExprImpliesExpr() */ + assert( nFarg==2 ); + sqlite3VdbeAddOp2(v, OP_Integer, + sqlite3ExprImpliesExpr(pParse,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1), + target); + break; + } + + case INLINEFUNC_implies_nonnull_row: { + /* REsult of sqlite3ExprImpliesNonNullRow() */ + Expr *pA1; + assert( nFarg==2 ); + pA1 = pFarg->a[1].pExpr; + if( pA1->op==TK_COLUMN ){ + sqlite3VdbeAddOp2(v, OP_Integer, + sqlite3ExprImpliesNonNullRow(pFarg->a[0].pExpr,pA1->iTable), + target); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + } + break; + } + +#ifdef SQLITE_DEBUG + case INLINEFUNC_affinity: { + /* The AFFINITY() function evaluates to a string that describes + ** the type affinity of the argument. This is used for testing of + ** the SQLite type logic. + */ + const char *azAff[] = { "blob", "text", "numeric", "integer", "real" }; + char aff; + assert( nFarg==1 ); + aff = sqlite3ExprAffinity(pFarg->a[0].pExpr); + sqlite3VdbeLoadString(v, target, + (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]); + break; + } +#endif + } + return target; +} + /* ** Generate code into the current Vdbe to evaluate the given @@ -3527,6 +3790,7 @@ expr_code_doover: } case TK_COLUMN: { int iTab = pExpr->iTable; + int iReg; if( ExprHasProperty(pExpr, EP_FixedCol) ){ /* This COLUMN expression is really a constant due to WHERE clause ** constraints, and that constant is coded by the pExpr->pLeft @@ -3534,8 +3798,13 @@ expr_code_doover: ** datatype by applying the Affinity of the table column to the ** constant. */ - int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); - int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); + int aff; + iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); + if( pExpr->y.pTab ){ + aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); + }else{ + aff = pExpr->affExpr; + } if( aff>SQLITE_AFF_BLOB ){ static const char zAff[] = "B\000C\000D\000E"; assert( SQLITE_AFF_BLOB=='A' ); @@ -3551,19 +3820,46 @@ expr_code_doover: } if( iTab<0 ){ if( pParse->iSelfTab<0 ){ - /* Generating CHECK constraints or inserting into partial index */ - assert( pExpr->y.pTab!=0 ); - assert( pExpr->iColumn>=XN_ROWID ); - assert( pExpr->iColumny.pTab->nCol ); - if( pExpr->iColumn>=0 - && pExpr->y.pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL - ){ - sqlite3VdbeAddOp2(v, OP_SCopy, pExpr->iColumn - pParse->iSelfTab, - target); + /* Other columns in the same row for CHECK constraints or + ** generated columns or for inserting into partial index. + ** The row is unpacked into registers beginning at + ** 0-(pParse->iSelfTab). The rowid (if any) is in a register + ** immediately prior to the first column. + */ + Column *pCol; + Table *pTab = pExpr->y.pTab; + int iSrc; + int iCol = pExpr->iColumn; + assert( pTab!=0 ); + assert( iCol>=XN_ROWID ); + assert( iColnCol ); + if( iCol<0 ){ + return -1-pParse->iSelfTab; + } + pCol = pTab->aCol + iCol; + testcase( iCol!=sqlite3TableColumnToStorage(pTab,iCol) ); + iSrc = sqlite3TableColumnToStorage(pTab, iCol) - pParse->iSelfTab; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( pCol->colFlags & COLFLAG_GENERATED ){ + if( pCol->colFlags & COLFLAG_BUSY ){ + sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", + pCol->zName); + return 0; + } + pCol->colFlags |= COLFLAG_BUSY; + if( pCol->colFlags & COLFLAG_NOTAVAIL ){ + sqlite3ExprCodeGeneratedColumn(pParse, pCol, iSrc); + } + pCol->colFlags &= ~(COLFLAG_BUSY|COLFLAG_NOTAVAIL); + return iSrc; + }else +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + if( pCol->affinity==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp2(v, OP_SCopy, iSrc, target); sqlite3VdbeAddOp1(v, OP_RealAffinity, target); return target; }else{ - return pExpr->iColumn - pParse->iSelfTab; + return iSrc; } }else{ /* Coding an expression that is part of an index where column names @@ -3571,9 +3867,13 @@ expr_code_doover: iTab = pParse->iSelfTab - 1; } } - return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, + iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, pExpr->iColumn, iTab, target, pExpr->op2); + if( pExpr->y.pTab==0 && pExpr->affExpr==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); + } + return iReg; } case TK_INTEGER: { codeInteger(pParse, pExpr, 0, target); @@ -3595,7 +3895,12 @@ expr_code_doover: sqlite3VdbeLoadString(v, target, pExpr->u.zToken); return target; } - case TK_NULL: { + default: { + /* Make NULL the default case so that if a bug causes an illegal + ** Expr node to be passed into this function, it will be handled + ** sanely and not crash. But keep the assert() to bring the problem + ** to the attention of the developers. */ + assert( op==TK_NULL ); sqlite3VdbeAddOp2(v, OP_Null, 0, target); return target; } @@ -3622,7 +3927,7 @@ expr_code_doover: sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); if( pExpr->u.zToken[1]!=0 ){ const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn); - assert( pExpr->u.zToken[0]=='?' || strcmp(pExpr->u.zToken, z)==0 ); + assert( pExpr->u.zToken[0]=='?' || (z && !strcmp(pExpr->u.zToken, z)) ); pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */ sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC); } @@ -3662,7 +3967,8 @@ expr_code_doover: r1 = sqlite3ExprCodeTemp(pParse, pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); codeCompare(pParse, pLeft, pExpr->pRight, op, - r1, r2, inReg, SQLITE_STOREP2 | p5); + r1, r2, inReg, SQLITE_STOREP2 | p5, + ExprHasProperty(pExpr,EP_Commuted)); assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); @@ -3814,48 +4120,15 @@ expr_code_doover: sqlite3ErrorMsg(pParse, "unknown function: %s()", zId); break; } - - /* Attempt a direct implementation of the built-in COALESCE() and - ** IFNULL() functions. This avoids unnecessary evaluation of - ** arguments past the first non-NULL argument. - */ - if( pDef->funcFlags & SQLITE_FUNC_COALESCE ){ - int endCoalesce = sqlite3VdbeMakeLabel(pParse); - assert( nFarg>=2 ); - sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target); - for(i=1; ia[i].pExpr, target); - } - sqlite3VdbeResolveLabel(v, endCoalesce); - break; + if( pDef->funcFlags & SQLITE_FUNC_INLINE ){ + assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 ); + assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 ); + return exprCodeInlineFunction(pParse, pFarg, + SQLITE_PTR_TO_INT(pDef->pUserData), target); + }else if( pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE) ){ + sqlite3ExprFunctionUsable(pParse, pExpr, pDef); } - /* The UNLIKELY() function is a no-op. The result is the value - ** of the first argument. - */ - if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){ - assert( nFarg>=1 ); - return sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target); - } - -#ifdef SQLITE_DEBUG - /* The AFFINITY() function evaluates to a string that describes - ** the type affinity of the argument. This is used for testing of - ** the SQLite type logic. - */ - if( pDef->funcFlags & SQLITE_FUNC_AFFINITY ){ - const char *azAff[] = { "blob", "text", "numeric", "integer", "real" }; - char aff; - assert( nFarg==1 ); - aff = sqlite3ExprAffinity(pFarg->a[0].pExpr); - sqlite3VdbeLoadString(v, target, - (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]); - return target; - } -#endif - for(i=0; ia[i].pExpr) ){ testcase( i==31 ); @@ -3931,12 +4204,15 @@ expr_code_doover: }else #endif { - sqlite3VdbeAddOp4(v, pParse->iSelfTab ? OP_PureFunc0 : OP_Function0, - constMask, r1, target, (char*)pDef, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nFarg); + sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg, + pDef, pExpr->op2); } - if( nFarg && constMask==0 ){ - sqlite3ReleaseTempRange(pParse, r1, nFarg); + if( nFarg ){ + if( constMask==0 ){ + sqlite3ReleaseTempRange(pParse, r1, nFarg); + }else{ + sqlite3VdbeReleaseRegisters(pParse, r1, nFarg, constMask, 1); + } } return target; } @@ -4030,17 +4306,19 @@ expr_code_doover: ** p1==2 -> old.b p1==5 -> new.b */ Table *pTab = pExpr->y.pTab; - int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn; + int iCol = pExpr->iColumn; + int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + + sqlite3TableColumnToStorage(pTab, iCol); assert( pExpr->iTable==0 || pExpr->iTable==1 ); - assert( pExpr->iColumn>=-1 && pExpr->iColumnnCol ); - assert( pTab->iPKey<0 || pExpr->iColumn!=pTab->iPKey ); + assert( iCol>=-1 && iColnCol ); + assert( pTab->iPKey<0 || iCol!=pTab->iPKey ); assert( p1>=0 && p1<(pTab->nCol*2+2) ); sqlite3VdbeAddOp2(v, OP_Param, p1, target); VdbeComment((v, "r[%d]=%s.%s", target, (pExpr->iTable ? "new" : "old"), - (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[pExpr->iColumn].zName) + (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[iCol].zName) )); #ifndef SQLITE_OMIT_FLOATING_POINT @@ -4049,9 +4327,7 @@ expr_code_doover: ** ** EVIDENCE-OF: R-60985-57662 SQLite will convert the value back to ** floating point when extracting it from the record. */ - if( pExpr->iColumn>=0 - && pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL - ){ + if( iCol>=0 && pTab->aCol[iCol].affinity==SQLITE_AFF_REAL ){ sqlite3VdbeAddOp1(v, OP_RealAffinity, target); } #endif @@ -4106,7 +4382,7 @@ expr_code_doover: ** or if there is no matching Ei, the ELSE term Y, or if there is ** no ELSE term, NULL. */ - default: assert( op==TK_CASE ); { + case TK_CASE: { int endLabel; /* GOTO label for end of CASE stmt */ int nextCase; /* GOTO label for next WHEN clause */ int nExpr; /* 2x number of WHEN terms */ @@ -4284,14 +4560,16 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ int inReg; assert( target>0 && target<=pParse->nMem ); - if( pExpr && pExpr->op==TK_REGISTER ){ - sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target); - }else{ - inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); - assert( pParse->pVdbe!=0 || pParse->db->mallocFailed ); - if( inReg!=target && pParse->pVdbe ){ - sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target); + inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); + assert( pParse->pVdbe!=0 || pParse->db->mallocFailed ); + if( inReg!=target && pParse->pVdbe ){ + u8 op; + if( ExprHasProperty(pExpr,EP_Subquery) ){ + op = OP_Copy; + }else{ + op = OP_SCopy; } + sqlite3VdbeAddOp2(pParse->pVdbe, op, inReg, target); } } @@ -4321,30 +4599,6 @@ void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ } } -/* -** Generate code that evaluates the given expression and puts the result -** in register target. -** -** Also make a copy of the expression results into another "cache" register -** and modify the expression so that the next time it is evaluated, -** the result is a copy of the cache register. -** -** This routine is used for expressions that are used multiple -** times. They are evaluated once and the results of the expression -** are reused. -*/ -void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){ - Vdbe *v = pParse->pVdbe; - int iMem; - - assert( target>0 ); - assert( pExpr->op!=TK_REGISTER ); - sqlite3ExprCode(pParse, pExpr, target); - iMem = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Copy, target, iMem); - exprToRegister(pExpr, iMem); -} - /* ** Generate code that pushes the value of every element of the given ** expression list into a sequence of registers beginning at target. @@ -4408,6 +4662,7 @@ int sqlite3ExprCodeExprList( && (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy && pOp->p1+pOp->p3+1==inReg && pOp->p2+pOp->p3+1==target+i + && pOp->p5==0 /* The do-not-merge flag must be clear */ ){ pOp->p3++; }else{ @@ -4582,7 +4837,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, dest, jumpIfNull); + r1, r2, dest, jumpIfNull, ExprHasProperty(pExpr,EP_Commuted)); assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); @@ -4757,7 +5012,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, dest, jumpIfNull); + r1, r2, dest, jumpIfNull,ExprHasProperty(pExpr,EP_Commuted)); assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); @@ -4943,7 +5198,8 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){ return 2; } } - if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; + if( (pA->flags & (EP_Distinct|EP_Commuted)) + != (pB->flags & (EP_Distinct|EP_Commuted)) ) return 2; if( (combinedFlags & EP_TokenOnly)==0 ){ if( combinedFlags & EP_xIsSelect ) return 2; if( (combinedFlags & EP_FixedCol)==0 @@ -4955,18 +5211,33 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){ && (combinedFlags & EP_Reduced)==0 ){ if( pA->iColumn!=pB->iColumn ) return 2; - if( pA->op2!=pB->op2 ) return 2; - if( pA->op!=TK_IN - && pA->iTable!=pB->iTable - && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2; + if( pA->op2!=pB->op2 ){ + if( pA->op==TK_TRUTH ) return 2; + if( pA->op==TK_FUNCTION && iTab<0 ){ + /* Ex: CREATE TABLE t1(a CHECK( aop!=TK_IN && pA->iTable!=pB->iTable && pA->iTable!=iTab ){ + return 2; + } } } return 0; } /* -** Compare two ExprList objects. Return 0 if they are identical and -** non-zero if they differ in any way. +** Compare two ExprList objects. Return 0 if they are identical, 1 +** if they are certainly different, or 2 if it is not possible to +** determine if they are identical or not. ** ** If any subelement of pB has Expr.iTable==(-1) then it is allowed ** to compare equal to an equivalent element in pA with Expr.iTable==iTab. @@ -4985,10 +5256,11 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){ if( pA==0 || pB==0 ) return 1; if( pA->nExpr!=pB->nExpr ) return 1; for(i=0; inExpr; i++){ + int res; Expr *pExprA = pA->a[i].pExpr; Expr *pExprB = pB->a[i].pExpr; if( pA->a[i].sortFlags!=pB->a[i].sortFlags ) return 1; - if( sqlite3ExprCompare(0, pExprA, pExprB, iTab) ) return 1; + if( (res = sqlite3ExprCompare(0, pExprA, pExprB, iTab)) ) return res; } return 0; } @@ -5125,7 +5397,7 @@ int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, int iTab){ } /* -** This is the Expr node callback for sqlite3ExprImpliesNotNullRow(). +** This is the Expr node callback for sqlite3ExprImpliesNonNullRow(). ** If the expression node requires that the table at pWalker->iCur ** have one or more non-NULL column, then set pWalker->eCode to 1 and abort. ** @@ -5143,6 +5415,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ case TK_NOTNULL: case TK_IS: case TK_OR: + case TK_VECTOR: case TK_CASE: case TK_IN: case TK_FUNCTION: @@ -5152,6 +5425,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_NOTNULL ); testcase( pExpr->op==TK_IS ); testcase( pExpr->op==TK_OR ); + testcase( pExpr->op==TK_VECTOR ); testcase( pExpr->op==TK_CASE ); testcase( pExpr->op==TK_IN ); testcase( pExpr->op==TK_FUNCTION ); @@ -5165,15 +5439,20 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ return WRC_Prune; case TK_AND: - if( sqlite3ExprImpliesNonNullRow(pExpr->pLeft, pWalker->u.iCur) - && sqlite3ExprImpliesNonNullRow(pExpr->pRight, pWalker->u.iCur) - ){ - pWalker->eCode = 1; + if( pWalker->eCode==0 ){ + sqlite3WalkExpr(pWalker, pExpr->pLeft); + if( pWalker->eCode ){ + pWalker->eCode = 0; + sqlite3WalkExpr(pWalker, pExpr->pRight); + } } return WRC_Prune; case TK_BETWEEN: - sqlite3WalkExpr(pWalker, pExpr->pLeft); + if( sqlite3WalkExpr(pWalker, pExpr->pLeft)==WRC_Abort ){ + assert( pWalker->eCode ); + return WRC_Abort; + } return WRC_Prune; /* Virtual tables are allowed to use constraints like x=NULL. So @@ -5227,14 +5506,13 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){ Walker w; p = sqlite3ExprSkipCollateAndLikely(p); - while( p ){ - if( p->op==TK_NOTNULL ){ - p = p->pLeft; - }else if( p->op==TK_AND ){ + if( p==0 ) return 0; + if( p->op==TK_NOTNULL ){ + p = p->pLeft; + }else{ + while( p->op==TK_AND ){ if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab) ) return 1; p = p->pRight; - }else{ - break; } } w.xExprCallback = impliesNotNullRow; @@ -5266,7 +5544,7 @@ struct IdxCover { static int exprIdxCover(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_COLUMN && pExpr->iTable==pWalker->u.pIdxCover->iCur - && sqlite3ColumnOfIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0 + && sqlite3TableColumnToIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0 ){ pWalker->eCode = 1; return WRC_Abort; @@ -5317,12 +5595,13 @@ struct SrcCount { ** Count the number of references to columns. */ static int exprSrcCount(Walker *pWalker, Expr *pExpr){ - /* The NEVER() on the second term is because sqlite3FunctionUsesThisSrc() - ** is always called before sqlite3ExprAnalyzeAggregates() and so the - ** TK_COLUMNs have not yet been converted into TK_AGG_COLUMN. If - ** sqlite3FunctionUsesThisSrc() is used differently in the future, the - ** NEVER() will need to be removed. */ - if( pExpr->op==TK_COLUMN || NEVER(pExpr->op==TK_AGG_COLUMN) ){ + /* There was once a NEVER() on the second term on the grounds that + ** sqlite3FunctionUsesThisSrc() was always called before + ** sqlite3ExprAnalyzeAggregates() and so the TK_COLUMNs have not yet + ** been converted into TK_AGG_COLUMN. But this is no longer true due + ** to window functions - sqlite3WindowRewrite() may now indirectly call + ** FunctionUsesThisSrc() when creating a new sub-select. */ + if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){ int i; struct SrcCount *p = pWalker->u.pSrcCount; SrcList *pSrc = p->pSrc; @@ -5360,6 +5639,11 @@ int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){ cnt.nThis = 0; cnt.nOther = 0; sqlite3WalkExprList(&w, pExpr->x.pList); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter); + } +#endif return cnt.nThis>0 || cnt.nOther==0; } @@ -5588,8 +5872,11 @@ int sqlite3GetTempReg(Parse *pParse){ ** purpose. */ void sqlite3ReleaseTempReg(Parse *pParse, int iReg){ - if( iReg && pParse->nTempRegaTempReg) ){ - pParse->aTempReg[pParse->nTempReg++] = iReg; + if( iReg ){ + sqlite3VdbeReleaseRegisters(pParse, iReg, 1, 0, 0); + if( pParse->nTempRegaTempReg) ){ + pParse->aTempReg[pParse->nTempReg++] = iReg; + } } } @@ -5615,6 +5902,7 @@ void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){ sqlite3ReleaseTempReg(pParse, iReg); return; } + sqlite3VdbeReleaseRegisters(pParse, iReg, nReg, 0, 0); if( nReg>pParse->nRangeReg ){ pParse->nRangeReg = nReg; pParse->iRangeReg = iReg; diff --git a/src/fkey.c b/src/fkey.c index fc750236..9698d343 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -349,7 +349,7 @@ static void fkLookupParent( VdbeCoverage(v); } for(i=0; inCol; i++){ - int iReg = aiCol[i] + regData + 1; + int iReg = sqlite3TableColumnToStorage(pFKey->pFrom,aiCol[i]) + regData + 1; sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); VdbeCoverage(v); } @@ -365,7 +365,8 @@ static void fkLookupParent( ** is no matching parent key. Before using MustBeInt, make a copy of ** the value. Otherwise, the value inserted into the child key column ** will have INTEGER affinity applied to it, which may not be correct. */ - sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp); + sqlite3VdbeAddOp2(v, OP_SCopy, + sqlite3TableColumnToStorage(pFKey->pFrom,aiCol[0])+1+regData, regTemp); iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0); VdbeCoverage(v); @@ -392,7 +393,9 @@ static void fkLookupParent( sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); for(i=0; ipFrom, aiCol[i])+1+regData, + regTemp+i); } /* If the parent table is the same as the child table, and we are about @@ -408,8 +411,11 @@ static void fkLookupParent( if( pTab==pFKey->pFrom && nIncr==1 ){ int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1; for(i=0; iaiColumn[i]+1+regData; + int iChild = sqlite3TableColumnToStorage(pFKey->pFrom,aiCol[i]) + +1+regData; + int iParent = 1+regData; + iParent += sqlite3TableColumnToStorage(pIdx->pTable, + pIdx->aiColumn[i]); assert( pIdx->aiColumn[i]>=0 ); assert( aiCol[i]!=pTab->iPKey ); if( pIdx->aiColumn[i]==pTab->iPKey ){ @@ -477,7 +483,7 @@ static Expr *exprTableRegister( if( pExpr ){ if( iCol>=0 && iCol!=pTab->iPKey ){ pCol = &pTab->aCol[iCol]; - pExpr->iTable = regBase + iCol + 1; + pExpr->iTable = regBase + sqlite3TableColumnToStorage(pTab,iCol) + 1; pExpr->affExpr = pCol->affinity; zColl = pCol->zColl; if( zColl==0 ) zColl = db->pDfltColl->zName; @@ -926,7 +932,9 @@ void sqlite3FkCheck( Vdbe *v = sqlite3GetVdbe(pParse); int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1; for(i=0; inCol; i++){ - int iReg = pFKey->aCol[i].iFrom + regOld + 1; + int iFromCol, iReg; + iFromCol = pFKey->aCol[i].iFrom; + iReg = sqlite3TableColumnToStorage(pFKey->pFrom,iFromCol) + regOld+1; sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump); VdbeCoverage(v); } sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1); @@ -1261,7 +1269,15 @@ static Trigger *fkActionTrigger( sqlite3ExprAlloc(db, TK_ID, &tNew, 0), sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)); }else if( action==OE_SetDflt ){ - Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt; + Column *pCol = pFKey->pFrom->aCol + iFromCol; + Expr *pDflt; + if( pCol->colFlags & COLFLAG_GENERATED ){ + testcase( pCol->colFlags & COLFLAG_VIRTUAL ); + testcase( pCol->colFlags & COLFLAG_STORED ); + pDflt = 0; + }else{ + pDflt = pCol->pDflt; + } if( pDflt ){ pNew = sqlite3ExprDup(db, pDflt, 0); }else{ @@ -1299,7 +1315,7 @@ static Trigger *fkActionTrigger( } /* Disable lookaside memory allocation */ - db->lookaside.bDisable++; + DisableLookaside; pTrigger = (Trigger *)sqlite3DbMallocZero(db, sizeof(Trigger) + /* struct Trigger */ @@ -1321,7 +1337,7 @@ static Trigger *fkActionTrigger( } /* Re-enable the lookaside buffer, if it was disabled earlier. */ - db->lookaside.bDisable--; + EnableLookaside; sqlite3ExprDelete(db, pWhere); sqlite3ExprDelete(db, pWhen); diff --git a/src/func.c b/src/func.c index 3201b6df..36ab5717 100644 --- a/src/func.c +++ b/src/func.c @@ -16,7 +16,9 @@ #include "sqliteInt.h" #include #include +#ifndef SQLITE_OMIT_FLOATING_POINT #include +#endif #include "vdbeInt.h" /* @@ -1907,12 +1909,20 @@ void sqlite3RegisterBuiltinFunctions(void){ ** For peak efficiency, put the most frequently used function last. */ static FuncDef aBuiltinFunc[] = { +/***** Functions only available with SQLITE_TESTCTRL_INTERNAL_FUNCTIONS *****/ + TEST_FUNC(implies_nonnull_row, 2, INLINEFUNC_implies_nonnull_row, 0), + TEST_FUNC(expr_compare, 2, INLINEFUNC_expr_compare, 0), + TEST_FUNC(expr_implies_expr, 2, INLINEFUNC_expr_implies_expr, 0), +#ifdef SQLITE_DEBUG + TEST_FUNC(affinity, 1, INLINEFUNC_affinity, 0), +#endif +/***** Regular functions *****/ #ifdef SQLITE_SOUNDEX FUNCTION(soundex, 1, 0, 0, soundexFunc ), #endif #ifndef SQLITE_OMIT_LOAD_EXTENSION - VFUNCTION(load_extension, 1, 0, 0, loadExt ), - VFUNCTION(load_extension, 2, 0, 0, loadExt ), + SFUNCTION(load_extension, 1, 0, 0, loadExt ), + SFUNCTION(load_extension, 2, 0, 0, loadExt ), #endif #if SQLITE_USER_AUTHENTICATION FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ), @@ -1921,12 +1931,9 @@ void sqlite3RegisterBuiltinFunctions(void){ DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ - FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), - FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), - FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), -#ifdef SQLITE_DEBUG - FUNCTION2(affinity, 1, 0, 0, noopFunc, SQLITE_FUNC_AFFINITY), -#endif + INLINE_FUNC(unlikely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY), + INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY), + INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY), #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC FUNCTION2(sqlite_offset, 1, 0, 0, noopFunc, SQLITE_FUNC_OFFSET| SQLITE_FUNC_TYPEOF), @@ -1959,7 +1966,7 @@ void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(upper, 1, 0, 0, upperFunc ), FUNCTION(lower, 1, 0, 0, lowerFunc ), FUNCTION(hex, 1, 0, 0, hexFunc ), - FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE), + INLINE_FUNC(ifnull, 2, INLINEFUNC_coalesce, SQLITE_FUNC_COALESCE), VFUNCTION(random, 0, 0, 0, randomFunc ), VFUNCTION(randomblob, 1, 0, 0, randomBlob ), FUNCTION(nullif, 2, 0, 1, nullifFunc ), @@ -1999,7 +2006,7 @@ void sqlite3RegisterBuiltinFunctions(void){ #endif FUNCTION(coalesce, 1, 0, 0, 0 ), FUNCTION(coalesce, 0, 0, 0, 0 ), - FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE), + INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, SQLITE_FUNC_COALESCE), }; #ifndef SQLITE_OMIT_ALTERTABLE sqlite3AlterFunctions(); diff --git a/src/global.c b/src/global.c index 4689e94b..a2c51f41 100644 --- a/src/global.c +++ b/src/global.c @@ -87,7 +87,6 @@ const unsigned char sqlite3UpperToLower[] = { ** non-ASCII UTF character. Hence the test for whether or not a character is ** part of an identifier is 0x46. */ -#ifdef SQLITE_ASCII const unsigned char sqlite3CtypeMap[256] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00..07 ........ */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */ @@ -125,7 +124,6 @@ const unsigned char sqlite3CtypeMap[256] = { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* f0..f7 ........ */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */ }; -#endif /* EVIDENCE-OF: R-02982-34736 In order to maintain full backwards ** compatibility for legacy applications, the URI filename capability is @@ -190,9 +188,18 @@ const unsigned char sqlite3CtypeMap[256] = { ** changed as start-time using sqlite3_config(SQLITE_CONFIG_LOOKASIDE) ** or at run-time for an individual database connection using ** sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE); +** +** With the two-size-lookaside enhancement, less lookaside is required. +** The default configuration of 1200,40 actually provides 30 1200-byte slots +** and 93 128-byte slots, which is more lookaside than is available +** using the older 1200,100 configuration without two-size-lookaside. */ #ifndef SQLITE_DEFAULT_LOOKASIDE -# define SQLITE_DEFAULT_LOOKASIDE 1200,100 +# ifdef SQLITE_OMIT_TWOSIZE_LOOKASIDE +# define SQLITE_DEFAULT_LOOKASIDE 1200,100 /* 120KB of memory */ +# else +# define SQLITE_DEFAULT_LOOKASIDE 1200,40 /* 48KB of memory */ +# endif #endif @@ -258,7 +265,6 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = { 0, /* xTestCallback */ #endif 0, /* bLocaltimeFault */ - 0, /* bInternalFunctions */ 0x7ffffffe, /* iOnceResetThreshold */ SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */ 0, /* iPrngSeed */ diff --git a/src/hwtime.h b/src/hwtime.h index 5b209db8..037c55a9 100644 --- a/src/hwtime.h +++ b/src/hwtime.h @@ -11,7 +11,7 @@ ****************************************************************************** ** ** This file contains inline asm code for retrieving "high-performance" -** counters for x86 class CPUs. +** counters for x86 and x86_64 class CPUs. */ #ifndef SQLITE_HWTIME_H #define SQLITE_HWTIME_H @@ -22,8 +22,9 @@ ** processor and returns that value. This can be used for high-res ** profiling. */ -#if (defined(__GNUC__) || defined(_MSC_VER)) && \ - (defined(i386) || defined(__i386__) || defined(_M_IX86)) +#if !defined(__STRICT_ANSI__) && \ + (defined(__GNUC__) || defined(_MSC_VER)) && \ + (defined(i386) || defined(__i386__) || defined(_M_IX86)) #if defined(__GNUC__) @@ -44,7 +45,7 @@ #endif -#elif (defined(__GNUC__) && defined(__x86_64__)) +#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) __inline__ sqlite_uint64 sqlite3Hwtime(void){ unsigned long val; @@ -52,7 +53,7 @@ return val; } -#elif (defined(__GNUC__) && defined(__ppc__)) +#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) __inline__ sqlite_uint64 sqlite3Hwtime(void){ unsigned long long retval; @@ -69,14 +70,13 @@ #else - #error Need implementation of sqlite3Hwtime() for your platform. - /* - ** To compile without implementing sqlite3Hwtime() for your platform, - ** you can remove the above #error and use the following - ** stub function. You will lose timing support for many - ** of the debugging and testing utilities, but it should at - ** least compile and run. + ** asm() is needed for hardware timing support. Without asm(), + ** disable the sqlite3Hwtime() routine. + ** + ** sqlite3Hwtime() is only used for some obscure debugging + ** and analysis configurations, not in any deliverable, so this + ** should not be a great loss. */ sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } diff --git a/src/insert.c b/src/insert.c index d9078b89..93f22a8c 100644 --- a/src/insert.c +++ b/src/insert.c @@ -37,7 +37,7 @@ void sqlite3OpenTable( sqlite3TableLock(pParse, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName); if( HasRowid(pTab) ){ - sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nCol); + sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nNVCol); VdbeComment((v, "%s", pTab->zName)); }else{ Index *pPk = sqlite3PrimaryKeyIndex(pTab); @@ -129,7 +129,7 @@ const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ ** 'E' REAL */ void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ - int i; + int i, j; char *zColAff = pTab->zColAff; if( zColAff==0 ){ sqlite3 *db = sqlite3VdbeDb(v); @@ -139,13 +139,15 @@ void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ return; } - for(i=0; inCol; i++){ + for(i=j=0; inCol; i++){ assert( pTab->aCol[i].affinity!=0 ); - zColAff[i] = pTab->aCol[i].affinity; + if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ + zColAff[j++] = pTab->aCol[i].affinity; + } } do{ - zColAff[i--] = 0; - }while( i>=0 && zColAff[i]<=SQLITE_AFF_BLOB ); + zColAff[j--] = 0; + }while( j>=0 && zColAff[j]<=SQLITE_AFF_BLOB ); pTab->zColAff = zColAff; } assert( zColAff!=0 ); @@ -199,6 +201,119 @@ static int readsTable(Parse *p, int iDb, Table *pTab){ return 0; } +/* This walker callback will compute the union of colFlags flags for all +** referenced columns in a CHECK constraint or generated column expression. +*/ +static int exprColumnFlagUnion(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 ){ + assert( pExpr->iColumn < pWalker->u.pTab->nCol ); + pWalker->eCode |= pWalker->u.pTab->aCol[pExpr->iColumn].colFlags; + } + return WRC_Continue; +} + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +/* +** All regular columns for table pTab have been puts into registers +** starting with iRegStore. The registers that correspond to STORED +** or VIRTUAL columns have not yet been initialized. This routine goes +** back and computes the values for those columns based on the previously +** computed normal columns. +*/ +void sqlite3ComputeGeneratedColumns( + Parse *pParse, /* Parsing context */ + int iRegStore, /* Register holding the first column */ + Table *pTab /* The table */ +){ + int i; + Walker w; + Column *pRedo; + int eProgress; + VdbeOp *pOp; + + assert( pTab->tabFlags & TF_HasGenerated ); + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + + /* Before computing generated columns, first go through and make sure + ** that appropriate affinity has been applied to the regular columns + */ + sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore); + if( (pTab->tabFlags & TF_HasStored)!=0 + && (pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1))->opcode==OP_Affinity + ){ + /* Change the OP_Affinity argument to '@' (NONE) for all stored + ** columns. '@' is the no-op affinity and those columns have not + ** yet been computed. */ + int ii, jj; + char *zP4 = pOp->p4.z; + assert( zP4!=0 ); + assert( pOp->p4type==P4_DYNAMIC ); + for(ii=jj=0; zP4[jj]; ii++){ + if( pTab->aCol[ii].colFlags & COLFLAG_VIRTUAL ){ + continue; + } + if( pTab->aCol[ii].colFlags & COLFLAG_STORED ){ + zP4[jj] = SQLITE_AFF_NONE; + } + jj++; + } + } + + /* Because there can be multiple generated columns that refer to one another, + ** this is a two-pass algorithm. On the first pass, mark all generated + ** columns as "not available". + */ + for(i=0; inCol; i++){ + if( pTab->aCol[i].colFlags & COLFLAG_GENERATED ){ + testcase( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ); + testcase( pTab->aCol[i].colFlags & COLFLAG_STORED ); + pTab->aCol[i].colFlags |= COLFLAG_NOTAVAIL; + } + } + + w.u.pTab = pTab; + w.xExprCallback = exprColumnFlagUnion; + w.xSelectCallback = 0; + w.xSelectCallback2 = 0; + + /* On the second pass, compute the value of each NOT-AVAILABLE column. + ** Companion code in the TK_COLUMN case of sqlite3ExprCodeTarget() will + ** compute dependencies and mark remove the COLSPAN_NOTAVAIL mark, as + ** they are needed. + */ + pParse->iSelfTab = -iRegStore; + do{ + eProgress = 0; + pRedo = 0; + for(i=0; inCol; i++){ + Column *pCol = pTab->aCol + i; + if( (pCol->colFlags & COLFLAG_NOTAVAIL)!=0 ){ + int x; + pCol->colFlags |= COLFLAG_BUSY; + w.eCode = 0; + sqlite3WalkExpr(&w, pCol->pDflt); + pCol->colFlags &= ~COLFLAG_BUSY; + if( w.eCode & COLFLAG_NOTAVAIL ){ + pRedo = pCol; + continue; + } + eProgress = 1; + assert( pCol->colFlags & COLFLAG_GENERATED ); + x = sqlite3TableColumnToStorage(pTab, i) + iRegStore; + sqlite3ExprCodeGeneratedColumn(pParse, pCol, x); + pCol->colFlags &= ~COLFLAG_NOTAVAIL; + } + } + }while( pRedo && eProgress ); + if( pRedo ){ + sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pRedo->zName); + } + pParse->iSelfTab = 0; +} +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + + #ifndef SQLITE_OMIT_AUTOINCREMENT /* ** Locate or create an AutoincInfo structure associated with table pTab @@ -506,7 +621,7 @@ void sqlite3Insert( Parse *pParse, /* Parser context */ SrcList *pTabList, /* Name of table into which we are inserting */ Select *pSelect, /* A SELECT statement to use as the data source */ - IdList *pColumn, /* Column names corresponding to IDLIST. */ + IdList *pColumn, /* Column names corresponding to IDLIST, or NULL. */ int onError, /* How to handle constraint errors */ Upsert *pUpsert /* ON CONFLICT clauses for upsert, or NULL */ ){ @@ -531,6 +646,7 @@ void sqlite3Insert( u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */ u8 bIdListInOrder; /* True if IDLIST is in table order */ ExprList *pList = 0; /* List of VALUES() to be inserted */ + int iRegStore; /* Register in which to store next column */ /* Register allocations */ int regFromSelect = 0;/* Base register for data coming from SELECT */ @@ -638,8 +754,8 @@ void sqlite3Insert( */ regAutoinc = autoIncBegin(pParse, iDb, pTab); - /* Allocate registers for holding the rowid of the new row, - ** the content of the new row, and the assembled row record. + /* Allocate a block registers to hold the rowid and the values + ** for all columns of the new row. */ regRowid = regIns = pParse->nMem+1; pParse->nMem += pTab->nCol + 1; @@ -658,9 +774,17 @@ void sqlite3Insert( ** the index into IDLIST of the primary key column. ipkColumn is ** the index of the primary key as it appears in IDLIST, not as ** is appears in the original table. (The index of the INTEGER - ** PRIMARY KEY in the original table is pTab->iPKey.) + ** PRIMARY KEY in the original table is pTab->iPKey.) After this + ** loop, if ipkColumn==(-1), that means that integer primary key + ** is unspecified, and hence the table is either WITHOUT ROWID or + ** it will automatically generated an integer primary key. + ** + ** bIdListInOrder is true if the columns in IDLIST are in storage + ** order. This enables an optimization that avoids shuffling the + ** columns into storage order. False negatives are harmless, + ** but false positives will cause database corruption. */ - bIdListInOrder = (pTab->tabFlags & TF_OOOHidden)==0; + bIdListInOrder = (pTab->tabFlags & (TF_OOOHidden|TF_HasStored))==0; if( pColumn ){ for(i=0; inId; i++){ pColumn->a[i].idx = -1; @@ -673,6 +797,14 @@ void sqlite3Insert( if( j==pTab->iPKey ){ ipkColumn = i; assert( !withoutRowid ); } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( pTab->aCol[j].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL) ){ + sqlite3ErrorMsg(pParse, + "cannot INSERT into generated column \"%s\"", + pTab->aCol[j].zName); + goto insert_cleanup; + } +#endif break; } } @@ -782,13 +914,26 @@ void sqlite3Insert( */ if( pColumn==0 && nColumn>0 ){ ipkColumn = pTab->iPKey; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( ipkColumn>=0 && (pTab->tabFlags & TF_HasGenerated)!=0 ){ + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + for(i=ipkColumn-1; i>=0; i--){ + if( pTab->aCol[i].colFlags & COLFLAG_GENERATED ){ + testcase( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ); + testcase( pTab->aCol[i].colFlags & COLFLAG_STORED ); + ipkColumn--; + } + } + } +#endif } /* Make sure the number of columns in the source data matches the number ** of columns to be inserted into the table. */ for(i=0; inCol; i++){ - nHidden += (IsHiddenColumn(&pTab->aCol[i]) ? 1 : 0); + if( pTab->aCol[i].colFlags & COLFLAG_NOINSERT ) nHidden++; } if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){ sqlite3ErrorMsg(pParse, @@ -834,6 +979,10 @@ void sqlite3Insert( pTab->zName); goto insert_cleanup; } + if( pTab->pSelect ){ + sqlite3ErrorMsg(pParse, "cannot UPSERT a view"); + goto insert_cleanup; + } if( sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget) ){ goto insert_cleanup; } @@ -871,10 +1020,91 @@ void sqlite3Insert( ** goto C ** D: ... */ + sqlite3VdbeReleaseRegisters(pParse, regData, pTab->nCol, 0, 0); addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v); + if( ipkColumn>=0 ){ + /* tag-20191021-001: If the INTEGER PRIMARY KEY is being generated by the + ** SELECT, go ahead and copy the value into the rowid slot now, so that + ** the value does not get overwritten by a NULL at tag-20191021-002. */ + sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid); + } } + /* Compute data for ordinary columns of the new entry. Values + ** are written in storage order into registers starting with regData. + ** Only ordinary columns are computed in this loop. The rowid + ** (if there is one) is computed later and generated columns are + ** computed after the rowid since they might depend on the value + ** of the rowid. + */ + nHidden = 0; + iRegStore = regData; assert( regData==regRowid+1 ); + for(i=0; inCol; i++, iRegStore++){ + int k; + u32 colFlags; + assert( i>=nHidden ); + if( i==pTab->iPKey ){ + /* tag-20191021-002: References to the INTEGER PRIMARY KEY are filled + ** using the rowid. So put a NULL in the IPK slot of the record to avoid + ** using excess space. The file format definition requires this extra + ** NULL - we cannot optimize further by skipping the column completely */ + sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore); + continue; + } + if( ((colFlags = pTab->aCol[i].colFlags) & COLFLAG_NOINSERT)!=0 ){ + nHidden++; + if( (colFlags & COLFLAG_VIRTUAL)!=0 ){ + /* Virtual columns do not participate in OP_MakeRecord. So back up + ** iRegStore by one slot to compensate for the iRegStore++ in the + ** outer for() loop */ + iRegStore--; + continue; + }else if( (colFlags & COLFLAG_STORED)!=0 ){ + /* Stored columns are computed later. But if there are BEFORE + ** triggers, the slots used for stored columns will be OP_Copy-ed + ** to a second block of registers, so the register needs to be + ** initialized to NULL to avoid an uninitialized register read */ + if( tmask & TRIGGER_BEFORE ){ + sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore); + } + continue; + }else if( pColumn==0 ){ + /* Hidden columns that are not explicitly named in the INSERT + ** get there default value */ + sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); + continue; + } + } + if( pColumn ){ + for(j=0; jnId && pColumn->a[j].idx!=i; j++){} + if( j>=pColumn->nId ){ + /* A column not named in the insert column list gets its + ** default value */ + sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); + continue; + } + k = j; + }else if( nColumn==0 ){ + /* This is INSERT INTO ... DEFAULT VALUES. Load the default value. */ + sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); + continue; + }else{ + k = i - nHidden; + } + + if( useTempTable ){ + sqlite3VdbeAddOp3(v, OP_Column, srcTab, k, iRegStore); + }else if( pSelect ){ + if( regFromSelect!=regData ){ + sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+k, iRegStore); + } + }else{ + sqlite3ExprCode(pParse, pList->a[k].pExpr, iRegStore); + } + } + + /* Run the BEFORE and INSTEAD OF triggers, if there are any */ endOfLoop = sqlite3VdbeMakeLabel(pParse); @@ -909,25 +1139,21 @@ void sqlite3Insert( */ assert( !IsVirtual(pTab) ); - /* Create the new column data - */ - for(i=j=0; inCol; i++){ - if( pColumn ){ - for(j=0; jnId; j++){ - if( pColumn->a[j].idx==i ) break; - } - } - if( (!useTempTable && !pList) || (pColumn && j>=pColumn->nId) - || (pColumn==0 && IsOrdinaryHiddenColumn(&pTab->aCol[i])) ){ - sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i+1); - }else if( useTempTable ){ - sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1); - }else{ - assert( pSelect==0 ); /* Otherwise useTempTable is true */ - sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i+1); - } - if( pColumn==0 && !IsOrdinaryHiddenColumn(&pTab->aCol[i]) ) j++; + /* Copy the new data already generated. */ + assert( pTab->nNVCol>0 ); + sqlite3VdbeAddOp3(v, OP_Copy, regRowid+1, regCols+1, pTab->nNVCol-1); + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + /* Compute the new value for generated columns after all other + ** columns have already been computed. This must be done after + ** computing the ROWID in case one of the generated columns + ** refers to the ROWID. */ + if( pTab->tabFlags & TF_HasGenerated ){ + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + sqlite3ComputeGeneratedColumns(pParse, regCols+1, pTab); } +#endif /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger, ** do not attempt any conversions before assembling the record. @@ -945,19 +1171,17 @@ void sqlite3Insert( sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1); } - /* Compute the content of the next row to insert into a range of - ** registers beginning at regIns. - */ if( !isView ){ if( IsVirtual(pTab) ){ /* The row that the VUpdate opcode will delete: none */ sqlite3VdbeAddOp2(v, OP_Null, 0, regIns); } if( ipkColumn>=0 ){ + /* Compute the new rowid */ if( useTempTable ){ sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regRowid); }else if( pSelect ){ - sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid); + /* Rowid already initialized at tag-20191021-001 */ }else{ Expr *pIpk = pList->a[ipkColumn].pExpr; if( pIpk->op==TK_NULL && !IsVirtual(pTab) ){ @@ -990,45 +1214,15 @@ void sqlite3Insert( } autoIncStep(pParse, regAutoinc, regRowid); - /* Compute data for all columns of the new entry, beginning - ** with the first column. - */ - nHidden = 0; - for(i=0; inCol; i++){ - int iRegStore = regRowid+1+i; - if( i==pTab->iPKey ){ - /* The value of the INTEGER PRIMARY KEY column is always a NULL. - ** Whenever this column is read, the rowid will be substituted - ** in its place. Hence, fill this column with a NULL to avoid - ** taking up data space with information that will never be used. - ** As there may be shallow copies of this value, make it a soft-NULL */ - sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore); - continue; - } - if( pColumn==0 ){ - if( IsHiddenColumn(&pTab->aCol[i]) ){ - j = -1; - nHidden++; - }else{ - j = i - nHidden; - } - }else{ - for(j=0; jnId; j++){ - if( pColumn->a[j].idx==i ) break; - } - } - if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){ - sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); - }else if( useTempTable ){ - sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore); - }else if( pSelect ){ - if( regFromSelect!=regData ){ - sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore); - } - }else{ - sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore); - } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + /* Compute the new value for generated columns after all other + ** columns have already been computed. This must be done after + ** computing the ROWID in case one of the generated columns + ** is derived from the INTEGER PRIMARY KEY. */ + if( pTab->tabFlags & TF_HasGenerated ){ + sqlite3ComputeGeneratedColumns(pParse, regRowid+1, pTab); } +#endif /* Generate code to check constraints and generate index keys and ** do the insertion. @@ -1058,9 +1252,7 @@ void sqlite3Insert( ** cursor that is disturbed. And these instructions both clear the ** VdbeCursor.seekResult variable, disabling the OPFLAG_USESEEKRESULT ** functionality. */ - bUseSeek = (isReplace==0 || (pTrigger==0 && - ((db->flags & SQLITE_ForeignKeys)==0 || sqlite3FkReferences(pTab)==0) - )); + bUseSeek = (isReplace==0 || !sqlite3VdbeHasSubProgram(v)); sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur, regIns, aRegIdx, 0, appendFlag, bUseSeek ); @@ -1089,6 +1281,15 @@ void sqlite3Insert( sqlite3VdbeAddOp1(v, OP_Close, srcTab); }else if( pSelect ){ sqlite3VdbeGoto(v, addrCont); +#ifdef SQLITE_DEBUG + /* If we are jumping back to an OP_Yield that is preceded by an + ** OP_ReleaseReg, set the p5 flag on the OP_Goto so that the + ** OP_ReleaseReg will be included in the loop. */ + if( sqlite3VdbeGetOp(v, addrCont-1)->opcode==OP_ReleaseReg ){ + assert( sqlite3VdbeGetOp(v, addrCont)->opcode==OP_Yield ); + sqlite3VdbeChangeP5(v, 1); + } +#endif sqlite3VdbeJumpHere(v, addrInsTop); } @@ -1311,7 +1512,6 @@ void sqlite3GenerateConstraintChecks( int ix; /* Index loop counter */ int nCol; /* Number of columns */ int onError; /* Conflict resolution strategy */ - int addr1; /* Address of jump instruction */ int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */ int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */ Index *pUpIdx = 0; /* Index to which to apply the upsert */ @@ -1321,6 +1521,13 @@ void sqlite3GenerateConstraintChecks( int upsertJump = 0; /* Address of Goto that jumps into upsert subroutine */ int ipkTop = 0; /* Top of the IPK uniqueness check */ int ipkBottom = 0; /* OP_Goto at the end of the IPK uniqueness check */ + /* Variables associated with retesting uniqueness constraints after + ** replace triggers fire have run */ + int regTrigCnt; /* Register used to count replace trigger invocations */ + int addrRecheck = 0; /* Jump here to recheck all uniqueness constraints */ + int lblRecheckOk = 0; /* Each recheck jumps to this label if it passes */ + Trigger *pTrigger; /* List of DELETE triggers on the table pTab */ + int nReplaceTrig = 0; /* Number of replace triggers coded */ isUpdate = regOldData!=0; db = pParse->db; @@ -1347,63 +1554,103 @@ void sqlite3GenerateConstraintChecks( /* Test all NOT NULL constraints. */ - for(i=0; iiPKey ){ - continue; /* ROWID is never NULL */ - } - if( aiChng && aiChng[i]<0 ){ - /* Don't bother checking for NOT NULL on columns that do not change */ - continue; - } - onError = pTab->aCol[i].notNull; - if( onError==OE_None ) continue; /* This column is allowed to be NULL */ - if( overrideError!=OE_Default ){ - onError = overrideError; - }else if( onError==OE_Default ){ - onError = OE_Abort; - } - if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){ - onError = OE_Abort; - } - assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail - || onError==OE_Ignore || onError==OE_Replace ); - addr1 = 0; - switch( onError ){ - case OE_Replace: { - assert( onError==OE_Replace ); - addr1 = sqlite3VdbeMakeLabel(pParse); - sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1); - VdbeCoverage(v); - sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i); - sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1); - VdbeCoverage(v); - onError = OE_Abort; - /* Fall through into the OE_Abort case to generate code that runs - ** if both the input and the default value are NULL */ - } - case OE_Abort: - sqlite3MayAbort(pParse); - /* Fall through */ - case OE_Rollback: - case OE_Fail: { - char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName, - pTab->aCol[i].zName); - sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError, - regNewData+1+i); - sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC); - sqlite3VdbeChangeP5(v, P5_ConstraintNotNull); - VdbeCoverage(v); - if( addr1 ) sqlite3VdbeResolveLabel(v, addr1); + if( pTab->tabFlags & TF_HasNotNull ){ + int b2ndPass = 0; /* True if currently running 2nd pass */ + int nSeenReplace = 0; /* Number of ON CONFLICT REPLACE operations */ + int nGenerated = 0; /* Number of generated columns with NOT NULL */ + while(1){ /* Make 2 passes over columns. Exit loop via "break" */ + for(i=0; iaCol[i]; /* The column to check for NOT NULL */ + int isGenerated; /* non-zero if column is generated */ + onError = pCol->notNull; + if( onError==OE_None ) continue; /* No NOT NULL on this column */ + if( i==pTab->iPKey ){ + continue; /* ROWID is never NULL */ + } + isGenerated = pCol->colFlags & COLFLAG_GENERATED; + if( isGenerated && !b2ndPass ){ + nGenerated++; + continue; /* Generated columns processed on 2nd pass */ + } + if( aiChng && aiChng[i]<0 && !isGenerated ){ + /* Do not check NOT NULL on columns that do not change */ + continue; + } + if( overrideError!=OE_Default ){ + onError = overrideError; + }else if( onError==OE_Default ){ + onError = OE_Abort; + } + if( onError==OE_Replace ){ + if( b2ndPass /* REPLACE becomes ABORT on the 2nd pass */ + || pCol->pDflt==0 /* REPLACE is ABORT if no DEFAULT value */ + ){ + testcase( pCol->colFlags & COLFLAG_VIRTUAL ); + testcase( pCol->colFlags & COLFLAG_STORED ); + testcase( pCol->colFlags & COLFLAG_GENERATED ); + onError = OE_Abort; + }else{ + assert( !isGenerated ); + } + }else if( b2ndPass && !isGenerated ){ + continue; + } + assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail + || onError==OE_Ignore || onError==OE_Replace ); + testcase( i!=sqlite3TableColumnToStorage(pTab, i) ); + iReg = sqlite3TableColumnToStorage(pTab, i) + regNewData + 1; + switch( onError ){ + case OE_Replace: { + int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, iReg); + VdbeCoverage(v); + assert( (pCol->colFlags & COLFLAG_GENERATED)==0 ); + nSeenReplace++; + sqlite3ExprCode(pParse, pCol->pDflt, iReg); + sqlite3VdbeJumpHere(v, addr1); + break; + } + case OE_Abort: + sqlite3MayAbort(pParse); + /* Fall through */ + case OE_Rollback: + case OE_Fail: { + char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName, + pCol->zName); + sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, + onError, iReg); + sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC); + sqlite3VdbeChangeP5(v, P5_ConstraintNotNull); + VdbeCoverage(v); + break; + } + default: { + assert( onError==OE_Ignore ); + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, ignoreDest); + VdbeCoverage(v); + break; + } + } /* end switch(onError) */ + } /* end loop i over columns */ + if( nGenerated==0 && nSeenReplace==0 ){ + /* If there are no generated columns with NOT NULL constraints + ** and no NOT NULL ON CONFLICT REPLACE constraints, then a single + ** pass is sufficient */ break; } - default: { - assert( onError==OE_Ignore ); - sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest); - VdbeCoverage(v); - break; + if( b2ndPass ) break; /* Never need more than 2 passes */ + b2ndPass = 1; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( nSeenReplace>0 && (pTab->tabFlags & TF_HasGenerated)!=0 ){ + /* If any NOT NULL ON CONFLICT REPLACE constraints fired on the + ** first pass, recomputed values for all generated columns, as + ** those values might depend on columns affected by the REPLACE. + */ + sqlite3ComputeGeneratedColumns(pParse, regNewData+1, pTab); } - } - } +#endif + } /* end of 2-pass loop */ + } /* end if( has-not-null-constraints ) */ /* Test all CHECK constraints */ @@ -1428,7 +1675,7 @@ void sqlite3GenerateConstraintChecks( if( onError==OE_Ignore ){ sqlite3VdbeGoto(v, ignoreDest); }else{ - char *zName = pCheck->a[i].zName; + char *zName = pCheck->a[i].zEName; if( zName==0 ) zName = pTab->zName; if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-26383-51744 */ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK, @@ -1485,6 +1732,50 @@ void sqlite3GenerateConstraintChecks( } } + /* Determine if it is possible that triggers (either explicitly coded + ** triggers or FK resolution actions) might run as a result of deletes + ** that happen when OE_Replace conflict resolution occurs. (Call these + ** "replace triggers".) If any replace triggers run, we will need to + ** recheck all of the uniqueness constraints after they have all run. + ** But on the recheck, the resolution is OE_Abort instead of OE_Replace. + ** + ** If replace triggers are a possibility, then + ** + ** (1) Allocate register regTrigCnt and initialize it to zero. + ** That register will count the number of replace triggers that + ** fire. Constraint recheck only occurs if the number is positive. + ** (2) Initialize pTrigger to the list of all DELETE triggers on pTab. + ** (3) Initialize addrRecheck and lblRecheckOk + ** + ** The uniqueness rechecking code will create a series of tests to run + ** in a second pass. The addrRecheck and lblRecheckOk variables are + ** used to link together these tests which are separated from each other + ** in the generate bytecode. + */ + if( (db->flags & (SQLITE_RecTriggers|SQLITE_ForeignKeys))==0 ){ + /* There are not DELETE triggers nor FK constraints. No constraint + ** rechecks are needed. */ + pTrigger = 0; + regTrigCnt = 0; + }else{ + if( db->flags&SQLITE_RecTriggers ){ + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); + regTrigCnt = pTrigger!=0 || sqlite3FkRequired(pParse, pTab, 0, 0); + }else{ + pTrigger = 0; + regTrigCnt = sqlite3FkRequired(pParse, pTab, 0, 0); + } + if( regTrigCnt ){ + /* Replace triggers might exist. Allocate the counter and + ** initialize it to zero. */ + regTrigCnt = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regTrigCnt); + VdbeComment((v, "trigger count")); + lblRecheckOk = sqlite3VdbeMakeLabel(pParse); + addrRecheck = lblRecheckOk; + } + } + /* If rowid is changing, make sure the new rowid does not previously ** exist in the table. */ @@ -1574,14 +1865,12 @@ void sqlite3GenerateConstraintChecks( ** to run without a statement journal if there are no indexes on the ** table. */ - Trigger *pTrigger = 0; - if( db->flags&SQLITE_RecTriggers ){ - pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); - } - if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){ + if( regTrigCnt ){ sqlite3MultiWrite(pParse); sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, regNewData, 1, 0, OE_Replace, 1, -1); + sqlite3VdbeAddOp2(v, OP_AddImm, regTrigCnt, 1); /* incr trigger cnt */ + nReplaceTrig++; }else{ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK assert( HasRowid(pTab) ); @@ -1631,6 +1920,7 @@ void sqlite3GenerateConstraintChecks( int regR; /* Range of registers holding conflicting PK */ int iThisCur; /* Cursor for this UNIQUE index */ int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */ + int addrConflictCk; /* First opcode in the conflict check logic */ if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ if( pUpIdx==pIdx ){ @@ -1670,14 +1960,15 @@ void sqlite3GenerateConstraintChecks( sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i); pParse->iSelfTab = 0; VdbeComment((v, "%s column %d", pIdx->zName, i)); + }else if( iField==XN_ROWID || iField==pTab->iPKey ){ + x = regNewData; + sqlite3VdbeAddOp2(v, OP_IntCopy, x, regIdx+i); + VdbeComment((v, "rowid")); }else{ - if( iField==XN_ROWID || iField==pTab->iPKey ){ - x = regNewData; - }else{ - x = iField + regNewData + 1; - } - sqlite3VdbeAddOp2(v, iField<0 ? OP_IntCopy : OP_SCopy, x, regIdx+i); - VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName)); + testcase( sqlite3TableColumnToStorage(pTab, iField)!=iField ); + x = sqlite3TableColumnToStorage(pTab, iField) + regNewData + 1; + sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i); + VdbeComment((v, "%s", pTab->aCol[iField].zName)); } } sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]); @@ -1687,6 +1978,7 @@ void sqlite3GenerateConstraintChecks( sqlite3SetMakeRecordP5(v, pIdx->pTable); } #endif + sqlite3VdbeReleaseRegisters(pParse, regIdx, pIdx->nColumn, 0, 0); /* In an UPDATE operation, if this index is the PRIMARY KEY index ** of a WITHOUT ROWID table and there has been no change the @@ -1744,8 +2036,9 @@ void sqlite3GenerateConstraintChecks( /* Check to see if the new index entry will be unique */ sqlite3VdbeVerifyAbortable(v, onError); - sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk, - regIdx, pIdx->nKeyCol); VdbeCoverage(v); + addrConflictCk = + sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk, + regIdx, pIdx->nKeyCol); VdbeCoverage(v); /* Generate code to handle collisions */ regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField); @@ -1766,7 +2059,7 @@ void sqlite3GenerateConstraintChecks( if( pIdx!=pPk ){ for(i=0; inKeyCol; i++){ assert( pPk->aiColumn[i]>=0 ); - x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]); + x = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i); VdbeComment((v, "%s.%s", pTab->zName, pTab->aCol[pPk->aiColumn[i]].zName)); @@ -1792,6 +2085,7 @@ void sqlite3GenerateConstraintChecks( addrJump = addrUniqueOk; op = OP_Eq; } + x = sqlite3TableColumnToStorage(pTab, x); sqlite3VdbeAddOp4(v, op, regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ ); @@ -1828,17 +2122,71 @@ void sqlite3GenerateConstraintChecks( break; } default: { - Trigger *pTrigger = 0; + int nConflictCk; /* Number of opcodes in conflict check logic */ + assert( onError==OE_Replace ); - if( db->flags&SQLITE_RecTriggers ){ - pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); - } - if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){ + nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk; + assert( nConflictCk>0 ); + testcase( nConflictCk>1 ); + if( regTrigCnt ){ sqlite3MultiWrite(pParse); + nReplaceTrig++; + } + if( pTrigger && isUpdate ){ + sqlite3VdbeAddOp1(v, OP_CursorLock, iDataCur); } sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, regR, nPkField, 0, OE_Replace, (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur); + if( pTrigger && isUpdate ){ + sqlite3VdbeAddOp1(v, OP_CursorUnlock, iDataCur); + } + if( regTrigCnt ){ + int addrBypass; /* Jump destination to bypass recheck logic */ + + sqlite3VdbeAddOp2(v, OP_AddImm, regTrigCnt, 1); /* incr trigger cnt */ + addrBypass = sqlite3VdbeAddOp0(v, OP_Goto); /* Bypass recheck */ + VdbeComment((v, "bypass recheck")); + + /* Here we insert code that will be invoked after all constraint + ** checks have run, if and only if one or more replace triggers + ** fired. */ + sqlite3VdbeResolveLabel(v, lblRecheckOk); + lblRecheckOk = sqlite3VdbeMakeLabel(pParse); + if( pIdx->pPartIdxWhere ){ + /* Bypass the recheck if this partial index is not defined + ** for the current row */ + sqlite3VdbeAddOp2(v, OP_IsNull, regIdx-1, lblRecheckOk); + VdbeCoverage(v); + } + /* Copy the constraint check code from above, except change + ** the constraint-ok jump destination to be the address of + ** the next retest block */ + while( nConflictCk>0 ){ + VdbeOp x; /* Conflict check opcode to copy */ + /* The sqlite3VdbeAddOp4() call might reallocate the opcode array. + ** Hence, make a complete copy of the opcode, rather than using + ** a pointer to the opcode. */ + x = *sqlite3VdbeGetOp(v, addrConflictCk); + if( x.opcode!=OP_IdxRowid ){ + int p2; /* New P2 value for copied conflict check opcode */ + if( sqlite3OpcodeProperty[x.opcode]&OPFLG_JUMP ){ + p2 = lblRecheckOk; + }else{ + p2 = x.p2; + } + sqlite3VdbeAddOp4(v, x.opcode, x.p1, p2, x.p3, x.p4.z, x.p4type); + sqlite3VdbeChangeP5(v, x.p5); + VdbeCoverageIf(v, p2!=x.p2); + } + nConflictCk--; + addrConflictCk++; + } + /* If the retest fails, issue an abort */ + sqlite3UniqueConstraint(pParse, OE_Abort, pIdx); + + sqlite3VdbeJumpHere(v, addrBypass); /* Terminate the recheck bypass */ + } seenReplace = 1; break; } @@ -1859,10 +2207,30 @@ void sqlite3GenerateConstraintChecks( sqlite3VdbeJumpHere(v, ipkBottom); } + /* Recheck all uniqueness constraints after replace triggers have run */ + testcase( regTrigCnt!=0 && nReplaceTrig==0 ); + assert( regTrigCnt!=0 || nReplaceTrig==0 ); + if( nReplaceTrig ){ + sqlite3VdbeAddOp2(v, OP_IfNot, regTrigCnt, lblRecheckOk);VdbeCoverage(v); + if( !pPk ){ + if( isUpdate ){ + sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRecheck, regOldData); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + VdbeCoverage(v); + } + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRecheck, regNewData); + VdbeCoverage(v); + sqlite3RowidConstraint(pParse, OE_Abort, pTab); + }else{ + sqlite3VdbeGoto(v, addrRecheck); + } + sqlite3VdbeResolveLabel(v, lblRecheckOk); + } + /* Generate the table record */ if( HasRowid(pTab) ){ int regRec = aRegIdx[ix]; - sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nCol, regRec); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nNVCol, regRec); sqlite3SetMakeRecordP5(v, pTab); if( !bAffinityDone ){ sqlite3TableAffinity(v, pTab, 0); @@ -1929,6 +2297,10 @@ void sqlite3CompleteInsertion( assert( v!=0 ); assert( pTab->pSelect==0 ); /* This table is not a VIEW */ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ + /* All REPLACE indexes are at the end of the list */ + assert( pIdx->onError!=OE_Replace + || pIdx->pNext==0 + || pIdx->pNext->onError==OE_Replace ); if( aRegIdx[i]==0 ) continue; if( pIdx->pPartIdxWhere ){ sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); @@ -2079,7 +2451,7 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){ int i; assert( pDest && pSrc ); assert( pDest->pTable!=pSrc->pTable ); - if( pDest->nKeyCol!=pSrc->nKeyCol ){ + if( pDest->nKeyCol!=pSrc->nKeyCol || pDest->nColumn!=pSrc->nColumn ){ return 0; /* Different number of columns */ } if( pDest->onError!=pSrc->onError ){ @@ -2256,6 +2628,39 @@ static int xferOptimization( ){ return 0; /* Neither table may have __hidden__ columns */ } +#endif +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + /* Even if tables t1 and t2 have identical schemas, if they contain + ** generated columns, then this statement is semantically incorrect: + ** + ** INSERT INTO t2 SELECT * FROM t1; + ** + ** The reason is that generated column values are returned by the + ** the SELECT statement on the right but the INSERT statement on the + ** left wants them to be omitted. + ** + ** Nevertheless, this is a useful notational shorthand to tell SQLite + ** to do a bulk transfer all of the content from t1 over to t2. + ** + ** We could, in theory, disable this (except for internal use by the + ** VACUUM command where it is actually needed). But why do that? It + ** seems harmless enough, and provides a useful service. + */ + if( (pDestCol->colFlags & COLFLAG_GENERATED) != + (pSrcCol->colFlags & COLFLAG_GENERATED) ){ + return 0; /* Both columns have the same generated-column type */ + } + /* But the transfer is only allowed if both the source and destination + ** tables have the exact same expressions for generated columns. + ** This requirement could be relaxed for VIRTUAL columns, I suppose. + */ + if( (pDestCol->colFlags & COLFLAG_GENERATED)!=0 ){ + if( sqlite3ExprCompare(0, pSrcCol->pDflt, pDestCol->pDflt, -1)!=0 ){ + testcase( pDestCol->colFlags & COLFLAG_VIRTUAL ); + testcase( pDestCol->colFlags & COLFLAG_STORED ); + return 0; /* Different generator expressions */ + } + } #endif if( pDestCol->affinity!=pSrcCol->affinity ){ return 0; /* Affinity must be the same on all columns */ @@ -2267,7 +2672,7 @@ static int xferOptimization( return 0; /* tab2 must be NOT NULL if tab1 is */ } /* Default values for second and subsequent columns need to match. */ - if( i>0 ){ + if( (pDestCol->colFlags & COLFLAG_GENERATED)==0 && i>0 ){ assert( pDestCol->pDflt==0 || pDestCol->pDflt->op==TK_SPAN ); assert( pSrcCol->pDflt==0 || pSrcCol->pDflt->op==TK_SPAN ); if( (pDestCol->pDflt==0)!=(pSrcCol->pDflt==0) diff --git a/src/loadext.c b/src/loadext.c index 423a16fd..245e9b00 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -468,6 +468,12 @@ static const sqlite3_api_routines sqlite3Apis = { #else 0, #endif + /* Version 3.31.0 and later */ + sqlite3_hard_heap_limit64, + sqlite3_uri_key, + sqlite3_filename_database, + sqlite3_filename_journal, + sqlite3_filename_wal, }; /* diff --git a/src/main.c b/src/main.c index 3ef3a3d9..903f187a 100644 --- a/src/main.c +++ b/src/main.c @@ -683,6 +683,9 @@ int sqlite3_config(int op, ...){ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ #ifndef SQLITE_OMIT_LOOKASIDE void *pStart; + sqlite3_int64 szAlloc = sz*(sqlite3_int64)cnt; + int nBig; /* Number of full-size slots */ + int nSm; /* Number smaller LOOKASIDE_SMALL-byte slots */ if( sqlite3LookasideUsed(db,0)>0 ){ return SQLITE_BUSY; @@ -705,37 +708,71 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ pStart = 0; }else if( pBuf==0 ){ sqlite3BeginBenignMalloc(); - pStart = sqlite3Malloc( sz*(sqlite3_int64)cnt ); /* IMP: R-61949-35727 */ + pStart = sqlite3Malloc( szAlloc ); /* IMP: R-61949-35727 */ sqlite3EndBenignMalloc(); - if( pStart ) cnt = sqlite3MallocSize(pStart)/sz; + if( pStart ) szAlloc = sqlite3MallocSize(pStart); }else{ pStart = pBuf; } +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + if( sz>=LOOKASIDE_SMALL*3 ){ + nBig = szAlloc/(3*LOOKASIDE_SMALL+sz); + nSm = (szAlloc - sz*nBig)/LOOKASIDE_SMALL; + }else if( sz>=LOOKASIDE_SMALL*2 ){ + nBig = szAlloc/(LOOKASIDE_SMALL+sz); + nSm = (szAlloc - sz*nBig)/LOOKASIDE_SMALL; + }else +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ + if( sz>0 ){ + nBig = szAlloc/sz; + nSm = 0; + }else{ + nBig = nSm = 0; + } db->lookaside.pStart = pStart; db->lookaside.pInit = 0; db->lookaside.pFree = 0; db->lookaside.sz = (u16)sz; + db->lookaside.szTrue = (u16)sz; if( pStart ){ int i; LookasideSlot *p; assert( sz > (int)sizeof(LookasideSlot*) ); - db->lookaside.nSlot = cnt; p = (LookasideSlot*)pStart; - for(i=cnt-1; i>=0; i--){ + for(i=0; ipNext = db->lookaside.pInit; db->lookaside.pInit = p; p = (LookasideSlot*)&((u8*)p)[sz]; } +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + db->lookaside.pSmallInit = 0; + db->lookaside.pSmallFree = 0; + db->lookaside.pMiddle = p; + for(i=0; ipNext = db->lookaside.pSmallInit; + db->lookaside.pSmallInit = p; + p = (LookasideSlot*)&((u8*)p)[LOOKASIDE_SMALL]; + } +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ + assert( ((uptr)p)<=szAlloc + (uptr)pStart ); db->lookaside.pEnd = p; db->lookaside.bDisable = 0; db->lookaside.bMalloced = pBuf==0 ?1:0; + db->lookaside.nSlot = nBig+nSm; }else{ db->lookaside.pStart = db; +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + db->lookaside.pSmallInit = 0; + db->lookaside.pSmallFree = 0; + db->lookaside.pMiddle = db; +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ db->lookaside.pEnd = db; db->lookaside.bDisable = 1; + db->lookaside.sz = 0; db->lookaside.bMalloced = 0; db->lookaside.nSlot = 0; } + assert( sqlite3LookasideUsed(db,0)==0 ); #endif /* SQLITE_OMIT_LOOKASIDE */ return SQLITE_OK; } @@ -849,6 +886,8 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){ { SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, SQLITE_LegacyAlter }, { SQLITE_DBCONFIG_DQS_DDL, SQLITE_DqsDDL }, { SQLITE_DBCONFIG_DQS_DML, SQLITE_DqsDML }, + { SQLITE_DBCONFIG_LEGACY_FILE_FORMAT, SQLITE_LegacyFileFmt }, + { SQLITE_DBCONFIG_TRUSTED_SCHEMA, SQLITE_TrustedSchema }, }; unsigned int i; rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ @@ -1387,6 +1426,7 @@ const char *sqlite3ErrName(int rc){ case SQLITE_CANTOPEN_ISDIR: zName = "SQLITE_CANTOPEN_ISDIR"; break; case SQLITE_CANTOPEN_FULLPATH: zName = "SQLITE_CANTOPEN_FULLPATH"; break; case SQLITE_CANTOPEN_CONVPATH: zName = "SQLITE_CANTOPEN_CONVPATH"; break; + case SQLITE_CANTOPEN_SYMLINK: zName = "SQLITE_CANTOPEN_SYMLINK"; break; case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; @@ -1719,8 +1759,15 @@ int sqlite3CreateFunc( assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); - extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|SQLITE_SUBTYPE); + extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY| + SQLITE_SUBTYPE|SQLITE_INNOCUOUS); enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); + + /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But + ** the meaning is inverted. So flip the bit. */ + assert( SQLITE_FUNC_UNSAFE==SQLITE_INNOCUOUS ); + extraFlags ^= SQLITE_FUNC_UNSAFE; + #ifndef SQLITE_OMIT_UTF16 /* If SQLITE_UTF16 is specified as the encoding type, transform this @@ -1734,11 +1781,13 @@ int sqlite3CreateFunc( enc = SQLITE_UTF16NATIVE; }else if( enc==SQLITE_ANY ){ int rc; - rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags, + rc = sqlite3CreateFunc(db, zFunctionName, nArg, + (SQLITE_UTF8|extraFlags)^SQLITE_FUNC_UNSAFE, pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); if( rc==SQLITE_OK ){ - rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags, - pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); + rc = sqlite3CreateFunc(db, zFunctionName, nArg, + (SQLITE_UTF16LE|extraFlags)^SQLITE_FUNC_UNSAFE, + pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); } if( rc!=SQLITE_OK ){ return rc; @@ -3064,6 +3113,7 @@ static int openDatabase( db->magic = SQLITE_MAGIC_BUSY; db->aDb = db->aDbStatic; db->lookaside.bDisable = 1; + db->lookaside.sz = 0; assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); @@ -3077,7 +3127,9 @@ static int openDatabase( | SQLITE_EnableTrigger | SQLITE_EnableView | SQLITE_CacheSpill - +#if !defined(SQLITE_TRUSTED_SCHEMA) || SQLITE_TRUSTED_SCHEMA+0!=0 + | SQLITE_TrustedSchema +#endif /* The SQLITE_DQS compile-time option determines the default settings ** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML. ** @@ -3307,6 +3359,13 @@ static int openDatabase( } #endif +#ifdef SQLITE_ENABLE_INTERNAL_FUNCTIONS + /* Testing use only!!! The -DSQLITE_ENABLE_INTERNAL_FUNCTIONS=1 compile-time + ** option gives access to internal functions by default. + ** Testing use only!!! */ + db->mDbFlags |= DBFLAG_InternalFunc; +#endif + /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking ** mode. Doing nothing at all also makes NORMAL the default. @@ -3845,6 +3904,7 @@ int sqlite3_test_control(int op, ...){ ** This test-control also resets the PRNG so that the new seed will ** be used for the next call to sqlite3_randomness(). */ +#ifndef SQLITE_OMIT_WSD case SQLITE_TESTCTRL_PRNG_SEED: { int x = va_arg(ap, int); int y; @@ -3855,6 +3915,7 @@ int sqlite3_test_control(int op, ...){ sqlite3_randomness(0,0); break; } +#endif /* ** sqlite3_test_control(BITVEC_TEST, size, program) @@ -4039,15 +4100,14 @@ int sqlite3_test_control(int op, ...){ break; } - /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCS, int onoff); + /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, sqlite3*); ** - ** If parameter onoff is non-zero, internal-use-only SQL functions - ** are visible to ordinary SQL. This is useful for testing but is - ** unsafe because invalid parameters to those internal-use-only functions - ** can result in crashes or segfaults. + ** Toggle the ability to use internal functions on or off for + ** the database connection given in the argument. */ case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: { - sqlite3GlobalConfig.bInternalFunctions = va_arg(ap, int); + sqlite3 *db = va_arg(ap, sqlite3*); + db->mDbFlags ^= DBFLAG_InternalFunc; break; } @@ -4206,6 +4266,19 @@ const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){ return 0; } +/* +** Return a pointer to the name of Nth query parameter of the filename. +*/ +const char *sqlite3_uri_key(const char *zFilename, int N){ + if( zFilename==0 || N<0 ) return 0; + zFilename += sqlite3Strlen30(zFilename) + 1; + while( zFilename[0] && (N--)>0 ){ + zFilename += sqlite3Strlen30(zFilename) + 1; + zFilename += sqlite3Strlen30(zFilename) + 1; + } + return zFilename[0] ? zFilename : 0; +} + /* ** Return a boolean value for a query parameter. */ @@ -4231,6 +4304,46 @@ sqlite3_int64 sqlite3_uri_int64( return bDflt; } +/* +** The Pager stores the Journal filename, WAL filename, and Database filename +** consecutively in memory, in that order, with prefixes \000\001\000, +** \002\000, and \003\000, in that order. Thus the three names look like query +** parameters if you start at the first prefix. +** +** This routine backs up a filename to the start of the first prefix. +** +** This only works if the filenamed passed in was obtained from the Pager. +*/ +static const char *startOfNameList(const char *zName){ + while( zName[0]!='\001' || zName[1]!=0 ){ + zName -= 3; + while( zName[0]!='\000' ){ zName--; } + zName++; + } + return zName-1; +} + +/* +** Translate a filename that was handed to a VFS routine into the corresponding +** database, journal, or WAL file. +** +** It is an error to pass this routine a filename string that was not +** passed into the VFS from the SQLite core. Doing so is similar to +** passing free() a pointer that was not obtained from malloc() - it is +** an error that we cannot easily detect but that will likely cause memory +** corruption. +*/ +const char *sqlite3_filename_database(const char *zFilename){ + return sqlite3_uri_parameter(zFilename - 3, "\003"); +} +const char *sqlite3_filename_journal(const char *zFilename){ + const char *z = sqlite3_uri_parameter(startOfNameList(zFilename), "\001"); + return ALWAYS(z) && z[0] ? z : 0; +} +const char *sqlite3_filename_wal(const char *zFilename){ + return sqlite3_uri_parameter(startOfNameList(zFilename), "\002"); +} + /* ** Return the Btree pointer identified by zDbName. Return NULL if not found. */ diff --git a/src/malloc.c b/src/malloc.c index 559e7259..9dd400a3 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -32,19 +32,27 @@ int sqlite3_release_memory(int n){ #endif } +/* +** Default value of the hard heap limit. 0 means "no limit". +*/ +#ifndef SQLITE_MAX_MEMORY +# define SQLITE_MAX_MEMORY 0 +#endif + /* ** State information local to the memory allocation subsystem. */ static SQLITE_WSD struct Mem0Global { sqlite3_mutex *mutex; /* Mutex to serialize access */ sqlite3_int64 alarmThreshold; /* The soft heap limit */ + sqlite3_int64 hardLimit; /* The hard upper bound on memory */ /* ** True if heap is nearly "full" where "full" is defined by the ** sqlite3_soft_heap_limit() setting. */ int nearlyFull; -} mem0 = { 0, 0, 0 }; +} mem0 = { 0, SQLITE_MAX_MEMORY, SQLITE_MAX_MEMORY, 0 }; #define mem0 GLOBAL(struct Mem0Global, mem0) @@ -74,8 +82,15 @@ int sqlite3_memory_alarm( #endif /* -** Set the soft heap-size limit for the library. Passing a zero or -** negative value indicates no limit. +** Set the soft heap-size limit for the library. An argument of +** zero disables the limit. A negative argument is a no-op used to +** obtain the return value. +** +** The return value is the value of the heap limit just before this +** interface was called. +** +** If the hard heap limit is enabled, then the soft heap limit cannot +** be disabled nor raised above the hard heap limit. */ sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){ sqlite3_int64 priorLimit; @@ -91,6 +106,9 @@ sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){ sqlite3_mutex_leave(mem0.mutex); return priorLimit; } + if( mem0.hardLimit>0 && (n>mem0.hardLimit || n==0) ){ + n = mem0.hardLimit; + } mem0.alarmThreshold = n; nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); mem0.nearlyFull = (n>0 && n<=nUsed); @@ -104,6 +122,37 @@ void sqlite3_soft_heap_limit(int n){ sqlite3_soft_heap_limit64(n); } +/* +** Set the hard heap-size limit for the library. An argument of zero +** disables the hard heap limit. A negative argument is a no-op used +** to obtain the return value without affecting the hard heap limit. +** +** The return value is the value of the hard heap limit just prior to +** calling this interface. +** +** Setting the hard heap limit will also activate the soft heap limit +** and constrain the soft heap limit to be no more than the hard heap +** limit. +*/ +sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 n){ + sqlite3_int64 priorLimit; +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return -1; +#endif + sqlite3_mutex_enter(mem0.mutex); + priorLimit = mem0.hardLimit; + if( n>=0 ){ + mem0.hardLimit = n; + if( nSQLITE_MAX_MEMORY ){ - *pp = 0; - return; - } -#endif - sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n); if( mem0.alarmThreshold>0 ){ sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); if( nUsed >= mem0.alarmThreshold - nFull ){ mem0.nearlyFull = 1; sqlite3MallocAlarm(nFull); + if( mem0.hardLimit ){ + nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + if( nUsed >= mem0.hardLimit - nFull ){ + *pp = 0; + return; + } + } }else{ mem0.nearlyFull = 0; } @@ -283,10 +332,17 @@ int sqlite3MallocSize(void *p){ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); return sqlite3GlobalConfig.m.xSize(p); } +static int lookasideMallocSize(sqlite3 *db, void *p){ +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + return plookaside.pMiddle ? db->lookaside.szTrue : LOOKASIDE_SMALL; +#else + return db->lookaside.szTrue; +#endif +} int sqlite3DbMallocSize(sqlite3 *db, void *p){ assert( p!=0 ); - if( db==0 || !isLookaside(db,p) ){ #ifdef SQLITE_DEBUG + if( db==0 || !isLookaside(db,p) ){ if( db==0 ){ assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); @@ -294,12 +350,23 @@ int sqlite3DbMallocSize(sqlite3 *db, void *p){ assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); } -#endif - return sqlite3GlobalConfig.m.xSize(p); - }else{ - assert( sqlite3_mutex_held(db->mutex) ); - return db->lookaside.sz; } +#endif + if( db ){ + if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){ +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ + assert( sqlite3_mutex_held(db->mutex) ); + return LOOKASIDE_SMALL; + } +#endif + if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){ + assert( sqlite3_mutex_held(db->mutex) ); + return db->lookaside.szTrue; + } + } + } + return sqlite3GlobalConfig.m.xSize(p); } sqlite3_uint64 sqlite3_msize(void *p){ assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); @@ -346,15 +413,27 @@ void sqlite3DbFreeNN(sqlite3 *db, void *p){ measureAllocationSize(db, p); return; } - if( isLookaside(db, p) ){ - LookasideSlot *pBuf = (LookasideSlot*)p; + if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){ +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ + LookasideSlot *pBuf = (LookasideSlot*)p; #ifdef SQLITE_DEBUG - /* Trash all content in the buffer being freed */ - memset(p, 0xaa, db->lookaside.sz); + memset(p, 0xaa, LOOKASIDE_SMALL); /* Trash freed content */ #endif - pBuf->pNext = db->lookaside.pFree; - db->lookaside.pFree = pBuf; - return; + pBuf->pNext = db->lookaside.pSmallFree; + db->lookaside.pSmallFree = pBuf; + return; + } +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ + if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){ + LookasideSlot *pBuf = (LookasideSlot*)p; +#ifdef SQLITE_DEBUG + memset(p, 0xaa, db->lookaside.szTrue); /* Trash freed content */ +#endif + pBuf->pNext = db->lookaside.pFree; + db->lookaside.pFree = pBuf; + return; + } } } assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); @@ -510,23 +589,37 @@ void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){ assert( db!=0 ); assert( sqlite3_mutex_held(db->mutex) ); assert( db->pnBytesFreed==0 ); - if( db->lookaside.bDisable==0 ){ - assert( db->mallocFailed==0 ); - if( n>db->lookaside.sz ){ - db->lookaside.anStat[1]++; - }else if( (pBuf = db->lookaside.pFree)!=0 ){ - db->lookaside.pFree = pBuf->pNext; - db->lookaside.anStat[0]++; - return (void*)pBuf; - }else if( (pBuf = db->lookaside.pInit)!=0 ){ - db->lookaside.pInit = pBuf->pNext; - db->lookaside.anStat[0]++; - return (void*)pBuf; - }else{ - db->lookaside.anStat[2]++; + if( n>db->lookaside.sz ){ + if( !db->lookaside.bDisable ){ + db->lookaside.anStat[1]++; + }else if( db->mallocFailed ){ + return 0; } - }else if( db->mallocFailed ){ - return 0; + return dbMallocRawFinish(db, n); + } +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + if( n<=LOOKASIDE_SMALL ){ + if( (pBuf = db->lookaside.pSmallFree)!=0 ){ + db->lookaside.pSmallFree = pBuf->pNext; + db->lookaside.anStat[0]++; + return (void*)pBuf; + }else if( (pBuf = db->lookaside.pSmallInit)!=0 ){ + db->lookaside.pSmallInit = pBuf->pNext; + db->lookaside.anStat[0]++; + return (void*)pBuf; + } + } +#endif + if( (pBuf = db->lookaside.pFree)!=0 ){ + db->lookaside.pFree = pBuf->pNext; + db->lookaside.anStat[0]++; + return (void*)pBuf; + }else if( (pBuf = db->lookaside.pInit)!=0 ){ + db->lookaside.pInit = pBuf->pNext; + db->lookaside.anStat[0]++; + return (void*)pBuf; + }else{ + db->lookaside.anStat[2]++; } #else assert( db!=0 ); @@ -550,7 +643,16 @@ void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){ assert( db!=0 ); if( p==0 ) return sqlite3DbMallocRawNN(db, n); assert( sqlite3_mutex_held(db->mutex) ); - if( isLookaside(db,p) && n<=db->lookaside.sz ) return p; + if( ((uptr)p)<(uptr)db->lookaside.pEnd ){ +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + if( ((uptr)p)>=(uptr)db->lookaside.pMiddle ){ + if( n<=LOOKASIDE_SMALL ) return p; + }else +#endif + if( ((uptr)p)>=(uptr)db->lookaside.pStart ){ + if( n<=db->lookaside.szTrue ) return p; + } + } return dbReallocFinish(db, p, n); } static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){ @@ -561,7 +663,7 @@ static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){ if( isLookaside(db, p) ){ pNew = sqlite3DbMallocRawNN(db, n); if( pNew ){ - memcpy(pNew, p, db->lookaside.sz); + memcpy(pNew, p, lookasideMallocSize(db, p)); sqlite3DbFree(db, p); } }else{ @@ -660,7 +762,7 @@ void sqlite3OomFault(sqlite3 *db){ if( db->nVdbeExec>0 ){ db->u1.isInterrupted = 1; } - db->lookaside.bDisable++; + DisableLookaside; if( db->pParse ){ db->pParse->rc = SQLITE_NOMEM_BKPT; } @@ -679,7 +781,7 @@ void sqlite3OomClear(sqlite3 *db){ db->mallocFailed = 0; db->u1.isInterrupted = 0; assert( db->lookaside.bDisable>0 ); - db->lookaside.bDisable--; + EnableLookaside; } } diff --git a/src/os.c b/src/os.c index b9ad29d4..b729e95e 100644 --- a/src/os.c +++ b/src/os.c @@ -215,7 +215,7 @@ int sqlite3OsOpen( ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example, ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before ** reaching the VFS. */ - rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut); + rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x1087f7f, pFlagsOut); assert( rc==SQLITE_OK || pFile->pMethods==0 ); return rc; } diff --git a/src/os_unix.c b/src/os_unix.c index f2ac89f2..07ae4bc0 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3685,7 +3685,7 @@ static int openDirectory(const char *zFilename, int *pFd){ if( zDirname[0]!='/' ) zDirname[0] = '.'; zDirname[1] = 0; } - fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0); + fd = robust_open(zDirname, O_RDONLY|O_BINARY|O_NOFOLLOW, 0); if( fd>=0 ){ OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname)); } @@ -4576,10 +4576,12 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ if( pInode->bProcessLock==0 ){ if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ - pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777)); + pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT|O_NOFOLLOW, + (sStat.st_mode&0777)); } if( pShmNode->hShm<0 ){ - pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777)); + pShmNode->hShm = robust_open(zShm, O_RDONLY|O_NOFOLLOW, + (sStat.st_mode&0777)); if( pShmNode->hShm<0 ){ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm); goto shm_open_err; @@ -5929,7 +5931,7 @@ static int unixOpen( unixFile *p = (unixFile *)pFile; int fd = -1; /* File descriptor returned by open() */ int openFlags = 0; /* Flags to pass to open() */ - int eType = flags&0xFFFFFF00; /* Type of file to open */ + int eType = flags&0x0FFF00; /* Type of file to open */ int noLock; /* True to omit locking primitives */ int rc = SQLITE_OK; /* Function Return Code */ int ctrlFlags = 0; /* UNIXFILE_* flags */ @@ -6039,7 +6041,7 @@ static int unixOpen( if( isReadWrite ) openFlags |= O_RDWR; if( isCreate ) openFlags |= O_CREAT; if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW); - openFlags |= (O_LARGEFILE|O_BINARY); + openFlags |= (O_LARGEFILE|O_BINARY|O_NOFOLLOW); if( fd<0 ){ mode_t openMode; /* Permissions to create file with */ @@ -6257,7 +6259,8 @@ static int unixAccess( if( flags==SQLITE_ACCESS_EXISTS ){ struct stat buf; - *pResOut = (0==osStat(zPath, &buf) && buf.st_size>0); + *pResOut = 0==osStat(zPath, &buf) && + (!S_ISREG(buf.st_mode) || buf.st_size>0); }else{ *pResOut = osAccess(zPath, W_OK|R_OK)==0; } @@ -6311,7 +6314,7 @@ static int unixFullPathname( #else int rc = SQLITE_OK; int nByte; - int nLink = 1; /* Number of symbolic links followed so far */ + int nLink = 0; /* Number of symbolic links followed so far */ const char *zIn = zPath; /* Input path for each iteration of loop */ char *zDel = 0; @@ -6340,10 +6343,11 @@ static int unixFullPathname( } if( bLink ){ + nLink++; if( zDel==0 ){ zDel = sqlite3_malloc(nOut); if( zDel==0 ) rc = SQLITE_NOMEM_BKPT; - }else if( ++nLink>SQLITE_MAX_SYMLINKS ){ + }else if( nLink>=SQLITE_MAX_SYMLINKS ){ rc = SQLITE_CANTOPEN_BKPT; } @@ -6379,6 +6383,7 @@ static int unixFullPathname( }while( rc==SQLITE_OK ); sqlite3_free(zDel); + if( rc==SQLITE_OK && nLink ) rc = SQLITE_OK_SYMLINK; return rc; #endif /* HAVE_READLINK && HAVE_LSTAT */ } @@ -6864,7 +6869,7 @@ static int proxyCreateUnixFile( int fd = -1; unixFile *pNew; int rc = SQLITE_OK; - int openFlags = O_RDWR | O_CREAT; + int openFlags = O_RDWR | O_CREAT | O_NOFOLLOW; sqlite3_vfs dummyVfs; int terrno = 0; UnixUnusedFd *pUnused = NULL; @@ -6894,7 +6899,7 @@ static int proxyCreateUnixFile( } } if( fd<0 ){ - openFlags = O_RDONLY; + openFlags = O_RDONLY | O_NOFOLLOW; fd = robust_open(path, openFlags, 0); terrno = errno; } @@ -7020,7 +7025,7 @@ static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){ goto end_breaklock; } /* write it out to the temporary break file */ - fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL), 0); + fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW), 0); if( fd<0 ){ sqlite3_snprintf(sizeof(errmsg), errmsg, "create failed (%d)", errno); goto end_breaklock; diff --git a/src/pager.c b/src/pager.c index 24c7a2d5..ae75aeb7 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1172,6 +1172,7 @@ static int pagerUnlockDb(Pager *pPager, int eLock){ } IOTRACE(("UNLOCK %p %d\n", pPager, eLock)) } + pPager->changeCountDone = pPager->tempFile; /* ticket fb3b3024ea238d5c */ return rc; } @@ -1359,6 +1360,7 @@ static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){ len = 0; } zMaster[len] = '\0'; + zMaster[len+1] = '\0'; return SQLITE_OK; } @@ -1892,7 +1894,6 @@ static void pager_unlock(Pager *pPager){ ** code is cleared and the cache reset in the block below. */ assert( pPager->errCode || pPager->eState!=PAGER_ERROR ); - pPager->changeCountDone = 0; pPager->eState = PAGER_OPEN; } @@ -2156,7 +2157,6 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0)) ){ rc2 = pagerUnlockDb(pPager, SHARED_LOCK); - pPager->changeCountDone = 0; } pPager->eState = PAGER_READER; pPager->setMaster = 0; @@ -2595,15 +2595,16 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){ rc = sqlite3OsFileSize(pMaster, &nMasterJournal); if( rc!=SQLITE_OK ) goto delmaster_out; nMasterPtr = pVfs->mxPathname+1; - zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 1); + zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 2); if( !zMasterJournal ){ rc = SQLITE_NOMEM_BKPT; goto delmaster_out; } - zMasterPtr = &zMasterJournal[nMasterJournal+1]; + zMasterPtr = &zMasterJournal[nMasterJournal+2]; rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0); if( rc!=SQLITE_OK ) goto delmaster_out; zMasterJournal[nMasterJournal] = 0; + zMasterJournal[nMasterJournal+1] = 0; zJournal = zMasterJournal; while( (zJournal-zMasterJournal)=0 ); + nUriByte = (int)(&z[1] - zUri); + assert( nUriByte>=1 ); if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){ /* This branch is taken when the journal path required by ** the database being opened will be more than pVfs->mxPathname @@ -4826,50 +4838,88 @@ int sqlite3PagerOpen( ** Database file handle (pVfs->szOsFile bytes) ** Sub-journal file handle (journalFileSize bytes) ** Main journal file handle (journalFileSize bytes) + ** \0\1\0 journal prefix (3 bytes) + ** Journal filename (nPathname+8+1 bytes) + ** \2\0 WAL prefix (2 bytes) + ** WAL filename (nPathname+4+1 bytes) + ** \3\0 database prefix (2 bytes) ** Database file name (nPathname+1 bytes) - ** Journal file name (nPathname+8+1 bytes) + ** URI query parameters (nUriByte bytes) + ** \0\0 terminator (2 bytes) */ pPtr = (u8 *)sqlite3MallocZero( - ROUND8(sizeof(*pPager)) + /* Pager structure */ - ROUND8(pcacheSize) + /* PCache object */ - ROUND8(pVfs->szOsFile) + /* The main db file */ - journalFileSize * 2 + /* The two journal files */ - nPathname + 1 + nUri + /* zFilename */ - nPathname + 8 + 2 /* zJournal */ + ROUND8(sizeof(*pPager)) + /* Pager structure */ + ROUND8(pcacheSize) + /* PCache object */ + ROUND8(pVfs->szOsFile) + /* The main db file */ + journalFileSize * 2 + /* The two journal files */ + 3 + /* Journal prefix */ + nPathname + 8 + 1 + /* Journal filename */ #ifndef SQLITE_OMIT_WAL - + nPathname + 4 + 2 /* zWal */ + 2 + /* WAL prefix */ + nPathname + 4 + 1 + /* WAL filename */ #endif + 2 + /* Database prefix */ + nPathname + 1 + /* database filename */ + nUriByte + /* query parameters */ + 2 /* Terminator */ ); assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); if( !pPtr ){ sqlite3DbFree(0, zPathname); return SQLITE_NOMEM_BKPT; } - pPager = (Pager*)(pPtr); - pPager->pPCache = (PCache*)(pPtr += ROUND8(sizeof(*pPager))); - pPager->fd = (sqlite3_file*)(pPtr += ROUND8(pcacheSize)); - pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile)); - pPager->jfd = (sqlite3_file*)(pPtr += journalFileSize); - pPager->zFilename = (char*)(pPtr += journalFileSize); + pPager = (Pager*)pPtr; pPtr += ROUND8(sizeof(*pPager)); + pPager->pPCache = (PCache*)pPtr; pPtr += ROUND8(pcacheSize); + pPager->fd = (sqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile); + pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; + pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); - /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */ - if( zPathname ){ - assert( nPathname>0 ); - pPager->zJournal = (char*)(pPtr += nPathname + 1 + nUri); - memcpy(pPager->zFilename, zPathname, nPathname); - if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri); - memcpy(pPager->zJournal, zPathname, nPathname); - memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+2); - sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal); -#ifndef SQLITE_OMIT_WAL - pPager->zWal = &pPager->zJournal[nPathname+8+1]; - memcpy(pPager->zWal, zPathname, nPathname); - memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1); - sqlite3FileSuffix3(pPager->zFilename, pPager->zWal); + + /* Fill in Pager.zJournal */ + pPtr[1] = '\001'; pPtr += 3; + if( nPathname>0 ){ + pPager->zJournal = (char*)pPtr; + memcpy(pPtr, zPathname, nPathname); pPtr += nPathname; + memcpy(pPtr, "-journal",8); pPtr += 8 + 1; +#ifdef SQLITE_ENABLE_8_3_NAMES + sqlite3FileSuffix3(zFilename,pPager->zJournal); + pPtr = (u8*)(pPager->zJournal + sqlite3Strlen30(pPager->zJournal)+1); #endif - sqlite3DbFree(0, zPathname); + }else{ + pPager->zJournal = 0; + pPtr++; } + +#ifndef SQLITE_OMIT_WAL + /* Fill in Pager.zWal */ + pPtr[0] = '\002'; pPtr[1] = 0; pPtr += 2; + if( nPathname>0 ){ + pPager->zWal = (char*)pPtr; + memcpy(pPtr, zPathname, nPathname); pPtr += nPathname; + memcpy(pPtr, "-wal", 4); pPtr += 4 + 1; +#ifdef SQLITE_ENABLE_8_3_NAMES + sqlite3FileSuffix3(zFilename, pPager->zWal); + pPtr = (u8*)(pPager->zWal + sqlite3Strlen30(pPager->zWal)+1); +#endif + }else{ + pPager->zWal = 0; + pPtr++; + } +#endif + + /* Fill in the Pager.zFilename and pPager.zQueryParam fields */ + pPtr[0] = '\003'; pPtr[1] = 0; pPtr += 2; + pPager->zFilename = (char*)pPtr; + if( nPathname>0 ){ + memcpy(pPtr, zPathname, nPathname); pPtr += nPathname + 1; + if( zUri ){ + memcpy(pPtr, zUri, nUriByte); /* pPtr += nUriByte; // not needed */ + } + /* Double-zero terminator implied by the sqlite3MallocZero */ + } + + if( nPathname ) sqlite3DbFree(0, zPathname); pPager->pVfs = pVfs; pPager->vfsFlags = vfsFlags; @@ -4918,9 +4968,9 @@ int sqlite3PagerOpen( } #endif } - pPager->noLock = sqlite3_uri_boolean(zFilename, "nolock", 0); + pPager->noLock = sqlite3_uri_boolean(pPager->zFilename, "nolock", 0); if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0 - || sqlite3_uri_boolean(zFilename, "immutable", 0) ){ + || sqlite3_uri_boolean(pPager->zFilename, "immutable", 0) ){ vfsFlags |= SQLITE_OPEN_READONLY; goto act_like_temp_file; } @@ -6611,6 +6661,7 @@ int sqlite3PagerCommitPhaseTwo(Pager *pPager){ ** But if (due to a coding error elsewhere in the system) it does get ** called, just return the same error code without doing anything. */ if( NEVER(pPager->errCode) ) return pPager->errCode; + pPager->iDataVersion++; assert( pPager->eState==PAGER_WRITER_LOCKED || pPager->eState==PAGER_WRITER_FINISHED @@ -6639,7 +6690,6 @@ int sqlite3PagerCommitPhaseTwo(Pager *pPager){ } PAGERTRACE(("COMMIT %d\n", PAGERID(pPager))); - pPager->iDataVersion++; rc = pager_end_transaction(pPager, pPager->setMaster, 1); return pager_error(pPager, rc); } @@ -6983,9 +7033,13 @@ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ ** behavior. But when the Btree needs to know the filename for matching to ** shared cache, it uses nullIfMemDb==0 so that in-memory databases can ** participate in shared-cache. +** +** The return value to this routine is always safe to use with +** sqlite3_uri_parameter() and sqlite3_filename_database() and friends. */ -const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){ - return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename; +const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){ + static const char zFake[] = { 0x00, 0x01, 0x00, 0x00, 0x00 }; + return (nullIfMemDb && pPager->memDb) ? &zFake[3] : pPager->zFilename; } /* @@ -7640,6 +7694,8 @@ int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){ return rc; } + + #ifdef SQLITE_ENABLE_SNAPSHOT /* ** If this is a WAL database, obtain a snapshot handle for the snapshot diff --git a/src/pager.h b/src/pager.h index de96dc55..90427894 100644 --- a/src/pager.h +++ b/src/pager.h @@ -203,7 +203,7 @@ u32 sqlite3PagerDataVersion(Pager*); int sqlite3PagerRefcount(Pager*); #endif int sqlite3PagerMemUsed(Pager*); -const char *sqlite3PagerFilename(Pager*, int); +const char *sqlite3PagerFilename(const Pager*, int); sqlite3_vfs *sqlite3PagerVfs(Pager*); sqlite3_file *sqlite3PagerFile(Pager*); sqlite3_file *sqlite3PagerJrnlFile(Pager*); diff --git a/src/parse.y b/src/parse.y index 2b69dd59..5876a1ae 100644 --- a/src/parse.y +++ b/src/parse.y @@ -106,8 +106,9 @@ struct FrameBound { int eType; Expr *pExpr; }; ** shared across database connections. */ static void disableLookaside(Parse *pParse){ + sqlite3 *db = pParse->db; pParse->disableLookaside++; - pParse->db->lookaside.bDisable++; + DisableLookaside; } } // end %include @@ -119,7 +120,7 @@ cmdlist ::= ecmd. ecmd ::= SEMI. ecmd ::= cmdx SEMI. %ifndef SQLITE_OMIT_EXPLAIN -ecmd ::= explain cmdx. +ecmd ::= explain cmdx SEMI. {NEVER-REDUCE} explain ::= EXPLAIN. { pParse->explain = 1; } explain ::= EXPLAIN QUERY PLAN. { pParse->explain = 2; } %endif SQLITE_OMIT_EXPLAIN @@ -219,6 +220,9 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);} CURRENT FOLLOWING PARTITION PRECEDING RANGE UNBOUNDED EXCLUDE GROUPS OTHERS TIES %endif SQLITE_OMIT_WINDOWFUNC +%ifndef SQLITE_OMIT_GENERATED_COLUMNS + GENERATED ALWAYS +%endif REINDEX RENAME CTIME_KW IF . %wildcard ANY. @@ -346,6 +350,10 @@ ccons ::= REFERENCES nm(T) eidlist_opt(TA) refargs(R). {sqlite3CreateForeignKey(pParse,0,&T,TA,R);} ccons ::= defer_subclause(D). {sqlite3DeferForeignKey(pParse,D);} ccons ::= COLLATE ids(C). {sqlite3AddCollateType(pParse, &C);} +ccons ::= GENERATED ALWAYS AS generated. +ccons ::= AS generated. +generated ::= LP expr(E) RP. {sqlite3AddGenerated(pParse,E,0);} +generated ::= LP expr(E) RP ID(TYPE). {sqlite3AddGenerated(pParse,E,&TYPE);} // The optional AUTOINCREMENT keyword %type autoinc {int} @@ -1070,6 +1078,9 @@ expr(A) ::= LP nexprlist(X) COMMA expr(Y) RP. { A = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); if( A ){ A->x.pList = pList; + if( ALWAYS(pList->nExpr) ){ + A->flags |= pList->a[0].pExpr->flags & EP_Propagate; + } }else{ sqlite3ExprListDelete(pParse->db, pList); } diff --git a/src/pcache1.c b/src/pcache1.c index d0051433..ed762ebf 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -448,13 +448,15 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){ } #else pPg = pcache1Alloc(pCache->szAlloc); - p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; #endif if( benignMalloc ){ sqlite3EndBenignMalloc(); } #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT pcache1EnterMutex(pCache->pGroup); #endif if( pPg==0 ) return 0; +#ifndef SQLITE_PCACHE_SEPARATE_HEADER + p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; +#endif p->page.pBuf = pPg; p->page.pExtra = &p[1]; p->isBulkLocal = 0; diff --git a/src/pragma.c b/src/pragma.c index 858e314a..4d33e8c4 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -295,6 +295,55 @@ static const PragmaName *pragmaLocate(const char *zName){ return lwr>upr ? 0 : &aPragmaName[mid]; } +/* +** Create zero or more entries in the output for the SQL functions +** defined by FuncDef p. +*/ +static void pragmaFunclistLine( + Vdbe *v, /* The prepared statement being created */ + FuncDef *p, /* A particular function definition */ + int isBuiltin, /* True if this is a built-in function */ + int showInternFuncs /* True if showing internal functions */ +){ + for(; p; p=p->pNext){ + const char *zType; + static const u32 mask = + SQLITE_DETERMINISTIC | + SQLITE_DIRECTONLY | + SQLITE_SUBTYPE | + SQLITE_INNOCUOUS | + SQLITE_FUNC_INTERNAL + ; + static const char *azEnc[] = { 0, "utf8", "utf16le", "utf16be" }; + + assert( SQLITE_FUNC_ENCMASK==0x3 ); + assert( strcmp(azEnc[SQLITE_UTF8],"utf8")==0 ); + assert( strcmp(azEnc[SQLITE_UTF16LE],"utf16le")==0 ); + assert( strcmp(azEnc[SQLITE_UTF16BE],"utf16be")==0 ); + + if( p->xSFunc==0 ) continue; + if( (p->funcFlags & SQLITE_FUNC_INTERNAL)!=0 + && showInternFuncs==0 + ){ + continue; + } + if( p->xValue!=0 ){ + zType = "w"; + }else if( p->xFinalize!=0 ){ + zType = "a"; + }else{ + zType = "s"; + } + sqlite3VdbeMultiLoad(v, 1, "sissii", + p->zName, isBuiltin, + zType, azEnc[p->funcFlags&SQLITE_FUNC_ENCMASK], + p->nArg, + (p->funcFlags & mask) ^ SQLITE_INNOCUOUS + ); + } +} + + /* ** Helper subroutine for PRAGMA integrity_check: ** @@ -1100,10 +1149,19 @@ void sqlite3Pragma( sqlite3CodeVerifySchema(pParse, iTabDb); sqlite3ViewGetColumnNames(pParse, pTab); for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ - int isHidden = IsHiddenColumn(pCol); - if( isHidden && pPragma->iArg==0 ){ - nHidden++; - continue; + int isHidden = 0; + if( pCol->colFlags & COLFLAG_NOINSERT ){ + if( pPragma->iArg==0 ){ + nHidden++; + continue; + } + if( pCol->colFlags & COLFLAG_VIRTUAL ){ + isHidden = 2; /* GENERATED ALWAYS AS ... VIRTUAL */ + }else if( pCol->colFlags & COLFLAG_STORED ){ + isHidden = 3; /* GENERATED ALWAYS AS ... STORED */ + }else{ assert( pCol->colFlags & COLFLAG_HIDDEN ); + isHidden = 1; /* HIDDEN */ + } } if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){ k = 0; @@ -1112,13 +1170,13 @@ void sqlite3Pragma( }else{ for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){} } - assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN ); + assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN || isHidden>=2 ); sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi", i-nHidden, pCol->zName, sqlite3ColumnType(pCol,""), pCol->notNull ? 1 : 0, - pCol->pDflt ? pCol->pDflt->u.zToken : 0, + pCol->pDflt && isHidden<2 ? pCol->pDflt->u.zToken : 0, k, isHidden); } @@ -1250,16 +1308,16 @@ void sqlite3Pragma( int i; HashElem *j; FuncDef *p; - pParse->nMem = 2; + int showInternFunc = (db->mDbFlags & DBFLAG_InternalFunc)!=0; + pParse->nMem = 6; for(i=0; iu.pHash ){ - if( p->funcFlags & SQLITE_FUNC_INTERNAL ) continue; - sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1); + pragmaFunclistLine(v, p, 1, showInternFunc); } } for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){ p = (FuncDef*)sqliteHashData(j); - sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 0); + pragmaFunclistLine(v, p, 0, showInternFunc); } } break; @@ -1577,7 +1635,7 @@ void sqlite3Pragma( loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); if( !isQuick ){ /* Sanity check on record header decoding */ - sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-1, 3); + sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nNVCol-1,3); sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); } /* Verify that all NOT NULL columns really are NOT NULL */ @@ -1587,7 +1645,9 @@ void sqlite3Pragma( if( j==pTab->iPKey ) continue; if( pTab->aCol[j].notNull==0 ) continue; sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); - sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); + if( sqlite3VdbeGetOp(v,-1)->opcode==OP_Column ){ + sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); + } jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v); zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, pTab->aCol[j].zName); @@ -1764,10 +1824,17 @@ void sqlite3Pragma( ** will be overwritten when the schema is next loaded. If it does not ** already exists, it will be created to use the new encoding value. */ - if( - !(DbHasProperty(db, 0, DB_SchemaLoaded)) || - DbHasProperty(db, 0, DB_Empty) - ){ + int canChangeEnc = 1; /* True if allowed to change the encoding */ + int i; /* For looping over all attached databases */ + for(i=0; inDb; i++){ + if( db->aDb[i].pBt!=0 + && DbHasProperty(db,i,DB_SchemaLoaded) + && !DbHasProperty(db,i,DB_Empty) + ){ + canChangeEnc = 0; + } + } + if( canChangeEnc ){ for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){ SCHEMA_ENC(db) = ENC(db) = @@ -2080,6 +2147,27 @@ void sqlite3Pragma( break; } + /* + ** PRAGMA hard_heap_limit + ** PRAGMA hard_heap_limit = N + ** + ** Invoke sqlite3_hard_heap_limit64() to query or set the hard heap + ** limit. The hard heap limit can be activated or lowered by this + ** pragma, but not raised or deactivated. Only the + ** sqlite3_hard_heap_limit64() C-language API can raise or deactivate + ** the hard heap limit. This allows an application to set a heap limit + ** constraint that cannot be relaxed by an untrusted SQL script. + */ + case PragTyp_HARD_HEAP_LIMIT: { + sqlite3_int64 N; + if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ + sqlite3_int64 iPrior = sqlite3_hard_heap_limit64(-1); + if( N>0 && (iPrior==0 || iPrior>N) ) sqlite3_hard_heap_limit64(N); + } + returnSingleInt(v, sqlite3_hard_heap_limit64(-1)); + break; + } + /* ** PRAGMA threads ** PRAGMA threads = N diff --git a/src/pragma.h b/src/pragma.h index b7f3282d..3edf5c1c 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -21,34 +21,35 @@ #define PragTyp_FOREIGN_KEY_CHECK 13 #define PragTyp_FOREIGN_KEY_LIST 14 #define PragTyp_FUNCTION_LIST 15 -#define PragTyp_INCREMENTAL_VACUUM 16 -#define PragTyp_INDEX_INFO 17 -#define PragTyp_INDEX_LIST 18 -#define PragTyp_INTEGRITY_CHECK 19 -#define PragTyp_JOURNAL_MODE 20 -#define PragTyp_JOURNAL_SIZE_LIMIT 21 -#define PragTyp_LOCK_PROXY_FILE 22 -#define PragTyp_LOCKING_MODE 23 -#define PragTyp_PAGE_COUNT 24 -#define PragTyp_MMAP_SIZE 25 -#define PragTyp_MODULE_LIST 26 -#define PragTyp_OPTIMIZE 27 -#define PragTyp_PAGE_SIZE 28 -#define PragTyp_PRAGMA_LIST 29 -#define PragTyp_SECURE_DELETE 30 -#define PragTyp_SHRINK_MEMORY 31 -#define PragTyp_SOFT_HEAP_LIMIT 32 -#define PragTyp_SYNCHRONOUS 33 -#define PragTyp_TABLE_INFO 34 -#define PragTyp_TEMP_STORE 35 -#define PragTyp_TEMP_STORE_DIRECTORY 36 -#define PragTyp_THREADS 37 -#define PragTyp_WAL_AUTOCHECKPOINT 38 -#define PragTyp_WAL_CHECKPOINT 39 -#define PragTyp_ACTIVATE_EXTENSIONS 40 -#define PragTyp_KEY 41 -#define PragTyp_LOCK_STATUS 42 -#define PragTyp_STATS 43 +#define PragTyp_HARD_HEAP_LIMIT 16 +#define PragTyp_INCREMENTAL_VACUUM 17 +#define PragTyp_INDEX_INFO 18 +#define PragTyp_INDEX_LIST 19 +#define PragTyp_INTEGRITY_CHECK 20 +#define PragTyp_JOURNAL_MODE 21 +#define PragTyp_JOURNAL_SIZE_LIMIT 22 +#define PragTyp_LOCK_PROXY_FILE 23 +#define PragTyp_LOCKING_MODE 24 +#define PragTyp_PAGE_COUNT 25 +#define PragTyp_MMAP_SIZE 26 +#define PragTyp_MODULE_LIST 27 +#define PragTyp_OPTIMIZE 28 +#define PragTyp_PAGE_SIZE 29 +#define PragTyp_PRAGMA_LIST 30 +#define PragTyp_SECURE_DELETE 31 +#define PragTyp_SHRINK_MEMORY 32 +#define PragTyp_SOFT_HEAP_LIMIT 33 +#define PragTyp_SYNCHRONOUS 34 +#define PragTyp_TABLE_INFO 35 +#define PragTyp_TEMP_STORE 36 +#define PragTyp_TEMP_STORE_DIRECTORY 37 +#define PragTyp_THREADS 38 +#define PragTyp_WAL_AUTOCHECKPOINT 39 +#define PragTyp_WAL_CHECKPOINT 40 +#define PragTyp_ACTIVATE_EXTENSIONS 41 +#define PragTyp_KEY 42 +#define PragTyp_LOCK_STATUS 43 +#define PragTyp_STATS 44 /* Property flags associated with various pragma. */ #define PragFlg_NeedSchema 0x01 /* Force schema load before running */ @@ -87,35 +88,39 @@ static const char *const pragCName[] = { /* 18 */ "desc", /* 19 */ "coll", /* 20 */ "key", - /* 21 */ "tbl", /* Used by: stats */ - /* 22 */ "idx", - /* 23 */ "wdth", - /* 24 */ "hght", - /* 25 */ "flgs", - /* 26 */ "seq", /* Used by: index_list */ - /* 27 */ "name", - /* 28 */ "unique", - /* 29 */ "origin", - /* 30 */ "partial", - /* 31 */ "table", /* Used by: foreign_key_check */ - /* 32 */ "rowid", - /* 33 */ "parent", - /* 34 */ "fkid", + /* 21 */ "name", /* Used by: function_list */ + /* 22 */ "builtin", + /* 23 */ "type", + /* 24 */ "enc", + /* 25 */ "narg", + /* 26 */ "flags", + /* 27 */ "tbl", /* Used by: stats */ + /* 28 */ "idx", + /* 29 */ "wdth", + /* 30 */ "hght", + /* 31 */ "flgs", + /* 32 */ "seq", /* Used by: index_list */ + /* 33 */ "name", + /* 34 */ "unique", + /* 35 */ "origin", + /* 36 */ "partial", + /* 37 */ "table", /* Used by: foreign_key_check */ + /* 38 */ "rowid", + /* 39 */ "parent", + /* 40 */ "fkid", /* index_info reuses 15 */ - /* 35 */ "seq", /* Used by: database_list */ - /* 36 */ "name", - /* 37 */ "file", - /* 38 */ "busy", /* Used by: wal_checkpoint */ - /* 39 */ "log", - /* 40 */ "checkpointed", - /* 41 */ "name", /* Used by: function_list */ - /* 42 */ "builtin", - /* collation_list reuses 26 */ - /* 43 */ "database", /* Used by: lock_status */ - /* 44 */ "status", - /* 45 */ "cache_size", /* Used by: default_cache_size */ + /* 41 */ "seq", /* Used by: database_list */ + /* 42 */ "name", + /* 43 */ "file", + /* 44 */ "busy", /* Used by: wal_checkpoint */ + /* 45 */ "log", + /* 46 */ "checkpointed", + /* collation_list reuses 32 */ + /* 47 */ "database", /* Used by: lock_status */ + /* 48 */ "status", + /* 49 */ "cache_size", /* Used by: default_cache_size */ /* module_list pragma_list reuses 9 */ - /* 46 */ "timeout", /* Used by: busy_timeout */ + /* 50 */ "timeout", /* Used by: busy_timeout */ }; /* Definitions of all built-in pragmas */ @@ -161,7 +166,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "busy_timeout", /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 46, 1, + /* ColNames: */ 50, 1, /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "cache_size", @@ -200,7 +205,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "collation_list", /* ePragTyp: */ PragTyp_COLLATION_LIST, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 26, 2, + /* ColNames: */ 32, 2, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) @@ -235,14 +240,14 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "database_list", /* ePragTyp: */ PragTyp_DATABASE_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0, - /* ColNames: */ 35, 3, + /* ColNames: */ 41, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) {/* zName: */ "default_cache_size", /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, - /* ColNames: */ 45, 1, + /* ColNames: */ 49, 1, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -272,7 +277,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "foreign_key_check", /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0, - /* ColNames: */ 31, 4, + /* ColNames: */ 37, 4, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FOREIGN_KEY) @@ -315,10 +320,15 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "function_list", /* ePragTyp: */ PragTyp_FUNCTION_LIST, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 41, 2, + /* ColNames: */ 21, 6, /* iArg: */ 0 }, #endif #endif + {/* zName: */ "hard_heap_limit", + /* ePragTyp: */ PragTyp_HARD_HEAP_LIMIT, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #if defined(SQLITE_HAS_CODEC) {/* zName: */ "hexkey", /* ePragTyp: */ PragTyp_KEY, @@ -356,7 +366,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "index_list", /* ePragTyp: */ PragTyp_INDEX_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 26, 5, + /* ColNames: */ 32, 5, /* iArg: */ 0 }, {/* zName: */ "index_xinfo", /* ePragTyp: */ PragTyp_INDEX_INFO, @@ -396,11 +406,6 @@ static const PragmaName aPragmaName[] = { /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_LegacyAlter }, - {/* zName: */ "legacy_file_format", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, - /* ColNames: */ 0, 0, - /* iArg: */ SQLITE_LegacyFileFmt }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE {/* zName: */ "lock_proxy_file", @@ -413,7 +418,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "lock_status", /* ePragTyp: */ PragTyp_LOCK_STATUS, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 43, 2, + /* ColNames: */ 47, 2, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) @@ -561,7 +566,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "stats", /* ePragTyp: */ PragTyp_STATS, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, - /* ColNames: */ 21, 5, + /* ColNames: */ 27, 5, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) @@ -612,6 +617,13 @@ static const PragmaName aPragmaName[] = { /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 0, 0, /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "trusted_schema", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_TrustedSchema }, +#endif #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) {/* zName: */ "user_version", /* ePragTyp: */ PragTyp_HEADER_VALUE, @@ -657,7 +669,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "wal_checkpoint", /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, /* ePragFlg: */ PragFlg_NeedSchema, - /* ColNames: */ 38, 3, + /* ColNames: */ 44, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -668,4 +680,4 @@ static const PragmaName aPragmaName[] = { /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError }, #endif }; -/* Number of pragmas: 65 on by default, 81 total. */ +/* Number of pragmas: 66 on by default, 82 total. */ diff --git a/src/prepare.c b/src/prepare.c index 70c16265..2d928f16 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -57,6 +57,18 @@ int sqlite3IndexHasDuplicateRootPage(Index *pIndex){ return 0; } +/* forward declaration */ +static int sqlite3Prepare( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ + Vdbe *pReprepare, /* VM being reprepared */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +); + + /* ** This is the callback routine for the code that initializes the ** database. See sqlite3Init() below for additional information. @@ -106,7 +118,8 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ db->init.newTnum = sqlite3Atoi(argv[3]); db->init.orphanTrigger = 0; db->init.azInit = argv; - TESTONLY(rcp = ) sqlite3_prepare(db, argv[4], -1, &pStmt, 0); + pStmt = 0; + TESTONLY(rcp = ) sqlite3Prepare(db, argv[4], -1, 0, 0, &pStmt, 0); rc = db->errCode; assert( (rc&0xFF)==(rcp&0xFF) ); db->init.iDb = saved_iDb; @@ -527,6 +540,7 @@ void sqlite3ParserReset(Parse *pParse){ if( db ){ assert( db->lookaside.bDisable >= pParse->disableLookaside ); db->lookaside.bDisable -= pParse->disableLookaside; + db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue; } pParse->disableLookaside = 0; } @@ -560,7 +574,7 @@ static int sqlite3Prepare( */ if( prepFlags & SQLITE_PREPARE_PERSISTENT ){ sParse.disableLookaside++; - db->lookaside.bDisable++; + DisableLookaside; } sParse.disableVtab = (prepFlags & SQLITE_PREPARE_NO_VTAB)!=0; @@ -587,16 +601,18 @@ static int sqlite3Prepare( ** but it does *not* override schema lock detection, so this all still ** works even if READ_UNCOMMITTED is set. */ - for(i=0; inDb; i++) { - Btree *pBt = db->aDb[i].pBt; - if( pBt ){ - assert( sqlite3BtreeHoldsMutex(pBt) ); - rc = sqlite3BtreeSchemaLocked(pBt); - if( rc ){ - const char *zDb = db->aDb[i].zDbSName; - sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb); - testcase( db->flags & SQLITE_ReadUncommit ); - goto end_prepare; + if( !db->noSharedCache ){ + for(i=0; inDb; i++) { + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + assert( sqlite3BtreeHoldsMutex(pBt) ); + rc = sqlite3BtreeSchemaLocked(pBt); + if( rc ){ + const char *zDb = db->aDb[i].zDbSName; + sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb); + testcase( db->flags & SQLITE_ReadUncommit ); + goto end_prepare; + } } } } @@ -627,48 +643,24 @@ static int sqlite3Prepare( } assert( 0==sParse.nQueryLoop ); - if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK; + if( sParse.rc==SQLITE_DONE ){ + sParse.rc = SQLITE_OK; + } if( sParse.checkSchema ){ schemaIsValid(&sParse); } - if( db->mallocFailed ){ - sParse.rc = SQLITE_NOMEM_BKPT; - } if( pzTail ){ *pzTail = sParse.zTail; } - rc = sParse.rc; - -#ifndef SQLITE_OMIT_EXPLAIN - /* Justification for the ALWAYS(): The only way for rc to be SQLITE_OK and - ** sParse.pVdbe to be NULL is if the input SQL is an empty string, but in - ** that case, sParse.explain will be false. */ - if( sParse.explain && rc==SQLITE_OK && ALWAYS(sParse.pVdbe) ){ - static const char * const azColName[] = { - "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", - "id", "parent", "notused", "detail" - }; - int iFirst, mx; - if( sParse.explain==2 ){ - sqlite3VdbeSetNumCols(sParse.pVdbe, 4); - iFirst = 8; - mx = 12; - }else{ - sqlite3VdbeSetNumCols(sParse.pVdbe, 8); - iFirst = 0; - mx = 8; - } - for(i=iFirst; iinit.busy==0 ){ sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags); } - if( rc!=SQLITE_OK || db->mallocFailed ){ + if( db->mallocFailed ){ + sParse.rc = SQLITE_NOMEM_BKPT; + } + rc = sParse.rc; + if( rc!=SQLITE_OK ){ if( sParse.pVdbe ) sqlite3VdbeFinalize(sParse.pVdbe); assert(!(*ppStmt)); }else{ diff --git a/src/resolve.c b/src/resolve.c index e66dc18e..119a07fd 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -132,13 +132,16 @@ static int nameInUsingClause(IdList *pUsing, const char *zCol){ ** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will ** match anything. */ -int sqlite3MatchSpanName( - const char *zSpan, +int sqlite3MatchEName( + const struct ExprList_item *pItem, const char *zCol, const char *zTab, const char *zDb ){ int n; + const char *zSpan; + if( NEVER(pItem->eEName!=ENAME_TAB) ) return 0; + zSpan = pItem->zEName; for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){ return 0; @@ -267,7 +270,7 @@ static int lookupName( int hit = 0; pEList = pItem->pSelect->pEList; for(j=0; jnExpr; j++){ - if( sqlite3MatchSpanName(pEList->a[j].zSpan, zCol, zTab, zDb) ){ + if( sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){ cnt++; cntTab = 2; pMatch = pItem; @@ -414,7 +417,7 @@ static int lookupName( if( cnt==0 && cntTab==1 && pMatch - && (pNC->ncFlags & NC_IdxExpr)==0 + && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 && sqlite3IsRowid(zCol) && VisibleRowid(pMatch->pTab) ){ @@ -448,8 +451,10 @@ static int lookupName( pEList = pNC->uNC.pEList; assert( pEList!=0 ); for(j=0; jnExpr; j++){ - char *zAs = pEList->a[j].zName; - if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ + char *zAs = pEList->a[j].zEName; + if( pEList->a[j].eEName==ENAME_NAME + && sqlite3_stricmp(zAs, zCol)==0 + ){ Expr *pOrig; assert( pExpr->pLeft==0 && pExpr->pRight==0 ); assert( pExpr->x.pList==0 ); @@ -459,7 +464,9 @@ static int lookupName( sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); return WRC_Abort; } - if( (pNC->ncFlags&NC_AllowWin)==0 && ExprHasProperty(pOrig, EP_Win) ){ + if( ExprHasProperty(pOrig, EP_Win) + && ((pNC->ncFlags&NC_AllowWin)==0 || pNC!=pTopNC ) + ){ sqlite3ErrorMsg(pParse, "misuse of aliased window function %s",zAs); return WRC_Abort; } @@ -551,18 +558,35 @@ static int lookupName( /* If a column from a table in pSrcList is referenced, then record ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes - ** bit 0 to be set. Column 1 sets bit 1. And so forth. If the - ** column number is greater than the number of bits in the bitmask - ** then set the high-order bit of the bitmask. + ** bit 0 to be set. Column 1 sets bit 1. And so forth. Bit 63 is + ** set if the 63rd or any subsequent column is used. + ** + ** The colUsed mask is an optimization used to help determine if an + ** index is a covering index. The correct answer is still obtained + ** if the mask contains extra set bits. However, it is important to + ** avoid setting bits beyond the maximum column number of the table. + ** (See ticket [b92e5e8ec2cdbaa1]). + ** + ** If a generated column is referenced, set bits for every column + ** of the table. */ if( pExpr->iColumn>=0 && pMatch!=0 ){ int n = pExpr->iColumn; - testcase( n==BMS-1 ); - if( n>=BMS ){ - n = BMS-1; - } + Table *pExTab = pExpr->y.pTab; + assert( pExTab!=0 ); assert( pMatch->iCursor==pExpr->iTable ); - pMatch->colUsed |= ((Bitmask)1)<tabFlags & TF_HasGenerated)!=0 + && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0 + ){ + testcase( pExTab->nCol==BMS-1 ); + testcase( pExTab->nCol==BMS ); + pMatch->colUsed = pExTab->nCol>=BMS ? ALLBITS : MASKBIT(pExTab->nCol)-1; + }else{ + testcase( n==BMS-1 ); + testcase( n==BMS ); + if( n>=BMS ) n = BMS-1; + pMatch->colUsed |= ((Bitmask)1)<a[iSrc]; - p->y.pTab = pItem->pTab; + Table *pTab = p->y.pTab = pItem->pTab; p->iTable = pItem->iCursor; if( p->y.pTab->iPKey==iCol ){ p->iColumn = -1; }else{ p->iColumn = (ynVar)iCol; - testcase( iCol==BMS ); - testcase( iCol==BMS-1 ); - pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol); + if( (pTab->tabFlags & TF_HasGenerated)!=0 + && (pTab->aCol[iCol].colFlags & COLFLAG_GENERATED)!=0 + ){ + testcase( pTab->nCol==63 ); + testcase( pTab->nCol==64 ); + pItem->colUsed = pTab->nCol>=64 ? ALLBITS : MASKBIT(pTab->nCol)-1; + }else{ + testcase( iCol==BMS ); + testcase( iCol==BMS-1 ); + pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol); + } } } return p; @@ -618,23 +650,39 @@ Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ /* ** Report an error that an expression is not valid for some set of ** pNC->ncFlags values determined by validMask. +** +** static void notValid( +** Parse *pParse, // Leave error message here +** NameContext *pNC, // The name context +** const char *zMsg, // Type of error +** int validMask, // Set of contexts for which prohibited +** Expr *pExpr // Invalidate this expression on error +** ){...} +** +** As an optimization, since the conditional is almost always false +** (because errors are rare), the conditional is moved outside of the +** function call using a macro. */ -static void notValid( - Parse *pParse, /* Leave error message here */ - NameContext *pNC, /* The name context */ - const char *zMsg, /* Type of error */ - int validMask /* Set of contexts for which prohibited */ +static void notValidImpl( + Parse *pParse, /* Leave error message here */ + NameContext *pNC, /* The name context */ + const char *zMsg, /* Type of error */ + Expr *pExpr /* Invalidate this expression on error */ ){ - assert( (validMask&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr))==0 ); - if( (pNC->ncFlags & validMask)!=0 ){ - const char *zIn = "partial index WHERE clauses"; - if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions"; + const char *zIn = "partial index WHERE clauses"; + if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions"; #ifndef SQLITE_OMIT_CHECK - else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints"; + else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints"; #endif - sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn); - } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + else if( pNC->ncFlags & NC_GenCol ) zIn = "generated columns"; +#endif + sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn); + if( pExpr ) pExpr->op = TK_NULL; } +#define sqlite3ResolveNotValid(P,N,M,X,E) \ + assert( ((X)&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 ); \ + if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E); /* ** Expression p should encode a floating point value between 1.0 and 0.0. @@ -723,7 +771,10 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ zColumn = pExpr->u.zToken; }else{ Expr *pLeft = pExpr->pLeft; - notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr); + testcase( pNC->ncFlags & NC_IdxExpr ); + testcase( pNC->ncFlags & NC_GenCol ); + sqlite3ResolveNotValid(pParse, pNC, "the \".\" operator", + NC_IdxExpr|NC_GenCol, 0); pRight = pExpr->pRight; if( pRight->op==TK_ID ){ zDb = 0; @@ -812,33 +863,39 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){ /* For the purposes of the EP_ConstFunc flag, date and time ** functions and other functions that change slowly are considered - ** constant because they are constant for the duration of one query */ + ** constant because they are constant for the duration of one query. + ** This allows them to be factored out of inner loops. */ ExprSetProperty(pExpr,EP_ConstFunc); } if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){ - /* Date/time functions that use 'now', and other functions like + /* Clearly non-deterministic functions like random(), but also + ** date/time functions that use 'now', and other functions like ** sqlite_version() that might change over time cannot be used - ** in an index. */ - notValid(pParse, pNC, "non-deterministic functions", - NC_IdxExpr|NC_PartIdx); + ** in an index or generated column. Curiously, they can be used + ** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all + ** all this. */ + sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions", + NC_IdxExpr|NC_PartIdx|NC_GenCol, 0); + }else{ + assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */ + pExpr->op2 = pNC->ncFlags & NC_SelfRef; + if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL); } if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0 && pParse->nested==0 - && sqlite3Config.bInternalFunctions==0 + && (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0 ){ /* Internal-use-only functions are disallowed unless the - ** SQL is being compiled using sqlite3NestedParse() */ + ** SQL is being compiled using sqlite3NestedParse() or + ** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be + ** used to activate internal functionsn for testing purposes */ no_such_func = 1; pDef = 0; }else - if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0 - && ExprHasProperty(pExpr, EP_Indirect) + if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 && !IN_RENAME_OBJECT ){ - /* Functions tagged with SQLITE_DIRECTONLY may not be used - ** inside of triggers and views */ - sqlite3ErrorMsg(pParse, "%s() prohibited in triggers and views", - pDef->zName); + sqlite3ExprFunctionUsable(pParse, pExpr, pDef); } } @@ -919,7 +976,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ Select *pSel = pNC->pWinSelect; assert( pWin==pExpr->y.pWin ); if( IN_RENAME_OBJECT==0 ){ - sqlite3WindowUpdate(pParse, pSel->pWinDefn, pWin, pDef); + sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef); } sqlite3WalkExprList(pWalker, pWin->pPartition); sqlite3WalkExprList(pWalker, pWin->pOrderBy); @@ -964,7 +1021,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_IN ); if( ExprHasProperty(pExpr, EP_xIsSelect) ){ int nRef = pNC->nRef; - notValid(pParse, pNC, "subqueries", NC_IsCheck|NC_PartIdx|NC_IdxExpr); + testcase( pNC->ncFlags & NC_IsCheck ); + testcase( pNC->ncFlags & NC_PartIdx ); + testcase( pNC->ncFlags & NC_IdxExpr ); + testcase( pNC->ncFlags & NC_GenCol ); + sqlite3ResolveNotValid(pParse, pNC, "subqueries", + NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr); sqlite3WalkSelect(pWalker, pExpr->x.pSelect); assert( pNC->nRef>=nRef ); if( nRef!=pNC->nRef ){ @@ -975,7 +1037,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ break; } case TK_VARIABLE: { - notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr); + testcase( pNC->ncFlags & NC_IsCheck ); + testcase( pNC->ncFlags & NC_PartIdx ); + testcase( pNC->ncFlags & NC_IdxExpr ); + testcase( pNC->ncFlags & NC_GenCol ); + sqlite3ResolveNotValid(pParse, pNC, "parameters", + NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr); break; } case TK_IS: @@ -1057,8 +1124,9 @@ static int resolveAsName( if( pE->op==TK_ID ){ char *zCol = pE->u.zToken; for(i=0; inExpr; i++){ - char *zAs = pEList->a[i].zName; - if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ + if( pEList->a[i].eEName==ENAME_NAME + && sqlite3_stricmp(pEList->a[i].zEName, zCol)==0 + ){ return i+1; } } @@ -1784,10 +1852,13 @@ void sqlite3ResolveSelectNames( ** Resolve names in expressions that can only reference a single table ** or which cannot reference any tables at all. Examples: ** -** (1) CHECK constraints -** (2) WHERE clauses on partial indices -** (3) Expressions in indexes on expressions -** (4) Expression arguments to VACUUM INTO. +** "type" flag +** ------------ +** (1) CHECK constraints NC_IsCheck +** (2) WHERE clauses on partial indices NC_PartIdx +** (3) Expressions in indexes on expressions NC_IdxExpr +** (4) Expression arguments to VACUUM INTO. 0 +** (5) GENERATED ALWAYS as expressions NC_GenCol ** ** In all cases except (4), the Expr.iTable value for Expr.op==TK_COLUMN ** nodes of the expression is set to -1 and the Expr.iColumn value is @@ -1796,18 +1867,19 @@ void sqlite3ResolveSelectNames( ** Any errors cause an error message to be set in pParse. */ int sqlite3ResolveSelfReference( - Parse *pParse, /* Parsing context */ - Table *pTab, /* The table being referenced, or NULL */ - int type, /* NC_IsCheck or NC_PartIdx or NC_IdxExpr, or 0 */ - Expr *pExpr, /* Expression to resolve. May be NULL. */ - ExprList *pList /* Expression list to resolve. May be NULL. */ + Parse *pParse, /* Parsing context */ + Table *pTab, /* The table being referenced, or NULL */ + int type, /* NC_IsCheck, NC_PartIdx, NC_IdxExpr, NC_GenCol, or 0 */ + Expr *pExpr, /* Expression to resolve. May be NULL. */ + ExprList *pList /* Expression list to resolve. May be NULL. */ ){ SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ NameContext sNC; /* Name context for pParse->pNewTable */ int rc; assert( type==0 || pTab!=0 ); - assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr || pTab==0 ); + assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr + || type==NC_GenCol || pTab==0 ); memset(&sNC, 0, sizeof(sNC)); memset(&sSrc, 0, sizeof(sSrc)); if( pTab ){ @@ -1815,6 +1887,11 @@ int sqlite3ResolveSelfReference( sSrc.a[0].zName = pTab->zName; sSrc.a[0].pTab = pTab; sSrc.a[0].iCursor = -1; + if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){ + /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP + ** schema elements */ + type |= NC_FromDDL; + } } sNC.pParse = pParse; sNC.pSrcList = &sSrc; diff --git a/src/select.c b/src/select.c index 7cc5cde0..595b6eb6 100644 --- a/src/select.c +++ b/src/select.c @@ -84,7 +84,10 @@ struct SortCtx { /* ** Delete all the content of a Select structure. Deallocate the structure -** itself only if bFree is true. +** itself depending on the value of bFree +** +** If bFree==1, call sqlite3DbFree() on the p object. +** If bFree==0, Leave the first Select object unfreed */ static void clearSelect(sqlite3 *db, Select *p, int bFree){ while( p ){ @@ -188,6 +191,21 @@ void sqlite3SelectDelete(sqlite3 *db, Select *p){ if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1); } +/* +** Delete all the substructure for p, but keep p allocated. Redefine +** p to be a single SELECT where every column of the result set has a +** value of NULL. +*/ +void sqlite3SelectReset(Parse *pParse, Select *p){ + if( ALWAYS(p) ){ + clearSelect(pParse->db, p, 0); + memset(&p->iLimit, 0, sizeof(Select) - offsetof(Select,iLimit)); + p->pEList = sqlite3ExprListAppend(pParse, 0, + sqlite3ExprAlloc(pParse->db,TK_NULL,0,0)); + p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(SrcList)); + } +} + /* ** Return a pointer to the right-most SELECT statement in a compound. */ @@ -296,7 +314,8 @@ static int tableAndColumnIndex( int N, /* Number of tables in pSrc->a[] to search */ const char *zCol, /* Name of the column we are looking for */ int *piTab, /* Write index of pSrc->a[] here */ - int *piCol /* Write index of pSrc->a[*piTab].pTab->aCol[] here */ + int *piCol, /* Write index of pSrc->a[*piTab].pTab->aCol[] here */ + int bIgnoreHidden /* True to ignore hidden columns */ ){ int i; /* For looping over tables in pSrc */ int iCol; /* Index of column matching zCol */ @@ -304,7 +323,9 @@ static int tableAndColumnIndex( assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ for(i=0; ia[i].pTab, zCol); - if( iCol>=0 ){ + if( iCol>=0 + && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0) + ){ if( piTab ){ *piTab = i; *piCol = iCol; @@ -385,7 +406,7 @@ static void addWhereTerm( ** after the t1 loop and rows with t1.x!=5 will never appear in ** the output, which is incorrect. */ -static void setJoinExpr(Expr *p, int iTable){ +void sqlite3SetJoinExpr(Expr *p, int iTable){ while( p ){ ExprSetProperty(p, EP_FromJoin); assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); @@ -394,15 +415,15 @@ static void setJoinExpr(Expr *p, int iTable){ if( p->op==TK_FUNCTION && p->x.pList ){ int i; for(i=0; ix.pList->nExpr; i++){ - setJoinExpr(p->x.pList->a[i].pExpr, iTable); + sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable); } } - setJoinExpr(p->pLeft, iTable); + sqlite3SetJoinExpr(p->pLeft, iTable); p = p->pRight; } } -/* Undo the work of setJoinExpr(). In the expression tree p, convert every +/* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every ** term that is marked with EP_FromJoin and iRightJoinTable==iTable into ** an ordinary term that omits the EP_FromJoin mark. ** @@ -469,10 +490,11 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ int iLeft; /* Matching left table */ int iLeftCol; /* Matching column in the left table */ + if( IsHiddenColumn(&pRightTab->aCol[j]) ) continue; zName = pRightTab->aCol[j].zName; - if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol) ){ + if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 1) ){ addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j, - isOuter, &p->pWhere); + isOuter, &p->pWhere); } } } @@ -489,7 +511,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ ** an AND operator. */ if( pRight->pOn ){ - if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor); + if( isOuter ) sqlite3SetJoinExpr(pRight->pOn, pRight->iCursor); p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->pOn); pRight->pOn = 0; } @@ -512,7 +534,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ zName = pList->a[j].zName; iRightCol = columnIndex(pRightTab, zName); if( iRightCol<0 - || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol) + || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 0) ){ sqlite3ErrorMsg(pParse, "cannot join using column %s - column " "not present in both tables", zName); @@ -669,6 +691,7 @@ static void pushOntoSorter( testcase( pKI->nAllField > pKI->nKeyField+2 ); pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat, pKI->nAllField-pKI->nKeyField-1); + pOp = 0; /* Ensure pOp not used after sqltie3VdbeAddOp3() */ addrJmp = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); pSort->labelBkOut = sqlite3VdbeMakeLabel(pParse); @@ -917,7 +940,7 @@ static void selectInnerLoop( if( srcTab>=0 ){ for(i=0; ipEList->a[i].zName)); + VdbeComment((v, "%s", p->pEList->a[i].zEName)); } }else if( eDest!=SRT_Exists ){ #ifdef SQLITE_ENABLE_SORTER_REFERENCES @@ -1031,6 +1054,7 @@ static void selectInnerLoop( pOp->opcode = OP_Null; pOp->p1 = 1; pOp->p2 = regPrev; + pOp = 0; /* Ensure pOp is not used after sqlite3VdbeAddOp() */ iJump = sqlite3VdbeCurrentAddr(v) + nResultCol; for(i=0; iop!=TK_AGG_COLUMN ); /* Agg processing has not run yet */ assert( p->op!=TK_COLUMN || p->y.pTab!=0 ); /* Covering idx not yet coded */ - if( pEList->a[i].zName ){ + if( pEList->a[i].zEName && pEList->a[i].eEName==ENAME_NAME ){ /* An AS clause always takes first priority */ - char *zName = pEList->a[i].zName; + char *zName = pEList->a[i].zEName; sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT); }else if( srcName && p->op==TK_COLUMN ){ char *zCol; @@ -1895,7 +1919,7 @@ static void generateColumnNames( sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT); } }else{ - const char *z = pEList->a[i].zSpan; + const char *z = pEList->a[i].zEName; z = z==0 ? sqlite3MPrintf(db, "column%d", i+1) : sqlite3DbStrDup(db, z); sqlite3VdbeSetColName(v, i, COLNAME_NAME, z, SQLITE_DYNAMIC); } @@ -1957,7 +1981,7 @@ int sqlite3ColumnsFromExprList( for(i=0, pCol=aCol; imallocFailed; i++, pCol++){ /* Get an appropriate name for the column */ - if( (zName = pEList->a[i].zName)!=0 ){ + if( (zName = pEList->a[i].zEName)!=0 && pEList->a[i].eEName==ENAME_NAME ){ /* If the column contains an "AS " phrase, use as the name */ }else{ Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr); @@ -1977,10 +2001,10 @@ int sqlite3ColumnsFromExprList( zName = pColExpr->u.zToken; }else{ /* Use the original text of the column expression as its name */ - zName = pEList->a[i].zSpan; + zName = pEList->a[i].zEName; } } - if( zName ){ + if( zName && !sqlite3IsTrueOrFalse(zName) ){ zName = sqlite3DbStrDup(db, zName); }else{ zName = sqlite3MPrintf(db,"column%d",i+1); @@ -2472,6 +2496,9 @@ static int multiSelectValues( assert( p->selFlags & SF_Values ); assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) ); assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr ); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin ) return -1; +#endif if( p->pPrior==0 ) break; assert( p->pPrior->pNext==p ); p = p->pPrior; @@ -2562,7 +2589,8 @@ static int multiSelect( */ if( p->selFlags & SF_MultiValue ){ rc = multiSelectValues(pParse, p, &dest); - goto multi_select_end; + if( rc>=0 ) goto multi_select_end; + rc = SQLITE_OK; } /* Make sure all SELECTs in the statement have the same number of elements @@ -2707,9 +2735,9 @@ static int multiSelect( ** it is that we currently need. */ assert( unionTab==dest.iSDParm || dest.eDest!=priorOp ); - if( dest.eDest!=priorOp ){ + assert( p->pEList || db->mallocFailed ); + if( dest.eDest!=priorOp && db->mallocFailed==0 ){ int iCont, iBreak, iStart; - assert( p->pEList ); iBreak = sqlite3VdbeMakeLabel(pParse); iCont = sqlite3VdbeMakeLabel(pParse); computeLimitRegisters(pParse, p, iBreak); @@ -2805,6 +2833,7 @@ static int multiSelect( } #endif } + if( pParse->nErr ) goto multi_select_end; /* Compute collating sequences used by ** temporary tables needed to implement the compound select. @@ -3596,6 +3625,7 @@ static void substSelect( ** (3b) the FROM clause of the subquery may not contain a virtual ** table and ** (3c) the outer query may not be an aggregate. +** (3d) the outer query may not be DISTINCT. ** ** (4) The subquery can not be DISTINCT. ** @@ -3646,6 +3676,7 @@ static void substSelect( ** (17d1) aggregate, or ** (17d2) DISTINCT, or ** (17d3) a join. +** (17e) the subquery may not contain window functions ** ** The parent and sub-query may contain WHERE clauses. Subject to ** rules (11), (13) and (14), they may also contain ORDER BY, @@ -3792,8 +3823,11 @@ static int flattenSubquery( */ if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){ isLeftJoin = 1; - if( pSubSrc->nSrc>1 || isAgg || IsVirtual(pSubSrc->a[0].pTab) ){ - /* (3a) (3c) (3b) */ + if( pSubSrc->nSrc>1 /* (3a) */ + || isAgg /* (3b) */ + || IsVirtual(pSubSrc->a[0].pTab) /* (3c) */ + || (p->selFlags & SF_Distinct)!=0 /* (3d) */ + ){ return 0; } } @@ -3827,6 +3861,9 @@ static int flattenSubquery( if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 /* (17b) */ || (pSub1->pPrior && pSub1->op!=TK_ALL) /* (17a) */ || pSub1->pSrc->nSrc<1 /* (17c) */ +#ifndef SQLITE_OMIT_WINDOWFUNC + || pSub1->pWin /* (17e) */ +#endif ){ return 0; } @@ -4053,7 +4090,7 @@ static int flattenSubquery( pWhere = pSub->pWhere; pSub->pWhere = 0; if( isLeftJoin>0 ){ - setJoinExpr(pWhere, iNewParent); + sqlite3SetJoinExpr(pWhere, iNewParent); } pParent->pWhere = sqlite3ExprAnd(pParse, pWhere, pParent->pWhere); if( db->mallocFailed==0 ){ @@ -4113,23 +4150,36 @@ struct WhereConst { /* ** Add a new entry to the pConst object. Except, do not add duplicate -** pColumn entires. +** pColumn entires. Also, do not add if doing so would not be appropriate. +** +** The caller guarantees the pColumn is a column and pValue is a constant. +** This routine has to do some additional checks before completing the +** insert. */ static void constInsert( - WhereConst *pConst, /* The WhereConst into which we are inserting */ - Expr *pColumn, /* The COLUMN part of the constraint */ - Expr *pValue /* The VALUE part of the constraint */ + WhereConst *pConst, /* The WhereConst into which we are inserting */ + Expr *pColumn, /* The COLUMN part of the constraint */ + Expr *pValue, /* The VALUE part of the constraint */ + Expr *pExpr /* Overall expression: COLUMN=VALUE or VALUE=COLUMN */ ){ int i; assert( pColumn->op==TK_COLUMN ); + assert( sqlite3ExprIsConstant(pValue) ); + + if( !ExprHasProperty(pValue, EP_FixedCol) && sqlite3ExprAffinity(pValue)!=0 ){ + return; + } + if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pConst->pParse,pExpr)) ){ + return; + } /* 2018-10-25 ticket [cf5ed20f] ** Make sure the same pColumn is not inserted more than once */ for(i=0; inConst; i++){ - const Expr *pExpr = pConst->apExpr[i*2]; - assert( pExpr->op==TK_COLUMN ); - if( pExpr->iTable==pColumn->iTable - && pExpr->iColumn==pColumn->iColumn + const Expr *pE2 = pConst->apExpr[i*2]; + assert( pE2->op==TK_COLUMN ); + if( pE2->iTable==pColumn->iTable + && pE2->iColumn==pColumn->iColumn ){ return; /* Already present. Return without doing anything. */ } @@ -4141,7 +4191,9 @@ static void constInsert( if( pConst->apExpr==0 ){ pConst->nConst = 0; }else{ - if( ExprHasProperty(pValue, EP_FixedCol) ) pValue = pValue->pLeft; + if( ExprHasProperty(pValue, EP_FixedCol) ){ + pValue = pValue->pLeft; + } pConst->apExpr[pConst->nConst*2-2] = pColumn; pConst->apExpr[pConst->nConst*2-1] = pValue; } @@ -4167,19 +4219,11 @@ static void findConstInWhere(WhereConst *pConst, Expr *pExpr){ pLeft = pExpr->pLeft; assert( pRight!=0 ); assert( pLeft!=0 ); - if( pRight->op==TK_COLUMN - && !ExprHasProperty(pRight, EP_FixedCol) - && sqlite3ExprIsConstant(pLeft) - && sqlite3IsBinary(sqlite3BinaryCompareCollSeq(pConst->pParse,pLeft,pRight)) - ){ - constInsert(pConst, pRight, pLeft); - }else - if( pLeft->op==TK_COLUMN - && !ExprHasProperty(pLeft, EP_FixedCol) - && sqlite3ExprIsConstant(pRight) - && sqlite3IsBinary(sqlite3BinaryCompareCollSeq(pConst->pParse,pLeft,pRight)) - ){ - constInsert(pConst, pLeft, pRight); + if( pRight->op==TK_COLUMN && sqlite3ExprIsConstant(pLeft) ){ + constInsert(pConst,pRight,pLeft,pExpr); + } + if( pLeft->op==TK_COLUMN && sqlite3ExprIsConstant(pRight) ){ + constInsert(pConst,pLeft,pRight,pExpr); } } @@ -4193,7 +4237,11 @@ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ int i; WhereConst *pConst; if( pExpr->op!=TK_COLUMN ) return WRC_Continue; - if( ExprHasProperty(pExpr, EP_FixedCol) ) return WRC_Continue; + if( ExprHasProperty(pExpr, EP_FixedCol|EP_FromJoin) ){ + testcase( ExprHasProperty(pExpr, EP_FixedCol) ); + testcase( ExprHasProperty(pExpr, EP_FromJoin) ); + return WRC_Continue; + } pConst = pWalker->u.pConst; for(i=0; inConst; i++){ Expr *pColumn = pConst->apExpr[i*2]; @@ -4215,10 +4263,9 @@ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ ** The WHERE-clause constant propagation optimization. ** ** If the WHERE clause contains terms of the form COLUMN=CONSTANT or -** CONSTANT=COLUMN that must be tree (in other words, if the terms top-level -** AND-connected terms that are not part of a ON clause from a LEFT JOIN) -** then throughout the query replace all other occurrences of COLUMN -** with CONSTANT within the WHERE clause. +** CONSTANT=COLUMN that are top-level AND-connected terms that are not +** part of a ON clause from a LEFT JOIN, then throughout the query +** replace all other occurrences of COLUMN with CONSTANT. ** ** For example, the query: ** @@ -4567,6 +4614,9 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ p->pPrior = 0; p->pNext = 0; p->pWith = 0; +#ifndef SQLITE_OMIT_WINDOWFUNC + p->pWinDefn = 0; +#endif p->selFlags &= ~SF_Compound; assert( (p->selFlags & SF_Converted)==0 ); p->selFlags |= SF_Converted; @@ -4666,6 +4716,9 @@ static int withExpand( With *pWith; /* WITH clause that pCte belongs to */ assert( pFrom->pTab==0 ); + if( pParse->nErr ){ + return SQLITE_ERROR; + } pCte = searchWith(pParse->pWith, pFrom, &pWith); if( pCte ){ @@ -4786,7 +4839,7 @@ static void selectPopWith(Walker *pWalker, Select *p){ if( OK_IF_ALWAYS_TRUE(pParse->pWith) && p->pPrior==0 ){ With *pWith = findRightmost(p)->pWith; if( pWith!=0 ){ - assert( pParse->pWith==pWith ); + assert( pParse->pWith==pWith || pParse->nErr ); pParse->pWith = pWith->pOuter; } } @@ -4917,7 +4970,7 @@ static int selectExpander(Walker *pWalker, Select *p){ if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){ return WRC_Abort; } -#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE) +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) if( IsVirtual(pTab) || pTab->pSelect ){ i16 nCol; u8 eCodeOrig = pWalker->eCode; @@ -4925,8 +4978,18 @@ static int selectExpander(Walker *pWalker, Select *p){ assert( pFrom->pSelect==0 ); if( pTab->pSelect && (db->flags & SQLITE_EnableView)==0 ){ sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", - pTab->zName); + pTab->zName); } +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) + && pFrom->fg.fromDDL + && ALWAYS(pTab->pVTable!=0) + && pTab->pVTable->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0) + ){ + sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"", + pTab->zName); + } +#endif pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); nCol = pTab->nCol; pTab->nCol = -1; @@ -4946,7 +5009,7 @@ static int selectExpander(Walker *pWalker, Select *p){ /* Process NATURAL keywords, and ON and USING clauses of joins. */ - if( db->mallocFailed || sqliteProcessJoin(pParse, p) ){ + if( pParse->nErr || db->mallocFailed || sqliteProcessJoin(pParse, p) ){ return WRC_Abort; } @@ -4993,10 +5056,9 @@ static int selectExpander(Walker *pWalker, Select *p){ */ pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr); if( pNew ){ - pNew->a[pNew->nExpr-1].zName = a[k].zName; - pNew->a[pNew->nExpr-1].zSpan = a[k].zSpan; - a[k].zName = 0; - a[k].zSpan = 0; + pNew->a[pNew->nExpr-1].zEName = a[k].zEName; + pNew->a[pNew->nExpr-1].eEName = a[k].eEName; + a[k].zEName = 0; } a[k].pExpr = 0; }else{ @@ -5035,7 +5097,7 @@ static int selectExpander(Walker *pWalker, Select *p){ assert( zName ); if( zTName && pSub - && sqlite3MatchSpanName(pSub->pEList->a[j].zSpan, 0, zTName, 0)==0 + && sqlite3MatchEName(&pSub->pEList->a[j], 0, zTName, 0)==0 ){ continue; } @@ -5053,7 +5115,7 @@ static int selectExpander(Walker *pWalker, Select *p){ if( i>0 && zTName==0 ){ if( (pFrom->fg.jointype & JT_NATURAL)!=0 - && tableAndColumnIndex(pTabList, i, zName, 0, 0) + && tableAndColumnIndex(pTabList, i, zName, 0, 0, 1) ){ /* In a NATURAL join, omit the join columns from the ** table to the right of the join */ @@ -5088,15 +5150,16 @@ static int selectExpander(Walker *pWalker, Select *p){ sqlite3ExprListSetName(pParse, pNew, &sColname, 0); if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){ struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; + sqlite3DbFree(db, pX->zEName); if( pSub ){ - pX->zSpan = sqlite3DbStrDup(db, pSub->pEList->a[j].zSpan); - testcase( pX->zSpan==0 ); + pX->zEName = sqlite3DbStrDup(db, pSub->pEList->a[j].zEName); + testcase( pX->zEName==0 ); }else{ - pX->zSpan = sqlite3MPrintf(db, "%s.%s.%s", + pX->zEName = sqlite3MPrintf(db, "%s.%s.%s", zSchemaName, zTabName, zColname); - testcase( pX->zSpan==0 ); + testcase( pX->zEName==0 ); } - pX->bSpanIsTab = 1; + pX->eEName = ENAME_TAB; } sqlite3DbFree(db, zToFree); } @@ -5723,11 +5786,13 @@ int sqlite3Select( } #ifndef SQLITE_OMIT_WINDOWFUNC - if( sqlite3WindowRewrite(pParse, p) ){ + rc = sqlite3WindowRewrite(pParse, p); + if( rc ){ + assert( db->mallocFailed || pParse->nErr>0 ); goto select_end; } #if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x108 ){ + if( p->pWin && (sqlite3SelectTrace & 0x108)!=0 ){ SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -6059,9 +6124,13 @@ int sqlite3Select( */ if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0 +#ifndef SQLITE_OMIT_WINDOWFUNC + && p->pWin==0 +#endif ){ p->selFlags &= ~SF_Distinct; pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0); + p->selFlags |= SF_Aggregate; /* Notice that even thought SF_Distinct has been cleared from p->selFlags, ** the sDistinct.isTnct is still set. Hence, isTnct represents the ** original setting of the SF_Distinct flag, not the current setting */ @@ -6136,7 +6205,7 @@ int sqlite3Select( #ifndef SQLITE_OMIT_WINDOWFUNC Window *pWin = p->pWin; /* Master window object (or NULL) */ if( pWin ){ - sqlite3WindowCodeInit(pParse, pWin); + sqlite3WindowCodeInit(pParse, p); } #endif assert( WHERE_USE_LIMIT==SF_FixedLimit ); diff --git a/src/shell.c.in b/src/shell.c.in index 7f82675e..0532f046 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -1021,6 +1021,7 @@ struct ShellState { int outCount; /* Revert to stdout when reaching zero */ int cnt; /* Number of records displayed so far */ int lineno; /* Line number of last line read from in */ + int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */ FILE *in; /* Read commands from this stream */ FILE *out; /* Write results here */ FILE *traceOut; /* Output for sqlite3_trace() */ @@ -1855,19 +1856,22 @@ static int shell_callback( const int *colWidth; int showHdr; char *rowSep; + int nWidth; if( p->cMode==MODE_Column ){ colWidth = p->colWidth; + nWidth = ArraySize(p->colWidth); showHdr = p->showHeader; rowSep = p->rowSeparator; }else{ colWidth = aExplainWidths; + nWidth = ArraySize(aExplainWidths); showHdr = 1; rowSep = SEP_Row; } if( p->cnt++==0 ){ for(i=0; icolWidth) ){ + if( idb, SQLITE_DBCONFIG_DEFENSIVE, -1, &defensiveMode); + sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, 0, 0); sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, -1, &wrSchema); sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, 1, 0); sqlite3_exec(p->db, @@ -2766,6 +2773,7 @@ static void bind_table_init(ShellState *p){ ") WITHOUT ROWID;", 0, 0, 0); sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, wrSchema, 0); + sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, defensiveMode, 0); } /* @@ -3508,9 +3516,7 @@ static const char *(azHelp[]) = { ".excel Display the output of next command in spreadsheet", ".exit ?CODE? Exit this program with return-code CODE", ".expert EXPERIMENTAL. Suggest indexes for queries", -/* Because explain mode comes on automatically now, the ".explain" mode -** is removed from the help screen. It is still supported for legacy, however */ -/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off",*/ + ".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto", ".filectrl CMD ... Run various sqlite3_file_control() operations", " Run \".filectrl\" with no arguments for details", ".fullschema ?--indent? Show schema and the content of sqlite_stat tables", @@ -3561,6 +3567,7 @@ static const char *(azHelp[]) = { " --maxsize N Maximum size for --hexdb or --deserialized database", #endif " --new Initialize FILE to an empty database", + " --nofollow Do not follow symbolic links", " --readonly Open FILE readonly", " --zip FILE is a ZIP archive", ".output ?FILE? Send output to FILE or stdout if FILE is omitted", @@ -4125,7 +4132,7 @@ static void open_db(ShellState *p, int openFlags){ switch( p->openMode ){ case SHELL_OPEN_APPENDVFS: { sqlite3_open_v2(p->zDbFilename, &p->db, - SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs"); + SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, "apndvfs"); break; } case SHELL_OPEN_HEXDB: @@ -4138,12 +4145,14 @@ static void open_db(ShellState *p, int openFlags){ break; } case SHELL_OPEN_READONLY: { - sqlite3_open_v2(p->zDbFilename, &p->db, SQLITE_OPEN_READONLY, 0); + sqlite3_open_v2(p->zDbFilename, &p->db, + SQLITE_OPEN_READONLY|p->openFlags, 0); break; } case SHELL_OPEN_UNSPEC: case SHELL_OPEN_NORMAL: { - sqlite3_open(p->zDbFilename, &p->db); + sqlite3_open_v2(p->zDbFilename, &p->db, + SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0); break; } } @@ -4917,7 +4926,7 @@ static unsigned int get4byteInt(unsigned char *a){ } /* -** Implementation of the ".info" command. +** Implementation of the ".dbinfo" command. ** ** Return 1 on error, 2 to exit, and 0 otherwise. */ @@ -7154,20 +7163,22 @@ static int do_meta_command(char *zLine, ShellState *p){ const char *zName; int op; } aDbConfig[] = { + { "defensive", SQLITE_DBCONFIG_DEFENSIVE }, + { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL }, + { "dqs_dml", SQLITE_DBCONFIG_DQS_DML }, { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY }, + { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG }, { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER }, { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW }, { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, + { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE }, + { "legacy_file_format", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT }, { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION }, { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, - { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG }, - { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP }, { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE }, - { "defensive", SQLITE_DBCONFIG_DEFENSIVE }, + { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP }, + { "trusted_schema", SQLITE_DBCONFIG_TRUSTED_SCHEMA }, { "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA }, - { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE }, - { "dqs_dml", SQLITE_DBCONFIG_DQS_DML }, - { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL }, }; int ii, v; open_db(p, 0); @@ -7177,7 +7188,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0); } sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v); - utf8_printf(p->out, "%18s %s\n", aDbConfig[ii].zName, v ? "on" : "off"); + utf8_printf(p->out, "%19s %s\n", aDbConfig[ii].zName, v ? "on" : "off"); if( nArg>1 ) break; } if( nArg>1 && ii==ArraySize(aDbConfig) ){ @@ -7758,10 +7769,19 @@ static int do_meta_command(char *zLine, ShellState *p){ char *zCollist = 0; sqlite3_stmt *pStmt; int tnum = 0; + int isWO = 0; /* True if making an imposter of a WITHOUT ROWID table */ + int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */ int i; if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){ utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n" " .imposter off\n"); + /* Also allowed, but not documented: + ** + ** .imposter TABLE IMPOSTER + ** + ** where TABLE is a WITHOUT ROWID table. In that case, the + ** imposter is another WITHOUT ROWID table with the columns in + ** storage order. */ rc = 1; goto meta_command_exit; } @@ -7770,19 +7790,22 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 1); goto meta_command_exit; } - zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master" - " WHERE name='%q' AND type='index'", azArg[1]); + zSql = sqlite3_mprintf( + "SELECT rootpage, 0 FROM sqlite_master" + " WHERE name='%q' AND type='index'" + "UNION ALL " + "SELECT rootpage, 1 FROM sqlite_master" + " WHERE name='%q' AND type='table'" + " AND sql LIKE '%%without%%rowid%%'", + azArg[1], azArg[1] + ); sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); if( sqlite3_step(pStmt)==SQLITE_ROW ){ tnum = sqlite3_column_int(pStmt, 0); + isWO = sqlite3_column_int(pStmt, 1); } sqlite3_finalize(pStmt); - if( tnum==0 ){ - utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]); - rc = 1; - goto meta_command_exit; - } zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]); rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); @@ -7799,6 +7822,9 @@ static int do_meta_command(char *zLine, ShellState *p){ zCol = zLabel; } } + if( isWO && lenPK==0 && sqlite3_column_int(pStmt,5)==0 && zCollist ){ + lenPK = (int)strlen(zCollist); + } if( zCollist==0 ){ zCollist = sqlite3_mprintf("\"%w\"", zCol); }else{ @@ -7806,9 +7832,16 @@ static int do_meta_command(char *zLine, ShellState *p){ } } sqlite3_finalize(pStmt); + if( i==0 || tnum==0 ){ + utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]); + rc = 1; + sqlite3_free(zCollist); + goto meta_command_exit; + } + if( lenPK==0 ) lenPK = 100000; zSql = sqlite3_mprintf( - "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%s))WITHOUT ROWID", - azArg[2], zCollist, zCollist); + "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%.*s))WITHOUT ROWID", + azArg[2], zCollist, lenPK, zCollist); sqlite3_free(zCollist); rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum); if( rc==SQLITE_OK ){ @@ -7819,7 +7852,8 @@ static int do_meta_command(char *zLine, ShellState *p){ }else{ utf8_printf(stdout, "%s;\n", zSql); raw_printf(stdout, - "WARNING: writing to an imposter table will corrupt the index!\n" + "WARNING: writing to an imposter table will corrupt the \"%s\" %s!\n", + azArg[1], isWO ? "table" : "index" ); } }else{ @@ -8017,6 +8051,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_free(p->zFreeOnClose); p->zFreeOnClose = 0; p->openMode = SHELL_OPEN_UNSPEC; + p->openFlags = 0; p->szMax = 0; /* Check for command-line arguments */ for(iName=1; iNameopenMode = SHELL_OPEN_APPENDVFS; }else if( optionMatch(z, "readonly") ){ p->openMode = SHELL_OPEN_READONLY; + }else if( optionMatch(z, "nofollow") ){ + p->openFlags |= SQLITE_OPEN_NOFOLLOW; #ifdef SQLITE_ENABLE_DESERIALIZE }else if( optionMatch(z, "deserialize") ){ p->openMode = SHELL_OPEN_DESERIALIZE; @@ -9187,7 +9224,7 @@ static int do_meta_command(char *zLine, ShellState *p){ { "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,"BOOLEAN" }, /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" },*/ { "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"}, - { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN" }, + { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "" }, { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" }, { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" }, { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" }, @@ -9303,7 +9340,6 @@ static int do_meta_command(char *zLine, ShellState *p){ /* sqlite3_test_control(int, int) */ case SQLITE_TESTCTRL_ASSERT: case SQLITE_TESTCTRL_ALWAYS: - case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: if( nArg==3 ){ int opt = booleanValue(azArg[2]); rc2 = sqlite3_test_control(testctrl, opt); @@ -9321,6 +9357,12 @@ static int do_meta_command(char *zLine, ShellState *p){ } break; + /* sqlite3_test_control(sqlite3*) */ + case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: + rc2 = sqlite3_test_control(testctrl, p->db); + isOk = 3; + break; + case SQLITE_TESTCTRL_IMPOSTER: if( nArg==5 ){ rc2 = sqlite3_test_control(testctrl, p->db, @@ -9951,6 +9993,7 @@ static const char zOptions[] = " -multiplex enable the multiplexor VFS\n" #endif " -newline SEP set output row separator. Default: '\\n'\n" + " -nofollow refuse to open symbolic links to database files\n" " -nullvalue TEXT set text string for NULL values. Default ''\n" " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" " -quote set output mode to 'quote'\n" @@ -10261,6 +10304,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #endif }else if( strcmp(z,"-readonly")==0 ){ data.openMode = SHELL_OPEN_READONLY; + }else if( strcmp(z,"-nofollow")==0 ){ + data.openFlags = SQLITE_OPEN_NOFOLLOW; #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) }else if( strncmp(z, "-A",2)==0 ){ /* All remaining command-line arguments are passed to the ".archive" @@ -10364,6 +10409,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #endif }else if( strcmp(z,"-readonly")==0 ){ data.openMode = SHELL_OPEN_READONLY; + }else if( strcmp(z,"-nofollow")==0 ){ + data.openFlags |= SQLITE_OPEN_NOFOLLOW; }else if( strcmp(z,"-ascii")==0 ){ data.mode = MODE_Ascii; sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 9dbc8076..6b32b648 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -516,6 +516,7 @@ int sqlite3_exec( #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) #define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */ +#define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) @@ -535,11 +536,13 @@ int sqlite3_exec( #define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8)) #define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8)) #define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8)) +#define SQLITE_CONSTRAINT_PINNED (SQLITE_CONSTRAINT |(11<<8)) #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) +#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* ** CAPI3REF: Flags For File Open Operations @@ -568,6 +571,7 @@ int sqlite3_exec( #define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ +#define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */ /* Reserved: 0x00F00000 */ @@ -979,16 +983,16 @@ struct sqlite3_io_methods { ** ^The [SQLITE_FCNTL_BUSYHANDLER] ** file-control may be invoked by SQLite on the database file handle ** shortly after it is opened in order to provide a custom VFS with access -** to the connections busy-handler callback. The argument is of type (void **) +** to the connection's busy-handler callback. The argument is of type (void**) ** - an array of two (void *) values. The first (void *) actually points -** to a function of type (int (*)(void *)). In order to invoke the connections +** to a function of type (int (*)(void *)). In order to invoke the connection's ** busy-handler, this function should be invoked with the second (void *) in ** the array as the only argument. If it returns non-zero, then the operation ** should be retried. If it returns zero, the custom VFS should abandon the ** current operation. ** **
    2. [[SQLITE_FCNTL_TEMPFILENAME]] -** ^Application can invoke the [SQLITE_FCNTL_TEMPFILENAME] file-control +** ^Applications can invoke the [SQLITE_FCNTL_TEMPFILENAME] file-control ** to have SQLite generate a ** temporary filename using the same algorithm that is followed to generate ** temporary filenames for TEMP tables and other internal uses. The @@ -1101,12 +1105,18 @@ struct sqlite3_io_methods { ** not provide a mechanism to detect changes to MAIN only. Also, the ** [sqlite3_total_changes()] interface responds to internal changes only and ** omits changes made by other database connections. The -** [PRAGMA data_version] command provide a mechanism to detect changes to +** [PRAGMA data_version] command provides a mechanism to detect changes to ** a single attached database that occur due to other database connections, ** but omits changes implemented by the database connection on which it is ** called. This file control is the only mechanism to detect changes that ** happen either internally or externally and that are associated with ** a particular attached database. +** +**
    3. [[SQLITE_FCNTL_CKPT_DONE]] +** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint +** in wal mode after the client has finished copying pages from the wal +** file to the database file, but before the *-shm file is updated to +** record the fact that the pages have been checkpointed. ** */ #define SQLITE_FCNTL_LOCKSTATE 1 @@ -1144,6 +1154,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_LOCK_TIMEOUT 34 #define SQLITE_FCNTL_DATA_VERSION 35 #define SQLITE_FCNTL_SIZE_LIMIT 36 +#define SQLITE_FCNTL_CKPT_DONE 37 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE @@ -1189,10 +1200,10 @@ typedef struct sqlite3_api_routines sqlite3_api_routines; ** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6]. Additional fields ** may be appended to the sqlite3_vfs object and the iVersion value ** may increase again in future versions of SQLite. -** Note that the structure -** of the sqlite3_vfs object changes in the transition from +** Note that due to an oversight, the structure +** of the sqlite3_vfs object changed in the transition from ** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0] -** and yet the iVersion field was not modified. +** and yet the iVersion field was not increased. ** ** The szOsFile field is the size of the subclassed [sqlite3_file] ** structure used by this VFS. mxPathname is the maximum length of @@ -1283,7 +1294,7 @@ typedef struct sqlite3_api_routines sqlite3_api_routines; ** for exclusive access. ** ** ^At least szOsFile bytes of memory are allocated by SQLite -** to hold the [sqlite3_file] structure passed as the third +** to hold the [sqlite3_file] structure passed as the third ** argument to xOpen. The xOpen method does not have to ** allocate the structure; it should just fill it in. Note that ** the xOpen method must set the sqlite3_file.pMethods to either @@ -1620,7 +1631,7 @@ int sqlite3_db_config(sqlite3*, int op, ...); ** that causes the corresponding memory allocation to fail. ** ** The xInit method initializes the memory allocator. For example, -** it might allocate any require mutexes or initialize internal data +** it might allocate any required mutexes or initialize internal data ** structures. The xShutdown method is invoked (indirectly) by ** [sqlite3_shutdown()] and should deallocate any resources acquired ** by xInit. The pAppData pointer is used as the only parameter to @@ -1742,6 +1753,7 @@ struct sqlite3_mem_methods { ** memory allocation statistics. ^(When memory allocation statistics are ** disabled, the following SQLite interfaces become non-operational: **
        +**
      • [sqlite3_hard_heap_limit64()] **
      • [sqlite3_memory_used()] **
      • [sqlite3_memory_highwater()] **
      • [sqlite3_soft_heap_limit64()] @@ -1760,7 +1772,7 @@ struct sqlite3_mem_methods { **
        ^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool ** that SQLite can use for the database page cache with the default page ** cache implementation. -** This configuration option is a no-op if an application-define page +** This configuration option is a no-op if an application-defined page ** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2]. ** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to ** 8-byte aligned memory (pMem), the size of each page cache line (sz), @@ -2245,7 +2257,7 @@ struct sqlite3_mem_methods { ** [[SQLITE_DBCONFIG_DQS_DML]] **
        SQLITE_DBCONFIG_DQS_DML **
        The SQLITE_DBCONFIG_DQS_DML option activates or deactivates -** the legacy [double-quoted string literal] misfeature for DML statement +** the legacy [double-quoted string literal] misfeature for DML statements ** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The ** default value of this setting is determined by the [-DSQLITE_DQS] ** compile-time option. @@ -2259,6 +2271,49 @@ struct sqlite3_mem_methods { ** default value of this setting is determined by the [-DSQLITE_DQS] ** compile-time option. **
        +** +** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]] +**
        SQLITE_DBCONFIG_TRUSTED_SCHEMA +**
        The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to +** assume that database schemas (the contents of the [sqlite_master] tables) +** are untainted by malicious content. +** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite +** takes additional defensive steps to protect the application from harm +** including: +**
          +**
        • Prohibit the use of SQL functions inside triggers, views, +** CHECK constraints, DEFAULT clauses, expression indexes, +** partial indexes, or generated columns +** unless those functions are tagged with [SQLITE_INNOCUOUS]. +**
        • Prohibit the use of virtual tables inside of triggers or views +** unless those virtual tables are tagged with [SQLITE_VTAB_INNOCUOUS]. +**
        +** This setting defaults to "on" for legacy compatibility, however +** all applications are advised to turn it off if possible. This setting +** can also be controlled using the [PRAGMA trusted_schema] statement. +**
        +** +** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]] +**
        SQLITE_DBCONFIG_LEGACY_FILE_FORMAT +**
        The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates +** the legacy file format flag. When activated, this flag causes all newly +** created database file to have a schema format version number (the 4-byte +** integer found at offset 44 into the database header) of 1. This in turn +** means that the resulting database file will be readable and writable by +** any SQLite version back to 3.0.0 ([dateof:3.0.0]). Without this setting, +** newly created databases are generally not understandable by SQLite versions +** prior to 3.3.0 ([dateof:3.3.0]). As these words are written, there +** is now scarcely any need to generated database files that are compatible +** all the way back to version 3.0.0, and so this setting is of little +** practical use, but is provided so that SQLite can continue to claim the +** ability to generate new database files that are compatible with version +** 3.0.0. +**

        Note that when the SQLITE_DBCONFIG_LEGACY_FILE_FORMAT setting is on, +** the [VACUUM] command will fail with an obscure error when attempting to +** process a table with generated columns and a descending index. This is +** not considered a bug since SQLite versions 3.3.0 and earlier do not support +** either generated columns or decending indexes. +**

        ** */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ @@ -2277,7 +2332,9 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */ #define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ -#define SQLITE_DBCONFIG_MAX 1015 /* Largest DBCONFIG */ +#define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ +#define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */ +#define SQLITE_DBCONFIG_MAX 1017 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes @@ -2483,7 +2540,7 @@ int sqlite3_total_changes(sqlite3*); ** ^The sqlite3_interrupt(D) call is in effect until all currently running ** SQL statements on [database connection] D complete. ^Any new SQL statements ** that are started after the sqlite3_interrupt() call and before the -** running statements reaches zero are interrupted as if they had been +** running statement count reaches zero are interrupted as if they had been ** running prior to the sqlite3_interrupt() call. ^New SQL statements ** that are started after the running statement count reaches zero are ** not effected by the sqlite3_interrupt(). @@ -2651,9 +2708,9 @@ int sqlite3_busy_timeout(sqlite3*, int ms); ** Cindy | 21 ** ** -** There are two column (M==2) and three rows (N==3). Thus the +** There are two columns (M==2) and three rows (N==3). Thus the ** result table has 8 entries. Suppose the result table is stored -** in an array names azResult. Then azResult holds this content: +** in an array named azResult. Then azResult holds this content: ** **
         **        azResult[0] = "Name";
        @@ -2746,7 +2803,7 @@ char *sqlite3_vsnprintf(int,char*,const char*, va_list);
         **
         ** The SQLite core uses these three routines for all of its own
         ** internal memory allocation needs. "Core" in the previous sentence
        -** does not include operating-system specific VFS implementation.  The
        +** does not include operating-system specific [VFS] implementation.  The
         ** Windows VFS uses native malloc() and free() for some operations.
         **
         ** ^The sqlite3_malloc() routine returns a pointer to a block
        @@ -2807,19 +2864,6 @@ char *sqlite3_vsnprintf(int,char*,const char*, va_list);
         ** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time
         ** option is used.
         **
        -** In SQLite version 3.5.0 and 3.5.1, it was possible to define
        -** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in
        -** implementation of these routines to be omitted.  That capability
        -** is no longer provided.  Only built-in memory allocators can be used.
        -**
        -** Prior to SQLite version 3.7.10, the Windows OS interface layer called
        -** the system malloc() and free() directly when converting
        -** filenames between the UTF-8 encoding used by SQLite
        -** and whatever filename encoding is used by the particular Windows
        -** installation.  Memory allocation errors were detected, but
        -** they were reported back as [SQLITE_CANTOPEN] or
        -** [SQLITE_IOERR] rather than [SQLITE_NOMEM].
        -**
         ** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
         ** must be either NULL or else pointers obtained from a prior
         ** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have
        @@ -2868,7 +2912,7 @@ sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
         ** SQLite contains a high-quality pseudo-random number generator (PRNG) used to
         ** select random [ROWID | ROWIDs] when inserting new records into a table that
         ** already uses the largest possible [ROWID].  The PRNG is also used for
        -** the build-in random() and randomblob() SQL functions.  This interface allows
        +** the built-in random() and randomblob() SQL functions.  This interface allows
         ** applications to access the same PRNG for other purposes.
         **
         ** ^A call to this routine stores N bytes of randomness into buffer P.
        @@ -3242,10 +3286,8 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
         ** The sqlite3_open_v2() interface works like sqlite3_open()
         ** except that it accepts two additional parameters for additional control
         ** over the new database connection.  ^(The flags parameter to
        -** sqlite3_open_v2() can take one of
        -** the following three values, optionally combined with the 
        -** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE],
        -** [SQLITE_OPEN_PRIVATECACHE], and/or [SQLITE_OPEN_URI] flags:)^
        +** sqlite3_open_v2() must include, at a minimum, one of the following
        +** three flag combinations:)^
         **
         ** 
        ** ^(
        [SQLITE_OPEN_READONLY]
        @@ -3263,23 +3305,51 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** sqlite3_open() and sqlite3_open16().)^ **
        ** +** In addition to the required flags, the following optional flags are +** also supported: +** +**
        +** ^(
        [SQLITE_OPEN_URI]
        +**
        The filename can be interpreted as a URI if this flag is set.
        )^ +** +** ^(
        [SQLITE_OPEN_MEMORY]
        +**
        The database will be opened as an in-memory database. The database +** is named by the "filename" argument for the purposes of cache-sharing, +** if shared cache mode is enabled, but the "filename" is otherwise ignored. +**
        )^ +** +** ^(
        [SQLITE_OPEN_NOMUTEX]
        +**
        The new database connection will use the "multi-thread" +** [threading mode].)^ This means that separate threads are allowed +** to use SQLite at the same time, as long as each thread is using +** a different [database connection]. +** +** ^(
        [SQLITE_OPEN_FULLMUTEX]
        +**
        The new database connection will use the "serialized" +** [threading mode].)^ This means the multiple threads can safely +** attempt to use the same database connection at the same time. +** (Mutexes will block any actual concurrency, but in this mode +** there is no harm in trying.) +** +** ^(
        [SQLITE_OPEN_SHAREDCACHE]
        +**
        The database is opened [shared cache] enabled, overriding +** the default shared cache setting provided by +** [sqlite3_enable_shared_cache()].)^ +** +** ^(
        [SQLITE_OPEN_PRIVATECACHE]
        +**
        The database is opened [shared cache] disabled, overriding +** the default shared cache setting provided by +** [sqlite3_enable_shared_cache()].)^ +** +** [[OPEN_NOFOLLOW]] ^(
        [SQLITE_OPEN_NOFOLLOW]
        +**
        The database filename is not allowed to be a symbolic link
        +**
        )^ +** ** If the 3rd parameter to sqlite3_open_v2() is not one of the -** combinations shown above optionally combined with other +** required combinations shown above optionally combined with other ** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] ** then the behavior is undefined. ** -** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection -** opens in the multi-thread [threading mode] as long as the single-thread -** mode has not been set at compile-time or start-time. ^If the -** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens -** in the serialized [threading mode] unless single-thread was -** previously selected at compile-time or start-time. -** ^The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be -** eligible to use [shared cache mode], regardless of whether or not shared -** cache is enabled using [sqlite3_enable_shared_cache()]. ^The -** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not -** participate in [shared cache mode] even if it is enabled. -** ** ^The fourth parameter to sqlite3_open_v2() is the name of the ** [sqlite3_vfs] object that defines the operating system interface that ** the new database connection should use. ^If the fourth parameter is @@ -3459,17 +3529,16 @@ int sqlite3_open_v2( /* ** CAPI3REF: Obtain Values For URI Parameters ** -** These are utility routines, useful to VFS implementations, that check -** to see if a database file was a URI that contained a specific query +** These are utility routines, useful to [VFS|custom VFS implementations], +** that check if a database file was a URI that contained a specific query ** parameter, and if so obtains the value of that query parameter. ** ** If F is the database filename pointer passed into the xOpen() method of -** a VFS implementation when the flags parameter to xOpen() has one or -** more of the [SQLITE_OPEN_URI] or [SQLITE_OPEN_MAIN_DB] bits set and -** P is the name of the query parameter, then +** a VFS implementation or it is the return value of [sqlite3_db_filename()] +** and if P is the name of the query parameter, then ** sqlite3_uri_parameter(F,P) returns the value of the P ** parameter if it exists or a NULL pointer if P does not appear as a -** query parameter on F. If P is a query parameter of F +** query parameter on F. If P is a query parameter of F and it ** has no explicit value, then sqlite3_uri_parameter(F,P) returns ** a pointer to an empty string. ** @@ -3481,25 +3550,72 @@ int sqlite3_open_v2( ** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of ** query parameter P is one of "no", "false", or "off" in any case or ** if the value begins with a numeric zero. If P is not a query -** parameter on F or if the value of P is does not match any of the +** parameter on F or if the value of P does not match any of the ** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0). ** ** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a ** 64-bit signed integer and returns that integer, or D if P does not ** exist. If the value of P is something other than an integer, then ** zero is returned. +** +** The sqlite3_uri_key(F,N) returns a pointer to the name (not +** the value) of the N-th query parameter for filename F, or a NULL +** pointer if N is less than zero or greater than the number of query +** parameters minus 1. The N value is zero-based so N should be 0 to obtain +** the name of the first query parameter, 1 for the second parameter, and +** so forth. ** ** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and ** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and -** is not a database file pathname pointer that SQLite passed into the xOpen -** VFS method, then the behavior of this routine is undefined and probably -** undesirable. +** is not a database file pathname pointer that the SQLite core passed +** into the xOpen VFS method, then the behavior of this routine is undefined +** and probably undesirable. +** +** Beginning with SQLite [version 3.31.0] ([dateof:3.31.0]) the input F +** parameter can also be the name of a rollback journal file or WAL file +** in addition to the main database file. Prior to version 3.31.0, these +** routines would only work if F was the name of the main database file. +** When the F parameter is the name of the rollback journal or WAL file, +** it has access to all the same query parameters as were found on the +** main database file. ** ** See the [URI filename] documentation for additional information. */ const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); +const char *sqlite3_uri_key(const char *zFilename, int N); + +/* +** CAPI3REF: Translate filenames +** +** These routines are available to [VFS|custom VFS implementations] for +** translating filenames between the main database file, the journal file, +** and the WAL file. +** +** If F is the name of an sqlite database file, journal file, or WAL file +** passed by the SQLite core into the VFS, then sqlite3_filename_database(F) +** returns the name of the corresponding database file. +** +** If F is the name of an sqlite database file, journal file, or WAL file +** passed by the SQLite core into the VFS, or if F is a database filename +** obtained from [sqlite3_db_filename()], then sqlite3_filename_journal(F) +** returns the name of the corresponding rollback journal file. +** +** If F is the name of an sqlite database file, journal file, or WAL file +** that was passed by the SQLite core into the VFS, or if F is a database +** filename obtained from [sqlite3_db_filename()], then +** sqlite3_filename_wal(F) returns the name of the corresponding +** WAL file. +** +** In all of the above, if F is not the name of a database, journal or WAL +** filename passed into the VFS from the SQLite core and F is not the +** return value from [sqlite3_db_filename()], then the result is +** undefined and is likely a memory access violation. +*/ +const char *sqlite3_filename_database(const char*); +const char *sqlite3_filename_journal(const char*); +const char *sqlite3_filename_wal(const char*); /* @@ -3818,12 +3934,12 @@ int sqlite3_limit(sqlite3*, int id, int newVal); **
      • ** **
      • -** ^If the specific value bound to [parameter | host parameter] in the +** ^If the specific value bound to a [parameter | host parameter] in the ** WHERE clause might influence the choice of query plan for a statement, ** then the statement will be automatically recompiled, as if there had been -** a schema change, on the first [sqlite3_step()] call following any change +** a schema change, on the first [sqlite3_step()] call following any change ** to the [sqlite3_bind_text | bindings] of that [parameter]. -** ^The specific value of WHERE-clause [parameter] might influence the +** ^The specific value of a WHERE-clause [parameter] might influence the ** choice of query plan if the parameter is the left-hand side of a [LIKE] ** or [GLOB] operator or if the parameter is compared to an indexed column ** and the [SQLITE_ENABLE_STAT4] compile-time option is enabled. @@ -4332,7 +4448,7 @@ const void *sqlite3_column_name16(sqlite3_stmt*, int N); ** ** ^If the Nth column returned by the statement is an expression or ** subquery and is not a column value, then all of these functions return -** NULL. ^These routine might also return NULL if a memory allocation error +** NULL. ^These routines might also return NULL if a memory allocation error ** occurs. ^Otherwise, they return the name of the attached database, table, ** or column that query result column was extracted from. ** @@ -4342,10 +4458,6 @@ const void *sqlite3_column_name16(sqlite3_stmt*, int N); ** ^These APIs are only available if the library was compiled with the ** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol. ** -** If two or more threads call one or more of these routines against the same -** prepared statement and column at the same time then the results are -** undefined. -** ** If two or more threads call one or more ** [sqlite3_column_database_name | column metadata interfaces] ** for the same [prepared statement] and result column @@ -4482,7 +4594,7 @@ int sqlite3_step(sqlite3_stmt*); ** ^The sqlite3_data_count(P) interface returns the number of columns in the ** current row of the result set of [prepared statement] P. ** ^If prepared statement P does not have results ready to return -** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of +** (via calls to the [sqlite3_column_int | sqlite3_column()] family of ** interfaces) then sqlite3_data_count(P) returns 0. ** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. ** ^The sqlite3_data_count(P) routine returns 0 if the previous call to @@ -4806,8 +4918,6 @@ int sqlite3_reset(sqlite3_stmt *pStmt); /* ** CAPI3REF: Create Or Redefine SQL Functions ** KEYWORDS: {function creation routines} -** KEYWORDS: {application-defined SQL function} -** KEYWORDS: {application-defined SQL functions} ** METHOD: sqlite3 ** ** ^These functions (collectively known as "function creation routines") @@ -4863,9 +4973,20 @@ int sqlite3_reset(sqlite3_stmt *pStmt); ** ** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY] ** flag, which if present prevents the function from being invoked from -** within VIEWs or TRIGGERs. For security reasons, the [SQLITE_DIRECTONLY] -** flag is recommended for any application-defined SQL function that has -** side-effects. +** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, +** index expressions, or the WHERE clause of partial indexes. +** +** +** For best security, the [SQLITE_DIRECTONLY] flag is recommended for +** all application-defined SQL functions that do not need to be +** used inside of triggers, view, CHECK constraints, or other elements of +** the database schema. This flags is especially recommended for SQL +** functions that have side effects or reveal internal application state. +** Without this flag, an attacker might be able to modify the schema of +** a database file to include invocations of the function with parameters +** chosen by the attacker, which the application will then execute when +** the database file is opened and read. +** ** ** ^(The fifth parameter is an arbitrary pointer. The implementation of the ** function can gain access to this pointer using [sqlite3_user_data()].)^ @@ -4984,18 +5105,53 @@ int sqlite3_create_window_function( ** to [sqlite3_create_function()], [sqlite3_create_function16()], or ** [sqlite3_create_function_v2()]. ** -** The SQLITE_DETERMINISTIC flag means that the new function will always -** maps the same inputs into the same output. The abs() function is -** deterministic, for example, but randomblob() is not. -** +**
        +** [[SQLITE_DETERMINISTIC]]
        SQLITE_DETERMINISTIC
        +** The SQLITE_DETERMINISTIC flag means that the new function always gives +** the same output when the input parameters are the same. +** The [abs|abs() function] is deterministic, for example, but +** [randomblob|randomblob()] is not. Functions must +** be deterministic in order to be used in certain contexts such as +** with the WHERE clause of [partial indexes] or in [generated columns]. +** SQLite might also optimize deterministic functions by factoring them +** out of inner loops. +**
        +** +** [[SQLITE_DIRECTONLY]]
        SQLITE_DIRECTONLY
        ** The SQLITE_DIRECTONLY flag means that the function may only be invoked -** from top-level SQL, and cannot be used in VIEWs or TRIGGERs. This is -** a security feature which is recommended for all -** [application-defined SQL functions] that have side-effects. This flag -** prevents an attacker from adding triggers and views to a schema then -** tricking a high-privilege application into causing unintended side-effects -** while performing ordinary queries. +** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in +** schema structures such as [CHECK constraints], [DEFAULT clauses], +** [expression indexes], [partial indexes], or [generated columns]. +** The SQLITE_DIRECTONLY flags is a security feature which is recommended +** for all [application-defined SQL functions], and especially for functions +** that have side-effects or that could potentially leak sensitive +** information. +**
        ** +** [[SQLITE_INNOCUOUS]]
        SQLITE_INNOCUOUS
        +** The SQLITE_INNOCUOUS flag means that the function is unlikely +** to cause problems even if misused. An innocuous function should have +** no side effects and should not depend on any values other than its +** input parameters. The [abs|abs() function] is an example of an +** innocuous function. +** The [load_extension() SQL function] is not innocuous because of its +** side effects. +**

        SQLITE_INNOCUOUS is similar to SQLITE_DETERMINISTIC, but is not +** exactly the same. The [random|random() function] is an example of a +** function that is innocuous but not deterministic. +**

        Some heightened security settings +** ([SQLITE_DBCONFIG_TRUSTED_SCHEMA] and [PRAGMA trusted_schema=OFF]) +** disable the use of SQL functions inside views and triggers and in +** schema structures such as [CHECK constraints], [DEFAULT clauses], +** [expression indexes], [partial indexes], and [generated columns] unless +** the function is tagged with SQLITE_INNOCUOUS. Most built-in functions +** are innocuous. Developers are advised to avoid using the +** SQLITE_INNOCUOUS flag for application-defined functions unless the +** function has been carefully audited and found to be free of potentially +** security-adverse side-effects and information-leaks. +**

        +** +** [[SQLITE_SUBTYPE]]
        SQLITE_SUBTYPE
        ** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call ** [sqlite3_value_subtype()] to inspect the sub-types of its arguments. ** Specifying this flag makes no difference for scalar or aggregate user @@ -5003,10 +5159,13 @@ int sqlite3_create_window_function( ** function, then any sub-types belonging to arguments passed to the window ** function may be discarded before the window function is called (i.e. ** sqlite3_value_subtype() will always return 0). +**
        +**
        */ #define SQLITE_DETERMINISTIC 0x000000800 #define SQLITE_DIRECTONLY 0x000080000 #define SQLITE_SUBTYPE 0x000100000 +#define SQLITE_INNOCUOUS 0x000200000 /* ** CAPI3REF: Deprecated Functions @@ -5065,8 +5224,8 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), ** ** These routines extract type, size, and content information from ** [protected sqlite3_value] objects. Protected sqlite3_value objects -** are used to pass parameter information into implementation of -** [application-defined SQL functions] and [virtual tables]. +** are used to pass parameter information into the functions that +** implement [application-defined SQL functions] and [virtual tables]. ** ** These routines work only with [protected sqlite3_value] objects. ** Any attempt to use these routines on an [unprotected sqlite3_value] @@ -5123,7 +5282,7 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), ** ^The sqlite3_value_frombind(X) interface returns non-zero if the ** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()] ** interfaces. ^If X comes from an SQL literal value, or a table column, -** and expression, then sqlite3_value_frombind(X) returns zero. +** or an expression, then sqlite3_value_frombind(X) returns zero. ** ** Please pay particular attention to the fact that the pointer returned ** from [sqlite3_value_blob()], [sqlite3_value_text()], or @@ -5209,8 +5368,8 @@ void sqlite3_value_free(sqlite3_value*); ** routine to allocate memory for storing their state. ** ** ^The first time the sqlite3_aggregate_context(C,N) routine is called -** for a particular aggregate function, SQLite -** allocates N of memory, zeroes out that memory, and returns a pointer +** for a particular aggregate function, SQLite allocates +** N bytes of memory, zeroes out that memory, and returns a pointer ** to the new memory. ^On second and subsequent calls to ** sqlite3_aggregate_context() for the same aggregate function instance, ** the same buffer is returned. Sqlite3_aggregate_context() is normally @@ -5227,7 +5386,7 @@ void sqlite3_value_free(sqlite3_value*); ** ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is ** determined by the N parameter on first successful call. Changing the -** value of N in subsequent call to sqlite3_aggregate_context() within +** value of N in any subsequents call to sqlite3_aggregate_context() within ** the same aggregate function instance will not resize the memory ** allocation.)^ Within the xFinal callback, it is customary to set ** N=0 in calls to sqlite3_aggregate_context(C,N) so that no @@ -5538,7 +5697,7 @@ void sqlite3_result_subtype(sqlite3_context*,unsigned int); **
      • [SQLITE_UTF16_ALIGNED]. **
      )^ ** ^The eTextRep argument determines the encoding of strings passed -** to the collating function callback, xCallback. +** to the collating function callback, xCompare. ** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep ** force strings to be UTF16 with native byte order. ** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin @@ -5547,18 +5706,19 @@ void sqlite3_result_subtype(sqlite3_context*,unsigned int); ** ^The fourth argument, pArg, is an application data pointer that is passed ** through as the first argument to the collating function callback. ** -** ^The fifth argument, xCallback, is a pointer to the collating function. +** ^The fifth argument, xCompare, is a pointer to the collating function. ** ^Multiple collating functions can be registered using the same name but ** with different eTextRep parameters and SQLite will use whichever ** function requires the least amount of data transformation. -** ^If the xCallback argument is NULL then the collating function is +** ^If the xCompare argument is NULL then the collating function is ** deleted. ^When all collating functions having the same name are deleted, ** that collation is no longer usable. ** ** ^The collating function callback is invoked with a copy of the pArg ** application data pointer and with two strings in the encoding specified -** by the eTextRep argument. The collating function must return an -** integer that is negative, zero, or positive +** by the eTextRep argument. The two integer parameters to the collating +** function callback are the length of the two strings, in bytes. The collating +** function must return an integer that is negative, zero, or positive ** if the first string is less than, equal to, or greater than the second, ** respectively. A collating function must always return the same answer ** given the same inputs. If two or more collating functions are registered @@ -5575,7 +5735,7 @@ void sqlite3_result_subtype(sqlite3_context*,unsigned int); **
    ** ** If a collating function fails any of the above constraints and that -** collating function is registered and used, then the behavior of SQLite +** collating function is registered and used, then the behavior of SQLite ** is undefined. ** ** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation() @@ -5902,16 +6062,31 @@ sqlite3 *sqlite3_db_handle(sqlite3_stmt*); ** CAPI3REF: Return The Filename For A Database Connection ** METHOD: sqlite3 ** -** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename -** associated with database N of connection D. ^The main database file -** has the name "main". If there is no attached database N on the database +** ^The sqlite3_db_filename(D,N) interface returns a pointer to the filename +** associated with database N of connection D. +** ^If there is no attached database N on the database ** connection D, or if database N is a temporary or in-memory database, then ** this function will return either a NULL pointer or an empty string. ** +** ^The string value returned by this routine is owned and managed by +** the database connection. ^The value will be valid until the database N +** is [DETACH]-ed or until the database connection closes. +** ** ^The filename returned by this function is the output of the ** xFullPathname method of the [VFS]. ^In other words, the filename ** will be an absolute pathname, even if the filename used ** to open the database originally was a URI or relative pathname. +** +** If the filename pointer returned by this routine is not NULL, then it +** can be used as the filename input parameter to these routines: +**
      +**
    • [sqlite3_uri_parameter()] +**
    • [sqlite3_uri_boolean()] +**
    • [sqlite3_uri_int64()] +**
    • [sqlite3_filename_database()] +**
    • [sqlite3_filename_journal()] +**
    • [sqlite3_filename_wal()] +**
    */ const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); @@ -6061,15 +6236,19 @@ void *sqlite3_update_hook( ** ** ^(The cache sharing mode set by this interface effects all subsequent ** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. -** Existing database connections continue use the sharing mode +** Existing database connections continue to use the sharing mode ** that was in effect at the time they were opened.)^ ** ** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled ** successfully. An [error code] is returned otherwise.)^ ** -** ^Shared cache is disabled by default. But this might change in -** future releases of SQLite. Applications that care about shared -** cache setting should set it explicitly. +** ^Shared cache is disabled by default. It is recommended that it stay +** that way. In other words, do not use this routine. This interface +** continues to be provided for historical compatibility, but its use is +** discouraged. Any use of shared cache is discouraged. If shared cache +** must be used, it is recommended that shared cache only be enabled for +** individual database connections using the [sqlite3_open_v2()] interface +** with the [SQLITE_OPEN_SHAREDCACHE] flag. ** ** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0 ** and will always return SQLITE_MISUSE. On those systems, @@ -6116,6 +6295,9 @@ int sqlite3_db_release_memory(sqlite3*); /* ** CAPI3REF: Impose A Limit On Heap Size ** +** These interfaces impose limits on the amount of heap memory that will be +** by all database connections within a single process. +** ** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the ** soft limit on the amount of heap memory that may be allocated by SQLite. ** ^SQLite strives to keep heap memory utilization below the soft heap @@ -6126,20 +6308,41 @@ int sqlite3_db_release_memory(sqlite3*); ** an [SQLITE_NOMEM] error. In other words, the soft heap limit ** is advisory only. ** -** ^The return value from sqlite3_soft_heap_limit64() is the size of -** the soft heap limit prior to the call, or negative in the case of an +** ^The sqlite3_hard_heap_limit64(N) interface sets a hard upper bound of +** N bytes on the amount of memory that will be allocated. ^The +** sqlite3_hard_heap_limit64(N) interface is similar to +** sqlite3_soft_heap_limit64(N) except that memory allocations will fail +** when the hard heap limit is reached. +** +** ^The return value from both sqlite3_soft_heap_limit64() and +** sqlite3_hard_heap_limit64() is the size of +** the heap limit prior to the call, or negative in the case of an ** error. ^If the argument N is negative -** then no change is made to the soft heap limit. Hence, the current -** size of the soft heap limit can be determined by invoking -** sqlite3_soft_heap_limit64() with a negative argument. +** then no change is made to the heap limit. Hence, the current +** size of heap limits can be determined by invoking +** sqlite3_soft_heap_limit64(-1) or sqlite3_hard_heap_limit(-1). ** -** ^If the argument N is zero then the soft heap limit is disabled. +** ^Setting the heap limits to zero disables the heap limiter mechanism. ** -** ^(The soft heap limit is not enforced in the current implementation +** ^The soft heap limit may not be greater than the hard heap limit. +** ^If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N) +** is invoked with a value of N that is greater than the hard heap limit, +** the the soft heap limit is set to the value of the hard heap limit. +** ^The soft heap limit is automatically enabled whenever the hard heap +** limit is enabled. ^When sqlite3_hard_heap_limit64(N) is invoked and +** the soft heap limit is outside the range of 1..N, then the soft heap +** limit is set to N. ^Invoking sqlite3_soft_heap_limit64(0) when the +** hard heap limit is enabled makes the soft heap limit equal to the +** hard heap limit. +** +** The memory allocation limits can also be adjusted using +** [PRAGMA soft_heap_limit] and [PRAGMA hard_heap_limit]. +** +** ^(The heap limits are not enforced in the current implementation ** if one or more of following conditions are true: ** **
      -**
    • The soft heap limit is set to zero. +**
    • The limit value is set to zero. **
    • Memory accounting is disabled using a combination of the ** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and ** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option. @@ -6150,21 +6353,11 @@ int sqlite3_db_release_memory(sqlite3*); ** from the heap. **
    )^ ** -** Beginning with SQLite [version 3.7.3] ([dateof:3.7.3]), -** the soft heap limit is enforced -** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT] -** compile-time option is invoked. With [SQLITE_ENABLE_MEMORY_MANAGEMENT], -** the soft heap limit is enforced on every memory allocation. Without -** [SQLITE_ENABLE_MEMORY_MANAGEMENT], the soft heap limit is only enforced -** when memory is allocated by the page cache. Testing suggests that because -** the page cache is the predominate memory user in SQLite, most -** applications will achieve adequate soft heap limit enforcement without -** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT]. -** -** The circumstances under which SQLite will enforce the soft heap limit may +** The circumstances under which SQLite will enforce the heap limits may ** changes in future releases of SQLite. */ sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); +sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N); /* ** CAPI3REF: Deprecated Soft Heap Limit Interface @@ -6188,7 +6381,7 @@ SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); ** interface returns SQLITE_OK and fills in the non-NULL pointers in ** the final five arguments with appropriate values if the specified ** column exists. ^The sqlite3_table_column_metadata() interface returns -** SQLITE_ERROR and if the specified column does not exist. +** SQLITE_ERROR if the specified column does not exist. ** ^If the column-name parameter to sqlite3_table_column_metadata() is a ** NULL pointer, then this routine simply checks for the existence of the ** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it @@ -6330,7 +6523,7 @@ int sqlite3_load_extension( ** to enable or disable only the C-API.)^ ** ** Security warning: It is recommended that extension loading -** be disabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method +** be enabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method ** rather than this interface, so the [load_extension()] SQL function ** remains disabled. This will prevent SQL injections from giving attackers ** access to extension loading capabilities. @@ -6417,7 +6610,7 @@ typedef struct sqlite3_module sqlite3_module; ** KEYWORDS: sqlite3_module {virtual table module} ** ** This structure, sometimes called a "virtual table module", -** defines the implementation of a [virtual tables]. +** defines the implementation of a [virtual table]. ** This structure consists mostly of methods for the module. ** ** ^A virtual table module is created by filling in a persistent @@ -6514,7 +6707,13 @@ struct sqlite3_module { ** the right-hand side of the corresponding aConstraint[] is evaluated ** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit ** is true, then the constraint is assumed to be fully handled by the -** virtual table and is not checked again by SQLite.)^ +** virtual table and might not be checked again by the byte code.)^ ^(The +** aConstraintUsage[].omit flag is an optimization hint. When the omit flag +** is left in its default setting of false, the constraint will always be +** checked separately in byte code. If the omit flag is change to true, then +** the constraint may or may not be checked in byte code. In other words, +** when the omit flag is true there is no guarantee that the constraint will +** not be checked again using byte code.)^ ** ** ^The idxNum and idxPtr values are recorded and passed into the ** [xFilter] method. @@ -6554,7 +6753,7 @@ struct sqlite3_module { ** If a virtual table extension is ** used with an SQLite version earlier than 3.8.2, the results of attempting ** to read or write the estimatedRows field are undefined (but are likely -** to included crashing the application). The estimatedRows field should +** to include crashing the application). The estimatedRows field should ** therefore only be used if [sqlite3_libversion_number()] returns a ** value greater than or equal to 3008002. Similarly, the idxFlags field ** was added for [version 3.9.0] ([dateof:3.9.0]). @@ -6606,7 +6805,7 @@ struct sqlite3_index_info { /* ** CAPI3REF: Virtual Table Constraint Operator Codes ** -** These macros defined the allowed values for the +** These macros define the allowed values for the ** [sqlite3_index_info].aConstraint[].op field. Each value represents ** an operator that is part of a constraint term in the wHERE clause of ** a query that uses a [virtual table]. @@ -7216,7 +7415,7 @@ void sqlite3_mutex_leave(sqlite3_mutex*); ** The only difference is that the public sqlite3_XXX functions enumerated ** above silently ignore any invocations that pass a NULL pointer instead ** of a valid mutex handle. The implementations of the methods defined -** by this structure are not required to handle this case, the results +** by this structure are not required to handle this case. The results ** of passing a NULL pointer instead of a valid mutex handle are undefined ** (i.e. it is acceptable to provide an implementation that segfaults if ** it is passed a NULL pointer). @@ -7689,7 +7888,7 @@ int sqlite3_status64( ** ** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(
    SQLITE_STATUS_PAGECACHE_SIZE
    **
    This parameter records the largest memory allocation request -** handed to [pagecache memory allocator]. Only the value returned in the +** handed to the [pagecache memory allocator]. Only the value returned in the ** *pHighwater parameter to [sqlite3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.
    )^ ** @@ -7765,7 +7964,7 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); ** checked out.)^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(
    SQLITE_DBSTATUS_LOOKASIDE_HIT
    -**
    This parameter returns the number malloc attempts that were +**
    This parameter returns the number of malloc attempts that were ** satisfied using lookaside memory. Only the high-water value is meaningful; ** the current value is always zero.)^ ** @@ -7847,7 +8046,7 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); ** cache overflowing. Transactions are more efficient if they are written ** to disk all at once. When pages spill mid-transaction, that introduces ** additional overhead. This parameter can be used help identify -** inefficiencies that can be resolve by increasing the cache size. +** inefficiencies that can be resolved by increasing the cache size. **
    ** ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(
    SQLITE_DBSTATUS_DEFERRED_FKS
    @@ -7936,7 +8135,7 @@ int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** ** [[SQLITE_STMTSTATUS_REPREPARE]]
    SQLITE_STMTSTATUS_REPREPARE
    **
    ^This is the number of times that the prepare statement has been -** automatically regenerated due to schema changes or change to +** automatically regenerated due to schema changes or changes to ** [bound parameters] that might affect the query plan. ** ** [[SQLITE_STMTSTATUS_RUN]]
    SQLITE_STMTSTATUS_RUN
    @@ -8107,7 +8306,7 @@ struct sqlite3_pcache_page { ** ** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1. SQLite ** will only use a createFlag of 2 after a prior call with a createFlag of 1 -** failed.)^ In between the to xFetch() calls, SQLite may +** failed.)^ In between the xFetch() calls, SQLite may ** attempt to unpin one or more cache pages by spilling the content of ** pinned pages to disk and synching the operating system disk cache. ** @@ -8425,7 +8624,7 @@ int sqlite3_backup_pagecount(sqlite3_backup *p); ** the first argument to register for a callback that will be invoked ** when the blocking connections current transaction is concluded. ^The ** callback is invoked from within the [sqlite3_step] or [sqlite3_close] -** call that concludes the blocking connections transaction. +** call that concludes the blocking connection's transaction. ** ** ^(If sqlite3_unlock_notify() is called in a multi-threaded application, ** there is a chance that the blocking connection will have already @@ -8463,7 +8662,7 @@ int sqlite3_backup_pagecount(sqlite3_backup *p); ** an unlock-notify callback is a pointer to an array of void* pointers, ** and the second is the number of entries in the array. ** -** When a blocking connections transaction is concluded, there may be +** When a blocking connection's transaction is concluded, there may be ** more than one blocked connection that has registered for an unlock-notify ** callback. ^If two or more such blocked connections have specified the ** same callback function, then instead of invoking the callback function @@ -8811,14 +9010,20 @@ int sqlite3_wal_checkpoint_v2( ** If this interface is invoked outside the context of an xConnect or ** xCreate virtual table method then the behavior is undefined. ** -** At present, there is only one option that may be configured using -** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options -** may be added in the future. +** In the call sqlite3_vtab_config(D,C,...) the D parameter is the +** [database connection] in which the virtual table is being created and +** which is passed in as the first argument to the [xConnect] or [xCreate] +** method that is invoking sqlite3_vtab_config(). The C parameter is one +** of the [virtual table configuration options]. The presence and meaning +** of parameters after C depend on which [virtual table configuration option] +** is used. */ int sqlite3_vtab_config(sqlite3*, int op, ...); /* ** CAPI3REF: Virtual Table Configuration Options +** KEYWORDS: {virtual table configuration options} +** KEYWORDS: {virtual table configuration option} ** ** These macros define the various options to the ** [sqlite3_vtab_config()] interface that [virtual table] implementations @@ -8826,7 +9031,7 @@ int sqlite3_vtab_config(sqlite3*, int op, ...); ** **
    ** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]] -**
    SQLITE_VTAB_CONSTRAINT_SUPPORT +**
    SQLITE_VTAB_CONSTRAINT_SUPPORT
    **
    Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, ** where X is an integer. If X is zero, then the [virtual table] whose @@ -8855,9 +9060,31 @@ int sqlite3_vtab_config(sqlite3*, int op, ...); ** return SQLITE_OK. Or, if this is not possible, it may return ** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT ** constraint handling. +**
    +** +** [[SQLITE_VTAB_DIRECTONLY]]
    SQLITE_VTAB_DIRECTONLY
    +**
    Calls of the form +** [sqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the +** the [xConnect] or [xCreate] methods of a [virtual table] implmentation +** prohibits that virtual table from being used from within triggers and +** views. +**
    +** +** [[SQLITE_VTAB_INNOCUOUS]]
    SQLITE_VTAB_INNOCUOUS
    +**
    Calls of the form +** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the +** the [xConnect] or [xCreate] methods of a [virtual table] implmentation +** identify that virtual table as being safe to use from within triggers +** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the +** virtual table can do no serious harm even if it is controlled by a +** malicious hacker. Developers should avoid setting the SQLITE_VTAB_INNOCUOUS +** flag unless absolutely necessary. +**
    **
    */ #define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 +#define SQLITE_VTAB_INNOCUOUS 2 +#define SQLITE_VTAB_DIRECTONLY 3 /* ** CAPI3REF: Determine The Virtual Table Conflict Policy @@ -8937,15 +9164,15 @@ SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); ** **
    ** [[SQLITE_SCANSTAT_NLOOP]]
    SQLITE_SCANSTAT_NLOOP
    -**
    ^The [sqlite3_int64] variable pointed to by the T parameter will be +**
    ^The [sqlite3_int64] variable pointed to by the V parameter will be ** set to the total number of times that the X-th loop has run.
    ** ** [[SQLITE_SCANSTAT_NVISIT]]
    SQLITE_SCANSTAT_NVISIT
    -**
    ^The [sqlite3_int64] variable pointed to by the T parameter will be set +**
    ^The [sqlite3_int64] variable pointed to by the V parameter will be set ** to the total number of rows examined by all iterations of the X-th loop.
    ** ** [[SQLITE_SCANSTAT_EST]]
    SQLITE_SCANSTAT_EST
    -**
    ^The "double" variable pointed to by the T parameter will be set to the +**
    ^The "double" variable pointed to by the V parameter will be set to the ** query planner's estimate for the average number of rows output from each ** iteration of the X-th loop. If the query planner's estimates was accurate, ** then this value will approximate the quotient NVISIT/NLOOP and the @@ -8953,17 +9180,17 @@ SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); ** be the NLOOP value for the current loop. ** ** [[SQLITE_SCANSTAT_NAME]]
    SQLITE_SCANSTAT_NAME
    -**
    ^The "const char *" variable pointed to by the T parameter will be set +**
    ^The "const char *" variable pointed to by the V parameter will be set ** to a zero-terminated UTF-8 string containing the name of the index or table ** used for the X-th loop. ** ** [[SQLITE_SCANSTAT_EXPLAIN]]
    SQLITE_SCANSTAT_EXPLAIN
    -**
    ^The "const char *" variable pointed to by the T parameter will be set +**
    ^The "const char *" variable pointed to by the V parameter will be set ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] ** description for the X-th loop. ** ** [[SQLITE_SCANSTAT_SELECTID]]
    SQLITE_SCANSTAT_SELECT
    -**
    ^The "int" variable pointed to by the T parameter will be set to the +**
    ^The "int" variable pointed to by the V parameter will be set to the ** "select-id" for the X-th loop. The select-id identifies which query or ** subquery the loop is part of. The main query has a select-id of zero. ** The select-id is the same value as is output in the first column diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index 416ac942..b5258e0d 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -324,6 +324,12 @@ struct sqlite3_api_routines { int (*value_frombind)(sqlite3_value*); /* Version 3.30.0 and later */ int (*drop_modules)(sqlite3*,const char**); + /* Version 3.31.0 and later */ + sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64); + const char *(*uri_key)(const char*,int); + const char *(*filename_database)(const char*); + const char *(*filename_journal)(const char*); + const char *(*filename_wal)(const char*); }; /* @@ -618,6 +624,12 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_value_frombind sqlite3_api->frombind /* Version 3.30.0 and later */ #define sqlite3_drop_modules sqlite3_api->drop_modules +/* Version 3.31.0 andn later */ +#define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64 +#define sqlite3_uri_key sqlite3_api->uri_key +#define sqlite3_filename_database sqlite3_api->filename_database +#define sqlite3_filename_journal sqlite3_api->filename_journal +#define sqlite3_filename_wal sqlite3_api->filename_wal #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 21d5ae89..53e7095d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -446,6 +446,26 @@ # define NEVER(X) (X) #endif +/* +** The harmless(X) macro indicates that expression X is usually false +** but can be true without causing any problems, but we don't know of +** any way to cause X to be true. +** +** In debugging and testing builds, this macro will abort if X is ever +** true. In this way, developers are alerted to a possible test case +** that causes X to be true. If a harmless macro ever fails, that is +** an opportunity to change the macro into a testcase() and add a new +** test case to the test suite. +** +** For normal production builds, harmless(X) is a no-op, since it does +** not matter whether expression X is true or false. +*/ +#ifdef SQLITE_DEBUG +# define harmless(X) assert(!(X)); +#else +# define harmless(X) +#endif + /* ** Some conditionals are optimizations only. In other words, if the ** conditionals are replaced with a constant 1 (true) or 0 (false) then @@ -1122,6 +1142,7 @@ typedef struct With With; ** A bit in a Bitmask */ #define MASKBIT(n) (((Bitmask)1)<<(n)) +#define MASKBIT64(n) (((u64)1)<<(n)) #define MASKBIT32(n) (((unsigned int)1)<<(n)) #define ALLBITS ((Bitmask)-1) @@ -1271,15 +1292,47 @@ struct Schema { ** is shared by multiple database connections. Therefore, while parsing ** schema information, the Lookaside.bEnabled flag is cleared so that ** lookaside allocations are not used to construct the schema objects. +** +** New lookaside allocations are only allowed if bDisable==0. When +** bDisable is greater than zero, sz is set to zero which effectively +** disables lookaside without adding a new test for the bDisable flag +** in a performance-critical path. sz should be set by to szTrue whenever +** bDisable changes back to zero. +** +** Lookaside buffers are initially held on the pInit list. As they are +** used and freed, they are added back to the pFree list. New allocations +** come off of pFree first, then pInit as a fallback. This dual-list +** allows use to compute a high-water mark - the maximum number of allocations +** outstanding at any point in the past - by subtracting the number of +** allocations on the pInit list from the total number of allocations. +** +** Enhancement on 2019-12-12: Two-size-lookaside +** The default lookaside configuration is 100 slots of 1200 bytes each. +** The larger slot sizes are important for performance, but they waste +** a lot of space, as most lookaside allocations are less than 128 bytes. +** The two-size-lookaside enhancement breaks up the lookaside allocation +** into two pools: One of 128-byte slots and the other of the default size +** (1200-byte) slots. Allocations are filled from the small-pool first, +** failing over to the full-size pool if that does not work. Thus more +** lookaside slots are available while also using less memory. +** This enhancement can be omitted by compiling with +** SQLITE_OMIT_TWOSIZE_LOOKASIDE. */ struct Lookaside { u32 bDisable; /* Only operate the lookaside when zero */ u16 sz; /* Size of each buffer in bytes */ + u16 szTrue; /* True value of sz, even if disabled */ u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ u32 nSlot; /* Number of lookaside slots allocated */ u32 anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ LookasideSlot *pInit; /* List of buffers not previously used */ LookasideSlot *pFree; /* List of available buffers */ +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + LookasideSlot *pSmallInit; /* List of small buffers not prediously used */ + LookasideSlot *pSmallFree; /* List of available small buffers */ + void *pMiddle; /* First byte past end of full-size buffers and + ** the first byte of LOOKASIDE_SMALL buffers */ +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ void *pStart; /* First byte of available memory space */ void *pEnd; /* First byte past end of available space */ }; @@ -1287,6 +1340,17 @@ struct LookasideSlot { LookasideSlot *pNext; /* Next buffer in the list of free buffers */ }; +#define DisableLookaside db->lookaside.bDisable++;db->lookaside.sz=0 +#define EnableLookaside db->lookaside.bDisable--;\ + db->lookaside.sz=db->lookaside.bDisable?0:db->lookaside.szTrue + +/* Size of the smaller allocations in two-size lookside */ +#ifdef SQLITE_OMIT_TWOSIZE_LOOKASIDE +# define LOOKASIDE_SMALL 0 +#else +# define LOOKASIDE_SMALL 128 +#endif + /* ** A hash table for built-in function definitions. (Application-defined ** functions use a regular table table from hash.h.) @@ -1495,6 +1559,13 @@ struct sqlite3 { #define SCHEMA_ENC(db) ((db)->aDb[0].pSchema->enc) #define ENC(db) ((db)->enc) +/* +** A u64 constant where the lower 32 bits are all zeros. Only the +** upper 32 bits are included in the argument. Necessary because some +** C-compilers still do not accept LL integer literals. +*/ +#define HI(X) ((u64)(X)<<32) + /* ** Possible values for the sqlite3.flags. ** @@ -1510,9 +1581,8 @@ struct sqlite3 { #define SQLITE_CkptFullFSync 0x00000010 /* Use full fsync for checkpoint */ #define SQLITE_CacheSpill 0x00000020 /* OK to spill pager cache */ #define SQLITE_ShortColNames 0x00000040 /* Show short columns names */ -#define SQLITE_CountRows 0x00000080 /* Count rows changed by INSERT, */ - /* DELETE, or UPDATE and return */ - /* the count using a callback. */ +#define SQLITE_TrustedSchema 0x00000080 /* Allow unsafe functions and + ** vtabs in the schema definition */ #define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */ /* result set is empty */ #define SQLITE_IgnoreChecks 0x00000200 /* Do not enforce check constraints */ @@ -1538,9 +1608,11 @@ struct sqlite3 { #define SQLITE_DqsDDL 0x20000000 /* dbl-quoted strings allowed in DDL*/ #define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/ #define SQLITE_EnableView 0x80000000 /* Enable the use of views */ +#define SQLITE_CountRows HI(0x00001) /* Count rows changed by INSERT, */ + /* DELETE, or UPDATE and return */ + /* the count using a callback. */ /* Flags used only if debugging */ -#define HI(X) ((u64)(X)<<32) #ifdef SQLITE_DEBUG #define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */ #define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */ @@ -1558,6 +1630,7 @@ struct sqlite3 { #define DBFLAG_Vacuum 0x0004 /* Currently in a VACUUM */ #define DBFLAG_VacuumInto 0x0008 /* Currently running VACUUM INTO */ #define DBFLAG_SchemaKnownOk 0x0010 /* Schema is known to be valid */ +#define DBFLAG_InternalFunc 0x0020 /* Allow use of internal functions */ /* ** Bits of the sqlite3.dbOptFlags field that are used by the @@ -1665,6 +1738,7 @@ struct FuncDestructor { ** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG ** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API ** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API +** SQLITE_FUNC_UNSAFE == SQLITE_INNOCUOUS ** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API */ #define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ @@ -1681,12 +1755,22 @@ struct FuncDestructor { #define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */ #define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a ** single query - might change over time */ -#define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */ +#define SQLITE_FUNC_TEST 0x4000 /* Built-in testing functions */ #define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */ #define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */ #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ #define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */ #define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */ +#define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */ +#define SQLITE_FUNC_INLINE 0x00400000 /* Functions implemented in-line */ + +/* Identifier numbers for each in-line function */ +#define INLINEFUNC_coalesce 0 +#define INLINEFUNC_implies_nonnull_row 1 +#define INLINEFUNC_expr_implies_expr 2 +#define INLINEFUNC_expr_compare 3 +#define INLINEFUNC_affinity 4 +#define INLINEFUNC_unlikely 99 /* Default case */ /* ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are @@ -1702,6 +1786,22 @@ struct FuncDestructor { ** VFUNCTION(zName, nArg, iArg, bNC, xFunc) ** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag. ** +** SFUNCTION(zName, nArg, iArg, bNC, xFunc) +** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag and +** adds the SQLITE_DIRECTONLY flag. +** +** INLINE_FUNC(zName, nArg, iFuncId, mFlags) +** zName is the name of a function that is implemented by in-line +** byte code rather than by the usual callbacks. The iFuncId +** parameter determines the function id. The mFlags parameter is +** optional SQLITE_FUNC_ flags for this function. +** +** TEST_FUNC(zName, nArg, iFuncId, mFlags) +** zName is the name of a test-only function implemented by in-line +** byte code rather than by the usual callbacks. The iFuncId +** parameter determines the function id. The mFlags parameter is +** optional SQLITE_FUNC_ flags for this function. +** ** DFUNCTION(zName, nArg, iArg, bNC, xFunc) ** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag and ** adds the SQLITE_FUNC_SLOCHNG flag. Used for date & time functions @@ -1741,6 +1841,16 @@ struct FuncDestructor { #define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } +#define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \ + {nArg, SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \ + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } +#define INLINE_FUNC(zName, nArg, iArg, mFlags) \ + {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ + SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} } +#define TEST_FUNC(zName, nArg, iArg, mFlags) \ + {nArg, SQLITE_UTF8|SQLITE_FUNC_INTERNAL|SQLITE_FUNC_TEST| \ + SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ + SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} } #define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \ 0, 0, xFunc, 0, 0, 0, #zName, {0} } @@ -1756,12 +1866,6 @@ struct FuncDestructor { #define LIKEFUNC(zName, nArg, arg, flags) \ {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \ (void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} } -#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue) \ - {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \ - SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,0,#zName, {0}} -#define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \ - {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \ - SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xFinal,0,#zName, {0}} #define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \ SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}} @@ -1807,26 +1911,45 @@ struct Module { }; /* -** information about each column of an SQL table is held in an instance -** of this structure. +** Information about each column of an SQL table is held in an instance +** of the Column structure, in the Table.aCol[] array. +** +** Definitions: +** +** "table column index" This is the index of the column in the +** Table.aCol[] array, and also the index of +** the column in the original CREATE TABLE stmt. +** +** "storage column index" This is the index of the column in the +** record BLOB generated by the OP_MakeRecord +** opcode. The storage column index is less than +** or equal to the table column index. It is +** equal if and only if there are no VIRTUAL +** columns to the left. */ struct Column { char *zName; /* Name of this column, \000, then the type */ - Expr *pDflt; /* Default value of this column */ + Expr *pDflt; /* Default value or GENERATED ALWAYS AS value */ char *zColl; /* Collating sequence. If NULL, use the default */ u8 notNull; /* An OE_ code for handling a NOT NULL constraint */ char affinity; /* One of the SQLITE_AFF_... values */ u8 szEst; /* Estimated size of value in this column. sizeof(INT)==1 */ - u8 colFlags; /* Boolean properties. See COLFLAG_ defines below */ + u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */ }; /* Allowed values for Column.colFlags: */ -#define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */ -#define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */ -#define COLFLAG_HASTYPE 0x0004 /* Type name follows column name */ -#define COLFLAG_UNIQUE 0x0008 /* Column def contains "UNIQUE" or "PK" */ +#define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */ +#define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */ +#define COLFLAG_HASTYPE 0x0004 /* Type name follows column name */ +#define COLFLAG_UNIQUE 0x0008 /* Column def contains "UNIQUE" or "PK" */ #define COLFLAG_SORTERREF 0x0010 /* Use sorter-refs with this column */ +#define COLFLAG_VIRTUAL 0x0020 /* GENERATED ALWAYS AS ... VIRTUAL */ +#define COLFLAG_STORED 0x0040 /* GENERATED ALWAYS AS ... STORED */ +#define COLFLAG_NOTAVAIL 0x0080 /* STORED column not yet calculated */ +#define COLFLAG_BUSY 0x0100 /* Blocks recursion on GENERATED columns */ +#define COLFLAG_GENERATED 0x0060 /* Combo: _STORED, _VIRTUAL */ +#define COLFLAG_NOINSERT 0x0062 /* Combo: _HIDDEN, _STORED, _VIRTUAL */ /* ** A "Collating Sequence" is defined by an instance of the following @@ -1944,10 +2067,17 @@ struct VTable { sqlite3_vtab *pVtab; /* Pointer to vtab instance */ int nRef; /* Number of pointers to this structure */ u8 bConstraint; /* True if constraints are supported */ + u8 eVtabRisk; /* Riskiness of allowing hacker access */ int iSavepoint; /* Depth of the SAVEPOINT stack */ VTable *pNext; /* Next in linked list (see above) */ }; +/* Allowed values for VTable.eVtabRisk +*/ +#define SQLITE_VTABRISK_Low 0 +#define SQLITE_VTABRISK_Normal 1 +#define SQLITE_VTABRISK_High 2 + /* ** The schema for each SQL table and view is represented in memory ** by an instance of the following structure. @@ -1966,6 +2096,7 @@ struct Table { u32 tabFlags; /* Mask of TF_* values */ i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */ i16 nCol; /* Number of columns in this table */ + i16 nNVCol; /* Number of columns that are not VIRTUAL */ LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */ LogEst szTabRow; /* Estimated size of each table row in bytes */ #ifdef SQLITE_ENABLE_COSTMULT @@ -1992,20 +2123,28 @@ struct Table { ** followed by non-hidden columns. Example: "CREATE VIRTUAL TABLE x USING ** vtab1(a HIDDEN, b);". Since "b" is a non-hidden column but "a" is hidden, ** the TF_OOOHidden attribute would apply in this case. Such tables require -** special handling during INSERT processing. +** special handling during INSERT processing. The "OOO" means "Out Of Order". +** +** Constraints: +** +** TF_HasVirtual == COLFLAG_Virtual +** TF_HasStored == COLFLAG_Stored */ #define TF_Readonly 0x0001 /* Read-only system table */ #define TF_Ephemeral 0x0002 /* An ephemeral table */ #define TF_HasPrimaryKey 0x0004 /* Table has a primary key */ #define TF_Autoincrement 0x0008 /* Integer primary key is autoincrement */ #define TF_HasStat1 0x0010 /* nRowLogEst set from sqlite_stat1 */ -#define TF_WithoutRowid 0x0020 /* No rowid. PRIMARY KEY is the key */ -#define TF_NoVisibleRowid 0x0040 /* No user-visible "rowid" column */ -#define TF_OOOHidden 0x0080 /* Out-of-Order hidden columns */ +#define TF_HasVirtual 0x0020 /* Has one or more VIRTUAL columns */ +#define TF_HasStored 0x0040 /* Has one or more STORED columns */ +#define TF_HasGenerated 0x0060 /* Combo: HasVirtual + HasStored */ +#define TF_WithoutRowid 0x0080 /* No rowid. PRIMARY KEY is the key */ #define TF_StatsUsed 0x0100 /* Query planner decisions affected by ** Index.aiRowLogEst[] values */ -#define TF_HasNotNull 0x0200 /* Contains NOT NULL constraints */ -#define TF_Shadow 0x0400 /* True for a shadow table */ +#define TF_NoVisibleRowid 0x0200 /* No user-visible "rowid" column */ +#define TF_OOOHidden 0x0400 /* Out-of-Order hidden columns */ +#define TF_HasNotNull 0x0800 /* Contains NOT NULL constraints */ +#define TF_Shadow 0x1000 /* True for a shadow table */ /* ** Test to see whether or not a table is a virtual table. This is @@ -2256,6 +2395,7 @@ struct Index { unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ unsigned bNoQuery:1; /* Do not use this index to optimize queries */ unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ + unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ #ifdef SQLITE_ENABLE_STAT4 int nSample; /* Number of elements in aSample[] */ int nSampleCol; /* Size of IndexSample.anEq[] and so on */ @@ -2447,6 +2587,10 @@ typedef int ynVar; struct Expr { u8 op; /* Operation performed by this node */ char affExpr; /* affinity, or RAISE type */ + u8 op2; /* TK_REGISTER/TK_TRUTH: original value of Expr.op + ** TK_COLUMN: the value of p5 for OP_Column + ** TK_AGG_FUNCTION: nesting depth + ** TK_FUNCTION: NC_SelfRef flag if needs OP_PureFunc */ u32 flags; /* Various flags. EP_* See below */ union { char *zToken; /* Token value. Zero terminated and dequoted */ @@ -2485,9 +2629,6 @@ struct Expr { ** TK_SELECT_COLUMN: column of the result vector */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */ - u8 op2; /* TK_REGISTER/TK_TRUTH: original value of Expr.op - ** TK_COLUMN: the value of p5 for OP_Column - ** TK_AGG_FUNCTION: nesting depth */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ union { Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL @@ -2516,7 +2657,7 @@ struct Expr { #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ #define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */ #define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */ - /* 0x000200 Available for reuse */ +#define EP_Commuted 0x000200 /* Comparison operator has been commuted */ #define EP_IntValue 0x000400 /* Integer value contained in u.iValue */ #define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */ #define EP_Skip 0x001000 /* Operator does not contribute to affinity */ @@ -2537,7 +2678,7 @@ struct Expr { #define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */ #define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */ #define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */ -#define EP_Indirect 0x40000000 /* Contained within a TRIGGER or a VIEW */ +#define EP_FromDDL 0x40000000 /* Originates from sqlite_master */ /* ** The EP_Propagate mask is a set of properties that automatically propagate @@ -2601,23 +2742,28 @@ struct Expr { ** also be used as the argument to a function, in which case the a.zName ** field is not used. ** -** By default the Expr.zSpan field holds a human-readable description of -** the expression that is used in the generation of error messages and -** column labels. In this case, Expr.zSpan is typically the text of a -** column expression as it exists in a SELECT statement. However, if -** the bSpanIsTab flag is set, then zSpan is overloaded to mean the name -** of the result column in the form: DATABASE.TABLE.COLUMN. This later -** form is used for name resolution with nested FROM clauses. +** In order to try to keep memory usage down, the Expr.a.zEName field +** is used for multiple purposes: +** +** eEName Usage +** ---------- ------------------------- +** ENAME_NAME (1) the AS of result set column +** (2) COLUMN= of an UPDATE +** +** ENAME_TAB DB.TABLE.NAME used to resolve names +** of subqueries +** +** ENAME_SPAN Text of the original result set +** expression. */ struct ExprList { int nExpr; /* Number of expressions on the list */ struct ExprList_item { /* For each expression in the list */ Expr *pExpr; /* The parse tree for this expression */ - char *zName; /* Token associated with this expression */ - char *zSpan; /* Original text of the expression */ + char *zEName; /* Token associated with this expression */ u8 sortFlags; /* Mask of KEYINFO_ORDER_* flags */ + unsigned eEName :2; /* Meaning of zEName */ unsigned done :1; /* A flag to indicate when processing is finished */ - unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */ unsigned reusable :1; /* Constant expression is reusable */ unsigned bSorterRef :1; /* Defer evaluation until after sorting */ unsigned bNulls: 1; /* True if explicit "NULLS FIRST/LAST" */ @@ -2631,6 +2777,13 @@ struct ExprList { } a[1]; /* One slot for each expression in the list */ }; +/* +** Allowed values for Expr.a.eEName +*/ +#define ENAME_NAME 0 /* The AS clause of a result set */ +#define ENAME_SPAN 1 /* Complete text of the result set expression */ +#define ENAME_TAB 2 /* "DB.TABLE.NAME" for the result set */ + /* ** An instance of this structure can hold a simple list of identifiers, ** such as the list "a,b,c" in the following statements: @@ -2694,6 +2847,7 @@ struct SrcList { unsigned isCorrelated :1; /* True if sub-query is correlated */ unsigned viaCoroutine :1; /* Implemented as a co-routine */ unsigned isRecursive :1; /* True for recursive reference in WITH */ + unsigned fromDDL :1; /* Comes from sqlite_master */ } fg; int iCursor; /* The VDBE cursor number used to access this table */ Expr *pOn; /* The ON clause of a join */ @@ -2797,21 +2951,24 @@ struct NameContext { ** NC_HasWin == EP_Win ** */ -#define NC_AllowAgg 0x0001 /* Aggregate functions are allowed here */ -#define NC_PartIdx 0x0002 /* True if resolving a partial index WHERE */ -#define NC_IsCheck 0x0004 /* True if resolving names in a CHECK constraint */ -#define NC_InAggFunc 0x0008 /* True if analyzing arguments to an agg func */ -#define NC_HasAgg 0x0010 /* One or more aggregate functions seen */ -#define NC_IdxExpr 0x0020 /* True if resolving columns of CREATE INDEX */ -#define NC_VarSelect 0x0040 /* A correlated subquery has been seen */ -#define NC_UEList 0x0080 /* True if uNC.pEList is used */ -#define NC_UAggInfo 0x0100 /* True if uNC.pAggInfo is used */ -#define NC_UUpsert 0x0200 /* True if uNC.pUpsert is used */ -#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */ -#define NC_Complex 0x2000 /* True if a function or subquery seen */ -#define NC_AllowWin 0x4000 /* Window functions are allowed here */ -#define NC_HasWin 0x8000 /* One or more window functions seen */ -#define NC_IsDDL 0x10000 /* Resolving names in a CREATE statement */ +#define NC_AllowAgg 0x00001 /* Aggregate functions are allowed here */ +#define NC_PartIdx 0x00002 /* True if resolving a partial index WHERE */ +#define NC_IsCheck 0x00004 /* True if resolving a CHECK constraint */ +#define NC_GenCol 0x00008 /* True for a GENERATED ALWAYS AS clause */ +#define NC_HasAgg 0x00010 /* One or more aggregate functions seen */ +#define NC_IdxExpr 0x00020 /* True if resolving columns of CREATE INDEX */ +#define NC_SelfRef 0x0002e /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */ +#define NC_VarSelect 0x00040 /* A correlated subquery has been seen */ +#define NC_UEList 0x00080 /* True if uNC.pEList is used */ +#define NC_UAggInfo 0x00100 /* True if uNC.pAggInfo is used */ +#define NC_UUpsert 0x00200 /* True if uNC.pUpsert is used */ +#define NC_MinMaxAgg 0x01000 /* min/max aggregates seen. See note above */ +#define NC_Complex 0x02000 /* True if a function or subquery seen */ +#define NC_AllowWin 0x04000 /* Window functions are allowed here */ +#define NC_HasWin 0x08000 /* One or more window functions seen */ +#define NC_IsDDL 0x10000 /* Resolving names in a CREATE statement */ +#define NC_InAggFunc 0x20000 /* True if analyzing arguments to an agg func */ +#define NC_FromDDL 0x40000 /* SQL text comes from sqlite_master */ /* ** An instance of the following object describes a single ON CONFLICT @@ -2861,13 +3018,13 @@ struct Upsert { ** sequences for the ORDER BY clause. */ struct Select { - ExprList *pEList; /* The fields of the result */ u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */ LogEst nSelectRow; /* Estimated number of result rows */ u32 selFlags; /* Various SF_* values */ int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ u32 selId; /* Unique identifier number for this SELECT */ int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */ + ExprList *pEList; /* The fields of the result */ SrcList *pSrc; /* The FROM clause */ Expr *pWhere; /* The WHERE clause */ ExprList *pGroupBy; /* The GROUP BY clause */ @@ -2892,26 +3049,28 @@ struct Select { ** SF_MinMaxAgg == NC_MinMaxAgg == SQLITE_FUNC_MINMAX ** SF_FixedLimit == WHERE_USE_LIMIT */ -#define SF_Distinct 0x00001 /* Output should be DISTINCT */ -#define SF_All 0x00002 /* Includes the ALL keyword */ -#define SF_Resolved 0x00004 /* Identifiers have been resolved */ -#define SF_Aggregate 0x00008 /* Contains agg functions or a GROUP BY */ -#define SF_HasAgg 0x00010 /* Contains aggregate functions */ -#define SF_UsesEphemeral 0x00020 /* Uses the OpenEphemeral opcode */ -#define SF_Expanded 0x00040 /* sqlite3SelectExpand() called on this */ -#define SF_HasTypeInfo 0x00080 /* FROM subqueries have Table metadata */ -#define SF_Compound 0x00100 /* Part of a compound query */ -#define SF_Values 0x00200 /* Synthesized from VALUES clause */ -#define SF_MultiValue 0x00400 /* Single VALUES term with multiple rows */ -#define SF_NestedFrom 0x00800 /* Part of a parenthesized FROM clause */ -#define SF_MinMaxAgg 0x01000 /* Aggregate containing min() or max() */ -#define SF_Recursive 0x02000 /* The recursive part of a recursive CTE */ -#define SF_FixedLimit 0x04000 /* nSelectRow set by a constant LIMIT */ -#define SF_MaybeConvert 0x08000 /* Need convertCompoundSelectToSubquery() */ -#define SF_Converted 0x10000 /* By convertCompoundSelectToSubquery() */ -#define SF_IncludeHidden 0x20000 /* Include hidden columns in output */ -#define SF_ComplexResult 0x40000 /* Result contains subquery or function */ -#define SF_WhereBegin 0x80000 /* Really a WhereBegin() call. Debug Only */ +#define SF_Distinct 0x0000001 /* Output should be DISTINCT */ +#define SF_All 0x0000002 /* Includes the ALL keyword */ +#define SF_Resolved 0x0000004 /* Identifiers have been resolved */ +#define SF_Aggregate 0x0000008 /* Contains agg functions or a GROUP BY */ +#define SF_HasAgg 0x0000010 /* Contains aggregate functions */ +#define SF_UsesEphemeral 0x0000020 /* Uses the OpenEphemeral opcode */ +#define SF_Expanded 0x0000040 /* sqlite3SelectExpand() called on this */ +#define SF_HasTypeInfo 0x0000080 /* FROM subqueries have Table metadata */ +#define SF_Compound 0x0000100 /* Part of a compound query */ +#define SF_Values 0x0000200 /* Synthesized from VALUES clause */ +#define SF_MultiValue 0x0000400 /* Single VALUES term with multiple rows */ +#define SF_NestedFrom 0x0000800 /* Part of a parenthesized FROM clause */ +#define SF_MinMaxAgg 0x0001000 /* Aggregate containing min() or max() */ +#define SF_Recursive 0x0002000 /* The recursive part of a recursive CTE */ +#define SF_FixedLimit 0x0004000 /* nSelectRow set by a constant LIMIT */ +#define SF_MaybeConvert 0x0008000 /* Need convertCompoundSelectToSubquery() */ +#define SF_Converted 0x0010000 /* By convertCompoundSelectToSubquery() */ +#define SF_IncludeHidden 0x0020000 /* Include hidden columns in output */ +#define SF_ComplexResult 0x0040000 /* Result contains subquery or function */ +#define SF_WhereBegin 0x0080000 /* Really a WhereBegin() call. Debug Only */ +#define SF_WinRewrite 0x0100000 /* Window function rewrite accomplished */ +#define SF_View 0x0200000 /* SELECT statement is a view */ /* ** The results of a SELECT can be distributed in several ways, as defined @@ -3191,8 +3350,8 @@ struct Parse { #define PARSE_MODE_NORMAL 0 #define PARSE_MODE_DECLARE_VTAB 1 -#define PARSE_MODE_RENAME_COLUMN 2 -#define PARSE_MODE_RENAME_TABLE 3 +#define PARSE_MODE_RENAME 2 +#define PARSE_MODE_UNMAP 3 /* ** Sizes and pointers of various parts of the Parse object. @@ -3214,7 +3373,7 @@ struct Parse { #if defined(SQLITE_OMIT_ALTERTABLE) #define IN_RENAME_OBJECT 0 #else - #define IN_RENAME_OBJECT (pParse->eParseMode>=PARSE_MODE_RENAME_COLUMN) + #define IN_RENAME_OBJECT (pParse->eParseMode>=PARSE_MODE_RENAME) #endif #if defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_OMIT_ALTERTABLE) @@ -3365,7 +3524,7 @@ typedef struct DbFixer DbFixer; struct DbFixer { Parse *pParse; /* The parsing context. Error messages written here */ Schema *pSchema; /* Fix items to this schema */ - int bVarOnly; /* Check for variable references only */ + u8 bTemp; /* True for TEMP schema entries */ const char *zDb; /* Make sure all objects are contained in this database */ const char *zType; /* Type of the container - used for error messages */ const Token *pName; /* Name of the container - used for error messages */ @@ -3470,7 +3629,6 @@ struct Sqlite3Config { int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ #endif int bLocaltimeFault; /* True to fail localtime() calls */ - int bInternalFunctions; /* Internal SQL functions are visible */ int iOnceResetThreshold; /* When to reset OP_Once counters */ u32 szSorterRef; /* Min size in bytes to use sorter-refs */ unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */ @@ -3503,7 +3661,7 @@ struct Walker { int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */ void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */ int walkerDepth; /* Number of subqueries */ - u8 eCode; /* A small processing code */ + u16 eCode; /* A small processing code */ union { /* Extra data for callback */ NameContext *pNC; /* Naming context */ int n; /* A counter */ @@ -3519,6 +3677,7 @@ struct Walker { struct WindowRewrite *pRewrite; /* Window rewrite context */ struct WhereConst *pConst; /* WHERE clause constants */ struct RenameCtx *pRename; /* RENAME COLUMN context */ + struct Table *pTab; /* Table of generated column */ } u; }; @@ -3632,7 +3791,7 @@ Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8); void sqlite3WindowAttach(Parse*, Expr*, Window*); void sqlite3WindowLink(Select *pSel, Window *pWin); int sqlite3WindowCompare(Parse*, Window*, Window*, int); -void sqlite3WindowCodeInit(Parse*, Window*); +void sqlite3WindowCodeInit(Parse*, Select*); void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int); int sqlite3WindowRewrite(Parse*, Select*); int sqlite3ExpandSubquery(Parse*, struct SrcList_item*); @@ -3898,6 +4057,7 @@ void sqlite3PExprAddSelect(Parse*, Expr*, Select*); Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*); Expr *sqlite3ExprSimplifiedAndOr(Expr*); Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int); +void sqlite3ExprFunctionUsable(Parse*,Expr*,FuncDef*); void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); void sqlite3ExprDelete(sqlite3*, Expr*); void sqlite3ExprUnmapAndDelete(Parse*, Expr*); @@ -3926,7 +4086,14 @@ void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char); Table *sqlite3ResultSetOfSelect(Parse*,Select*,char); void sqlite3OpenMasterTable(Parse *, int); Index *sqlite3PrimaryKeyIndex(Table*); -i16 sqlite3ColumnOfIndex(Index*, i16); +i16 sqlite3TableColumnToIndex(Index*, i16); +#ifdef SQLITE_OMIT_GENERATED_COLUMNS +# define sqlite3TableColumnToStorage(T,X) (X) /* No-op pass-through */ +# define sqlite3StorageColumnToTable(T,X) (X) /* No-op pass-through */ +#else + i16 sqlite3TableColumnToStorage(Table*, i16); + i16 sqlite3StorageColumnToTable(Table*, i16); +#endif void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int); #if SQLITE_ENABLE_HIDDEN_COLUMNS void sqlite3ColumnPropertiesFromName(Table*, Column*); @@ -3939,6 +4106,7 @@ void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int); void sqlite3AddCheckConstraint(Parse*, Expr*); void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*); void sqlite3AddCollateType(Parse*, Token*); +void sqlite3AddGenerated(Parse*,Expr*,Token*); void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*); int sqlite3ParseUri(const char*,const char*,unsigned int*, sqlite3_vfs**,char**,char **); @@ -3996,6 +4164,9 @@ void sqlite3FreeIndex(sqlite3*, Index*); # define sqlite3AutoincrementEnd(X) #endif void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upsert*); +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + void sqlite3ComputeGeneratedColumns(Parse*, int, Table*); +#endif void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*); IdList *sqlite3IdListAppend(Parse*, IdList*, Token*); int sqlite3IdListIndex(IdList*,const char*); @@ -4018,6 +4189,7 @@ int sqlite3Select(Parse*, Select*, SelectDest*); Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, Expr*,ExprList*,u32,Expr*); void sqlite3SelectDelete(sqlite3*, Select*); +void sqlite3SelectReset(Parse*, Select*); Table *sqlite3SrcListLookup(Parse*, SrcList*); int sqlite3IsReadOnly(Parse*, Table*, int); void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); @@ -4040,17 +4212,20 @@ int sqlite3WhereOkOnePass(WhereInfo*, int*); #define ONEPASS_OFF 0 /* Use of ONEPASS not allowed */ #define ONEPASS_SINGLE 1 /* ONEPASS valid for a single row update */ #define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */ +int sqlite3WhereUsesDeferredSeek(WhereInfo*); void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int); int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); void sqlite3ExprCodeMove(Parse*, int, int, int); void sqlite3ExprCode(Parse*, Expr*, int); +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +void sqlite3ExprCodeGeneratedColumn(Parse*, Column*, int); +#endif void sqlite3ExprCodeCopy(Parse*, Expr*, int); void sqlite3ExprCodeFactorable(Parse*, Expr*, int); int sqlite3ExprCodeAtInit(Parse*, Expr*, int); int sqlite3ExprCodeTemp(Parse*, Expr*, int*); int sqlite3ExprCodeTarget(Parse*, Expr*, int); -void sqlite3ExprCodeAndCache(Parse*, Expr*, int); int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8); #define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */ #define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */ @@ -4092,6 +4267,7 @@ void sqlite3EndTransaction(Parse*,int); void sqlite3Savepoint(Parse*, int, Token*); void sqlite3CloseSavepoints(sqlite3 *); void sqlite3LeaveMutexAndCloseZombie(sqlite3*); +u32 sqlite3IsTrueOrFalse(const char*); int sqlite3ExprIdToTrueFalse(Expr*); int sqlite3ExprTruthValue(const Expr*); int sqlite3ExprIsConstant(Expr*); @@ -4187,6 +4363,7 @@ void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); #endif int sqlite3JoinType(Parse*, Token*, Token*, Token*); +void sqlite3SetJoinExpr(Expr*,int); void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int); void sqlite3DeferForeignKey(Parse*, int); #ifndef SQLITE_OMIT_AUTHORIZATION @@ -4347,7 +4524,12 @@ void sqlite3CodeRhsOfIN(Parse*, Expr*, int); int sqlite3CodeSubselect(Parse*, Expr*); void sqlite3SelectPrep(Parse*, Select*, NameContext*); void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); -int sqlite3MatchSpanName(const char*, const char*, const char*, const char*); +int sqlite3MatchEName( + const struct ExprList_item*, + const char*, + const char*, + const char* +); int sqlite3ResolveExprNames(NameContext*, Expr*); int sqlite3ResolveExprListNames(NameContext*, ExprList*); void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); @@ -4485,6 +4667,12 @@ void sqlite3AutoLoadExtensions(sqlite3*); ); # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) #endif +int sqlite3ReadOnlyShadowTables(sqlite3 *db); +#ifndef SQLITE_OMIT_VIRTUALTABLE + int sqlite3ShadowTableName(sqlite3 *db, const char *zName); +#else +# define sqlite3ShadowTableName(A,B) 0 +#endif int sqlite3VtabEponymousTableInit(Parse*,Module*); void sqlite3VtabEponymousTableClear(sqlite3*,Module*); void sqlite3VtabMakeWritable(Parse*,Table*); @@ -4506,6 +4694,7 @@ char *sqlite3Normalize(Vdbe*, const char*); #endif int sqlite3Reprepare(Vdbe*); void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); +CollSeq *sqlite3ExprCompareCollSeq(Parse*,Expr*); CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); int sqlite3TempInMemory(const sqlite3*); const char *sqlite3JournalModename(int); diff --git a/src/status.c b/src/status.c index a5a39f4c..c42bcc28 100644 --- a/src/status.c +++ b/src/status.c @@ -188,6 +188,10 @@ static u32 countLookasideSlots(LookasideSlot *p){ int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){ u32 nInit = countLookasideSlots(db->lookaside.pInit); u32 nFree = countLookasideSlots(db->lookaside.pFree); +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + nInit += countLookasideSlots(db->lookaside.pSmallInit); + nFree += countLookasideSlots(db->lookaside.pSmallFree); +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ if( pHighwater ) *pHighwater = db->lookaside.nSlot - nInit; return db->lookaside.nSlot - (nInit+nFree); } @@ -220,6 +224,15 @@ int sqlite3_db_status( db->lookaside.pInit = db->lookaside.pFree; db->lookaside.pFree = 0; } +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + p = db->lookaside.pSmallFree; + if( p ){ + while( p->pNext ) p = p->pNext; + p->pNext = db->lookaside.pSmallInit; + db->lookaside.pSmallInit = db->lookaside.pSmallFree; + db->lookaside.pSmallFree = 0; + } +#endif } break; } diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 80a05726..2cae5804 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -2341,20 +2341,22 @@ static int SQLITE_TCLAPI DbObjCmd( const char *zName; int op; } aDbConfig[] = { + { "defensive", SQLITE_DBCONFIG_DEFENSIVE }, + { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL }, + { "dqs_dml", SQLITE_DBCONFIG_DQS_DML }, { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY }, + { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG }, { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER }, { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW }, { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, + { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE }, + { "legacy_file_format", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT }, { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION }, { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, - { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG }, - { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP }, { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE }, - { "defensive", SQLITE_DBCONFIG_DEFENSIVE }, + { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP }, + { "trusted_schema", SQLITE_DBCONFIG_TRUSTED_SCHEMA }, { "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA }, - { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE }, - { "dqs_dml", SQLITE_DBCONFIG_DQS_DML }, - { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL }, }; Tcl_Obj *pResult; int ii; @@ -2818,6 +2820,7 @@ deserialize_error: ** --argcount N Function has exactly N arguments ** --deterministic The function is pure ** --directonly Prohibit use inside triggers and views + ** --innocuous Has no side effects or information leaks ** --returntype TYPE Specify the return type of the function */ case DB_FUNCTION: { @@ -2854,6 +2857,9 @@ deserialize_error: if( n>1 && strncmp(z, "-directonly",n)==0 ){ flags |= SQLITE_DIRECTONLY; }else + if( n>1 && strncmp(z, "-innocuous",n)==0 ){ + flags |= SQLITE_INNOCUOUS; + }else if( n>1 && strncmp(z, "-returntype", n)==0 ){ const char *azType[] = {"integer", "real", "text", "blob", "any", 0}; assert( SQLITE_INTEGER==1 && SQLITE_FLOAT==2 && SQLITE_TEXT==3 ); @@ -2870,7 +2876,7 @@ deserialize_error: }else{ Tcl_AppendResult(interp, "bad option \"", z, "\": must be -argcount, -deterministic, -directonly," - " or -returntype", (char*)0 + " -innocuous, or -returntype", (char*)0 ); return TCL_ERROR; } @@ -3670,6 +3676,7 @@ static int sqliteCmdUsage( ){ Tcl_WrongNumArgs(interp, 1, objv, "HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?" + " ?-nofollow BOOLEAN?" " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) " ?-key CODECKEY?" @@ -3681,6 +3688,7 @@ static int sqliteCmdUsage( /* ** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN? ** ?-create BOOLEAN? ?-nomutex BOOLEAN? +** ?-nofollow BOOLEAN? ** ** This is the main Tcl command. When the "sqlite" Tcl command is ** invoked, this routine runs to process that command. @@ -3779,6 +3787,14 @@ static int SQLITE_TCLAPI DbMain( }else{ flags &= ~SQLITE_OPEN_CREATE; } + }else if( strcmp(zArg, "-nofollow")==0 ){ + int b; + if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; + if( b ){ + flags |= SQLITE_OPEN_NOFOLLOW; + }else{ + flags &= ~SQLITE_OPEN_NOFOLLOW; + } }else if( strcmp(zArg, "-nomutex")==0 ){ int b; if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; diff --git a/src/test1.c b/src/test1.c index ffd6091f..5b07aef2 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5526,6 +5526,33 @@ static int SQLITE_TCLAPI test_soft_heap_limit( return TCL_OK; } +/* +** Usage: sqlite3_hard_heap_limit ?N? +** +** Query or set the hard heap limit for the current thread. The +** limit is only changed if the N is present. The previous limit +** is returned. +*/ +static int SQLITE_TCLAPI test_hard_heap_limit( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3_int64 amt; + Tcl_WideInt N = -1; + if( objc!=1 && objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "?N?"); + return TCL_ERROR; + } + if( objc==2 ){ + if( Tcl_GetWideIntFromObj(interp, objv[1], &N) ) return TCL_ERROR; + } + amt = sqlite3_hard_heap_limit64(N); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(amt)); + return TCL_OK; +} + /* ** Usage: sqlite3_thread_cleanup ** @@ -6845,7 +6872,16 @@ static int SQLITE_TCLAPI test_test_control( iFlag = aVerb[iVerb].i; switch( iFlag ){ - case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: + case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: { + sqlite3 *db = 0; + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 2, objv, "DB"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR; + sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, db); + break; + } case SQLITE_TESTCTRL_LOCALTIME_FAULT: { int val; if( objc!=3 ){ @@ -7682,14 +7718,15 @@ static int SQLITE_TCLAPI test_sqlite3_db_config( { "LEGACY_ALTER_TABLE", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE }, { "DQS_DML", SQLITE_DBCONFIG_DQS_DML }, { "DQS_DDL", SQLITE_DBCONFIG_DQS_DDL }, + { "LEGACY_FILE_FORMAT", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT }, }; int i; - int v; + int v = 0; const char *zSetting; sqlite3 *db; - if( objc!=4 ){ - Tcl_WrongNumArgs(interp, 1, objv, "DB SETTING VALUE"); + if( objc!=4 && objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB SETTING [VALUE]"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; @@ -7705,7 +7742,11 @@ static int SQLITE_TCLAPI test_sqlite3_db_config( Tcl_NewStringObj("unknown sqlite3_db_config setting", -1)); return TCL_ERROR; } - if( Tcl_GetIntFromObj(interp, objv[3], &v) ) return TCL_ERROR; + if( objc==4 ){ + if( Tcl_GetIntFromObj(interp, objv[3], &v) ) return TCL_ERROR; + }else{ + v = -1; + } sqlite3_db_config(db, aSetting[i].eVal, v, &v); Tcl_SetObjResult(interp, Tcl_NewIntObj(v)); return TCL_OK; @@ -7973,6 +8014,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_db_filename", test_db_filename, 0}, { "sqlite3_db_readonly", test_db_readonly, 0}, { "sqlite3_soft_heap_limit", test_soft_heap_limit, 0}, + { "sqlite3_soft_heap_limit64", test_soft_heap_limit, 0}, + { "sqlite3_hard_heap_limit64", test_hard_heap_limit, 0}, { "sqlite3_thread_cleanup", test_thread_cleanup, 0}, { "sqlite3_pager_refcounts", test_pager_refcounts, 0}, diff --git a/src/test_vfs.c b/src/test_vfs.c index 3357a0a2..9d753896 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -1390,7 +1390,9 @@ static void SQLITE_TCLAPI testvfs_obj_del(ClientData cd){ Testvfs *p = (Testvfs *)cd; if( p->pScript ) Tcl_DecrRefCount(p->pScript); sqlite3_vfs_unregister(p->pVfs); + memset(p->pVfs, 0, sizeof(sqlite3_vfs)); ckfree((char *)p->pVfs); + memset(p, 0, sizeof(Testvfs)); ckfree((char *)p); } diff --git a/src/tokenize.c b/src/tokenize.c index 40f7b4aa..48f92218 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -757,7 +757,7 @@ char *sqlite3Normalize( int nParen; /* Number of nested levels of parentheses */ int iStartIN; /* Start of RHS of IN operator in z[] */ int nParenAtIN; /* Value of nParent at start of RHS of IN operator */ - int j; /* Bytes of normalized SQL generated so far */ + u32 j; /* Bytes of normalized SQL generated so far */ sqlite3_str *pStr; /* The normalized SQL string under construction */ db = sqlite3VdbeDb(pVdbe); @@ -801,7 +801,7 @@ char *sqlite3Normalize( } case TK_RP: { if( iStartIN>0 && nParen==nParenAtIN ){ - assert( pStr->nChar>=iStartIN ); + assert( pStr->nChar>=(u32)iStartIN ); pStr->nChar = iStartIN+1; sqlite3_str_append(pStr, "?,?,?", 5); iStartIN = 0; diff --git a/src/treeview.c b/src/treeview.c index 4979f59b..90a1d2dc 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -66,7 +66,7 @@ static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ va_start(ap, zFormat); sqlite3_str_vappendf(&acc, zFormat, ap); va_end(ap); - assert( acc.nChar>0 ); + assert( acc.nChar>0 || acc.accError ); sqlite3_str_append(&acc, "\n", 1); } sqlite3StrAccumFinish(&acc); @@ -106,7 +106,7 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ char cSep = '('; int j; for(j=0; jpCols->nExpr; j++){ - sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zName); + sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zEName); cSep = ','; } sqlite3_str_appendf(&x, ")"); @@ -131,7 +131,7 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ StrAccum x; char zLine[100]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); - sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor); + sqlite3_str_appendf(&x, "{%d:*}", pItem->iCursor); if( pItem->zDatabase ){ sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName); }else if( pItem->zName ){ @@ -147,6 +147,9 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ if( pItem->fg.jointype & JT_LEFT ){ sqlite3_str_appendf(&x, " LEFT-JOIN"); } + if( pItem->fg.fromDDL ){ + sqlite3_str_appendf(&x, " DDL"); + } sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inSrc-1); if( pItem->pSelect ){ @@ -403,14 +406,17 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ return; } if( pExpr->flags || pExpr->affExpr ){ + StrAccum x; + sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0); + sqlite3_str_appendf(&x, " fg.af=%x.%c", + pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n'); if( ExprHasProperty(pExpr, EP_FromJoin) ){ - sqlite3_snprintf(sizeof(zFlgs),zFlgs," fg.af=%x.%c iRJT=%d", - pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n', - pExpr->iRightJoinTable); - }else{ - sqlite3_snprintf(sizeof(zFlgs),zFlgs," fg.af=%x.%c", - pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n'); + sqlite3_str_appendf(&x, " iRJT=%d", pExpr->iRightJoinTable); } + if( ExprHasProperty(pExpr, EP_FromDDL) ){ + sqlite3_str_appendf(&x, " DDL"); + } + sqlite3StrAccumFinish(&x); }else{ zFlgs[0] = 0; } @@ -423,10 +429,18 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ case TK_COLUMN: { if( pExpr->iTable<0 ){ /* This only happens when coding check constraints */ - sqlite3TreeViewLine(pView, "COLUMN(%d)%s", pExpr->iColumn, zFlgs); + char zOp2[16]; + if( pExpr->op2 ){ + sqlite3_snprintf(sizeof(zOp2),zOp2," op2=0x%02x",pExpr->op2); + }else{ + zOp2[0] = 0; + } + sqlite3TreeViewLine(pView, "COLUMN(%d)%s%s", + pExpr->iColumn, zFlgs, zOp2); }else{ - sqlite3TreeViewLine(pView, "{%d:%d}%s", - pExpr->iTable, pExpr->iColumn, zFlgs); + sqlite3TreeViewLine(pView, "{%d:%d} pTab=%p%s", + pExpr->iTable, pExpr->iColumn, + pExpr->y.pTab, zFlgs); } if( ExprHasProperty(pExpr, EP_FixedCol) ){ sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); @@ -558,7 +572,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ }else{ pFarg = pExpr->x.pList; #ifndef SQLITE_OMIT_WINDOWFUNC - pWin = pExpr->y.pWin; + pWin = ExprHasProperty(pExpr, EP_WinFunc) ? pExpr->y.pWin : 0; #else pWin = 0; #endif @@ -566,6 +580,17 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ if( pExpr->op==TK_AGG_FUNCTION ){ sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s", pExpr->op2, pExpr->u.zToken, zFlgs); + }else if( pExpr->op2!=0 ){ + const char *zOp2; + char zBuf[8]; + sqlite3_snprintf(sizeof(zBuf),zBuf,"0x%02x",pExpr->op2); + zOp2 = zBuf; + if( pExpr->op2==NC_IsCheck ) zOp2 = "NC_IsCheck"; + if( pExpr->op2==NC_IdxExpr ) zOp2 = "NC_IdxExpr"; + if( pExpr->op2==NC_PartIdx ) zOp2 = "NC_PartIdx"; + if( pExpr->op2==NC_GenCol ) zOp2 = "NC_GenCol"; + sqlite3TreeViewLine(pView, "FUNCTION %Q%s op2=%s", + pExpr->u.zToken, zFlgs, zOp2); }else{ sqlite3TreeViewLine(pView, "FUNCTION %Q%s", pExpr->u.zToken, zFlgs); } @@ -661,7 +686,9 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ break; } case TK_VECTOR: { - sqlite3TreeViewBareExprList(pView, pExpr->x.pList, "VECTOR"); + char *z = sqlite3_mprintf("VECTOR%s",zFlgs); + sqlite3TreeViewBareExprList(pView, pExpr->x.pList, z); + sqlite3_free(z); break; } case TK_SELECT_COLUMN: { @@ -707,8 +734,9 @@ void sqlite3TreeViewBareExprList( sqlite3TreeViewLine(pView, "%s", zLabel); for(i=0; inExpr; i++){ int j = pList->a[i].u.x.iOrderByCol; - char *zName = pList->a[i].zName; + char *zName = pList->a[i].zEName; int moreToFollow = inExpr - 1; + if( pList->a[i].eEName!=ENAME_NAME ) zName = 0; if( j || zName ){ sqlite3TreeViewPush(pView, moreToFollow); moreToFollow = 0; diff --git a/src/trigger.c b/src/trigger.c index 83685a0a..458aa299 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -662,8 +662,12 @@ void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){ Table *pTab = tableOfTrigger(pTrigger); if( pTab ){ Trigger **pp; - for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext)); - *pp = (*pp)->pNext; + for(pp=&pTab->pTrigger; *pp; pp=&((*pp)->pNext)){ + if( *pp==pTrigger ){ + *pp = (*pp)->pNext; + break; + } + } } } sqlite3DeleteTrigger(db, pTrigger); @@ -684,7 +688,7 @@ static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){ int e; if( pIdList==0 || NEVER(pEList==0) ) return 1; for(e=0; enExpr; e++){ - if( sqlite3IdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1; + if( sqlite3IdListIndex(pIdList, pEList->a[e].zEName)>=0 ) return 1; } return 0; } diff --git a/src/update.c b/src/update.c index 458550b9..61b1740b 100644 --- a/src/update.c +++ b/src/update.c @@ -147,7 +147,7 @@ void sqlite3Update( Expr *pLimit, /* LIMIT clause. May be null */ Upsert *pUpsert /* ON CONFLICT clause, or null */ ){ - int i, j; /* Loop counters */ + int i, j, k; /* Loop counters */ Table *pTab; /* The table to be updated */ int addrTop = 0; /* VDBE instruction address of the start of the loop */ WhereInfo *pWInfo; /* Information about the WHERE clause */ @@ -191,6 +191,7 @@ void sqlite3Update( int iPk = 0; /* First of nPk cells holding PRIMARY KEY value */ i16 nPk = 0; /* Number of components of the PRIMARY KEY */ int bReplace = 0; /* True if REPLACE conflict resolution might happen */ + int bFinishSeek = 1; /* The OP_FinishSeek opcode is needed */ /* Register Allocations */ int regRowCount = 0; /* A count of rows changed */ @@ -289,6 +290,10 @@ void sqlite3Update( sNC.uNC.pUpsert = pUpsert; sNC.ncFlags = NC_UUpsert; + /* Begin generating code. */ + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto update_cleanup; + /* Resolve the column names in all the expressions of the ** of the UPDATE statement. Also find the column index ** for each column to be updated in the pChanges array. For each @@ -301,24 +306,34 @@ void sqlite3Update( goto update_cleanup; } for(j=0; jnCol; j++){ - if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){ + if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zEName)==0 ){ if( j==pTab->iPKey ){ chngRowid = 1; pRowidExpr = pChanges->a[i].pExpr; }else if( pPk && (pTab->aCol[j].colFlags & COLFLAG_PRIMKEY)!=0 ){ chngPk = 1; } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + else if( pTab->aCol[j].colFlags & COLFLAG_GENERATED ){ + testcase( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ); + testcase( pTab->aCol[j].colFlags & COLFLAG_STORED ); + sqlite3ErrorMsg(pParse, + "cannot UPDATE generated column \"%s\"", + pTab->aCol[j].zName); + goto update_cleanup; + } +#endif aXRef[j] = i; break; } } if( j>=pTab->nCol ){ - if( pPk==0 && sqlite3IsRowid(pChanges->a[i].zName) ){ + if( pPk==0 && sqlite3IsRowid(pChanges->a[i].zEName) ){ j = -1; chngRowid = 1; pRowidExpr = pChanges->a[i].pExpr; }else{ - sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName); + sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zEName); pParse->checkSchema = 1; goto update_cleanup; } @@ -342,6 +357,33 @@ void sqlite3Update( assert( chngPk==0 || chngPk==1 ); chngKey = chngRowid + chngPk; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + /* Mark generated columns as changing if their generator expressions + ** reference any changing column. The actual aXRef[] value for + ** generated expressions is not used, other than to check to see that it + ** is non-negative, so the value of aXRef[] for generated columns can be + ** set to any non-negative number. We use 99999 so that the value is + ** obvious when looking at aXRef[] in a symbolic debugger. + */ + if( pTab->tabFlags & TF_HasGenerated ){ + int bProgress; + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + do{ + bProgress = 0; + for(i=0; inCol; i++){ + if( aXRef[i]>=0 ) continue; + if( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 ) continue; + if( sqlite3ExprReferencesUpdatedColumn(pTab->aCol[i].pDflt, + aXRef, chngRowid) ){ + aXRef[i] = 99999; + bProgress = 1; + } + } + }while( bProgress ); + } +#endif + /* The SET expressions are not actually used inside the WHERE loop. ** So reset the colUsed mask. Unless this is a virtual table. In that ** case, set all bits of the colUsed mask (to ensure that the virtual @@ -386,9 +428,6 @@ void sqlite3Update( memset(aToOpen, 1, nIdx+1); } - /* Begin generating code. */ - v = sqlite3GetVdbe(pParse); - if( v==0 ) goto update_cleanup; if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); sqlite3BeginWriteOperation(pParse, pTrigger || hasFK, iDb); @@ -486,6 +525,7 @@ void sqlite3Update( pWInfo = 0; eOnePass = ONEPASS_SINGLE; sqlite3ExprIfFalse(pParse, pWhere, labelBreak, SQLITE_JUMPIFNULL); + bFinishSeek = 0; }else{ /* Begin the database scan. ** @@ -512,6 +552,7 @@ void sqlite3Update( ** strategy that uses an index for which one or more columns are being ** updated. */ eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); + bFinishSeek = sqlite3WhereUsesDeferredSeek(pWInfo); if( eOnePass!=ONEPASS_SINGLE ){ sqlite3MultiWrite(pParse); if( eOnePass==ONEPASS_MULTI ){ @@ -542,7 +583,8 @@ void sqlite3Update( ** is not required) and leave the PK fields in the array of registers. */ for(i=0; iaiColumn[i]>=0 ); - sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur,pPk->aiColumn[i],iPk+i); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, + pPk->aiColumn[i], iPk+i); } if( eOnePass ){ if( addrOpen ) sqlite3VdbeChangeToNoop(v, addrOpen); @@ -623,14 +665,16 @@ void sqlite3Update( pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError ); for(i=0; inCol; i++){ + u32 colFlags = pTab->aCol[i].colFlags; + k = sqlite3TableColumnToStorage(pTab, i) + regOld; if( oldmask==0xffffffff || (i<32 && (oldmask & MASKBIT32(i))!=0) - || (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0 + || (colFlags & COLFLAG_PRIMKEY)!=0 ){ testcase( oldmask!=0xffffffff && i==31 ); - sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regOld+i); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k); }else{ - sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i); + sqlite3VdbeAddOp2(v, OP_Null, 0, k); } } if( chngRowid==0 && pPk==0 ){ @@ -654,13 +698,15 @@ void sqlite3Update( newmask = sqlite3TriggerColmask( pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError ); - for(i=0; inCol; i++){ + for(i=0, k=regNew; inCol; i++, k++){ if( i==pTab->iPKey ){ - sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i); + sqlite3VdbeAddOp2(v, OP_Null, 0, k); + }else if( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)!=0 ){ + if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) k--; }else{ j = aXRef[i]; if( j>=0 ){ - sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i); + sqlite3ExprCode(pParse, pChanges->a[j].pExpr, k); }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i)) ){ /* This branch loads the value of a column that will not be changed ** into a register. This is done if there are no BEFORE triggers, or @@ -669,12 +715,20 @@ void sqlite3Update( */ testcase( i==31 ); testcase( i==32 ); - sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k); + bFinishSeek = 0; }else{ - sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i); + sqlite3VdbeAddOp2(v, OP_Null, 0, k); } } } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( pTab->tabFlags & TF_HasGenerated ){ + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + sqlite3ComputeGeneratedColumns(pParse, regNew, pTab); + } +#endif /* Fire any BEFORE UPDATE triggers. This happens before constraints are ** verified. One could argue that this is wrong. @@ -707,11 +761,20 @@ void sqlite3Update( ** BEFORE trigger runs. See test case trigger1-18.0 (added 2018-04-26) ** for an example. */ - for(i=0; inCol; i++){ - if( aXRef[i]<0 && i!=pTab->iPKey ){ - sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i); + for(i=0, k=regNew; inCol; i++, k++){ + if( pTab->aCol[i].colFlags & COLFLAG_GENERATED ){ + if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) k--; + }else if( aXRef[i]<0 && i!=pTab->iPKey ){ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k); } } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( pTab->tabFlags & TF_HasGenerated ){ + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + sqlite3ComputeGeneratedColumns(pParse, regNew, pTab); + } +#endif } if( !isView ){ @@ -741,6 +804,15 @@ void sqlite3Update( /* Delete the index entries associated with the current record. */ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1); + /* We must run the OP_FinishSeek opcode to resolve a prior + ** OP_DeferredSeek if there is any possibility that there have been + ** no OP_Column opcodes since the OP_DeferredSeek was issued. But + ** we want to avoid the OP_FinishSeek if possible, as running it + ** costs CPU cycles. */ + if( bFinishSeek ){ + sqlite3VdbeAddOp1(v, OP_FinishSeek, iDataCur); + } + /* If changing the rowid value, or if there are foreign key constraints ** to process, delete the old record. Otherwise, add a noop OP_Delete ** to invoke the pre-update hook. @@ -917,6 +989,7 @@ static void updateVirtualTable( /* Populate the argument registers. */ for(i=0; inCol; i++){ + assert( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 ); if( aXRef[i]>=0 ){ sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i); }else{ diff --git a/src/upsert.c b/src/upsert.c index 7beb9ffa..9a33f75d 100644 --- a/src/upsert.c +++ b/src/upsert.c @@ -226,7 +226,7 @@ void sqlite3UpsertDoUpdate( for(i=0; iaiColumn[i]>=0 ); - k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]); + k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); sqlite3VdbeAddOp3(v, OP_Column, iCur, k, iPk+i); VdbeComment((v, "%s.%s", pIdx->zName, pTab->aCol[pPk->aiColumn[i]].zName)); @@ -236,6 +236,7 @@ void sqlite3UpsertDoUpdate( VdbeCoverage(v); sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CORRUPT, OE_Abort, 0, "corrupt database", P4_STATIC); + sqlite3MayAbort(pParse); sqlite3VdbeJumpHere(v, i); } } diff --git a/src/utf.c b/src/utf.c index 9191ed5c..f5fb3ef3 100644 --- a/src/utf.c +++ b/src/utf.c @@ -215,9 +215,11 @@ SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ #if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG) { - char zBuf[100]; - sqlite3VdbeMemPrettyPrint(pMem, zBuf); - fprintf(stderr, "INPUT: %s\n", zBuf); + StrAccum acc; + char zBuf[1000]; + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3VdbeMemPrettyPrint(pMem, &acc); + fprintf(stderr, "INPUT: %s\n", sqlite3StrAccumFinish(&acc)); } #endif @@ -325,9 +327,11 @@ SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ translate_out: #if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG) { - char zBuf[100]; - sqlite3VdbeMemPrettyPrint(pMem, zBuf); - fprintf(stderr, "OUTPUT: %s\n", zBuf); + StrAccum acc; + char zBuf[1000]; + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3VdbeMemPrettyPrint(pMem, &acc); + fprintf(stderr, "OUTPUT: %s\n", sqlite3StrAccumFinish(&acc)); } #endif return SQLITE_OK; diff --git a/src/util.c b/src/util.c index 7adce4ef..3e3a9244 100644 --- a/src/util.c +++ b/src/util.c @@ -17,7 +17,9 @@ */ #include "sqliteInt.h" #include +#ifndef SQLITE_OMIT_FLOATING_POINT #include +#endif /* ** Routine needed to support the testcase() macro. @@ -192,6 +194,7 @@ void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ sqlite3DbFree(db, pParse->zErrMsg); pParse->zErrMsg = zMsg; pParse->rc = SQLITE_ERROR; + pParse->pWith = 0; } } @@ -382,10 +385,13 @@ static LONGDOUBLE_TYPE sqlite3Pow10(int E){ ** returns FALSE but it still converts the prefix and writes the result ** into *pResult. */ +#if defined(_MSC_VER) +#pragma warning(disable : 4756) +#endif int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ #ifndef SQLITE_OMIT_FLOATING_POINT int incr; - const char *zEnd = z + length; + const char *zEnd; /* sign * significand * (10 ^ (esign * exponent)) */ int sign = 1; /* sign of significand */ i64 s = 0; /* significand */ @@ -399,12 +405,15 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); *pResult = 0.0; /* Default return value, in case of an error */ + if( length==0 ) return 0; if( enc==SQLITE_UTF8 ){ incr = 1; + zEnd = z + length; }else{ int i; incr = 2; + length &= ~1; assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); testcase( enc==SQLITE_UTF16LE ); testcase( enc==SQLITE_UTF16BE ); @@ -569,6 +578,9 @@ do_atof_calc: return !sqlite3Atoi64(z, pResult, length, enc); #endif /* SQLITE_OMIT_FLOATING_POINT */ } +#if defined(_MSC_VER) +#pragma warning(default : 4756) +#endif /* ** Compare the 19-character string zNum against the text representation diff --git a/src/vdbe.c b/src/vdbe.c index 777582b9..b9d2d125 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -117,6 +117,26 @@ int sqlite3_found_count = 0; # define UPDATE_MAX_BLOBSIZE(P) #endif +#ifdef SQLITE_DEBUG +/* This routine provides a convenient place to set a breakpoint during +** tracing with PRAGMA vdbe_trace=on. The breakpoint fires right after +** each opcode is printed. Variables "pc" (program counter) and pOp are +** available to add conditionals to the breakpoint. GDB example: +** +** break test_trace_breakpoint if pc=22 +** +** Other useful labels for breakpoints include: +** test_addop_breakpoint(pc,pOp) +** sqlite3CorruptError(lineno) +** sqlite3MisuseError(lineno) +** sqlite3CantopenError(lineno) +*/ +static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ + static int n = 0; + n++; +} +#endif + /* ** Invoke the VDBE coverage callback, if that callback is defined. This ** feature is used for test suite validation only and does not appear an @@ -461,12 +481,9 @@ static u16 numericType(Mem *pMem){ ** Write a nice string representation of the contents of cell pMem ** into buffer zBuf, length nBuf. */ -void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){ - char *zCsr = zBuf; +void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr){ int f = pMem->flags; - static const char *const encnames[] = {"(X)", "(8)", "(16LE)", "(16BE)"}; - if( f&MEM_Blob ){ int i; char c; @@ -482,57 +499,40 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){ }else{ c = 's'; } - *(zCsr++) = c; - *(zCsr++) = 'x'; - sqlite3_snprintf(100, zCsr, "%d[", pMem->n); - zCsr += sqlite3Strlen30(zCsr); + sqlite3_str_appendf(pStr, "%cx[", c); for(i=0; i<25 && in; i++){ - sqlite3_snprintf(100, zCsr, "%02X", ((int)pMem->z[i] & 0xFF)); - zCsr += sqlite3Strlen30(zCsr); + sqlite3_str_appendf(pStr, "%02X", ((int)pMem->z[i] & 0xFF)); } - *zCsr++ = '|'; + sqlite3_str_appendf(pStr, "|"); for(i=0; i<25 && in; i++){ char z = pMem->z[i]; - if( z<32 || z>126 ) *zCsr++ = '.'; - else *zCsr++ = z; + sqlite3_str_appendchar(pStr, 1, (z<32||z>126)?'.':z); } - *(zCsr++) = ']'; + sqlite3_str_appendf(pStr,"]"); if( f & MEM_Zero ){ - sqlite3_snprintf(100, zCsr,"+%dz",pMem->u.nZero); - zCsr += sqlite3Strlen30(zCsr); + sqlite3_str_appendf(pStr, "+%dz",pMem->u.nZero); } - *zCsr = '\0'; }else if( f & MEM_Str ){ - int j, k; - zBuf[0] = ' '; + int j; + u8 c; if( f & MEM_Dyn ){ - zBuf[1] = 'z'; + c = 'z'; assert( (f & (MEM_Static|MEM_Ephem))==0 ); }else if( f & MEM_Static ){ - zBuf[1] = 't'; + c = 't'; assert( (f & (MEM_Dyn|MEM_Ephem))==0 ); }else if( f & MEM_Ephem ){ - zBuf[1] = 'e'; + c = 'e'; assert( (f & (MEM_Static|MEM_Dyn))==0 ); }else{ - zBuf[1] = 's'; + c = 's'; } - k = 2; - sqlite3_snprintf(100, &zBuf[k], "%d", pMem->n); - k += sqlite3Strlen30(&zBuf[k]); - zBuf[k++] = '['; + sqlite3_str_appendf(pStr, " %c%d[", c, pMem->n); for(j=0; j<25 && jn; j++){ - u8 c = pMem->z[j]; - if( c>=0x20 && c<0x7f ){ - zBuf[k++] = c; - }else{ - zBuf[k++] = '.'; - } + c = pMem->z[j]; + sqlite3_str_appendchar(pStr, 1, (c>=0x20&&c<=0x7f) ? c : '.'); } - zBuf[k++] = ']'; - sqlite3_snprintf(100,&zBuf[k], encnames[pMem->enc]); - k += sqlite3Strlen30(&zBuf[k]); - zBuf[k++] = 0; + sqlite3_str_appendf(pStr, "]%s", encnames[pMem->enc]); } } #endif @@ -559,20 +559,37 @@ static void memTracePrint(Mem *p){ }else if( sqlite3VdbeMemIsRowSet(p) ){ printf(" (rowset)"); }else{ - char zBuf[200]; - sqlite3VdbeMemPrettyPrint(p, zBuf); - printf(" %s", zBuf); + StrAccum acc; + char zBuf[1000]; + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3VdbeMemPrettyPrint(p, &acc); + printf(" %s", sqlite3StrAccumFinish(&acc)); } if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype); } static void registerTrace(int iReg, Mem *p){ - printf("REG[%d] = ", iReg); + printf("R[%d] = ", iReg); memTracePrint(p); + if( p->pScopyFrom ){ + printf(" <== R[%d]", (int)(p->pScopyFrom - &p[-iReg])); + } printf("\n"); sqlite3VdbeCheckMemInvariants(p); } #endif +#ifdef SQLITE_DEBUG +/* +** Show the values of all registers in the virtual machine. Used for +** interactive debugging. +*/ +void sqlite3VdbeRegisterDump(Vdbe *v){ + int i; + for(i=1; inMem; i++) registerTrace(i, v->aMem+i); +} +#endif /* SQLITE_DEBUG */ + + #ifdef SQLITE_DEBUG # define REGISTER_TRACE(R,M) if(db->flags&SQLITE_VdbeTrace)registerTrace(R,M) #else @@ -738,6 +755,7 @@ int sqlite3VdbeExec( #ifdef SQLITE_DEBUG if( db->flags & SQLITE_VdbeTrace ){ sqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp); + test_trace_breakpoint((int)(pOp - aOp),pOp,p); } #endif @@ -845,6 +863,20 @@ int sqlite3VdbeExec( ** to the current line should be indented for EXPLAIN output. */ case OP_Goto: { /* jump */ + +#ifdef SQLITE_DEBUG + /* In debuggging mode, when the p5 flags is set on an OP_Goto, that + ** means we should really jump back to the preceeding OP_ReleaseReg + ** instruction. */ + if( pOp->p5 ){ + assert( pOp->p2 < (int)(pOp - aOp) ); + assert( pOp->p2 > 1 ); + pOp = &aOp[pOp->p2 - 2]; + assert( pOp[1].opcode==OP_ReleaseReg ); + goto check_for_interrupt; + } +#endif + jump_to_p2_and_check_for_interrupt: pOp = &aOp[pOp->p2 - 1]; @@ -1321,8 +1353,13 @@ case OP_Move: { memAboutToChange(p, pOut); sqlite3VdbeMemMove(pOut, pIn1); #ifdef SQLITE_DEBUG - if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrompScopyFrom += pOp->p2 - p1; + pIn1->pScopyFrom = 0; + { int i; + for(i=1; inMem; i++){ + if( aMem[i].pScopyFrom==pIn1 ){ + aMem[i].pScopyFrom = pOut; + } + } } #endif Deephemeralize(pOut); @@ -1463,6 +1500,14 @@ case OP_ResultRow: { || (pMem[i].flags & (MEM_Str|MEM_Blob))==0 ); sqlite3VdbeMemNulTerminate(&pMem[i]); REGISTER_TRACE(pOp->p1+i, &pMem[i]); +#ifdef SQLITE_DEBUG + /* The registers in the result will not be used again when the + ** prepared statement restarts. This is because sqlite3_column() + ** APIs might have caused type conversions of made other changes to + ** the register values. Therefore, we can go ahead and break any + ** OP_SCopy dependencies. */ + pMem[i].pScopyFrom = 0; +#endif } if( db->mallocFailed ) goto no_mem; @@ -1470,6 +1515,7 @@ case OP_ResultRow: { db->xTrace(SQLITE_TRACE_ROW, db->pTraceArg, p, 0); } + /* Return SQLITE_ROW */ p->pc = (int)(pOp - aOp) + 1; @@ -1866,9 +1912,11 @@ case OP_Cast: { /* in1 */ pIn1 = &aMem[pOp->p1]; memAboutToChange(p, pIn1); rc = ExpandBlob(pIn1); - sqlite3VdbeMemCast(pIn1, pOp->p2, encoding); - UPDATE_MAX_BLOBSIZE(pIn1); if( rc ) goto abort_due_to_error; + rc = sqlite3VdbeMemCast(pIn1, pOp->p2, encoding); + if( rc ) goto abort_due_to_error; + UPDATE_MAX_BLOBSIZE(pIn1); + REGISTER_TRACE(pOp->p1, pIn1); break; } #endif /* SQLITE_OMIT_CAST */ @@ -2027,12 +2075,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ if( (flags1 | flags3)&MEM_Str ){ if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn1,0); - assert( flags3==pIn3->flags ); - /* testcase( flags3!=pIn3->flags ); - ** this used to be possible with pIn1==pIn3, but not since - ** the column cache was removed. The following assignment - ** is essentially a no-op. But, it provides defense-in-depth - ** in case our analysis is incorrect, so it is left in. */ + testcase( flags3!=pIn3->flags ); flags3 = pIn3->flags; } if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ @@ -2055,7 +2098,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ sqlite3VdbeMemStringify(pIn1, encoding, 1); testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); - assert( pIn1!=pIn3 ); + if( pIn1==pIn3 ) flags3 = flags1 | MEM_Str; } if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ testcase( pIn3->flags & MEM_Int ); @@ -2090,10 +2133,10 @@ compare_op: } /* Undo any changes made by applyAffinity() to the input registers. */ - assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) ); - pIn1->flags = flags1; assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) ); pIn3->flags = flags3; + assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) ); + pIn1->flags = flags1; if( pOp->p5 & SQLITE_STOREP2 ){ pOut = &aMem[pOp->p2]; @@ -2129,16 +2172,31 @@ compare_op: /* Opcode: ElseNotEq * P2 * * * ** -** This opcode must immediately follow an OP_Lt or OP_Gt comparison operator. -** If result of an OP_Eq comparison on the same two operands -** would have be NULL or false (0), then then jump to P2. -** If the result of an OP_Eq comparison on the two previous operands -** would have been true (1), then fall through. +** This opcode must follow an OP_Lt or OP_Gt comparison operator. There +** can be zero or more OP_ReleaseReg opcodes intervening, but no other +** opcodes are allowed to occur between this instruction and the previous +** OP_Lt or OP_Gt. Furthermore, the prior OP_Lt or OP_Gt must have the +** SQLITE_STOREP2 bit set in the P5 field. +** +** If result of an OP_Eq comparison on the same two operands as the +** prior OP_Lt or OP_Gt would have been NULL or false (0), then then +** jump to P2. If the result of an OP_Eq comparison on the two previous +** operands would have been true (1), then fall through. */ case OP_ElseNotEq: { /* same as TK_ESCAPE, jump */ - assert( pOp>aOp ); - assert( pOp[-1].opcode==OP_Lt || pOp[-1].opcode==OP_Gt ); - assert( pOp[-1].p5 & SQLITE_STOREP2 ); + +#ifdef SQLITE_DEBUG + /* Verify the preconditions of this opcode - that it follows an OP_Lt or + ** OP_Gt with the SQLITE_STOREP2 flag set, with zero or more intervening + ** OP_ReleaseReg opcodes */ + int iAddr; + for(iAddr = (int)(pOp - aOp) - 1; ALWAYS(iAddr>=0); iAddr--){ + if( aOp[iAddr].opcode==OP_ReleaseReg ) continue; + assert( aOp[iAddr].opcode==OP_Lt || aOp[iAddr].opcode==OP_Gt ); + assert( aOp[iAddr].p5 & SQLITE_STOREP2 ); + break; + } +#endif /* SQLITE_DEBUG */ VdbeBranchTaken(iCompare!=0, 2); if( iCompare!=0 ) goto jump_to_p2; break; @@ -2549,7 +2607,9 @@ case OP_Column: { u32 t; /* A type code from the record header */ Mem *pReg; /* PseudoTable input register */ + assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); p2 = pOp->p2; /* If the cursor cache is stale (meaning it is not currently point at @@ -2561,7 +2621,6 @@ case OP_Column: { assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); pDest = &aMem[pOp->p3]; memAboutToChange(p, pDest); - assert( pOp->p1>=0 && pOp->p1nCursor ); assert( pC!=0 ); assert( p2nField ); aOffset = pC->aOffset; @@ -2772,10 +2831,11 @@ case OP_Column: { ** ** Although sqlite3VdbeSerialGet() may read at most 8 bytes from the ** buffer passed to it, debugging function VdbeMemPrettyPrint() may - ** read up to 16. So 16 bytes of bogus content is supplied. + ** read more. Use the global constant sqlite3CtypeMap[] as the array, + ** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint()) + ** and it begins with a bunch of zeros. */ - static u8 aZero[16]; /* This is the bogus content */ - sqlite3VdbeSerialGet(aZero, t, pDest); + sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest); }else{ rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest); if( rc!=SQLITE_OK ) goto abort_due_to_error; @@ -2818,7 +2878,7 @@ case OP_Affinity: { pIn1 = &aMem[pOp->p1]; while( 1 /*exit-by-break*/ ){ assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] ); - assert( memIsValid(pIn1) ); + assert( zAffinity[0]==SQLITE_AFF_NONE || memIsValid(pIn1) ); applyAffinity(pIn1, zAffinity[0], encoding); if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){ /* When applying REAL affinity, if the result is still an MEM_Int @@ -3143,11 +3203,11 @@ case OP_Count: { /* out2 */ pCrsr = p->apCsr[pOp->p1]->uc.pCursor; assert( pCrsr ); nEntry = 0; /* Not needed. Only used to silence a warning. */ - rc = sqlite3BtreeCount(pCrsr, &nEntry); + rc = sqlite3BtreeCount(db, pCrsr, &nEntry); if( rc ) goto abort_due_to_error; pOut = out2Prerelease(p, pOp); pOut->u.i = nEntry; - break; + goto check_for_interrupt; } #endif @@ -3264,8 +3324,12 @@ case OP_Savepoint: { p->rc = rc = SQLITE_BUSY; goto vdbe_return; } - db->isTransactionSavepoint = 0; rc = p->rc; + if( rc ){ + db->autoCommit = 0; + }else{ + db->isTransactionSavepoint = 0; + } }else{ int isSchemaChange; iSavepoint = db->nSavepoint - iSavepoint - 1; @@ -3293,6 +3357,7 @@ case OP_Savepoint: { db->mDbFlags |= DBFLAG_SchemaChange; } } + if( rc ) goto abort_due_to_error; /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all ** savepoints nested inside of the savepoint being operated on. */ @@ -3375,7 +3440,6 @@ case OP_AutoCommit: { p->rc = rc = SQLITE_BUSY; goto vdbe_return; } - assert( db->nStatement==0 ); sqlite3CloseSavepoints(db); if( p->rc==SQLITE_OK ){ rc = SQLITE_DONE; @@ -3456,7 +3520,8 @@ case OP_Transaction: { goto abort_due_to_error; } - if( pOp->p2 && p->usesStmtJournal + if( p->usesStmtJournal + && pOp->p2 && (db->autoCommit==0 || db->nVdbeRead>1) ){ assert( sqlite3BtreeIsInTrans(pBt) ); @@ -3788,6 +3853,7 @@ case OP_OpenDup: { VdbeCursor *pCx; /* The new cursor */ pOrig = p->apCsr[pOp->p2]; + assert( pOrig ); assert( pOrig->pBtx!=0 ); /* Only ephemeral cursors can be duplicated */ pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE); @@ -3851,15 +3917,13 @@ case OP_OpenEphemeral: { assert( pOp->p1>=0 ); assert( pOp->p2>=0 ); pCx = p->apCsr[pOp->p1]; - if( pCx ){ + if( pCx && pCx->pBtx ){ /* If the ephermeral table is already open, erase all existing content ** so that the table is empty again, rather than creating a new table. */ assert( pCx->isEphemeral ); pCx->seqCount = 0; pCx->cacheStatus = CACHE_STALE; - if( pCx->pBtx ){ - rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0); - } + rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0); }else{ pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE); if( pCx==0 ) goto no_mem; @@ -4291,7 +4355,7 @@ seek_not_found: ** Synopsis: seekHit=P2 ** ** Set the seekHit flag on cursor P1 to the value in P2. -** The seekHit flag is used by the IfNoHope opcode. +* The seekHit flag is used by the IfNoHope opcode. ** ** P1 must be a valid b-tree cursor. P2 must be a boolean value, ** either 0 or 1. @@ -4306,6 +4370,20 @@ case OP_SeekHit: { break; } +/* Opcode: IfNotOpen P1 P2 * * * +** Synopsis: if( !csr[P1] ) goto P2 +** +** If cursor P1 is not open, jump to instruction P2. Otherwise, fall through. +*/ +case OP_IfNotOpen: { /* jump */ + assert( pOp->p1>=0 && pOp->p1nCursor ); + VdbeBranchTaken(p->apCsr[pOp->p1]==0, 2); + if( !p->apCsr[pOp->p1] ){ + goto jump_to_p2_and_check_for_interrupt; + } + break; +} + /* Opcode: Found P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** @@ -4794,6 +4872,7 @@ case OP_Insert: { pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->deferredMoveto==0 ); assert( pC->uc.pCursor!=0 ); assert( (pOp->p5 & OPFLAG_ISNOOP) || pC->isTable ); assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC ); @@ -4911,7 +4990,11 @@ case OP_Delete: { sqlite3VdbeIncrWriteCounter(p, pC); #ifdef SQLITE_DEBUG - if( pOp->p4type==P4_TABLE && HasRowid(pOp->p4.pTab) && pOp->p5==0 ){ + if( pOp->p4type==P4_TABLE + && HasRowid(pOp->p4.pTab) + && pOp->p5==0 + && sqlite3BtreeCursorIsValidNN(pC->uc.pCursor) + ){ /* If p5 is zero, the seek operation that positioned the cursor prior to ** OP_Delete will have also set the pC->movetoTarget field to the rowid of ** the row that is being deleted */ @@ -5667,6 +5750,24 @@ case OP_IdxRowid: { /* out2 */ break; } +/* Opcode: FinishSeek P1 * * * * +** +** If cursor P1 was previously moved via OP_DeferredSeek, complete that +** seek operation now, without further delay. If the cursor seek has +** already occurred, this instruction is a no-op. +*/ +case OP_FinishSeek: { + VdbeCursor *pC; /* The P1 index cursor */ + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + if( pC->deferredMoveto ){ + rc = sqlite3VdbeFinishMoveto(pC); + if( rc ) goto abort_due_to_error; + } + break; +} + /* Opcode: IdxGE P1 P2 P3 P4 P5 ** Synopsis: key=r[P3@P4] ** @@ -6103,7 +6204,7 @@ case OP_IntegrityCk: { pIn1 = &aMem[pOp->p1]; assert( pOp->p5nDb ); assert( DbMaskTest(p->btreeMask, pOp->p5) ); - z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, &aRoot[1], nRoot, + z = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot, (int)pnErr->u.i+1, &nErr); sqlite3VdbeMemSetNull(pIn1); if( nErr==0 ){ @@ -6116,7 +6217,7 @@ case OP_IntegrityCk: { } UPDATE_MAX_BLOBSIZE(pIn1); sqlite3VdbeChangeEncoding(pIn1, encoding); - break; + goto check_for_interrupt; } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ @@ -6973,6 +7074,36 @@ case OP_Expire: { break; } +/* Opcode: CursorLock P1 * * * * +** +** Lock the btree to which cursor P1 is pointing so that the btree cannot be +** written by an other cursor. +*/ +case OP_CursorLock: { + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + sqlite3BtreeCursorPin(pC->uc.pCursor); + break; +} + +/* Opcode: CursorUnlock P1 * * * * +** +** Unlock the btree to which cursor P1 is pointing so that it can be +** written by other cursors. +*/ +case OP_CursorUnlock: { + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + sqlite3BtreeCursorUnpin(pC->uc.pCursor); + break; +} + #ifndef SQLITE_OMIT_SHARED_CACHE /* Opcode: TableLock P1 P2 P3 P4 * ** Synopsis: iDb=P1 root=P2 write=P3 @@ -7217,7 +7348,7 @@ case OP_VColumn: { assert( pModule->xColumn ); memset(&sContext, 0, sizeof(sContext)); sContext.pOut = pDest; - testcase( (pOp->p5 & OPFLAG_NOCHNG)==0 && pOp->p5!=0 ); + assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 ); if( pOp->p5 & OPFLAG_NOCHNG ){ sqlite3VdbeMemSetNull(pDest); pDest->flags = MEM_Null|MEM_Zero; @@ -7442,29 +7573,14 @@ case OP_MaxPgcnt: { /* out2 */ } #endif -/* Opcode: Function0 P1 P2 P3 P4 P5 -** Synopsis: r[P3]=func(r[P2@P5]) -** -** Invoke a user function (P4 is a pointer to a FuncDef object that -** defines the function) with P5 arguments taken from register P2 and -** successors. The result of the function is stored in register P3. -** Register P3 must not be one of the function inputs. -** -** P1 is a 32-bit bitmask indicating whether or not each argument to the -** function was determined to be constant at compile time. If the first -** argument was constant then bit 0 of P1 is set. This is used to determine -** whether meta data associated with a user function argument using the -** sqlite3_set_auxdata() API may be safely retained until the next -** invocation of this opcode. -** -** See also: Function, AggStep, AggFinal -*/ -/* Opcode: Function P1 P2 P3 P4 P5 +/* Opcode: Function P1 P2 P3 P4 * ** Synopsis: r[P3]=func(r[P2@P5]) ** ** Invoke a user function (P4 is a pointer to an sqlite3_context object that -** contains a pointer to the function to be run) with P5 arguments taken -** from register P2 and successors. The result of the function is stored +** contains a pointer to the function to be run) with arguments taken +** from register P2 and successors. The number of arguments is in +** the sqlite3_context object that P4 points to. +** The result of the function is stored ** in register P3. Register P3 must not be one of the function inputs. ** ** P1 is a 32-bit bitmask indicating whether or not each argument to the @@ -7474,40 +7590,35 @@ case OP_MaxPgcnt: { /* out2 */ ** sqlite3_set_auxdata() API may be safely retained until the next ** invocation of this opcode. ** -** SQL functions are initially coded as OP_Function0 with P4 pointing -** to a FuncDef object. But on first evaluation, the P4 operand is -** automatically converted into an sqlite3_context object and the operation -** changed to this OP_Function opcode. In this way, the initialization of -** the sqlite3_context object occurs only once, rather than once for each -** evaluation of the function. -** -** See also: Function0, AggStep, AggFinal +** See also: AggStep, AggFinal, PureFunc +*/ +/* Opcode: PureFunc P1 P2 P3 P4 * +** Synopsis: r[P3]=func(r[P2@P5]) +** +** Invoke a user function (P4 is a pointer to an sqlite3_context object that +** contains a pointer to the function to be run) with arguments taken +** from register P2 and successors. The number of arguments is in +** the sqlite3_context object that P4 points to. +** The result of the function is stored +** in register P3. Register P3 must not be one of the function inputs. +** +** P1 is a 32-bit bitmask indicating whether or not each argument to the +** function was determined to be constant at compile time. If the first +** argument was constant then bit 0 of P1 is set. This is used to determine +** whether meta data associated with a user function argument using the +** sqlite3_set_auxdata() API may be safely retained until the next +** invocation of this opcode. +** +** This opcode works exactly like OP_Function. The only difference is in +** its name. This opcode is used in places where the function must be +** purely non-deterministic. Some built-in date/time functions can be +** either determinitic of non-deterministic, depending on their arguments. +** When those function are used in a non-deterministic way, they will check +** to see if they were called using OP_PureFunc instead of OP_Function, and +** if they were, they throw an error. +** +** See also: AggStep, AggFinal, Function */ -case OP_PureFunc0: /* group */ -case OP_Function0: { /* group */ - int n; - sqlite3_context *pCtx; - - assert( pOp->p4type==P4_FUNCDEF ); - n = pOp->p5; - assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); - assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); - assert( pOp->p3p2 || pOp->p3>=pOp->p2+n ); - pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); - if( pCtx==0 ) goto no_mem; - pCtx->pOut = 0; - pCtx->pFunc = pOp->p4.pFunc; - pCtx->iOp = (int)(pOp - aOp); - pCtx->pVdbe = p; - pCtx->isError = 0; - pCtx->argc = n; - pOp->p4type = P4_FUNCCTX; - pOp->p4.pCtx = pCtx; - assert( OP_PureFunc == OP_PureFunc0+2 ); - assert( OP_Function == OP_Function0+2 ); - pOp->opcode += 2; - /* Fall through into OP_Function */ -} case OP_PureFunc: /* group */ case OP_Function: { /* group */ int i; @@ -7522,9 +7633,11 @@ case OP_Function: { /* group */ ** reinitializes the relavant parts of the sqlite3_context object */ pOut = &aMem[pOp->p3]; if( pCtx->pOut != pOut ){ + pCtx->pVdbe = p; pCtx->pOut = pOut; for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i]; } + assert( pCtx->pVdbe==p ); memAboutToChange(p, pOut); #ifdef SQLITE_DEBUG @@ -7696,6 +7809,55 @@ case OP_Abortable: { } #endif +#ifdef SQLITE_DEBUG +/* Opcode: ReleaseReg P1 P2 P3 * P5 +** Synopsis: release r[P1@P2] mask P3 +** +** Release registers from service. Any content that was in the +** the registers is unreliable after this opcode completes. +** +** The registers released will be the P2 registers starting at P1, +** except if bit ii of P3 set, then do not release register P1+ii. +** In other words, P3 is a mask of registers to preserve. +** +** Releasing a register clears the Mem.pScopyFrom pointer. That means +** that if the content of the released register was set using OP_SCopy, +** a change to the value of the source register for the OP_SCopy will no longer +** generate an assertion fault in sqlite3VdbeMemAboutToChange(). +** +** If P5 is set, then all released registers have their type set +** to MEM_Undefined so that any subsequent attempt to read the released +** register (before it is reinitialized) will generate an assertion fault. +** +** P5 ought to be set on every call to this opcode. +** However, there are places in the code generator will release registers +** before their are used, under the (valid) assumption that the registers +** will not be reallocated for some other purpose before they are used and +** hence are safe to release. +** +** This opcode is only available in testing and debugging builds. It is +** not generated for release builds. The purpose of this opcode is to help +** validate the generated bytecode. This opcode does not actually contribute +** to computing an answer. +*/ +case OP_ReleaseReg: { + Mem *pMem; + int i; + u32 constMask; + assert( pOp->p1>0 ); + assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); + pMem = &aMem[pOp->p1]; + constMask = pOp->p3; + for(i=0; ip2; i++, pMem++){ + if( i>=32 || (constMask & MASKBIT32(i))==0 ){ + pMem->pScopyFrom = 0; + if( i<32 && pOp->p5 ) MemSetTypeFlag(pMem, MEM_Undefined); + } + } + break; +} +#endif + /* Opcode: Noop * * * * * ** ** Do nothing. This instruction is often useful as a jump @@ -7747,6 +7909,12 @@ default: { /* This is really OP_Noop, OP_Explain */ if( opProperty & OPFLG_OUT3 ){ registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]); } + if( opProperty==0xff ){ + /* Never happens. This code exists to avoid a harmless linkage + ** warning aboud sqlite3VdbeRegisterDump() being defined but not + ** used. */ + sqlite3VdbeRegisterDump(p); + } } #endif /* SQLITE_DEBUG */ #endif /* NDEBUG */ diff --git a/src/vdbe.h b/src/vdbe.h index e3aaaa1c..bfde2587 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -179,6 +179,7 @@ typedef struct VdbeOpList VdbeOpList; ** for a description of what each of these routines does. */ Vdbe *sqlite3VdbeCreate(Parse*); +Parse *sqlite3VdbeParser(Vdbe*); int sqlite3VdbeAddOp0(Vdbe*,int); int sqlite3VdbeAddOp1(Vdbe*,int,int); int sqlite3VdbeAddOp2(Vdbe*,int,int,int); @@ -189,6 +190,7 @@ int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int); int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); +int sqlite3VdbeAddFunctionCall(Parse*,int,int,int,int,const FuncDef*,int); void sqlite3VdbeEndCoroutine(Vdbe*,int); #if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N); @@ -230,6 +232,11 @@ void sqlite3VdbeChangeP5(Vdbe*, u16 P5); void sqlite3VdbeJumpHere(Vdbe*, int addr); int sqlite3VdbeChangeToNoop(Vdbe*, int addr); int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op); +#ifdef SQLITE_DEBUG + void sqlite3VdbeReleaseRegisters(Parse*,int addr, int n, u32 mask, int); +#else +# define sqlite3VdbeReleaseRegisters(P,A,N,M,F) +#endif void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type); void sqlite3VdbeSetP4KeyInfo(Parse*, Index*); @@ -278,9 +285,8 @@ UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); -#ifndef SQLITE_OMIT_TRIGGER void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); -#endif +int sqlite3VdbeHasSubProgram(Vdbe*); int sqlite3NotPureFunc(sqlite3_context*); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index bd035535..9311591f 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -286,7 +286,8 @@ struct sqlite3_value { ** True if Mem X is a NULL-nochng type. */ #define MemNullNochng(X) \ - ((X)->flags==(MEM_Null|MEM_Zero) && (X)->n==0 && (X)->u.nZero==0) + (((X)->flags&MEM_TypeMask)==(MEM_Null|MEM_Zero) \ + && (X)->n==0 && (X)->u.nZero==0) /* ** Return true if a memory cell is not marked as invalid. This macro @@ -482,6 +483,7 @@ struct PreUpdate { void sqlite3VdbeError(Vdbe*, const char *, ...); void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); void sqliteVdbePopStack(Vdbe*,int); +int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*); int sqlite3VdbeCursorMoveto(VdbeCursor**, int*); int sqlite3VdbeCursorRestore(VdbeCursor*); u32 sqlite3VdbeSerialTypeLen(u32); @@ -528,7 +530,7 @@ int sqlite3VdbeBooleanValue(Mem*, int ifNull); void sqlite3VdbeIntegerAffinity(Mem*); int sqlite3VdbeMemRealify(Mem*); int sqlite3VdbeMemNumerify(Mem*); -void sqlite3VdbeMemCast(Mem*,u8,u8); +int sqlite3VdbeMemCast(Mem*,u8,u8); int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*); void sqlite3VdbeMemRelease(Mem *p); int sqlite3VdbeMemFinalize(Mem*, FuncDef*); @@ -594,7 +596,7 @@ int sqlite3VdbeCheckFk(Vdbe *, int); #ifdef SQLITE_DEBUG void sqlite3VdbePrintSql(Vdbe*); - void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf); + void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr); #endif #ifndef SQLITE_OMIT_UTF16 int sqlite3VdbeMemTranslate(Mem*, u8); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index c7968ee6..074d4588 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1831,7 +1831,7 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ goto preupdate_old_out; } if( p->pPk ){ - iIdx = sqlite3ColumnOfIndex(p->pPk, iIdx); + iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx); } if( iIdx>=p->pCsr->nField || iIdx<0 ){ rc = SQLITE_RANGE; @@ -1921,7 +1921,7 @@ int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ goto preupdate_new_out; } if( p->pPk && p->op!=SQLITE_UPDATE ){ - iIdx = sqlite3ColumnOfIndex(p->pPk, iIdx); + iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx); } if( iIdx>=p->pCsr->nField || iIdx<0 ){ rc = SQLITE_RANGE; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 039812c5..fab8b705 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -15,6 +15,10 @@ #include "sqliteInt.h" #include "vdbeInt.h" +/* Forward references */ +static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef); +static void vdbeFreeOpArray(sqlite3 *, Op *, int); + /* ** Create a new virtual database engine. */ @@ -42,6 +46,13 @@ Vdbe *sqlite3VdbeCreate(Parse *pParse){ return p; } +/* +** Return the Parse object that owns a Vdbe object. +*/ +Parse *sqlite3VdbeParser(Vdbe *p){ + return p->pParse; +} + /* ** Change the error string stored in Vdbe.zErrMsg */ @@ -122,7 +133,7 @@ void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ zTmp = pA->zSql; pA->zSql = pB->zSql; pB->zSql = zTmp; -#if 0 +#ifdef SQLITE_ENABLE_NORMALIZE zTmp = pA->zNormSql; pA->zNormSql = pB->zNormSql; pB->zNormSql = zTmp; @@ -183,9 +194,16 @@ static int growOpArray(Vdbe *v, int nOp){ #ifdef SQLITE_DEBUG /* This routine is just a convenient place to set a breakpoint that will ** fire after each opcode is inserted and displayed using -** "PRAGMA vdbe_addoptrace=on". +** "PRAGMA vdbe_addoptrace=on". Parameters "pc" (program counter) and +** pOp are available to make the breakpoint conditional. +** +** Other useful labels for breakpoints include: +** test_trace_breakpoint(pc,pOp) +** sqlite3CorruptError(lineno) +** sqlite3MisuseError(lineno) +** sqlite3CantopenError(lineno) */ -static void test_addop_breakpoint(void){ +static void test_addop_breakpoint(int pc, Op *pOp){ static int n = 0; n++; } @@ -238,7 +256,7 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ #ifdef SQLITE_DEBUG if( p->db->flags & SQLITE_VdbeAddopTrace ){ sqlite3VdbePrintOp(0, i, &p->aOp[i]); - test_addop_breakpoint(); + test_addop_breakpoint(i, &p->aOp[i]); } #endif #ifdef VDBE_PROFILE @@ -321,6 +339,49 @@ int sqlite3VdbeAddOp4( return addr; } +/* +** Add an OP_Function or OP_PureFunc opcode. +** +** The eCallCtx argument is information (typically taken from Expr.op2) +** that describes the calling context of the function. 0 means a general +** function call. NC_IsCheck means called by a check constraint, +** NC_IdxExpr means called as part of an index expression. NC_PartIdx +** means in the WHERE clause of a partial index. NC_GenCol means called +** while computing a generated column value. 0 is the usual case. +*/ +int sqlite3VdbeAddFunctionCall( + Parse *pParse, /* Parsing context */ + int p1, /* Constant argument mask */ + int p2, /* First argument register */ + int p3, /* Register into which results are written */ + int nArg, /* Number of argument */ + const FuncDef *pFunc, /* The function to be invoked */ + int eCallCtx /* Calling context */ +){ + Vdbe *v = pParse->pVdbe; + int nByte; + int addr; + sqlite3_context *pCtx; + assert( v ); + nByte = sizeof(*pCtx) + (nArg-1)*sizeof(sqlite3_value*); + pCtx = sqlite3DbMallocRawNN(pParse->db, nByte); + if( pCtx==0 ){ + assert( pParse->db->mallocFailed ); + freeEphemeralFunction(pParse->db, (FuncDef*)pFunc); + return 0; + } + pCtx->pOut = 0; + pCtx->pFunc = (FuncDef*)pFunc; + pCtx->pVdbe = 0; + pCtx->isError = 0; + pCtx->argc = nArg; + pCtx->iOp = sqlite3VdbeCurrentAddr(v); + addr = sqlite3VdbeAddOp4(v, eCallCtx ? OP_PureFunc : OP_Function, + p1, p2, p3, (char*)pCtx, P4_FUNCCTX); + sqlite3VdbeChangeP5(v, eCallCtx & NC_SelfRef); + return addr; +} + /* ** Add an opcode that includes the p4 value with a P4_INT64 or ** P4_REAL type. @@ -613,6 +674,7 @@ static Op *opIterNext(VdbeOpIter *p){ ** * OP_HaltIfNull with P1=SQLITE_CONSTRAINT and P2=OE_Abort. ** * OP_Destroy ** * OP_VUpdate +** * OP_VCreate ** * OP_VRename ** * OP_FkCounter with P2==0 (immediate foreign key constraint) ** * OP_CreateBtree/BTREE_INTKEY and OP_InitCoroutine @@ -640,6 +702,7 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ int opcode = pOp->opcode; if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename || opcode==OP_VDestroy + || opcode==OP_VCreate || (opcode==OP_ParseSchema && pOp->p4.z==0) || ((opcode==OP_Halt || opcode==OP_HaltIfNull) && ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort)) @@ -1013,8 +1076,6 @@ static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ } } -static void vdbeFreeOpArray(sqlite3 *, Op *, int); - /* ** Delete a P4 value if necessary. */ @@ -1024,7 +1085,7 @@ static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){ } static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){ freeEphemeralFunction(db, p->pFunc); - sqlite3DbFreeNN(db, p); + sqlite3DbFreeNN(db, p); } static void freeP4(sqlite3 *db, int p4type, void *p4){ assert( db ); @@ -1098,6 +1159,13 @@ void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){ pVdbe->pProgram = p; } +/* +** Return true if the given Vdbe has any SubPrograms. +*/ +int sqlite3VdbeHasSubProgram(Vdbe *pVdbe){ + return pVdbe->pProgram!=0; +} + /* ** Change the opcode at addr into OP_Noop */ @@ -1125,6 +1193,41 @@ int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){ } } +#ifdef SQLITE_DEBUG +/* +** Generate an OP_ReleaseReg opcode to indicate that a range of +** registers, except any identified by mask, are no longer in use. +*/ +void sqlite3VdbeReleaseRegisters( + Parse *pParse, /* Parsing context */ + int iFirst, /* Index of first register to be released */ + int N, /* Number of registers to release */ + u32 mask, /* Mask of registers to NOT release */ + int bUndefine /* If true, mark registers as undefined */ +){ + if( N==0 ) return; + assert( pParse->pVdbe ); + assert( iFirst>=1 ); + assert( iFirst+N-1<=pParse->nMem ); + if( N<=31 && mask!=0 ){ + while( N>0 && (mask&1)!=0 ){ + mask >>= 1; + iFirst++; + N--; + } + while( N>0 && N<=32 && (mask & MASKBIT32(N-1))!=0 ){ + mask &= ~MASKBIT32(N-1); + N--; + } + } + if( N>0 ){ + sqlite3VdbeAddOp3(pParse->pVdbe, OP_ReleaseReg, iFirst, N, *(int*)&mask); + if( bUndefine ) sqlite3VdbeChangeP5(pParse->pVdbe, 1); + } +} +#endif /* SQLITE_DEBUG */ + + /* ** Change the value of the P4 operand for a specific instruction. ** This routine is useful when a large program is loaded from a @@ -1242,7 +1345,8 @@ void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){ */ static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){ assert( p->nOp>0 || p->aOp==0 ); - assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed ); + assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed + || p->pParse->nErr>0 ); if( p->nOp ){ assert( p->aOp ); sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment); @@ -1523,13 +1627,11 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg); break; } -#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) case P4_FUNCCTX: { FuncDef *pDef = pOp->p4.pCtx->pFunc; sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg); break; } -#endif case P4_INT64: { sqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64); break; @@ -2223,8 +2325,26 @@ void sqlite3VdbeMakeReady( resolveP2Values(p, &nArg); p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); - if( pParse->explain && nMem<10 ){ - nMem = 10; + if( pParse->explain ){ + static const char * const azColName[] = { + "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", + "id", "parent", "notused", "detail" + }; + int iFirst, mx, i; + if( nMem<10 ) nMem = 10; + if( pParse->explain==2 ){ + sqlite3VdbeSetNumCols(p, 4); + iFirst = 8; + mx = 12; + }else{ + sqlite3VdbeSetNumCols(p, 8); + iFirst = 0; + mx = 8; + } + for(i=iFirst; iexpired = 0; @@ -2574,7 +2694,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ /* Select a master journal file name */ nMainFile = sqlite3Strlen30(zMainFile); - zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz", zMainFile); + zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz%c%c", zMainFile, 0, 0); if( zMaster==0 ) return SQLITE_NOMEM_BKPT; do { u32 iRandom; @@ -3313,7 +3433,7 @@ void sqlite3VdbeDelete(Vdbe *p){ ** carried out. Seek the cursor now. If an error occurs, return ** the appropriate error code. */ -static int SQLITE_NOINLINE handleDeferredMoveto(VdbeCursor *p){ +int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor *p){ int res, rc; #ifdef SQLITE_TEST extern int sqlite3_search_count; @@ -3385,7 +3505,7 @@ int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){ *piCol = iMap - 1; return SQLITE_OK; } - return handleDeferredMoveto(p); + return sqlite3VdbeFinishMoveto(p); } if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ return handleMovedCursor(p); @@ -4925,13 +5045,25 @@ void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ ** features such as 'now'. */ int sqlite3NotPureFunc(sqlite3_context *pCtx){ + const VdbeOp *pOp; #ifdef SQLITE_ENABLE_STAT4 if( pCtx->pVdbe==0 ) return 1; #endif - if( pCtx->pVdbe->aOp[pCtx->iOp].opcode==OP_PureFunc ){ - sqlite3_result_error(pCtx, - "non-deterministic function in index expression or CHECK constraint", - -1); + pOp = pCtx->pVdbe->aOp + pCtx->iOp; + if( pOp->opcode==OP_PureFunc ){ + const char *zContext; + char *zMsg; + if( pOp->p5 & NC_IsCheck ){ + zContext = "a CHECK constraint"; + }else if( pOp->p5 & NC_GenCol ){ + zContext = "a generated column"; + }else{ + zContext = "an index"; + } + zMsg = sqlite3_mprintf("non-deterministic use of %s() in %s", + pCtx->pFunc->zName, zContext); + sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_free(zMsg); return 0; } return 1; diff --git a/src/vdbemem.c b/src/vdbemem.c index 820789fb..ddb6b2c1 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -460,15 +460,11 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ #ifndef SQLITE_OMIT_WINDOWFUNC int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){ sqlite3_context ctx; - Mem t; assert( pFunc!=0 ); assert( pFunc->xValue!=0 ); assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef ); assert( pAccum->db==0 || sqlite3_mutex_held(pAccum->db->mutex) ); memset(&ctx, 0, sizeof(ctx)); - memset(&t, 0, sizeof(t)); - t.flags = MEM_Null; - t.db = pAccum->db; sqlite3VdbeMemSetNull(pOut); ctx.pOut = pOut; ctx.pMem = pAccum; @@ -594,8 +590,7 @@ i64 sqlite3VdbeIntValue(Mem *pMem){ return pMem->u.i; }else if( flags & MEM_Real ){ return doubleToInt64(pMem->u.r); - }else if( flags & (MEM_Str|MEM_Blob) ){ - assert( pMem->z || pMem->n==0 ); + }else if( (flags & (MEM_Str|MEM_Blob))!=0 && pMem->z!=0 ){ return memIntValue(pMem); }else{ return 0; @@ -752,8 +747,8 @@ int sqlite3VdbeMemNumerify(Mem *pMem){ ** affinity even if that results in loss of data. This routine is ** used (for example) to implement the SQL "cast()" operator. */ -void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ - if( pMem->flags & MEM_Null ) return; +int sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ + if( pMem->flags & MEM_Null ) return SQLITE_OK; switch( aff ){ case SQLITE_AFF_BLOB: { /* Really a cast to BLOB */ if( (pMem->flags & MEM_Blob)==0 ){ @@ -784,9 +779,10 @@ void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero); - break; + return sqlite3VdbeChangeEncoding(pMem, encoding); } } + return SQLITE_OK; } /* @@ -952,23 +948,30 @@ int sqlite3VdbeMemTooBig(Mem *p){ ** its link to a shallow copy and by marking any current shallow ** copies of this cell as invalid. ** -** This is used for testing and debugging only - to make sure shallow -** copies are not misused. +** This is used for testing and debugging only - to help ensure that shallow +** copies (created by OP_SCopy) are not misused. */ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ int i; Mem *pX; - for(i=0, pX=pVdbe->aMem; inMem; i++, pX++){ + for(i=1, pX=pVdbe->aMem+1; inMem; i++, pX++){ if( pX->pScopyFrom==pMem ){ + u16 mFlags; + if( pVdbe->db->flags & SQLITE_VdbeTrace ){ + sqlite3DebugPrintf("Invalidate R[%d] due to change in R[%d]\n", + (int)(pX - pVdbe->aMem), (int)(pMem - pVdbe->aMem)); + } /* If pX is marked as a shallow copy of pMem, then verify that ** no significant changes have been made to pX since the OP_SCopy. ** A significant change would indicated a missed call to this ** function for pX. Minor changes, such as adding or removing a ** dual type, are allowed, as long as the underlying value is the ** same. */ - u16 mFlags = pMem->flags & pX->flags & pX->mScopyFlags; + mFlags = pMem->flags & pX->flags & pX->mScopyFlags; assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i ); - assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r ); + /* assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r ); */ + /* ^^ */ + /* Cannot reliably compare doubles for equality */ assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) ); assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 ); @@ -982,7 +985,6 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ } #endif /* SQLITE_DEBUG */ - /* ** Make an shallow copy of pFrom into pTo. Prior contents of ** pTo are freed. The pFrom->z field is not duplicated. If @@ -1128,10 +1130,19 @@ int sqlite3VdbeMemSetStr( pMem->n = nByte; pMem->flags = flags; - pMem->enc = (enc==0 ? SQLITE_UTF8 : enc); + if( enc ){ + pMem->enc = enc; +#ifdef SQLITE_ENABLE_SESSION + }else if( pMem->db==0 ){ + pMem->enc = SQLITE_UTF8; +#endif + }else{ + assert( pMem->db!=0 ); + pMem->enc = ENC(pMem->db); + } #ifndef SQLITE_OMIT_UTF16 - if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){ + if( enc>SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){ return SQLITE_NOMEM_BKPT; } #endif @@ -1548,7 +1559,11 @@ static int valueFromExpr( if( pVal->flags & MEM_Real ){ pVal->u.r = -pVal->u.r; }else if( pVal->u.i==SMALLEST_INT64 ){ +#ifndef SQLITE_OMIT_FLOATING_POINT pVal->u.r = -(double)SMALLEST_INT64; +#else + pVal->u.r = LARGEST_INT64; +#endif MemSetTypeFlag(pVal, MEM_Real); }else{ pVal->u.i = -pVal->u.i; diff --git a/src/vdbesort.c b/src/vdbesort.c index 7d60ee51..ad93489c 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -1396,20 +1396,16 @@ static SorterCompare vdbeSorterGetCompare(VdbeSorter *p){ */ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){ int i; - SorterRecord **aSlot; SorterRecord *p; int rc; + SorterRecord *aSlot[64]; rc = vdbeSortAllocUnpacked(pTask); if( rc!=SQLITE_OK ) return rc; p = pList->pList; pTask->xCompare = vdbeSorterGetCompare(pTask->pSorter); - - aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *)); - if( !aSlot ){ - return SQLITE_NOMEM_BKPT; - } + memset(aSlot, 0, sizeof(aSlot)); while( p ){ SorterRecord *pNext; @@ -1434,13 +1430,12 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){ } p = 0; - for(i=0; i<64; i++){ + for(i=0; ipList = p; - sqlite3_free(aSlot); assert( pTask->pUnpacked->errCode==SQLITE_OK || pTask->pUnpacked->errCode==SQLITE_NOMEM ); diff --git a/src/vtab.c b/src/vtab.c index 08529091..013511cf 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -305,12 +305,12 @@ void sqlite3VtabDisconnect(sqlite3 *db, Table *p){ */ void sqlite3VtabUnlockList(sqlite3 *db){ VTable *p = db->pDisconnect; - db->pDisconnect = 0; assert( sqlite3BtreeHoldsAllMutexes(db) ); assert( sqlite3_mutex_held(db->mutex) ); if( p ){ + db->pDisconnect = 0; sqlite3ExpirePreparedStatements(db, 0); do { VTable *pNext = p->pNext; @@ -457,6 +457,8 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ int iReg; Vdbe *v; + sqlite3MayAbort(pParse); + /* Compute the complete text of the CREATE VIRTUAL TABLE statement */ if( pEnd ){ pParse->sNameToken.n = (int)(pEnd->z - pParse->sNameToken.z) + pEnd->n; @@ -482,13 +484,13 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ zStmt, pParse->regRowid ); - sqlite3DbFree(db, zStmt); v = sqlite3GetVdbe(pParse); sqlite3ChangeCookie(pParse, iDb); sqlite3VdbeAddOp0(v, OP_Expire); - zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName); + zWhere = sqlite3MPrintf(db, "name=%Q AND sql=%Q", pTab->zName, zStmt); sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); + sqlite3DbFree(db, zStmt); iReg = ++pParse->nMem; sqlite3VdbeLoadString(v, iReg, pTab->zName); @@ -585,6 +587,7 @@ static int vtabCallConstructor( } pVTable->db = db; pVTable->pMod = pMod; + pVTable->eVtabRisk = SQLITE_VTABRISK_Normal; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); pTab->azModuleArg[1] = db->aDb[iDb].zDbSName; @@ -624,7 +627,7 @@ static int vtabCallConstructor( rc = SQLITE_ERROR; }else{ int iCol; - u8 oooHidden = 0; + u16 oooHidden = 0; /* If everything went according to plan, link the new VTable structure ** into the linked list headed by pTab->pVTable. Then loop through the ** columns of the table to see if any of them contain the token "hidden". @@ -890,7 +893,8 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ } p = vtabDisconnectAll(db, pTab); xDestroy = p->pMod->pModule->xDestroy; - assert( xDestroy!=0 ); /* Checked before the virtual table is created */ + if( xDestroy==0 ) xDestroy = p->pMod->pModule->xDisconnect; + assert( xDestroy!=0 ); pTab->nTabRef++; rc = xDestroy(p->pVtab); /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */ @@ -1273,28 +1277,38 @@ int sqlite3_vtab_on_conflict(sqlite3 *db){ int sqlite3_vtab_config(sqlite3 *db, int op, ...){ va_list ap; int rc = SQLITE_OK; + VtabCtx *p; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif sqlite3_mutex_enter(db->mutex); - va_start(ap, op); - switch( op ){ - case SQLITE_VTAB_CONSTRAINT_SUPPORT: { - VtabCtx *p = db->pVtabCtx; - if( !p ){ - rc = SQLITE_MISUSE_BKPT; - }else{ - assert( p->pTab==0 || IsVirtual(p->pTab) ); + p = db->pVtabCtx; + if( !p ){ + rc = SQLITE_MISUSE_BKPT; + }else{ + assert( p->pTab==0 || IsVirtual(p->pTab) ); + va_start(ap, op); + switch( op ){ + case SQLITE_VTAB_CONSTRAINT_SUPPORT: { p->pVTable->bConstraint = (u8)va_arg(ap, int); + break; + } + case SQLITE_VTAB_INNOCUOUS: { + p->pVTable->eVtabRisk = SQLITE_VTABRISK_Low; + break; + } + case SQLITE_VTAB_DIRECTONLY: { + p->pVTable->eVtabRisk = SQLITE_VTABRISK_High; + break; + } + default: { + rc = SQLITE_MISUSE_BKPT; + break; } - break; } - default: - rc = SQLITE_MISUSE_BKPT; - break; + va_end(ap); } - va_end(ap); if( rc!=SQLITE_OK ) sqlite3Error(db, rc); sqlite3_mutex_leave(db->mutex); diff --git a/src/wal.c b/src/wal.c index 669be952..9873f8bf 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1824,7 +1824,19 @@ static int walCheckpoint( ** not decreasing it. So assuming either that either the "old" or ** "new" version of the value is read, and not some arbitrary value ** that would never be written by a real client, things are still - ** safe. */ + ** safe. + ** + ** Astute readers have pointed out that the assumption stated in the + ** last sentence of the previous paragraph is not guaranteed to be + ** true for all conforming systems. However, the assumption is true + ** for all compilers and architectures in common use today (circa + ** 2019-11-27) and the alternatives are both slow and complex, and + ** so we will continue to go with the current design for now. If this + ** bothers you, or if you really are running on a system where aligned + ** 32-bit reads and writes are not atomic, then you can simply avoid + ** the use of WAL mode, or only use WAL mode together with + ** PRAGMA locking_mode=EXCLUSIVE and all will be well. + */ u32 y = pInfo->aReadMark[i]; if( mxSafeFrame>y ){ assert( y<=pWal->hdr.mxFrame ); @@ -1901,6 +1913,10 @@ static int walCheckpoint( rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags)); } } + if( rc==SQLITE_OK ){ + rc = sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0); + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; + } if( rc==SQLITE_OK ){ pInfo->nBackfill = mxSafeFrame; } diff --git a/src/walker.c b/src/walker.c index 67ecd8a8..5733210c 100644 --- a/src/walker.c +++ b/src/walker.c @@ -73,8 +73,8 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ rc = pWalker->xExprCallback(pWalker, pExpr); if( rc ) return rc & WRC_Abort; if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ + assert( pExpr->x.pList==0 || pExpr->pRight==0 ); if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; - assert( pExpr->x.pList==0 || pExpr->pRight==0 ); if( pExpr->pRight ){ assert( !ExprHasProperty(pExpr, EP_WinFunc) ); pExpr = pExpr->pRight; diff --git a/src/where.c b/src/where.c index 1a43b8d1..e7447dee 100644 --- a/src/where.c +++ b/src/where.c @@ -120,7 +120,7 @@ int sqlite3WhereBreakLabel(WhereInfo *pWInfo){ /* ** Return ONEPASS_OFF (0) if an UPDATE or DELETE statement is unable to -** operate directly on the rowis returned by a WHERE clause. Return +** operate directly on the rowids returned by a WHERE clause. Return ** ONEPASS_SINGLE (1) if the statement can operation directly because only ** a single row is to be changed. Return ONEPASS_MULTI (2) if the one-pass ** optimization can be used on multiple @@ -147,6 +147,14 @@ int sqlite3WhereOkOnePass(WhereInfo *pWInfo, int *aiCur){ return pWInfo->eOnePass; } +/* +** Return TRUE if the WHERE loop uses the OP_DeferredSeek opcode to move +** the data cursor to the row selected by the index cursor. +*/ +int sqlite3WhereUsesDeferredSeek(WhereInfo *pWInfo){ + return pWInfo->bDeferredSeek; +} + /* ** Move the content of pSrc into pDest */ @@ -279,8 +287,7 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ continue; } assert(pX->pLeft); - pColl = sqlite3BinaryCompareCollSeq(pParse, - pX->pLeft, pX->pRight); + pColl = sqlite3ExprCompareCollSeq(pParse, pX); if( pColl==0 ) pColl = pParse->db->pDfltColl; if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){ continue; @@ -606,7 +613,7 @@ static void translateColumnToCopy( ** are no-ops. */ #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED) -static void TRACE_IDX_INPUTS(sqlite3_index_info *p){ +static void whereTraceIndexInfoInputs(sqlite3_index_info *p){ int i; if( !sqlite3WhereTrace ) return; for(i=0; inConstraint; i++){ @@ -624,7 +631,7 @@ static void TRACE_IDX_INPUTS(sqlite3_index_info *p){ p->aOrderBy[i].desc); } } -static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){ +static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ int i; if( !sqlite3WhereTrace ) return; for(i=0; inConstraint; i++){ @@ -640,8 +647,8 @@ static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){ sqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows); } #else -#define TRACE_IDX_INPUTS(A) -#define TRACE_IDX_OUTPUTS(A) +#define whereTraceIndexInfoInputs(A) +#define whereTraceIndexInfoOutputs(A) #endif #ifndef SQLITE_OMIT_AUTOMATIC_INDEX @@ -801,7 +808,8 @@ static void constructAutomaticIndex( Expr *pX = pTerm->pExpr; idxCols |= cMask; pIdx->aiColumn[n] = pTerm->u.leftColumn; - pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); + pColl = sqlite3ExprCompareCollSeq(pParse, pX); + assert( pColl!=0 || pParse->nErr>0 ); /* TH3 collate01.800 */ pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY; n++; } @@ -870,8 +878,8 @@ static void constructAutomaticIndex( pTabItem->fg.viaCoroutine = 0; }else{ sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); } - sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); sqlite3VdbeJumpHere(v, addrTop); sqlite3ReleaseTempReg(pParse, regRecord); @@ -950,23 +958,14 @@ static sqlite3_index_info *allocateIndexInfo( sqlite3ErrorMsg(pParse, "out of memory"); return 0; } - - /* Initialize the structure. The sqlite3_index_info structure contains - ** many fields that are declared "const" to prevent xBestIndex from - ** changing them. We have to do some funky casting in order to - ** initialize those fields. - */ pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1]; pIdxCons = (struct sqlite3_index_constraint*)&pHidden[1]; pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm]; pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy]; - *(int*)&pIdxInfo->nConstraint = nTerm; - *(int*)&pIdxInfo->nOrderBy = nOrderBy; - *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint = pIdxCons; - *(struct sqlite3_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy; - *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage = - pUsage; - + pIdxInfo->nOrderBy = nOrderBy; + pIdxInfo->aConstraint = pIdxCons; + pIdxInfo->aOrderBy = pIdxOrderBy; + pIdxInfo->aConstraintUsage = pUsage; pHidden->pWC = pWC; pHidden->pParse = pParse; for(i=j=0, pTerm=pWC->a; inTerm; i++, pTerm++){ @@ -980,18 +979,13 @@ static sqlite3_index_info *allocateIndexInfo( testcase( pTerm->eOperator & WO_ALL ); if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; if( pTerm->wtFlags & TERM_VNULL ) continue; + + /* tag-20191211-002: WHERE-clause constraints are not useful to the + ** right-hand table of a LEFT JOIN. See tag-20191211-001 for the + ** equivalent restriction for ordinary tables. */ if( (pSrc->fg.jointype & JT_LEFT)!=0 && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) - && (pTerm->eOperator & (WO_IS|WO_ISNULL)) ){ - /* An "IS" term in the WHERE clause where the virtual table is the rhs - ** of a LEFT JOIN. Do not pass this term to the virtual table - ** implementation, as this can lead to incorrect results from SQL such - ** as: - ** - ** "LEFT JOIN vtab WHERE vtab.col IS NULL" */ - testcase( pTerm->eOperator & WO_ISNULL ); - testcase( pTerm->eOperator & WO_IS ); continue; } assert( pTerm->u.leftColumn>=(-1) ); @@ -1022,7 +1016,8 @@ static sqlite3_index_info *allocateIndexInfo( if( op & (WO_LT|WO_LE|WO_GT|WO_GE) && sqlite3ExprIsVector(pTerm->pExpr->pRight) ){ - if( i<16 ) mNoOmit |= (1 << i); + testcase( j!=i ); + if( j<16 ) mNoOmit |= (1 << j); if( op==WO_LT ) pIdxCons[j].op = WO_LE; if( op==WO_GT ) pIdxCons[j].op = WO_GE; } @@ -1030,6 +1025,7 @@ static sqlite3_index_info *allocateIndexInfo( j++; } + pIdxInfo->nConstraint = j; for(i=0; ia[i].pExpr; pIdxOrderBy[i].iColumn = pExpr->iColumn; @@ -1060,9 +1056,9 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; int rc; - TRACE_IDX_INPUTS(p); + whereTraceIndexInfoInputs(p); rc = pVtab->pModule->xBestIndex(pVtab, p); - TRACE_IDX_OUTPUTS(p); + whereTraceIndexInfoOutputs(p); if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){ if( rc==SQLITE_NOMEM ){ @@ -1743,16 +1739,17 @@ static int whereInScanEst( /* ** Print the content of a WhereTerm object */ -static void whereTermPrint(WhereTerm *pTerm, int iTerm){ +void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){ if( pTerm==0 ){ sqlite3DebugPrintf("TERM-%-3d NULL\n", iTerm); }else{ - char zType[4]; + char zType[8]; char zLeft[50]; - memcpy(zType, "...", 4); + memcpy(zType, "....", 5); if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V'; if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E'; if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L'; + if( pTerm->wtFlags & TERM_CODED ) zType[3] = 'C'; if( pTerm->eOperator & WO_SINGLE ){ sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}", pTerm->leftCursor, pTerm->u.leftColumn); @@ -1763,14 +1760,21 @@ static void whereTermPrint(WhereTerm *pTerm, int iTerm){ sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor); } sqlite3DebugPrintf( - "TERM-%-3d %p %s %-12s prob=%-3d op=0x%03x wtFlags=0x%04x", - iTerm, pTerm, zType, zLeft, pTerm->truthProb, - pTerm->eOperator, pTerm->wtFlags); - if( pTerm->iField ){ - sqlite3DebugPrintf(" iField=%d\n", pTerm->iField); - }else{ - sqlite3DebugPrintf("\n"); + "TERM-%-3d %p %s %-12s op=%03x wtFlags=%04x", + iTerm, pTerm, zType, zLeft, pTerm->eOperator, pTerm->wtFlags); + /* The 0x10000 .wheretrace flag causes extra information to be + ** shown about each Term */ + if( sqlite3WhereTrace & 0x10000 ){ + sqlite3DebugPrintf(" prob=%-3d prereq=%llx,%llx", + pTerm->truthProb, (u64)pTerm->prereqAll, (u64)pTerm->prereqRight); } + if( pTerm->iField ){ + sqlite3DebugPrintf(" iField=%d", pTerm->iField); + } + if( pTerm->iParent>=0 ){ + sqlite3DebugPrintf(" iParent=%d", pTerm->iParent); + } + sqlite3DebugPrintf("\n"); sqlite3TreeViewExpr(0, pTerm->pExpr, 0); } } @@ -1783,7 +1787,7 @@ static void whereTermPrint(WhereTerm *pTerm, int iTerm){ void sqlite3WhereClausePrint(WhereClause *pWC){ int i; for(i=0; inTerm; i++){ - whereTermPrint(&pWC->a[i], i); + sqlite3WhereTermPrint(&pWC->a[i], i); } } #endif @@ -1792,7 +1796,7 @@ void sqlite3WhereClausePrint(WhereClause *pWC){ /* ** Print a WhereLoop object for debugging purposes */ -static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){ +void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){ WhereInfo *pWInfo = pWC->pWInfo; int nb = 1+(pWInfo->pTabList->nSrc+3)/4; struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab; @@ -1817,7 +1821,7 @@ static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){ }else{ char *z; if( p->u.vtab.idxStr ){ - z = sqlite3_mprintf("(%d,\"%s\",%x)", + z = sqlite3_mprintf("(%d,\"%s\",%#x)", p->u.vtab.idxNum, p->u.vtab.idxStr, p->u.vtab.omitMask); }else{ z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask); @@ -1834,7 +1838,7 @@ static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){ if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){ int i; for(i=0; inLTerm; i++){ - whereTermPrint(p->aLTerm[i], i); + sqlite3WhereTermPrint(p->aLTerm[i], i); } } } @@ -1938,6 +1942,7 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ pWInfo->pLoops = p->pNextLoop; whereLoopDelete(db, p); } + assert( pWInfo->pExprMods==0 ); sqlite3DbFreeNN(db, pWInfo); } @@ -2139,6 +2144,8 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ } pBuilder->iPlanLimit--; + whereLoopAdjustCost(pWInfo->pLoops, pTemplate); + /* If pBuilder->pOrSet is defined, then only keep track of the costs ** and prereqs. */ @@ -2153,7 +2160,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ #if WHERETRACE_ENABLED /* 0x8 */ if( sqlite3WhereTrace & 0x8 ){ sqlite3DebugPrintf(x?" or-%d: ":" or-X: ", n); - whereLoopPrint(pTemplate, pBuilder->pWC); + sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC); } #endif } @@ -2162,7 +2169,6 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ /* Look for an existing WhereLoop to replace with pTemplate */ - whereLoopAdjustCost(pWInfo->pLoops, pTemplate); ppPrev = whereLoopFindLesser(&pWInfo->pLoops, pTemplate); if( ppPrev==0 ){ @@ -2171,7 +2177,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ #if WHERETRACE_ENABLED /* 0x8 */ if( sqlite3WhereTrace & 0x8 ){ sqlite3DebugPrintf(" skip: "); - whereLoopPrint(pTemplate, pBuilder->pWC); + sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC); } #endif return SQLITE_OK; @@ -2187,12 +2193,12 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ if( sqlite3WhereTrace & 0x8 ){ if( p!=0 ){ sqlite3DebugPrintf("replace: "); - whereLoopPrint(p, pBuilder->pWC); + sqlite3WhereLoopPrint(p, pBuilder->pWC); sqlite3DebugPrintf(" with: "); }else{ sqlite3DebugPrintf(" add: "); } - whereLoopPrint(pTemplate, pBuilder->pWC); + sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC); } #endif if( p==0 ){ @@ -2216,7 +2222,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ #if WHERETRACE_ENABLED /* 0x8 */ if( sqlite3WhereTrace & 0x8 ){ sqlite3DebugPrintf(" delete: "); - whereLoopPrint(pToDel, pBuilder->pWC); + sqlite3WhereLoopPrint(pToDel, pBuilder->pWC); } #endif whereLoopDelete(db, pToDel); @@ -2425,8 +2431,9 @@ static int whereLoopAddBtreeIndex( pNew = pBuilder->pNew; if( db->mallocFailed ) return SQLITE_NOMEM_BKPT; - WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d\n", - pProbe->pTable->zName,pProbe->zName, pNew->u.btree.nEq)); + WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d, nSkip=%d\n", + pProbe->pTable->zName,pProbe->zName, + pNew->u.btree.nEq, pNew->nSkip)); assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 ); assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 ); @@ -2472,9 +2479,9 @@ static int whereLoopAddBtreeIndex( ** to mix with a lower range bound from some other source */ if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue; - /* Do not allow constraints from the WHERE clause to be used by the - ** right table of a LEFT JOIN. Only constraints in the ON clause are - ** allowed */ + /* tag-20191211-001: Do not allow constraints from the WHERE clause to + ** be used by the right table of a LEFT JOIN. Only constraints in the + ** ON clause are allowed. See tag-20191211-002 for the vtab equivalent. */ if( (pSrc->fg.jointype & JT_LEFT)!=0 && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) ){ @@ -2723,6 +2730,7 @@ static int whereLoopAddBtreeIndex( assert( 42==sqlite3LogEst(18) ); if( saved_nEq==saved_nSkip && saved_nEq+1nKeyCol + && saved_nEq==pNew->nLTerm && pProbe->noSkipScan==0 && OptimizationEnabled(db, SQLITE_SkipScan) && pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */ @@ -2791,20 +2799,25 @@ static int indexMightHelpWithOrderBy( /* Check to see if a partial index with pPartIndexWhere can be used ** in the current query. Return true if it can be and false if not. */ -static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){ +static int whereUsablePartialIndex( + int iTab, /* The table for which we want an index */ + int isLeft, /* True if iTab is the right table of a LEFT JOIN */ + WhereClause *pWC, /* The WHERE clause of the query */ + Expr *pWhere /* The WHERE clause from the partial index */ +){ int i; WhereTerm *pTerm; Parse *pParse = pWC->pWInfo->pParse; while( pWhere->op==TK_AND ){ - if( !whereUsablePartialIndex(iTab,pWC,pWhere->pLeft) ) return 0; + if( !whereUsablePartialIndex(iTab,isLeft,pWC,pWhere->pLeft) ) return 0; pWhere = pWhere->pRight; } if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0; for(i=0, pTerm=pWC->a; inTerm; i++, pTerm++){ Expr *pExpr; - if( pTerm->wtFlags & TERM_NOPARTIDX ) continue; pExpr = pTerm->pExpr; if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab) + && (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin)) && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) ){ return 1; @@ -2967,8 +2980,11 @@ static int whereLoopAddBtree( for(; rc==SQLITE_OK && pProbe; pProbe=(pSrc->pIBIndex ? 0 : pProbe->pNext), iSortIdx++ ){ + int isLeft = (pSrc->fg.jointype & JT_OUTER)!=0; if( pProbe->pPartIdxWhere!=0 - && !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){ + && !whereUsablePartialIndex(pSrc->iCursor, isLeft, pWC, + pProbe->pPartIdxWhere) + ){ testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */ continue; /* Partial index inappropriate for this query */ } @@ -3195,7 +3211,14 @@ static int whereLoopAddVirtualOne( if( iTerm>mxTerm ) mxTerm = iTerm; testcase( iTerm==15 ); testcase( iTerm==16 ); - if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<u.vtab.omitMask |= 1<eOperator & WO_IN)!=0 ){ /* A virtual table that is constrained by an IN clause may not ** consume the ORDER BY clause because (1) the order of IN terms @@ -3208,7 +3231,6 @@ static int whereLoopAddVirtualOne( } } } - pNew->u.vtab.omitMask &= ~mNoOmit; pNew->nLTerm = mxTerm+1; for(i=0; i<=mxTerm; i++){ @@ -3265,7 +3287,7 @@ const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){ int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset; Expr *pX = pHidden->pWC->a[iTerm].pExpr; if( pX->pLeft ){ - pC = sqlite3BinaryCompareCollSeq(pHidden->pParse, pX->pLeft, pX->pRight); + pC = sqlite3ExprCompareCollSeq(pHidden->pParse, pX); } zRet = (pC ? pC->zName : sqlite3StrBINARY); } @@ -3490,7 +3512,8 @@ static int whereLoopAddOr( if( rc==SQLITE_OK ){ rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable); } - assert( rc==SQLITE_OK || sCur.n==0 ); + assert( rc==SQLITE_OK || rc==SQLITE_DONE || sCur.n==0 ); + testcase( rc==SQLITE_DONE ); if( sCur.n==0 ){ sSum.n = 0; break; @@ -3698,7 +3721,9 @@ static i8 wherePathSatisfiesOrderBy( pLoop = pLast; } if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){ - if( pLoop->u.vtab.isOrdered ) obSat = obDone; + if( pLoop->u.vtab.isOrdered && (wctrlFlags & WHERE_DISTINCTBY)==0 ){ + obSat = obDone; + } break; }else if( wctrlFlags & WHERE_DISTINCTBY ){ pLoop->u.btree.nDistinctCol = 0; @@ -4801,6 +4826,7 @@ WhereInfo *sqlite3WhereBegin( } } if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ + sqlite3DebugPrintf("---- WHERE clause at start of analysis:\n"); sqlite3WhereClausePrint(sWLB.pWC); } #endif @@ -4817,7 +4843,7 @@ WhereInfo *sqlite3WhereBegin( "ABCDEFGHIJKLMNOPQRSTUVWYXZ"; for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){ p->cId = zLabel[i%(sizeof(zLabel)-1)]; - whereLoopPrint(p, sWLB.pWC); + sqlite3WhereLoopPrint(p, sWLB.pWC); } } #endif @@ -4857,7 +4883,7 @@ WhereInfo *sqlite3WhereBegin( } sqlite3DebugPrintf("\n"); for(ii=0; iinLevel; ii++){ - whereLoopPrint(pWInfo->a[ii].pWLoop, sWLB.pWC); + sqlite3WhereLoopPrint(pWInfo->a[ii].pWLoop, sWLB.pWC); } } #endif @@ -4882,14 +4908,14 @@ WhereInfo *sqlite3WhereBegin( ** then table t2 can be omitted from the following: ** ** SELECT v1, v3 FROM t1 - ** LEFT JOIN t2 USING (t1.ipk=t2.ipk) - ** LEFT JOIN t3 USING (t1.ipk=t3.ipk) + ** LEFT JOIN t2 ON (t1.ipk=t2.ipk) + ** LEFT JOIN t3 ON (t1.ipk=t3.ipk) ** ** or from: ** ** SELECT DISTINCT v1, v3 FROM t1 ** LEFT JOIN t2 - ** LEFT JOIN t3 USING (t1.ipk=t3.ipk) + ** LEFT JOIN t3 ON (t1.ipk=t3.ipk) */ notReady = ~(Bitmask)0; if( pWInfo->nLevel>=2 @@ -4939,7 +4965,13 @@ WhereInfo *sqlite3WhereBegin( nTabList--; } } +#if defined(WHERETRACE_ENABLED) + if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ + sqlite3DebugPrintf("---- WHERE clause at end of analysis:\n"); + sqlite3WhereClausePrint(sWLB.pWC); + } WHERETRACE(0xffff,("*** Optimizer Finished ***\n")); +#endif pWInfo->pParse->nQueryLoop += pWInfo->nRowOut; /* If the caller is an UPDATE or DELETE statement that is requesting @@ -5016,7 +5048,13 @@ WhereInfo *sqlite3WhereBegin( assert( pTabItem->iCursor==pLevel->iTabCur ); testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 ); testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS ); - if( pWInfo->eOnePass==ONEPASS_OFF && pTab->nColeOnePass==ONEPASS_OFF + && pTab->nColtabFlags & (TF_HasGenerated|TF_WithoutRowid))==0 + ){ + /* If we know that only a prefix of the record will be used, + ** it is advantageous to reduce the "column count" field in + ** the P4 operand of the OP_OpenRead/Write opcode. */ Bitmask b = pTabItem->colUsed; int n = 0; for(; b; b=b>>1, n++){} @@ -5237,10 +5275,26 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ if( pIn->eEndLoopOp!=OP_Noop ){ if( pIn->nPrefix ){ assert( pLoop->wsFlags & WHERE_IN_EARLYOUT ); - sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur, - sqlite3VdbeCurrentAddr(v)+2, - pIn->iBase, pIn->nPrefix); - VdbeCoverage(v); + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){ + sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur, + sqlite3VdbeCurrentAddr(v)+2+(pLevel->iLeftJoin!=0), + pIn->iBase, pIn->nPrefix); + VdbeCoverage(v); + } + if( pLevel->iLeftJoin ){ + /* For LEFT JOIN queries, cursor pIn->iCur may not have been + ** opened yet. This occurs for WHERE clauses such as + ** "a = ? AND b IN (...)", where the index is on (a, b). If + ** the RHS of the (a=?) is NULL, then the "b IN (...)" may + ** never have been coded, but the body of the loop run to + ** return the null-row. So, if the cursor is not open yet, + ** jump over the OP_Next or OP_Prev instruction about to + ** be coded. */ + sqlite3VdbeAddOp2(v, OP_IfNotOpen, pIn->iCur, + sqlite3VdbeCurrentAddr(v) + 2 + ); + VdbeCoverage(v); + } } sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); VdbeCoverage(v); @@ -5378,8 +5432,11 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ Index *pPk = sqlite3PrimaryKeyIndex(pTab); x = pPk->aiColumn[x]; assert( x>=0 ); + }else{ + testcase( x!=sqlite3StorageColumnToTable(pTab,x) ); + x = sqlite3StorageColumnToTable(pTab,x); } - x = sqlite3ColumnOfIndex(pIdx, x); + x = sqlite3TableColumnToIndex(pIdx, x); if( x>=0 ){ pOp->p2 = x; pOp->p1 = pLevel->iIdxCur; @@ -5402,6 +5459,14 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ } } + /* Undo all Expr node modifications */ + while( pWInfo->pExprMods ){ + WhereExprMod *p = pWInfo->pExprMods; + pWInfo->pExprMods = p->pNext; + memcpy(p->pExpr, &p->orig, sizeof(p->orig)); + sqlite3DbFree(db, p); + } + /* Final cleanup */ pParse->nQueryLoop = pWInfo->savedNQueryLoop; diff --git a/src/whereInt.h b/src/whereInt.h index 64978cf1..74101624 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -274,24 +274,23 @@ struct WhereTerm { /* ** Allowed values of WhereTerm.wtFlags */ -#define TERM_DYNAMIC 0x01 /* Need to call sqlite3ExprDelete(db, pExpr) */ -#define TERM_VIRTUAL 0x02 /* Added by the optimizer. Do not code */ -#define TERM_CODED 0x04 /* This term is already coded */ -#define TERM_COPIED 0x08 /* Has a child */ -#define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */ -#define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */ -#define TERM_OR_OK 0x40 /* Used during OR-clause processing */ +#define TERM_DYNAMIC 0x0001 /* Need to call sqlite3ExprDelete(db, pExpr) */ +#define TERM_VIRTUAL 0x0002 /* Added by the optimizer. Do not code */ +#define TERM_CODED 0x0004 /* This term is already coded */ +#define TERM_COPIED 0x0008 /* Has a child */ +#define TERM_ORINFO 0x0010 /* Need to free the WhereTerm.u.pOrInfo object */ +#define TERM_ANDINFO 0x0020 /* Need to free the WhereTerm.u.pAndInfo obj */ +#define TERM_OR_OK 0x0040 /* Used during OR-clause processing */ #ifdef SQLITE_ENABLE_STAT4 -# define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */ +# define TERM_VNULL 0x0080 /* Manufactured x>NULL or x<=NULL term */ #else -# define TERM_VNULL 0x00 /* Disabled if not using stat4 */ +# define TERM_VNULL 0x0000 /* Disabled if not using stat4 */ #endif -#define TERM_LIKEOPT 0x100 /* Virtual terms from the LIKE optimization */ -#define TERM_LIKECOND 0x200 /* Conditionally this LIKE operator term */ -#define TERM_LIKE 0x400 /* The original LIKE operator */ -#define TERM_IS 0x800 /* Term.pExpr is an IS operator */ +#define TERM_LIKEOPT 0x0100 /* Virtual terms from the LIKE optimization */ +#define TERM_LIKECOND 0x0200 /* Conditionally this LIKE operator term */ +#define TERM_LIKE 0x0400 /* The original LIKE operator */ +#define TERM_IS 0x0800 /* Term.pExpr is an IS operator */ #define TERM_VARSELECT 0x1000 /* Term.pExpr contains a correlated sub-query */ -#define TERM_NOPARTIDX 0x2000 /* Not for use to enable a partial index */ /* ** An instance of the WhereScan object is used as an iterator for locating @@ -434,6 +433,20 @@ struct WhereLoopBuilder { # define SQLITE_QUERY_PLANNER_LIMIT_INCR 1000 #endif +/* +** Each instance of this object records a change to a single node +** in an expression tree to cause that node to point to a column +** of an index rather than an expression or a virtual column. All +** such transformations need to be undone at the end of WHERE clause +** processing. +*/ +typedef struct WhereExprMod WhereExprMod; +struct WhereExprMod { + WhereExprMod *pNext; /* Next translation on a list of them all */ + Expr *pExpr; /* The Expr node that was transformed */ + Expr orig; /* Original value of the Expr node */ +}; + /* ** The WHERE clause processing routine has two halves. The ** first part does the start of the WHERE loop and the second @@ -450,23 +463,25 @@ struct WhereInfo { ExprList *pOrderBy; /* The ORDER BY clause or NULL */ ExprList *pResultSet; /* Result set of the query */ Expr *pWhere; /* The complete WHERE clause */ - LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */ int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */ int iContinue; /* Jump here to continue with next record */ int iBreak; /* Jump here to break out of the loop */ int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ + LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */ u8 nLevel; /* Number of nested loop */ i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ - u8 sorted; /* True if really sorted (not just grouped) */ u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */ - u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ u8 eDistinct; /* One of the WHERE_DISTINCT_* values */ - u8 bOrderedInnerLoop; /* True if only the inner-most loop is ordered */ + unsigned bDeferredSeek :1; /* Uses OP_DeferredSeek */ + unsigned untestedTerms :1; /* Not all WHERE terms resolved by outer loop */ + unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */ + unsigned sorted :1; /* True if really sorted (not just grouped) */ + LogEst nRowOut; /* Estimated number of output rows */ int iTop; /* The very beginning of the WHERE loop */ WhereLoop *pLoops; /* List of all WhereLoop objects */ + WhereExprMod *pExprMods; /* Expression modifications */ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ - LogEst nRowOut; /* Estimated number of output rows */ WhereClause sWC; /* Decomposition of the WHERE clause */ WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ WhereLevel a[1]; /* Information about each nest loop in WHERE */ @@ -480,6 +495,8 @@ struct WhereInfo { Bitmask sqlite3WhereGetMask(WhereMaskSet*,int); #ifdef WHERETRACE_ENABLED void sqlite3WhereClausePrint(WhereClause *pWC); +void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm); +void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC); #endif WhereTerm *sqlite3WhereFindTerm( WhereClause *pWC, /* The WHERE clause to be searched */ diff --git a/src/wherecode.c b/src/wherecode.c index 2fbcba17..0014a695 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -415,7 +415,8 @@ static Expr *removeUnindexableInClauseTerms( Expr *pX /* The IN expression to be reduced */ ){ sqlite3 *db = pParse->db; - Expr *pNew = sqlite3ExprDup(db, pX, 0); + Expr *pNew; + pNew = sqlite3ExprDup(db, pX, 0); if( db->mallocFailed==0 ){ ExprList *pOrigRhs = pNew->x.pSelect->pEList; /* Original unmodified RHS */ ExprList *pOrigLhs = pNew->pLeft->x.pList; /* Original unmodified LHS */ @@ -592,7 +593,7 @@ static int codeEqualityTerm( if( i==iEq ){ pIn->iCur = iTab; pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; - if( iEq>0 && (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){ + if( iEq>0 ){ pIn->iBase = iReg - i; pIn->nPrefix = i; pLoop->wsFlags |= WHERE_IN_EARLYOUT; @@ -823,7 +824,7 @@ static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){ assert( pHint->pIdx!=0 ); if( pExpr->op==TK_COLUMN && pExpr->iTable==pHint->iTabCur - && sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn)<0 + && sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn)<0 ){ pWalker->eCode = 1; } @@ -891,7 +892,7 @@ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ pExpr->iTable = reg; }else if( pHint->pIdx!=0 ){ pExpr->iTable = pHint->iIdxCur; - pExpr->iColumn = sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn); + pExpr->iColumn = sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn); assert( pExpr->iColumn>=0 ); } }else if( pExpr->op==TK_AGG_FUNCTION ){ @@ -1044,6 +1045,7 @@ static void codeDeferredSeek( assert( iIdxCur>0 ); assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 ); + pWInfo->bDeferredSeek = 1; sqlite3VdbeAddOp3(v, OP_DeferredSeek, iIdxCur, 0, iCur); if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE) && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask) @@ -1054,8 +1056,12 @@ static void codeDeferredSeek( if( ai ){ ai[0] = pTab->nCol; for(i=0; inColumn-1; i++){ + int x1, x2; assert( pIdx->aiColumn[i]nCol ); - if( pIdx->aiColumn[i]>=0 ) ai[pIdx->aiColumn[i]+1] = i+1; + x1 = pIdx->aiColumn[i]; + x2 = sqlite3TableColumnToStorage(pTab, x1); + testcase( x1!=x2 ); + if( x1>=0 ) ai[x2+1] = i+1; } sqlite3VdbeChangeP4(v, -1, (char*)ai, P4_INTARRAY); } @@ -1106,8 +1112,24 @@ typedef struct IdxExprTrans { int iTabCur; /* The cursor of the corresponding table */ int iIdxCur; /* The cursor for the index */ int iIdxCol; /* The column for the index */ + int iTabCol; /* The column for the table */ + WhereInfo *pWInfo; /* Complete WHERE clause information */ + sqlite3 *db; /* Database connection (for malloc()) */ } IdxExprTrans; +/* +** Preserve pExpr on the WhereETrans list of the WhereInfo. +*/ +static void preserveExpr(IdxExprTrans *pTrans, Expr *pExpr){ + WhereExprMod *pNew; + pNew = sqlite3DbMallocRaw(pTrans->db, sizeof(*pNew)); + if( pNew==0 ) return; + pNew->pNext = pTrans->pWInfo->pExprMods; + pTrans->pWInfo->pExprMods = pNew; + pNew->pExpr = pExpr; + memcpy(&pNew->orig, pExpr, sizeof(*pExpr)); +} + /* The walker node callback used to transform matching expressions into ** a reference to an index column for an index on an expression. ** @@ -1117,21 +1139,49 @@ typedef struct IdxExprTrans { static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ IdxExprTrans *pX = p->u.pIdxTrans; if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ + preserveExpr(pX, pExpr); pExpr->affExpr = sqlite3ExprAffinity(pExpr); pExpr->op = TK_COLUMN; pExpr->iTable = pX->iIdxCur; pExpr->iColumn = pX->iIdxCol; pExpr->y.pTab = 0; + testcase( ExprHasProperty(pExpr, EP_Skip) ); + testcase( ExprHasProperty(pExpr, EP_Unlikely) ); + ExprClearProperty(pExpr, EP_Skip|EP_Unlikely); return WRC_Prune; }else{ return WRC_Continue; } } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +/* A walker node callback that translates a column reference to a table +** into a corresponding column reference of an index. +*/ +static int whereIndexExprTransColumn(Walker *p, Expr *pExpr){ + if( pExpr->op==TK_COLUMN ){ + IdxExprTrans *pX = p->u.pIdxTrans; + if( pExpr->iTable==pX->iTabCur && pExpr->iColumn==pX->iTabCol ){ + assert( pExpr->y.pTab!=0 ); + preserveExpr(pX, pExpr); + pExpr->affExpr = sqlite3TableColumnAffinity(pExpr->y.pTab,pExpr->iColumn); + pExpr->iTable = pX->iIdxCur; + pExpr->iColumn = pX->iIdxCol; + pExpr->y.pTab = 0; + } + } + return WRC_Continue; +} +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + /* ** For an indexes on expression X, locate every instance of expression X ** in pExpr and change that subexpression into a reference to the appropriate ** column of the index. +** +** 2019-10-24: Updated to also translate references to a VIRTUAL column in +** the table into references to the corresponding (stored) column of the +** index. */ static void whereIndexExprTrans( Index *pIdx, /* The Index */ @@ -1141,20 +1191,48 @@ static void whereIndexExprTrans( ){ int iIdxCol; /* Column number of the index */ ExprList *aColExpr; /* Expressions that are indexed */ + Table *pTab; Walker w; IdxExprTrans x; aColExpr = pIdx->aColExpr; - if( aColExpr==0 ) return; /* Not an index on expressions */ + if( aColExpr==0 && !pIdx->bHasVCol ){ + /* The index does not reference any expressions or virtual columns + ** so no translations are needed. */ + return; + } + pTab = pIdx->pTable; memset(&w, 0, sizeof(w)); - w.xExprCallback = whereIndexExprTransNode; w.u.pIdxTrans = &x; x.iTabCur = iTabCur; x.iIdxCur = iIdxCur; - for(iIdxCol=0; iIdxColnExpr; iIdxCol++){ - if( pIdx->aiColumn[iIdxCol]!=XN_EXPR ) continue; - assert( aColExpr->a[iIdxCol].pExpr!=0 ); + x.pWInfo = pWInfo; + x.db = pWInfo->pParse->db; + for(iIdxCol=0; iIdxColnColumn; iIdxCol++){ + i16 iRef = pIdx->aiColumn[iIdxCol]; + if( iRef==XN_EXPR ){ + assert( aColExpr->a[iIdxCol].pExpr!=0 ); + x.pIdxExpr = aColExpr->a[iIdxCol].pExpr; + if( sqlite3ExprIsConstant(x.pIdxExpr) ) continue; + w.xExprCallback = whereIndexExprTransNode; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + }else if( iRef>=0 + && (pTab->aCol[iRef].colFlags & COLFLAG_VIRTUAL)!=0 + && (pTab->aCol[iRef].zColl==0 + || sqlite3StrICmp(pTab->aCol[iRef].zColl, sqlite3StrBINARY)==0) + ){ + /* Check to see if there are direct references to generated columns + ** that are contained in the index. Pulling the generated column + ** out of the index is an optimization only - the main table is always + ** available if the index cannot be used. To avoid unnecessary + ** complication, omit this optimization if the collating sequence for + ** the column is non-standard */ + x.iTabCol = iRef; + w.xExprCallback = whereIndexExprTransColumn; +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + }else{ + continue; + } x.iIdxCol = iIdxCol; - x.pIdxExpr = aColExpr->a[iIdxCol].pExpr; sqlite3WalkExpr(&w, pWInfo->pWhere); sqlite3WalkExprList(&w, pWInfo->pOrderBy); sqlite3WalkExprList(&w, pWInfo->pResultSet); @@ -1226,6 +1304,21 @@ Bitmask sqlite3WhereCodeOneLoopStart( pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); bRev = (pWInfo->revMask>>iLevel)&1; VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); +#if WHERETRACE_ENABLED /* 0x20800 */ + if( sqlite3WhereTrace & 0x800 ){ + sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n", + iLevel, pWInfo->nLevel, (u64)notReady, pLevel->iFrom); + sqlite3WhereLoopPrint(pLoop, pWC); + } + if( sqlite3WhereTrace & 0x20000 ){ + if( iLevel==0 ){ + sqlite3DebugPrintf("WHERE clause being coded:\n"); + sqlite3TreeViewExpr(0, pWInfo->pWhere, 0); + } + sqlite3DebugPrintf("All WHERE-clause terms before coding:\n"); + sqlite3WhereClausePrint(pWC); + } +#endif /* Create labels for the "break" and "continue" instructions ** for the current loop. Jump to addrBrk to break out of a loop. @@ -1305,9 +1398,12 @@ Bitmask sqlite3WhereCodeOneLoopStart( iIn = pLevel->u.in.nIn; for(j=nConstraint-1; j>=0; j--){ pTerm = pLoop->aLTerm[j]; + if( (pTerm->eOperator & WO_IN)!=0 ) iIn--; if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){ disableTerm(pLevel, pTerm); - }else if( (pTerm->eOperator & WO_IN)!=0 ){ + }else if( (pTerm->eOperator & WO_IN)!=0 + && sqlite3ExprVectorSize(pTerm->pExpr->pLeft)==1 + ){ Expr *pCompare; /* The comparison operator */ Expr *pRight; /* RHS of the comparison */ VdbeOp *pOp; /* Opcode to access the value of the IN constraint */ @@ -1318,8 +1414,8 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** encoding of the value in the register, so it *must* be reloaded. */ assert( pLevel->u.in.aInLoop!=0 || db->mallocFailed ); if( !db->mallocFailed ){ - assert( iIn>0 ); - pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[--iIn].addrInTop); + assert( iIn>=0 && iInu.in.nIn ); + pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[iIn].addrInTop); assert( pOp->opcode==OP_Column || pOp->opcode==OP_Rowid ); assert( pOp->opcode!=OP_Column || pOp->p3==iReg+j+2 ); assert( pOp->opcode!=OP_Rowid || pOp->p2==iReg+j+2 ); @@ -1343,6 +1439,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( } } } + assert( iIn==0 || db->mallocFailed ); /* These registers need to be preserved in case there is an IN operator ** loop. So we could deallocate the registers here (and potentially ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems @@ -1608,7 +1705,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( ){ assert( bSeekPastNull==0 && nExtraReg==0 && nBtm==0 && nTop==0 ); assert( pRangeEnd==0 && pRangeStart==0 ); - assert( pLoop->nSkip==0 ); + testcase( pLoop->nSkip>0 ); nExtraReg = 1; bSeekPastNull = 1; pLevel->regBignull = regBignull = ++pParse->nMem; @@ -1807,10 +1904,10 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ }else if( HasRowid(pIdx->pTable) ){ - if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE) || ( - (pWInfo->wctrlFlags & WHERE_SEEK_UNIQ_TABLE) - && (pWInfo->eOnePass==ONEPASS_SINGLE) - )){ + if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE) + || ( (pWInfo->wctrlFlags & WHERE_SEEK_UNIQ_TABLE)!=0 + && (pWInfo->eOnePass==ONEPASS_SINGLE || pLoop->nLTerm==0) ) + ){ iRowidReg = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg); @@ -1822,40 +1919,53 @@ Bitmask sqlite3WhereCodeOneLoopStart( Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol); for(j=0; jnKeyCol; j++){ - k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]); + k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]); sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j); } sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont, iRowidReg, pPk->nKeyCol); VdbeCoverage(v); } - /* If pIdx is an index on one or more expressions, then look through - ** all the expressions in pWInfo and try to transform matching expressions - ** into reference to index columns. - ** - ** Do not do this for the RHS of a LEFT JOIN. This is because the - ** expression may be evaluated after OP_NullRow has been executed on - ** the cursor. In this case it is important to do the full evaluation, - ** as the result of the expression may not be NULL, even if all table - ** column values are. https://www.sqlite.org/src/info/7fa8049685b50b5a - ** - ** Also, do not do this when processing one index an a multi-index - ** OR clause, since the transformation will become invalid once we - ** move forward to the next index. - ** https://sqlite.org/src/info/4e8e4857d32d401f - */ - if( pLevel->iLeftJoin==0 && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){ - whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo); + if( pLevel->iLeftJoin==0 ){ + /* If pIdx is an index on one or more expressions, then look through + ** all the expressions in pWInfo and try to transform matching expressions + ** into reference to index columns. Also attempt to translate references + ** to virtual columns in the table into references to (stored) columns + ** of the index. + ** + ** Do not do this for the RHS of a LEFT JOIN. This is because the + ** expression may be evaluated after OP_NullRow has been executed on + ** the cursor. In this case it is important to do the full evaluation, + ** as the result of the expression may not be NULL, even if all table + ** column values are. https://www.sqlite.org/src/info/7fa8049685b50b5a + ** + ** Also, do not do this when processing one index an a multi-index + ** OR clause, since the transformation will become invalid once we + ** move forward to the next index. + ** https://sqlite.org/src/info/4e8e4857d32d401f + */ + if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){ + whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo); + } + + /* If a partial index is driving the loop, try to eliminate WHERE clause + ** terms from the query that must be true due to the WHERE clause of + ** the partial index. + ** + ** 2019-11-02 ticket 623eff57e76d45f6: This optimization does not work + ** for a LEFT JOIN. + */ + if( pIdx->pPartIdxWhere ){ + whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC); + } + }else{ + testcase( pIdx->pPartIdxWhere ); + /* The following assert() is not a requirement, merely an observation: + ** The OR-optimization doesn't work for the right hand table of + ** a LEFT JOIN: */ + assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ); } - - /* If a partial index is driving the loop, try to eliminate WHERE clause - ** terms from the query that must be true due to the WHERE clause of - ** the partial index - */ - if( pIdx->pPartIdxWhere ){ - whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC); - } - + /* Record the instruction used to terminate the loop. */ if( pLoop->wsFlags & WHERE_ONEROW ){ pLevel->op = OP_Noop; @@ -2040,9 +2150,9 @@ Bitmask sqlite3WhereCodeOneLoopStart( WhereInfo *pSubWInfo; /* Info for single OR-term scan */ Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ int jmp1 = 0; /* Address of jump operation */ - assert( (pTabItem[0].fg.jointype & JT_LEFT)==0 - || ExprHasProperty(pOrExpr, EP_FromJoin) - ); + testcase( (pTabItem[0].fg.jointype & JT_LEFT)!=0 + && !ExprHasProperty(pOrExpr, EP_FromJoin) + ); /* See TH3 vtab25.400 and ticket 614b25314c766238 */ if( pAndExpr ){ pAndExpr->pLeft = pOrExpr; pOrExpr = pAndExpr; @@ -2082,7 +2192,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( r = sqlite3GetTempRange(pParse, nPk); for(iPk=0; iPkaiColumn[iPk]; - sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol, r+iPk); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk); } /* Check if the temp table already contains this key. If so, @@ -2264,6 +2374,10 @@ Bitmask sqlite3WhereCodeOneLoopStart( VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d", pWC->nTerm-j, pTerm, iLoop)); } + if( sqlite3WhereTrace & 0x800 ){ + sqlite3DebugPrintf("Coding auxiliary constraint:\n"); + sqlite3WhereTermPrint(pTerm, pWC->nTerm-j); + } #endif sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr); @@ -2287,8 +2401,14 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue; if( (pTerm->eOperator & WO_EQUIV)==0 ) continue; if( pTerm->leftCursor!=iCur ) continue; - if( pLevel->iLeftJoin ) continue; + if( pTabItem->fg.jointype & JT_LEFT ) continue; pE = pTerm->pExpr; +#ifdef WHERETRACE_ENABLED /* 0x800 */ + if( sqlite3WhereTrace & 0x800 ){ + sqlite3DebugPrintf("Coding transitive constraint:\n"); + sqlite3WhereTermPrint(pTerm, pWC->nTerm-j); + } +#endif assert( !ExprHasProperty(pE, EP_FromJoin) ); assert( (pTerm->prereqRight & pLevel->notReady)!=0 ); pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.leftColumn, notReady, @@ -2331,5 +2451,16 @@ Bitmask sqlite3WhereCodeOneLoopStart( } } +#if WHERETRACE_ENABLED /* 0x20800 */ + if( sqlite3WhereTrace & 0x20000 ){ + sqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n", + iLevel); + sqlite3WhereClausePrint(pWC); + } + if( sqlite3WhereTrace & 0x800 ){ + sqlite3DebugPrintf("End Coding level %d: notReady=%llx\n", + iLevel, (u64)pLevel->notReady); + } +#endif return pLevel->notReady; } diff --git a/src/whereexpr.c b/src/whereexpr.c index a1613107..cec0aefd 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -109,39 +109,14 @@ static int allowedOp(int op){ /* ** Commute a comparison operator. Expressions of the form "X op Y" ** are converted into "Y op X". -** -** If left/right precedence rules come into play when determining the -** collating sequence, then COLLATE operators are adjusted to ensure -** that the collating sequence does not change. For example: -** "Y collate NOCASE op X" becomes "X op Y" because any collation sequence on -** the left hand side of a comparison overrides any collation sequence -** attached to the right. For the same reason the EP_Collate flag -** is not commuted. -** -** The return value is extra flags that are added to the WhereTerm object -** after it is commuted. The only extra flag ever added is TERM_NOPARTIDX -** which prevents the term from being used to enable a partial index if -** COLLATE changes have been made. */ static u16 exprCommute(Parse *pParse, Expr *pExpr){ - u16 expRight = (pExpr->pRight->flags & EP_Collate); - u16 expLeft = (pExpr->pLeft->flags & EP_Collate); - u16 wtFlags = 0; - assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN ); - if( expRight==expLeft ){ - /* Either X and Y both have COLLATE operator or neither do */ - if( expRight ){ - /* Both X and Y have COLLATE operators. Make sure X is always - ** used by clearing the EP_Collate flag from Y. */ - pExpr->pRight->flags &= ~EP_Collate; - wtFlags |= TERM_NOPARTIDX; - }else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){ - /* Neither X nor Y have COLLATE operators, but X has a non-default - ** collating sequence. So add the EP_Collate marker on X to cause - ** it to be searched first. */ - pExpr->pLeft->flags |= EP_Collate; - wtFlags |= TERM_NOPARTIDX; - } + if( pExpr->pLeft->op==TK_VECTOR + || pExpr->pRight->op==TK_VECTOR + || sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight) != + sqlite3BinaryCompareCollSeq(pParse, pExpr->pRight, pExpr->pLeft) + ){ + pExpr->flags ^= EP_Commuted; } SWAP(Expr*,pExpr->pRight,pExpr->pLeft); if( pExpr->op>=TK_GT ){ @@ -152,7 +127,7 @@ static u16 exprCommute(Parse *pParse, Expr *pExpr){ assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE ); pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT; } - return wtFlags; + return 0; } /* @@ -930,7 +905,7 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr){ ){ return 0; } - pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight); + pColl = sqlite3ExprCompareCollSeq(pParse, pExpr); if( sqlite3IsBinary(pColl) ) return 1; return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight); } @@ -1323,6 +1298,7 @@ static void exprAnalyze( 0, sqlite3ExprDup(db, pRight, 0)); if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){ ExprSetProperty(pNewExpr, EP_FromJoin); + pNewExpr->iRightJoinTable = pExpr->iRightJoinTable; } idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew==0 ); @@ -1379,11 +1355,15 @@ static void exprAnalyze( ** expression). The WhereTerm.iField variable identifies the index within ** the vector on the LHS that the virtual term represents. ** - ** This only works if the RHS is a simple SELECT, not a compound + ** This only works if the RHS is a simple SELECT (not a compound) that does + ** not use window functions. */ if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->iField==0 && pExpr->pLeft->op==TK_VECTOR && pExpr->x.pSelect->pPrior==0 +#ifndef SQLITE_OMIT_WINDOWFUNC + && pExpr->x.pSelect->pWin==0 +#endif ){ int i; for(i=0; ipLeft); i++){ @@ -1541,9 +1521,10 @@ Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){ mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList); } #ifndef SQLITE_OMIT_WINDOWFUNC - if( p->op==TK_FUNCTION && p->y.pWin ){ + if( (p->op==TK_FUNCTION || p->op==TK_AGG_FUNCTION) && p->y.pWin ){ mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pPartition); mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pOrderBy); + mask |= sqlite3WhereExprUsage(pMaskSet, p->y.pWin->pFilter); } #endif return mask; @@ -1619,6 +1600,9 @@ void sqlite3WhereTabFuncArgs( pRhs = sqlite3PExpr(pParse, TK_UPLUS, sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs); + if( pItem->fg.jointype & JT_LEFT ){ + sqlite3SetJoinExpr(pTerm, pItem->iCursor); + } whereClauseInsert(pWC, pTerm, TERM_DYNAMIC); } } diff --git a/src/window.c b/src/window.c index e8dfa6c3..a72ec0d2 100644 --- a/src/window.c +++ b/src/window.c @@ -787,8 +787,21 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){ case TK_AGG_FUNCTION: case TK_COLUMN: { - Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0); - p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup); + int iCol = -1; + if( p->pSub ){ + int i; + for(i=0; ipSub->nExpr; i++){ + if( 0==sqlite3ExprCompare(0, p->pSub->a[i].pExpr, pExpr, -1) ){ + iCol = i; + break; + } + } + } + if( iCol<0 ){ + Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0); + if( pDup && pDup->op==TK_AGG_FUNCTION ) pDup->op = TK_FUNCTION; + p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup); + } if( p->pSub ){ assert( ExprHasProperty(pExpr, EP_Static)==0 ); ExprSetProperty(pExpr, EP_Static); @@ -797,11 +810,11 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){ memset(pExpr, 0, sizeof(Expr)); pExpr->op = TK_COLUMN; - pExpr->iColumn = p->pSub->nExpr-1; + pExpr->iColumn = (iCol<0 ? p->pSub->nExpr-1: iCol); pExpr->iTable = p->pWin->iEphCsr; pExpr->y.pTab = p->pTab; } - + if( pParse->db->mallocFailed ) return WRC_Abort; break; } @@ -882,10 +895,13 @@ static ExprList *exprListAppendList( int i; int nInit = pList ? pList->nExpr : 0; for(i=0; inExpr; i++){ + int iDummy; Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0); - if( bIntToNull && pDup && pDup->op==TK_INTEGER ){ + assert( pDup==0 || !ExprHasProperty(pDup, EP_MemToken) ); + if( bIntToNull && pDup && sqlite3ExprIsInteger(pDup, &iDummy) ){ pDup->op = TK_NULL; pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); + pDup->u.zToken = 0; } pList = sqlite3ExprListAppend(pParse, pList, pDup); if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags; @@ -903,7 +919,7 @@ static ExprList *exprListAppendList( */ int sqlite3WindowRewrite(Parse *pParse, Select *p){ int rc = SQLITE_OK; - if( p->pWin && p->pPrior==0 ){ + if( p->pWin && p->pPrior==0 && (p->selFlags & SF_WinRewrite)==0 ){ Vdbe *v = sqlite3GetVdbe(pParse); sqlite3 *db = pParse->db; Select *pSub = 0; /* The subquery */ @@ -920,7 +936,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){ pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ){ - return SQLITE_NOMEM; + return sqlite3ErrorToParser(db, SQLITE_NOMEM); } p->pSrc = 0; @@ -928,11 +944,12 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){ p->pGroupBy = 0; p->pHaving = 0; p->selFlags &= ~SF_Aggregate; + p->selFlags |= SF_WinRewrite; /* Create the ORDER BY clause for the sub-select. This is the concatenation ** of the window PARTITION and ORDER BY clauses. Then, if this makes it ** redundant, remove the ORDER BY from the parent SELECT. */ - pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0); + pSort = exprListAppendList(pParse, 0, pMWin->pPartition, 1); pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy, 1); if( pSort && p->pOrderBy && p->pOrderBy->nExpr<=pSort->nExpr ){ int nSave = pSort->nExpr; @@ -1006,6 +1023,9 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){ pSub->selFlags |= SF_Expanded; pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE); if( pTab2==0 ){ + /* Might actually be some other kind of error, but in that case + ** pParse->nErr will be set, so if SQLITE_NOMEM is set, we will get + ** the correct error message regardless. */ rc = SQLITE_NOMEM; }else{ memcpy(pTab, pTab2, sizeof(Table)); @@ -1013,10 +1033,6 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){ p->pSrc->a[0].pTab = pTab; pTab = pTab2; } - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr); - sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr); - sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr); - sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr); }else{ sqlite3SelectDelete(db, pSub); } @@ -1024,6 +1040,13 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){ sqlite3DbFree(db, pTab); } + if( rc ){ + if( pParse->nErr==0 ){ + assert( pParse->db->mallocFailed ); + sqlite3ErrorToParser(pParse->db, SQLITE_NOMEM); + } + sqlite3SelectReset(pParse, p); + } return rc; } @@ -1243,8 +1266,8 @@ void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ ** SELECT, or (b) the windows already linked use a compatible window frame. */ void sqlite3WindowLink(Select *pSel, Window *pWin){ - if( 0==pSel->pWin - || 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0) + if( pSel!=0 + && (0==pSel->pWin || 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0)) ){ pWin->pNextWin = pSel->pWin; if( pSel->pWin ){ @@ -1256,20 +1279,29 @@ void sqlite3WindowLink(Select *pSel, Window *pWin){ } /* -** Return 0 if the two window objects are identical, or non-zero otherwise. -** Identical window objects can be processed in a single scan. +** Return 0 if the two window objects are identical, 1 if they are +** different, or 2 if it cannot be determined if the objects are identical +** or not. Identical window objects can be processed in a single scan. */ int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2, int bFilter){ + int res; + if( NEVER(p1==0) || NEVER(p2==0) ) return 1; if( p1->eFrmType!=p2->eFrmType ) return 1; if( p1->eStart!=p2->eStart ) return 1; if( p1->eEnd!=p2->eEnd ) return 1; if( p1->eExclude!=p2->eExclude ) return 1; if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1; if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1; - if( sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1) ) return 1; - if( sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1) ) return 1; + if( (res = sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1)) ){ + return res; + } + if( (res = sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1)) ){ + return res; + } if( bFilter ){ - if( sqlite3ExprCompare(pParse, p1->pFilter, p2->pFilter, -1) ) return 1; + if( (res = sqlite3ExprCompare(pParse, p1->pFilter, p2->pFilter, -1)) ){ + return res; + } } return 0; } @@ -1280,10 +1312,17 @@ int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2, int bFilter){ ** to begin iterating through the sub-query results. It is used to allocate ** and initialize registers and cursors used by sqlite3WindowCodeStep(). */ -void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){ +void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){ + int nEphExpr = pSelect->pSrc->a[0].pSelect->pEList->nExpr; + Window *pMWin = pSelect->pWin; Window *pWin; Vdbe *v = sqlite3GetVdbe(pParse); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr); + sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr); + sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr); + sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr); + /* Allocate registers to use for PARTITION BY values, if any. Initialize ** said registers to NULL. */ if( pMWin->pPartition ){ @@ -1549,7 +1588,7 @@ static void windowAggStep( /* All OVER clauses in the same window function aggregate step must ** be the same. */ - assert( pWin==pMWin || sqlite3WindowCompare(pParse,pWin,pMWin,0)==0 ); + assert( pWin==pMWin || sqlite3WindowCompare(pParse,pWin,pMWin,0)!=1 ); for(i=0; izName!=nth_valueName ){ diff --git a/test/alter.test b/test/alter.test index a82456d4..0ec485ef 100644 --- a/test/alter.test +++ b/test/alter.test @@ -684,7 +684,7 @@ do_test alter-8.2 { # alter-9.X - Special test: Make sure the sqlite_rename_column() and # rename_table() functions do not crash when handed bad input. # -sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1 +sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db do_test alter-9.1 { execsql {SELECT SQLITE_RENAME_COLUMN(0,0,0,0,0,0,0,0,0)} } {{}} @@ -697,7 +697,7 @@ foreach {tn sql} { catch { execsql $sql } } 1 } -sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0 +sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db # If the INTERNAL_FUNCTIONS test-control is disabled (which is the default), # then the sqlite_rename_table() SQL function is not accessible to ordinary SQL. diff --git a/test/alter3.test b/test/alter3.test index 44b31c98..b16a7f30 100644 --- a/test/alter3.test +++ b/test/alter3.test @@ -54,8 +54,8 @@ proc get_file_format {{fname test.db}} { } do_test alter3-1.1 { + sqlite3_db_config db LEGACY_FILE_FORMAT 1 execsql { - PRAGMA legacy_file_format=ON; CREATE TABLE abc(a, b, c); SELECT sql FROM sqlite_master; } @@ -198,8 +198,8 @@ do_test alter3-4.1 { db close forcedelete test.db set ::DB [sqlite3 db test.db] + sqlite3_db_config db LEGACY_FILE_FORMAT 1 execsql { - PRAGMA legacy_file_format=ON; CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 100); INSERT INTO t1 VALUES(2, 300); diff --git a/test/alter4.test b/test/alter4.test index ca917595..92f33e7a 100644 --- a/test/alter4.test +++ b/test/alter4.test @@ -383,8 +383,8 @@ do_execsql_test alter4-9.3 { do_test alter4-10.1 { db close sqlite3 db :memory: + sqlite3_db_config db LEGACY_FILE_FORMAT 1 db eval { - PRAGMA legacy_file_format=on; CREATE TABLE t1(a,b,c); CREATE INDEX t1a ON t1(a DESC); INSERT INTO t1 VALUES(1,2,3); diff --git a/test/altercol.test b/test/altercol.test index d71a9b06..1479b3a7 100644 --- a/test/altercol.test +++ b/test/altercol.test @@ -618,7 +618,7 @@ foreach {tn trigger error} { #------------------------------------------------------------------------- # Passing invalid parameters directly to sqlite_rename_column(). # -sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1 +sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db do_execsql_test 14.1 { CREATE TABLE ddd(sql, type, object, db, tbl, icol, znew, bquote); INSERT INTO ddd VALUES( @@ -641,7 +641,7 @@ do_execsql_test 14.2 { sqlite_rename_column(sql, type, object, db, tbl, icol, znew, bquote, 0) FROM ddd; } {{} {} {} {}} -sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0 +sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db # If the INTERNAL_FUNCTIONS test-control is disabled (which is the default) # then the sqlite_rename_table() SQL function is not accessible to diff --git a/test/altertab.test b/test/altertab.test index 2eed636e..7dcf8a5e 100644 --- a/test/altertab.test +++ b/test/altertab.test @@ -240,13 +240,13 @@ ifcapable vtab { ); } {} - sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1 + sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db do_execsql_test 7.2 { SELECT sqlite_rename_table(db, 0, 0, sql, zOld, zNew, bTemp) FROM ddd; } {{} {} {}} - sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0 + sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db } #------------------------------------------------------------------------- @@ -542,19 +542,39 @@ ifcapable fts3 { CREATE VIRTUAL TABLE y1 USING fts3; } - do_catchsql_test 16.1 { + do_catchsql_test 16.10 { INSERT INTO y1_segments VALUES(1, X'1234567890'); } {1 {table y1_segments may not be modified}} - do_catchsql_test 16.2 { + do_catchsql_test 16.20 { + DROP TABLE y1_segments; + } {1 {table y1_segments may not be dropped}} + + do_catchsql_test 16.20 { ALTER TABLE y1_segments RENAME TO abc; } {1 {table y1_segments may not be altered}} + sqlite3_db_config db DEFENSIVE 0 + do_catchsql_test 16.22 { + ALTER TABLE y1_segments RENAME TO abc; + } {0 {}} + sqlite3_db_config db DEFENSIVE 1 + do_catchsql_test 16.23 { + CREATE TABLE y1_segments AS SELECT * FROM abc; + } {1 {object name reserved for internal use: y1_segments}} + do_catchsql_test 16.24 { + CREATE VIEW y1_segments AS SELECT * FROM abc; + } {1 {object name reserved for internal use: y1_segments}} + sqlite3_db_config db DEFENSIVE 0 + do_catchsql_test 16.25 { + ALTER TABLE abc RENAME TO y1_segments; + } {0 {}} + sqlite3_db_config db DEFENSIVE 1 - do_execsql_test 16.3 { + do_execsql_test 16.30 { ALTER TABLE y1 RENAME TO z1; } - do_execsql_test 16.4 { + do_execsql_test 16.40 { SELECT * FROM z1_segments; } } diff --git a/test/altertab2.test b/test/altertab2.test index f14dc13f..9c1ad581 100644 --- a/test/altertab2.test +++ b/test/altertab2.test @@ -343,22 +343,21 @@ do_execsql_test 8.4 { CREATE VIEW v4 AS SELECT * FROM t4 WHERE (a=1 AND 0) OR b=2; } -# Do not rename branches of an expression tree that is optimized out by -# the AND optimization. +# Branches of an expression tree that are optimized out by the AND +# optimization are renamed. # do_execsql_test 8.5 { ALTER TABLE t4 RENAME a TO c; SELECT sql FROM sqlite_master WHERE name = 'v4' -} {{CREATE VIEW v4 AS SELECT * FROM t4 WHERE (a=1 AND 0) OR b=2}} -# "a" is not renamed to "c" ---^ +} {{CREATE VIEW v4 AS SELECT * FROM t4 WHERE (c=1 AND 0) OR b=2}} # 2019-06-10 https://www.sqlite.org/src/info/533010b8cacebe82 reset_db -do_execsql_test 8.6 { +do_catchsql_test 8.6 { CREATE TABLE t0(c0); CREATE INDEX i0 ON t0(LIKELIHOOD(1,2) AND 0); ALTER TABLE t0 RENAME TO t1; SELECT sql FROM sqlite_master WHERE name='i0'; -} {{CREATE INDEX i0 ON "t1"(LIKELIHOOD(1,2) AND 0)}} +} {1 {error in index i0: second argument to likelihood() must be a constant between 0.0 and 1.0}} finish_test diff --git a/test/altertab3.test b/test/altertab3.test index 948a351e..b3906558 100644 --- a/test/altertab3.test +++ b/test/altertab3.test @@ -20,7 +20,6 @@ ifcapable !altertable { return } - ifcapable windowfunc { do_execsql_test 1.0 { CREATE TABLE t1(a, b); @@ -381,5 +380,211 @@ do_execsql_test 17.2 { END} } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 18.1 { + CREATE TABLE t1(a,b); + CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN + SELECT a, b FROM t1 + INTERSECT SELECT b,a FROM t1 + ORDER BY b IN ( + SELECT a UNION SELECT b + FROM t1 + ORDER BY b COLLATE nocase + ) + ; + END; +} + +do_catchsql_test 18.2 { + SELECT a, b FROM t1 + INTERSECT + SELECT b,a FROM t1 + ORDER BY b IN ( + SELECT a UNION SELECT b + FROM t1 + ORDER BY b COLLATE nocase + ); +} {1 {1st ORDER BY term does not match any column in the result set}} + +do_catchsql_test 18.3 { + ALTER TABLE t1 RENAME TO t1x; +} {1 {error in trigger r1: 1st ORDER BY term does not match any column in the result set}} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 19.0 { + CREATE TABLE a(a,h CONSTRAINT a UNIQUE ON CONFLICT FAIL,CONSTRAINT a); +} + +foreach {tn v res} { + 1 { + CREATE VIEW q AS SELECT 123 + + WINDOW x AS ( + RANGE BETWEEN UNBOUNDED PRECEDING AND INDEXED() OVER( + PARTITION BY ( WITH x AS(VALUES(col1)) VALUES(453) ) + ) + FOLLOWING + ) + } {1 {error in view q: no such column: col1}} + + 2 { + CREATE VIEW q AS SELECT + CAST(CAST(CAST(CAST(CAST(CAST(CAST(CAST(CAST(CAST(CAST(RIGHT + AS)AS)AS)AS)AS)AS)AS)AS)AS)AS)AS)WINDOW x AS(RANGE BETWEEN UNBOUNDED + PRECEDING AND INDEXED(*)OVER(PARTITION BY + CROSS,CROSS,NATURAL,sqlite_master(*)OVER a,(WITH a AS(VALUES(LEFT)UNION + VALUES(LEFT)UNION VALUES(LEFT)UNION VALUES(LEFT)UNION VALUES(LEFT)UNION + VALUES(LEFT)UNION VALUES(LEFT))VALUES(LEFT))IN + STORED,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT)*LEFT FOLLOWING)ORDER BY + LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT LIMIT + LEFT,INDEXED(*)OVER(PARTITION BY + CROSS,CROSS,CROSS,LEFT,INDEXED(*)OVER(PARTITION BY + CROSS,CROSS,CROSS),INDEXED(*)OVER(PARTITION BY + LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT,LEFT), + LEFT,LEFT,INNER,CROSS,CROSS,CROSS,INNER,NATURAL ORDER BY + OUTER,NATURAL,NATURAL,NATURAL,NATURAL,NATURAL,NATURAL,NATURAL,INNER, + INNER,INNER NULLS LAST GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED + FOLLOWING); + } {1 {error in view q: no such column: LEFT}} + + 3 { + CREATE VIEW q AS SELECT 99 WINDOW x AS (RANGE BETWEEN UNBOUNDED PRECEDING + AND count(*)OVER(PARTITION BY (WITH a AS(VALUES(2),(x3))VALUES(0))) + FOLLOWING)ORDER BY x2,sum(1)OVER(PARTITION BY avg(5)OVER(PARTITION BY x1)); + } {1 {error in view q: no such column: x3}} +} { + do_execsql_test 19.$tn.1 " + DROP VIEW IF EXISTS q; + $v + " {} + + do_catchsql_test 19.$tn.2 { + ALTER TABLE a RENAME TO g; + } $res +} + +# Verify that the "if( pParse->nErr ) return WRC_Abort" at the top of the +# renameUnmapSelectCb() routine in alter.c (2019-12-04) is really required. +# +sqlite3 db :memory: +do_catchsql_test 20.10 { + CREATE TABLE s(a, b, c); + CREATE INDEX k ON s( (WITH s AS( SELECT * ) VALUES(2) ) IN () ); + ALTER TABLE s RENAME a TO a2; +} {1 {error in index k: no tables specified}} + +#------------------------------------------------------------------------ +# +reset_db +do_execsql_test 21.1 { + CREATE TABLE s(col); + CREATE VIEW v AS SELECT ( + WITH x(a) AS(SELECT * FROM s) VALUES(RIGHT) + ) IN() ; + CREATE TABLE a(a); + ALTER TABLE a RENAME a TO b; +} + +#------------------------------------------------------------------------ +# +reset_db +do_execsql_test 22.1 { + CREATE TABLE t1(a); + CREATE VIEW v2(b) AS SELECT * FROM v2; +} + +do_catchsql_test 22.2 { + ALTER TABLE t1 RENAME TO t4; +} {1 {error in view v2: view v2 is circularly defined}} + +do_execsql_test 22.3 { + DROP VIEW v2; + CREATE VIEW v2(b) AS WITH t3 AS (SELECT b FROM v2) SELECT * FROM t3; +} + +do_catchsql_test 22.4 { + ALTER TABLE t1 RENAME TO t4; +} {1 {error in view v2: view v2 is circularly defined}} + +do_execsql_test 22.5 { + DROP VIEW v2; + CREATE VIEW v2(b) AS WITH t3 AS (SELECT b FROM v2) VALUES(1); +} + +do_catchsql_test 22.6 { + ALTER TABLE t1 RENAME TO t4; +} {0 {}} + +#------------------------------------------------------------------------ +# +reset_db +do_execsql_test 23.1 { + CREATE TABLE t1(x); + CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN + UPDATE t1 SET (c,d)=((SELECT 1 FROM t1 JOIN t2 ON b=x),1); + END; +} + +do_catchsql_test 23.2 { + ALTER TABLE t1 RENAME TO t1x; +} {1 {error in trigger r1: no such table: main.t2}} + +#------------------------------------------------------------------------ +# +reset_db +do_execsql_test 23.1 { + CREATE TABLE v0 (a); + CREATE VIEW v2 (v3) AS + WITH x1 AS (SELECT * FROM v2) + SELECT v3 AS x, v3 AS y FROM v2; +} + +do_catchsql_test 23.2 { + SELECT * FROM v2 +} {1 {view v2 is circularly defined}} + +db close +sqlite3 db test.db + +do_catchsql_test 23.3 { + ALTER TABLE v0 RENAME TO t3 ; +} {1 {error in view v2: view v2 is circularly defined}} + +#------------------------------------------------------------------------ +# +reset_db +do_execsql_test 24.1 { + CREATE TABLE v0 (v1); + CREATE TABLE v2 (v3 INTEGER UNIQUE ON CONFLICT ABORT); + CREATE TRIGGER x AFTER INSERT ON v2 WHEN ( + ( SELECT v1 AS PROMO_REVENUE FROM v2 JOIN v0 USING ( VALUE ) ) AND 0 ) + BEGIN + DELETE FROM v2; + END; +} +do_catchsql_test 24.2 { + ALTER TABLE v0 RENAME TO x ; +} {1 {error in trigger x: cannot join using column VALUE - column not present in both tables}} + +do_execsql_test 24.3 { + DROP TRIGGER x; + CREATE TRIGGER x AFTER INSERT ON v2 WHEN ( + 0 AND (SELECT rowid FROM v0) + ) BEGIN + DELETE FROM v2; + END; +} + +do_execsql_test 24.4 { + ALTER TABLE v0 RENAME TO xyz; + SELECT sql FROM sqlite_master WHERE type='trigger' +} {{CREATE TRIGGER x AFTER INSERT ON v2 WHEN ( + 0 AND (SELECT rowid FROM "xyz") + ) BEGIN + DELETE FROM v2; + END}} finish_test + diff --git a/test/atof1.test b/test/atof1.test index 55f5e44d..34e69c12 100644 --- a/test/atof1.test +++ b/test/atof1.test @@ -56,5 +56,29 @@ for {set i 1} {$i<20000} {incr i} { } {1} } +# 2020-01-08 ticket 9eda2697f5cc1aba +# When running sqlite3AtoF() on a blob with an odd number of bytes using +# UTF16, ignore the last byte so that the string has an integer number of +# UTF16 code points. +# +reset_db +do_execsql_test atof1-2.10 { + PRAGMA encoding = 'UTF16be'; + CREATE TABLE t1(a, b); + INSERT INTO t1(rowid,a) VALUES (1,x'00'),(2,3); + SELECT substr(a,',') is true FROM t1 ORDER BY rowid; +} {0 1} +do_execsql_test atof1-2.20 { + SELECT substr(a,',') is true FROM t1 ORDER BY rowid DESC; +} {1 0} +do_execsql_test atof1-2.30 { + CREATE INDEX i1 ON t1(a); + SELECT count(*) FROM t1 WHERE substr(a,','); +} {1} + + + + + finish_test diff --git a/test/attach4.test b/test/attach4.test index 77dd7e41..87911814 100644 --- a/test/attach4.test +++ b/test/attach4.test @@ -115,4 +115,24 @@ do_test 1.8 { db close foreach {name f} $files { forcedelete $f } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + ATTACH DATABASE '' AS aux; + CREATE TABLE IF NOT EXISTS aux.t1(a, b); + CREATE TEMPORARY TRIGGER tr1 DELETE ON t1 BEGIN + DELETE FROM t1; + END; + CREATE TABLE temp.t1(a, b); +} + +do_execsql_test 2.1 { + DETACH DATABASE aux; +} + +do_execsql_test 2.2 { + DROP TRIGGER tr1; +} + finish_test + diff --git a/test/cast.test b/test/cast.test index e6795ce4..d2eaffcb 100644 --- a/test/cast.test +++ b/test/cast.test @@ -461,6 +461,18 @@ do_execsql_test cast-7.43 { SELECT CAST('-1.0' AS numeric); } -1 +ifcapable utf16 { + reset_db + execsql { PRAGMA encoding='utf16' } + + do_execsql_test cast-8.1 { + SELECT quote(X'310032003300')==quote(substr(X'310032003300', 1)) + } 1 + do_execsql_test cast-8.2 { + SELECT CAST(X'310032003300' AS TEXT) + ==CAST(substr(X'310032003300', 1) AS TEXT) + } 1 +} finish_test diff --git a/test/check.test b/test/check.test index e23043eb..3e16b9dc 100644 --- a/test/check.test +++ b/test/check.test @@ -11,7 +11,6 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing CHECK constraints # -# $Id: check.test,v 1.13 2009/06/05 17:09:12 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -442,7 +441,7 @@ do_test check-6.15 { # reset_db proc myfunc {x} {expr $x < 10} -db func myfunc myfunc +db func myfunc -deterministic myfunc do_execsql_test 7.1 { CREATE TABLE t6(a CHECK (myfunc(a))) } do_execsql_test 7.2 { INSERT INTO t6 VALUES(9) } @@ -536,7 +535,71 @@ do_execsql_test 11.6 { INSERT INTO t2(b, a) VALUES(2, 'abc'); } -finish_test - +# 2019-12-24 ticket b383b90278186263 +# +reset_db +do_execsql_test 12.10 { + CREATE TABLE t1(a TEXT, CHECK(a=+a)); + INSERT INTO t1(a) VALUES(NULL),('xyz'),(5),(x'303132'),(4.75); + SELECT quote(a) FROM t1 ORDER BY rowid; +} {NULL 'xyz' '5' X'303132' '4.75'} +do_execsql_test 12.20 { + DROP TABLE t1; + CREATE TABLE t1(a TEXT, CHECK(a<>+a)); + INSERT INTO t1(a) VALUES(NULL); +} {} +do_catchsql_test 12.21 { + INSERT INTO t1(a) VALUES('xyz'); +} {1 {CHECK constraint failed: t1}} +do_catchsql_test 12.22 { + INSERT INTO t1(a) VALUES(123); +} {1 {CHECK constraint failed: t1}} +do_execsql_test 12.30 { + DROP TABLE t1; + CREATE TABLE t1(a TEXT, CHECK(NOT(a=+a))); + INSERT INTO t1(a) VALUES(NULL); +} {} +do_catchsql_test 12.31 { + INSERT INTO t1(a) VALUES('xyz'); +} {1 {CHECK constraint failed: t1}} +do_catchsql_test 12.32 { + INSERT INTO t1(a) VALUES(123); +} {1 {CHECK constraint failed: t1}} +do_execsql_test 12.40 { + DROP TABLE t1; + CREATE TABLE t1(a TEXT, CHECK(NOT(a<>+a))); + INSERT INTO t1(a) VALUES(NULL),('xyz'),(5),(x'303132'),(4.75); + SELECT quote(a) FROM t1 ORDER BY rowid; +} {NULL 'xyz' '5' X'303132' '4.75'} +do_execsql_test 12.50 { + DROP TABLE t1; + CREATE TABLE t1(a TEXT, CHECK(a BETWEEN 0 AND +a)); + INSERT INTO t1(a) VALUES(NULL),('xyz'),(5),(x'303132'),(4.75); + SELECT quote(a) FROM t1 ORDER BY rowid; +} {NULL 'xyz' '5' X'303132' '4.75'} +do_execsql_test 12.60 { + DROP TABLE t1; + CREATE TABLE t1(a TEXT, CHECK(a NOT BETWEEN 0 AND +a)); + INSERT INTO t1(a) VALUES(NULL); + SELECT quote(a) FROM t1 ORDER BY rowid; +} {NULL} +do_catchsql_test 12.61 { + INSERT INTO t1(a) VALUES(456); +} {1 {CHECK constraint failed: t1}} +do_execsql_test 12.70 { + DROP TABLE t1; + CREATE TABLE t1(a TEXT, CHECK(a BETWEEN +a AND 999999)); + INSERT INTO t1(a) VALUES(NULL),(5); + SELECT quote(a) FROM t1 ORDER BY rowid; +} {NULL '5'} +do_execsql_test 12.80 { + DROP TABLE t1; + CREATE TABLE t1(a TEXT, CHECK(a NOT BETWEEN +a AND 999999)); + INSERT INTO t1(a) VALUES(NULL); + SELECT quote(a) FROM t1 ORDER BY rowid; +} {NULL} +do_catchsql_test 12.81 { + INSERT INTO t1(a) VALUES(456); +} {1 {CHECK constraint failed: t1}} finish_test diff --git a/test/collate1.test b/test/collate1.test index a1623f07..007dd7c3 100644 --- a/test/collate1.test +++ b/test/collate1.test @@ -417,4 +417,35 @@ do_execsql_test 8.2 { SELECT * FROM t0 WHERE c1 = 1; } {{ } 1} +# 2019-10-09 +# ALWAYS() macro fails following OOM +# Problem detected by dbsqlfuzz. +# +do_execsql_test 9.0 { + CREATE TABLE t1(a, b); + CREATE TABLE t2(c, d); +} + +do_faultsim_test 9.1 -faults oom* -body { + execsql { + SELECT * FROM ( + SELECT b COLLATE nocase IN (SELECT c FROM t2) FROM t1 + ); + } +} -test { + faultsim_test_result {0 {}} +} + +# 2020-01-03 dbsqlfuzz find +# +reset_db +do_catchsql_test 10.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY,b); + INSERT INTO t1 VALUES(0,NULL); + CREATE TABLE t2(x UNIQUE); + CREATE VIEW v1a(z,y) AS SELECT x COLLATE x FROM t2; + SELECT a,b,z,y,'' FROM t1 JOIN v1a ON b IS NOT FALSE; +} {1 {no such collation sequence: x}} + + finish_test diff --git a/test/conflict.test b/test/conflict.test index 136bc3fe..b86f8602 100644 --- a/test/conflict.test +++ b/test/conflict.test @@ -834,5 +834,27 @@ do_catchsql_test conflict-14.1 { REPLACE INTO t1 DEFAULT VALUES; } {1 {NOT NULL constraint failed: t1.x}} +# 2019-12-15 gramfuzz1 find +# Three UNIQUE constraints, where the third would is a duplicate except +# that it adds ON CONFLICT REPLACE. Verify that the indexes end up +# sorted in the correct order (REPLACE last) so that constraint processing +# works correctly. +# +reset_db +do_execsql_test conflict-15.10 { + CREATE TABLE t1( + x PRIMARY KEY, + UNIQUE(x,x), + UNIQUE(x,x) ON CONFLICT REPLACE + ); + INSERT INTO t1(x) VALUES(1); + SELECT * FROM t1; +} {1} +do_catchsql_test conflict-15.20 { + INSERT INTO t1(x) VALUES(1); +} {1 {UNIQUE constraint failed: t1.x}} +do_execsql_test conflict-15.30 { + SELECT * FROM t1; +} {1} finish_test diff --git a/test/conflict3.test b/test/conflict3.test index 413e8241..8eb4c1b0 100644 --- a/test/conflict3.test +++ b/test/conflict3.test @@ -380,15 +380,15 @@ ifcapable trigger { INSERT INTO t0 VALUES(0, NULL); } - do_execsql_test 13.1.1 { + do_catchsql_test 13.1.1 { UPDATE OR REPLACE t0 SET c1 = 1; - } + } {1 {constraint failed}} integrity_check 13.1.2 do_execsql_test 13.1.3 { SELECT * FROM t0 - } {} + } {1 {} 0 {}} do_execsql_test 13.2.0 { CREATE TABLE t2 (a PRIMARY KEY, b UNIQUE, c UNIQUE) WITHOUT ROWID; @@ -400,15 +400,15 @@ ifcapable trigger { INSERT INTO t2 VALUES(2, 2, 2); } - do_execsql_test 13.2.1 { + do_catchsql_test 13.2.1 { UPDATE OR REPLACE t2 SET c = 0; - } + } {1 {constraint failed}} integrity_check 13.2.2 do_execsql_test 13.2.3 { SELECT * FROM t2 - } {} + } {1 1 1 2 2 2} do_execsql_test 13.3.0 { CREATE TABLE t1(a, b); @@ -435,4 +435,3 @@ ifcapable trigger { } finish_test - diff --git a/test/corruptC.test b/test/corruptC.test index d151a273..a56abeec 100644 --- a/test/corruptC.test +++ b/test/corruptC.test @@ -34,9 +34,9 @@ database_may_be_corrupt # Construct a compact, dense database for testing. # do_test corruptC-1.1 { + sqlite3_db_config db LEGACY_FILE_FORMAT 1 execsql { PRAGMA auto_vacuum = 0; - PRAGMA legacy_file_format=1; BEGIN; CREATE TABLE t1(x,y); INSERT INTO t1 VALUES(1,1); diff --git a/test/corruptE.test b/test/corruptE.test index 54aa420f..8c55623e 100644 --- a/test/corruptE.test +++ b/test/corruptE.test @@ -36,9 +36,9 @@ ifcapable oversize_cell_check { # Construct a compact, dense database for testing. # do_test corruptE-1.1 { + sqlite3_db_config db LEGACY_FILE_FORMAT 1 execsql { PRAGMA auto_vacuum = 0; - PRAGMA legacy_file_format=1; BEGIN; CREATE TABLE t1(x,y); INSERT INTO t1 VALUES(1,1); diff --git a/test/corruptL.test b/test/corruptL.test index b0ad66db..72aedd9a 100644 --- a/test/corruptL.test +++ b/test/corruptL.test @@ -1071,4 +1071,72 @@ do_catchsql_test 11.1 { DELETE FROM t3 WHERE x IN (SELECT x FROM t4); } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +reset_db +do_test 12.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 12288 pagesize 4096 filename crash-e6d070858a3a85.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........ +| 96: 00 00 00 00 0d 00 00 00 02 0f 8f 00 0f bf 0f 8f ................ +| 3968: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2e ................ +| 3984: 02 06 17 15 11 01 45 69 6e 64 65 78 74 31 63 62 ......Eindext1cb +| 4000: 74 31 03 43 52 45 41 54 45 20 49 4e 44 45 58 20 t1.CREATE INDEX +| 4016: 74 31 63 62 20 4f 4e 20 74 31 28 63 2c 62 29 3f t1cb ON t1(c,b)? +| 4032: 01 06 17 11 11 01 6b 74 61 62 6c 65 74 31 74 31 ......ktablet1t1 +| 4048: 02 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 31 .CREATE TABLE t1 +| 4064: 28 61 20 49 4e 54 2c 20 62 20 49 4e 54 2c 20 43 (a INT, b INT, C +| 4080: 20 49 4e 54 20 44 45 46 41 55 4c 54 20 31 36 29 INT DEFAULT 16) +| page 2 offset 4096 +| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4000: 00 00 00 00 00 00 00 00 07 0b 04 01 01 01 63 63 ..............cc +| 4016: 11 05 0a 04 00 00 01 11 05 09 04 08 08 01 0f 05 ................ +| 4032: 08 04 00 00 01 01 56 07 04 01 08 01 07 10 07 06 ......V......... +| 4048: 14 01 01 01 06 08 10 06 05 04 f5 00 01 05 10 07 ................ +| 4064: 04 04 01 01 01 04 03 10 06 03 04 01 09 01 03 10 ................ +| 4080: 06 02 04 01 00 01 02 10 06 01 04 09 01 01 02 10 ................ +| page 3 offset 8192 +| 0: 0a 00 00 00 0b 0f b0 00 0f f9 0f f2 0f eb 0f e4 ................ +| 16: 0f dd 0f d6 0f 9f 0f c7 0f be 00 00 00 00 00 00 ................ +| 4016: 07 04 01 01 01 11 e2 0b 06 04 91 00 01 11 0a 07 ................ +| 4032: 04 01 01 01 10 08 06 07 04 01 01 01 10 04 04 06 ................ +| 4048: 04 01 01 09 10 02 06 04 01 0a 01 10 00 00 00 00 ................ +| end crash-e6d070858a3a85.db +}]} {} + +do_catchsql_test 12.1 { + SELECT CAST((SELECT b FROM t1 WHERE 16=c) AS int) FROM t1 WHERE 16=c; +} {1 {database disk image is malformed}} + +#------------------------------------------------------------------------- +reset_db +do_test 13.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 8192 pagesize 4096 filename crash-81dd2952aef34f.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 02 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................ +| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 96: 00 00 00 00 0d 00 00 00 01 0f c4 00 0f c4 00 00 ................ +| 4032: 00 00 00 00 3a 11 06 17 11 11 01 61 74 61 62 6c ....:......atabl +| 4048: 65 74 31 74 31 02 43 52 45 41 54 45 20 54 41 42 et1t1.CREATE TAB +| 4064: 4c 45 20 74 31 28 61 20 49 4e 54 45 47 45 52 20 LE t1(a INTEGER +| 4080: 50 52 49 4d 41 52 59 20 4b 45 59 2c 62 2c 63 29 PRIMARY KEY,b,c) +| page 2 offset 4096 +| 0: 0d 07 70 00 02 0f eb 00 0f fa 00 00 00 00 00 00 ..p............. +| 4064: 00 00 00 00 00 00 00 00 00 00 00 05 bf ff ff ff ................ +| 4080: ff ff ff ff ff 04 00 01 00 02 04 01 00 00 00 00 ................ +| end crash-81dd2952aef34f.db +}]} {} + +do_catchsql_test 13.1 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x-2019 FROM c WHERE x<2) + INSERT INTO t1(b,c) SELECT last_insert_rowid(), x FROM c; +} {1 {database disk image is malformed}} + + finish_test diff --git a/test/date2.test b/test/date2.test index 2815df5e..820420cc 100644 --- a/test/date2.test +++ b/test/date2.test @@ -30,7 +30,7 @@ do_execsql_test date2-100 { } {} do_catchsql_test date2-110 { INSERT INTO t1(x,y) VALUES('now','two'); -} {1 {non-deterministic function in index expression or CHECK constraint}} +} {1 {non-deterministic use of date() in a CHECK constraint}} do_execsql_test date2-120 { SELECT * FROM t1; } {2017-07-20 one} @@ -45,7 +45,7 @@ do_execsql_test date2-200 { } do_catchsql_test date2-210 { INSERT INTO t2(x,y) VALUES(3, 'now'); -} {1 {non-deterministic function in index expression or CHECK constraint}} +} {1 {non-deterministic use of date() in an index}} do_execsql_test date2-220 { SELECT x, y FROM t2 ORDER BY x; } {1 2017-07-20 2 xyzzy} @@ -58,7 +58,7 @@ do_execsql_test date2-300 { } do_catchsql_test date2-310 { CREATE INDEX t3b1 ON t3(datetime(b)); -} {1 {non-deterministic function in index expression or CHECK constraint}} +} {1 {non-deterministic use of datetime() in an index}} do_catchsql_test date2-320 { CREATE INDEX t3b1 ON t3(datetime(b)) WHERE typeof(b)='real'; } {0 {}} @@ -84,7 +84,7 @@ do_execsql_test date2-400 { do_catchsql_test date2-410 { CREATE INDEX t4b1 ON t4(b) WHERE date(b) BETWEEN '2017-06-01' AND '2017-08-31'; -} {1 {non-deterministic function in index expression or CHECK constraint}} +} {1 {non-deterministic use of date() in an index}} do_execsql_test date2-420 { DELETE FROM t4 WHERE a=500; CREATE INDEX t4b1 ON t4(b) @@ -92,7 +92,7 @@ do_execsql_test date2-420 { } do_catchsql_test date2-430 { INSERT INTO t4(a,b) VALUES(9999,'now'); -} {1 {non-deterministic function in index expression or CHECK constraint}} +} {1 {non-deterministic use of date() in an index}} do_execsql_test date2-500 { CREATE TABLE mods(x); @@ -121,14 +121,49 @@ do_execsql_test date2-500 { } do_catchsql_test date2-510 { INSERT INTO t5(y,m) VALUES('2017-07-20','localtime'); -} {1 {non-deterministic function in index expression or CHECK constraint}} +} {1 {non-deterministic use of datetime() in an index}} do_catchsql_test date2-520 { INSERT INTO t5(y,m) VALUES('2017-07-20','utc'); -} {1 {non-deterministic function in index expression or CHECK constraint}} +} {1 {non-deterministic use of datetime() in an index}} + +# 2019-10-30 Ticket 830277d9db6c3ba1 +# +do_catchsql_test date2-600 { + CREATE TABLE t600(a REAL CHECK( a(b=3 AND 0),a) + FROM dual LEFT JOIN t1; +} {0} +do_execsql_test expr-16.101 { + SELECT implies_nonnull_row( (b=1 AND 0)>(b=3 AND a=4),a) + FROM dual LEFT JOIN t1; +} {1} +do_execsql_test expr-16.102 { + SELECT implies_nonnull_row( (b=1 AND a=2)>(b=3 AND a=4),a) + FROM dual LEFT JOIN t1; +} {1} + finish_test diff --git a/test/filter1.test b/test/filter1.test index 9309b744..ee17099d 100644 --- a/test/filter1.test +++ b/test/filter1.test @@ -184,5 +184,24 @@ do_execsql_test 5.3 { SELECT count(*) FILTER (WHERE b>2) OVER (ORDER BY b) FROM (SELECT * FROM t1) } {0 1} -finish_test +#------------------------------------------------------------------------- +reset_db +do_execsql_test 6.0 { + CREATE TABLE t1(a,b); + INSERT INTO t1 VALUES(1,1); + INSERT INTO t1 VALUES(2,2); + CREATE TABLE t2(x,y); + INSERT INTO t2 VALUES(1,1); +} +do_execsql_test 6.1 { + SELECT (SELECT COUNT(a) FILTER(WHERE x) FROM t2) FROM t1; +} {1 1} +do_execsql_test 6.2 { + SELECT (SELECT COUNT(a+x) FROM t2) FROM t1; +} {1 1} +do_execsql_test 6.3 { + SELECT (SELECT COUNT(a) FROM t2) FROM t1; +} {2} + +finish_test diff --git a/test/fkey2.test b/test/fkey2.test index 86316f29..e7fa7b64 100644 --- a/test/fkey2.test +++ b/test/fkey2.test @@ -987,7 +987,7 @@ ifcapable altertable { 'main', 'table', 't1', $zCreate, $zOld, $zNew, 0 )} } - sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1 + sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db do_test fkey2-14.2.1.1 { test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3 } {{CREATE TABLE t1(a REFERENCES "t3")}} @@ -997,7 +997,7 @@ ifcapable altertable { do_test fkey2-14.2.1.3 { test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3 } {{CREATE TABLE t1(a REFERENCES "t3")}} - sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0 + sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db # Test ALTER TABLE RENAME TABLE a bit. # @@ -1070,7 +1070,7 @@ ifcapable altertable { } } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}} - sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1 + sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db do_test fkey2-14.2tmp.1.1 { test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3 } {{CREATE TABLE t1(a REFERENCES "t3")}} @@ -1080,7 +1080,7 @@ ifcapable altertable { do_test fkey2-14.2tmp.1.3 { test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3 } {{CREATE TABLE t1(a REFERENCES "t3")}} - sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0 + sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db # Test ALTER TABLE RENAME TABLE a bit. # @@ -1154,7 +1154,7 @@ ifcapable altertable { } } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}} - sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1 + sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db do_test fkey2-14.2aux.1.1 { test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3 } {{CREATE TABLE t1(a REFERENCES "t3")}} @@ -1164,7 +1164,7 @@ ifcapable altertable { do_test fkey2-14.2aux.1.3 { test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3 } {{CREATE TABLE t1(a REFERENCES "t3")}} - sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0 + sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db # Test ALTER TABLE RENAME TABLE a bit. # diff --git a/test/format4.test b/test/format4.test index 14d79470..a850ce2e 100644 --- a/test/format4.test +++ b/test/format4.test @@ -17,7 +17,8 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -db eval {PRAGMA legacy_file_format=OFF} +#db eval {PRAGMA legacy_file_format=OFF} +sqlite3_db_config db LEGACY_FILE_FORMAT 0 # The size of the database depends on whether or not autovacuum # is enabled. diff --git a/test/fts3atoken.test b/test/fts3atoken.test index 1dccf412..4981480b 100644 --- a/test/fts3atoken.test +++ b/test/fts3atoken.test @@ -129,6 +129,29 @@ do_test fts3atoken-1.9 { } } {1 blob blob blob blob} +# 2019-12-31: The fts3_tokenizer() function can never be invoked from +# within a trigger or view. +# +do_catchsql_test fts3atoken-1.10 { + CREATE VIEW v110(x) AS + SELECT fts3_tokenizer('tok110', fts3_tokenizer('simple')) IS NULL; +} {0 {}} +do_catchsql_test fts3atoken-1.11 { + SELECT * FROM v110; +} {1 {unsafe use of fts3_tokenizer()}} +do_catchsql_test fts3atoken-1.12 { + CREATE TABLE t110(a,b); + CREATE TRIGGER r110 AFTER INSERT ON t110 BEGIN + SELECT fts3_tokenizer('tok110', fts3_tokenizer('simple')) IS NULL; + END; +} {0 {}} +do_catchsql_test fts3atoken-1.13 { + INSERT INTO t110(a,b) VALUES(1,2); +} {1 {unsafe use of fts3_tokenizer()}} +do_catchsql_test fts3atoken-1.14 { + SELECT * FROM t110; +} {0 {}} + #-------------------------------------------------------------------------- # Test cases fts3atoken-2.* test error cases in the scalar function based # API for getting and setting tokenizers. diff --git a/test/fts3auto.test b/test/fts3auto.test index 4abf06ff..19193973 100644 --- a/test/fts3auto.test +++ b/test/fts3auto.test @@ -570,6 +570,13 @@ foreach {tn create} { do_fts3query_test 4.$tn.4.3 -deferred fi* t1 {on* NEAR/1 fi*} do_fts3query_test 4.$tn.4.4 -deferred fi* t1 {on* NEAR/2 fi*} do_fts3query_test 4.$tn.4.5 -deferred fi* t1 {on* NEAR/3 fi*} + + ifcapable fts4_deferred { + db eval {UPDATE t1_stat SET value=x'' WHERE id=0} + do_catchsql_test 4.$tn.4.6 { + SELECT docid FROM t1 WHERE t1 MATCH 'on* NEAR/3 fi*' + } {1 {database disk image is malformed}} + } } #-------------------------------------------------------------------------- diff --git a/test/fts3corrupt.test b/test/fts3corrupt.test index 664b1393..4019509a 100644 --- a/test/fts3corrupt.test +++ b/test/fts3corrupt.test @@ -165,5 +165,20 @@ do_catchsql_test 5.3 { } {1 {database disk image is malformed}} do_test 5.3.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB +# 2019-11-18 https://bugs.chromium.org/p/chromium/issues/detail?id=1025467 +# bug1 +db close +sqlite3 db :memory: +do_catchsql_test 6.10 { + CREATE VIRTUAL TABLE f using fts3(a,b); + CREATE TABLE f_stat(id INTEGER PRIMARY KEY, value BLOB); + INSERT INTO f_segdir VALUES (2000, 0,0,0, '16', ''); + INSERT INTO f_segdir VALUES (1999, 0,0,0, '0 18', + x'000131030102000103323334050101010200'); + INSERT INTO f_segments (blockid) values (16); + INSERT INTO f_segments values (0, x''); + INSERT INTO f_stat VALUES (1,x'cf0f01'); + INSERT INTO f(f) VALUES ("merge=1"); +} {1 {database disk image is malformed}} finish_test diff --git a/test/fts3corrupt4.test b/test/fts3corrupt4.test index 3aecc296..7404ddeb 100644 --- a/test/fts3corrupt4.test +++ b/test/fts3corrupt4.test @@ -4139,7 +4139,7 @@ do_catchsql_test 24.1 { PRAGMA writable_schema = 1; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT '4hE'+x FROM c WHERE x<72) INSERT INTO t1(a) SELECT randomblob(2829) FROM c; -} {0 {}} +} {1 {database disk image is malformed}} do_catchsql_test 24.2 { UPDATE t1 SET b=quote((true) ) WHERE t1 MATCH 'h'; @@ -4148,7 +4148,7 @@ do_catchsql_test 24.2 { do_catchsql_test 24.3 { WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT 3+x FROM c WHERE x<72) INSERT INTO t1(a) SELECT randomblob(2829) FROM c; -} {0 {}} +} {1 {database disk image is malformed}} do_catchsql_test 24.4 { WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT null<.$.. +| 80: 0b 48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .H.............. +| 2880: 00 00 00 00 00 00 00 00 81 3f 25 06 00 82 7f 00 .........?%..... +| 2896: 00 43 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e .COMPILER=gcc-5. +| 2912: 34 2e 30 20 32 30 31 36 30 36 30 39 20 44 45 42 4.0 20160609 DEB +| 2928: 55 47 20 45 4e 41 42 4c 45 20 44 42 53 54 7e 54 UG ENABLE DBST~T +| 2944: 20 56 54 41 42 20 45 4e 41 42 4c 45 20 46 54 53 VTAB ENABLE FTS +| 2960: 44 20 45 4e 41 42 4c 45 20 46 54 53 35 20 45 4e D ENABLE FTS5 EN +| 2976: 41 42 4c 45 20 47 45 4f 50 4f 4c 59 20 45 4e 41 ABLE GEOPOLY ENA +| 2992: 42 4c 45 20 4a 53 4f 4e 31 20 45 4e 41 42 4c 45 BLE JSON1 ENABLE +| 3008: 20 4d 45 4d 53 59 53 35 20 45 4e 41 42 4c 45 20 MEMSYS5 ENABLE +| 3024: 52 54 52 45 45 20 4d 41 58 20 4d 45 4d 4f 52 59 RTREE MAX MEMORY +| 3040: 3d 35 30 30 30 30 30 30 30 20 4f 4d 49 54 20 4c =50000000 OMIT L +| 3056: 4f 41 44 20 45 58 54 45 4e 53 49 4f 4e 20 54 48 OAD EXTENSION TH +| 3072: 52 45 41 44 53 41 46 45 3d 30 18 24 05 00 25 0f READSAFE=0.$..%. +| 3088: 19 54 48 52 45 41 44 54 41 46 45 3d 30 58 42 49 .THREADTAFE=0XBI +| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA +| 3120: 44 53 41 46 45 3d 30 bd 4e 4f 43 41 53 45 17 22 DSAFE=0.NOCASE.. +| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d ..%..THREADSAFE= +| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM +| 3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 4e IT LOAD EXTENSIN +| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O +| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI +| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3.. +| 3232: 4f 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMIT LOAD EXTENS +| 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 0f 19 IONXRTRIM....3.. +| 3264: 4d 41 58 1f 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX.MEMORY=50000 +| 3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f 000XBINARY....3. +| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000 +| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 33 0000XNOCASE....3 +| 3328: 0f 17 4d 41 58 20 4d 44 4d 4f 52 59 3d 35 30 30 ..MAX MDMORY=500 +| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....% +| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB +| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3392: 4c 55 20 52 54 52 45 45 58 4e 4f 43 41 53 45 17 LU RTREEXNOCASE. +| 3408: 19 05 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 ...%..ENABLE RTR +| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E +| 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 NABLE MEMSYS5XBI +| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL +| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 3f 43 41 53 45 E MEMSYS5XN?CASE +| 3488: 19 16 05 00 29 0f 17 45 4e a1 42 4c 45 20 4d 45 ....)..EN.BLE ME +| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 00 25 MSYS5XRTRIM....% +| 3520: 0f 19 45 4e 41 42 4c 45 20 4a 53 4f 4e 31 58 42 ..ENABLE JSON1XB +| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3552: 4c 45 20 4a 53 4f 4e 31 58 4e 4f 43 41 53 45 17 LE JSON1XNOCASE. +| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO +| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E +| 3600: 4e 41 42 4c 45 20 47 45 4f 50 5f 4c 59 58 42 49 NABLE GEOP_LYXBI +| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL +| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4b bf 43 41 53 45 E GEOPOLYXK.CASE +| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE +| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....# +| 3680: 0f 19 45 4e 41 42 4c 55 20 46 54 53 35 58 42 49 ..ENABLU FTS5XBI +| 3696: 4e 4b a2 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NK.Y....#..ENABL +| 3712: 45 20 46 54 52 35 58 4e 4f 43 41 53 45 16 0d 05 E FTR5XNOCASE... +| 3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X +| 3744: 52 54 52 49 4d 17 0b 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB +| 3760: 4c 45 20 46 54 53 34 58 42 49 4e 41 52 59 17 0b LE FTS4XBINARY.. +| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4 +| 3792: 58 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e XNOCASE....#..EN +| 3808: 41 42 4c 45 20 46 54 53 34 58 52 54 52 49 4d 1e ABLE FTS4XRTRIM. +| 3824: 09 05 07 e1 0f 19 45 4e 41 42 4c 45 20 44 42 53 ......ENABLE DBS +| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY. +| 3856: 18 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3872: 54 41 54 20 56 54 41 41 18 4e 4f 43 41 53 45 1d TAT VTAA.NOCASE. +| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 32 53 ...1..ENABLE D2S +| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 TAT VTABXRTRIM.. +| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52 .....DEBUGXBINAR +| 3936: 59 11 05 05 00 17 0f 19 44 45 00 00 00 00 00 00 Y.......DE...... +| page 5 offset 16384 +| 0: 0d 00 00 00 02 0b a0 00 0c ad 0b a0 01 00 00 00 ................ +| 2976: 82 0a 02 08 08 09 08 08 17 84 06 30 20 32 35 33 ...........0 253 +| 2992: 00 01 30 04 25 06 1b 00 00 08 32 30 31 36 30 36 ..0.%.....201606 +| 3008: 30 38 03 25 07 00 00 01 34 03 25 05 00 00 01 35 08.%....4.%....5 +| 3024: 03 25 13 00 01 07 30 30 30 30 30 30 30 03 25 1a .%....0000000.%. +| 3040: 00 00 08 63 6f 6d 70 69 6c 65 72 03 25 02 00 00 ...compiler.%... +| 3056: 06 64 62 73 74 61 74 03 25 0a 00 01 04 65 62 75 .dbstat.%....ebu +| 3072: 67 03 25 08 00 00 06 65 6e 61 62 6c 65 09 25 09 g.%....enable.%. +| 3088: 05 04 04 04 04 04 00 01 08 78 74 65 6e 73 69 6f .........xtensio +| 3104: 6e 03 25 1d 00 00 04 66 74 73 34 03 25 0d 00 03 n.%....fts4.%... +| 3120: 01 35 03 25 0f 00 00 03 67 63 63 03 25 03 00 01 .5.%....gcc.%... +| 3136: 06 65 6f 70 6f 6c 79 03 25 11 00 00 05 6a 73 6f .eopoly.%....jso +| 3152: 6e 31 03 25 13 00 00 04 6c 6f 61 64 03 25 1c 00 n1.%....load.%.. +| 3168: 00 03 6d 62 78 03 25 18 00 01 05 65 6d 6f 72 79 ..mbx.%....emory +| 3184: 03 25 19 00 03 04 73 c8 73 35 03 25 15 00 00 04 .%....s.s5.%.... +| 3200: 6f 6d 69 74 03 25 1b 00 00 05 72 74 72 65 65 03 omit.%....rtree. +| 3216: 25 17 00 00 0a 74 68 72 65 61 64 73 61 66 65 03 %....threadsafe. +| 3232: 25 1e 00 00 04 76 74 61 62 03 25 0b 00 86 50 01 %....vtab.%...P. +| 3248: 08 08 08 08 08 17 8d 12 30 20 38 33 35 00 01 30 ........0 835..0 +| 3264: 12 01 06 00 01 06 00 01 06 00 1f 03 00 01 03 00 ................ +| 3280: 01 03 00 00 08 32 30 31 36 30 36 30 39 09 01 07 .....20160609... +| 3296: 00 01 07 00 01 07 00 00 01 34 09 01 05 00 01 05 .........4...... +| 3312: 00 01 05 00 00 01 35 09 01 04 00 01 04 00 02 04 ......5......... +| 3328: 00 01 07 30 2f 30 30 30 30 30 09 1c 04 00 01 04 ...0/00000...... +| 3344: 00 01 04 00 00 06 62 69 6e 61 72 79 3c 03 01 02 ......binary<... +| 3360: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................ +| 3376: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 ................ +| 3392: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 ................ +| 3408: 01 02 02 00 03 01 02 02 00 00 08 63 6f 6d 70 69 ...........compi +| 3424: 6c 65 72 09 01 02 00 01 02 00 01 02 00 00 06 64 ler............d +| 3440: 62 73 74 61 74 09 07 03 00 01 03 00 01 03 00 01 bstat........... +| 3456: 04 65 62 75 67 09 04 02 00 01 02 00 01 02 00 00 .ebug........... +| 3472: 06 65 6e 61 6c 2c 65 3f 07 02 00 01 02 00 01 02 .enal,e?........ +| 3488: 00 01 02 00 01 02 00 01 02 00 01 02 00 01 02 00 ................ +| 3504: 01 02 00 01 02 00 01 02 00 01 01 ff f1 02 00 01 ................ +| 3520: 02 00 01 02 00 01 02 00 f1 02 00 01 02 00 01 4f ...............O +| 3536: 00 01 02 00 01 02 00 01 08 78 74 65 6e 73 69 6f .........xtensio +| 3552: 6e 09 1f 04 00 01 04 00 01 04 00 00 04 66 74 73 n............fts +| 3568: 34 09 0a 03 00 01 03 00 00 f3 00 03 01 35 09 0d 4............5.. +| 3584: 03 00 01 04 00 01 03 00 00 03 67 63 63 09 01 03 ..........gcc... +| 3600: 00 01 03 00 01 03 00 01 06 65 6f 70 6f 6c 79 09 .........eopoly. +| 3616: 10 03 00 01 03 00 01 03 00 00 05 6a 73 6f 6e 31 ...........json1 +| 3632: 09 13 03 00 01 02 ff 01 03 00 00 04 6c 6f 61 63 ............loac +| 3648: 09 1f 03 00 01 03 00 01 03 00 00 03 6d 61 78 09 ............max. +| 3664: 1c 02 00 01 02 00 01 02 00 01 05 64 6d 6f 72 79 ...........dmory +| 3680: 09 1c 03 00 01 03 00 01 03 00 03 04 73 79 73 35 ............sys5 +| 3696: 09 16 02 f0 01 03 00 01 03 00 00 06 6e 6f 63 61 ............noca +| 3712: 73 65 3c 02 01 02 02 00 03 01 02 02 00 03 01 02 se<............. +| 3728: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................ +| 3744: 00 03 01 02 02 00 03 01 02 02 00 4b 01 02 02 00 ...........K.... +| 3760: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 00 ................ +| 3776: 04 6f 6d 69 74 09 1f 02 00 01 02 00 01 02 00 00 .omit........... +| 3792: 05 72 74 72 65 65 09 19 03 00 01 03 00 01 03 00 .rtree.......... +| 3808: 03 02 69 6d 3c 01 01 02 02 00 03 01 02 02 00 03 ..im<........... +| 3824: 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 ................ +| 3840: 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 ................ +| 3856: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................ +| 3872: 00 00 0a 74 68 72 65 61 64 73 61 66 65 09 22 02 ...threadsafe... +| 3888: 00 01 02 00 01 02 00 00 04 76 74 61 62 09 07 04 .........vtab... +| 3904: 00 01 04 00 01 04 00 00 01 78 b4 01 01 01 01 02 .........x...... +| 3920: 00 01 f4 01 02 00 01 02 01 02 00 01 01 01 02 ff ................ +| 3936: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 ................ +| 3952: 01 01 02 ae 01 01 01 02 00 01 01 01 02 00 01 01 ................ +| 3968: 01 12 00 01 01 01 02 00 01 01 01 02 00 01 01 01 ................ +| 3984: 12 00 01 01 01 02 01 01 01 01 02 00 01 01 01 02 ................ +| 4000: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................ +| 4016: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 ................ +| 4032: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 ................ +| 4048: 01 02 00 01 01 01 02 00 01 76 01 02 00 01 01 01 .........v...... +| 4064: 02 00 01 01 01 02 01 01 01 01 02 00 01 01 01 02 ................ +| 4080: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................ +| page 6 offset 20480 +| 0: 0a 00 00 00 02 0f f5 00 0f fb 0f f5 00 00 00 00 ................ +| 4080: 00 00 00 00 00 05 04 08 09 01 02 04 04 08 08 09 ................ +| end crash-74fdbc96edbc04.db +}]} {} + +do_catchsql_test 32.1 { + UPDATE t1 SET b=quote(zeroblob(6.51158946e+5)) WHERE a MATCH '*t*'; +} {1 {database disk image is malformed}} + +#do_catchsql_test 32.2 { +# UPDATE t1 SET b=((- '' )) WHERE a MATCH '0*t'; +#} {1 {database disk image is malformed}} + +#------------------------------------------------------------------------- +# +ifcapable icu { + reset_db + do_catchsql_test 33.0 { + CREATE VIRTUAL TABLE f USING fts3(a,b,tokenize=icu); + CREATE TABLE 'f_docsize'(docid INTEGER PRIMARY KEY, size BLOB); + CREATE TABLE 'f_stat'(id INTEGER PRIMARY KEY, value BLOB); + INSERT INTO f VALUES (1, '1234'); + INSERT INTO f_stat VALUES (1,x'0000000165656565db6569746565c5c52bc5c5c53e3a003bc502ffffffffc5c5c53e3a003bc502fffffffffb8b2afbfb6565f0740100650000000165656565db6569746565c5c52bc5c5c53e3a003bc502ffffffffc5c5c53e3a003b8b00c5c5c5c5c5bfc5'); + INSERT INTO f(f) VALUES ('merge=198,49'); + } {1 {database disk image is malformed}} +} + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 34.0 { + CREATE VIRTUAL TABLE f USING fts3(a,b); + INSERT INTO f VALUES (1, '1234'); + INSERT INTO f_segdir VALUES (1,255,0,0,'1 255',x'00'); + UPDATE f_segdir SET level = 0 WHERE level IN ( + SELECT level FROM f_segdir LIMIT 1 OFFSET 1 + ); + INSERT INTO f_segdir VALUES (255,249,0,121,'0 0',x'00'); + INSERT INTO f_content VALUES (255,0,x'ff'); + INSERT INTO f_segdir VALUES (1,255,16,0,'1 255',x'00'); +} + +do_catchsql_test 34.1 { + UPDATE f SET b = x'00' WHERE b IN (SELECT b FROM f LIMIT 1 OFFSET 0); +} {1 {database disk image is malformed}} + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 35.0 { + CREATE VIRTUAL TABLE f USING fts3(a,b); + INSERT INTO f_segdir VALUES (1,255,0,0,'1 255',x'0001ff000001ff000001ff000001ff000001ff00c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5bec5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5'); +} + +do_catchsql_test 35.1 { + INSERT INTO f(f) VALUES ('integrity-check'); +} {1 {database disk image is malformed}} + +reset_db +do_catchsql_test 36.0 { + CREATE VIRTUAL TABLE f USING fts3(a,tokenize=porter); + CREATE TABLE 'f_stat'(id INTEGER PRIMARY KEY, value BLOB); + INSERT INTO f VALUES (1); + INSERT INTO f_stat VALUES (1,x'00000000000101010119013d00ffff0400fa83717b71a69297979701f63d010101010101010101010101190000000000000000fa83717b71a601f63d01010101010101010101010119013d00ffffff0400fa83717b71a69297979701f63d010101010101010101010101190000000000000000fa83717b71a69201f63d010101f63d01010101010101010101010119013d00ffffff0400fa83717b71a6929797010101010101010101010119013d00ffff01f63d01010101010101010101010119013d00ffffff0400fa83717b71a69297979701f63d00fa03ffffffa69297979701f63d010101000000000101010101197e9797976567656565ffa63535354e'); + INSERT INTO f(f) VALUES ('merge=53,216'); +} {0 {}} + finish_test diff --git a/test/fts3cov.test b/test/fts3cov.test index 95269a6b..5d838365 100644 --- a/test/fts3cov.test +++ b/test/fts3cov.test @@ -97,7 +97,7 @@ do_test fts3cov-2.2 { } {} do_error_test fts3cov-2.3 { SELECT * FROM t1 WHERE t1 MATCH 'c*' -} {SQL logic error} +} {database disk image is malformed} # Test the "replaced with NULL" case: do_test fts3cov-2.4 { @@ -105,7 +105,7 @@ do_test fts3cov-2.4 { } {} do_error_test fts3cov-2.5 { SELECT * FROM t1 WHERE t1 MATCH 'cloud' -} {SQL logic error} +} {database disk image is malformed} #-------------------------------------------------------------------------- # The following tests are to test the effects of OOM errors while storing diff --git a/test/fts3misc.test b/test/fts3misc.test index 60126dd6..92b93d03 100644 --- a/test/fts3misc.test +++ b/test/fts3misc.test @@ -226,5 +226,81 @@ do_execsql_test 6.1 { SELECT rowid FROM t6 WHERE t6 MATCH 'b OR "x a"' } {50001 50002 50003 50004} +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 7.0 { + CREATE VIRTUAL TABLE vt0 USING fts3(c0); + INSERT INTO vt0 VALUES (x'00'); +} +do_execsql_test 7.1 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} + +#------------------------------------------------------------------------- +# Ticket [8a6fa2bb]. +# +reset_db +do_execsql_test 7.0.1 { + CREATE VIRTUAL TABLE vt0 USING fts4(c0, order=DESC); + INSERT INTO vt0(c0) VALUES (0), (0); +} +do_execsql_test 7.0.2 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} +reset_db +do_execsql_test 7.1.1 { + CREATE VIRTUAL TABLE vt0 USING fts4(c0, order=ASC); + INSERT INTO vt0(c0) VALUES (0), (0); +} +do_execsql_test 7.1.2 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} +do_execsql_test 7.2.1 { + CREATE VIRTUAL TABLE ft USING fts4(c0, c1, order=DESC, prefix=1); + INSERT INTO ft VALUES('a b c d', 'hello world'); + INSERT INTO ft VALUES('negative', 'positive'); + INSERT INTO ft VALUES('hello world', 'a b c d'); +} +do_execsql_test 7.2.2 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} + +#------------------------------------------------------------------------- +# Ticket [745f1abc]. +# +reset_db +do_execsql_test 8.1 { + CREATE VIRTUAL TABLE vt0 USING fts4(c0, prefix=1); +} +do_execsql_test 8.2 { + BEGIN; + INSERT INTO vt0 VALUES (0); + INSERT INTO vt0(vt0) VALUES('optimize'); + COMMIT; +} +do_execsql_test 8.3 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 9.0 { + CREATE VIRTUAL TABLE t1 using fts4(mailcontent); + insert into t1(rowid, mailcontent) values + (-4764623217061966105, 'we are going to upgrade'), + (8324454597464624651, 'we are going to upgrade'); +} + +do_execsql_test 9.1 { + INSERT INTO t1(t1) VALUES('integrity-check'); +} + +do_execsql_test 9.2 { + SELECT rowid FROM t1 WHERE t1 MATCH 'upgrade'; +} { + -4764623217061966105 8324454597464624651 +} finish_test diff --git a/test/fts3snippet.test b/test/fts3snippet.test index 976c8c84..749aa4e0 100644 --- a/test/fts3snippet.test +++ b/test/fts3snippet.test @@ -561,6 +561,7 @@ do_test 4.3 { }] } {64} + #------------------------------------------------------------------------- # Request a snippet from a query with more than 64 phrases. # @@ -587,5 +588,18 @@ do_execsql_test 5.1 { {[a70] [a71] [a72]} } +#------------------------------------------------------------------------- +# Request a snippet from a query with more than 64 phrases. +# +reset_db +do_execsql_test 6.0 { + CREATE VIRTUAL TABLE f USING fts3(b); + INSERT INTO f VALUES ( x'746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218'); +} + +do_execsql_test 6.1 { + SELECT length(snippet(f))>0 FROM f WHERE b MATCH x'1065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a010f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c2a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e0f42'; +} {1} + set sqlite_fts3_enable_parentheses 0 finish_test diff --git a/test/fts4aa.test b/test/fts4aa.test index e6c7f933..7349841d 100644 --- a/test/fts4aa.test +++ b/test/fts4aa.test @@ -191,4 +191,61 @@ foreach {q r} [array get fts4aa_res] { } $r } +# 2019-11-16 https://bugs.chromium.org/p/chromium/issues/detail?id=1025472 +# +db close +sqlite3 db :memory: +do_execsql_test fts4aa-5.10 { + CREATE VIRTUAL TABLE t1 USING fts4(a, b, c, d, e,f,g,h,i,j,k,l,m,n,o,p,q,r); + INSERT INTO t1 VALUES('X Y', '2', '3', '4', '5', '6', '7', '8', '9', '0', + 'a','b','c','d','e','f','g','h'); + UPDATE t1_docsize SET size=x'88' WHERE docid=1; +} {} +do_catchsql_test fts4aa-5.20 { + SELECT quote(matchinfo(t1, 'l')) FROM t1 WHERE t1 MATCH 'X Y'; +} {1 {database disk image is malformed}} +do_execsql_test fts4aa-5.30 { + DROP TABLE t1; + CREATE VIRTUAL TABLE t1 USING fts4(a,b,c,d); + INSERT INTO t1 VALUES('one two','three four','five six','seven eight'); +} {} +do_catchsql_test fts4aa-5.40 { + UPDATE t1_stat SET value=x'01010101' WHERE id=0; + SELECT quote(matchinfo(t1,'a')) FROM t1 WHERE t1 MATCH 'one two'; +} {1 {database disk image is malformed}} +do_catchsql_test fts4aa-5.50 { + UPDATE t1_stat SET value=x'010101' WHERE id=0; + SELECT quote(matchinfo(t1,'a')) FROM t1 WHERE t1 MATCH 'one two'; +} {1 {database disk image is malformed}} +do_catchsql_test fts4aa-5.60 { + UPDATE t1_stat SET value=x'01' WHERE id=0; + SELECT quote(matchinfo(t1,'a')) FROM t1 WHERE t1 MATCH 'one two'; +} {1 {database disk image is malformed}} +do_catchsql_test fts4aa-5.70 { + UPDATE t1_stat SET value=x'' WHERE id=0; + SELECT quote(matchinfo(t1,'a')) FROM t1 WHERE t1 MATCH 'one two'; +} {1 {database disk image is malformed}} + +# 2019-11-18 https://bugs.chromium.org/p/chromium/issues/detail?id=1025467 +db close +sqlite3 db :memory: +do_execsql_test fts4aa-6.10 { + CREATE VIRTUAL TABLE f USING fts4(); + INSERT INTO f_segdir VALUES (77,91,0,0,'255 77',x'0001308000004d5c4ddddddd4d4d7b4d4d4d614d8019ff4d05000001204d4d2e4d6e4d4d4d4b4d6c4d004d4d4d4d4d4d3d000000004d5d4d4d645d4d004d4d4d4d4d4d4d4d4d454d6910004d05ffff054d646c4d004d5d4d4d4d4d3d000000004d4d4d4d4d4d4d4d4d4d4d69624d4d4d04004d4d4d4d4d604d4ce1404d554d45'); + INSERT INTO f_segdir VALUES (77,108,0,0,'255 77',x'0001310000fa64004d4d4d3c5d4d654d4d4d614d8000ff4d05000001204d4d2e4d6e4d4d4dff4d4d4d4d4d4d00104d4d4d4d000000004d4d4d0400311d4d4d4d4d4d4d4d4d4d684d6910004d05ffff054d4d6c4d004d4d4d4d4d4d3d000000004d4d4d4d644d4d4d4d4d4d69624d4d4d03ed4d4d4d4d4d604d4ce1404d550080'); + INSERT INTO f_stat VALUES (0,x'80808080100000000064004d4d4d3c4d4d654d4d4d614d8000ff4df6ff1a00204d4d2e4d6e4d4d4d104d4d4d4d4d4d00104d4d4d4d4d4d69574d4d4d000031044d4d4d3e4d4d4c4d05004d6910'); + SELECT quote(matchinfo(f,'pnax')) from f where f match '0 1'; +} {X'0200000000000000000000000E0000000E00000001000000010000000100000001000000'} + +# 2019-11-18 Detect infinite loop in fts3SelectLeaf() +db close +sqlite3 db :memory: +do_catchsql_test fts4aa-7.10 { + CREATE VIRTUAL TABLE f USING fts4(); + INSERT INTO f_segdir VALUES (63,60,60,60,'60 60',x'3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c483c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c20003c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c283c3c3c3c3c3c3c3c3c3c3c223c3c3c3c3c3c3c3c3c'); + INSERT INTO f_segments VALUES (60,x'3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c5a3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c2a3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c5e3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c803c3c3c3c3c3c233c3c3c3c1c3c3c3c3c3c3c3c3c3c3c3c1b3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c273c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c1a3c3c3c3c3c3c000200003c3c3c3c3c3c3c3c3c3c3c3c3c383c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d898d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d3c3c3c3c3c3c3c3c3c3cba3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c1c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c00023c3c3c3c3c3c383c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3cbc3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c2c3c3c3c403c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c16161616161616163c3c3c3c3c3c3c3c3c3c3c3c3c583c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c2b3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c1c013c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c20003c3c3c3c3c3c3c3c3c3c3c800000003c3c3c3c3c3c3c2c3c3c3c3c3c3c353c08080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808f4080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808083c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c323c3c3c3c3c3c3c3c3c3c3c4f3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3cfcfcfcfcfcfcfcfcfcfcfc10fcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfd02fcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc03e8fcfcfcfc3c3c3c3c3c3c8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c553c3c3c3c3c3c3c3c3c3c3c3c3c573c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c000000803c3c4dd5d5a6d52cf3d5d5d5d5d5d5d5d5d5d5d5d5d5d53c3c3c3c3f3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c2d3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c013c3c3c3c00643c3c3c3ce93c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c263c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c363c3c3c3c3c3c3c3c3c3c3c3c3c3c543c3c3c3c3c3c3c3c3c3c273c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c330000003c3c3c3c3c3c3c3c3c3c3c3c3c3c4d3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c000010003c3c3c3c3c3c413c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c1c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c403c3c3c3c3c3c3c3c3c3c3c3cec0000fa3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c2d3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c4c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c5e3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c1b3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c593c3c3c3c3c3c243c3c373c3c3c3c3cff3c3c3c3c3c3c3c3c3c3c3c3c3c000080003c3c3c3c3c3c3c3c3c3c353c3c3c3c3c3d3c3c3c3c3c3c3c3c3c3c3c3c4d3c3c3c3c3c3c3c3c3c3c3c3c3c40003c3c3c3c3c293c3c3c3c3c3c3c3c3c3d3c3c3c3c3c3c3c3c353c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c4f3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3f3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3cff7f3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c2d3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ca43c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3cbf3c3c3c3c3c3c3c3c3c008000003c3c3c3c3c3c3c3c343c3c373c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c593c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c'); + SELECT * from f where f match '0'; +} {1 {database disk image is malformed}} + + finish_test diff --git a/test/fts4content.test b/test/fts4content.test index 2da51d15..980586ea 100644 --- a/test/fts4content.test +++ b/test/fts4content.test @@ -634,5 +634,41 @@ do_catchsql_test 11.1 { CREATE VIRTUAL TABLE x1 USING fts4(content=x1); } {1 {vtable constructor called recursively: x1}} +#--------------------------------------------------------------------------- +# Check that an fts4 table cannot be its own content table. +# +reset_db +breakpoint +do_execsql_test 12.1.1 { + CREATE VIRTUAL TABLE t1 USING fts4(a, content=t1 ); + INSERT INTO t1(rowid, a) VALUES(1, 'abc'); +} +do_catchsql_test 12.1.2 { + SELECT * FROM t1; +} {1 {SQL logic error}} +do_catchsql_test 12.1.3 { + SELECT * FROM t1('abc'); +} {1 {SQL logic error}} +do_catchsql_test 12.1.4 { + SELECT count(*) FROM t1; +} {1 {SQL logic error}} + +reset_db +do_execsql_test 12.2.1 { + CREATE VIRTUAL TABLE t1 USING fts4(a, content=t2 ); + CREATE VIRTUAL TABLE t2 USING fts4(a, content=t1 ); + INSERT INTO t1(rowid, a) VALUES(1, 'abc'); +} +do_catchsql_test 12.2.2 { + SELECT * FROM t1; +} {1 {SQL logic error}} +do_catchsql_test 12.2.3 { + SELECT * FROM t1('abc'); +} {1 {SQL logic error}} +do_catchsql_test 12.2.4 { + SELECT count(*) FROM t1; +} {1 {SQL logic error}} + + finish_test diff --git a/test/fts4langid.test b/test/fts4langid.test index 9fffe952..45e851f9 100644 --- a/test/fts4langid.test +++ b/test/fts4langid.test @@ -489,4 +489,19 @@ foreach lid [list 4 [expr 1<<30]] { SELECT count(*) FROM t6_segments; } {1 2} } + +reset_db +do_execsql_test 6.0 { + CREATE VIRTUAL TABLE vt0 USING fts4(c0, languageid="lid"); + INSERT INTO vt0 VALUES ('a'), ('b'); + BEGIN; + UPDATE vt0 SET lid = 1 WHERE lid=0; +} +do_execsql_test 6.1 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} +do_execsql_test 6.2 { + COMMIT; + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} finish_test diff --git a/test/fts4merge.test b/test/fts4merge.test index 48661afd..3cd69320 100644 --- a/test/fts4merge.test +++ b/test/fts4merge.test @@ -326,7 +326,22 @@ foreach mod {fts3 fts4} { execsql { INSERT INTO t1(t1) VALUES('merge=200,10') } expr { ([db total_changes] - $x)>1 } } {0} +} +#------------------------------------------------------------------------- +# Test cases 8.* - ticket [bf1aab89]. +# +set testprefix fts4merge +reset_db +do_execsql_test 8.0 { + CREATE VIRTUAL TABLE t1 USING fts4(a, order=DESC); + INSERT INTO t1(a) VALUES (0); + INSERT INTO t1(a) VALUES (0); + UPDATE t1 SET a = NULL; +} + +do_execsql_test 8.1 { + INSERT INTO t1(t1) VALUES('merge=1,4'); } finish_test diff --git a/test/func.test b/test/func.test index 7315af32..34a6f18b 100644 --- a/test/func.test +++ b/test/func.test @@ -315,9 +315,9 @@ ifcapable floatingpoint { do_test func-4.38 { execsql {SELECT round(9999999999999.556,2);} } {9999999999999.56} - do_execsql_test func-4.39 { - SELECT round(1e500), round(-1e500); - } {Inf -Inf} + do_test func-4.39 { + string tolower [db eval {SELECT round(1e500), round(-1e500);}] + } {inf -inf} } # Test the upper() and lower() functions @@ -1430,7 +1430,7 @@ do_test func-33.1 { do_catchsql_test func-33.2 { CREATE VIEW v33(y) AS SELECT testdirectonly(15); SELECT * FROM v33; -} {1 {testdirectonly() prohibited in triggers and views}} +} {1 {unsafe use of testdirectonly()}} do_execsql_test func-33.3 { SELECT * FROM (SELECT testdirectonly(15)) AS v33; } {30} @@ -1441,7 +1441,7 @@ do_execsql_test func-33.4 { do_catchsql_test func-33.5 { WITH c(x) AS (SELECT * FROM v33) SELECT * FROM c; -} {1 {testdirectonly() prohibited in triggers and views}} +} {1 {unsafe use of testdirectonly()}} do_execsql_test func-33.10 { CREATE TABLE t33a(a,b); CREATE TABLE t33b(x,y); @@ -1451,7 +1451,7 @@ do_execsql_test func-33.10 { } {} do_catchsql_test func-33.11 { INSERT INTO t33a VALUES(1,2); -} {1 {testdirectonly() prohibited in triggers and views}} +} {1 {unsafe use of testdirectonly()}} do_execsql_test func-33.20 { ALTER TABLE t33a RENAME COLUMN a TO aaa; SELECT sql FROM sqlite_master WHERE name='r1'; @@ -1459,5 +1459,22 @@ do_execsql_test func-33.20 { INSERT INTO t33b(x,y) VALUES(testdirectonly(new.aaa),new.b); END}} +# 2020-01-09 Yongheng fuzzer find +# The bug is in the register-validity debug logic, not in the SQLite core +# and as such it only impacts debug builds. Release builds work fine. +# +reset_db +do_execsql_test func-34.10 { + CREATE TABLE t1(a INT CHECK( + datetime( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29, + 30,31,32,33,34,35,36,37,38,39, + 40,41,42,43,44,45,46,47,48,a) + ) + ); + INSERT INTO t1(a) VALUES(1),(2); + SELECT * FROM t1; +} {1 2} finish_test diff --git a/test/fuzz_common.tcl b/test/fuzz_common.tcl index 4ab7dff5..520555bd 100644 --- a/test/fuzz_common.tcl +++ b/test/fuzz_common.tcl @@ -363,6 +363,7 @@ proc do_fuzzy_test {testname args} { lappend ::fuzzyopts(-errorlist) {ORDER BY} lappend ::fuzzyopts(-errorlist) {GROUP BY} lappend ::fuzzyopts(-errorlist) {datatype mismatch} + lappend ::fuzzyopts(-errorlist) {non-deterministic functions prohibited} for {set ii 0} {$ii < $::fuzzyopts(-repeats)} {incr ii} { do_test ${testname}.$ii { diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 4d52aede..5add53c1 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -134,6 +134,7 @@ struct Blob { */ static struct GlobalVars { const char *zArgv0; /* Name of program */ + const char *zDbFile; /* Name of database file */ VFile aFile[MX_FILE]; /* The virtual filesystem */ int nDb; /* Number of template databases */ Blob *pFirstDb; /* Content of first template database */ @@ -148,11 +149,10 @@ static struct GlobalVars { */ static void fatalError(const char *zFormat, ...){ va_list ap; - if( g.zTestName[0] ){ - fprintf(stderr, "%s (%s): ", g.zArgv0, g.zTestName); - }else{ - fprintf(stderr, "%s: ", g.zArgv0); - } + fprintf(stderr, "%s", g.zArgv0); + if( g.zDbFile ) fprintf(stderr, " %s", g.zDbFile); + if( g.zTestName[0] ) fprintf(stderr, " (%s)", g.zTestName); + fprintf(stderr, ": "); va_start(ap, zFormat); vfprintf(stderr, zFormat, ap); va_end(ap); @@ -161,12 +161,21 @@ static void fatalError(const char *zFormat, ...){ } /* -** Timeout handler +** signal handler */ #ifdef __unix__ -static void timeoutHandler(int NotUsed){ - (void)NotUsed; - fatalError("timeout\n"); +static void signalHandler(int signum){ + const char *zSig; + if( signum==SIGABRT ){ + zSig = "abort"; + }else if( signum==SIGALRM ){ + zSig = "timeout"; + }else if( signum==SIGSEGV ){ + zSig = "segfault"; + }else{ + zSig = "signal"; + } + fatalError(zSig); } #endif @@ -453,6 +462,12 @@ static unsigned int mxProgressCb = 2000; /* Maximum string length in SQLite */ static int lengthLimit = 1000000; +/* Maximum expression depth */ +static int depthLimit = 500; + +/* Limit on the amount of heap memory that can be used */ +static sqlite3_int64 heapLimit = 1000000000; + /* Maximum byte-code program length in SQLite */ static int vdbeOpLimit = 25000; @@ -777,6 +792,10 @@ int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte){ if( lengthLimit>0 ){ sqlite3_limit(cx.db, SQLITE_LIMIT_LENGTH, lengthLimit); } + if( depthLimit>0 ){ + sqlite3_limit(cx.db, SQLITE_LIMIT_EXPR_DEPTH, depthLimit); + } + sqlite3_hard_heap_limit64(heapLimit); if( nDb>=20 && aDb[18]==2 && aDb[19]==2 ){ aDb[18] = aDb[19] = 1; @@ -1291,6 +1310,7 @@ static void showHelp(void){ " --export-sql DIR Write SQL to file(s) in DIR. Also works with --sqlid\n" " --help Show this help text\n" " --info Show information about SOURCE-DB w/o running tests\n" +" --limit-depth N Limit expression depth to N\n" " --limit-mem N Limit memory used by test SQLite instance to N bytes\n" " --limit-vdbe Panic if any test runs for more than 100,000 cycles\n" " --load-sql ARGS... Load SQL scripts fron files into SOURCE-DB\n" @@ -1307,6 +1327,7 @@ static void showHelp(void){ " --sqlid N Use only SQL where sqlid=N\n" " --timeout N Abort if any single test needs more than N seconds\n" " -v|--verbose Increased output. Repeat for more output.\n" +" --vdbe-debug Activate VDBE debugging.\n" ); } @@ -1341,7 +1362,7 @@ int main(int argc, char **argv){ int cellSzCkFlag = 0; /* --cell-size-check */ int sqlFuzz = 0; /* True for SQL fuzz. False for DB fuzz */ int iTimeout = 120; /* Default 120-second timeout */ - int nMem = 0; /* Memory limit */ + int nMem = 0; /* Memory limit override */ int nMemThisDb = 0; /* Memory limit set by the CONFIG table */ char *zExpDb = 0; /* Write Databases to files in this directory */ char *zExpSql = 0; /* Write SQL to files in this directory */ @@ -1356,7 +1377,9 @@ int main(int argc, char **argv){ sqlite3_initialize(); iBegin = timeOfDay(); #ifdef __unix__ - signal(SIGALRM, timeoutHandler); + signal(SIGALRM, signalHandler); + signal(SIGSEGV, signalHandler); + signal(SIGABRT, signalHandler); #endif g.zArgv0 = argv[0]; openFlags4Data = SQLITE_OPEN_READONLY; @@ -1390,14 +1413,13 @@ int main(int argc, char **argv){ if( strcmp(z,"info")==0 ){ infoFlag = 1; }else + if( strcmp(z,"limit-depth")==0 ){ + if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]); + depthLimit = integerValue(argv[++i]); + }else if( strcmp(z,"limit-mem")==0 ){ -#if !defined(SQLITE_ENABLE_MEMSYS3) && !defined(SQLITE_ENABLE_MEMSYS5) - fatalError("the %s option requires -DSQLITE_ENABLE_MEMSYS5 or _MEMSYS3", - argv[i]); -#else if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]); nMem = integerValue(argv[++i]); -#endif }else if( strcmp(z,"limit-vdbe")==0 ){ vdbeLimitFlag = 1; @@ -1465,6 +1487,9 @@ int main(int argc, char **argv){ fatalError("timeout is not available on non-unix systems"); #endif }else + if( strcmp(z,"vdbe-debug")==0 ){ + bVdbeDebug = 1; + }else if( strcmp(z,"verbose")==0 ){ quietFlag = 0; verboseFlag++; @@ -1507,6 +1532,7 @@ int main(int argc, char **argv){ /* Process each source database separately */ for(iSrcDb=0; iSrcDbzName); if( rc ){ @@ -1586,14 +1612,9 @@ int main(int argc, char **argv){ ossFuzzThisDb = sqlite3_column_int(pStmt,1); if( verboseFlag ) printf("Config: oss-fuzz=%d\n", ossFuzzThisDb); } - if( strcmp(zName, "limit-mem")==0 && !nativeMalloc ){ -#if !defined(SQLITE_ENABLE_MEMSYS3) && !defined(SQLITE_ENABLE_MEMSYS5) - fatalError("the limit-mem option requires -DSQLITE_ENABLE_MEMSYS5" - " or _MEMSYS3"); -#else + if( strcmp(zName, "limit-mem")==0 ){ nMemThisDb = sqlite3_column_int(pStmt,1); if( verboseFlag ) printf("Config: limit-mem=%d\n", nMemThisDb); -#endif } } sqlite3_finalize(pStmt); @@ -1720,12 +1741,18 @@ int main(int argc, char **argv){ /* Limit available memory, if requested */ sqlite3_shutdown(); - if( nMemThisDb>0 && !nativeMalloc ){ - pHeap = realloc(pHeap, nMemThisDb); - if( pHeap==0 ){ - fatalError("failed to allocate %d bytes of heap memory", nMem); + if( nMemThisDb>0 && nMem==0 ){ + if( !nativeMalloc ){ + pHeap = realloc(pHeap, nMemThisDb); + if( pHeap==0 ){ + fatalError("failed to allocate %d bytes of heap memory", nMem); + } + sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nMemThisDb, 128); + }else{ + sqlite3_hard_heap_limit64((sqlite3_int64)nMemThisDb); } - sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nMemThisDb, 128); + }else{ + sqlite3_hard_heap_limit64(0); } /* Disable lookaside with the --native-malloc option */ @@ -1809,6 +1836,9 @@ int main(int argc, char **argv){ #ifdef SQLITE_TESTCTRL_PRNG_SEED sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, 1, db); #endif + if( bVdbeDebug ){ + sqlite3_exec(db, "PRAGMA vdbe_debug=ON", 0, 0, 0); + } do{ runSql(db, (char*)pSql->a, runFlags); }while( timeoutTest ); diff --git a/test/fuzzdata1.db b/test/fuzzdata1.db index 4b4a6b574b04ded0397562fbdea8aca49fa0e006..091a6452989e432ef808624af32296e531a3d2e9 100644 GIT binary patch delta 280235 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�-m@s1-72Wffv~!jlpw$K|Cg|64L~~um(lroSBrQ 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�#x*1ULN{i~XyuCjxd(hI1@W`A}N^ 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%0AX@ArVc4dwlI)+_hg7o)t#zHtHm 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
    HgIh_>&~cM^^NFNtu?tUXz>ho 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
    kAc6G&bd-8 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 N0k+sK{-N#=_kWqd3OxV- diff --git a/test/gencol1.test b/test/gencol1.test new file mode 100644 index 00000000..5276d969 --- /dev/null +++ b/test/gencol1.test @@ -0,0 +1,563 @@ +# 2019-10-31 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Test cases for generated columns. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# ticket 830277d9db6c3ba1 on 2019-10-31 +do_execsql_test gencol1-100 { + CREATE TABLE t0(c0 AS(TYPEOF(c1)), c1); + INSERT INTO t0(c1) VALUES(0); + CREATE TABLE t1(x AS (typeof(y)), y); + INSERT INTO t1 SELECT * FROM t0; + SELECT * FROM t1; +} {integer 0} + +foreach {tn schema} { +1 { + CREATE TABLE t1( + a INT, + b TEXT, + c ANY, + w INT GENERATED ALWAYS AS (a*10), + x TEXT AS (typeof(c)), + y TEXT AS (substr(b,a,a+2)) + ); + } +2 { + CREATE TABLE t1( + w INT GENERATED ALWAYS AS (a*10), + x TEXT AS (typeof(c)), + y TEXT AS (substr(b,a,a+2)), + a INT, + b TEXT, + c ANY + ); + } +3 { + CREATE TABLE t1( + w INT GENERATED ALWAYS AS (a*10), + a INT, + x TEXT AS (typeof(c)) STORED, + b TEXT, + y TEXT AS (substr(b,a,a+2)), + c ANY + ); + } +4 { + CREATE TABLE t1( + a INTEGER PRIMARY KEY, + w INT GENERATED ALWAYS AS (a*10), + b TEXT, + x TEXT AS (typeof(c)), + y TEXT AS (substr(b,a,a+2)) STORED, + c ANY + ); + } +5 { + CREATE TABLE t1( + w INT GENERATED ALWAYS AS (a*10), + a INT, + x TEXT AS (typeof(c)), + b TEXT, + y TEXT AS (substr(b,a,a+2)) STORED, + c ANY, + PRIMARY KEY(a,b) + ) WITHOUT ROWID; + } +6 { + CREATE TABLE t1( + w INT GENERATED ALWAYS AS (m*5), + m INT AS (a*2) STORED, + a INT, + x TEXT AS (typeof(c)), + b TEXT, + y TEXT AS (substr(b,m/2,m/2+2)) STORED, + c ANY, + PRIMARY KEY(a,b) + ); + } +7 { + CREATE TABLE t1( + w INT GENERATED ALWAYS AS (m*5), + m INT AS (a*2) NOT NULL, + a INT, + x TEXT AS (typeof(c)) CHECK (x<>'blank'), + b TEXT, + y TEXT AS (substr(b,m/2,m/2+2)) STORED, + c ANY, + PRIMARY KEY(b,a) + ) WITHOUT ROWID; + } +} { + catch {db close} + sqlite3 db :memory: + db eval $schema + do_execsql_test gencol1-2.$tn.100 { + INSERT INTO t1(a,b,c) VALUES(1,'abcdef',5.5),(3,'cantaloupe',NULL); + SELECT w, x, y, '|' FROM t1 ORDER BY a; + } {10 real abc | 30 null ntalo |} + do_execsql_test gencol1-2.$tn.101 { + SELECT w, x, y, '|' FROM t1 ORDER BY w; + } {10 real abc | 30 null ntalo |} + do_execsql_test gencol1-2.$tn.102 { + SELECT a FROM t1 WHERE w=30; + } {3} + do_execsql_test gencol1-2.$tn.103 { + SELECT a FROM t1 WHERE x='real'; + } {1} + do_execsql_test gencol1-2.$tn.104 { + SELECT a FROM t1 WHERE y LIKE '%tal%' OR x='real' ORDER BY b; + } {1 3} + do_execsql_test gencol1-2.$tn.110 { + CREATE INDEX t1w ON t1(w); + SELECT a FROM t1 WHERE w=10; + } {1} + do_execsql_test gencol1-2.$tn.120 { + CREATE INDEX t1x ON t1(x) WHERE w BETWEEN 20 AND 40; + SELECT a FROM t1 WHERE x='null' AND w BETWEEN 20 AND 40; + } {3} + do_execsql_test gencol1-2.$tn.121 { + SELECT a FROM t1 WHERE x='real'; + } {1} + do_execsql_test gencol1-2.$tn.130 { + VACUUM; + PRAGMA integrity_check; + } {ok} + do_execsql_test gencol1-2.$tn.140 { + UPDATE t1 SET a=a+100 WHERE w<20; + SELECT a, w, '|' FROM t1 ORDER BY w; + } {3 30 | 101 1010 |} + do_execsql_test gencol1-2.$tn.150 { + INSERT INTO t1 VALUES(4,'jambalaya','Chef John'),(15,87719874135,0); + SELECT w, x, y, '|' FROM t1 ORDER BY w; + } {30 null ntalo | 40 text balaya | 150 integer {} | 1010 real {} |} +} + +# 2019-10-31 ticket b9befa4b83a660cc +db close +sqlite3 db :memory: +do_execsql_test gencol1-3.100 { + PRAGMA foreign_keys = true; + CREATE TABLE t0(c0 PRIMARY KEY, c1, c2 AS (c0+c1-c3) REFERENCES t0, c3); + INSERT INTO t0 VALUES (0, 0, 0), (11, 5, 5); + UPDATE t0 SET c1 = c0, c3 = c0; + SELECT *, '|' FROM t0 ORDER BY +c0; +} {0 0 0 0 | 11 11 11 11 |} +do_catchsql_test gencol1-3.110 { + UPDATE t0 SET c1 = c0, c3 = c0+1; +} {1 {FOREIGN KEY constraint failed}} + +# 2019-11-01 ticket c28a01da72f8957c +db close +sqlite3 db :memory: +do_execsql_test gencol1-4.100 { + CREATE TABLE t0 ( + c0, + c1 a UNIQUE AS (1), + c2, + c3 REFERENCES t0(c1) + ); + PRAGMA foreign_keys = true; + INSERT INTO t0(c0,c2,c3) VALUES(0,0,1); +} {} +do_catchsql_test gencol1-4.110 { + REPLACE INTO t0(c0,c2,c3) VALUES(0,0,0),(0,0,0); +} {1 {FOREIGN KEY constraint failed}} + +# 2019-11-01 Problem found while adding new foreign key test cases in TH3. +db close +sqlite3 db :memory: +do_execsql_test gencol1-5.100 { + PRAGMA foreign_keys=ON; + CREATE TABLE t1( + gcb AS (b*1), + a INTEGER PRIMARY KEY, + gcc AS (c+0), + b UNIQUE, + gca AS (1*a+0), + c UNIQUE + ) WITHOUT ROWID; + INSERT INTO t1 VALUES(1,2,3); + INSERT INTO t1 VALUES(4,5,6); + INSERT INTO t1 VALUES(7,8,9); + CREATE TABLE t1a( + gcx AS (x+0) REFERENCES t1(a) ON DELETE CASCADE, + id, + x, + gcid AS (1*id) + ); + INSERT INTO t1a VALUES(1, 1); + INSERT INTO t1a VALUES(2, 4); + INSERT INTO t1a VALUES(3, 7); + DELETE FROM t1 WHERE b=5; + SELECT id,x,'|' FROM t1a ORDER BY id; +} {1 1 | 3 7 |} + +do_catchsql_test gencol1-6.10 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0(c0 NOT NULL AS(c1), c1); + REPLACE INTO t0(c1) VALUES(NULL); +} {1 {NOT NULL constraint failed: t0.c0}} + +# 2019-11-06 ticket https://www.sqlite.org/src/info/2399f5986134f79c +# 2019-12-27 ticket https://www.sqlite.org/src/info/5fbc159eeb092130 +# 2019-12-27 ticket https://www.sqlite.org/src/info/37823501c68a09f9 +# +# All of the above tickets deal with NOT NULL ON CONFLICT REPLACE +# constraints on tables that have generated columns. +# +reset_db +do_execsql_test gencol1-7.10 { + CREATE TABLE t0 (c0 GENERATED ALWAYS AS (1), c1 UNIQUE, c2 UNIQUE); + INSERT INTO t0(c1) VALUES (1); + SELECT quote(0 = t0.c2 OR t0.c1 BETWEEN t0.c2 AND 1) FROM t0; +} {NULL} +do_execsql_test gencol1-7.11 { + DROP TABLE t0; + CREATE TABLE t0(c0 NOT NULL DEFAULT 'xyz', c1 AS(c0) NOT NULL); + REPLACE INTO t0(c0) VALUES(NULL); + SELECT * FROM t0; +} {xyz xyz} +do_execsql_test gencol1-7.12 { + DROP TABLE t0; + CREATE TABLE t0(c0 NOT NULL DEFAULT 'xyz', c1 AS(c0) STORED NOT NULL); + REPLACE INTO t0(c0) VALUES(NULL); + SELECT * FROM t0; +} {xyz xyz} +do_execsql_test gencol1-7.20 { + CREATE TABLE t1( + a NOT NULL DEFAULT 'aaa', + b AS(c) NOT NULL, + c NOT NULL DEFAULT 'ccc'); + REPLACE INTO t1(a,c) VALUES(NULL,NULL); + SELECT * FROM t1; +} {aaa ccc ccc} +do_execsql_test gencol1-7.21 { + DROP TABLE t1; + CREATE TABLE t1( + a NOT NULL DEFAULT 'aaa', + b AS(c) STORED NOT NULL, + c NOT NULL DEFAULT 'ccc'); + REPLACE INTO t1(a,c) VALUES(NULL,NULL); + SELECT * FROM t1; +} {aaa ccc ccc} +do_execsql_test gencol1-7.30 { + CREATE TABLE t2( + a NOT NULL DEFAULT 'aaa', + b AS(a) NOT NULL, + c NOT NULL DEFAULT 'ccc'); + REPLACE INTO t2(a,c) VALUES(NULL,NULL); + SELECT * FROM t2; +} {aaa aaa ccc} +do_execsql_test gencol1-7.31 { + DROP TABLE t2; + CREATE TABLE t2( + a NOT NULL DEFAULT 'aaa', + b AS(a) STORED NOT NULL, + c NOT NULL DEFAULT 'ccc'); + REPLACE INTO t2(a,c) VALUES(NULL,NULL); + SELECT * FROM t2; +} {aaa aaa ccc} +do_execsql_test gencol1-7.40 { + CREATE TABLE t3(a NOT NULL DEFAULT 123, b AS(a) UNIQUE); + REPLACE INTO t3 VALUES(NULL); + SELECT * FROM t3; +} {123 123} +do_execsql_test gencol1-7.41 { + SELECT * FROM t3 WHERE b=123; +} {123 123} +do_execsql_test gencol1-7.50 { + CREATE TABLE t4(a NOT NULL DEFAULT 123, b AS(a*10+4) STORED UNIQUE); + REPLACE INTO t4 VALUES(NULL); + SELECT * FROM t4; +} {123 1234} +do_execsql_test gencol1-7.51 { + SELECT * FROM t4 WHERE b=1234; +} {123 1234} + +# 2019-11-06 ticket 4fc08501f4e56692 +do_execsql_test gencol1-8.10 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0( + c0 AS (('a', 9) < ('b', c1)), + c1 AS (1), + c2 CHECK (1 = c1) + ); + INSERT INTO t0 VALUES (0),(99); + SELECT * FROM t0; +} {1 1 0 1 1 99} +do_catchsql_test gencol1-8.20 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0( + c0, + c1 AS(c0 + c2), + c2 AS(c1) CHECK(c2) + ); + UPDATE t0 SET c0 = NULL; +} {1 {generated column loop on "c2"}} + +# 2019-11-21 Problems in the new generated column logic +# reported by Yongheng Chen and Rui Zhong +reset_db +do_execsql_test gencol1-9.10 { + PRAGMA foreign_keys=OFF; + CREATE TABLE t1(aa , bb AS (17) UNIQUE); + INSERT INTO t1 VALUES(17); + CREATE TABLE t2(cc); + INSERT INTO t2 VALUES(41); + SELECT * FROM t2 JOIN t1 WHERE t1.bb=t1.aa AND t1.bb=17; +} {41 17 17} +do_execsql_test gencol1-9.20 { + CREATE TABLE t3(aa INT PRIMARY KEY, bb UNIQUE AS(aa)); + INSERT INTO t3 VALUES(1); + SELECT 100, * FROM t3; + DELETE FROM t3 WHERE (SELECT bb FROM t3); + SELECT 200, * FROM t3; +} {100 1 1} + +# 2019-12-04 Generated column in a CREATE TABLE IF NOT EXISTS that +# does already exist. +# +sqlite3 db :memory: +do_execsql_test gencol1-10.10 { + CREATE TABLE t1(aa,bb); + CREATE TABLE IF NOT EXISTS t1(aa, bb AS (aa+1)); + PRAGMA integrity_check; +} {ok} + +# 2019-12-06 Found by mrigger +# +sqlite3 db :memory: +do_execsql_test gencol1-11.10 { + PRAGMA foreign_keys = true; + CREATE TABLE t0( + c0, + c1 INTEGER PRIMARY KEY, + c2 BLOB UNIQUE DEFAULT x'00', + c3 BLOB GENERATED ALWAYS AS (1), + FOREIGN KEY(c1) REFERENCES t0(c2) + ); +} +do_catchsql_test gencol1-11.20 { + INSERT OR REPLACE INTO t0(c0, c1) VALUES (2, 1), (1, 0) +} {1 {FOREIGN KEY constraint failed}} +do_execsql_test gencol1-11.30 { + DROP TABLE t0; + CREATE TABLE t0( + c0, + c1 INTEGER PRIMARY KEY, + c3 BLOB GENERATED ALWAYS AS (1), + c2 BLOB UNIQUE DEFAULT x'00', + FOREIGN KEY(c1) REFERENCES t0(c2) + ); +} +do_catchsql_test gencol1-11.40 { + INSERT OR REPLACE INTO t0(c0, c1) VALUES (2, 1), (1, 0) +} {1 {FOREIGN KEY constraint failed}} +do_execsql_test gencol1-11.50 { + DROP TABLE t0; + CREATE TABLE t0( + c0, + c3 BLOB GENERATED ALWAYS AS (1), + c1 INTEGER PRIMARY KEY, + c2 BLOB UNIQUE DEFAULT x'00', + FOREIGN KEY(c1) REFERENCES t0(c2) + ); +} +do_catchsql_test gencol1-11.60 { + INSERT OR REPLACE INTO t0(c0, c1) VALUES (2, 1), (1, 0) +} {1 {FOREIGN KEY constraint failed}} +do_execsql_test gencol1-11.70 { + DROP TABLE t0; + CREATE TABLE t0( + c3 BLOB GENERATED ALWAYS AS (1), + c0, + c1 INTEGER PRIMARY KEY, + c2 BLOB UNIQUE DEFAULT x'00', + FOREIGN KEY(c1) REFERENCES t0(c2) + ); +} +do_catchsql_test gencol1-11.80 { + INSERT OR REPLACE INTO t0(c0, c1) VALUES (2, 1), (1, 0) +} {1 {FOREIGN KEY constraint failed}} + +# 2019-12-09 ticket bd8c280671ba44a7 +# With generated columns, the sqlite3ExprGetColumnOfTable() routine might +# generate a code sequence that does not end with OP_Column. So check to +# make sure that the last instruction generated is an OP_column prior to +# applying the OPFLAG_TYPEOFARG optimization to NOT NULL checks in the +# PRAGMA integrity_check code. +# +sqlite3 db :memory: +do_execsql_test gencol1-12.10 { + CREATE TABLE t0 (c0, c1 NOT NULL AS (c0==0)); + INSERT INTO t0(c0) VALUES (0); + PRAGMA integrity_check; +} {ok} + +# 2019-12-09 bug report from Yongheng Chen +# Ensure that the SrcList_item.colUsed field is set correctly when a +# generated column appears in the USING clause of a join. +# +do_execsql_test gencol1-13.10 { + CREATE TABLE t1(x, y AS(x+1)); + INSERT INTO t1 VALUES(10); + SELECT y FROM t1 JOIN t1 USING (y,y); +} {11} +do_execsql_test gencol1-13.11 { + SELECT 123 FROM t1 JOIN t1 USING (x); +} {123} +do_execsql_test gencol1-13.11 { + SELECT 456 FROM t1 JOIN t1 USING (x,x); +} {456} +do_execsql_test gencol1-13.20 { + CREATE INDEX t1y ON t1(y); + SELECT y FROM t1 JOIN t1 USING (y,y); +} {11} +do_execsql_test gencol1-13.21 { + CREATE INDEX t1x ON t1(x); + SELECT 123 FROM t1 JOIN t1 USING (x); +} {123} +do_execsql_test gencol1-13.22 { + SELECT 456 FROM t1 JOIN t1 USING (x,x); +} {456} + +# 2019-12-14 ticket b439bfcfb7deedc6 +# +sqlite3 db :memory: +do_execsql_test gencol1-14.10 { + CREATE TABLE t0(c0 AS(1 >= 1), c1 UNIQUE AS(TYPEOF(c0)), c2); + INSERT INTO t0 VALUES(0); + REINDEX; + SELECT * FROM t0; +} {1 integer 0} +do_catchsql_test gencol1-14.10 { + INSERT INTO t0 VALUES(2); +} {1 {UNIQUE constraint failed: t0.c1}} + +# 2019-12-14 gramfuzz1 find +# The schema is malformed in that it has a subquery on a generated +# column expression. This will be loaded if writable_schema=ON. SQLite +# must not use such an expression during code generation as the code generator +# will add bits of content to the expression tree that might be allocated +# from lookaside. But the schema is not tied to a particular database +# connection, so the use of lookaside memory is prohibited. The fix +# is to change the generated column expression to NULL before adding it +# to the schema. +# +reset_db +do_test gencol1-15.10 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 8192 pagesize 4096 filename c27.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 02 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................ +| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ................ +| 96: 00 2e 3f d8 0d 00 00 00 01 0f ba 00 0f ba 00 00 ..?............. +| 4016: 00 00 00 00 00 00 00 00 00 00 44 01 06 17 11 11 ..........D..... +| 4032: 01 75 74 61 62 6c 65 74 31 74 31 02 43 52 45 41 .utablet1t1.CREA +| 4048: 54 45 20 54 41 42 4c 45 20 74 31 28 61 20 49 4e TE TABLE t1(a IN +| 4064: 54 2c 20 62 20 41 53 28 28 56 41 4c 55 45 53 28 T, b AS((VALUES( +| 4080: 31 29 29 20 49 53 20 75 6e 6b 6e 6f 77 6e 29 29 1)) IS unknown)) +| page 2 offset 4096 +| 0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 ................ +| end c27.db +}]} {} +do_execsql_test gencol1-15.20 { + PRAGMA writable_schema=ON; + REPLACE INTO t1 VALUES(9); + SELECT a, quote(b) FROM t1 +} {9 NULL} + +# 2019-12-16 ticket 3b84b42943644d6f +# When a table is the right table of a LEFT JOIN and the ON clause is +# false, make sure any generated columns evaluate to NULL. +reset_db +do_execsql_test gencol1-16.10 { + CREATE TABLE t0(c0); + CREATE TABLE t1(c1, c2 AS(1)); + INSERT INTO t0 VALUES(0); + SELECT c0, c1, c2 FROM t0 LEFT JOIN t1; +} {0 {} {}} +do_execsql_test gencol1-16.20 { + DROP TABLE t1; + CREATE TABLE t1(c1, c2 AS (c1 ISNULL)); + SELECT c0, c1, c2 FROM t0 LEFT JOIN t1; +} {0 {} {}} +do_execsql_test gencol1-16.30 { + INSERT INTO t1(c1) VALUES(1),(NULL); + SELECT * FROM t1; +} {1 0 {} 1} +do_execsql_test gencol1-16.40 { + SELECT c0, c1, c2 FROM t0 LEFT JOIN t1 ON c0=c1; +} {0 {} {}} + +# 2019-12-20 ticket e0a8120553f4b082 +# Generated columns with REAL affinity need to have an OP_RealAffinity +# opcode applied, even when the column value is extracted from an index. +# +reset_db +do_execsql_test gencol1-17.10 { + CREATE TABLE t0(c0 REAL AS(1) UNIQUE, c1 INT); + INSERT INTO t0 VALUES(''); + SELECT quote(c0), quote(c1) from t0; +} {1.0 ''} +do_execsql_test gencol1-17.20 { + SELECT *, (1 BETWEEN CAST(t0.c0 AS TEXT) AND t0.c0) FROM t0; +} {1.0 {} 0} +do_execsql_test gencol1-17.30 { + SELECT * FROM t0 WHERE (1 BETWEEN CAST(t0.c0 AS TEXT) AND t0.c0); +} {} +do_execsql_test gencol1-17.40 { + CREATE TABLE t1(a TEXT AS(b) COLLATE nocase, b TEXT, c INT, d DEFAULT 1); + INSERT INTO t1(b,c) VALUES('abc',11),('DEF',22),('ghi',33); + SELECT a FROM t1 WHERE b='DEF' AND a='def'; +} {DEF} +do_execsql_test gencol1-17.50 { + CREATE INDEX t1bca ON t1(b,c,a); + SELECT a FROM t1 WHERE b='DEF' AND a='def'; +} {DEF} + +# 2019-12-26 ticket ec8abb025e78f40c +# An index on a virtual column with a constant value (why would anybody +# ever do such a thing?) can cause problems for a one-pass DELETE. +# +reset_db +do_execsql_test gencol1-18.10 { + CREATE TABLE t0(c0 UNIQUE AS(0), c1, c2); + INSERT INTO t0(c1) VALUES(0); + SELECT * FROM t0; +} {0 0 {}} +do_execsql_test gencol1-18.20 { + UPDATE t0 SET c1=0, c2=0 WHERE c0>=0; + SELECT * FROM t0; +} {0 0 0} + +# 2019-12-27 ticket de4b04149b9fdeae +# +reset_db +do_catchsql_test gencol1-19.10 { + CREATE TABLE t0( + c0 INT AS(2) UNIQUE, + c1 TEXT UNIQUE, + FOREIGN KEY(c0) REFERENCES t0(c1) + ); + INSERT INTO t0(c1) VALUES(0.16334143182538696), (0); +} {1 {UNIQUE constraint failed: t0.c0}} + +finish_test diff --git a/test/in4.test b/test/in4.test index 787b9ea3..37eafdeb 100644 --- a/test/in4.test +++ b/test/in4.test @@ -13,6 +13,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix in4 do_test in4-1.1 { execsql { @@ -338,5 +339,30 @@ do_execsql_test in4-6.2-eqp { SELECT * FROM t6a, t6b WHERE a=3 AND c IN (b); } {~/SCAN/} +reset_db +do_execsql_test 7.0 { + CREATE TABLE t1(a, b, c); + CREATE TABLE t2(d, e); + CREATE INDEX t1bc ON t1(c, b); + INSERT INTO t2(e) VALUES(1); + INSERT INTO t1 VALUES(NULL, NULL, NULL); +} + +do_execsql_test 7.1 { + SELECT * FROM t2 LEFT JOIN t1 ON c = d AND b IN (10,10,10); +} {{} 1 {} {} {}} + +ifcapable rtree { + reset_db + do_execsql_test 7.2 { + CREATE VIRTUAL TABLE t1 USING rtree(a, b, c); + CREATE TABLE t2(d INTEGER, e INT); + INSERT INTO t2(e) VALUES(1); + } + + do_execsql_test 7.3 { + SELECT * FROM t2 LEFT JOIN t1 ON c IN (d) AND b IN (10,10,10); + } {{} 1 {} {} {}} +} finish_test diff --git a/test/index6.test b/test/index6.test index 976c49fb..d3856925 100644 --- a/test/index6.test +++ b/test/index6.test @@ -478,7 +478,24 @@ do_execsql_test index6-16.3 { SELECT 3 FROM t0 WHERE c1 <= c0; } {3} - - +# 2019-11-02 +# Ticket https://sqlite.org/src/tktview/a9efb42811fa41ee286e8 +db close +sqlite3 db :memory: +do_execsql_test index6-17.1 { + CREATE TABLE t0(c0); + CREATE INDEX i0 ON t0(0) WHERE c0 GLOB c0; + INSERT INTO t0 VALUES (0); + CREATE UNIQUE INDEX i1 ON t0(0); + PRAGMA integrity_check; +} {ok} +do_execsql_test index6-17.2 { + CREATE UNIQUE INDEX i2 ON t0(0); + REPLACE INTO t0 VALUES(0); + PRAGMA integrity_check; +} {ok} +do_execsql_test index6-17.3 { + SELECT COUNT(*) FROM t0 WHERE t0.c0 GLOB t0.c0; +} {1} finish_test diff --git a/test/indexexpr1.test b/test/indexexpr1.test index 6b134dbd..19c25735 100644 --- a/test/indexexpr1.test +++ b/test/indexexpr1.test @@ -186,7 +186,7 @@ do_catchsql_test indexexpr1-300 { } {1 {non-deterministic functions prohibited in index expressions}} do_catchsql_test indexexpr1-301 { CREATE INDEX t2x1 ON t2(julianday('now',a)); -} {1 {non-deterministic function in index expression or CHECK constraint}} +} {1 {non-deterministic use of julianday() in an index}} do_catchsql_test indexexpr1-310 { CREATE INDEX t2x2 ON t2(a,b+(SELECT 15)); } {1 {subqueries prohibited in index expressions}} diff --git a/test/indexexpr2.test b/test/indexexpr2.test index 5d387c75..35caef3c 100644 --- a/test/indexexpr2.test +++ b/test/indexexpr2.test @@ -373,4 +373,3 @@ foreach {tn expr} { } finish_test - diff --git a/test/insert.test b/test/insert.test index 397a0e6f..51e62268 100644 --- a/test/insert.test +++ b/test/insert.test @@ -1,4 +1,4 @@ -# 2001 September 15 +# 2001-09-15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: @@ -11,7 +11,6 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the INSERT statement. # -# $Id: insert.test,v 1.31 2007/04/05 11:25:59 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -458,7 +457,7 @@ do_execsql_test insert-14.1 { SELECT x FROM t14; } {1} -integrity_check insert-99.0 +integrity_check insert-14.2 # 2019-08-12. # @@ -475,5 +474,130 @@ do_execsql_test insert-15.1 { SELECT a, length(b) FROM t1; } {4 33000} +# 2019-10-16 +# ticket https://www.sqlite.org/src/info/a8a4847a2d96f5de +# On a REPLACE INTO, if an AFTER trigger adds back the conflicting +# row, you can end up with the wrong number of rows in an index. +# +db close +sqlite3 db :memory: +do_catchsql_test insert-16.1 { + PRAGMA recursive_triggers = true; + CREATE TABLE t0(c0,c1); + CREATE UNIQUE INDEX i0 ON t0(c0); + INSERT INTO t0(c0,c1) VALUES(123,1); + CREATE TRIGGER tr0 AFTER DELETE ON t0 + BEGIN + INSERT INTO t0 VALUES(123,2); + END; + REPLACE INTO t0(c0,c1) VALUES(123,3); +} {1 {UNIQUE constraint failed: t0.c0}} +do_execsql_test insert-16.2 { + SELECT * FROM t0; +} {123 1} +integrity_check insert-16.3 +do_catchsql_test insert-16.4 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + CREATE INDEX t1b ON t1(b); + INSERT INTO t1 VALUES(1, 'one'); + CREATE TRIGGER tr3 AFTER DELETE ON t1 BEGIN + INSERT INTO t1 VALUES(1, 'three'); + END; + REPLACE INTO t1 VALUES(1, 'two'); +} {1 {UNIQUE constraint failed: t1.a}} +integrity_check insert-16.5 +do_catchsql_test insert-16.6 { + PRAGMA foreign_keys = 1; + CREATE TABLE p1(a, b UNIQUE); + CREATE TABLE c1(c, d REFERENCES p1(b) ON DELETE CASCADE); + CREATE TRIGGER tr6 AFTER DELETE ON c1 BEGIN + INSERT INTO p1 VALUES(4, 1); + END; + INSERT INTO p1 VALUES(1, 1); + INSERT INTO c1 VALUES(2, 1); + REPLACE INTO p1 VALUES(3, 1);2 +} {1 {UNIQUE constraint failed: p1.b}} +integrity_check insert-16.7 + +# 2019-10-25 ticket c1e19e12046d23fe +do_catchsql_test insert-17.1 { + PRAGMA temp.recursive_triggers = true; + DROP TABLE IF EXISTS t0; + CREATE TABLE t0(aa, bb); + CREATE UNIQUE INDEX t0bb ON t0(bb); + CREATE TRIGGER "r17.1" BEFORE DELETE ON t0 + BEGIN INSERT INTO t0(aa,bb) VALUES(99,1); + END; + INSERT INTO t0(aa,bb) VALUES(10,20); + REPLACE INTO t0(aa,bb) VALUES(30,20); +} {1 {UNIQUE constraint failed: t0.rowid}} +integrity_check insert-17.2 +do_catchsql_test insert-17.3 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a, b UNIQUE, c UNIQUE); + INSERT INTO t1(a,b,c) VALUES(1,1,1),(2,2,2),(3,3,3),(4,4,4); + CREATE TRIGGER "r17.3" AFTER DELETE ON t1 WHEN OLD.c<>3 BEGIN + INSERT INTO t1(rowid,a,b,c) VALUES(100,100,100,3); + END; + REPLACE INTO t1(rowid,a,b,c) VALUES(200,1,2,3); +} {1 {UNIQUE constraint failed: t1.c}} +integrity_check insert-17.4 +do_execsql_test insert-17.5 { + CREATE TABLE t2(a INTEGER PRIMARY KEY, b); + CREATE UNIQUE INDEX t2b ON t2(b); + INSERT INTO t2(a,b) VALUES(1,1),(2,2),(3,3),(4,4); + CREATE TABLE fire(x); + CREATE TRIGGER t2r1 AFTER DELETE ON t2 BEGIN + INSERT INTO fire VALUES(old.a); + END; + UPDATE OR REPLACE t2 SET a=4, b=3 WHERE a=1; + SELECT *, 'x' FROM t2 ORDER BY a; +} {2 2 x 4 3 x} +do_execsql_test insert-17.6 { + SELECT x FROM fire ORDER BY x; +} {3 4} +do_execsql_test insert-17.7 { + DELETE FROM t2; + DELETE FROM fire; + INSERT INTO t2(a,b) VALUES(1,1),(2,2),(3,3),(4,4); + UPDATE OR REPLACE t2 SET a=1, b=3 WHERE a=1; + SELECT *, 'x' FROM t2 ORDER BY a; +} {1 3 x 2 2 x 4 4 x} +do_execsql_test insert-17.8 { + SELECT x FROM fire ORDER BY x; +} {3} +do_execsql_test insert-17.10 { + CREATE TABLE t3(a INTEGER PRIMARY KEY, b INT, c INT, d INT); + CREATE UNIQUE INDEX t3bpi ON t3(b) WHERE c<=d; + CREATE UNIQUE INDEX t3d ON t3(d); + INSERT INTO t3(a,b,c,d) VALUES(1,1,1,1),(2,1,3,2),(3,4,5,6); + CREATE TRIGGER t3r1 AFTER DELETE ON t3 BEGIN + SELECT 'hi'; + END; + REPLACE INTO t3(a,b,c,d) VALUES(4,4,8,9); +} {} +do_execsql_test insert-17.11 { + SELECT *, 'x' FROM t3 ORDER BY a; +} {1 1 1 1 x 2 1 3 2 x 4 4 8 9 x} +do_execsql_test insert-17.12 { + REPLACE INTO t3(a,b,c,d) VALUES(5,1,11,2); + SELECT *, 'x' FROM t3 ORDER BY a; +} {1 1 1 1 x 4 4 8 9 x 5 1 11 2 x} + +do_execsql_test insert-17.13 { + DELETE FROM t3; + INSERT INTO t3(a,b,c,d) VALUES(1,1,1,1),(2,1,3,2),(3,4,5,6); + DROP TRIGGER t3r1; + CREATE TRIGGER t3r1 AFTER DELETE ON t3 BEGIN + INSERT INTO t3(b,c,d) VALUES(old.b,old.c,old.d); + END; +} {} +do_catchsql_test insert-17.14 { + REPLACE INTO t3(a,b,c,d) VALUES(4,4,8,9); +} {1 {UNIQUE constraint failed: t3.b}} +do_catchsql_test insert-17.15 { + REPLACE INTO t3(a,b,c,d) VALUES(5,1,11,2); +} {1 {UNIQUE constraint failed: t3.d}} + finish_test diff --git a/test/insert4.test b/test/insert4.test index c819b808..4c6a6d4a 100644 --- a/test/insert4.test +++ b/test/insert4.test @@ -34,8 +34,8 @@ proc xferopt_test {testname N} { # Create tables used for testing. # +sqlite3_db_config db LEGACY_FILE_FORMAT 0 execsql { - PRAGMA legacy_file_format = 0; CREATE TABLE t1(a int, b int, check(b>a)); CREATE TABLE t2(x int, y int); CREATE VIEW v2 AS SELECT y, x FROM t2; diff --git a/test/instrfault.test b/test/instrfault.test index 0ddb12c8..848e46e4 100644 --- a/test/instrfault.test +++ b/test/instrfault.test @@ -69,7 +69,7 @@ foreach {enc} { do_faultsim_test 1.$enc.4 -faults oom-t* -prep { set ::stmt [sqlite3_prepare_v2 db "SELECT instr(?, ?)" -1 dummy] sqlite3_bind_blob $::stmt 1 $::HAYSTACK [string length $::HAYSTACK] - sqlite3_bind_text $::stmt 2 $::NEEDLE [string length $::NEEDLE] + sqlite3_bind_blob $::stmt 2 $::NEEDLE [string length $::NEEDLE] } -body { set rc [sqlite3_step $::stmt] if {$rc=="SQLITE_NOMEM"} { error "out of memory" } diff --git a/test/join.test b/test/join.test index 68218620..75f311b8 100644 --- a/test/join.test +++ b/test/join.test @@ -905,5 +905,125 @@ do_execsql_test join-18.4 { SELECT NOT(v0.a IS FALSE) FROM v0 } {1} +#------------------------------------------------------------------------- +reset_db +do_execsql_test join-19.0 { + CREATE TABLE t1(a); + CREATE TABLE t2(b); + INSERT INTO t1(a) VALUES(0); + CREATE VIEW v0(c) AS SELECT t2.b FROM t1 LEFT JOIN t2; +} + +do_execsql_test join-19.1 { + SELECT * FROM v0 WHERE v0.c NOTNULL NOTNULL; +} {{}} + +do_execsql_test join-19.2 { + SELECT * FROM t1 LEFT JOIN t2 +} {0 {}} + +do_execsql_test join-19.3 { + SELECT * FROM t1 LEFT JOIN t2 WHERE (b IS NOT NULL) IS NOT NULL; +} {0 {}} + +do_execsql_test join-19.4 { + SELECT (b IS NOT NULL) IS NOT NULL FROM t1 LEFT JOIN t2 +} {1} + +do_execsql_test join-19.5 { + SELECT * FROM t1 LEFT JOIN t2 WHERE + (b IS NOT NULL AND b IS NOT NULL) IS NOT NULL; +} {0 {}} + +# 2019-11-02 ticket 623eff57e76d45f6 +# The optimization of exclusing the WHERE expression of a partial index +# from the WHERE clause of the query if the index is used does not work +# of the table of the index is the right-hand table of a LEFT JOIN. +# +db close +sqlite3 db :memory: +do_execsql_test join-20.1 { + CREATE TABLE t1(c1); + CREATE TABLE t0(c0); + INSERT INTO t0(c0) VALUES (0); + SELECT * FROM t0 LEFT JOIN t1 WHERE NULL IN (c1); +} {} +do_execsql_test join-20.2 { + CREATE INDEX t1x ON t1(0) WHERE NULL IN (c1); + SELECT * FROM t0 LEFT JOIN t1 WHERE NULL IN (c1); +} {} + +# 2019-11-30 ticket 7f39060a24b47353 +# Do not allow a WHERE clause term to qualify a partial index on the +# right table of a LEFT JOIN. +# +do_execsql_test join-21.10 { + DROP TABLE t0; + DROP TABLE t1; + CREATE TABLE t0(aa); + CREATE TABLE t1(bb); + INSERT INTO t0(aa) VALUES (1); + INSERT INTO t1(bb) VALUES (1); + SELECT 11, * FROM t1 LEFT JOIN t0 WHERE aa ISNULL; + SELECT 12, * FROM t1 LEFT JOIN t0 WHERE +aa ISNULL; + SELECT 13, * FROM t1 LEFT JOIN t0 ON aa ISNULL; + SELECT 14, * FROM t1 LEFT JOIN t0 ON +aa ISNULL; + CREATE INDEX i0 ON t0(aa) WHERE aa ISNULL; + SELECT 21, * FROM t1 LEFT JOIN t0 WHERE aa ISNULL; + SELECT 22, * FROM t1 LEFT JOIN t0 WHERE +aa ISNULL; + SELECT 23, * FROM t1 LEFT JOIN t0 ON aa ISNULL; + SELECT 24, * FROM t1 LEFT JOIN t0 ON +aa ISNULL; +} {13 1 {} 14 1 {} 23 1 {} 24 1 {}} + +# 2019-12-18 problem with a LEFT JOIN where the RHS is a view. +# Detected by Yongheng and Rui. +# Follows from the optimization attempt of check-in 41c27bc0ff1d3135 +# on 2017-04-18 +# +reset_db +do_execsql_test join-22.10 { + CREATE TABLE t0(a, b); + CREATE INDEX t0a ON t0(a); + INSERT INTO t0 VALUES(10,10),(10,11),(10,12); + SELECT DISTINCT c FROM t0 LEFT JOIN (SELECT a+1 AS c FROM t0) ORDER BY c ; +} {11} + +# 2019-12-22 ticket 7929c1efb2d67e98 +# +reset_db +ifcapable vtab { +do_execsql_test join-23.10 { + CREATE TABLE t0(c0); + INSERT INTO t0(c0) VALUES(123); + CREATE VIEW v0(c0) AS SELECT 0 GROUP BY 1; + SELECT t0.c0, v0.c0, vt0.name + FROM v0, t0 LEFT JOIN pragma_table_info('t0') AS vt0 + ON vt0.name LIKE 'c0' + WHERE v0.c0 == 0; +} {123 0 c0} +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test join-24.1 { + CREATE TABLE t1(a PRIMARY KEY, x); + CREATE TABLE t2(b INT); + CREATE INDEX t1aa ON t1(a, a); + + INSERT INTO t1 VALUES('abc', 'def'); + INSERT INTO t2 VALUES(1); +} + +do_execsql_test join-24.2 { + SELECT * FROM t2 JOIN t1 WHERE a='abc' AND x='def'; +} {1 abc def} +do_execsql_test join-24.3 { + SELECT * FROM t2 JOIN t1 WHERE a='abc' AND x='abc'; +} {} + +do_execsql_test join-24.2 { + SELECT * FROM t2 LEFT JOIN t1 ON a=0 WHERE (x='x' OR x IS NULL); +} {1 {} {}} + finish_test diff --git a/test/join2.test b/test/join2.test index 5a70573e..bfcecda2 100644 --- a/test/join2.test +++ b/test/join2.test @@ -279,5 +279,19 @@ do_execsql_test 7.0 { SELECT * FROM test; } {3 4 {} {} {} x 5 6 {} {} {} x} +#------------------------------------------------------------------------- +# Ticket [dfd66334]. +# +reset_db +do_execsql_test 8.0 { + CREATE TABLE t0(c0); + CREATE TABLE t1(c0); +} + +do_execsql_test 8.1 { + SELECT * FROM t0 LEFT JOIN t1 + WHERE (t1.c0 BETWEEN 0 AND 0) > ('' AND t0.c0); +} + finish_test diff --git a/test/journal3.test b/test/journal3.test index 9dc7aa25..c3e3d12d 100644 --- a/test/journal3.test +++ b/test/journal3.test @@ -38,6 +38,7 @@ if {$::tcl_platform(platform) == "unix" } { db close #set effective [format %.5o [expr $permissions & ~$umask]] + set res "/[regsub {^00} $permissions {0.}]/" if {$tcl_version>=8.7} { regsub {^00} $permissions {0o} permissions } @@ -46,7 +47,7 @@ if {$::tcl_platform(platform) == "unix" catch { forcedelete test.db-journal } file attributes test.db -permissions $permissions file attributes test.db -permissions - } $permissions + } $res do_test journal3-1.2.$tn.2 { file exists test.db-journal } {0} do_test journal3-1.2.$tn.3 { sqlite3 db test.db @@ -58,7 +59,7 @@ if {$::tcl_platform(platform) == "unix" } {1} do_test journal3-1.2.$tn.4 { file attr test.db-journal -perm - } $effective + } $res do_execsql_test journal3-1.2.$tn.5 { ROLLBACK } {} } diff --git a/test/json101.test b/test/json101.test index 534478df..0d59f2e8 100644 --- a/test/json101.test +++ b/test/json101.test @@ -832,4 +832,19 @@ do_execsql_test json-15.130 { SELECT xyz.* FROM (JSON_EACH('{"a":1, "b":2}')) AS xyz; } {a 1 integer 1 2 {} {$.a} {$} b 2 integer 2 4 {} {$.b} {$}} +# 2019-11-10 +# Mailing list bug report on the handling of surrogate pairs +# in JSON. +# +do_execsql_test json-16.10 { + SELECT length(json_extract('"abc\uD834\uDD1Exyz"','$')); +} {7} +do_execsql_test json-16.20 { + SELECT length(json_extract('"\uD834\uDD1E"','$')); +} {1} +do_execsql_test json-16.30 { + SELECT unicode(json_extract('"\uD834\uDD1E"','$')); +} {119070} + + finish_test diff --git a/test/json105.test b/test/json105.test new file mode 100644 index 00000000..46d36774 --- /dev/null +++ b/test/json105.test @@ -0,0 +1,118 @@ +# 2019-11-22 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements tests for "[#]" extension to json-path +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix json104 + +ifcapable !json1 { + finish_test + return +} + +# This is the example from pages 2 and 3 of RFC-7396 +db eval { + CREATE TABLE t1(j); + INSERT INTO t1(j) VALUES('{"a":1,"b":[1,[2,3],4],"c":99}'); +} +proc json_extract_test {testnum path result} { + do_execsql_test json105-1.$testnum "SELECT quote(json_extract(j,$path)) FROM t1" $result +} +json_extract_test 10 {'$.b[#]'} NULL +json_extract_test 20 {'$.b[#-1]'} 4 +json_extract_test 30 {'$.b[#-2]'} {'[2,3]'} +json_extract_test 31 {'$.b[#-02]'} {'[2,3]'} +json_extract_test 40 {'$.b[#-3]'} 1 +json_extract_test 50 {'$.b[#-4]'} NULL +json_extract_test 60 {'$.b[#-2][#-1]'} 3 +json_extract_test 70 {'$.b[0]','$.b[#-1]'} {'[1,4]'} + +json_extract_test 100 {'$.a[#-1]'} NULL +json_extract_test 110 {'$.b[#-000001]'} 4 + +proc json_remove_test {testnum path result} { + do_execsql_test json105-2.$testnum "SELECT quote(json_remove(j,$path)) FROM t1" $result +} +json_remove_test 10 {'$.b[#]'} {'{"a":1,"b":[1,[2,3],4],"c":99}'} +json_remove_test 20 {'$.b[#-0]'} {'{"a":1,"b":[1,[2,3],4],"c":99}'} +json_remove_test 30 {'$.b[#-1]'} {'{"a":1,"b":[1,[2,3]],"c":99}'} +json_remove_test 40 {'$.b[#-2]'} {'{"a":1,"b":[1,4],"c":99}'} +json_remove_test 50 {'$.b[#-3]'} {'{"a":1,"b":[[2,3],4],"c":99}'} +json_remove_test 60 {'$.b[#-4]'} {'{"a":1,"b":[1,[2,3],4],"c":99}'} +json_remove_test 70 {'$.b[#-2][#-1]'} {'{"a":1,"b":[1,[2],4],"c":99}'} + +json_remove_test 100 {'$.b[0]','$.b[#-1]'} {'{"a":1,"b":[[2,3]],"c":99}'} +json_remove_test 110 {'$.b[#-1]','$.b[0]'} {'{"a":1,"b":[[2,3]],"c":99}'} +json_remove_test 120 {'$.b[#-1]','$.b[#-2]'} {'{"a":1,"b":[[2,3]],"c":99}'} +json_remove_test 130 {'$.b[#-1]','$.b[#-1]'} {'{"a":1,"b":[1],"c":99}'} +json_remove_test 140 {'$.b[#-2]','$.b[#-1]'} {'{"a":1,"b":[1],"c":99}'} + +proc json_insert_test {testnum x result} { + do_execsql_test json105-3.$testnum "SELECT quote(json_insert(j,$x)) FROM t1" $result +} +json_insert_test 10 {'$.b[#]','AAA'} {'{"a":1,"b":[1,[2,3],4,"AAA"],"c":99}'} +json_insert_test 20 {'$.b[1][#]','AAA'} {'{"a":1,"b":[1,[2,3,"AAA"],4],"c":99}'} +json_insert_test 30 {'$.b[1][#]','AAA','$.b[#]','BBB'} \ + {'{"a":1,"b":[1,[2,3,"AAA"],4,"BBB"],"c":99}'} +json_insert_test 40 {'$.b[#]','AAA','$.b[#]','BBB'} \ + {'{"a":1,"b":[1,[2,3],4,"AAA","BBB"],"c":99}'} + +proc json_set_test {testnum x result} { + do_execsql_test json105-4.$testnum "SELECT quote(json_set(j,$x)) FROM t1" $result +} +json_set_test 10 {'$.b[#]','AAA'} {'{"a":1,"b":[1,[2,3],4,"AAA"],"c":99}'} +json_set_test 20 {'$.b[1][#]','AAA'} {'{"a":1,"b":[1,[2,3,"AAA"],4],"c":99}'} +json_set_test 30 {'$.b[1][#]','AAA','$.b[#]','BBB'} \ + {'{"a":1,"b":[1,[2,3,"AAA"],4,"BBB"],"c":99}'} +json_set_test 40 {'$.b[#]','AAA','$.b[#]','BBB'} \ + {'{"a":1,"b":[1,[2,3],4,"AAA","BBB"],"c":99}'} +json_set_test 50 {'$.b[#-1]','AAA'} {'{"a":1,"b":[1,[2,3],"AAA"],"c":99}'} +json_set_test 60 {'$.b[1][#-1]','AAA'} {'{"a":1,"b":[1,[2,"AAA"],4],"c":99}'} +json_set_test 70 {'$.b[1][#-1]','AAA','$.b[#-1]','BBB'} \ + {'{"a":1,"b":[1,[2,"AAA"],"BBB"],"c":99}'} +json_set_test 80 {'$.b[#-1]','AAA','$.b[#-1]','BBB'} \ + {'{"a":1,"b":[1,[2,3],"BBB"],"c":99}'} + +proc json_replace_test {testnum x result} { + do_execsql_test json105-5.$testnum "SELECT quote(json_replace(j,$x)) FROM t1" $result +} +json_replace_test 10 {'$.b[#]','AAA'} {'{"a":1,"b":[1,[2,3],4],"c":99}'} +json_replace_test 20 {'$.b[1][#]','AAA'} {'{"a":1,"b":[1,[2,3],4],"c":99}'} +json_replace_test 30 {'$.b[1][#]','AAA','$.b[#]','BBB'} \ + {'{"a":1,"b":[1,[2,3],4],"c":99}'} +json_replace_test 40 {'$.b[#]','AAA','$.b[#]','BBB'} \ + {'{"a":1,"b":[1,[2,3],4],"c":99}'} +json_replace_test 50 {'$.b[#-1]','AAA'} {'{"a":1,"b":[1,[2,3],"AAA"],"c":99}'} +json_replace_test 60 {'$.b[1][#-1]','AAA'} {'{"a":1,"b":[1,[2,"AAA"],4],"c":99}'} +json_replace_test 70 {'$.b[1][#-1]','AAA','$.b[#-1]','BBB'} \ + {'{"a":1,"b":[1,[2,"AAA"],"BBB"],"c":99}'} +json_replace_test 80 {'$.b[#-1]','AAA','$.b[#-1]','BBB'} \ + {'{"a":1,"b":[1,[2,3],"BBB"],"c":99}'} + +do_catchsql_test json105-6.10 { + SELECT json_extract(j, '$.b[#-]') FROM t1; +} {1 {JSON path error near '[#-]'}} +do_catchsql_test json105-6.20 { + SELECT json_extract(j, '$.b[#9]') FROM t1; +} {1 {JSON path error near '[#9]'}} +do_catchsql_test json105-6.30 { + SELECT json_extract(j, '$.b[#+2]') FROM t1; +} {1 {JSON path error near '[#+2]'}} +do_catchsql_test json105-6.40 { + SELECT json_extract(j, '$.b[#-1') FROM t1; +} {1 {JSON path error near '[#-1'}} +do_catchsql_test json105-6.50 { + SELECT json_extract(j, '$.b[#-1x]') FROM t1; +} {1 {JSON path error near '[#-1x]'}} + +finish_test diff --git a/test/minmax2.test b/test/minmax2.test index b6114f2e..51291462 100644 --- a/test/minmax2.test +++ b/test/minmax2.test @@ -21,8 +21,8 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl do_test minmax2-1.0 { + sqlite3_db_config db LEGACY_FILE_FORMAT 0 execsql { - PRAGMA legacy_file_format=0; BEGIN; CREATE TABLE t1(x, y); INSERT INTO t1 VALUES(1,1); diff --git a/test/normalize.test b/test/normalize.test index 8b0c7ed8..29a5aabb 100644 --- a/test/normalize.test +++ b/test/normalize.test @@ -347,6 +347,36 @@ foreach {tnum sql flags norm} { {SELECT x FROM t1 WHERE x IN ([x] IS NOT NULL, NULL, 1, 'a', "b", x'00');} 0x2 {0 {SELECT x FROM t1 WHERE x IN(x IS NOT NULL,?,?,?,b,?);}} + + 800 + {ATTACH "normalize800.db" AS somefile;} + 0x2 + {0 {ATTACH"normalize800.db"AS somefile;}} + + 810 + {ATTACH DATABASE "normalize810.db" AS somefile;} + 0x2 + {0 {ATTACH DATABASE"normalize810.db"AS somefile;}} + + 900 + {INSERT INTO t1 (x) VALUES("sl1"), (1), ("sl2"), ('i');} + 0x2 + {0 {INSERT INTO t1(x)VALUES(?),(?),(?),(?);}} + + 910 + {UPDATE t1 SET x = "sl1" WHERE x IN (1, "sl2", 'i');} + 0x2 + {0 {UPDATE t1 SET x=?WHERE x IN(?,?,?);}} + + 920 + {UPDATE t1 SET x = "y" WHERE x IN (1, "sl1", 'i');} + 0x2 + {0 {UPDATE t1 SET x=y WHERE x IN(?,?,?);}} + + 930 + {DELETE FROM t1 WHERE x IN (1, "sl1", 'i');} + 0x2 + {0 {DELETE FROM t1 WHERE x IN(?,?,?);}} } { do_test $tnum { set code [catch { diff --git a/test/nulls1.test b/test/nulls1.test index 98fc6ab3..9f4402f9 100644 --- a/test/nulls1.test +++ b/test/nulls1.test @@ -248,6 +248,54 @@ do_execsql_test 7.0 { SELECT * FROM t71 ORDER BY a DESC NULLS FIRST; } +# 2019-12-18 gramfuzz1 find +# NULLS LAST not allows on an INTEGER PRIMARY KEY. +# +do_catchsql_test 8.0 { + CREATE TABLE t80(a, b INTEGER, PRIMARY KEY(b NULLS LAST)) WITHOUT ROWID; +} {1 {unsupported use of NULLS LAST}} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 9.0 { + CREATE TABLE v0 (c1, c2, c3); + CREATE INDEX v3 ON v0 (c1, c2, c3); +} +do_execsql_test 9.1 { + ANALYZE sqlite_master; + INSERT INTO sqlite_stat1 VALUES('v0','v3','648 324 81'); + ANALYZE sqlite_master; +} + +do_execsql_test 9.2 { + INSERT INTO v0 VALUES + (1, 10, 'b'), + (1, 10, 'd'), + (1, 10, NULL), + (2, 10, 'a'), + (2, 10, NULL), + (1, 10, 'c'), + (2, 10, 'b'), + (1, 10, 'a'), + (1, 10, NULL), + (2, 10, NULL), + (2, 10, 'd'), + (2, 10, 'c'); +} + +do_execsql_test 9.3 { + SELECT c1, c2, ifnull(c3, 'NULL') FROM v0 + WHERE c2=10 ORDER BY c1, c3 NULLS LAST +} { + 1 10 a 1 10 b 1 10 c 1 10 d 1 10 NULL 1 10 NULL + 2 10 a 2 10 b 2 10 c 2 10 d 2 10 NULL 2 10 NULL +} + +do_eqp_test 9.4 { + SELECT c1, c2, ifnull(c3, 'NULL') FROM v0 + WHERE c2=10 ORDER BY c1, c3 NULLS LAST +} {SEARCH TABLE v0 USING COVERING INDEX v3 (ANY(c1) AND c2=?)} + + + finish_test - - diff --git a/test/orderby1.test b/test/orderby1.test index 836ca4b8..5152ffaf 100644 --- a/test/orderby1.test +++ b/test/orderby1.test @@ -558,5 +558,9 @@ do_execsql_test 10.0 { SELECT b, rowid, '^' FROM t10 ORDER BY b, a LIMIT 4; } {2 1 ^ 4 3 ^ 4 4 ^ 7 5 ^} +do_catchsql_test 11.0 { + VALUES(2) EXCEPT SELECT '' ORDER BY abc +} {1 {1st ORDER BY term does not match any column in the result set}} + finish_test diff --git a/test/ossfuzz.c b/test/ossfuzz.c index 3b1017f7..b0156a64 100644 --- a/test/ossfuzz.c +++ b/test/ossfuzz.c @@ -155,6 +155,9 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { /* Set a limit on the maximum size of a prepared statement */ sqlite3_limit(cx.db, SQLITE_LIMIT_VDBE_OP, 25000); + /* Limit total memory available to SQLite to 20MB */ + sqlite3_hard_heap_limit64(20000000); + /* Set a limit on the maximum length of a string or BLOB. Without this ** limit, fuzzers will invoke randomblob(N) for a large N, and the process ** will timeout trying to generate the huge blob */ diff --git a/test/pragma3.test b/test/pragma3.test index eebbcbb9..c4794c74 100644 --- a/test/pragma3.test +++ b/test/pragma3.test @@ -255,4 +255,33 @@ if {[permutation]!="inmemory_journal"} { } } +#------------------------------------------------------------------------- +# Check that empty write transactions do not cause the return of "PRAGMA +# data_version" to be decremented with journal_mode=PERSIST and +# locking_mode=EXCLUSIVE +# +foreach {tn sql} { + A { + } + B { + PRAGMA journal_mode = PERSIST; + PRAGMA locking_mode = EXCLUSIVE; + } +} { + reset_db + execsql $sql + + do_execsql_test pragma3-510$tn { + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES(1, 2); + PRAGMA data_version; + } {1} + + do_execsql_test pragma3-520$tn { + BEGIN EXCLUSIVE; + COMMIT; + PRAGMA data_version; + } {1} +} + finish_test diff --git a/test/pragma4.test b/test/pragma4.test index bceb4b84..2eef060b 100644 --- a/test/pragma4.test +++ b/test/pragma4.test @@ -44,7 +44,6 @@ foreach {tn sql} { 14 "PRAGMA full_column_names = 1" 15 "PRAGMA fullfsync = 1" 16 "PRAGMA ignore_check_constraints = 1" - 17 "PRAGMA legacy_file_format = 1" 18 "PRAGMA page_size = 511" 19 "PRAGMA page_size = 512" 20 "PRAGMA query_only = false" diff --git a/test/pragma5.test b/test/pragma5.test index f16e4627..6d9b5bbc 100644 --- a/test/pragma5.test +++ b/test/pragma5.test @@ -32,12 +32,18 @@ do_execsql_test 1.0 { } { 0 name {} 0 {} 0 1 builtin {} 0 {} 0 + 2 type {} 0 {} 0 + 3 enc {} 0 {} 0 + 4 narg {} 0 {} 0 + 5 flags {} 0 {} 0 } do_execsql_test 1.1 { - SELECT * FROM pragma_function_list WHERE name='upper' AND builtin + SELECT DISTINCT name, builtin + FROM pragma_function_list WHERE name='upper' AND builtin } {upper 1} do_execsql_test 1.2 { - SELECT * FROM pragma_function_list WHERE name LIKE 'exter%'; + SELECT DISTINCT name, builtin + FROM pragma_function_list WHERE name LIKE 'exter%'; } {external 0} ifcapable fts5 { diff --git a/test/rowvalue.test b/test/rowvalue.test index e8590247..e3b66a10 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -570,4 +570,78 @@ do_execsql_test 22.100 { SELECT (SELECT 5,6 UNION SELECT 3,4 ORDER BY 1 DESC) IN (SELECT 5,6); } {1 0 1 0 0 1 0 1} +# 2019-10-21 Ticket b47e3627ecaadbde +# +do_execsql_test 23.100 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0(aa COLLATE NOCASE, bb); + INSERT INTO t0 VALUES('a', 'A'); + SELECT (+bb,1) >= (aa, 1), (aa,1)<=(+bb,1) FROM t0; + SELECT 2 FROM t0 WHERE (+bb,1) >= (aa,1); + SELECT 3 FROM t0 WHERE (aa,1) <= (+bb,1); +} {0 1 3} +do_execsql_test 23.110 { + SELECT (SELECT +bb,1) >= (aa, 1), (aa,1)<=(SELECT +bb,1) FROM t0; + SELECT 2 FROM t0 WHERE (SELECT +bb,1) >= (aa,1); + SELECT 3 FROM t0 WHERE (aa,1) <= (SELECT +bb,1); +} {0 1 3} + +# 2019-10-22 Ticket 6ef984af8972c2eb +do_execsql_test 24.100 { + DROP TABLE t0; + CREATE TABLE t0(c0 TEXT PRIMARY KEY); + INSERT INTO t0(c0) VALUES (''); + SELECT (t0.c0, TRUE) > (CAST(0 AS REAL), FALSE) FROM t0; + SELECT 2 FROM t0 WHERE (t0.c0, TRUE) > (CAST('' AS REAL), FALSE); +} {1 2} + +# 2019-10-23 Ticket 135c9da7513e5a97 +do_execsql_test 25.10 { + DROP TABLE t0; + CREATE TABLE t0(c0 UNIQUE); + INSERT INTO t0(c0) VALUES('a'); + SELECT (t0.c0, 0) < ('B' COLLATE NOCASE, 0) FROM t0; + SELECT 2 FROM t0 WHERE (t0.c0, 0) < ('B' COLLATE NOCASE, 0); +} {1 2} +do_execsql_test 25.20 { + SELECT ('B' COLLATE NOCASE, 0)> (t0.c0, 0) FROM t0; + SELECT 2 FROM t0 WHERE ('B' COLLATE NOCASE, 0)> (t0.c0, 0); +} {1 2} +do_execsql_test 25.30 { + SELECT ('B', 0)> (t0.c0 COLLATE nocase, 0) FROM t0; + SELECT 2 FROM t0 WHERE ('B', 0)> (t0.c0 COLLATE nocase, 0); +} {1 2} +do_execsql_test 25.40 { + SELECT (t0.c0 COLLATE nocase, 0) < ('B', 0) FROM t0; + SELECT 2 FROM t0 WHERE (t0.c0 COLLATE nocase, 0) < ('B', 0); +} {1 2} + +# 2019-11-04 Ticket 02aa2bd02f97d0f2 +# The TK_VECTOR operator messes up sqlite3ExprImpliesNonNull() which +# causes incorrect LEFT JOIN strength reduction. TK_VECTOR should be +# treated the same as TK_OR. +# +db close +sqlite3 db :memory: +do_execsql_test 26.10 { + CREATE TABLE t0(c0); + CREATE TABLE t1(c1); + INSERT INTO t1(c1) VALUES (0); + SELECT (c0, x'') != (NULL, 0) FROM t1 LEFT JOIN t0; +} {1} +do_execsql_test 26.20 { + SELECT 2 FROM t1 LEFT JOIN t0 ON (c0, x'') != (NULL, 0); +} {2} +do_execsql_test 26.30 { + SELECT 3 FROM t1 LEFT JOIN t0 WHERE (c0, x'') != (NULL, 0); +} {3} + +# 2019-12-30 ticket 892575cdba4e1e36 +# +reset_db +do_catchsql_test 27.10 { + CREATE TABLE t0(c0 CHECK(((0, 0) > (0, c0)))); + INSERT INTO t0(c0) VALUES(0) ON CONFLICT(c0) DO UPDATE SET c0 = 3; +} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}} + finish_test diff --git a/test/rowvaluevtab.test b/test/rowvaluevtab.test new file mode 100644 index 00000000..d3e0ac7b --- /dev/null +++ b/test/rowvaluevtab.test @@ -0,0 +1,95 @@ +# 2018 October 14 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix rowvaluevtab + +ifcapable !vtab { + finish_test + return +} + +register_echo_module db + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, c); + CREATE INDEX t1b ON t1(b); + INSERT INTO t1 VALUES('one', 1, 1); + INSERT INTO t1 VALUES('two', 1, 2); + INSERT INTO t1 VALUES('three', 1, 3); + INSERT INTO t1 VALUES('four', 2, 1); + INSERT INTO t1 VALUES('five', 2, 2); + INSERT INTO t1 VALUES('six', 2, 3); + INSERT INTO t1 VALUES('seven', 3, 1); + INSERT INTO t1 VALUES('eight', 3, 2); + INSERT INTO t1 VALUES('nine', 3, 3); + + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10000 + ) INSERT INTO t1 SELECT NULL, NULL, NULL FROM s; + CREATE VIRTUAL TABLE e1 USING echo(t1); +} + +proc do_vfilter4_test {tn sql expected} { + set res [list] + db eval "explain $sql" { + if {$opcode=="VFilter"} { + lappend res $p4 + } + } + uplevel [list do_test $tn [list set {} $res] [list {*}$expected]] +} + +do_execsql_test 1.1 { + SELECT a FROM e1 WHERE (b, c) = (2, 2) +} {five} +do_vfilter4_test 1.1f { + SELECT a FROM e1 WHERE (b, c) = (?, ?) +} {{SELECT rowid, a, b, c FROM 't1' WHERE b = ?}} + +do_execsql_test 1.2 { + SELECT a FROM e1 WHERE (b, c) > (2, 2) +} {six seven eight nine} +do_vfilter4_test 1.2f { + SELECT a FROM e1 WHERE (b, c) > (2, 2) +} { + {SELECT rowid, a, b, c FROM 't1' WHERE b >= ?} +} + +do_execsql_test 1.3 { + SELECT a FROM e1 WHERE (b, c) >= (2, 2) +} {five six seven eight nine} +do_vfilter4_test 1.3f { + SELECT a FROM e1 WHERE (b, c) >= (2, 2) +} { + {SELECT rowid, a, b, c FROM 't1' WHERE b >= ?} +} + +do_execsql_test 1.3 { + SELECT a FROM e1 WHERE (b, c) BETWEEN (1, 2) AND (2, 3) +} {two three four five six} +do_vfilter4_test 1.3f { + SELECT a FROM e1 WHERE (b, c) BETWEEN (1, 2) AND (2, 3) +} { + {SELECT rowid, a, b, c FROM 't1' WHERE b >= ? AND b <= ?} +} + +do_execsql_test 1.4 { + SELECT a FROM e1 WHERE (b, c) IN ( VALUES(2, 2) ) +} {five} +do_vfilter4_test 1.4f { + SELECT a FROM e1 WHERE (b, c) IN ( VALUES(2, 2) ) +} {{SELECT rowid, a, b, c FROM 't1' WHERE b = ?}} + +finish_test diff --git a/test/select1.test b/test/select1.test index 27191caf..b9414d38 100644 --- a/test/select1.test +++ b/test/select1.test @@ -1165,4 +1165,40 @@ do_execsql_test select1-18.4 { ); } {1} +# 2019-12-17 gramfuzz find +# +do_execsql_test select-19.10 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(x); +} {} +do_catchsql_test select-19.20 { + INSERT INTO t1 + SELECT 1,2,3,4,5,6,7 + UNION ALL SELECT 1,2,3,4,5,6,7 + ORDER BY 1; +} {1 {table t1 has 1 columns but 7 values were supplied}} +do_catchsql_test select-19.21 { + INSERT INTO t1 + SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + UNION ALL SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + ORDER BY 1; +} {1 {table t1 has 1 columns but 15 values were supplied}} + +# 2020-01-01 Found by Yongheng's fuzzer +# +reset_db +do_execsql_test select-20.10 { + CREATE TABLE t1 ( + a INTEGER PRIMARY KEY, + b AS('Y') UNIQUE + ); + INSERT INTO t1(a) VALUES (10); + SELECT * FROM t1 JOIN t1 USING(a,b) + WHERE ((SELECT t1.a FROM t1 AS x GROUP BY b) AND b=0) + OR a = 10; +} {10 Y} +do_execsql_test select-20.20 { + SELECT ifnull(a, max((SELECT 123))), count(a) FROM t1 ; +} {10 1} + finish_test diff --git a/test/skipscan1.test b/test/skipscan1.test index da9df8fe..367cd2a1 100644 --- a/test/skipscan1.test +++ b/test/skipscan1.test @@ -398,4 +398,25 @@ do_eqp_test skipscan1-3.2 { `--USE TEMP B-TREE FOR DISTINCT } +# 2020-01-06 ticket 304017f5f04a0035 +# +reset_db +do_execsql_test skipscan1-4.10 { + CREATE TABLE t1(a,b INT); + INSERT INTO t1(a,b) VALUES(1,2),(3,3),(4,5); + CREATE UNIQUE INDEX i1 ON t1(b,b,a,a,a,a,a,b,a); + ANALYZE; + DROP TABLE IF EXISTS sqlite_stat4; + INSERT INTO sqlite_stat1 VALUES('t1','i1','30 30 30 2 2 2 2 2 2 2'); + ANALYZE sqlite_master; + + SELECT DISTINCT a + FROM t1 + WHERE a = b + AND a = 3 + AND b IN (1,3,2,4) + AND b >= 0 + AND a <= 10; +} {3} + finish_test diff --git a/test/stat.test b/test/stat.test index 66ca5e2f..105169df 100644 --- a/test/stat.test +++ b/test/stat.test @@ -108,7 +108,7 @@ do_execsql_test stat-2.1 { INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3 ORDER BY rowid; SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload - FROM stat WHERE name != 'sqlite_master'; + FROM stat WHERE name != 'sqlite_master' ORDER BY name; } [list \ sqlite_autoindex_t3_1 / 3 internal 3 368 623 125 \ sqlite_autoindex_t3_1 /000/ 8 leaf 8 946 46 123 \ @@ -134,6 +134,14 @@ do_execsql_test stat-2.1 { t3 /00f/ 23 leaf 2 738 268 370 \ ] +do_execsql_test stat-2.1agg { + SELECT * FROM dbstat WHERE aggregate=TRUE ORDER BY name; +} [list \ + sqlite_autoindex_t3_1 {} 5 {} 32 3898 1065 132 {} 5120 \ + sqlite_master {} 1 {} 2 84 824 49 {} 1024 \ + t3 {} 17 {} 47 11188 5815 370 {} 17408 \ +] + # With every index entry overflowing, make sure no pages are missed # (other than the locking page which is 64 in this test build.) # @@ -150,7 +158,7 @@ do_execsql_test stat-3.1 { CREATE INDEX i4 ON t4(x); INSERT INTO t4(rowid, x) VALUES(2, a_string(7777)); SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload - FROM stat WHERE name != 'sqlite_master'; + FROM stat WHERE name != 'sqlite_master' ORDER BY name; } [list \ i4 / 3 leaf 1 103 905 7782 \ i4 /000+000000 4 overflow 0 1020 0 0 \ @@ -171,6 +179,15 @@ do_execsql_test stat-3.1 { t4 /000+000006 18 overflow 0 1020 0 0 \ ] +do_execsql_test stat-3.2 { + SELECT *, '|' FROM dbstat WHERE aggregate=TRUE ORDER BY name; +} [list \ + i4 {} 9 {} 1 7782 1386 7782 {} 9216 | \ + sqlite_master {} 1 {} 2 74 834 40 {} 1024 | \ + t4 {} 8 {} 1 7780 367 7780 {} 8192 | \ +] + + do_execsql_test stat-4.1 { CREATE TABLE t5(x); CREATE INDEX i5 ON t5(x); @@ -201,6 +218,16 @@ do_execsql_test stat-5.1 { t1 /001+000000 4 overflow 0 1020 0 0 \ ] +do_execsql_test stat-5.20 { + SELECT name, quote(path), pageno, quote(pagetype), ncell, payload, + unused, mx_payload, '|' FROM dbstat('main',1); +} {sqlite_master NULL 1 NULL 1 34 878 34 | tx NULL 1 NULL 0 0 1016 0 |} +do_execsql_test stat-5.21 { + SELECT name, quote(path), pageno, quote(pagetype), ncell, payload, + unused, mx_payload, '|' FROM dbstat('aux1',1); +} {sqlite_master NULL 1 NULL 1 34 878 34 | t1 NULL 3 NULL 2 3033 5 1517 |} + + do_catchsql_test stat-6.1 { CREATE VIRTUAL TABLE temp.s2 USING dbstat(mainx); } {1 {no such database: mainx}} @@ -271,4 +298,21 @@ do_catchsql_test 7.2.4 { SELECT * FROM x3; } {1 {unrecognized token: "123corp"}} + +do_execsql_test 8.1 { + CREATE VIRTUAL TABLE st4 USING dbstat; +} +do_execsql_test 8.2 { + SELECT * FROM st4 WHERE st4.aggregate = NULL; +} +do_execsql_test 8.3 { + SELECT aggregate=1 FROM st4 WHERE aggregate = 5 +} +do_execsql_test 8.4 { + SELECT * FROM st4 WHERE name = NULL; +} {} +do_execsql_test 8.5 { + SELECT * FROM st4 WHERE schema = NULL; +} {} + finish_test diff --git a/test/symlink.test b/test/symlink.test index 4695b29f..98b2a32c 100644 --- a/test/symlink.test +++ b/test/symlink.test @@ -37,11 +37,30 @@ do_test 1.1 { sqlite3_db_filename db2 main } [file join [pwd] test.db] +# But not with the -nofollow flag +# +do_test 1.1.2 { + db2 close + set rc [catch {sqlite3 db2 test.db2 -nofollow 1} msg] + lappend rc $msg +} {1 {unable to open database file}} + +# If the main database is successfully opened with -nofollow, then -nofollow +# is also used for ATTACH. +# +do_test 1.1.3 { + catch {db2 close} + sqlite3 db2 test.db -nofollow 1 +} {} +do_test 1.1.4 { + catchsql {ATTACH 'test.db2' AS aux1;} db2 +} {1 {unable to open database: test.db2}} + # Test that if the symlink points to a file that does not exists, it is # created when it is opened. # do_test 1.2.1 { - db2 close + catch {db2 close} db close forcedelete test.db file exists test.db diff --git a/test/symlink2.test b/test/symlink2.test new file mode 100644 index 00000000..4123092d --- /dev/null +++ b/test/symlink2.test @@ -0,0 +1,116 @@ +# 2019 November 18 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing that SQLite can follow symbolic links. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix symlink2 + +# This only runs on Windows. +if {$::tcl_platform(platform)!="windows"} { + finish_test + return +} + +proc createWin32Symlink { link target } { + exec -- $::env(ComSpec) /c mklink \ + [file nativename $link] [file nativename $target] + return "" +} + +proc deleteWin32Symlink { link } { + exec -- $::env(ComSpec) /c del [file nativename $link] + return "" +} + +proc canCreateWin32Symlink {} { + set link [file join $::testdir lnk[pid].sym] + if {[file exists $link]} { return 0 } + set target [info nameofexecutable] + if {[catch {createWin32Symlink $link $target}] == 0} { + deleteWin32Symlink $link + return 1 + } + return 0 +} + +# Creating symlinks may require administrator privileges on Windows. +if {![canCreateWin32Symlink]} { + finish_test + return +} + +# Ensure that test.db has been created. +# +do_execsql_test 1.0 { + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES(1,9999); +} + +do_test 2.0 { + createWin32Symlink link.db test.db +} {} + +do_test 2.1 { + file exists test.db +} {1} + +do_test 2.2 { + file exists link.db +} {1} + +do_test 3.1 { + execsql { SELECT x, y FROM t1; } db +} {1 9999} + +do_test 3.2 { + sqlite3 db2 link.db + execsql { SELECT x, y FROM t1; } db2 +} {1 9999} + +do_test 3.3 { + sqlite3 db3 test.db -nofollow true + execsql { SELECT x, y FROM t1; } db3 +} {1 9999} + +do_test 3.4 { + db3 close +} {} + +do_test 3.5 { + list [catch { + sqlite3 db4 link.db -nofollow true + execsql { SELECT x, y FROM t1; } db4 + } res] $res +} {1 {unable to open database file}} + +catch {db4 close} + +do_test 4.0 { + db2 close + deleteWin32Symlink link.db +} {} + +do_test 4.1 { + file exists test.db +} {1} + +do_test 4.2 { + file exists link.db +} {0} + +do_test 5.1 { + execsql { SELECT x, y FROM t1; } db +} {1 9999} + +finish_test diff --git a/test/tabfunc01.test b/test/tabfunc01.test index 49f0df88..04bc6f42 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -218,6 +218,15 @@ do_test tabfunc01-750 { } } {5.0 x5 | 7.0 x7 | 13.0 x13 | 17.0 x17 | 23.0 x23 |} +# ticket https://www.sqlite.org/src/info/2ae0c599b735d59e +do_test tabfunc01-751 { + db eval { + SELECT aa.value, bb.value, '|' + FROM carray(inttoptr($PTR4),5,'double') AS aa + LEFT JOIN carray(inttoptr($PTR5),5,'char*') AS bb ON aa.rowid=bb.rowid; + } +} {5.0 x5 | 7.0 x7 | 13.0 x13 | 17.0 x17 | 23.0 x23 |} + # Free up memory allocations intarray_addr int64array_addr diff --git a/test/tclsqlite.test b/test/tclsqlite.test index 92425aef..c111325b 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -25,7 +25,7 @@ set testprefix tcl # Check the error messages generated by tclsqlite # -set r "sqlite_orig HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" +set r "sqlite_orig HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nofollow BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" if {[sqlite3 -has-codec]} { append r " ?-key CODECKEY?" } @@ -371,9 +371,10 @@ ifcapable tclvar { db function r1 userfunc_r1 execsql {SELECT r1(10)} } {55} - do_test tcl-9.11 { - execsql {SELECT r1(100)} - } {5050} + # Fails under -fsanitize=address,undefined due to stack overflow + # do_test tcl-9.11 { + # execsql {SELECT r1(100)} + # } {5050} } # Tests for the new transaction method @@ -789,7 +790,7 @@ do_test 17.6.2 { do_test 17.6.3 { list [catch { db function xyz -n object ret } msg] $msg -} {1 {bad option "-n": must be -argcount, -deterministic, -directonly, or -returntype}} +} {1 {bad option "-n": must be -argcount, -deterministic, -directonly, -innocuous, or -returntype}} # 2019-02-28: The "bind_fallback" command. # diff --git a/test/tester.tcl b/test/tester.tcl index 6efb59bd..05c52343 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -388,6 +388,7 @@ proc print_help_and_quit {} { puts {Options: --pause Wait for user input before continuing --soft-heap-limit=N Set the soft-heap-limit to N + --hard-heap-limit=N Set the hard-heap-limit to N --maxerror=N Quit after N errors --verbose=(0|1) Control the amount of output. Default '1' --output=FILE set --verbose=2 and output to FILE. Implies -q @@ -408,6 +409,7 @@ if {[info exists cmdlinearg]==0} { # # --pause # --soft-heap-limit=NN + # --hard-heap-limit=NN # --maxerror=NN # --malloctrace=N # --backtrace=N @@ -424,6 +426,7 @@ if {[info exists cmdlinearg]==0} { # --help # set cmdlinearg(soft-heap-limit) 0 + set cmdlinearg(hard-heap-limit) 0 set cmdlinearg(maxerror) 1000 set cmdlinearg(malloctrace) 0 set cmdlinearg(backtrace) 10 @@ -450,6 +453,9 @@ if {[info exists cmdlinearg]==0} { {^-+soft-heap-limit=.+$} { foreach {dummy cmdlinearg(soft-heap-limit)} [split $a =] break } + {^-+hard-heap-limit=.+$} { + foreach {dummy cmdlinearg(hard-heap-limit)} [split $a =] break + } {^-+maxerror=.+$} { foreach {dummy cmdlinearg(maxerror)} [split $a =] break } @@ -586,7 +592,8 @@ if {[info exists cmdlinearg]==0} { # way if an individual test file changes the soft-heap-limit, it # will be reset at the start of the next test file. # -sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit) +sqlite3_soft_heap_limit64 $cmdlinearg(soft-heap-limit) +sqlite3_hard_heap_limit64 $cmdlinearg(hard-heap-limit) # Create a test database # @@ -1207,7 +1214,8 @@ proc finalize_testing {} { db close sqlite3_reset_auto_extension - sqlite3_soft_heap_limit 0 + sqlite3_soft_heap_limit64 0 + sqlite3_hard_heap_limit64 0 set nTest [incr_ntest] set nErr [set_test_counter errors] diff --git a/test/tkt-18458b1a.test b/test/tkt-18458b1a.test index 996ca884..4a612748 100644 --- a/test/tkt-18458b1a.test +++ b/test/tkt-18458b1a.test @@ -50,4 +50,3 @@ foreach tn {1 2} { } finish_test - diff --git a/test/tkt-a7debbe0.test b/test/tkt-a7debbe0.test index 974f6d66..cc72eb7b 100644 --- a/test/tkt-a7debbe0.test +++ b/test/tkt-a7debbe0.test @@ -100,4 +100,3 @@ foreach tn {1 2} { } finish_test - diff --git a/test/tkt3292.test b/test/tkt3292.test index 0f952446..717a29c9 100644 --- a/test/tkt3292.test +++ b/test/tkt3292.test @@ -20,8 +20,8 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl do_test tkt3292-1.1 { + sqlite3_db_config db LEGACY_FILE_FORMAT 0 execsql { - PRAGMA legacy_file_format=OFF; CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT); INSERT INTO t1 VALUES(0, 1); INSERT INTO t1 VALUES(1, 1); diff --git a/test/trigger1.test b/test/trigger1.test index ddb40e3a..456e9833 100644 --- a/test/trigger1.test +++ b/test/trigger1.test @@ -782,4 +782,49 @@ do_execsql_test trigger1-20.1 { DROP TRIGGER r20_3; } {} +# 2019-10-24 ticket 50c09fc2cf0d91ce +# +db close +sqlite3 db :memory: +do_execsql_test trigger1-21.1 { + PRAGMA recursive_triggers = true; + CREATE TABLE t0(a, b, c UNIQUE); + CREATE UNIQUE INDEX i0 ON t0(b) WHERE a; + CREATE TRIGGER tr0 AFTER DELETE ON t0 BEGIN + DELETE FROM t0; + END; + INSERT INTO t0(a,b,c) VALUES(0,0,9),(1,1,1); + REPLACE INTO t0(a,b,c) VALUES(2,0,9); + SELECT * FROM t0; +} {2 0 9} + +# 2020-01-04 From Yongheng +# The test case below caused problems for the register validity +# tracking logic. There was no bug in the release build. The +# only problem was a false-positive in the register validity +# tracking. +# +reset_db +do_execsql_test trigger1-22.10 { + CREATE TABLE t1( + a INTEGER PRIMARY KEY, + b DOUBLE + ); + CREATE TRIGGER x AFTER UPDATE ON t1 BEGIN + SELECT sum(b)OVER(ORDER BY (SELECT b FROM t1 AS x + WHERE b IN (t1.a,127,t1.b) + GROUP BY b)) + FROM t1 + GROUP BY a; + END; + CREATE TEMP TRIGGER x BEFORE INSERT ON t1 BEGIN + UPDATE t1 + SET b=randomblob(10) + WHERE b >= 'E' + AND a < (SELECT a FROM t1 WHERE a<22 GROUP BY b); + END; + INSERT INTO t1(b) VALUES('Y'),('X'),('Z'); + SELECT a, CASE WHEN typeof(b)='text' THEN quote(b) ELSE '' END, '|' FROM t1; +} {1 | 2 'X' | 3 'Z' |} + finish_test diff --git a/test/trigger2.test b/test/trigger2.test index 7b939bda..1be72131 100644 --- a/test/trigger2.test +++ b/test/trigger2.test @@ -752,8 +752,23 @@ do_test trigger2-9.1 { } } {} +integrity_check trigger2-9.99 + +# 2019-11-02 Problem found by TH3, related to generated column support. +db close +sqlite3 db :memory: +do_execsql_test trigger2-10.1 { + CREATE TABLE t1(a,b,c,d); + CREATE VIEW v2(a,b,c,d) AS SELECT * FROM t1; + CREATE TRIGGER v2ins INSTEAD OF INSERT ON v2 BEGIN + INSERT INTO t1(a,b,c,d) VALUES(new.a, new.b, new.c, new.d); + END; + INSERT INTO v2(a,d) VALUES(11,14); + SELECT * FROM t1; +} {11 {} {} 14} + } ;# ifcapable view -integrity_check trigger2-9.9 +integrity_check trigger2-999 finish_test diff --git a/test/triggerG.test b/test/triggerG.test index f5965e17..8cf20b5e 100644 --- a/test/triggerG.test +++ b/test/triggerG.test @@ -75,4 +75,20 @@ do_catchsql_test 310 { INSERT INTO t4 VALUES(1); } {1 {hex literal too big: 0x2147483648e0e0099}} +#------------------------------------------------------------------------- +# +do_execsql_test 400 { + CREATE VIEW v0(a) AS SELECT 1234; + CREATE TRIGGER t0001 INSTEAD OF DELETE ON v0 BEGIN + SELECT old.a; + END; +} +do_execsql_test 405 { + SELECT a FROM v0; +} {1234} +do_execsql_test 410 { + DELETE FROM v0; +} + + finish_test diff --git a/test/trustschema1.test b/test/trustschema1.test new file mode 100644 index 00000000..dba954f1 --- /dev/null +++ b/test/trustschema1.test @@ -0,0 +1,251 @@ +# 2020-01-08 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Test cases for managing execution of code snippets found in untrusted +# schemas. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix trustschema1 + +# edgy functions used in generated columns +# +proc f1 {x} {return $x} +do_test 1.100 { + db function f1 -innocuous -deterministic f1 + db function f2 -deterministic f1 + db function f3 -directonly -deterministic f1 + db eval { + CREATE TABLE t1(a, b AS (f1(a+1)), c AS (f2(a+2))); + INSERT INTO t1 VALUES(100),(200); + } +} {} +do_catchsql_test 1.110 { + SELECT a, b, c FROM t1; +} {0 {100 101 102 200 201 202}} +do_execsql_test 1.120 { + PRAGMA trusted_schema=OFF; +} {} +do_catchsql_test 1.130 { + SELECT a, b FROM t1; +} {0 {100 101 200 201}} +do_catchsql_test 1.140 { + SELECT a, b, c FROM t1; +} {1 {unsafe use of f2()}} +do_catchsql_test 1.150 { + PRAGMA trusted_schema=ON; + DROP TABLE t1; + CREATE TABLE t1(a, b AS (f3(a+1))); +} {1 {unsafe use of f3()}} +do_execsql_test 1.160 { + PRAGMA trusted_schema=OFF; + CREATE TEMP TABLE temp1(a,b AS (f3(a+1))); + INSERT INTO temp1(a) VALUES(100),(900); + SELECT * FROM temp1; +} {100 101 900 901} + +# edgy functions used in CHECK constraints +# +do_catchsql_test 1.200 { + PRAGMA trusted_schema=ON; + CREATE TABLE t2(a,b,c,CHECK(f3(c)==c)); +} {1 {unsafe use of f3()}} +do_catchsql_test 1.210 { + PRAGMA trusted_schema=Off; + CREATE TABLE t2(a,b,c,CHECK(f2(c)==c)); +} {1 {unsafe use of f2()}} +do_catchsql_test 1.211 { + PRAGMA trusted_schema=On; + CREATE TABLE t2(a,b,c,CHECK(f2(c)==c)); +} {0 {}} +do_catchsql_test 1.220 { + INSERT INTO t2 VALUES(1,2,3); + SELECT * FROM t2; +} {0 {1 2 3}} +do_catchsql_test 1.230 { + PRAGMA trusted_schema=off; + INSERT INTO t2 VALUES(4,5,6); +} {1 {unsafe use of f2()}} +do_execsql_test 1.231 { + SELECT * FROM t2; +} {1 2 3} +# Ok to put as many edgy functions as you want in a +# TEMP table. +do_execsql_test 1.240 { + PRAGMA trusted_schema=OFF; + CREATE TEMP TABLE temp2(a, b, CHECK(f3(b)==b)); + INSERT INTO temp2(a,b) VALUES(1,2),('x','y'); + SELECT * FROM temp2; +} {1 2 x y} + +# edgy functions used in DEFAULT constraints +# +do_catchsql_test 1.300 { + CREATE TABLE t3(a,b DEFAULT(f2(25))); +} {0 {}} +do_catchsql_test 1.310 { + PRAGMA trusted_schema=Off; + INSERT INTO t3(a) VALUES(1); +} {1 {unsafe use of f2()}} +do_catchsql_test 1.311 { + INSERT INTO t3(a,b) VALUES(1,2); +} {0 {}} +do_execsql_test 1.320 { + CREATE TEMP TABLE temp3(a, b DEFAULT(f3(31))); + INSERT INTO temp3(a) VALUES(22); + SELECT * FROM temp3; +} {22 31} + +# edgy functions used in partial indexes. +# +do_execsql_test 1.400 { + CREATE TABLE t4(a,b,c); + INSERT INTO t4 VALUES(1,2,3),('a','b','c'),(4,'d',0); + SELECT * FROM t4; + CREATE TEMP TABLE temp4(a,b,c); + INSERT INTO temp4 SELECT * FROM t4; +} {1 2 3 a b c 4 d 0} +do_catchsql_test 1.410 { + CREATE INDEX t4a ON t4(a) WHERE f3(c); +} {1 {unsafe use of f3()}} +do_catchsql_test 1.420 { + PRAGMA trusted_schema=OFF; + CREATE INDEX t4a ON t4(a) WHERE f2(c); +} {1 {unsafe use of f2()}} +do_execsql_test 1.421 { + CREATE INDEX t4a ON t4(a) WHERE f1(c); + SELECT a FROM t4 WHERE f1(c) ORDER BY a; +} {1} +do_execsql_test 1.430 { + PRAGMA trusted_schema=ON; + CREATE INDEX t4b ON t4(b) WHERE f2(c); + SELECT b FROM t4 WHERE f2(c) ORDER BY b; +} {2} +do_execsql_test 1.440 { + PRAGMA trusted_schema=OFF; + CREATE INDEX temp4a ON temp4(a) WHERE f3(c); + SELECT a FROM temp4 WHERE f2(c) ORDER BY a; +} {1} + +# edgy functions used in index expressions +# +do_execsql_test 1.500 { + CREATE TABLE t5(a,b,c); + INSERT INTO t5 VALUES(1,2,3),(4,5,6),(7,0,-3); + SELECT * FROM t5; + CREATE TEMP TABLE temp5(a,b,c); + INSERT INTO temp5 SELECT * FROM t5; +} {1 2 3 4 5 6 7 0 -3} +do_catchsql_test 1.510 { + CREATE INDEX t5x1 ON t5(a+f3(b)); +} {1 {unsafe use of f3()}} +do_catchsql_test 1.520 { + PRAGMA trusted_schema=OFF; + CREATE INDEX t5x1 ON t5(a+f2(b)); +} {1 {unsafe use of f2()}} +do_execsql_test 1.521 { + CREATE INDEX t5x1 ON t5(a+f1(b)); + SELECT * FROM t5 INDEXED BY t5x1 WHERE a+f1(b)=3; +} {1 2 3} +do_execsql_test 1.530 { + PRAGMA trusted_schema=ON; + CREATE INDEX t5x2 ON t5(b+f2(c)); + SELECT * FROM t5 INDEXED BY t5x2 WHERE b+f2(c)=11; +} {4 5 6} +do_execsql_test 1.540 { + PRAGMA trusted_schema=OFF; + CREATE INDEX temp5x1 ON temp5(a+f3(b)); + SELECT * FROM temp5 INDEXED BY temp5x1 WHERE a+f3(b)=7; +} {7 0 -3} + +# edgy functions in VIEWs +# +reset_db +db function f1 -innocuous -deterministic f1 +db function f2 -deterministic f1 +db function f3 -directonly -deterministic f1 +do_execsql_test 2.100 { + CREATE TABLE t1(a,b,c); + INSERT INTO t1 VALUES(1,2,3),(100,50,75),(-11,22,-33); + CREATE VIEW v1a AS SELECT f3(a+b) FROM t1; + SELECT f3(a+b) FROM t1; +} {3 150 11} +do_catchsql_test 2.110 { + PRAGMA trusted_schema=ON; + SELECT * FROM v1a; +} {1 {unsafe use of f3()}} +do_catchsql_test 2.111 { + PRAGMA trusted_schema=OFF; + SELECT * FROM v1a; +} {1 {unsafe use of f3()}} +do_execsql_test 2.120 { + DROP VIEW v1a; + CREATE TEMP VIEW v1a AS SELECT f3(a+b) FROM t1; + SELECT * FROM v1a; +} {3 150 11} +do_execsql_test 2.130 { + CREATE VIEW v1b AS SELECT f2(b+c) FROM t1; + SELECT f2(b+c) FROM t1; +} {5 125 -11} +do_catchsql_test 2.140 { + PRAGMA trusted_schema=ON; + SELECT * FROM v1b; +} {0 {5 125 -11}} +do_catchsql_test 2.141 { + PRAGMA trusted_schema=OFF; + SELECT * FROM v1b; +} {1 {unsafe use of f2()}} +do_execsql_test 2.150 { + DROP VIEW v1b; + CREATE TEMP VIEW v1b AS SELECT f2(b+c) FROM t1; + SELECT * FROM v1b; +} {5 125 -11} + +# edgy functions inside of triggers +# +do_execsql_test 3.100 { + DELETE FROM t1; + CREATE TABLE t2(x); + CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN + INSERT INTO t2(x) SELECT f3(new.a); + END; +} {} +do_catchsql_test 3.110 { + INSERT INTO t1 VALUES(7,6,5); +} {1 {unsafe use of f3()}} +do_execsql_test 3.111 { + SELECT * FROM t1; + SELECT * FROM t2; +} {} + +do_execsql_test 3.120 { + DROP TRIGGER r1; + CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN + INSERT INTO t2(x) SELECT f2(new.a)+100; + END; + PRAGMA trusted_schema=ON; + INSERT INTO t1 VALUES(7,6,5); + SELECT * FROM t1, t2; +} {7 6 5 107} +do_catchsql_test 3.130 { + DELETE FROM t1; + DELETE FROM t2; + PRAGMA trusted_schema=OFF; + INSERT INTO t1 VALUES(7,6,5); +} {1 {unsafe use of f2()}} +do_execsql_test 3.131 { + SELECT * FROM t1; + SELECT * FROM t2; +} {} + + +finish_test diff --git a/test/update.test b/test/update.test index 99fff458..dd96124b 100644 --- a/test/update.test +++ b/test/update.test @@ -641,4 +641,93 @@ do_execsql_test update-16.1 { SELECT * FROM t16 ORDER BY +a; } {1 2 3 4 5 6} +# 2019-12-09 gramfuzz find +# If a partial index that does not reference any column of its table (which is you +# must admit is a very strange index, but one that is allowed) is used by an UPDATE +# statement, void the use of OP_DeferredSeek on the main loop, as the seek will not +# be resolved prior to the OP_Delete. +# +do_execsql_test update-17.10 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(x,y); + INSERT INTO t1(x) VALUES(1); + CREATE INDEX t1x1 ON t1(1) WHERE 3; + UPDATE t1 SET x=2, y=3 WHERE 3; + SELECT * FROM t1; +} {2 3} + +# 2019-12-22 ticket 5ad2aa6921faa1ee +# Make a hard-copy of values that need to be run through OP_RealAffinity +# rather than a soft-copy. This is not strictly necessary, but it avoids +# a memory-accounting assert(). +# +reset_db +do_execsql_test update-18.10 { + PRAGMA encoding = 'UTF16'; + CREATE TABLE t0(c0 REAL, c1); + INSERT INTO t0(c0,c1) VALUES('xyz',11),('uvw',22); + CREATE INDEX i0 ON t0(c1) WHERE c0 GLOB 3; + CREATE INDEX i1 ON t0(c0,c1) WHERE typeof(c0)='text' AND typeof(c1)='integer'; + UPDATE t0 SET c1=345; + SELECT * FROM t0; +} {xyz 345 uvw 345} + +# 2019-12-22 ticket c62c5e58524b204d +# This is really the same underlying problem as 5ad2aa6921faa1ee +# +reset_db +do_execsql_test update-18.20 { + PRAGMA encoding = 'utf16'; + CREATE TABLE t0(c0 TEXT); + CREATE INDEX i0 ON t0(0 LIKE COALESCE(c0, 0)); + INSERT INTO t0(c0) VALUES (0), (0); + SELECT * FROM t0; +} {0 0} + +# 2019-12-28 assertion fault reported by Yongheng +# Similar to ticket ec8abb025e78f40c +# An UPDATE was reaching the OP_Delete after running OP_DeferredSeek +# without ever hitting an OP_Column. The enhanced solution is to +# fix OP_Delete so that it can do the seek itself. +# +reset_db +do_execsql_test update-19.10 { + CREATE TABLE t1( + a TEXT, + b INTEGER PRIMARY KEY UNIQUE + ); + INSERT INTO t1 VALUES(1,2); + UPDATE t1 SET a = quote(b) WHERE b>=2; + SELECT * FROM t1; +} {2 2} + +# 2019-12-29 ticket https://www.sqlite.org/src/info/314cc133e5ada126 +# REPLACE conflict resolution during an UPDATE causes a DELETE trigger +# to fire. If that DELETE trigger subsequently modifies the row +# being updated, bad things can happen. Prevent this by prohibiting +# triggers from making changes to the table being updated while doing +# REPLACE conflict resolution on the UPDATE. +# +# See also tickets: +# https://www.sqlite.org/src/info/c1e19e12046d23fe 2019-10-25 +# https://www.sqlite.org/src/info/a8a4847a2d96f5de 2019-10-16 +# +reset_db +do_execsql_test update-20.10 { + PRAGMA recursive_triggers = true; + CREATE TABLE t1(a UNIQUE ON CONFLICT REPLACE, b); + INSERT INTO t1(a,b) VALUES(4,12),(9,13); + CREATE INDEX i0 ON t1(b); + CREATE TRIGGER tr0 DELETE ON t1 BEGIN + UPDATE t1 SET b = a; + END; + PRAGMA integrity_check; +} {ok} +do_catchsql_test update-20.20 { + UPDATE t1 SET a=0; +} {1 {constraint failed}} +do_execsql_test update-20.30 { + PRAGMA integrity_check; +} {ok} + finish_test diff --git a/test/upsert1.test b/test/upsert1.test index 006af438..5250a5d2 100644 --- a/test/upsert1.test +++ b/test/upsert1.test @@ -221,4 +221,24 @@ do_execsql_test upsert1-800 { REINDEX; } {ok} +# 2019-12-06 gramfuzz find +sqlite3 db :memory: +do_execsql_test upsert1-900 { + CREATE VIEW t1(a) AS SELECT 1; + CREATE TRIGGER t1r1 INSTEAD OF INSERT ON t1 BEGIN + SELECT 2; + END; +} +do_catchsql_test upsert1-910 { + INSERT INTO t1 VALUES(3) ON CONFLICT(x) DO NOTHING; +} {1 {cannot UPSERT a view}} + +# 2019-12-26 ticket 7c13db5c3bf74001 +reset_db +do_catchsql_test upsert1-1000 { + CREATE TABLE t0(c0 PRIMARY KEY, c1, c2 UNIQUE) WITHOUT ROWID; + INSERT OR FAIL INTO t0(c2) VALUES (0), (NULL) + ON CONFLICT(c2) DO UPDATE SET c1 = c0; +} {1 {NOT NULL constraint failed: t0.c0}} + finish_test diff --git a/test/walvfs.test b/test/walvfs.test index 8ffc6f9b..da0f43c3 100644 --- a/test/walvfs.test +++ b/test/walvfs.test @@ -387,6 +387,7 @@ do_execsql_test 8.3 { PRAGMA wal_checkpoint; SELECT count(*) FROM t1 } {0 5 5 21} +db close tvfs2 delete #------------------------------------------------------------------------- diff --git a/test/whereG.test b/test/whereG.test index 595de116..9d4cde7b 100644 --- a/test/whereG.test +++ b/test/whereG.test @@ -306,7 +306,15 @@ do_execsql_test 8.10 { SELECT * FROM t0 WHERE likelihood(t0.rowid <= '0', 0.5); } {} - - +# 2019-12-31: assertion fault discovered by Yongheng's fuzzer. +# Harmless memIsValid() due to the code generators failure to +# release the registers used by OP_ResultRow. +# +do_execsql_test 9.10 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a, b FLOAT); + INSERT INTO t1(a) VALUES(''),(NULL),('X'),(NULL); + SELECT coalesce(max(quote(a)),10) FROM t1 GROUP BY a; +} {NULL '' 'X'} finish_test diff --git a/test/whereL.test b/test/whereL.test index d0e5f0b6..bd2f5616 100644 --- a/test/whereL.test +++ b/test/whereL.test @@ -122,4 +122,27 @@ do_execsql_test 400 { SELECT x.a FROM x JOIN y ON x.c = y.a WHERE x.b = 1 AND x.b = 1; } {} +# 2020-01-07: ticket 82ac75ba0093e5dc +# Incorrect join result due to mishandling of affinity in constant +# propagation. +# +reset_db +do_execsql_test 500 { + PRAGMA automatic_index=OFF; + CREATE TABLE t0(c0); + INSERT INTO t0 VALUES('0'); + CREATE VIEW v0(c0) AS SELECT CAST(0 AS INT) FROM t0; + SELECT 200, * FROM t0, v0 WHERE 0 = t0.c0 AND t0.c0 = v0.c0; +} {} +do_execsql_test 510 { + SELECT 200, * FROM t0, v0 WHERE t0.c0 = 0 AND t0.c0 = v0.c0; +} {} +do_execsql_test 520 { + SELECT 200, * FROM t0, v0 WHERE 0 = t0.c0 AND v0.c0 = t0.c0; +} {} +do_execsql_test 530 { + SELECT 200, * FROM t0, v0 WHERE t0.c0 = 0 AND v0.c0 = t0.c0; +} {} + + finish_test diff --git a/test/window1.test b/test/window1.test index 7a41e726..833e211f 100644 --- a/test/window1.test +++ b/test/window1.test @@ -1234,4 +1234,364 @@ do_catchsql_test 31.3 { ); } {1 {frame ending offset must be a non-negative integer}} +# 2019-11-16 chromium issue 1025467 +db close +sqlite3 db :memory: +do_catchsql_test 32.10 { + CREATE VIEW a AS SELECT NULL INTERSECT SELECT NULL ORDER BY s() OVER R; + CREATE TABLE a0 AS SELECT 0; + ALTER TABLE a0 RENAME TO S; +} {1 {error in view a: 1st ORDER BY term does not match any column in the result set}} + +reset_db +do_execsql_test 33.1 { + CREATE TABLE t1(aa, bb); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(5, 6); + CREATE TABLE t2(x); + INSERT INTO t2 VALUES(1); +} +do_execsql_test 33.2 { + SELECT (SELECT DISTINCT sum(aa) OVER() FROM t1 ORDER BY 1), x FROM t2 + ORDER BY 1; +} {6 1} + +reset_db +do_execsql_test 34.1 { + CREATE TABLE t1(a,b,c); +} +do_execsql_test 34.2 { + SELECT avg(a) OVER ( + ORDER BY (SELECT sum(b) OVER () + FROM t1 ORDER BY ( + SELECT total(d) OVER (ORDER BY c) + FROM (SELECT 1 AS d) ORDER BY 1 + ) + ) + ) + FROM t1; +} + +#------------------------------------------------------------------------- +reset_db +do_catchsql_test 35.0 { + SELECT * WINDOW f AS () ORDER BY name COLLATE nocase; +} {1 {no tables specified}} + +do_catchsql_test 35.1 { + VALUES(1) INTERSECT SELECT * WINDOW f AS () ORDER BY x COLLATE nocase; +} {1 {no tables specified}} + +do_execsql_test 35.2 { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(1), (2), (3); + VALUES(1) INTERSECT + SELECT sum(x) OVER f FROM t1 WINDOW f AS (ORDER BY x) ORDER BY 1; +} {1} + +do_execsql_test 35.3 { + VALUES(8) EXCEPT + SELECT sum(x) OVER f FROM t1 WINDOW f AS (ORDER BY x) ORDER BY 1; +} {8} + +do_execsql_test 35.4 { + VALUES(1) UNION + SELECT sum(x) OVER f FROM t1 WINDOW f AS (ORDER BY x) ORDER BY 1; +} {1 3 6} + +# 2019-12-07 gramfuzz find +# +do_execsql_test 36.10 { + VALUES(count(*)OVER()); +} {1} +do_execsql_test 36.20 { + VALUES(count(*)OVER()),(2); +} {1 2} +do_execsql_test 36.30 { + VALUES(2),(count(*)OVER()); +} {2 1} +do_execsql_test 36.40 { + VALUES(2),(3),(count(*)OVER()),(4),(5); +} {2 3 1 4 5} + +# 2019-12-17 crash test case found by Yongheng and Rui +# See check-in 1ca0bd982ab1183b +# +reset_db +do_execsql_test 37.10 { + CREATE TABLE t0(a UNIQUE, b PRIMARY KEY); + CREATE VIEW v0(c) AS SELECT max((SELECT count(a)OVER(ORDER BY 1))) FROM t0; + SELECT c FROM v0 WHERE c BETWEEN 10 AND 20; +} {} +do_execsql_test 37.20 { + DROP VIEW v0; + CREATE VIEW v0(c) AS SELECT max((SELECT count(a)OVER(ORDER BY 1234))) FROM t0; + SELECT c FROM v0 WHERE c BETWEEN -10 AND 20; +} {} + +# 2019-12-20 mrigger reported problem with a FILTER clause on an aggregate +# in a join. +# +reset_db +do_catchsql_test 38.10 { + CREATE TABLE t0(c0); + CREATE TABLE t1(c0, c1 UNIQUE); + INSERT INTO t0(c0) VALUES(1); + INSERT INTO t1(c0,c1) VALUES(2,3); + SELECT COUNT(*) FROM t0, t1 WHERE (SELECT AVG(0) FILTER(WHERE t1.c1)); +} {1 {misuse of aggregate: AVG()}} +do_execsql_test 38.20 { + SELECT COUNT(*), AVG(1) FILTER(WHERE t1.c1) FROM t0, t1; +} {1 1.0} +do_catchsql_test 38.30 { + SELECT COUNT(*) FROM t0, t1 WHERE (SELECT AVG(1) FILTER(WHERE t1.c1)); +} {1 {misuse of aggregate: AVG()}} + +reset_db +do_execsql_test 39.1 { + CREATE TABLE t0(c0 UNIQUE); +} +do_execsql_test 39.2 { + SELECT FIRST_VALUE(0) OVER(); +} {0} +do_execsql_test 39.3 { + SELECT * FROM t0 WHERE(c0, 0) IN(SELECT FIRST_VALUE(0) OVER(), 0); +} +do_execsql_test 39.4 { + SELECT * FROM t0 WHERE (t0.c0, 1) IN(SELECT NTILE(1) OVER(), 0 FROM t0); +} + +ifcapable rtree { + # 2019-12-25 ticket d87336c81c7d0873 + # + reset_db + do_catchsql_test 40.1 { + CREATE VIRTUAL TABLE t0 USING rtree(c0, c1, c2); + SELECT * FROM t0 + WHERE ((0,0) IN (SELECT COUNT(*),LAG(5)OVER(PARTITION BY 0) FROM t0),0)<=(c1,0); + } {0 {}} +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 41.1 { + CREATE TABLE t1(a, b, c); + INSERT INTO t1 VALUES(NULL,'bb',355); + INSERT INTO t1 VALUES('CC','aa',158); + INSERT INTO t1 VALUES('GG','bb',929); + INSERT INTO t1 VALUES('FF','Rb',574); +} + +do_execsql_test 41.2 { + SELECT min(c) OVER ( + ORDER BY a RANGE BETWEEN 5.2 PRECEDING AND 0.1 PRECEDING + ) FROM t1 +} {355 158 574 929} + +do_execsql_test 41.2 { + SELECT min(c) OVER ( + ORDER BY a RANGE BETWEEN 5.2 PRECEDING AND 0.1 PRECEDING + ) << 100 FROM t1 +} {0 0 0 0} + +do_execsql_test 41.3 { + SELECT + min(c) OVER win3 << first_value(c) OVER win3, + min(c) OVER win3 << first_value(c) OVER win3 + FROM t1 + WINDOW win3 AS ( + PARTITION BY 6 ORDER BY a RANGE BETWEEN 5.2 PRECEDING AND 0.1 PRECEDING + ); +} {0 0 0 0 0 0 0 0} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 42.1 { + CREATE TABLE t1(a, b, c); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); +} +do_execsql_test 42.2 { + SELECT * FROM t1 WHERE (0, 0) IN ( SELECT count(*), 0 FROM t1 ) +} {} +do_execsql_test 42.3 { + SELECT * FROM t1 WHERE (2, 0) IN ( SELECT count(*), 0 FROM t1 ) +} {1 1 1 2 2 2} + +do_execsql_test 42.3 { + SELECT count(*), max(a) OVER () FROM t1 GROUP BY c; +} {1 2 1 2} + +do_execsql_test 42.4 { + SELECT sum(a), max(b) OVER () FROM t1; +} {3 1} + +do_execsql_test 42.5 { + CREATE TABLE t2(a, b); + INSERT INTO t2 VALUES('a', 1); + INSERT INTO t2 VALUES('a', 2); + INSERT INTO t2 VALUES('a', 3); + INSERT INTO t2 VALUES('b', 4); + INSERT INTO t2 VALUES('b', 5); + INSERT INTO t2 VALUES('b', 6); +} + +do_execsql_test 42.6 { + SELECT a, sum(b), sum( sum(b) ) OVER (ORDER BY a) FROM t2 GROUP BY a; +} {a 6 6 b 15 21} + +do_execsql_test 42.7 { + SELECT sum(b), sum( sum(b) ) OVER (ORDER BY a) FROM t2; +} {21 21} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 43.1.1 { + CREATE TABLE t1(x INTEGER PRIMARY KEY); + INSERT INTO t1 VALUES (10); +} +do_catchsql_test 43.1.2 { + SELECT count() OVER() AS m FROM t1 ORDER BY (SELECT m); +} {1 {misuse of aliased window function m}} + +reset_db +do_execsql_test 43.2.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b INTEGER); + INSERT INTO t1(a, b) VALUES(1, 10); -- 10 + INSERT INTO t1(a, b) VALUES(2, 15); -- 25 + INSERT INTO t1(a, b) VALUES(3, -5); -- 20 + INSERT INTO t1(a, b) VALUES(4, -5); -- 15 + INSERT INTO t1(a, b) VALUES(5, 20); -- 35 + INSERT INTO t1(a, b) VALUES(6, -11); -- 24 +} + +do_execsql_test 43.2.2 { + SELECT a, sum(b) OVER (ORDER BY a) AS abc FROM t1 ORDER BY 2 +} { + 1 10 4 15 3 20 6 24 2 25 5 35 +} + +do_execsql_test 43.2.3 { + SELECT a, sum(b) OVER (ORDER BY a) AS abc FROM t1 ORDER BY abc +} { + 1 10 4 15 3 20 6 24 2 25 5 35 +} + +do_execsql_test 43.2.4 { + SELECT a, sum(b) OVER (ORDER BY a) AS abc FROM t1 ORDER BY abc+5 +} { + 1 10 4 15 3 20 6 24 2 25 5 35 +} + +do_catchsql_test 43.2.5 { + SELECT a, sum(b) OVER (ORDER BY a) AS abc FROM t1 ORDER BY (SELECT abc) +} {1 {misuse of aliased window function abc}} + +do_catchsql_test 43.2.6 { + SELECT a, 1+sum(b) OVER (ORDER BY a) AS abc FROM t1 ORDER BY (SELECT abc) +} {1 {misuse of aliased window function abc}} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 44.1 { + CREATE TABLE t0(c0); +} + +do_catchsql_test 44.2.1 { + SELECT ntile(0) OVER (); +} {1 {argument of ntile must be a positive integer}} +do_catchsql_test 44.2.2 { + SELECT (0, 0) IN(SELECT MIN(c0), NTILE(0) OVER()) FROM t0; +} {1 {argument of ntile must be a positive integer}} + +do_execsql_test 44.3.1 { + SELECT ntile(1) OVER (); +} {1} +do_execsql_test 44.3.2 { + SELECT (0, 0) IN(SELECT MIN(c0), NTILE(1) OVER()) FROM t0; +} {0} + +do_execsql_test 44.4.2 { + INSERT INTO t0 VALUES(2), (1), (0); + SELECT (0, 1) IN(SELECT MIN(c0), NTILE(1) OVER()) FROM t0; +} {1} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 45.1 { + CREATE TABLE t0(x); + CREATE TABLE t1(a); + INSERT INTO t1 VALUES(1000); + INSERT INTO t1 VALUES(1000); + INSERT INTO t0 VALUES(10000); +} +do_execsql_test 45.2 { + SELECT * FROM ( + SELECT sum (a) OVER() FROM t1 UNION ALL SELECT x FROM t0 + ); +} {2000 2000 10000} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 46.1 { + CREATE TABLE t1 (a); + CREATE INDEX i1 ON t1(a); + + INSERT INTO t1 VALUES (10); +} + +do_execsql_test 46.2 { + SELECT (SELECT sum(a) OVER(ORDER BY a)) FROM t1 +} 10 + +do_execsql_test 46.3 { + SELECT * FROM t1 WHERE (SELECT sum(a) OVER(ORDER BY a)); +} 10 + +do_execsql_test 46.4 { + SELECT * FROM t1 NATURAL JOIN t1 + WHERE a=1 + OR ((SELECT sum(a)OVER(ORDER BY a)) AND a<=10) +} 10 + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 47.0 { + CREATE TABLE t1( + a, + e, + f, + g UNIQUE, + h UNIQUE + ); +} + +do_execsql_test 47.1 { + CREATE VIEW t2(k) AS + SELECT e FROM t1 WHERE g = 'abc' OR h BETWEEN 10 AND f; +} + +do_catchsql_test 47.2 { + SELECT 234 FROM t2 + WHERE k=1 + OR (SELECT k FROM t2 WHERE (SELECT sum(a) OVER() FROM t1 GROUP BY 1)); +} {1 {misuse of window function sum()}} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 48.0 { + CREATE TABLE t1(a); + INSERT INTO t1 VALUES(1); + INSERT INTO t1 VALUES(2); + INSERT INTO t1 VALUES(3); + SELECT (SELECT max(x)OVER(ORDER BY x) + min(x)OVER(ORDER BY x)) + FROM (SELECT (SELECT sum(a) FROM t1) AS x FROM t1); +} {12 12 12} + +do_execsql_test 48.1 { + SELECT (SELECT max(x)OVER(ORDER BY x) + min(x)OVER(ORDER BY x)) + FROM (SELECT (SELECT sum(a) FROM t1 GROUP BY a) AS x FROM t1); +} {2 2 2} + + finish_test diff --git a/test/window2.tcl b/test/window2.tcl index 5edc5368..4c18b797 100644 --- a/test/window2.tcl +++ b/test/window2.tcl @@ -448,6 +448,47 @@ execsql_float_test 5.1 { SELECT avg(x) OVER (ORDER BY y) AS z FROM t1 ORDER BY z; } +========== + +execsql_test 6.0 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0(c0 INTEGER UNIQUE); + INSERT INTO t0 VALUES(0); +} +execsql_test 6.1 { + SELECT DENSE_RANK() OVER(), LAG(0) OVER() FROM t0; +} +execsql_test 6.2 { + SELECT * FROM t0 WHERE + (0, t0.c0) IN (SELECT DENSE_RANK() OVER(), LAG(0) OVER() FROM t0); +} + +========== + +execsql_test 7.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a INTEGER, b INTEGER, c INTEGER); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(1, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); + INSERT INTO t1 VALUES(3, 4, 4); +} + +execsql_test 7.1 { + SELECT c, sum(c) OVER win1 FROM t1 + WINDOW win1 AS (ORDER BY b) +} + +execsql_test 7.2 { + SELECT c, sum(c) OVER win1 FROM t1 + WINDOW win1 AS (PARTITION BY 1 ORDER BY b) +} + +execsql_test 7.3 { + SELECT c, sum(c) OVER win1 FROM t1 + WINDOW win1 AS (ORDER BY 1) +} + finish_test diff --git a/test/window2.test b/test/window2.test index 5f028eb7..e241d596 100644 --- a/test/window2.test +++ b/test/window2.test @@ -930,4 +930,47 @@ do_test 5.1 { set {} {} } {} +#========================================================================== + +do_execsql_test 6.0 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0(c0 INTEGER UNIQUE); + INSERT INTO t0 VALUES(0); +} {} + +do_execsql_test 6.1 { + SELECT DENSE_RANK() OVER(), LAG(0) OVER() FROM t0; +} {1 {}} + +do_execsql_test 6.2 { + SELECT * FROM t0 WHERE + (0, t0.c0) IN (SELECT DENSE_RANK() OVER(), LAG(0) OVER() FROM t0); +} {} + +#========================================================================== + +do_execsql_test 7.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a INTEGER, b INTEGER, c INTEGER); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(1, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); + INSERT INTO t1 VALUES(3, 4, 4); +} {} + +do_execsql_test 7.1 { + SELECT c, sum(c) OVER win1 FROM t1 + WINDOW win1 AS (ORDER BY b) +} {1 1 2 3 3 6 4 10} + +do_execsql_test 7.2 { + SELECT c, sum(c) OVER win1 FROM t1 + WINDOW win1 AS (PARTITION BY 1 ORDER BY b) +} {1 1 2 3 3 6 4 10} + +do_execsql_test 7.3 { + SELECT c, sum(c) OVER win1 FROM t1 + WINDOW win1 AS (ORDER BY 1) +} {1 10 2 10 3 10 4 10} + finish_test diff --git a/test/window9.test b/test/window9.test index 6f2f2d95..adfeaba3 100644 --- a/test/window9.test +++ b/test/window9.test @@ -233,4 +233,3 @@ do_execsql_test 7.4 { } finish_test - diff --git a/test/windowfault.test b/test/windowfault.test index e037c467..e97544f4 100644 --- a/test/windowfault.test +++ b/test/windowfault.test @@ -230,7 +230,7 @@ do_execsql_test 10.0 { CREATE TABLE t2(a, b, c, d); } -do_faultsim_test 1 -faults oom* -prep { +do_faultsim_test 10 -faults oom* -prep { } -body { execsql { SELECT row_number() OVER win @@ -246,4 +246,21 @@ do_faultsim_test 1 -faults oom* -prep { faultsim_test_result {0 {}} } +reset_db +do_execsql_test 11.0 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0(c0 INTEGER UNIQUE); + INSERT INTO t0 VALUES(0); +} {} + +do_faultsim_test 11 -faults oom* -prep { +} -body { + execsql { + SELECT * FROM t0 WHERE + (0, t0.c0) IN (SELECT DENSE_RANK() OVER(), LAG(0) OVER() FROM t0); + } +} -test { + faultsim_test_result {0 {}} +} + finish_test diff --git a/test/with1.test b/test/with1.test index 5631bfb6..66e45634 100644 --- a/test/with1.test +++ b/test/with1.test @@ -1140,4 +1140,35 @@ do_execsql_test 24.2 { 3 1 1 3 } +# 2020-01-02 chromium ticket 1033461 +# Do not allow the generated name of a CTE be "true" or "false" as +# such a label might be later confused for the boolean literals of +# the same name, causing inconsistencies in the abstract syntax +# tree. This problem first arose in version 3.23.0 when SQLite +# began recognizing "true" and "false" as boolean literals, but also +# had to continue to recognize "true" and "false" as identifiers for +# backwards compatibility. +# +reset_db +do_execsql_test 25.1 { + CREATE TABLE dual(dummy); + INSERT INTO dual(dummy) VALUES('X'); + WITH cte1 AS ( + SELECT TRUE, ( + WITH cte2 AS (SELECT avg(DISTINCT TRUE) FROM dual) + SELECT 2571 FROM cte2 + ) AS subquery1 + FROM dual + GROUP BY 1 + ) + SELECT (SELECT 1324 FROM cte1) FROM cte1; +} {1324} + +do_catchsql_test 26.0 { + WITH i(x) AS ( + VALUES(1) UNION ALL SELECT x+1 FRO, a.b,O. * ,I¬i O, a.b,O. * ORDER BY 1 + ) + SELECT x,O. * O FROM i ¬I,I? 10; +} {1 {near "O": syntax error}} + finish_test diff --git a/test/with3.test b/test/with3.test index 360d37f9..2a67727a 100644 --- a/test/with3.test +++ b/test/with3.test @@ -30,7 +30,15 @@ do_catchsql_test 1.0 { SELECT 5 FROM t0 UNION SELECT 8 FROM m ) SELECT * FROM i; -} {1 {no such table: m}} +} {1 {no such table: t0}} + +# 2019-11-09 dbfuzzcheck find +do_catchsql_test 1.1 { + CREATE VIEW v1(x,y) AS + WITH t1(a,b) AS (VALUES(1,2)) + SELECT * FROM nosuchtable JOIN t1; + SELECT * FROM v1; +} {1 {no such table: main.nosuchtable}} # Additional test cases that came out of the work to # fix for Kostya's problem. @@ -165,5 +173,29 @@ do_execsql_test 4.1 { ); } {1} +# 2020-01-18 chrome ticket 1043236 +# Correct handling of the sequence: +# OP_OpenEphem +# OP_OpenDup +# Op_OpenEphem +# OP_OpenDup +# +do_execsql_test 4.2 { + SELECT ( + WITH t1(a) AS (VALUES(1)) + SELECT ( + WITH t2(b) AS ( + WITH t3(c) AS ( + WITH t4(d) AS (VALUES('elvis')) + SELECT t4a.d FROM t4 AS t4a JOIN t4 AS t4b LEFT JOIN t4 AS t4c + ) + SELECT c FROM t3 WHERE a = 1 + ) + SELECT t2a.b FROM t2 AS t2a JOIN t2 AS t2x + ) + FROM t1 GROUP BY 1 + ) + GROUP BY 1; +} {elvis} finish_test diff --git a/test/without_rowid1.test b/test/without_rowid1.test index 23fae118..3497ca0c 100644 --- a/test/without_rowid1.test +++ b/test/without_rowid1.test @@ -430,5 +430,27 @@ do_execsql_test 12.1 { PRAGMA integrity_check; } {ok} +# 2019-11-07 ticket https://www.sqlite.org/src/info/302027baf1374498 +# The xferCompatibleIndex() function confuses a PRIMARY KEY index +# with a UNIQUE index. +# +do_execsql_test 13.10 { + DROP TABLE IF EXISTS t0; + DROP TABLE IF EXISTS t1; + CREATE TABLE t0( + c0, + c1 UNIQUE, + PRIMARY KEY(c1, c1) + ) WITHOUT ROWID; + INSERT INTO t0(c0,c1) VALUES('abc','xyz'); + CREATE TABLE t1( + c0, + c1 UNIQUE, + PRIMARY KEY(c1, c1) + ) WITHOUT ROWID; + INSERT INTO t1 SELECT * FROM t0; + PRAGMA integrity_check; + SELECT * FROM t0, t1; +} {ok abc xyz abc xyz} finish_test diff --git a/test/without_rowid3.test b/test/without_rowid3.test index b895f06c..24ef2304 100644 --- a/test/without_rowid3.test +++ b/test/without_rowid3.test @@ -953,7 +953,7 @@ ifcapable altertable { 'main', 'table', 't1', $zCreate, $zOld, $zNew, 0 )} } - sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1 + sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db do_test without_rowid3-14.2.1.1 { test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3 } {{CREATE TABLE t1(a REFERENCES "t3")}} @@ -963,7 +963,7 @@ ifcapable altertable { do_test without_rowid3-14.2.1.3 { test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3 } {{CREATE TABLE t1(a REFERENCES "t3")}} - sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0 + sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db # Test ALTER TABLE RENAME TABLE a bit. # @@ -1039,7 +1039,7 @@ ifcapable altertable { } } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}} - sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1 + sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db do_test without_rowid3-14.2tmp.1.1 { test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3 } {{CREATE TABLE t1(a REFERENCES "t3")}} @@ -1049,7 +1049,7 @@ ifcapable altertable { do_test without_rowid3-14.2tmp.1.3 { test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3 } {{CREATE TABLE t1(a REFERENCES "t3")}} - sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0 + sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db # Test ALTER TABLE RENAME TABLE a bit. # @@ -1126,7 +1126,7 @@ ifcapable altertable { } } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}} - sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1 + sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db do_test without_rowid3-14.2aux.1.1 { test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3 } {{CREATE TABLE t1(a REFERENCES "t3")}} @@ -1136,7 +1136,7 @@ ifcapable altertable { do_test without_rowid3-14.2aux.1.3 { test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3 } {{CREATE TABLE t1(a REFERENCES "t3")}} - sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0 + sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db # Test ALTER TABLE RENAME TABLE a bit. # diff --git a/test/zipfile.test b/test/zipfile.test index 2bab066d..79298a05 100644 --- a/test/zipfile.test +++ b/test/zipfile.test @@ -795,4 +795,52 @@ if {$tcl_platform(platform)!="windows"} { } {. ./x1.txt ./x2.txt} } +# 2019-12-18 Yongheng and Rui fuzzer +# +do_execsql_test 13.10 { + DROP TABLE IF EXISTS t0; + DROP TABLE IF EXISTS t1; + CREATE TABLE t0(a,b,c,d,e,f,g); + REPLACE INTO t0(c,b,f) VALUES(10,10,10); + CREATE VIRTUAL TABLE t1 USING zipfile('h.zip'); + REPLACE INTO t1 SELECT * FROM t0; + SELECT quote(name),quote(mode),quote(mtime),quote(sz),quote(rawdata), + quote(data),quote(method) FROM t1; +} {'' 10 10 2 X'3130' X'3130' 0} + +# 2019-12-23 Yongheng and Rui fuzzer +# Run using valgrind to see the problem. +# +do_execsql_test 14.10 { + DROP TABLE t1; + CREATE TABLE t1(x char); + INSERT INTO t1(x) VALUES('1'); + INSERT INTO t1(x) SELECT zipfile(x, 'xyz') FROM t1; + INSERT INTO t1(x) SELECT zipfile(x, 'uvw') FROM t1; + SELECT count(*) FROM t1; + PRAGMA integrity_check; +} {3 ok} + +# 2019-12-26 More problems in zipfile from the Yongheng and Rui fuzzer +# +do_execsql_test 15.10 { + DROP TABLE IF EXISTS t1; + CREATE VIRTUAL TABLE t1 USING zipfile(null); + REPLACE INTO t1 VALUES(null,null,0,null,null,null,null); +} {} +do_execsql_test 15.20 { + DROP TABLE IF EXISTS t2; + CREATE VIRTUAL TABLE t2 USING zipfile(null); + REPLACE INTO t2 values(null,null,null,null,null,10,null); +} {} + +# 2020-01-02 Yongheng fuzzer discovery +# +do_catchsql_test 16.10 { + DELETE FROM zipfile; +} {1 {zipfile: missing filename}} +do_catchsql_test 16.20 { + REPLACE INTO zipfile VALUES(null,null,null,null,null,123,null); +} {1 {zipfile: missing filename}} + finish_test diff --git a/tool/GetFile.cs b/tool/GetFile.cs index 56601f3e..1784a792 100644 --- a/tool/GetFile.cs +++ b/tool/GetFile.cs @@ -167,7 +167,8 @@ namespace GetFile string fileName = Path.GetFileName( Process.GetCurrentProcess().MainModule.FileName); - Console.WriteLine(String.Format("usage: {0} ", fileName)); + Console.WriteLine(String.Format( + "usage: {0} [fileName]", fileName)); } /////////////////////////////////////////////////////////////////////// @@ -336,7 +337,7 @@ namespace GetFile return (int)ExitCode.MissingArgs; } - if (args.Length != 1) + if ((args.Length < 1) || (args.Length > 2)) { Error(null, true); return (int)ExitCode.WrongNumArgs; @@ -355,15 +356,26 @@ namespace GetFile } // - // NOTE: Attempt to extract the file name portion of the URI we - // just created. + // NOTE: If a file name was specified on the command line, try to + // use it (without its directory name); otherwise, fallback + // to using the file name portion of the URI. // - string fileName = GetFileName(uri); + string fileName = (args.Length == 2) ? + Path.GetFileName(args[1]) : null; - if (fileName == null) + if (String.IsNullOrEmpty(fileName)) { - Error("Could not extract the file name from the URI.", false); - return (int)ExitCode.BadFileName; + // + // NOTE: Attempt to extract the file name portion of the URI + // we just created. + // + fileName = GetFileName(uri); + + if (fileName == null) + { + Error("Could not extract file name from URI.", false); + return (int)ExitCode.BadFileName; + } } // @@ -381,6 +393,15 @@ namespace GetFile try { + // + // HACK: For use of the TLS 1.2 security protocol because some + // web servers fail without it. In order to support the + // .NET Framework 2.0+ at compilation time, must use its + // integer constant here. + // + ServicePointManager.SecurityProtocol = + (SecurityProtocolType)0xC00; + using (WebClient webClient = new WebClient()) { // diff --git a/tool/dbhash.c b/tool/dbhash.c index b1c72b3e..7696ddbd 100644 --- a/tool/dbhash.c +++ b/tool/dbhash.c @@ -62,24 +62,9 @@ struct GlobalVars { * * blk0le() for little-endian and blk0be() for big-endian. */ -#if __GNUC__ && (defined(__i386__) || defined(__x86_64__)) -/* - * GCC by itself only generates left rotates. Use right rotates if - * possible to be kinder to dinky implementations with iterative rotate - * instructions. - */ -#define SHA_ROT(op, x, k) \ - ({ unsigned int y; asm(op " %1,%0" : "=r" (y) : "I" (k), "0" (x)); y; }) -#define rol(x,k) SHA_ROT("roll", x, k) -#define ror(x,k) SHA_ROT("rorl", x, k) - -#else -/* Generic C equivalent */ #define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r)) #define rol(x,k) SHA_ROT(x,k,32-(k)) #define ror(x,k) SHA_ROT(x,32-(k),k) -#endif - #define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \ |(rol(block[i],8)&0x00FF00FF)) diff --git a/tool/lemon.c b/tool/lemon.c index 6efc6af3..8dcf6517 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -218,7 +218,7 @@ void Plink_delete(struct plink *); /********** From the file "report.h" *************************************/ void Reprint(struct lemon *); void ReportOutput(struct lemon *); -void ReportTable(struct lemon *, int); +void ReportTable(struct lemon *, int, int); void ReportHeader(struct lemon *); void CompressTables(struct lemon *); void ResortStates(struct lemon *); @@ -292,13 +292,15 @@ struct rule { const char *code; /* The code executed when this rule is reduced */ const char *codePrefix; /* Setup code before code[] above */ const char *codeSuffix; /* Breakdown code after code[] above */ - int noCode; /* True if this rule has no associated C code */ - int codeEmitted; /* True if the code has been emitted already */ struct symbol *precsym; /* Precedence symbol for this rule */ int index; /* An index number for this rule */ int iRule; /* Rule number as used in the generated tables */ + Boolean noCode; /* True if this rule has no associated C code */ + Boolean codeEmitted; /* True if the code has been emitted already */ Boolean canReduce; /* True if this rule is ever reduced */ Boolean doesReduce; /* Reduce actions occur after optimization */ + Boolean neverReduce; /* Reduce is theoretically possible, but prevented + ** by actions or other outside implementation */ struct rule *nextlhs; /* Next rule with the same LHS */ struct rule *next; /* Next rule in the global list */ }; @@ -385,6 +387,7 @@ struct lemon { int nstate; /* Number of states */ int nxstate; /* nstate with tail degenerate states removed */ int nrule; /* Number of rules */ + int nruleWithAction; /* Number of rules with actions */ int nsymbol; /* Number of terminal and nonterminal symbols */ int nterminal; /* Number of terminal symbols */ int minShiftReduce; /* Minimum shift-reduce action value */ @@ -907,9 +910,9 @@ void FindStates(struct lemon *lemp) sp = Symbol_find(lemp->start); if( sp==0 ){ ErrorMsg(lemp->filename,0, -"The specified start symbol \"%s\" is not \ -in a nonterminal of the grammar. \"%s\" will be used as the start \ -symbol instead.",lemp->start,lemp->startRule->lhs->name); + "The specified start symbol \"%s\" is not " + "in a nonterminal of the grammar. \"%s\" will be used as the start " + "symbol instead.",lemp->start,lemp->startRule->lhs->name); lemp->errorcnt++; sp = lemp->startRule->lhs; } @@ -925,9 +928,9 @@ symbol instead.",lemp->start,lemp->startRule->lhs->name); for(i=0; inrhs; i++){ if( rp->rhs[i]==sp ){ /* FIX ME: Deal with multiterminals */ ErrorMsg(lemp->filename,0, -"The start symbol \"%s\" occurs on the \ -right-hand side of a rule. This will result in a parser which \ -does not work properly.",sp->name); + "The start symbol \"%s\" occurs on the " + "right-hand side of a rule. This will result in a parser which " + "does not work properly.",sp->name); lemp->errorcnt++; } } @@ -1632,6 +1635,7 @@ int main(int argc, char **argv) static int mhflag = 0; static int nolinenosflag = 0; static int noResort = 0; + static int sqlFlag = 0; static struct s_options options[] = { {OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."}, @@ -1650,6 +1654,8 @@ int main(int argc, char **argv) {OPT_FLAG, "r", (char*)&noResort, "Do not sort or renumber states"}, {OPT_FLAG, "s", (char*)&statistics, "Print parser stats to standard output."}, + {OPT_FLAG, "S", (char*)&sqlFlag, + "Generate the *.sql file describing the parser tables."}, {OPT_FLAG, "x", (char*)&version, "Print the version number."}, {OPT_FSTR, "T", (char*)handle_T_option, "Specify a template file."}, {OPT_FSTR, "W", 0, "Ignored. (Placeholder for '-W' compiler options.)"}, @@ -1711,6 +1717,7 @@ int main(int argc, char **argv) for(i=0, rp=lem.rule; rp; rp=rp->next){ rp->iRule = rp->code ? i++ : -1; } + lem.nruleWithAction = i; for(rp=lem.rule; rp; rp=rp->next){ if( rp->iRule<0 ) rp->iRule = i++; } @@ -1758,7 +1765,7 @@ int main(int argc, char **argv) if( !quiet ) ReportOutput(&lem); /* Generate the source code for the parser */ - ReportTable(&lem, mhflag); + ReportTable(&lem, mhflag, sqlFlag); /* Produce a header file for use by the scanner. (This step is ** omitted if the "-m" option is used because makeheaders will @@ -2267,14 +2274,16 @@ static void parseonetoken(struct pstate *psp) }else if( x[0]=='{' ){ if( psp->prevrule==0 ){ ErrorMsg(psp->filename,psp->tokenlineno, -"There is no prior rule upon which to attach the code \ -fragment which begins on this line."); + "There is no prior rule upon which to attach the code " + "fragment which begins on this line."); psp->errorcnt++; }else if( psp->prevrule->code!=0 ){ ErrorMsg(psp->filename,psp->tokenlineno, -"Code fragment beginning on this line is not the first \ -to follow the previous rule."); + "Code fragment beginning on this line is not the first " + "to follow the previous rule."); psp->errorcnt++; + }else if( strcmp(x, "{NEVER-REDUCE")==0 ){ + psp->prevrule->neverReduce = 1; }else{ psp->prevrule->line = psp->tokenlineno; psp->prevrule->code = &x[1]; @@ -2300,8 +2309,8 @@ to follow the previous rule."); psp->errorcnt++; }else if( psp->prevrule->precsym!=0 ){ ErrorMsg(psp->filename,psp->tokenlineno, -"Precedence mark on this line is not the first \ -to follow the previous rule."); + "Precedence mark on this line is not the first " + "to follow the previous rule."); psp->errorcnt++; }else{ psp->prevrule->precsym = Symbol_new(x); @@ -2904,7 +2913,8 @@ void Parse(struct lemon *gp) } if( c==0 ){ ErrorMsg(ps.filename,startline, -"String starting on this line is not terminated before the end of the file."); + "String starting on this line is not terminated before " + "the end of the file."); ps.errorcnt++; nextcp = cp; }else{ @@ -2943,7 +2953,8 @@ void Parse(struct lemon *gp) } if( c==0 ){ ErrorMsg(ps.filename,ps.tokenlineno, -"C code starting on this line is not terminated before the end of the file."); + "C code starting on this line is not terminated before " + "the end of the file."); ps.errorcnt++; nextcp = cp; }else{ @@ -4143,9 +4154,10 @@ static void writeRuleText(FILE *out, struct rule *rp){ /* Generate C source code for the parser */ void ReportTable( struct lemon *lemp, - int mhflag /* Output in makeheaders format if true */ + int mhflag, /* Output in makeheaders format if true */ + int sqlFlag /* Generate the *.sql file too */ ){ - FILE *out, *in; + FILE *out, *in, *sql; char line[LINESIZE]; int lineno; struct state *stp; @@ -4175,6 +4187,78 @@ void ReportTable( fclose(in); return; } + if( sqlFlag==0 ){ + sql = 0; + }else{ + sql = file_open(lemp, ".sql", "wb"); + if( sql==0 ){ + fclose(in); + fclose(out); + return; + } + fprintf(sql, + "BEGIN;\n" + "CREATE TABLE symbol(\n" + " id INTEGER PRIMARY KEY,\n" + " name TEXT NOT NULL,\n" + " isTerminal BOOLEAN NOT NULL,\n" + " fallback INTEGER REFERENCES symbol" + " DEFERRABLE INITIALLY DEFERRED\n" + ");\n" + ); + for(i=0; insymbol; i++){ + fprintf(sql, + "INSERT INTO symbol(id,name,isTerminal,fallback)" + "VALUES(%d,'%s',%s", + i, lemp->symbols[i]->name, + interminal ? "TRUE" : "FALSE" + ); + if( lemp->symbols[i]->fallback ){ + fprintf(sql, ",%d);\n", lemp->symbols[i]->fallback->index); + }else{ + fprintf(sql, ",NULL);\n"); + } + } + fprintf(sql, + "CREATE TABLE rule(\n" + " ruleid INTEGER PRIMARY KEY,\n" + " lhs INTEGER REFERENCES symbol(id),\n" + " txt TEXT\n" + ");\n" + "CREATE TABLE rulerhs(\n" + " ruleid INTEGER REFERENCES rule(ruleid),\n" + " pos INTEGER,\n" + " sym INTEGER REFERENCES symbol(id)\n" + ");\n" + ); + for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ + assert( i==rp->iRule ); + fprintf(sql, + "INSERT INTO rule(ruleid,lhs,txt)VALUES(%d,%d,'", + rp->iRule, rp->lhs->index + ); + writeRuleText(sql, rp); + fprintf(sql,"');\n"); + for(j=0; jnrhs; j++){ + struct symbol *sp = rp->rhs[j]; + if( sp->type!=MULTITERMINAL ){ + fprintf(sql, + "INSERT INTO rulerhs(ruleid,pos,sym)VALUES(%d,%d,%d);\n", + i,j,sp->index + ); + }else{ + int k; + for(k=0; knsubsym; k++){ + fprintf(sql, + "INSERT INTO rulerhs(ruleid,pos,sym)VALUES(%d,%d,%d);\n", + i,j,sp->subsym[k]->index + ); + } + } + } + } + fprintf(sql, "COMMIT;\n"); + } lineno = 1; tplt_xfer(lemp->name,in,out,&lineno); @@ -4350,6 +4434,8 @@ void ReportTable( ** been computed */ fprintf(out,"#define YYNSTATE %d\n",lemp->nxstate); lineno++; fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++; + fprintf(out,"#define YYNRULE_WITH_ACTION %d\n",lemp->nruleWithAction); + lineno++; fprintf(out,"#define YYNTOKEN %d\n",lemp->nterminal); lineno++; fprintf(out,"#define YY_MAX_SHIFT %d\n",lemp->nxstate-1); lineno++; i = lemp->minShiftReduce; @@ -4669,7 +4755,10 @@ void ReportTable( assert( rp->noCode ); fprintf(out," /* (%d) ", rp->iRule); writeRuleText(out, rp); - if( rp->doesReduce ){ + if( rp->neverReduce ){ + fprintf(out, " (NEVER REDUCES) */ assert(yyruleno!=%d);\n", + rp->iRule); lineno++; + }else if( rp->doesReduce ){ fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++; }else{ fprintf(out, " (OPTIMIZED OUT) */ assert(yyruleno!=%d);\n", @@ -4697,6 +4786,7 @@ void ReportTable( acttab_free(pActtab); fclose(in); fclose(out); + if( sql ) fclose(sql); return; } diff --git a/tool/lempar.c b/tool/lempar.c index f75ad51c..c82e3329 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -725,12 +725,15 @@ static YYACTIONTYPE yy_reduce( if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ yysize = yyRuleInfoNRhs[yyruleno]; if( yysize ){ - fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n", + fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", yyTracePrompt, - yyruleno, yyRuleName[yyruleno], yymsp[yysize].stateno); + yyruleno, yyRuleName[yyruleno], + yyruleno= aKeywordTable[j].priority ) return; + aKeywordTable[i].iNext = aKeywordTable[j].iNext; + aKeywordTable[j].iNext = i+1; + *pFrom = j+1; + reorder(&aKeywordTable[i].iNext); +} + /* ** This routine does the work. The generated code is printed on standard ** output. @@ -489,6 +515,7 @@ int main(int argc, char **argv){ h = aKeywordTable[i].hash % bestSize; aKeywordTable[i].iNext = aKWHash[h]; aKWHash[h] = i+1; + reorder(&aKWHash[h]); } /* Begin generating code */ @@ -603,6 +630,17 @@ int main(int argc, char **argv){ } } printf("%s};\n", j==0 ? "" : "\n"); + printf("/* Hash table decoded:\n"); + for(i=0; i sqlite3.def dumpbin /all $(LIBOBJ) \\ - | .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \\ + | .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser|rbu)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \\ | sort >> sqlite3.def }]] diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index 83215391..9ce5bd40 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -41,11 +41,6 @@ set pragma_def { ARG: SQLITE_NullCallback IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS) - NAME: legacy_file_format - TYPE: FLAG - ARG: SQLITE_LegacyFileFmt - IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS) - NAME: fullfsync TYPE: FLAG ARG: SQLITE_FullFSync @@ -133,6 +128,11 @@ set pragma_def { ARG: SQLITE_RecTriggers IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS) + NAME: trusted_schema + TYPE: FLAG + ARG: SQLITE_TrustedSchema + IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS) + NAME: foreign_keys TYPE: FLAG ARG: SQLITE_ForeignKeys @@ -262,7 +262,7 @@ set pragma_def { NAME: function_list FLAG: Result0 - COLS: name builtin + COLS: name builtin type enc narg flags IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) IF: !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) @@ -406,6 +406,9 @@ set pragma_def { NAME: soft_heap_limit FLAG: Result0 + NAME: hard_heap_limit + FLAG: Result0 + NAME: threads FLAG: Result0 diff --git a/tool/mksourceid.c b/tool/mksourceid.c index 282f5c44..dd153997 100644 --- a/tool/mksourceid.c +++ b/tool/mksourceid.c @@ -540,27 +540,9 @@ struct SHA1Context { * * blk0le() for little-endian and blk0be() for big-endian. */ -#if __GNUC__ && (defined(__i386__) || defined(__x86_64__)) -/* - * GCC by itself only generates left rotates. Use right rotates if - * possible to be kinder to dinky implementations with iterative rotate - * instructions. - */ -#define SHA_ROT(op, x, k) \ - ({ unsigned int y; asm(op " %1,%0" : "=r" (y) : "I" (k), "0" (x)); y; }) -#define rol(x,k) SHA_ROT("roll", x, k) -#define ror(x,k) SHA_ROT("rorl", x, k) - -#else -/* Generic C equivalent */ #define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r)) #define rol(x,k) SHA_ROT(x,k,32-(k)) #define ror(x,k) SHA_ROT(x,32-(k),k) -#endif - - - - #define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \ |(rol(block[i],8)&0x00FF00FF)) diff --git a/tool/omittest.tcl b/tool/omittest.tcl index fc51127a..120fc2af 100644 --- a/tool/omittest.tcl +++ b/tool/omittest.tcl @@ -98,7 +98,7 @@ proc run_quick_test {dir omit_symbol_list} { } if {$::SKIP_RUN} { - puts "Skip testing $dir." + # puts "Skip testing $dir." } else { # Run the test suite. puts -nonewline "Testing $dir..." @@ -127,7 +127,7 @@ proc process_options {argv} { } else { set ::MAKEFILE ./Makefile.linux-gcc ;# Default value } - set ::SKIP_RUN 0 ;# Default to attempt test + set ::SKIP_RUN 1 ;# Default to attempt test set ::TARGET testfixture ;# Default thing to build for {set i 0} {$i < [llength $argv]} {incr i} { @@ -150,6 +150,9 @@ proc process_options {argv} { -{1,2}skip_run { set ::SKIP_RUN 1 } + -{1,2}run { + set ::SKIP_RUN 0 + } -{1,2}help { puts $::USAGE_MESSAGE @@ -192,6 +195,7 @@ proc main {argv} { SQLITE_OMIT_BETWEEN_OPTIMIZATION \ SQLITE_OMIT_BLOB_LITERAL \ SQLITE_OMIT_BTREECOUNT \ + SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA \ SQLITE_OMIT_CAST \ SQLITE_OMIT_CHECK \ SQLITE_OMIT_COMPILEOPTION_DIAGS \ @@ -207,16 +211,17 @@ proc main {argv} { SQLITE_OMIT_FLAG_PRAGMAS \ SQLITE_OMIT_FLOATING_POINT \ SQLITE_OMIT_FOREIGN_KEY \ + SQLITE_OMIT_GENERATED_COLUMNS \ SQLITE_OMIT_GET_TABLE \ SQLITE_OMIT_HEX_INTEGER \ SQLITE_OMIT_INCRBLOB \ SQLITE_OMIT_INTEGRITY_CHECK \ + SQLITE_OMIT_INTROSPECTION_PRAGMAS \ SQLITE_OMIT_LIKE_OPTIMIZATION \ SQLITE_OMIT_LOAD_EXTENSION \ SQLITE_OMIT_LOCALTIME \ SQLITE_OMIT_LOOKASIDE \ SQLITE_OMIT_MEMORYDB \ - SQLITE_OMIT_MEMORY_ALLOCATION \ SQLITE_OMIT_OR_OPTIMIZATION \ SQLITE_OMIT_PAGER_PRAGMAS \ SQLITE_OMIT_PARSER_TRACE \ diff --git a/tool/showdb.c b/tool/showdb.c index a28656b3..fe4e9aca 100644 --- a/tool/showdb.c +++ b/tool/showdb.c @@ -956,7 +956,7 @@ static void page_usage_freelist(int pgno){ ** Determine pages used as PTRMAP pages */ static void page_usage_ptrmap(unsigned char *a){ - if( a[55] ){ + if( decodeInt32(a+52) ){ int usable = g.pagesize - a[20]; int pgno = 2; int perPage = usable/5;

    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�~9UYsmUeHZGa$w7$n$)wA&( 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 z zTh}-4&Tp4@KFM$0$v3cfIi19O^UZv-*eo~K*S(Ce*Lm-ITi3Qar{wD^* zQBrc8D}LGQ*^PHDDqIrbvaWA!ck*+;`q`b`YU9i5?j2W4ms)&LZ=c`3@V(CZn;%#6 zSJwA5bGLW8vvFoZlNQ>aAJF>uE^U9WL$t9Q*REfBcdJuu+&@i_wa$j`E=AtBqEKt+ zi3H&Vn)l!Mj+cWLzFqg<=ygvo);d2OGBn0aINE79K*j3>rg@5$oBZ#kKYfb-tItUq zfj|4!SFgT&>bL*!36Nvr#!%=Jk)dn3Zjz6vsa!U3EyXB)cIcvDR(i;2??LnI@AAn>(JX-TlcHto6j!=MBa;jXcn6b2ZB<7urYw!+vN0^Zv z-vqvHq+y0pSQlZz=loL_5pmUYiyc$r9Zh;abyl)PjM(6$N9tt4F{r2-)W6P2Ky23< z^xvF@&Uing0HZs2Kjl5*D@S{PW7i1FB!!?7wxhNr3FK)M8n0%GYPh8}Vh}`R&?3Bt zkz9kF)u3DINewE~@c$;g1SD%K-)|)=w1mtmVW5?xiZ6mlphk&Yv&`_XRKhDLVcwK5 z4N3^_64#@ML6IDg0Nk|%t3!flOrC;eP@p$lFs=n6QF*W^N_0a@X0Rx7zVP#~A1l}b z1*+Hu(_av)yudqMF+-Y(P_lpkESUNN2D=Qk3NYLP^j&VbOxl@2dls~;Aj)Egub9v1-k+Ik*{2EAqr(tT*Joj+J4orq9d;$@ZdPZg^TedH zs_E2jRsti_y8@`0?xZ7-?hyZ@PZe4-o59>kFQ?79nN6BQJR1X+Q%Woh-JNKD)Ffgt z91=5`N2H|3=l^XYj<+q1X~ABMRZR0iV@&b?#{U2PIQ2;hW&jJ__287j?5B|QZh}ZO z-Hic1>2Bnvz&iw-4&ec$mjmEHx|30Ly6d$(*>xE^oyV|Wvk7Z8+)OHfn}30C(dexR z23ZW^J;@vC=fI+neuh8lcrzVFheL3>gl<}GFR%|d-GDbJmEzTz!t6{f&8@$!Q%6t{1f{$y%J2v zUuVoioakQ8z6y!v;N;;Ni@kU~1(giX5%& zgQ*WA)@O!72;D(S02~g_pAr9Wpwo_k6=Z& z={HK4BNG8@$fOt`GbF4?tOPsF7R1Z00eDW7#xsUMoT!SL64ffv8jBep;8h8LA;<<_9zw@B z*&5_61h&c7ps*@TQ*l=g3k&%hf;}0-R?sri^}}eHFYGP0UX=kYD`}k`yO%gtN=XY# zT39lMC6rc)B5Dbfq@;x4_gMiI#LXi;@7nC60Mb|flGkQNrWfrM89g$hA= zu!p#Afn*mFm4pz41v00C78bOypoIlI!@?+4o-xY>m@{g{P^qNj^eaHm3jm*|RwaK5 zmtY1drk}SKM%>uGc)sOxR)S5*Up(U#bV2aRdp;@LjF(`0~soZ z5>#7xV}~O4&glNGUb+n5HhO$`DJ`Z7BxJ@$$asjI~ zbf=flLh(mJCaH`c(pMbGY@UWf0ezj!XBQwF-iUe+*PiOL8KiDO`;dt{I7=a6?p=q| zArP)Ee5dec&L)o6eXz=S!{L~&V<(4C!cUyAK5&@0sIhkf6AN8q3b3#WZIi}#x{ec% zC3>7DrX9r~mx{3(h@0vQlNK}3#20|Ib{yP6nGiuNA!N*8KtOt`&zhe&_W$1zx;Ozc zhil2}!!_0;aZt2R{EE|f4LFX%cro~d2ML*aa4!8DaP;mhE?T>b3#ebiyo_`~9jGBN z@=64QCmt$JuTU6+44T!ry7s5y5{dW2 zwvcx?&Yn;scQ2@~IB8!2y~1E)pA@gV87I1b(ZlwvaUExl1C&EPjHB-IICDLzX!#M& z*w9^YpHQ5*@bQ{#;kxilC8mhe6Fein$vqoU+Ul(1E(~>Fw%w)Tq!1E{QwWQ2EwVD? zV7@VA3QH6@U&^k`AWAe9U1N3@>DwG#rYL zVH1bvBZNC)7Uc*e7G_vpOa@4cZ-8iUKtloj#I%4b3i>Qo4JxCE0sR%gQMy0qf;F^j z=9>?Uue#aves%TTt!tgndzsnTpXr~4qeXC3XMPX3+st2a>}x_IsCJ9NiYc%Ld49Ts3}zhG{^{=QrasIzEF zeSGtyk8knCgMy6mi|Y1nb$19Od#~tA7i^-7jhm;>Uk@5fqtlH4ohw22sC(M?iiOl3 zC8z&0KK0W0Bq_g~^tSx#YhP^=!1Et|>nUjGfU%-M*!DF5>%s*|*f;E`z*y4HX@|)~ zffHSiRZ!38BB_z%GfH<=g0-Q>CK*_xgQR_+rZyCkxM1Vg@L z^T8}Wl=}oJZ-QbWIeq@!C$Rs2`UQ2NV1|guT5PgGj~~{Bf@HX$BZ3&te);6OPjD7M zPtJWpvYcOHw;WB|#oaN}Hng!Q9VP)AemU%6}4+gr#c$y!bH;r{| zOfdml`+#fdAAGP-RLu7rx=?63!vKabR$vTn92h(pfXz{3T%fJ>Po|03VkUEHxaka_ z2SAcet=uO(&+ZeV<^G9spTPeAdsu=FQF>}F6cFzT*OKv$HU*moivr1)bYKbiAeDV8 zE)-;|%f>v=g~E&DJ^?oe{68l533-Xe#__vPz;^10?h}ypomBS;$xa_HpD4Q|_X%th z&Y4GdpTPeA8B|r|A7ask0uD&of%qMGye<^bTza-$D4a0&37X9V-6vQAxODtY-VY9T zpCHE^4|Ja(4WpCmK0&H`%YCAw6X`x^o;vplX2gm9X;!1liw@oao)jbqK654r4WlOo z=Rx7kt+y^+Iie8Li3ZQyU$17P9>TqMuAP7D?em>`U)(M}zI*5PozL!_yZYVl#^*P0 zm(~3bZ{Du&Ab-5yJDS@AJS0fc*7Wjlke7rbI8<0jid%^2eWAD6!~Oe4f3x4`&tS8& zd-t=d!{u;uIHdg(FRGlMy}#Khh)uRJ|KUd)^Rr*Pf_nvdWk7&jeN^4GYhHOt`R-8f z=AE~$UA^&+WT@oNzIXoJOIO}%y08y3m8G|0&5I4srzVXK3EZ(kWr#t)9 z*>@6mS7)B;q|}bDQ!VR!r^BBzmx)EO+}ya)A-V-k*K4aqrbD zH!fd}lJK~wH`X`ya}Ls;;PKfJYMo$Ct%)8C(j zFI~B?9iu0pg>d28mi(bO#f1C)4$epL!BVh~_H?1KaM$mAx_k4Jn_pH6Qn1kcMzS-0 zdB2|Bm;C>yaQ^XA|L)2I$cfTA_;Ww~)!CO%{U6^xAsPm9z#z8x)AIs?ccvtCYzV8p z;L)Cd&HjCVF8k^X1NZl?2F|-r*>~U=t-q7+ACVso>3Xk({!;DSFW^GkcgjlWzY_Wr zb`75oI`-w^n- z|2uMd5aK4Rg#K(sQ-u)VR?r10N9c((_}WjjQElX&e#``u=_?M!elZg)!Aj^K1EIgr zLjQ)qUox+agQThpQp6)9ZOepLLjNH2$7=hrNd3_dSjqj7k~if3K{a9}|L>tg67^de z@_)|%HKM!Y$$x)G{`kFsL4?CXLi0iEG=gX+fvj18uBPbP@=F$;tigh6=1 z!?(^Vh_=+yMXrgiZ$|xH3{ZQF7NCzT44Tbj0PWs>0kqlw-)ICr-Y+twgfaTQKtZ%$ z0D%zxJ>A4M1VS&8Fi2~d3WF2{#PJ;+!wD|1NhHerw=6)-zVo@Z0L4o%kiZOB4-rKBIT8l3 z|G#Csze{{)MZ-e!FC#pL0!(KWL|dVBG#=7BdB`Bzm{ODZSrG^wr!a`PXXui|^+d$i zhD1!h9650WXtei0L{6jysFaSL9SczT%-4cFbO3Gk|Igt{)BOX^w-KTkqZS3hXDW#H z(XBu=XeTs?c9J?QT7fL@=ApQpe(WHADx_Uhs`KlI37Z zkNe>0-FFwyzRsF&p_gs(SO0W|3EzdQSH64s(glo8Pj@a}?f4;A#Pi}DvWntWEdLH^ zO1R8uaG?d__`jZY_YT;vq*Y<|f2V%t)TzI$pY-|He&(w#9&Z1k!82$^1x~Z^uly}v zef#B8fAy!I!R9}SAlm&o;fu}et7$&BG6Wlr&W1oDT@98J8;PBG>3@$i% z7H+s39x875%H8moxJ%=@U+mo^*)V7K%=%LtGLJ|$8(S!Or#CzkacK^IPl~YF2?)jfKS}O} z6|1S+aJ(#adPQ(_LV9uRVA=wzVKNe%Ry;fuH8Y6mW+z-BZJqoV&GL}_|0*MyEdP=V zPdr;HQm1qt7|;p21oCo=A1EyeCk=|6L+&*pj+ZN?SvTY`&t)b)?q~AdU>SMRD;gRH zFO21(7_%>cu(`P_wFsKR=7$wDvxZiJW(i3U&6^*<;FVXbej<`F$WF2^sol{8&Fue8 zLZOBNq|QDDNG6f}#5Q&UlGX&dv?aEhfmsEQmlA-r#h%GkXDYzSd6EW#g9!nasO@cG zvw;o=UQ!`~9r|w{4_-`KtEB;C3GH9G8xHP~^S93alV}i=l`Efn`Z+7$#Y399&$61Ory?hS@0#$Wd5D ztg~mq-7uo5u%X+#g5_)bfu(IA2P)FZ_@@c$bHJwQ`drZ>^;rp;88nG?Wo)gGmq`-I zvus=u!L<3PKfxQy!V?JsTWQGU?7|3ZZ-t}cmANGB|Fe=8%CgX0!ZtIuT@F8HVY8?T zt9<2dxG{VCSsoJ2kJAR7O&!iUijojlR;|K^v=N!^fkKvRU}suc&WN8Vx+y&&+*xN} zPD;X3IE=8lU$Vwh5zoKn;UEAghPtlcQrT}^53~1&-0v{L#6Od|6M=vSlljwdH@qPJ zTPjWVzEWdS_W!pfL>`1tp+Odk_gF7D46#%93V!oV9PWBa=s{xMy}nx8!sh(kuYPuC zx7vu}U{)+LUng%y{Ox=q_Yh{rcAMb4VYnExMoID!s+b4UyxouQ&P#<<^<7`T|HYSI zezCrJr>^f+yZ6k7s_n`*wr>6I?%k^DT-iE*t+OUCy}eF#d!FCILvIv{x3k7t>tC}l zuC2Z;n-6oEdu{8&jceC0y}Q*ZHtw4bpHUg zWJ$WQv3#MJU+Jd1;RWT1^A|57iobm0?JJ#&Ti-o@iVVG(t>tU4$+bCG z#oBB2{MJ2PmTRx|`U5Viwb#xJM`NyPdqfoIZ0#c+^7`zkdX-7f);?Z)?fu@SmC~D> z?T@N6!_6P9-Cuicw7K>L*}6a3agLKS7;{evUu=l^>kx{P=tCy}JD?Yv1|e z+^>B3_1UctUwQq*o3G!#-TD3(zx;jFVh-@-{;kLA%l){#wlCRX9ttH3TEA!y2jjli zfN_V|OZ(S<(CSX-{@z2eT_Vasoc}#Ukc9e3g2)Vfa^m$ukl;?H{mH%(T_l)7c}|Ex zxI#V;86%FQb7l-Fz0f)JEo%p>RrgF(-Idr?86K)ReovoF>{<4|38q48AnU}BM3%arD_YmZlO_;${?!tP@c@Caai<=u zKzL?Eh%;$1PqsliBIwYYNTd=>g64@S1|T(tbFhek*>1v~0kox)q)DpXgXTrfzFEv_!M?&^wL)E334`JKJ41=E;)Z?C zz|<5W8tZEbh?AGV2{JJ!YGFE0j4+t}@0NxWUBnim_S1k-f(n8Q2!3jouSwe^d(eV3 zMx}}1rrgh4vcE;|2wFfZfw1jPhSW(x+6L5uTVlHgfu?wJO>yi@{=u7$Bpr+h$sb)H z{7eXg;cPMrZXC6yv=WozN*IhMB@C9cY%`qa&>!(nvnTk@S~s_jYR|A+AY8QVl9<%>PO$~+svw}2Qc>alTMN53fBgda5!<0~tC@|HNDPQitY>0Y%!Z+RsLc5LifA*DOFeY9s#$GnwH~GxPCt~{Xh8M4AK}y!!AXM;pKA%G;PB78wkM@}(#A&biQIDN^J(KNt6+?|6d36$)J~i`^yO(2;+Uru+Q0XHFSrXx==xc@H`uh8c1w-Nj}*| zqv%C4DUWV6%JD`)&xMRorf+`TKMOKK(XPRpM%rJGU@*%5e ztfe49{^Rwp++Ftmc(~(zaD$V4?@xa6)$rw0|MZ8CT3xf;E*kb_iODF=4smpd51Sg? zucEr|{`n8S8oYe!ch5ayb>2aWy430&sFVAkYe{wA`Lo~us{it--~Od1P@S*1{ioL+ zmN673=V(O@aQ8UvR@1y&4YsGi{7&c178}QG zGJZgeRH=Aj_=jf|cE>&;QceEb@F$EseC1F01euS%fTCgc|IZ({PvIBbgp~dN+=zz( zYO?TJiG~>l?@!pX!4T{{5B`MN|L0}hkwpEE*MxNCPuTI!(Hnaf#KX^@Xc$Y1m1sDr zudx5$d?8IpSK?t70cSgW3Y<>ZM_3C$NdmDX>e){;EF6b1LTc-%gPUnuc#E~U|D--LAK zPZ$6ydt7`Suwk5DFLye|XWq$jBSNe^023ywp7AyN&+Pqyxd9er7g{933D;npgziq> zg3Mcvy%Xp@8Rnzx|E*T=+Lj!5j}hac<*Lj4*Lo@Bi|9}I0h08U17P`1-rvf%9ZUBi z900du{x5=G-^2R!mALc0z)?=y1WZC=tO5Fp=>@sx^v^3zLLRj%L>f>4w?Lk#YrTvuoN z`>sA}EaPlMq!kujjULksC(=Ux)iFY(?W+-DT2y`#G*Nuzx|*?CzOUl&lTb7J;DOi1 zS=a!!9OR0DZ6bh@+*cFr41SZ}^i%vBs7-P4sGZruz{haLM~r67@*$W}Tt73f`X{of z&P8a|=%CdVUb^zqsnVg4)Z=ES-{gVGX0r?IvJXy-h^b{QR>V2QeKn(|A+gF>*19&^ z=5dvo-i-`B-J?0ME>UNq;A-eIiZ(Z{zI2L%tg~NTdHPM(Ge<(c6Y2;k%alUH>_x@T$U3X-Ru+rnKKryY&v9yW=XPhey0@#F;s>4l&Ye%H zyPf&&oliP0%e=Vx!^(mYv=8p%EO{w)*9eQT58B}AVeb`55kelr@&3RfzjkRKz1Rh` z;0a&_5z;)+QH<9#U10^wQJh6bF^9$q90u^LVFf@CqEtM$Sb z%-~tT3LY9K;EX(8oWS7)cEq+30T-XIagZ9aQbTLiRl!%M`4ZfKnK%M&Kw6!vZQQ`l zYZUr9?1d>D3RNIaLKTGNDEGsn3RFu0e(}=v?d#!5 z&$~422giE7&gs4W`oxghdqTI72nz`JI1@ea^nUaNU;E=wEu&#IoQ-k}3VV)s-lRa<~J1pqd9FHKB1NZ668y=CAe|&f6z5o)r8e$^mg4 z^&XN~P!SB5;06lqKrk0Z!2J`VEg4Zjt*I9e#o8}Ky{&;xkOV!$l@%){l}I~;vG*vd z-MMqb2a9a!a=r_8f3N!R*3ElO zle-SKeLvXnJ~Tham1$WKwD7~$)Ba}X)9P+f-6oV_Gc_UDiqAf&J}fD+S;VdRM;mN> zbIbX8FY_jS*?X6+T)g^T_Ia;!{(9DM*V*vZS!UO+zIVOz=GOLmTU%E;{mwgtYTUYb z>B?IcxDTLn_44Jb6!aDm)IRSo6x8XjHdaQpn5m$y2*{f&9&!uPf={PB&R0zY0pzrEFY^U{^`*M2F^ z7c)zE#hwm=Yg^XsSflsW3JceHYt35jS~v2aW3gtjXBW<2-@=D0K^(7ifO4H}T}-;O z&emmK3?|drXePdBXY0zv?ArM&Z_yOLW)3mWSs0LpGgyY+TgEkLt5qOjdHK|TbKwz{fZv zE$8sehKXUx^$xT*T&{!oz@Shp>A;K+cTMrizHIoA_yK%iv^?JaQ@{7C@ynq+vCJ`ARPf8e!bBv79kgSPC&KqowK}86v9V6kAyw_t=X z7M!(9#-h1hFaaPb7*(Hr3wDSrqM;Utf3eB%_1gtwH9ZhBSOuH;^{62wv1pdo-~)nQ z>OEcWf!+7{4)_jP75^aLD-9`GmP}q@27}lO@1-#@z$KdmKmS3zgq>@ywQGEXV7~2z zS_j#=E{tpnJqq_Y2$*~^;tU7bm^~7+hZY?esS~U`@-%{vX4i|%#p#^lA&`mEwlpjB zX@4NPrPUEKjvxx)Ps0;u_#kBB6T+wu7eygML?9X`#w&CpWtjABi^|9yCi@tZ;${z6 z4NQm=ShZg0x!>co0s2ZTQZKq`7GU`)eB8rQnK}j}73H!wOWBBTstn80_!y`_9jjl4 zZ*0@XGAQ_ocQYl*aIRh-mPV*v~{n6mfjgCveii?S(?Gj^DT%NXYx_E}%U7qd2o zel{wgrkXpj)upyL*F@4JM080isB5lixnRb zl3}&Q&Jn|z#O{{ngiX?D%qhgc>oa2tW_m8hNv7otTnU*=5{dBuAB6;BM<5mB%7C3V zv^_5jLcy>gU)isugCPqZv?+$LVkm!P0<{rL80l}QKG!yZi~*S?e`B~Qn0C@iir2k= zhFp|2qCy!mor!+6uo!g^!*3bo6d+Nb4hFSPi$UxXhL}4l=6B4y3EMQ3%B{Ml5zz@I z=W*0&ZLEmeCxNMr<&b9#0KMY9z_AKrvu8?bH?cOou$J=NPq2iGjwfXz$CzTQ7OJ!A zrde6g4uipdur;`hTtCN$mb!>ygjz9%JFZr!HMAaj!dl1Xqe^C#L&+vn`>N!h`EuZ; z+h>{zWzb+(LyetvvImRJid0+O41>nNZj%T!JhIm5b&nwi4)~fiE)_$~Qm_S}mTA^C zIJDNyqK4hgp&xV#rbQ%;Ye$`fU^&U=M_NUUr&3`P9O0&(NTfhNk*|3rT^U{je^25?p)Jz zp7k?x51k&$)4FVaToS1$C^nVdO{83Irb8-5z2IKOy0mr1{sJB5mLOAnLnZ}g(#a^* z0Dbxlg^HP4TD7D$eFfJpu?P`Ls3v7e#psE;qXJmiyiuoI-D*kdL&2SRoA!<~h+F-$ zTLsIcAoS;XqF?HV1W@*7H|00my;JwCO*%BxCMDHJ5*&3y#kqS{BllBdP^w!MS4=W5 zl}ZK1W@HQ#jf6ewY7ukP01@{(cGY~%s@|%VBbz2SR_a`60&7`g)el{?*|Ye&hItGz!$hv}&FcvOrMN{=NKp=GIxH5zU|xNa%sNNO{F;X+Qh6q#Q) zZmYWW6N+;qp%ta<8r-ma6`5P8v0IUDXi()t9gn0MShYi$3U7|0)+{biy)SL)x~-)) zk1Uls$cE4yxlC$_+Z+aNz<;z{T@W`F?N%Ui3$DTnvn9hm#8OmE*KJr=oa;RCb+L>G z)=D>KswxbIt|{Jc`H|P{Vxelv-2jFq;noXUNj%p$slD1j-RY?Bps6#b6x^K;s*FkM z3Ahhbs{^_kH;o^wX%YJKCXAnsN_W0%_zBFXRsrmk#R_oii}O&&jAc}7NUSZ*fNM-0 z^b%U-c82RP!#=k2#-mIm)zNDM%;t`WgH@yM(?!lx9mm4!{rP2863$qy8V0<=vbed_ zA#6w|&kQxC7~*u>5zSBw3*n7B1sJ~Z5adO5O#1BqYwiTMtZo7v+|qoiJp)FEqnmcS zMJ$1r8p7(gzOdo7Ox?QGIn5Ev-F}CK5OKpTgj$d;92=?zBu3CQ?5H%nD$oYp;c8aA zRyd|w*0pJXzkXfWWCWNM-~-EqjIQ~N57XkXLPM8%qrm1Wl7LQ4l!{T5t|AG-9t4@E zn-gBR+QSwWW~(kWPaq9?^X%ck7oy%mp2!k*;xOPkJPWYE(7gz@9grI9jLM)84XLsM zv=rQ;RZHFB$~`T03)F*0m&2ZgV~iAd=5sii73F}3(7Uj{!;v;();yg;%5by|m5v2v z$D86uXs&d4Y1CMUHmt(4J?6?&WmYO%y6Oy11Zeb`lGErF;n+s7STSxF8ZAZ3G=|C) zPD4C6GaU`$!U}W?8d0t=Sq-{jt5%#|vArF3Z3SsvGwil}9drZh)4&f^FtnUBGR+ZaGZn3yym6mJUL62C?$^xL(jt_V?&jUkaLQSU4zc!3_YU~#5Yt*|lH9ck>!mtt8Y)=@|JQVWk$jJMDWz8JS81e} zb3K2p&E$|0aox3>T^cc7)l;Qc{pufpNjRXBeTRbFwvxteP#2Jzi&g`_(p9M^>XG`< zRmj)jD5nmIt>3$}{XGOIh)%CxdUvZ+Y;<1F-rRcY67ohbL|b2XK`0Rxb&+FtH;3KL z0WzCCIT36k2-@(5QAnH#LP_|?^Or9N>CpXGy`D-T(bl!C&iyweXIvCeMJ1JnqgxGv zmlNW0_TBRrZrphL^=!9SdQnkHix$e+&;06O)mB1JmgT4@>tYIOQO>7hNTO+#&+~d( zjd;|rdZX!-19?={X#V8AX+9s!tLbQ*=d)2g?G@E9pA8B^wLk((v%BmMF|v6|)gmBF z<8^Qw)>AN5xd^`3dF%4kH#^=_@af)&36MbfS38%O=H>I-xpL$3<$d~kzxzf2yp{G*fnmU;`&+*Wq@gqD7I7yaM2b zBbR~05$J?G{QLLr+-7x!ggDuy0@1OeC3HRp;7vQ7S%pm25v|qLi1wkSl$8_-?kGD8 z)Ri!>Ag^p8)KE256cg$Tjb{jkXs-02QaUjN)M)=q4F&k~P%U>4|0#OU65^Q}-^>iI zPIW?oQ~(WcHeFney41N+*V1m{uZ^+9h8!8ZL77s@QswkD@(XRE$!@^IxP)GWd)I?B zz^?V_-Zi{6;A(YBfTA1iZ4PueOBmMNHC7GfE7>OUk~+($I$ZLp%q_^NZ3ekwOSmPI zZQVdU7{UghL3~4a==6?{I?2d70#*;=$Ki+nKYMQi7+03o_o^g!2Ws*HlRyYzD`sd) z?v{tTwbyj32eqx~HsiJ%+3xAVD5jQM-JX^uk1Wr~JzL5^2qf%}M+n;k9*{f;%Mi8@ z_9buFdcyJ&LP$b@up|(cB=ZQ6dB6WTcdtcNQfc)qTeoiA<=k`6`kn9pegDt=w2LeM zjDN!aHpl7zSN#k44nSIatc>=n)?F6X4LI9q1I{+utBmha1Z@Bm=t*QoKe4x@V=HPPWH%u&E#Dj7hAjW=KnVLbKM|{;***87X8^G)2J~Fi^xB3&{ z1Mn4id5%PUNHhlc2%oKe;v^qQ^A%bXhP@Oacx_9Cw5g&VAT>jshWFVSkl zK7^^pNIxvgB9D>5t~sAAvKrzEtO})V;af{%?dzD9&V(B<^IS5=EEIVx-GViUmsEe2 zy^AOVtGB^~Es3|JJWI!M z!lh{B8*9r3P=y1ocZ<~pm|J+5hMnM+fp@T4vzq%xks^&gh1)U2K);fiwcXUF-pj3@!_CV?mUDV2-%Jd=&R0PC*c^9auvcw1XjlP-&%H`$IJ z2+|2{{$n@T^Sio@=STACKS+uM@8jnqn$aX?NRvW0!VRm^8+i2;*n3_#%oL$9wD}q6 z5FVb72a+*oWy+aM#%nXCIV|R7fRQi|loe(Hlo)~ZKZqw{#ukmx0A(KJVU*Pr02NF?`e62~y#|IKZ#N0|3WMgYj ztt$}+qw=9lnGhS8@Y}_3TSG`;T&tAZT67`;gwvL(L%m-J1)D=E3sbEL6-u0>NOsdv z4Z^0|-q`H)>0OdHWl;j1y>#*Q7tWu(GT%I%J9jB}^_g-9x!-8ykfgwWG@hGv4t5_} zN7?=6n>X%kt~b}N-@fsZd?jw)*fQh3Ju4R;|4PPNf1m#U9Fv8nG#QeRd==e=v}Y*c z%`(*9P9R|a7A6oWn(gr-n7zO6m7sRtanibKcis3Q__shyGcN7Rybj_ z|3CfnFaH!R!n*@FFi4435}G$d(Xu-lY*mo@e6a2H03gzs+p=B!XU z(3R!AR^?CKy3SvdzZQRO{;;LNWC(!;lSfr z0rsP1gZ~+QEIez5Qyyb{;ryGuF?Kh{)NRbibaJ~J)|~|$?NRSKYS!kO{{JSO@$Z*P zAt->@L3@AvLho2u0KpxIUxiOA;B(gn7wQzsO&7B|CWA`7T*47Aaj;n`t~#AYEoc3# zaBG31bP=m+MJ~7Et1;UsgYBo8HMUjyQOB{hc}_1di2=7pC9w=_fq1 zTh|kZ48e-PW>jvm^ZtlL0u3C;nwC5;zfAGML3Jx-Jm-@-^!F;bb5QiUp8KQXrZ&3U)X-QRtLp0D-%DAMt7PpJx72+@Q^C0Vl>RUjD-c=L9&aHThu;Tjp#RLLQf-Bq(-_y zZYi+dvH#4Hq-0zxwBqnqDD)ljB4Y<>LCUCLkzQa;!dKhB(fj^T)-DdK6u51=R`yk9k$>5fG2KDOdr~|F8KgqHb`MBU$rcnhqpq{G`TY{mmqQv-Ya>vs1Edz=51QOyCR$IyX7s*cz|5snX#v3W*@ivRiP6oMTi zvO@+5e}K5(l_ja7=BBRc}sDK%49y@-PqpR+}O%{D#Q<4_T;Wo zpgs&pgv~PHH1gi*sKD2D68!sUeQt4gR3X_G-N7^T|J9YHC!b!*bvHKM8_%y_f6={r z9UhJLiviQX70aq{$kDPHWU}yAJ{6%J=GIYW*G2E9fAG)1i$Xa%$ z+`KObU&wvRrSlhaxho>|D2S26H(`6mW)(ogeIC+}Afu8F9jqkFpnLkDd$ixIFZ9u3 zBKhHZTzLC#u)?Q*+}`AC-kSn-z*n+b4xpU18oQXX?!#iAi0ZDHJGXrKtbv8@E{sT^ z9l`=Uf#<#Ck3zcjtKI*rJh;jgd3VCa;-$dg;p9r*e5H zDnxVXQH8KF5^{&FUE2NpZ)b|D>^x z4Pn#&|JE^qvCT_Kl_I9-LxHie-8au40Au@*djyq6sU_fo{ObDsg|YK$`GLNAOc?w2 zTh?xDx!2npH*c-o*l=%c-Pl;ae&@E^VNK5~Y*pare1H#A`B~JwCD+Lx;T!0|1KOgAxS7)q}0#i<%zmLEJjZ?nraD0>@sJrOB z;gFX|kp6$&)OF%`;#hdrXl+PtH!wv29z@<|_t1s17~l`3e-W7c-s$VNP$YSz_4R|AJBwC^Jn=xF-|q+zL=&$k*%vm2F@Shq3q6}Z=OS2 z79@dwC8~z6G&;3a^c>fUHEAd7I71X0+H0W5Dz>!OJP_R_psNfGSu@j(jTN|hpHIxp zQH+T2Ugs>O`ivh?uQ||CPMrX#u%j%T|>UsJ|`8|RRuUNd&WmzsWtI+(t4$y5Y_1oaAq)M zK<^6dGU#RgK4ut}2h=kY7_s_=70;p$;p#U5Z}hEphpcsXT<03H$XlgCZvI9`$jS1P zQ0G0fa{g%%MZRJAO`-XR<e1ggN26ldNMaWun9rZ@SU~rfYBkFadp~FJ* zY>k%_I5&pzo{tem2(DyQBv0eRC3M`l7d>uo8>SE9|IB1w zJ;VR>Gq?o)`^WU^56tv_Z*i#bC(BV}Mzj8wv}UBxaCPC0L;kG5&rqh(xj5eKT^;%A z!@J$OBpbB>yc=+sK$t~2;&v(p&fuJdc|^HIviJ`bfsYDKCA!d#5w^=GUv5S$zWa`Y zDC>j(Q9$s}Hz&Fx@4Ly~11^Qds4=^1R0kL9RE{d_hZGFsc{A_{igi z98Er~#)~z{J{geTgUVZx-G_p$<15Du#OHaqTCY`cePY)ZKCG-5NS1&McUnm4c&>bA z6M%3OX*S8r2q2ogz&05#OYk?|X^`9qZ!TMgF#9s{8Z^Fx(O_-LJ$3;hlYb1>mZxEa z3zeV9{+Ic~Atn|nFYxFB`@|a9P`#;Kju{6iIS$wdMNLtI*2BKVea`{v@p~Hc6?qG# z9H8=vs!3ZZorH#yLCm0|RFl$c97hgN`ag^d1IPBHs>T*h$^kk#2Pj+usD$)MIY3z) zGe1XYdZ5RY9|vkV)Q!Z=gzE-14J8J99n(5vHos3i2Wa__I6&$DGU_$PY#IcSMx?)F zn{t3gEa+JRryQV$nsOMeo9GJ#>qxzhw2GIS)bDbg;FnLIW)$u|7H9Rz9N*?)Swow%J(ifK%prki2>wfBxsXW3*ccX2dHWN6!Z=p zpxCe;90#Z>{`hl%LNUZYVS_0LD8iOV4-IH&cmREWPoD#n{{OtOg*Gc6Gg3)U<&Rqy zOl51#SC9%gqY>VYZbyd$RD({+0cr`WQw~ttJT0E(gPL!^UA#vQP~$>#;y6I1g;g1; z%Nqh4xrtb9>J&IYEhnf33<-vlaDako1Qs>IG>#-6sAui)yt{F0W9{zs+k`#z_cz_= z@2oX9<2;}X`P*A}*WATdb#JV#y>@+L-F@^nhTbo_uiY$nyxlWzyV2Qt;kC}IWc}@1 zM0*Aq?fCLD`_ zNkM^zQ+Sotp`GlYZ+iiIG<55uxI!t|LqX76rWNq*5WpV#|4pMJm6A?j9rT$v=$kcd zJ*=Q_Dd2-ZYn80y1$|TGDT4+@BY+CL*SLT5!5&F$DcCa|uty3X<~>!u%rQXsj1{vD zYN**!$L`OdZzmJ*Nx>eP^w8jMUp4wOA~swM2f4j|KQFdq)3{&F9-bsrTAbGyk@I=ngr@ zOyQe4dUPGan$?LQEr>fxYhc26)-aX9);MPUZ;oJuHQWcvx08=1f#ZIi1*I2*Gpb*= zG@^vMB~lYKVxi*QdSiI5OymKo1+7U%B@k24dtMvz+aM5gm1mT=bfgo<5JwMW{~P?> z!bK_MSP9?8^QqFCC`=MrZFWa-8KizgrpBYLBllHvinY=dMhd-&jGAsYgbV z!(~f8la-Qj%T$naI6iBHq%t&9mNr=&x($4$JD5mAKnoiz`3UsK_ZO5zaZ^Tvp`;@X zBgq?AY}1e-^8z^PirAOA(`*&O&2!x~alL~pAWsgXV#9VMZzN5*Bm{L6mzkL6994ko zV+kYC|2HWJ`NtYFVbLR7I4~A+oL5CXjzA(ZY233227o|txPC(wksUTn_;#o0;skGS zi(0E}YMDwR{4VDUh*Wmpv;gA3s|gs7U~C?EDZD(KMp@BjC71(B>Mkt-$ELp$@v8b*EBA`Pe zBJ^<|hE0wsKD9o3@Eh7sD2ZuZK38?8M!*&`R2ls?D?exz&}p)Eg27OLhXp>w8*E)0 z{H=811{O7!>n=sY*0CCY(vw>pmSR!hG$o^SiR&CBWN+7ljUJVdxVp`j8}TTd7FSvi zIYsx@0}c^N(hI^SA_UZGf|X}Nt+3S#5{yT1pMF|jE=EAJ??Fb>@Eh_<2KPW>McFbl zg{=1GKbCI;T~MZ$MMaHNi-z&p%mliHa3HEJ<&i)zN~T^Z%8A7^4zGbUOK#S* z4hHx8&2NbQzeVE}m@CI@Q^P5gq&0@xm0FG+9~ejYW!;`610p0aP)bO!UM7k}tTqP8 zNK~AXH03+Ls;5Kt!wN%O6UIfwJir@QIbwk=QI^a9%BAUQ{8a|z-$e2N%|-x096^0l zsaX`y?}=q!*5P8?1K6U@QjYA9Z3n5UWVx&-%<05*prjN=qSzU`^v{lDilUrYVknY{ zSz~aKKZTZz=1`UI&nZU8^!)Ygq+tg=e^8V}EA~}xshfsJyHaDUcId>&wM&PQ!$wu=vI0pk#9r|X2Qy6@7*XaVf;jrV!9JqMtO2|v=IYA`|N9TzF zL4ip6_0#Qyn^nt3Y#Z+hM0NF& z+ib3PHg2}oHd^!Wy(wfyB3&VogWR`-|IN<4WoGuz*&M{@TQ_=-otpWTeZ%hT$jd^! z3iT}UK3&lp5Dd-;-`y5;c?2VNyEQOi0wuKCg%0Bk-Wa-q;FwNnwWQG|&@fiw4A?Ap zh#nT_!yBMsB<6X!Ej~6Bl4uYHX&89|v~(iML#x;zh8(juYR#5b1u)?RicQTJ9;RSb zH1S`f*!hxJj@7|>V2)z- zWw62D+uHCC!Z%oVAhEOo?h-Jm6kS0hM9LU}lP0=GAF!CEKS{ynC1F5;Avmc5wi`Kj z2uvz^$}w@$onX>v9BKipBM9+4n0BapRJPoqHA5(ltYrBIqd>52W)4nEtLlBlY#r$PNPu_6ZbvS8kIKcs@Q1M z_ev6eg+r-!M`Kz+V8}tRcsv>NGDAnBVj(+xH1hcV15hiRaj2OAm=?iDBjen(9E_K=@@5xxK+DI;VyoFZi5&Uj$16Q0)iOZQ*pN$MLUIS z+Bl-Pa3ZT#Fm(f=7{~UT2X8XhD2m$VbAW4^^*L-E6clg_}5h_a4>*UXw85u-0XrGX?`(Wa}}GM zMp{fwO~OhZid(cL_K?BZyv3%_8IusX;WC#sE*)H|4MSKbdfz^^3kzgrJG%Jg)`?Lp zy%8^H1`cm^O)@GOEz&(jjE0n;jKW8l(lO;0X&RR3k6^VVK}U@gX$-|`jYP35h?O-` zk*${%hFdEWQsUFdgT1Bc| zq+6X;o34SDO4@XzbT^7D=?biCfmLfMd5;**qm+}5gF95DTq|tRCN~WaCmubfchd+0 zJCt!&v19T@xs%D!1a>ST>~m@IdL6wU!vV*T3cTO6AAx0xTJNj;&}0)gOr;%F{AoF$ zW4>08p@Uxu*CkDXRy{BMeZ^FQ3S2rLtJ+Z>RN1OZtK+ws?wmKb(#;W5(7nc}ocK>NbB zu2jHWF$`}~S=rXYxa3_r2ymkRzoaVH)hbnedyW8R-#)Tsi+&8UIx1c{QzP)-q;1d~ zn-C9@o-u5odW9jN6K8h7oWSy_8^5vHHa5_AsiuOD?dMwb1mm|-kFei*M z$&*!%2B4Fp#7zUCT!czCi%m14f;dG+RF#{`kH*Bz%e)#fIpCC%Fg3+I=2<>)v}n4z zrTtRT+bW>;>Fmt2=05tNZYd>i5KA!X2xf(C8<8wCB5KSzDtyk zZRZkCDPMm1KCXbWYEBCCXnUM;M%&>sJ>Q5oobjhNvEo_vxR2w8<*Q`5mls4-u_Kn9 zFbHJky?{3an_p@udKB@zDgJ@j5(AA&K((U<0)NI-hv)cxZES2wkdy_Nr1JASEYI)8 z@Fj^g=5^Jzgc5qTG#s;Ii;f|L8KIPe{)A)zrh)iU)5AyX03i8I!a?1et7uksZDJ(` z4H>i`O<7i2GI{YvCnJK5bW^fknF<@`NwM5+=VE3<+Ono}CL|t#YB9Q6l8(@Z5Y zs+kf_!{kS3hs=OzE83b83WgwRARzfR$$0mK;=W?$QHv%)br8mQ>NLW;z!}QfJPIv< zny5)gqdvv%m7h7EEersdOcU`j8$TKKPFs_97*+?jb?ezO2=3GcF@VV&@h8!-@gDsiF^DB6&0OnujPgg4wug6gCndO58HPS9z)`n~7wwr z9d0J&qdRCc2@Q6)Thn_e_XUMZ^L&gR4p4{rGh3T?+|xFma=yL!WT|-@*6M||JD>5^ z+*@;{>Jzy)zGHFWlee1HtLx3}Td#e6>(0kN{@jI?EA3CqKepv=-emrNM~C2soeshD z*bu0jC(^8qeJznkG}HvDA-P6yez=lP=Zp2M^jj5m7$szsiM38Fp&*c?=`O@h2t!NS zBUUwxv&2Z%uvul=8;mLj6ZGL47v^QOZgll>1IYNZH7^g-X(!^n3{)a{$tV@A!XqvgV{7G0wIoGOj@SK+wQjvvD*+Fp?QHB~bOJ>l98P+IlN70;7LKgcQh*6Y! zO~dRnw1inS(Qf+m%hZv%R5>$3i7YLQb*EmPk+x%W2}o92e|Pm`NQ)VEdn4J1P#(ux zk%S4oSRazZ^L-G+w5<3qMNN$>`3Ak5o%p3S47_p%HyL%DWWh)MiM*CW|9>Z;hGabJ zcX~vCc;it%lm1V;Q9xG6GtI|171(ANv7=`c2b^ORH#mM*zZ4p_)mbglSFPmCKyKuY zvde{h956g4W{pn@ha_`4Sy0pq6)gCrmb7Dhqv#ru)y(+1Kw;q}{+Ps!zJsT8jA6E@ z$-#bDzVc6xlys*Ej^?9DNtOqia1@D`tzukis*{Xg49tNwFX;}&j2)`u0Za3CnjApgGG<&Jt-)=BGWVUkiZneC3GG`^CI>O>1N0rn{MIZf)Gm zH5C*z*KBXyc&nipjfc`}Z>(<-)OIo7a+|uPb?4?y4{Qw}!y_;+ye^n5s*Q=uu}ayl z(x4b9ofd;ur7BTbi!zy)(u9iwPLSX@Bk>V=uSPgB`hYwc)I!vui%v(@?lMzDP_|Q6 zQjDPgzl%u1PM>?SS5gTTNXJI~XE6?mUw_d#I?M&VnCTt6d7>iSC7`rLO zv;>i#lDH>RYeM8=ZvMar-t~d^zG0>3&(jArrK5@uMu$U`zUJ+`=gs^vSt=UIuV4K7 zUxRMhSqj)u{G$KAdmlwGA~0HG*MktjCY;kXuiFXm0|)#uI?$L5p?S%YX?oH~MAlzsQju~XY377DdV1hQ>)%nVWk(t343)GQ zC_FSgo-3NSf?!4@(@J7RrhF$>1Oo)qs4>=HXuK2^Yx;#YXQ0+<2`dCO0tB zuP^{l`gJNq6qO`bEJ;}?-!)(GmF7kY7ET+XQJ2}@z`VY6DS1!_qf#IJ|8INB6A6x8 z6es?6gbRpJ=DplI!6pkw&T{ zBMucK;*c-s#N`|o)k#5T*Hg3+LX$$y#!f;`MBu%&(%FcLyt#2?-D2+Y@|9dT3WT!m zfe#g9P3?QvrmUys#8?-#{EX-e_D$;~{l5$x!opo=!DQ|< zx$`D@sVpAZe&p`M>|mkJ|3@6m)%maQTbno5x4K%gZJ&9lv+z(Szp%Z4E&JRGiMho;d$S_-YZb^28;PNt9o}6 zNymE;b2xG7w)5Cxr4T;&MrWMMmoA8iPzLRYi|T#@|uLS0e%pZ>p1_uez#TO{Vk)dP53ya>EsLrTIJ%YtclQ9)Oj1f`iXMv@p$2z)?3X0pZ3 zp7E8B7B>=&`Iq>3HKC(c)635LUViysu^KR+NvkN#Sh3(XTLl*#I_3Cw{yx*D7~eX< z3r^pI28?jBMO*4YGZ1Yox|pV^BoD=dCiNOQ30@=g|IaEOU(b=)x`oBZuyqTo5hL=+ zbVodOA#R>}jySvX9NCrENWsPV2)~huyhqBO9Tat#dXHd@=2_@W#e0PQ|JhUXAi*Tg z8at*QB)G*O`vpd$hv7jong?xS4-(_5qIE6Jg*B})A+$Vb)(RGDL|=sLS8ZbwXxvSV zt4Rg>i#GD*emb0>RF-uD0=BXG@U5L?xGnoZ8AD*~p|@b)w{XU;KZ}4JH@hbZZjwoN z)bPHD#fFlJnjv?%Qz{ebvr*8?5YpbFr`cq5#LD^t^$*D5M6N3OXuwE1oY4RO4mxxy zmkU%9dI4)Vq8w}Anv3X{j7WSNUoT#c?{rd#*z|L0>U46{olb0mvHtV**S{pChWK)L|nX+q8f#odXZ~}Zd)Zv8w|2gXJ>h`JAiEQTV zI8PC3gqQL*bvi+F#YBlFOYr*?oKC_yMomtVgp!rFh3pOlQro$E3JxdMzXzvF+BZ{g z>TtsN8Fe_3y4x1|ec^N>&m`YDMrIJG0*psogwSkPPA8bawx;EHg0;o5Av8lG9DolN z15hq>Rk7HqTuvTe%!eS~E-z@`+1vy!yxwVUxl?>tKmz7x%Nd#YVqO7z&aGT}2G*`~ z%g+I*ZSQc$nOdV1q&dG;el+RR6P)z3;B$+q=oYv09ZY_hoSJl6yq=2fj$3S2oo<+q```kg;KrZj&Rep4?j33xWPu^1N}4xIm*-j z|Na=BTm9zUh!W}qGGnse!#l+OTdW)Q0M9kr^JVdV9gbJ^N%N>a86)U%^r+tN0g(Rx z`4^VYUdj3DhTVAr4|I|_HiO`<2EY@@7E%e!*bxXvvgN+wfIidLK%6{|mp#>*bcXv< zm(#B~Xrk3o_nw;MHGIrD+avre2*hX2Kye<|G(H*7K+^yrbv&g)+B?%yuQcMktvt= ziIuvdwjJvp*2!_T&%8m|(q?(7ip&RpZigP+B3Zz1DR25OI#HG}5b*Ec)xQ4}8u}z!n z;!YqI3E!`Z7%?`U7!?=eKO9b_vn&2X+Q2@t=!iI{Qfu@FTY{x}l+PS5EzV){*(umk z7!V6`9Mf}Q-!$FOHjUuu&fKR1k}_>7p#7AQC6yFy7WDrw8AA7wWzjm+Z>}nz0_U~7wMqV7YAsUz4gWT7iB7R<&+vr8qJr5JQ#)j5b`ENuV?mU||K z9d}@)|9|ON6k{G&%fWHEFssPVY&w)-46Ol!>M@`U+XZ2mle>Inc`Afq1+S`Mhk1JG z%GsxK`3boNEq~3j6~!Z5K+`0#fx~78E+Er>lC-!1hg{kq;A4htlK%g{Kc$KZspj^F zaPnw0iZ$^`i642_go){th8w61kqCsmYue1imub@J%nt4J|1TRhyho|N2Lk+)uwbTB z+TQ8y(kX3PGS2u`E<^Z}kI-}$v0U^-qJF-^T>hc<#^$=a`A|Mio=E@yKi+u$%2T zw6gZHf$vIR3&~X_x9_ok$^Iw8x0?2`li$a>Wpwtwem)T;s&1HUiFsRX8{MzG@`>dp z9)1PI6ahfR5%OX~U`suYUrf!01?LwEKA!;|GIygsuOEc^eC6EoO74j_<;0vjjZUqe zwf$J5K`bMt!{R&)$vaGkuq%7hp+6km)&1G?7cVcbT){v1$|c-`=Wlc%WFC{fnev3B z+Q;&ypgE1K^6R)CLM3MSe>0h1pW%P{If*6kGq-!6{J>1_%Wv!v#vMdRYXGh(64IuQ zrw8hIitPUd{C$PTP%dx~ybr5_G)`jsB>P0#00=f5!t{J1%d&>@LdzVKPh{%RV+fgs z#P*9Q28Loe^#6YtNGCfg{Pyh8^Zwm@+#Leu97&rpO59VPzQY2VIV;!;Q(@k4Tq z1U|OMCXFLKN=DkF@6YC)_1lx%YAF6sX6EjU{vYV)Yi{?JPR;z_i|Mk|*mKu9c8W3j zH)H>4^*wev_Ihe$g0_J_$`yrqCv00h*jn6nGM&+j#YP3*>a4MbcZzhv8Zu8vz-8zo zVup#)0_RF&n0w;5(2)KA0e@c|PAEk0YcSNc%qX2sg`>Kb)r{AMy7j8`3Rxncy49}K zDnknSWU@-#FWQs1XfUBm@<;@p;ddn<=+S^LFY`-SHE`cc(Z+-z=NUvt-M_{Efu2&v1~j)8cC$@vp}m#c(` z^L}F58xd!;(n2zS0$JRV^7Y}Q8^=DoFdtRg4&*{iVTqc7J+VegEfU8LGCU2oh;*n{ zz#SV9#0}90_B76G#4l&BRoJe=|6g*br5dIUI7%wyfF`JNbav~=Q`JroB+#i6>y+)P z38-P>&PRO)a4)68i!Bnu+mqBcI`*B zbz3@!D{<4boH|a%EEL^VqtI#B3vSKT8JvupWjPreA8CAyjgv7l)Ia*+&EDBlGaonz zl%2=@pI=q!J#lL0`!=RjFuZx(H#-IO{WupI`;6Boke?T zpc87t7zstNJ~>XL;`4~-L`XLu$1PNejHqx8gJk{bS9Kk%UUJYd))v(^`>#iO+#sSBP10JQ#+>o#$(=NT+N`Lie@3EB*if8qV@_|4iBCYK_3D z_2M)QIu1fTcbq_v$Y>Y?+xKzGW_p!kaNm`Lhwy4BC=3SenJP?R#TAuC=>OkHAxZK) zA`(d|jns<9Mx`!070*hADvHtQ?GkrAPNT)4>D`CY9RZP^IPsSL|4rCR8rd`};S_wt znx91k)+)v;!xsRlh`SF4)Vo_}rbbDM5s_-7`r_OT6>sVP-+c69-5p!Mu0xOmQxSK7 z_Btx!rs8c(QECBA-+o+x|Ix4^Pet4c3%Yi-d;q2;qeNUo_%z&SaV*8+{#wl9K{sa%5C{973fLKKBNw%gi+J(rSukks zf<1G0t~&cn>3)R81SW(B&xBs|qZw=Ezl%3*IpPZUczyI|^>yR?GmM0%G{&kpq3X;Q z>vp{@?OlS5f5?ki9{ysjN^h$=6bGnV8TO@UU8!Os zxkmo~zvVqvEjQ#%irEO#6zNB80(1*UDwUE#2b3fHue^&xTnhN4cyt5r0b0$fZ&O*U z6k27qp>C&6NRw`%Tc>3a7Z8pp!kf4l*l~=1uFGGihOwPnaGRBaTkmACxFZ@07Bw#B zcy5t>nq!9xJDp0Q(`sRjS15Gq7;siOPOOwpiQ|}fw!8dsvW?|lyTKpGWT9QD71|}Y z&?ccaMw#Tx*t?Nqc2^n4y5tu7&w8=eCC7zwsoX8|Bwn~JQ<_o-Po5Gl$zzIcsmvdR ztnN^9I9w=Ivuxx$CF`3arAR5U=Z3N=XNs8XVQaw!6u2$nzNVK$NCooSHqKkIhi1!7YK_8H4JK~v@Vlcr9h9tT3mTX8K%y>I>RGeHEj$f-j}j%J zIO*X(&QoSGj$*IPzQY^y&`Oo5g$mT*=$l;f#KU-Cg=i_%fp<^MW+zJ~$#OJ5WL00UkTH|+Q^=A;G~+JxYkm^7(Yf%G@ZTa!o;qOjZjeBu zO#lBDQ@uOYZt_hqYK|l`ZW8e~Y5OT;QFM=)M5IFMba%fF8){+dY*}?!>ekkq2DC_P zQDbqM{WsBdlJ}6)Y}i_yMsSn*Tcle@9~8-3)2W*~h*Lyk!A&=E3$JQ=Ud8mhME;si zEqY`BeYCCM#%OUioN91mB9F-j`uWV#9O@3rUBC0hUo9Lv5_zmUwwIa?XYa}SVLM_s zMe|p4!d{xpUoc3isWLivJ+7%~hrD@(7%Pj|u$RbRlZnsVm$juo^2TT$8=zqR0~2}7 z%BC_LX#GBAx>SuxOt;yQA=W$)AIz{F&7sCDX1g(NiRKN{^x%#lZ(eH;pW;_7HOrJ2 z+z@mR^$r@O%~iQlr~iLzd^D}$E7AWlE`xp{yp0kK$I>b@s(;6jobjYc&Rnn^ZYUuJ zsB^@sXTU5;+lm$+r6*xvf&|R{CdX2BX!!47!S5#!WZ8}!%+p+>**Q8-$MWwWDpU|4 zC}O=pFy$w5sYb{{23!>_J%kN2k~+0!i(xQGOf#h46N)wFS&}N-7B)gS$qtrIB%F{t zE5KQM%^Cs>veob;v!ewbFUiQOFl(EBXOcu{)a+zMD5lnNWGI_t_}Y>ran+0pm1MeQ zNXFX4$YYPwY**_=+F+4ZQKxCKb!v!)$Yn-GL%tyih9BaSiNjPO91!)Q(wm+P1q!FF z1)ftXn_rYU9|ze|=adtI<#2K2pUyC+=uJ= zZo)Rfb1R~XIcC>fB4Bl`)K0LrLW2|PG3DT&Zmf&JMHkAd%=#Xa6N-#a*^AI%AEaXl zS6S~hjD(BGDv6f<|4(=u9$?CdTvp_(L~?Bz#E_u%m8n#lJO<-TI<1a!wIt{=uZcKc zHP3Mro{uLHvxo9Gm+5tA6C~Op*`k-E!ub(9iozhmk1~}dMO)ND9Ytqm6SOrYk1gbB z5;4_4f6}MP%h%0O9#7sJ6q{aB)^N96BT9t|(Yzi>;gn^{%`_9+NIDLKHW$VH(-4ky4RicOMlzBpAt5d338K~%{=r-BP8kDX% zpN(9mR)yP{+KLLd)K)d~K5B7e>}AKjaOdmP7=q>>w0^ys@)F%9dqRV<3QLvNrKF*LBFSrbs7-3XiA0{F`5Uq?O2g3!_4h{v{zzrn`lZiggU;Dt3@CME zorK>#Ta^R#W*S8&UMieX*Q!;^tdmr(rpy?#IPCpMbY2NF(X-k|ya_upVS`Kb|8EPg z(o5RQ!j7$%=ugJ)_mA`kIolo^|=spQKxhQY6A#SB&&Sc7RY>7wjnFKfJQc-hj1<+Uq^4J!t_W0M60On2j0TOHbj9?d?q$!M$$9|>3QlgJxzJv? zy?*1?Eq7~v%UQ@@%P-{fXWDl*Hwlk(ee1?eNF$mzZ!I{5)7f~SgQg#iZgXqXb%|n< zd-Ls$_1F&wS84BACQf1hlNNIMd~V^4Gj{q;^kI?oq1EI~nz1M3l{$ZC&gAuof-~ML zIHTWTV2Mrs9(u^Rpx7dBVoPe+Q@nQ>w>lD5-Hcl@7rY<)P>)UqcE6#0#G=TxLe6X z;%T6Ra5u;GU=_hEft>;`76A@WL>&*@4KoD`R_zLRqmu==8y#Ck;8`$)n48-Nh=l;6 zEwO?Du*SvQimr#H4#C{$|KDZinxlZb4X}@i4LtjVy8+@waJT3ar-i#QZ9*It;%?|} z4g+^PFf6TkzhP+=V;yFICae2BE;t(f|DQ%R!&qXaSXzpuS^c`%f`>{O9l<+%HFvS# zHe#?_TX=1F*6cI0CyoeMO&&^Kv|B9AJm2;}i@S`*(qy_h9W1Q?mgd1eJXkNN=LSeh-@39+<# z)AqN1luH08{U*fHoNl+fC-lmqR>PjxpR_&V_g#}48i_eNK9*){GIp~NG@Fd}Y_0}A zC4OOei^|3PMUv6kaG>db-Y_gpgu%n1G%~6WdXiRs1gy5NkXp@i6vKFc_eLoYLTqPh zucDUeDw1VUSNo<0P1iH2_#116C4H1^>US4-WD#?{#4v%i5Y?-s9UTEm@s1e3JId_a z`TJfBKw^B>LB8a|H~oBtxfqhKqku>H6uSF@M+)am@kkb$(U4k$(dVP)4|o`OBpO!1 z1yP9F^8nntKOp`8`xx+JK7rH3BoVI<$1ku{+@)V&5}IWAyx&{`_Y<0gOm=rJfkzOU zJOM6&^#AW4;1+mP;K>7oCOdc@_qij5aJ)sV?h|OT&%JM;cVA!(0Q9#rG+DxRBmw&! z1((1&ZWSj1nhdy!El(pjX14-lW^-f%Ev z=qwKgTd$&b~YP z3m#XDbBC5ayqQkivZ;~*zJfkxr~Y-o_~tIVbkrgw>Rp}s3ijiOIx-PhxjTGw;6wI~ zZ_@vN&}2X2E@+ymhjFrRL!vS|5Fk~=a6&%4OBjug3J4mHu!_sDP|e2J_o@Uz)wU%^!|cA%a?fZKuTGSSvr8edGBnPvusY&t6@*eE!+xTzh`|bZ+T# zZvNRNLz)TNdiCP@OBZuX7cS)d=RD%rC$&AM$nD4Etd+=E^R$2crl>1#w$?UU3PD!z z@Y{AQmoJgSFoVM(Uh7wQad~Ma_bT~HIyrZ}*;;d7)fZ8AK6rklToQQ{nC!n)Sa?^T zIk$wj9Juo3KLRXf3n@>^dyf?S;DwFZoZ;URpV~ypnt3O*wPa?&{_97oW^^w{BP7y3ua7=JU%AetI}q z=1DnGQjb5LC@O~P)4An~=W>4W1P-q%oli8SvvhIk!ka#AId`*pV?D@*_xKV`(f59B zs#$I?NZ3lCaKPjI&>!Q8p!%V$k^ z++wbN$#c^!MovuUWxd*@cHHMTZ*1MY-hRPtznF|$Ke|%~&aFXPvV5(6*>2~%#hTk_ zce<5&9oj&r+G!KQTORM74pmqyHS2AWqd3imiz$1f>~v9I*J@6=1(i%0%k@^hQftyE zg6wwO?dvzzyBp+e+u6BEZQcHY{{A?)vz=SH^o-Zq&c8ml{M`A=S1!|r`-(f+3)Qsz zRyC;8J+b`c`HPbktm_XHj@OxQbm&~UdEb+})7)~Qd1=t2hGlxJ@#R_5W0%j_5w=l) z0k~e%rcTLDWjsEEeM2xH<5hnC$%~g(G*Vo-r11gA=y2RySiiHjW}8ww8;(leun6Vb zL)!~>Jekj5duZVgSMv+o57+9x8BREin|7IKlVQ!g>dsbft=Zbx%(+{+&c@otrWv!n z$DE_u&tE)yCHJtOz=%R-KndoKK{qo0|8Ovw$9DF^N+Y#22zYFP!O*bE>3TmspHoW% z&xtv;G^h<^9;W~QNYDgP{zB8XkJbjMr9qT|IJGqJm`r67VEyWnj5@?rY_k5b4Z=$iMLfH<`@NVfUZ(!e;RMmT|EUht`e^m7Xpkth4e2yjm5|a z;5Jd*$>u&Lq#reB8MB{xD02$%pA>*!U3|o6?q5W3Xkvh-uIYpxOt)e>{8R`lW~`uLfTqQ$Kv?)zx92I8_DzSHqQPch-$V8RMi4ZbM| zFx(sHeLgx;trUZ%HtS-0wcG+}wAv}axE6dqwz%+7!-Nani1+#MaJC1^yFJk5+=EX7 z$J1zp*m^~_0XUPFicYmMQ5afWL=!3ZMbVu+94Lv3|2vcUjT!!@pOaYv-}TPkQ>SKr z``rgZi_IjG{7lC2y#rNtN=ZGv5V^?yKgHkAXKTeuw`6?t5-j1C@B_9czfN(DFBfV~ ztysd}0MbXN6eA0F2GBLfNWO!hvZ+7j5rEfD0_!t84XqY|0Sbjqy$nUoP}XOB4I71a zwpK5+E44zqocC0B^X+q3R72wQoL0ClO{lvJe~n{}+s|H$W0nqUS*OZ5^!a*1{vv zBkYGBQHc{l68-%#=6=a_sq3Z15wW?hHEOIrp_#4%YWZlCA4#`bb%6>?geNS)?pkUC zu=FEfAr>~~-U)KOByg-+VdBMycV|QLER}b)4s24XrbN#)C|D0|SKgx+r&1Zi{W2IQ zc6eMk(DYxp_dvF^8js}pxWQ~^kf-aVN*zh4-f)V0rbUinY&px&d$YOKe!(MjUC7^R zZ{Ka*7K!oeSLDOx^Ph(7ovtW?qmEa>HGz*E6v4V^0w1s7R=MXvmF#_mu;3ta&!}JJ z5T0BU|99rvOy=>Km-(9J=lh=Nz2Vf%A3bzXxD%qxuYKR^d!NEHUwHt}oAR)xJgn6QE%@gipvRw|{Zh7>KbZTox&JZuM|1yW z?ziXuubca-xi6pllDW^H`@3_W zIrpx)yK`G}8*^`-bLT!|?%Le5bDuhQVeZMfC*~IC>T{*J*UX)s`-HiVoBNw{A3pb? zbFY|ta4s|Z=d+Cnr ze*NrM&;EniFP;5@+0UK*tl4+ZzBGGh_SWo+v)$R|?5EGZadu_)>Di}d&(1zR+n6oS ze$wpe*;mhg%{H}m6}AIyAj<~uXr zlKIBW*Ji#V^QD>3&wNg%mw9{UPG%!>Bh${TX5N_j)XW<)%bC|@8kth&OeUZCcoocM z?@5a4YkTL|er0co?U(mHnQgE4I<|LukFj0vy_W3@Jr!!RS7&>nS7W=_tFW#19JcwM z!YzGd?=@^+*;`=yLA^)VW_l0L%*_6`-f6bK*~_#2<=!W<{e|8`Y+vqu0^6VKy_)S$ z_Fl#I2YX~|_6K@7w*R#EacsY{_c3h0t@qJvzoGY0Y`>=W5p2J__u*_mzxUVJeqQgD zY~S7cP_}RH{S~%bJx2f8_1-JkzSzsMeZKd>Y(Jy-L2TdHdywtr-YK?E_U71raxcU7 z@prRXd>5OC-^u3VUt;qS+iYI(HZ~8wmCf88HnW>-X5K>iec%?GKigpQKiAp(=}k88 zUt{y%-^}KZZm{{o=h^(%E}K7a+5G1Yo8N1*`P~+q-)XY>PuJP}I)T13zs5Y3`K3=| z^Rv&fdC#+K{?S!7-wd67=IcI{%~w9d=F2Xz`NE5AKKE%hpLv1JJKw-&^HbQo_!JwL zn$28)J)7s2*<7NEGfzIjW|?ZvEKf>xGi)=oLiq4#Vl+CND?99hd*O^yP)tOV& z@ys8W+59f`Jo6tviOs*EmS_GYl|1t@bv*NPRPoHuP{T7nHP7b9so$9&rFv)nIkh|U zJyht-cYQ3I_fU~D-%btAeA`E|`KG_Y<{wg(Ghaqc&U^_KIrBw-mCfIwGG|nmGn*g6 zrcHg$Jg3S0;$LQSfhwK(6zX#3DXMbjNosPY@c^5Lsm+;>rZQ(fe3s3JWpwbJ8D-?b zZydA#f92el&3)nA=hFM%Irp}?x6Hjr-@iWhrn$>=Pt)_4<{q7^%zYC5{?&6IGxrg5 zucX&MF#CboKb`#(`uuOt{`%~%&i*nz{=Kt5KKp~S-%Ef0mf3Hd{o2{Dptpbi?B~q( zX5UU<-9W=`R>fOXZ~^K8!}&=`SQ#cXZ~L1vor6`+|At1+{`?m zX=bivu4XP}&S%bM7BjVslX=9vJ|!^X^WazBqlzB<;(Ix^pL35s_uxD4QC|<U zc;g;D@4;v9QEv}kxJSi3_{2SG?!o#!s_wzp-23Zn=kHO24}R3W4`ch`_o%}Mv-haP z2T$Fj?jHDyd(_(l|MMPo_Q3DoqtYJut$Wnf1OMtCmG!{O_cCmM{vJ7e;OBaDzz2S; zM-P192YYX4`+Yt7-~->$yUX^Qd)sWkzDGBF;46D~*nU}Wi|v>6ZnMqz=#-~^xkraQ z^}ZfG^3+fC*4h3*Z;kDD_UMnN{z>lzw%^#JN1pnsp3C;jdi2CopWmY^p8D)wlkK~D zpTTycN0&VHe2+eP>U!_f**?>|#`dY+o7g_udyZ|sNAEn9>s@C1kv;n7slVEzgPzLv z=%I7}vqu-5`_DbP=iD#$=$dms+k1-bcc&xnfsMFx|EgcEwv|5%3ek@~TlS z*Xqd=FeVr?C?bWIE8S`;T2>pWNtv;dbBd^Iu#)S>t>kDVC3KnaOrUmiv(QbHiH#gP zSSuGwWh`+p!~uR3A+m)Zt*>ISHt3GsFg7sQ{_6?=U>oIOty(G-s!p-y|H_t}YBBs- zDppJUYLx0|x6s2ndMnb*hv; z#oHO?ZJ5RPt-;6>pvUaTjI=m20Iu%43K%9VQn~8j1A?~q^!gwUMg3J7N@Y9g<``v&&P)EY6?qk1NBsL`fWo8PqQ{=N4b>s3bI24K|g`O zKF{Ns7&uSI>N}N-cUGn_J$*CRu(tS8E%7;Fjg64z!E=}GWriN@!W$+ z8U6p?HW&x{?X607MQT_v%vqUAg+^IbR2SV^A!Tpqv$(RRKNGiXX$2_FPL)vOn80;S zyT`&UW%O^AWte6D?O>agGWw5GN~RZM=qB??VP5Lg`WG+UX_}QeIA#{QZPqcZdiE%@ zH$*L_2>v`c47X<_mNzv1`H0O~0sqMo^bWOhz}BFPUb-8-Xt?3n=GLa`<}NNTt>j+y z=GzfFY?%DGzSFSEy@Pd|a6?0cF zpTGEI4*R#tTQ`WWKA+!m^23PhM{%Af?cp$l+Y`C`SQS6kMPBO|hd+H`8WGZm##i4t z^tU?y%-p~87eW4a3jLwWPN6>#fm$78(*fCGNUK&rsGJ%Y4^m2lC8Ien^helLt%N*S z<5&v)m5vGYXJ9}2|G!V6zharSJj@Ypx6lEVi!w@-ibEMC3hhZ4B~s|GXceHLcRj;w z8r_=+3QiY00jY~iM&ArFTyDtcnDT;x8GSKOFA8EozhHGG=B94hMK>B%Sr3fvJva$J z1;Kvw|NjtCu{tgbPd_I$DOiW+#81XoU1!M`uY&U2PrwF;kiCqd7b(NcjDQTp?Za*M zJNYI~C%cOz;&0LRQ^;bFFlLPLP%(_nMoS6Ai4Z)Z=&=1JGG2F@{Wm4sJok{(Yyi2` z969mYCnb=A=z}78J4R&fDfAcA^U;I;46Z`||8)aRrqR7q=nteg0;(l3wQO-9-<5~c zMdqSn4OJ3j+EFKKx9i>e7Wy-=AN~J7%62b>{;9a}D|9^v;v?L2Y)xyNkU$NUwBvGk0Q3+w=j15f# zvhn~r)Jy7z(5^NYz&c>iuHb^;d}}%`tGFwUb$FoRGUbWVz@v0zI)T~+oS*g zr<3iwH-Zv=G63&>p@f$UU`hw?Lo%Rlb;St94;TCmN11Y!uTH{MY)1gEv|j*T9QK+R zyrcjBb_(EmZa*o2=Qo9N<8bKUfsYd)Xy{<9yk#v{JvejIF&Kk!rE4TSp_N1z=jv{` zO+bq{PTn+uZgIiO4)ES1 zx6Xgb#<&l@dq<8EKBa?)+@fVvly!xEz>xwwzz0 zbH**pTDJIGgDF|9THR28bZUhxMwB-0tZuU^(Ri#`9oJ3hLs^>@YZzFXN7!gwa=_WU z-yZ${cOhN2Zz6X{FrBRTDu$^7PfWv1VV-Pt>~Ys0a>vlijqjdBZ+%h#&xfRa;A|usw?6=$X^fgc{X9$t-WmL_j_tdgfbECiUoFka z$CMI&VC3ceHN4DL`8#taKWW_MH=e)pRBmPY?A4Xa=bv59wdc1_=aw$#=AT`>9EZM3aLCU$7uu(D z{>=;Pch=Ut`?Gy%BQKrVUbwY+V|}YTpTG9dLWlR-ez;aABZiV5=RGea%U{2JdLh?r z-6q=$xvk9`H?@PSq1{>Yc04~oC%AWNj*H6|md{?vO*^?}tDRq5oX;;kaW?;scbr|i zysVPGm~$R+7K^zn+Rf*4XD?m2AUDKyd<}2A+2spd#$m1sPPJ~VH#hI*aF#p0qif@y zS^LMQ>mSGYbQ*r8q70tR)Mw_NW|Mx#E`c9-OYiAZGw**sW&W?Bv%~tUUM$HqFhT?w zbqW+UYTQk*CPvFrb|;3*(66v2Cd#^5GHU?}VdatX(L|8`FW>(my$h#i{`l3$q*0LN z-{kN2hY;3MH!#~4k!$hsq_pL})deDLqwAHIR%UF1pcsjwCvbas44N%LcTaMDt98 zl^<1BS^EDUR?4;L#KgQLHUe5aZg43&Jr+B^M5w5NMW9S&xpSW~%T5EGPLXNGZ_w}p z<_L9MQ)x}o)f;_1-ccO~`H>6iC527qEa1JOB3HGqHMeeH%c{E{;Ip<3^#4DK*f$uq zPnkEQ==5<$r-je?*i^6|dVK|l5*JP1z0~9*Y4D$>w;4)6_(Z^AmW?z)UKXze1aQY1Ei!v6B zeF$}PA!o4Lc{pbmI;Sm$JMSzM7fPo+6t}tN-g+UQHR$d<#}~@}nU=fdA1~!V_jCEy zjoimSlWP|8`SsP-Yv1BN_o-*zR?0o{_@_Mf++%mny|kRW`DA{f>fitTjhpUT-b01Y zbn*g$vtCs92p{g$A@P;vXD%$A4Z#1B5B#?l3KoVR78yPtMtzU^hiyRyPCb!ChkazQ0M zY>&2_T*zqLS2R!}pU(OA8w*8{|4FEQecOwN@(a1;=gwcgf-y*EnxnRsh%$dk< z?|p&_a8CQ?8V@hzyxe=22XEly&MjX)8(wJN(Yxy6(v_<#a4dfc^w2qb?DV*Aq#&&S zP5iD^A$&2;TWOj5alR9PPVu708=Y#F3azrS(CX9+-DbDYt;4QP)BxC23NS+!x3NuqElrz8S@aCQ>$HcDc*`Sjd{55$Q1qm zzlR=;p|1Ssqf-&WIrvjeT(xodQ+?LbH0Gi2oZ{&%h4yt);?rorG2-=A4e~P}USHfr zI@J9hj^8AD`lPE`1kDBVG>`c5|7 zI6xZsPEONrl1F$gui$xfS}tKRLI*V)%@sadVWXqtx~Oi^0goH95Y#h)`5d>Hhx>(0 zRr&%lpJd`w`v3dU->e2YmSUl0bTsW|M|*%*Y**p%ZX%pnM*+5g59IoxLPT7@p%r<`a0i8 zY`Wl(poBq}8YQupgi&NCk_(l_i4#V*EDf_or^;0qoA8FHMGbGL^|ubU3_{sz6)Zze z%?(Daek4P#+G)%~{Lr0R3EpQg9f8IkQRwdX_5q!u(WJiif%EE#@Kp|4(D^ zjm3d>c&6#hLv!SxJv4O6AB+a(FdS(5Pv6hz)F=-#X5Q@Qq?%}sZG z>w2fTMM%OYmY+Niq2$$P&dKABi!Lu;$+ael;TNJC-t(+0XU@7Y-fV8QU%0W}-5@IC zLjG2J`)=!Y{`7F9!F~8)-0i$Lgy%1wTYfILUCdp&D0j;?`u_ki@SftS-pROq&G}|= zQ6NIDSz0XO@p7XBzJ-_8|Ij=E=zG%OO#|llpba^3H ziS>-cORp^3k!36HIK4QgYp$t=N3+i^oxOVX>EI1w?PJT`youws|5in>FYEB)V%|D7 z)A7C0w~%~+zOJ2k0ptHW^EYQ^K3ALQ=Z9B&mrl)m;B^P!%!m;3XFqhgck$HBUp#UE zkCRl{_eq1ECIR4V(cr>0#czuv!)@F)arKqS7%@SIxR1(vRNlH=S7nt^D{-l8f_J)Q zhikIc{qst#-Ctg*bh|&{@6Tg>!E&3iBp^rSaF zWCSOUV$HBBj*7Eq!t5c&r?xP@g@XOwcUzeI(GG_G|G$VS?1Rsa0iW-CPwmte28Xgl zqd11PFqp3b<}+@LXA5&b+QHEOKQMu(c4`Y#9zp?bt#`6;B4L>0bihk}Yn;G*$7_s3 z5{R&~%W1O$t~0>@I%-?*51wS+NQ@NvWE+!tjZSv<1TLM!8LR zj!LnVv?q24Cm9xWVDv(|_ol40&2ohe*Xml zCNeVdR^qcgyNw3{kb!UXtoAY8NP_@V3gfnMjdJ%5 zhqxU(c;z$*us0g?TchYm!j#2Y=OhlA%O*Z%?O^Etv+C4+Pco55)QO7_fs0(E+ihtt zd#%ED6*;VoIj{x?)>mf#1aXLuvJLPM)^SV(@Bw`l*zA%4wXZBaaY1%5+i;0rTzYyr z=ejw_zg-vG881yAvJpdaT zuK)t4*rC=lcW%krNajVY+}mCtoGtb()=FpbjPEL3t<+06?tnSgYmFkytvInanphu1 z_br+7?TC3rV7fHacxF`d7^hvxIam!NQSE`LMb20NuY30&0*zCxzDM%?Ozrc1UI2AK02yLl^_=omXVHf$$Cfj8M2%&l*=VcatpsK`ct-!&yrcJiOD@1kh=#r8Fu!-79?d9sENh9 z$QmlkWF+o-pA5TLE%B>Ssv|jJG~nsr2f7Mv zj1(_7SNeO|HLVCDiTjN2I;vYw83jBf!zE&)kPIA=vv?va=z|ObO@Q!WeCjEqKqreG zYXisFqmH7|{~x4Aqc96oQXk)SiljnIBad^BAHak1Y?$O^9q-6@oua5IidrgT=arC7 zJjgRL53v@K{h@_C8&Sy9M?ACmah8f5f(Y>K3cZdt;yT%g5SXieR1 zfModx?q@XSePa|jdMIl3K1NZEsrb=AQR)951VbFl^$GZ{j|`IPgB~~}7$73H4IO>e zor6mw`%^_yQxr926rgR5i}sr9h8so{3QZJ3b;HQ*RME*1Sy3Zq1Am0DIqw}srT>4h z=@AJ4&>BZ14i36-=VKPLw3*&xf+?dwq1z@XOAF6}DqAV=kXDMK@=)|mnGe9^4#$3_ zgh@Z8zN&o6uCjE`%Lg2_Bp`8a4|4-QGhcdlqPR;!JUpi<;fz*Q<8ARrxV3cv^At-*1=)dn_26Sir&u~Gs*zawam3N-|Noode;|J+^nVUrq@dO} zK3C&V>w|eR-eWfao*2O}Qg(jImZHI5D8XDHFJ(Q`p(ZG06(~2lUD4H>DiMV|396LJ2(o-ybx>$Op zwo5GiIO6E^{||x3AB#{EXV|V?9jLPfgUjs)E6pJ-H89ktcdhYa1%9?3@t zOFxb{I{p7c4KxlKABPVvvvzUrGMy@e7I10?#T<6p2&qH|Dy~rJj)AVet{e07;N^t zLm8*zt9(oW_LJ*)9Afi<%XJFOi=Dwb9q-_@UTai_ayZ}vJkU!#bRC|O%d*A)^D{I2 zAMyF&O7Bxo&HS&86icr;U8h@c>cx@_?(pn2st$vcdT!KM!-*Ncu}}=+KJAu^#YR;z@M;jZIY4;? zcy@eOb7cQl@b_VfW(-!3qi0qdwPE{{$nxVL|K?T$*w@3{XN^}eG?>H4)JNq$?j|qZ zfmn8x$Am=!e)8kE$!GC-4E^LQWBJKbknM&EgWy&RUAL=WxYDy-#l)dm$A{kjWA(yi zgutw`VnXFtY!wvO-f9a(V@YM%ErW@8>2#!IJr?w%Uee{!@Rz!vW-bf2($ngAC9y?g zYm>64{VfSZRku7x8Vvue64HK^R;0dWnEuFF)h4A(+AQy3Pxjm6CPN|k3T5(R^~uVk z7pu_El`Ao%a;eC?@mJpNW7fd{(NY7vQOgmqk&vu(l_wHy4=DiiTKAb=)n z$10M2+1MyhAWj3x1(OHK>`4=;n1vIof#^Nip*KZM8)_!BOo7E>7w?@R4P%^`i2B@^7}^eXkJ^oAmRVn6es_M5Hq6fVAYn)L()a!n>*>N}X)H zr2v+XaZ`eiqhasKs-?s!D56h_ zvj5aXK5f;6H%9VWXY7d-iRAKtZ7dqOA(qFw6X~V#A_?zF#x)s0Y(k;~LPSt;Dv%CE zVdxi%m`C&*r|A_Vrctr{H5q9AqDVB3EQZzb8>6Gb2xF||eU&0BD=(uv8)LzW8Ove9 z7As!t6A+susZip%GJR|WcS^Z0SGH4mMrDI?rCXvUR%H%SQR|jutF!OH9noA7I9@lD zm~i?SU4{f_h?Sh1W!jlEfoP5+(ILdC6z7x~l7mQx(X7wolhGm6+N0fA4RF9^@zSIJ z{|%;d)0s?yHO$Ev%_|j}X>`rG!alhntOsg&mPwTtoNY?IO1j!>jA^%@HHVWRY&VL__Sh z`EK!z`A)aVH}Xig!8dk4UFbTw7h#8Q40*bU#9cyybt`;RPhFG;T_mwW7nKJ*E=WRr zV`0!`Ebkhzjc=qVmsF5>kdXLx30zTOyNdEhvt@w+OY$mhL>h$HZ%O#k^H$iis}Ehz zv+V_1j&OjbOZ>N+_}xkTHr5VgfcuRs&jcBJB6DB-H%3v>9Py&@-)eKnrok&&dx^+z zEU01$B#OZJI!9hvNyTsQ%fKr$iaBa0)e-$N@Df1Ujo*+c0xM64Z@^H5 z+DBRR3Z0?FCgA@zWe_=UOh)*vDpCggA~3(T!tl$$zrb$>cI9Q)&3d5uEuFvFvk$e` z1TsC1ktRtK?4stXvRy6kK2$3)UFB$w#=F5v*DaLg_U-XRKYM=V%GIR{IgjwVn7exU z{KY48-L2b|w{EnXt@-?xlV8Zgu$vze4n2XG#bX|y;oBYe*=>MrEkK|VIO zHeJ^c;hKV+gxq%MOZOAz4zA1ckV3t&etWCA-gYAuIw=t71IxvQ+*XOdvd_<4e2toe zAw%9Onf=ABviS~+WaDij9=06miN+J8GnnUjhsQ2@j~xH;xoR#Ft~<&y{TSi8+s)f< z$TA#K1TW++Ub>QV7IOL52UwKc9Pn zpBB}pI$!jujaxU1m3iW>FXY&q&WG(v7d@IC6aV|(MsMZR%pbgMzwke+CYKyC_!C4U z7X5{ZM%-fRw9$x5)q>kbCjeCinga9y49cx)_8ObjN)@FBs%#6|)jDzTz;{)IS)~E_ zg@rqe^P)Whvjx0rP@;{3><}mz0qqS2vTJF{V8wFoV=2ngxP|xuM3Y4YUoCO~?9k{I zSU=!j!S5n_97FbMF&szG8b-Mo;9&q6d?~XUduz?Wb<;Rl`o{{@1ST@bOEb75t7J^p zC-l!m8QbLL0;H*eWL$}5o(S!nsHK{Y6uEy)I4Q+}{5b+AwT15AvQyrzjv-bP zOn>Mv3}{w@I$7XZsU)yWQGh6Z*0RL5s5`|(lL3IDt(2vrH{h7r-eJ>3t-# zm~1`#PN7K+k$n{2)NTq*N{W^U8%Hz7IyMRBbAq5r`u|63En$~fJ8usdo+Mvd2WiU) zokEi=JNMAWxi<<;qFd;%@D!S)jO;R4rRDAIJ2a`qdgOWGlSl1M0h*-$e+-W>4?lwN zB*It=6+F+?N66M?v!2)Qs_Xp;W_u_9@*D^=D7M+=@zp-I-)vFP;y z;+H~`5!?r0z!(IK00C)AQ4p|(rXJMgeupOM{~uS3LxR!Z^@j~lrqCqlO~ed1ipZwW zWQdAkQ4~YXXv6W}J}j3)lXl6cm5rcDga1*ET6^eN0--%@c+#xD4hx!$qjf$~L~vdY zzl+5PO~6hG%yRwC+S)FW$|P9$j>*u%5ztr^oLU5&0-QDI)YzV92Z<*}g28$vGAY71 zs=E46LR%7VJb&dW!Zn}0x^nsav&*^m{PyYG(&gOzvr8AQE?=G}vgg%{=PzB1ptF7} znKq0$tggJ53cz&_1hpunaR>GS^!jirFsOh?zpgF*_hU0N{6C(b@A=r?MQQ#=aWfTvwtmSlnMBhl?);HmK= zv;MS#d<}XlfqGjx|=GV$G|wt7I^kRpRv+G<(o7piji@VXB4qR6P|esb<3Ll8v&?7*nyCK_&NRk>rr8Y~Xz2g19_>U^ zH?D*j4YaXpZAX1*vY`_VnIwSpD%W=Lhrl$aUaZMxmB58^5P>|fAv^I(e~9M3Ac!&+ zmdT7~hAbc5aV(_!uEO*iuLNv-lec@e?S02%R{6=Z*-#6YJQa6sNS^gfiKVtv)Lb}X zF#@u;40BZB{8&ykV}xhM3v^5`CegEs)Id71ooaol;8s+V-x~ z2|cNBH&N@@sc|H9brGmw((ug2!-f9;326NXcrs<_u*NdYXq?%^jrS*k3bKp>mH`{P zDx-Ck>!Edgu#+~OBkU+qB^MqzF;AwrLx}PB3Z05#?hi>XCQ8@H2eu#LCpLgqT4U6X zUQC2X_d`4TjT!?p%EP!@3~~nx$Bw=-?DJxhyI7w`QVbm$+lxuwLETo&jY*?HVl?%J zJ!ljR!E>Yx0fT%mrg7Y#qNBnHFQzO~K*aq?u9BvODW5xgF-2P;bSi@=rPZRax1=LY z;KiiY9=j!$tC3KFoMEE%YI7BHV-mh*>a|q!b2XM1Q#@D3jVUOr3B8zTSJ6yTa&n%n z(ElGA<_ZPlY>8C^W|;I&%2Mw@8m69Qohg^Uh%1xVp~GG_rYBRj(83c)4KtYX6FD8r zlS!@{W;BhvG40liDQn^>_em!bPU5*6?#0ApYUG`Gh~{BQM!HYbi>XkIick}UXU1#* z2~50(_ERjhjAuu?+0h=S*{(9avk%8K7H&Y zyCsjVSN2REjq7w37a4MAZOFB_^T<5l^&nm*e@r=0M|l5u9iL(&WY{p|%(k3DUJWIx zW5NtP4s7{f6)?2492&a7luyhw4HY_6%@Tega1N<5%u%iuBWS>oVGiOn#>eNC)y;Yp z8huEHq3cQ=o*t!-EoHeBd5urNH(?T-fIOQ1|A|;=Q)=`ck~2PT5lRQWBFPa8(v+Lu zOlTw>2kewaQZJQCHMi7kx;PbegduRHR@1tHt@R>f-t6UXd5M@a!bE36>kf)T^FAuFRL&if1=MbW;*QWX&K=h4W@2_Z@mnrdK0Q zPjXfbqMzzUuck*tx5{&r>!v|jg{4XfTeevl*DFwGjq-txgI1GFBMZ;~pGdHYjp}n87lEWsSuw&~5!kg_gm5U=r9&PbI z8o-XtS>>f#+wsD(Z-H$K#3RBnY}#IP3foplaZjV=65|jWREo-vF$P^+hyH1;6cdlP zZ7V$J;F~*UK9koC@6zK1W42A2Hc+dg)sou_{SSGMmxzv1{HoPkqRFxUY?;`X)0K%m zTULpKCdrA9sjU2dx5qtOR!U^g3EEukB^lc$$x1lT^yka>X)WT+s>!5_Hj6#Hr`cMn z8VNwkha?5E#&HU@{zI5Sk-ePt>z!{Q$zBv~<59-p+ zOFLXU5Xx=(zJcfdfA-!yNRB+a?`tj*4o51&5&na+^k40+R@FUIz*c769Q4Ropl22& z1{ea3*R@y)3SWqq$yFPE|WfFQ$A!V!nSPF zha}3jWJ{JM%2tF;f8OuPv#P85LN|~FbX8?#=I?mF_xt7hz2p1ZZ;AcyyH`G2`NB_p z;VK`e_4>)qiw`cW{L=j+8trV@Aah9OiA*2;k~|yolF4UZZ`d#LSqdl|bz^jna{>xE z%M}C_PJ;Vr#m6eBP|%b>SkjZ-;D8G9C+BC!-^ux4jP5j;97lBGLVBZ)Sl|PSDYC zqGD>fNReUrh}%iY_@fz;jtjtO&Pv@x+|I{HZ6a>9&Guk(XA{mk!v-#PZvm~Ac{dH1 z|8Hb=^U3Row#%AU1{G3bV1~0RtGhhuHMZs1MB5dV7rXH?-$Y2S{5a#cTuAGvLEDu* zfZhq%_e?8z6trDMd@1tGgtIdL-<0fh=MZgI&(C5=D@qrU^@POP`?(5f9RP8x6|xAG z`Ch2+3!?4HYNZHJ31sE>S3RWFcD@N`1T|=K-)zb^Rm!(V@%&e5}?Pu z?(2=VDZRVm3zQqJ}S=IFAfEj4CZ-=&a#h+brWzmX09gI1>~5KcA5Vd zGmCvL(lqA>f@9dCXuBz%YniW428ykHeQGPpIa(Y~NGpI^IXa#I+HSI>pNhb4H)y*J z+Ai)gqKp(vy7;>sAJQ)S2?2X0PIPIcUFQF#*?zevjkXI^Dc&^M3SeDT1ls?lqV0|_ zi#KSy7HZZ6hvI7@dUd@iVIRRmp?EC9L+*Tow#!~i_WBNOSM9y>$JQ!|>GC*`c3YRn zGZ0#Lwm}Dd-hF$$^_F)t7r!b7zgf_!#TeEsX3${6+8-x=W8{ceg z`Jc52)!g$}KLay&aeP~lRso~UaDewa;in(2J~z;-pZcwLZ{NE6zI0+g16O@>-*xCP zsI*m#Ul#@3x_af#MytQpS_M2<0lwaBt@@o{t+n~}jhn4@_$Yb$uvzH&7_itZ$_q{8vttWfQhdWz)&mSlN zV%JAAXtiCnTr~AF@>GYLsOn<6%w&K4=??X!tL+qM;pZ2>vfJ(?#NTR&+kIHMuTXjS z{mbiP^-b7Y|Mt9l8DQufn=iuRmoHn6e#@KH-vfSs9PU4O8h)5Oh_;_S*;^O;;alGA z4b6aiFy^fLyT#5=*TYULT%VfGhL_3dds3$P3nGqGaW*jzjC$U2LClUqoG}lAX;lFb zC6v~x!HfK3#|1Gfz*7}#Y%zFNtjoBi^$%{lctn>Pe>jNQK?>QA2V!>E_l^rUw`{er0_`w6>F@ktn=%*E_K zCL?AvBvh3I8OAf^tl+mI|Kppe{hrR3!K=o$bx4C3v#m)lIn&?;BAk#~Tdnjv*Wzaz z+uyBcsB*?FrkAvrP=L&bCbi@;ELvx~&EvP$7`rNNJh>kjyTN$u^JvMXmSp~$i6kwn znNx@PO&FqNi!Ky%{OKjF&Bq$IGBa29O}s2j9!l@;h|HSy|Y!%A{W*;)Wq->KhiU<~?1p5(63orm_KW$i{i7GtB6qDBE zg{`8PKCLl&nLy-oZS;Dp5|~|#AV0FjD;Ktj)9%Z$c*#u4qT83UcrpL``I`@sWAY8L zR%W5r`Niu@TD>MCA{sHmSm@UxL+Fky6rEiN8CSvCSw7AsqqD2Q*{@KJNz`D7mQZ{= zI3rfCmuKH!=E~qZHBe{*$b@YPw%fz z!0Kf!!!#_7CAM75Wobfw>zGt;Bi`>5jD?mVn4-=>VT-O|L_iSXL8D0!*(pM3RwYZ|n;ryWRk$!LhTteo_naJdhlmnu3=H{jug1Voo5QX#FbK*HX(0s;i8#T&!+tm>1-1UiYDmx{7#}+LvKLH6T$YCdtEX1&nRlgx zH0og;e=P^67g5s_WoABJqX6qclZU!h$D-O?Mthr!sA&ugg%Q%D^{PhHoP%f@8#%+| zVE&KQ1j^5k1B?vd@X$#toJdf>|n4(Y6z%WdTwu{EVz@QkbLStZX zHZZ+gk%yT6=e+OOO{hp2FD2Jnj{^+|G9gEhJX|y|7)Wd!9~e<{z6=b^|A_*ART?p4 znD7LYQLqZo(UTq7M#q$t^fkz@_8#tRB5GI_vww|o0S%y_i0ViX?S&&a7#jRjMBbbq zcp3GzprJnF5jAx|E|bGW)0~2Bf%*TvX$ARpk|DoJT;37v3x$y@0Kdw3XZmsph{);W z3%8wwZ6Q?V$INJw88C{inv47@@ZzP3eQsg_n)78_ z5dD8Q^^kBy{NP2V8A)&P3|F6#kCUll6ffpwnNKB$l91jMN9uS_Bp`dFEQlr2Y1CbEO2!Z-* zfIvYuY~pyb4OWhqR0vQxpsI=Ec_}6~=KtHUao&Um+Fho%l5YwdtauI5bsjyRiyAYV z&``wM1>UtOWT8uE6bHocXe?eXUIv=4OtIy0YRqg<(AcMB&od-Dh(KTZl0lJE1rwDb z_Waltb9Na^a9x3C#l*(^{|%ZCYg&28IG%2AFhVgloL~f)UvME}1~I?7Vpn;0G;sDz)?Bv;g-19{_@xyH%R0vOD)aIMm6i?|XZ9;~a|5pleEcpbB4RD<-fy-FQ@^d&@DugGH%n(Ih zY|Lzv*~t~pmznL%n%G3;ZwxXb$|B4v`&rK7L(UUzurXFORKdj`l$q^U@-MmD+Tg6g z$sSvKlRdWfCXUtijHhL0aQdx_yl68|%j_mOR(Zr|h3OM+%*FF6Z=T@O*$ZsMi#@gx zFZS35yx3#Wi{yyZK;5yCww68FQtMrjrjb5&&UTAK-C4&wXnn?mep+{~e6aEUt?M^8 z&tLq{)kd3*HVD;ygGzN)P^n%DA{7>ikvuo%XtL!|xRk{mYp z3-f? zouj0mD$PG>a0dB81Q#o(F@CMI*{7F=&R( zW+UrolcdpRpT&TYoU)pjD5cf4%IPC1ug`^ETJ--czy)PC5zNJ7ONN&gG{W{ow@AB| zypBO5gDN1E!+MfzAGbHiKXP5=0*RjO>?BY29>n2Z(jnPLXV4jTMx8O^+?6;Ip3-Ys zc8~qmwT(MhD{xWMwbln$Zrt6tv+AIzK!g!6su`gs?_Jrv`t?>j-TNZ2R3^{GPV#B8 zvzt74_GEh}PIi*`!EW*>iS~BaZ{3_x43RLpB))v(`sUYL(dyQk#KWvzxwC3oG*~0E z%l1tRXSHTvtsZYZS@qYxv(-v(-+HeV6}$Ab*KMtC#kN=EOraxR+j#dn4LK@^mg((B zB>e~o{(Z;Z=XOrH<Er?!>cpU2D_j!bzP;w_w|Og;N~?Ls_yzf!ClpGD9PD)>lK;R~(HnZ`fo0-vs}Y zRPJt;7DJJ;@TyY{m1>O3fD0;2%sfWoD~m=bekseuS>@v%7dI@EfYg|_bL*#wQ&jH@ z0_6l#I5u$L_ea9*In%B3Zm7Aew77JU0PIyGTNu%NgYi%Uof3746_H`g$PuBcF z7b`KLiG!dQ>kO&^Pun2r_4yOoyn;q}OonCV|1G~a#N$W)NKKTFh9sI(Id!O(q8pgk zQm@?9tjLVmHlRaqwKgsz7Z(l5jbWLzMc%z3@ApYU z*F%{0N32S?e*>;1mKoL$<2VZGP9f+?Y<|OuGA{e!AeZfE3FC4aKH5!=!N80`)>vY9 zwm%cgrcQX#e^2$!;4{<~w5M6*IB2emlc)J9#6?!5!L;^kx{G z3wG;T5XHh33t6^JHy(x4mtFk&%>~TXMdNv4$o7(*$7>yzjH+*kh@aQj+fTNma5p)I#GB7@fi<<#s$N$jl0R(>B~lYbKUN<$E&z$ymS4=CcLz&r$P9(l>CAG z@cxzCo7Xq5-?}M$7H8E(Zt58P&oBJc%6I=d-kMiKf%8CtpZ?ok+`F*ySO3ma@bo}F z{((Of1B1`D4j1xQQZuJd=hP?&J| zDps>$$q1Ws#b}%j1`3ZDCxfnWGH9F)3=18?*?{?f$8unU%PPqaQF%0}57~T{jI+yF zaZkv58{uqC$v>B*);!2#Oa)_6|~Ph?W5z16E9>Qsr zWOuRaYM7MggD}H_-Vz60CrQu6V1En+iZ?}lF?d}wGoy;LK|)@h6LL0S{@=y$@^aE2 z`oYU{HgHIrhl*q$r_NqF!lslVnNC*9{{QT9!zA;&gw%k|P*+BdT z1jF@gVY1GRVrTw;prf#r6|^=Ay9DT(W9l)^PMABjcaP*6VOC)^En%#dEU9PD*`R3Y zEl0BBmSp=h1DADh4kFq8SdA1$rQ=9_NEZ6@oB9xrJq2e2keyzdvq3gR4{|nO{(oaJ zhl9c-X(HL1NcMthzd=}KgJ4l+4SWFl2u&kYe=MX z&X6B=T34^!*=Vg!Nt8$+H}+1#-S>8$C7qztTWf8~aXWmJJbl=fhPk+|*k7@naa6 zp9@y;8b^i${1~v2-+lkumCX%tbGWmy*_y6vp9mL|PnrfiA&lwQ(rxeIP7=mKIu${G zd*kZe+jp*iut6;S{#xq_5#T0}-d}4Gb&i4f%8eT~ntuOHUw0%j#qM90)RQHbfN;%T zzY{)*w;vOPK3#>|F+MA|45IH139engvw8g{IWC<|{4GP?phfEsh>gE?`_}tha&6FOq)>MN_Q4cR4|7 zCHc;#KsK&1h2nl5bo*1;80Bxz-|Ynx{-IdwPh>0IPY3v4avboD-|)y3Fm6e-Hx+*= zU@VlOB8ys7=CecCJ{r46KOB>_S^q;Tb$;z0;ys5Q;9vw_(TJBU8z|%E{I-lj`5f9k zkpF*BkoPl8TCGrC_PxnRck&3nHlVVOVV7akI&N=*EML_i%P^j2x?uj_W92U!H^kK8 zetT7IAJ{#-dp&F)_mNooUE&y(W#+_ydyi)BI7~!kW8_c~l>-Dzq|gY(ybso87m0F= zs7VSe5J)AvT~ajF944ajoEkZp|KA>r50iZEoEbVABS#^etub;){zF36tyQE9TFln= zbue-;|L68h!D#upHn_VK0$a$Cwxx$9P^3$V+xo&SPLxzR-|~mEL1P^|A!Puyfd_dm3_ zz&G#SxY5Dj((bf;_1SgW`Grh1`|U8Ari8)|{bZ8xH11D=lvs!$8HvjxfI7oz+#4s8 z!Dt#z7=bt@lRN~*9WDTK#*gv42%>>C>YQ(5PtMR~DQ~S!E)ujIPQ}>rBr`OaOG9HA zSiR_XTUTygYe|%;f2o_i*pO3nc1%uL}| z2bz^X1pXQWmy5KW5@%xU;qQ{6X|Ei9U7{a!G^KF=UH0;t@MHU=`cChd2gJbPq< zr6aFmmBhc`^5y-`(;a%4uD0)er4!#*Z|%2DfTrxWz-;f?eyZv?=jFL$dr-Si0 zibH=GM}%c#{qM(d6i!FIa2(+x*Ym?k;wLB^{1gquXyo^&66!?;l<9ad3KzBey=(Bo zwN-S>|NQxW3llEz;-7b(clNU=`Zs0;$Y;xl!TQQbME3tCf5eNZ z_`&0DUpyp6GYBTb3CeXb-%mhZ!+ama5TO7{PbjQ-7?^gb@7?|aA+YMo#xJ3UQ34gm z#ZCqO5`XNp&p`ALo)vVv;8ul0Og#-Bd?oGlWr0Yy2&{1B6@a{!L*yld~W;_ zYCQt1z4YXQFVBEq0`or}kOx?RqX+z@vgfD;jLwHO)}|7+CA{P`!i`^o1bl{gwy+qm zu`9%Fok67MV*47ugwyp)VEzNUOALI9w2wnn7VC~BgS=ld$fHLqp0|OA#(iK*hq^`|OL2uCl&L&-!Lj=$G=2$Z!Y|=OjDgAoctp1ZVG|0)J%m z;{Jt|zqQ-=B{YejwX?j2xH{)p%*g&f%->cp7CW)^JE&TdJkeIjHvUL=nkymoNQfv^l!CXa@-CUO@{6BkYPK+sW^)c7R>*T&K2l& z$q@s^g~_mehMg=>!yKc7#jpXre$5;#(7VmVEIA_Z1M~l5^n0%f=rz)b*X@sn+VM>} zHx>Q5xS+|f?VLdt0DegDdlT)k(h<-3rv1yR7s7foK(Aj)hV2tZfOwhNwd=7UnE#LZ zUOj+yF&QY&SJ@8;U*_PiT3uu_LQCU(Q;F?IH|>@mVl2#m+S6Ag?P>z)Rpi zXZF1e0NMa-w+)nbskApf5tG-m?Y(5xAxaC>bRJc@u2jdWWBAf!1d&VD_8H{ zeed|neKVX=>g^2y)z%Tz`@kxz@abt5It{r758@=+j*}|PbnqY!_rO#r5py0icO4PU z(3rfo;}%8UDir5E@2)1N6&V4k|%o)_CQwO-3uQ-1#}!x zicchuwV;N$(F{9axjQR0K0zC|?`!}S?mT<)r?nA#`u2J|X&Yd6!M2bh09-F&E9`*? zU`jE_CVRnKULkV6ZrpdDY(0IN>`A8i)?@c>`tQg^MLAz8>pm6@>>J3?wo?RVc^?;A9buZ-1~=aP87 zrGI?hy*xJgzgK?G$`^hMZ)flIvsYg{xUlj!e^q07e`PK2NT5%D=7SeMbYbOhu%jIK z{YdbZ$XJMFhww?@PasjI`UKwb1%@#)QiU#cvZaA^?U+vrd}c+)V*HM zWYt6c{a%hBT4_=U>@XCSeL;uJoHEiNAP@A3!k2Dgk#?|!e}W&ZETxq&*Dy)T1% zFw-Q@IF2M#VW?Xs8#&$hBYa!N-g#{K7*Isc#XM+C@~<1_!8}%8hDGaU#A%x2ng6>I zCREpsxxaY_+~Rl7H0}Y*oz@@Cv{}oVC0u>rg$G|J3~>y_NGS`L@!% ze$rh8{NU`FL{oN1DOHDC}Lll(EmAOyV; zKu692hAm0XMxMu8$YQ^-s%w{-iFiU_v@YCIw2l|^hn$=_9%Fpo9MAlJrjzv%G~Afv zYn&Jw7zBJG75hrYoPgYnqmpBoXycd{>Z%ba5bCN|1_q%o2%TiKAAs+d2W#+p{U8yT zw`{N77f?Xu=mKaR6=;tw8|dS6W|BWHbL(MpB(SN|Oyb(&+gimEIhjl{^R$iVl@nr6RjH_pc^cj%<%2CCGwv$`$QlLN z#M@%>yM60DG5VL1NEefDTMK{xE$_+=%(Sh|D_^@IX{q;Hw>NHHd2ge&d5a^Lx;Wo4 zkjd-Ku}c`xor6T?+HkNFg4nE$#ag)-7^`cH5j@*)I+*kyX5cM1S1*u}!vZ zHvp@WN_?$#*`*eLlONu6xepk-0~q#VkLOTrX7BHOrzW-c@d5N-EaCH4p!xGm0S@7q zjL_o&+OA%|*DG1;qjK7jSv+L8plrBrD@*&*Y>Y(zki1uZt3^u2ol@At>U15(2y0E!5R zBq%bUdq1i@M$(DN?qWmLfg9BX`FconXn=1b!WI=s75zFMT`E z6v_Pmyn37BG+WeZnj;%iB&;mVT`(6mrpRvO2gE4#a4=5$qK7|U(ZOfe6v_Pmk!~^6 z$seQkvvv;5axp~nP) zx!G1S5jqriuQ1%lXo_V1e@AWp#lbQctoxG8k&P)*vM&oe%#K;^7bB??^#9z@40Ykfc@vVdD@s_Wx&DaeKJw8|Km$ujH6Kp~L}WIm zKSS7qb90wXfAy)k^Mlve|E$Teg3f)K_CJOH{e>T2;eYdLC~zhz@H68VKYU^3uRm*| zgO4`|9NGUf{{Ei9U=kdEc5$}y13{IV35VU7kB`B89Q7h3Co*@RMR4f`SX$X~4r7>h~s+RhyO@^Rck*f#%~Jn^tVk%8L1#086XL%<~8=&HVp+ zYb?$Te#HtczcrDpI-Y}fp^)Iq=ug6(%^CFYsY=i7rJ;AP$H9Hn>wUEJuN}DbY}0W8 zUi4T@#|y-dHm2jM>6rQd_w@&UV?Lgc>$nU#91_wdwm88yE=O-F^lx^g_C8|~^9(5R z(A_9@)qJFA>Bd~N=-4L*lL1(-ARIeWaM@X7dGqlAgzn74qujn+MY*;u5y@IKZ=YNw z>)8gD2CTXOcO9vroeg)5RoAXh3N(B~_FG{FbB9;pAs3TcSVs?II%fX={Zdb3J{B)FEr*DDEWiqnsW{lDWIkrXEELHqV0)&O*$QyxBUx)q$KpnbBV`lCI%K`q z5u1i2E}6F|eAPw`I+YW8H<7GPrazD1(m7<^QfOxdWZKyIEP`yHO;SW6PS@UEUky4z zE@E`9N%^EBI%`{K8kn~(&I~y%U9{hM?t*07%#G2-?&xCBZFkz+Pm(shE?qw_q}C8| z>xn=txAz_36Q`4cG_@o%y8+#Do$D@tiS>EoVt%B`p=*1Yu?@+N5Yz>%FkZk?~-e z|NoFENklKeL*!I3VM8&W@zNGF`+1_4w6hzCdDtM#f(H0lENM*;CdQr^*R?TlcKIx? zy|^aJYd#X{M6GBfX;iW@Mk=phDH!`YVr-DNQVrDB%&2dFW@L$^8FEOwg?e09XRcV6PH-oR1gvxv1u{(gJf7 zOPZ*a%4n-+%aV2iftXDYrbwWEg9j@~s|&U|{KksM)6#KRIws`~>CbX0SjXl9i~l;x zj+y`es1p4fOjr`lsZ40z#ft|)Y}TS{zF7g+T=%Q!i=m5^B#UFb{doFld%DW_cC(C| zGi^?}JAy%1U|jQ;&cTmu`7Mheo4;ePXG14H+TDKgAlcvB2_wm6d1=417hJ+L_Kvpp zby^Z;*~{O%AinHeYvB>2PEP_<*5cwyyDzV|R`v1P>e`xQFirOPkz}07o88tV3p}k0 zR9!44HD8@WfX&QwyMhFI01)WWU~0wYcQ8kq&YU7t?c2l$E9Q$#c;x_HJ0?eC4Ct93h-5h;aS73Mo+HdDPvVtCQol}Xr#(++5j-u zThbc<=3@e2M)v(i5VW0`Ul_auaJ~|Q9X8$ZE zkR`jgw$5Sz*I!Uv4Ew_XFCgWtLZV$`A!na0S4ftiGwLwF{QoCto$W{F#1M2z&LA#8 z-Y~&0XfjNPi9+|z?6BHx;3OOdMguaxcd0TOO%VIb)INtg_wHMzxF z9&y$m_VbA3?wX!TDnIrkiq4Iq^d3&ewIi0y^VBUD*fG>aqxxftbqx{AtTkT=sdjE7jwzyJ2AZmsp{&oY`I~T5(b&Y4A zdC1@wD-vPpr5&(EEG6Bgywvr4PSlZ@zUyDUcW>Cgk9{wVMqDxK#`x8f`g6=Ly1!$ExKiivL&Ie;}G$uA-NX1Tn z#r*#rqgeJWt}wsRVfAFkGYY-opd5CGaN=A>gES~`uVd^A^Z$2BlJbEP zixRRn3-XnU02q+@&kv$uz+VrMK)resGKBF>Rx$I7qz&WiA(Duhz-+fk*1OnYe#@@+ z7qSH(XL*)&bh_H2j7sl~I!bwR8+BB4O0RRL_ClXs%;s(V%e*p|75&-*VNrz2z6g~( zRM|+xi^3`hq{5kiRrp>~jw9uy0iR;?V?L)um67tBv`Tz3nG@2KlMs-k<$NX$v_gZ* zuN=x$q{eHPAiUs+fS-vqx|cI%S6~(9d-s?G+r=RM>5}pL(ze#-)jAKPytmd&JOpL` z|H8Eu{x`3N0*9i&&;FVh(S?;?MuZ&r{fLbdRwI!j#fG8`EdnU?if*eD=`0qq{=pkX zarp?q3$Wq#FCB6l+5aEs@1HuRb_Ijf6YKyn8}>wrpuVHkIylC^fdbd=6+wkT&QB)k zW&^0UqGA!QT4U$@wv3_oAOHhIc+pob;g7)l|EGr|qvy1Dn=(*;Vaqm(LFLp?=O|FT zN#9y|mrfq~W_9mN^+$jZjX%QDoXxmpeBbyZoJoHK=Knv#dLff|Ne=*-(%CKJ_)zWx zx?HiUO?!!VuOD^8`(%R7<)+1ajvoL95Fa}_X`lN;K4O)LI3FLnX!hu%0~d5L zN1q2jge4pgqM42dET#5eDIhl`Xfh+jlE4Mb|9{q3nAIl=UJxt=UZ8R1jL*p&@PY=o zK=uoHmy}*tTwIu&2Ai+%(7ex&OUn6lM@e%;f4RT~*5{?{z~ex}^Kc5x|9@_&4AMP# ztF!=}mkiPxUcZcQP&Dvh15uAWb=3%uoB`b(U>21=t3?cK81T9ke!j8-P3BvHtYOL8 zmCgqQ`03iJ{1n+F9b$eO@CpB>eLnkm*Q7nZSXqXP0elz8>IR(tQDiL zXBw|QxN`OG-S=E+&IqL|yOw+snDKhJD^?&>Vw94v78Rl?5)Krs|3 z-`acrG}%s9!?jLpXZzWcc$KS7ICQ0`dK`m0S3cNy{}$!9fFeJjKkdC;2ya?o$BmJ_ zee1@JuU)zN{Vf`)N_opmy6!R=Zn6J;Vdd*9E59snhkyOpuYQqSSot}&5=XKD+1Z8* zf_AOcK1S?d&6fjREA@48cREb?nua)Pu$N5|znhHt3;IYr|H4mw^dbfl{98wCZN(9E zV7#PeI)a`(2hhg(6I*3qBWfjG;juV>_RawmI5XjQ@%OvCaTIl99RHMB2w3R|5p0SF z&~)09dF0*W?LNY8>>QBCBO+g|X+Zp-vnb%?7 z>2QSESfb}}I~=QF39zhkJKqByctqs|NZe?yX10YWOyG-)M#q}AWKHpUI8R#-$hmFt zt8KxZdYZXYd!^}wO_a_Mrs(hhO22f&QcIzdZkcD;vUG#8Gf!!6eMq*r9}mlL?H-#L zxjbdiCTwXELJwCe;RMl05a%c0SkeP8D7vsq-PRKAzR&ZI*PJGI zd1Anprb_r`6%1e6fYh{5WV}~%`@vB9<2opP&m<0z&M0R~9QgI9m?MiTA@Lry8Mob? z9!|YQ zt&axNVK9gpi~!eUaZrXU6%!*NQ6N%d?g6Irf|q||9WJ#S zzZAO`n&;pfrE+roasaP*b8}+!ZR=}R9Y-#^T-aO@istsmg}g}$cWAojmYszdeb%bO z-ZZ!DlvW+-f?ajo_t`lv>;msDm8KqU)v;usb^Gj9hxz}b`k^4P>e4roc+6%l#c<4L zX|r8<%5&R2!Q=sEN6}ooI45O{qym$8jH=nAI92CZA=ij%umnW0>I4dXA&X*?R+d=Z ztvbT;EaW1RSk{-zXRSIW45G_2k}$%FT5V*HPM#Ex1t@|&)8SMej2c3)7bCTRU%;%F zg^A@%!2t-2!i41t6mryEvU?EBX0#33cgEvu8lvzTML1`ZJlN;teYBPe;889!FVRrQ zp;m!t+pYY@g3ud{qcIjh`NuI=@u=2&sUVS9NXfb)S_QdyC$i--B%n#rp@J;?nm8m$5L(^;@rwfr_Iqp+M@{R_1Jnnk=W+HN`mjr)M zwm@i%)lFF&}DhA`zR#sOVdF{NB^_5V(^oQizIz?iqexK zVr_W84{>E&B!9GwQFbJ>A^d=93c01ZDxIqBZ$eRVUydXd^)$J!ng*?z==>Y{vg4;j z;m{rrsqPTabM?3~-?(0?u-CgQM2e`~#>FZ+!WQnXK+-TSp{@Y8qlcqXq70cW_NhvwFh2Xq<_XfP*M@a8Ub|SVH%tw&~L_&acRtk|91Byasl}%t+xaCN&UbN^DDs&I!>L{*7GN`%pIp+Dk7lJOFSC%ZSZG|wLT;4Z z*k+7$a_r-V8urP?dNOaU1=!Unzbep&3ii-|^BHWtPRncQ*Tbz3A3owwpiw)m0B}Q# z-`DbT7>92vltWJ^TLi21~lNHr=n<{vV3S zR;}6pn=QTD;w`=Z|J6Dq)D@6zykGPEzfv~YJ^z{A|7#Uev;Tk9_W#=d=Z9Cm`_9S_ z8%5Nye*8=KUVM0AavF~}2;tKcGGtcrg z_Q&}9m-A*Y=Lk_TqM|WxTsOMnK?A+U_|o9mglQ!6su>^w8v|v$ox8+qp|!zn zdxqD>tD?1$&3@JK2M?!n z%in6ZyW!>Wlj(Rfj#Pfjxd|@Cx8sY>xx@N);Ac1q21APf`UWXS^R6AWo*i<*Ti%r$ zn;W-Vn^(RDLgSvl-@3hV^U8aGH4-mIeA@fBue|%-mDbjiz2w84t-a?DqK8SuT?;s< z(2bx)VA&kE6x;IonKx&{+ri8IL&pEZG?ckM}2| z-IO23 zE4bBewV_-5?D6C0oz|1^aiU}Lp6-MnJ`Nw0Z|1`AQK#k3K6(^NsSh4)?e4i&FW_Zk z5I%`ByuI=MjVo6-T2r5fZ?>ZK=*{-kFI`>l?6vMby!Leat;-Jw!N;xpPxpSL_rWJ` zj62_ZZE)%CJ3kyh9kpq@104O@#^yIRHg2~1Ey+q;j;CA(qLknhz*37NDSL{`#vomMQ$VU!w;Lc_(Bm{<)JmU6~J zQ5uEDOHgQt{C}#UC~R9*h`}N3|KE$}yYlqU#RHrr|9=SxD7<_hF?T|k1Wx-i{r?x= zN%keA;U)S1H}?Ny^#9+uef!q6*4MtJc9L!i@6s|G(=OSNPw&UO5W<^MA*S zhZk0U`ip1Y6y1cNyaWsiWdDDazkjRQ^)_bwe$b#Vlwng|haE5T|KE-rQbfV&$A<0~ zery03QV9$xD+#Ul#PR?P&93()?0V1JjyG0F4FdQeLF0lja9k1ZBJ#4Uw8=XU5%pf! z@yfwD-t|tv<){KDyfR+zc88f^e(ra|OV2w~{&x3v(!H(6$!aMYy}!14QE12NiTsd>?e%4sINYuWK#4j2)A<6T#)(2N^+}*gdYQy|HZ9qKR6|B+Ky=3Pxc1_#J zzOfU^&#fERzkj3E-VS$@T7*#T|DUX^{FxQrPU!Wctrs6%Soz}{r?3r0p81L2{cB!q zU0C_UN6kmq#2n!KimcNhFKY9+!me7<6ZlLcFEUsDP5yqe@&s2;aSK(e&&~nVZ31VS zz?mZl&ScKjYQf1Nj#}uyGIU%6A9@@yD9rzV*8=%rD?Sj>Rb5+z5N+a6fE6o3p5}r` zUPJiM#%1IDpocL3e@b!^HwrACGdQ;yoMk~*ZqP$fGzogHdo1~6Zhb&}!K(NEmD`)wH?QBiDIO)O)35m5 zHSgB#YnfOF_^WBY>^%%c<^J};6-n_PPt@ZxxjjJ2iuHSrD`H)||dz<)#&DQN( z-|#G+WYBWOWT=vM2WpktT!S&mlcdy*A(Gb1X-8)jVDA7LMj>73` zd(Uro+R^r-oO;U^v!v4PL=|a28`fvq`Ns9lujAei8Sh;GVB?F?>i(K2AXkkB&tGfZ zy(vR<<;D#gv#|f>K!+bhMqjsoc{o}lqfob(#67@p^76VW^dz*9qC0y#Ny7NF zKHA-W;-lI-wCe7{A5;~T-~49(PvR02B<_I2>u|%H^dSY&NfJ$DCgYTxX1UFLgC2Uu z&_j{`fBNO^|Kq`_;82jpbJRn(@zT>JsACm5bjXfLvk1tCVPrP6Fp@Nib<9)q?$d1`TsLV%OG-oaVQ4q z@%mE1CPz?3smZu>_K?M+hhAp(kXI~v$SNi>9f;bFD+C9n$-qS?uZ4(4ZqILa{MnuL znMiJ43I(jfB2kpF9!8hOqugnmS$Gw=2c3kZ3RIEhAlU}?VXbX+JEAslfk>r%%D>5! zo9SPw-83FfvAxtm6rh^$MYBX+=VvHSn-5WQ&HLIM;Ko9I_WL|Cd7vDNU`9^I*R_o%(kXjl=no-hxp6qOsP-VJGf}n{{ znxDZMO*ZHa+$xX_Gjd;RdOPjR-ou?Fj3pU%o(-t1wclDR@xmVDy>|Q7`>pG!<-RFM zAsM}GM_?DDNYfYXqnf+PrK?eAno-qc)Bfby_Fhu<3F{eBtgpA9pm5twK5>JALQw!q zR*gdOGazo`NSyoRcYATK<3-ONCl6vUG4drm3O`&$>7`VZpZPXR zj`t1PkB0FxSmTbjTF_ihGi_r`;_7eQaXQPOq^tB>?~vE}7G=GQ8{%idGG*22KWEpR z(~2sF%yLcR@B7*R4 z2l)FV%7LeGr#cRIs+XrqC4jHV#9W{H+9?M!Ki>0_iTMOosXF~T^Z$=lQ@}flDRn9~ zoD)^2k{Wcb2Jf{=#@xgLzUr}nDtU#|C5k%E;@Qe~4N-fliI|!Hf9$*@V;1G%pJVU8;8_J-BF zx=z+NeEZwey^kOM;HMu%pTCU~_t#&&b|wAtud`bEV;zXv?id!2lQh|RkZ$iJTOU4o z@Nx2dcm38)*L1A{o(lk6b{o9#?}@(_uJ7U=BfeTFB+g^h=ZMriy+*M#Osoq`PO;Qz zc$%b5q^t7#0$roh*jThDM&>A(Q=8H&QrSWWIXKQ ziZvO9Lx6(HQI#I!5cDJbmL#;k#_z5?agX9Kr?osUTf;MGG(1I!IlO?$s5|wi0K<;i z)D}FbwIinb&9R3%>IP+A%CnNy(HR}|VqC=h|9SEMYaHghdw%No?)!soDDH9MA!lBv z;xIRkB%_hm292rRIE=v`s5~a_2Z;w6s()iLD4o%C+vJWpA&0qMn(zJy;xJBB*XvFs zMusgXqai3>h}~VpZGet(#{A>K@B#{d&r7+e{j)mM%ACJOE_+C4-Movp+dRcUw^OIkDCvVTN4#accdW}=puMVA!|B@Fs{tNvRrfOS&6%U% z$$5C0mTkqY)vXvM#iQ*AH!GdVsiaylKbqR9)ZDwk_P-Q1sQrI_W#tP$xAH5p7QAM! zpZxNRCl^+J>HAN?+d?l{rT6pfjWiv+bfpo}>woZjfBlQc7gqlLA83X!+uwV3gUS9u zl2q61?RgYKy+6+1e<)jh4vT6)zp4ft40(HAShM52-y4M++) z;ZGLx@o+Hg2az}I1rfEU!zn*-TGZRU7<*xNn6j%^>pojgpZ&e;@FxN7XNP~PVC!ej z!Rp*NS6S7gXjii2>Zcs5dMv89v#M)5ik?l>oX3UvpVzZ7|NrAj0@e>2w?^02P2>J6 z7OR?fW_gp)zV@XbTFAXhLF+43TwdRHuoF?O?}}5p?HNUu^SavpOmtlWV)fwD@X=Ph z`ngqkWtzD+I_>YYZ7Z@U!8ZXVGf|Ny$@)+t0Zm&yVB-RkSNF2rwRycZ>VmTMw!bUwi<&%a3$R>Vu-aC!w@4F^7gIwS{a5Ib`Aj% zyR&h7Q}DsAzkBl*IqR?ARC(uDaSh4>P|2Ub{QplLJu+o@6^t@}+`YKpdAdWI`gFB@ z?<<}7e!H{(#%PRIQ`hTsk5-dOccxPlZQ6c!?~Qirl2S`vetSCA-`+BW&qjEz?$zo( zj~0k4l24WZ7hHC+zbl6az70^9%LNJn6g2OC+E4T^!PtmI5z@~TF$mcwm|%jC2cuYV zd=J448*WJ(q5wqa*=v;~mM=US_C18J0e?gOaKb`~9}PqKv+wG2$}hB(_W)6ic8Oeu zpoWNsTqeDuM;^yM`_4#`Sdm*U>G^1aqHahG3`P>UBzJ`XBaIQ+C<-?!+!ENj(*&_3 z^b?Q3C<^H(Qk)2s<(nzdA4Y;bBYS>l(+RuDXe!T|IATr3t}{-t77Q^n^|287oW|;w zMAL2(@;RDffaU#uFzkjHF2tY{VB(zh8u=5>P6k*arji(S;wRJbK)l`M+tUyl{OS5z28DfK4v_QmSOjeN;=;fPOC~yEP=>ie*XZ4tCq|3t|U_V~gz?$|A z5W*KMPW1iVf!7O$6(W{eI9RMmk0$m5$ap{t*_)^_p3`B^^tk6IJw?Dd^kWw^uQ;_W zFvSJ9-;C$B4znV~$qcV)oi0iSiSZZ&_-VjmDVJpzL0gXUzc73-L;e@2>tS0SaiI`dS`;$b@s;8-A<`t@+X$;P zy`@7b9ZaRiY$_3^(}WJj35!Y$2}E*>QZckg>3u5fQIeEvzfIgX7}T5{xo=|f*LMi# zs&5`&?2kS7O@wecovm}!f|;8(-uEtEbP~z!>+imcG_ivW@XjV*>=RjF8|3MDvn9ev z*t&UZQz2V`cJS`?oA$x2AJ+koYk|*beW20+sT+(8Bi|$3m$yGV+GCOD|DVjfW@QgA zT5KLpPMwc-O8?lMloSohkuc}T=5Dcfl(lJ1jByiV>=aVg1GTCKf9Y_IBAcCIxW?G! z>pVJKBlG`1ts*~`C+^96puTi9H~@;U<`AGx^NI3O{O&{u;X#k+g^(Xq(|k;Z{n6Mk zjQXB!G7NaITPD4n!>_tj$Sh(rk~YT$;~8y1tvW)@+Ni-#K@I-es=%55{}~RZBV-z_ z_O)tYd&~qt3_cML)Nq8*)Ww%TocP#vB2`K4nHQ}5A~Df6GJ2w}5kWuD!r7!d0kX2M zWoraSOD}qy#+i_WkYdl9;hd% z2FE<4x72mMtmq0v3xQU^IU+ip0Nf;!yU6p0ayLCGHTY|*0%!jJ=W4bv(O%`$w|OZAlK-^>!|IYh6cj?z0jUJ+CJO z(wh1g1Be;GuobvR#zIk}WYonN*wUHMZL=tA*E<7lM9`jlk-)cOlxwH?QB>Bwod7yQ^+;$yMFU3EVX8B4{x|!yyo&u*WbFfap!7wp&kr#)y*rLcW;vd8^A1+_5bDE^hVg9aUc>RF>M`acPww|PYlh^a17=g=k!XQ6O*31^j{HSzXi zg~KT^IGLT{xa!W#BersKwHP8RL)3>m+s~dp2zPcQGqtH7q|I2&P-~GhIvFTV-#~HZ zfHt>%L=+GEX>ayyc1i|95@YwH5w1uR~Jc-)OzqzOeFVPb0m#7S&4cXF7;r zGMVFnUUWG>ugDWh9p{wa?0X2o%4^W|FWqpK`rPV;N<}Co+)3seNA~{({{BnC|Hr7m zF!^>v*?eOdP6vS~>nB(OFoc`n;PFTdyb{PPwqs(t`Ai5fAi6*q%X=8hxq?C_*xIpF zqB!e`b=>R6(8M?sLK#$E@?J40NO6;an60a}d9f~Im-mce-qbbr@lY5k6`eRp`s2W# zVtvRGdEzcfMdLcsX9{Qv(>+HCr+flLb4S-DY~9dA)n3eWY|mg$_r#H)dJ_h%fHN_c z_#hW#J*JwB*uDOk%6k1N_$xReNH(#A+USP*M#h_7+*3;O+)ZkPxUDoms$e%jUS))Q z<<4M7h&W<9LZtx;luA<#sw%@b{t}GL>=EK786h)3hNmE?SffY&K!#@sA9y)N;Fg|v zN}w$$j*!q(+zgCkhPtj&_|zN0YE&>15=uj9v9w_#3`qe6zXe!D)I-W=L$gXZr_B`~ zY+P97zG6!lRR`A~=Pj#@P;SVG560pgksoO8|rgk)%fDT(%81w&6o9QbBDt{6^g;C0(>B5;89~YEX-P{c3CyzwA z6S4DQC-DV(2e)81#RnjUiUHA#t=LB8<;>r`0jrE-3U46Z!rAH|lUJr~&Rs_+MC<2q zpSlZrIR?yiXC#*3Y~cMtagC_;)e(-*4?M-0H3C0OJvwfUC=7pf^gZ#YF5O}m4;ZdI z{Hz7J6`{`(%7PH|5|)9kbkLWn0sUf@Ip`K(Ix&|-Tr%k~&UyqhtsB;H<%vUBwtPzy zyaIf_-RBZYWNdstR!-ZAdRU2bcYh@Q06PDq@AsHxf@lH}pryV;9EJMBu}8EIen-w^ zFGhJCSdSk^_2LLXO)La@$mLOK>k2Tb%URLR+PeD6e((Du&Z)Xafv4)S zapO1=CBk03i{(EV+!sR)lLlx2?h=PCaaot3bN5uh6AI?j<&AaIr5^o~0&!E464eLV zVRJ%7#i#d~2`m)d$()jNWu=k(xvvPyepER30dD-nnx3#-<7Ge#>@wCyAcz>~4LUJlNaW`tZYKXLsHIO@h!? zY<(q<$ki)%HdkA1$sDq!>oZ%xN82A>dZVM?TWR=cH^F<=zhw4w{4R%Yc~@?Tmx*zN z#p&eQwbs>JH}1Z7v-R*{Yjfk9o36oacDhBs*`8H@xQ(KtDlW9o$q%yq*@Gv~9#4}U zo8x2EskELe|JLjZGYs9#QFq@YII)eZ(t;Eu;ktDi4KGitSLmcBE<;OzVyI@Ye!#Ly zNkfSnjnhzyzY)5|uEPF%|HhT8dFNQXZ91{LbkIR7sT0>2hW>14YfoWJ?vm{1aj2m8 ziUaG|vih^I*jwJl&1;p>BK7i>_cmH#3n$$$#IL!~{@n1aRsaU*h8}u5b|{^yv+se* zO;jc;ZIvzW+i$CRRH!qb7sp@gtOooUHOoawiO(scSI$7+Q%CqDV0DPpD;4E5K#LR=`(%3s~@Jn!H{ZWAwefMw|Pqz9eJxHFkp za+ziYwpshq9`s0WdFISu^?BBS-DlI?y&cN#cLq+kWSZA{5Ehvwf45CTO?TqwVlfvKu9< zo$lJ3rYDx|eWt=<~8I$u(%wa%CJ{(&zU<^I#1@WaPp9>DU! zBXS3ohQ+tTLdESTt?#T~^6y{UPtq%&e7p6f>o?k$FAp=+i_er3-SwMRg*pF8V295> zCq93ZQRhh^n!c=zH(IMuQ|n7PfB9{mAZq5yEZJmfz4^|K>sL2dLx^Sxt20EE7XVbR zcCs**a&x%e$47qMreq3pn!3DqpURH@AWov~IH@9n_z&W6kCnoVNce1Tn+S^N*|W#% zx88XNF21E63uag%%Oh`LI5&`|Z+W-g>uLSpFRpyoFCJ3))!cT5De&Xoi>DV>{=~06 zA~uG|r{-nFVSQ-uw$y&WUXlNFn#r^;z8+yW8YyXgOf*10?IvTqmDw95eS!fH*W*#t zjr)^s6prOe?;daW*$0Mdv#3-_B}GMFp}zJB0q9L-(_|AHm3E3~jdI!qZer786%{xv zi(U)$K!RYN?Gn*OW_t#LZz&TQb~IPS)HVaGt! z#nZ4GhYS;NU3gu0WArVkQM&Ok_PX(aiw0cO?{#A~`7s-%7*Q=|%N&Cp60=c`02zze z%tR#Lj1oA4y2w-VqDduQNmxhiw=T6 zejmjAaV<<0;SLn_C>Xt86ws=OR#0d+Vrv-D5{l?f(}X`lN6>Cg@f@EQ31NPe&ZHznyx7#!O+)X>Zz{26TvmrxZGcK|?liA$W2jv40yNzOhxZAN?i2Ry z6IwcnV*YTPpYl27(}PA6Mq@HzSIUS?#yF?5S(LrHcrdb4RsQ}c#Zb6X2!k`B2cm(T zfRi_2KR)p(ql+iK>`cedW{j)-7)PBkV?2%s6<|Qd4Es35lONiQnZe@`*AUJ#9&ima z3MFfI%oG_1ocAbEG_$g69Wm4+iKjw=F(Qy-M6*X>+#S*C(KzLgYernd3>gubFrt+s z2{nMmBcE2`_Ag3a!pu=BGipOZ9#DLs0%2uB2EgoPYPrcJq##BLCOixjkv(|y8|K*1}O@@B;jw^9mIUb zL$5o4V+SZY2Jp;);Tyo917bJ^tYU*9yguMU7;=ENWWXvm2*U1w=>_|;`ot(GQHR87 zx9`R1Sz!G>bE_XtQ5A6k&F)JS4bASe@$S>wKD^h5vz3-o)N=%uP+hl|g4CDb!WW~m z=%E_vMflAzS$h=N!-CKwV5CP2Q4V!`W3c#WWp5PoH(>t%*WDhiMZezdF@<{lgg*+S z)jh9AL0I8MLEeMYWeJ9V`9nnj#|K1k1*{MOlQ@7m1DKP*v2HL;_~SF=6E{DW*W!aC z8naqa2;+(hI8FUY_M(HF6-^044R4?WhO^|z=Li~m{2(rY?gx&gUHVwxPMbNFIY42( z)E!Y+j}F>vSsnO+-tz-3p$BN)vzOEjBihSld;_LV@mR<~)gE=Jy5S}H!PYHJ)<<%) zI9l3vO4Wj~Sg9Ht092RDHH}QaIo4Fkjx)OGsx?_`)er@LJJk{?Ow&YeW_26~EIOv{ z$^dXR-jlYaswuLP7Jta-qUvVq$azyYyl#)AFijFywI}?f`wcE;HuRGTQ-sSiD(Sj4 zm0Y)3U~E%DqQPma&TNwq}(YzGF&rc}699-UPU(nwD0WL(Xa{Ral1+ zR5v@$s*qT2))Z7NDG@==YI=^~tIEx^llVzX16`FSait}uA&TCtq-7pw{{J`T5>0f~ zn$mof);LDZ2Fz0fr-%w_t{czN&C=G4ZS~c9fO3sd9Iv=u>e3^YJ8fsAqUp@>Q)fYe zbuFn96`pfvOYMY>kb2~-Fb>V=8jhdQ4pwnfR2^do;;ChDsYugG2&O2Y)=;zf)wI%$ zWo6`Pr9@cfo9V`_wjFNV>dwOP#b&yxs9UMWO|e8xE8QqcE3*!oNsRm=t#or<>6R-? zogH(;1V>G;vBJPM@c>)U2O0J`u~d)w1;XBR9>2 zujGgPQr71<8w@$pgQ1rm;BH-ELQm{u>R6_9Wi+JdY?|n*vejK5=P4?c<<@sO%$|7^ zhNNRVqUr{2*AX~JU*`Xx)ejqtv-)vimsw0Ft_W5CFr$sE`2H|kah3DAgf{Zr0?re>hx;15N-Fk(voX65-yWUH^5+74Hn-)tcRX1W= z@mRBuE{@8O`Q-dW9{6&osbcCze6=^LZX+AZv6@1q1xKpZ%%fxnS;c*J80PW{gUH!= zlNq-OxmT_66%xzM^Cq*;=AhC}yS__9GuG4Xbc=9pI~~F8+5GzMBNJEZ($iH)Ao8cB zSZT22Y_=#@I!QbG8Otj2vy(7|*_PxUCHST2(W+nJeZ+0olG4~oOZ3>8#j&{j$!Rx| zm3G23Z2Y8XVH&yCt-{huM=P^7N`U#CP8iv^j>94*j**m2Gu`^GpF@71`TyU#v8-)r zwyH>RMwFgGF(X>fI-6UEy(&SCpgp6dM(kE+i}#Ay=Cdsl8o4=dgz#A{abs6x3oW+! zMoO=#OGYb`*~?EGbv9e$>&R&&c=NPD^0KW~OAlMn;;|YU0+iqrwd@%gUibzsG7`L5 zdU6uG;(d0{6}B`6)kcQ5Rh#wQ)~&hSkslC`O5J+qsj3UB z``G7!UusK67u9Ve!`r$w!`iAfgPN*g(M)2m3;^9W61(dr+K&Pmj8M*bbTmR_BZr&1 zjo5AKmMw9f>(JkrZWmd@Q~Mh6NU)bH5*wj9YfDBKU9~2Qty&QU9StKS9m#k_4Y%5w z&wSEg;mfLqiD|Xk8#4d@yBU+jNW-(vI_|Pmwo9ODO(q=|DWSw)bZi-&ij!G-hLW|^ zSho-tr>okyh^L_;dfi#k9=S0o)g^Rrj9S}Hw=hd5Z3kr$m3^u>U|6E+PP>O_T}zBW ztms)I;%4%(C8$}fbHu&Q;rHBxH3i zdtM8zXtuw}$T2W88%neetWu6hE>swYBAwx0wkjmY2)6&e2pqzALRp}BAFZpp5 zF}q3_wUSbd8<%RsjR;=X`6v^|t1@XMlDMw1(zd=4%GCoTCy=wAh&V1IXqFQrkINB@ z2}(~XQY|H@6YY1=|NZwl;Tyt;9?*8T%%gY?+q&^Hjsz%2k4}qg$p{uAI0{ zZARFx8`}X&eQAlQ%!u6_shyY+yG{3u*sZ!}L~dP~?zX-v%A{*c*Nh<8wHa|%bC|; zs%e{=r}Z1UzL7$O6(XZ1cD36*jyxZYz^Trar!yup=Kn8RvevXtb2m5Fv<}xuGai*2 z8F6(^wJy^$SLtSC)>@4S#=DsnL`Hh8X_*-O=7<*su{JV7Z7t;jBjVPdbPudb=c7#c z&8Vh19xgJvYt`@)zmc>-by%(KsO#-o!UB|2Vzb5%g8V|m406Qo8{t>25IIqoijAOK z=#ASBWKu6hiIFN-cTUsHa%4nasesf>uHu206K#TC|#qc>NOmTDNw&qsk0UZ2*0;}p zl0Nn>Nrl#u;e`#mvY z<$nxIw|JKbpxM8fw}EPZU}fl6i~kry1sh5QOSLfsdGo;9idC_?;jU44m+j!pu7zTn zTZoRi4vO!`qPJx&#mQr;?-I|AjO_N?%r;JBBB(Yp|NqD8ol@M40iX2kt<~G=?oyqk zq2fL;n<^}dHUE<0J(l#kd&GIv+(I$Mn+mOT_vA<~g$x(EsaV}m;8^L=EYjDuZs^Zz zoqEI+Yf-IZ?k-C^ZxAkj6AM;NMV9Q2c*Pdt+ER0qA$#c_M|LEbg>SOe^~Hh9v5;+5 z#_P2N?~8+$yQ#novWlpCT&rwNz2U((*=y~mEU@B1HEV6EZ5=D|%+?8C)!szC9P@;`~5t8A;Xo9(yi76R~MHZeykmJVj+s*N)4hPdb*qSz9x zYKk2%TCCFw*uH0x`d4@P-u?Uj!V$+xT|L4>q zrQT-H*DlO*4dLJM5>vQbtYe7kxJ_#bY}mJk5ODk=;}$MJh!V#yRO}2Q=uxa`?t-n& zO|>dR9J*L&W!cQF2N|C&Rcyu#u)<`iDJ<-hr>$XzDl3c+oWkXM9A9PSmoGt@&Jnjl z21kUfgQe!`qN~M%x-w%OlM!^~s;Qvg3RIX??4Uq|GBX^$*s+&uF7yA-XN;h~Em^ds z7wmwZdIlvHBZL~oDuGElvvjc)hNvla#uQepkt2fb;DYP`j?c{2$^-up4|iF0{Spz1 z3~~5kA;Jl4Qcx_;rov)GU<9jUMx4}4;?6F%#0)jX&YZ$!#-D1s%arh{gqo)uj#6zdg*&R%GiE>w{oV5~w@ zOEYZ2LQACYmHNL-p^mr8{l^TuWJ_I9vxy2k-9m-xHA^P@0_zreN#+!)Y!>CtWi7Pd z%2$xOuu^EoSBK;&%(Z%DAqcEGSw$REyiqfwGSFN(6L%tIIoveMC zSEQ_FELrmG9#Y3<$nTJh8JJHK*J2UDPTD_MTGcm%q{}nC*Zd{FPZ;;k>5Rn zNAzoQ@G4q#TPYVw%PKB0V8EH;?FcPouC$%RDN%bnV7QibLxRe6A~?aa17(gV>Xabr zG!|C~66C4ucl;jmdq`CwL31g70OZP%HN^`w#nhkT^qAs`D5H_$SCHbs zlwxpC@v=(sUrLEr71MKydkO|WPO$6|Ge!zaxR?n2gwX$lz;Ij$@M_=~@PdTE`~)wC z1UGQV;9`g7?vJ7c}gGcO1A28g>EyilgH$AVUGWfCC9m8b`!k z(69^Mao{d!*aecK9vyc zu{p&Z1NMT3UcgJ{=-3Mydcivm>;(3^(-L*;?TGYvT^HWp?sC+B1Pw%Z*fWFxZsq?aX#X! z4<^LXaTnAhS>Pp(j=KPn@a&V&v?Jp#Xm>!Kg?yp7T-+88k{su}7CF*XQGSaY72}fx zyjVTJl=rE!L@@vVSCIqdwKVpEs$QjXRlQY*IZsCFhhGf4;JL@KcHyjZewCh?*nQ1i zT%JX8RTxChx^ajQM6 zhK;-ji zw#HXxA+eQ!tK1{z+TWyp!mXM(-zI8Ev zkhU&|y`aO_)Dl=n@>%h0>iJy4UeJr9T>_;WZfUMtbmn0%IC{w!MG?0Y*S4}|Db7*T zNXzw48$XM6t8HbrqR=A=ZoB+rYMVm`S#5IhY#c3*yI}ZArb$kISIgeA zxC{D0BijKfOmn(haWSKSoIItJgwuYiIO6j^wPrh7GnyTB#&hluZB@&iqBve5oGGS?s>~mye zC~9P5xmv9$nJ`>c2s0mzG(2OfTj@BP%y#)x^DmQ*?K4-O*6U`ybgbqG?KClO85&V0 z4_CNJ+BtVJqcT!_RVR4J%}ze9ZD-B4#;)(u&`empDFp5lZCBrXk7hDIcjA#Vjx(8b=?t@Pex6Ft`g^uGR88>w2ayuF$R)cY*o;SFAb52)XJZh74?k zT-`mV?oyHLxsikbiXCf&00q5Z>BY0dh^~6M5ft>Sm;`v?$uoq-!0pxl%a(uI+ zSjAqL)iv$TKx)2jAhMRYBj9=fBz+3TeadpFToAyxPr5+`8(Cm;?aK&mIesVj^GpwtsE3=%vak}=)`U~VO7Bok5}kako& z32-Ff8fHgAVc;%^OD`8A+{P3bD#sCh)6C5o_ z$`J!7fMpZ_hA}9}$XPM?Q89iCI=ce}vC_n-24YsRm>p~kBgbr+D29I|V!)Oi0ZSi& zaUTJP5K$W09hisMStBs+BQWkGyfJh(2QEZU83Bi?P#u_AI(q}>*_Q$656T0m4tQKl z>Dv@Mh^ZF=`+%3llx8dF2bw)aA}8kp4v}1h>THUVNhfO{;{%&bagQNc9e?CpAiDwR z^dxJbRUsvYIF1l2Le>U8X<%u>z&?ba@rR)Chu|lKKt_a!ZXp6yNQvlzhnBq0TlgDeTaWegxRsXs~9Ku3YikW8He9COHC3Qh;-X*G#s zz#B%Q!9hnY_yYm-V1?+@(mt*1li;JzsP*ASph-yBfPw%hkv?8NeUg0iDX`DJt&atv zKSWyY(?l|}fb_wQ=pOqh>qLU+GxG(mr_TzG=*6m}@?U}if)$F@1g}Fp3V3QVUwh!Y z^gJeP56`9^T(8hU06gh2VS6kuJtk~V_M-woE&C#YUlZjq^Ry?rFH!v{bql`ZDGLoM zEMP=fzTo_T)gYkYfK?!1y$UE0OEFGoHouQ{BB;KTsMMnK$zvh{qo%Tp(a$=iO(lhn zT5EZFSDsGX>&?OBlcL=|zACP9)`&&*`agKlt@0F=A@kL>Bg5vCvrc5w0wp(B)Tvsm zRw@>Y&sQtDdE8vEESnqULrfxlgQ#tUB#xayvfNIw{#sDK8RVQ}`H_3I0*3kje{z4- zwO%f9V_A`%8F&K)sF7^@Jc-QHTpO|aIW$0K7?+mB-iRkx;*k!dJQ zb9i>_=t57VGR?$FsDk4SVxX;C)5O(12PhjV6;T7>EfyFv27Jl|8C_J}IrKnUV(Np_(LS zFRJT;IkN3%g*oJGjhBcSLE)@C{$F_)##v3l+R4mW=JL$_4yUsnkEnh7*;cf+okm$O zV>0LWqc!a;X;bY!S|}zp&z{K4|G&l%81sl5f^2gtZFL-Pm%wa)THBS{@l(Txt<~;P zXAm_*3#?mo3|^qHkrb671lF}9!w9TBn_G#?JA7zn_N%j6=@#a4E5%$SS>P;xOHp$a ztekaYS8k=6hjZ`(rD*p+t$QXKQx1J#eJ^nhgKjK4ZqPIDta3|)iOg=d9;y+nwAuSW zZq9tQ^6k`9T28z5z0yvoX*S8`NmJY;b5>2W%z$MP3U#;S_G~cZNDqct_RMzKkwC0K zW=dCR0L5|+RceLJcFcOkE!c&q%rk}|v+Nl|kg413oL${>>^@X2Ugw3?J-2^WZ85eT z*KM`uuzq7@w%CYqwlWCRZwxk4yspkY_{;;pV3eWnTxM&O zqwKjSh2@0-#@||5luoOp@Ipct!4_)Sx_buGIy=rtqXck^Wv$8HGgcH$_Fk6JMadRD z<5X1NZ2~4T*+EuuC1BGQF0U|%oSiwD)xB&|q$728$<6a7bFVBM=ht|lQT7nk?R1N9 zZ9BE3VR}(s-+P&STww*;naRib$!ynml}v6%CuwKSxk;W)y-Xl3w^NqCo{@-WkUNu) zYul-roO|oU+uj`cm`$9KkA-QZ8SV*MW2NJ?8@X~P)XjP(R7PFd!nj$FoH||NeW}@v zW2KAIN+U&!oW;dPjGjTQI-3vk|F7#En!4Yt!)hLu9vD*mJaMRJ#O_izt=QHpWya|l zA$(R_-PmOm&BQhZh&hADq@8XSRvDDD*&1IVDQKrkf|u|KnAK#(aSKhs9ZSwLIQg9g zf>v(P>lyjoEIc`RU2(n<*K-7L^HA!}N$;}Y_KfuI+ET#(h82tiZ`M4|$nUo9;;yD= z(LZksMuxwW0%@VMw1={>8vxT{f6vJ8i*+Zd8;)wxZLn$nrPULikq8+qMTWd!u> z*lcR-&Z1`=luX@5=r(m5ky~z7B(JylI2JWRc2<|>qwF}Ni+au&so7QyQG^+6-PwYy z>z+N4rP~>m)bbsmqcM+)YyxBx)#7H?KZP=}SW`Ivs9<_za&a$Z{{M~YqB9Rbd)yQJ zknDLZ1v+WCwyiZ&+4cn9%B158J4n%Ur*d96F3a!`HJ4UK4M8Rk*S6EG!?kOCCLPzd zQ;(lo{POfPYy2GPn5k=|V__V+oC(9lRv!wv}d6!#u2Qha0!rv+i-4r=^~ULIL+Uty{m1(5*;a>LO#VMQ~>i;|DkI zYFpyQt?n$uu-k!rL$#B-7 z#$e==KyqkgceC{5WOc>&26?=0wP*hSGS#tbE!Cf`@apMPh$@f@HC3fTInq>A)e}CI zlh>twkR>ghDnuqq#bl+iT@6f70LOY~5g7U1_B}8Xyslf6)Up`qu1lP>U7B>&8Jku{ zQ0gwO@PScZXKl&IB7+u)5N_9aIn+yrty|MXw^O?9c&ox5R4p>Ll^uk{ff1`+-C0}! z%s^#EayH#Ia1=nYU#0&4a9N@X=aj zk2M*PY_yEl-8|RoZbk)`J>}GjAtqzTIMpc8zIoUX{AFwUp{s^|Y62>=``c1%DVD_<&)X8H|nnnZor}zY8GZlJNO(M&0+)cm=t&SqQ2V!4d`XsVaP6g!u|1RNNLkRW4w=^kJ zg2l|5e)H+88KMz8kk+miELatBu{h?x#V5M(SQ%{25H(cDftD)fZFUbK!fDR#VL8kGmRSM$|Eu(MSUZSfunYku+Uy<> zq0R0gLeXaT5W{zEPK!+^DNK8c%G`Zblts8!e9gNZY{Qv7kpKU;T05)+ttTpNb`NBN zB;>_@b6&-C+h&uLHoJ!mMcV8h8)f$>zSfIV;9-jV|9`meIi?m@*~n}a8(^_m5p4O1 zHoJ#UR7Vq3(9|=mV$Vfyu2gr!8VR8)f-m$5^UxpT)CrCHZ1bcFA`svr zMR1B9G*-Jjl(RZ2J|a9pLW9Xjj&lMF%ebYB`%O#*F*J%L`ZOMC67!ONjqXUaz5V)8 zlDtcNuintxrs(V~;ZSNV#MNLO0V&qZpn0uyIBGN;Lf3B)U?m)q^Un1oP>t|QE{cu7 zvLsaoYn6$aIrz9B|DS6DdcL%vEjU*z20^a|i#O4HVc~i-(7@LKYt0n$z7z>wtKXzd zj%~&eWpSka=7*=05;ffh9HIr1&+7C^4|d1I80mJgKH4i9fa`uaJsC_3>$-u zX0tH5iVkam&6z=_Wo!1C-(`jw%ETqUP(arFKJ!H_4{kxXwD2~8o4fajV2ao4k~Ab z4S`0ZfrVONRsp>hP?zko3$FT=u4d77%~#r?NYr6%PwA<78E8S#lz=WAOp*WZ$|1Qn9ca~;|0;=jo)c{k%@Hm(jd23UkaDbj3g_r$TvVaIy z-dTq1y^UDFm)8>6doByC=zgE34sYeC>PLDNJ*E0BK+{HpBjOr3J>|1NE~~j5Hd27S z8d(*mjWv79G{2;(UB227DB;;u^Q&A*Ho#OCi*sF#{GTf_z*qvk;n$V2Bvk7vHb_}CYy&-1!$6G@r_y)2gcU{{wji!5<_oi&$zlRC zY^7`~YYP<{21?~@>br(J#;}1TKNV`NsLX4im;{;?b1|iq^2`^kR@7D~mQ+=yK~>oK z260s}g+QT{X&{>$F&9I@F{Z!uTe^anegS<(v4G$R zO?3k+n})ToLDO_4Sp%`5Z6r8E_%xNdWM9c$G_D3mwTxY+NjJ`n&yDFw11YwN;KXS` zN%{?}B0n1$>zXF+sDW7+=F0}fiX>qt)-qaMTcB95uWbV>n?`PunqJdQ)0Jg>CFGwM zIve@_ZcjH>#o{mH$>2o7MDpaWhi>#))TZ2u{|E-55)JL#pH*L8(k|a*=M( zw8=^(>5$&mhgV(Wp0j17R%>zA zC@46#2P+wpSk!B6zT`Z)4R3lkQB`kq_hze`@KL4$xC5Zs= zIAE2Y`~clp;AF38Frx;UG<#1|o8> z@;Q=#9fa$XEDJ;OLJUchF^nW@0s#bYWhXfT2@uF*Fd(nPfb0PSoF-^7X`i9N4U6-c-(a%J>L6@rD2*c%coNCIPv6L5+{0bUarXxIgZM*!jXBriKT1=y*B zv4NZ#F`fo7&Jr>H4KdyZF%kY^LJ#A#LA)Mn#CsI)4~YTmeQ20i97vf``p0Ap)+RQq z{g-h(2@leB3R(b^6G~Dc@4`}jf<>W5r=Vnu4`M1JT~iQ!T2ZiEE^DB)JE^R(T+rev z<#1`DLXDLrD)Rqx>~Sr&@hpt3)>}2rj0fR@ippL&r;!TXe$#?^Bc&WK9MWzCd!(K| zWUvWzh*iuUs)ZUyp@OP`9!I2#x@0lU&o zp|sH8(n%kev1K_@zu3HG6HE45D&*h;V6$~;3o7UHwHJ^rZDnwD2-gyeuV8EK$^x1` z8y#X@I%9?a6;|{a@=s~MT%&~*c|NWSUgq|@;Fscp&1cW4+f~9`V9I1YZREA0QRVY z5G95vgH9T9S*`*by?#|84+QXvIuwd1zJ`A^(4EAUjNqgMAHwtLf`8M2Q{Zv@tu__hA!uh|^NP z!Cm$r^bK&l)d%@+0NVhU<=SC`e$(BSnr^Fd>R3}Vh(t1EW5V6&Ei8|lPms2SAsee< zYxJ1{oPl+ip-kLGjW#bUbH(v_U)iGo*g&7Ttia%?SjYm)e~V8*gy2iqGQ-BKFw4Zu zg0fsIzZ-(ZgfVN%3dsNW)Urci*oHZ0V|K{KrGfWPJY9<&6vyZNWsl1JHeJaMy=8&p zEwKDI05-@D_I0sgzd>84+sX{FG1#b?SGnZ_elrm+62ZQu)%$0%W}o?Bjdmy#cd|m8 zm)XZrG#23i*or<=+99KD-oP3vWRybdPAXr*(t{b?tVlz!7<-);aFH1{2fOemDailN zbyd#V7+ZQliNlyMq}x<4miukEHaj?qrkWj^&aiC*8}{3MbA2TsW9!MQsgYCwX zlz!<2>}rQb#La1o{Qo?IGZ?e`6O6Uqvb>f5t_fPe3cUpGM*U`GSO1oVZGdg0(M|K@ z$8?*=5M_2~YQ7MNnjspoLsH8Q8&6W=5<9rsVS_#sIuYT=yxWg@l7b^mjZjoiEL~uRsD~M3ycDMcdxQs2!$^o!eI|Nw)`TzNiKxYcw zg3I;7+G7Tx6(8O_tU-rRHZP1I#$jx&Vpebg+gPJ3OftCuq5}3%F=>Jc6oqXk?yC)mLhzX#$KjBsNZ;c$U>AND^I zhz*w`A|OyFehY+hAPNGG5G3^+k|$9|LRjMbkq``F&>hSOh%mtqf{Y#mnl-?&LiiHu zk{FAJ`n0`2!#M(v406-p9KkvC=@amvFB!*h<>*ma4;uDx^H7lzBz37IrjcaXH$ zyr^xgE=dHAjf*;z(&X_)xu&VpbXBFq1<4V$N7B^k8dTEd6s=Uz(W+W2E5$FQ&he$L zsW|wAI8oE8mLVn$d(~kEX|XhwU@5^`RX^2KO0Bp^`URF@e<71z`%I=%Q> za0L#*sggKcjsyNErm%jUc#LFdCDCRY7exO5I!9Mfc4*5M8>t&wiS4ikThR`c1=(D- zMl&;p;N4Q;l4Ka6y21voULIk!tWjZQPYSK-n#gcE=N_l~12oMVC~VOWx+GPzfW?%J zW>l!Lk~;iuK99AlvF;GUH zLL*hd)t-LA4#5)QD%Y$o&9qv#I?kS!N_hGuY>IKzvODpW!u3U0R7wL~7gM*^p?PH% zg+yTetwlH8Acj++!!C7m&{;)Z|4y{zJ6=SF>UdkDw*I;;C zfiLTWh9QvuzrpgLORri=p+N)ubjRejNhOyMwupe#+r8$VdWZGN8ivG#vt3ct7acRi z6{hHI%oIH%bn6d8V&bs`@zu1drBV`TE|$%61mQ`zDXtksvgqH>Z1-Ep#!)Tv56 zE$lLb2#|xYU#}FcAD7k*Lr7-5PE#{lQ7cO{>lC$EtCBFpX2TGcfy$NUw5p>Ln_8Ws z$p0_O6_Y+PrL#s_l$B~@!O1CJQ8X{1j{qg@C5p>N{6xu2=<-J9b=Nj`;izK6^`@kN zsxMk0b!GndXeCWutf7i?YDvjR2B#a1O}oS~@k;u%s%w#U4wn7>clVyV8i54G0|JVR!jzqkdM< z;woexHn4by3sxBQHNCXGGhA@BRo9er8Yrj^RvYz$6=DHgY4HvhlyC>?Lv#QMQz`xh zyrq}KL0C=+x--VffLrWS;l(l_umwH^ON_uc51{VxFTkgORrr)8?Uc*|q(NXU8J_}{ zy%!673L?@lEXZ}RU~POs9DoH83l<5n5zu2gy8=E1Gkgm0ESeKbfqL;T=;2>L)&w(CWJm1vj{(C5uO&qqxclC2tQ^Ke#|2Ln5YCJ zydg#eBpA`;5e^LaC$QIONUQ>!4%nKCF9ER>@Dmu~XCb?{X$d|A_zU2uF`)Saycq_# z1rSXEw*iT#(8XndGeRHqS>^BJQGl<&1U~_M18_>{QJ{yPg_wO3Qd%ScB9I>TQ``ff zVL}CLKfpO0uPpp7Vk%aBxJ;uvWMv?sLMZly@|__qL%-*Ia)Gf&$p0^~Pet}g*kh$z zjxA)%Sb+LhaeVO+n5H&knoLlNWdho?_y{lCl|E&K4rdQZrE=DuyD=_SKeZwI&2NCkkg=3nRyvB!WL#I)(qH{DNBoG1Y1v&2EjIF z+>9COsGzx9lvSOZnwnXJ(DgwVpAf&QB3PFh8WA@{gqadE0p*2M2=y8A|2Kt2Sa5eS zR`dep%n{HZ52&+-7)LH#sU5H@^T-#=Xxe%VQGA4VM8G*V!@Gd3VF&Gs;Mp*q}4!0JFMALx>`1O6fn(ome6D~pr-e$bk+typ%uQm1yq}Mf8Jrzmmb-< za0sA=uY3-Huz867e8O&zDroAks7AL0bXvj``TwOBY@xHVM&@m|MCIaG(EG~hKc&B#t%k_^?&fCk7;`tpr{ zdc0L6D(mTM096gN{geNefI7CTQuDRJZ0cd9L1F1gMyoB7B}X(sNm0y5t1Nt_qNZf# zGG68@YiF(~I;b=&3MkXooKp5k@EtV9*Q1pxDrQCG|8J@HgQ&nc8WfDpULV!tTrey8 z^r|h|U(vIw7cG7AUukZCO}BAFFI6;KeefEo#k(F~Wmea{n5!9kR9n=p7SjLrd44Ue zYKsyevH=r&3?a0Vrp9YhNz<4e4HRu4uz8o*BURGD*ETS3b8S?B-uu#;NTo}z(w_09Rv_vUQF-@;pO3f=(v89sUN8>PrMVQTV8!-h9oUdNtsc7ol z)50!8hyc|$wV;MIjm$UEd8;@6#IqG@So&Twf_!JR5{8&xOOgM-&ElXc z4p2&CEZ}M>HL6j?eo2pBQtN09Rcx`aM zWf&6of(UCK_Sw)atV%js*f!A8Xa(>0JT+`8GiB?CAuOYY2pq=Op_L$hBVkaP|*L1UeewMJB$iNg<6zk^S$n# z^@kxWsfT-3)2fb2#D@qMRUPG&bQr=SoHka&mLYUWw#TNMs$skXgjVvwg&>JY0|4b% zv_5oF1=%z|KboWp1Q?hTec&jPDnyc1;b@X7;Ne3YgcV5@qB|s#nC=%B3mvg-yf{=? zZbANk8SVxR7tpOqEH{cd3|KVaNPvTNFm7lU66c6jV9R!Yq}l%$z?KE{vKikhw#Ec5 zEN3O7Z2jDVvMN@7Hv}uA^NkkJ%S6cRjncV*ZM=YPnIQ+6F+-WSquK>@8AkhMz$%Ap zkNigjTM}dk`pn3Mp>2WVEwKDI0Jg$UMfc!_eI~&^a%{`Yurb(Zxbcdq#Q*)}nPg}} zI1GV(ag7CZ%@8?VvzcF+z(iSD*>AoeWxSQcFM}mnb_1|Z1DkPKuYw)4Id0>AL-9M< z78zo5uwy^OqpNP#RyY~0$nCS%0=h6m-c@p>dN9yuiAx3Nl~$u3OUzIPOXh5cxYb~@ z1{Tp3lmlSr)nGUG2}?+v?P2RP!^W(@cJmcJVaWflC^ggXH=huOUbrT%dKmfye{Z~&|sk0JlRvdYI|ZFcDOpcl@{jo!jm z9^}_HKmRTJg~f|nSt}1AbFhwfC{tqLy@d-bQKGM6h#XCO6ac$&OjhD}3oQRFgPjLo zYnCBO=vEQe*PvLSvhkP&<&GLQ1dGXJdL*n+aJT{N#;o9Ihca=eYq5gj_Pnp`Q2^{p zRw!}11(yE?z*daMbPqP{Gvxn^0npBvtjrJ%L6^ZslOXpRnOh62QOv^M1WK$Kl&zj& z8|_d=cT#!_JK7g(ER&RYbO_BLL{L3gro!qhZ^bf>qNyhCun{XLMYB$y4J%ne29jQ% zA^+dI7HE$h{Bh|axNN|ftj>ja&7p`99?3UbB@|6%0){AdEnowKvP_sg`nt3&XompU z#zwMCJ6PVzf6HL&lm2bGc_r?bM9tL>l~l+vm7@T*>Lsjomeq>+?*?EMt%#u8;4SPA zi+oJwtTbd}xpBi+n#T-fD)bs^2H`Km3}tl7U`tuvw)o`KRT3QF_(q^h?BHsL4f;)* zMob4YCOhg$N_+(DP#U&@ZpENXX@^=OI1CZ!H)lYWDH_{vC9sMin)Df)bZg8PGNmeU zd?T>I@tD;PC3K~u8-dNnV-}R9fc$O# zjW?p3dsp`^-RewtXPtL%Tz|iF5O+TM^4^WT&a89g+D_a(-?@I{^4^WkJ3qiP)6TWq zSFhgeT)lYn*6xfVm-lX7+Ku0g--^Bm`TzVD%K(2>z8Zgi=nsGKvnOBJ`W=7%{Q>cC z`t#vr)Mv+vL|DgmHC&Koo?P=#0W$D`7VLtS4bF1rd!k?9pc5`Iz4&8^o6!E!j_$8Uw~4wui$R_Moi-6dp`rE`whna){shp&AhreIA@8E6T8+1EaV z;)qSZ$6grz_$4Mi$zuBi-W>GFjY7Eke%j|q_N9;5w4xs5@{(6K7kV)(v^bFr6aM6P z)gN2k*v?KbM`ZCBBcDm~?2pFD+*ZUMG&aH`%utCBFMNf8!A+v7VOXbo^;N?L@J91Q7n*i8w_kWPr;K%jw?SOzJH9nt}1aNo!G|J?i&39umH6edbTNGf&mGjM&9 zfO9k=_V{o<8Yo2~EVZN;CPaZ4c1LvTlB^e!4`JZri5M)0y-^Rwn^Fy!5BrgODV`RQ z_Hp(BfVTo@v5%UfZ!w@r8SZ1c3)vU!7x98u&6rg*AAO1mZTg^}XbR@%@wf`}2m(Vc z>81Q}7LmqE5V?VbDDf9X&>x`!M8>tm6s|{^2qioR$ra&=!x8|1lp|h%AN6>0AUen` z0al`NygEw{m7k&EL?4kChLV2t9Rf&J4z_Ic7l>a%HZkI8(1?lGK$>Wp#7-%sWFWGS z5HI9y!yTg`BVU*BjBwC0e}E=A^L>36#|NK z&t#2WvFcrrANHV|7H9b`T`8*9$kng9F+K>@6i42wTM>C|Kr;Zx_=0!VNR)><<3+@o zgnCi00kk9!-PYxT|G$IeilPSq*P=f3H<9)+g;#x)Oo~{N(Zk_yJ z6FjRyIe?&AYX3p#iht6Lz? zaU)R8gzD(zuq=bkFbF-h4pzwj?g~}34!9Q73JQe!t9)(ACt4DUu6%2gD{T)pr`jt< zE9C!;L$T~DMz5Aub)xj*m_bdcumv@lQUxa|GN)SqUl3F+n93>D`k-8Vy(v|r5lwMG zq^DHK|C_}-8-XhV(dR)>bsSWEuMuxGn^rXfRgH;zr!lB7ecY=-TDcE2KduC|{*=VaLE16TRKczZutZeJo`#n0Wkbf2f*Q>qm=@wKSb^LoRt$cdaowc;8 zqmF-X9a`@6+bq}q&Q`>{93j6m@_$n6iA6y0U8?ox_DCxDTuJZk=Syv@i)zhvraDAl` zlv^M)&+@OeD_K@poBftVx>>Q%Q!S_vRffoaFQ`|Kh+Z=1YFDy?q(4rwONB?&gDt4$ zy?6R(h5Yw}j9B03mbdEZ&gARhqX|(rP`D%hPQ8Tdz>{lD>s@KFYEG|~RvXX?`G324v8pG}4Cx6)71Sap zzJY|^^AVpH&i%Xj8Nr_9U({dfgQ{;L{h3Es{YLc<^wawL?p;9X*l+H|X2-?$tiUP^ zRCe|f$Isn(%W;#PyIG+nPU8*$6D*4Ogv%*$D^0XW0#!=vsO6Gye@ku=&2O1!1>3$O$5c$6lpH`-C$l^J(7miN6RJRQ*^jMJ~C$b0QW5TMa;#bh75v`E_FBKnb zc79BaT(eO{TwAP)6sbOMX;n>|;+?ZfE9C!g&qVI5HnMGCMu8$O`8xd@N{eO!>nP`0wRV8Xb6?@2@BmeK%_?=WBwhqLo~)p;uk8(7hF)dSv%#`fmlOreNf`R|OR56(q%!wQbv@ zZf{X9)b3qxfnb$3a0`}?4Jf5DRBWA?q$4`W4hfu0PN2m zR~8Edv_>V-;wozc=EFjOIU)m=IhtpF&$I5_T$^@nhOJ2imGo!KYJmPo8mvoQo6tlS zD)In8EG6)eZTK{}aWmi{03#yJf{=E}Pt7BPKK>jb&_TyMu z@JZVA>_n2jo!taSec?WBdoWCw(AAetE98GK*tahovlgo$1wvdDzSj0&m@c8KuPm*Q z|93awvsad0uNtk|Wd(Zt40Aj3|DINeXSk7V14Hk;x@$+x4DGT)#p1%tURFT1l<+NCcmC7 zb|C*(Mv_NOFK(*Uhj>(`NZpn0l+5<(pA^rJWKlz|$ohm`R*1W^sVso-9o-r7y+0lg zMyx>a@FecB<}vGa$91)Z?ltOqKbBnRjJ) z9LdmYkPVx(BS##u+0%}sWRQ~&dit@rYw#W28S$;RXil1K(QN%Fs-&j*^;eyXD=CHi zUkymwS*O>r_)|M#RfvTdN>U*)s52g@|6x^kvyh5UaQYUr72 zWZS?H1)5)Lnc>XR3id+R&V`c9N)v32Y2O&9Qy{~rjf{}(~80Qc(pPXuVUf>uS+ z)}6P$6Lr*a?^VU12>MP;GvA5%tL{62{QugLV)0*E4PQ}yq3~G?DomHq)iX`2)^{S* z<<-}YjTw;tJ1gYB8Y{VTY?!rJ)e*iWdmVNBd#93CNA5c@%X}vmj_(BW|LbbfgSW9K zd{)}z>{PPfIt^_b*qB-;&UXU&-`Ci;z1X-H+dePBLF1|G&Noer+!{p^|>4 zrBzF-OhKM-WSr-uC1dX?OAU_vPg%om&I%4gG%M7`o^aQx%g3$ngyTce`cCK^ z9c$(AI859LY96))Cy6xHk{Ay2imYDTLg^_@We=Pl`*5neyl zvT1W_wX{0vv_k$Dt8hG(y?EsQ6N}7$V(Iu#w7wH%?m3nGQf@}|l{3^p^?sF?5MERNb{Tda?DLDEmveS6bhR!}?Aj|6g?} znjg2ZCvsZUAFbs(ky_u0n0(-E-j14g&l-BNPTk7A7E~35kpHih@11FS9jX6B%Ufmc zslIZi`AV97>Kcgr->>ek@SRiF$Z#{NufFOHJSyJ_#y8!5+>h=o`QD$5hLbqfz7vBX zw~}7c8+Iq%xGRqH?l)(>QFq8Sxvu}Z=_F2G^`5Eb+47x6v_k$Ll#7P0Gy)eYSiaVR zD$}Iu%CXZbuBy52`f98igIx`(W{%+F*n;xuQFmr&h5SFPd#vfbmh??2bqWWG&6}p5 zY?+}s#a=S4kpD*&`t>Da)?!sbfm6d<75KM&b%J^j`F~u|PxV+Hsuz8)ibH|&v1~#4 z^r$;)X;nuZ|K6FU74rXe+tgFn$aTFcPD%rPj|#zxJ(!LDnFtiarQRl9{EqAeKP1I$ z(e2eQVV3Wj<==&~z+8T)*_9gKi7T2HYtt%BLAlxp6!QP1 z2qNrN(Fj}-RQUYW29;UYwbeT|mhWzFVWrpo%|zP0=pR>U1OKT}Tnj4G7#Qv2SzJ;u zeng5|P*QIOu7~-)8;`<_AXkITkkLqr3x(pY90jv^#NEuLB57SJYTqMeMTPu7tu2yk zx$;pNTnnm9C4J>g)2el;sOt9c^^?O4$p3+h_d0gd=X=mCu! z$yjTUjghoH`c%}@XZ78npMWivnb%vN3L#05RvC?4p9okIip-(=XPWfV;I@IGZVz8; zX%(hR=;{fh74rWZ&8zK%Vb%<*Y*2GZzlx>ut5`DX>DfFV@j&}kC_jxh&qtY=PbI^Y zn^Aq`6=)#x|C?%uw$;=r-#I#ZwRt|)=#--)dpqiR)yR(g|K_qF=T}^%_zRI&CQestB<61DY@JBkpJ36T{YfBB=GOQd(0b*g4kk^8edcVA+r%UR4hY zk9rMhl}lUoQ46Y?HpM$Ft%?+>KKE&b{Qro@!PN!BcYJV%2X*Q^C`^-E?}@5?=X&`x z%stgt*Wjzxd%~_zhkxt5Cy@UiEtWc|z6#1up@{4z=SSbb%#hxCPgHftdfpSm%zI+o zdQa58Ro76I0d0%?{|*oQ;lQ<^JPHH|UUC2Ak-hbvXx@AB#H5=JCGE#@(eEy&qwaDv=`Q=T?lN9<({$NQ=W#ck z^yDdGQ;hi8Pv+f8chnv0G$Qe=pLECg+m3rlkHcQSM+l1^DMsX4)nF_e0dMgsK12oM zLItCE5D%#!@hTYD3Nmm-P~~%gj|#wt-BH{JcvpZ&pg-s(px?95%Rs8G032YJG?Ajs z0O$!o#|Cu`JYEmDY9P=7W}z$KeSmiXK6L3q=T#EE(mx&G0P}$NI8UWFJ>ZKRcw@2y zT!6VOlW;x|&;{>>5n2Fq`x|hR<_c3$#LZ^#^gAi~KH^2;FkfU8X622x2Ni$=yZ56Wp8k5x_A& z`|w!b&{7(mp9!M*nQ&r$HsClv>qoFsekvJ!@-w=dyHbVD*(1^SgaVT+6A(lJ8EL|P z;o3~DMQ^+jUAcC1@5Zgpm20=Ica}TL^PLYbUcJ3{v$M1PAbs+2dSSFX+CKkQ#QXnu zYeJ|>^i%^MOO9vWG7Ag^oQFN!r_dc3VR2?;pMC`h=l*gB< zJ@Tt%2->B{%3^`MEcpY>tVdILxlQR~uQjSP{b5x~de=+1y|*s-_h_7y9} zBL9E)ok21h?kBN#jT%5=A{cgPMfl3;8 z_a!W@gUp=)lg|Bw*rP&>T(!mBzLIvnxy84L)FMtRMM{w``-&+ffV)&XsRlf;fO|=E zz!L?Sv6)i5Suc1P&n)2nup!_D@DyN#Pb9K}6blP@P_11uDyRcUu~2|fGZONw0`SrT z9D zXcD90z+Lc@cTyGZgB*HdDK7nFK0easOrR^aj^(J#*Fr1wsoZPuuJEg%6H(fNuYIe) zcMh$`IljG$jzs={j}MeH!DdXO_G2U_o=g^K|0zc(#u3-d^G0DYQPCd}Ek3dIwR}V( z_#{SSS=mUSu-1L%!NdYG4<;6neZw0-s%r$GsW4IREkMOcNjwuQv0O7BnglCs+4OX zm6;@>Gn2&EbV;I>W_J!o1|kTQAkLF`Ki0i#o&wdw3~S*sW)iN^O@BQ11VBrT>D zJ$WHGt?HRprRD_z6`57ai(m@=-c{AAdGV^WD$y_3!5nE#U_9_0^XAsC90gJE6>X3V zq+hU|-AP81#dv=#ci}f)QqpVm>3DxCy_U++OrBF(O9r@?Z(RR?;qB$UuXGOL=kZ(7 z&AqF8mu_{YyPc=c9_%d6cdmc9ccZfteQ@!{tt+>#T))Gq8qd)IDtZe0JUbMe~c&h2aOT)z$c%bjb10D$J^j?Ul|)U*5a1*V&=|+4;_e&W^$7buPRTr|D>pmWZeP9nR&-;}()+FGgBus$d;enR-ou0R z<0tnHKD|5tB%OaPYu&;$II*xV!~$(+wmU!nr3*XpZUQAP(_^>xENRS>&o4ZDcK?0` z=<=1Dx2{~HUthD&QO@i7Bztzc3;5l|?sl|oA2vYe7lwJqOAqaK=1#HBrHeP|I#v3- z6cIY?CcC}!om+Bpph(0;F75Ws#qHU_cBG%>;_lF1{`lU5^!|3VcNLJ^Z)|t=u3e4{ z*F+ifO`Y1QHbZysE0^{@xYfyc#J#5(Z1(os+uIJH&gH$Emv(3RXWqGZ^U_=1$%y65SG+aFxMNFQ9k(Ydkr!PSeG_Byke>Th-C7v`^TU;5>j zF6ccc0$-R(io``iurUgWV2f751}ILl3=o_4+%VsU=M=IhJ3g)bs6Le=!|T znGp?!6U<}N*?5qQNBw2D*GnezUVpm;_w@kG>F$Gj4^bLQXM8i>UEX{0^x*C{ruUzv z&ei+Vz{Tj{!6)`f*xEqIx*WZ6`T9rEH{t)A(N2vry8hA4jC4uogByF7_AaAy6cN!f zRtM#DcyjP0O_kW~Y#+qi`3;vqWwLtB{~qN3b6elLCI72GKl#pQPtR@r%+DG0262Br zWb{28B;DbVJ^smXF=Xh1&4Smp>Q}M#V6jND`H8Tae3b6yH=Zt+Y6OrCCG3zwaiw}z zf7$7(;g{?VudX3;Lp$eJRsB-s?=;KW^W7{GT@66 za5bvy4szg88M*=<7l4nF*>If9hg1G$$%H`@1dq9jxh)<@53tK8Ax6t!)Wi44bjn~k z>TxB;8FN50<+%24x34jaY`bYaBlP}Uu&gf%0n%Yi?+=o>t~8kpG1EmD3NRH2vBz<5 zCWsn5h1~p!iP|N#SEZ(`5Q7egq%Zm-dI8dtCOhHc0!$e;@W71g@*58ZJhxOmrU5S~ zl`>ez>Ov>YF4s{ZusJfNzHeN&xFAGy}We&k-u0Vd@p4zQe9%$x`9rHr;peiULgrp@WN z%G_zyQ#Z3>I?8QB)23L8`6QaqMboB?&AGdliIO5nkIb#b+Spr)wNYtE88v$rMY+(- zjyRni(vFCAE3+TcRmy%ioQv_X&VHB%?S~tf1ew+OCcy#oB20>rVH@yxaV9}DnBqZ% zYIBpIon4R2{Ms>4GXJx}i56aDuSa7N^vr*pD5Iae^Q#SiJY@}j9O@Zsbce&-c*hA+ z8#3DUmr8ChB?XLjSaG$K_JteH(lcZ?y81trI})5i=T&j_nC zB;dfpkgH`&76uzk18M=KY>VQKAiXcYx$(rBl6p&4WU~*?Fv^rV%_WR4TnibAta-*Q zYmGwD9W|a%a!YY-&v8I1tC_OoOuMrMuT;;HLka$C!;I~GYfrI2tUblz?ipt21@#<8 zXnI1cSo5G~nBh5Nm|#uOp^B4}pD2G!2e zYTAkkmAml9qgWhjW?zMe>n3W2M~?`u8vlRp7jE&t{a6b8y>~u4IJfl&-#Vh{4q~F^ z%E*l!MKCY%KcW&)PMc3{rpG+Bk$GP>Z(=adIK6Ia!wW;^O~*2|=}%6`)FvJcnWC6k z)GpJ5&U5AI zUh~2^7^QOo)q1i7Jz0?dzmM_X(Rs6EJ*f^(us4gHjVhB=?QFEtn`PX{lSRB;Hki8N zE#yyKg`jHcs!9Apr>@Q{bMvXIbx1Pv6W6!KpSo`B&C+_ZsM)qRi>~lG(@fMw{{Mb+ z$Q0>#yjhr2y*l13ArC)8;GE7U)|;hdsPIu&vw3T{2z#^q_9O6Sv4)Gay;%y_VrUbK ziZUaFJXtm}m{5nouijw7b1%@7g-rz7=R^EF*6?IO{{I0?9;eZp1@|2Jr@UHTtT#)+ z6Gr&!xV%{^+&1hA?^-S!CAW!>uH5=E%lvVPJA9881b9A zc=f9FNO=Cbad??qca66h^`EyM2e=VjdGFeF{9u&hIrgt94j) zq=1%n%_Z(_>|-!XlCoetlw($PSugH!nE6!;JoP!zV_-3P9onn=n8v~OH6R|+(xFRc zDIBTwBv$`rTZGK+cuS}wecWRxsXtOo*4UOyy!My)ld-%wlod7BCiy2zc(NKe;a^@v zoTuf}M~xOg@siFqm&NoYpFXaaiUsWrw-5zzD9~5(0=hC=k^g*z&q1kxcBktbH$cAt zJjVu^0gFMbX;FtPysHIws39B6h6Ay_;T0-3fXoWLzRsI|D1X@chY%O9i7~|BNS>ob z3?#cl@$;ABYCRwGdvBh9=$&EmtDpU-2-X(QvkOgi#l%!3mBr$y7xZPieNDF`!7n2t zjkp8z>6`utk%;H%14DcBd?cNq3L4U>6Z1s@WvA5lZ3S5;TSGxU!3k_UVWwh+3Z~{l z1(PC1!aas7ge(0I7){FsvL-QPVWDEWKh{1UV2qcE#=Gk)7xuKVb;)NZ=|=fzk{IPE zTd}&hVD=}{!LqducM(j*)8Uq~|9}23ZSlYTv=lhY6!-(5e)jC#)}Q_6;l>`B6PsPt zF{_~+@gEeoRwZIe2F=%rbz)=e|NHp+hbqjfMtRT*t0XHP%o>|Nmmewp2dLw*bl3~V$mCdd5*pmi&xsy)p42g? zq8)vDG`3f9kO){iPtZ<6m6>Bm3+6wpW}Iygk#e*iOP@u)Ssm3UA{en}GcDq;THbeK38V zZ4T-k--e&v=$pwpn}_m^i~c4eXM^K;VD?B z$?aIBAZZM?0XLn-SC4=YPFI~_(^Pb0VUl_lM!Bh3-r(9>+ z)@L70JTX_^#+bwdZ@615eW5t`GORDpS%^Ig6*KfEp7Vb&%)?In1CY_vaVn!nZh zHYmf9@6Zp6!HLxRdjJ39tu6k)h|eE;{Mk3oZT;o+cot!DqrY7cuttd!y9iUJP57n}06w2Es|NEYi>K4>bj&oTD@2l@La%w_%43Q8MtqYb&CWx)zc z#k%)tS|GPgDK3U1|35B`Ener+>02b%y_S8m_~1swSg{gfinXieIzF$vV`->-%y|2> z@pr8p1y;<>yBo1tBmVBo-m!%I|3nrHxH6PSccz8~XMNS&)f~sWYMv4%SE6iq!9#M- zgmTmpXJbx23e51ugX5K4HJ>$G@jvoa^ZZ?Llq=>hW361~{5S;b2G#FZ0=-uw$gVF| zNunay7S`O=p0Wm^Y4RAtFF4}vF|3o@;I9&F*9`^hn5l`x%Ua>f+gJ2{XC9UJEWLr0 z?mm7(tlH(y^KI-6_+TyvV`2soQjq=3gWi0B9cE7Ihk0)>Cc4#pNsb5hMG#dG;aHMO zXFixOi5(ad^pOZ_6T+Ts?{44u;_hO9d-wTk{Wl2}tL%w{m0e@K`$d@CYU>dD-{-f! zy7gVZhp%J({KU`u?D@H^pZ*oC<*$t)YJ-!umcQ&>Bd=fvjxH-mtNcEn8#j%V18A~ZY`Hk8(6Qb<{JOq*Mk&@q)envDixpxJ1n0rLM( z$=p6rxDE6ov+BXiPg#UwuCNoV5$Hwno3axePmmW#b-X5%E|%F%O(v%C{?DsvGAV2Z zK>q)rPZoU!ab7^$BD=%?v;}%$qNqO23@0q5n1;3~i^O0DZ#9qYTV+5Q4NcmlEZVP| zU`R*(EhZlcJQ; z_*m!emGNLQFEo=WN2dJWZk8>_WQxI^P13{ckZ9-p1;V?`d<@0iZRg?iL26SBEoM&- zrUz?TMK0aglbkf#-t-*5DapXIGpC{tFJ8KR`~A$BF6_NWZl}59&ZlD9e9LUlaGbDm zKR=Z>$asS_Nf_iOUO70o4Q4yr%ZKw%-}vIw?cGjF937pkr{HX#IofLn{7<`YCuAjg zE4p~~7CEVIU3};2p3v{&<;$H**RS4w|61phPdc~uzH*D~KJQ+Mq{E9ZD43K)Ua}LB%Ynh$IQv0^6wkL~GN~?Nn;)rMH7>ob*RMhKNW|SU zMfPkQCYwqNzTy4Tad~W}fY*iP z`BUX}(ZJ*4MZ_r}TD=Z{@bWVrx8?)G$ofa7-wYc_mVL|_kCFdBB2#^;^=wQ|7U4z- zZ9MFinW;4&oWwY>FD_2O>CJfDJBp0QYnl(pCB06@<7p?G10QalAoG8d-S^V<_us#A zYkjy(d$5C5vnb?kaRYEvfH_T?_p|FNlAKQQsXkqG(}4$fx@(Zg<&XXr?5%o+2h6ZAQjuh z)AXP-yRiLyyYuaDGj09mC+U;4GbOt-p?{}u^xld*>S%9l|E4ShB(?ZmE5HdFj_6r`zd{~eDdglbco*rU!n)fo%JBtTNij%=l}Y}Tc7*Iq6ylM zrNEDW@Y$#5w*J%?Uw|8iH*{*ZU$xt>Uexw0#{PeZzkg=)+|i$;_a6`1+|fsqI~qN( zPG-%Q=Z#G?b#WKr`}23mpE=scd*s**WlB3{c1*|2+*&yYI`nt9JI7T=e_o5S5aHw4 zzmf)WlUL|h(4Ai5yjYCMj+;HOd%%q^ync{v&pdfpN`JMRV(XGZ;`KkpC7 z(_qP*Judj>z<1-L>c5b5~-DCv&CUvby~)}ZmpoTR8-`Hp1Q!DymRCUTt2 zB*AJj=}9gH>2&^e2?>!?a@d2nmVoQ$M{L!tX43pIXf^~hNm?RUgZF5J{Qq;#wTV>} z5jtZzlla9t>jr|Jl13vP5W1TDD2ow)+?!AMBb@b&{cJJc5(#?>AIKV^gcKf-TtlDH zNa5}oNu%QdJ18>F=#kN(Vgw>APQ`jd>Pt$a*U6IM@WMH%3nfN7uDeh&9t^tuA?!cm zeLf!J?8rBPV|xo{fkLH;cT>by_ZJCA`u#;Zd-idq>KXM$lf1j55veXVG zHSQ%qob`G=Y?){aR5!Qh{bgU0yw8WcYALehX(Rd^kz->J^E*hCpA+x~`$@Mz(&1z= z-k(lcl+99&D|@?2HSW81;2e^h#de;)Uh@1&j9nAF>KjMunEAIf6T}0=K_Qab< zr-*fF$A<;57q}{ zb|HDQTd%Gq4#QIm+8M(S7x;R{ z?i)SJp%he0?~*6YUHHMSZ#_Pb_l1Z2{|iU<(tDDABYpBTz5DFpqbCd2g%)?8vQ{xa zcpB#!BG2mEF!c7Mhxwqe$<&q>A1EcQ+bEG{)iRmmJFBtK-%EypUWPasFVti(?9Rv< zR~lGUXWPR7u#j|u>QkyI_ZBrz@Y74v;=saE2E%gxoIQe+B!l!vDmGDIC}|@GD&~)o z9l99QYqC7jWGc{YC{@Jp)(*KWLcD<&)Sy3kld}wi`E&NDmo9aa0hQMz1tcpa^M3y1 zh`ZER{KP%U;^z<`CSrluA`*t?i+Gt}c!8|Uo8t+?^@YSLU>L8aEqyr}@Vv})6ku8J zD%POSUu-%MOh;G;+-W8*P!+SML4QA97N%6Pi6c%67pJ{sKVB3r9?O2d@S?8L=y~Lx zTUkg(NRPNo8Oc<^4D96A)UcM4CE!qitl0@YK zZUfXD4M|b}6Mx&GIJA4xvNCPwRZIZP#iX<;-toVVeJ1$`TG||<)CEM2i>3#p+mhviLD6s=&-7TY8~4X# z2UnEn#tC+H(_F}F){47nU{U$Fw$6|kE}dcBSg?k)!GiM3T^E9MFMKs9IU=K9ZnilK4({l+PooKD+<7JQ02x}gf)5Z>h*Uz+Xu5p+p<|? z_N5Ek_fBNo2_0i4-{~`Y6D!-KOPJTtmW_k{N}mDQrg6Sgj!XMGSr>0y$AoXAg&gS; zz_+s&RD{o{*mDB+&%b7T5^#^$yShg#7C$=5R620`;G5sCdy#hBR&&h552i}BV-osI1<^pHJ#ljN$HN7#fU_Pae94wX3-IBd`?zDWavSHKTY9^23#`9qH$ zaW^NKiA}sM(PN^$uUxr#>t<)Cu>H+Y;iA3coEro$Q|`*OOSd|4t{WabKDhVb-nY`M zcQP*+-3p!m>*m%L|BvYNlfUq@A3V49@BgZkV)#j-JFd$xvz=7tz01jv@Xk0c^Qz-Y zbce5fytcHnEn#_>F2}i}lDLrJsi|C1i45&IGAN%YmQ)7J2(eD{Ag*Jqw47AKPldas zcw4S;?lUX+_`iu`uIKhzTeRrcCl13yd|V^ft*@8)HiL#MWg=U#o%0g+nN@>Up% zmU+6Q5~;k)iBO$p62RsUMzs$>E5l!`2K%d<;g>7i18fXcuwo zx`4mK+71iiKPI-Wgy0cEw+b%--jq7fPrSyG^NDmnpp6xuqc(#^cNWTuh)Ov*VTYBG zPYiwLQ>4Y(#!uw`U+phsS*W=$Ld>R5%&VAyR>uum&IEcgt%5Ev1ezF_*y>c|VA1ii zxr2NBur;O6FwMZ)%;4D?JDKX>KD8L__a)*?EJp*`iz2Uj@l72wDUwm8+7+Zsfm6K6 zhU^uRD`FmWOoI%VR8ikD$c{Y%+Iahjk|eYhCSl`cfB$8L3Oe!jPDneFy+UL9jJ!h} zt%wpt$H^X9yopQOh{6UBne*@6+$kG9JoCw>R!<`C--k8mM?62$f$GsX$r)g&~PK|3b3|r@d7Q?`Pr{>nf z0#oD$>5%d8#@;2f6CgJu`WC#|g|9z*bdctvfIcLKwT|PA0apj*j){~MZs5_FA2U1M z(ODbc7~)pj9gRoXf=eB<4ZI1}V`sm`iE?WYmF>gP zFkvI|3X|uVHi*KT|1y97M#eC5&@#>G2|)GgSkaAVORmZCBbm17&&#o*OWh~Kdsfq= z9C*IYdlvcsH>Cx2x$6|%)`M2abj%*K#9JAuuuKg@GPNGGC(c+b8+vPksLYprwc!Vo z)`{5NhW!6q!q~F+5F;@kwMVHn7-ytdSlju)8Xof^G{V}?YXlnXnlg^0= zTRsw!1`3-_Bna&xmWtda{%0{Sn`cdma(O1PcqgNrwAUAc7yKU~t< z&9I_g<}!zi=*Gos@9kwSCbL09)D$CsMYwujYeeLqz<<7g;uU@_W5pKkh zjU?`59u$M0xS(R-)RxYvHV$)s#(Z>xR@=<3YkX8C<6^<@a=t@0Kk>RWfdJQZ=ACC2 z-8!3jl~K89HLrEEJz_6gZv{w4>pz?W?Q1)}7qJR$c43easFBH=U3Z34eQ(;_nbvr? zKK=Urdk5)VojsxRe7E!X$@Jp~)4K=aO?>zHy@$(3JI~)#nJTUO^_vHuK29%eA55R| zNDlDjdFQ?ebNmpKgRy21CJ1KOn(^C7JX=CkJTnVw7AB~AgtDhws*>XXh#Hf z#l}1!GDac5r47s522EeXhgLX^j~(YSSIrLXSh?N}Hc^rCU}f>|Y-A=}{ao%U+Sllb z|EQLhm4$N@)RY@g;l1-C`=GdAsy2t8%PTHh|HQUu!FX0a1&{InpETA#L(|O9Q-In= zdKXP2OV=2{bL)^hC4Q7s!bA&J1W6wC zm}a2~365N`nLWDGXRo?M$+!IgokGr-?)~Wmm{JA1@J!DPmjl}$0Fdnq%E>hkNat11 zWOq8-6-;O5JQ5QDU^$>><&Gt{xksF5`NYJ^UJ?+j;H0UsazavCgmr@^DFVANlhHth zP|*~?btRJY;EoB6lPm&py4q;Q6WX70s=SXl)jpNuQID-1n>$HHchr2n+cX+eT;=d4 z{!(-;{&N^DWYS&XvN^M6CzdK9_^K#DvIiWqQzbm1YRHl$BMb`ZPXkZKaeomGThuT_ z5p>DSC0H(;mSO%l>=b#0&=){}bghtBp2!yH4e{{Cz(djcS|hAGDai})z2!w?G*#AJqZ9Y3ku z6BUF9oj3ns=B;Xv9p(1njavf z$^zHX5wEAabL&EvSthg#*7lQwCuu4(=}xi&CI%PBE^^sCy&x0Ls&eC&07 zW?u2cxg@iS6XsDps2}kQ=xYShoD>6TM#T%}QT;Poi279@3($Z5PydYisP$pNYBnR! zOTT+KHzsk4vLDk_b82tcUvv5U?9=iJD@;Pw0BJcTfKY$gO_%d-IzfZ*wLid&s`eJD zpn-%sD(o$kn1!gNVFK5W(4wMHs7QxIvVoC?DlI{*9ff3=N0uWVVw}&u&;KJkfRsjE56C5J0a?p?L%xSS zVkb(T4-w#jl(k6|dLx}eLG+JugW{#8rsXwR6e4*5O(A(oy6lzAHG*UZks+Mq7FuF7 z;7l|_8jC-<>{U!8jY*$4sYA)zLb?Y;AyL;sdLfy2M#Ck8Q6VrssFLD@kc$JYa-?-q zg9wApMuMtI#burEedr-I2z^NtF`IKPkPW>_RwBtGdh(*A23Lg%WtR-8C5P2u-@Hjn z(N%fKhN117l^K_9N&F%mCl6`96;bMZ_1XP0q_?Hm2Y)7C^`KV+Qh%WyMA4iF}-6hIaf9$V0Jw7d? zUZqvprAX3r)Y+x7#8W!Gk$g*bCLxtgq0$$U#4PnCJ)QsaC$>KK6EA-x(qd3Wf#3UU zKKsq*w*J5`In=B7&-@v~>(cp0{3<<4CO=dom3dEx!uF%`l4mO%UHGM?R~t$Y?m)Z( zcZ@@hJ@Do|HD|iT*FGvw*Wd}n(m zrq2!@J>ZG?-Fpug>GKO0;_ij(*WQYl78Y)0MP|>QetMViE9s+W2NyhG52nxWKAwJ@ z-km>sM$ni6X^0Fa^C{t>?mlG>bN>ym$b3p-g{SGmr}qx-eIsT5^0l;c^~(3}b*{hr zZeBXQfB)`N!oBDqQwl)~*uRyn8xPcKF+eV0;>!Si^T|EEPWBXZ9!y<862eMaoQJVu zON^;xIlcchWgkuY65$5M^DmwA3wbNwe-`cF3jaK@Md!M?7_pk zvLff*qyWXZ{qX6*6Y?G%=*B(mTw-CH;8`8!gZCb|;1pGPYWncw^l9gUOQEkmdiLZY zEl@}7Yb>C^s;GR`Mv-*H=!SO)=h;(G zmoyyAauw6DzG{kuI#s{_?{9tX{zlT@7FvS>zwPIL=X2+_eq_^};)&9ZG8M``+0a(a z2<#x(s>9?W2EnT1*uRY0&dSAu%WB z-NR}~F>$Ax0hhhC7RK+?zV3#ur( zj~><-A#Dac$%2=3uH5WgyMC)fsKLEAR8G9_lf-!6w~fl^cAql__zwn4W#L$2@SC}G z>kTAb?VJg_WE_>$A(H1%We*&v3=XCEN@Hb85VMI&FAB@_C7UVvOtGI2W&A|~f~CC9 z9d7ahNAXA?L!inrfjO6C4gKLH8YMO>lU`ugm&vpW`>Nqmwr0j=b!7%3NC+kY!W=jQ zCg~E=JIM+?02X|wpsTprzlwFDXV>i+RF*HjOT470B)FJ(3C>9l!ECt6;X%byy^I-@ceW?uV30G+mVj~ynV&@|1YKmg(B(T-Z zDV9h^kr;_pQz{$MBLhuw*bS$Th7v#^h8(m?&T#KQ-m=r4XoZo=dP}Q~iE2zIcnwpH z^Wv^a8eS1*D5)~q`T@ykHiGNq;T;a8Q^@A2Ojst^m#hwmuvul847;=bnEXJZAeU3d zq@olh1?`a0WS{FS<;cG@<&QkLDJ!`tIXBYrf_!>Bm=0!LStCs`_@-Ec82WS<3v5}W z(_Ju{O|fl&LwAABU7%$bu$W11&;9`U|1+pH2#ENg z(b9fQ&SITN1P#Wh9?p=J&(l2dS%=a4hLgRS{}K;iGp4Vkpf2aUUGK{7CY0viXrx zmBCqFRj7%6pCn7vA49Vq-$Q;-_3@a#!H`IYkZ!5!DdruLoC(?v5@ee~y_!NZwm}1$ zLU0IuD`{K$vJR7#8R?27qfU;`P#4-L6%@hq1VP&Bq6((sH$(FpWRuFMm8YE1`DRiS zz6CL&it2<^83>!uN`?<)v?86Q1)%kdym4!Lw%Cdo(Oe&dPMl*~F}Dy%aZc^YtN|8I zXOM+K0BA;`<6wq<5{baluNm(a5FfMTiGo18NHQ-^P`ol=8W~QJ1V59Q@t~?nWKGpn zu1Etw{{O6^@-!YR{P1Iusv@_TCbpHl0*+Hm`_eE|uv`x9phcE~E=eb(qOb)Ecor+P zbR>5qZ#I45MBWU3|89R(b986n98%d#R#mR(*e97b;BQS5@{Y;+dcshuf`(DC zpd}(SWR*r0(@EkS7Ga!&J{SG!VkkO`7hSjr)X0mt{Yx0}tVGtohU4=h9#%@mP>yBl z=_>kVth7|s7xA$YkrIEqrHn>3rG2cZ#lb3NWrzYybu3mnzd3J6IvyNJ9?nbCQTI?z z#sEG5Bwx!T>BF;EtOcOTD~!cQR5ErgwC9+@AVawxfWd!CU(15wAY#x>r^8#kzo>!N zy~Yyx{||)*6qpDT3Z~N6g(qDKVvAGSQ~|_@nFGwJ#+D-`Jh*5`r8NVTC_F-u0g6vY zKtduauLK#@4|)tprzwo})N-l<$?#I%PHGr6m%o4`-Z3)vOLzlnSkS(y05W;lnK0z%f@=uyVa zdJC7o{tJS*gmPQ^-4WhLok2%cbfC@z6DHsJ$ViUlj%-NdGggxa#<~%67>Su7qe(Fj z$Y;o;AdzX4%5t34l_1@(y4U0IVB;S#R`{ZH^16RJiEr_9VIGLuo5 z=#^WdkEt=du1Kyi28$R(OC8z=s;39P>WZQd7?P$C>;H0yTebqG`)Dx4Nl+>fGX{<2 zY3a1Snsu@8+8xaY@+Os9WG2s$Tpp9AASr^OEJ_-X;vk9koTqqx_xcOg_wl@DU8Cq)8EHUN&fFEq3NKyrcI zn7-+and%4vw2Rl0VsvOF69;{w+y{{V|47bRAZLkC=mku7svuIM*2V=xm?Zlaz$gN7 zKvT6i-*QWOR+d(zko#TaG8wC=`;qgQaFzI2q!1kf<7q(~Xp?YUgQG}2nBXwpxJVUf zVTg?VGwzqB2`=up;5=I7k}!c*n*YqVfPxm8SSY8H01(AjV-=hRpA*q~PDOM%m1(m*+J1zQ@BJ&@hELM|+s(TBVG7=e!v zV=eLWND%tHAg}W zrIe8WKZjxxf|w>}yag_GEwOXRqge(c0;vDhZ>4+bWm$fm@u0r zDXisK6zC9>nApqEPq=`oTlqK58;wbqC*BhBPXnkt(zL3)t$_P?QGX%Ogg-6Uhj9Ca zS72kS)3hoUW`Q+SbNw}q)k-?pn(OGLnIYKv%=XPf1ePIj%VH}9u355RA--8MM351X zAR+?=Jsz^oT)g>b@={L8+r3Ot4+~`nmd=s2Vs6SXi}4B`!PdNtxtF&u35>-o#9f?- zxa(e3KENyXf`(!@ZudX=_V(+~wexD8*=3ZRFS-p+&nt&l5_Y&LbQn&WeY$KN^}UB} zh{BzNC(qLJq?9QHC*1x7XTtSRmgTFfd!W!eDwNl&zpdL(0JIsKtf2Yx?Wr2Hi)a0I zAlzv0?YEDJUsoU!l9wZ6yn<8y0hO6e^`>zLNomn6{Lluic>cvgE~mj{lJrJzKW`@W z2MLY_#RkZ=@>QBeN+u+B-ByLb$Flza`K^z(KL3mOI=atK{nGDz7s;P5VES9%i<9Y? zQr+rXzA|sMbSAfkSVZNOy&U6d%pzFIqRC>;n$0McJ4)|MG5N6TX(|DxdDo-+iEqnm z(Ru`_scc_uM^?+n+Q5$yM@+J6u|peKunfq46|(r5oOXXqhQw0WFbLt6!RXoN0QO#Ro21{)@}8i92}|^ zcm;qYv;lC;xQIG>Jj#&pKmMt`?|lB;*8lbM+WtFz{U`IsRb8&0p`-safB#A20#$s} zIts|hQI_1#nxg>5CqLDhs~4@dQr1D^Z-ARf>nQLN9R=2P5m*=(GzKJBI(1G0$p3#P-UWqqMYEE}x|X*V+ByleP6BubxGVmdB50ii zu!onO1O_a*m)7`Cj*|fL|L2*Fu67h?odmSUNb4lvx(TQi?bb=)q&W%TB%zkLRyzqG z|NnU-M*&&5IVL9o?LLq%!j)Z7S|IjFSSkr+LZ~OYn=o{@QioD>30%PD@>=^Phf);OTF$YOMZm^KJk7E zt)D>aCvZeQ3dMEsQ|BjeggyZ=@BjZwnYG!pvTA3kza_NYS*rF2vRjfptL@HG6L2oy zS=ufbo%jVKwjCh<|8={wRBcj{o$C$ubmm)mW$CNkS*m@c+6AN2xvLcU|8H2-W+y(o z?b@BCdX+;jWwkp?@&3aNk{7wz+bUaAji9#+MmEB(-l%$7cano$at2EOV8Jw%*3PBFT;dgTr=PqXmrMB0+gSq>lgn zTer6O|FS-R?ALwg+_|m4e7MbmCMJ0E9fIx7z_oV<9(tn~apg{LL|K$4pEDFuma+eT z$=_d;(8*OhQeUyXudgwVW}h{Kz%Y`?lOlac@bzO>uDjhnnOZgQj5?S%vjC)lIx z7u10!^C`xPv`1(yRuDS zepjeVE8EEb|5$!G5m{D>Ig6UaGi>7~J8_fS?U3zuNUY<!2=Nz=3lTCr&Gy2ZY zKDYIcJzY04uU^|zgHHLFe?gdC%K4-tkHSE5#ws(!dPpu}GCerJ zz&FP}GO@sGV%}02vA~(!&PnDgz#M^aLxBrc1XXMz5s+d|GFoDon+_z19QiL)7L4c) zX**_;vs*=9A_Ye1AzO}-C-GlRf$oxUO-=!wRl`7K+#ZBVHRRj?o=QG#+{G?kzkTi2 z4%sT+y>j)|-i;ldb>ic<-yVMHLO(GMg*)cq>27Cd_L@DbDOxHy>!_jtym+(ovCf}C zeE#!=^S2^X)A`Qz5BF|#cCO#J%+Cc|<&if4>PvRxg^H`6l7SL68r|V*zdwVY5X6M_u&$q>-Am$av%w(&&h^<) zt|R$MET%OA>lBi3`XZuICXu{wyl!mBdt%=caa-h<+|le`7%RD!tZQ-4&mND0P@=7V zyW}G*YNsq4DD|j^sB0|Qsz;K%+-46L31~71Nn$eA@Fh>3dO9A0qdw}6NyO?xmvH@( zBT=>%+lNTaEUAan{EDcQguKw?HV{Rp+CaW3`+`-fRqzrz^pYiNg#))5H!ioWM&-FS zT9$-{;3)C_tJJLMpt)d?%xR{^f&f2#mB2o4?s7@;ZmFR=^f4$lbV$;7x0#Bf05>m> zfn;JJ!=*<|vPtz~SWjh1aGO^EuAXy%tMm+{poJ~nHwD9zT)FpDAFX~-j7S`9Iv#ND zyTS)2xgE%|=M$mO4WwrnlfX^D#R@z3ZQ+B{Qjt`HQ*RX2rGQiKi#dIvRKH3siRzD+ zX}qseuaTIGl!9@80R_e;&ES~E$n~DQBhu-<%1x^GjLA`n@kg>VNeS8NAh|L0vFs#)U+pLfAY^iy?n^o*DI(QqYp7I3 zpHVzzh{|&#lkrKzkxYgHH>P?JAJ4}VsZidAx=NBaMRz94*+SYwo+#LgcN~2qnK~q| z6IYNY>3n)DdgG1g(v7`~xAr<8Ub%7W_Qk86TNmHCy4N{~JGXCMx%OV?$-$E}-MP2e zecs)D9`AnI-TgG)eLa1izYAWouclolpq;CG@80VCn(J4tbq;!+>(@G8zwq3oWqSPj z8^bqA9^bim?Q&;&;p^GU!~#eF5SIaTuHPWHi+;~cFLWN4%0GGZP4Jt(D-nUFo%b)^ zy7c7^X(>lz^iZjiIEdx*3tzWbUPyEWua^-Fmvvfr!EIr~s`KK>g>u_0ZB|!p&<@Zw zT-I%JfT*h~?)2VdkNhyBn%nX>Al-)-FWtWV{@OHn{F;HAG0BS_5PadUAYook8Bwe# z-)tn_i~BQP9q4YQc;uVcgp5SfRFuwaxX-&+8-|x81s%z90(nWNh_wj0L>HHcq*@UT zc~a=oFd7H(H6yb5Zik`fY&ZJ&$)jhF z@6I1RoKFvSX1kqjGF<6_VU!KO=AHL$T)+Ln&CWY}w?5k2yVkjV?HvZSm-jArKDe=W zY45T~zVyJQ+c$3PUAxt}as8vt-d8SNy?uF)VPxm}tuOE0xEZOD=)*^MA02#>K6zTM z`i(KU_KyvnOw>;zCqj~D4Hs?GSQ1)R zT+NCtFBTQ@8>2V7!%6!3XxNM;kBc4uP(zVuT>oj%j6rrpkF%(Pl|{@CU-;jd&_-CZ zWR@bc+GMy;$6eB+5@cGAD=c$klc$aZba`o#Bs0~SP-xVjFdrH-m>8%SG6_dqlgThI zcFCbPBWHa)W*|?+%95-my5!JfzR5LXE3l_SM*Y?EqbwVhDvD8U#AHb@Q=^**OiaqW z%I2uy4Te2Q(Tq7nIsY#4-kLfE_Ngp_lut|96%4DN}*N~e1c11}FStMtBk`>QK5ClkurZ<2j$ zQ2Mt027us@|5LfP?OiD>$6oe#9v*5?cBZH&m%0gSUz0uTdcwIH3`8jTF$s<)Z@0xt z5XLfPEmhD+s*nfmH_aksdxAYjhRGQK^^5?M1Hsidw4`~$m(C#^+SPL6v%2_^C&-}ANPe$yfV?B@6T2g-3wx->0 z>0@dPg}f<4zLtXNaotg1>YtiQ`pL?%=R;no@6qg}dbC9Pj^|2Od%X~00l z-BKZ}uBK&?dyGB}D}Cvza=DvMGP26NB|B7L)!)ZO!CyrG|J}jt3%Mo>Z`fm=uzoPEX~UnSg5a(P;j?I9V{iireWEMq^&_0m!q(`)EFrAo}YX}NsqMTHJG)N(;p zp=vMJg|dhl<2;3H{yh&FWPMeXuB$0}c;UkQi~9sm^T*NWo~3B zzB4?YdCT2W4fYs4b))2pVzs+V)G+d8BlvrINx5w46~$6nAM^Jpyjgca!9$MWsn;k_ zzfLRFLf&ziv$yl7%a z$wKjk%sI{07==X((*&b#GitT@W6p1B%?nqni0QlhiRU<1I@4gj}AvEOS-c zlU;_0hAU;d~?L)m>SYe9C83&Q9{}9 z$M=wL3s(L=P5N2t0fP^ol!tQ{))sL5w5@c8DJcU2&6d)DJOA1cWp? zINwNE5xF4qAR+M`2{XheW?keK32#m|r+uiR3j31q^XFyA)xH*4O3%Fu2Uxlk_oLGO zxU?T;`zFgXK^E@F+*jPkuADCs4_e$;n?p8DABp*;m_W*`+#@k56!%M2psb1sd>u%} zrw*v*!g(sZxbLgLR<7!Vz7CQMkZy|?l&ZkV)9#7r|NlxiHS>D@P4J>!Cdr#&xG3)X zYH&ihMgn)<_O;6J_23iudT?tSw{}*&`F&pvZaUnqG{W3-myHgWqz0^K6OzlL@Y+rxp!OmW^x)<$kom;DWt8+84 zE9>xu3oF}{@qV;Yx^%b}dgwut+*|)wgjx`8;A{6+w*#&#S)+p_{c2~ejztWxf=9)@ zh{g0p519)xkOR;C%EcS&VENXHmj<%yqNN@zH#MBp~y)+j(lAd3aytl zPV5Zta&=)Jz(rxdwYD{UNOH5+zS~Mm^ySM}FJ1d`?cD$!d2MypD<9Xe5@#mmX33Ns z)L*@J<;pekdhOg=?OosslX=mGO1Ugxm{xABX}P6su9RoaY-dL9>>jUPll{+^vUYw3 zHl{tJ`)qFC-y3d+k@`?#mQUZ@L`##ke)5&gPCu(|GwV-j% zzwK#VDd|f))|Wg4bd9dyAAl|d68451K9bX*SM%o`d}s98mGMfhfh$Q`RrAJ!c2cSt z<3T!X0Pbn=mnLt%tSg@1YuPs^-M63(du{uj-o69ecIsHvnt$)~jTJiO^tYRqGneJ( z^dyHWvbyrti}km$@VSbI z^z=@Gj9M9OH9M=p%Z;@E3&uDxLh zm&=#V*Bt-ne{<#x|Bw0hKL(FJ`P`Y`U)p6vn!?BPQSn= zb`d_nM~BJ-v1?>L66geDd?KO{onV(g{^<;VP>h0&!jl492G+wEVK(Rql3BEMn)`LP zix^{mG(OClJK})8z;_jhgOzr{mYCW+b6J?(6Z7Q^n{8Ob1Sda;dG^^6PltWB8KCQ% zWuL`LT9fS68|I9*9Q4P^_~5(^G%dGm6m~^T*%VE-rbA>^IuElfb7F6Z&QVG)v(;mF_Ruuk238h*FTkW@tLJsIr`QTVSQ# zx8m@L!(Zm{0SY&&zgcQB7@%n@ZG)ey==OUausN-6OR19bk~&>v|Noc2-)Gefw!RPE zy(YLj1q@JIN*UGBnibPFT3uCBGm>qZUrqZZn