diff options
Diffstat (limited to 'share/security/patches/EN-19:03/sqlite-11.patch')
-rw-r--r-- | share/security/patches/EN-19:03/sqlite-11.patch | 76146 |
1 files changed, 0 insertions, 76146 deletions
diff --git a/share/security/patches/EN-19:03/sqlite-11.patch b/share/security/patches/EN-19:03/sqlite-11.patch deleted file mode 100644 index 774a894939..0000000000 --- a/share/security/patches/EN-19:03/sqlite-11.patch +++ /dev/null @@ -1,76146 +0,0 @@ ---- contrib/sqlite3/Makefile.am.orig -+++ contrib/sqlite3/Makefile.am -@@ -1,6 +1,5 @@ - --AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ @SESSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE -- -+AM_CFLAGS = @BUILD_CFLAGS@ - lib_LTLIBRARIES = libsqlite3.la - libsqlite3_la_SOURCES = sqlite3.c - libsqlite3_la_LDFLAGS = -no-undefined -version-info 8:6:8 -@@ -10,11 +9,11 @@ - EXTRA_sqlite3_SOURCES = sqlite3.c - sqlite3_LDADD = @EXTRA_SHELL_OBJ@ @READLINE_LIBS@ - sqlite3_DEPENDENCIES = @EXTRA_SHELL_OBJ@ --sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -+sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_STMTVTAB -DSQLITE_ENABLE_DBSTAT_VTAB $(SHELL_CFLAGS) - - include_HEADERS = sqlite3.h sqlite3ext.h - --EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs -+EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs Makefile.fallback - pkgconfigdir = ${libdir}/pkgconfig - pkgconfig_DATA = sqlite3.pc - ---- contrib/sqlite3/Makefile.fallback.orig -+++ contrib/sqlite3/Makefile.fallback -@@ -0,0 +1,19 @@ -+#!/usr/bin/make -+# -+# If the configure script does not work, then this Makefile is available -+# as a backup. Manually configure the variables below. -+# -+# Note: This makefile works out-of-the-box on MacOS 10.2 (Jaguar) -+# -+CC = gcc -+CFLAGS = -O0 -I. -+LIBS = -lz -+COPTS += -D_BSD_SOURCE -+COPTS += -DSQLITE_ENABLE_LOCKING_STYLE=0 -+COPTS += -DSQLITE_THREADSAFE=0 -+COPTS += -DSQLITE_OMIT_LOAD_EXTENSION -+COPTS += -DSQLITE_WITHOUT_ZONEMALLOC -+COPTS += -DSQLITE_ENABLE_RTREE -+ -+sqlite3: shell.c sqlite3.c -+ $(CC) $(CFLAGS) $(COPTS) -o sqlite3 shell.c sqlite3.c $(LIBS) ---- contrib/sqlite3/Makefile.in.orig -+++ contrib/sqlite3/Makefile.in -@@ -260,7 +260,6 @@ - DLLTOOL = @DLLTOOL@ - DSYMUTIL = @DSYMUTIL@ - DUMPBIN = @DUMPBIN@ --DYNAMIC_EXTENSION_FLAGS = @DYNAMIC_EXTENSION_FLAGS@ - ECHO_C = @ECHO_C@ - ECHO_N = @ECHO_N@ - ECHO_T = @ECHO_T@ -@@ -268,7 +267,6 @@ - EXEEXT = @EXEEXT@ - EXTRA_SHELL_OBJ = @EXTRA_SHELL_OBJ@ - FGREP = @FGREP@ --FTS5_FLAGS = @FTS5_FLAGS@ - GREP = @GREP@ - INSTALL = @INSTALL@ - INSTALL_DATA = @INSTALL_DATA@ -@@ -275,7 +273,6 @@ - INSTALL_PROGRAM = @INSTALL_PROGRAM@ - INSTALL_SCRIPT = @INSTALL_SCRIPT@ - INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ --JSON1_FLAGS = @JSON1_FLAGS@ - LD = @LD@ - LDFLAGS = @LDFLAGS@ - LIBOBJS = @LIBOBJS@ -@@ -305,11 +302,10 @@ - RANLIB = @RANLIB@ - READLINE_LIBS = @READLINE_LIBS@ - SED = @SED@ --SESSION_FLAGS = @SESSION_FLAGS@ - SET_MAKE = @SET_MAKE@ - SHELL = @SHELL@ -+SHELL_CFLAGS = @SHELL_CFLAGS@ - STRIP = @STRIP@ --THREADSAFE_FLAGS = @THREADSAFE_FLAGS@ - VERSION = @VERSION@ - abs_builddir = @abs_builddir@ - abs_srcdir = @abs_srcdir@ -@@ -363,7 +359,7 @@ - top_build_prefix = @top_build_prefix@ - top_builddir = @top_builddir@ - top_srcdir = @top_srcdir@ --AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ @SESSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE -+AM_CFLAGS = @BUILD_CFLAGS@ - lib_LTLIBRARIES = libsqlite3.la - libsqlite3_la_SOURCES = sqlite3.c - libsqlite3_la_LDFLAGS = -no-undefined -version-info 8:6:8 -@@ -371,9 +367,9 @@ - EXTRA_sqlite3_SOURCES = sqlite3.c - sqlite3_LDADD = @EXTRA_SHELL_OBJ@ @READLINE_LIBS@ - sqlite3_DEPENDENCIES = @EXTRA_SHELL_OBJ@ --sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -+sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_STMTVTAB -DSQLITE_ENABLE_DBSTAT_VTAB $(SHELL_CFLAGS) - include_HEADERS = sqlite3.h sqlite3ext.h --EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs -+EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs Makefile.fallback - pkgconfigdir = ${libdir}/pkgconfig - pkgconfig_DATA = sqlite3.pc - man_MANS = sqlite3.1 ---- contrib/sqlite3/Makefile.msc.orig -+++ contrib/sqlite3/Makefile.msc -@@ -277,6 +277,12 @@ - !IF $(MINIMAL_AMALGAMATION)==0 - OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1 - OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 -+OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1 -+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 - !ENDIF - OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1 - !ENDIF -@@ -561,6 +567,7 @@ - !ENDIF - !ENDIF - -+ - # This is the core library that the shell executable should link with. - # - !IFNDEF SHELL_CORE_LIB -@@ -808,7 +815,7 @@ - # If requested, link to the RPCRT4 library. - # - !IF $(USE_RPCRT4_LIB)!=0 --LTLINK = $(LTLINK) rpcrt4.lib -+LTLIBS = $(LTLIBS) rpcrt4.lib - !ENDIF - - # If a platform was set, force the linker to target that. -@@ -927,7 +934,9 @@ - # when the shell is not being dynamically linked. - # - !IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0 --SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB -+SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1 -+SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1 -+SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1 - !ENDIF - - -@@ -934,8 +943,16 @@ - # This is the default Makefile target. The objects listed here - # are what get build when you type just "make" with no arguments. - # --all: dll shell -+core: dll shell - -+# Targets that require the Tcl library. -+# -+tcl: $(ALL_TCL_TARGETS) -+ -+# This Makefile target builds all of the standard binaries. -+# -+all: core tcl -+ - # Dynamic link library section. - # - dll: $(SQLITE3DLL) -@@ -954,11 +971,11 @@ - sqlite3.def: Replace.exe $(LIBOBJ) - echo EXPORTS > sqlite3.def - dumpbin /all $(LIBOBJ) \ -- | .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \ -+ | .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \ - | sort >> sqlite3.def - --$(SQLITE3EXE): $(TOP)\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H) -- $(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\shell.c $(SHELL_CORE_SRC) \ -+$(SQLITE3EXE): shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H) -+ $(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) shell.c $(SHELL_CORE_SRC) \ - /link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS) - - -@@ -973,7 +990,7 @@ - !IF $(USE_RC)!=0 - _HASHCHAR=^# - !IF ![echo !IFNDEF VERSION > rcver.vc] && \ -- ![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| find "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \ -+ ![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| "%SystemRoot%\System32\find.exe" "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \ - ![echo !ENDIF >> rcver.vc] - !INCLUDE rcver.vc - !ENDIF ---- contrib/sqlite3/configure.orig -+++ contrib/sqlite3/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.20.0. -+# Generated by GNU Autoconf 2.69 for sqlite 3.26.0. - # - # Report bugs to <http://www.sqlite.org>. - # -@@ -590,8 +590,8 @@ - # Identity of this package. - PACKAGE_NAME='sqlite' - PACKAGE_TARNAME='sqlite' --PACKAGE_VERSION='3.20.0' --PACKAGE_STRING='sqlite 3.20.0' -+PACKAGE_VERSION='3.26.0' -+PACKAGE_STRING='sqlite 3.26.0' - PACKAGE_BUGREPORT='http://www.sqlite.org' - PACKAGE_URL='' - -@@ -636,12 +636,8 @@ - am__EXEEXT_TRUE - LTLIBOBJS - LIBOBJS -+SHELL_CFLAGS - EXTRA_SHELL_OBJ --SESSION_FLAGS --JSON1_FLAGS --FTS5_FLAGS --DYNAMIC_EXTENSION_FLAGS --THREADSAFE_FLAGS - READLINE_LIBS - BUILD_CFLAGS - CPP -@@ -775,9 +771,13 @@ - enable_readline - enable_threadsafe - enable_dynamic_extensions -+enable_fts4 -+enable_fts3 - enable_fts5 - enable_json1 -+enable_rtree - enable_session -+enable_debug - enable_static_shell - ' - ac_precious_vars='build_alias -@@ -1330,7 +1330,7 @@ - # 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.20.0 to adapt to many kinds of systems. -+\`configure' configures sqlite 3.26.0 to adapt to many kinds of systems. - - Usage: $0 [OPTION]... [VAR=VALUE]... - -@@ -1400,7 +1400,7 @@ - - if test -n "$ac_init_help"; then - case $ac_init_help in -- short | recursive ) echo "Configuration of sqlite 3.20.0:";; -+ short | recursive ) echo "Configuration of sqlite 3.26.0:";; - esac - cat <<\_ACEOF - -@@ -1425,9 +1425,13 @@ - --enable-threadsafe build a thread-safe library [default=yes] - --enable-dynamic-extensions - support loadable extensions [default=yes] -- --enable-fts5 include fts5 support [default=no] -- --enable-json1 include json1 support [default=no] -+ --enable-fts4 include fts4 support [default=yes] -+ --enable-fts3 include fts3 support [default=no] -+ --enable-fts5 include fts5 support [default=yes] -+ --enable-json1 include json1 support [default=yes] -+ --enable-rtree include rtree support [default=yes] - --enable-session enable the session extension [default=no] -+ --enable-debug build with debugging features enabled [default=no] - --enable-static-shell statically link libsqlite3 into shell tool - [default=yes] - -@@ -1521,7 +1525,7 @@ - test -n "$ac_init_help" && exit $ac_status - if $ac_init_version; then - cat <<\_ACEOF --sqlite configure 3.20.0 -+sqlite configure 3.26.0 - generated by GNU Autoconf 2.69 - - Copyright (C) 2012 Free Software Foundation, Inc. -@@ -1936,7 +1940,7 @@ - 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.20.0, which was -+It was created by sqlite $as_me 3.26.0, which was - generated by GNU Autoconf 2.69. Invocation command line was - - $ $0 $@ -@@ -2285,12 +2289,8 @@ - - - -- --# Use automake. --am__api_version='1.15' -- - ac_aux_dir= --for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do -+for ac_dir in . "$srcdir"/.; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" -@@ -2306,7 +2306,7 @@ - fi - done - if test -z "$ac_aux_dir"; then -- as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 -+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in . \"$srcdir\"/." "$LINENO" 5 - fi - - # These three variables are undocumented and unsupported, -@@ -2318,6 +2318,10 @@ - ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -+ -+# Use automake. -+am__api_version='1.15' -+ - # Find a good install program. We prefer a C program (faster), - # so one script is as good as another. But avoid the broken or - # incompatible versions: -@@ -2802,7 +2806,7 @@ - - # Define the identity of the package. - PACKAGE='sqlite' -- VERSION='3.20.0' -+ VERSION='3.26.0' - - - cat >>confdefs.h <<_ACEOF -@@ -13038,6 +13042,7 @@ - - ac_config_files="$ac_config_files Makefile sqlite3.pc" - -+BUILD_CFLAGS= - - - #------------------------------------------------------------------------- -@@ -13302,9 +13307,8 @@ - enable_threadsafe=yes - fi - --THREADSAFE_FLAGS=-DSQLITE_THREADSAFE=0 - if test x"$enable_threadsafe" != "xno"; then -- THREADSAFE_FLAGS="-D_REENTRANT=1 -DSQLITE_THREADSAFE=1" -+ BUILD_CFLAGS="$BUILD_CFLAGS -D_REENTRANT=1 -DSQLITE_THREADSAFE=1" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create" >&5 - $as_echo_n "checking for library containing pthread_create... " >&6; } - if ${ac_cv_search_pthread_create+:} false; then : -@@ -13418,7 +13422,6 @@ - fi - - fi -- - #----------------------------------------------------------------------- - - #----------------------------------------------------------------------- -@@ -13489,16 +13492,43 @@ - fi - - else -- DYNAMIC_EXTENSION_FLAGS=-DSQLITE_OMIT_LOAD_EXTENSION=1 -+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_OMIT_LOAD_EXTENSION=1" - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for whether to support dynamic extensions" >&5 - $as_echo_n "checking for whether to support dynamic extensions... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_dynamic_extensions" >&5 - $as_echo "$enable_dynamic_extensions" >&6; } -+#----------------------------------------------------------------------- - - #----------------------------------------------------------------------- -+# --enable-fts4 -+# -+# Check whether --enable-fts4 was given. -+if test "${enable_fts4+set}" = set; then : -+ enableval=$enable_fts4; -+else -+ enable_fts4=yes -+fi - -+if test x"$enable_fts4" = "xyes"; then -+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS4" -+fi - #----------------------------------------------------------------------- -+ -+#----------------------------------------------------------------------- -+# --enable-fts3 -+# -+# Check whether --enable-fts3 was given. -+if test "${enable_fts3+set}" = set; then : -+ enableval=$enable_fts3; -+fi -+ -+if test x"$enable_fts3" = "xyes" -a x"$enable_fts4" = "xno"; then -+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS3" -+fi -+#----------------------------------------------------------------------- -+ -+#----------------------------------------------------------------------- - # --enable-fts5 - # - # Check whether --enable-fts5 was given. -@@ -13505,7 +13535,7 @@ - if test "${enable_fts5+set}" = set; then : - enableval=$enable_fts5; - else -- enable_fts5=no -+ enable_fts5=yes - fi - - if test x"$enable_fts5" = "xyes"; then -@@ -13565,9 +13595,8 @@ - - fi - -- FTS5_FLAGS=-DSQLITE_ENABLE_FTS5 -+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS5" - fi -- - #----------------------------------------------------------------------- - - #----------------------------------------------------------------------- -@@ -13577,32 +13606,57 @@ - if test "${enable_json1+set}" = set; then : - enableval=$enable_json1; - else -- enable_json1=no -+ enable_json1=yes - fi - - if test x"$enable_json1" = "xyes"; then -- JSON1_FLAGS=-DSQLITE_ENABLE_JSON1 -+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_JSON1" - fi -+#----------------------------------------------------------------------- - - #----------------------------------------------------------------------- -+# --enable-rtree -+# -+# Check whether --enable-rtree was given. -+if test "${enable_rtree+set}" = set; then : -+ enableval=$enable_rtree; -+else -+ enable_rtree=yes -+fi - -+if test x"$enable_rtree" = "xyes"; then -+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE" -+fi - #----------------------------------------------------------------------- -+ -+#----------------------------------------------------------------------- - # --enable-session - # - # Check whether --enable-session was given. - if test "${enable_session+set}" = set; then : - enableval=$enable_session; --else -- enable_session=no - fi - - if test x"$enable_session" = "xyes"; then -- SESSION_FLAGS="-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK" -+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK" - fi -+#----------------------------------------------------------------------- - - #----------------------------------------------------------------------- -+# --enable-debug -+# -+# Check whether --enable-debug was given. -+if test "${enable_debug+set}" = set; then : -+ enableval=$enable_debug; -+fi - -+if test x"$enable_debug" = "xyes"; then -+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_DEBUG -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE" -+ CFLAGS="-g -O0" -+fi - #----------------------------------------------------------------------- -+ -+#----------------------------------------------------------------------- - # --enable-static-shell - # - # Check whether --enable-static-shell was given. -@@ -13631,7 +13685,136 @@ - fi - done - -+for ac_header in zlib.h -+do : -+ ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" -+if test "x$ac_cv_header_zlib_h" = xyes; then : -+ cat >>confdefs.h <<_ACEOF -+#define HAVE_ZLIB_H 1 -+_ACEOF - -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing deflate" >&5 -+$as_echo_n "checking for library containing deflate... " >&6; } -+if ${ac_cv_search_deflate+:} false; then : -+ $as_echo_n "(cached) " >&6 -+else -+ ac_func_search_save_LIBS=$LIBS -+cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+/* Override any GCC internal prototype to avoid an error. -+ Use char because int might match the return type of a GCC -+ builtin and then its argument prototype would still apply. */ -+#ifdef __cplusplus -+extern "C" -+#endif -+char deflate (); -+int -+main () -+{ -+return deflate (); -+ ; -+ return 0; -+} -+_ACEOF -+for ac_lib in '' z; do -+ if test -z "$ac_lib"; then -+ ac_res="none required" -+ else -+ ac_res=-l$ac_lib -+ LIBS="-l$ac_lib $ac_func_search_save_LIBS" -+ fi -+ if ac_fn_c_try_link "$LINENO"; then : -+ ac_cv_search_deflate=$ac_res -+fi -+rm -f core conftest.err conftest.$ac_objext \ -+ conftest$ac_exeext -+ if ${ac_cv_search_deflate+:} false; then : -+ break -+fi -+done -+if ${ac_cv_search_deflate+:} false; then : -+ -+else -+ ac_cv_search_deflate=no -+fi -+rm conftest.$ac_ext -+LIBS=$ac_func_search_save_LIBS -+fi -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_deflate" >&5 -+$as_echo "$ac_cv_search_deflate" >&6; } -+ac_res=$ac_cv_search_deflate -+if test "$ac_res" != no; then : -+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" -+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_HAVE_ZLIB" -+fi -+ -+ -+fi -+ -+done -+ -+ -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing system" >&5 -+$as_echo_n "checking for library containing system... " >&6; } -+if ${ac_cv_search_system+:} false; then : -+ $as_echo_n "(cached) " >&6 -+else -+ ac_func_search_save_LIBS=$LIBS -+cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+/* Override any GCC internal prototype to avoid an error. -+ Use char because int might match the return type of a GCC -+ builtin and then its argument prototype would still apply. */ -+#ifdef __cplusplus -+extern "C" -+#endif -+char system (); -+int -+main () -+{ -+return system (); -+ ; -+ return 0; -+} -+_ACEOF -+for ac_lib in '' ; do -+ if test -z "$ac_lib"; then -+ ac_res="none required" -+ else -+ ac_res=-l$ac_lib -+ LIBS="-l$ac_lib $ac_func_search_save_LIBS" -+ fi -+ if ac_fn_c_try_link "$LINENO"; then : -+ ac_cv_search_system=$ac_res -+fi -+rm -f core conftest.err conftest.$ac_objext \ -+ conftest$ac_exeext -+ if ${ac_cv_search_system+:} false; then : -+ break -+fi -+done -+if ${ac_cv_search_system+:} false; then : -+ -+else -+ ac_cv_search_system=no -+fi -+rm conftest.$ac_ext -+LIBS=$ac_func_search_save_LIBS -+fi -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_system" >&5 -+$as_echo "$ac_cv_search_system" >&6; } -+ac_res=$ac_cv_search_system -+if test "$ac_res" != no; then : -+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" -+ -+else -+ SHELL_CFLAGS="-DSQLITE_NOHAVE_SYSTEM" -+fi -+ -+ -+ - #----------------------------------------------------------------------- - # UPDATE: Maybe it's better if users just set CFLAGS before invoking - # configure. This option doesn't really add much... -@@ -14227,7 +14410,7 @@ - # 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.20.0, which was -+This file was extended by sqlite $as_me 3.26.0, which was - generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES -@@ -14284,7 +14467,7 @@ - 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.20.0 -+sqlite config.status 3.26.0 - configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" - ---- contrib/sqlite3/configure.ac.orig -+++ contrib/sqlite3/configure.ac -@@ -10,8 +10,9 @@ - # - - AC_PREREQ(2.61) --AC_INIT(sqlite, 3.20.0, http://www.sqlite.org) -+AC_INIT(sqlite, 3.26.0, http://www.sqlite.org) - AC_CONFIG_SRCDIR([sqlite3.c]) -+AC_CONFIG_AUX_DIR([.]) - - # Use automake. - AM_INIT_AUTOMAKE([foreign]) -@@ -28,6 +29,7 @@ - AC_FUNC_STRERROR_R - - AC_CONFIG_FILES([Makefile sqlite3.pc]) -+BUILD_CFLAGS= - AC_SUBST(BUILD_CFLAGS) - - #------------------------------------------------------------------------- -@@ -85,13 +87,11 @@ - AC_ARG_ENABLE(threadsafe, [AS_HELP_STRING( - [--enable-threadsafe], [build a thread-safe library [default=yes]])], - [], [enable_threadsafe=yes]) --THREADSAFE_FLAGS=-DSQLITE_THREADSAFE=0 - if test x"$enable_threadsafe" != "xno"; then -- THREADSAFE_FLAGS="-D_REENTRANT=1 -DSQLITE_THREADSAFE=1" -+ BUILD_CFLAGS="$BUILD_CFLAGS -D_REENTRANT=1 -DSQLITE_THREADSAFE=1" - AC_SEARCH_LIBS(pthread_create, pthread) - AC_SEARCH_LIBS(pthread_mutexattr_init, pthread) - fi --AC_SUBST(THREADSAFE_FLAGS) - #----------------------------------------------------------------------- - - #----------------------------------------------------------------------- -@@ -103,24 +103,44 @@ - if test x"$enable_dynamic_extensions" != "xno"; then - AC_SEARCH_LIBS(dlopen, dl) - else -- DYNAMIC_EXTENSION_FLAGS=-DSQLITE_OMIT_LOAD_EXTENSION=1 -+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_OMIT_LOAD_EXTENSION=1" - fi - AC_MSG_CHECKING([for whether to support dynamic extensions]) - AC_MSG_RESULT($enable_dynamic_extensions) --AC_SUBST(DYNAMIC_EXTENSION_FLAGS) - #----------------------------------------------------------------------- - - #----------------------------------------------------------------------- -+# --enable-fts4 -+# -+AC_ARG_ENABLE(fts4, [AS_HELP_STRING( -+ [--enable-fts4], [include fts4 support [default=yes]])], -+ [], [enable_fts4=yes]) -+if test x"$enable_fts4" = "xyes"; then -+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS4" -+fi -+#----------------------------------------------------------------------- -+ -+#----------------------------------------------------------------------- -+# --enable-fts3 -+# -+AC_ARG_ENABLE(fts3, [AS_HELP_STRING( -+ [--enable-fts3], [include fts3 support [default=no]])], -+ [], []) -+if test x"$enable_fts3" = "xyes" -a x"$enable_fts4" = "xno"; then -+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS3" -+fi -+#----------------------------------------------------------------------- -+ -+#----------------------------------------------------------------------- - # --enable-fts5 - # - AC_ARG_ENABLE(fts5, [AS_HELP_STRING( -- [--enable-fts5], [include fts5 support [default=no]])], -- [], [enable_fts5=no]) -+ [--enable-fts5], [include fts5 support [default=yes]])], -+ [], [enable_fts5=yes]) - if test x"$enable_fts5" = "xyes"; then - AC_SEARCH_LIBS(log, m) -- FTS5_FLAGS=-DSQLITE_ENABLE_FTS5 -+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS5" - fi --AC_SUBST(FTS5_FLAGS) - #----------------------------------------------------------------------- - - #----------------------------------------------------------------------- -@@ -127,27 +147,48 @@ - # --enable-json1 - # - AC_ARG_ENABLE(json1, [AS_HELP_STRING( -- [--enable-json1], [include json1 support [default=no]])], -- [], [enable_json1=no]) -+ [--enable-json1], [include json1 support [default=yes]])], -+ [],[enable_json1=yes]) - if test x"$enable_json1" = "xyes"; then -- JSON1_FLAGS=-DSQLITE_ENABLE_JSON1 -+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_JSON1" - fi --AC_SUBST(JSON1_FLAGS) - #----------------------------------------------------------------------- - - #----------------------------------------------------------------------- -+# --enable-rtree -+# -+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" -+fi -+#----------------------------------------------------------------------- -+ -+#----------------------------------------------------------------------- - # --enable-session - # - AC_ARG_ENABLE(session, [AS_HELP_STRING( - [--enable-session], [enable the session extension [default=no]])], -- [], [enable_session=no]) -+ [], []) - if test x"$enable_session" = "xyes"; then -- SESSION_FLAGS="-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK" -+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK" - fi --AC_SUBST(SESSION_FLAGS) - #----------------------------------------------------------------------- - - #----------------------------------------------------------------------- -+# --enable-debug -+# -+AC_ARG_ENABLE(debug, [AS_HELP_STRING( -+ [--enable-debug], [build with debugging features enabled [default=no]])], -+ [], []) -+if test x"$enable_debug" = "xyes"; then -+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_DEBUG -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE" -+ CFLAGS="-g -O0" -+fi -+#----------------------------------------------------------------------- -+ -+#----------------------------------------------------------------------- - # --enable-static-shell - # - AC_ARG_ENABLE(static-shell, [AS_HELP_STRING( -@@ -163,7 +204,13 @@ - #----------------------------------------------------------------------- - - AC_CHECK_FUNCS(posix_fallocate) -+AC_CHECK_HEADERS(zlib.h,[ -+ AC_SEARCH_LIBS(deflate,z,[BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_HAVE_ZLIB"]) -+]) - -+AC_SEARCH_LIBS(system,,,[SHELL_CFLAGS="-DSQLITE_NOHAVE_SYSTEM"]) -+AC_SUBST(SHELL_CFLAGS) -+ - #----------------------------------------------------------------------- - # UPDATE: Maybe it's better if users just set CFLAGS before invoking - # configure. This option doesn't really add much... ---- contrib/sqlite3/shell.c.orig -+++ contrib/sqlite3/shell.c -@@ -79,6 +79,9 @@ - #include <stdio.h> - #include <assert.h> - #include "sqlite3.h" -+typedef sqlite3_int64 i64; -+typedef sqlite3_uint64 u64; -+typedef unsigned char u8; - #if SQLITE_USER_AUTHENTICATION - # include "sqlite3userauth.h" - #endif -@@ -90,9 +93,22 @@ - # if !defined(__RTP__) && !defined(_WRS_KERNEL) - # include <pwd.h> - # endif -+#endif -+#if (!defined(_WIN32) && !defined(WIN32)) || defined(__MINGW32__) - # include <unistd.h> --# include <sys/types.h> -+# include <dirent.h> -+# define GETPID getpid -+# if defined(__MINGW32__) -+# define DIRENT dirent -+# ifndef S_ISLNK -+# define S_ISLNK(mode) (0) -+# endif -+# endif -+#else -+# define GETPID (int)GetCurrentProcessId - #endif -+#include <sys/types.h> -+#include <sys/stat.h> - - #if HAVE_READLINE - # include <readline/readline.h> -@@ -137,6 +153,9 @@ - # ifndef access - # define access(f,m) _access((f),(m)) - # endif -+# ifndef unlink -+# define unlink _unlink -+# endif - # undef popen - # define popen _popen - # undef pclose -@@ -358,6 +377,11 @@ - #define UNUSED_PARAMETER(x) (void)(x) - - /* -+** Number of elements in an array -+*/ -+#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) -+ -+/* - ** If the following flag is set, then command execution stops - ** at an error if we are not interactive. - */ -@@ -433,6 +457,12 @@ - # define raw_printf fprintf - #endif - -+/* Indicate out-of-memory and exit. */ -+static void shell_out_of_memory(void){ -+ raw_printf(stderr,"Error: out of memory\n"); -+ exit(1); -+} -+ - /* - ** Write I/O traces to the following stream. - */ -@@ -556,7 +586,7 @@ - if( n+100>nLine ){ - nLine = nLine*2 + 100; - zLine = realloc(zLine, nLine); -- if( zLine==0 ) return 0; -+ if( zLine==0 ) shell_out_of_memory(); - } - if( fgets(&zLine[n], nLine - n, in)==0 ){ - if( n==0 ){ -@@ -583,10 +613,7 @@ - int nTrans = strlen30(zTrans)+1; - if( nTrans>nLine ){ - zLine = realloc(zLine, nTrans); -- if( zLine==0 ){ -- sqlite3_free(zTrans); -- return 0; -- } -+ if( zLine==0 ) shell_out_of_memory(); - } - memcpy(zLine, zTrans, nTrans); - sqlite3_free(zTrans); -@@ -629,7 +656,66 @@ - } - return zResult; - } -+ -+ - /* -+** Return the value of a hexadecimal digit. Return -1 if the input -+** is not a hex digit. -+*/ -+static int hexDigitValue(char c){ -+ if( c>='0' && c<='9' ) return c - '0'; -+ if( c>='a' && c<='f' ) return c - 'a' + 10; -+ if( c>='A' && c<='F' ) return c - 'A' + 10; -+ return -1; -+} -+ -+/* -+** Interpret zArg as an integer value, possibly with suffixes. -+*/ -+static sqlite3_int64 integerValue(const char *zArg){ -+ sqlite3_int64 v = 0; -+ static const struct { char *zSuffix; int iMult; } aMult[] = { -+ { "KiB", 1024 }, -+ { "MiB", 1024*1024 }, -+ { "GiB", 1024*1024*1024 }, -+ { "KB", 1000 }, -+ { "MB", 1000000 }, -+ { "GB", 1000000000 }, -+ { "K", 1000 }, -+ { "M", 1000000 }, -+ { "G", 1000000000 }, -+ }; -+ int i; -+ int isNeg = 0; -+ if( zArg[0]=='-' ){ -+ isNeg = 1; -+ zArg++; -+ }else if( zArg[0]=='+' ){ -+ zArg++; -+ } -+ if( zArg[0]=='0' && zArg[1]=='x' ){ -+ int x; -+ zArg += 2; -+ while( (x = hexDigitValue(zArg[0]))>=0 ){ -+ v = (v<<4) + x; -+ zArg++; -+ } -+ }else{ -+ while( IsDigit(zArg[0]) ){ -+ v = v*10 + zArg[0] - '0'; -+ zArg++; -+ } -+ } -+ for(i=0; i<ArraySize(aMult); i++){ -+ if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){ -+ v *= aMult[i].iMult; -+ break; -+ } -+ } -+ return isNeg? -v : v; -+} -+ -+/* - ** A variable length string to which one can append text. - */ - typedef struct ShellText ShellText; -@@ -674,10 +760,7 @@ - if( p->n+len>=p->nAlloc ){ - p->nAlloc = p->nAlloc*2 + len + 20; - p->z = realloc(p->z, p->nAlloc); -- if( p->z==0 ){ -- memset(p, 0, sizeof(*p)); -- return; -- } -+ if( p->z==0 ) shell_out_of_memory(); - } - - if( quote ){ -@@ -706,48 +789,82 @@ - ** Return '"' if quoting is required. Return 0 if no quoting is required. - */ - static char quoteChar(const char *zName){ -- /* All SQLite keywords, in alphabetical order */ -- static const char *azKeywords[] = { -- "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS", -- "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY", -- "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT", -- "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE", -- "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE", -- "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH", -- "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN", -- "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF", -- "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER", -- "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", -- "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL", -- "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA", -- "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP", -- "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT", -- "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP", -- "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE", -- "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE", -- "WITH", "WITHOUT", -- }; -- int i, lwr, upr, mid, c; -+ int i; - if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"'; - for(i=0; zName[i]; i++){ - if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"'; - } -- lwr = 0; -- upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1; -- while( lwr<=upr ){ -- mid = (lwr+upr)/2; -- c = sqlite3_stricmp(azKeywords[mid], zName); -- if( c==0 ) return '"'; -- if( c<0 ){ -- lwr = mid+1; -- }else{ -- upr = mid-1; -- } -+ return sqlite3_keyword_check(zName, i) ? '"' : 0; -+} -+ -+/* -+** Construct a fake object name and column list to describe the structure -+** of the view, virtual table, or table valued function zSchema.zName. -+*/ -+static char *shellFakeSchema( -+ sqlite3 *db, /* The database connection containing the vtab */ -+ const char *zSchema, /* Schema of the database holding the vtab */ -+ const char *zName /* The name of the virtual table */ -+){ -+ sqlite3_stmt *pStmt = 0; -+ char *zSql; -+ ShellText s; -+ char cQuote; -+ char *zDiv = "("; -+ int nRow = 0; -+ -+ zSql = sqlite3_mprintf("PRAGMA \"%w\".table_info=%Q;", -+ zSchema ? zSchema : "main", zName); -+ sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); -+ sqlite3_free(zSql); -+ initText(&s); -+ if( zSchema ){ -+ cQuote = quoteChar(zSchema); -+ if( cQuote && sqlite3_stricmp(zSchema,"temp")==0 ) cQuote = 0; -+ appendText(&s, zSchema, cQuote); -+ appendText(&s, ".", 0); - } -- return 0; -+ cQuote = quoteChar(zName); -+ appendText(&s, zName, cQuote); -+ while( sqlite3_step(pStmt)==SQLITE_ROW ){ -+ const char *zCol = (const char*)sqlite3_column_text(pStmt, 1); -+ nRow++; -+ appendText(&s, zDiv, 0); -+ zDiv = ","; -+ cQuote = quoteChar(zCol); -+ appendText(&s, zCol, cQuote); -+ } -+ appendText(&s, ")", 0); -+ sqlite3_finalize(pStmt); -+ if( nRow==0 ){ -+ freeText(&s); -+ s.z = 0; -+ } -+ return s.z; - } - - /* -+** SQL function: shell_module_schema(X) -+** -+** Return a fake schema for the table-valued function or eponymous virtual -+** table X. -+*/ -+static void shellModuleSchema( -+ sqlite3_context *pCtx, -+ int nVal, -+ sqlite3_value **apVal -+){ -+ const char *zName = (const char*)sqlite3_value_text(apVal[0]); -+ char *zFake = shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName); -+ UNUSED_PARAMETER(nVal); -+ if( zFake ){ -+ sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake), -+ -1, sqlite3_free); -+ free(zFake); -+ } -+} -+ -+/* - ** SQL function: shell_add_schema(S,X) - ** - ** Add the schema name X to the CREATE statement in S and return the result. -@@ -782,20 +899,38 @@ - int i = 0; - const char *zIn = (const char*)sqlite3_value_text(apVal[0]); - const char *zSchema = (const char*)sqlite3_value_text(apVal[1]); -- assert( nVal==2 ); -+ const char *zName = (const char*)sqlite3_value_text(apVal[2]); -+ sqlite3 *db = sqlite3_context_db_handle(pCtx); -+ UNUSED_PARAMETER(nVal); - if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){ - for(i=0; i<(int)(sizeof(aPrefix)/sizeof(aPrefix[0])); i++){ - int n = strlen30(aPrefix[i]); - if( strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){ -- char cQuote = quoteChar(zSchema); -- char *z; -- if( cQuote ){ -- z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8); -- }else{ -- z = sqlite3_mprintf("%.*s %s.%s", n+7, zIn, zSchema, zIn+n+8); -+ char *z = 0; -+ char *zFake = 0; -+ if( zSchema ){ -+ char cQuote = quoteChar(zSchema); -+ if( cQuote && sqlite3_stricmp(zSchema,"temp")!=0 ){ -+ z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8); -+ }else{ -+ z = sqlite3_mprintf("%.*s %s.%s", n+7, zIn, zSchema, zIn+n+8); -+ } - } -- sqlite3_result_text(pCtx, z, -1, sqlite3_free); -- return; -+ if( zName -+ && aPrefix[i][0]=='V' -+ && (zFake = shellFakeSchema(db, zSchema, zName))!=0 -+ ){ -+ if( z==0 ){ -+ z = sqlite3_mprintf("%s\n/* %s */", zIn, zFake); -+ }else{ -+ z = sqlite3_mprintf("%z\n/* %s */", z, zFake); -+ } -+ free(zFake); -+ } -+ if( z ){ -+ sqlite3_result_text(pCtx, z, -1, sqlite3_free); -+ return; -+ } - } - } - } -@@ -811,6 +946,364 @@ - #define SQLITE_EXTENSION_INIT1 - #define SQLITE_EXTENSION_INIT2(X) (void)(X) - -+#if defined(_WIN32) && defined(_MSC_VER) -+/************************* Begin test_windirent.h ******************/ -+/* -+** 2015 November 30 -+** -+** 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 contains declarations for most of the opendir() family of -+** POSIX functions on Win32 using the MSVCRT. -+*/ -+ -+#if defined(_WIN32) && defined(_MSC_VER) && !defined(SQLITE_WINDIRENT_H) -+#define SQLITE_WINDIRENT_H -+ -+/* -+** We need several data types from the Windows SDK header. -+*/ -+ -+#ifndef WIN32_LEAN_AND_MEAN -+#define WIN32_LEAN_AND_MEAN -+#endif -+ -+#include "windows.h" -+ -+/* -+** We need several support functions from the SQLite core. -+*/ -+ -+ -+/* -+** We need several things from the ANSI and MSVCRT headers. -+*/ -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include <errno.h> -+#include <io.h> -+#include <limits.h> -+#include <sys/types.h> -+#include <sys/stat.h> -+ -+/* -+** We may need several defines that should have been in "sys/stat.h". -+*/ -+ -+#ifndef S_ISREG -+#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) -+#endif -+ -+#ifndef S_ISDIR -+#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) -+#endif -+ -+#ifndef S_ISLNK -+#define S_ISLNK(mode) (0) -+#endif -+ -+/* -+** We may need to provide the "mode_t" type. -+*/ -+ -+#ifndef MODE_T_DEFINED -+ #define MODE_T_DEFINED -+ typedef unsigned short mode_t; -+#endif -+ -+/* -+** We may need to provide the "ino_t" type. -+*/ -+ -+#ifndef INO_T_DEFINED -+ #define INO_T_DEFINED -+ typedef unsigned short ino_t; -+#endif -+ -+/* -+** We need to define "NAME_MAX" if it was not present in "limits.h". -+*/ -+ -+#ifndef NAME_MAX -+# ifdef FILENAME_MAX -+# define NAME_MAX (FILENAME_MAX) -+# else -+# define NAME_MAX (260) -+# endif -+#endif -+ -+/* -+** We need to define "NULL_INTPTR_T" and "BAD_INTPTR_T". -+*/ -+ -+#ifndef NULL_INTPTR_T -+# define NULL_INTPTR_T ((intptr_t)(0)) -+#endif -+ -+#ifndef BAD_INTPTR_T -+# define BAD_INTPTR_T ((intptr_t)(-1)) -+#endif -+ -+/* -+** We need to provide the necessary structures and related types. -+*/ -+ -+#ifndef DIRENT_DEFINED -+#define DIRENT_DEFINED -+typedef struct DIRENT DIRENT; -+typedef DIRENT *LPDIRENT; -+struct DIRENT { -+ ino_t d_ino; /* Sequence number, do not use. */ -+ unsigned d_attributes; /* Win32 file attributes. */ -+ char d_name[NAME_MAX + 1]; /* Name within the directory. */ -+}; -+#endif -+ -+#ifndef DIR_DEFINED -+#define DIR_DEFINED -+typedef struct DIR DIR; -+typedef DIR *LPDIR; -+struct DIR { -+ intptr_t d_handle; /* Value returned by "_findfirst". */ -+ DIRENT d_first; /* DIRENT constructed based on "_findfirst". */ -+ DIRENT d_next; /* DIRENT constructed based on "_findnext". */ -+}; -+#endif -+ -+/* -+** Provide a macro, for use by the implementation, to determine if a -+** particular directory entry should be skipped over when searching for -+** the next directory entry that should be returned by the readdir() or -+** readdir_r() functions. -+*/ -+ -+#ifndef is_filtered -+# define is_filtered(a) ((((a).attrib)&_A_HIDDEN) || (((a).attrib)&_A_SYSTEM)) -+#endif -+ -+/* -+** Provide the function prototype for the POSIX compatiable getenv() -+** function. This function is not thread-safe. -+*/ -+ -+extern const char *windirent_getenv(const char *name); -+ -+/* -+** Finally, we can provide the function prototypes for the opendir(), -+** readdir(), readdir_r(), and closedir() POSIX functions. -+*/ -+ -+extern LPDIR opendir(const char *dirname); -+extern LPDIRENT readdir(LPDIR dirp); -+extern INT readdir_r(LPDIR dirp, LPDIRENT entry, LPDIRENT *result); -+extern INT closedir(LPDIR dirp); -+ -+#endif /* defined(WIN32) && defined(_MSC_VER) */ -+ -+/************************* End test_windirent.h ********************/ -+/************************* Begin test_windirent.c ******************/ -+/* -+** 2015 November 30 -+** -+** 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 contains code to implement most of the opendir() family of -+** POSIX functions on Win32 using the MSVCRT. -+*/ -+ -+#if defined(_WIN32) && defined(_MSC_VER) -+/* #include "test_windirent.h" */ -+ -+/* -+** Implementation of the POSIX getenv() function using the Win32 API. -+** This function is not thread-safe. -+*/ -+const char *windirent_getenv( -+ const char *name -+){ -+ static char value[32768]; /* Maximum length, per MSDN */ -+ DWORD dwSize = sizeof(value) / sizeof(char); /* Size in chars */ -+ DWORD dwRet; /* Value returned by GetEnvironmentVariableA() */ -+ -+ memset(value, 0, sizeof(value)); -+ dwRet = GetEnvironmentVariableA(name, value, dwSize); -+ if( dwRet==0 || dwRet>dwSize ){ -+ /* -+ ** The function call to GetEnvironmentVariableA() failed -OR- -+ ** the buffer is not large enough. Either way, return NULL. -+ */ -+ return 0; -+ }else{ -+ /* -+ ** The function call to GetEnvironmentVariableA() succeeded -+ ** -AND- the buffer contains the entire value. -+ */ -+ return value; -+ } -+} -+ -+/* -+** Implementation of the POSIX opendir() function using the MSVCRT. -+*/ -+LPDIR opendir( -+ const char *dirname -+){ -+ struct _finddata_t data; -+ LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR)); -+ SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]); -+ -+ if( dirp==NULL ) return NULL; -+ memset(dirp, 0, sizeof(DIR)); -+ -+ /* TODO: Remove this if Unix-style root paths are not used. */ -+ if( sqlite3_stricmp(dirname, "/")==0 ){ -+ dirname = windirent_getenv("SystemDrive"); -+ } -+ -+ memset(&data, 0, sizeof(struct _finddata_t)); -+ _snprintf(data.name, namesize, "%s\\*", dirname); -+ dirp->d_handle = _findfirst(data.name, &data); -+ -+ if( dirp->d_handle==BAD_INTPTR_T ){ -+ closedir(dirp); -+ return NULL; -+ } -+ -+ /* TODO: Remove this block to allow hidden and/or system files. */ -+ if( is_filtered(data) ){ -+next: -+ -+ memset(&data, 0, sizeof(struct _finddata_t)); -+ if( _findnext(dirp->d_handle, &data)==-1 ){ -+ closedir(dirp); -+ return NULL; -+ } -+ -+ /* TODO: Remove this block to allow hidden and/or system files. */ -+ if( is_filtered(data) ) goto next; -+ } -+ -+ dirp->d_first.d_attributes = data.attrib; -+ strncpy(dirp->d_first.d_name, data.name, NAME_MAX); -+ dirp->d_first.d_name[NAME_MAX] = '\0'; -+ -+ return dirp; -+} -+ -+/* -+** Implementation of the POSIX readdir() function using the MSVCRT. -+*/ -+LPDIRENT readdir( -+ LPDIR dirp -+){ -+ struct _finddata_t data; -+ -+ if( dirp==NULL ) return NULL; -+ -+ if( dirp->d_first.d_ino==0 ){ -+ dirp->d_first.d_ino++; -+ dirp->d_next.d_ino++; -+ -+ return &dirp->d_first; -+ } -+ -+next: -+ -+ memset(&data, 0, sizeof(struct _finddata_t)); -+ if( _findnext(dirp->d_handle, &data)==-1 ) return NULL; -+ -+ /* TODO: Remove this block to allow hidden and/or system files. */ -+ if( is_filtered(data) ) goto next; -+ -+ dirp->d_next.d_ino++; -+ dirp->d_next.d_attributes = data.attrib; -+ strncpy(dirp->d_next.d_name, data.name, NAME_MAX); -+ dirp->d_next.d_name[NAME_MAX] = '\0'; -+ -+ return &dirp->d_next; -+} -+ -+/* -+** Implementation of the POSIX readdir_r() function using the MSVCRT. -+*/ -+INT readdir_r( -+ LPDIR dirp, -+ LPDIRENT entry, -+ LPDIRENT *result -+){ -+ struct _finddata_t data; -+ -+ if( dirp==NULL ) return EBADF; -+ -+ if( dirp->d_first.d_ino==0 ){ -+ dirp->d_first.d_ino++; -+ dirp->d_next.d_ino++; -+ -+ entry->d_ino = dirp->d_first.d_ino; -+ entry->d_attributes = dirp->d_first.d_attributes; -+ strncpy(entry->d_name, dirp->d_first.d_name, NAME_MAX); -+ entry->d_name[NAME_MAX] = '\0'; -+ -+ *result = entry; -+ return 0; -+ } -+ -+next: -+ -+ memset(&data, 0, sizeof(struct _finddata_t)); -+ if( _findnext(dirp->d_handle, &data)==-1 ){ -+ *result = NULL; -+ return ENOENT; -+ } -+ -+ /* TODO: Remove this block to allow hidden and/or system files. */ -+ if( is_filtered(data) ) goto next; -+ -+ entry->d_ino = (ino_t)-1; /* not available */ -+ entry->d_attributes = data.attrib; -+ strncpy(entry->d_name, data.name, NAME_MAX); -+ entry->d_name[NAME_MAX] = '\0'; -+ -+ *result = entry; -+ return 0; -+} -+ -+/* -+** Implementation of the POSIX closedir() function using the MSVCRT. -+*/ -+INT closedir( -+ LPDIR dirp -+){ -+ INT result = 0; -+ -+ if( dirp==NULL ) return EINVAL; -+ -+ if( dirp->d_handle!=NULL_INTPTR_T && dirp->d_handle!=BAD_INTPTR_T ){ -+ result = _findclose(dirp->d_handle); -+ } -+ -+ sqlite3_free(dirp); -+ return result; -+} -+ -+#endif /* defined(WIN32) && defined(_MSC_VER) */ -+ -+/************************* End test_windirent.c ********************/ -+#define dirent DIRENT -+#endif - /************************* Begin ../ext/misc/shathree.c ******************/ - /* - ** 2017-03-08 -@@ -824,7 +1317,7 @@ - ** - ****************************************************************************** - ** --** This SQLite extension implements a functions that compute SHA1 hashes. -+** This SQLite extension implements functions that compute SHA3 hashes. - ** Two SQL functions are implemented: - ** - ** sha3(X,SIZE) -@@ -844,7 +1337,7 @@ - #include <assert.h> - #include <string.h> - #include <stdarg.h> --typedef sqlite3_uint64 u64; -+/* typedef sqlite3_uint64 u64; */ - - /****************************************************************************** - ** The Hash Engine -@@ -891,9 +1384,9 @@ - */ - static void KeccakF1600Step(SHA3Context *p){ - int i; -- u64 B0, B1, B2, B3, B4; -- u64 C0, C1, C2, C3, C4; -- u64 D0, D1, D2, D3, D4; -+ u64 b0, b1, b2, b3, b4; -+ u64 c0, c1, c2, c3, c4; -+ u64 d0, d1, d2, d3, d4; - static const u64 RC[] = { - 0x0000000000000001ULL, 0x0000000000008082ULL, - 0x800000000000808aULL, 0x8000000080008000ULL, -@@ -908,301 +1401,301 @@ - 0x8000000080008081ULL, 0x8000000000008080ULL, - 0x0000000080000001ULL, 0x8000000080008008ULL - }; --# define A00 (p->u.s[0]) --# define A01 (p->u.s[1]) --# define A02 (p->u.s[2]) --# define A03 (p->u.s[3]) --# define A04 (p->u.s[4]) --# define A10 (p->u.s[5]) --# define A11 (p->u.s[6]) --# define A12 (p->u.s[7]) --# define A13 (p->u.s[8]) --# define A14 (p->u.s[9]) --# define A20 (p->u.s[10]) --# define A21 (p->u.s[11]) --# define A22 (p->u.s[12]) --# define A23 (p->u.s[13]) --# define A24 (p->u.s[14]) --# define A30 (p->u.s[15]) --# define A31 (p->u.s[16]) --# define A32 (p->u.s[17]) --# define A33 (p->u.s[18]) --# define A34 (p->u.s[19]) --# define A40 (p->u.s[20]) --# define A41 (p->u.s[21]) --# define A42 (p->u.s[22]) --# define A43 (p->u.s[23]) --# define A44 (p->u.s[24]) -+# define a00 (p->u.s[0]) -+# define a01 (p->u.s[1]) -+# define a02 (p->u.s[2]) -+# define a03 (p->u.s[3]) -+# define a04 (p->u.s[4]) -+# define a10 (p->u.s[5]) -+# define a11 (p->u.s[6]) -+# define a12 (p->u.s[7]) -+# define a13 (p->u.s[8]) -+# define a14 (p->u.s[9]) -+# define a20 (p->u.s[10]) -+# define a21 (p->u.s[11]) -+# define a22 (p->u.s[12]) -+# define a23 (p->u.s[13]) -+# define a24 (p->u.s[14]) -+# define a30 (p->u.s[15]) -+# define a31 (p->u.s[16]) -+# define a32 (p->u.s[17]) -+# define a33 (p->u.s[18]) -+# define a34 (p->u.s[19]) -+# define a40 (p->u.s[20]) -+# define a41 (p->u.s[21]) -+# define a42 (p->u.s[22]) -+# define a43 (p->u.s[23]) -+# define a44 (p->u.s[24]) - # define ROL64(a,x) ((a<<x)|(a>>(64-x))) - - for(i=0; i<24; i+=4){ -- C0 = A00^A10^A20^A30^A40; -- C1 = A01^A11^A21^A31^A41; -- C2 = A02^A12^A22^A32^A42; -- C3 = A03^A13^A23^A33^A43; -- C4 = A04^A14^A24^A34^A44; -- D0 = C4^ROL64(C1, 1); -- D1 = C0^ROL64(C2, 1); -- D2 = C1^ROL64(C3, 1); -- D3 = C2^ROL64(C4, 1); -- D4 = C3^ROL64(C0, 1); -+ c0 = a00^a10^a20^a30^a40; -+ c1 = a01^a11^a21^a31^a41; -+ c2 = a02^a12^a22^a32^a42; -+ c3 = a03^a13^a23^a33^a43; -+ c4 = a04^a14^a24^a34^a44; -+ d0 = c4^ROL64(c1, 1); -+ d1 = c0^ROL64(c2, 1); -+ d2 = c1^ROL64(c3, 1); -+ d3 = c2^ROL64(c4, 1); -+ d4 = c3^ROL64(c0, 1); - -- B0 = (A00^D0); -- B1 = ROL64((A11^D1), 44); -- B2 = ROL64((A22^D2), 43); -- B3 = ROL64((A33^D3), 21); -- B4 = ROL64((A44^D4), 14); -- A00 = B0 ^((~B1)& B2 ); -- A00 ^= RC[i]; -- A11 = B1 ^((~B2)& B3 ); -- A22 = B2 ^((~B3)& B4 ); -- A33 = B3 ^((~B4)& B0 ); -- A44 = B4 ^((~B0)& B1 ); -+ b0 = (a00^d0); -+ b1 = ROL64((a11^d1), 44); -+ b2 = ROL64((a22^d2), 43); -+ b3 = ROL64((a33^d3), 21); -+ b4 = ROL64((a44^d4), 14); -+ a00 = b0 ^((~b1)& b2 ); -+ a00 ^= RC[i]; -+ a11 = b1 ^((~b2)& b3 ); -+ a22 = b2 ^((~b3)& b4 ); -+ a33 = b3 ^((~b4)& b0 ); -+ a44 = b4 ^((~b0)& b1 ); - -- B2 = ROL64((A20^D0), 3); -- B3 = ROL64((A31^D1), 45); -- B4 = ROL64((A42^D2), 61); -- B0 = ROL64((A03^D3), 28); -- B1 = ROL64((A14^D4), 20); -- A20 = B0 ^((~B1)& B2 ); -- A31 = B1 ^((~B2)& B3 ); -- A42 = B2 ^((~B3)& B4 ); -- A03 = B3 ^((~B4)& B0 ); -- A14 = B4 ^((~B0)& B1 ); -+ b2 = ROL64((a20^d0), 3); -+ b3 = ROL64((a31^d1), 45); -+ b4 = ROL64((a42^d2), 61); -+ b0 = ROL64((a03^d3), 28); -+ b1 = ROL64((a14^d4), 20); -+ a20 = b0 ^((~b1)& b2 ); -+ a31 = b1 ^((~b2)& b3 ); -+ a42 = b2 ^((~b3)& b4 ); -+ a03 = b3 ^((~b4)& b0 ); -+ a14 = b4 ^((~b0)& b1 ); - -- B4 = ROL64((A40^D0), 18); -- B0 = ROL64((A01^D1), 1); -- B1 = ROL64((A12^D2), 6); -- B2 = ROL64((A23^D3), 25); -- B3 = ROL64((A34^D4), 8); -- A40 = B0 ^((~B1)& B2 ); -- A01 = B1 ^((~B2)& B3 ); -- A12 = B2 ^((~B3)& B4 ); -- A23 = B3 ^((~B4)& B0 ); -- A34 = B4 ^((~B0)& B1 ); -+ b4 = ROL64((a40^d0), 18); -+ b0 = ROL64((a01^d1), 1); -+ b1 = ROL64((a12^d2), 6); -+ b2 = ROL64((a23^d3), 25); -+ b3 = ROL64((a34^d4), 8); -+ a40 = b0 ^((~b1)& b2 ); -+ a01 = b1 ^((~b2)& b3 ); -+ a12 = b2 ^((~b3)& b4 ); -+ a23 = b3 ^((~b4)& b0 ); -+ a34 = b4 ^((~b0)& b1 ); - -- B1 = ROL64((A10^D0), 36); -- B2 = ROL64((A21^D1), 10); -- B3 = ROL64((A32^D2), 15); -- B4 = ROL64((A43^D3), 56); -- B0 = ROL64((A04^D4), 27); -- A10 = B0 ^((~B1)& B2 ); -- A21 = B1 ^((~B2)& B3 ); -- A32 = B2 ^((~B3)& B4 ); -- A43 = B3 ^((~B4)& B0 ); -- A04 = B4 ^((~B0)& B1 ); -+ b1 = ROL64((a10^d0), 36); -+ b2 = ROL64((a21^d1), 10); -+ b3 = ROL64((a32^d2), 15); -+ b4 = ROL64((a43^d3), 56); -+ b0 = ROL64((a04^d4), 27); -+ a10 = b0 ^((~b1)& b2 ); -+ a21 = b1 ^((~b2)& b3 ); -+ a32 = b2 ^((~b3)& b4 ); -+ a43 = b3 ^((~b4)& b0 ); -+ a04 = b4 ^((~b0)& b1 ); - -- B3 = ROL64((A30^D0), 41); -- B4 = ROL64((A41^D1), 2); -- B0 = ROL64((A02^D2), 62); -- B1 = ROL64((A13^D3), 55); -- B2 = ROL64((A24^D4), 39); -- A30 = B0 ^((~B1)& B2 ); -- A41 = B1 ^((~B2)& B3 ); -- A02 = B2 ^((~B3)& B4 ); -- A13 = B3 ^((~B4)& B0 ); -- A24 = B4 ^((~B0)& B1 ); -+ b3 = ROL64((a30^d0), 41); -+ b4 = ROL64((a41^d1), 2); -+ b0 = ROL64((a02^d2), 62); -+ b1 = ROL64((a13^d3), 55); -+ b2 = ROL64((a24^d4), 39); -+ a30 = b0 ^((~b1)& b2 ); -+ a41 = b1 ^((~b2)& b3 ); -+ a02 = b2 ^((~b3)& b4 ); -+ a13 = b3 ^((~b4)& b0 ); -+ a24 = b4 ^((~b0)& b1 ); - -- C0 = A00^A20^A40^A10^A30; -- C1 = A11^A31^A01^A21^A41; -- C2 = A22^A42^A12^A32^A02; -- C3 = A33^A03^A23^A43^A13; -- C4 = A44^A14^A34^A04^A24; -- D0 = C4^ROL64(C1, 1); -- D1 = C0^ROL64(C2, 1); -- D2 = C1^ROL64(C3, 1); -- D3 = C2^ROL64(C4, 1); -- D4 = C3^ROL64(C0, 1); -+ c0 = a00^a20^a40^a10^a30; -+ c1 = a11^a31^a01^a21^a41; -+ c2 = a22^a42^a12^a32^a02; -+ c3 = a33^a03^a23^a43^a13; -+ c4 = a44^a14^a34^a04^a24; -+ d0 = c4^ROL64(c1, 1); -+ d1 = c0^ROL64(c2, 1); -+ d2 = c1^ROL64(c3, 1); -+ d3 = c2^ROL64(c4, 1); -+ d4 = c3^ROL64(c0, 1); - -- B0 = (A00^D0); -- B1 = ROL64((A31^D1), 44); -- B2 = ROL64((A12^D2), 43); -- B3 = ROL64((A43^D3), 21); -- B4 = ROL64((A24^D4), 14); -- A00 = B0 ^((~B1)& B2 ); -- A00 ^= RC[i+1]; -- A31 = B1 ^((~B2)& B3 ); -- A12 = B2 ^((~B3)& B4 ); -- A43 = B3 ^((~B4)& B0 ); -- A24 = B4 ^((~B0)& B1 ); -+ b0 = (a00^d0); -+ b1 = ROL64((a31^d1), 44); -+ b2 = ROL64((a12^d2), 43); -+ b3 = ROL64((a43^d3), 21); -+ b4 = ROL64((a24^d4), 14); -+ a00 = b0 ^((~b1)& b2 ); -+ a00 ^= RC[i+1]; -+ a31 = b1 ^((~b2)& b3 ); -+ a12 = b2 ^((~b3)& b4 ); -+ a43 = b3 ^((~b4)& b0 ); -+ a24 = b4 ^((~b0)& b1 ); - -- B2 = ROL64((A40^D0), 3); -- B3 = ROL64((A21^D1), 45); -- B4 = ROL64((A02^D2), 61); -- B0 = ROL64((A33^D3), 28); -- B1 = ROL64((A14^D4), 20); -- A40 = B0 ^((~B1)& B2 ); -- A21 = B1 ^((~B2)& B3 ); -- A02 = B2 ^((~B3)& B4 ); -- A33 = B3 ^((~B4)& B0 ); -- A14 = B4 ^((~B0)& B1 ); -+ b2 = ROL64((a40^d0), 3); -+ b3 = ROL64((a21^d1), 45); -+ b4 = ROL64((a02^d2), 61); -+ b0 = ROL64((a33^d3), 28); -+ b1 = ROL64((a14^d4), 20); -+ a40 = b0 ^((~b1)& b2 ); -+ a21 = b1 ^((~b2)& b3 ); -+ a02 = b2 ^((~b3)& b4 ); -+ a33 = b3 ^((~b4)& b0 ); -+ a14 = b4 ^((~b0)& b1 ); - -- B4 = ROL64((A30^D0), 18); -- B0 = ROL64((A11^D1), 1); -- B1 = ROL64((A42^D2), 6); -- B2 = ROL64((A23^D3), 25); -- B3 = ROL64((A04^D4), 8); -- A30 = B0 ^((~B1)& B2 ); -- A11 = B1 ^((~B2)& B3 ); -- A42 = B2 ^((~B3)& B4 ); -- A23 = B3 ^((~B4)& B0 ); -- A04 = B4 ^((~B0)& B1 ); -+ b4 = ROL64((a30^d0), 18); -+ b0 = ROL64((a11^d1), 1); -+ b1 = ROL64((a42^d2), 6); -+ b2 = ROL64((a23^d3), 25); -+ b3 = ROL64((a04^d4), 8); -+ a30 = b0 ^((~b1)& b2 ); -+ a11 = b1 ^((~b2)& b3 ); -+ a42 = b2 ^((~b3)& b4 ); -+ a23 = b3 ^((~b4)& b0 ); -+ a04 = b4 ^((~b0)& b1 ); - -- B1 = ROL64((A20^D0), 36); -- B2 = ROL64((A01^D1), 10); -- B3 = ROL64((A32^D2), 15); -- B4 = ROL64((A13^D3), 56); -- B0 = ROL64((A44^D4), 27); -- A20 = B0 ^((~B1)& B2 ); -- A01 = B1 ^((~B2)& B3 ); -- A32 = B2 ^((~B3)& B4 ); -- A13 = B3 ^((~B4)& B0 ); -- A44 = B4 ^((~B0)& B1 ); -+ b1 = ROL64((a20^d0), 36); -+ b2 = ROL64((a01^d1), 10); -+ b3 = ROL64((a32^d2), 15); -+ b4 = ROL64((a13^d3), 56); -+ b0 = ROL64((a44^d4), 27); -+ a20 = b0 ^((~b1)& b2 ); -+ a01 = b1 ^((~b2)& b3 ); -+ a32 = b2 ^((~b3)& b4 ); -+ a13 = b3 ^((~b4)& b0 ); -+ a44 = b4 ^((~b0)& b1 ); - -- B3 = ROL64((A10^D0), 41); -- B4 = ROL64((A41^D1), 2); -- B0 = ROL64((A22^D2), 62); -- B1 = ROL64((A03^D3), 55); -- B2 = ROL64((A34^D4), 39); -- A10 = B0 ^((~B1)& B2 ); -- A41 = B1 ^((~B2)& B3 ); -- A22 = B2 ^((~B3)& B4 ); -- A03 = B3 ^((~B4)& B0 ); -- A34 = B4 ^((~B0)& B1 ); -+ b3 = ROL64((a10^d0), 41); -+ b4 = ROL64((a41^d1), 2); -+ b0 = ROL64((a22^d2), 62); -+ b1 = ROL64((a03^d3), 55); -+ b2 = ROL64((a34^d4), 39); -+ a10 = b0 ^((~b1)& b2 ); -+ a41 = b1 ^((~b2)& b3 ); -+ a22 = b2 ^((~b3)& b4 ); -+ a03 = b3 ^((~b4)& b0 ); -+ a34 = b4 ^((~b0)& b1 ); - -- C0 = A00^A40^A30^A20^A10; -- C1 = A31^A21^A11^A01^A41; -- C2 = A12^A02^A42^A32^A22; -- C3 = A43^A33^A23^A13^A03; -- C4 = A24^A14^A04^A44^A34; -- D0 = C4^ROL64(C1, 1); -- D1 = C0^ROL64(C2, 1); -- D2 = C1^ROL64(C3, 1); -- D3 = C2^ROL64(C4, 1); -- D4 = C3^ROL64(C0, 1); -+ c0 = a00^a40^a30^a20^a10; -+ c1 = a31^a21^a11^a01^a41; -+ c2 = a12^a02^a42^a32^a22; -+ c3 = a43^a33^a23^a13^a03; -+ c4 = a24^a14^a04^a44^a34; -+ d0 = c4^ROL64(c1, 1); -+ d1 = c0^ROL64(c2, 1); -+ d2 = c1^ROL64(c3, 1); -+ d3 = c2^ROL64(c4, 1); -+ d4 = c3^ROL64(c0, 1); - -- B0 = (A00^D0); -- B1 = ROL64((A21^D1), 44); -- B2 = ROL64((A42^D2), 43); -- B3 = ROL64((A13^D3), 21); -- B4 = ROL64((A34^D4), 14); -- A00 = B0 ^((~B1)& B2 ); -- A00 ^= RC[i+2]; -- A21 = B1 ^((~B2)& B3 ); -- A42 = B2 ^((~B3)& B4 ); -- A13 = B3 ^((~B4)& B0 ); -- A34 = B4 ^((~B0)& B1 ); -+ b0 = (a00^d0); -+ b1 = ROL64((a21^d1), 44); -+ b2 = ROL64((a42^d2), 43); -+ b3 = ROL64((a13^d3), 21); -+ b4 = ROL64((a34^d4), 14); -+ a00 = b0 ^((~b1)& b2 ); -+ a00 ^= RC[i+2]; -+ a21 = b1 ^((~b2)& b3 ); -+ a42 = b2 ^((~b3)& b4 ); -+ a13 = b3 ^((~b4)& b0 ); -+ a34 = b4 ^((~b0)& b1 ); - -- B2 = ROL64((A30^D0), 3); -- B3 = ROL64((A01^D1), 45); -- B4 = ROL64((A22^D2), 61); -- B0 = ROL64((A43^D3), 28); -- B1 = ROL64((A14^D4), 20); -- A30 = B0 ^((~B1)& B2 ); -- A01 = B1 ^((~B2)& B3 ); -- A22 = B2 ^((~B3)& B4 ); -- A43 = B3 ^((~B4)& B0 ); -- A14 = B4 ^((~B0)& B1 ); -+ b2 = ROL64((a30^d0), 3); -+ b3 = ROL64((a01^d1), 45); -+ b4 = ROL64((a22^d2), 61); -+ b0 = ROL64((a43^d3), 28); -+ b1 = ROL64((a14^d4), 20); -+ a30 = b0 ^((~b1)& b2 ); -+ a01 = b1 ^((~b2)& b3 ); -+ a22 = b2 ^((~b3)& b4 ); -+ a43 = b3 ^((~b4)& b0 ); -+ a14 = b4 ^((~b0)& b1 ); - -- B4 = ROL64((A10^D0), 18); -- B0 = ROL64((A31^D1), 1); -- B1 = ROL64((A02^D2), 6); -- B2 = ROL64((A23^D3), 25); -- B3 = ROL64((A44^D4), 8); -- A10 = B0 ^((~B1)& B2 ); -- A31 = B1 ^((~B2)& B3 ); -- A02 = B2 ^((~B3)& B4 ); -- A23 = B3 ^((~B4)& B0 ); -- A44 = B4 ^((~B0)& B1 ); -+ b4 = ROL64((a10^d0), 18); -+ b0 = ROL64((a31^d1), 1); -+ b1 = ROL64((a02^d2), 6); -+ b2 = ROL64((a23^d3), 25); -+ b3 = ROL64((a44^d4), 8); -+ a10 = b0 ^((~b1)& b2 ); -+ a31 = b1 ^((~b2)& b3 ); -+ a02 = b2 ^((~b3)& b4 ); -+ a23 = b3 ^((~b4)& b0 ); -+ a44 = b4 ^((~b0)& b1 ); - -- B1 = ROL64((A40^D0), 36); -- B2 = ROL64((A11^D1), 10); -- B3 = ROL64((A32^D2), 15); -- B4 = ROL64((A03^D3), 56); -- B0 = ROL64((A24^D4), 27); -- A40 = B0 ^((~B1)& B2 ); -- A11 = B1 ^((~B2)& B3 ); -- A32 = B2 ^((~B3)& B4 ); -- A03 = B3 ^((~B4)& B0 ); -- A24 = B4 ^((~B0)& B1 ); -+ b1 = ROL64((a40^d0), 36); -+ b2 = ROL64((a11^d1), 10); -+ b3 = ROL64((a32^d2), 15); -+ b4 = ROL64((a03^d3), 56); -+ b0 = ROL64((a24^d4), 27); -+ a40 = b0 ^((~b1)& b2 ); -+ a11 = b1 ^((~b2)& b3 ); -+ a32 = b2 ^((~b3)& b4 ); -+ a03 = b3 ^((~b4)& b0 ); -+ a24 = b4 ^((~b0)& b1 ); - -- B3 = ROL64((A20^D0), 41); -- B4 = ROL64((A41^D1), 2); -- B0 = ROL64((A12^D2), 62); -- B1 = ROL64((A33^D3), 55); -- B2 = ROL64((A04^D4), 39); -- A20 = B0 ^((~B1)& B2 ); -- A41 = B1 ^((~B2)& B3 ); -- A12 = B2 ^((~B3)& B4 ); -- A33 = B3 ^((~B4)& B0 ); -- A04 = B4 ^((~B0)& B1 ); -+ b3 = ROL64((a20^d0), 41); -+ b4 = ROL64((a41^d1), 2); -+ b0 = ROL64((a12^d2), 62); -+ b1 = ROL64((a33^d3), 55); -+ b2 = ROL64((a04^d4), 39); -+ a20 = b0 ^((~b1)& b2 ); -+ a41 = b1 ^((~b2)& b3 ); -+ a12 = b2 ^((~b3)& b4 ); -+ a33 = b3 ^((~b4)& b0 ); -+ a04 = b4 ^((~b0)& b1 ); - -- C0 = A00^A30^A10^A40^A20; -- C1 = A21^A01^A31^A11^A41; -- C2 = A42^A22^A02^A32^A12; -- C3 = A13^A43^A23^A03^A33; -- C4 = A34^A14^A44^A24^A04; -- D0 = C4^ROL64(C1, 1); -- D1 = C0^ROL64(C2, 1); -- D2 = C1^ROL64(C3, 1); -- D3 = C2^ROL64(C4, 1); -- D4 = C3^ROL64(C0, 1); -+ c0 = a00^a30^a10^a40^a20; -+ c1 = a21^a01^a31^a11^a41; -+ c2 = a42^a22^a02^a32^a12; -+ c3 = a13^a43^a23^a03^a33; -+ c4 = a34^a14^a44^a24^a04; -+ d0 = c4^ROL64(c1, 1); -+ d1 = c0^ROL64(c2, 1); -+ d2 = c1^ROL64(c3, 1); -+ d3 = c2^ROL64(c4, 1); -+ d4 = c3^ROL64(c0, 1); - -- B0 = (A00^D0); -- B1 = ROL64((A01^D1), 44); -- B2 = ROL64((A02^D2), 43); -- B3 = ROL64((A03^D3), 21); -- B4 = ROL64((A04^D4), 14); -- A00 = B0 ^((~B1)& B2 ); -- A00 ^= RC[i+3]; -- A01 = B1 ^((~B2)& B3 ); -- A02 = B2 ^((~B3)& B4 ); -- A03 = B3 ^((~B4)& B0 ); -- A04 = B4 ^((~B0)& B1 ); -+ b0 = (a00^d0); -+ b1 = ROL64((a01^d1), 44); -+ b2 = ROL64((a02^d2), 43); -+ b3 = ROL64((a03^d3), 21); -+ b4 = ROL64((a04^d4), 14); -+ a00 = b0 ^((~b1)& b2 ); -+ a00 ^= RC[i+3]; -+ a01 = b1 ^((~b2)& b3 ); -+ a02 = b2 ^((~b3)& b4 ); -+ a03 = b3 ^((~b4)& b0 ); -+ a04 = b4 ^((~b0)& b1 ); - -- B2 = ROL64((A10^D0), 3); -- B3 = ROL64((A11^D1), 45); -- B4 = ROL64((A12^D2), 61); -- B0 = ROL64((A13^D3), 28); -- B1 = ROL64((A14^D4), 20); -- A10 = B0 ^((~B1)& B2 ); -- A11 = B1 ^((~B2)& B3 ); -- A12 = B2 ^((~B3)& B4 ); -- A13 = B3 ^((~B4)& B0 ); -- A14 = B4 ^((~B0)& B1 ); -+ b2 = ROL64((a10^d0), 3); -+ b3 = ROL64((a11^d1), 45); -+ b4 = ROL64((a12^d2), 61); -+ b0 = ROL64((a13^d3), 28); -+ b1 = ROL64((a14^d4), 20); -+ a10 = b0 ^((~b1)& b2 ); -+ a11 = b1 ^((~b2)& b3 ); -+ a12 = b2 ^((~b3)& b4 ); -+ a13 = b3 ^((~b4)& b0 ); -+ a14 = b4 ^((~b0)& b1 ); - -- B4 = ROL64((A20^D0), 18); -- B0 = ROL64((A21^D1), 1); -- B1 = ROL64((A22^D2), 6); -- B2 = ROL64((A23^D3), 25); -- B3 = ROL64((A24^D4), 8); -- A20 = B0 ^((~B1)& B2 ); -- A21 = B1 ^((~B2)& B3 ); -- A22 = B2 ^((~B3)& B4 ); -- A23 = B3 ^((~B4)& B0 ); -- A24 = B4 ^((~B0)& B1 ); -+ b4 = ROL64((a20^d0), 18); -+ b0 = ROL64((a21^d1), 1); -+ b1 = ROL64((a22^d2), 6); -+ b2 = ROL64((a23^d3), 25); -+ b3 = ROL64((a24^d4), 8); -+ a20 = b0 ^((~b1)& b2 ); -+ a21 = b1 ^((~b2)& b3 ); -+ a22 = b2 ^((~b3)& b4 ); -+ a23 = b3 ^((~b4)& b0 ); -+ a24 = b4 ^((~b0)& b1 ); - -- B1 = ROL64((A30^D0), 36); -- B2 = ROL64((A31^D1), 10); -- B3 = ROL64((A32^D2), 15); -- B4 = ROL64((A33^D3), 56); -- B0 = ROL64((A34^D4), 27); -- A30 = B0 ^((~B1)& B2 ); -- A31 = B1 ^((~B2)& B3 ); -- A32 = B2 ^((~B3)& B4 ); -- A33 = B3 ^((~B4)& B0 ); -- A34 = B4 ^((~B0)& B1 ); -+ b1 = ROL64((a30^d0), 36); -+ b2 = ROL64((a31^d1), 10); -+ b3 = ROL64((a32^d2), 15); -+ b4 = ROL64((a33^d3), 56); -+ b0 = ROL64((a34^d4), 27); -+ a30 = b0 ^((~b1)& b2 ); -+ a31 = b1 ^((~b2)& b3 ); -+ a32 = b2 ^((~b3)& b4 ); -+ a33 = b3 ^((~b4)& b0 ); -+ a34 = b4 ^((~b0)& b1 ); - -- B3 = ROL64((A40^D0), 41); -- B4 = ROL64((A41^D1), 2); -- B0 = ROL64((A42^D2), 62); -- B1 = ROL64((A43^D3), 55); -- B2 = ROL64((A44^D4), 39); -- A40 = B0 ^((~B1)& B2 ); -- A41 = B1 ^((~B2)& B3 ); -- A42 = B2 ^((~B3)& B4 ); -- A43 = B3 ^((~B4)& B0 ); -- A44 = B4 ^((~B0)& B1 ); -+ b3 = ROL64((a40^d0), 41); -+ b4 = ROL64((a41^d1), 2); -+ b0 = ROL64((a42^d2), 62); -+ b1 = ROL64((a43^d3), 55); -+ b2 = ROL64((a44^d4), 39); -+ a40 = b0 ^((~b1)& b2 ); -+ a41 = b1 ^((~b2)& b3 ); -+ a42 = b2 ^((~b3)& b4 ); -+ a43 = b3 ^((~b4)& b0 ); -+ a44 = b4 ^((~b0)& b1 ); - } - } - -@@ -1499,7 +1992,7 @@ - - - #ifdef _WIN32 --__declspec(dllexport) -+ - #endif - int sqlite3_shathree_init( - sqlite3 *db, -@@ -1541,29 +2034,122 @@ - ****************************************************************************** - ** - ** This SQLite extension implements SQL functions readfile() and --** writefile(). -+** writefile(), and eponymous virtual type "fsdir". -+** -+** WRITEFILE(FILE, DATA [, MODE [, MTIME]]): -+** -+** If neither of the optional arguments is present, then this UDF -+** function writes blob DATA to file FILE. If successful, the number -+** of bytes written is returned. If an error occurs, NULL is returned. -+** -+** If the first option argument - MODE - is present, then it must -+** be passed an integer value that corresponds to a POSIX mode -+** value (file type + permissions, as returned in the stat.st_mode -+** field by the stat() system call). Three types of files may -+** be written/created: -+** -+** regular files: (mode & 0170000)==0100000 -+** symbolic links: (mode & 0170000)==0120000 -+** directories: (mode & 0170000)==0040000 -+** -+** For a directory, the DATA is ignored. For a symbolic link, it is -+** interpreted as text and used as the target of the link. For a -+** regular file, it is interpreted as a blob and written into the -+** named file. Regardless of the type of file, its permissions are -+** set to (mode & 0777) before returning. -+** -+** If the optional MTIME argument is present, then it is interpreted -+** as an integer - the number of seconds since the unix epoch. The -+** modification-time of the target file is set to this value before -+** returning. -+** -+** If three or more arguments are passed to this function and an -+** error is encountered, an exception is raised. -+** -+** READFILE(FILE): -+** -+** Read and return the contents of file FILE (type blob) from disk. -+** -+** FSDIR: -+** -+** Used as follows: -+** -+** SELECT * FROM fsdir($path [, $dir]); -+** -+** Parameter $path is an absolute or relative pathname. If the file that it -+** refers to does not exist, it is an error. If the path refers to a regular -+** file or symbolic link, it returns a single row. Or, if the path refers -+** to a directory, it returns one row for the directory, and one row for each -+** file within the hierarchy rooted at $path. -+** -+** Each row has the following columns: -+** -+** name: Path to file or directory (text value). -+** mode: Value of stat.st_mode for directory entry (an integer). -+** mtime: Value of stat.st_mtime for directory entry (an integer). -+** data: For a regular file, a blob containing the file data. For a -+** symlink, a text value containing the text of the link. For a -+** directory, NULL. -+** -+** If a non-NULL value is specified for the optional $dir parameter and -+** $path is a relative path, then $path is interpreted relative to $dir. -+** And the paths returned in the "name" column of the table are also -+** relative to directory $dir. - */ - SQLITE_EXTENSION_INIT1 - #include <stdio.h> -+#include <string.h> -+#include <assert.h> - -+#include <sys/types.h> -+#include <sys/stat.h> -+#include <fcntl.h> -+#if !defined(_WIN32) && !defined(WIN32) -+# include <unistd.h> -+# include <dirent.h> -+# include <utime.h> -+# include <sys/time.h> -+#else -+# include "windows.h" -+# include <io.h> -+# include <direct.h> -+/* # include "test_windirent.h" */ -+# define dirent DIRENT -+# ifndef chmod -+# define chmod _chmod -+# endif -+# ifndef stat -+# define stat _stat -+# endif -+# define mkdir(path,mode) _mkdir(path) -+# define lstat(path,buf) stat(path,buf) -+#endif -+#include <time.h> -+#include <errno.h> -+ -+ - /* --** Implementation of the "readfile(X)" SQL function. The entire content --** of the file named X is read and returned as a BLOB. NULL is returned --** if the file does not exist or is unreadable. -+** Structure of the fsdir() table-valued function - */ --static void readfileFunc( -- sqlite3_context *context, -- int argc, -- sqlite3_value **argv --){ -- const char *zName; -+ /* 0 1 2 3 4 5 */ -+#define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)" -+#define FSDIR_COLUMN_NAME 0 /* Name of the file */ -+#define FSDIR_COLUMN_MODE 1 /* Access mode */ -+#define FSDIR_COLUMN_MTIME 2 /* Last modification time */ -+#define FSDIR_COLUMN_DATA 3 /* File content */ -+#define FSDIR_COLUMN_PATH 4 /* Path to top of search */ -+#define FSDIR_COLUMN_DIR 5 /* Path is relative to this directory */ -+ -+ -+/* -+** Set the result stored by context ctx to a blob containing the -+** contents of file zName. -+*/ -+static void readFileContents(sqlite3_context *ctx, const char *zName){ - FILE *in; - long nIn; - void *pBuf; - -- (void)(argc); /* Unused parameter */ -- zName = (const char*)sqlite3_value_text(argv[0]); -- if( zName==0 ) return; - in = fopen(zName, "rb"); - if( in==0 ) return; - fseek(in, 0, SEEK_END); -@@ -1571,7 +2157,7 @@ - rewind(in); - pBuf = sqlite3_malloc( nIn ); - if( pBuf && 1==fread(pBuf, nIn, 1, in) ){ -- sqlite3_result_blob(context, pBuf, nIn, sqlite3_free); -+ sqlite3_result_blob(ctx, pBuf, nIn, sqlite3_free); - }else{ - sqlite3_free(pBuf); - } -@@ -1579,39 +2165,807 @@ - } - - /* --** Implementation of the "writefile(X,Y)" SQL function. The argument Y --** is written into file X. The number of bytes written is returned. Or --** NULL is returned if something goes wrong, such as being unable to open --** file X for writing. -+** Implementation of the "readfile(X)" SQL function. The entire content -+** of the file named X is read and returned as a BLOB. NULL is returned -+** if the file does not exist or is unreadable. - */ -+static void readfileFunc( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ const char *zName; -+ (void)(argc); /* Unused parameter */ -+ zName = (const char*)sqlite3_value_text(argv[0]); -+ if( zName==0 ) return; -+ readFileContents(context, zName); -+} -+ -+/* -+** Set the error message contained in context ctx to the results of -+** vprintf(zFmt, ...). -+*/ -+static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){ -+ char *zMsg = 0; -+ va_list ap; -+ va_start(ap, zFmt); -+ zMsg = sqlite3_vmprintf(zFmt, ap); -+ sqlite3_result_error(ctx, zMsg, -1); -+ sqlite3_free(zMsg); -+ va_end(ap); -+} -+ -+#if defined(_WIN32) -+/* -+** This function is designed to convert a Win32 FILETIME structure into the -+** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC). -+*/ -+static sqlite3_uint64 fileTimeToUnixTime( -+ LPFILETIME pFileTime -+){ -+ SYSTEMTIME epochSystemTime; -+ ULARGE_INTEGER epochIntervals; -+ FILETIME epochFileTime; -+ ULARGE_INTEGER fileIntervals; -+ -+ memset(&epochSystemTime, 0, sizeof(SYSTEMTIME)); -+ epochSystemTime.wYear = 1970; -+ epochSystemTime.wMonth = 1; -+ epochSystemTime.wDay = 1; -+ SystemTimeToFileTime(&epochSystemTime, &epochFileTime); -+ epochIntervals.LowPart = epochFileTime.dwLowDateTime; -+ epochIntervals.HighPart = epochFileTime.dwHighDateTime; -+ -+ fileIntervals.LowPart = pFileTime->dwLowDateTime; -+ fileIntervals.HighPart = pFileTime->dwHighDateTime; -+ -+ return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000; -+} -+ -+/* -+** This function attempts to normalize the time values found in the stat() -+** buffer to UTC. This is necessary on Win32, where the runtime library -+** appears to return these values as local times. -+*/ -+static void statTimesToUtc( -+ const char *zPath, -+ struct stat *pStatBuf -+){ -+ HANDLE hFindFile; -+ WIN32_FIND_DATAW fd; -+ LPWSTR zUnicodeName; -+ extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*); -+ zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath); -+ if( zUnicodeName ){ -+ memset(&fd, 0, sizeof(WIN32_FIND_DATAW)); -+ hFindFile = FindFirstFileW(zUnicodeName, &fd); -+ if( hFindFile!=NULL ){ -+ pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime); -+ pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime); -+ pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime); -+ FindClose(hFindFile); -+ } -+ sqlite3_free(zUnicodeName); -+ } -+} -+#endif -+ -+/* -+** This function is used in place of stat(). On Windows, special handling -+** is required in order for the included time to be returned as UTC. On all -+** other systems, this function simply calls stat(). -+*/ -+static int fileStat( -+ const char *zPath, -+ struct stat *pStatBuf -+){ -+#if defined(_WIN32) -+ int rc = stat(zPath, pStatBuf); -+ if( rc==0 ) statTimesToUtc(zPath, pStatBuf); -+ return rc; -+#else -+ return stat(zPath, pStatBuf); -+#endif -+} -+ -+/* -+** This function is used in place of lstat(). On Windows, special handling -+** is required in order for the included time to be returned as UTC. On all -+** other systems, this function simply calls lstat(). -+*/ -+static int fileLinkStat( -+ const char *zPath, -+ struct stat *pStatBuf -+){ -+#if defined(_WIN32) -+ int rc = lstat(zPath, pStatBuf); -+ if( rc==0 ) statTimesToUtc(zPath, pStatBuf); -+ return rc; -+#else -+ return lstat(zPath, pStatBuf); -+#endif -+} -+ -+/* -+** Argument zFile is the name of a file that will be created and/or written -+** by SQL function writefile(). This function ensures that the directory -+** zFile will be written to exists, creating it if required. The permissions -+** for any path components created by this function are set to (mode&0777). -+** -+** If an OOM condition is encountered, SQLITE_NOMEM is returned. Otherwise, -+** SQLITE_OK is returned if the directory is successfully created, or -+** SQLITE_ERROR otherwise. -+*/ -+static int makeDirectory( -+ const char *zFile, -+ mode_t mode -+){ -+ char *zCopy = sqlite3_mprintf("%s", zFile); -+ int rc = SQLITE_OK; -+ -+ if( zCopy==0 ){ -+ rc = SQLITE_NOMEM; -+ }else{ -+ int nCopy = (int)strlen(zCopy); -+ int i = 1; -+ -+ while( rc==SQLITE_OK ){ -+ struct stat sStat; -+ int rc2; -+ -+ for(; zCopy[i]!='/' && i<nCopy; i++); -+ if( i==nCopy ) break; -+ zCopy[i] = '\0'; -+ -+ rc2 = fileStat(zCopy, &sStat); -+ if( rc2!=0 ){ -+ if( mkdir(zCopy, mode & 0777) ) rc = SQLITE_ERROR; -+ }else{ -+ if( !S_ISDIR(sStat.st_mode) ) rc = SQLITE_ERROR; -+ } -+ zCopy[i] = '/'; -+ i++; -+ } -+ -+ sqlite3_free(zCopy); -+ } -+ -+ return rc; -+} -+ -+/* -+** This function does the work for the writefile() UDF. Refer to -+** header comments at the top of this file for details. -+*/ -+static int writeFile( -+ sqlite3_context *pCtx, /* Context to return bytes written in */ -+ const char *zFile, /* File to write */ -+ sqlite3_value *pData, /* Data to write */ -+ mode_t mode, /* MODE parameter passed to writefile() */ -+ sqlite3_int64 mtime /* MTIME parameter (or -1 to not set time) */ -+){ -+#if !defined(_WIN32) && !defined(WIN32) -+ if( S_ISLNK(mode) ){ -+ const char *zTo = (const char*)sqlite3_value_text(pData); -+ if( symlink(zTo, zFile)<0 ) return 1; -+ }else -+#endif -+ { -+ if( S_ISDIR(mode) ){ -+ if( mkdir(zFile, mode) ){ -+ /* The mkdir() call to create the directory failed. This might not -+ ** be an error though - if there is already a directory at the same -+ ** path and either the permissions already match or can be changed -+ ** to do so using chmod(), it is not an error. */ -+ struct stat sStat; -+ if( errno!=EEXIST -+ || 0!=fileStat(zFile, &sStat) -+ || !S_ISDIR(sStat.st_mode) -+ || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777)) -+ ){ -+ return 1; -+ } -+ } -+ }else{ -+ sqlite3_int64 nWrite = 0; -+ const char *z; -+ int rc = 0; -+ FILE *out = fopen(zFile, "wb"); -+ if( out==0 ) return 1; -+ z = (const char*)sqlite3_value_blob(pData); -+ if( z ){ -+ sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out); -+ nWrite = sqlite3_value_bytes(pData); -+ if( nWrite!=n ){ -+ rc = 1; -+ } -+ } -+ fclose(out); -+ if( rc==0 && mode && chmod(zFile, mode & 0777) ){ -+ rc = 1; -+ } -+ if( rc ) return 2; -+ sqlite3_result_int64(pCtx, nWrite); -+ } -+ } -+ -+ if( mtime>=0 ){ -+#if defined(_WIN32) -+ /* Windows */ -+ FILETIME lastAccess; -+ FILETIME lastWrite; -+ SYSTEMTIME currentTime; -+ LONGLONG intervals; -+ HANDLE hFile; -+ LPWSTR zUnicodeName; -+ extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*); -+ -+ GetSystemTime(¤tTime); -+ SystemTimeToFileTime(¤tTime, &lastAccess); -+ intervals = Int32x32To64(mtime, 10000000) + 116444736000000000; -+ lastWrite.dwLowDateTime = (DWORD)intervals; -+ lastWrite.dwHighDateTime = intervals >> 32; -+ zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile); -+ if( zUnicodeName==0 ){ -+ return 1; -+ } -+ hFile = CreateFileW( -+ zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, -+ FILE_FLAG_BACKUP_SEMANTICS, NULL -+ ); -+ sqlite3_free(zUnicodeName); -+ if( hFile!=INVALID_HANDLE_VALUE ){ -+ BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite); -+ CloseHandle(hFile); -+ return !bResult; -+ }else{ -+ return 1; -+ } -+#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */ -+ /* Recent unix */ -+ struct timespec times[2]; -+ times[0].tv_nsec = times[1].tv_nsec = 0; -+ times[0].tv_sec = time(0); -+ times[1].tv_sec = mtime; -+ if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){ -+ return 1; -+ } -+#else -+ /* Legacy unix */ -+ struct timeval times[2]; -+ times[0].tv_usec = times[1].tv_usec = 0; -+ times[0].tv_sec = time(0); -+ times[1].tv_sec = mtime; -+ if( utimes(zFile, times) ){ -+ return 1; -+ } -+#endif -+ } -+ -+ return 0; -+} -+ -+/* -+** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function. -+** Refer to header comments at the top of this file for details. -+*/ - static void writefileFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv - ){ -- FILE *out; -- const char *z; -- sqlite3_int64 rc; - const char *zFile; -+ mode_t mode = 0; -+ int res; -+ sqlite3_int64 mtime = -1; - -- (void)(argc); /* Unused parameter */ -+ if( argc<2 || argc>4 ){ -+ sqlite3_result_error(context, -+ "wrong number of arguments to function writefile()", -1 -+ ); -+ return; -+ } -+ - zFile = (const char*)sqlite3_value_text(argv[0]); - if( zFile==0 ) return; -- out = fopen(zFile, "wb"); -- if( out==0 ) return; -- z = (const char*)sqlite3_value_blob(argv[1]); -- if( z==0 ){ -- rc = 0; -+ if( argc>=3 ){ -+ mode = (mode_t)sqlite3_value_int(argv[2]); -+ } -+ if( argc==4 ){ -+ mtime = sqlite3_value_int64(argv[3]); -+ } -+ -+ res = writeFile(context, zFile, argv[1], mode, mtime); -+ if( res==1 && errno==ENOENT ){ -+ if( makeDirectory(zFile, mode)==SQLITE_OK ){ -+ res = writeFile(context, zFile, argv[1], mode, mtime); -+ } -+ } -+ -+ if( argc>2 && res!=0 ){ -+ if( S_ISLNK(mode) ){ -+ ctxErrorMsg(context, "failed to create symlink: %s", zFile); -+ }else if( S_ISDIR(mode) ){ -+ ctxErrorMsg(context, "failed to create directory: %s", zFile); -+ }else{ -+ ctxErrorMsg(context, "failed to write file: %s", zFile); -+ } -+ } -+} -+ -+/* -+** SQL function: lsmode(MODE) -+** -+** Given a numberic st_mode from stat(), convert it into a human-readable -+** text string in the style of "ls -l". -+*/ -+static void lsModeFunc( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ int i; -+ int iMode = sqlite3_value_int(argv[0]); -+ char z[16]; -+ (void)argc; -+ if( S_ISLNK(iMode) ){ -+ z[0] = 'l'; -+ }else if( S_ISREG(iMode) ){ -+ z[0] = '-'; -+ }else if( S_ISDIR(iMode) ){ -+ z[0] = 'd'; - }else{ -- rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out); -+ z[0] = '?'; - } -- fclose(out); -- sqlite3_result_int64(context, rc); -+ for(i=0; i<3; i++){ -+ int m = (iMode >> ((2-i)*3)); -+ char *a = &z[1 + i*3]; -+ a[0] = (m & 0x4) ? 'r' : '-'; -+ a[1] = (m & 0x2) ? 'w' : '-'; -+ a[2] = (m & 0x1) ? 'x' : '-'; -+ } -+ z[10] = '\0'; -+ sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT); - } - -+#ifndef SQLITE_OMIT_VIRTUALTABLE - -+/* -+** Cursor type for recursively iterating through a directory structure. -+*/ -+typedef struct fsdir_cursor fsdir_cursor; -+typedef struct FsdirLevel FsdirLevel; -+ -+struct FsdirLevel { -+ DIR *pDir; /* From opendir() */ -+ char *zDir; /* Name of directory (nul-terminated) */ -+}; -+ -+struct fsdir_cursor { -+ sqlite3_vtab_cursor base; /* Base class - must be first */ -+ -+ int nLvl; /* Number of entries in aLvl[] array */ -+ int iLvl; /* Index of current entry */ -+ FsdirLevel *aLvl; /* Hierarchy of directories being traversed */ -+ -+ const char *zBase; -+ int nBase; -+ -+ struct stat sStat; /* Current lstat() results */ -+ char *zPath; /* Path to current entry */ -+ sqlite3_int64 iRowid; /* Current rowid */ -+}; -+ -+typedef struct fsdir_tab fsdir_tab; -+struct fsdir_tab { -+ sqlite3_vtab base; /* Base class - must be first */ -+}; -+ -+/* -+** Construct a new fsdir virtual table object. -+*/ -+static int fsdirConnect( -+ sqlite3 *db, -+ void *pAux, -+ int argc, const char *const*argv, -+ sqlite3_vtab **ppVtab, -+ char **pzErr -+){ -+ fsdir_tab *pNew = 0; -+ int rc; -+ (void)pAux; -+ (void)argc; -+ (void)argv; -+ (void)pzErr; -+ rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA); -+ if( rc==SQLITE_OK ){ -+ pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) ); -+ if( pNew==0 ) return SQLITE_NOMEM; -+ memset(pNew, 0, sizeof(*pNew)); -+ } -+ *ppVtab = (sqlite3_vtab*)pNew; -+ return rc; -+} -+ -+/* -+** This method is the destructor for fsdir vtab objects. -+*/ -+static int fsdirDisconnect(sqlite3_vtab *pVtab){ -+ sqlite3_free(pVtab); -+ return SQLITE_OK; -+} -+ -+/* -+** Constructor for a new fsdir_cursor object. -+*/ -+static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ -+ fsdir_cursor *pCur; -+ (void)p; -+ pCur = sqlite3_malloc( sizeof(*pCur) ); -+ if( pCur==0 ) return SQLITE_NOMEM; -+ memset(pCur, 0, sizeof(*pCur)); -+ pCur->iLvl = -1; -+ *ppCursor = &pCur->base; -+ return SQLITE_OK; -+} -+ -+/* -+** Reset a cursor back to the state it was in when first returned -+** by fsdirOpen(). -+*/ -+static void fsdirResetCursor(fsdir_cursor *pCur){ -+ int i; -+ for(i=0; i<=pCur->iLvl; i++){ -+ FsdirLevel *pLvl = &pCur->aLvl[i]; -+ if( pLvl->pDir ) closedir(pLvl->pDir); -+ sqlite3_free(pLvl->zDir); -+ } -+ sqlite3_free(pCur->zPath); -+ sqlite3_free(pCur->aLvl); -+ pCur->aLvl = 0; -+ pCur->zPath = 0; -+ pCur->zBase = 0; -+ pCur->nBase = 0; -+ pCur->nLvl = 0; -+ pCur->iLvl = -1; -+ pCur->iRowid = 1; -+} -+ -+/* -+** Destructor for an fsdir_cursor. -+*/ -+static int fsdirClose(sqlite3_vtab_cursor *cur){ -+ fsdir_cursor *pCur = (fsdir_cursor*)cur; -+ -+ fsdirResetCursor(pCur); -+ sqlite3_free(pCur); -+ return SQLITE_OK; -+} -+ -+/* -+** Set the error message for the virtual table associated with cursor -+** pCur to the results of vprintf(zFmt, ...). -+*/ -+static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...){ -+ va_list ap; -+ va_start(ap, zFmt); -+ pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap); -+ va_end(ap); -+} -+ -+ -+/* -+** Advance an fsdir_cursor to its next row of output. -+*/ -+static int fsdirNext(sqlite3_vtab_cursor *cur){ -+ fsdir_cursor *pCur = (fsdir_cursor*)cur; -+ mode_t m = pCur->sStat.st_mode; -+ -+ pCur->iRowid++; -+ if( S_ISDIR(m) ){ -+ /* Descend into this directory */ -+ int iNew = pCur->iLvl + 1; -+ FsdirLevel *pLvl; -+ if( iNew>=pCur->nLvl ){ -+ int nNew = iNew+1; -+ int nByte = nNew*sizeof(FsdirLevel); -+ FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc(pCur->aLvl, nByte); -+ if( aNew==0 ) return SQLITE_NOMEM; -+ memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl)); -+ pCur->aLvl = aNew; -+ pCur->nLvl = nNew; -+ } -+ pCur->iLvl = iNew; -+ pLvl = &pCur->aLvl[iNew]; -+ -+ pLvl->zDir = pCur->zPath; -+ pCur->zPath = 0; -+ pLvl->pDir = opendir(pLvl->zDir); -+ if( pLvl->pDir==0 ){ -+ fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath); -+ return SQLITE_ERROR; -+ } -+ } -+ -+ while( pCur->iLvl>=0 ){ -+ FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl]; -+ struct dirent *pEntry = readdir(pLvl->pDir); -+ if( pEntry ){ -+ if( pEntry->d_name[0]=='.' ){ -+ if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue; -+ if( pEntry->d_name[1]=='\0' ) continue; -+ } -+ sqlite3_free(pCur->zPath); -+ pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name); -+ if( pCur->zPath==0 ) return SQLITE_NOMEM; -+ if( fileLinkStat(pCur->zPath, &pCur->sStat) ){ -+ fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath); -+ return SQLITE_ERROR; -+ } -+ return SQLITE_OK; -+ } -+ closedir(pLvl->pDir); -+ sqlite3_free(pLvl->zDir); -+ pLvl->pDir = 0; -+ pLvl->zDir = 0; -+ pCur->iLvl--; -+ } -+ -+ /* EOF */ -+ sqlite3_free(pCur->zPath); -+ pCur->zPath = 0; -+ return SQLITE_OK; -+} -+ -+/* -+** Return values of columns for the row at which the series_cursor -+** is currently pointing. -+*/ -+static int fsdirColumn( -+ sqlite3_vtab_cursor *cur, /* The cursor */ -+ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ -+ int i /* Which column to return */ -+){ -+ fsdir_cursor *pCur = (fsdir_cursor*)cur; -+ switch( i ){ -+ case FSDIR_COLUMN_NAME: { -+ sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT); -+ break; -+ } -+ -+ case FSDIR_COLUMN_MODE: -+ sqlite3_result_int64(ctx, pCur->sStat.st_mode); -+ break; -+ -+ case FSDIR_COLUMN_MTIME: -+ sqlite3_result_int64(ctx, pCur->sStat.st_mtime); -+ break; -+ -+ case FSDIR_COLUMN_DATA: { -+ mode_t m = pCur->sStat.st_mode; -+ if( S_ISDIR(m) ){ -+ sqlite3_result_null(ctx); -+#if !defined(_WIN32) && !defined(WIN32) -+ }else if( S_ISLNK(m) ){ -+ char aStatic[64]; -+ char *aBuf = aStatic; -+ int nBuf = 64; -+ int n; -+ -+ while( 1 ){ -+ n = readlink(pCur->zPath, aBuf, nBuf); -+ if( n<nBuf ) break; -+ if( aBuf!=aStatic ) sqlite3_free(aBuf); -+ nBuf = nBuf*2; -+ aBuf = sqlite3_malloc(nBuf); -+ if( aBuf==0 ){ -+ sqlite3_result_error_nomem(ctx); -+ return SQLITE_NOMEM; -+ } -+ } -+ -+ sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT); -+ if( aBuf!=aStatic ) sqlite3_free(aBuf); -+#endif -+ }else{ -+ readFileContents(ctx, pCur->zPath); -+ } -+ } -+ case FSDIR_COLUMN_PATH: -+ default: { -+ /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters. -+ ** always return their values as NULL */ -+ break; -+ } -+ } -+ return SQLITE_OK; -+} -+ -+/* -+** Return the rowid for the current row. In this implementation, the -+** first row returned is assigned rowid value 1, and each subsequent -+** row a value 1 more than that of the previous. -+*/ -+static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ -+ fsdir_cursor *pCur = (fsdir_cursor*)cur; -+ *pRowid = pCur->iRowid; -+ return SQLITE_OK; -+} -+ -+/* -+** Return TRUE if the cursor has been moved off of the last -+** row of output. -+*/ -+static int fsdirEof(sqlite3_vtab_cursor *cur){ -+ fsdir_cursor *pCur = (fsdir_cursor*)cur; -+ return (pCur->zPath==0); -+} -+ -+/* -+** xFilter callback. -+** -+** idxNum==1 PATH parameter only -+** idxNum==2 Both PATH and DIR supplied -+*/ -+static int fsdirFilter( -+ sqlite3_vtab_cursor *cur, -+ int idxNum, const char *idxStr, -+ int argc, sqlite3_value **argv -+){ -+ const char *zDir = 0; -+ fsdir_cursor *pCur = (fsdir_cursor*)cur; -+ (void)idxStr; -+ fsdirResetCursor(pCur); -+ -+ if( idxNum==0 ){ -+ fsdirSetErrmsg(pCur, "table function fsdir requires an argument"); -+ return SQLITE_ERROR; -+ } -+ -+ assert( argc==idxNum && (argc==1 || argc==2) ); -+ zDir = (const char*)sqlite3_value_text(argv[0]); -+ if( zDir==0 ){ -+ fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument"); -+ return SQLITE_ERROR; -+ } -+ if( argc==2 ){ -+ pCur->zBase = (const char*)sqlite3_value_text(argv[1]); -+ } -+ if( pCur->zBase ){ -+ pCur->nBase = (int)strlen(pCur->zBase)+1; -+ pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir); -+ }else{ -+ pCur->zPath = sqlite3_mprintf("%s", zDir); -+ } -+ -+ if( pCur->zPath==0 ){ -+ return SQLITE_NOMEM; -+ } -+ if( fileLinkStat(pCur->zPath, &pCur->sStat) ){ -+ fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath); -+ return SQLITE_ERROR; -+ } -+ -+ return SQLITE_OK; -+} -+ -+/* -+** SQLite will invoke this method one or more times while planning a query -+** that uses the generate_series virtual table. This routine needs to create -+** a query plan for each invocation and compute an estimated cost for that -+** plan. -+** -+** In this implementation idxNum is used to represent the -+** query plan. idxStr is unused. -+** -+** The query plan is represented by values of idxNum: -+** -+** (1) The path value is supplied by argv[0] -+** (2) Path is in argv[0] and dir is in argv[1] -+*/ -+static int fsdirBestIndex( -+ sqlite3_vtab *tab, -+ sqlite3_index_info *pIdxInfo -+){ -+ int i; /* Loop over constraints */ -+ int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */ -+ int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */ -+ int seenPath = 0; /* True if an unusable PATH= constraint is seen */ -+ int seenDir = 0; /* True if an unusable DIR= constraint is seen */ -+ const struct sqlite3_index_constraint *pConstraint; -+ -+ (void)tab; -+ pConstraint = pIdxInfo->aConstraint; -+ for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ -+ if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; -+ switch( pConstraint->iColumn ){ -+ case FSDIR_COLUMN_PATH: { -+ if( pConstraint->usable ){ -+ idxPath = i; -+ seenPath = 0; -+ }else if( idxPath<0 ){ -+ seenPath = 1; -+ } -+ break; -+ } -+ case FSDIR_COLUMN_DIR: { -+ if( pConstraint->usable ){ -+ idxDir = i; -+ seenDir = 0; -+ }else if( idxDir<0 ){ -+ seenDir = 1; -+ } -+ break; -+ } -+ } -+ } -+ if( seenPath || seenDir ){ -+ /* If input parameters are unusable, disallow this plan */ -+ return SQLITE_CONSTRAINT; -+ } -+ -+ if( idxPath<0 ){ -+ pIdxInfo->idxNum = 0; -+ /* The pIdxInfo->estimatedCost should have been initialized to a huge -+ ** number. Leave it unchanged. */ -+ pIdxInfo->estimatedRows = 0x7fffffff; -+ }else{ -+ pIdxInfo->aConstraintUsage[idxPath].omit = 1; -+ pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1; -+ if( idxDir>=0 ){ -+ pIdxInfo->aConstraintUsage[idxDir].omit = 1; -+ pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2; -+ pIdxInfo->idxNum = 2; -+ pIdxInfo->estimatedCost = 10.0; -+ }else{ -+ pIdxInfo->idxNum = 1; -+ pIdxInfo->estimatedCost = 100.0; -+ } -+ } -+ -+ return SQLITE_OK; -+} -+ -+/* -+** Register the "fsdir" virtual table. -+*/ -+static int fsdirRegister(sqlite3 *db){ -+ static sqlite3_module fsdirModule = { -+ 0, /* iVersion */ -+ 0, /* xCreate */ -+ fsdirConnect, /* xConnect */ -+ fsdirBestIndex, /* xBestIndex */ -+ fsdirDisconnect, /* xDisconnect */ -+ 0, /* xDestroy */ -+ fsdirOpen, /* xOpen - open a cursor */ -+ fsdirClose, /* xClose - close a cursor */ -+ fsdirFilter, /* xFilter - configure scan constraints */ -+ fsdirNext, /* xNext - advance a cursor */ -+ fsdirEof, /* xEof - check for end of scan */ -+ fsdirColumn, /* xColumn - read data */ -+ fsdirRowid, /* xRowid - read data */ -+ 0, /* xUpdate */ -+ 0, /* xBegin */ -+ 0, /* xSync */ -+ 0, /* xCommit */ -+ 0, /* xRollback */ -+ 0, /* xFindMethod */ -+ 0, /* xRename */ -+ 0, /* xSavepoint */ -+ 0, /* xRelease */ -+ 0, /* xRollbackTo */ -+ 0, /* xShadowName */ -+ }; -+ -+ int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0); -+ return rc; -+} -+#else /* SQLITE_OMIT_VIRTUALTABLE */ -+# define fsdirRegister(x) SQLITE_OK -+#endif -+ - #ifdef _WIN32 --__declspec(dllexport) -+ - #endif - int sqlite3_fileio_init( - sqlite3 *db, -@@ -1624,9 +2978,16 @@ - rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0, - readfileFunc, 0, 0); - if( rc==SQLITE_OK ){ -- rc = sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0, -+ rc = sqlite3_create_function(db, "writefile", -1, SQLITE_UTF8, 0, - writefileFunc, 0, 0); - } -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0, -+ lsModeFunc, 0, 0); -+ } -+ if( rc==SQLITE_OK ){ -+ rc = fsdirRegister(db); -+ } - return rc; - } - -@@ -1695,6 +3056,7 @@ - char *zPrefix; /* The prefix for the word we want to complete */ - char *zLine; /* The whole that we want to complete */ - const char *zCurrentRow; /* Current output row */ -+ int szRow; /* Length of the zCurrentRow string */ - sqlite3_stmt *pStmt; /* Current statement */ - sqlite3_int64 iRowid; /* The rowid */ - int ePhase; /* Current phase */ -@@ -1711,7 +3073,7 @@ - #define COMPLETION_INDEXES 5 - #define COMPLETION_TRIGGERS 6 - #define COMPLETION_DATABASES 7 --#define COMPLETION_TABLES 8 -+#define COMPLETION_TABLES 8 /* Also VIEWs and TRIGGERs */ - #define COMPLETION_COLUMNS 9 - #define COMPLETION_MODULES 10 - #define COMPLETION_EOF 11 -@@ -1808,32 +3170,6 @@ - } - - /* --** All SQL keywords understood by SQLite --*/ --static const char *completionKwrds[] = { -- "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS", -- "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY", -- "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT", -- "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE", -- "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE", -- "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH", -- "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN", -- "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF", -- "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER", -- "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", -- "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL", -- "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA", -- "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP", -- "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT", -- "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP", -- "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE", -- "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE", -- "WITH", "WITHOUT", --}; --#define completionKwCount \ -- (int)(sizeof(completionKwrds)/sizeof(completionKwrds[0])) -- --/* - ** Advance a completion_cursor to its next row of output. - ** - ** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object -@@ -1855,11 +3191,11 @@ - while( pCur->ePhase!=COMPLETION_EOF ){ - switch( pCur->ePhase ){ - case COMPLETION_KEYWORDS: { -- if( pCur->j >= completionKwCount ){ -+ if( pCur->j >= sqlite3_keyword_count() ){ - pCur->zCurrentRow = 0; - pCur->ePhase = COMPLETION_DATABASES; - }else{ -- pCur->zCurrentRow = completionKwrds[pCur->j++]; -+ sqlite3_keyword_name(pCur->j++, &pCur->zCurrentRow, &pCur->szRow); - } - iCol = -1; - break; -@@ -1883,8 +3219,7 @@ - const char *zDb = (const char*)sqlite3_column_text(pS2, 1); - zSql = sqlite3_mprintf( - "%z%s" -- "SELECT name FROM \"%w\".sqlite_master" -- " WHERE type='table'", -+ "SELECT name FROM \"%w\".sqlite_master", - zSql, zSep, zDb - ); - if( zSql==0 ) return SQLITE_NOMEM; -@@ -1932,6 +3267,7 @@ - if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){ - /* Extract the next row of content */ - pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol); -+ pCur->szRow = sqlite3_column_bytes(pCur->pStmt, iCol); - }else{ - /* When all rows are finished, advance to the next phase */ - sqlite3_finalize(pCur->pStmt); -@@ -1941,7 +3277,9 @@ - } - } - if( pCur->nPrefix==0 ) break; -- if( sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0 ){ -+ if( pCur->nPrefix<=pCur->szRow -+ && sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0 -+ ){ - break; - } - } -@@ -1961,7 +3299,7 @@ - completion_cursor *pCur = (completion_cursor*)cur; - switch( i ){ - case COMPLETION_COLUMN_CANDIDATE: { -- sqlite3_result_text(ctx, pCur->zCurrentRow, -1, SQLITE_TRANSIENT); -+ sqlite3_result_text(ctx, pCur->zCurrentRow, pCur->szRow,SQLITE_TRANSIENT); - break; - } - case COMPLETION_COLUMN_PREFIX: { -@@ -2021,7 +3359,7 @@ - pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); - if( pCur->zPrefix==0 ) return SQLITE_NOMEM; - } -- iArg++; -+ iArg = 1; - } - if( idxNum & 2 ){ - pCur->nLine = sqlite3_value_bytes(argv[iArg]); -@@ -2029,7 +3367,6 @@ - pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); - if( pCur->zLine==0 ) return SQLITE_NOMEM; - } -- iArg++; - } - if( pCur->zLine!=0 && pCur->zPrefix==0 ){ - int i = pCur->nLine; -@@ -2125,7 +3462,8 @@ - 0, /* xRename */ - 0, /* xSavepoint */ - 0, /* xRelease */ -- 0 /* xRollbackTo */ -+ 0, /* xRollbackTo */ -+ 0 /* xShadowName */ - }; - - #endif /* SQLITE_OMIT_VIRTUALTABLE */ -@@ -2139,7 +3477,7 @@ - } - - #ifdef _WIN32 --__declspec(dllexport) -+ - #endif - int sqlite3_completion_init( - sqlite3 *db, -@@ -2156,7 +3494,5004 @@ - } - - /************************* End ../ext/misc/completion.c ********************/ -+/************************* Begin ../ext/misc/appendvfs.c ******************/ -+/* -+** 2017-10-20 -+** -+** 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 a VFS shim that allows an SQLite database to be -+** appended onto the end of some other file, such as an executable. -+** -+** A special record must appear at the end of the file that identifies the -+** file as an appended database and provides an offset to page 1. For -+** best performance page 1 should be located at a disk page boundary, though -+** that is not required. -+** -+** When opening a database using this VFS, the connection might treat -+** the file as an ordinary SQLite database, or it might treat is as a -+** database appended onto some other file. Here are the rules: -+** -+** (1) When opening a new empty file, that file is treated as an ordinary -+** database. -+** -+** (2) When opening a file that begins with the standard SQLite prefix -+** string "SQLite format 3", that file is treated as an ordinary -+** database. -+** -+** (3) When opening a file that ends with the appendvfs trailer string -+** "Start-Of-SQLite3-NNNNNNNN" that file is treated as an appended -+** database. -+** -+** (4) If none of the above apply and the SQLITE_OPEN_CREATE flag is -+** set, then a new database is appended to the already existing file. -+** -+** (5) Otherwise, SQLITE_CANTOPEN is returned. -+** -+** To avoid unnecessary complications with the PENDING_BYTE, the size of -+** the file containing the database is limited to 1GB. This VFS will refuse -+** to read or write past the 1GB mark. This restriction might be lifted in -+** future versions. For now, if you need a large database, then keep the -+** database in a separate file. -+** -+** If the file being opened is not an appended database, then this shim is -+** a pass-through into the default underlying VFS. -+**/ -+SQLITE_EXTENSION_INIT1 -+#include <string.h> -+#include <assert.h> - -+/* The append mark at the end of the database is: -+** -+** Start-Of-SQLite3-NNNNNNNN -+** 123456789 123456789 12345 -+** -+** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is -+** the offset to page 1. -+*/ -+#define APND_MARK_PREFIX "Start-Of-SQLite3-" -+#define APND_MARK_PREFIX_SZ 17 -+#define APND_MARK_SIZE 25 -+ -+/* -+** Maximum size of the combined prefix + database + append-mark. This -+** must be less than 0x40000000 to avoid locking issues on Windows. -+*/ -+#define APND_MAX_SIZE (65536*15259) -+ -+/* -+** Forward declaration of objects used by this utility -+*/ -+typedef struct sqlite3_vfs ApndVfs; -+typedef struct ApndFile ApndFile; -+ -+/* Access to a lower-level VFS that (might) implement dynamic loading, -+** access to randomness, etc. -+*/ -+#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) -+#define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1)) -+ -+/* An open file */ -+struct ApndFile { -+ sqlite3_file base; /* IO methods */ -+ sqlite3_int64 iPgOne; /* File offset to page 1 */ -+ sqlite3_int64 iMark; /* Start of the append-mark */ -+}; -+ -+/* -+** Methods for ApndFile -+*/ -+static int apndClose(sqlite3_file*); -+static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); -+static int apndWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); -+static int apndTruncate(sqlite3_file*, sqlite3_int64 size); -+static int apndSync(sqlite3_file*, int flags); -+static int apndFileSize(sqlite3_file*, sqlite3_int64 *pSize); -+static int apndLock(sqlite3_file*, int); -+static int apndUnlock(sqlite3_file*, int); -+static int apndCheckReservedLock(sqlite3_file*, int *pResOut); -+static int apndFileControl(sqlite3_file*, int op, void *pArg); -+static int apndSectorSize(sqlite3_file*); -+static int apndDeviceCharacteristics(sqlite3_file*); -+static int apndShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**); -+static int apndShmLock(sqlite3_file*, int offset, int n, int flags); -+static void apndShmBarrier(sqlite3_file*); -+static int apndShmUnmap(sqlite3_file*, int deleteFlag); -+static int apndFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); -+static int apndUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p); -+ -+/* -+** Methods for ApndVfs -+*/ -+static int apndOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); -+static int apndDelete(sqlite3_vfs*, const char *zName, int syncDir); -+static int apndAccess(sqlite3_vfs*, const char *zName, int flags, int *); -+static int apndFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); -+static void *apndDlOpen(sqlite3_vfs*, const char *zFilename); -+static void apndDlError(sqlite3_vfs*, int nByte, char *zErrMsg); -+static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void); -+static void apndDlClose(sqlite3_vfs*, void*); -+static int apndRandomness(sqlite3_vfs*, int nByte, char *zOut); -+static int apndSleep(sqlite3_vfs*, int microseconds); -+static int apndCurrentTime(sqlite3_vfs*, double*); -+static int apndGetLastError(sqlite3_vfs*, int, char *); -+static int apndCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); -+static int apndSetSystemCall(sqlite3_vfs*, const char*,sqlite3_syscall_ptr); -+static sqlite3_syscall_ptr apndGetSystemCall(sqlite3_vfs*, const char *z); -+static const char *apndNextSystemCall(sqlite3_vfs*, const char *zName); -+ -+static sqlite3_vfs apnd_vfs = { -+ 3, /* iVersion (set when registered) */ -+ 0, /* szOsFile (set when registered) */ -+ 1024, /* mxPathname */ -+ 0, /* pNext */ -+ "apndvfs", /* zName */ -+ 0, /* pAppData (set when registered) */ -+ apndOpen, /* xOpen */ -+ apndDelete, /* xDelete */ -+ apndAccess, /* xAccess */ -+ apndFullPathname, /* xFullPathname */ -+ apndDlOpen, /* xDlOpen */ -+ apndDlError, /* xDlError */ -+ apndDlSym, /* xDlSym */ -+ apndDlClose, /* xDlClose */ -+ apndRandomness, /* xRandomness */ -+ apndSleep, /* xSleep */ -+ apndCurrentTime, /* xCurrentTime */ -+ apndGetLastError, /* xGetLastError */ -+ apndCurrentTimeInt64, /* xCurrentTimeInt64 */ -+ apndSetSystemCall, /* xSetSystemCall */ -+ apndGetSystemCall, /* xGetSystemCall */ -+ apndNextSystemCall /* xNextSystemCall */ -+}; -+ -+static const sqlite3_io_methods apnd_io_methods = { -+ 3, /* iVersion */ -+ apndClose, /* xClose */ -+ apndRead, /* xRead */ -+ apndWrite, /* xWrite */ -+ apndTruncate, /* xTruncate */ -+ apndSync, /* xSync */ -+ apndFileSize, /* xFileSize */ -+ apndLock, /* xLock */ -+ apndUnlock, /* xUnlock */ -+ apndCheckReservedLock, /* xCheckReservedLock */ -+ apndFileControl, /* xFileControl */ -+ apndSectorSize, /* xSectorSize */ -+ apndDeviceCharacteristics, /* xDeviceCharacteristics */ -+ apndShmMap, /* xShmMap */ -+ apndShmLock, /* xShmLock */ -+ apndShmBarrier, /* xShmBarrier */ -+ apndShmUnmap, /* xShmUnmap */ -+ apndFetch, /* xFetch */ -+ apndUnfetch /* xUnfetch */ -+}; -+ -+ -+ -+/* -+** Close an apnd-file. -+*/ -+static int apndClose(sqlite3_file *pFile){ -+ pFile = ORIGFILE(pFile); -+ return pFile->pMethods->xClose(pFile); -+} -+ -+/* -+** Read data from an apnd-file. -+*/ -+static int apndRead( -+ sqlite3_file *pFile, -+ void *zBuf, -+ int iAmt, -+ sqlite_int64 iOfst -+){ -+ ApndFile *p = (ApndFile *)pFile; -+ pFile = ORIGFILE(pFile); -+ return pFile->pMethods->xRead(pFile, zBuf, iAmt, iOfst+p->iPgOne); -+} -+ -+/* -+** Add the append-mark onto the end of the file. -+*/ -+static int apndWriteMark(ApndFile *p, sqlite3_file *pFile){ -+ int i; -+ unsigned char a[APND_MARK_SIZE]; -+ memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ); -+ for(i=0; i<8; i++){ -+ a[APND_MARK_PREFIX_SZ+i] = (p->iPgOne >> (56 - i*8)) & 0xff; -+ } -+ return pFile->pMethods->xWrite(pFile, a, APND_MARK_SIZE, p->iMark); -+} -+ -+/* -+** Write data to an apnd-file. -+*/ -+static int apndWrite( -+ sqlite3_file *pFile, -+ const void *zBuf, -+ int iAmt, -+ sqlite_int64 iOfst -+){ -+ int rc; -+ ApndFile *p = (ApndFile *)pFile; -+ pFile = ORIGFILE(pFile); -+ if( iOfst+iAmt>=APND_MAX_SIZE ) return SQLITE_FULL; -+ rc = pFile->pMethods->xWrite(pFile, zBuf, iAmt, iOfst+p->iPgOne); -+ if( rc==SQLITE_OK && iOfst + iAmt + p->iPgOne > p->iMark ){ -+ sqlite3_int64 sz = 0; -+ rc = pFile->pMethods->xFileSize(pFile, &sz); -+ if( rc==SQLITE_OK ){ -+ p->iMark = sz - APND_MARK_SIZE; -+ if( iOfst + iAmt + p->iPgOne > p->iMark ){ -+ p->iMark = p->iPgOne + iOfst + iAmt; -+ rc = apndWriteMark(p, pFile); -+ } -+ } -+ } -+ return rc; -+} -+ -+/* -+** Truncate an apnd-file. -+*/ -+static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){ -+ int rc; -+ ApndFile *p = (ApndFile *)pFile; -+ pFile = ORIGFILE(pFile); -+ rc = pFile->pMethods->xTruncate(pFile, size+p->iPgOne+APND_MARK_SIZE); -+ if( rc==SQLITE_OK ){ -+ p->iMark = p->iPgOne+size; -+ rc = apndWriteMark(p, pFile); -+ } -+ return rc; -+} -+ -+/* -+** Sync an apnd-file. -+*/ -+static int apndSync(sqlite3_file *pFile, int flags){ -+ pFile = ORIGFILE(pFile); -+ return pFile->pMethods->xSync(pFile, flags); -+} -+ -+/* -+** Return the current file-size of an apnd-file. -+*/ -+static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ -+ ApndFile *p = (ApndFile *)pFile; -+ int rc; -+ pFile = ORIGFILE(p); -+ rc = pFile->pMethods->xFileSize(pFile, pSize); -+ if( rc==SQLITE_OK && p->iPgOne ){ -+ *pSize -= p->iPgOne + APND_MARK_SIZE; -+ } -+ return rc; -+} -+ -+/* -+** Lock an apnd-file. -+*/ -+static int apndLock(sqlite3_file *pFile, int eLock){ -+ pFile = ORIGFILE(pFile); -+ return pFile->pMethods->xLock(pFile, eLock); -+} -+ -+/* -+** Unlock an apnd-file. -+*/ -+static int apndUnlock(sqlite3_file *pFile, int eLock){ -+ pFile = ORIGFILE(pFile); -+ return pFile->pMethods->xUnlock(pFile, eLock); -+} -+ -+/* -+** Check if another file-handle holds a RESERVED lock on an apnd-file. -+*/ -+static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){ -+ pFile = ORIGFILE(pFile); -+ return pFile->pMethods->xCheckReservedLock(pFile, pResOut); -+} -+ -+/* -+** File control method. For custom operations on an apnd-file. -+*/ -+static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){ -+ ApndFile *p = (ApndFile *)pFile; -+ int rc; -+ pFile = ORIGFILE(pFile); -+ rc = pFile->pMethods->xFileControl(pFile, op, pArg); -+ if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){ -+ *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", p->iPgOne, *(char**)pArg); -+ } -+ return rc; -+} -+ -+/* -+** Return the sector-size in bytes for an apnd-file. -+*/ -+static int apndSectorSize(sqlite3_file *pFile){ -+ pFile = ORIGFILE(pFile); -+ return pFile->pMethods->xSectorSize(pFile); -+} -+ -+/* -+** Return the device characteristic flags supported by an apnd-file. -+*/ -+static int apndDeviceCharacteristics(sqlite3_file *pFile){ -+ pFile = ORIGFILE(pFile); -+ return pFile->pMethods->xDeviceCharacteristics(pFile); -+} -+ -+/* Create a shared memory file mapping */ -+static int apndShmMap( -+ sqlite3_file *pFile, -+ int iPg, -+ int pgsz, -+ int bExtend, -+ void volatile **pp -+){ -+ pFile = ORIGFILE(pFile); -+ return pFile->pMethods->xShmMap(pFile,iPg,pgsz,bExtend,pp); -+} -+ -+/* Perform locking on a shared-memory segment */ -+static int apndShmLock(sqlite3_file *pFile, int offset, int n, int flags){ -+ pFile = ORIGFILE(pFile); -+ return pFile->pMethods->xShmLock(pFile,offset,n,flags); -+} -+ -+/* Memory barrier operation on shared memory */ -+static void apndShmBarrier(sqlite3_file *pFile){ -+ pFile = ORIGFILE(pFile); -+ pFile->pMethods->xShmBarrier(pFile); -+} -+ -+/* Unmap a shared memory segment */ -+static int apndShmUnmap(sqlite3_file *pFile, int deleteFlag){ -+ pFile = ORIGFILE(pFile); -+ return pFile->pMethods->xShmUnmap(pFile,deleteFlag); -+} -+ -+/* Fetch a page of a memory-mapped file */ -+static int apndFetch( -+ sqlite3_file *pFile, -+ sqlite3_int64 iOfst, -+ int iAmt, -+ void **pp -+){ -+ ApndFile *p = (ApndFile *)pFile; -+ pFile = ORIGFILE(pFile); -+ return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp); -+} -+ -+/* Release a memory-mapped page */ -+static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ -+ ApndFile *p = (ApndFile *)pFile; -+ pFile = ORIGFILE(pFile); -+ return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage); -+} -+ -+/* -+** Check to see if the file is an ordinary SQLite database file. -+*/ -+static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){ -+ int rc; -+ char zHdr[16]; -+ static const char aSqliteHdr[] = "SQLite format 3"; -+ if( sz<512 ) return 0; -+ rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0); -+ if( rc ) return 0; -+ return memcmp(zHdr, aSqliteHdr, sizeof(zHdr))==0; -+} -+ -+/* -+** Try to read the append-mark off the end of a file. Return the -+** start of the appended database if the append-mark is present. If -+** there is no append-mark, return -1; -+*/ -+static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){ -+ int rc, i; -+ sqlite3_int64 iMark; -+ unsigned char a[APND_MARK_SIZE]; -+ -+ if( sz<=APND_MARK_SIZE ) return -1; -+ rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE); -+ if( rc ) return -1; -+ if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1; -+ iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ]&0x7f))<<56; -+ for(i=1; i<8; i++){ -+ iMark += (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<(56-8*i); -+ } -+ return iMark; -+} -+ -+/* -+** Open an apnd file handle. -+*/ -+static int apndOpen( -+ sqlite3_vfs *pVfs, -+ const char *zName, -+ sqlite3_file *pFile, -+ int flags, -+ int *pOutFlags -+){ -+ ApndFile *p; -+ sqlite3_file *pSubFile; -+ sqlite3_vfs *pSubVfs; -+ int rc; -+ sqlite3_int64 sz; -+ pSubVfs = ORIGVFS(pVfs); -+ if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){ -+ return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags); -+ } -+ p = (ApndFile*)pFile; -+ memset(p, 0, sizeof(*p)); -+ pSubFile = ORIGFILE(pFile); -+ p->base.pMethods = &apnd_io_methods; -+ rc = pSubVfs->xOpen(pSubVfs, zName, pSubFile, flags, pOutFlags); -+ if( rc ) goto apnd_open_done; -+ rc = pSubFile->pMethods->xFileSize(pSubFile, &sz); -+ if( rc ){ -+ pSubFile->pMethods->xClose(pSubFile); -+ goto apnd_open_done; -+ } -+ if( apndIsOrdinaryDatabaseFile(sz, pSubFile) ){ -+ memmove(pFile, pSubFile, pSubVfs->szOsFile); -+ return SQLITE_OK; -+ } -+ p->iMark = 0; -+ p->iPgOne = apndReadMark(sz, pFile); -+ if( p->iPgOne>0 ){ -+ return SQLITE_OK; -+ } -+ if( (flags & SQLITE_OPEN_CREATE)==0 ){ -+ pSubFile->pMethods->xClose(pSubFile); -+ rc = SQLITE_CANTOPEN; -+ } -+ p->iPgOne = (sz+0xfff) & ~(sqlite3_int64)0xfff; -+apnd_open_done: -+ if( rc ) pFile->pMethods = 0; -+ return rc; -+} -+ -+/* -+** All other VFS methods are pass-thrus. -+*/ -+static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ -+ return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync); -+} -+static int apndAccess( -+ sqlite3_vfs *pVfs, -+ const char *zPath, -+ int flags, -+ int *pResOut -+){ -+ return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut); -+} -+static int apndFullPathname( -+ sqlite3_vfs *pVfs, -+ const char *zPath, -+ int nOut, -+ char *zOut -+){ -+ return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs),zPath,nOut,zOut); -+} -+static void *apndDlOpen(sqlite3_vfs *pVfs, const char *zPath){ -+ return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath); -+} -+static void apndDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ -+ ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg); -+} -+static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){ -+ return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym); -+} -+static void apndDlClose(sqlite3_vfs *pVfs, void *pHandle){ -+ ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle); -+} -+static int apndRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ -+ return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut); -+} -+static int apndSleep(sqlite3_vfs *pVfs, int nMicro){ -+ return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro); -+} -+static int apndCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ -+ return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut); -+} -+static int apndGetLastError(sqlite3_vfs *pVfs, int a, char *b){ -+ return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b); -+} -+static int apndCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ -+ return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p); -+} -+static int apndSetSystemCall( -+ sqlite3_vfs *pVfs, -+ const char *zName, -+ sqlite3_syscall_ptr pCall -+){ -+ return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall); -+} -+static sqlite3_syscall_ptr apndGetSystemCall( -+ sqlite3_vfs *pVfs, -+ const char *zName -+){ -+ return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs),zName); -+} -+static const char *apndNextSystemCall(sqlite3_vfs *pVfs, const char *zName){ -+ return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName); -+} -+ -+ -+#ifdef _WIN32 -+ -+#endif -+/* -+** This routine is called when the extension is loaded. -+** Register the new VFS. -+*/ -+int sqlite3_appendvfs_init( -+ sqlite3 *db, -+ char **pzErrMsg, -+ const sqlite3_api_routines *pApi -+){ -+ int rc = SQLITE_OK; -+ sqlite3_vfs *pOrig; -+ SQLITE_EXTENSION_INIT2(pApi); -+ (void)pzErrMsg; -+ (void)db; -+ pOrig = sqlite3_vfs_find(0); -+ apnd_vfs.iVersion = pOrig->iVersion; -+ apnd_vfs.pAppData = pOrig; -+ apnd_vfs.szOsFile = pOrig->szOsFile + sizeof(ApndFile); -+ rc = sqlite3_vfs_register(&apnd_vfs, 0); -+#ifdef APPENDVFS_TEST -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3_auto_extension((void(*)(void))apndvfsRegister); -+ } -+#endif -+ if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY; -+ return rc; -+} -+ -+/************************* End ../ext/misc/appendvfs.c ********************/ -+#ifdef SQLITE_HAVE_ZLIB -+/************************* Begin ../ext/misc/zipfile.c ******************/ -+/* -+** 2017-12-26 -+** -+** 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 a virtual table for reading and writing ZIP archive -+** files. -+** -+** Usage example: -+** -+** SELECT name, sz, datetime(mtime,'unixepoch') FROM zipfile($filename); -+** -+** Current limitations: -+** -+** * No support for encryption -+** * No support for ZIP archives spanning multiple files -+** * No support for zip64 extensions -+** * Only the "inflate/deflate" (zlib) compression method is supported -+*/ -+SQLITE_EXTENSION_INIT1 -+#include <stdio.h> -+#include <string.h> -+#include <assert.h> -+ -+#include <zlib.h> -+ -+#ifndef SQLITE_OMIT_VIRTUALTABLE -+ -+#ifndef SQLITE_AMALGAMATION -+ -+/* typedef sqlite3_int64 i64; */ -+/* typedef unsigned char u8; */ -+typedef unsigned short u16; -+typedef unsigned long u32; -+#define MIN(a,b) ((a)<(b) ? (a) : (b)) -+ -+#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) -+# define ALWAYS(X) (1) -+# define NEVER(X) (0) -+#elif !defined(NDEBUG) -+# define ALWAYS(X) ((X)?1:(assert(0),0)) -+# define NEVER(X) ((X)?(assert(0),1):0) -+#else -+# define ALWAYS(X) (X) -+# define NEVER(X) (X) -+#endif -+ -+#endif /* SQLITE_AMALGAMATION */ -+ -+/* -+** Definitions for mode bitmasks S_IFDIR, S_IFREG and S_IFLNK. -+** -+** In some ways it would be better to obtain these values from system -+** header files. But, the dependency is undesirable and (a) these -+** have been stable for decades, (b) the values are part of POSIX and -+** are also made explicit in [man stat], and (c) are part of the -+** file format for zip archives. -+*/ -+#ifndef S_IFDIR -+# define S_IFDIR 0040000 -+#endif -+#ifndef S_IFREG -+# define S_IFREG 0100000 -+#endif -+#ifndef S_IFLNK -+# define S_IFLNK 0120000 -+#endif -+ -+static const char ZIPFILE_SCHEMA[] = -+ "CREATE TABLE y(" -+ "name PRIMARY KEY," /* 0: Name of file in zip archive */ -+ "mode," /* 1: POSIX mode for file */ -+ "mtime," /* 2: Last modification time (secs since 1970)*/ -+ "sz," /* 3: Size of object */ -+ "rawdata," /* 4: Raw data */ -+ "data," /* 5: Uncompressed data */ -+ "method," /* 6: Compression method (integer) */ -+ "z HIDDEN" /* 7: Name of zip file */ -+ ") WITHOUT ROWID;"; -+ -+#define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */ -+#define ZIPFILE_BUFFER_SIZE (64*1024) -+ -+ -+/* -+** Magic numbers used to read and write zip files. -+** -+** ZIPFILE_NEWENTRY_MADEBY: -+** Use this value for the "version-made-by" field in new zip file -+** entries. The upper byte indicates "unix", and the lower byte -+** indicates that the zip file matches pkzip specification 3.0. -+** This is what info-zip seems to do. -+** -+** ZIPFILE_NEWENTRY_REQUIRED: -+** Value for "version-required-to-extract" field of new entries. -+** Version 2.0 is required to support folders and deflate compression. -+** -+** ZIPFILE_NEWENTRY_FLAGS: -+** Value for "general-purpose-bit-flags" field of new entries. Bit -+** 11 means "utf-8 filename and comment". -+** -+** ZIPFILE_SIGNATURE_CDS: -+** First 4 bytes of a valid CDS record. -+** -+** ZIPFILE_SIGNATURE_LFH: -+** First 4 bytes of a valid LFH record. -+** -+** ZIPFILE_SIGNATURE_EOCD -+** First 4 bytes of a valid EOCD record. -+*/ -+#define ZIPFILE_EXTRA_TIMESTAMP 0x5455 -+#define ZIPFILE_NEWENTRY_MADEBY ((3<<8) + 30) -+#define ZIPFILE_NEWENTRY_REQUIRED 20 -+#define ZIPFILE_NEWENTRY_FLAGS 0x800 -+#define ZIPFILE_SIGNATURE_CDS 0x02014b50 -+#define ZIPFILE_SIGNATURE_LFH 0x04034b50 -+#define ZIPFILE_SIGNATURE_EOCD 0x06054b50 -+ -+/* -+** The sizes of the fixed-size part of each of the three main data -+** structures in a zip archive. -+*/ -+#define ZIPFILE_LFH_FIXED_SZ 30 -+#define ZIPFILE_EOCD_FIXED_SZ 22 -+#define ZIPFILE_CDS_FIXED_SZ 46 -+ -+/* -+*** 4.3.16 End of central directory record: -+*** -+*** end of central dir signature 4 bytes (0x06054b50) -+*** number of this disk 2 bytes -+*** number of the disk with the -+*** start of the central directory 2 bytes -+*** total number of entries in the -+*** central directory on this disk 2 bytes -+*** total number of entries in -+*** the central directory 2 bytes -+*** size of the central directory 4 bytes -+*** offset of start of central -+*** directory with respect to -+*** the starting disk number 4 bytes -+*** .ZIP file comment length 2 bytes -+*** .ZIP file comment (variable size) -+*/ -+typedef struct ZipfileEOCD ZipfileEOCD; -+struct ZipfileEOCD { -+ u16 iDisk; -+ u16 iFirstDisk; -+ u16 nEntry; -+ u16 nEntryTotal; -+ u32 nSize; -+ u32 iOffset; -+}; -+ -+/* -+*** 4.3.12 Central directory structure: -+*** -+*** ... -+*** -+*** central file header signature 4 bytes (0x02014b50) -+*** version made by 2 bytes -+*** version needed to extract 2 bytes -+*** general purpose bit flag 2 bytes -+*** compression method 2 bytes -+*** last mod file time 2 bytes -+*** last mod file date 2 bytes -+*** crc-32 4 bytes -+*** compressed size 4 bytes -+*** uncompressed size 4 bytes -+*** file name length 2 bytes -+*** extra field length 2 bytes -+*** file comment length 2 bytes -+*** disk number start 2 bytes -+*** internal file attributes 2 bytes -+*** external file attributes 4 bytes -+*** relative offset of local header 4 bytes -+*/ -+typedef struct ZipfileCDS ZipfileCDS; -+struct ZipfileCDS { -+ u16 iVersionMadeBy; -+ u16 iVersionExtract; -+ u16 flags; -+ u16 iCompression; -+ u16 mTime; -+ u16 mDate; -+ u32 crc32; -+ u32 szCompressed; -+ u32 szUncompressed; -+ u16 nFile; -+ u16 nExtra; -+ u16 nComment; -+ u16 iDiskStart; -+ u16 iInternalAttr; -+ u32 iExternalAttr; -+ u32 iOffset; -+ char *zFile; /* Filename (sqlite3_malloc()) */ -+}; -+ -+/* -+*** 4.3.7 Local file header: -+*** -+*** local file header signature 4 bytes (0x04034b50) -+*** version needed to extract 2 bytes -+*** general purpose bit flag 2 bytes -+*** compression method 2 bytes -+*** last mod file time 2 bytes -+*** last mod file date 2 bytes -+*** crc-32 4 bytes -+*** compressed size 4 bytes -+*** uncompressed size 4 bytes -+*** file name length 2 bytes -+*** extra field length 2 bytes -+*** -+*/ -+typedef struct ZipfileLFH ZipfileLFH; -+struct ZipfileLFH { -+ u16 iVersionExtract; -+ u16 flags; -+ u16 iCompression; -+ u16 mTime; -+ u16 mDate; -+ u32 crc32; -+ u32 szCompressed; -+ u32 szUncompressed; -+ u16 nFile; -+ u16 nExtra; -+}; -+ -+typedef struct ZipfileEntry ZipfileEntry; -+struct ZipfileEntry { -+ ZipfileCDS cds; /* Parsed CDS record */ -+ u32 mUnixTime; /* Modification time, in UNIX format */ -+ u8 *aExtra; /* cds.nExtra+cds.nComment bytes of extra data */ -+ i64 iDataOff; /* Offset to data in file (if aData==0) */ -+ u8 *aData; /* cds.szCompressed bytes of compressed data */ -+ ZipfileEntry *pNext; /* Next element in in-memory CDS */ -+}; -+ -+/* -+** Cursor type for zipfile tables. -+*/ -+typedef struct ZipfileCsr ZipfileCsr; -+struct ZipfileCsr { -+ sqlite3_vtab_cursor base; /* Base class - must be first */ -+ i64 iId; /* Cursor ID */ -+ u8 bEof; /* True when at EOF */ -+ u8 bNoop; /* If next xNext() call is no-op */ -+ -+ /* Used outside of write transactions */ -+ FILE *pFile; /* Zip file */ -+ i64 iNextOff; /* Offset of next record in central directory */ -+ ZipfileEOCD eocd; /* Parse of central directory record */ -+ -+ ZipfileEntry *pFreeEntry; /* Free this list when cursor is closed or reset */ -+ ZipfileEntry *pCurrent; /* Current entry */ -+ ZipfileCsr *pCsrNext; /* Next cursor on same virtual table */ -+}; -+ -+typedef struct ZipfileTab ZipfileTab; -+struct ZipfileTab { -+ sqlite3_vtab base; /* Base class - must be first */ -+ char *zFile; /* Zip file this table accesses (may be NULL) */ -+ sqlite3 *db; /* Host database connection */ -+ u8 *aBuffer; /* Temporary buffer used for various tasks */ -+ -+ ZipfileCsr *pCsrList; /* List of cursors */ -+ i64 iNextCsrid; -+ -+ /* The following are used by write transactions only */ -+ ZipfileEntry *pFirstEntry; /* Linked list of all files (if pWriteFd!=0) */ -+ ZipfileEntry *pLastEntry; /* Last element in pFirstEntry list */ -+ FILE *pWriteFd; /* File handle open on zip archive */ -+ i64 szCurrent; /* Current size of zip archive */ -+ i64 szOrig; /* Size of archive at start of transaction */ -+}; -+ -+/* -+** Set the error message contained in context ctx to the results of -+** vprintf(zFmt, ...). -+*/ -+static void zipfileCtxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){ -+ char *zMsg = 0; -+ va_list ap; -+ va_start(ap, zFmt); -+ zMsg = sqlite3_vmprintf(zFmt, ap); -+ sqlite3_result_error(ctx, zMsg, -1); -+ sqlite3_free(zMsg); -+ va_end(ap); -+} -+ -+/* -+** If string zIn is quoted, dequote it in place. Otherwise, if the string -+** is not quoted, do nothing. -+*/ -+static void zipfileDequote(char *zIn){ -+ char q = zIn[0]; -+ if( q=='"' || q=='\'' || q=='`' || q=='[' ){ -+ int iIn = 1; -+ int iOut = 0; -+ if( q=='[' ) q = ']'; -+ while( ALWAYS(zIn[iIn]) ){ -+ char c = zIn[iIn++]; -+ if( c==q && zIn[iIn++]!=q ) break; -+ zIn[iOut++] = c; -+ } -+ zIn[iOut] = '\0'; -+ } -+} -+ -+/* -+** Construct a new ZipfileTab virtual table object. -+** -+** argv[0] -> module name ("zipfile") -+** argv[1] -> database name -+** argv[2] -> table name -+** argv[...] -> "column name" and other module argument fields. -+*/ -+static int zipfileConnect( -+ sqlite3 *db, -+ void *pAux, -+ int argc, const char *const*argv, -+ sqlite3_vtab **ppVtab, -+ char **pzErr -+){ -+ int nByte = sizeof(ZipfileTab) + ZIPFILE_BUFFER_SIZE; -+ int nFile = 0; -+ const char *zFile = 0; -+ ZipfileTab *pNew = 0; -+ int rc; -+ -+ /* If the table name is not "zipfile", require that the argument be -+ ** specified. This stops zipfile tables from being created as: -+ ** -+ ** CREATE VIRTUAL TABLE zzz USING zipfile(); -+ ** -+ ** It does not prevent: -+ ** -+ ** CREATE VIRTUAL TABLE zipfile USING zipfile(); -+ */ -+ assert( 0==sqlite3_stricmp(argv[0], "zipfile") ); -+ if( (0!=sqlite3_stricmp(argv[2], "zipfile") && argc<4) || argc>4 ){ -+ *pzErr = sqlite3_mprintf("zipfile constructor requires one argument"); -+ return SQLITE_ERROR; -+ } -+ -+ if( argc>3 ){ -+ zFile = argv[3]; -+ nFile = (int)strlen(zFile)+1; -+ } -+ -+ rc = sqlite3_declare_vtab(db, ZIPFILE_SCHEMA); -+ if( rc==SQLITE_OK ){ -+ pNew = (ZipfileTab*)sqlite3_malloc(nByte+nFile); -+ if( pNew==0 ) return SQLITE_NOMEM; -+ memset(pNew, 0, nByte+nFile); -+ pNew->db = db; -+ pNew->aBuffer = (u8*)&pNew[1]; -+ if( zFile ){ -+ pNew->zFile = (char*)&pNew->aBuffer[ZIPFILE_BUFFER_SIZE]; -+ memcpy(pNew->zFile, zFile, nFile); -+ zipfileDequote(pNew->zFile); -+ } -+ } -+ *ppVtab = (sqlite3_vtab*)pNew; -+ return rc; -+} -+ -+/* -+** Free the ZipfileEntry structure indicated by the only argument. -+*/ -+static void zipfileEntryFree(ZipfileEntry *p){ -+ if( p ){ -+ sqlite3_free(p->cds.zFile); -+ sqlite3_free(p); -+ } -+} -+ -+/* -+** Release resources that should be freed at the end of a write -+** transaction. -+*/ -+static void zipfileCleanupTransaction(ZipfileTab *pTab){ -+ ZipfileEntry *pEntry; -+ ZipfileEntry *pNext; -+ -+ if( pTab->pWriteFd ){ -+ fclose(pTab->pWriteFd); -+ pTab->pWriteFd = 0; -+ } -+ for(pEntry=pTab->pFirstEntry; pEntry; pEntry=pNext){ -+ pNext = pEntry->pNext; -+ zipfileEntryFree(pEntry); -+ } -+ pTab->pFirstEntry = 0; -+ pTab->pLastEntry = 0; -+ pTab->szCurrent = 0; -+ pTab->szOrig = 0; -+} -+ -+/* -+** This method is the destructor for zipfile vtab objects. -+*/ -+static int zipfileDisconnect(sqlite3_vtab *pVtab){ -+ zipfileCleanupTransaction((ZipfileTab*)pVtab); -+ sqlite3_free(pVtab); -+ return SQLITE_OK; -+} -+ -+/* -+** Constructor for a new ZipfileCsr object. -+*/ -+static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){ -+ ZipfileTab *pTab = (ZipfileTab*)p; -+ ZipfileCsr *pCsr; -+ pCsr = sqlite3_malloc(sizeof(*pCsr)); -+ *ppCsr = (sqlite3_vtab_cursor*)pCsr; -+ if( pCsr==0 ){ -+ return SQLITE_NOMEM; -+ } -+ memset(pCsr, 0, sizeof(*pCsr)); -+ pCsr->iId = ++pTab->iNextCsrid; -+ pCsr->pCsrNext = pTab->pCsrList; -+ pTab->pCsrList = pCsr; -+ return SQLITE_OK; -+} -+ -+/* -+** Reset a cursor back to the state it was in when first returned -+** by zipfileOpen(). -+*/ -+static void zipfileResetCursor(ZipfileCsr *pCsr){ -+ ZipfileEntry *p; -+ ZipfileEntry *pNext; -+ -+ pCsr->bEof = 0; -+ if( pCsr->pFile ){ -+ fclose(pCsr->pFile); -+ pCsr->pFile = 0; -+ zipfileEntryFree(pCsr->pCurrent); -+ pCsr->pCurrent = 0; -+ } -+ -+ for(p=pCsr->pFreeEntry; p; p=pNext){ -+ pNext = p->pNext; -+ zipfileEntryFree(p); -+ } -+} -+ -+/* -+** Destructor for an ZipfileCsr. -+*/ -+static int zipfileClose(sqlite3_vtab_cursor *cur){ -+ ZipfileCsr *pCsr = (ZipfileCsr*)cur; -+ ZipfileTab *pTab = (ZipfileTab*)(pCsr->base.pVtab); -+ ZipfileCsr **pp; -+ zipfileResetCursor(pCsr); -+ -+ /* Remove this cursor from the ZipfileTab.pCsrList list. */ -+ for(pp=&pTab->pCsrList; *pp!=pCsr; pp=&((*pp)->pCsrNext)); -+ *pp = pCsr->pCsrNext; -+ -+ sqlite3_free(pCsr); -+ return SQLITE_OK; -+} -+ -+/* -+** Set the error message for the virtual table associated with cursor -+** pCsr to the results of vprintf(zFmt, ...). -+*/ -+static void zipfileTableErr(ZipfileTab *pTab, const char *zFmt, ...){ -+ va_list ap; -+ va_start(ap, zFmt); -+ sqlite3_free(pTab->base.zErrMsg); -+ pTab->base.zErrMsg = sqlite3_vmprintf(zFmt, ap); -+ va_end(ap); -+} -+static void zipfileCursorErr(ZipfileCsr *pCsr, const char *zFmt, ...){ -+ va_list ap; -+ va_start(ap, zFmt); -+ sqlite3_free(pCsr->base.pVtab->zErrMsg); -+ pCsr->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap); -+ va_end(ap); -+} -+ -+/* -+** Read nRead bytes of data from offset iOff of file pFile into buffer -+** aRead[]. Return SQLITE_OK if successful, or an SQLite error code -+** otherwise. -+** -+** If an error does occur, output variable (*pzErrmsg) may be set to point -+** to an English language error message. It is the responsibility of the -+** caller to eventually free this buffer using -+** sqlite3_free(). -+*/ -+static int zipfileReadData( -+ FILE *pFile, /* Read from this file */ -+ u8 *aRead, /* Read into this buffer */ -+ int nRead, /* Number of bytes to read */ -+ i64 iOff, /* Offset to read from */ -+ char **pzErrmsg /* OUT: Error message (from sqlite3_malloc) */ -+){ -+ size_t n; -+ fseek(pFile, (long)iOff, SEEK_SET); -+ n = fread(aRead, 1, nRead, pFile); -+ if( (int)n!=nRead ){ -+ *pzErrmsg = sqlite3_mprintf("error in fread()"); -+ return SQLITE_ERROR; -+ } -+ return SQLITE_OK; -+} -+ -+static int zipfileAppendData( -+ ZipfileTab *pTab, -+ const u8 *aWrite, -+ int nWrite -+){ -+ size_t n; -+ fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET); -+ n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd); -+ if( (int)n!=nWrite ){ -+ pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()"); -+ return SQLITE_ERROR; -+ } -+ pTab->szCurrent += nWrite; -+ return SQLITE_OK; -+} -+ -+/* -+** Read and return a 16-bit little-endian unsigned integer from buffer aBuf. -+*/ -+static u16 zipfileGetU16(const u8 *aBuf){ -+ return (aBuf[1] << 8) + aBuf[0]; -+} -+ -+/* -+** Read and return a 32-bit little-endian unsigned integer from buffer aBuf. -+*/ -+static u32 zipfileGetU32(const u8 *aBuf){ -+ return ((u32)(aBuf[3]) << 24) -+ + ((u32)(aBuf[2]) << 16) -+ + ((u32)(aBuf[1]) << 8) -+ + ((u32)(aBuf[0]) << 0); -+} -+ -+/* -+** Write a 16-bit little endiate integer into buffer aBuf. -+*/ -+static void zipfilePutU16(u8 *aBuf, u16 val){ -+ aBuf[0] = val & 0xFF; -+ aBuf[1] = (val>>8) & 0xFF; -+} -+ -+/* -+** Write a 32-bit little endiate integer into buffer aBuf. -+*/ -+static void zipfilePutU32(u8 *aBuf, u32 val){ -+ aBuf[0] = val & 0xFF; -+ aBuf[1] = (val>>8) & 0xFF; -+ aBuf[2] = (val>>16) & 0xFF; -+ aBuf[3] = (val>>24) & 0xFF; -+} -+ -+#define zipfileRead32(aBuf) ( aBuf+=4, zipfileGetU32(aBuf-4) ) -+#define zipfileRead16(aBuf) ( aBuf+=2, zipfileGetU16(aBuf-2) ) -+ -+#define zipfileWrite32(aBuf,val) { zipfilePutU32(aBuf,val); aBuf+=4; } -+#define zipfileWrite16(aBuf,val) { zipfilePutU16(aBuf,val); aBuf+=2; } -+ -+/* -+** Magic numbers used to read CDS records. -+*/ -+#define ZIPFILE_CDS_NFILE_OFF 28 -+#define ZIPFILE_CDS_SZCOMPRESSED_OFF 20 -+ -+/* -+** Decode the CDS record in buffer aBuf into (*pCDS). Return SQLITE_ERROR -+** if the record is not well-formed, or SQLITE_OK otherwise. -+*/ -+static int zipfileReadCDS(u8 *aBuf, ZipfileCDS *pCDS){ -+ u8 *aRead = aBuf; -+ u32 sig = zipfileRead32(aRead); -+ int rc = SQLITE_OK; -+ if( sig!=ZIPFILE_SIGNATURE_CDS ){ -+ rc = SQLITE_ERROR; -+ }else{ -+ pCDS->iVersionMadeBy = zipfileRead16(aRead); -+ pCDS->iVersionExtract = zipfileRead16(aRead); -+ pCDS->flags = zipfileRead16(aRead); -+ pCDS->iCompression = zipfileRead16(aRead); -+ pCDS->mTime = zipfileRead16(aRead); -+ pCDS->mDate = zipfileRead16(aRead); -+ pCDS->crc32 = zipfileRead32(aRead); -+ pCDS->szCompressed = zipfileRead32(aRead); -+ pCDS->szUncompressed = zipfileRead32(aRead); -+ assert( aRead==&aBuf[ZIPFILE_CDS_NFILE_OFF] ); -+ pCDS->nFile = zipfileRead16(aRead); -+ pCDS->nExtra = zipfileRead16(aRead); -+ pCDS->nComment = zipfileRead16(aRead); -+ pCDS->iDiskStart = zipfileRead16(aRead); -+ pCDS->iInternalAttr = zipfileRead16(aRead); -+ pCDS->iExternalAttr = zipfileRead32(aRead); -+ pCDS->iOffset = zipfileRead32(aRead); -+ assert( aRead==&aBuf[ZIPFILE_CDS_FIXED_SZ] ); -+ } -+ -+ return rc; -+} -+ -+/* -+** Decode the LFH record in buffer aBuf into (*pLFH). Return SQLITE_ERROR -+** if the record is not well-formed, or SQLITE_OK otherwise. -+*/ -+static int zipfileReadLFH( -+ u8 *aBuffer, -+ ZipfileLFH *pLFH -+){ -+ u8 *aRead = aBuffer; -+ int rc = SQLITE_OK; -+ -+ u32 sig = zipfileRead32(aRead); -+ if( sig!=ZIPFILE_SIGNATURE_LFH ){ -+ rc = SQLITE_ERROR; -+ }else{ -+ pLFH->iVersionExtract = zipfileRead16(aRead); -+ pLFH->flags = zipfileRead16(aRead); -+ pLFH->iCompression = zipfileRead16(aRead); -+ pLFH->mTime = zipfileRead16(aRead); -+ pLFH->mDate = zipfileRead16(aRead); -+ pLFH->crc32 = zipfileRead32(aRead); -+ pLFH->szCompressed = zipfileRead32(aRead); -+ pLFH->szUncompressed = zipfileRead32(aRead); -+ pLFH->nFile = zipfileRead16(aRead); -+ pLFH->nExtra = zipfileRead16(aRead); -+ } -+ return rc; -+} -+ -+ -+/* -+** Buffer aExtra (size nExtra bytes) contains zip archive "extra" fields. -+** Scan through this buffer to find an "extra-timestamp" field. If one -+** exists, extract the 32-bit modification-timestamp from it and store -+** the value in output parameter *pmTime. -+** -+** Zero is returned if no extra-timestamp record could be found (and so -+** *pmTime is left unchanged), or non-zero otherwise. -+** -+** The general format of an extra field is: -+** -+** Header ID 2 bytes -+** Data Size 2 bytes -+** Data N bytes -+*/ -+static int zipfileScanExtra(u8 *aExtra, int nExtra, u32 *pmTime){ -+ int ret = 0; -+ u8 *p = aExtra; -+ u8 *pEnd = &aExtra[nExtra]; -+ -+ while( p<pEnd ){ -+ u16 id = zipfileRead16(p); -+ u16 nByte = zipfileRead16(p); -+ -+ switch( id ){ -+ case ZIPFILE_EXTRA_TIMESTAMP: { -+ u8 b = p[0]; -+ if( b & 0x01 ){ /* 0x01 -> modtime is present */ -+ *pmTime = zipfileGetU32(&p[1]); -+ ret = 1; -+ } -+ break; -+ } -+ } -+ -+ p += nByte; -+ } -+ return ret; -+} -+ -+/* -+** Convert the standard MS-DOS timestamp stored in the mTime and mDate -+** fields of the CDS structure passed as the only argument to a 32-bit -+** UNIX seconds-since-the-epoch timestamp. Return the result. -+** -+** "Standard" MS-DOS time format: -+** -+** File modification time: -+** Bits 00-04: seconds divided by 2 -+** Bits 05-10: minute -+** Bits 11-15: hour -+** File modification date: -+** Bits 00-04: day -+** Bits 05-08: month (1-12) -+** Bits 09-15: years from 1980 -+** -+** https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx -+*/ -+static u32 zipfileMtime(ZipfileCDS *pCDS){ -+ int Y = (1980 + ((pCDS->mDate >> 9) & 0x7F)); -+ int M = ((pCDS->mDate >> 5) & 0x0F); -+ int D = (pCDS->mDate & 0x1F); -+ int B = -13; -+ -+ int sec = (pCDS->mTime & 0x1F)*2; -+ int min = (pCDS->mTime >> 5) & 0x3F; -+ int hr = (pCDS->mTime >> 11) & 0x1F; -+ i64 JD; -+ -+ /* JD = INT(365.25 * (Y+4716)) + INT(30.6001 * (M+1)) + D + B - 1524.5 */ -+ -+ /* Calculate the JD in seconds for noon on the day in question */ -+ if( M<3 ){ -+ Y = Y-1; -+ M = M+12; -+ } -+ JD = (i64)(24*60*60) * ( -+ (int)(365.25 * (Y + 4716)) -+ + (int)(30.6001 * (M + 1)) -+ + D + B - 1524 -+ ); -+ -+ /* Correct the JD for the time within the day */ -+ JD += (hr-12) * 3600 + min * 60 + sec; -+ -+ /* Convert JD to unix timestamp (the JD epoch is 2440587.5) */ -+ return (u32)(JD - (i64)(24405875) * 24*60*6); -+} -+ -+/* -+** The opposite of zipfileMtime(). This function populates the mTime and -+** mDate fields of the CDS structure passed as the first argument according -+** to the UNIX timestamp value passed as the second. -+*/ -+static void zipfileMtimeToDos(ZipfileCDS *pCds, u32 mUnixTime){ -+ /* Convert unix timestamp to JD (2440588 is noon on 1/1/1970) */ -+ i64 JD = (i64)2440588 + mUnixTime / (24*60*60); -+ -+ int A, B, C, D, E; -+ int yr, mon, day; -+ int hr, min, sec; -+ -+ A = (int)((JD - 1867216.25)/36524.25); -+ A = (int)(JD + 1 + A - (A/4)); -+ B = A + 1524; -+ C = (int)((B - 122.1)/365.25); -+ D = (36525*(C&32767))/100; -+ E = (int)((B-D)/30.6001); -+ -+ day = B - D - (int)(30.6001*E); -+ mon = (E<14 ? E-1 : E-13); -+ yr = mon>2 ? C-4716 : C-4715; -+ -+ hr = (mUnixTime % (24*60*60)) / (60*60); -+ min = (mUnixTime % (60*60)) / 60; -+ sec = (mUnixTime % 60); -+ -+ if( yr>=1980 ){ -+ pCds->mDate = (u16)(day + (mon << 5) + ((yr-1980) << 9)); -+ pCds->mTime = (u16)(sec/2 + (min<<5) + (hr<<11)); -+ }else{ -+ pCds->mDate = pCds->mTime = 0; -+ } -+ -+ assert( mUnixTime<315507600 -+ || mUnixTime==zipfileMtime(pCds) -+ || ((mUnixTime % 2) && mUnixTime-1==zipfileMtime(pCds)) -+ /* || (mUnixTime % 2) */ -+ ); -+} -+ -+/* -+** If aBlob is not NULL, then it is a pointer to a buffer (nBlob bytes in -+** size) containing an entire zip archive image. Or, if aBlob is NULL, -+** then pFile is a file-handle open on a zip file. In either case, this -+** function creates a ZipfileEntry object based on the zip archive entry -+** for which the CDS record is at offset iOff. -+** -+** If successful, SQLITE_OK is returned and (*ppEntry) set to point to -+** the new object. Otherwise, an SQLite error code is returned and the -+** final value of (*ppEntry) undefined. -+*/ -+static int zipfileGetEntry( -+ ZipfileTab *pTab, /* Store any error message here */ -+ const u8 *aBlob, /* Pointer to in-memory file image */ -+ int nBlob, /* Size of aBlob[] in bytes */ -+ FILE *pFile, /* If aBlob==0, read from this file */ -+ i64 iOff, /* Offset of CDS record */ -+ ZipfileEntry **ppEntry /* OUT: Pointer to new object */ -+){ -+ u8 *aRead; -+ char **pzErr = &pTab->base.zErrMsg; -+ int rc = SQLITE_OK; -+ -+ if( aBlob==0 ){ -+ aRead = pTab->aBuffer; -+ rc = zipfileReadData(pFile, aRead, ZIPFILE_CDS_FIXED_SZ, iOff, pzErr); -+ }else{ -+ aRead = (u8*)&aBlob[iOff]; -+ } -+ -+ if( rc==SQLITE_OK ){ -+ int nAlloc; -+ ZipfileEntry *pNew; -+ -+ int nFile = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF]); -+ int nExtra = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+2]); -+ nExtra += zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+4]); -+ -+ nAlloc = sizeof(ZipfileEntry) + nExtra; -+ if( aBlob ){ -+ nAlloc += zipfileGetU32(&aRead[ZIPFILE_CDS_SZCOMPRESSED_OFF]); -+ } -+ -+ pNew = (ZipfileEntry*)sqlite3_malloc(nAlloc); -+ if( pNew==0 ){ -+ rc = SQLITE_NOMEM; -+ }else{ -+ memset(pNew, 0, sizeof(ZipfileEntry)); -+ rc = zipfileReadCDS(aRead, &pNew->cds); -+ if( rc!=SQLITE_OK ){ -+ *pzErr = sqlite3_mprintf("failed to read CDS at offset %lld", iOff); -+ }else if( aBlob==0 ){ -+ rc = zipfileReadData( -+ pFile, aRead, nExtra+nFile, iOff+ZIPFILE_CDS_FIXED_SZ, pzErr -+ ); -+ }else{ -+ aRead = (u8*)&aBlob[iOff + ZIPFILE_CDS_FIXED_SZ]; -+ } -+ } -+ -+ if( rc==SQLITE_OK ){ -+ u32 *pt = &pNew->mUnixTime; -+ pNew->cds.zFile = sqlite3_mprintf("%.*s", nFile, aRead); -+ pNew->aExtra = (u8*)&pNew[1]; -+ memcpy(pNew->aExtra, &aRead[nFile], nExtra); -+ if( pNew->cds.zFile==0 ){ -+ rc = SQLITE_NOMEM; -+ }else if( 0==zipfileScanExtra(&aRead[nFile], pNew->cds.nExtra, pt) ){ -+ pNew->mUnixTime = zipfileMtime(&pNew->cds); -+ } -+ } -+ -+ if( rc==SQLITE_OK ){ -+ static const int szFix = ZIPFILE_LFH_FIXED_SZ; -+ ZipfileLFH lfh; -+ if( pFile ){ -+ rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr); -+ }else{ -+ aRead = (u8*)&aBlob[pNew->cds.iOffset]; -+ } -+ -+ rc = zipfileReadLFH(aRead, &lfh); -+ if( rc==SQLITE_OK ){ -+ pNew->iDataOff = pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ; -+ pNew->iDataOff += lfh.nFile + lfh.nExtra; -+ if( aBlob && pNew->cds.szCompressed ){ -+ pNew->aData = &pNew->aExtra[nExtra]; -+ memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed); -+ } -+ }else{ -+ *pzErr = sqlite3_mprintf("failed to read LFH at offset %d", -+ (int)pNew->cds.iOffset -+ ); -+ } -+ } -+ -+ if( rc!=SQLITE_OK ){ -+ zipfileEntryFree(pNew); -+ }else{ -+ *ppEntry = pNew; -+ } -+ } -+ -+ return rc; -+} -+ -+/* -+** Advance an ZipfileCsr to its next row of output. -+*/ -+static int zipfileNext(sqlite3_vtab_cursor *cur){ -+ ZipfileCsr *pCsr = (ZipfileCsr*)cur; -+ int rc = SQLITE_OK; -+ -+ if( pCsr->pFile ){ -+ i64 iEof = pCsr->eocd.iOffset + pCsr->eocd.nSize; -+ zipfileEntryFree(pCsr->pCurrent); -+ pCsr->pCurrent = 0; -+ if( pCsr->iNextOff>=iEof ){ -+ pCsr->bEof = 1; -+ }else{ -+ ZipfileEntry *p = 0; -+ ZipfileTab *pTab = (ZipfileTab*)(cur->pVtab); -+ rc = zipfileGetEntry(pTab, 0, 0, pCsr->pFile, pCsr->iNextOff, &p); -+ if( rc==SQLITE_OK ){ -+ pCsr->iNextOff += ZIPFILE_CDS_FIXED_SZ; -+ pCsr->iNextOff += (int)p->cds.nExtra + p->cds.nFile + p->cds.nComment; -+ } -+ pCsr->pCurrent = p; -+ } -+ }else{ -+ if( !pCsr->bNoop ){ -+ pCsr->pCurrent = pCsr->pCurrent->pNext; -+ } -+ if( pCsr->pCurrent==0 ){ -+ pCsr->bEof = 1; -+ } -+ } -+ -+ pCsr->bNoop = 0; -+ return rc; -+} -+ -+static void zipfileFree(void *p) { -+ sqlite3_free(p); -+} -+ -+/* -+** Buffer aIn (size nIn bytes) contains compressed data. Uncompressed, the -+** size is nOut bytes. This function uncompresses the data and sets the -+** return value in context pCtx to the result (a blob). -+** -+** If an error occurs, an error code is left in pCtx instead. -+*/ -+static void zipfileInflate( -+ sqlite3_context *pCtx, /* Store result here */ -+ const u8 *aIn, /* Compressed data */ -+ int nIn, /* Size of buffer aIn[] in bytes */ -+ int nOut /* Expected output size */ -+){ -+ u8 *aRes = sqlite3_malloc(nOut); -+ if( aRes==0 ){ -+ sqlite3_result_error_nomem(pCtx); -+ }else{ -+ int err; -+ z_stream str; -+ memset(&str, 0, sizeof(str)); -+ -+ str.next_in = (Byte*)aIn; -+ str.avail_in = nIn; -+ str.next_out = (Byte*)aRes; -+ str.avail_out = nOut; -+ -+ err = inflateInit2(&str, -15); -+ if( err!=Z_OK ){ -+ zipfileCtxErrorMsg(pCtx, "inflateInit2() failed (%d)", err); -+ }else{ -+ err = inflate(&str, Z_NO_FLUSH); -+ if( err!=Z_STREAM_END ){ -+ zipfileCtxErrorMsg(pCtx, "inflate() failed (%d)", err); -+ }else{ -+ sqlite3_result_blob(pCtx, aRes, nOut, zipfileFree); -+ aRes = 0; -+ } -+ } -+ sqlite3_free(aRes); -+ inflateEnd(&str); -+ } -+} -+ -+/* -+** Buffer aIn (size nIn bytes) contains uncompressed data. This function -+** compresses it and sets (*ppOut) to point to a buffer containing the -+** compressed data. The caller is responsible for eventually calling -+** sqlite3_free() to release buffer (*ppOut). Before returning, (*pnOut) -+** is set to the size of buffer (*ppOut) in bytes. -+** -+** If no error occurs, SQLITE_OK is returned. Otherwise, an SQLite error -+** code is returned and an error message left in virtual-table handle -+** pTab. The values of (*ppOut) and (*pnOut) are left unchanged in this -+** case. -+*/ -+static int zipfileDeflate( -+ const u8 *aIn, int nIn, /* Input */ -+ u8 **ppOut, int *pnOut, /* Output */ -+ char **pzErr /* OUT: Error message */ -+){ -+ int nAlloc = (int)compressBound(nIn); -+ u8 *aOut; -+ int rc = SQLITE_OK; -+ -+ aOut = (u8*)sqlite3_malloc(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; -+ }else{ -+ sqlite3_free(aOut); -+ *pzErr = sqlite3_mprintf("zipfile: deflate() error"); -+ rc = SQLITE_ERROR; -+ } -+ deflateEnd(&str); -+ } -+ -+ return rc; -+} -+ -+ -+/* -+** Return values of columns for the row at which the series_cursor -+** is currently pointing. -+*/ -+static int zipfileColumn( -+ sqlite3_vtab_cursor *cur, /* The cursor */ -+ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ -+ int i /* Which column to return */ -+){ -+ ZipfileCsr *pCsr = (ZipfileCsr*)cur; -+ ZipfileCDS *pCDS = &pCsr->pCurrent->cds; -+ int rc = SQLITE_OK; -+ switch( i ){ -+ case 0: /* name */ -+ sqlite3_result_text(ctx, pCDS->zFile, -1, SQLITE_TRANSIENT); -+ break; -+ case 1: /* mode */ -+ /* TODO: Whether or not the following is correct surely depends on -+ ** the platform on which the archive was created. */ -+ sqlite3_result_int(ctx, pCDS->iExternalAttr >> 16); -+ break; -+ case 2: { /* mtime */ -+ sqlite3_result_int64(ctx, pCsr->pCurrent->mUnixTime); -+ break; -+ } -+ case 3: { /* sz */ -+ if( sqlite3_vtab_nochange(ctx)==0 ){ -+ sqlite3_result_int64(ctx, pCDS->szUncompressed); -+ } -+ break; -+ } -+ case 4: /* rawdata */ -+ if( sqlite3_vtab_nochange(ctx) ) break; -+ case 5: { /* data */ -+ if( i==4 || pCDS->iCompression==0 || pCDS->iCompression==8 ){ -+ int sz = pCDS->szCompressed; -+ int szFinal = pCDS->szUncompressed; -+ if( szFinal>0 ){ -+ u8 *aBuf; -+ u8 *aFree = 0; -+ if( pCsr->pCurrent->aData ){ -+ aBuf = pCsr->pCurrent->aData; -+ }else{ -+ aBuf = aFree = sqlite3_malloc(sz); -+ if( aBuf==0 ){ -+ rc = SQLITE_NOMEM; -+ }else{ -+ FILE *pFile = pCsr->pFile; -+ if( pFile==0 ){ -+ pFile = ((ZipfileTab*)(pCsr->base.pVtab))->pWriteFd; -+ } -+ rc = zipfileReadData(pFile, aBuf, sz, pCsr->pCurrent->iDataOff, -+ &pCsr->base.pVtab->zErrMsg -+ ); -+ } -+ } -+ if( rc==SQLITE_OK ){ -+ if( i==5 && pCDS->iCompression ){ -+ zipfileInflate(ctx, aBuf, sz, szFinal); -+ }else{ -+ sqlite3_result_blob(ctx, aBuf, sz, SQLITE_TRANSIENT); -+ } -+ } -+ sqlite3_free(aFree); -+ }else{ -+ /* Figure out if this is a directory or a zero-sized file. Consider -+ ** it to be a directory either if the mode suggests so, or if -+ ** the final character in the name is '/'. */ -+ u32 mode = pCDS->iExternalAttr >> 16; -+ if( !(mode & S_IFDIR) && pCDS->zFile[pCDS->nFile-1]!='/' ){ -+ sqlite3_result_blob(ctx, "", 0, SQLITE_STATIC); -+ } -+ } -+ } -+ break; -+ } -+ case 6: /* method */ -+ sqlite3_result_int(ctx, pCDS->iCompression); -+ break; -+ default: /* z */ -+ assert( i==7 ); -+ sqlite3_result_int64(ctx, pCsr->iId); -+ break; -+ } -+ -+ return rc; -+} -+ -+/* -+** Return TRUE if the cursor is at EOF. -+*/ -+static int zipfileEof(sqlite3_vtab_cursor *cur){ -+ ZipfileCsr *pCsr = (ZipfileCsr*)cur; -+ return pCsr->bEof; -+} -+ -+/* -+** If aBlob is not NULL, then it points to a buffer nBlob bytes in size -+** containing an entire zip archive image. Or, if aBlob is NULL, then pFile -+** is guaranteed to be a file-handle open on a zip file. -+** -+** This function attempts to locate the EOCD record within the zip archive -+** and populate *pEOCD with the results of decoding it. SQLITE_OK is -+** returned if successful. Otherwise, an SQLite error code is returned and -+** an English language error message may be left in virtual-table pTab. -+*/ -+static int zipfileReadEOCD( -+ ZipfileTab *pTab, /* Return errors here */ -+ const u8 *aBlob, /* Pointer to in-memory file image */ -+ int nBlob, /* Size of aBlob[] in bytes */ -+ FILE *pFile, /* Read from this file if aBlob==0 */ -+ ZipfileEOCD *pEOCD /* Object to populate */ -+){ -+ u8 *aRead = pTab->aBuffer; /* Temporary buffer */ -+ int nRead; /* Bytes to read from file */ -+ int rc = SQLITE_OK; -+ -+ if( aBlob==0 ){ -+ i64 iOff; /* Offset to read from */ -+ i64 szFile; /* Total size of file in bytes */ -+ fseek(pFile, 0, SEEK_END); -+ szFile = (i64)ftell(pFile); -+ if( szFile==0 ){ -+ memset(pEOCD, 0, sizeof(ZipfileEOCD)); -+ return SQLITE_OK; -+ } -+ nRead = (int)(MIN(szFile, ZIPFILE_BUFFER_SIZE)); -+ iOff = szFile - nRead; -+ rc = zipfileReadData(pFile, aRead, nRead, iOff, &pTab->base.zErrMsg); -+ }else{ -+ nRead = (int)(MIN(nBlob, ZIPFILE_BUFFER_SIZE)); -+ aRead = (u8*)&aBlob[nBlob-nRead]; -+ } -+ -+ if( rc==SQLITE_OK ){ -+ int i; -+ -+ /* Scan backwards looking for the signature bytes */ -+ for(i=nRead-20; i>=0; i--){ -+ if( aRead[i]==0x50 && aRead[i+1]==0x4b -+ && aRead[i+2]==0x05 && aRead[i+3]==0x06 -+ ){ -+ break; -+ } -+ } -+ if( i<0 ){ -+ pTab->base.zErrMsg = sqlite3_mprintf( -+ "cannot find end of central directory record" -+ ); -+ return SQLITE_ERROR; -+ } -+ -+ aRead += i+4; -+ pEOCD->iDisk = zipfileRead16(aRead); -+ pEOCD->iFirstDisk = zipfileRead16(aRead); -+ pEOCD->nEntry = zipfileRead16(aRead); -+ pEOCD->nEntryTotal = zipfileRead16(aRead); -+ pEOCD->nSize = zipfileRead32(aRead); -+ pEOCD->iOffset = zipfileRead32(aRead); -+ } -+ -+ return rc; -+} -+ -+/* -+** Add object pNew to the linked list that begins at ZipfileTab.pFirstEntry -+** and ends with pLastEntry. If argument pBefore is NULL, then pNew is added -+** to the end of the list. Otherwise, it is added to the list immediately -+** before pBefore (which is guaranteed to be a part of said list). -+*/ -+static void zipfileAddEntry( -+ ZipfileTab *pTab, -+ ZipfileEntry *pBefore, -+ ZipfileEntry *pNew -+){ -+ assert( (pTab->pFirstEntry==0)==(pTab->pLastEntry==0) ); -+ assert( pNew->pNext==0 ); -+ if( pBefore==0 ){ -+ if( pTab->pFirstEntry==0 ){ -+ pTab->pFirstEntry = pTab->pLastEntry = pNew; -+ }else{ -+ assert( pTab->pLastEntry->pNext==0 ); -+ pTab->pLastEntry->pNext = pNew; -+ pTab->pLastEntry = pNew; -+ } -+ }else{ -+ ZipfileEntry **pp; -+ for(pp=&pTab->pFirstEntry; *pp!=pBefore; pp=&((*pp)->pNext)); -+ pNew->pNext = pBefore; -+ *pp = pNew; -+ } -+} -+ -+static int zipfileLoadDirectory(ZipfileTab *pTab, const u8 *aBlob, int nBlob){ -+ ZipfileEOCD eocd; -+ int rc; -+ int i; -+ i64 iOff; -+ -+ rc = zipfileReadEOCD(pTab, aBlob, nBlob, pTab->pWriteFd, &eocd); -+ iOff = eocd.iOffset; -+ for(i=0; rc==SQLITE_OK && i<eocd.nEntry; i++){ -+ ZipfileEntry *pNew = 0; -+ rc = zipfileGetEntry(pTab, aBlob, nBlob, pTab->pWriteFd, iOff, &pNew); -+ -+ if( rc==SQLITE_OK ){ -+ zipfileAddEntry(pTab, 0, pNew); -+ iOff += ZIPFILE_CDS_FIXED_SZ; -+ iOff += (int)pNew->cds.nExtra + pNew->cds.nFile + pNew->cds.nComment; -+ } -+ } -+ return rc; -+} -+ -+/* -+** xFilter callback. -+*/ -+static int zipfileFilter( -+ sqlite3_vtab_cursor *cur, -+ int idxNum, const char *idxStr, -+ int argc, sqlite3_value **argv -+){ -+ ZipfileTab *pTab = (ZipfileTab*)cur->pVtab; -+ ZipfileCsr *pCsr = (ZipfileCsr*)cur; -+ const char *zFile = 0; /* Zip file to scan */ -+ int rc = SQLITE_OK; /* Return Code */ -+ int bInMemory = 0; /* True for an in-memory zipfile */ -+ -+ zipfileResetCursor(pCsr); -+ -+ if( pTab->zFile ){ -+ zFile = pTab->zFile; -+ }else if( idxNum==0 ){ -+ zipfileCursorErr(pCsr, "zipfile() function requires an argument"); -+ return SQLITE_ERROR; -+ }else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){ -+ const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]); -+ int nBlob = sqlite3_value_bytes(argv[0]); -+ assert( pTab->pFirstEntry==0 ); -+ rc = zipfileLoadDirectory(pTab, aBlob, nBlob); -+ pCsr->pFreeEntry = pTab->pFirstEntry; -+ pTab->pFirstEntry = pTab->pLastEntry = 0; -+ if( rc!=SQLITE_OK ) return rc; -+ bInMemory = 1; -+ }else{ -+ zFile = (const char*)sqlite3_value_text(argv[0]); -+ } -+ -+ if( 0==pTab->pWriteFd && 0==bInMemory ){ -+ pCsr->pFile = fopen(zFile, "rb"); -+ if( pCsr->pFile==0 ){ -+ zipfileCursorErr(pCsr, "cannot open file: %s", zFile); -+ rc = SQLITE_ERROR; -+ }else{ -+ rc = zipfileReadEOCD(pTab, 0, 0, pCsr->pFile, &pCsr->eocd); -+ if( rc==SQLITE_OK ){ -+ if( pCsr->eocd.nEntry==0 ){ -+ pCsr->bEof = 1; -+ }else{ -+ pCsr->iNextOff = pCsr->eocd.iOffset; -+ rc = zipfileNext(cur); -+ } -+ } -+ } -+ }else{ -+ pCsr->bNoop = 1; -+ pCsr->pCurrent = pCsr->pFreeEntry ? pCsr->pFreeEntry : pTab->pFirstEntry; -+ rc = zipfileNext(cur); -+ } -+ -+ return rc; -+} -+ -+/* -+** xBestIndex callback. -+*/ -+static int zipfileBestIndex( -+ sqlite3_vtab *tab, -+ sqlite3_index_info *pIdxInfo -+){ -+ int i; -+ int idx = -1; -+ int unusable = 0; -+ -+ for(i=0; i<pIdxInfo->nConstraint; i++){ -+ const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i]; -+ if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue; -+ if( pCons->usable==0 ){ -+ unusable = 1; -+ }else if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){ -+ idx = i; -+ } -+ } -+ 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; -+ } -+ return SQLITE_OK; -+} -+ -+static ZipfileEntry *zipfileNewEntry(const char *zPath){ -+ ZipfileEntry *pNew; -+ pNew = sqlite3_malloc(sizeof(ZipfileEntry)); -+ if( pNew ){ -+ memset(pNew, 0, sizeof(ZipfileEntry)); -+ pNew->cds.zFile = sqlite3_mprintf("%s", zPath); -+ if( pNew->cds.zFile==0 ){ -+ sqlite3_free(pNew); -+ pNew = 0; -+ } -+ } -+ return pNew; -+} -+ -+static int zipfileSerializeLFH(ZipfileEntry *pEntry, u8 *aBuf){ -+ ZipfileCDS *pCds = &pEntry->cds; -+ u8 *a = aBuf; -+ -+ pCds->nExtra = 9; -+ -+ /* Write the LFH itself */ -+ zipfileWrite32(a, ZIPFILE_SIGNATURE_LFH); -+ zipfileWrite16(a, pCds->iVersionExtract); -+ zipfileWrite16(a, pCds->flags); -+ zipfileWrite16(a, pCds->iCompression); -+ zipfileWrite16(a, pCds->mTime); -+ zipfileWrite16(a, pCds->mDate); -+ zipfileWrite32(a, pCds->crc32); -+ zipfileWrite32(a, pCds->szCompressed); -+ zipfileWrite32(a, pCds->szUncompressed); -+ zipfileWrite16(a, (u16)pCds->nFile); -+ zipfileWrite16(a, pCds->nExtra); -+ assert( a==&aBuf[ZIPFILE_LFH_FIXED_SZ] ); -+ -+ /* Add the file name */ -+ memcpy(a, pCds->zFile, (int)pCds->nFile); -+ a += (int)pCds->nFile; -+ -+ /* The "extra" data */ -+ zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP); -+ zipfileWrite16(a, 5); -+ *a++ = 0x01; -+ zipfileWrite32(a, pEntry->mUnixTime); -+ -+ return a-aBuf; -+} -+ -+static int zipfileAppendEntry( -+ ZipfileTab *pTab, -+ ZipfileEntry *pEntry, -+ const u8 *pData, -+ int nData -+){ -+ u8 *aBuf = pTab->aBuffer; -+ int nBuf; -+ int rc; -+ -+ nBuf = zipfileSerializeLFH(pEntry, aBuf); -+ rc = zipfileAppendData(pTab, aBuf, nBuf); -+ if( rc==SQLITE_OK ){ -+ pEntry->iDataOff = pTab->szCurrent; -+ rc = zipfileAppendData(pTab, pData, nData); -+ } -+ -+ return rc; -+} -+ -+static int zipfileGetMode( -+ sqlite3_value *pVal, -+ int bIsDir, /* If true, default to directory */ -+ u32 *pMode, /* OUT: Mode value */ -+ char **pzErr /* OUT: Error message */ -+){ -+ const char *z = (const char*)sqlite3_value_text(pVal); -+ u32 mode = 0; -+ if( z==0 ){ -+ mode = (bIsDir ? (S_IFDIR + 0755) : (S_IFREG + 0644)); -+ }else if( z[0]>='0' && z[0]<='9' ){ -+ mode = (unsigned int)sqlite3_value_int(pVal); -+ }else{ -+ const char zTemplate[11] = "-rwxrwxrwx"; -+ int i; -+ if( strlen(z)!=10 ) goto parse_error; -+ switch( z[0] ){ -+ case '-': mode |= S_IFREG; break; -+ case 'd': mode |= S_IFDIR; break; -+ case 'l': mode |= S_IFLNK; break; -+ default: goto parse_error; -+ } -+ for(i=1; i<10; i++){ -+ if( z[i]==zTemplate[i] ) mode |= 1 << (9-i); -+ else if( z[i]!='-' ) goto parse_error; -+ } -+ } -+ if( ((mode & S_IFDIR)==0)==bIsDir ){ -+ /* The "mode" attribute is a directory, but data has been specified. -+ ** Or vice-versa - no data but "mode" is a file or symlink. */ -+ *pzErr = sqlite3_mprintf("zipfile: mode does not match data"); -+ return SQLITE_CONSTRAINT; -+ } -+ *pMode = mode; -+ return SQLITE_OK; -+ -+ parse_error: -+ *pzErr = sqlite3_mprintf("zipfile: parse error in mode: %s", z); -+ return SQLITE_ERROR; -+} -+ -+/* -+** Both (const char*) arguments point to nul-terminated strings. Argument -+** nB is the value of strlen(zB). This function returns 0 if the strings are -+** 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==nB && memcmp(zA, zB, nA)==0 ) return 0; -+ return 1; -+} -+ -+static int zipfileBegin(sqlite3_vtab *pVtab){ -+ ZipfileTab *pTab = (ZipfileTab*)pVtab; -+ int rc = SQLITE_OK; -+ -+ assert( pTab->pWriteFd==0 ); -+ -+ /* Open a write fd on the file. Also load the entire central directory -+ ** structure into memory. During the transaction any new file data is -+ ** appended to the archive file, but the central directory is accumulated -+ ** in main-memory until the transaction is committed. */ -+ pTab->pWriteFd = fopen(pTab->zFile, "ab+"); -+ if( pTab->pWriteFd==0 ){ -+ pTab->base.zErrMsg = sqlite3_mprintf( -+ "zipfile: failed to open file %s for writing", pTab->zFile -+ ); -+ rc = SQLITE_ERROR; -+ }else{ -+ fseek(pTab->pWriteFd, 0, SEEK_END); -+ pTab->szCurrent = pTab->szOrig = (i64)ftell(pTab->pWriteFd); -+ rc = zipfileLoadDirectory(pTab, 0, 0); -+ } -+ -+ if( rc!=SQLITE_OK ){ -+ zipfileCleanupTransaction(pTab); -+ } -+ -+ return rc; -+} -+ -+/* -+** Return the current time as a 32-bit timestamp in UNIX epoch format (like -+** time(2)). -+*/ -+static u32 zipfileTime(void){ -+ sqlite3_vfs *pVfs = sqlite3_vfs_find(0); -+ u32 ret; -+ if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){ -+ i64 ms; -+ pVfs->xCurrentTimeInt64(pVfs, &ms); -+ ret = (u32)((ms/1000) - ((i64)24405875 * 8640)); -+ }else{ -+ double day; -+ pVfs->xCurrentTime(pVfs, &day); -+ ret = (u32)((day - 2440587.5) * 86400); -+ } -+ return ret; -+} -+ -+/* -+** Return a 32-bit timestamp in UNIX epoch format. -+** -+** If the value passed as the only argument is either NULL or an SQL NULL, -+** return the current time. Otherwise, return the value stored in (*pVal) -+** cast to a 32-bit unsigned integer. -+*/ -+static u32 zipfileGetTime(sqlite3_value *pVal){ -+ if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){ -+ return zipfileTime(); -+ } -+ return (u32)sqlite3_value_int64(pVal); -+} -+ -+/* -+** Unless it is NULL, entry pOld is currently part of the pTab->pFirstEntry -+** linked list. Remove it from the list and free the object. -+*/ -+static void zipfileRemoveEntryFromList(ZipfileTab *pTab, ZipfileEntry *pOld){ -+ if( pOld ){ -+ ZipfileEntry **pp; -+ for(pp=&pTab->pFirstEntry; (*pp)!=pOld; pp=&((*pp)->pNext)); -+ *pp = (*pp)->pNext; -+ zipfileEntryFree(pOld); -+ } -+} -+ -+/* -+** xUpdate method. -+*/ -+static int zipfileUpdate( -+ sqlite3_vtab *pVtab, -+ int nVal, -+ sqlite3_value **apVal, -+ sqlite_int64 *pRowid -+){ -+ ZipfileTab *pTab = (ZipfileTab*)pVtab; -+ int rc = SQLITE_OK; /* Return Code */ -+ ZipfileEntry *pNew = 0; /* New in-memory CDS entry */ -+ -+ u32 mode = 0; /* Mode for new entry */ -+ u32 mTime = 0; /* Modification time for new entry */ -+ i64 sz = 0; /* Uncompressed size */ -+ const char *zPath = 0; /* Path for new entry */ -+ int nPath = 0; /* strlen(zPath) */ -+ const u8 *pData = 0; /* Pointer to buffer containing content */ -+ int nData = 0; /* Size of pData buffer in bytes */ -+ int iMethod = 0; /* Compression method for new entry */ -+ u8 *pFree = 0; /* Free this */ -+ char *zFree = 0; /* Also free this */ -+ ZipfileEntry *pOld = 0; -+ ZipfileEntry *pOld2 = 0; -+ int bUpdate = 0; /* True for an update that modifies "name" */ -+ int bIsDir = 0; -+ u32 iCrc32 = 0; -+ -+ if( pTab->pWriteFd==0 ){ -+ rc = zipfileBegin(pVtab); -+ if( rc!=SQLITE_OK ) return rc; -+ } -+ -+ /* If this is a DELETE or UPDATE, find the archive entry to delete. */ -+ if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ -+ const char *zDelete = (const char*)sqlite3_value_text(apVal[0]); -+ int nDelete = (int)strlen(zDelete); -+ if( nVal>1 ){ -+ const char *zUpdate = (const char*)sqlite3_value_text(apVal[1]); -+ if( zUpdate && zipfileComparePath(zUpdate, zDelete, nDelete)!=0 ){ -+ bUpdate = 1; -+ } -+ } -+ for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){ -+ if( zipfileComparePath(pOld->cds.zFile, zDelete, nDelete)==0 ){ -+ break; -+ } -+ assert( pOld->pNext ); -+ } -+ } -+ -+ if( nVal>1 ){ -+ /* Check that "sz" and "rawdata" are both NULL: */ -+ if( sqlite3_value_type(apVal[5])!=SQLITE_NULL ){ -+ zipfileTableErr(pTab, "sz must be NULL"); -+ rc = SQLITE_CONSTRAINT; -+ } -+ if( sqlite3_value_type(apVal[6])!=SQLITE_NULL ){ -+ zipfileTableErr(pTab, "rawdata must be NULL"); -+ rc = SQLITE_CONSTRAINT; -+ } -+ -+ if( rc==SQLITE_OK ){ -+ if( sqlite3_value_type(apVal[7])==SQLITE_NULL ){ -+ /* data=NULL. A directory */ -+ bIsDir = 1; -+ }else{ -+ /* Value specified for "data", and possibly "method". This must be -+ ** a regular file or a symlink. */ -+ const u8 *aIn = sqlite3_value_blob(apVal[7]); -+ int nIn = sqlite3_value_bytes(apVal[7]); -+ int bAuto = sqlite3_value_type(apVal[8])==SQLITE_NULL; -+ -+ iMethod = sqlite3_value_int(apVal[8]); -+ sz = nIn; -+ pData = aIn; -+ nData = nIn; -+ if( iMethod!=0 && iMethod!=8 ){ -+ zipfileTableErr(pTab, "unknown compression method: %d", iMethod); -+ rc = SQLITE_CONSTRAINT; -+ }else{ -+ if( bAuto || iMethod ){ -+ int nCmp; -+ rc = zipfileDeflate(aIn, nIn, &pFree, &nCmp, &pTab->base.zErrMsg); -+ if( rc==SQLITE_OK ){ -+ if( iMethod || nCmp<nIn ){ -+ iMethod = 8; -+ pData = pFree; -+ nData = nCmp; -+ } -+ } -+ } -+ iCrc32 = crc32(0, aIn, nIn); -+ } -+ } -+ } -+ -+ if( rc==SQLITE_OK ){ -+ rc = zipfileGetMode(apVal[3], bIsDir, &mode, &pTab->base.zErrMsg); -+ } -+ -+ if( rc==SQLITE_OK ){ -+ zPath = (const char*)sqlite3_value_text(apVal[2]); -+ nPath = (int)strlen(zPath); -+ mTime = zipfileGetTime(apVal[4]); -+ } -+ -+ if( rc==SQLITE_OK && bIsDir ){ -+ /* For a directory, check that the last character in the path is a -+ ** '/'. 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]!='/' ){ -+ zFree = sqlite3_mprintf("%s/", zPath); -+ if( zFree==0 ){ rc = SQLITE_NOMEM; } -+ zPath = (const char*)zFree; -+ nPath++; -+ } -+ } -+ -+ /* Check that we're not inserting a duplicate entry -OR- updating an -+ ** entry with a path, thereby making it into a duplicate. */ -+ if( (pOld==0 || bUpdate) && rc==SQLITE_OK ){ -+ ZipfileEntry *p; -+ for(p=pTab->pFirstEntry; p; p=p->pNext){ -+ if( zipfileComparePath(p->cds.zFile, zPath, nPath)==0 ){ -+ switch( sqlite3_vtab_on_conflict(pTab->db) ){ -+ case SQLITE_IGNORE: { -+ goto zipfile_update_done; -+ } -+ case SQLITE_REPLACE: { -+ pOld2 = p; -+ break; -+ } -+ default: { -+ zipfileTableErr(pTab, "duplicate name: \"%s\"", zPath); -+ rc = SQLITE_CONSTRAINT; -+ break; -+ } -+ } -+ break; -+ } -+ } -+ } -+ -+ if( rc==SQLITE_OK ){ -+ /* Create the new CDS record. */ -+ pNew = zipfileNewEntry(zPath); -+ if( pNew==0 ){ -+ rc = SQLITE_NOMEM; -+ }else{ -+ pNew->cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY; -+ pNew->cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED; -+ pNew->cds.flags = ZIPFILE_NEWENTRY_FLAGS; -+ pNew->cds.iCompression = (u16)iMethod; -+ zipfileMtimeToDos(&pNew->cds, mTime); -+ pNew->cds.crc32 = iCrc32; -+ pNew->cds.szCompressed = nData; -+ pNew->cds.szUncompressed = (u32)sz; -+ pNew->cds.iExternalAttr = (mode<<16); -+ pNew->cds.iOffset = (u32)pTab->szCurrent; -+ pNew->cds.nFile = (u16)nPath; -+ pNew->mUnixTime = (u32)mTime; -+ rc = zipfileAppendEntry(pTab, pNew, pData, nData); -+ zipfileAddEntry(pTab, pOld, pNew); -+ } -+ } -+ } -+ -+ if( rc==SQLITE_OK && (pOld || pOld2) ){ -+ ZipfileCsr *pCsr; -+ for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){ -+ if( pCsr->pCurrent && (pCsr->pCurrent==pOld || pCsr->pCurrent==pOld2) ){ -+ pCsr->pCurrent = pCsr->pCurrent->pNext; -+ pCsr->bNoop = 1; -+ } -+ } -+ -+ zipfileRemoveEntryFromList(pTab, pOld); -+ zipfileRemoveEntryFromList(pTab, pOld2); -+ } -+ -+zipfile_update_done: -+ sqlite3_free(pFree); -+ sqlite3_free(zFree); -+ return rc; -+} -+ -+static int zipfileSerializeEOCD(ZipfileEOCD *p, u8 *aBuf){ -+ u8 *a = aBuf; -+ zipfileWrite32(a, ZIPFILE_SIGNATURE_EOCD); -+ zipfileWrite16(a, p->iDisk); -+ zipfileWrite16(a, p->iFirstDisk); -+ zipfileWrite16(a, p->nEntry); -+ zipfileWrite16(a, p->nEntryTotal); -+ zipfileWrite32(a, p->nSize); -+ zipfileWrite32(a, p->iOffset); -+ zipfileWrite16(a, 0); /* Size of trailing comment in bytes*/ -+ -+ return a-aBuf; -+} -+ -+static int zipfileAppendEOCD(ZipfileTab *pTab, ZipfileEOCD *p){ -+ int nBuf = zipfileSerializeEOCD(p, pTab->aBuffer); -+ assert( nBuf==ZIPFILE_EOCD_FIXED_SZ ); -+ return zipfileAppendData(pTab, pTab->aBuffer, nBuf); -+} -+ -+/* -+** Serialize the CDS structure into buffer aBuf[]. Return the number -+** of bytes written. -+*/ -+static int zipfileSerializeCDS(ZipfileEntry *pEntry, u8 *aBuf){ -+ u8 *a = aBuf; -+ ZipfileCDS *pCDS = &pEntry->cds; -+ -+ if( pEntry->aExtra==0 ){ -+ pCDS->nExtra = 9; -+ } -+ -+ zipfileWrite32(a, ZIPFILE_SIGNATURE_CDS); -+ zipfileWrite16(a, pCDS->iVersionMadeBy); -+ zipfileWrite16(a, pCDS->iVersionExtract); -+ zipfileWrite16(a, pCDS->flags); -+ zipfileWrite16(a, pCDS->iCompression); -+ zipfileWrite16(a, pCDS->mTime); -+ zipfileWrite16(a, pCDS->mDate); -+ zipfileWrite32(a, pCDS->crc32); -+ zipfileWrite32(a, pCDS->szCompressed); -+ zipfileWrite32(a, pCDS->szUncompressed); -+ assert( a==&aBuf[ZIPFILE_CDS_NFILE_OFF] ); -+ zipfileWrite16(a, pCDS->nFile); -+ zipfileWrite16(a, pCDS->nExtra); -+ zipfileWrite16(a, pCDS->nComment); -+ zipfileWrite16(a, pCDS->iDiskStart); -+ zipfileWrite16(a, pCDS->iInternalAttr); -+ zipfileWrite32(a, pCDS->iExternalAttr); -+ zipfileWrite32(a, pCDS->iOffset); -+ -+ memcpy(a, pCDS->zFile, pCDS->nFile); -+ a += pCDS->nFile; -+ -+ if( pEntry->aExtra ){ -+ int n = (int)pCDS->nExtra + (int)pCDS->nComment; -+ memcpy(a, pEntry->aExtra, n); -+ a += n; -+ }else{ -+ assert( pCDS->nExtra==9 ); -+ zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP); -+ zipfileWrite16(a, 5); -+ *a++ = 0x01; -+ zipfileWrite32(a, pEntry->mUnixTime); -+ } -+ -+ return a-aBuf; -+} -+ -+static int zipfileCommit(sqlite3_vtab *pVtab){ -+ ZipfileTab *pTab = (ZipfileTab*)pVtab; -+ int rc = SQLITE_OK; -+ if( pTab->pWriteFd ){ -+ i64 iOffset = pTab->szCurrent; -+ ZipfileEntry *p; -+ ZipfileEOCD eocd; -+ int nEntry = 0; -+ -+ /* Write out all entries */ -+ for(p=pTab->pFirstEntry; rc==SQLITE_OK && p; p=p->pNext){ -+ int n = zipfileSerializeCDS(p, pTab->aBuffer); -+ rc = zipfileAppendData(pTab, pTab->aBuffer, n); -+ nEntry++; -+ } -+ -+ /* Write out the EOCD record */ -+ eocd.iDisk = 0; -+ eocd.iFirstDisk = 0; -+ eocd.nEntry = (u16)nEntry; -+ eocd.nEntryTotal = (u16)nEntry; -+ eocd.nSize = (u32)(pTab->szCurrent - iOffset); -+ eocd.iOffset = (u32)iOffset; -+ rc = zipfileAppendEOCD(pTab, &eocd); -+ -+ zipfileCleanupTransaction(pTab); -+ } -+ return rc; -+} -+ -+static int zipfileRollback(sqlite3_vtab *pVtab){ -+ return zipfileCommit(pVtab); -+} -+ -+static ZipfileCsr *zipfileFindCursor(ZipfileTab *pTab, i64 iId){ -+ ZipfileCsr *pCsr; -+ for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){ -+ if( iId==pCsr->iId ) break; -+ } -+ return pCsr; -+} -+ -+static void zipfileFunctionCds( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ ZipfileCsr *pCsr; -+ ZipfileTab *pTab = (ZipfileTab*)sqlite3_user_data(context); -+ assert( argc>0 ); -+ -+ pCsr = zipfileFindCursor(pTab, sqlite3_value_int64(argv[0])); -+ if( pCsr ){ -+ ZipfileCDS *p = &pCsr->pCurrent->cds; -+ char *zRes = sqlite3_mprintf("{" -+ "\"version-made-by\" : %u, " -+ "\"version-to-extract\" : %u, " -+ "\"flags\" : %u, " -+ "\"compression\" : %u, " -+ "\"time\" : %u, " -+ "\"date\" : %u, " -+ "\"crc32\" : %u, " -+ "\"compressed-size\" : %u, " -+ "\"uncompressed-size\" : %u, " -+ "\"file-name-length\" : %u, " -+ "\"extra-field-length\" : %u, " -+ "\"file-comment-length\" : %u, " -+ "\"disk-number-start\" : %u, " -+ "\"internal-attr\" : %u, " -+ "\"external-attr\" : %u, " -+ "\"offset\" : %u }", -+ (u32)p->iVersionMadeBy, (u32)p->iVersionExtract, -+ (u32)p->flags, (u32)p->iCompression, -+ (u32)p->mTime, (u32)p->mDate, -+ (u32)p->crc32, (u32)p->szCompressed, -+ (u32)p->szUncompressed, (u32)p->nFile, -+ (u32)p->nExtra, (u32)p->nComment, -+ (u32)p->iDiskStart, (u32)p->iInternalAttr, -+ (u32)p->iExternalAttr, (u32)p->iOffset -+ ); -+ -+ if( zRes==0 ){ -+ sqlite3_result_error_nomem(context); -+ }else{ -+ sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT); -+ sqlite3_free(zRes); -+ } -+ } -+} -+ -+/* -+** xFindFunction method. -+*/ -+static int zipfileFindFunction( -+ sqlite3_vtab *pVtab, /* Virtual table handle */ -+ int nArg, /* Number of SQL function arguments */ -+ const char *zName, /* Name of SQL function */ -+ void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */ -+ void **ppArg /* OUT: User data for *pxFunc */ -+){ -+ if( sqlite3_stricmp("zipfile_cds", zName)==0 ){ -+ *pxFunc = zipfileFunctionCds; -+ *ppArg = (void*)pVtab; -+ return 1; -+ } -+ return 0; -+} -+ -+typedef struct ZipfileBuffer ZipfileBuffer; -+struct ZipfileBuffer { -+ u8 *a; /* Pointer to buffer */ -+ int n; /* Size of buffer in bytes */ -+ int nAlloc; /* Byte allocated at a[] */ -+}; -+ -+typedef struct ZipfileCtx ZipfileCtx; -+struct ZipfileCtx { -+ int nEntry; -+ ZipfileBuffer body; -+ ZipfileBuffer cds; -+}; -+ -+static int zipfileBufferGrow(ZipfileBuffer *pBuf, int nByte){ -+ if( pBuf->n+nByte>pBuf->nAlloc ){ -+ u8 *aNew; -+ int nNew = pBuf->n ? pBuf->n*2 : 512; -+ int nReq = pBuf->n + nByte; -+ -+ while( nNew<nReq ) nNew = nNew*2; -+ aNew = sqlite3_realloc(pBuf->a, nNew); -+ if( aNew==0 ) return SQLITE_NOMEM; -+ pBuf->a = aNew; -+ pBuf->nAlloc = nNew; -+ } -+ return SQLITE_OK; -+} -+ -+/* -+** xStep() callback for the zipfile() aggregate. This can be called in -+** any of the following ways: -+** -+** SELECT zipfile(name,data) ... -+** SELECT zipfile(name,mode,mtime,data) ... -+** SELECT zipfile(name,mode,mtime,data,method) ... -+*/ -+void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){ -+ ZipfileCtx *p; /* Aggregate function context */ -+ ZipfileEntry e; /* New entry to add to zip archive */ -+ -+ sqlite3_value *pName = 0; -+ sqlite3_value *pMode = 0; -+ sqlite3_value *pMtime = 0; -+ sqlite3_value *pData = 0; -+ sqlite3_value *pMethod = 0; -+ -+ int bIsDir = 0; -+ u32 mode; -+ int rc = SQLITE_OK; -+ char *zErr = 0; -+ -+ int iMethod = -1; /* Compression method to use (0 or 8) */ -+ -+ const u8 *aData = 0; /* Possibly compressed data for new entry */ -+ int nData = 0; /* Size of aData[] in bytes */ -+ int szUncompressed = 0; /* Size of data before compression */ -+ u8 *aFree = 0; /* Free this before returning */ -+ u32 iCrc32 = 0; /* crc32 of uncompressed data */ -+ -+ char *zName = 0; /* Path (name) of new entry */ -+ int nName = 0; /* Size of zName in bytes */ -+ char *zFree = 0; /* Free this before returning */ -+ int nByte; -+ -+ memset(&e, 0, sizeof(e)); -+ p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx)); -+ if( p==0 ) return; -+ -+ /* Martial the arguments into stack variables */ -+ if( nVal!=2 && nVal!=4 && nVal!=5 ){ -+ zErr = sqlite3_mprintf("wrong number of arguments to function zipfile()"); -+ rc = SQLITE_ERROR; -+ goto zipfile_step_out; -+ } -+ pName = apVal[0]; -+ if( nVal==2 ){ -+ pData = apVal[1]; -+ }else{ -+ pMode = apVal[1]; -+ pMtime = apVal[2]; -+ pData = apVal[3]; -+ if( nVal==5 ){ -+ pMethod = apVal[4]; -+ } -+ } -+ -+ /* Check that the 'name' parameter looks ok. */ -+ zName = (char*)sqlite3_value_text(pName); -+ nName = sqlite3_value_bytes(pName); -+ if( zName==0 ){ -+ zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL"); -+ rc = SQLITE_ERROR; -+ goto zipfile_step_out; -+ } -+ -+ /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use -+ ** deflate compression) or NULL (choose automatically). */ -+ if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){ -+ iMethod = (int)sqlite3_value_int64(pMethod); -+ if( iMethod!=0 && iMethod!=8 ){ -+ zErr = sqlite3_mprintf("illegal method value: %d", iMethod); -+ rc = SQLITE_ERROR; -+ goto zipfile_step_out; -+ } -+ } -+ -+ /* Now inspect the data. If this is NULL, then the new entry must be a -+ ** directory. Otherwise, figure out whether or not the data should -+ ** be deflated or simply stored in the zip archive. */ -+ if( sqlite3_value_type(pData)==SQLITE_NULL ){ -+ bIsDir = 1; -+ iMethod = 0; -+ }else{ -+ aData = sqlite3_value_blob(pData); -+ szUncompressed = nData = sqlite3_value_bytes(pData); -+ iCrc32 = crc32(0, aData, nData); -+ if( iMethod<0 || iMethod==8 ){ -+ int nOut = 0; -+ rc = zipfileDeflate(aData, nData, &aFree, &nOut, &zErr); -+ if( rc!=SQLITE_OK ){ -+ goto zipfile_step_out; -+ } -+ if( iMethod==8 || nOut<nData ){ -+ aData = aFree; -+ nData = nOut; -+ iMethod = 8; -+ }else{ -+ iMethod = 0; -+ } -+ } -+ } -+ -+ /* Decode the "mode" argument. */ -+ rc = zipfileGetMode(pMode, bIsDir, &mode, &zErr); -+ if( rc ) goto zipfile_step_out; -+ -+ /* Decode the "mtime" argument. */ -+ e.mUnixTime = zipfileGetTime(pMtime); -+ -+ /* If this is a directory entry, ensure that there is exactly one '/' -+ ** 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]=='/' ){ -+ zErr = sqlite3_mprintf("non-directory name must not end with /"); -+ rc = SQLITE_ERROR; -+ goto zipfile_step_out; -+ } -+ }else{ -+ if( zName[nName-1]!='/' ){ -+ zName = zFree = sqlite3_mprintf("%s/", zName); -+ nName++; -+ if( zName==0 ){ -+ rc = SQLITE_NOMEM; -+ goto zipfile_step_out; -+ } -+ }else{ -+ while( nName>1 && zName[nName-2]=='/' ) nName--; -+ } -+ } -+ -+ /* Assemble the ZipfileEntry object for the new zip archive entry */ -+ e.cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY; -+ e.cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED; -+ e.cds.flags = ZIPFILE_NEWENTRY_FLAGS; -+ e.cds.iCompression = (u16)iMethod; -+ zipfileMtimeToDos(&e.cds, (u32)e.mUnixTime); -+ e.cds.crc32 = iCrc32; -+ e.cds.szCompressed = nData; -+ e.cds.szUncompressed = szUncompressed; -+ e.cds.iExternalAttr = (mode<<16); -+ e.cds.iOffset = p->body.n; -+ e.cds.nFile = (u16)nName; -+ e.cds.zFile = zName; -+ -+ /* Append the LFH to the body of the new archive */ -+ nByte = ZIPFILE_LFH_FIXED_SZ + e.cds.nFile + 9; -+ if( (rc = zipfileBufferGrow(&p->body, nByte)) ) goto zipfile_step_out; -+ p->body.n += zipfileSerializeLFH(&e, &p->body.a[p->body.n]); -+ -+ /* Append the data to the body of the new archive */ -+ if( nData>0 ){ -+ if( (rc = zipfileBufferGrow(&p->body, nData)) ) goto zipfile_step_out; -+ memcpy(&p->body.a[p->body.n], aData, nData); -+ p->body.n += nData; -+ } -+ -+ /* Append the CDS record to the directory of the new archive */ -+ nByte = ZIPFILE_CDS_FIXED_SZ + e.cds.nFile + 9; -+ if( (rc = zipfileBufferGrow(&p->cds, nByte)) ) goto zipfile_step_out; -+ p->cds.n += zipfileSerializeCDS(&e, &p->cds.a[p->cds.n]); -+ -+ /* Increment the count of entries in the archive */ -+ p->nEntry++; -+ -+ zipfile_step_out: -+ sqlite3_free(aFree); -+ sqlite3_free(zFree); -+ if( rc ){ -+ if( zErr ){ -+ sqlite3_result_error(pCtx, zErr, -1); -+ }else{ -+ sqlite3_result_error_code(pCtx, rc); -+ } -+ } -+ sqlite3_free(zErr); -+} -+ -+/* -+** xFinalize() callback for zipfile aggregate function. -+*/ -+void zipfileFinal(sqlite3_context *pCtx){ -+ ZipfileCtx *p; -+ ZipfileEOCD eocd; -+ int nZip; -+ u8 *aZip; -+ -+ p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx)); -+ if( p==0 ) return; -+ if( p->nEntry>0 ){ -+ memset(&eocd, 0, sizeof(eocd)); -+ eocd.nEntry = (u16)p->nEntry; -+ eocd.nEntryTotal = (u16)p->nEntry; -+ eocd.nSize = p->cds.n; -+ eocd.iOffset = p->body.n; -+ -+ nZip = p->body.n + p->cds.n + ZIPFILE_EOCD_FIXED_SZ; -+ aZip = (u8*)sqlite3_malloc(nZip); -+ if( aZip==0 ){ -+ sqlite3_result_error_nomem(pCtx); -+ }else{ -+ memcpy(aZip, p->body.a, p->body.n); -+ memcpy(&aZip[p->body.n], p->cds.a, p->cds.n); -+ zipfileSerializeEOCD(&eocd, &aZip[p->body.n + p->cds.n]); -+ sqlite3_result_blob(pCtx, aZip, nZip, zipfileFree); -+ } -+ } -+ -+ sqlite3_free(p->body.a); -+ sqlite3_free(p->cds.a); -+} -+ -+ -+/* -+** Register the "zipfile" virtual table. -+*/ -+static int zipfileRegister(sqlite3 *db){ -+ static sqlite3_module zipfileModule = { -+ 1, /* iVersion */ -+ zipfileConnect, /* xCreate */ -+ zipfileConnect, /* xConnect */ -+ zipfileBestIndex, /* xBestIndex */ -+ zipfileDisconnect, /* xDisconnect */ -+ zipfileDisconnect, /* xDestroy */ -+ zipfileOpen, /* xOpen - open a cursor */ -+ zipfileClose, /* xClose - close a cursor */ -+ zipfileFilter, /* xFilter - configure scan constraints */ -+ zipfileNext, /* xNext - advance a cursor */ -+ zipfileEof, /* xEof - check for end of scan */ -+ zipfileColumn, /* xColumn - read data */ -+ 0, /* xRowid - read data */ -+ zipfileUpdate, /* xUpdate */ -+ zipfileBegin, /* xBegin */ -+ 0, /* xSync */ -+ zipfileCommit, /* xCommit */ -+ zipfileRollback, /* xRollback */ -+ zipfileFindFunction, /* xFindMethod */ -+ 0, /* xRename */ -+ }; -+ -+ int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0); -+ if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1); -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3_create_function(db, "zipfile", -1, SQLITE_UTF8, 0, 0, -+ zipfileStep, zipfileFinal -+ ); -+ } -+ return rc; -+} -+#else /* SQLITE_OMIT_VIRTUALTABLE */ -+# define zipfileRegister(x) SQLITE_OK -+#endif -+ -+#ifdef _WIN32 -+ -+#endif -+int sqlite3_zipfile_init( -+ sqlite3 *db, -+ char **pzErrMsg, -+ const sqlite3_api_routines *pApi -+){ -+ SQLITE_EXTENSION_INIT2(pApi); -+ (void)pzErrMsg; /* Unused parameter */ -+ return zipfileRegister(db); -+} -+ -+/************************* End ../ext/misc/zipfile.c ********************/ -+/************************* Begin ../ext/misc/sqlar.c ******************/ -+/* -+** 2017-12-17 -+** -+** 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. -+** -+****************************************************************************** -+** -+** Utility functions sqlar_compress() and sqlar_uncompress(). Useful -+** for working with sqlar archives and used by the shell tool's built-in -+** sqlar support. -+*/ -+SQLITE_EXTENSION_INIT1 -+#include <zlib.h> -+ -+/* -+** Implementation of the "sqlar_compress(X)" SQL function. -+** -+** If the type of X is SQLITE_BLOB, and compressing that blob using -+** zlib utility function compress() yields a smaller blob, return the -+** compressed blob. Otherwise, return a copy of X. -+** -+** SQLar uses the "zlib format" for compressed content. The zlib format -+** contains a two-byte identification header and a four-byte checksum at -+** the end. This is different from ZIP which uses the raw deflate format. -+** -+** Future enhancements to SQLar might add support for new compression formats. -+** If so, those new formats will be identified by alternative headers in the -+** compressed data. -+*/ -+static void sqlarCompressFunc( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ assert( argc==1 ); -+ if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){ -+ const Bytef *pData = sqlite3_value_blob(argv[0]); -+ uLong nData = sqlite3_value_bytes(argv[0]); -+ uLongf nOut = compressBound(nData); -+ Bytef *pOut; -+ -+ pOut = (Bytef*)sqlite3_malloc(nOut); -+ if( pOut==0 ){ -+ sqlite3_result_error_nomem(context); -+ return; -+ }else{ -+ if( Z_OK!=compress(pOut, &nOut, pData, nData) ){ -+ sqlite3_result_error(context, "error in compress()", -1); -+ }else if( nOut<nData ){ -+ sqlite3_result_blob(context, pOut, nOut, SQLITE_TRANSIENT); -+ }else{ -+ sqlite3_result_value(context, argv[0]); -+ } -+ sqlite3_free(pOut); -+ } -+ }else{ -+ sqlite3_result_value(context, argv[0]); -+ } -+} -+ -+/* -+** Implementation of the "sqlar_uncompress(X,SZ)" SQL function -+** -+** Parameter SZ is interpreted as an integer. If it is less than or -+** equal to zero, then this function returns a copy of X. Or, if -+** SZ is equal to the size of X when interpreted as a blob, also -+** return a copy of X. Otherwise, decompress blob X using zlib -+** utility function uncompress() and return the results (another -+** blob). -+*/ -+static void sqlarUncompressFunc( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ uLong nData; -+ uLongf sz; -+ -+ assert( argc==2 ); -+ sz = sqlite3_value_int(argv[1]); -+ -+ if( sz<=0 || sz==(nData = sqlite3_value_bytes(argv[0])) ){ -+ sqlite3_result_value(context, argv[0]); -+ }else{ -+ const Bytef *pData= sqlite3_value_blob(argv[0]); -+ Bytef *pOut = sqlite3_malloc(sz); -+ if( Z_OK!=uncompress(pOut, &sz, pData, nData) ){ -+ sqlite3_result_error(context, "error in uncompress()", -1); -+ }else{ -+ sqlite3_result_blob(context, pOut, sz, SQLITE_TRANSIENT); -+ } -+ sqlite3_free(pOut); -+ } -+} -+ -+ -+#ifdef _WIN32 -+ -+#endif -+int sqlite3_sqlar_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, "sqlar_compress", 1, SQLITE_UTF8, 0, -+ sqlarCompressFunc, 0, 0); -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3_create_function(db, "sqlar_uncompress", 2, SQLITE_UTF8, 0, -+ sqlarUncompressFunc, 0, 0); -+ } -+ return rc; -+} -+ -+/************************* End ../ext/misc/sqlar.c ********************/ -+#endif -+/************************* Begin ../ext/expert/sqlite3expert.h ******************/ -+/* -+** 2017 April 07 -+** -+** 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. -+** -+************************************************************************* -+*/ -+ -+ -+ -+typedef struct sqlite3expert sqlite3expert; -+ -+/* -+** Create a new sqlite3expert object. -+** -+** If successful, a pointer to the new object is returned and (*pzErr) set -+** to NULL. Or, if an error occurs, NULL is returned and (*pzErr) set to -+** an English-language error message. In this case it is the responsibility -+** of the caller to eventually free the error message buffer using -+** sqlite3_free(). -+*/ -+sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErr); -+ -+/* -+** Configure an sqlite3expert object. -+** -+** EXPERT_CONFIG_SAMPLE: -+** By default, sqlite3_expert_analyze() generates sqlite_stat1 data for -+** each candidate index. This involves scanning and sorting the entire -+** contents of each user database table once for each candidate index -+** associated with the table. For large databases, this can be -+** prohibitively slow. This option allows the sqlite3expert object to -+** be configured so that sqlite_stat1 data is instead generated based on a -+** subset of each table, or so that no sqlite_stat1 data is used at all. -+** -+** A single integer argument is passed to this option. If the value is less -+** than or equal to zero, then no sqlite_stat1 data is generated or used by -+** the analysis - indexes are recommended based on the database schema only. -+** Or, if the value is 100 or greater, complete sqlite_stat1 data is -+** generated for each candidate index (this is the default). Finally, if the -+** value falls between 0 and 100, then it represents the percentage of user -+** table rows that should be considered when generating sqlite_stat1 data. -+** -+** Examples: -+** -+** // Do not generate any sqlite_stat1 data -+** sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 0); -+** -+** // Generate sqlite_stat1 data based on 10% of the rows in each table. -+** sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 10); -+*/ -+int sqlite3_expert_config(sqlite3expert *p, int op, ...); -+ -+#define EXPERT_CONFIG_SAMPLE 1 /* int */ -+ -+/* -+** Specify zero or more SQL statements to be included in the analysis. -+** -+** Buffer zSql must contain zero or more complete SQL statements. This -+** function parses all statements contained in the buffer and adds them -+** to the internal list of statements to analyze. If successful, SQLITE_OK -+** is returned and (*pzErr) set to NULL. Or, if an error occurs - for example -+** due to a error in the SQL - an SQLite error code is returned and (*pzErr) -+** may be set to point to an English language error message. In this case -+** the caller is responsible for eventually freeing the error message buffer -+** using sqlite3_free(). -+** -+** If an error does occur while processing one of the statements in the -+** buffer passed as the second argument, none of the statements in the -+** buffer are added to the analysis. -+** -+** This function must be called before sqlite3_expert_analyze(). If a call -+** to this function is made on an sqlite3expert object that has already -+** been passed to sqlite3_expert_analyze() SQLITE_MISUSE is returned -+** immediately and no statements are added to the analysis. -+*/ -+int sqlite3_expert_sql( -+ sqlite3expert *p, /* From a successful sqlite3_expert_new() */ -+ const char *zSql, /* SQL statement(s) to add */ -+ char **pzErr /* OUT: Error message (if any) */ -+); -+ -+ -+/* -+** This function is called after the sqlite3expert object has been configured -+** with all SQL statements using sqlite3_expert_sql() to actually perform -+** the analysis. Once this function has been called, it is not possible to -+** add further SQL statements to the analysis. -+** -+** If successful, SQLITE_OK is returned and (*pzErr) is set to NULL. Or, if -+** an error occurs, an SQLite error code is returned and (*pzErr) set to -+** point to a buffer containing an English language error message. In this -+** case it is the responsibility of the caller to eventually free the buffer -+** using sqlite3_free(). -+** -+** If an error does occur within this function, the sqlite3expert object -+** is no longer useful for any purpose. At that point it is no longer -+** possible to add further SQL statements to the object or to re-attempt -+** the analysis. The sqlite3expert object must still be freed using a call -+** sqlite3_expert_destroy(). -+*/ -+int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr); -+ -+/* -+** Return the total number of statements loaded using sqlite3_expert_sql(). -+** The total number of SQL statements may be different from the total number -+** to calls to sqlite3_expert_sql(). -+*/ -+int sqlite3_expert_count(sqlite3expert*); -+ -+/* -+** Return a component of the report. -+** -+** This function is called after sqlite3_expert_analyze() to extract the -+** results of the analysis. Each call to this function returns either a -+** NULL pointer or a pointer to a buffer containing a nul-terminated string. -+** The value passed as the third argument must be one of the EXPERT_REPORT_* -+** #define constants defined below. -+** -+** For some EXPERT_REPORT_* parameters, the buffer returned contains -+** information relating to a specific SQL statement. In these cases that -+** SQL statement is identified by the value passed as the second argument. -+** SQL statements are numbered from 0 in the order in which they are parsed. -+** If an out-of-range value (less than zero or equal to or greater than the -+** value returned by sqlite3_expert_count()) is passed as the second argument -+** along with such an EXPERT_REPORT_* parameter, NULL is always returned. -+** -+** EXPERT_REPORT_SQL: -+** Return the text of SQL statement iStmt. -+** -+** EXPERT_REPORT_INDEXES: -+** Return a buffer containing the CREATE INDEX statements for all recommended -+** indexes for statement iStmt. If there are no new recommeded indexes, NULL -+** is returned. -+** -+** EXPERT_REPORT_PLAN: -+** Return a buffer containing the EXPLAIN QUERY PLAN output for SQL query -+** iStmt after the proposed indexes have been added to the database schema. -+** -+** EXPERT_REPORT_CANDIDATES: -+** Return a pointer to a buffer containing the CREATE INDEX statements -+** for all indexes that were tested (for all SQL statements). The iStmt -+** parameter is ignored for EXPERT_REPORT_CANDIDATES calls. -+*/ -+const char *sqlite3_expert_report(sqlite3expert*, int iStmt, int eReport); -+ -+/* -+** Values for the third argument passed to sqlite3_expert_report(). -+*/ -+#define EXPERT_REPORT_SQL 1 -+#define EXPERT_REPORT_INDEXES 2 -+#define EXPERT_REPORT_PLAN 3 -+#define EXPERT_REPORT_CANDIDATES 4 -+ -+/* -+** Free an (sqlite3expert*) handle and all associated resources. There -+** should be one call to this function for each successful call to -+** sqlite3-expert_new(). -+*/ -+void sqlite3_expert_destroy(sqlite3expert*); -+ -+ -+ -+/************************* End ../ext/expert/sqlite3expert.h ********************/ -+/************************* Begin ../ext/expert/sqlite3expert.c ******************/ -+/* -+** 2017 April 09 -+** -+** 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. -+** -+************************************************************************* -+*/ -+#include <assert.h> -+#include <string.h> -+#include <stdio.h> -+ -+#ifndef SQLITE_OMIT_VIRTUALTABLE -+ -+/* typedef sqlite3_int64 i64; */ -+/* typedef sqlite3_uint64 u64; */ -+ -+typedef struct IdxColumn IdxColumn; -+typedef struct IdxConstraint IdxConstraint; -+typedef struct IdxScan IdxScan; -+typedef struct IdxStatement IdxStatement; -+typedef struct IdxTable IdxTable; -+typedef struct IdxWrite IdxWrite; -+ -+#define STRLEN (int)strlen -+ -+/* -+** A temp table name that we assume no user database will actually use. -+** If this assumption proves incorrect triggers on the table with the -+** conflicting name will be ignored. -+*/ -+#define UNIQUE_TABLE_NAME "t592690916721053953805701627921227776" -+ -+/* -+** A single constraint. Equivalent to either "col = ?" or "col < ?" (or -+** any other type of single-ended range constraint on a column). -+** -+** pLink: -+** Used to temporarily link IdxConstraint objects into lists while -+** creating candidate indexes. -+*/ -+struct IdxConstraint { -+ char *zColl; /* Collation sequence */ -+ int bRange; /* True for range, false for eq */ -+ int iCol; /* Constrained table column */ -+ int bFlag; /* Used by idxFindCompatible() */ -+ int bDesc; /* True if ORDER BY <expr> DESC */ -+ IdxConstraint *pNext; /* Next constraint in pEq or pRange list */ -+ IdxConstraint *pLink; /* See above */ -+}; -+ -+/* -+** A single scan of a single table. -+*/ -+struct IdxScan { -+ IdxTable *pTab; /* Associated table object */ -+ int iDb; /* Database containing table zTable */ -+ i64 covering; /* Mask of columns required for cov. index */ -+ IdxConstraint *pOrder; /* ORDER BY columns */ -+ IdxConstraint *pEq; /* List of == constraints */ -+ IdxConstraint *pRange; /* List of < constraints */ -+ IdxScan *pNextScan; /* Next IdxScan object for same analysis */ -+}; -+ -+/* -+** Information regarding a single database table. Extracted from -+** "PRAGMA table_info" by function idxGetTableInfo(). -+*/ -+struct IdxColumn { -+ char *zName; -+ char *zColl; -+ int iPk; -+}; -+struct IdxTable { -+ int nCol; -+ char *zName; /* Table name */ -+ IdxColumn *aCol; -+ IdxTable *pNext; /* Next table in linked list of all tables */ -+}; -+ -+/* -+** An object of the following type is created for each unique table/write-op -+** seen. The objects are stored in a singly-linked list beginning at -+** sqlite3expert.pWrite. -+*/ -+struct IdxWrite { -+ IdxTable *pTab; -+ int eOp; /* SQLITE_UPDATE, DELETE or INSERT */ -+ IdxWrite *pNext; -+}; -+ -+/* -+** Each statement being analyzed is represented by an instance of this -+** structure. -+*/ -+struct IdxStatement { -+ int iId; /* Statement number */ -+ char *zSql; /* SQL statement */ -+ char *zIdx; /* Indexes */ -+ char *zEQP; /* Plan */ -+ IdxStatement *pNext; -+}; -+ -+ -+/* -+** A hash table for storing strings. With space for a payload string -+** with each entry. Methods are: -+** -+** idxHashInit() -+** idxHashClear() -+** idxHashAdd() -+** idxHashSearch() -+*/ -+#define IDX_HASH_SIZE 1023 -+typedef struct IdxHashEntry IdxHashEntry; -+typedef struct IdxHash IdxHash; -+struct IdxHashEntry { -+ char *zKey; /* nul-terminated key */ -+ char *zVal; /* nul-terminated value string */ -+ char *zVal2; /* nul-terminated value string 2 */ -+ IdxHashEntry *pHashNext; /* Next entry in same hash bucket */ -+ IdxHashEntry *pNext; /* Next entry in hash */ -+}; -+struct IdxHash { -+ IdxHashEntry *pFirst; -+ IdxHashEntry *aHash[IDX_HASH_SIZE]; -+}; -+ -+/* -+** sqlite3expert object. -+*/ -+struct sqlite3expert { -+ int iSample; /* Percentage of tables to sample for stat1 */ -+ sqlite3 *db; /* User database */ -+ sqlite3 *dbm; /* In-memory db for this analysis */ -+ sqlite3 *dbv; /* Vtab schema for this analysis */ -+ IdxTable *pTable; /* List of all IdxTable objects */ -+ IdxScan *pScan; /* List of scan objects */ -+ IdxWrite *pWrite; /* List of write objects */ -+ IdxStatement *pStatement; /* List of IdxStatement objects */ -+ int bRun; /* True once analysis has run */ -+ char **pzErrmsg; -+ int rc; /* Error code from whereinfo hook */ -+ IdxHash hIdx; /* Hash containing all candidate indexes */ -+ char *zCandidates; /* For EXPERT_REPORT_CANDIDATES */ -+}; -+ -+ -+/* -+** Allocate and return nByte bytes of zeroed memory using sqlite3_malloc(). -+** If the allocation fails, set *pRc to SQLITE_NOMEM and return NULL. -+*/ -+static void *idxMalloc(int *pRc, int nByte){ -+ void *pRet; -+ assert( *pRc==SQLITE_OK ); -+ assert( nByte>0 ); -+ pRet = sqlite3_malloc(nByte); -+ if( pRet ){ -+ memset(pRet, 0, nByte); -+ }else{ -+ *pRc = SQLITE_NOMEM; -+ } -+ return pRet; -+} -+ -+/* -+** Initialize an IdxHash hash table. -+*/ -+static void idxHashInit(IdxHash *pHash){ -+ memset(pHash, 0, sizeof(IdxHash)); -+} -+ -+/* -+** Reset an IdxHash hash table. -+*/ -+static void idxHashClear(IdxHash *pHash){ -+ int i; -+ for(i=0; i<IDX_HASH_SIZE; i++){ -+ IdxHashEntry *pEntry; -+ IdxHashEntry *pNext; -+ for(pEntry=pHash->aHash[i]; pEntry; pEntry=pNext){ -+ pNext = pEntry->pHashNext; -+ sqlite3_free(pEntry->zVal2); -+ sqlite3_free(pEntry); -+ } -+ } -+ memset(pHash, 0, sizeof(IdxHash)); -+} -+ -+/* -+** Return the index of the hash bucket that the string specified by the -+** arguments to this function belongs. -+*/ -+static int idxHashString(const char *z, int n){ -+ unsigned int ret = 0; -+ int i; -+ for(i=0; i<n; i++){ -+ ret += (ret<<3) + (unsigned char)(z[i]); -+ } -+ return (int)(ret % IDX_HASH_SIZE); -+} -+ -+/* -+** If zKey is already present in the hash table, return non-zero and do -+** nothing. Otherwise, add an entry with key zKey and payload string zVal to -+** the hash table passed as the second argument. -+*/ -+static int idxHashAdd( -+ int *pRc, -+ IdxHash *pHash, -+ const char *zKey, -+ const char *zVal -+){ -+ int nKey = STRLEN(zKey); -+ int iHash = idxHashString(zKey, nKey); -+ int nVal = (zVal ? STRLEN(zVal) : 0); -+ IdxHashEntry *pEntry; -+ assert( iHash>=0 ); -+ for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){ -+ if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){ -+ return 1; -+ } -+ } -+ pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + nKey+1 + nVal+1); -+ if( pEntry ){ -+ pEntry->zKey = (char*)&pEntry[1]; -+ memcpy(pEntry->zKey, zKey, nKey); -+ if( zVal ){ -+ pEntry->zVal = &pEntry->zKey[nKey+1]; -+ memcpy(pEntry->zVal, zVal, nVal); -+ } -+ pEntry->pHashNext = pHash->aHash[iHash]; -+ pHash->aHash[iHash] = pEntry; -+ -+ pEntry->pNext = pHash->pFirst; -+ pHash->pFirst = pEntry; -+ } -+ return 0; -+} -+ -+/* -+** If zKey/nKey is present in the hash table, return a pointer to the -+** hash-entry object. -+*/ -+static IdxHashEntry *idxHashFind(IdxHash *pHash, const char *zKey, int nKey){ -+ int iHash; -+ IdxHashEntry *pEntry; -+ if( nKey<0 ) nKey = STRLEN(zKey); -+ iHash = idxHashString(zKey, nKey); -+ assert( iHash>=0 ); -+ for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){ -+ if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){ -+ return pEntry; -+ } -+ } -+ return 0; -+} -+ -+/* -+** If the hash table contains an entry with a key equal to the string -+** passed as the final two arguments to this function, return a pointer -+** to the payload string. Otherwise, if zKey/nKey is not present in the -+** hash table, return NULL. -+*/ -+static const char *idxHashSearch(IdxHash *pHash, const char *zKey, int nKey){ -+ IdxHashEntry *pEntry = idxHashFind(pHash, zKey, nKey); -+ if( pEntry ) return pEntry->zVal; -+ return 0; -+} -+ -+/* -+** Allocate and return a new IdxConstraint object. Set the IdxConstraint.zColl -+** variable to point to a copy of nul-terminated string zColl. -+*/ -+static IdxConstraint *idxNewConstraint(int *pRc, const char *zColl){ -+ IdxConstraint *pNew; -+ int nColl = STRLEN(zColl); -+ -+ assert( *pRc==SQLITE_OK ); -+ pNew = (IdxConstraint*)idxMalloc(pRc, sizeof(IdxConstraint) * nColl + 1); -+ if( pNew ){ -+ pNew->zColl = (char*)&pNew[1]; -+ memcpy(pNew->zColl, zColl, nColl+1); -+ } -+ return pNew; -+} -+ -+/* -+** An error associated with database handle db has just occurred. Pass -+** the error message to callback function xOut. -+*/ -+static void idxDatabaseError( -+ sqlite3 *db, /* Database handle */ -+ char **pzErrmsg /* Write error here */ -+){ -+ *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); -+} -+ -+/* -+** Prepare an SQL statement. -+*/ -+static int idxPrepareStmt( -+ sqlite3 *db, /* Database handle to compile against */ -+ sqlite3_stmt **ppStmt, /* OUT: Compiled SQL statement */ -+ char **pzErrmsg, /* OUT: sqlite3_malloc()ed error message */ -+ const char *zSql /* SQL statement to compile */ -+){ -+ int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); -+ if( rc!=SQLITE_OK ){ -+ *ppStmt = 0; -+ idxDatabaseError(db, pzErrmsg); -+ } -+ return rc; -+} -+ -+/* -+** Prepare an SQL statement using the results of a printf() formatting. -+*/ -+static int idxPrintfPrepareStmt( -+ sqlite3 *db, /* Database handle to compile against */ -+ sqlite3_stmt **ppStmt, /* OUT: Compiled SQL statement */ -+ char **pzErrmsg, /* OUT: sqlite3_malloc()ed error message */ -+ const char *zFmt, /* printf() format of SQL statement */ -+ ... /* Trailing printf() arguments */ -+){ -+ va_list ap; -+ int rc; -+ char *zSql; -+ va_start(ap, zFmt); -+ zSql = sqlite3_vmprintf(zFmt, ap); -+ if( zSql==0 ){ -+ rc = SQLITE_NOMEM; -+ }else{ -+ rc = idxPrepareStmt(db, ppStmt, pzErrmsg, zSql); -+ sqlite3_free(zSql); -+ } -+ va_end(ap); -+ return rc; -+} -+ -+ -+/************************************************************************* -+** Beginning of virtual table implementation. -+*/ -+typedef struct ExpertVtab ExpertVtab; -+struct ExpertVtab { -+ sqlite3_vtab base; -+ IdxTable *pTab; -+ sqlite3expert *pExpert; -+}; -+ -+typedef struct ExpertCsr ExpertCsr; -+struct ExpertCsr { -+ sqlite3_vtab_cursor base; -+ sqlite3_stmt *pData; -+}; -+ -+static char *expertDequote(const char *zIn){ -+ int n = STRLEN(zIn); -+ char *zRet = sqlite3_malloc(n); -+ -+ assert( zIn[0]=='\'' ); -+ assert( zIn[n-1]=='\'' ); -+ -+ if( zRet ){ -+ int iOut = 0; -+ int iIn = 0; -+ for(iIn=1; iIn<(n-1); iIn++){ -+ if( zIn[iIn]=='\'' ){ -+ assert( zIn[iIn+1]=='\'' ); -+ iIn++; -+ } -+ zRet[iOut++] = zIn[iIn]; -+ } -+ zRet[iOut] = '\0'; -+ } -+ -+ return zRet; -+} -+ -+/* -+** This function is the implementation of both the xConnect and xCreate -+** methods of the r-tree virtual table. -+** -+** argv[0] -> module name -+** argv[1] -> database name -+** argv[2] -> table name -+** argv[...] -> column names... -+*/ -+static int expertConnect( -+ sqlite3 *db, -+ void *pAux, -+ int argc, const char *const*argv, -+ sqlite3_vtab **ppVtab, -+ char **pzErr -+){ -+ sqlite3expert *pExpert = (sqlite3expert*)pAux; -+ ExpertVtab *p = 0; -+ int rc; -+ -+ if( argc!=4 ){ -+ *pzErr = sqlite3_mprintf("internal error!"); -+ rc = SQLITE_ERROR; -+ }else{ -+ char *zCreateTable = expertDequote(argv[3]); -+ if( zCreateTable ){ -+ rc = sqlite3_declare_vtab(db, zCreateTable); -+ if( rc==SQLITE_OK ){ -+ p = idxMalloc(&rc, sizeof(ExpertVtab)); -+ } -+ if( rc==SQLITE_OK ){ -+ p->pExpert = pExpert; -+ p->pTab = pExpert->pTable; -+ assert( sqlite3_stricmp(p->pTab->zName, argv[2])==0 ); -+ } -+ sqlite3_free(zCreateTable); -+ }else{ -+ rc = SQLITE_NOMEM; -+ } -+ } -+ -+ *ppVtab = (sqlite3_vtab*)p; -+ return rc; -+} -+ -+static int expertDisconnect(sqlite3_vtab *pVtab){ -+ ExpertVtab *p = (ExpertVtab*)pVtab; -+ sqlite3_free(p); -+ return SQLITE_OK; -+} -+ -+static int expertBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo){ -+ ExpertVtab *p = (ExpertVtab*)pVtab; -+ int rc = SQLITE_OK; -+ int n = 0; -+ IdxScan *pScan; -+ const int opmask = -+ SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_GT | -+ SQLITE_INDEX_CONSTRAINT_LT | SQLITE_INDEX_CONSTRAINT_GE | -+ SQLITE_INDEX_CONSTRAINT_LE; -+ -+ pScan = idxMalloc(&rc, sizeof(IdxScan)); -+ if( pScan ){ -+ int i; -+ -+ /* Link the new scan object into the list */ -+ pScan->pTab = p->pTab; -+ pScan->pNextScan = p->pExpert->pScan; -+ p->pExpert->pScan = pScan; -+ -+ /* Add the constraints to the IdxScan object */ -+ for(i=0; i<pIdxInfo->nConstraint; i++){ -+ struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i]; -+ if( pCons->usable -+ && pCons->iColumn>=0 -+ && p->pTab->aCol[pCons->iColumn].iPk==0 -+ && (pCons->op & opmask) -+ ){ -+ IdxConstraint *pNew; -+ const char *zColl = sqlite3_vtab_collation(pIdxInfo, i); -+ pNew = idxNewConstraint(&rc, zColl); -+ if( pNew ){ -+ pNew->iCol = pCons->iColumn; -+ if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){ -+ pNew->pNext = pScan->pEq; -+ pScan->pEq = pNew; -+ }else{ -+ pNew->bRange = 1; -+ pNew->pNext = pScan->pRange; -+ pScan->pRange = pNew; -+ } -+ } -+ n++; -+ pIdxInfo->aConstraintUsage[i].argvIndex = n; -+ } -+ } -+ -+ /* Add the ORDER BY to the IdxScan object */ -+ for(i=pIdxInfo->nOrderBy-1; i>=0; i--){ -+ int iCol = pIdxInfo->aOrderBy[i].iColumn; -+ if( iCol>=0 ){ -+ IdxConstraint *pNew = idxNewConstraint(&rc, p->pTab->aCol[iCol].zColl); -+ if( pNew ){ -+ pNew->iCol = iCol; -+ pNew->bDesc = pIdxInfo->aOrderBy[i].desc; -+ pNew->pNext = pScan->pOrder; -+ pNew->pLink = pScan->pOrder; -+ pScan->pOrder = pNew; -+ n++; -+ } -+ } -+ } -+ } -+ -+ pIdxInfo->estimatedCost = 1000000.0 / (n+1); -+ return rc; -+} -+ -+static int expertUpdate( -+ sqlite3_vtab *pVtab, -+ int nData, -+ sqlite3_value **azData, -+ sqlite_int64 *pRowid -+){ -+ (void)pVtab; -+ (void)nData; -+ (void)azData; -+ (void)pRowid; -+ return SQLITE_OK; -+} -+ -+/* -+** Virtual table module xOpen method. -+*/ -+static int expertOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ -+ int rc = SQLITE_OK; -+ ExpertCsr *pCsr; -+ (void)pVTab; -+ pCsr = idxMalloc(&rc, sizeof(ExpertCsr)); -+ *ppCursor = (sqlite3_vtab_cursor*)pCsr; -+ return rc; -+} -+ -+/* -+** Virtual table module xClose method. -+*/ -+static int expertClose(sqlite3_vtab_cursor *cur){ -+ ExpertCsr *pCsr = (ExpertCsr*)cur; -+ sqlite3_finalize(pCsr->pData); -+ sqlite3_free(pCsr); -+ return SQLITE_OK; -+} -+ -+/* -+** Virtual table module xEof method. -+** -+** Return non-zero if the cursor does not currently point to a valid -+** record (i.e if the scan has finished), or zero otherwise. -+*/ -+static int expertEof(sqlite3_vtab_cursor *cur){ -+ ExpertCsr *pCsr = (ExpertCsr*)cur; -+ return pCsr->pData==0; -+} -+ -+/* -+** Virtual table module xNext method. -+*/ -+static int expertNext(sqlite3_vtab_cursor *cur){ -+ ExpertCsr *pCsr = (ExpertCsr*)cur; -+ int rc = SQLITE_OK; -+ -+ assert( pCsr->pData ); -+ rc = sqlite3_step(pCsr->pData); -+ if( rc!=SQLITE_ROW ){ -+ rc = sqlite3_finalize(pCsr->pData); -+ pCsr->pData = 0; -+ }else{ -+ rc = SQLITE_OK; -+ } -+ -+ return rc; -+} -+ -+/* -+** Virtual table module xRowid method. -+*/ -+static int expertRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ -+ (void)cur; -+ *pRowid = 0; -+ return SQLITE_OK; -+} -+ -+/* -+** Virtual table module xColumn method. -+*/ -+static int expertColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ -+ ExpertCsr *pCsr = (ExpertCsr*)cur; -+ sqlite3_value *pVal; -+ pVal = sqlite3_column_value(pCsr->pData, i); -+ if( pVal ){ -+ sqlite3_result_value(ctx, pVal); -+ } -+ return SQLITE_OK; -+} -+ -+/* -+** Virtual table module xFilter method. -+*/ -+static int expertFilter( -+ sqlite3_vtab_cursor *cur, -+ int idxNum, const char *idxStr, -+ int argc, sqlite3_value **argv -+){ -+ ExpertCsr *pCsr = (ExpertCsr*)cur; -+ ExpertVtab *pVtab = (ExpertVtab*)(cur->pVtab); -+ sqlite3expert *pExpert = pVtab->pExpert; -+ int rc; -+ -+ (void)idxNum; -+ (void)idxStr; -+ (void)argc; -+ (void)argv; -+ rc = sqlite3_finalize(pCsr->pData); -+ pCsr->pData = 0; -+ if( rc==SQLITE_OK ){ -+ rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg, -+ "SELECT * FROM main.%Q WHERE sample()", pVtab->pTab->zName -+ ); -+ } -+ -+ if( rc==SQLITE_OK ){ -+ rc = expertNext(cur); -+ } -+ return rc; -+} -+ -+static int idxRegisterVtab(sqlite3expert *p){ -+ static sqlite3_module expertModule = { -+ 2, /* iVersion */ -+ expertConnect, /* xCreate - create a table */ -+ expertConnect, /* xConnect - connect to an existing table */ -+ expertBestIndex, /* xBestIndex - Determine search strategy */ -+ expertDisconnect, /* xDisconnect - Disconnect from a table */ -+ expertDisconnect, /* xDestroy - Drop a table */ -+ expertOpen, /* xOpen - open a cursor */ -+ expertClose, /* xClose - close a cursor */ -+ expertFilter, /* xFilter - configure scan constraints */ -+ expertNext, /* xNext - advance a cursor */ -+ expertEof, /* xEof */ -+ expertColumn, /* xColumn - read data */ -+ expertRowid, /* xRowid - read data */ -+ expertUpdate, /* xUpdate - write data */ -+ 0, /* xBegin - begin transaction */ -+ 0, /* xSync - sync transaction */ -+ 0, /* xCommit - commit transaction */ -+ 0, /* xRollback - rollback transaction */ -+ 0, /* xFindFunction - function overloading */ -+ 0, /* xRename - rename the table */ -+ 0, /* xSavepoint */ -+ 0, /* xRelease */ -+ 0, /* xRollbackTo */ -+ 0, /* xShadowName */ -+ }; -+ -+ return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p); -+} -+/* -+** End of virtual table implementation. -+*************************************************************************/ -+/* -+** Finalize SQL statement pStmt. If (*pRc) is SQLITE_OK when this function -+** is called, set it to the return value of sqlite3_finalize() before -+** returning. Otherwise, discard the sqlite3_finalize() return value. -+*/ -+static void idxFinalize(int *pRc, sqlite3_stmt *pStmt){ -+ int rc = sqlite3_finalize(pStmt); -+ if( *pRc==SQLITE_OK ) *pRc = rc; -+} -+ -+/* -+** Attempt to allocate an IdxTable structure corresponding to table zTab -+** in the main database of connection db. If successful, set (*ppOut) to -+** point to the new object and return SQLITE_OK. Otherwise, return an -+** SQLite error code and set (*ppOut) to NULL. In this case *pzErrmsg may be -+** set to point to an error string. -+** -+** It is the responsibility of the caller to eventually free either the -+** IdxTable object or error message using sqlite3_free(). -+*/ -+static int idxGetTableInfo( -+ sqlite3 *db, /* Database connection to read details from */ -+ const char *zTab, /* Table name */ -+ IdxTable **ppOut, /* OUT: New object (if successful) */ -+ char **pzErrmsg /* OUT: Error message (if not) */ -+){ -+ sqlite3_stmt *p1 = 0; -+ int nCol = 0; -+ int nTab = STRLEN(zTab); -+ int nByte = sizeof(IdxTable) + nTab + 1; -+ IdxTable *pNew = 0; -+ int rc, rc2; -+ char *pCsr = 0; -+ -+ rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab); -+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){ -+ const char *zCol = (const char*)sqlite3_column_text(p1, 1); -+ nByte += 1 + STRLEN(zCol); -+ rc = sqlite3_table_column_metadata( -+ db, "main", zTab, zCol, 0, &zCol, 0, 0, 0 -+ ); -+ nByte += 1 + STRLEN(zCol); -+ nCol++; -+ } -+ rc2 = sqlite3_reset(p1); -+ if( rc==SQLITE_OK ) rc = rc2; -+ -+ nByte += sizeof(IdxColumn) * nCol; -+ if( rc==SQLITE_OK ){ -+ pNew = idxMalloc(&rc, nByte); -+ } -+ if( rc==SQLITE_OK ){ -+ pNew->aCol = (IdxColumn*)&pNew[1]; -+ pNew->nCol = nCol; -+ pCsr = (char*)&pNew->aCol[nCol]; -+ } -+ -+ nCol = 0; -+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){ -+ const char *zCol = (const char*)sqlite3_column_text(p1, 1); -+ int nCopy = STRLEN(zCol) + 1; -+ pNew->aCol[nCol].zName = pCsr; -+ pNew->aCol[nCol].iPk = sqlite3_column_int(p1, 5); -+ memcpy(pCsr, zCol, nCopy); -+ pCsr += nCopy; -+ -+ rc = sqlite3_table_column_metadata( -+ db, "main", zTab, zCol, 0, &zCol, 0, 0, 0 -+ ); -+ if( rc==SQLITE_OK ){ -+ nCopy = STRLEN(zCol) + 1; -+ pNew->aCol[nCol].zColl = pCsr; -+ memcpy(pCsr, zCol, nCopy); -+ pCsr += nCopy; -+ } -+ -+ nCol++; -+ } -+ idxFinalize(&rc, p1); -+ -+ if( rc!=SQLITE_OK ){ -+ sqlite3_free(pNew); -+ pNew = 0; -+ }else{ -+ pNew->zName = pCsr; -+ memcpy(pNew->zName, zTab, nTab+1); -+ } -+ -+ *ppOut = pNew; -+ return rc; -+} -+ -+/* -+** This function is a no-op if *pRc is set to anything other than -+** SQLITE_OK when it is called. -+** -+** If *pRc is initially set to SQLITE_OK, then the text specified by -+** the printf() style arguments is appended to zIn and the result returned -+** in a buffer allocated by sqlite3_malloc(). sqlite3_free() is called on -+** zIn before returning. -+*/ -+static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){ -+ va_list ap; -+ char *zAppend = 0; -+ char *zRet = 0; -+ int nIn = zIn ? STRLEN(zIn) : 0; -+ int nAppend = 0; -+ va_start(ap, zFmt); -+ if( *pRc==SQLITE_OK ){ -+ zAppend = sqlite3_vmprintf(zFmt, ap); -+ if( zAppend ){ -+ nAppend = STRLEN(zAppend); -+ zRet = (char*)sqlite3_malloc(nIn + nAppend + 1); -+ } -+ if( zAppend && zRet ){ -+ if( nIn ) memcpy(zRet, zIn, nIn); -+ memcpy(&zRet[nIn], zAppend, nAppend+1); -+ }else{ -+ sqlite3_free(zRet); -+ zRet = 0; -+ *pRc = SQLITE_NOMEM; -+ } -+ sqlite3_free(zAppend); -+ sqlite3_free(zIn); -+ } -+ va_end(ap); -+ return zRet; -+} -+ -+/* -+** Return true if zId must be quoted in order to use it as an SQL -+** identifier, or false otherwise. -+*/ -+static int idxIdentifierRequiresQuotes(const char *zId){ -+ int i; -+ for(i=0; zId[i]; i++){ -+ if( !(zId[i]=='_') -+ && !(zId[i]>='0' && zId[i]<='9') -+ && !(zId[i]>='a' && zId[i]<='z') -+ && !(zId[i]>='A' && zId[i]<='Z') -+ ){ -+ return 1; -+ } -+ } -+ return 0; -+} -+ -+/* -+** This function appends an index column definition suitable for constraint -+** pCons to the string passed as zIn and returns the result. -+*/ -+static char *idxAppendColDefn( -+ int *pRc, /* IN/OUT: Error code */ -+ char *zIn, /* Column defn accumulated so far */ -+ IdxTable *pTab, /* Table index will be created on */ -+ IdxConstraint *pCons -+){ -+ char *zRet = zIn; -+ IdxColumn *p = &pTab->aCol[pCons->iCol]; -+ if( zRet ) zRet = idxAppendText(pRc, zRet, ", "); -+ -+ if( idxIdentifierRequiresQuotes(p->zName) ){ -+ zRet = idxAppendText(pRc, zRet, "%Q", p->zName); -+ }else{ -+ zRet = idxAppendText(pRc, zRet, "%s", p->zName); -+ } -+ -+ if( sqlite3_stricmp(p->zColl, pCons->zColl) ){ -+ if( idxIdentifierRequiresQuotes(pCons->zColl) ){ -+ zRet = idxAppendText(pRc, zRet, " COLLATE %Q", pCons->zColl); -+ }else{ -+ zRet = idxAppendText(pRc, zRet, " COLLATE %s", pCons->zColl); -+ } -+ } -+ -+ if( pCons->bDesc ){ -+ zRet = idxAppendText(pRc, zRet, " DESC"); -+ } -+ return zRet; -+} -+ -+/* -+** Search database dbm for an index compatible with the one idxCreateFromCons() -+** would create from arguments pScan, pEq and pTail. If no error occurs and -+** such an index is found, return non-zero. Or, if no such index is found, -+** return zero. -+** -+** If an error occurs, set *pRc to an SQLite error code and return zero. -+*/ -+static int idxFindCompatible( -+ int *pRc, /* OUT: Error code */ -+ sqlite3* dbm, /* Database to search */ -+ IdxScan *pScan, /* Scan for table to search for index on */ -+ IdxConstraint *pEq, /* List of == constraints */ -+ IdxConstraint *pTail /* List of range constraints */ -+){ -+ const char *zTbl = pScan->pTab->zName; -+ sqlite3_stmt *pIdxList = 0; -+ IdxConstraint *pIter; -+ int nEq = 0; /* Number of elements in pEq */ -+ int rc; -+ -+ /* Count the elements in list pEq */ -+ for(pIter=pEq; pIter; pIter=pIter->pLink) nEq++; -+ -+ rc = idxPrintfPrepareStmt(dbm, &pIdxList, 0, "PRAGMA index_list=%Q", zTbl); -+ while( rc==SQLITE_OK && sqlite3_step(pIdxList)==SQLITE_ROW ){ -+ int bMatch = 1; -+ IdxConstraint *pT = pTail; -+ sqlite3_stmt *pInfo = 0; -+ const char *zIdx = (const char*)sqlite3_column_text(pIdxList, 1); -+ -+ /* Zero the IdxConstraint.bFlag values in the pEq list */ -+ for(pIter=pEq; pIter; pIter=pIter->pLink) pIter->bFlag = 0; -+ -+ rc = idxPrintfPrepareStmt(dbm, &pInfo, 0, "PRAGMA index_xInfo=%Q", zIdx); -+ while( rc==SQLITE_OK && sqlite3_step(pInfo)==SQLITE_ROW ){ -+ int iIdx = sqlite3_column_int(pInfo, 0); -+ int iCol = sqlite3_column_int(pInfo, 1); -+ const char *zColl = (const char*)sqlite3_column_text(pInfo, 4); -+ -+ if( iIdx<nEq ){ -+ for(pIter=pEq; pIter; pIter=pIter->pLink){ -+ if( pIter->bFlag ) continue; -+ if( pIter->iCol!=iCol ) continue; -+ if( sqlite3_stricmp(pIter->zColl, zColl) ) continue; -+ pIter->bFlag = 1; -+ break; -+ } -+ if( pIter==0 ){ -+ bMatch = 0; -+ break; -+ } -+ }else{ -+ if( pT ){ -+ if( pT->iCol!=iCol || sqlite3_stricmp(pT->zColl, zColl) ){ -+ bMatch = 0; -+ break; -+ } -+ pT = pT->pLink; -+ } -+ } -+ } -+ idxFinalize(&rc, pInfo); -+ -+ if( rc==SQLITE_OK && bMatch ){ -+ sqlite3_finalize(pIdxList); -+ return 1; -+ } -+ } -+ idxFinalize(&rc, pIdxList); -+ -+ *pRc = rc; -+ return 0; -+} -+ -+static int idxCreateFromCons( -+ sqlite3expert *p, -+ IdxScan *pScan, -+ IdxConstraint *pEq, -+ IdxConstraint *pTail -+){ -+ sqlite3 *dbm = p->dbm; -+ int rc = SQLITE_OK; -+ if( (pEq || pTail) && 0==idxFindCompatible(&rc, dbm, pScan, pEq, pTail) ){ -+ IdxTable *pTab = pScan->pTab; -+ char *zCols = 0; -+ char *zIdx = 0; -+ IdxConstraint *pCons; -+ unsigned int h = 0; -+ const char *zFmt; -+ -+ for(pCons=pEq; pCons; pCons=pCons->pLink){ -+ zCols = idxAppendColDefn(&rc, zCols, pTab, pCons); -+ } -+ for(pCons=pTail; pCons; pCons=pCons->pLink){ -+ zCols = idxAppendColDefn(&rc, zCols, pTab, pCons); -+ } -+ -+ if( rc==SQLITE_OK ){ -+ /* Hash the list of columns to come up with a name for the index */ -+ const char *zTable = pScan->pTab->zName; -+ char *zName; /* Index name */ -+ int i; -+ for(i=0; zCols[i]; i++){ -+ h += ((h<<3) + zCols[i]); -+ } -+ zName = sqlite3_mprintf("%s_idx_%08x", zTable, h); -+ if( zName==0 ){ -+ rc = SQLITE_NOMEM; -+ }else{ -+ if( idxIdentifierRequiresQuotes(zTable) ){ -+ zFmt = "CREATE INDEX '%q' ON %Q(%s)"; -+ }else{ -+ zFmt = "CREATE INDEX %s ON %s(%s)"; -+ } -+ zIdx = sqlite3_mprintf(zFmt, zName, zTable, zCols); -+ if( !zIdx ){ -+ rc = SQLITE_NOMEM; -+ }else{ -+ rc = sqlite3_exec(dbm, zIdx, 0, 0, p->pzErrmsg); -+ idxHashAdd(&rc, &p->hIdx, zName, zIdx); -+ } -+ sqlite3_free(zName); -+ sqlite3_free(zIdx); -+ } -+ } -+ -+ sqlite3_free(zCols); -+ } -+ return rc; -+} -+ -+/* -+** Return true if list pList (linked by IdxConstraint.pLink) contains -+** a constraint compatible with *p. Otherwise return false. -+*/ -+static int idxFindConstraint(IdxConstraint *pList, IdxConstraint *p){ -+ IdxConstraint *pCmp; -+ for(pCmp=pList; pCmp; pCmp=pCmp->pLink){ -+ if( p->iCol==pCmp->iCol ) return 1; -+ } -+ return 0; -+} -+ -+static int idxCreateFromWhere( -+ sqlite3expert *p, -+ IdxScan *pScan, /* Create indexes for this scan */ -+ IdxConstraint *pTail /* range/ORDER BY constraints for inclusion */ -+){ -+ IdxConstraint *p1 = 0; -+ IdxConstraint *pCon; -+ int rc; -+ -+ /* Gather up all the == constraints. */ -+ for(pCon=pScan->pEq; pCon; pCon=pCon->pNext){ -+ if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){ -+ pCon->pLink = p1; -+ p1 = pCon; -+ } -+ } -+ -+ /* Create an index using the == constraints collected above. And the -+ ** range constraint/ORDER BY terms passed in by the caller, if any. */ -+ rc = idxCreateFromCons(p, pScan, p1, pTail); -+ -+ /* If no range/ORDER BY passed by the caller, create a version of the -+ ** index for each range constraint. */ -+ if( pTail==0 ){ -+ for(pCon=pScan->pRange; rc==SQLITE_OK && pCon; pCon=pCon->pNext){ -+ assert( pCon->pLink==0 ); -+ if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){ -+ rc = idxCreateFromCons(p, pScan, p1, pCon); -+ } -+ } -+ } -+ -+ return rc; -+} -+ -+/* -+** Create candidate indexes in database [dbm] based on the data in -+** linked-list pScan. -+*/ -+static int idxCreateCandidates(sqlite3expert *p){ -+ int rc = SQLITE_OK; -+ IdxScan *pIter; -+ -+ for(pIter=p->pScan; pIter && rc==SQLITE_OK; pIter=pIter->pNextScan){ -+ rc = idxCreateFromWhere(p, pIter, 0); -+ if( rc==SQLITE_OK && pIter->pOrder ){ -+ rc = idxCreateFromWhere(p, pIter, pIter->pOrder); -+ } -+ } -+ -+ return rc; -+} -+ -+/* -+** Free all elements of the linked list starting at pConstraint. -+*/ -+static void idxConstraintFree(IdxConstraint *pConstraint){ -+ IdxConstraint *pNext; -+ IdxConstraint *p; -+ -+ for(p=pConstraint; p; p=pNext){ -+ pNext = p->pNext; -+ sqlite3_free(p); -+ } -+} -+ -+/* -+** Free all elements of the linked list starting from pScan up until pLast -+** (pLast is not freed). -+*/ -+static void idxScanFree(IdxScan *pScan, IdxScan *pLast){ -+ IdxScan *p; -+ IdxScan *pNext; -+ for(p=pScan; p!=pLast; p=pNext){ -+ pNext = p->pNextScan; -+ idxConstraintFree(p->pOrder); -+ idxConstraintFree(p->pEq); -+ idxConstraintFree(p->pRange); -+ sqlite3_free(p); -+ } -+} -+ -+/* -+** Free all elements of the linked list starting from pStatement up -+** until pLast (pLast is not freed). -+*/ -+static void idxStatementFree(IdxStatement *pStatement, IdxStatement *pLast){ -+ IdxStatement *p; -+ IdxStatement *pNext; -+ for(p=pStatement; p!=pLast; p=pNext){ -+ pNext = p->pNext; -+ sqlite3_free(p->zEQP); -+ sqlite3_free(p->zIdx); -+ sqlite3_free(p); -+ } -+} -+ -+/* -+** Free the linked list of IdxTable objects starting at pTab. -+*/ -+static void idxTableFree(IdxTable *pTab){ -+ IdxTable *pIter; -+ IdxTable *pNext; -+ for(pIter=pTab; pIter; pIter=pNext){ -+ pNext = pIter->pNext; -+ sqlite3_free(pIter); -+ } -+} -+ -+/* -+** Free the linked list of IdxWrite objects starting at pTab. -+*/ -+static void idxWriteFree(IdxWrite *pTab){ -+ IdxWrite *pIter; -+ IdxWrite *pNext; -+ for(pIter=pTab; pIter; pIter=pNext){ -+ pNext = pIter->pNext; -+ sqlite3_free(pIter); -+ } -+} -+ -+ -+ -+/* -+** This function is called after candidate indexes have been created. It -+** runs all the queries to see which indexes they prefer, and populates -+** IdxStatement.zIdx and IdxStatement.zEQP with the results. -+*/ -+int idxFindIndexes( -+ sqlite3expert *p, -+ char **pzErr /* OUT: Error message (sqlite3_malloc) */ -+){ -+ IdxStatement *pStmt; -+ sqlite3 *dbm = p->dbm; -+ int rc = SQLITE_OK; -+ -+ IdxHash hIdx; -+ idxHashInit(&hIdx); -+ -+ for(pStmt=p->pStatement; rc==SQLITE_OK && pStmt; pStmt=pStmt->pNext){ -+ IdxHashEntry *pEntry; -+ sqlite3_stmt *pExplain = 0; -+ idxHashClear(&hIdx); -+ rc = idxPrintfPrepareStmt(dbm, &pExplain, pzErr, -+ "EXPLAIN QUERY PLAN %s", pStmt->zSql -+ ); -+ while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){ -+ /* int iId = sqlite3_column_int(pExplain, 0); */ -+ /* int iParent = sqlite3_column_int(pExplain, 1); */ -+ /* int iNotUsed = sqlite3_column_int(pExplain, 2); */ -+ const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3); -+ int nDetail = STRLEN(zDetail); -+ int i; -+ -+ for(i=0; i<nDetail; i++){ -+ const char *zIdx = 0; -+ if( memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){ -+ zIdx = &zDetail[i+13]; -+ }else if( memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 ){ -+ zIdx = &zDetail[i+22]; -+ } -+ if( zIdx ){ -+ const char *zSql; -+ int nIdx = 0; -+ while( zIdx[nIdx]!='\0' && (zIdx[nIdx]!=' ' || zIdx[nIdx+1]!='(') ){ -+ nIdx++; -+ } -+ zSql = idxHashSearch(&p->hIdx, zIdx, nIdx); -+ if( zSql ){ -+ idxHashAdd(&rc, &hIdx, zSql, 0); -+ if( rc ) goto find_indexes_out; -+ } -+ break; -+ } -+ } -+ -+ if( zDetail[0]!='-' ){ -+ pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%s\n", zDetail); -+ } -+ } -+ -+ for(pEntry=hIdx.pFirst; pEntry; pEntry=pEntry->pNext){ -+ pStmt->zIdx = idxAppendText(&rc, pStmt->zIdx, "%s;\n", pEntry->zKey); -+ } -+ -+ idxFinalize(&rc, pExplain); -+ } -+ -+ find_indexes_out: -+ idxHashClear(&hIdx); -+ return rc; -+} -+ -+static int idxAuthCallback( -+ void *pCtx, -+ int eOp, -+ const char *z3, -+ const char *z4, -+ const char *zDb, -+ const char *zTrigger -+){ -+ int rc = SQLITE_OK; -+ (void)z4; -+ (void)zTrigger; -+ if( eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE || eOp==SQLITE_DELETE ){ -+ if( sqlite3_stricmp(zDb, "main")==0 ){ -+ sqlite3expert *p = (sqlite3expert*)pCtx; -+ IdxTable *pTab; -+ for(pTab=p->pTable; pTab; pTab=pTab->pNext){ -+ if( 0==sqlite3_stricmp(z3, pTab->zName) ) break; -+ } -+ if( pTab ){ -+ IdxWrite *pWrite; -+ for(pWrite=p->pWrite; pWrite; pWrite=pWrite->pNext){ -+ if( pWrite->pTab==pTab && pWrite->eOp==eOp ) break; -+ } -+ if( pWrite==0 ){ -+ pWrite = idxMalloc(&rc, sizeof(IdxWrite)); -+ if( rc==SQLITE_OK ){ -+ pWrite->pTab = pTab; -+ pWrite->eOp = eOp; -+ pWrite->pNext = p->pWrite; -+ p->pWrite = pWrite; -+ } -+ } -+ } -+ } -+ } -+ return rc; -+} -+ -+static int idxProcessOneTrigger( -+ sqlite3expert *p, -+ IdxWrite *pWrite, -+ char **pzErr -+){ -+ static const char *zInt = UNIQUE_TABLE_NAME; -+ static const char *zDrop = "DROP TABLE " UNIQUE_TABLE_NAME; -+ IdxTable *pTab = pWrite->pTab; -+ const char *zTab = pTab->zName; -+ const char *zSql = -+ "SELECT 'CREATE TEMP' || substr(sql, 7) FROM sqlite_master " -+ "WHERE tbl_name = %Q AND type IN ('table', 'trigger') " -+ "ORDER BY type;"; -+ sqlite3_stmt *pSelect = 0; -+ int rc = SQLITE_OK; -+ char *zWrite = 0; -+ -+ /* Create the table and its triggers in the temp schema */ -+ rc = idxPrintfPrepareStmt(p->db, &pSelect, pzErr, zSql, zTab, zTab); -+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSelect) ){ -+ const char *zCreate = (const char*)sqlite3_column_text(pSelect, 0); -+ rc = sqlite3_exec(p->dbv, zCreate, 0, 0, pzErr); -+ } -+ idxFinalize(&rc, pSelect); -+ -+ /* Rename the table in the temp schema to zInt */ -+ if( rc==SQLITE_OK ){ -+ char *z = sqlite3_mprintf("ALTER TABLE temp.%Q RENAME TO %Q", zTab, zInt); -+ if( z==0 ){ -+ rc = SQLITE_NOMEM; -+ }else{ -+ rc = sqlite3_exec(p->dbv, z, 0, 0, pzErr); -+ sqlite3_free(z); -+ } -+ } -+ -+ switch( pWrite->eOp ){ -+ case SQLITE_INSERT: { -+ int i; -+ zWrite = idxAppendText(&rc, zWrite, "INSERT INTO %Q VALUES(", zInt); -+ for(i=0; i<pTab->nCol; i++){ -+ zWrite = idxAppendText(&rc, zWrite, "%s?", i==0 ? "" : ", "); -+ } -+ zWrite = idxAppendText(&rc, zWrite, ")"); -+ break; -+ } -+ case SQLITE_UPDATE: { -+ int i; -+ zWrite = idxAppendText(&rc, zWrite, "UPDATE %Q SET ", zInt); -+ for(i=0; i<pTab->nCol; i++){ -+ zWrite = idxAppendText(&rc, zWrite, "%s%Q=?", i==0 ? "" : ", ", -+ pTab->aCol[i].zName -+ ); -+ } -+ break; -+ } -+ default: { -+ assert( pWrite->eOp==SQLITE_DELETE ); -+ if( rc==SQLITE_OK ){ -+ zWrite = sqlite3_mprintf("DELETE FROM %Q", zInt); -+ if( zWrite==0 ) rc = SQLITE_NOMEM; -+ } -+ } -+ } -+ -+ if( rc==SQLITE_OK ){ -+ sqlite3_stmt *pX = 0; -+ rc = sqlite3_prepare_v2(p->dbv, zWrite, -1, &pX, 0); -+ idxFinalize(&rc, pX); -+ if( rc!=SQLITE_OK ){ -+ idxDatabaseError(p->dbv, pzErr); -+ } -+ } -+ sqlite3_free(zWrite); -+ -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3_exec(p->dbv, zDrop, 0, 0, pzErr); -+ } -+ -+ return rc; -+} -+ -+static int idxProcessTriggers(sqlite3expert *p, char **pzErr){ -+ int rc = SQLITE_OK; -+ IdxWrite *pEnd = 0; -+ IdxWrite *pFirst = p->pWrite; -+ -+ while( rc==SQLITE_OK && pFirst!=pEnd ){ -+ IdxWrite *pIter; -+ for(pIter=pFirst; rc==SQLITE_OK && pIter!=pEnd; pIter=pIter->pNext){ -+ rc = idxProcessOneTrigger(p, pIter, pzErr); -+ } -+ pEnd = pFirst; -+ pFirst = p->pWrite; -+ } -+ -+ return rc; -+} -+ -+ -+static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){ -+ int rc = idxRegisterVtab(p); -+ sqlite3_stmt *pSchema = 0; -+ -+ /* For each table in the main db schema: -+ ** -+ ** 1) Add an entry to the p->pTable list, and -+ ** 2) Create the equivalent virtual table in dbv. -+ */ -+ rc = idxPrepareStmt(p->db, &pSchema, pzErrmsg, -+ "SELECT type, name, sql, 1 FROM sqlite_master " -+ "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%%' " -+ " UNION ALL " -+ "SELECT type, name, sql, 2 FROM sqlite_master " -+ "WHERE type = 'trigger'" -+ " AND tbl_name IN(SELECT name FROM sqlite_master WHERE type = 'view') " -+ "ORDER BY 4, 1" -+ ); -+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSchema) ){ -+ const char *zType = (const char*)sqlite3_column_text(pSchema, 0); -+ const char *zName = (const char*)sqlite3_column_text(pSchema, 1); -+ const char *zSql = (const char*)sqlite3_column_text(pSchema, 2); -+ -+ if( zType[0]=='v' || zType[1]=='r' ){ -+ rc = sqlite3_exec(p->dbv, zSql, 0, 0, pzErrmsg); -+ }else{ -+ IdxTable *pTab; -+ rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg); -+ if( rc==SQLITE_OK ){ -+ int i; -+ char *zInner = 0; -+ char *zOuter = 0; -+ pTab->pNext = p->pTable; -+ p->pTable = pTab; -+ -+ /* The statement the vtab will pass to sqlite3_declare_vtab() */ -+ zInner = idxAppendText(&rc, 0, "CREATE TABLE x("); -+ for(i=0; i<pTab->nCol; i++){ -+ zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %s", -+ (i==0 ? "" : ", "), pTab->aCol[i].zName, pTab->aCol[i].zColl -+ ); -+ } -+ zInner = idxAppendText(&rc, zInner, ")"); -+ -+ /* The CVT statement to create the vtab */ -+ zOuter = idxAppendText(&rc, 0, -+ "CREATE VIRTUAL TABLE %Q USING expert(%Q)", zName, zInner -+ ); -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3_exec(p->dbv, zOuter, 0, 0, pzErrmsg); -+ } -+ sqlite3_free(zInner); -+ sqlite3_free(zOuter); -+ } -+ } -+ } -+ idxFinalize(&rc, pSchema); -+ return rc; -+} -+ -+struct IdxSampleCtx { -+ int iTarget; -+ double target; /* Target nRet/nRow value */ -+ double nRow; /* Number of rows seen */ -+ double nRet; /* Number of rows returned */ -+}; -+ -+static void idxSampleFunc( -+ sqlite3_context *pCtx, -+ int argc, -+ sqlite3_value **argv -+){ -+ struct IdxSampleCtx *p = (struct IdxSampleCtx*)sqlite3_user_data(pCtx); -+ int bRet; -+ -+ (void)argv; -+ assert( argc==0 ); -+ if( p->nRow==0.0 ){ -+ bRet = 1; -+ }else{ -+ bRet = (p->nRet / p->nRow) <= p->target; -+ if( bRet==0 ){ -+ unsigned short rnd; -+ sqlite3_randomness(2, (void*)&rnd); -+ bRet = ((int)rnd % 100) <= p->iTarget; -+ } -+ } -+ -+ sqlite3_result_int(pCtx, bRet); -+ p->nRow += 1.0; -+ p->nRet += (double)bRet; -+} -+ -+struct IdxRemCtx { -+ int nSlot; -+ struct IdxRemSlot { -+ int eType; /* SQLITE_NULL, INTEGER, REAL, TEXT, BLOB */ -+ i64 iVal; /* SQLITE_INTEGER value */ -+ double rVal; /* SQLITE_FLOAT value */ -+ int nByte; /* Bytes of space allocated at z */ -+ int n; /* Size of buffer z */ -+ char *z; /* SQLITE_TEXT/BLOB value */ -+ } aSlot[1]; -+}; -+ -+/* -+** Implementation of scalar function rem(). -+*/ -+static void idxRemFunc( -+ sqlite3_context *pCtx, -+ int argc, -+ sqlite3_value **argv -+){ -+ struct IdxRemCtx *p = (struct IdxRemCtx*)sqlite3_user_data(pCtx); -+ struct IdxRemSlot *pSlot; -+ int iSlot; -+ assert( argc==2 ); -+ -+ iSlot = sqlite3_value_int(argv[0]); -+ assert( iSlot<=p->nSlot ); -+ pSlot = &p->aSlot[iSlot]; -+ -+ switch( pSlot->eType ){ -+ case SQLITE_NULL: -+ /* no-op */ -+ break; -+ -+ case SQLITE_INTEGER: -+ sqlite3_result_int64(pCtx, pSlot->iVal); -+ break; -+ -+ case SQLITE_FLOAT: -+ sqlite3_result_double(pCtx, pSlot->rVal); -+ break; -+ -+ case SQLITE_BLOB: -+ sqlite3_result_blob(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT); -+ break; -+ -+ case SQLITE_TEXT: -+ sqlite3_result_text(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT); -+ break; -+ } -+ -+ pSlot->eType = sqlite3_value_type(argv[1]); -+ switch( pSlot->eType ){ -+ case SQLITE_NULL: -+ /* no-op */ -+ break; -+ -+ case SQLITE_INTEGER: -+ pSlot->iVal = sqlite3_value_int64(argv[1]); -+ break; -+ -+ case SQLITE_FLOAT: -+ pSlot->rVal = sqlite3_value_double(argv[1]); -+ break; -+ -+ case SQLITE_BLOB: -+ case SQLITE_TEXT: { -+ int nByte = sqlite3_value_bytes(argv[1]); -+ if( nByte>pSlot->nByte ){ -+ char *zNew = (char*)sqlite3_realloc(pSlot->z, nByte*2); -+ if( zNew==0 ){ -+ sqlite3_result_error_nomem(pCtx); -+ return; -+ } -+ pSlot->nByte = nByte*2; -+ pSlot->z = zNew; -+ } -+ pSlot->n = nByte; -+ if( pSlot->eType==SQLITE_BLOB ){ -+ memcpy(pSlot->z, sqlite3_value_blob(argv[1]), nByte); -+ }else{ -+ memcpy(pSlot->z, sqlite3_value_text(argv[1]), nByte); -+ } -+ break; -+ } -+ } -+} -+ -+static int idxLargestIndex(sqlite3 *db, int *pnMax, char **pzErr){ -+ int rc = SQLITE_OK; -+ const char *zMax = -+ "SELECT max(i.seqno) FROM " -+ " sqlite_master AS s, " -+ " pragma_index_list(s.name) AS l, " -+ " pragma_index_info(l.name) AS i " -+ "WHERE s.type = 'table'"; -+ sqlite3_stmt *pMax = 0; -+ -+ *pnMax = 0; -+ rc = idxPrepareStmt(db, &pMax, pzErr, zMax); -+ if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){ -+ *pnMax = sqlite3_column_int(pMax, 0) + 1; -+ } -+ idxFinalize(&rc, pMax); -+ -+ return rc; -+} -+ -+static int idxPopulateOneStat1( -+ sqlite3expert *p, -+ sqlite3_stmt *pIndexXInfo, -+ sqlite3_stmt *pWriteStat, -+ const char *zTab, -+ const char *zIdx, -+ char **pzErr -+){ -+ char *zCols = 0; -+ char *zOrder = 0; -+ char *zQuery = 0; -+ int nCol = 0; -+ int i; -+ sqlite3_stmt *pQuery = 0; -+ int *aStat = 0; -+ int rc = SQLITE_OK; -+ -+ assert( p->iSample>0 ); -+ -+ /* Formulate the query text */ -+ sqlite3_bind_text(pIndexXInfo, 1, zIdx, -1, SQLITE_STATIC); -+ while( SQLITE_OK==rc && SQLITE_ROW==sqlite3_step(pIndexXInfo) ){ -+ const char *zComma = zCols==0 ? "" : ", "; -+ const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0); -+ const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1); -+ zCols = idxAppendText(&rc, zCols, -+ "%sx.%Q IS rem(%d, x.%Q) COLLATE %s", zComma, zName, nCol, zName, zColl -+ ); -+ zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol); -+ } -+ sqlite3_reset(pIndexXInfo); -+ if( rc==SQLITE_OK ){ -+ if( p->iSample==100 ){ -+ zQuery = sqlite3_mprintf( -+ "SELECT %s FROM %Q x ORDER BY %s", zCols, zTab, zOrder -+ ); -+ }else{ -+ zQuery = sqlite3_mprintf( -+ "SELECT %s FROM temp."UNIQUE_TABLE_NAME" x ORDER BY %s", zCols, zOrder -+ ); -+ } -+ } -+ sqlite3_free(zCols); -+ sqlite3_free(zOrder); -+ -+ /* Formulate the query text */ -+ if( rc==SQLITE_OK ){ -+ sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv); -+ rc = idxPrepareStmt(dbrem, &pQuery, pzErr, zQuery); -+ } -+ sqlite3_free(zQuery); -+ -+ if( rc==SQLITE_OK ){ -+ aStat = (int*)idxMalloc(&rc, sizeof(int)*(nCol+1)); -+ } -+ if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){ -+ IdxHashEntry *pEntry; -+ char *zStat = 0; -+ for(i=0; i<=nCol; i++) aStat[i] = 1; -+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){ -+ aStat[0]++; -+ for(i=0; i<nCol; i++){ -+ if( sqlite3_column_int(pQuery, i)==0 ) break; -+ } -+ for(/*no-op*/; i<nCol; i++){ -+ aStat[i+1]++; -+ } -+ } -+ -+ if( rc==SQLITE_OK ){ -+ int s0 = aStat[0]; -+ zStat = sqlite3_mprintf("%d", s0); -+ if( zStat==0 ) rc = SQLITE_NOMEM; -+ for(i=1; rc==SQLITE_OK && i<=nCol; i++){ -+ zStat = idxAppendText(&rc, zStat, " %d", (s0+aStat[i]/2) / aStat[i]); -+ } -+ } -+ -+ if( rc==SQLITE_OK ){ -+ sqlite3_bind_text(pWriteStat, 1, zTab, -1, SQLITE_STATIC); -+ sqlite3_bind_text(pWriteStat, 2, zIdx, -1, SQLITE_STATIC); -+ sqlite3_bind_text(pWriteStat, 3, zStat, -1, SQLITE_STATIC); -+ sqlite3_step(pWriteStat); -+ rc = sqlite3_reset(pWriteStat); -+ } -+ -+ pEntry = idxHashFind(&p->hIdx, zIdx, STRLEN(zIdx)); -+ if( pEntry ){ -+ assert( pEntry->zVal2==0 ); -+ pEntry->zVal2 = zStat; -+ }else{ -+ sqlite3_free(zStat); -+ } -+ } -+ sqlite3_free(aStat); -+ idxFinalize(&rc, pQuery); -+ -+ return rc; -+} -+ -+static int idxBuildSampleTable(sqlite3expert *p, const char *zTab){ -+ int rc; -+ char *zSql; -+ -+ rc = sqlite3_exec(p->dbv,"DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0); -+ if( rc!=SQLITE_OK ) return rc; -+ -+ zSql = sqlite3_mprintf( -+ "CREATE TABLE temp." UNIQUE_TABLE_NAME " AS SELECT * FROM %Q", zTab -+ ); -+ if( zSql==0 ) return SQLITE_NOMEM; -+ rc = sqlite3_exec(p->dbv, zSql, 0, 0, 0); -+ sqlite3_free(zSql); -+ -+ return rc; -+} -+ -+/* -+** This function is called as part of sqlite3_expert_analyze(). Candidate -+** indexes have already been created in database sqlite3expert.dbm, this -+** function populates sqlite_stat1 table in the same database. -+** -+** The stat1 data is generated by querying the -+*/ -+static int idxPopulateStat1(sqlite3expert *p, char **pzErr){ -+ int rc = SQLITE_OK; -+ int nMax =0; -+ struct IdxRemCtx *pCtx = 0; -+ struct IdxSampleCtx samplectx; -+ int i; -+ i64 iPrev = -100000; -+ sqlite3_stmt *pAllIndex = 0; -+ sqlite3_stmt *pIndexXInfo = 0; -+ sqlite3_stmt *pWrite = 0; -+ -+ const char *zAllIndex = -+ "SELECT s.rowid, s.name, l.name FROM " -+ " sqlite_master AS s, " -+ " pragma_index_list(s.name) AS l " -+ "WHERE s.type = 'table'"; -+ const char *zIndexXInfo = -+ "SELECT name, coll FROM pragma_index_xinfo(?) WHERE key"; -+ const char *zWrite = "INSERT INTO sqlite_stat1 VALUES(?, ?, ?)"; -+ -+ /* If iSample==0, no sqlite_stat1 data is required. */ -+ if( p->iSample==0 ) return SQLITE_OK; -+ -+ rc = idxLargestIndex(p->dbm, &nMax, pzErr); -+ if( nMax<=0 || rc!=SQLITE_OK ) return rc; -+ -+ rc = sqlite3_exec(p->dbm, "ANALYZE; PRAGMA writable_schema=1", 0, 0, 0); -+ -+ if( rc==SQLITE_OK ){ -+ int nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax); -+ pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte); -+ } -+ -+ if( rc==SQLITE_OK ){ -+ sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv); -+ rc = sqlite3_create_function( -+ dbrem, "rem", 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0 -+ ); -+ } -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3_create_function( -+ p->db, "sample", 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0 -+ ); -+ } -+ -+ if( rc==SQLITE_OK ){ -+ pCtx->nSlot = nMax+1; -+ rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex); -+ } -+ if( rc==SQLITE_OK ){ -+ rc = idxPrepareStmt(p->dbm, &pIndexXInfo, pzErr, zIndexXInfo); -+ } -+ if( rc==SQLITE_OK ){ -+ rc = idxPrepareStmt(p->dbm, &pWrite, pzErr, zWrite); -+ } -+ -+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pAllIndex) ){ -+ i64 iRowid = sqlite3_column_int64(pAllIndex, 0); -+ const char *zTab = (const char*)sqlite3_column_text(pAllIndex, 1); -+ const char *zIdx = (const char*)sqlite3_column_text(pAllIndex, 2); -+ if( p->iSample<100 && iPrev!=iRowid ){ -+ samplectx.target = (double)p->iSample / 100.0; -+ samplectx.iTarget = p->iSample; -+ samplectx.nRow = 0.0; -+ samplectx.nRet = 0.0; -+ rc = idxBuildSampleTable(p, zTab); -+ if( rc!=SQLITE_OK ) break; -+ } -+ rc = idxPopulateOneStat1(p, pIndexXInfo, pWrite, zTab, zIdx, pzErr); -+ iPrev = iRowid; -+ } -+ if( rc==SQLITE_OK && p->iSample<100 ){ -+ rc = sqlite3_exec(p->dbv, -+ "DROP TABLE IF EXISTS temp." UNIQUE_TABLE_NAME, 0,0,0 -+ ); -+ } -+ -+ idxFinalize(&rc, pAllIndex); -+ idxFinalize(&rc, pIndexXInfo); -+ idxFinalize(&rc, pWrite); -+ -+ for(i=0; i<pCtx->nSlot; i++){ -+ sqlite3_free(pCtx->aSlot[i].z); -+ } -+ sqlite3_free(pCtx); -+ -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_master", 0, 0, 0); -+ } -+ -+ sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0); -+ return rc; -+} -+ -+/* -+** Allocate a new sqlite3expert object. -+*/ -+sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){ -+ int rc = SQLITE_OK; -+ sqlite3expert *pNew; -+ -+ pNew = (sqlite3expert*)idxMalloc(&rc, sizeof(sqlite3expert)); -+ -+ /* Open two in-memory databases to work with. The "vtab database" (dbv) -+ ** will contain a virtual table corresponding to each real table in -+ ** the user database schema, and a copy of each view. It is used to -+ ** collect information regarding the WHERE, ORDER BY and other clauses -+ ** of the user's query. -+ */ -+ if( rc==SQLITE_OK ){ -+ pNew->db = db; -+ pNew->iSample = 100; -+ rc = sqlite3_open(":memory:", &pNew->dbv); -+ } -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3_open(":memory:", &pNew->dbm); -+ if( rc==SQLITE_OK ){ -+ sqlite3_db_config(pNew->dbm, SQLITE_DBCONFIG_TRIGGER_EQP, 1, (int*)0); -+ } -+ } -+ -+ -+ /* Copy the entire schema of database [db] into [dbm]. */ -+ if( rc==SQLITE_OK ){ -+ sqlite3_stmt *pSql; -+ rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg, -+ "SELECT sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%%'" -+ " AND sql NOT LIKE 'CREATE VIRTUAL %%'" -+ ); -+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ -+ const char *zSql = (const char*)sqlite3_column_text(pSql, 0); -+ rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg); -+ } -+ idxFinalize(&rc, pSql); -+ } -+ -+ /* Create the vtab schema */ -+ if( rc==SQLITE_OK ){ -+ rc = idxCreateVtabSchema(pNew, pzErrmsg); -+ } -+ -+ /* Register the auth callback with dbv */ -+ if( rc==SQLITE_OK ){ -+ sqlite3_set_authorizer(pNew->dbv, idxAuthCallback, (void*)pNew); -+ } -+ -+ /* If an error has occurred, free the new object and reutrn NULL. Otherwise, -+ ** return the new sqlite3expert handle. */ -+ if( rc!=SQLITE_OK ){ -+ sqlite3_expert_destroy(pNew); -+ pNew = 0; -+ } -+ return pNew; -+} -+ -+/* -+** Configure an sqlite3expert object. -+*/ -+int sqlite3_expert_config(sqlite3expert *p, int op, ...){ -+ int rc = SQLITE_OK; -+ va_list ap; -+ va_start(ap, op); -+ switch( op ){ -+ case EXPERT_CONFIG_SAMPLE: { -+ int iVal = va_arg(ap, int); -+ if( iVal<0 ) iVal = 0; -+ if( iVal>100 ) iVal = 100; -+ p->iSample = iVal; -+ break; -+ } -+ default: -+ rc = SQLITE_NOTFOUND; -+ break; -+ } -+ -+ va_end(ap); -+ return rc; -+} -+ -+/* -+** Add an SQL statement to the analysis. -+*/ -+int sqlite3_expert_sql( -+ sqlite3expert *p, /* From sqlite3_expert_new() */ -+ const char *zSql, /* SQL statement to add */ -+ char **pzErr /* OUT: Error message (if any) */ -+){ -+ IdxScan *pScanOrig = p->pScan; -+ IdxStatement *pStmtOrig = p->pStatement; -+ int rc = SQLITE_OK; -+ const char *zStmt = zSql; -+ -+ if( p->bRun ) return SQLITE_MISUSE; -+ -+ while( rc==SQLITE_OK && zStmt && zStmt[0] ){ -+ sqlite3_stmt *pStmt = 0; -+ rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt); -+ if( rc==SQLITE_OK ){ -+ if( pStmt ){ -+ IdxStatement *pNew; -+ const char *z = sqlite3_sql(pStmt); -+ int n = STRLEN(z); -+ pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1); -+ if( rc==SQLITE_OK ){ -+ pNew->zSql = (char*)&pNew[1]; -+ memcpy(pNew->zSql, z, n+1); -+ pNew->pNext = p->pStatement; -+ if( p->pStatement ) pNew->iId = p->pStatement->iId+1; -+ p->pStatement = pNew; -+ } -+ sqlite3_finalize(pStmt); -+ } -+ }else{ -+ idxDatabaseError(p->dbv, pzErr); -+ } -+ } -+ -+ if( rc!=SQLITE_OK ){ -+ idxScanFree(p->pScan, pScanOrig); -+ idxStatementFree(p->pStatement, pStmtOrig); -+ p->pScan = pScanOrig; -+ p->pStatement = pStmtOrig; -+ } -+ -+ return rc; -+} -+ -+int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr){ -+ int rc; -+ IdxHashEntry *pEntry; -+ -+ /* Do trigger processing to collect any extra IdxScan structures */ -+ rc = idxProcessTriggers(p, pzErr); -+ -+ /* Create candidate indexes within the in-memory database file */ -+ if( rc==SQLITE_OK ){ -+ rc = idxCreateCandidates(p); -+ } -+ -+ /* Generate the stat1 data */ -+ if( rc==SQLITE_OK ){ -+ rc = idxPopulateStat1(p, pzErr); -+ } -+ -+ /* Formulate the EXPERT_REPORT_CANDIDATES text */ -+ for(pEntry=p->hIdx.pFirst; pEntry; pEntry=pEntry->pNext){ -+ p->zCandidates = idxAppendText(&rc, p->zCandidates, -+ "%s;%s%s\n", pEntry->zVal, -+ pEntry->zVal2 ? " -- stat1: " : "", pEntry->zVal2 -+ ); -+ } -+ -+ /* Figure out which of the candidate indexes are preferred by the query -+ ** planner and report the results to the user. */ -+ if( rc==SQLITE_OK ){ -+ rc = idxFindIndexes(p, pzErr); -+ } -+ -+ if( rc==SQLITE_OK ){ -+ p->bRun = 1; -+ } -+ return rc; -+} -+ -+/* -+** Return the total number of statements that have been added to this -+** sqlite3expert using sqlite3_expert_sql(). -+*/ -+int sqlite3_expert_count(sqlite3expert *p){ -+ int nRet = 0; -+ if( p->pStatement ) nRet = p->pStatement->iId+1; -+ return nRet; -+} -+ -+/* -+** Return a component of the report. -+*/ -+const char *sqlite3_expert_report(sqlite3expert *p, int iStmt, int eReport){ -+ const char *zRet = 0; -+ IdxStatement *pStmt; -+ -+ if( p->bRun==0 ) return 0; -+ for(pStmt=p->pStatement; pStmt && pStmt->iId!=iStmt; pStmt=pStmt->pNext); -+ switch( eReport ){ -+ case EXPERT_REPORT_SQL: -+ if( pStmt ) zRet = pStmt->zSql; -+ break; -+ case EXPERT_REPORT_INDEXES: -+ if( pStmt ) zRet = pStmt->zIdx; -+ break; -+ case EXPERT_REPORT_PLAN: -+ if( pStmt ) zRet = pStmt->zEQP; -+ break; -+ case EXPERT_REPORT_CANDIDATES: -+ zRet = p->zCandidates; -+ break; -+ } -+ return zRet; -+} -+ -+/* -+** Free an sqlite3expert object. -+*/ -+void sqlite3_expert_destroy(sqlite3expert *p){ -+ if( p ){ -+ sqlite3_close(p->dbm); -+ sqlite3_close(p->dbv); -+ idxScanFree(p->pScan, 0); -+ idxStatementFree(p->pStatement, 0); -+ idxTableFree(p->pTable); -+ idxWriteFree(p->pWrite); -+ idxHashClear(&p->hIdx); -+ sqlite3_free(p->zCandidates); -+ sqlite3_free(p); -+ } -+} -+ -+#endif /* ifndef SQLITE_OMIT_VIRTUAL_TABLE */ -+ -+/************************* End ../ext/expert/sqlite3expert.c ********************/ -+ - #if defined(SQLITE_ENABLE_SESSION) - /* - ** State information for a single open session -@@ -2182,6 +8517,29 @@ - int colWidth[100]; /* Column widths prior to ".explain on" */ - }; - -+typedef struct ExpertInfo ExpertInfo; -+struct ExpertInfo { -+ sqlite3expert *pExpert; -+ int bVerbose; -+}; -+ -+/* A single line in the EQP output */ -+typedef struct EQPGraphRow EQPGraphRow; -+struct EQPGraphRow { -+ int iEqpId; /* ID for this row */ -+ int iParentId; /* ID of the parent row */ -+ EQPGraphRow *pNext; /* Next row in sequence */ -+ char zText[1]; /* Text to display for this row */ -+}; -+ -+/* All EQP output is collected into an instance of the following */ -+typedef struct EQPGraph EQPGraph; -+struct EQPGraph { -+ EQPGraphRow *pRow; /* Linked list of all rows of the EQP output */ -+ EQPGraphRow *pLast; /* Last element of the pRow list */ -+ char zPrefix[100]; /* Graph prefix */ -+}; -+ - /* - ** State information about the database connection is contained in an - ** instance of the following structure. -@@ -2189,10 +8547,15 @@ - typedef struct ShellState ShellState; - struct ShellState { - sqlite3 *db; /* The database */ -- int autoExplain; /* Automatically turn on .explain mode */ -- int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ -- int statsOn; /* True to display memory stats before each finalize */ -- int scanstatsOn; /* True to display scan stats before each finalize */ -+ u8 autoExplain; /* Automatically turn on .explain mode */ -+ u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ -+ u8 autoEQPtest; /* autoEQP is in test mode */ -+ u8 statsOn; /* True to display memory stats before each finalize */ -+ u8 scanstatsOn; /* True to display scan stats before each finalize */ -+ u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */ -+ u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */ -+ u8 nEqpLevel; /* Depth of the EQP output graph */ -+ unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */ - int outCount; /* Revert to stdout when reaching zero */ - int cnt; /* Number of records displayed so far */ - FILE *out; /* Write results here */ -@@ -2199,6 +8562,7 @@ - FILE *traceOut; /* Output for sqlite3_trace() */ - int nErr; /* Number of errors seen */ - int mode; /* An output mode setting */ -+ int modePrior; /* Saved mode */ - int cMode; /* temporary output mode for the current query */ - int normalMode; /* Output mode before ".explain on" */ - int writableSchema; /* True if PRAGMA writable_schema=ON */ -@@ -2206,9 +8570,12 @@ - int nCheck; /* Number of ".check" commands run */ - unsigned shellFlgs; /* Various flags */ - char *zDestTable; /* Name of destination table when MODE_Insert */ -+ char *zTempFile; /* Temporary file that might need deleting */ - char zTestcase[30]; /* Name of current test case */ - char colSeparator[20]; /* Column separator character for several modes */ - char rowSeparator[20]; /* Row separator character for MODE_Ascii */ -+ char colSepPrior[20]; /* Saved column separator */ -+ char rowSepPrior[20]; /* Saved row separator */ - int colWidth[100]; /* Requested width of each column when in column mode*/ - int actualWidth[100]; /* Actual width of each column */ - char nullValue[20]; /* The text to print when a NULL comes back from -@@ -2222,23 +8589,41 @@ - int *aiIndent; /* Array of indents used in MODE_Explain */ - int nIndent; /* Size of array aiIndent[] */ - int iIndent; /* Index of current op in aiIndent[] */ -+ EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */ - #if defined(SQLITE_ENABLE_SESSION) - int nSession; /* Number of active sessions */ - OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */ - #endif -+ ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */ - }; - -+ -+/* Allowed values for ShellState.autoEQP -+*/ -+#define AUTOEQP_off 0 /* Automatic EXPLAIN QUERY PLAN is off */ -+#define AUTOEQP_on 1 /* Automatic EQP is on */ -+#define AUTOEQP_trigger 2 /* On and also show plans for triggers */ -+#define AUTOEQP_full 3 /* Show full EXPLAIN */ -+ -+/* Allowed values for ShellState.openMode -+*/ -+#define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */ -+#define SHELL_OPEN_NORMAL 1 /* Normal database file */ -+#define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */ -+#define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */ -+#define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */ -+#define SHELL_OPEN_DESERIALIZE 5 /* Open using sqlite3_deserialize() */ -+ - /* - ** These are the allowed shellFlgs values - */ --#define SHFLG_Scratch 0x00000001 /* The --scratch option is used */ --#define SHFLG_Pagecache 0x00000002 /* The --pagecache option is used */ --#define SHFLG_Lookaside 0x00000004 /* Lookaside memory is used */ --#define SHFLG_Backslash 0x00000008 /* The --backslash option is used */ --#define SHFLG_PreserveRowid 0x00000010 /* .dump preserves rowid values */ --#define SHFLG_Newlines 0x00000020 /* .dump --newline flag */ --#define SHFLG_CountChanges 0x00000040 /* .changes setting */ --#define SHFLG_Echo 0x00000080 /* .echo or --echo setting */ -+#define SHFLG_Pagecache 0x00000001 /* The --pagecache option is used */ -+#define SHFLG_Lookaside 0x00000002 /* Lookaside memory is used */ -+#define SHFLG_Backslash 0x00000004 /* The --backslash option is used */ -+#define SHFLG_PreserveRowid 0x00000008 /* .dump preserves rowid values */ -+#define SHFLG_Newlines 0x00000010 /* .dump --newline flag */ -+#define SHFLG_CountChanges 0x00000020 /* .changes setting */ -+#define SHFLG_Echo 0x00000040 /* .echo or --echo setting */ - - /* - ** Macros for testing and setting shellFlgs -@@ -2262,6 +8647,7 @@ - #define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */ - #define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */ - #define MODE_Pretty 11 /* Pretty-print schemas */ -+#define MODE_EQP 12 /* Converts EXPLAIN QUERY PLAN output into a graph */ - - static const char *modeDescr[] = { - "line", -@@ -2276,6 +8662,7 @@ - "explain", - "ascii", - "prettyprint", -+ "eqp" - }; - - /* -@@ -2292,11 +8679,6 @@ - #define SEP_Record "\x1E" - - /* --** Number of elements in an array --*/ --#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) -- --/* - ** A callback for the sqlite3_log() interface. - */ - static void shellLog(void *pArg, int iErrCode, const char *zMsg){ -@@ -2307,6 +8689,181 @@ - } - - /* -+** SQL function: shell_putsnl(X) -+** -+** Write the text X to the screen (or whatever output is being directed) -+** adding a newline at the end, and then return X. -+*/ -+static void shellPutsFunc( -+ sqlite3_context *pCtx, -+ int nVal, -+ sqlite3_value **apVal -+){ -+ ShellState *p = (ShellState*)sqlite3_user_data(pCtx); -+ (void)nVal; -+ utf8_printf(p->out, "%s\n", sqlite3_value_text(apVal[0])); -+ sqlite3_result_value(pCtx, apVal[0]); -+} -+ -+/* -+** SQL function: edit(VALUE) -+** edit(VALUE,EDITOR) -+** -+** These steps: -+** -+** (1) Write VALUE into a temporary file. -+** (2) Run program EDITOR on that temporary file. -+** (3) Read the temporary file back and return its content as the result. -+** (4) Delete the temporary file -+** -+** If the EDITOR argument is omitted, use the value in the VISUAL -+** environment variable. If still there is no EDITOR, through an error. -+** -+** Also throw an error if the EDITOR program returns a non-zero exit code. -+*/ -+#ifndef SQLITE_NOHAVE_SYSTEM -+static void editFunc( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ const char *zEditor; -+ char *zTempFile = 0; -+ sqlite3 *db; -+ char *zCmd = 0; -+ int bBin; -+ int rc; -+ int hasCRNL = 0; -+ FILE *f = 0; -+ sqlite3_int64 sz; -+ sqlite3_int64 x; -+ unsigned char *p = 0; -+ -+ if( argc==2 ){ -+ zEditor = (const char*)sqlite3_value_text(argv[1]); -+ }else{ -+ zEditor = getenv("VISUAL"); -+ } -+ if( zEditor==0 ){ -+ sqlite3_result_error(context, "no editor for edit()", -1); -+ return; -+ } -+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ -+ sqlite3_result_error(context, "NULL input to edit()", -1); -+ return; -+ } -+ db = sqlite3_context_db_handle(context); -+ zTempFile = 0; -+ sqlite3_file_control(db, 0, SQLITE_FCNTL_TEMPFILENAME, &zTempFile); -+ if( zTempFile==0 ){ -+ sqlite3_uint64 r = 0; -+ sqlite3_randomness(sizeof(r), &r); -+ zTempFile = sqlite3_mprintf("temp%llx", r); -+ if( zTempFile==0 ){ -+ sqlite3_result_error_nomem(context); -+ return; -+ } -+ } -+ bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB; -+ /* When writing the file to be edited, do \n to \r\n conversions on systems -+ ** that want \r\n line endings */ -+ f = fopen(zTempFile, bBin ? "wb" : "w"); -+ if( f==0 ){ -+ sqlite3_result_error(context, "edit() cannot open temp file", -1); -+ goto edit_func_end; -+ } -+ sz = sqlite3_value_bytes(argv[0]); -+ if( bBin ){ -+ x = fwrite(sqlite3_value_blob(argv[0]), 1, sz, f); -+ }else{ -+ const char *z = (const char*)sqlite3_value_text(argv[0]); -+ /* Remember whether or not the value originally contained \r\n */ -+ if( z && strstr(z,"\r\n")!=0 ) hasCRNL = 1; -+ x = fwrite(sqlite3_value_text(argv[0]), 1, sz, f); -+ } -+ fclose(f); -+ f = 0; -+ if( x!=sz ){ -+ sqlite3_result_error(context, "edit() could not write the whole file", -1); -+ goto edit_func_end; -+ } -+ zCmd = sqlite3_mprintf("%s \"%s\"", zEditor, zTempFile); -+ if( zCmd==0 ){ -+ sqlite3_result_error_nomem(context); -+ goto edit_func_end; -+ } -+ rc = system(zCmd); -+ sqlite3_free(zCmd); -+ if( rc ){ -+ sqlite3_result_error(context, "EDITOR returned non-zero", -1); -+ goto edit_func_end; -+ } -+ f = fopen(zTempFile, "rb"); -+ if( f==0 ){ -+ sqlite3_result_error(context, -+ "edit() cannot reopen temp file after edit", -1); -+ goto edit_func_end; -+ } -+ fseek(f, 0, SEEK_END); -+ sz = ftell(f); -+ rewind(f); -+ p = sqlite3_malloc64( sz+(bBin==0) ); -+ if( p==0 ){ -+ sqlite3_result_error_nomem(context); -+ goto edit_func_end; -+ } -+ x = fread(p, 1, sz, f); -+ fclose(f); -+ f = 0; -+ if( x!=sz ){ -+ sqlite3_result_error(context, "could not read back the whole file", -1); -+ goto edit_func_end; -+ } -+ if( bBin ){ -+ sqlite3_result_blob64(context, p, sz, sqlite3_free); -+ }else{ -+ sqlite3_int64 i, j; -+ if( hasCRNL ){ -+ /* If the original contains \r\n then do no conversions back to \n */ -+ j = sz; -+ }else{ -+ /* If the file did not originally contain \r\n then convert any new -+ ** \r\n back into \n */ -+ for(i=j=0; i<sz; i++){ -+ if( p[i]=='\r' && p[i+1]=='\n' ) i++; -+ p[j++] = p[i]; -+ } -+ sz = j; -+ p[sz] = 0; -+ } -+ sqlite3_result_text64(context, (const char*)p, sz, -+ sqlite3_free, SQLITE_UTF8); -+ } -+ p = 0; -+ -+edit_func_end: -+ if( f ) fclose(f); -+ unlink(zTempFile); -+ sqlite3_free(zTempFile); -+ sqlite3_free(p); -+} -+#endif /* SQLITE_NOHAVE_SYSTEM */ -+ -+/* -+** Save or restore the current output mode -+*/ -+static void outputModePush(ShellState *p){ -+ p->modePrior = p->mode; -+ memcpy(p->colSepPrior, p->colSeparator, sizeof(p->colSeparator)); -+ memcpy(p->rowSepPrior, p->rowSeparator, sizeof(p->rowSeparator)); -+} -+static void outputModePop(ShellState *p){ -+ p->mode = p->modePrior; -+ memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator)); -+ memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator)); -+} -+ -+/* - ** Output the given string as a hex-encoded blob (eg. X'1234' ) - */ - static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ -@@ -2551,12 +9108,9 @@ - } - } - if( i==0 ){ -- putc('"', out); -- for(i=0; z[i]; i++){ -- if( z[i]=='"' ) putc('"', out); -- putc(z[i], out); -- } -- putc('"', out); -+ char *zQuoted = sqlite3_mprintf("\"%w\"", z); -+ utf8_printf(out, "%s", zQuoted); -+ sqlite3_free(zQuoted); - }else{ - utf8_printf(out, "%s", z); - } -@@ -2566,7 +9120,6 @@ - } - } - --#ifdef SIGINT - /* - ** This routine runs when the user presses Ctrl-C - */ -@@ -2576,6 +9129,20 @@ - if( seenInterrupt>2 ) exit(1); - if( globalDb ) sqlite3_interrupt(globalDb); - } -+ -+#if (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE) -+/* -+** This routine runs for console events (e.g. Ctrl-C) on Win32 -+*/ -+static BOOL WINAPI ConsoleCtrlHandler( -+ DWORD dwCtrlType /* One of the CTRL_*_EVENT constants */ -+){ -+ if( dwCtrlType==CTRL_C_EVENT ){ -+ interrupt_handler(0); -+ return TRUE; -+ } -+ return FALSE; -+} - #endif - - #ifndef SQLITE_OMIT_AUTHORIZATION -@@ -2646,6 +9213,108 @@ - } - - /* -+** Return true if string z[] has nothing but whitespace and comments to the -+** end of the first line. -+*/ -+static int wsToEol(const char *z){ -+ int i; -+ for(i=0; z[i]; i++){ -+ if( z[i]=='\n' ) return 1; -+ if( IsSpace(z[i]) ) continue; -+ if( z[i]=='-' && z[i+1]=='-' ) return 1; -+ return 0; -+ } -+ return 1; -+} -+ -+/* -+** Add a new entry to the EXPLAIN QUERY PLAN data -+*/ -+static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){ -+ EQPGraphRow *pNew; -+ int nText = strlen30(zText); -+ if( p->autoEQPtest ){ -+ utf8_printf(p->out, "%d,%d,%s\n", iEqpId, p2, zText); -+ } -+ pNew = sqlite3_malloc64( sizeof(*pNew) + nText ); -+ if( pNew==0 ) shell_out_of_memory(); -+ pNew->iEqpId = iEqpId; -+ pNew->iParentId = p2; -+ memcpy(pNew->zText, zText, nText+1); -+ pNew->pNext = 0; -+ if( p->sGraph.pLast ){ -+ p->sGraph.pLast->pNext = pNew; -+ }else{ -+ p->sGraph.pRow = pNew; -+ } -+ p->sGraph.pLast = pNew; -+} -+ -+/* -+** Free and reset the EXPLAIN QUERY PLAN data that has been collected -+** in p->sGraph. -+*/ -+static void eqp_reset(ShellState *p){ -+ EQPGraphRow *pRow, *pNext; -+ for(pRow = p->sGraph.pRow; pRow; pRow = pNext){ -+ pNext = pRow->pNext; -+ sqlite3_free(pRow); -+ } -+ memset(&p->sGraph, 0, sizeof(p->sGraph)); -+} -+ -+/* Return the next EXPLAIN QUERY PLAN line with iEqpId that occurs after -+** pOld, or return the first such line if pOld is NULL -+*/ -+static EQPGraphRow *eqp_next_row(ShellState *p, int iEqpId, EQPGraphRow *pOld){ -+ EQPGraphRow *pRow = pOld ? pOld->pNext : p->sGraph.pRow; -+ while( pRow && pRow->iParentId!=iEqpId ) pRow = pRow->pNext; -+ return pRow; -+} -+ -+/* Render a single level of the graph that has iEqpId as its parent. Called -+** recursively to render sublevels. -+*/ -+static void eqp_render_level(ShellState *p, int iEqpId){ -+ EQPGraphRow *pRow, *pNext; -+ int n = strlen30(p->sGraph.zPrefix); -+ char *z; -+ for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){ -+ pNext = eqp_next_row(p, iEqpId, pRow); -+ z = pRow->zText; -+ utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix, pNext ? "|--" : "`--", z); -+ if( n<(int)sizeof(p->sGraph.zPrefix)-7 ){ -+ memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4); -+ eqp_render_level(p, pRow->iEqpId); -+ p->sGraph.zPrefix[n] = 0; -+ } -+ } -+} -+ -+/* -+** Display and reset the EXPLAIN QUERY PLAN data -+*/ -+static void eqp_render(ShellState *p){ -+ EQPGraphRow *pRow = p->sGraph.pRow; -+ if( pRow ){ -+ if( pRow->zText[0]=='-' ){ -+ if( pRow->pNext==0 ){ -+ eqp_reset(p); -+ return; -+ } -+ utf8_printf(p->out, "%s\n", pRow->zText+3); -+ p->sGraph.pRow = pRow->pNext; -+ sqlite3_free(pRow); -+ }else{ -+ utf8_printf(p->out, "QUERY PLAN\n"); -+ } -+ p->sGraph.zPrefix[0] = 0; -+ eqp_render_level(p, 0); -+ eqp_reset(p); -+ } -+} -+ -+/* - ** This is the callback routine that the shell - ** invokes for each row of a query result. - */ -@@ -2659,6 +9328,7 @@ - int i; - ShellState *p = (ShellState*)pArg; - -+ if( azArg==0 ) return 0; - switch( p->cMode ){ - case MODE_Line: { - int w = 5; -@@ -2773,6 +9443,7 @@ - for(i=0; IsSpace(z[i]); i++){} - for(; (c = z[i])!=0; i++){ - if( IsSpace(c) ){ -+ if( z[j-1]=='\r' ) z[j-1] = '\n'; - if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue; - }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){ - j--; -@@ -2782,7 +9453,7 @@ - while( j>0 && IsSpace(z[j-1]) ){ j--; } - z[j] = 0; - if( strlen30(z)>=79 ){ -- for(i=j=0; (c = z[i])!=0; i++){ -+ for(i=j=0; (c = z[i])!=0; i++){ /* Copy changes from z[i] back to z[j] */ - if( c==cEnd ){ - cEnd = 0; - }else if( c=='"' || c=='\'' || c=='`' ){ -@@ -2789,6 +9460,8 @@ - cEnd = c; - }else if( c=='[' ){ - cEnd = ']'; -+ }else if( c=='-' && z[i+1]=='-' ){ -+ cEnd = '\n'; - }else if( c=='(' ){ - nParen++; - }else if( c==')' ){ -@@ -2799,7 +9472,9 @@ - } - } - z[j++] = c; -- if( nParen==1 && (c=='(' || c==',' || c=='\n') ){ -+ if( nParen==1 && cEnd==0 -+ && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1))) -+ ){ - if( c=='\n' ) j--; - printSchemaLineN(p->out, z, j, "\n "); - j = 0; -@@ -2919,8 +9594,16 @@ - }else if( aiType && aiType[i]==SQLITE_FLOAT ){ - char z[50]; - double r = sqlite3_column_double(p->pStmt, i); -- sqlite3_snprintf(50,z,"%!.20g", r); -- raw_printf(p->out, "%s", z); -+ sqlite3_uint64 ur; -+ memcpy(&ur,&r,sizeof(r)); -+ if( ur==0x7ff0000000000000LL ){ -+ raw_printf(p->out, "1e999"); -+ }else if( ur==0xfff0000000000000LL ){ -+ raw_printf(p->out, "-1e999"); -+ }else{ -+ sqlite3_snprintf(50,z,"%!.20g", r); -+ raw_printf(p->out, "%s", z); -+ } - }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ - const void *pBlob = sqlite3_column_blob(p->pStmt, i); - int nBlob = sqlite3_column_bytes(p->pStmt, i); -@@ -2988,6 +9671,10 @@ - utf8_printf(p->out, "%s", p->rowSeparator); - break; - } -+ case MODE_EQP: { -+ eqp_append(p, atoi(azArg[0]), atoi(azArg[1]), azArg[3]); -+ break; -+ } - } - return 0; - } -@@ -3009,6 +9696,7 @@ - ShellText *p = (ShellText*)pArg; - int i; - UNUSED_PARAMETER(az); -+ if( azArg==0 ) return 0; - if( p->n ) appendText(p, "|", 0); - for(i=0; i<nArg; i++){ - if( i ) appendText(p, ",", 0); -@@ -3073,7 +9761,7 @@ - */ - static void set_table_name(ShellState *p, const char *zName){ - int i, n; -- int cQuote; -+ char cQuote; - char *z; - - if( p->zDestTable ){ -@@ -3085,10 +9773,7 @@ - n = strlen30(zName); - if( cQuote ) n += n+2; - z = p->zDestTable = malloc( n+1 ); -- if( z==0 ){ -- raw_printf(stderr,"Error: out of memory\n"); -- exit(1); -- } -+ if( z==0 ) shell_out_of_memory(); - n = 0; - if( cQuote ) z[n++] = cQuote; - for(i=0; zName[i]; i++){ -@@ -3196,7 +9881,7 @@ - }; - int i; - for(i=0; i<ArraySize(aTrans); i++){ -- int n = (int)strlen(aTrans[i].zPattern); -+ int n = strlen30(aTrans[i].zPattern); - if( strncmp(aTrans[i].zPattern, z, n)==0 ){ - utf8_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]); - break; -@@ -3243,37 +9928,54 @@ - ){ - int iCur; - int iHiwtr; -+ FILE *out; -+ if( pArg==0 || pArg->out==0 ) return 0; -+ out = pArg->out; - -- if( pArg && pArg->out ){ -- displayStatLine(pArg, "Memory Used:", -- "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset); -- displayStatLine(pArg, "Number of Outstanding Allocations:", -- "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset); -- if( pArg->shellFlgs & SHFLG_Pagecache ){ -- displayStatLine(pArg, "Number of Pcache Pages Used:", -- "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset); -+ if( pArg->pStmt && (pArg->statsOn & 2) ){ -+ int nCol, i, x; -+ sqlite3_stmt *pStmt = pArg->pStmt; -+ char z[100]; -+ nCol = sqlite3_column_count(pStmt); -+ raw_printf(out, "%-36s %d\n", "Number of output columns:", nCol); -+ for(i=0; i<nCol; i++){ -+ sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x); -+ utf8_printf(out, "%-36s %s\n", z, sqlite3_column_name(pStmt,i)); -+#ifndef SQLITE_OMIT_DECLTYPE -+ sqlite3_snprintf(30, z+x, "declared type:"); -+ utf8_printf(out, "%-36s %s\n", z, sqlite3_column_decltype(pStmt, i)); -+#endif -+#ifdef SQLITE_ENABLE_COLUMN_METADATA -+ sqlite3_snprintf(30, z+x, "database name:"); -+ utf8_printf(out, "%-36s %s\n", z, sqlite3_column_database_name(pStmt,i)); -+ sqlite3_snprintf(30, z+x, "table name:"); -+ utf8_printf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i)); -+ sqlite3_snprintf(30, z+x, "origin name:"); -+ utf8_printf(out, "%-36s %s\n", z, sqlite3_column_origin_name(pStmt,i)); -+#endif - } -- displayStatLine(pArg, "Number of Pcache Overflow Bytes:", -- "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset); -- if( pArg->shellFlgs & SHFLG_Scratch ){ -- displayStatLine(pArg, "Number of Scratch Allocations Used:", -- "%lld (max %lld)", SQLITE_STATUS_SCRATCH_USED, bReset); -- } -- displayStatLine(pArg, "Number of Scratch Overflow Bytes:", -- "%lld (max %lld) bytes", SQLITE_STATUS_SCRATCH_OVERFLOW, bReset); -- displayStatLine(pArg, "Largest Allocation:", -- "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset); -- displayStatLine(pArg, "Largest Pcache Allocation:", -- "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset); -- displayStatLine(pArg, "Largest Scratch Allocation:", -- "%lld bytes", SQLITE_STATUS_SCRATCH_SIZE, bReset); -+ } -+ -+ displayStatLine(pArg, "Memory Used:", -+ "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset); -+ displayStatLine(pArg, "Number of Outstanding Allocations:", -+ "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset); -+ if( pArg->shellFlgs & SHFLG_Pagecache ){ -+ displayStatLine(pArg, "Number of Pcache Pages Used:", -+ "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset); -+ } -+ displayStatLine(pArg, "Number of Pcache Overflow Bytes:", -+ "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset); -+ displayStatLine(pArg, "Largest Allocation:", -+ "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset); -+ displayStatLine(pArg, "Largest Pcache Allocation:", -+ "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset); - #ifdef YYTRACKMAXSTACKDEPTH -- displayStatLine(pArg, "Deepest Parser Stack:", -- "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset); -+ displayStatLine(pArg, "Deepest Parser Stack:", -+ "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset); - #endif -- } - -- if( pArg && pArg->out && db ){ -+ if( db ){ - if( pArg->shellFlgs & SHFLG_Lookaside ){ - iHiwtr = iCur = -1; - sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, -@@ -3308,6 +10010,9 @@ - sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); - raw_printf(pArg->out, "Page cache writes: %d\n", iCur); - iHiwtr = iCur = -1; -+ sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1); -+ raw_printf(pArg->out, "Page cache spills: %d\n", iCur); -+ iHiwtr = iCur = -1; - sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n", - iCur); -@@ -3317,7 +10022,7 @@ - iCur); - } - -- if( pArg && pArg->out && db && pArg->pStmt ){ -+ if( pArg->pStmt ){ - iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, - bReset); - raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur); -@@ -3327,6 +10032,12 @@ - raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur); - iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); - raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur); -+ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE, bReset); -+ raw_printf(pArg->out, "Reprepare operations: %d\n", iCur); -+ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset); -+ raw_printf(pArg->out, "Number of times run: %d\n", iCur); -+ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset); -+ raw_printf(pArg->out, "Memory used by prepared stmt: %d\n", iCur); - } - - #ifdef __linux__ -@@ -3425,8 +10136,7 @@ - int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ - int iOp; /* Index of operation in p->aiIndent[] */ - -- const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", -- "NextIfOpen", "PrevIfOpen", 0 }; -+ const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 }; - const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead", - "Rewind", 0 }; - const char *azGoto[] = { "Goto", 0 }; -@@ -3476,7 +10186,9 @@ - } - nAlloc += 100; - p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int)); -+ if( p->aiIndent==0 ) shell_out_of_memory(); - abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int)); -+ if( abYield==0 ) shell_out_of_memory(); - } - abYield[iOp] = str_in_array(zOp, azYield); - p->aiIndent[iOp] = 0; -@@ -3542,8 +10254,7 @@ - */ - static void exec_prepared_stmt( - ShellState *pArg, /* Pointer to ShellState */ -- sqlite3_stmt *pStmt, /* Statment to run */ -- int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */ -+ sqlite3_stmt *pStmt /* Statment to run */ - ){ - int rc; - -@@ -3553,57 +10264,181 @@ - rc = sqlite3_step(pStmt); - /* if we have a result set... */ - if( SQLITE_ROW == rc ){ -- /* if we have a callback... */ -- if( xCallback ){ -- /* allocate space for col name ptr, value ptr, and type */ -- int nCol = sqlite3_column_count(pStmt); -- void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1); -- if( !pData ){ -- rc = SQLITE_NOMEM; -- }else{ -- char **azCols = (char **)pData; /* Names of result columns */ -- char **azVals = &azCols[nCol]; /* Results */ -- int *aiTypes = (int *)&azVals[nCol]; /* Result types */ -- int i, x; -- assert(sizeof(int) <= sizeof(char *)); -- /* save off ptrs to column names */ -+ /* allocate space for col name ptr, value ptr, and type */ -+ int nCol = sqlite3_column_count(pStmt); -+ void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1); -+ if( !pData ){ -+ rc = SQLITE_NOMEM; -+ }else{ -+ char **azCols = (char **)pData; /* Names of result columns */ -+ char **azVals = &azCols[nCol]; /* Results */ -+ int *aiTypes = (int *)&azVals[nCol]; /* Result types */ -+ int i, x; -+ assert(sizeof(int) <= sizeof(char *)); -+ /* save off ptrs to column names */ -+ for(i=0; i<nCol; i++){ -+ azCols[i] = (char *)sqlite3_column_name(pStmt, i); -+ } -+ do{ -+ /* extract the data and data types */ - for(i=0; i<nCol; i++){ -- azCols[i] = (char *)sqlite3_column_name(pStmt, i); -+ aiTypes[i] = x = sqlite3_column_type(pStmt, i); -+ if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){ -+ azVals[i] = ""; -+ }else{ -+ azVals[i] = (char*)sqlite3_column_text(pStmt, i); -+ } -+ if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){ -+ rc = SQLITE_NOMEM; -+ break; /* from for */ -+ } -+ } /* end for */ -+ -+ /* if data and types extracted successfully... */ -+ if( SQLITE_ROW == rc ){ -+ /* call the supplied callback with the result row data */ -+ if( shell_callback(pArg, nCol, azVals, azCols, aiTypes) ){ -+ rc = SQLITE_ABORT; -+ }else{ -+ rc = sqlite3_step(pStmt); -+ } - } -- do{ -- /* extract the data and data types */ -- for(i=0; i<nCol; i++){ -- aiTypes[i] = x = sqlite3_column_type(pStmt, i); -- if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){ -- azVals[i] = ""; -- }else{ -- azVals[i] = (char*)sqlite3_column_text(pStmt, i); -- } -- if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){ -- rc = SQLITE_NOMEM; -- break; /* from for */ -- } -- } /* end for */ -+ } while( SQLITE_ROW == rc ); -+ sqlite3_free(pData); -+ } -+ } -+} - -- /* if data and types extracted successfully... */ -- if( SQLITE_ROW == rc ){ -- /* call the supplied callback with the result row data */ -- if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){ -- rc = SQLITE_ABORT; -- }else{ -- rc = sqlite3_step(pStmt); -- } -- } -- } while( SQLITE_ROW == rc ); -- sqlite3_free(pData); -+#ifndef SQLITE_OMIT_VIRTUALTABLE -+/* -+** This function is called to process SQL if the previous shell command -+** was ".expert". It passes the SQL in the second argument directly to -+** the sqlite3expert object. -+** -+** If successful, SQLITE_OK is returned. Otherwise, an SQLite error -+** code. In this case, (*pzErr) may be set to point to a buffer containing -+** an English language error message. It is the responsibility of the -+** caller to eventually free this buffer using sqlite3_free(). -+*/ -+static int expertHandleSQL( -+ ShellState *pState, -+ const char *zSql, -+ char **pzErr -+){ -+ assert( pState->expert.pExpert ); -+ assert( pzErr==0 || *pzErr==0 ); -+ return sqlite3_expert_sql(pState->expert.pExpert, zSql, pzErr); -+} -+ -+/* -+** This function is called either to silently clean up the object -+** created by the ".expert" command (if bCancel==1), or to generate a -+** report from it and then clean it up (if bCancel==0). -+** -+** If successful, SQLITE_OK is returned. Otherwise, an SQLite error -+** code. In this case, (*pzErr) may be set to point to a buffer containing -+** an English language error message. It is the responsibility of the -+** caller to eventually free this buffer using sqlite3_free(). -+*/ -+static int expertFinish( -+ ShellState *pState, -+ int bCancel, -+ char **pzErr -+){ -+ int rc = SQLITE_OK; -+ sqlite3expert *p = pState->expert.pExpert; -+ assert( p ); -+ assert( bCancel || pzErr==0 || *pzErr==0 ); -+ if( bCancel==0 ){ -+ FILE *out = pState->out; -+ int bVerbose = pState->expert.bVerbose; -+ -+ rc = sqlite3_expert_analyze(p, pzErr); -+ if( rc==SQLITE_OK ){ -+ int nQuery = sqlite3_expert_count(p); -+ int i; -+ -+ if( bVerbose ){ -+ const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES); -+ raw_printf(out, "-- Candidates -----------------------------\n"); -+ raw_printf(out, "%s\n", zCand); - } -+ for(i=0; i<nQuery; i++){ -+ const char *zSql = sqlite3_expert_report(p, i, EXPERT_REPORT_SQL); -+ const char *zIdx = sqlite3_expert_report(p, i, EXPERT_REPORT_INDEXES); -+ const char *zEQP = sqlite3_expert_report(p, i, EXPERT_REPORT_PLAN); -+ if( zIdx==0 ) zIdx = "(no new indexes)\n"; -+ if( bVerbose ){ -+ raw_printf(out, "-- Query %d --------------------------------\n",i+1); -+ raw_printf(out, "%s\n\n", zSql); -+ } -+ raw_printf(out, "%s\n", zIdx); -+ raw_printf(out, "%s\n", zEQP); -+ } -+ } -+ } -+ sqlite3_expert_destroy(p); -+ pState->expert.pExpert = 0; -+ return rc; -+} -+ -+/* -+** Implementation of ".expert" dot command. -+*/ -+static int expertDotCommand( -+ ShellState *pState, /* Current shell tool state */ -+ char **azArg, /* Array of arguments passed to dot command */ -+ int nArg /* Number of entries in azArg[] */ -+){ -+ int rc = SQLITE_OK; -+ char *zErr = 0; -+ int i; -+ int iSample = 0; -+ -+ assert( pState->expert.pExpert==0 ); -+ memset(&pState->expert, 0, sizeof(ExpertInfo)); -+ -+ for(i=1; rc==SQLITE_OK && i<nArg; i++){ -+ char *z = azArg[i]; -+ int n; -+ if( z[0]=='-' && z[1]=='-' ) z++; -+ n = strlen30(z); -+ if( n>=2 && 0==strncmp(z, "-verbose", n) ){ -+ pState->expert.bVerbose = 1; -+ } -+ else if( n>=2 && 0==strncmp(z, "-sample", n) ){ -+ if( i==(nArg-1) ){ -+ raw_printf(stderr, "option requires an argument: %s\n", z); -+ rc = SQLITE_ERROR; -+ }else{ -+ iSample = (int)integerValue(azArg[++i]); -+ if( iSample<0 || iSample>100 ){ -+ raw_printf(stderr, "value out of range: %s\n", azArg[i]); -+ rc = SQLITE_ERROR; -+ } -+ } -+ } -+ else{ -+ raw_printf(stderr, "unknown option: %s\n", z); -+ rc = SQLITE_ERROR; -+ } -+ } -+ -+ if( rc==SQLITE_OK ){ -+ pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr); -+ if( pState->expert.pExpert==0 ){ -+ raw_printf(stderr, "sqlite3_expert_new: %s\n", zErr); -+ rc = SQLITE_ERROR; - }else{ -- do{ -- rc = sqlite3_step(pStmt); -- } while( rc == SQLITE_ROW ); -+ sqlite3_expert_config( -+ pState->expert.pExpert, EXPERT_CONFIG_SAMPLE, iSample -+ ); - } - } -+ -+ return rc; - } -+#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ - - /* - ** Execute a statement or set of statements. Print -@@ -3615,11 +10450,8 @@ - ** and callback data argument. - */ - static int shell_exec( -- sqlite3 *db, /* An open database */ -+ ShellState *pArg, /* Pointer to ShellState */ - const char *zSql, /* SQL to be evaluated */ -- int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */ -- /* (not the same as sqlite3_exec) */ -- ShellState *pArg, /* Pointer to ShellState */ - char **pzErrMsg /* Error msg written here */ - ){ - sqlite3_stmt *pStmt = NULL; /* Statement to execute. */ -@@ -3626,11 +10458,19 @@ - int rc = SQLITE_OK; /* Return Code */ - int rc2; - const char *zLeftover; /* Tail of unprocessed SQL */ -+ sqlite3 *db = pArg->db; - - if( pzErrMsg ){ - *pzErrMsg = NULL; - } - -+#ifndef SQLITE_OMIT_VIRTUALTABLE -+ if( pArg->expert.pExpert ){ -+ rc = expertHandleSQL(pArg, zSql, pzErrMsg); -+ return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg); -+ } -+#endif -+ - while( zSql[0] && (SQLITE_OK == rc) ){ - static const char *zStmtSql; - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); -@@ -3664,20 +10504,27 @@ - if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){ - sqlite3_stmt *pExplain; - char *zEQP; -+ int triggerEQP = 0; - disable_debug_trace_modes(); -+ sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP); -+ if( pArg->autoEQP>=AUTOEQP_trigger ){ -+ sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0); -+ } - zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql); - rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); - if( rc==SQLITE_OK ){ - while( sqlite3_step(pExplain)==SQLITE_ROW ){ -- raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0)); -- raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1)); -- raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2)); -- utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3)); -+ const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3); -+ int iEqpId = sqlite3_column_int(pExplain, 0); -+ int iParentId = sqlite3_column_int(pExplain, 1); -+ if( zEQPLine[0]=='-' ) eqp_render(pArg); -+ eqp_append(pArg, iEqpId, iParentId, zEQPLine); - } -+ eqp_render(pArg); - } - sqlite3_finalize(pExplain); - sqlite3_free(zEQP); -- if( pArg->autoEQP>=2 ){ -+ if( pArg->autoEQP>=AUTOEQP_full ){ - /* Also do an EXPLAIN for ".eqp full" mode */ - zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql); - rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); -@@ -3684,22 +10531,34 @@ - if( rc==SQLITE_OK ){ - pArg->cMode = MODE_Explain; - explain_data_prepare(pArg, pExplain); -- exec_prepared_stmt(pArg, pExplain, xCallback); -+ exec_prepared_stmt(pArg, pExplain); - explain_data_delete(pArg); - } - sqlite3_finalize(pExplain); - sqlite3_free(zEQP); - } -+ if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){ -+ sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0); -+ /* Reprepare pStmt before reactiving trace modes */ -+ sqlite3_finalize(pStmt); -+ sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); -+ if( pArg ) pArg->pStmt = pStmt; -+ } - restore_debug_trace_modes(); - } - - if( pArg ){ - pArg->cMode = pArg->mode; -- if( pArg->autoExplain -- && sqlite3_column_count(pStmt)==8 -- && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0 -- ){ -- pArg->cMode = MODE_Explain; -+ if( pArg->autoExplain ){ -+ if( sqlite3_column_count(pStmt)==8 -+ && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0 -+ ){ -+ pArg->cMode = MODE_Explain; -+ } -+ if( sqlite3_column_count(pStmt)==4 -+ && sqlite3_strlike("EXPLAIN QUERY PLAN%", zStmtSql,0)==0 ){ -+ pArg->cMode = MODE_EQP; -+ } - } - - /* If the shell is currently in ".explain" mode, gather the extra -@@ -3709,8 +10568,9 @@ - } - } - -- exec_prepared_stmt(pArg, pStmt, xCallback); -+ exec_prepared_stmt(pArg, pStmt); - explain_data_delete(pArg); -+ eqp_render(pArg); - - /* print usage stats if stats on */ - if( pArg && pArg->statsOn ){ -@@ -3788,10 +10648,7 @@ - if( nCol>=nAlloc-2 ){ - nAlloc = nAlloc*2 + nCol + 10; - azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0])); -- if( azCol==0 ){ -- raw_printf(stderr, "Error: out of memory\n"); -- exit(1); -- } -+ if( azCol==0 ) shell_out_of_memory(); - } - azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1)); - if( sqlite3_column_int(pStmt, 5) ){ -@@ -3807,6 +10664,7 @@ - } - } - sqlite3_finalize(pStmt); -+ if( azCol==0 ) return 0; - azCol[0] = 0; - azCol[nCol+1] = 0; - -@@ -3890,7 +10748,7 @@ - ShellState *p = (ShellState *)pArg; - - UNUSED_PARAMETER(azNotUsed); -- if( nArg!=3 ) return 1; -+ if( nArg!=3 || azArg==0 ) return 0; - zTable = azArg[0]; - zType = azArg[1]; - zSql = azArg[2]; -@@ -3971,11 +10829,11 @@ - savedMode = p->mode; - p->zDestTable = sTable.z; - p->mode = p->cMode = MODE_Insert; -- rc = shell_exec(p->db, sSelect.z, shell_callback, p, 0); -+ rc = shell_exec(p, sSelect.z, 0); - if( (rc&0xff)==SQLITE_CORRUPT ){ - raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n"); - toggleSelectOrder(p->db); -- shell_exec(p->db, sSelect.z, shell_callback, p, 0); -+ shell_exec(p, sSelect.z, 0); - toggleSelectOrder(p->db); - } - p->zDestTable = savedDestTable; -@@ -4026,124 +10884,239 @@ - } - - /* --** Text of a help message -+** Text of help messages. -+** -+** The help text for each individual command begins with a line that starts -+** with ".". Subsequent lines are supplimental information. -+** -+** There must be two or more spaces between the end of the command and the -+** start of the description of what that command does. - */ --static char zHelp[] = -+static const char *(azHelp[]) = { -+#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE) -+ ".archive ... Manage SQL archives", -+ " Each command must have exactly one of the following options:", -+ " -c, --create Create a new archive", -+ " -u, --update Update or add files to an existing archive", -+ " -t, --list List contents of archive", -+ " -x, --extract Extract files from archive", -+ " Optional arguments:", -+ " -v, --verbose Print each filename as it is processed", -+ " -f FILE, --file FILE Operate on archive FILE (default is current db)", -+ " -a FILE, --append FILE Operate on FILE opened using the apndvfs VFS", -+ " -C DIR, --directory DIR Change to directory DIR to read/extract files", -+ " -n, --dryrun Show the SQL that would have occurred", -+ " Examples:", -+ " .ar -cf archive.sar foo bar # Create archive.sar from files foo and bar", -+ " .ar -tf archive.sar # List members of archive.sar", -+ " .ar -xvf archive.sar # Verbosely extract files from archive.sar", -+ " See also:", -+ " http://sqlite.org/cli.html#sqlar_archive_support", -+#endif - #ifndef SQLITE_OMIT_AUTHORIZATION -- ".auth ON|OFF Show authorizer callbacks\n" -+ ".auth ON|OFF Show authorizer callbacks", - #endif -- ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" -- ".bail on|off Stop after hitting an error. Default OFF\n" -- ".binary on|off Turn binary output on or off. Default OFF\n" -- ".cd DIRECTORY Change the working directory to DIRECTORY\n" -- ".changes on|off Show number of rows changed by SQL\n" -- ".check GLOB Fail if output since .testcase does not match\n" -- ".clone NEWDB Clone data into NEWDB from the existing database\n" -- ".databases List names and files of attached databases\n" -- ".dbinfo ?DB? Show status information about the database\n" -- ".dump ?TABLE? ... Dump the database in an SQL text format\n" -- " If TABLE specified, only dump tables matching\n" -- " LIKE pattern TABLE.\n" -- ".echo on|off Turn command echo on or off\n" -- ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n" -- ".exit Exit this program\n" -+ ".backup ?DB? FILE Backup DB (default \"main\") to FILE", -+ " --append Use the appendvfs", -+ ".bail on|off Stop after hitting an error. Default OFF", -+ ".binary on|off Turn binary output on or off. Default OFF", -+ ".cd DIRECTORY Change the working directory to DIRECTORY", -+ ".changes on|off Show number of rows changed by SQL", -+ ".check GLOB Fail if output since .testcase does not match", -+ ".clone NEWDB Clone data into NEWDB from the existing database", -+ ".databases List names and files of attached databases", -+ ".dbconfig ?op? ?val? List or change sqlite3_db_config() options", -+ ".dbinfo ?DB? Show status information about the database", -+ ".dump ?TABLE? ... Render all database content as SQL", -+ " Options:", -+ " --preserve-rowids Include ROWID values in the output", -+ " --newlines Allow unescaped newline characters in output", -+ " TABLE is LIKE pattern for the tables to dump", -+ ".echo on|off Turn command echo on or off", -+ ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN", -+ ".excel Display the output of next command in a spreadsheet", -+ ".exit ?CODE? Exit this program with return-code CODE", -+ ".expert EXPERIMENTAL. Suggest indexes for specified 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 or to automatic\n"*/ -- ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n" -- ".headers on|off Turn display of headers on or off\n" -- ".help Show this message\n" -- ".import FILE TABLE Import data from FILE into TABLE\n" -+/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic",*/ -+ ".fullschema ?--indent? Show schema and the content of sqlite_stat tables", -+ ".headers on|off Turn display of headers on or off", -+ ".help ?-all? ?PATTERN? Show help text for PATTERN", -+ ".import FILE TABLE Import data from FILE into TABLE", - #ifndef SQLITE_OMIT_TEST_CONTROL -- ".imposter INDEX TABLE Create imposter table TABLE on index INDEX\n" -+ ".imposter INDEX TABLE Create imposter table TABLE on index INDEX", - #endif -- ".indexes ?TABLE? Show names of all indexes\n" -- " If TABLE specified, only show indexes for tables\n" -- " matching LIKE pattern TABLE.\n" -+ ".indexes ?TABLE? Show names of indexes", -+ " If TABLE is specified, only show indexes for", -+ " tables matching TABLE using the LIKE operator.", - #ifdef SQLITE_ENABLE_IOTRACE -- ".iotrace FILE Enable I/O diagnostic logging to FILE\n" -+ ".iotrace FILE Enable I/O diagnostic logging to FILE", - #endif -- ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n" -- ".lint OPTIONS Report potential schema issues. Options:\n" -- " fkey-indexes Find missing foreign key indexes\n" -+ ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT", -+ ".lint OPTIONS Report potential schema issues.", -+ " Options:", -+ " fkey-indexes Find missing foreign key indexes", - #ifndef SQLITE_OMIT_LOAD_EXTENSION -- ".load FILE ?ENTRY? Load an extension library\n" -+ ".load FILE ?ENTRY? Load an extension library", - #endif -- ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n" -- ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" -- " ascii Columns/rows delimited by 0x1F and 0x1E\n" -- " csv Comma-separated values\n" -- " column Left-aligned columns. (See .width)\n" -- " html HTML <table> code\n" -- " insert SQL insert statements for TABLE\n" -- " line One value per line\n" -- " list Values delimited by \"|\"\n" -- " quote Escape answers as for SQL\n" -- " tabs Tab-separated values\n" -- " tcl TCL list elements\n" -- ".nullvalue STRING Use STRING in place of NULL values\n" -- ".once FILENAME Output for the next SQL command only to FILENAME\n" -- ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n" -- " The --new option starts with an empty file\n" -- ".output ?FILENAME? Send output to FILENAME or stdout\n" -- ".print STRING... Print literal STRING\n" -- ".prompt MAIN CONTINUE Replace the standard prompts\n" -- ".quit Exit this program\n" -- ".read FILENAME Execute SQL in FILENAME\n" -- ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" -- ".save FILE Write in-memory database into FILE\n" -- ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n" -- ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n" -- " Add --indent for pretty-printing\n" -- ".selftest ?--init? Run tests defined in the SELFTEST table\n" -- ".separator COL ?ROW? Change the column separator and optionally the row\n" -- " separator for both the output mode and .import\n" -+ ".log FILE|off Turn logging on or off. FILE can be stderr/stdout", -+ ".mode MODE ?TABLE? Set output mode", -+ " MODE is one of:", -+ " ascii Columns/rows delimited by 0x1F and 0x1E", -+ " csv Comma-separated values", -+ " column Left-aligned columns. (See .width)", -+ " html HTML <table> code", -+ " insert SQL insert statements for TABLE", -+ " line One value per line", -+ " list Values delimited by \"|\"", -+ " quote Escape answers as for SQL", -+ " tabs Tab-separated values", -+ " tcl TCL list elements", -+ ".nullvalue STRING Use STRING in place of NULL values", -+ ".once (-e|-x|FILE) Output for the next SQL command only to FILE", -+ " If FILE begins with '|' then open as a pipe", -+ " Other options:", -+ " -e Invoke system text editor", -+ " -x Open in a spreadsheet", -+ ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE", -+ " Options:", -+ " --append Use appendvfs to append database to the end of FILE", -+#ifdef SQLITE_ENABLE_DESERIALIZE -+ " --deserialize Load into memory useing sqlite3_deserialize()", -+#endif -+ " --new Initialize FILE to an empty database", -+ " --readonly Open FILE readonly", -+ " --zip FILE is a ZIP archive", -+ ".output ?FILE? Send output to FILE or stdout if FILE is omitted", -+ " If FILE begins with '|' then open it as a pipe.", -+ ".print STRING... Print literal STRING", -+ ".prompt MAIN CONTINUE Replace the standard prompts", -+ ".quit Exit this program", -+ ".read FILE Read input from FILE", -+ ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE", -+ ".save FILE Write in-memory database into FILE", -+ ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off", -+ ".schema ?PATTERN? Show the CREATE statements matching PATTERN", -+ " Options:", -+ " --indent Try to pretty-print the schema", -+ ".selftest ?OPTIONS? Run tests defined in the SELFTEST table", -+ " Options:", -+ " --init Create a new SELFTEST table", -+ " -v Verbose output", -+ ".separator COL ?ROW? Change the column and row separators", - #if defined(SQLITE_ENABLE_SESSION) -- ".session CMD ... Create or control sessions\n" -+ ".session ?NAME? CMD ... Create or control sessions", -+ " Subcommands:", -+ " attach TABLE Attach TABLE", -+ " changeset FILE Write a changeset into FILE", -+ " close Close one session", -+ " enable ?BOOLEAN? Set or query the enable bit", -+ " filter GLOB... Reject tables matching GLOBs", -+ " indirect ?BOOLEAN? Mark or query the indirect status", -+ " isempty Query whether the session is empty", -+ " list List currently open session names", -+ " open DB NAME Open a new session on DB", -+ " patchset FILE Write a patchset into FILE", -+ " If ?NAME? is omitted, the first defined session is used.", - #endif -- ".sha3sum ?OPTIONS...? Compute a SHA3 hash of database content\n" -- ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" -- ".show Show the current values for various settings\n" -- ".stats ?on|off? Show stats or turn stats on or off\n" -- ".system CMD ARGS... Run CMD ARGS... in a system shell\n" -- ".tables ?TABLE? List names of tables\n" -- " If TABLE specified, only list tables matching\n" -- " LIKE pattern TABLE.\n" -- ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n" -- ".timeout MS Try opening locked tables for MS milliseconds\n" -- ".timer on|off Turn SQL timer on or off\n" -- ".trace FILE|off Output each SQL statement as it is run\n" -- ".vfsinfo ?AUX? Information about the top-level VFS\n" -- ".vfslist List all available VFSes\n" -- ".vfsname ?AUX? Print the name of the VFS stack\n" -- ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n" -- " Negative values right-justify\n" --; -+ ".sha3sum ... Compute a SHA3 hash of database content", -+ " Options:", -+ " --schema Also hash the sqlite_master table", -+ " --sha3-224 Use the sha3-224 algorithm", -+ " --sha3-256 Use the sha3-256 algorithm. This is the default.", -+ " --sha3-384 Use the sha3-384 algorithm", -+ " --sha3-512 Use the sha3-512 algorithm", -+ " Any other argument is a LIKE pattern for tables to hash", -+#ifndef SQLITE_NOHAVE_SYSTEM -+ ".shell CMD ARGS... Run CMD ARGS... in a system shell", -+#endif -+ ".show Show the current values for various settings", -+ ".stats ?on|off? Show stats or turn stats on or off", -+#ifndef SQLITE_NOHAVE_SYSTEM -+ ".system CMD ARGS... Run CMD ARGS... in a system shell", -+#endif -+ ".tables ?TABLE? List names of tables matching LIKE pattern TABLE", -+ ".testcase NAME Begin redirecting output to 'testcase-out.txt'", -+ ".timeout MS Try opening locked tables for MS milliseconds", -+ ".timer on|off Turn SQL timer on or off", -+ ".trace FILE|off Output each SQL statement as it is run", -+ ".vfsinfo ?AUX? Information about the top-level VFS", -+ ".vfslist List all available VFSes", -+ ".vfsname ?AUX? Print the name of the VFS stack", -+ ".width NUM1 NUM2 ... Set column widths for \"column\" mode", -+ " Negative values right-justify", -+}; - --#if defined(SQLITE_ENABLE_SESSION) - /* --** Print help information for the ".sessions" command -+** Output help text. -+** -+** zPattern describes the set of commands for which help text is provided. -+** If zPattern is NULL, then show all commands, but only give a one-line -+** description of each. -+** -+** Return the number of matches. - */ --void session_help(ShellState *p){ -- raw_printf(p->out, -- ".session ?NAME? SUBCOMMAND ?ARGS...?\n" -- "If ?NAME? is omitted, the first defined session is used.\n" -- "Subcommands:\n" -- " attach TABLE Attach TABLE\n" -- " changeset FILE Write a changeset into FILE\n" -- " close Close one session\n" -- " enable ?BOOLEAN? Set or query the enable bit\n" -- " filter GLOB... Reject tables matching GLOBs\n" -- " indirect ?BOOLEAN? Mark or query the indirect status\n" -- " isempty Query whether the session is empty\n" -- " list List currently open session names\n" -- " open DB NAME Open a new session on DB\n" -- " patchset FILE Write a patchset into FILE\n" -- ); -+static int showHelp(FILE *out, const char *zPattern){ -+ int i = 0; -+ int j = 0; -+ int n = 0; -+ char *zPat; -+ if( zPattern==0 -+ || zPattern[0]=='0' -+ || strcmp(zPattern,"-a")==0 -+ || strcmp(zPattern,"-all")==0 -+ ){ -+ /* Show all commands, but only one line per command */ -+ if( zPattern==0 ) zPattern = ""; -+ for(i=0; i<ArraySize(azHelp); i++){ -+ if( azHelp[i][0]=='.' || zPattern[0] ){ -+ utf8_printf(out, "%s\n", azHelp[i]); -+ n++; -+ } -+ } -+ }else{ -+ /* Look for commands that for which zPattern is an exact prefix */ -+ zPat = sqlite3_mprintf(".%s*", zPattern); -+ for(i=0; i<ArraySize(azHelp); i++){ -+ if( sqlite3_strglob(zPat, azHelp[i])==0 ){ -+ utf8_printf(out, "%s\n", azHelp[i]); -+ j = i+1; -+ n++; -+ } -+ } -+ sqlite3_free(zPat); -+ if( n ){ -+ if( n==1 ){ -+ /* when zPattern is a prefix of exactly one command, then include the -+ ** details of that command, which should begin at offset j */ -+ while( j<ArraySize(azHelp)-1 && azHelp[j][0]!='.' ){ -+ utf8_printf(out, "%s\n", azHelp[j]); -+ j++; -+ } -+ } -+ return n; -+ } -+ /* Look for commands that contain zPattern anywhere. Show the complete -+ ** text of all commands that match. */ -+ zPat = sqlite3_mprintf("%%%s%%", zPattern); -+ for(i=0; i<ArraySize(azHelp); i++){ -+ if( azHelp[i][0]=='.' ) j = i; -+ if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){ -+ utf8_printf(out, "%s\n", azHelp[j]); -+ while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]!='.' ){ -+ j++; -+ utf8_printf(out, "%s\n", azHelp[j]); -+ } -+ i = j; -+ n++; -+ } -+ } -+ sqlite3_free(zPat); -+ } -+ return n; - } --#endif - -- - /* Forward reference */ - static int process_input(ShellState *p, FILE *in); - -@@ -4172,7 +11145,7 @@ - nIn = ftell(in); - rewind(in); - pBuf = sqlite3_malloc64( nIn+1 ); -- if( pBuf==0 ) return 0; -+ if( pBuf==0 ){ fclose(in); return 0; } - nRead = fread(pBuf, nIn, 1, in); - fclose(in); - if( nRead!=1 ){ -@@ -4232,18 +11205,105 @@ - #endif - - /* -+** Try to deduce the type of file for zName based on its content. Return -+** one of the SHELL_OPEN_* constants. -+** -+** If the file does not exist or is empty but its name looks like a ZIP -+** archive and the dfltZip flag is true, then assume it is a ZIP archive. -+** Otherwise, assume an ordinary database regardless of the filename if -+** the type cannot be determined from content. -+*/ -+int deduceDatabaseType(const char *zName, int dfltZip){ -+ FILE *f = fopen(zName, "rb"); -+ size_t n; -+ int rc = SHELL_OPEN_UNSPEC; -+ char zBuf[100]; -+ if( f==0 ){ -+ if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){ -+ return SHELL_OPEN_ZIPFILE; -+ }else{ -+ return SHELL_OPEN_NORMAL; -+ } -+ } -+ n = fread(zBuf, 16, 1, f); -+ if( n==1 && memcmp(zBuf, "SQLite format 3", 16)==0 ){ -+ fclose(f); -+ return SHELL_OPEN_NORMAL; -+ } -+ fseek(f, -25, SEEK_END); -+ n = fread(zBuf, 25, 1, f); -+ if( n==1 && memcmp(zBuf, "Start-Of-SQLite3-", 17)==0 ){ -+ rc = SHELL_OPEN_APPENDVFS; -+ }else{ -+ fseek(f, -22, SEEK_END); -+ n = fread(zBuf, 22, 1, f); -+ if( n==1 && zBuf[0]==0x50 && zBuf[1]==0x4b && zBuf[2]==0x05 -+ && zBuf[3]==0x06 ){ -+ rc = SHELL_OPEN_ZIPFILE; -+ }else if( n==0 && dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){ -+ rc = SHELL_OPEN_ZIPFILE; -+ } -+ } -+ fclose(f); -+ return rc; -+} -+ -+/* Flags for open_db(). -+** -+** The default behavior of open_db() is to exit(1) if the database fails to -+** open. The OPEN_DB_KEEPALIVE flag changes that so that it prints an error -+** but still returns without calling exit. -+** -+** The OPEN_DB_ZIPFILE flag causes open_db() to prefer to open files as a -+** ZIP archive if the file does not exist or is empty and its name matches -+** the *.zip pattern. -+*/ -+#define OPEN_DB_KEEPALIVE 0x001 /* Return after error if true */ -+#define OPEN_DB_ZIPFILE 0x002 /* Open as ZIP if name matches *.zip */ -+ -+/* - ** Make sure the database is open. If it is not, then open it. If - ** the database fails to open, print an error message and exit. - */ --static void open_db(ShellState *p, int keepAlive){ -+static void open_db(ShellState *p, int openFlags){ - if( p->db==0 ){ -- sqlite3_initialize(); -- sqlite3_open(p->zDbFilename, &p->db); -+ if( p->openMode==SHELL_OPEN_UNSPEC ){ -+ if( p->zDbFilename==0 || p->zDbFilename[0]==0 ){ -+ p->openMode = SHELL_OPEN_NORMAL; -+ }else{ -+ p->openMode = (u8)deduceDatabaseType(p->zDbFilename, -+ (openFlags & OPEN_DB_ZIPFILE)!=0); -+ } -+ } -+ switch( p->openMode ){ -+ case SHELL_OPEN_APPENDVFS: { -+ sqlite3_open_v2(p->zDbFilename, &p->db, -+ SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs"); -+ break; -+ } -+ case SHELL_OPEN_DESERIALIZE: { -+ sqlite3_open(0, &p->db); -+ break; -+ } -+ case SHELL_OPEN_ZIPFILE: { -+ sqlite3_open(":memory:", &p->db); -+ break; -+ } -+ case SHELL_OPEN_READONLY: { -+ sqlite3_open_v2(p->zDbFilename, &p->db, SQLITE_OPEN_READONLY, 0); -+ break; -+ } -+ case SHELL_OPEN_UNSPEC: -+ case SHELL_OPEN_NORMAL: { -+ sqlite3_open(p->zDbFilename, &p->db); -+ break; -+ } -+ } - globalDb = p->db; - if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ - utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n", - p->zDbFilename, sqlite3_errmsg(p->db)); -- if( keepAlive ) return; -+ if( openFlags & OPEN_DB_KEEPALIVE ) return; - exit(1); - } - #ifndef SQLITE_OMIT_LOAD_EXTENSION -@@ -4252,11 +11312,54 @@ - sqlite3_fileio_init(p->db, 0, 0); - sqlite3_shathree_init(p->db, 0, 0); - sqlite3_completion_init(p->db, 0, 0); -- sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0, -+#ifdef SQLITE_HAVE_ZLIB -+ sqlite3_zipfile_init(p->db, 0, 0); -+ sqlite3_sqlar_init(p->db, 0, 0); -+#endif -+ sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0, - shellAddSchemaName, 0, 0); -+ sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0, -+ shellModuleSchema, 0, 0); -+ sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p, -+ shellPutsFunc, 0, 0); -+#ifndef SQLITE_NOHAVE_SYSTEM -+ sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0, -+ editFunc, 0, 0); -+ sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0, -+ editFunc, 0, 0); -+#endif -+ if( p->openMode==SHELL_OPEN_ZIPFILE ){ -+ char *zSql = sqlite3_mprintf( -+ "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename); -+ sqlite3_exec(p->db, zSql, 0, 0, 0); -+ sqlite3_free(zSql); -+ } -+#ifdef SQLITE_ENABLE_DESERIALIZE -+ else if( p->openMode==SHELL_OPEN_DESERIALIZE ){ -+ int nData = 0; -+ unsigned char *aData = (unsigned char*)readFile(p->zDbFilename, &nData); -+ int rc = sqlite3_deserialize(p->db, "main", aData, nData, nData, -+ SQLITE_DESERIALIZE_RESIZEABLE | -+ SQLITE_DESERIALIZE_FREEONCLOSE); -+ if( rc ){ -+ utf8_printf(stderr, "Error: sqlite3_deserialize() returns %d\n", rc); -+ } -+ } -+#endif - } - } - -+/* -+** Attempt to close the databaes connection. Report errors. -+*/ -+void close_db(sqlite3 *db){ -+ int rc = sqlite3_close(db); -+ if( rc ){ -+ utf8_printf(stderr, "Error: sqlite3_close() returns %d: %s\n", -+ rc, sqlite3_errmsg(db)); -+ } -+} -+ - #if HAVE_READLINE || HAVE_EDITLINE - /* - ** Readline completion callbacks -@@ -4291,7 +11394,7 @@ - ** Linenoise completion callback - */ - static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){ -- int nLine = (int)strlen(zLine); -+ int nLine = strlen30(zLine); - int i, iStart; - sqlite3_stmt *pStmt = 0; - char *zSql; -@@ -4298,7 +11401,7 @@ - char zBuf[1000]; - - if( nLine>sizeof(zBuf)-30 ) return; -- if( zLine[0]=='.' ) return; -+ if( zLine[0]=='.' || zLine[0]=='#') return; - for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){} - if( i==nLine-1 ) return; - iStart = i+1; -@@ -4382,63 +11485,6 @@ - } - - /* --** Return the value of a hexadecimal digit. Return -1 if the input --** is not a hex digit. --*/ --static int hexDigitValue(char c){ -- if( c>='0' && c<='9' ) return c - '0'; -- if( c>='a' && c<='f' ) return c - 'a' + 10; -- if( c>='A' && c<='F' ) return c - 'A' + 10; -- return -1; --} -- --/* --** Interpret zArg as an integer value, possibly with suffixes. --*/ --static sqlite3_int64 integerValue(const char *zArg){ -- sqlite3_int64 v = 0; -- static const struct { char *zSuffix; int iMult; } aMult[] = { -- { "KiB", 1024 }, -- { "MiB", 1024*1024 }, -- { "GiB", 1024*1024*1024 }, -- { "KB", 1000 }, -- { "MB", 1000000 }, -- { "GB", 1000000000 }, -- { "K", 1000 }, -- { "M", 1000000 }, -- { "G", 1000000000 }, -- }; -- int i; -- int isNeg = 0; -- if( zArg[0]=='-' ){ -- isNeg = 1; -- zArg++; -- }else if( zArg[0]=='+' ){ -- zArg++; -- } -- if( zArg[0]=='0' && zArg[1]=='x' ){ -- int x; -- zArg += 2; -- while( (x = hexDigitValue(zArg[0]))>=0 ){ -- v = (v<<4) + x; -- zArg++; -- } -- }else{ -- while( IsDigit(zArg[0]) ){ -- v = v*10 + zArg[0] - '0'; -- zArg++; -- } -- } -- for(i=0; i<ArraySize(aMult); i++){ -- if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){ -- v *= aMult[i].iMult; -- break; -- } -- } -- return isNeg? -v : v; --} -- --/* - ** Interpret zArg as either an integer or a boolean value. Return 1 or 0 - ** for TRUE and FALSE. Return the integer value if appropriate. - */ -@@ -4484,7 +11530,7 @@ - ** recognized and do the right thing. NULL is returned if the output - ** filename is "off". - */ --static FILE *output_file_open(const char *zFile){ -+static FILE *output_file_open(const char *zFile, int bTextMode){ - FILE *f; - if( strcmp(zFile,"stdout")==0 ){ - f = stdout; -@@ -4493,7 +11539,7 @@ - }else if( strcmp(zFile, "off")==0 ){ - f = 0; - }else{ -- f = fopen(zFile, "wb"); -+ f = fopen(zFile, bTextMode ? "w" : "wb"); - if( f==0 ){ - utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile); - } -@@ -4501,7 +11547,6 @@ - return f; - } - --#if !defined(SQLITE_UNTESTABLE) - #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) - /* - ** A routine for handling output from sqlite3_trace(). -@@ -4517,7 +11562,7 @@ - UNUSED_PARAMETER(pP); - if( f ){ - const char *z = (const char*)pX; -- int i = (int)strlen(z); -+ int i = strlen30(z); - while( i>0 && z[i-1]==';' ){ i--; } - utf8_printf(f, "%.*s;\n", i, z); - } -@@ -4524,7 +11569,6 @@ - return 0; - } - #endif --#endif - - /* - ** A no-op routine that runs with the ".breakpoint" doc-command. This is -@@ -4557,10 +11601,7 @@ - if( p->n+1>=p->nAlloc ){ - p->nAlloc += p->nAlloc + 100; - p->z = sqlite3_realloc64(p->z, p->nAlloc); -- if( p->z==0 ){ -- raw_printf(stderr, "out of memory\n"); -- exit(1); -- } -+ if( p->z==0 ) shell_out_of_memory(); - } - p->z[p->n++] = (char)c; - } -@@ -4706,7 +11747,7 @@ - char *zInsert = 0; - int rc; - int i, j, n; -- int nTable = (int)strlen(zTable); -+ int nTable = strlen30(zTable); - int k = 0; - int cnt = 0; - const int spinRate = 10000; -@@ -4721,13 +11762,10 @@ - } - n = sqlite3_column_count(pQuery); - zInsert = sqlite3_malloc64(200 + nTable + n*3); -- if( zInsert==0 ){ -- raw_printf(stderr, "out of memory\n"); -- goto end_data_xfer; -- } -+ if( zInsert==0 ) shell_out_of_memory(); - sqlite3_snprintf(200+nTable,zInsert, - "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable); -- i = (int)strlen(zInsert); -+ i = strlen30(zInsert); - for(j=1; j<n; j++){ - memcpy(zInsert+i, ",?", 2); - i += 2; -@@ -4902,11 +11940,15 @@ - sqlite3_exec(newDb, "COMMIT;", 0, 0, 0); - sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); - } -- sqlite3_close(newDb); -+ close_db(newDb); - } - - /* --** Change the output file back to stdout -+** Change the output file back to stdout. -+** -+** If the p->doXdgOpen flag is set, that means the output was being -+** redirected to a temporary file named by p->zTempFile. In that case, -+** launch start/open/xdg-open on that temporary file. - */ - static void output_reset(ShellState *p){ - if( p->outfile[0]=='|' ){ -@@ -4915,6 +11957,26 @@ - #endif - }else{ - output_file_close(p->out); -+#ifndef SQLITE_NOHAVE_SYSTEM -+ if( p->doXdgOpen ){ -+ const char *zXdgOpenCmd = -+#if defined(_WIN32) -+ "start"; -+#elif defined(__APPLE__) -+ "open"; -+#else -+ "xdg-open"; -+#endif -+ char *zCmd; -+ zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile); -+ if( system(zCmd) ){ -+ utf8_printf(stderr, "Failed: [%s]\n", zCmd); -+ } -+ sqlite3_free(zCmd); -+ outputModePop(p); -+ p->doXdgOpen = 0; -+ } -+#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */ - } - p->outfile[0] = 0; - p->out = stdout; -@@ -4976,20 +12038,25 @@ - { "schema size:", - "SELECT total(length(sql)) FROM %s" }, - }; -- sqlite3_file *pFile = 0; - int i; -+ unsigned iDataVersion; - char *zSchemaTab; - char *zDb = nArg>=2 ? azArg[1] : "main"; -+ sqlite3_stmt *pStmt = 0; - unsigned char aHdr[100]; - open_db(p, 0); - if( p->db==0 ) return 1; -- sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile); -- if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){ -- return 1; -- } -- i = pFile->pMethods->xRead(pFile, aHdr, 100, 0); -- if( i!=SQLITE_OK ){ -+ sqlite3_prepare_v2(p->db,"SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1", -+ -1, &pStmt, 0); -+ sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC); -+ if( sqlite3_step(pStmt)==SQLITE_ROW -+ && sqlite3_column_bytes(pStmt,0)>100 -+ ){ -+ memcpy(aHdr, sqlite3_column_blob(pStmt,0), 100); -+ sqlite3_finalize(pStmt); -+ }else{ - raw_printf(stderr, "unable to read database header\n"); -+ sqlite3_finalize(pStmt); - return 1; - } - i = get2byteInt(aHdr+16); -@@ -5025,6 +12092,8 @@ - utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val); - } - sqlite3_free(zSchemaTab); -+ sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion); -+ utf8_printf(p->out, "%-20s %u\n", "data version", iDataVersion); - return 0; - } - -@@ -5038,14 +12107,6 @@ - } - - /* --** Print an out-of-memory message to stderr and return 1. --*/ --static int shellNomemError(void){ -- raw_printf(stderr, "Error: out of memory\n"); -- return 1; --} -- --/* - ** Compare the pattern in zGlob[] against the text in z[]. Return TRUE - ** if they match and FALSE (0) if they do not match. - ** -@@ -5169,8 +12230,43 @@ - return rc; - } - -+/* -+** Try to delete the temporary file (if there is one) and free the -+** memory used to hold the name of the temp file. -+*/ -+static void clearTempFile(ShellState *p){ -+ if( p->zTempFile==0 ) return; -+ if( p->doXdgOpen ) return; -+ if( shellDeleteFile(p->zTempFile) ) return; -+ sqlite3_free(p->zTempFile); -+ p->zTempFile = 0; -+} - - /* -+** Create a new temp file name with the given suffix. -+*/ -+static void newTempFile(ShellState *p, const char *zSuffix){ -+ clearTempFile(p); -+ sqlite3_free(p->zTempFile); -+ p->zTempFile = 0; -+ if( p->db ){ -+ sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile); -+ } -+ if( p->zTempFile==0 ){ -+ sqlite3_uint64 r; -+ sqlite3_randomness(sizeof(r), &r); -+ p->zTempFile = sqlite3_mprintf("temp%llx.%s", r, zSuffix); -+ }else{ -+ p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix); -+ } -+ if( p->zTempFile==0 ){ -+ raw_printf(stderr, "out of memory\n"); -+ exit(1); -+ } -+} -+ -+ -+/* - ** The implementation of SQL scalar function fkey_collate_clause(), used - ** by the ".lint fkey-indexes" command. This scalar function is always - ** called with four arguments - the parent table name, the parent column name, -@@ -5246,10 +12342,10 @@ - ** - ** 0. The text of an SQL statement similar to: - ** -- ** "EXPLAIN QUERY PLAN SELECT rowid FROM child_table WHERE child_key=?" -+ ** "EXPLAIN QUERY PLAN SELECT 1 FROM child_table WHERE child_key=?" - ** -- ** This is the same SELECT that the foreign keys implementation needs -- ** to run internally on child tables. If there is an index that can -+ ** This SELECT is similar to the one that the foreign keys implementation -+ ** needs to run internally on child tables. If there is an index that can - ** be used to optimize this query, then it can also be used by the FK - ** implementation to optimize DELETE or UPDATE statements on the parent - ** table. -@@ -5277,7 +12373,7 @@ - */ - const char *zSql = - "SELECT " -- " 'EXPLAIN QUERY PLAN SELECT rowid FROM ' || quote(s.name) || ' WHERE '" -+ " 'EXPLAIN QUERY PLAN SELECT 1 FROM ' || quote(s.name) || ' WHERE '" - " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' " - " || fkey_collate_clause(" - " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')" -@@ -5305,7 +12401,7 @@ - const char *zGlobIPK = "SEARCH TABLE * USING INTEGER PRIMARY KEY (rowid=?)"; - - for(i=2; i<nArg; i++){ -- int n = (int)strlen(azArg[i]); -+ int n = strlen30(azArg[i]); - if( n>1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){ - bVerbose = 1; - } -@@ -5408,7 +12504,7 @@ - int nArg /* Number of entries in azArg[] */ - ){ - int n; -- n = (nArg>=2 ? (int)strlen(azArg[1]) : 0); -+ n = (nArg>=2 ? strlen30(azArg[1]) : 0); - if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage; - return lintFkeyIndexes(pState, azArg, nArg); - -@@ -5419,8 +12515,741 @@ - return SQLITE_ERROR; - } - -+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) -+/********************************************************************************* -+** The ".archive" or ".ar" command. -+*/ -+static void shellPrepare( -+ sqlite3 *db, -+ int *pRc, -+ const char *zSql, -+ sqlite3_stmt **ppStmt -+){ -+ *ppStmt = 0; -+ if( *pRc==SQLITE_OK ){ -+ int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); -+ if( rc!=SQLITE_OK ){ -+ raw_printf(stderr, "sql error: %s (%d)\n", -+ sqlite3_errmsg(db), sqlite3_errcode(db) -+ ); -+ *pRc = rc; -+ } -+ } -+} - -+static void shellPreparePrintf( -+ sqlite3 *db, -+ int *pRc, -+ sqlite3_stmt **ppStmt, -+ const char *zFmt, -+ ... -+){ -+ *ppStmt = 0; -+ if( *pRc==SQLITE_OK ){ -+ va_list ap; -+ char *z; -+ va_start(ap, zFmt); -+ z = sqlite3_vmprintf(zFmt, ap); -+ va_end(ap); -+ if( z==0 ){ -+ *pRc = SQLITE_NOMEM; -+ }else{ -+ shellPrepare(db, pRc, z, ppStmt); -+ sqlite3_free(z); -+ } -+ } -+} -+ -+static void shellFinalize( -+ int *pRc, -+ sqlite3_stmt *pStmt -+){ -+ if( pStmt ){ -+ sqlite3 *db = sqlite3_db_handle(pStmt); -+ int rc = sqlite3_finalize(pStmt); -+ if( *pRc==SQLITE_OK ){ -+ if( rc!=SQLITE_OK ){ -+ raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db)); -+ } -+ *pRc = rc; -+ } -+ } -+} -+ -+static void shellReset( -+ int *pRc, -+ sqlite3_stmt *pStmt -+){ -+ int rc = sqlite3_reset(pStmt); -+ if( *pRc==SQLITE_OK ){ -+ if( rc!=SQLITE_OK ){ -+ sqlite3 *db = sqlite3_db_handle(pStmt); -+ raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db)); -+ } -+ *pRc = rc; -+ } -+} - /* -+** Structure representing a single ".ar" command. -+*/ -+typedef struct ArCommand ArCommand; -+struct ArCommand { -+ u8 eCmd; /* An AR_CMD_* value */ -+ u8 bVerbose; /* True if --verbose */ -+ u8 bZip; /* True if the archive is a ZIP */ -+ u8 bDryRun; /* True if --dry-run */ -+ u8 bAppend; /* True if --append */ -+ u8 fromCmdLine; /* Run from -A instead of .archive */ -+ int nArg; /* Number of command arguments */ -+ char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */ -+ const char *zFile; /* --file argument, or NULL */ -+ const char *zDir; /* --directory argument, or NULL */ -+ char **azArg; /* Array of command arguments */ -+ ShellState *p; /* Shell state */ -+ sqlite3 *db; /* Database containing the archive */ -+}; -+ -+/* -+** Print a usage message for the .ar command to stderr and return SQLITE_ERROR. -+*/ -+static int arUsage(FILE *f){ -+ showHelp(f,"archive"); -+ return SQLITE_ERROR; -+} -+ -+/* -+** Print an error message for the .ar command to stderr and return -+** SQLITE_ERROR. -+*/ -+static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){ -+ va_list ap; -+ char *z; -+ va_start(ap, zFmt); -+ z = sqlite3_vmprintf(zFmt, ap); -+ va_end(ap); -+ utf8_printf(stderr, "Error: %s\n", z); -+ if( pAr->fromCmdLine ){ -+ utf8_printf(stderr, "Use \"-A\" for more help\n"); -+ }else{ -+ utf8_printf(stderr, "Use \".archive --help\" for more help\n"); -+ } -+ sqlite3_free(z); -+ return SQLITE_ERROR; -+} -+ -+/* -+** Values for ArCommand.eCmd. -+*/ -+#define AR_CMD_CREATE 1 -+#define AR_CMD_EXTRACT 2 -+#define AR_CMD_LIST 3 -+#define AR_CMD_UPDATE 4 -+#define AR_CMD_HELP 5 -+ -+/* -+** Other (non-command) switches. -+*/ -+#define AR_SWITCH_VERBOSE 6 -+#define AR_SWITCH_FILE 7 -+#define AR_SWITCH_DIRECTORY 8 -+#define AR_SWITCH_APPEND 9 -+#define AR_SWITCH_DRYRUN 10 -+ -+static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){ -+ switch( eSwitch ){ -+ case AR_CMD_CREATE: -+ case AR_CMD_EXTRACT: -+ case AR_CMD_LIST: -+ case AR_CMD_UPDATE: -+ case AR_CMD_HELP: -+ if( pAr->eCmd ){ -+ return arErrorMsg(pAr, "multiple command options"); -+ } -+ pAr->eCmd = eSwitch; -+ break; -+ -+ case AR_SWITCH_DRYRUN: -+ pAr->bDryRun = 1; -+ break; -+ case AR_SWITCH_VERBOSE: -+ pAr->bVerbose = 1; -+ break; -+ case AR_SWITCH_APPEND: -+ pAr->bAppend = 1; -+ /* Fall thru into --file */ -+ case AR_SWITCH_FILE: -+ pAr->zFile = zArg; -+ break; -+ case AR_SWITCH_DIRECTORY: -+ pAr->zDir = zArg; -+ break; -+ } -+ -+ return SQLITE_OK; -+} -+ -+/* -+** Parse the command line for an ".ar" command. The results are written into -+** structure (*pAr). SQLITE_OK is returned if the command line is parsed -+** successfully, otherwise an error message is written to stderr and -+** SQLITE_ERROR returned. -+*/ -+static int arParseCommand( -+ char **azArg, /* Array of arguments passed to dot command */ -+ int nArg, /* Number of entries in azArg[] */ -+ ArCommand *pAr /* Populate this object */ -+){ -+ struct ArSwitch { -+ const char *zLong; -+ char cShort; -+ u8 eSwitch; -+ u8 bArg; -+ } aSwitch[] = { -+ { "create", 'c', AR_CMD_CREATE, 0 }, -+ { "extract", 'x', AR_CMD_EXTRACT, 0 }, -+ { "list", 't', AR_CMD_LIST, 0 }, -+ { "update", 'u', AR_CMD_UPDATE, 0 }, -+ { "help", 'h', AR_CMD_HELP, 0 }, -+ { "verbose", 'v', AR_SWITCH_VERBOSE, 0 }, -+ { "file", 'f', AR_SWITCH_FILE, 1 }, -+ { "append", 'a', AR_SWITCH_APPEND, 1 }, -+ { "directory", 'C', AR_SWITCH_DIRECTORY, 1 }, -+ { "dryrun", 'n', AR_SWITCH_DRYRUN, 0 }, -+ }; -+ int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch); -+ struct ArSwitch *pEnd = &aSwitch[nSwitch]; -+ -+ if( nArg<=1 ){ -+ utf8_printf(stderr, "Wrong number of arguments. Usage:\n"); -+ return arUsage(stderr); -+ }else{ -+ char *z = azArg[1]; -+ if( z[0]!='-' ){ -+ /* Traditional style [tar] invocation */ -+ int i; -+ int iArg = 2; -+ for(i=0; z[i]; i++){ -+ const char *zArg = 0; -+ struct ArSwitch *pOpt; -+ for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){ -+ if( z[i]==pOpt->cShort ) break; -+ } -+ if( pOpt==pEnd ){ -+ return arErrorMsg(pAr, "unrecognized option: %c", z[i]); -+ } -+ if( pOpt->bArg ){ -+ if( iArg>=nArg ){ -+ return arErrorMsg(pAr, "option requires an argument: %c",z[i]); -+ } -+ zArg = azArg[iArg++]; -+ } -+ if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR; -+ } -+ pAr->nArg = nArg-iArg; -+ if( pAr->nArg>0 ){ -+ pAr->azArg = &azArg[iArg]; -+ } -+ }else{ -+ /* Non-traditional invocation */ -+ int iArg; -+ for(iArg=1; iArg<nArg; iArg++){ -+ int n; -+ z = azArg[iArg]; -+ if( z[0]!='-' ){ -+ /* All remaining command line words are command arguments. */ -+ pAr->azArg = &azArg[iArg]; -+ pAr->nArg = nArg-iArg; -+ break; -+ } -+ n = strlen30(z); -+ -+ if( z[1]!='-' ){ -+ int i; -+ /* One or more short options */ -+ for(i=1; i<n; i++){ -+ const char *zArg = 0; -+ struct ArSwitch *pOpt; -+ for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){ -+ if( z[i]==pOpt->cShort ) break; -+ } -+ if( pOpt==pEnd ){ -+ return arErrorMsg(pAr, "unrecognized option: %c", z[i]); -+ } -+ if( pOpt->bArg ){ -+ if( i<(n-1) ){ -+ zArg = &z[i+1]; -+ i = n; -+ }else{ -+ if( iArg>=(nArg-1) ){ -+ return arErrorMsg(pAr, "option requires an argument: %c",z[i]); -+ } -+ zArg = azArg[++iArg]; -+ } -+ } -+ if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR; -+ } -+ }else if( z[2]=='\0' ){ -+ /* A -- option, indicating that all remaining command line words -+ ** are command arguments. */ -+ pAr->azArg = &azArg[iArg+1]; -+ pAr->nArg = nArg-iArg-1; -+ break; -+ }else{ -+ /* A long option */ -+ const char *zArg = 0; /* Argument for option, if any */ -+ struct ArSwitch *pMatch = 0; /* Matching option */ -+ struct ArSwitch *pOpt; /* Iterator */ -+ for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){ -+ const char *zLong = pOpt->zLong; -+ if( (n-2)<=strlen30(zLong) && 0==memcmp(&z[2], zLong, n-2) ){ -+ if( pMatch ){ -+ return arErrorMsg(pAr, "ambiguous option: %s",z); -+ }else{ -+ pMatch = pOpt; -+ } -+ } -+ } -+ -+ if( pMatch==0 ){ -+ return arErrorMsg(pAr, "unrecognized option: %s", z); -+ } -+ if( pMatch->bArg ){ -+ if( iArg>=(nArg-1) ){ -+ return arErrorMsg(pAr, "option requires an argument: %s", z); -+ } -+ zArg = azArg[++iArg]; -+ } -+ if( arProcessSwitch(pAr, pMatch->eSwitch, zArg) ) return SQLITE_ERROR; -+ } -+ } -+ } -+ } -+ -+ return SQLITE_OK; -+} -+ -+/* -+** This function assumes that all arguments within the ArCommand.azArg[] -+** array refer to archive members, as for the --extract or --list commands. -+** It checks that each of them are present. If any specified file is not -+** present in the archive, an error is printed to stderr and an error -+** code returned. Otherwise, if all specified arguments are present in -+** the archive, SQLITE_OK is returned. -+** -+** This function strips any trailing '/' characters from each argument. -+** This is consistent with the way the [tar] command seems to work on -+** Linux. -+*/ -+static int arCheckEntries(ArCommand *pAr){ -+ int rc = SQLITE_OK; -+ if( pAr->nArg ){ -+ int i, j; -+ sqlite3_stmt *pTest = 0; -+ -+ shellPreparePrintf(pAr->db, &rc, &pTest, -+ "SELECT name FROM %s WHERE name=$name", -+ pAr->zSrcTable -+ ); -+ j = sqlite3_bind_parameter_index(pTest, "$name"); -+ for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){ -+ char *z = pAr->azArg[i]; -+ int n = strlen30(z); -+ int bOk = 0; -+ while( n>0 && z[n-1]=='/' ) n--; -+ z[n] = '\0'; -+ sqlite3_bind_text(pTest, j, z, -1, SQLITE_STATIC); -+ if( SQLITE_ROW==sqlite3_step(pTest) ){ -+ bOk = 1; -+ } -+ shellReset(&rc, pTest); -+ if( rc==SQLITE_OK && bOk==0 ){ -+ utf8_printf(stderr, "not found in archive: %s\n", z); -+ rc = SQLITE_ERROR; -+ } -+ } -+ shellFinalize(&rc, pTest); -+ } -+ return rc; -+} -+ -+/* -+** Format a WHERE clause that can be used against the "sqlar" table to -+** identify all archive members that match the command arguments held -+** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning. -+** The caller is responsible for eventually calling sqlite3_free() on -+** any non-NULL (*pzWhere) value. -+*/ -+static void arWhereClause( -+ int *pRc, -+ ArCommand *pAr, -+ char **pzWhere /* OUT: New WHERE clause */ -+){ -+ char *zWhere = 0; -+ if( *pRc==SQLITE_OK ){ -+ if( pAr->nArg==0 ){ -+ zWhere = sqlite3_mprintf("1"); -+ }else{ -+ int i; -+ const char *zSep = ""; -+ for(i=0; i<pAr->nArg; i++){ -+ const char *z = pAr->azArg[i]; -+ zWhere = sqlite3_mprintf( -+ "%z%s name = '%q' OR substr(name,1,%d) = '%q/'", -+ zWhere, zSep, z, strlen30(z)+1, z -+ ); -+ if( zWhere==0 ){ -+ *pRc = SQLITE_NOMEM; -+ break; -+ } -+ zSep = " OR "; -+ } -+ } -+ } -+ *pzWhere = zWhere; -+} -+ -+/* -+** Implementation of .ar "lisT" command. -+*/ -+static int arListCommand(ArCommand *pAr){ -+ const char *zSql = "SELECT %s FROM %s WHERE %s"; -+ const char *azCols[] = { -+ "name", -+ "lsmode(mode), sz, datetime(mtime, 'unixepoch'), name" -+ }; -+ -+ char *zWhere = 0; -+ sqlite3_stmt *pSql = 0; -+ int rc; -+ -+ rc = arCheckEntries(pAr); -+ arWhereClause(&rc, pAr, &zWhere); -+ -+ shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose], -+ pAr->zSrcTable, zWhere); -+ if( pAr->bDryRun ){ -+ utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql)); -+ }else{ -+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ -+ if( pAr->bVerbose ){ -+ utf8_printf(pAr->p->out, "%s % 10d %s %s\n", -+ sqlite3_column_text(pSql, 0), -+ sqlite3_column_int(pSql, 1), -+ sqlite3_column_text(pSql, 2), -+ sqlite3_column_text(pSql, 3) -+ ); -+ }else{ -+ utf8_printf(pAr->p->out, "%s\n", sqlite3_column_text(pSql, 0)); -+ } -+ } -+ } -+ shellFinalize(&rc, pSql); -+ sqlite3_free(zWhere); -+ return rc; -+} -+ -+ -+/* -+** Implementation of .ar "eXtract" command. -+*/ -+static int arExtractCommand(ArCommand *pAr){ -+ const char *zSql1 = -+ "SELECT " -+ " ($dir || name)," -+ " writefile(($dir || name), %s, mode, mtime) " -+ "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)" -+ " AND name NOT GLOB '*..[/\\]*'"; -+ -+ const char *azExtraArg[] = { -+ "sqlar_uncompress(data, sz)", -+ "data" -+ }; -+ -+ sqlite3_stmt *pSql = 0; -+ int rc = SQLITE_OK; -+ char *zDir = 0; -+ char *zWhere = 0; -+ int i, j; -+ -+ /* If arguments are specified, check that they actually exist within -+ ** the archive before proceeding. And formulate a WHERE clause to -+ ** match them. */ -+ rc = arCheckEntries(pAr); -+ arWhereClause(&rc, pAr, &zWhere); -+ -+ if( rc==SQLITE_OK ){ -+ if( pAr->zDir ){ -+ zDir = sqlite3_mprintf("%s/", pAr->zDir); -+ }else{ -+ zDir = sqlite3_mprintf(""); -+ } -+ if( zDir==0 ) rc = SQLITE_NOMEM; -+ } -+ -+ shellPreparePrintf(pAr->db, &rc, &pSql, zSql1, -+ azExtraArg[pAr->bZip], pAr->zSrcTable, zWhere -+ ); -+ -+ if( rc==SQLITE_OK ){ -+ j = sqlite3_bind_parameter_index(pSql, "$dir"); -+ sqlite3_bind_text(pSql, j, zDir, -1, SQLITE_STATIC); -+ -+ /* Run the SELECT statement twice. The first time, writefile() is called -+ ** for all archive members that should be extracted. The second time, -+ ** only for the directories. This is because the timestamps for -+ ** extracted directories must be reset after they are populated (as -+ ** populating them changes the timestamp). */ -+ for(i=0; i<2; i++){ -+ j = sqlite3_bind_parameter_index(pSql, "$dirOnly"); -+ sqlite3_bind_int(pSql, j, i); -+ if( pAr->bDryRun ){ -+ utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql)); -+ }else{ -+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ -+ if( i==0 && pAr->bVerbose ){ -+ utf8_printf(pAr->p->out, "%s\n", sqlite3_column_text(pSql, 0)); -+ } -+ } -+ } -+ shellReset(&rc, pSql); -+ } -+ shellFinalize(&rc, pSql); -+ } -+ -+ sqlite3_free(zDir); -+ sqlite3_free(zWhere); -+ return rc; -+} -+ -+/* -+** Run the SQL statement in zSql. Or if doing a --dryrun, merely print it out. -+*/ -+static int arExecSql(ArCommand *pAr, const char *zSql){ -+ int rc; -+ if( pAr->bDryRun ){ -+ utf8_printf(pAr->p->out, "%s\n", zSql); -+ rc = SQLITE_OK; -+ }else{ -+ char *zErr = 0; -+ rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr); -+ if( zErr ){ -+ utf8_printf(stdout, "ERROR: %s\n", zErr); -+ sqlite3_free(zErr); -+ } -+ } -+ return rc; -+} -+ -+ -+/* -+** Implementation of .ar "create" and "update" commands. -+** -+** Create the "sqlar" table in the database if it does not already exist. -+** Then add each file in the azFile[] array to the archive. Directories -+** are added recursively. If argument bVerbose is non-zero, a message is -+** printed on stdout for each file archived. -+** -+** The create command is the same as update, except that it drops -+** any existing "sqlar" table before beginning. -+*/ -+static int arCreateOrUpdateCommand( -+ ArCommand *pAr, /* Command arguments and options */ -+ int bUpdate /* true for a --create. false for --update */ -+){ -+ const char *zCreate = -+ "CREATE TABLE IF NOT EXISTS sqlar(\n" -+ " name TEXT PRIMARY KEY, -- name of the file\n" -+ " mode INT, -- access permissions\n" -+ " mtime INT, -- last modification time\n" -+ " sz INT, -- original file size\n" -+ " data BLOB -- compressed content\n" -+ ")"; -+ const char *zDrop = "DROP TABLE IF EXISTS sqlar"; -+ const char *zInsertFmt[2] = { -+ "REPLACE INTO %s(name,mode,mtime,sz,data)\n" -+ " SELECT\n" -+ " %s,\n" -+ " mode,\n" -+ " mtime,\n" -+ " CASE substr(lsmode(mode),1,1)\n" -+ " WHEN '-' THEN length(data)\n" -+ " WHEN 'd' THEN 0\n" -+ " ELSE -1 END,\n" -+ " sqlar_compress(data)\n" -+ " FROM fsdir(%Q,%Q)\n" -+ " WHERE lsmode(mode) NOT LIKE '?%%';", -+ "REPLACE INTO %s(name,mode,mtime,data)\n" -+ " SELECT\n" -+ " %s,\n" -+ " mode,\n" -+ " mtime,\n" -+ " data\n" -+ " FROM fsdir(%Q,%Q)\n" -+ " WHERE lsmode(mode) NOT LIKE '?%%';" -+ }; -+ int i; /* For iterating through azFile[] */ -+ int rc; /* Return code */ -+ const char *zTab = 0; /* SQL table into which to insert */ -+ char *zSql; -+ char zTemp[50]; -+ -+ arExecSql(pAr, "PRAGMA page_size=512"); -+ rc = arExecSql(pAr, "SAVEPOINT ar;"); -+ if( rc!=SQLITE_OK ) return rc; -+ zTemp[0] = 0; -+ if( pAr->bZip ){ -+ /* Initialize the zipfile virtual table, if necessary */ -+ if( pAr->zFile ){ -+ sqlite3_uint64 r; -+ sqlite3_randomness(sizeof(r),&r); -+ sqlite3_snprintf(sizeof(zTemp),zTemp,"zip%016llx",r); -+ zTab = zTemp; -+ zSql = sqlite3_mprintf( -+ "CREATE VIRTUAL TABLE temp.%s USING zipfile(%Q)", -+ zTab, pAr->zFile -+ ); -+ rc = arExecSql(pAr, zSql); -+ sqlite3_free(zSql); -+ }else{ -+ zTab = "zip"; -+ } -+ }else{ -+ /* Initialize the table for an SQLAR */ -+ zTab = "sqlar"; -+ if( bUpdate==0 ){ -+ rc = arExecSql(pAr, zDrop); -+ if( rc!=SQLITE_OK ) goto end_ar_transaction; -+ } -+ rc = arExecSql(pAr, zCreate); -+ } -+ for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){ -+ char *zSql2 = sqlite3_mprintf(zInsertFmt[pAr->bZip], zTab, -+ pAr->bVerbose ? "shell_putsnl(name)" : "name", -+ pAr->azArg[i], pAr->zDir); -+ rc = arExecSql(pAr, zSql2); -+ sqlite3_free(zSql2); -+ } -+end_ar_transaction: -+ if( rc!=SQLITE_OK ){ -+ arExecSql(pAr, "ROLLBACK TO ar; RELEASE ar;"); -+ }else{ -+ rc = arExecSql(pAr, "RELEASE ar;"); -+ if( pAr->bZip && pAr->zFile ){ -+ zSql = sqlite3_mprintf("DROP TABLE %s", zTemp); -+ arExecSql(pAr, zSql); -+ sqlite3_free(zSql); -+ } -+ } -+ return rc; -+} -+ -+/* -+** Implementation of ".ar" dot command. -+*/ -+static int arDotCommand( -+ ShellState *pState, /* Current shell tool state */ -+ int fromCmdLine, /* True if -A command-line option, not .ar cmd */ -+ char **azArg, /* Array of arguments passed to dot command */ -+ int nArg /* Number of entries in azArg[] */ -+){ -+ ArCommand cmd; -+ int rc; -+ memset(&cmd, 0, sizeof(cmd)); -+ cmd.fromCmdLine = fromCmdLine; -+ rc = arParseCommand(azArg, nArg, &cmd); -+ if( rc==SQLITE_OK ){ -+ int eDbType = SHELL_OPEN_UNSPEC; -+ cmd.p = pState; -+ cmd.db = pState->db; -+ if( cmd.zFile ){ -+ eDbType = deduceDatabaseType(cmd.zFile, 1); -+ }else{ -+ eDbType = pState->openMode; -+ } -+ if( eDbType==SHELL_OPEN_ZIPFILE ){ -+ if( cmd.eCmd==AR_CMD_EXTRACT || cmd.eCmd==AR_CMD_LIST ){ -+ if( cmd.zFile==0 ){ -+ cmd.zSrcTable = sqlite3_mprintf("zip"); -+ }else{ -+ cmd.zSrcTable = sqlite3_mprintf("zipfile(%Q)", cmd.zFile); -+ } -+ } -+ cmd.bZip = 1; -+ }else if( cmd.zFile ){ -+ int flags; -+ if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS; -+ if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_UPDATE ){ -+ flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; -+ }else{ -+ flags = SQLITE_OPEN_READONLY; -+ } -+ cmd.db = 0; -+ if( cmd.bDryRun ){ -+ utf8_printf(pState->out, "-- open database '%s'%s\n", cmd.zFile, -+ eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : ""); -+ } -+ rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags, -+ eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0); -+ if( rc!=SQLITE_OK ){ -+ utf8_printf(stderr, "cannot open file: %s (%s)\n", -+ cmd.zFile, sqlite3_errmsg(cmd.db) -+ ); -+ goto end_ar_command; -+ } -+ sqlite3_fileio_init(cmd.db, 0, 0); -+ sqlite3_sqlar_init(cmd.db, 0, 0); -+ sqlite3_create_function(cmd.db, "shell_putsnl", 1, SQLITE_UTF8, cmd.p, -+ shellPutsFunc, 0, 0); -+ -+ } -+ if( cmd.zSrcTable==0 && cmd.bZip==0 && cmd.eCmd!=AR_CMD_HELP ){ -+ if( cmd.eCmd!=AR_CMD_CREATE -+ && sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0) -+ ){ -+ utf8_printf(stderr, "database does not contain an 'sqlar' table\n"); -+ rc = SQLITE_ERROR; -+ goto end_ar_command; -+ } -+ cmd.zSrcTable = sqlite3_mprintf("sqlar"); -+ } -+ -+ switch( cmd.eCmd ){ -+ case AR_CMD_CREATE: -+ rc = arCreateOrUpdateCommand(&cmd, 0); -+ break; -+ -+ case AR_CMD_EXTRACT: -+ rc = arExtractCommand(&cmd); -+ break; -+ -+ case AR_CMD_LIST: -+ rc = arListCommand(&cmd); -+ break; -+ -+ case AR_CMD_HELP: -+ arUsage(pState->out); -+ break; -+ -+ default: -+ assert( cmd.eCmd==AR_CMD_UPDATE ); -+ rc = arCreateOrUpdateCommand(&cmd, 1); -+ break; -+ } -+ } -+end_ar_command: -+ if( cmd.db!=pState->db ){ -+ close_db(cmd.db); -+ } -+ sqlite3_free(cmd.zSrcTable); -+ -+ return rc; -+} -+/* End of the ".archive" or ".ar" command logic -+**********************************************************************************/ -+#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */ -+ -+ -+/* - ** If an input line begins with "." then invoke this routine to - ** process that line. - ** -@@ -5433,6 +13262,12 @@ - int rc = 0; - char *azArg[50]; - -+#ifndef SQLITE_OMIT_VIRTUALTABLE -+ if( p->expert.pExpert ){ -+ expertFinish(p, 1, 0); -+ } -+#endif -+ - /* Parse the input line into tokens. - */ - while( zLine[h] && nArg<ArraySize(azArg) ){ -@@ -5462,6 +13297,7 @@ - if( nArg==0 ) return 0; /* no tokens, no error */ - n = strlen30(azArg[0]); - c = azArg[0][0]; -+ clearTempFile(p); - - #ifndef SQLITE_OMIT_AUTHORIZATION - if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){ -@@ -5479,6 +13315,13 @@ - }else - #endif - -+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) -+ if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){ -+ open_db(p, 0); -+ rc = arDotCommand(p, 0, azArg, nArg); -+ }else -+#endif -+ - if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0) - || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0) - ){ -@@ -5487,11 +13330,14 @@ - sqlite3 *pDest; - sqlite3_backup *pBackup; - int j; -+ const char *zVfs = 0; - for(j=1; j<nArg; j++){ - const char *z = azArg[j]; - if( z[0]=='-' ){ -- while( z[0]=='-' ) z++; -- /* No options to process at this time */ -+ if( z[1]=='-' ) z++; -+ if( strcmp(z, "-append")==0 ){ -+ zVfs = "apndvfs"; -+ }else - { - utf8_printf(stderr, "unknown option: %s\n", azArg[j]); - return 1; -@@ -5502,7 +13348,7 @@ - zDb = zDestFile; - zDestFile = azArg[j]; - }else{ -- raw_printf(stderr, "too many arguments to .backup\n"); -+ raw_printf(stderr, "Usage: .backup ?DB? ?--append? FILENAME\n"); - return 1; - } - } -@@ -5511,10 +13357,11 @@ - return 1; - } - if( zDb==0 ) zDb = "main"; -- rc = sqlite3_open(zDestFile, &pDest); -+ rc = sqlite3_open_v2(zDestFile, &pDest, -+ SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs); - if( rc!=SQLITE_OK ){ - utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile); -- sqlite3_close(pDest); -+ close_db(pDest); - return 1; - } - open_db(p, 0); -@@ -5521,7 +13368,7 @@ - pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb); - if( pBackup==0 ){ - utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); -- sqlite3_close(pDest); -+ close_db(pDest); - return 1; - } - while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){} -@@ -5532,7 +13379,7 @@ - utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); - rc = 1; - } -- sqlite3_close(pDest); -+ close_db(pDest); - }else - - if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){ -@@ -5609,7 +13456,7 @@ - utf8_printf(stderr, - "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", - p->zTestcase, azArg[1], zRes); -- rc = 2; -+ rc = 1; - }else{ - utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase); - p->nCheck++; -@@ -5644,7 +13491,39 @@ - } - }else - -- if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){ -+ if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){ -+ static const struct DbConfigChoices { -+ const char *zName; -+ int op; -+ } aDbConfig[] = { -+ { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY }, -+ { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER }, -+ { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, -+ { "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 }, -+ }; -+ int ii, v; -+ open_db(p, 0); -+ for(ii=0; ii<ArraySize(aDbConfig); ii++){ -+ if( nArg>1 && strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue; -+ if( nArg>=3 ){ -+ 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"); -+ if( nArg>1 ) break; -+ } -+ if( nArg>1 && ii==ArraySize(aDbConfig) ){ -+ utf8_printf(stderr, "Error: unknown dbconfig \"%s\"\n", azArg[1]); -+ utf8_printf(stderr, "Enter \".dbconfig\" with no arguments for a list\n"); -+ } -+ }else -+ -+ if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){ - rc = shell_dbinfo_command(p, nArg, azArg); - }else - -@@ -5652,7 +13531,8 @@ - const char *zLike = 0; - int i; - int savedShowHeader = p->showHeader; -- ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines); -+ int savedShellFlags = p->shellFlgs; -+ ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo); - for(i=1; i<nArg; i++){ - if( azArg[i][0]=='-' ){ - const char *z = azArg[i]+1; -@@ -5734,6 +13614,7 @@ - sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0); - raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n"); - p->showHeader = savedShowHeader; -+ p->shellFlgs = savedShellFlags; - }else - - if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){ -@@ -5747,13 +13628,19 @@ - - if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){ - if( nArg==2 ){ -+ p->autoEQPtest = 0; - if( strcmp(azArg[1],"full")==0 ){ -- p->autoEQP = 2; -+ p->autoEQP = AUTOEQP_full; -+ }else if( strcmp(azArg[1],"trigger")==0 ){ -+ p->autoEQP = AUTOEQP_trigger; -+ }else if( strcmp(azArg[1],"test")==0 ){ -+ p->autoEQP = AUTOEQP_on; -+ p->autoEQPtest = 1; - }else{ -- p->autoEQP = booleanValue(azArg[1]); -+ p->autoEQP = (u8)booleanValue(azArg[1]); - } - }else{ -- raw_printf(stderr, "Usage: .eqp on|off|full\n"); -+ raw_printf(stderr, "Usage: .eqp off|on|trigger|full\n"); - rc = 1; - } - }else -@@ -5787,6 +13674,13 @@ - } - }else - -+#ifndef SQLITE_OMIT_VIRTUALTABLE -+ if( c=='e' && strncmp(azArg[0], "expert", n)==0 ){ -+ open_db(p, 0); -+ expertDotCommand(p, azArg, nArg); -+ }else -+#endif -+ - if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){ - ShellState data; - char *zErrMsg = 0; -@@ -5830,14 +13724,11 @@ - callback, &data, &zErrMsg); - data.cMode = data.mode = MODE_Insert; - data.zDestTable = "sqlite_stat1"; -- shell_exec(p->db, "SELECT * FROM sqlite_stat1", -- shell_callback, &data,&zErrMsg); -+ shell_exec(&data, "SELECT * FROM sqlite_stat1", &zErrMsg); - data.zDestTable = "sqlite_stat3"; -- shell_exec(p->db, "SELECT * FROM sqlite_stat3", -- shell_callback, &data,&zErrMsg); -+ shell_exec(&data, "SELECT * FROM sqlite_stat3", &zErrMsg); - data.zDestTable = "sqlite_stat4"; -- shell_exec(p->db, "SELECT * FROM sqlite_stat4", -- shell_callback, &data, &zErrMsg); -+ shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg); - raw_printf(p->out, "ANALYZE sqlite_master;\n"); - } - }else -@@ -5852,7 +13743,14 @@ - }else - - if( c=='h' && strncmp(azArg[0], "help", n)==0 ){ -- utf8_printf(p->out, "%s", zHelp); -+ if( nArg>=2 ){ -+ n = showHelp(p->out, azArg[1]); -+ if( n==0 ){ -+ utf8_printf(p->out, "Nothing matches '%s'\n", azArg[1]); -+ } -+ }else{ -+ showHelp(p->out, 0); -+ } - }else - - if( c=='i' && strncmp(azArg[0], "import", n)==0 ){ -@@ -5935,9 +13833,8 @@ - sCtx.cRowSep = p->rowSeparator[0]; - zSql = sqlite3_mprintf("SELECT * FROM %s", zTable); - if( zSql==0 ){ -- raw_printf(stderr, "Error: out of memory\n"); - xCloser(sCtx.in); -- return 1; -+ shell_out_of_memory(); - } - nByte = strlen30(zSql); - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); -@@ -5982,9 +13879,8 @@ - if( nCol==0 ) return 0; /* no columns, no error */ - zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 ); - if( zSql==0 ){ -- raw_printf(stderr, "Error: out of memory\n"); - xCloser(sCtx.in); -- return 1; -+ shell_out_of_memory(); - } - sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable); - j = strlen30(zSql); -@@ -6060,12 +13956,17 @@ - sqlite3_stmt *pStmt; - int tnum = 0; - int i; -- if( nArg!=3 ){ -- utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n"); -+ if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){ -+ utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n" -+ " .imposter off\n"); - rc = 1; - goto meta_command_exit; - } - open_db(p, 0); -+ if( nArg==2 ){ -+ 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]); - sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); -@@ -6241,13 +14142,13 @@ - }else{ - const char *zFile = azArg[1]; - output_file_close(p->pLog); -- p->pLog = output_file_open(zFile); -+ p->pLog = output_file_open(zFile, 0); - } - }else - - if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){ - const char *zMode = nArg>=2 ? azArg[1] : ""; -- int n2 = (int)strlen(zMode); -+ int n2 = strlen30(zMode); - int c2 = zMode[0]; - if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){ - p->mode = MODE_Line; -@@ -6307,16 +14208,29 @@ - int newFlag = 0; /* True to delete file before opening */ - /* Close the existing database */ - session_close_all(p); -- sqlite3_close(p->db); -+ close_db(p->db); - p->db = 0; - p->zDbFilename = 0; - sqlite3_free(p->zFreeOnClose); - p->zFreeOnClose = 0; -+ p->openMode = SHELL_OPEN_UNSPEC; - /* Check for command-line arguments */ - for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){ - const char *z = azArg[iName]; - if( optionMatch(z,"new") ){ - newFlag = 1; -+#ifdef SQLITE_HAVE_ZLIB -+ }else if( optionMatch(z, "zip") ){ -+ p->openMode = SHELL_OPEN_ZIPFILE; -+#endif -+ }else if( optionMatch(z, "append") ){ -+ p->openMode = SHELL_OPEN_APPENDVFS; -+ }else if( optionMatch(z, "readonly") ){ -+ p->openMode = SHELL_OPEN_READONLY; -+#ifdef SQLITE_ENABLE_DESERIALIZE -+ }else if( optionMatch(z, "deserialize") ){ -+ p->openMode = SHELL_OPEN_DESERIALIZE; -+#endif - }else if( z[0]=='-' ){ - utf8_printf(stderr, "unknown option: %s\n", z); - rc = 1; -@@ -6328,7 +14242,7 @@ - if( zNewFilename ){ - if( newFlag ) shellDeleteFile(zNewFilename); - p->zDbFilename = zNewFilename; -- open_db(p, 1); -+ open_db(p, OPEN_DB_KEEPALIVE); - if( p->db==0 ){ - utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename); - sqlite3_free(zNewFilename); -@@ -6343,18 +14257,27 @@ - } - }else - -- if( c=='o' -- && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0) -+ if( (c=='o' -+ && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0)) -+ || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0) - ){ - const char *zFile = nArg>=2 ? azArg[1] : "stdout"; -+ int bTxtMode = 0; -+ if( azArg[0][0]=='e' ){ -+ /* Transform the ".excel" command into ".once -x" */ -+ nArg = 2; -+ azArg[0] = "once"; -+ zFile = azArg[1] = "-x"; -+ n = 4; -+ } - if( nArg>2 ){ -- utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]); -+ utf8_printf(stderr, "Usage: .%s [-e|-x|FILE]\n", azArg[0]); - rc = 1; - goto meta_command_exit; - } - if( n>1 && strncmp(azArg[0], "once", n)==0 ){ - if( nArg<2 ){ -- raw_printf(stderr, "Usage: .once FILE\n"); -+ raw_printf(stderr, "Usage: .once (-e|-x|FILE)\n"); - rc = 1; - goto meta_command_exit; - } -@@ -6363,6 +14286,23 @@ - p->outCount = 0; - } - output_reset(p); -+ if( zFile[0]=='-' && zFile[1]=='-' ) zFile++; -+#ifndef SQLITE_NOHAVE_SYSTEM -+ if( strcmp(zFile, "-e")==0 || strcmp(zFile, "-x")==0 ){ -+ p->doXdgOpen = 1; -+ outputModePush(p); -+ if( zFile[1]=='x' ){ -+ newTempFile(p, "csv"); -+ p->mode = MODE_Csv; -+ sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); -+ sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); -+ }else{ -+ newTempFile(p, "txt"); -+ bTxtMode = 1; -+ } -+ zFile = p->zTempFile; -+ } -+#endif /* SQLITE_NOHAVE_SYSTEM */ - if( zFile[0]=='|' ){ - #ifdef SQLITE_OMIT_POPEN - raw_printf(stderr, "Error: pipes are not supported in this OS\n"); -@@ -6379,7 +14319,7 @@ - } - #endif - }else{ -- p->out = output_file_open(zFile); -+ p->out = output_file_open(zFile, bTxtMode); - if( p->out==0 ){ - if( strcmp(zFile,"off")!=0 ){ - utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile); -@@ -6452,7 +14392,7 @@ - rc = sqlite3_open(zSrcFile, &pSrc); - if( rc!=SQLITE_OK ){ - utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile); -- sqlite3_close(pSrc); -+ close_db(pSrc); - return 1; - } - open_db(p, 0); -@@ -6459,7 +14399,7 @@ - pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main"); - if( pBackup==0 ){ - utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); -- sqlite3_close(pSrc); -+ close_db(pSrc); - return 1; - } - while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK -@@ -6479,13 +14419,12 @@ - utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); - rc = 1; - } -- sqlite3_close(pSrc); -+ close_db(pSrc); - }else - -- - if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){ - if( nArg==2 ){ -- p->scanstatsOn = booleanValue(azArg[1]); -+ p->scanstatsOn = (u8)booleanValue(azArg[1]); - #ifndef SQLITE_ENABLE_STMT_SCANSTATUS - raw_printf(stderr, "Warning: .scanstats not available in this build.\n"); - #endif -@@ -6499,8 +14438,11 @@ - ShellText sSelect; - ShellState data; - char *zErrMsg = 0; -- const char *zDiv = 0; -+ const char *zDiv = "("; -+ const char *zName = 0; - int iSchema = 0; -+ int bDebug = 0; -+ int ii; - - open_db(p, 0); - memcpy(&data, p, sizeof(data)); -@@ -6507,51 +14449,37 @@ - data.showHeader = 0; - data.cMode = data.mode = MODE_Semi; - initText(&sSelect); -- if( nArg>=2 && optionMatch(azArg[1], "indent") ){ -- data.cMode = data.mode = MODE_Pretty; -- nArg--; -- if( nArg==2 ) azArg[1] = azArg[2]; -+ for(ii=1; ii<nArg; ii++){ -+ if( optionMatch(azArg[ii],"indent") ){ -+ data.cMode = data.mode = MODE_Pretty; -+ }else if( optionMatch(azArg[ii],"debug") ){ -+ bDebug = 1; -+ }else if( zName==0 ){ -+ zName = azArg[ii]; -+ }else{ -+ raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n"); -+ rc = 1; -+ goto meta_command_exit; -+ } - } -- if( nArg==2 && azArg[1][0]!='-' ){ -- int i; -- for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]); -- if( strcmp(azArg[1],"sqlite_master")==0 ){ -+ if( zName!=0 ){ -+ int isMaster = sqlite3_strlike(zName, "sqlite_master", '\\')==0; -+ if( isMaster || sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0 ){ - char *new_argv[2], *new_colv[2]; -- new_argv[0] = "CREATE TABLE sqlite_master (\n" -+ new_argv[0] = sqlite3_mprintf( -+ "CREATE TABLE %s (\n" - " type text,\n" - " name text,\n" - " tbl_name text,\n" - " rootpage integer,\n" - " sql text\n" -- ")"; -+ ")", isMaster ? "sqlite_master" : "sqlite_temp_master"); - new_argv[1] = 0; - new_colv[0] = "sql"; - new_colv[1] = 0; - callback(&data, 1, new_argv, new_colv); -- rc = SQLITE_OK; -- }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){ -- char *new_argv[2], *new_colv[2]; -- new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n" -- " type text,\n" -- " name text,\n" -- " tbl_name text,\n" -- " rootpage integer,\n" -- " sql text\n" -- ")"; -- new_argv[1] = 0; -- new_colv[0] = "sql"; -- new_colv[1] = 0; -- callback(&data, 1, new_argv, new_colv); -- rc = SQLITE_OK; -- }else{ -- zDiv = "("; -+ sqlite3_free(new_argv[0]); - } -- }else if( nArg==1 ){ -- zDiv = "("; -- }else{ -- raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n"); -- rc = 1; -- goto meta_command_exit; - } - if( zDiv ){ - sqlite3_stmt *pStmt = 0; -@@ -6571,39 +14499,53 @@ - sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema); - appendText(&sSelect, zDiv, 0); - zDiv = " UNION ALL "; -- if( strcmp(zDb, "main")!=0 ){ -- appendText(&sSelect, "SELECT shell_add_schema(sql,", 0); -+ appendText(&sSelect, "SELECT shell_add_schema(sql,", 0); -+ if( sqlite3_stricmp(zDb, "main")!=0 ){ - appendText(&sSelect, zDb, '"'); -- appendText(&sSelect, ") AS sql, type, tbl_name, name, rowid,", 0); -- appendText(&sSelect, zScNum, 0); -- appendText(&sSelect, " AS snum, ", 0); -- appendText(&sSelect, zDb, '\''); -- appendText(&sSelect, " AS sname FROM ", 0); -- appendText(&sSelect, zDb, '"'); -- appendText(&sSelect, ".sqlite_master", 0); - }else{ -- appendText(&sSelect, "SELECT sql, type, tbl_name, name, rowid, ", 0); -- appendText(&sSelect, zScNum, 0); -- appendText(&sSelect, " AS snum, 'main' AS sname FROM sqlite_master",0); -+ appendText(&sSelect, "NULL", 0); - } -+ appendText(&sSelect, ",name) AS sql, type, tbl_name, name, rowid,", 0); -+ appendText(&sSelect, zScNum, 0); -+ appendText(&sSelect, " AS snum, ", 0); -+ appendText(&sSelect, zDb, '\''); -+ appendText(&sSelect, " AS sname FROM ", 0); -+ appendText(&sSelect, zDb, '"'); -+ appendText(&sSelect, ".sqlite_master", 0); - } - sqlite3_finalize(pStmt); -+#ifdef SQLITE_INTROSPECTION_PRAGMAS -+ if( zName ){ -+ appendText(&sSelect, -+ " UNION ALL SELECT shell_module_schema(name)," -+ " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list", 0); -+ } -+#endif - appendText(&sSelect, ") WHERE ", 0); -- if( nArg>1 ){ -- char *zQarg = sqlite3_mprintf("%Q", azArg[1]); -- if( strchr(azArg[1], '.') ){ -+ if( zName ){ -+ char *zQarg = sqlite3_mprintf("%Q", zName); -+ int bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 || -+ strchr(zName, '[') != 0; -+ if( strchr(zName, '.') ){ - appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0); - }else{ - appendText(&sSelect, "lower(tbl_name)", 0); - } -- appendText(&sSelect, strchr(azArg[1], '*') ? " GLOB " : " LIKE ", 0); -+ appendText(&sSelect, bGlob ? " GLOB " : " LIKE ", 0); - appendText(&sSelect, zQarg, 0); -+ if( !bGlob ){ -+ appendText(&sSelect, " ESCAPE '\\' ", 0); -+ } - appendText(&sSelect, " AND ", 0); - sqlite3_free(zQarg); - } - appendText(&sSelect, "type!='meta' AND sql IS NOT NULL" - " ORDER BY snum, rowid", 0); -- rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg); -+ if( bDebug ){ -+ utf8_printf(p->out, "SQL: %s;\n", sSelect.z); -+ }else{ -+ rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg); -+ } - freeText(&sSelect); - } - if( zErrMsg ){ -@@ -6816,7 +14758,7 @@ - }else - /* If no command name matches, show a syntax error */ - session_syntax_error: -- session_help(p); -+ showHelp(p->out, "session"); - }else - #endif - -@@ -6997,7 +14939,7 @@ - utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n", - azArg[i], azArg[0]); - raw_printf(stderr, "Should be one of: --schema" -- " --sha3-224 --sha3-255 --sha3-384 --sha3-512\n"); -+ " --sha3-224 --sha3-256 --sha3-384 --sha3-512\n"); - rc = 1; - goto meta_command_exit; - } -@@ -7008,7 +14950,7 @@ - }else{ - zLike = z; - bSeparate = 1; -- if( sqlite3_strlike("sqlite_%", zLike, 0)==0 ) bSchema = 1; -+ if( sqlite3_strlike("sqlite\\_%", zLike, '\\')==0 ) bSchema = 1; - } - } - if( bSchema ){ -@@ -7075,11 +15017,12 @@ - if( bDebug ){ - utf8_printf(p->out, "%s\n", zSql); - }else{ -- shell_exec(p->db, zSql, shell_callback, p, 0); -+ shell_exec(p, zSql, 0); - } - sqlite3_free(zSql); - }else - -+#ifndef SQLITE_NOHAVE_SYSTEM - if( c=='s' - && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) - ){ -@@ -7099,9 +15042,10 @@ - sqlite3_free(zCmd); - if( x ) raw_printf(stderr, "System command returns %d\n", x); - }else -+#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */ - - if( c=='s' && strncmp(azArg[0], "show", n)==0 ){ -- static const char *azBool[] = { "off", "on", "full", "unk" }; -+ static const char *azBool[] = { "off", "on", "trigger", "full"}; - int i; - if( nArg!=1 ){ - raw_printf(stderr, "Usage: .show\n"); -@@ -7138,7 +15082,7 @@ - - if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){ - if( nArg==2 ){ -- p->statsOn = booleanValue(azArg[1]); -+ p->statsOn = (u8)booleanValue(azArg[1]); - }else if( nArg==1 ){ - display_stats(p->db, p, 0); - }else{ -@@ -7159,7 +15103,10 @@ - initText(&s); - open_db(p, 0); - rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0); -- if( rc ) return shellDatabaseError(p->db); -+ if( rc ){ -+ sqlite3_finalize(pStmt); -+ return shellDatabaseError(p->db); -+ } - - if( nArg>2 && c=='i' ){ - /* It is an historical accident that the .indexes command shows an error -@@ -7167,6 +15114,7 @@ - ** command does not. */ - raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n"); - rc = 1; -+ sqlite3_finalize(pStmt); - goto meta_command_exit; - } - for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){ -@@ -7211,18 +15159,12 @@ - char **azNew; - int n2 = nAlloc*2 + 10; - azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2); -- if( azNew==0 ){ -- rc = shellNomemError(); -- break; -- } -+ if( azNew==0 ) shell_out_of_memory(); - nAlloc = n2; - azResult = azNew; - } - azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); -- if( 0==azResult[nRow] ){ -- rc = shellNomemError(); -- break; -- } -+ if( 0==azResult[nRow] ) shell_out_of_memory(); - nRow++; - } - if( sqlite3_finalize(pStmt)!=SQLITE_OK ){ -@@ -7258,7 +15200,7 @@ - /* Begin redirecting output to the file "testcase-out.txt" */ - if( c=='t' && strcmp(azArg[0],"testcase")==0 ){ - output_reset(p); -- p->out = output_file_open("testcase-out.txt"); -+ p->out = output_file_open("testcase-out.txt", 0); - if( p->out==0 ){ - raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n"); - } -@@ -7270,50 +15212,78 @@ - }else - - #ifndef SQLITE_UNTESTABLE -- if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){ -+ if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){ - static const struct { - const char *zCtrlName; /* Name of a test-control option */ - int ctrlCode; /* Integer code for that option */ -+ const char *zUsage; /* Usage notes */ - } aCtrl[] = { -- { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE }, -- { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE }, -- { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET }, -- { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST }, -- { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL }, -- { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS }, -- { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE }, -- { "assert", SQLITE_TESTCTRL_ASSERT }, -- { "always", SQLITE_TESTCTRL_ALWAYS }, -- { "reserve", SQLITE_TESTCTRL_RESERVE }, -- { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, -- { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, -- { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, -- { "byteorder", SQLITE_TESTCTRL_BYTEORDER }, -- { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT }, -- { "imposter", SQLITE_TESTCTRL_IMPOSTER }, -+ { "always", SQLITE_TESTCTRL_ALWAYS, "BOOLEAN" }, -+ { "assert", SQLITE_TESTCTRL_ASSERT, "BOOLEAN" }, -+ /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/ -+ /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/ -+ { "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" }, -+ /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" }, */ -+ { "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"}, -+ { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN" }, -+ { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" }, -+ { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" }, -+ { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" }, -+#ifdef YYCOVERAGE -+ { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" }, -+#endif -+ { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " }, -+ { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET, "" }, -+ { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" }, -+ { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" }, -+ { "reserve", SQLITE_TESTCTRL_RESERVE, "BYTES-OF-RESERVE" }, - }; - int testctrl = -1; -- int rc2 = 0; -+ int iCtrl = -1; -+ int rc2 = 0; /* 0: usage. 1: %d 2: %x 3: no-output */ -+ int isOk = 0; - int i, n2; -+ const char *zCmd = 0; -+ - open_db(p, 0); -+ zCmd = nArg>=2 ? azArg[1] : "help"; - -+ /* The argument can optionally begin with "-" or "--" */ -+ if( zCmd[0]=='-' && zCmd[1] ){ -+ zCmd++; -+ if( zCmd[0]=='-' && zCmd[1] ) zCmd++; -+ } -+ -+ /* --help lists all test-controls */ -+ if( strcmp(zCmd,"help")==0 ){ -+ utf8_printf(p->out, "Available test-controls:\n"); -+ for(i=0; i<ArraySize(aCtrl); i++){ -+ utf8_printf(p->out, " .testctrl %s %s\n", -+ aCtrl[i].zCtrlName, aCtrl[i].zUsage); -+ } -+ rc = 1; -+ goto meta_command_exit; -+ } -+ - /* convert testctrl text option to value. allow any unique prefix - ** of the option name, or a numerical value. */ -- n2 = strlen30(azArg[1]); -+ n2 = strlen30(zCmd); - for(i=0; i<ArraySize(aCtrl); i++){ -- if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){ -+ if( strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){ - if( testctrl<0 ){ - testctrl = aCtrl[i].ctrlCode; -+ iCtrl = i; - }else{ -- utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]); -- testctrl = -1; -- break; -+ utf8_printf(stderr, "Error: ambiguous test-control: \"%s\"\n" -+ "Use \".testctrl --help\" for help\n", zCmd); -+ rc = 1; -+ goto meta_command_exit; - } - } - } -- if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]); -- if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){ -- utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]); -+ if( testctrl<0 ){ -+ utf8_printf(stderr,"Error: unknown test-control: %s\n" -+ "Use \".testctrl --help\" for help\n", zCmd); - }else{ - switch(testctrl){ - -@@ -7323,10 +15293,7 @@ - if( nArg==3 ){ - int opt = (int)strtol(azArg[2], 0, 0); - rc2 = sqlite3_test_control(testctrl, p->db, opt); -- raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); -- } else { -- utf8_printf(stderr,"Error: testctrl %s takes a single int option\n", -- azArg[1]); -+ isOk = 3; - } - break; - -@@ -7337,10 +15304,7 @@ - case SQLITE_TESTCTRL_BYTEORDER: - if( nArg==2 ){ - rc2 = sqlite3_test_control(testctrl); -- raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); -- } else { -- utf8_printf(stderr,"Error: testctrl %s takes no options\n", -- azArg[1]); -+ isOk = testctrl==SQLITE_TESTCTRL_BYTEORDER ? 1 : 3; - } - break; - -@@ -7349,10 +15313,7 @@ - if( nArg==3 ){ - unsigned int opt = (unsigned int)integerValue(azArg[2]); - rc2 = sqlite3_test_control(testctrl, opt); -- raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); -- } else { -- utf8_printf(stderr,"Error: testctrl %s takes a single unsigned" -- " int option\n", azArg[1]); -+ isOk = 3; - } - break; - -@@ -7359,31 +15320,23 @@ - /* sqlite3_test_control(int, int) */ - case SQLITE_TESTCTRL_ASSERT: - case SQLITE_TESTCTRL_ALWAYS: -- case SQLITE_TESTCTRL_NEVER_CORRUPT: -+ case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: - if( nArg==3 ){ - int opt = booleanValue(azArg[2]); - rc2 = sqlite3_test_control(testctrl, opt); -- raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); -- } else { -- utf8_printf(stderr,"Error: testctrl %s takes a single int option\n", -- azArg[1]); -+ isOk = 1; - } - break; - -- /* sqlite3_test_control(int, char *) */ --#ifdef SQLITE_N_KEYWORD -- case SQLITE_TESTCTRL_ISKEYWORD: -+ /* sqlite3_test_control(int, int) */ -+ case SQLITE_TESTCTRL_LOCALTIME_FAULT: -+ case SQLITE_TESTCTRL_NEVER_CORRUPT: - if( nArg==3 ){ -- const char *opt = azArg[2]; -+ int opt = booleanValue(azArg[2]); - rc2 = sqlite3_test_control(testctrl, opt); -- raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); -- } else { -- utf8_printf(stderr, -- "Error: testctrl %s takes a single char * option\n", -- azArg[1]); -+ isOk = 3; - } - break; --#endif - - case SQLITE_TESTCTRL_IMPOSTER: - if( nArg==5 ){ -@@ -7391,23 +15344,27 @@ - azArg[2], - integerValue(azArg[3]), - integerValue(azArg[4])); -- raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); -- }else{ -- raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n"); -+ isOk = 3; - } - break; - -- case SQLITE_TESTCTRL_BITVEC_TEST: -- case SQLITE_TESTCTRL_FAULT_INSTALL: -- case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: -- case SQLITE_TESTCTRL_SCRATCHMALLOC: -- default: -- utf8_printf(stderr, -- "Error: CLI support for testctrl %s not implemented\n", -- azArg[1]); -- break; -+#ifdef YYCOVERAGE -+ case SQLITE_TESTCTRL_PARSER_COVERAGE: -+ if( nArg==2 ){ -+ sqlite3_test_control(testctrl, p->out); -+ isOk = 3; -+ } -+#endif - } - } -+ if( isOk==0 && iCtrl>=0 ){ -+ utf8_printf(p->out, "Usage: .testctrl %s %s\n", zCmd, aCtrl[iCtrl].zUsage); -+ rc = 1; -+ }else if( isOk==1 ){ -+ raw_printf(p->out, "%d\n", rc2); -+ }else if( isOk==2 ){ -+ raw_printf(p->out, "0x%08x\n", rc2); -+ } - }else - #endif /* !defined(SQLITE_UNTESTABLE) */ - -@@ -7437,7 +15394,7 @@ - goto meta_command_exit; - } - output_file_close(p->traceOut); -- p->traceOut = output_file_open(azArg[1]); -+ p->traceOut = output_file_open(azArg[1], 0); - #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) - if( p->traceOut==0 ){ - sqlite3_trace_v2(p->db, 0, 0, 0); -@@ -7461,8 +15418,7 @@ - rc = 1; - goto meta_command_exit; - } -- rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], -- (int)strlen(azArg[3])); -+ rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], strlen30(azArg[3])); - if( rc ){ - utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]); - rc = 1; -@@ -7473,8 +15429,7 @@ - rc = 1; - goto meta_command_exit; - } -- rc = sqlite3_user_add(p->db, azArg[2], -- azArg[3], (int)strlen(azArg[3]), -+ rc = sqlite3_user_add(p->db, azArg[2], azArg[3], strlen30(azArg[3]), - booleanValue(azArg[4])); - if( rc ){ - raw_printf(stderr, "User-Add failed: %d\n", rc); -@@ -7486,8 +15441,7 @@ - rc = 1; - goto meta_command_exit; - } -- rc = sqlite3_user_change(p->db, azArg[2], -- azArg[3], (int)strlen(azArg[3]), -+ rc = sqlite3_user_change(p->db, azArg[2], azArg[3], strlen30(azArg[3]), - booleanValue(azArg[4])); - if( rc ){ - raw_printf(stderr, "User-Edit failed: %d\n", rc); -@@ -7515,6 +15469,20 @@ - if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ - utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/, - sqlite3_libversion(), sqlite3_sourceid()); -+#if SQLITE_HAVE_ZLIB -+ utf8_printf(p->out, "zlib version %s\n", zlibVersion()); -+#endif -+#define CTIMEOPT_VAL_(opt) #opt -+#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) -+#if defined(__clang__) && defined(__clang_major__) -+ utf8_printf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "." -+ CTIMEOPT_VAL(__clang_minor__) "." -+ CTIMEOPT_VAL(__clang_patchlevel__) "\n"); -+#elif defined(_MSC_VER) -+ utf8_printf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) "\n"); -+#elif defined(__GNUC__) && defined(__VERSION__) -+ utf8_printf(p->out, "gcc-" __VERSION__ "\n"); -+#endif - }else - - if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){ -@@ -7641,6 +15609,16 @@ - } - - /* -+** We need a default sqlite3_complete() implementation to use in case -+** the shell is compiled with SQLITE_OMIT_COMPLETE. The default assumes -+** any arbitrary text is a complete SQL statement. This is not very -+** user-friendly, but it does seem to work. -+*/ -+#ifdef SQLITE_OMIT_COMPLETE -+#define sqlite3_complete(x) 1 -+#endif -+ -+/* - ** Return true if zSql is a complete SQL statement. Return false if it - ** ends in the middle of a string literal or C-style comment. - */ -@@ -7655,7 +15633,7 @@ - } - - /* --** Run a single line of SQL -+** Run a single line of SQL. Return the number of errors. - */ - static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){ - int rc; -@@ -7664,7 +15642,7 @@ - open_db(p, 0); - if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql); - BEGIN_TIMER; -- rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg); -+ rc = shell_exec(p, zSql, &zErrMsg); - END_TIMER; - if( rc || zErrMsg ){ - char zPrefix[100]; -@@ -7728,13 +15706,15 @@ - if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine); - continue; - } -- if( zLine && zLine[0]=='.' && nSql==0 ){ -+ if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){ - if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine); -- rc = do_meta_command(zLine, p); -- if( rc==2 ){ /* exit requested */ -- break; -- }else if( rc ){ -- errCnt++; -+ if( zLine[0]=='.' ){ -+ rc = do_meta_command(zLine, p); -+ if( rc==2 ){ /* exit requested */ -+ break; -+ }else if( rc ){ -+ errCnt++; -+ } - } - continue; - } -@@ -7745,10 +15725,7 @@ - if( nSql+nLine+2>=nAlloc ){ - nAlloc = nSql+nLine+100; - zSql = realloc(zSql, nAlloc); -- if( zSql==0 ){ -- raw_printf(stderr, "Error: out of memory\n"); -- exit(1); -- } -+ if( zSql==0 ) shell_out_of_memory(); - } - nSqlPrior = nSql; - if( nSql==0 ){ -@@ -7770,6 +15747,8 @@ - if( p->outCount ){ - output_reset(p); - p->outCount = 0; -+ }else{ -+ clearTempFile(p); - } - }else if( nSql && _all_whitespace(zSql) ){ - if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql); -@@ -7777,7 +15756,7 @@ - } - } - if( nSql && !_all_whitespace(zSql) ){ -- runOneSqlLine(p, zSql, in, startline); -+ errCnt += runOneSqlLine(p, zSql, in, startline); - } - free(zSql); - free(zLine); -@@ -7875,7 +15854,6 @@ - " cannot read ~/.sqliterc\n"); - return; - } -- sqlite3_initialize(); - zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); - sqliterc = zBuf; - } -@@ -7894,6 +15872,10 @@ - ** Show available command line options - */ - static const char zOptions[] = -+#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE) -+ " -A ARGS... run \".archive ARGS\" and exit\n" -+#endif -+ " -append append the database to the end of the file\n" - " -ascii set output mode to 'ascii'\n" - " -bail stop after hitting an error\n" - " -batch force batch I/O\n" -@@ -7920,8 +15902,11 @@ - " -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" -- " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n" -+ " -readonly open the database read-only\n" - " -separator SEP set output column separator. Default: '|'\n" -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ " -sorterref SIZE sorter references threshold size\n" -+#endif - " -stats print memory stats before each finalize\n" - " -version show SQLite version\n" - " -vfs NAME use NAME as the default VFS\n" -@@ -7928,6 +15913,9 @@ - #ifdef SQLITE_ENABLE_VFSTRACE - " -vfstrace enable tracing of all VFS calls\n" - #endif -+#ifdef SQLITE_HAVE_ZLIB -+ " -zip open the file as a ZIP Archive\n" -+#endif - ; - static void usage(int showDetail){ - utf8_printf(stderr, -@@ -7943,6 +15931,17 @@ - } - - /* -+** Internal check: Verify that the SQLite is uninitialized. Print a -+** error message if it is initialized. -+*/ -+static void verify_uninitialized(void){ -+ if( sqlite3_config(-1)==SQLITE_MISUSE ){ -+ utf8_printf(stdout, "WARNING: attempt to configure SQLite after" -+ " initialization.\n"); -+ } -+} -+ -+/* - ** Initialize the state information in data - */ - static void main_init(ShellState *data) { -@@ -7953,6 +15952,7 @@ - memcpy(data->rowSeparator,SEP_Row, 2); - data->showHeader = 0; - data->shellFlgs = SHFLG_Lookaside; -+ verify_uninitialized(); - sqlite3_config(SQLITE_CONFIG_URI, 1); - sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); - sqlite3_config(SQLITE_CONFIG_MULTITHREAD); -@@ -8016,6 +16016,11 @@ - int readStdin = 1; - int nCmd = 0; - char **azCmd = 0; -+ const char *zVfs = 0; /* Value of -vfs command-line option */ -+#if !SQLITE_SHELL_IS_UTF8 -+ char **argvToFree = 0; -+ int argcToFree = 0; -+#endif - - setBinaryMode(stdin, 0); - setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ -@@ -8022,8 +16027,25 @@ - stdin_is_interactive = isatty(0); - stdout_is_console = isatty(1); - -+#if !defined(_WIN32_WCE) -+ if( getenv("SQLITE_DEBUG_BREAK") ){ -+ if( isatty(0) && isatty(2) ){ -+ fprintf(stderr, -+ "attach debugger to process %d and press any key to continue.\n", -+ GETPID()); -+ fgetc(stdin); -+ }else{ -+#if defined(_WIN32) || defined(WIN32) -+ DebugBreak(); -+#elif defined(SIGTRAP) -+ raise(SIGTRAP); -+#endif -+ } -+ } -+#endif -+ - #if USE_SYSTEM_SQLITE+0!=1 -- if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ -+ if( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){ - utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", - sqlite3_sourceid(), SQLITE_SOURCE_ID); - exit(1); -@@ -8030,21 +16052,33 @@ - } - #endif - main_init(&data); -+ -+ /* On Windows, we must translate command-line arguments into UTF-8. -+ ** The SQLite memory allocator subsystem has to be enabled in order to -+ ** do this. But we want to run an sqlite3_shutdown() afterwards so that -+ ** subsequent sqlite3_config() calls will work. So copy all results into -+ ** memory that does not come from the SQLite memory allocator. -+ */ - #if !SQLITE_SHELL_IS_UTF8 - sqlite3_initialize(); -- argv = sqlite3_malloc64(sizeof(argv[0])*argc); -- if( argv==0 ){ -- raw_printf(stderr, "out of memory\n"); -- exit(1); -- } -+ argvToFree = malloc(sizeof(argv[0])*argc*2); -+ argcToFree = argc; -+ argv = argvToFree + argc; -+ if( argv==0 ) shell_out_of_memory(); - for(i=0; i<argc; i++){ -- argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]); -- if( argv[i]==0 ){ -- raw_printf(stderr, "out of memory\n"); -- exit(1); -- } -+ char *z = sqlite3_win32_unicode_to_utf8(wargv[i]); -+ int n; -+ if( z==0 ) shell_out_of_memory(); -+ n = (int)strlen(z); -+ argv[i] = malloc( n+1 ); -+ if( argv[i]==0 ) shell_out_of_memory(); -+ memcpy(argv[i], z, n+1); -+ argvToFree[i] = argv[i]; -+ sqlite3_free(z); - } -+ sqlite3_shutdown(); - #endif -+ - assert( argc>=1 && argv && argv[0] ); - Argv0 = argv[0]; - -@@ -8053,6 +16087,8 @@ - */ - #ifdef SIGINT - signal(SIGINT, interrupt_handler); -+#elif (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE) -+ SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE); - #endif - - #ifdef SQLITE_SHELL_DBNAME_PROC -@@ -8072,6 +16108,7 @@ - ** the size of the alternative malloc heap, - ** and the first command to execute. - */ -+ verify_uninitialized(); - for(i=1; i<argc; i++){ - char *z; - z = argv[i]; -@@ -8084,10 +16121,7 @@ - readStdin = 0; - nCmd++; - azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd); -- if( azCmd==0 ){ -- raw_printf(stderr, "out of memory\n"); -- exit(1); -- } -+ if( azCmd==0 ) shell_out_of_memory(); - azCmd[nCmd-1] = z; - } - } -@@ -8118,16 +16152,6 @@ - #else - (void)cmdline_option_value(argc, argv, ++i); - #endif -- }else if( strcmp(z,"-scratch")==0 ){ -- int n, sz; -- sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); -- if( sz>400000 ) sz = 400000; -- if( sz<2500 ) sz = 2500; -- n = (int)integerValue(cmdline_option_value(argc,argv,++i)); -- if( n>10 ) n = 10; -- if( n<1 ) n = 1; -- sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n); -- data.shellFlgs |= SHFLG_Scratch; - }else if( strcmp(z,"-pagecache")==0 ){ - int n, sz; - sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); -@@ -8164,16 +16188,61 @@ - }else if( strcmp(z,"-mmap")==0 ){ - sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i)); - sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz); -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ }else if( strcmp(z,"-sorterref")==0 ){ -+ sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i)); -+ sqlite3_config(SQLITE_CONFIG_SORTERREF_SIZE, (int)sz); -+#endif - }else if( strcmp(z,"-vfs")==0 ){ -- sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i)); -- if( pVfs ){ -- sqlite3_vfs_register(pVfs, 1); -- }else{ -- utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]); -- exit(1); -- } -+ zVfs = cmdline_option_value(argc, argv, ++i); -+#ifdef SQLITE_HAVE_ZLIB -+ }else if( strcmp(z,"-zip")==0 ){ -+ data.openMode = SHELL_OPEN_ZIPFILE; -+#endif -+ }else if( strcmp(z,"-append")==0 ){ -+ data.openMode = SHELL_OPEN_APPENDVFS; -+#ifdef SQLITE_ENABLE_DESERIALIZE -+ }else if( strcmp(z,"-deserialize")==0 ){ -+ data.openMode = SHELL_OPEN_DESERIALIZE; -+#endif -+ }else if( strcmp(z,"-readonly")==0 ){ -+ data.openMode = SHELL_OPEN_READONLY; -+#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" -+ ** command, so ignore them */ -+ break; -+#endif - } - } -+ verify_uninitialized(); -+ -+ -+#ifdef SQLITE_SHELL_INIT_PROC -+ { -+ /* If the SQLITE_SHELL_INIT_PROC macro is defined, then it is the name -+ ** of a C-function that will perform initialization actions on SQLite that -+ ** occur just before or after sqlite3_initialize(). Use this compile-time -+ ** option to embed this shell program in larger applications. */ -+ extern void SQLITE_SHELL_INIT_PROC(void); -+ SQLITE_SHELL_INIT_PROC(); -+ } -+#else -+ /* All the sqlite3_config() calls have now been made. So it is safe -+ ** to call sqlite3_initialize() and process any command line -vfs option. */ -+ sqlite3_initialize(); -+#endif -+ -+ if( zVfs ){ -+ sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs); -+ if( pVfs ){ -+ sqlite3_vfs_register(pVfs, 1); -+ }else{ -+ utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]); -+ exit(1); -+ } -+ } -+ - if( data.zDbFilename==0 ){ - #ifndef SQLITE_OMIT_MEMORYDB - data.zDbFilename = ":memory:"; -@@ -8184,6 +16253,7 @@ - #endif - } - data.out = stdout; -+ sqlite3_appendvfs_init(0,0,0); - - /* Go ahead and open the database file if it already exists. If the - ** file does not exist, delay opening it. This prevents empty database -@@ -8224,6 +16294,18 @@ - }else if( strcmp(z,"-csv")==0 ){ - data.mode = MODE_Csv; - memcpy(data.colSeparator,",",2); -+#ifdef SQLITE_HAVE_ZLIB -+ }else if( strcmp(z,"-zip")==0 ){ -+ data.openMode = SHELL_OPEN_ZIPFILE; -+#endif -+ }else if( strcmp(z,"-append")==0 ){ -+ data.openMode = SHELL_OPEN_APPENDVFS; -+#ifdef SQLITE_ENABLE_DESERIALIZE -+ }else if( strcmp(z,"-deserialize")==0 ){ -+ data.openMode = SHELL_OPEN_DESERIALIZE; -+#endif -+ }else if( strcmp(z,"-readonly")==0 ){ -+ data.openMode = SHELL_OPEN_READONLY; - }else if( strcmp(z,"-ascii")==0 ){ - data.mode = MODE_Ascii; - sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, -@@ -8246,9 +16328,9 @@ - }else if( strcmp(z,"-echo")==0 ){ - ShellSetFlag(&data, SHFLG_Echo); - }else if( strcmp(z,"-eqp")==0 ){ -- data.autoEQP = 1; -+ data.autoEQP = AUTOEQP_on; - }else if( strcmp(z,"-eqpfull")==0 ){ -- data.autoEQP = 2; -+ data.autoEQP = AUTOEQP_full; - }else if( strcmp(z,"-stats")==0 ){ - data.statsOn = 1; - }else if( strcmp(z,"-scanstats")==0 ){ -@@ -8271,8 +16353,6 @@ - stdin_is_interactive = 0; - }else if( strcmp(z,"-heap")==0 ){ - i++; -- }else if( strcmp(z,"-scratch")==0 ){ -- i+=2; - }else if( strcmp(z,"-pagecache")==0 ){ - i+=2; - }else if( strcmp(z,"-lookaside")==0 ){ -@@ -8279,6 +16359,10 @@ - i+=2; - }else if( strcmp(z,"-mmap")==0 ){ - i++; -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ }else if( strcmp(z,"-sorterref")==0 ){ -+ i++; -+#endif - }else if( strcmp(z,"-vfs")==0 ){ - i++; - #ifdef SQLITE_ENABLE_VFSTRACE -@@ -8303,7 +16387,7 @@ - if( rc && bail_on_error ) return rc==2 ? 0 : rc; - }else{ - open_db(&data, 0); -- rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg); -+ rc = shell_exec(&data, z, &zErrMsg); - if( zErrMsg!=0 ){ - utf8_printf(stderr,"Error: %s\n", zErrMsg); - if( bail_on_error ) return rc!=0 ? rc : 1; -@@ -8312,6 +16396,23 @@ - if( bail_on_error ) return rc; - } - } -+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) -+ }else if( strncmp(z, "-A", 2)==0 ){ -+ if( nCmd>0 ){ -+ utf8_printf(stderr, "Error: cannot mix regular SQL or dot-commands" -+ " with \"%s\"\n", z); -+ return 1; -+ } -+ open_db(&data, OPEN_DB_ZIPFILE); -+ if( z[2] ){ -+ argv[i] = &z[2]; -+ arDotCommand(&data, 1, argv+(i-1), argc-(i-1)); -+ }else{ -+ arDotCommand(&data, 1, argv+i, argc-i); -+ } -+ readStdin = 0; -+ break; -+#endif - }else{ - utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z); - raw_printf(stderr,"Use -help for a list of options.\n"); -@@ -8331,7 +16432,7 @@ - if( rc ) return rc==2 ? 0 : rc; - }else{ - open_db(&data, 0); -- rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg); -+ rc = shell_exec(&data, azCmd[i], &zErrMsg); - if( zErrMsg!=0 ){ - utf8_printf(stderr,"Error: %s\n", zErrMsg); - return rc!=0 ? rc : 1; -@@ -8347,7 +16448,7 @@ - */ - if( stdin_is_interactive ){ - char *zHome; -- char *zHistory = 0; -+ char *zHistory; - int nHistory; - printf( - "SQLite version %s %.19s\n" /*extra-version-info*/ -@@ -8360,8 +16461,10 @@ - printf(".\nUse \".open FILENAME\" to reopen on a " - "persistent database.\n"); - } -- zHome = find_home_dir(0); -- if( zHome ){ -+ zHistory = getenv("SQLITE_HISTORY"); -+ if( zHistory ){ -+ zHistory = strdup(zHistory); -+ }else if( (zHome = find_home_dir(0))!=0 ){ - nHistory = strlen30(zHome) + 20; - if( (zHistory = malloc(nHistory))!=0 ){ - sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); -@@ -8386,13 +16489,19 @@ - set_table_name(&data, 0); - if( data.db ){ - session_close_all(&data); -- sqlite3_close(data.db); -+ close_db(data.db); - } - sqlite3_free(data.zFreeOnClose); - find_home_dir(1); -+ output_reset(&data); -+ data.doXdgOpen = 0; -+ clearTempFile(&data); - #if !SQLITE_SHELL_IS_UTF8 -- for(i=0; i<argc; i++) sqlite3_free(argv[i]); -- sqlite3_free(argv); -+ for(i=0; i<argcToFree; i++) free(argvToFree[i]); -+ free(argvToFree); - #endif -+ /* Clear the global data structure so that valgrind will detect memory -+ ** leaks */ -+ memset(&data, 0, sizeof(data)); - return rc; - } ---- contrib/sqlite3/sqlite3.c.orig -+++ contrib/sqlite3/sqlite3.c -@@ -1,6 +1,6 @@ - /****************************************************************************** - ** This file is an amalgamation of many separate C source files from SQLite --** version 3.20.0. By combining all the individual C code files into this -+** version 3.26.0. By combining all the individual C code files into this - ** single large file, the entire code can be compiled as a single translation - ** unit. This allows many compilers to do optimizations that would not be - ** possible if the files were compiled separately. Performance improvements -@@ -55,6 +55,12 @@ - #define CTIMEOPT_VAL_(opt) #opt - #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) - -+/* Like CTIMEOPT_VAL, but especially for SQLITE_DEFAULT_LOOKASIDE. This -+** option requires a separate macro because legal values contain a single -+** comma. e.g. (-DSQLITE_DEFAULT_LOOKASIDE="100,100") */ -+#define CTIMEOPT_VAL2_(opt1,opt2) #opt1 "," #opt2 -+#define CTIMEOPT_VAL2(opt) CTIMEOPT_VAL2_(opt) -+ - /* - ** An array of names of all compile-time options. This array should - ** be sorted A-Z. -@@ -138,7 +144,7 @@ - "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE), - #endif - #ifdef SQLITE_DEFAULT_LOOKASIDE -- "DEFAULT_LOOKASIDE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOOKASIDE), -+ "DEFAULT_LOOKASIDE=" CTIMEOPT_VAL2(SQLITE_DEFAULT_LOOKASIDE), - #endif - #if SQLITE_DEFAULT_MEMSTATUS - "DEFAULT_MEMSTATUS", -@@ -209,8 +215,11 @@ - #if SQLITE_ENABLE_ATOMIC_WRITE - "ENABLE_ATOMIC_WRITE", - #endif -+#if SQLITE_ENABLE_BATCH_ATOMIC_WRITE -+ "ENABLE_BATCH_ATOMIC_WRITE", -+#endif - #if SQLITE_ENABLE_CEROD -- "ENABLE_CEROD", -+ "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD), - #endif - #if SQLITE_ENABLE_COLUMN_METADATA - "ENABLE_COLUMN_METADATA", -@@ -251,6 +260,9 @@ - #if SQLITE_ENABLE_FTS5 - "ENABLE_FTS5", - #endif -+#if SQLITE_ENABLE_GEOPOLY -+ "ENABLE_GEOPOLY", -+#endif - #if SQLITE_ENABLE_HIDDEN_COLUMNS - "ENABLE_HIDDEN_COLUMNS", - #endif -@@ -281,6 +293,9 @@ - #if SQLITE_ENABLE_MULTIPLEX - "ENABLE_MULTIPLEX", - #endif -+#if SQLITE_ENABLE_NORMALIZE -+ "ENABLE_NORMALIZE", -+#endif - #if SQLITE_ENABLE_NULL_TRIM - "ENABLE_NULL_TRIM", - #endif -@@ -308,6 +323,9 @@ - #if SQLITE_ENABLE_SNAPSHOT - "ENABLE_SNAPSHOT", - #endif -+#if SQLITE_ENABLE_SORTER_REFERENCES -+ "ENABLE_SORTER_REFERENCES", -+#endif - #if SQLITE_ENABLE_SQLLOG - "ENABLE_SQLLOG", - #endif -@@ -828,14 +846,6 @@ - #endif - - /* --** Make sure that rand_s() is available on Windows systems with MSVC 2005 --** or higher. --*/ --#if defined(_MSC_VER) && _MSC_VER>=1400 --# define _CRT_RAND_S --#endif -- --/* - ** Include the header file used to customize the compiler options for MSVC. - ** This should be done first so that it can successfully prevent spurious - ** compiler warnings due to subsequent content in this file and other files -@@ -1144,15 +1154,17 @@ - ** a string which identifies a particular check-in of SQLite - ** within its configuration management system. ^The SQLITE_SOURCE_ID - ** string contains the date and time of the check-in (UTC) and a SHA1 --** or SHA3-256 hash of the entire source tree. -+** or SHA3-256 hash of the entire source tree. If the source code has -+** been edited in any way since it was last checked in, then the last -+** four hexadecimal digits of the hash may be modified. - ** - ** See also: [sqlite3_libversion()], - ** [sqlite3_libversion_number()], [sqlite3_sourceid()], - ** [sqlite_version()] and [sqlite_source_id()]. - */ --#define SQLITE_VERSION "3.20.0" --#define SQLITE_VERSION_NUMBER 3020000 --#define SQLITE_SOURCE_ID "2017-08-01 13:24:15 9501e22dfeebdcefa783575e47c60b514d7c2e0cad73b2a496c0bc4b680900a8" -+#define SQLITE_VERSION "3.26.0" -+#define SQLITE_VERSION_NUMBER 3026000 -+#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9" - - /* - ** CAPI3REF: Run-Time Library Version Numbers -@@ -1168,7 +1180,7 @@ - ** - ** <blockquote><pre> - ** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER ); --** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 ); -+** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 ); - ** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 ); - ** </pre></blockquote>)^ - ** -@@ -1178,9 +1190,11 @@ - ** function is provided for use in DLLs since DLL users usually do not have - ** direct access to string constants within the DLL. ^The - ** sqlite3_libversion_number() function returns an integer equal to --** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns -+** [SQLITE_VERSION_NUMBER]. ^(The sqlite3_sourceid() function returns - ** a pointer to a string constant whose value is the same as the --** [SQLITE_SOURCE_ID] C preprocessor macro. -+** [SQLITE_SOURCE_ID] C preprocessor macro. Except if SQLite is built -+** using an edited copy of [the amalgamation], then the last four characters -+** of the hash might be different from [SQLITE_SOURCE_ID].)^ - ** - ** See also: [sqlite_version()] and [sqlite_source_id()]. - */ -@@ -1461,7 +1475,7 @@ - #define SQLITE_FULL 13 /* Insertion failed because database is full */ - #define SQLITE_CANTOPEN 14 /* Unable to open the database file */ - #define SQLITE_PROTOCOL 15 /* Database lock protocol error */ --#define SQLITE_EMPTY 16 /* Not used */ -+#define SQLITE_EMPTY 16 /* Internal use only */ - #define SQLITE_SCHEMA 17 /* The database schema changed */ - #define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ - #define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ -@@ -1495,6 +1509,9 @@ - ** the most recent error can be obtained using - ** [sqlite3_extended_errcode()]. - */ -+#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8)) -+#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8)) -+#define SQLITE_ERROR_SNAPSHOT (SQLITE_ERROR | (3<<8)) - #define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) - #define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) - #define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) -@@ -1523,7 +1540,11 @@ - #define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) - #define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8)) - #define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8)) -+#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8)) -+#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) -+#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) - #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) -+#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) - #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) - #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) - #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) -@@ -1530,11 +1551,15 @@ - #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) - #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_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) -+#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8)) - #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) - #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) - #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) - #define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8)) -+#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8)) -+#define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8)) - #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) - #define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8)) - #define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8)) -@@ -1609,6 +1634,11 @@ - ** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on - ** read-only media and cannot be changed even by processes with - ** elevated privileges. -+** -+** The SQLITE_IOCAP_BATCH_ATOMIC property means that the underlying -+** filesystem supports doing multiple write operations atomically when those -+** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and -+** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. - */ - #define SQLITE_IOCAP_ATOMIC 0x00000001 - #define SQLITE_IOCAP_ATOMIC512 0x00000002 -@@ -1624,6 +1654,7 @@ - #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 - #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 - #define SQLITE_IOCAP_IMMUTABLE 0x00002000 -+#define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 - - /* - ** CAPI3REF: File Locking Levels -@@ -1758,6 +1789,7 @@ - ** <li> [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN] - ** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE] - ** <li> [SQLITE_IOCAP_IMMUTABLE] -+** <li> [SQLITE_IOCAP_BATCH_ATOMIC] - ** </ul> - ** - ** The SQLITE_IOCAP_ATOMIC property means that all writes of -@@ -1895,7 +1927,8 @@ - ** <li>[[SQLITE_FCNTL_PERSIST_WAL]] - ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the - ** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary --** write ahead log and shared memory files used for transaction control -+** write ahead log ([WAL file]) and shared memory -+** files used for transaction control - ** are automatically deleted when the latest connection to the database - ** closes. Setting persistent WAL mode causes those files to persist after - ** close. Persisting the files is useful when other processes that do not -@@ -2041,6 +2074,66 @@ - ** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by - ** the RBU extension only. All other VFS should return SQLITE_NOTFOUND for - ** this opcode. -+** -+** <li>[[SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]] -+** If the [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] opcode returns SQLITE_OK, then -+** the file descriptor is placed in "batch write mode", which -+** means all subsequent write operations will be deferred and done -+** atomically at the next [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. Systems -+** that do not support batch atomic writes will return SQLITE_NOTFOUND. -+** ^Following a successful SQLITE_FCNTL_BEGIN_ATOMIC_WRITE and prior to -+** the closing [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] or -+** [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE], SQLite will make -+** no VFS interface calls on the same [sqlite3_file] file descriptor -+** except for calls to the xWrite method and the xFileControl method -+** with [SQLITE_FCNTL_SIZE_HINT]. -+** -+** <li>[[SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]] -+** The [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] opcode causes all write -+** operations since the previous successful call to -+** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be performed atomically. -+** This file control returns [SQLITE_OK] if and only if the writes were -+** all performed successfully and have been committed to persistent storage. -+** ^Regardless of whether or not it is successful, this file control takes -+** the file descriptor out of batch write mode so that all subsequent -+** write operations are independent. -+** ^SQLite will never invoke SQLITE_FCNTL_COMMIT_ATOMIC_WRITE without -+** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]. -+** -+** <li>[[SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE]] -+** The [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE] opcode causes all write -+** operations since the previous successful call to -+** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be rolled back. -+** ^This file control takes the file descriptor out of batch write mode -+** so that all subsequent write operations are independent. -+** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without -+** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]. -+** -+** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]] -+** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain -+** a file lock using the xLock or xShmLock methods of the VFS to wait -+** for up to M milliseconds before failing, where M is the single -+** unsigned integer parameter. -+** -+** <li>[[SQLITE_FCNTL_DATA_VERSION]] -+** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to -+** a database file. The argument is a pointer to a 32-bit unsigned integer. -+** The "data version" for the pager is written into the pointer. The -+** "data version" changes whenever any change occurs to the corresponding -+** database file, either through SQL statements on the same database -+** connection or through transactions committed by separate database -+** connections possibly in other processes. The [sqlite3_total_changes()] -+** interface can be used to find if any database on the connection has changed, -+** but that interface responds to changes on TEMP as well as MAIN and does -+** 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 -+** 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. - ** </ul> - */ - #define SQLITE_FCNTL_LOCKSTATE 1 -@@ -2072,6 +2165,11 @@ - #define SQLITE_FCNTL_JOURNAL_POINTER 28 - #define SQLITE_FCNTL_WIN32_GET_HANDLE 29 - #define SQLITE_FCNTL_PDB 30 -+#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31 -+#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32 -+#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33 -+#define SQLITE_FCNTL_LOCK_TIMEOUT 34 -+#define SQLITE_FCNTL_DATA_VERSION 35 - - /* deprecated names */ - #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE -@@ -2109,12 +2207,18 @@ - ** in the name of the object stands for "virtual file system". See - ** the [VFS | VFS documentation] for further information. - ** --** The value of the iVersion field is initially 1 but may be larger in --** future versions of SQLite. Additional fields may be appended to this --** object when the iVersion value is increased. Note that the structure --** of the sqlite3_vfs object changes in the transaction between --** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not --** modified. -+** The VFS interface is sometimes extended by adding new methods onto -+** the end. Each time such an extension occurs, the iVersion field -+** is incremented. The iVersion value started out as 1 in -+** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2 -+** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased -+** 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 -+** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0] -+** and yet the iVersion field was not modified. - ** - ** The szOsFile field is the size of the subclassed [sqlite3_file] - ** structure used by this VFS. mxPathname is the maximum length of -@@ -2642,6 +2746,16 @@ - ** routines with a wrapper that simulations memory allocation failure or - ** tracks memory usage, for example. </dd> - ** -+** [[SQLITE_CONFIG_SMALL_MALLOC]] <dt>SQLITE_CONFIG_SMALL_MALLOC</dt> -+** <dd> ^The SQLITE_CONFIG_SMALL_MALLOC option takes single argument of -+** type int, interpreted as a boolean, which if true provides a hint to -+** SQLite that it should avoid large memory allocations if possible. -+** SQLite will run faster if it is free to make large memory allocations, -+** but some application might prefer to run slower in exchange for -+** guarantees about memory fragmentation that are possible if large -+** allocations are avoided. This hint is normally off. -+** </dd> -+** - ** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt> - ** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int, - ** interpreted as a boolean, which enables or disables the collection of -@@ -2659,25 +2773,7 @@ - ** </dd> - ** - ** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt> --** <dd> ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer --** that SQLite can use for scratch memory. ^(There are three arguments --** to SQLITE_CONFIG_SCRATCH: A pointer an 8-byte --** aligned memory buffer from which the scratch allocations will be --** drawn, the size of each scratch allocation (sz), --** and the maximum number of scratch allocations (N).)^ --** The first argument must be a pointer to an 8-byte aligned buffer --** of at least sz*N bytes of memory. --** ^SQLite will not use more than one scratch buffers per thread. --** ^SQLite will never request a scratch buffer that is more than 6 --** times the database page size. --** ^If SQLite needs needs additional --** scratch memory beyond what is provided by this configuration option, then --** [sqlite3_malloc()] will be used to obtain the memory needed.<p> --** ^When the application provides any amount of scratch memory using --** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large --** [sqlite3_malloc|heap allocations]. --** This can help [Robson proof|prevent memory allocation failures] due to heap --** fragmentation in low-memory embedded systems. -+** <dd> The SQLITE_CONFIG_SCRATCH option is no longer used. - ** </dd> - ** - ** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt> -@@ -2713,8 +2809,7 @@ - ** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt> - ** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer - ** that SQLite will use for all of its dynamic memory allocation needs --** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and --** [SQLITE_CONFIG_PAGECACHE]. -+** beyond those provided for by [SQLITE_CONFIG_PAGECACHE]. - ** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled - ** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns - ** [SQLITE_ERROR] if invoked otherwise. -@@ -2900,6 +2995,22 @@ - ** I/O required to support statement rollback. - ** The default value for this setting is controlled by the - ** [SQLITE_STMTJRNL_SPILL] compile-time option. -+** -+** [[SQLITE_CONFIG_SORTERREF_SIZE]] -+** <dt>SQLITE_CONFIG_SORTERREF_SIZE -+** <dd>The SQLITE_CONFIG_SORTERREF_SIZE option accepts a single parameter -+** of type (int) - the new value of the sorter-reference size threshold. -+** Usually, when SQLite uses an external sort to order records according -+** to an ORDER BY clause, all fields required by the caller are present in the -+** sorted records. However, if SQLite determines based on the declared type -+** of a table column that its values are likely to be very large - larger -+** than the configured sorter-reference size threshold - then a reference -+** is stored in each sorted record and the required column values loaded -+** from the database as records are returned in sorted order. The default -+** value for this option is to never use this optimization. Specifying a -+** negative value for this option restores the default behaviour. -+** This option is only available if SQLite is compiled with the -+** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option. - ** </dl> - */ - #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ -@@ -2907,7 +3018,7 @@ - #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ - #define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ - #define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ --#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */ -+#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */ - #define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ - #define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ - #define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ -@@ -2928,6 +3039,8 @@ - #define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */ - #define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ - #define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */ -+#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */ -+#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */ - - /* - ** CAPI3REF: Database Connection Configuration Options -@@ -2943,6 +3056,7 @@ - ** is invoked. - ** - ** <dl> -+** [[SQLITE_DBCONFIG_LOOKASIDE]] - ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt> - ** <dd> ^This option takes three additional arguments that determine the - ** [lookaside memory allocator] configuration for the [database connection]. -@@ -2965,6 +3079,7 @@ - ** memory is in use leaves the configuration unchanged and returns - ** [SQLITE_BUSY].)^</dd> - ** -+** [[SQLITE_DBCONFIG_ENABLE_FKEY]] - ** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt> - ** <dd> ^This option is used to enable or disable the enforcement of - ** [foreign key constraints]. There should be two additional arguments. -@@ -2975,6 +3090,7 @@ - ** following this call. The second parameter may be a NULL pointer, in - ** which case the FK enforcement setting is not reported back. </dd> - ** -+** [[SQLITE_DBCONFIG_ENABLE_TRIGGER]] - ** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt> - ** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers]. - ** There should be two additional arguments. -@@ -2985,6 +3101,7 @@ - ** following this call. The second parameter may be a NULL pointer, in - ** which case the trigger setting is not reported back. </dd> - ** -+** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] - ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> - ** <dd> ^This option is used to enable or disable the two-argument - ** version of the [fts3_tokenizer()] function which is part of the -@@ -2998,6 +3115,7 @@ - ** following this call. The second parameter may be a NULL pointer, in - ** which case the new setting is not reported back. </dd> - ** -+** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]] - ** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt> - ** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()] - ** interface independently of the [load_extension()] SQL function. -@@ -3015,7 +3133,7 @@ - ** be a NULL pointer, in which case the new setting is not reported back. - ** </dd> - ** --** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt> -+** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt> - ** <dd> ^This option is used to change the name of the "main" database - ** schema. ^The sole argument is a pointer to a constant UTF8 string - ** which will become the new schema name in place of "main". ^SQLite -@@ -3024,6 +3142,7 @@ - ** until after the database connection closes. - ** </dd> - ** -+** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]] - ** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt> - ** <dd> Usually, when a database in wal mode is closed or detached from a - ** database handle, SQLite checks if this will mean that there are now no -@@ -3030,13 +3149,14 @@ - ** connections at all to the database. If so, it performs a checkpoint - ** operation before closing the connection. This option may be used to - ** override this behaviour. The first parameter passed to this operation --** is an integer - non-zero to disable checkpoints-on-close, or zero (the --** default) to enable them. The second parameter is a pointer to an integer -+** is an integer - positive to disable checkpoints-on-close, or zero (the -+** default) to enable them, and negative to leave the setting unchanged. -+** The second parameter is a pointer to an integer - ** into which is written 0 or 1 to indicate whether checkpoints-on-close - ** have been disabled - 0 if they are not disabled, 1 if they are. - ** </dd> - ** --** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt> -+** [[SQLITE_DBCONFIG_ENABLE_QPSG]] <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt> - ** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates - ** the [query planner stability guarantee] (QPSG). When the QPSG is active, - ** a single SQL query statement will always use the same algorithm regardless -@@ -3045,8 +3165,57 @@ - ** slower. But the QPSG has the advantage of more predictable behavior. With - ** the QPSG active, SQLite will always use the same query plan in the field as - ** was used during testing in the lab. -+** The first argument to this setting is an integer which is 0 to disable -+** the QPSG, positive to enable QPSG, or negative to leave the setting -+** unchanged. The second parameter is a pointer to an integer into which -+** is written 0 or 1 to indicate whether the QPSG is disabled or enabled -+** following this call. - ** </dd> - ** -+** [[SQLITE_DBCONFIG_TRIGGER_EQP]] <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt> -+** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not -+** include output for any operations performed by trigger programs. This -+** option is used to set or clear (the default) a flag that governs this -+** behavior. The first parameter passed to this operation is an integer - -+** positive to enable output for trigger programs, or zero to disable it, -+** or negative to leave the setting unchanged. -+** The second parameter is a pointer to an integer into which is written -+** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if -+** it is not disabled, 1 if it is. -+** </dd> -+** -+** [[SQLITE_DBCONFIG_RESET_DATABASE]] <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt> -+** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run -+** [VACUUM] in order to reset a database back to an empty database -+** with no schema and no content. The following process works even for -+** a badly corrupted database file: -+** <ol> -+** <li> If the database connection is newly opened, make sure it has read the -+** database schema by preparing then discarding some query against the -+** database, or calling sqlite3_table_column_metadata(), ignoring any -+** errors. This step is only necessary if the application desires to keep -+** the database in WAL mode after the reset if it was in WAL mode before -+** the reset. -+** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); -+** <li> [sqlite3_exec](db, "[VACUUM]", 0, 0, 0); -+** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); -+** </ol> -+** Because resetting a database is destructive and irreversible, the -+** process requires the use of this obscure API and multiple steps to help -+** ensure that it does not happen by accident. -+** -+** [[SQLITE_DBCONFIG_DEFENSIVE]] <dt>SQLITE_DBCONFIG_DEFENSIVE</dt> -+** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the -+** "defensive" flag for a database connection. When the defensive -+** flag is enabled, language features that allow ordinary SQL to -+** deliberately corrupt the database file are disabled. The disabled -+** features include but are not limited to the following: -+** <ul> -+** <li> The [PRAGMA writable_schema=ON] statement. -+** <li> Writes to the [sqlite_dbpage] virtual table. -+** <li> Direct writes to [shadow tables]. -+** </ul> -+** </dd> - ** </dl> - */ - #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ -@@ -3057,8 +3226,11 @@ - #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */ - #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */ - #define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */ -+#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */ -+#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */ -+#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */ -+#define SQLITE_DBCONFIG_MAX 1010 /* Largest DBCONFIG */ - -- - /* - ** CAPI3REF: Enable Or Disable Extended Result Codes - ** METHOD: sqlite3 -@@ -3185,12 +3357,17 @@ - ** program, the value returned reflects the number of rows modified by the - ** previous INSERT, UPDATE or DELETE statement within the same trigger. - ** --** See also the [sqlite3_total_changes()] interface, the --** [count_changes pragma], and the [changes() SQL function]. --** - ** If a separate thread makes changes on the same database connection - ** while [sqlite3_changes()] is running then the value returned - ** is unpredictable and not meaningful. -+** -+** See also: -+** <ul> -+** <li> the [sqlite3_total_changes()] interface -+** <li> the [count_changes pragma] -+** <li> the [changes() SQL function] -+** <li> the [data_version pragma] -+** </ul> - */ - SQLITE_API int sqlite3_changes(sqlite3*); - -@@ -3208,13 +3385,26 @@ - ** count, but those made as part of REPLACE constraint resolution are - ** not. ^Changes to a view that are intercepted by INSTEAD OF triggers - ** are not counted. -+** -+** This the [sqlite3_total_changes(D)] interface only reports the number -+** of rows that changed due to SQL statement run against database -+** connection D. Any changes by other database connections are ignored. -+** To detect changes against a database file from other database -+** connections use the [PRAGMA data_version] command or the -+** [SQLITE_FCNTL_DATA_VERSION] [file control]. - ** --** See also the [sqlite3_changes()] interface, the --** [count_changes pragma], and the [total_changes() SQL function]. --** - ** If a separate thread makes changes on the same database connection - ** while [sqlite3_total_changes()] is running then the value - ** returned is unpredictable and not meaningful. -+** -+** See also: -+** <ul> -+** <li> the [sqlite3_changes()] interface -+** <li> the [count_changes pragma] -+** <li> the [changes() SQL function] -+** <li> the [data_version pragma] -+** <li> the [SQLITE_FCNTL_DATA_VERSION] [file control] -+** </ul> - */ - SQLITE_API int sqlite3_total_changes(sqlite3*); - -@@ -3463,16 +3653,16 @@ - ** - ** These routines are work-alikes of the "printf()" family of functions - ** from the standard C library. --** These routines understand most of the common K&R formatting options, --** plus some additional non-standard formats, detailed below. --** Note that some of the more obscure formatting options from recent --** C-library standards are omitted from this implementation. -+** These routines understand most of the common formatting options from -+** the standard library printf() -+** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]). -+** See the [built-in printf()] documentation for details. - ** - ** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their --** results into memory obtained from [sqlite3_malloc()]. -+** results into memory obtained from [sqlite3_malloc64()]. - ** The strings returned by these two routines should be - ** released by [sqlite3_free()]. ^Both routines return a --** NULL pointer if [sqlite3_malloc()] is unable to allocate enough -+** NULL pointer if [sqlite3_malloc64()] is unable to allocate enough - ** memory to hold the resulting string. - ** - ** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from -@@ -3496,71 +3686,7 @@ - ** - ** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf(). - ** --** These routines all implement some additional formatting --** options that are useful for constructing SQL statements. --** All of the usual printf() formatting options apply. In addition, there --** is are "%q", "%Q", "%w" and "%z" options. --** --** ^(The %q option works like %s in that it substitutes a nul-terminated --** string from the argument list. But %q also doubles every '\'' character. --** %q is designed for use inside a string literal.)^ By doubling each '\'' --** character it escapes that character and allows it to be inserted into --** the string. --** --** For example, assume the string variable zText contains text as follows: --** --** <blockquote><pre> --** char *zText = "It's a happy day!"; --** </pre></blockquote> --** --** One can use this text in an SQL statement as follows: --** --** <blockquote><pre> --** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText); --** sqlite3_exec(db, zSQL, 0, 0, 0); --** sqlite3_free(zSQL); --** </pre></blockquote> --** --** Because the %q format string is used, the '\'' character in zText --** is escaped and the SQL generated is as follows: --** --** <blockquote><pre> --** INSERT INTO table1 VALUES('It''s a happy day!') --** </pre></blockquote> --** --** This is correct. Had we used %s instead of %q, the generated SQL --** would have looked like this: --** --** <blockquote><pre> --** INSERT INTO table1 VALUES('It's a happy day!'); --** </pre></blockquote> --** --** This second example is an SQL syntax error. As a general rule you should --** always use %q instead of %s when inserting text into a string literal. --** --** ^(The %Q option works like %q except it also adds single quotes around --** the outside of the total string. Additionally, if the parameter in the --** argument list is a NULL pointer, %Q substitutes the text "NULL" (without --** single quotes).)^ So, for example, one could say: --** --** <blockquote><pre> --** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText); --** sqlite3_exec(db, zSQL, 0, 0, 0); --** sqlite3_free(zSQL); --** </pre></blockquote> --** --** The code above will render a correct SQL statement in the zSQL --** variable even if the zText variable is a NULL pointer. --** --** ^(The "%w" formatting option is like "%q" except that it expects to --** be contained within double-quotes instead of single quotes, and it --** escapes the double-quote character instead of the single-quote --** character.)^ The "%w" formatting option is intended for safely inserting --** table and column names into a constructed SQL statement. --** --** ^(The "%z" formatting option works like "%s" but with the --** addition that after the string has been read and copied into --** the result, [sqlite3_free()] is called on the input string.)^ -+** See also: [built-in printf()], [printf() SQL function] - */ - SQLITE_API char *sqlite3_mprintf(const char*,...); - SQLITE_API char *sqlite3_vmprintf(const char*, va_list); -@@ -3918,8 +4044,8 @@ - ** KEYWORDS: SQLITE_TRACE - ** - ** These constants identify classes of events that can be monitored --** using the [sqlite3_trace_v2()] tracing logic. The third argument --** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of -+** using the [sqlite3_trace_v2()] tracing logic. The M argument -+** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of - ** the following constants. ^The first argument to the trace callback - ** is one of the following constants. - ** -@@ -4128,10 +4254,10 @@ - ** ^If [URI filename] interpretation is enabled, and the filename argument - ** begins with "file:", then the filename is interpreted as a URI. ^URI - ** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is --** set in the fourth argument to sqlite3_open_v2(), or if it has -+** set in the third argument to sqlite3_open_v2(), or if it has - ** been enabled globally using the [SQLITE_CONFIG_URI] option with the - ** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. --** As of SQLite version 3.7.7, URI filename interpretation is turned off -+** URI filename interpretation is turned off - ** by default, but future releases of SQLite might enable URI filename - ** interpretation by default. See "[URI filenames]" for additional - ** information. -@@ -4334,13 +4460,24 @@ - ** [database connection] D failed, then the sqlite3_errcode(D) interface - ** returns the numeric [result code] or [extended result code] for that - ** API call. --** If the most recent API call was successful, --** then the return value from sqlite3_errcode() is undefined. - ** ^The sqlite3_extended_errcode() - ** interface is the same except that it always returns the - ** [extended result code] even when extended result codes are - ** disabled. - ** -+** The values returned by sqlite3_errcode() and/or -+** sqlite3_extended_errcode() might change with each API call. -+** Except, there are some interfaces that are guaranteed to never -+** change the value of the error code. The error-code preserving -+** interfaces are: -+** -+** <ul> -+** <li> sqlite3_errcode() -+** <li> sqlite3_extended_errcode() -+** <li> sqlite3_errmsg() -+** <li> sqlite3_errmsg16() -+** </ul> -+** - ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language - ** text that describes the error, as either UTF-8 or UTF-16 respectively. - ** ^(Memory to hold the error message string is managed internally. -@@ -4530,9 +4667,19 @@ - ** on this hint by avoiding the use of [lookaside memory] so as not to - ** deplete the limited store of lookaside memory. Future versions of - ** SQLite may act on this hint differently. -+** -+** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt> -+** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized -+** representation of the SQL statement should be calculated and then -+** associated with the prepared statement, which can be obtained via -+** the [sqlite3_normalized_sql()] interface.)^ The semantics used to -+** normalize a SQL statement are unspecified and subject to change. -+** At a minimum, literal values will be replaced with suitable -+** placeholders. - ** </dl> - */ - #define SQLITE_PREPARE_PERSISTENT 0x01 -+#define SQLITE_PREPARE_NORMALIZE 0x02 - - /* - ** CAPI3REF: Compiling An SQL Statement -@@ -4626,6 +4773,7 @@ - ** or [GLOB] operator or if the parameter is compared to an indexed column - ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. - ** </li> -+** </ol> - ** - ** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having - ** the extra prepFlags parameter, which is a bit array consisting of zero or -@@ -4632,7 +4780,6 @@ - ** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags. ^The - ** sqlite3_prepare_v2() interface works exactly the same as - ** sqlite3_prepare_v3() with a zero prepFlags parameter. --** </ol> - */ - SQLITE_API int sqlite3_prepare( - sqlite3 *db, /* Database handle */ -@@ -4690,6 +4837,11 @@ - ** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8 - ** string containing the SQL text of prepared statement P with - ** [bound parameters] expanded. -+** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8 -+** string containing the normalized SQL text of prepared statement P. The -+** semantics used to normalize a SQL statement are unspecified and subject -+** to change. At a minimum, literal values will be replaced with suitable -+** placeholders. - ** - ** ^(For example, if a prepared statement is created using the SQL - ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345 -@@ -4705,8 +4857,9 @@ - ** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time - ** option causes sqlite3_expanded_sql() to always return NULL. - ** --** ^The string returned by sqlite3_sql(P) is managed by SQLite and is --** automatically freed when the prepared statement is finalized. -+** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P) -+** are managed by SQLite and are automatically freed when the prepared -+** statement is finalized. - ** ^The string returned by sqlite3_expanded_sql(P), on the other hand, - ** is obtained from [sqlite3_malloc()] and must be free by the application - ** by passing it to [sqlite3_free()]. -@@ -4713,6 +4866,7 @@ - */ - SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); - SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt); -+SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); - - /* - ** CAPI3REF: Determine If An SQL Statement Writes The Database -@@ -4805,8 +4959,9 @@ - ** implementation of [application-defined SQL functions] are protected. - ** ^The sqlite3_value object returned by - ** [sqlite3_column_value()] is unprotected. --** Unprotected sqlite3_value objects may only be used with --** [sqlite3_result_value()] and [sqlite3_bind_value()]. -+** Unprotected sqlite3_value objects may only be used as arguments -+** to [sqlite3_result_value()], [sqlite3_bind_value()], and -+** [sqlite3_value_dup()]. - ** The [sqlite3_value_blob | sqlite3_value_type()] family of - ** interfaces require protected sqlite3_value objects. - */ -@@ -5228,7 +5383,7 @@ - ** other than [SQLITE_ROW] before any subsequent invocation of - ** sqlite3_step(). Failure to reset the prepared statement using - ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from --** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1]), -+** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1], - ** sqlite3_step() began - ** calling [sqlite3_reset()] automatically in this circumstance rather - ** than returning [SQLITE_MISUSE]. This is not considered a compatibility -@@ -5493,11 +5648,25 @@ - ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into - ** [sqlite3_free()]. - ** --** ^(If a memory allocation error occurs during the evaluation of any --** of these routines, a default value is returned. The default value --** is either the integer 0, the floating point number 0.0, or a NULL --** pointer. Subsequent calls to [sqlite3_errcode()] will return --** [SQLITE_NOMEM].)^ -+** As long as the input parameters are correct, these routines will only -+** fail if an out-of-memory error occurs during a format conversion. -+** Only the following subset of interfaces are subject to out-of-memory -+** errors: -+** -+** <ul> -+** <li> sqlite3_column_blob() -+** <li> sqlite3_column_text() -+** <li> sqlite3_column_text16() -+** <li> sqlite3_column_bytes() -+** <li> sqlite3_column_bytes16() -+** </ul> -+** -+** If an out-of-memory error occurs, then the return value from these -+** routines is the same as if the column had contained an SQL NULL value. -+** Valid SQL NULL returns can be distinguished from out-of-memory errors -+** by invoking the [sqlite3_errcode()] immediately after the suspect -+** return value is obtained and before any -+** other SQLite interface is called on the same [database connection]. - */ - SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); - SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); -@@ -5574,11 +5743,13 @@ - ** - ** ^These functions (collectively known as "function creation routines") - ** are used to add SQL functions or aggregates or to redefine the behavior --** of existing SQL functions or aggregates. The only differences between --** these routines are the text encoding expected for --** the second parameter (the name of the function being created) --** and the presence or absence of a destructor callback for --** the application data pointer. -+** of existing SQL functions or aggregates. The only differences between -+** the three "sqlite3_create_function*" routines are the text encoding -+** expected for the second parameter (the name of the function being -+** created) and the presence or absence of a destructor callback for -+** the application data pointer. Function sqlite3_create_window_function() -+** is similar, but allows the user to supply the extra callback functions -+** needed by [aggregate window functions]. - ** - ** ^The first parameter is the [database connection] to which the SQL - ** function is to be added. ^If an application uses more than one database -@@ -5624,7 +5795,8 @@ - ** ^(The fifth parameter is an arbitrary pointer. The implementation of the - ** function can gain access to this pointer using [sqlite3_user_data()].)^ - ** --** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are -+** ^The sixth, seventh and eighth parameters passed to the three -+** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are - ** pointers to C-language functions that implement the SQL function or - ** aggregate. ^A scalar SQL function requires an implementation of the xFunc - ** callback only; NULL pointers must be passed as the xStep and xFinal -@@ -5633,16 +5805,25 @@ - ** SQL function or aggregate, pass NULL pointers for all three function - ** callbacks. - ** --** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL, --** then it is destructor for the application data pointer. --** The destructor is invoked when the function is deleted, either by being --** overloaded or when the database connection closes.)^ --** ^The destructor is also invoked if the call to --** sqlite3_create_function_v2() fails. --** ^When the destructor callback of the tenth parameter is invoked, it --** is passed a single argument which is a copy of the application data --** pointer which was the fifth parameter to sqlite3_create_function_v2(). -+** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue -+** and xInverse) passed to sqlite3_create_window_function are pointers to -+** C-language callbacks that implement the new function. xStep and xFinal -+** must both be non-NULL. xValue and xInverse may either both be NULL, in -+** which case a regular aggregate function is created, or must both be -+** non-NULL, in which case the new function may be used as either an aggregate -+** or aggregate window function. More details regarding the implementation -+** of aggregate window functions are -+** [user-defined window functions|available here]. - ** -+** ^(If the final parameter to sqlite3_create_function_v2() or -+** sqlite3_create_window_function() is not NULL, then it is destructor for -+** the application data pointer. The destructor is invoked when the function -+** is deleted, either by being overloaded or when the database connection -+** closes.)^ ^The destructor is also invoked if the call to -+** sqlite3_create_function_v2() fails. ^When the destructor callback is -+** invoked, it is passed a single argument which is a copy of the application -+** data pointer which was the fifth parameter to sqlite3_create_function_v2(). -+** - ** ^It is permitted to register multiple implementations of the same - ** functions with the same name but with either differing numbers of - ** arguments or differing preferred text encodings. ^SQLite will use -@@ -5694,6 +5875,18 @@ - void (*xFinal)(sqlite3_context*), - void(*xDestroy)(void*) - ); -+SQLITE_API int sqlite3_create_window_function( -+ sqlite3 *db, -+ const char *zFunctionName, -+ int nArg, -+ int eTextRep, -+ void *pApp, -+ void (*xStep)(sqlite3_context*,int,sqlite3_value**), -+ void (*xFinal)(sqlite3_context*), -+ void (*xValue)(sqlite3_context*), -+ void (*xInverse)(sqlite3_context*,int,sqlite3_value**), -+ void(*xDestroy)(void*) -+); - - /* - ** CAPI3REF: Text Encodings -@@ -5764,6 +5957,9 @@ - ** datatype of the value - ** <tr><td><b>sqlite3_value_numeric_type </b> - ** <td>→ <td>Best numeric datatype of the value -+** <tr><td><b>sqlite3_value_nochange </b> -+** <td>→ <td>True if the column is unchanged in an UPDATE -+** against a virtual table. - ** </table></blockquote> - ** - ** <b>Details:</b> -@@ -5812,6 +6008,19 @@ - ** then the conversion is performed. Otherwise no conversion occurs. - ** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ - ** -+** ^Within the [xUpdate] method of a [virtual table], the -+** sqlite3_value_nochange(X) interface returns true if and only if -+** the column corresponding to X is unchanged by the UPDATE operation -+** that the xUpdate method call was invoked to implement and if -+** and the prior [xColumn] method call that was invoked to extracted -+** the value for that column returned without setting a result (probably -+** because it queried [sqlite3_vtab_nochange()] and found that the column -+** was unchanging). ^Within an [xUpdate] method, any value for which -+** sqlite3_value_nochange(X) is true will in all other respects appear -+** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other -+** than within an [xUpdate] method call for an UPDATE statement, then -+** the return value is arbitrary and meaningless. -+** - ** Please pay particular attention to the fact that the pointer returned - ** from [sqlite3_value_blob()], [sqlite3_value_text()], or - ** [sqlite3_value_text16()] can be invalidated by a subsequent call to -@@ -5820,6 +6029,28 @@ - ** - ** These routines must be called from the same thread as - ** the SQL function that supplied the [sqlite3_value*] parameters. -+** -+** As long as the input parameter is correct, these routines can only -+** fail if an out-of-memory error occurs during a format conversion. -+** Only the following subset of interfaces are subject to out-of-memory -+** errors: -+** -+** <ul> -+** <li> sqlite3_value_blob() -+** <li> sqlite3_value_text() -+** <li> sqlite3_value_text16() -+** <li> sqlite3_value_text16le() -+** <li> sqlite3_value_text16be() -+** <li> sqlite3_value_bytes() -+** <li> sqlite3_value_bytes16() -+** </ul> -+** -+** If an out-of-memory error occurs, then the return value from these -+** routines is the same as if the column had contained an SQL NULL value. -+** Valid SQL NULL returns can be distinguished from out-of-memory errors -+** by invoking the [sqlite3_errcode()] immediately after the suspect -+** return value is obtained and before any -+** other SQLite interface is called on the same [database connection]. - */ - SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); - SQLITE_API double sqlite3_value_double(sqlite3_value*); -@@ -5834,6 +6065,7 @@ - SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); - SQLITE_API int sqlite3_value_type(sqlite3_value*); - SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); -+SQLITE_API int sqlite3_value_nochange(sqlite3_value*); - - /* - ** CAPI3REF: Finding The Subtype Of SQL Values -@@ -6490,6 +6722,41 @@ - SQLITE_API char *sqlite3_data_directory; - - /* -+** CAPI3REF: Win32 Specific Interface -+** -+** These interfaces are available only on Windows. The -+** [sqlite3_win32_set_directory] interface is used to set the value associated -+** with the [sqlite3_temp_directory] or [sqlite3_data_directory] variable, to -+** zValue, depending on the value of the type parameter. The zValue parameter -+** should be NULL to cause the previous value to be freed via [sqlite3_free]; -+** a non-NULL value will be copied into memory obtained from [sqlite3_malloc] -+** prior to being used. The [sqlite3_win32_set_directory] interface returns -+** [SQLITE_OK] to indicate success, [SQLITE_ERROR] if the type is unsupported, -+** or [SQLITE_NOMEM] if memory could not be allocated. The value of the -+** [sqlite3_data_directory] variable is intended to act as a replacement for -+** the current directory on the sub-platforms of Win32 where that concept is -+** not present, e.g. WinRT and UWP. The [sqlite3_win32_set_directory8] and -+** [sqlite3_win32_set_directory16] interfaces behave exactly the same as the -+** sqlite3_win32_set_directory interface except the string parameter must be -+** UTF-8 or UTF-16, respectively. -+*/ -+SQLITE_API int sqlite3_win32_set_directory( -+ unsigned long type, /* Identifier for directory being set or reset */ -+ void *zValue /* New value for directory being set or reset */ -+); -+SQLITE_API int sqlite3_win32_set_directory8(unsigned long type, const char *zValue); -+SQLITE_API int sqlite3_win32_set_directory16(unsigned long type, const void *zValue); -+ -+/* -+** CAPI3REF: Win32 Directory Types -+** -+** These macros are only available on Windows. They define the allowed values -+** for the type argument to the [sqlite3_win32_set_directory] interface. -+*/ -+#define SQLITE_WIN32_DATA_DIRECTORY_TYPE 1 -+#define SQLITE_WIN32_TEMP_DIRECTORY_TYPE 2 -+ -+/* - ** CAPI3REF: Test For Auto-Commit Mode - ** KEYWORDS: {autocommit mode} - ** METHOD: sqlite3 -@@ -7089,6 +7356,9 @@ - int (*xSavepoint)(sqlite3_vtab *pVTab, int); - int (*xRelease)(sqlite3_vtab *pVTab, int); - int (*xRollbackTo)(sqlite3_vtab *pVTab, int); -+ /* The methods above are in versions 1 and 2 of the sqlite_module object. -+ ** Those below are for version 3 and greater. */ -+ int (*xShadowName)(const char*); - }; - - /* -@@ -7221,6 +7491,10 @@ - - /* - ** CAPI3REF: Virtual Table Scan Flags -+** -+** Virtual table implementations are allowed to set the -+** [sqlite3_index_info].idxFlags field to some combination of -+** these bits. - */ - #define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */ - -@@ -7232,15 +7506,21 @@ - ** an operator that is part of a constraint term in the wHERE clause of - ** a query that uses a [virtual table]. - */ --#define SQLITE_INDEX_CONSTRAINT_EQ 2 --#define SQLITE_INDEX_CONSTRAINT_GT 4 --#define SQLITE_INDEX_CONSTRAINT_LE 8 --#define SQLITE_INDEX_CONSTRAINT_LT 16 --#define SQLITE_INDEX_CONSTRAINT_GE 32 --#define SQLITE_INDEX_CONSTRAINT_MATCH 64 --#define SQLITE_INDEX_CONSTRAINT_LIKE 65 --#define SQLITE_INDEX_CONSTRAINT_GLOB 66 --#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 -+#define SQLITE_INDEX_CONSTRAINT_EQ 2 -+#define SQLITE_INDEX_CONSTRAINT_GT 4 -+#define SQLITE_INDEX_CONSTRAINT_LE 8 -+#define SQLITE_INDEX_CONSTRAINT_LT 16 -+#define SQLITE_INDEX_CONSTRAINT_GE 32 -+#define SQLITE_INDEX_CONSTRAINT_MATCH 64 -+#define SQLITE_INDEX_CONSTRAINT_LIKE 65 -+#define SQLITE_INDEX_CONSTRAINT_GLOB 66 -+#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 -+#define SQLITE_INDEX_CONSTRAINT_NE 68 -+#define SQLITE_INDEX_CONSTRAINT_ISNOT 69 -+#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 -+#define SQLITE_INDEX_CONSTRAINT_ISNULL 71 -+#define SQLITE_INDEX_CONSTRAINT_IS 72 -+#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 - - /* - ** CAPI3REF: Register A Virtual Table Implementation -@@ -7917,6 +8197,7 @@ - /* - ** CAPI3REF: Low-Level Control Of Database Files - ** METHOD: sqlite3 -+** KEYWORDS: {file control} - ** - ** ^The [sqlite3_file_control()] interface makes a direct call to the - ** xFileControl method for the [sqlite3_io_methods] object associated -@@ -7931,11 +8212,18 @@ - ** the xFileControl method. ^The return value of the xFileControl - ** method becomes the return value of this routine. - ** --** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes -+** A few opcodes for [sqlite3_file_control()] are handled directly -+** by the SQLite core and never invoke the -+** sqlite3_io_methods.xFileControl method. -+** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes - ** a pointer to the underlying [sqlite3_file] object to be written into --** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER --** case is a short-circuit path which does not actually invoke the --** underlying sqlite3_io_methods.xFileControl method. -+** the space pointed to by the 4th parameter. The -+** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns -+** the [sqlite3_file] object associated with the journal file instead of -+** the main database. The [SQLITE_FCNTL_VFS_POINTER] opcode returns -+** a pointer to the underlying [sqlite3_vfs] object for the file. -+** The [SQLITE_FCNTL_DATA_VERSION] returns the data version counter -+** from the pager. - ** - ** ^If the second parameter (zDbName) does not match the name of any - ** open database file, then SQLITE_ERROR is returned. ^This error -@@ -7945,7 +8233,7 @@ - ** an incorrect zDbName and an SQLITE_ERROR return from the underlying - ** xFileControl method. - ** --** See also: [SQLITE_FCNTL_LOCKSTATE] -+** See also: [file control opcodes] - */ - SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); - -@@ -7991,8 +8279,9 @@ - #define SQLITE_TESTCTRL_ALWAYS 13 - #define SQLITE_TESTCTRL_RESERVE 14 - #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 --#define SQLITE_TESTCTRL_ISKEYWORD 16 --#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 -+#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ -+#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ -+#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 - #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 - #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ - #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19 -@@ -8002,9 +8291,193 @@ - #define SQLITE_TESTCTRL_ISINIT 23 - #define SQLITE_TESTCTRL_SORTER_MMAP 24 - #define SQLITE_TESTCTRL_IMPOSTER 25 --#define SQLITE_TESTCTRL_LAST 25 -+#define SQLITE_TESTCTRL_PARSER_COVERAGE 26 -+#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */ - - /* -+** CAPI3REF: SQL Keyword Checking -+** -+** These routines provide access to the set of SQL language keywords -+** recognized by SQLite. Applications can uses these routines to determine -+** whether or not a specific identifier needs to be escaped (for example, -+** by enclosing in double-quotes) so as not to confuse the parser. -+** -+** The sqlite3_keyword_count() interface returns the number of distinct -+** keywords understood by SQLite. -+** -+** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and -+** makes *Z point to that keyword expressed as UTF8 and writes the number -+** of bytes in the keyword into *L. The string that *Z points to is not -+** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns -+** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z -+** or L are NULL or invalid pointers then calls to -+** sqlite3_keyword_name(N,Z,L) result in undefined behavior. -+** -+** The sqlite3_keyword_check(Z,L) interface checks to see whether or not -+** the L-byte UTF8 identifier that Z points to is a keyword, returning non-zero -+** if it is and zero if not. -+** -+** The parser used by SQLite is forgiving. It is often possible to use -+** a keyword as an identifier as long as such use does not result in a -+** parsing ambiguity. For example, the statement -+** "CREATE TABLE BEGIN(REPLACE,PRAGMA,END);" is accepted by SQLite, and -+** creates a new table named "BEGIN" with three columns named -+** "REPLACE", "PRAGMA", and "END". Nevertheless, best practice is to avoid -+** using keywords as identifiers. Common techniques used to avoid keyword -+** name collisions include: -+** <ul> -+** <li> Put all identifier names inside double-quotes. This is the official -+** SQL way to escape identifier names. -+** <li> Put identifier names inside [...]. This is not standard SQL, -+** but it is what SQL Server does and so lots of programmers use this -+** technique. -+** <li> Begin every identifier with the letter "Z" as no SQL keywords start -+** with "Z". -+** <li> Include a digit somewhere in every identifier name. -+** </ul> -+** -+** Note that the number of keywords understood by SQLite can depend on -+** compile-time options. For example, "VACUUM" is not a keyword if -+** SQLite is compiled with the [-DSQLITE_OMIT_VACUUM] option. Also, -+** new keywords may be added to future releases of SQLite. -+*/ -+SQLITE_API int sqlite3_keyword_count(void); -+SQLITE_API int sqlite3_keyword_name(int,const char**,int*); -+SQLITE_API int sqlite3_keyword_check(const char*,int); -+ -+/* -+** CAPI3REF: Dynamic String Object -+** KEYWORDS: {dynamic string} -+** -+** An instance of the sqlite3_str object contains a dynamically-sized -+** string under construction. -+** -+** The lifecycle of an sqlite3_str object is as follows: -+** <ol> -+** <li> ^The sqlite3_str object is created using [sqlite3_str_new()]. -+** <li> ^Text is appended to the sqlite3_str object using various -+** methods, such as [sqlite3_str_appendf()]. -+** <li> ^The sqlite3_str object is destroyed and the string it created -+** is returned using the [sqlite3_str_finish()] interface. -+** </ol> -+*/ -+typedef struct sqlite3_str sqlite3_str; -+ -+/* -+** CAPI3REF: Create A New Dynamic String Object -+** CONSTRUCTOR: sqlite3_str -+** -+** ^The [sqlite3_str_new(D)] interface allocates and initializes -+** a new [sqlite3_str] object. To avoid memory leaks, the object returned by -+** [sqlite3_str_new()] must be freed by a subsequent call to -+** [sqlite3_str_finish(X)]. -+** -+** ^The [sqlite3_str_new(D)] interface always returns a pointer to a -+** valid [sqlite3_str] object, though in the event of an out-of-memory -+** error the returned object might be a special singleton that will -+** silently reject new text, always return SQLITE_NOMEM from -+** [sqlite3_str_errcode()], always return 0 for -+** [sqlite3_str_length()], and always return NULL from -+** [sqlite3_str_finish(X)]. It is always safe to use the value -+** returned by [sqlite3_str_new(D)] as the sqlite3_str parameter -+** to any of the other [sqlite3_str] methods. -+** -+** The D parameter to [sqlite3_str_new(D)] may be NULL. If the -+** D parameter in [sqlite3_str_new(D)] is not NULL, then the maximum -+** length of the string contained in the [sqlite3_str] object will be -+** the value set for [sqlite3_limit](D,[SQLITE_LIMIT_LENGTH]) instead -+** of [SQLITE_MAX_LENGTH]. -+*/ -+SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*); -+ -+/* -+** CAPI3REF: Finalize A Dynamic String -+** DESTRUCTOR: sqlite3_str -+** -+** ^The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X -+** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()] -+** that contains the constructed string. The calling application should -+** pass the returned value to [sqlite3_free()] to avoid a memory leak. -+** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any -+** errors were encountered during construction of the string. ^The -+** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the -+** string in [sqlite3_str] object X is zero bytes long. -+*/ -+SQLITE_API char *sqlite3_str_finish(sqlite3_str*); -+ -+/* -+** CAPI3REF: Add Content To A Dynamic String -+** METHOD: sqlite3_str -+** -+** These interfaces add content to an sqlite3_str object previously obtained -+** from [sqlite3_str_new()]. -+** -+** ^The [sqlite3_str_appendf(X,F,...)] and -+** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf] -+** functionality of SQLite to append formatted text onto the end of -+** [sqlite3_str] object X. -+** -+** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S -+** onto the end of the [sqlite3_str] object X. N must be non-negative. -+** S must contain at least N non-zero bytes of content. To append a -+** zero-terminated string in its entirety, use the [sqlite3_str_appendall()] -+** method instead. -+** -+** ^The [sqlite3_str_appendall(X,S)] method appends the complete content of -+** zero-terminated string S onto the end of [sqlite3_str] object X. -+** -+** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the -+** single-byte character C onto the end of [sqlite3_str] object X. -+** ^This method can be used, for example, to add whitespace indentation. -+** -+** ^The [sqlite3_str_reset(X)] method resets the string under construction -+** inside [sqlite3_str] object X back to zero bytes in length. -+** -+** These methods do not return a result code. ^If an error occurs, that fact -+** is recorded in the [sqlite3_str] object and can be recovered by a -+** subsequent call to [sqlite3_str_errcode(X)]. -+*/ -+SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...); -+SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list); -+SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N); -+SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn); -+SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C); -+SQLITE_API void sqlite3_str_reset(sqlite3_str*); -+ -+/* -+** CAPI3REF: Status Of A Dynamic String -+** METHOD: sqlite3_str -+** -+** These interfaces return the current status of an [sqlite3_str] object. -+** -+** ^If any prior errors have occurred while constructing the dynamic string -+** in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return -+** an appropriate error code. ^The [sqlite3_str_errcode(X)] method returns -+** [SQLITE_NOMEM] following any out-of-memory error, or -+** [SQLITE_TOOBIG] if the size of the dynamic string exceeds -+** [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors. -+** -+** ^The [sqlite3_str_length(X)] method returns the current length, in bytes, -+** of the dynamic string under construction in [sqlite3_str] object X. -+** ^The length returned by [sqlite3_str_length(X)] does not include the -+** zero-termination byte. -+** -+** ^The [sqlite3_str_value(X)] method returns a pointer to the current -+** content of the dynamic string under construction in X. The value -+** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X -+** and might be freed or altered by any subsequent method on the same -+** [sqlite3_str] object. Applications must not used the pointer returned -+** [sqlite3_str_value(X)] after any subsequent method call on the same -+** object. ^Applications may change the content of the string returned -+** by [sqlite3_str_value(X)] as long as they do not write into any bytes -+** outside the range of 0 to [sqlite3_str_length(X)] and do not read or -+** write any byte after any subsequent sqlite3_str method call. -+*/ -+SQLITE_API int sqlite3_str_errcode(sqlite3_str*); -+SQLITE_API int sqlite3_str_length(sqlite3_str*); -+SQLITE_API char *sqlite3_str_value(sqlite3_str*); -+ -+/* - ** CAPI3REF: SQLite Runtime Status - ** - ** ^These interfaces are used to retrieve runtime status information -@@ -8051,8 +8524,7 @@ - ** <dd>This parameter is the current amount of memory checked out - ** using [sqlite3_malloc()], either directly or indirectly. The - ** figure includes calls made to [sqlite3_malloc()] by the application --** and internal memory usage by the SQLite library. Scratch memory --** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache -+** and internal memory usage by the SQLite library. Auxiliary page-cache - ** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in - ** this parameter. The amount returned is the sum of the allocation - ** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>)^ -@@ -8090,29 +8562,14 @@ - ** *pHighwater parameter to [sqlite3_status()] is of interest. - ** The value written into the *pCurrent parameter is undefined.</dd>)^ - ** --** [[SQLITE_STATUS_SCRATCH_USED]] ^(<dt>SQLITE_STATUS_SCRATCH_USED</dt> --** <dd>This parameter returns the number of allocations used out of the --** [scratch memory allocator] configured using --** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not --** in bytes. Since a single thread may only have one scratch allocation --** outstanding at time, this parameter also reports the number of threads --** using scratch memory at the same time.</dd>)^ -+** [[SQLITE_STATUS_SCRATCH_USED]] <dt>SQLITE_STATUS_SCRATCH_USED</dt> -+** <dd>No longer used.</dd> - ** - ** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt> --** <dd>This parameter returns the number of bytes of scratch memory --** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH] --** buffer and where forced to overflow to [sqlite3_malloc()]. The values --** returned include overflows because the requested allocation was too --** larger (that is, because the requested allocation was larger than the --** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer --** slots were available. --** </dd>)^ -+** <dd>No longer used.</dd> - ** --** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt> --** <dd>This parameter records the largest memory allocation request --** handed to [scratch 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.</dd>)^ -+** [[SQLITE_STATUS_SCRATCH_SIZE]] <dt>SQLITE_STATUS_SCRATCH_SIZE</dt> -+** <dd>No longer used.</dd> - ** - ** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt> - ** <dd>The *pHighwater parameter records the deepest parser stack. -@@ -8125,12 +8582,12 @@ - #define SQLITE_STATUS_MEMORY_USED 0 - #define SQLITE_STATUS_PAGECACHE_USED 1 - #define SQLITE_STATUS_PAGECACHE_OVERFLOW 2 --#define SQLITE_STATUS_SCRATCH_USED 3 --#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 -+#define SQLITE_STATUS_SCRATCH_USED 3 /* NOT USED */ -+#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 /* NOT USED */ - #define SQLITE_STATUS_MALLOC_SIZE 5 - #define SQLITE_STATUS_PARSER_STACK 6 - #define SQLITE_STATUS_PAGECACHE_SIZE 7 --#define SQLITE_STATUS_SCRATCH_SIZE 8 -+#define SQLITE_STATUS_SCRATCH_SIZE 8 /* NOT USED */ - #define SQLITE_STATUS_MALLOC_COUNT 9 - - /* -@@ -8253,6 +8710,15 @@ - ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. - ** </dd> - ** -+** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt> -+** <dd>This parameter returns the number of dirty cache entries that have -+** been written to disk in the middle of a transaction due to the page -+** 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. -+** </dd> -+** - ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt> - ** <dd>This parameter returns zero for the current value if and only if - ** all foreign key constraints (deferred or immediate) have been -@@ -8272,7 +8738,8 @@ - #define SQLITE_DBSTATUS_CACHE_WRITE 9 - #define SQLITE_DBSTATUS_DEFERRED_FKS 10 - #define SQLITE_DBSTATUS_CACHE_USED_SHARED 11 --#define SQLITE_DBSTATUS_MAX 11 /* Largest defined DBSTATUS */ -+#define SQLITE_DBSTATUS_CACHE_SPILL 12 -+#define SQLITE_DBSTATUS_MAX 12 /* Largest defined DBSTATUS */ - - - /* -@@ -9227,6 +9694,7 @@ - ** can use to customize and optimize their behavior. - ** - ** <dl> -+** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]] - ** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT - ** <dd>Calls of the form - ** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, -@@ -9273,6 +9741,40 @@ - SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); - - /* -+** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE -+** -+** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn] -+** method of a [virtual table], then it returns true if and only if the -+** column is being fetched as part of an UPDATE operation during which the -+** column value will not change. Applications might use this to substitute -+** a return value that is less expensive to compute and that the corresponding -+** [xUpdate] method understands as a "no-change" value. -+** -+** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that -+** the column is not changed by the UPDATE statement, then the xColumn -+** method can optionally return without setting a result, without calling -+** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces]. -+** In that case, [sqlite3_value_nochange(X)] will return true for the -+** same column in the [xUpdate] method. -+*/ -+SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*); -+ -+/* -+** CAPI3REF: Determine The Collation For a Virtual Table Constraint -+** -+** This function may only be called from within a call to the [xBestIndex] -+** method of a [virtual table]. -+** -+** The first argument must be the sqlite3_index_info object that is the -+** first parameter to the xBestIndex() method. The second argument must be -+** an index into the aConstraint[] array belonging to the sqlite3_index_info -+** structure passed to xBestIndex. This function returns a pointer to a buffer -+** containing the name of the collation sequence for the corresponding -+** constraint. -+*/ -+SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); -+ -+/* - ** CAPI3REF: Conflict resolution modes - ** KEYWORDS: {conflict resolution mode} - ** -@@ -9542,7 +10044,6 @@ - /* - ** CAPI3REF: Database Snapshot - ** KEYWORDS: {snapshot} {sqlite3_snapshot} --** EXPERIMENTAL - ** - ** An instance of the snapshot object records the state of a [WAL mode] - ** database for some specific point in history. -@@ -9559,11 +10060,6 @@ - ** version of the database file so that it is possible to later open a new read - ** transaction that sees that historical version of the database rather than - ** the most recent version. --** --** The constructor for this object is [sqlite3_snapshot_get()]. The --** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer --** to an historical snapshot (if possible). The destructor for --** sqlite3_snapshot objects is [sqlite3_snapshot_free()]. - */ - typedef struct sqlite3_snapshot { - unsigned char hidden[48]; -@@ -9571,7 +10067,7 @@ - - /* - ** CAPI3REF: Record A Database Snapshot --** EXPERIMENTAL -+** CONSTRUCTOR: sqlite3_snapshot - ** - ** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a - ** new [sqlite3_snapshot] object that records the current state of -@@ -9587,7 +10083,7 @@ - ** in this case. - ** - ** <ul> --** <li> The database handle must be in [autocommit mode]. -+** <li> The database handle must not be in [autocommit mode]. - ** - ** <li> Schema S of [database connection] D must be a [WAL mode] database. - ** -@@ -9610,7 +10106,7 @@ - ** to avoid a memory leak. - ** - ** The [sqlite3_snapshot_get()] interface is only available when the --** SQLITE_ENABLE_SNAPSHOT compile-time option is used. -+** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. - */ - SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( - sqlite3 *db, -@@ -9620,24 +10116,35 @@ - - /* - ** CAPI3REF: Start a read transaction on an historical snapshot --** EXPERIMENTAL -+** METHOD: sqlite3_snapshot - ** --** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a --** read transaction for schema S of --** [database connection] D such that the read transaction --** refers to historical [snapshot] P, rather than the most --** recent change to the database. --** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success --** or an appropriate [error code] if it fails. -+** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read -+** transaction or upgrades an existing one for schema S of -+** [database connection] D such that the read transaction refers to -+** historical [snapshot] P, rather than the most recent change to the -+** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK -+** on success or an appropriate [error code] if it fails. - ** --** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be --** the first operation following the [BEGIN] that takes the schema S --** out of [autocommit mode]. --** ^In other words, schema S must not currently be in --** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the --** database connection D must be out of [autocommit mode]. --** ^A [snapshot] will fail to open if it has been overwritten by a --** [checkpoint]. -+** ^In order to succeed, the database connection must not be in -+** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there -+** is already a read transaction open on schema S, then the database handle -+** must have no active statements (SELECT statements that have been passed -+** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). -+** SQLITE_ERROR is returned if either of these conditions is violated, or -+** if schema S does not exist, or if the snapshot object is invalid. -+** -+** ^A call to sqlite3_snapshot_open() will fail to open if the specified -+** snapshot has been overwritten by a [checkpoint]. In this case -+** SQLITE_ERROR_SNAPSHOT is returned. -+** -+** If there is already a read transaction open when this function is -+** invoked, then the same read transaction remains open (on the same -+** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT -+** is returned. If another error code - for example SQLITE_PROTOCOL or an -+** SQLITE_IOERR error code - is returned, then the final state of the -+** read transaction is undefined. If SQLITE_OK is returned, then the -+** read transaction is now open on database snapshot P. -+** - ** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the - ** database connection D does not know that the database file for - ** schema S is in [WAL mode]. A database connection might not know -@@ -9648,7 +10155,7 @@ - ** database connection in order to make it ready to use snapshots.) - ** - ** The [sqlite3_snapshot_open()] interface is only available when the --** SQLITE_ENABLE_SNAPSHOT compile-time option is used. -+** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. - */ - SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open( - sqlite3 *db, -@@ -9658,7 +10165,7 @@ - - /* - ** CAPI3REF: Destroy a snapshot --** EXPERIMENTAL -+** DESTRUCTOR: sqlite3_snapshot - ** - ** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P. - ** The application must eventually free every [sqlite3_snapshot] object -@@ -9665,13 +10172,13 @@ - ** using this routine to avoid a memory leak. - ** - ** The [sqlite3_snapshot_free()] interface is only available when the --** SQLITE_ENABLE_SNAPSHOT compile-time option is used. -+** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. - */ - SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); - - /* - ** CAPI3REF: Compare the ages of two snapshot handles. --** EXPERIMENTAL -+** METHOD: sqlite3_snapshot - ** - ** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages - ** of two valid snapshot handles. -@@ -9690,6 +10197,9 @@ - ** Otherwise, this API returns a negative value if P1 refers to an older - ** snapshot than P2, zero if the two handles refer to the same database - ** snapshot, and a positive value if P1 is a newer snapshot than P2. -+** -+** This interface is only available if SQLite is compiled with the -+** [SQLITE_ENABLE_SNAPSHOT] option. - */ - SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( - sqlite3_snapshot *p1, -@@ -9698,27 +10208,152 @@ - - /* - ** CAPI3REF: Recover snapshots from a wal file --** EXPERIMENTAL -+** METHOD: sqlite3_snapshot - ** --** If all connections disconnect from a database file but do not perform --** a checkpoint, the existing wal file is opened along with the database --** file the next time the database is opened. At this point it is only --** possible to successfully call sqlite3_snapshot_open() to open the most --** recent snapshot of the database (the one at the head of the wal file), --** even though the wal file may contain other valid snapshots for which --** clients have sqlite3_snapshot handles. -+** If a [WAL file] remains on disk after all database connections close -+** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control] -+** or because the last process to have the database opened exited without -+** calling [sqlite3_close()]) and a new connection is subsequently opened -+** on that database and [WAL file], the [sqlite3_snapshot_open()] interface -+** will only be able to open the last transaction added to the WAL file -+** even though the WAL file contains other valid transactions. - ** --** This function attempts to scan the wal file associated with database zDb -+** This function attempts to scan the WAL file associated with database zDb - ** of database handle db and make all valid snapshots available to - ** sqlite3_snapshot_open(). It is an error if there is already a read --** transaction open on the database, or if the database is not a wal mode -+** transaction open on the database, or if the database is not a WAL mode - ** database. - ** - ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. -+** -+** This interface is only available if SQLite is compiled with the -+** [SQLITE_ENABLE_SNAPSHOT] option. - */ - SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); - - /* -+** CAPI3REF: Serialize a database -+** -+** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory -+** that is a serialization of the S database on [database connection] D. -+** If P is not a NULL pointer, then the size of the database in bytes -+** is written into *P. -+** -+** For an ordinary on-disk database file, the serialization is just a -+** copy of the disk file. For an in-memory database or a "TEMP" database, -+** the serialization is the same sequence of bytes which would be written -+** to disk if that database where backed up to disk. -+** -+** The usual case is that sqlite3_serialize() copies the serialization of -+** the database into memory obtained from [sqlite3_malloc64()] and returns -+** a pointer to that memory. The caller is responsible for freeing the -+** returned value to avoid a memory leak. However, if the F argument -+** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations -+** are made, and the sqlite3_serialize() function will return a pointer -+** to the contiguous memory representation of the database that SQLite -+** is currently using for that database, or NULL if the no such contiguous -+** memory representation of the database exists. A contiguous memory -+** representation of the database will usually only exist if there has -+** been a prior call to [sqlite3_deserialize(D,S,...)] with the same -+** values of D and S. -+** The size of the database is written into *P even if the -+** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy -+** of the database exists. -+** -+** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the -+** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory -+** allocation error occurs. -+** -+** This interface is only available if SQLite is compiled with the -+** [SQLITE_ENABLE_DESERIALIZE] option. -+*/ -+SQLITE_API unsigned char *sqlite3_serialize( -+ sqlite3 *db, /* The database connection */ -+ const char *zSchema, /* Which DB to serialize. ex: "main", "temp", ... */ -+ sqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */ -+ unsigned int mFlags /* Zero or more SQLITE_SERIALIZE_* flags */ -+); -+ -+/* -+** CAPI3REF: Flags for sqlite3_serialize -+** -+** Zero or more of the following constants can be OR-ed together for -+** the F argument to [sqlite3_serialize(D,S,P,F)]. -+** -+** SQLITE_SERIALIZE_NOCOPY means that [sqlite3_serialize()] will return -+** a pointer to contiguous in-memory database that it is currently using, -+** without making a copy of the database. If SQLite is not currently using -+** a contiguous in-memory database, then this option causes -+** [sqlite3_serialize()] to return a NULL pointer. SQLite will only be -+** using a contiguous in-memory database if it has been initialized by a -+** prior call to [sqlite3_deserialize()]. -+*/ -+#define SQLITE_SERIALIZE_NOCOPY 0x001 /* Do no memory allocations */ -+ -+/* -+** CAPI3REF: Deserialize a database -+** -+** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the -+** [database connection] D to disconnect from database S and then -+** reopen S as an in-memory database based on the serialization contained -+** in P. The serialized database P is N bytes in size. M is the size of -+** the buffer P, which might be larger than N. If M is larger than N, and -+** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is -+** permitted to add content to the in-memory database as long as the total -+** size does not exceed M bytes. -+** -+** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will -+** invoke sqlite3_free() on the serialization buffer when the database -+** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then -+** SQLite will try to increase the buffer size using sqlite3_realloc64() -+** if writes on the database cause it to grow larger than M bytes. -+** -+** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the -+** database is currently in a read transaction or is involved in a backup -+** operation. -+** -+** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the -+** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then -+** [sqlite3_free()] is invoked on argument P prior to returning. -+** -+** This interface is only available if SQLite is compiled with the -+** [SQLITE_ENABLE_DESERIALIZE] option. -+*/ -+SQLITE_API int sqlite3_deserialize( -+ sqlite3 *db, /* The database connection */ -+ const char *zSchema, /* Which DB to reopen with the deserialization */ -+ unsigned char *pData, /* The serialized database content */ -+ sqlite3_int64 szDb, /* Number bytes in the deserialization */ -+ sqlite3_int64 szBuf, /* Total size of buffer pData[] */ -+ unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */ -+); -+ -+/* -+** CAPI3REF: Flags for sqlite3_deserialize() -+** -+** The following are allowed values for 6th argument (the F argument) to -+** the [sqlite3_deserialize(D,S,P,N,M,F)] interface. -+** -+** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization -+** in the P argument is held in memory obtained from [sqlite3_malloc64()] -+** and that SQLite should take ownership of this memory and automatically -+** free it when it has finished using it. Without this flag, the caller -+** is responsible for freeing any dynamically allocated memory. -+** -+** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to -+** grow the size of the database using calls to [sqlite3_realloc64()]. This -+** flag should only be used if SQLITE_DESERIALIZE_FREEONCLOSE is also used. -+** Without this flag, the deserialized database cannot increase in size beyond -+** the number of bytes specified by the M parameter. -+** -+** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database -+** should be treated as read-only. -+*/ -+#define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */ -+#define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */ -+#define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */ -+ -+/* - ** Undo the hack that converts floating point types to integer for - ** builds on processors without floating point support. - */ -@@ -9829,7 +10464,7 @@ - sqlite3_int64 iRowid; /* Rowid for current entry */ - sqlite3_rtree_dbl rParentScore; /* Score of parent node */ - int eParentWithin; /* Visibility of parent node */ -- int eWithin; /* OUT: Visiblity */ -+ int eWithin; /* OUT: Visibility */ - sqlite3_rtree_dbl rScore; /* OUT: Write the score here */ - /* The following fields are only available in 3.8.11 and later */ - sqlite3_value **apSqlParam; /* Original SQL values of parameters */ -@@ -9865,16 +10500,23 @@ - - /* - ** CAPI3REF: Session Object Handle -+** -+** An instance of this object is a [session] that can be used to -+** record changes to a database. - */ - typedef struct sqlite3_session sqlite3_session; - - /* - ** CAPI3REF: Changeset Iterator Handle -+** -+** An instance of this object acts as a cursor for iterating -+** over the elements of a [changeset] or [patchset]. - */ - typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; - - /* - ** CAPI3REF: Create A New Session Object -+** CONSTRUCTOR: sqlite3_session - ** - ** Create a new session object attached to database handle db. If successful, - ** a pointer to the new object is written to *ppSession and SQLITE_OK is -@@ -9911,6 +10553,7 @@ - - /* - ** CAPI3REF: Delete A Session Object -+** DESTRUCTOR: sqlite3_session - ** - ** Delete a session object previously allocated using - ** [sqlite3session_create()]. Once a session object has been deleted, the -@@ -9926,6 +10569,7 @@ - - /* - ** CAPI3REF: Enable Or Disable A Session Object -+** METHOD: sqlite3_session - ** - ** Enable or disable the recording of changes by a session object. When - ** enabled, a session object records changes made to the database. When -@@ -9945,6 +10589,7 @@ - - /* - ** CAPI3REF: Set Or Clear the Indirect Change Flag -+** METHOD: sqlite3_session - ** - ** Each change recorded by a session object is marked as either direct or - ** indirect. A change is marked as indirect if either: -@@ -9974,6 +10619,7 @@ - - /* - ** CAPI3REF: Attach A Table To A Session Object -+** METHOD: sqlite3_session - ** - ** If argument zTab is not NULL, then it is the name of a table to attach - ** to the session object passed as the first argument. All subsequent changes -@@ -9999,6 +10645,35 @@ - ** - ** SQLITE_OK is returned if the call completes without error. Or, if an error - ** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned. -+** -+** <h3>Special sqlite_stat1 Handling</h3> -+** -+** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to -+** some of the rules above. In SQLite, the schema of sqlite_stat1 is: -+** <pre> -+** CREATE TABLE sqlite_stat1(tbl,idx,stat) -+** </pre> -+** -+** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are -+** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes -+** are recorded for rows for which (idx IS NULL) is true. However, for such -+** rows a zero-length blob (SQL value X'') is stored in the changeset or -+** patchset instead of a NULL value. This allows such changesets to be -+** manipulated by legacy implementations of sqlite3changeset_invert(), -+** concat() and similar. -+** -+** The sqlite3changeset_apply() function automatically converts the -+** zero-length blob back to a NULL value when updating the sqlite_stat1 -+** table. However, if the application calls sqlite3changeset_new(), -+** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset -+** iterator directly (including on a changeset iterator passed to a -+** conflict-handler callback) then the X'' value is returned. The application -+** must translate X'' to NULL itself if required. -+** -+** Legacy (older than 3.22.0) versions of the sessions module cannot capture -+** changes made to the sqlite_stat1 table. Legacy versions of the -+** sqlite3changeset_apply() function silently ignore any modifications to the -+** sqlite_stat1 table that are part of a changeset or patchset. - */ - SQLITE_API int sqlite3session_attach( - sqlite3_session *pSession, /* Session object */ -@@ -10007,6 +10682,7 @@ - - /* - ** CAPI3REF: Set a table filter on a Session Object. -+** METHOD: sqlite3_session - ** - ** 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 -@@ -10025,6 +10701,7 @@ - - /* - ** CAPI3REF: Generate A Changeset From A Session Object -+** METHOD: sqlite3_session - ** - ** Obtain a changeset containing changes to the tables attached to the - ** session object passed as the first argument. If successful, -@@ -10134,7 +10811,8 @@ - ); - - /* --** CAPI3REF: Load The Difference Between Tables Into A Session -+** CAPI3REF: Load The Difference Between Tables Into A Session -+** METHOD: sqlite3_session - ** - ** If it is not already attached to the session object passed as the first - ** argument, this function attaches table zTbl in the same manner as the -@@ -10199,6 +10877,7 @@ - - /* - ** CAPI3REF: Generate A Patchset From A Session Object -+** METHOD: sqlite3_session - ** - ** The differences between a patchset and a changeset are that: - ** -@@ -10227,8 +10906,8 @@ - */ - SQLITE_API int sqlite3session_patchset( - sqlite3_session *pSession, /* Session object */ -- int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */ -- void **ppPatchset /* OUT: Buffer containing changeset */ -+ int *pnPatchset, /* OUT: Size of buffer at *ppPatchset */ -+ void **ppPatchset /* OUT: Buffer containing patchset */ - ); - - /* -@@ -10250,6 +10929,7 @@ - - /* - ** CAPI3REF: Create An Iterator To Traverse A Changeset -+** CONSTRUCTOR: sqlite3_changeset_iter - ** - ** Create an iterator used to iterate through the contents of a changeset. - ** If successful, *pp is set to point to the iterator handle and SQLITE_OK -@@ -10280,6 +10960,13 @@ - ** consecutively. There is no chance that the iterator will visit a change - ** the applies to table X, then one for table Y, and then later on visit - ** another change for table X. -+** -+** The behavior of sqlite3changeset_start_v2() and its streaming equivalent -+** may be modified by passing a combination of -+** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter. -+** -+** Note that the sqlite3changeset_start_v2() API is still <b>experimental</b> -+** and therefore subject to change. - */ - SQLITE_API int sqlite3changeset_start( - sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ -@@ -10286,10 +10973,30 @@ - int nChangeset, /* Size of changeset blob in bytes */ - void *pChangeset /* Pointer to blob containing changeset */ - ); -+SQLITE_API int sqlite3changeset_start_v2( -+ sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ -+ int nChangeset, /* Size of changeset blob in bytes */ -+ void *pChangeset, /* Pointer to blob containing changeset */ -+ int flags /* SESSION_CHANGESETSTART_* flags */ -+); - -+/* -+** CAPI3REF: Flags for sqlite3changeset_start_v2 -+** -+** The following flags may passed via the 4th parameter to -+** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]: -+** -+** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd> -+** Invert the changeset while iterating through it. This is equivalent to -+** inverting a changeset using sqlite3changeset_invert() before applying it. -+** It is an error to specify this flag with a patchset. -+*/ -+#define SQLITE_CHANGESETSTART_INVERT 0x0002 - -+ - /* - ** CAPI3REF: Advance A Changeset Iterator -+** METHOD: sqlite3_changeset_iter - ** - ** This function may only be used with iterators created by function - ** [sqlite3changeset_start()]. If it is called on an iterator passed to -@@ -10314,6 +11021,7 @@ - - /* - ** CAPI3REF: Obtain The Current Operation From A Changeset Iterator -+** METHOD: sqlite3_changeset_iter - ** - ** The pIter argument passed to this function may either be an iterator - ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator -@@ -10348,6 +11056,7 @@ - - /* - ** CAPI3REF: Obtain The Primary Key Definition Of A Table -+** METHOD: sqlite3_changeset_iter - ** - ** For each modified table, a changeset includes the following: - ** -@@ -10379,6 +11088,7 @@ - - /* - ** CAPI3REF: Obtain old.* Values From A Changeset Iterator -+** METHOD: sqlite3_changeset_iter - ** - ** The pIter argument passed to this function may either be an iterator - ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator -@@ -10409,6 +11119,7 @@ - - /* - ** CAPI3REF: Obtain new.* Values From A Changeset Iterator -+** METHOD: sqlite3_changeset_iter - ** - ** The pIter argument passed to this function may either be an iterator - ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator -@@ -10442,6 +11153,7 @@ - - /* - ** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator -+** METHOD: sqlite3_changeset_iter - ** - ** This function should only be used with iterator objects passed to a - ** conflict-handler callback by [sqlite3changeset_apply()] with either -@@ -10469,6 +11181,7 @@ - - /* - ** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations -+** METHOD: sqlite3_changeset_iter - ** - ** This function may only be called with an iterator passed to an - ** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case -@@ -10485,6 +11198,7 @@ - - /* - ** CAPI3REF: Finalize A Changeset Iterator -+** METHOD: sqlite3_changeset_iter - ** - ** This function is used to finalize an iterator allocated with - ** [sqlite3changeset_start()]. -@@ -10501,6 +11215,7 @@ - ** to that error is returned by this function. Otherwise, SQLITE_OK is - ** returned. This is to allow the following pattern (pseudo-code): - ** -+** <pre> - ** sqlite3changeset_start(); - ** while( SQLITE_ROW==sqlite3changeset_next() ){ - ** // Do something with change. -@@ -10509,6 +11224,7 @@ - ** if( rc!=SQLITE_OK ){ - ** // An error has occurred - ** } -+** </pre> - */ - SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); - -@@ -10556,6 +11272,7 @@ - ** sqlite3_changegroup object. Calling it produces similar results as the - ** following code fragment: - ** -+** <pre> - ** sqlite3_changegroup *pGrp; - ** rc = sqlite3_changegroup_new(&pGrp); - ** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA); -@@ -10566,6 +11283,7 @@ - ** *ppOut = 0; - ** *pnOut = 0; - ** } -+** </pre> - ** - ** Refer to the sqlite3_changegroup documentation below for details. - */ -@@ -10581,11 +11299,15 @@ - - /* - ** CAPI3REF: Changegroup Handle -+** -+** A changegroup is an object used to combine two or more -+** [changesets] or [patchsets] - */ - typedef struct sqlite3_changegroup sqlite3_changegroup; - - /* - ** CAPI3REF: Create A New Changegroup Object -+** CONSTRUCTOR: sqlite3_changegroup - ** - ** An sqlite3_changegroup object is used to combine two or more changesets - ** (or patchsets) into a single changeset (or patchset). A single changegroup -@@ -10623,6 +11345,7 @@ - - /* - ** CAPI3REF: Add A Changeset To A Changegroup -+** METHOD: sqlite3_changegroup - ** - ** Add all changes within the changeset (or patchset) in buffer pData (size - ** nData bytes) to the changegroup. -@@ -10700,6 +11423,7 @@ - - /* - ** CAPI3REF: Obtain A Composite Changeset From A Changegroup -+** METHOD: sqlite3_changegroup - ** - ** Obtain a buffer containing a changeset (or patchset) representing the - ** current contents of the changegroup. If the inputs to the changegroup -@@ -10730,6 +11454,7 @@ - - /* - ** CAPI3REF: Delete A Changegroup Object -+** DESTRUCTOR: sqlite3_changegroup - */ - SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*); - -@@ -10736,19 +11461,18 @@ - /* - ** CAPI3REF: Apply A Changeset To A Database - ** --** Apply a changeset to a database. This function attempts to update the --** "main" database attached to handle db with the changes found in the --** changeset passed via the second and third arguments. -+** Apply a changeset or patchset to a database. These functions attempt to -+** update the "main" database attached to handle db with the changes found in -+** the changeset passed via the second and third arguments. - ** --** The fourth argument (xFilter) passed to this function is the "filter -+** The fourth argument (xFilter) passed to these functions is the "filter - ** callback". If it is not NULL, then for each table affected by at least one - ** change in the changeset, the filter callback is invoked with - ** the table name as the second argument, and a copy of the context pointer --** passed as the sixth argument to this function as the first. If the "filter --** callback" returns zero, then no attempt is made to apply any changes to --** the table. Otherwise, if the return value is non-zero or the xFilter --** argument to this function is NULL, all changes related to the table are --** attempted. -+** passed as the sixth argument as the first. If the "filter callback" -+** returns zero, then no attempt is made to apply any changes to the table. -+** Otherwise, if the return value is non-zero or the xFilter argument to -+** is NULL, all changes related to the table are attempted. - ** - ** For each table that is not excluded by the filter callback, this function - ** tests that the target database contains a compatible table. A table is -@@ -10793,7 +11517,7 @@ - ** - ** <dl> - ** <dt>DELETE Changes<dd> --** For each DELETE change, this function checks if the target database -+** For each DELETE change, the function checks if the target database - ** contains a row with the same primary key value (or values) as the - ** original row values stored in the changeset. If it does, and the values - ** stored in all non-primary key columns also match the values stored in -@@ -10838,7 +11562,7 @@ - ** [SQLITE_CHANGESET_REPLACE]. - ** - ** <dt>UPDATE Changes<dd> --** For each UPDATE change, this function checks if the target database -+** For each UPDATE change, the function checks if the target database - ** contains a row with the same primary key value (or values) as the - ** original row values stored in the changeset. If it does, and the values - ** stored in all modified non-primary key columns also match the values -@@ -10869,11 +11593,28 @@ - ** This can be used to further customize the applications conflict - ** resolution strategy. - ** --** All changes made by this function are enclosed in a savepoint transaction. -+** All changes made by these functions are enclosed in a savepoint transaction. - ** If any other error (aside from a constraint failure when attempting to - ** write to the target database) occurs, then the savepoint transaction is - ** rolled back, restoring the target database to its original state, and an - ** SQLite error code returned. -+** -+** If the output parameters (ppRebase) and (pnRebase) are non-NULL and -+** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2() -+** may set (*ppRebase) to point to a "rebase" that may be used with the -+** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase) -+** is set to the size of the buffer in bytes. It is the responsibility of the -+** caller to eventually free any such buffer using sqlite3_free(). The buffer -+** is only allocated and populated if one or more conflicts were encountered -+** while applying the patchset. See comments surrounding the sqlite3_rebaser -+** APIs for further details. -+** -+** The behavior of sqlite3changeset_apply_v2() and its streaming equivalent -+** may be modified by passing a combination of -+** [SQLITE_CHANGESETAPPLY_NOSAVEPOINT | supported flags] as the 9th parameter. -+** -+** Note that the sqlite3changeset_apply_v2() API is still <b>experimental</b> -+** and therefore subject to change. - */ - SQLITE_API int sqlite3changeset_apply( - sqlite3 *db, /* Apply change to "main" db of this handle */ -@@ -10890,7 +11631,48 @@ - ), - void *pCtx /* First argument passed to xConflict */ - ); -+SQLITE_API int sqlite3changeset_apply_v2( -+ sqlite3 *db, /* Apply change to "main" db of this handle */ -+ int nChangeset, /* Size of changeset in bytes */ -+ void *pChangeset, /* Changeset blob */ -+ int(*xFilter)( -+ void *pCtx, /* Copy of sixth arg to _apply() */ -+ const char *zTab /* Table name */ -+ ), -+ int(*xConflict)( -+ void *pCtx, /* Copy of sixth arg to _apply() */ -+ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ -+ sqlite3_changeset_iter *p /* Handle describing change and conflict */ -+ ), -+ void *pCtx, /* First argument passed to xConflict */ -+ void **ppRebase, int *pnRebase, /* OUT: Rebase data */ -+ int flags /* SESSION_CHANGESETAPPLY_* flags */ -+); - -+/* -+** CAPI3REF: Flags for sqlite3changeset_apply_v2 -+** -+** The following flags may passed via the 9th parameter to -+** [sqlite3changeset_apply_v2] and [sqlite3changeset_apply_v2_strm]: -+** -+** <dl> -+** <dt>SQLITE_CHANGESETAPPLY_NOSAVEPOINT <dd> -+** Usually, the sessions module encloses all operations performed by -+** a single call to apply_v2() or apply_v2_strm() in a [SAVEPOINT]. The -+** SAVEPOINT is committed if the changeset or patchset is successfully -+** applied, or rolled back if an error occurs. Specifying this flag -+** causes the sessions module to omit this savepoint. In this case, if the -+** caller has an open transaction or savepoint when apply_v2() is called, -+** it may revert the partially applied changeset by rolling it back. -+** -+** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd> -+** Invert the changeset before applying it. This is equivalent to inverting -+** a changeset using sqlite3changeset_invert() before applying it. It is -+** an error to specify this flag with a patchset. -+*/ -+#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 -+#define SQLITE_CHANGESETAPPLY_INVERT 0x0002 -+ - /* - ** CAPI3REF: Constants Passed To The Conflict Handler - ** -@@ -10987,7 +11769,162 @@ - #define SQLITE_CHANGESET_REPLACE 1 - #define SQLITE_CHANGESET_ABORT 2 - -+/* -+** CAPI3REF: Rebasing changesets -+** EXPERIMENTAL -+** -+** Suppose there is a site hosting a database in state S0. And that -+** modifications are made that move that database to state S1 and a -+** changeset recorded (the "local" changeset). Then, a changeset based -+** on S0 is received from another site (the "remote" changeset) and -+** applied to the database. The database is then in state -+** (S1+"remote"), where the exact state depends on any conflict -+** resolution decisions (OMIT or REPLACE) made while applying "remote". -+** Rebasing a changeset is to update it to take those conflict -+** resolution decisions into account, so that the same conflicts -+** do not have to be resolved elsewhere in the network. -+** -+** For example, if both the local and remote changesets contain an -+** INSERT of the same key on "CREATE TABLE t1(a PRIMARY KEY, b)": -+** -+** local: INSERT INTO t1 VALUES(1, 'v1'); -+** remote: INSERT INTO t1 VALUES(1, 'v2'); -+** -+** and the conflict resolution is REPLACE, then the INSERT change is -+** removed from the local changeset (it was overridden). Or, if the -+** conflict resolution was "OMIT", then the local changeset is modified -+** to instead contain: -+** -+** UPDATE t1 SET b = 'v2' WHERE a=1; -+** -+** Changes within the local changeset are rebased as follows: -+** -+** <dl> -+** <dt>Local INSERT<dd> -+** This may only conflict with a remote INSERT. If the conflict -+** resolution was OMIT, then add an UPDATE change to the rebased -+** changeset. Or, if the conflict resolution was REPLACE, add -+** nothing to the rebased changeset. -+** -+** <dt>Local DELETE<dd> -+** This may conflict with a remote UPDATE or DELETE. In both cases the -+** only possible resolution is OMIT. If the remote operation was a -+** DELETE, then add no change to the rebased changeset. If the remote -+** operation was an UPDATE, then the old.* fields of change are updated -+** to reflect the new.* values in the UPDATE. -+** -+** <dt>Local UPDATE<dd> -+** This may conflict with a remote UPDATE or DELETE. If it conflicts -+** with a DELETE, and the conflict resolution was OMIT, then the update -+** is changed into an INSERT. Any undefined values in the new.* record -+** from the update change are filled in using the old.* values from -+** the conflicting DELETE. Or, if the conflict resolution was REPLACE, -+** the UPDATE change is simply omitted from the rebased changeset. -+** -+** If conflict is with a remote UPDATE and the resolution is OMIT, then -+** the old.* values are rebased using the new.* values in the remote -+** change. Or, if the resolution is REPLACE, then the change is copied -+** into the rebased changeset with updates to columns also updated by -+** the conflicting remote UPDATE removed. If this means no columns would -+** be updated, the change is omitted. -+** </dl> -+** -+** A local change may be rebased against multiple remote changes -+** simultaneously. If a single key is modified by multiple remote -+** changesets, they are combined as follows before the local changeset -+** is rebased: -+** -+** <ul> -+** <li> If there has been one or more REPLACE resolutions on a -+** key, it is rebased according to a REPLACE. -+** -+** <li> If there have been no REPLACE resolutions on a key, then -+** the local changeset is rebased according to the most recent -+** of the OMIT resolutions. -+** </ul> -+** -+** Note that conflict resolutions from multiple remote changesets are -+** combined on a per-field basis, not per-row. This means that in the -+** case of multiple remote UPDATE operations, some fields of a single -+** local change may be rebased for REPLACE while others are rebased for -+** OMIT. -+** -+** In order to rebase a local changeset, the remote changeset must first -+** be applied to the local database using sqlite3changeset_apply_v2() and -+** the buffer of rebase information captured. Then: -+** -+** <ol> -+** <li> An sqlite3_rebaser object is created by calling -+** sqlite3rebaser_create(). -+** <li> The new object is configured with the rebase buffer obtained from -+** sqlite3changeset_apply_v2() by calling sqlite3rebaser_configure(). -+** If the local changeset is to be rebased against multiple remote -+** changesets, then sqlite3rebaser_configure() should be called -+** multiple times, in the same order that the multiple -+** sqlite3changeset_apply_v2() calls were made. -+** <li> Each local changeset is rebased by calling sqlite3rebaser_rebase(). -+** <li> The sqlite3_rebaser object is deleted by calling -+** sqlite3rebaser_delete(). -+** </ol> -+*/ -+typedef struct sqlite3_rebaser sqlite3_rebaser; -+ - /* -+** CAPI3REF: Create a changeset rebaser object. -+** EXPERIMENTAL -+** -+** Allocate a new changeset rebaser object. If successful, set (*ppNew) to -+** point to the new object and return SQLITE_OK. Otherwise, if an error -+** occurs, return an SQLite error code (e.g. SQLITE_NOMEM) and set (*ppNew) -+** to NULL. -+*/ -+SQLITE_API int sqlite3rebaser_create(sqlite3_rebaser **ppNew); -+ -+/* -+** CAPI3REF: Configure a changeset rebaser object. -+** EXPERIMENTAL -+** -+** Configure the changeset rebaser object to rebase changesets according -+** to the conflict resolutions described by buffer pRebase (size nRebase -+** bytes), which must have been obtained from a previous call to -+** sqlite3changeset_apply_v2(). -+*/ -+SQLITE_API int sqlite3rebaser_configure( -+ sqlite3_rebaser*, -+ int nRebase, const void *pRebase -+); -+ -+/* -+** CAPI3REF: Rebase a changeset -+** EXPERIMENTAL -+** -+** 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 -+** rebaser object passed as the first argument. If successful, (*ppOut) -+** is set to point to the new buffer containing the rebased changset and -+** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the -+** responsibility of the caller to eventually free the new buffer using -+** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut) -+** are set to zero and an SQLite error code returned. -+*/ -+SQLITE_API int sqlite3rebaser_rebase( -+ sqlite3_rebaser*, -+ int nIn, const void *pIn, -+ int *pnOut, void **ppOut -+); -+ -+/* -+** CAPI3REF: Delete a changeset rebaser object. -+** EXPERIMENTAL -+** -+** Delete the changeset rebaser object and all associated resources. There -+** should be one call to this function for each successful invocation -+** of sqlite3rebaser_create(). -+*/ -+SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p); -+ -+/* - ** CAPI3REF: Streaming Versions of API functions. - ** - ** The six streaming API xxx_strm() functions serve similar purposes to the -@@ -10995,12 +11932,13 @@ - ** - ** <table border=1 style="margin-left:8ex;margin-right:8ex"> - ** <tr><th>Streaming function<th>Non-streaming equivalent</th> --** <tr><td>sqlite3changeset_apply_str<td>[sqlite3changeset_apply] --** <tr><td>sqlite3changeset_concat_str<td>[sqlite3changeset_concat] --** <tr><td>sqlite3changeset_invert_str<td>[sqlite3changeset_invert] --** <tr><td>sqlite3changeset_start_str<td>[sqlite3changeset_start] --** <tr><td>sqlite3session_changeset_str<td>[sqlite3session_changeset] --** <tr><td>sqlite3session_patchset_str<td>[sqlite3session_patchset] -+** <tr><td>sqlite3changeset_apply_strm<td>[sqlite3changeset_apply] -+** <tr><td>sqlite3changeset_apply_strm_v2<td>[sqlite3changeset_apply_v2] -+** <tr><td>sqlite3changeset_concat_strm<td>[sqlite3changeset_concat] -+** <tr><td>sqlite3changeset_invert_strm<td>[sqlite3changeset_invert] -+** <tr><td>sqlite3changeset_start_strm<td>[sqlite3changeset_start] -+** <tr><td>sqlite3session_changeset_strm<td>[sqlite3session_changeset] -+** <tr><td>sqlite3session_patchset_strm<td>[sqlite3session_patchset] - ** </table> - ** - ** Non-streaming functions that accept changesets (or patchsets) as input -@@ -11091,6 +12029,23 @@ - ), - void *pCtx /* First argument passed to xConflict */ - ); -+SQLITE_API int sqlite3changeset_apply_v2_strm( -+ sqlite3 *db, /* Apply change to "main" db of this handle */ -+ int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ -+ void *pIn, /* First arg for xInput */ -+ int(*xFilter)( -+ void *pCtx, /* Copy of sixth arg to _apply() */ -+ const char *zTab /* Table name */ -+ ), -+ int(*xConflict)( -+ void *pCtx, /* Copy of sixth arg to _apply() */ -+ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ -+ sqlite3_changeset_iter *p /* Handle describing change and conflict */ -+ ), -+ void *pCtx, /* First argument passed to xConflict */ -+ void **ppRebase, int *pnRebase, -+ int flags -+); - SQLITE_API int sqlite3changeset_concat_strm( - int (*xInputA)(void *pIn, void *pData, int *pnData), - void *pInA, -@@ -11110,6 +12065,12 @@ - int (*xInput)(void *pIn, void *pData, int *pnData), - void *pIn - ); -+SQLITE_API int sqlite3changeset_start_v2_strm( -+ sqlite3_changeset_iter **pp, -+ int (*xInput)(void *pIn, void *pData, int *pnData), -+ void *pIn, -+ int flags -+); - SQLITE_API int sqlite3session_changeset_strm( - sqlite3_session *pSession, - int (*xOutput)(void *pOut, const void *pData, int nData), -@@ -11128,9 +12089,55 @@ - int (*xOutput)(void *pOut, const void *pData, int nData), - void *pOut - ); -+SQLITE_API int sqlite3rebaser_rebase_strm( -+ sqlite3_rebaser *pRebaser, -+ int (*xInput)(void *pIn, void *pData, int *pnData), -+ void *pIn, -+ int (*xOutput)(void *pOut, const void *pData, int nData), -+ void *pOut -+); - -+/* -+** CAPI3REF: Configure global parameters -+** -+** The sqlite3session_config() interface is used to make global configuration -+** changes to the sessions module in order to tune it to the specific needs -+** of the application. -+** -+** The sqlite3session_config() interface is not threadsafe. If it is invoked -+** while any other thread is inside any other sessions method then the -+** results are undefined. Furthermore, if it is invoked after any sessions -+** related objects have been created, the results are also undefined. -+** -+** The first argument to the sqlite3session_config() function must be one -+** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The -+** interpretation of the (void*) value passed as the second parameter and -+** the effect of calling this function depends on the value of the first -+** parameter. -+** -+** <dl> -+** <dt>SQLITE_SESSION_CONFIG_STRMSIZE<dd> -+** By default, the sessions module streaming interfaces attempt to input -+** and output data in approximately 1 KiB chunks. This operand may be used -+** to set and query the value of this configuration setting. The pointer -+** passed as the second argument must point to a value of type (int). -+** If this value is greater than 0, it is used as the new streaming data -+** chunk size for both input and output. Before returning, the (int) value -+** pointed to by pArg is set to the final value of the streaming interface -+** chunk size. -+** </dl> -+** -+** This function returns SQLITE_OK if successful, or an SQLite error code -+** otherwise. -+*/ -+SQLITE_API int sqlite3session_config(int op, void *pArg); - - /* -+** CAPI3REF: Values for sqlite3session_config(). -+*/ -+#define SQLITE_SESSION_CONFIG_STRMSIZE 1 -+ -+/* - ** Make sure we can call this stuff from C++. - */ - #if 0 -@@ -11586,7 +12593,7 @@ - ** This way, even if the tokenizer does not provide synonyms - ** when tokenizing query text (it should not - to do would be - ** inefficient), it doesn't matter if the user queries for --** 'first + place' or '1st + place', as there are entires in the -+** 'first + place' or '1st + place', as there are entries in the - ** FTS index corresponding to both forms of the first token. - ** </ol> - ** -@@ -11614,7 +12621,7 @@ - ** extra data to the FTS index or require FTS5 to query for multiple terms, - ** so it is efficient in terms of disk space and query speed. However, it - ** does not support prefix queries very well. If, as suggested above, the --** token "first" is subsituted for "1st" by the tokenizer, then the query: -+** token "first" is substituted for "1st" by the tokenizer, then the query: - ** - ** <codeblock> - ** ... MATCH '1s*'</codeblock> -@@ -12221,6 +13228,21 @@ - #endif - - /* -+** Some conditionals are optimizations only. In other words, if the -+** conditionals are replaced with a constant 1 (true) or 0 (false) then -+** the correct answer is still obtained, though perhaps not as quickly. -+** -+** The following macros mark these optimizations conditionals. -+*/ -+#if defined(SQLITE_MUTATION_TEST) -+# define OK_IF_ALWAYS_TRUE(X) (1) -+# define OK_IF_ALWAYS_FALSE(X) (0) -+#else -+# define OK_IF_ALWAYS_TRUE(X) (X) -+# define OK_IF_ALWAYS_FALSE(X) (X) -+#endif -+ -+/* - ** Some malloc failures are only possible if SQLITE_TEST_REALLOC_STRESS is - ** defined. We need to defend against those failures when testing with - ** SQLITE_TEST_REALLOC_STRESS, but we don't want the unreachable branches -@@ -12414,144 +13436,153 @@ - #define TK_AS 24 - #define TK_WITHOUT 25 - #define TK_COMMA 26 --#define TK_ID 27 --#define TK_ABORT 28 --#define TK_ACTION 29 --#define TK_AFTER 30 --#define TK_ANALYZE 31 --#define TK_ASC 32 --#define TK_ATTACH 33 --#define TK_BEFORE 34 --#define TK_BY 35 --#define TK_CASCADE 36 --#define TK_CAST 37 --#define TK_COLUMNKW 38 --#define TK_CONFLICT 39 --#define TK_DATABASE 40 --#define TK_DESC 41 --#define TK_DETACH 42 --#define TK_EACH 43 --#define TK_FAIL 44 --#define TK_FOR 45 --#define TK_IGNORE 46 --#define TK_INITIALLY 47 --#define TK_INSTEAD 48 --#define TK_LIKE_KW 49 --#define TK_MATCH 50 --#define TK_NO 51 --#define TK_KEY 52 --#define TK_OF 53 --#define TK_OFFSET 54 --#define TK_PRAGMA 55 --#define TK_RAISE 56 --#define TK_RECURSIVE 57 --#define TK_REPLACE 58 --#define TK_RESTRICT 59 --#define TK_ROW 60 --#define TK_TRIGGER 61 --#define TK_VACUUM 62 --#define TK_VIEW 63 --#define TK_VIRTUAL 64 --#define TK_WITH 65 --#define TK_REINDEX 66 --#define TK_RENAME 67 --#define TK_CTIME_KW 68 --#define TK_ANY 69 --#define TK_OR 70 --#define TK_AND 71 --#define TK_IS 72 --#define TK_BETWEEN 73 --#define TK_IN 74 --#define TK_ISNULL 75 --#define TK_NOTNULL 76 --#define TK_NE 77 --#define TK_EQ 78 --#define TK_GT 79 --#define TK_LE 80 --#define TK_LT 81 --#define TK_GE 82 --#define TK_ESCAPE 83 --#define TK_BITAND 84 --#define TK_BITOR 85 --#define TK_LSHIFT 86 --#define TK_RSHIFT 87 --#define TK_PLUS 88 --#define TK_MINUS 89 --#define TK_STAR 90 --#define TK_SLASH 91 --#define TK_REM 92 --#define TK_CONCAT 93 --#define TK_COLLATE 94 --#define TK_BITNOT 95 --#define TK_INDEXED 96 --#define TK_STRING 97 --#define TK_JOIN_KW 98 --#define TK_CONSTRAINT 99 --#define TK_DEFAULT 100 --#define TK_NULL 101 --#define TK_PRIMARY 102 --#define TK_UNIQUE 103 --#define TK_CHECK 104 --#define TK_REFERENCES 105 --#define TK_AUTOINCR 106 --#define TK_ON 107 --#define TK_INSERT 108 --#define TK_DELETE 109 --#define TK_UPDATE 110 --#define TK_SET 111 --#define TK_DEFERRABLE 112 --#define TK_FOREIGN 113 --#define TK_DROP 114 --#define TK_UNION 115 --#define TK_ALL 116 --#define TK_EXCEPT 117 --#define TK_INTERSECT 118 --#define TK_SELECT 119 --#define TK_VALUES 120 --#define TK_DISTINCT 121 --#define TK_DOT 122 --#define TK_FROM 123 --#define TK_JOIN 124 --#define TK_USING 125 --#define TK_ORDER 126 --#define TK_GROUP 127 --#define TK_HAVING 128 --#define TK_LIMIT 129 --#define TK_WHERE 130 --#define TK_INTO 131 --#define TK_FLOAT 132 --#define TK_BLOB 133 --#define TK_INTEGER 134 --#define TK_VARIABLE 135 --#define TK_CASE 136 --#define TK_WHEN 137 --#define TK_THEN 138 --#define TK_ELSE 139 --#define TK_INDEX 140 --#define TK_ALTER 141 --#define TK_ADD 142 --#define TK_TO_TEXT 143 --#define TK_TO_BLOB 144 --#define TK_TO_NUMERIC 145 --#define TK_TO_INT 146 --#define TK_TO_REAL 147 --#define TK_ISNOT 148 --#define TK_END_OF_FILE 149 --#define TK_UNCLOSED_STRING 150 --#define TK_FUNCTION 151 --#define TK_COLUMN 152 --#define TK_AGG_FUNCTION 153 --#define TK_AGG_COLUMN 154 --#define TK_UMINUS 155 --#define TK_UPLUS 156 --#define TK_REGISTER 157 --#define TK_VECTOR 158 --#define TK_SELECT_COLUMN 159 --#define TK_IF_NULL_ROW 160 --#define TK_ASTERISK 161 --#define TK_SPAN 162 --#define TK_SPACE 163 --#define TK_ILLEGAL 164 -+#define TK_ABORT 27 -+#define TK_ACTION 28 -+#define TK_AFTER 29 -+#define TK_ANALYZE 30 -+#define TK_ASC 31 -+#define TK_ATTACH 32 -+#define TK_BEFORE 33 -+#define TK_BY 34 -+#define TK_CASCADE 35 -+#define TK_CAST 36 -+#define TK_CONFLICT 37 -+#define TK_DATABASE 38 -+#define TK_DESC 39 -+#define TK_DETACH 40 -+#define TK_EACH 41 -+#define TK_FAIL 42 -+#define TK_OR 43 -+#define TK_AND 44 -+#define TK_IS 45 -+#define TK_MATCH 46 -+#define TK_LIKE_KW 47 -+#define TK_BETWEEN 48 -+#define TK_IN 49 -+#define TK_ISNULL 50 -+#define TK_NOTNULL 51 -+#define TK_NE 52 -+#define TK_EQ 53 -+#define TK_GT 54 -+#define TK_LE 55 -+#define TK_LT 56 -+#define TK_GE 57 -+#define TK_ESCAPE 58 -+#define TK_ID 59 -+#define TK_COLUMNKW 60 -+#define TK_DO 61 -+#define TK_FOR 62 -+#define TK_IGNORE 63 -+#define TK_INITIALLY 64 -+#define TK_INSTEAD 65 -+#define TK_NO 66 -+#define TK_KEY 67 -+#define TK_OF 68 -+#define TK_OFFSET 69 -+#define TK_PRAGMA 70 -+#define TK_RAISE 71 -+#define TK_RECURSIVE 72 -+#define TK_REPLACE 73 -+#define TK_RESTRICT 74 -+#define TK_ROW 75 -+#define TK_ROWS 76 -+#define TK_TRIGGER 77 -+#define TK_VACUUM 78 -+#define TK_VIEW 79 -+#define TK_VIRTUAL 80 -+#define TK_WITH 81 -+#define TK_CURRENT 82 -+#define TK_FOLLOWING 83 -+#define TK_PARTITION 84 -+#define TK_PRECEDING 85 -+#define TK_RANGE 86 -+#define TK_UNBOUNDED 87 -+#define TK_REINDEX 88 -+#define TK_RENAME 89 -+#define TK_CTIME_KW 90 -+#define TK_ANY 91 -+#define TK_BITAND 92 -+#define TK_BITOR 93 -+#define TK_LSHIFT 94 -+#define TK_RSHIFT 95 -+#define TK_PLUS 96 -+#define TK_MINUS 97 -+#define TK_STAR 98 -+#define TK_SLASH 99 -+#define TK_REM 100 -+#define TK_CONCAT 101 -+#define TK_COLLATE 102 -+#define TK_BITNOT 103 -+#define TK_ON 104 -+#define TK_INDEXED 105 -+#define TK_STRING 106 -+#define TK_JOIN_KW 107 -+#define TK_CONSTRAINT 108 -+#define TK_DEFAULT 109 -+#define TK_NULL 110 -+#define TK_PRIMARY 111 -+#define TK_UNIQUE 112 -+#define TK_CHECK 113 -+#define TK_REFERENCES 114 -+#define TK_AUTOINCR 115 -+#define TK_INSERT 116 -+#define TK_DELETE 117 -+#define TK_UPDATE 118 -+#define TK_SET 119 -+#define TK_DEFERRABLE 120 -+#define TK_FOREIGN 121 -+#define TK_DROP 122 -+#define TK_UNION 123 -+#define TK_ALL 124 -+#define TK_EXCEPT 125 -+#define TK_INTERSECT 126 -+#define TK_SELECT 127 -+#define TK_VALUES 128 -+#define TK_DISTINCT 129 -+#define TK_DOT 130 -+#define TK_FROM 131 -+#define TK_JOIN 132 -+#define TK_USING 133 -+#define TK_ORDER 134 -+#define TK_GROUP 135 -+#define TK_HAVING 136 -+#define TK_LIMIT 137 -+#define TK_WHERE 138 -+#define TK_INTO 139 -+#define TK_NOTHING 140 -+#define TK_FLOAT 141 -+#define TK_BLOB 142 -+#define TK_INTEGER 143 -+#define TK_VARIABLE 144 -+#define TK_CASE 145 -+#define TK_WHEN 146 -+#define TK_THEN 147 -+#define TK_ELSE 148 -+#define TK_INDEX 149 -+#define TK_ALTER 150 -+#define TK_ADD 151 -+#define TK_WINDOW 152 -+#define TK_OVER 153 -+#define TK_FILTER 154 -+#define TK_TRUEFALSE 155 -+#define TK_ISNOT 156 -+#define TK_FUNCTION 157 -+#define TK_COLUMN 158 -+#define TK_AGG_FUNCTION 159 -+#define TK_AGG_COLUMN 160 -+#define TK_UMINUS 161 -+#define TK_UPLUS 162 -+#define TK_TRUTH 163 -+#define TK_REGISTER 164 -+#define TK_VECTOR 165 -+#define TK_SELECT_COLUMN 166 -+#define TK_IF_NULL_ROW 167 -+#define TK_ASTERISK 168 -+#define TK_SPAN 169 -+#define TK_END_OF_FILE 170 -+#define TK_UNCLOSED_STRING 171 -+#define TK_SPACE 172 -+#define TK_ILLEGAL 173 - - /* The token codes above must all fit in 8 bits */ - #define TKFLG_MASK 0xff -@@ -12672,6 +13703,22 @@ - #endif - - /* -+** Default value for the SQLITE_CONFIG_SORTERREF_SIZE option. -+*/ -+#ifndef SQLITE_DEFAULT_SORTERREF_SIZE -+# define SQLITE_DEFAULT_SORTERREF_SIZE 0x7fffffff -+#endif -+ -+/* -+** The compile-time options SQLITE_MMAP_READWRITE and -+** SQLITE_ENABLE_BATCH_ATOMIC_WRITE are not compatible with one another. -+** You must choose one or the other (or neither) but not both. -+*/ -+#if defined(SQLITE_MMAP_READWRITE) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) -+#error Cannot use both SQLITE_MMAP_READWRITE and SQLITE_ENABLE_BATCH_ATOMIC_WRITE -+#endif -+ -+/* - ** GCC does not define the offsetof() macro so we'll have to do it - ** ourselves. - */ -@@ -12809,7 +13856,8 @@ - # if defined(__SIZEOF_POINTER__) - # define SQLITE_PTRSIZE __SIZEOF_POINTER__ - # elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ -- defined(_M_ARM) || defined(__arm__) || defined(__x86) -+ defined(_M_ARM) || defined(__arm__) || defined(__x86) || \ -+ (defined(__TOS_AIX__) && !defined(__64BIT__)) - # define SQLITE_PTRSIZE 4 - # else - # define SQLITE_PTRSIZE 8 -@@ -12850,7 +13898,7 @@ - # if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ - defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ - defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ -- defined(__arm__) -+ defined(__arm__) || defined(_M_ARM64) - # define SQLITE_BYTEORDER 1234 - # elif defined(sparc) || defined(__ppc__) - # define SQLITE_BYTEORDER 4321 -@@ -12969,7 +14017,7 @@ - ** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not - ** the Select query generator tracing logic is turned on. - */ --#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_SELECTTRACE) -+#if defined(SQLITE_ENABLE_SELECTTRACE) - # define SELECTTRACE_ENABLED 1 - #else - # define SELECTTRACE_ENABLED 0 -@@ -12986,9 +14034,10 @@ - */ - typedef struct BusyHandler BusyHandler; - struct BusyHandler { -- int (*xFunc)(void *,int); /* The busy callback */ -- void *pArg; /* First arg to busy callback */ -- int nBusy; /* Incremented with each busy call */ -+ int (*xBusyHandler)(void *,int); /* The busy callback */ -+ void *pBusyArg; /* First arg to busy callback */ -+ int nBusy; /* Incremented with each busy call */ -+ u8 bExtraFileArg; /* Include sqlite3_file as callback arg */ - }; - - /* -@@ -13088,7 +14137,6 @@ - typedef struct Schema Schema; - typedef struct Expr Expr; - typedef struct ExprList ExprList; --typedef struct ExprSpan ExprSpan; - typedef struct FKey FKey; - typedef struct FuncDestructor FuncDestructor; - typedef struct FuncDef FuncDef; -@@ -13105,6 +14153,7 @@ - typedef struct Parse Parse; - typedef struct PreUpdate PreUpdate; - typedef struct PrintfArguments PrintfArguments; -+typedef struct RenameToken RenameToken; - typedef struct RowSet RowSet; - typedef struct Savepoint Savepoint; - typedef struct Select Select; -@@ -13111,7 +14160,7 @@ - typedef struct SQLiteThread SQLiteThread; - typedef struct SelectDest SelectDest; - typedef struct SrcList SrcList; --typedef struct StrAccum StrAccum; -+typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */ - typedef struct Table Table; - typedef struct TableLock TableLock; - typedef struct Token Token; -@@ -13120,12 +14169,40 @@ - typedef struct TriggerPrg TriggerPrg; - typedef struct TriggerStep TriggerStep; - typedef struct UnpackedRecord UnpackedRecord; -+typedef struct Upsert Upsert; - typedef struct VTable VTable; - typedef struct VtabCtx VtabCtx; - typedef struct Walker Walker; - typedef struct WhereInfo WhereInfo; -+typedef struct Window Window; - typedef struct With With; - -+ -+/* -+** The bitmask datatype defined below is used for various optimizations. -+** -+** Changing this from a 64-bit to a 32-bit type limits the number of -+** tables in a join to 32 instead of 64. But it also reduces the size -+** of the library by 738 bytes on ix86. -+*/ -+#ifdef SQLITE_BITMASK_TYPE -+ typedef SQLITE_BITMASK_TYPE Bitmask; -+#else -+ typedef u64 Bitmask; -+#endif -+ -+/* -+** The number of bits in a Bitmask. "BMS" means "BitMask Size". -+*/ -+#define BMS ((int)(sizeof(Bitmask)*8)) -+ -+/* -+** A bit in a Bitmask -+*/ -+#define MASKBIT(n) (((Bitmask)1)<<(n)) -+#define MASKBIT32(n) (((unsigned int)1)<<(n)) -+#define ALLBITS ((Bitmask)-1) -+ - /* A VList object records a mapping between parameters/variables/wildcards - ** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer - ** variable number associated with that parameter. See the format description -@@ -13221,7 +14298,7 @@ - SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p); - SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int); - SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *); --SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int); -+SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int,int*); - SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster); - SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int); - SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*); -@@ -13373,6 +14450,7 @@ - struct KeyInfo*, /* First argument to compare function */ - BtCursor *pCursor /* Space to write cursor structure */ - ); -+SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void); - SQLITE_PRIVATE int sqlite3BtreeCursorSize(void); - SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*); - SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned); -@@ -13401,14 +14479,29 @@ - ** entry in either an index or table btree. - ** - ** Index btrees (used for indexes and also WITHOUT ROWID tables) contain --** an arbitrary key and no data. These btrees have pKey,nKey set to their --** key and pData,nData,nZero set to zero. -+** an arbitrary key and no data. These btrees have pKey,nKey set to the -+** key and the pData,nData,nZero fields are uninitialized. The aMem,nMem -+** fields give an array of Mem objects that are a decomposition of the key. -+** The nMem field might be zero, indicating that no decomposition is available. - ** - ** Table btrees (used for rowid tables) contain an integer rowid used as - ** the key and passed in the nKey field. The pKey field is zero. - ** pData,nData hold the content of the new entry. nZero extra zero bytes - ** are appended to the end of the content when constructing the entry. -+** The aMem,nMem fields are uninitialized for table btrees. - ** -+** Field usage summary: -+** -+** Table BTrees Index Btrees -+** -+** pKey always NULL encoded key -+** nKey the ROWID length of pKey -+** pData data not used -+** aMem not used decomposed key value -+** nMem not used entries in aMem -+** nData length of pData not used -+** nZero extra zeros after pData not used -+** - ** This object is used to pass information into sqlite3BtreeInsert(). The - ** same information used to be passed as five separate parameters. But placing - ** the information into this object helps to keep the interface more -@@ -13418,7 +14511,7 @@ - struct BtreePayload { - const void *pKey; /* Key content for indexes. NULL for tables */ - sqlite3_int64 nKey; /* Size of pKey for indexes. PRIMARY KEY for tabs */ -- const void *pData; /* Data for tables. NULL for indexes */ -+ const void *pData; /* Data for tables. */ - sqlite3_value *aMem; /* First of nMem value in the unpacked pKey */ - u16 nMem; /* Number of aMem[] value. Might be zero */ - int nData; /* Size of pData. 0 if none. */ -@@ -13428,11 +14521,17 @@ - SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload, - int flags, int seekResult); - SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes); -+#ifndef SQLITE_OMIT_WINDOWFUNC -+SQLITE_PRIVATE void sqlite3BtreeSkipNext(BtCursor*); -+#endif - SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes); - SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int flags); - SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*); - SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags); - SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*); -+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC -+SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*); -+#endif - SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*); - SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt); - SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*); -@@ -13592,7 +14691,8 @@ - u64 cycles; /* Total time spent executing this instruction */ - #endif - #ifdef SQLITE_VDBE_COVERAGE -- int iSrcLine; /* Source-code line that generated this opcode */ -+ u32 iSrcLine; /* Source-code line that generated this opcode -+ ** with flags in the upper 8 bits */ - #endif - }; - typedef struct VdbeOp VdbeOp; -@@ -13646,6 +14746,7 @@ - #define P4_INT64 (-14) /* P4 is a 64-bit signed integer */ - #define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */ - #define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */ -+#define P4_DYNBLOB (-17) /* Pointer to memory from sqliteMalloc() */ - - /* Error message codes for OP_Halt */ - #define P5_ConstraintNotNull 1 -@@ -13691,171 +14792,177 @@ - #define OP_Savepoint 0 - #define OP_AutoCommit 1 - #define OP_Transaction 2 --#define OP_SorterNext 3 --#define OP_PrevIfOpen 4 --#define OP_NextIfOpen 5 --#define OP_Prev 6 --#define OP_Next 7 --#define OP_Checkpoint 8 --#define OP_JournalMode 9 --#define OP_Vacuum 10 --#define OP_VFilter 11 /* synopsis: iplan=r[P3] zplan='P4' */ --#define OP_VUpdate 12 /* synopsis: data=r[P3@P2] */ --#define OP_Goto 13 --#define OP_Gosub 14 --#define OP_InitCoroutine 15 --#define OP_Yield 16 --#define OP_MustBeInt 17 --#define OP_Jump 18 -+#define OP_SorterNext 3 /* jump */ -+#define OP_Prev 4 /* jump */ -+#define OP_Next 5 /* jump */ -+#define OP_Checkpoint 6 -+#define OP_JournalMode 7 -+#define OP_Vacuum 8 -+#define OP_VFilter 9 /* jump, synopsis: iplan=r[P3] zplan='P4' */ -+#define OP_VUpdate 10 /* synopsis: data=r[P3@P2] */ -+#define OP_Goto 11 /* jump */ -+#define OP_Gosub 12 /* jump */ -+#define OP_InitCoroutine 13 /* jump */ -+#define OP_Yield 14 /* jump */ -+#define OP_MustBeInt 15 /* jump */ -+#define OP_Jump 16 /* jump */ -+#define OP_Once 17 /* jump */ -+#define OP_If 18 /* jump */ - #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ --#define OP_Once 20 --#define OP_If 21 --#define OP_IfNot 22 --#define OP_IfNullRow 23 /* synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ --#define OP_SeekLT 24 /* synopsis: key=r[P3@P4] */ --#define OP_SeekLE 25 /* synopsis: key=r[P3@P4] */ --#define OP_SeekGE 26 /* synopsis: key=r[P3@P4] */ --#define OP_SeekGT 27 /* synopsis: key=r[P3@P4] */ --#define OP_NoConflict 28 /* synopsis: key=r[P3@P4] */ --#define OP_NotFound 29 /* synopsis: key=r[P3@P4] */ --#define OP_Found 30 /* synopsis: key=r[P3@P4] */ --#define OP_SeekRowid 31 /* synopsis: intkey=r[P3] */ --#define OP_NotExists 32 /* synopsis: intkey=r[P3] */ --#define OP_Last 33 --#define OP_IfSmaller 34 --#define OP_SorterSort 35 --#define OP_Sort 36 --#define OP_Rewind 37 --#define OP_IdxLE 38 /* synopsis: key=r[P3@P4] */ --#define OP_IdxGT 39 /* synopsis: key=r[P3@P4] */ --#define OP_IdxLT 40 /* synopsis: key=r[P3@P4] */ --#define OP_IdxGE 41 /* synopsis: key=r[P3@P4] */ --#define OP_RowSetRead 42 /* synopsis: r[P3]=rowset(P1) */ --#define OP_RowSetTest 43 /* synopsis: if r[P3] in rowset(P1) goto P2 */ --#define OP_Program 44 --#define OP_FkIfZero 45 /* synopsis: if fkctr[P1]==0 goto P2 */ --#define OP_IfPos 46 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ --#define OP_IfNotZero 47 /* synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ --#define OP_DecrJumpZero 48 /* synopsis: if (--r[P1])==0 goto P2 */ --#define OP_IncrVacuum 49 --#define OP_VNext 50 --#define OP_Init 51 /* synopsis: Start at P2 */ --#define OP_Return 52 --#define OP_EndCoroutine 53 --#define OP_HaltIfNull 54 /* synopsis: if r[P3]=null halt */ --#define OP_Halt 55 --#define OP_Integer 56 /* synopsis: r[P2]=P1 */ --#define OP_Int64 57 /* synopsis: r[P2]=P4 */ --#define OP_String 58 /* synopsis: r[P2]='P4' (len=P1) */ --#define OP_Null 59 /* synopsis: r[P2..P3]=NULL */ --#define OP_SoftNull 60 /* synopsis: r[P1]=NULL */ --#define OP_Blob 61 /* synopsis: r[P2]=P4 (len=P1) */ --#define OP_Variable 62 /* synopsis: r[P2]=parameter(P1,P4) */ --#define OP_Move 63 /* synopsis: r[P2@P3]=r[P1@P3] */ --#define OP_Copy 64 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ --#define OP_SCopy 65 /* synopsis: r[P2]=r[P1] */ --#define OP_IntCopy 66 /* synopsis: r[P2]=r[P1] */ --#define OP_ResultRow 67 /* synopsis: output=r[P1@P2] */ --#define OP_CollSeq 68 --#define OP_AddImm 69 /* synopsis: r[P1]=r[P1]+P2 */ --#define OP_Or 70 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ --#define OP_And 71 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ --#define OP_RealAffinity 72 --#define OP_Cast 73 /* synopsis: affinity(r[P1]) */ --#define OP_Permutation 74 --#define OP_IsNull 75 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ --#define OP_NotNull 76 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ --#define OP_Ne 77 /* same as TK_NE, synopsis: IF r[P3]!=r[P1] */ --#define OP_Eq 78 /* same as TK_EQ, synopsis: IF r[P3]==r[P1] */ --#define OP_Gt 79 /* same as TK_GT, synopsis: IF r[P3]>r[P1] */ --#define OP_Le 80 /* same as TK_LE, synopsis: IF r[P3]<=r[P1] */ --#define OP_Lt 81 /* same as TK_LT, synopsis: IF r[P3]<r[P1] */ --#define OP_Ge 82 /* same as TK_GE, synopsis: IF r[P3]>=r[P1] */ --#define OP_ElseNotEq 83 /* same as TK_ESCAPE */ --#define OP_BitAnd 84 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ --#define OP_BitOr 85 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ --#define OP_ShiftLeft 86 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ --#define OP_ShiftRight 87 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ --#define OP_Add 88 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ --#define OP_Subtract 89 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ --#define OP_Multiply 90 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ --#define OP_Divide 91 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ --#define OP_Remainder 92 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ --#define OP_Concat 93 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ --#define OP_Compare 94 /* synopsis: r[P1@P3] <-> r[P2@P3] */ --#define OP_BitNot 95 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */ --#define OP_Column 96 /* synopsis: r[P3]=PX */ --#define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */ --#define OP_Affinity 98 /* synopsis: affinity(r[P1@P2]) */ --#define OP_MakeRecord 99 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ --#define OP_Count 100 /* synopsis: r[P2]=count() */ --#define OP_ReadCookie 101 --#define OP_SetCookie 102 --#define OP_ReopenIdx 103 /* synopsis: root=P2 iDb=P3 */ --#define OP_OpenRead 104 /* synopsis: root=P2 iDb=P3 */ --#define OP_OpenWrite 105 /* synopsis: root=P2 iDb=P3 */ --#define OP_OpenDup 106 --#define OP_OpenAutoindex 107 /* synopsis: nColumn=P2 */ --#define OP_OpenEphemeral 108 /* synopsis: nColumn=P2 */ --#define OP_SorterOpen 109 --#define OP_SequenceTest 110 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ --#define OP_OpenPseudo 111 /* synopsis: P3 columns in r[P2] */ --#define OP_Close 112 --#define OP_ColumnsUsed 113 --#define OP_Sequence 114 /* synopsis: r[P2]=cursor[P1].ctr++ */ --#define OP_NewRowid 115 /* synopsis: r[P2]=rowid */ --#define OP_Insert 116 /* synopsis: intkey=r[P3] data=r[P2] */ --#define OP_InsertInt 117 /* synopsis: intkey=P3 data=r[P2] */ --#define OP_Delete 118 --#define OP_ResetCount 119 --#define OP_SorterCompare 120 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ --#define OP_SorterData 121 /* synopsis: r[P2]=data */ --#define OP_RowData 122 /* synopsis: r[P2]=data */ --#define OP_Rowid 123 /* synopsis: r[P2]=rowid */ --#define OP_NullRow 124 --#define OP_SorterInsert 125 /* synopsis: key=r[P2] */ --#define OP_IdxInsert 126 /* synopsis: key=r[P2] */ --#define OP_IdxDelete 127 /* synopsis: key=r[P2@P3] */ --#define OP_DeferredSeek 128 /* synopsis: Move P3 to P1.rowid if needed */ --#define OP_IdxRowid 129 /* synopsis: r[P2]=rowid */ --#define OP_Destroy 130 --#define OP_Clear 131 --#define OP_Real 132 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ --#define OP_ResetSorter 133 --#define OP_CreateIndex 134 /* synopsis: r[P2]=root iDb=P1 */ --#define OP_CreateTable 135 /* synopsis: r[P2]=root iDb=P1 */ --#define OP_SqlExec 136 --#define OP_ParseSchema 137 --#define OP_LoadAnalysis 138 --#define OP_DropTable 139 --#define OP_DropIndex 140 --#define OP_DropTrigger 141 --#define OP_IntegrityCk 142 --#define OP_RowSetAdd 143 /* synopsis: rowset(P1)=r[P2] */ --#define OP_Param 144 --#define OP_FkCounter 145 /* synopsis: fkctr[P1]+=P2 */ --#define OP_MemMax 146 /* synopsis: r[P1]=max(r[P1],r[P2]) */ --#define OP_OffsetLimit 147 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ --#define OP_AggStep0 148 /* synopsis: accum=r[P3] step(r[P2@P5]) */ --#define OP_AggStep 149 /* synopsis: accum=r[P3] step(r[P2@P5]) */ --#define OP_AggFinal 150 /* synopsis: accum=r[P1] N=P2 */ --#define OP_Expire 151 --#define OP_TableLock 152 /* synopsis: iDb=P1 root=P2 write=P3 */ --#define OP_VBegin 153 --#define OP_VCreate 154 --#define OP_VDestroy 155 --#define OP_VOpen 156 --#define OP_VColumn 157 /* synopsis: r[P3]=vcolumn(P2) */ --#define OP_VRename 158 --#define OP_Pagecount 159 --#define OP_MaxPgcnt 160 --#define OP_PureFunc0 161 --#define OP_Function0 162 /* synopsis: r[P3]=func(r[P2@P5]) */ --#define OP_PureFunc 163 --#define OP_Function 164 /* synopsis: r[P3]=func(r[P2@P5]) */ --#define OP_CursorHint 165 --#define OP_Noop 166 --#define OP_Explain 167 -+#define OP_IfNot 20 /* jump */ -+#define OP_IfNullRow 21 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ -+#define OP_SeekLT 22 /* jump, synopsis: key=r[P3@P4] */ -+#define OP_SeekLE 23 /* jump, synopsis: key=r[P3@P4] */ -+#define OP_SeekGE 24 /* jump, synopsis: key=r[P3@P4] */ -+#define OP_SeekGT 25 /* jump, synopsis: key=r[P3@P4] */ -+#define OP_IfNoHope 26 /* jump, synopsis: key=r[P3@P4] */ -+#define OP_NoConflict 27 /* jump, synopsis: key=r[P3@P4] */ -+#define OP_NotFound 28 /* jump, synopsis: key=r[P3@P4] */ -+#define OP_Found 29 /* jump, synopsis: key=r[P3@P4] */ -+#define OP_SeekRowid 30 /* jump, synopsis: intkey=r[P3] */ -+#define OP_NotExists 31 /* jump, synopsis: intkey=r[P3] */ -+#define OP_Last 32 /* jump */ -+#define OP_IfSmaller 33 /* jump */ -+#define OP_SorterSort 34 /* jump */ -+#define OP_Sort 35 /* jump */ -+#define OP_Rewind 36 /* jump */ -+#define OP_IdxLE 37 /* jump, synopsis: key=r[P3@P4] */ -+#define OP_IdxGT 38 /* jump, synopsis: key=r[P3@P4] */ -+#define OP_IdxLT 39 /* jump, synopsis: key=r[P3@P4] */ -+#define OP_IdxGE 40 /* jump, synopsis: key=r[P3@P4] */ -+#define OP_RowSetRead 41 /* jump, synopsis: r[P3]=rowset(P1) */ -+#define OP_RowSetTest 42 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ -+#define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ -+#define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ -+#define OP_Program 45 /* jump */ -+#define OP_FkIfZero 46 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ -+#define OP_IfPos 47 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ -+#define OP_IfNotZero 48 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ -+#define OP_DecrJumpZero 49 /* jump, synopsis: if (--r[P1])==0 goto P2 */ -+#define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ -+#define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ -+#define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ -+#define OP_Eq 53 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */ -+#define OP_Gt 54 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */ -+#define OP_Le 55 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */ -+#define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */ -+#define OP_Ge 57 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */ -+#define OP_ElseNotEq 58 /* jump, same as TK_ESCAPE */ -+#define OP_IncrVacuum 59 /* jump */ -+#define OP_VNext 60 /* jump */ -+#define OP_Init 61 /* jump, synopsis: Start at P2 */ -+#define OP_PureFunc0 62 -+#define OP_Function0 63 /* synopsis: r[P3]=func(r[P2@P5]) */ -+#define OP_PureFunc 64 -+#define OP_Function 65 /* synopsis: r[P3]=func(r[P2@P5]) */ -+#define OP_Return 66 -+#define OP_EndCoroutine 67 -+#define OP_HaltIfNull 68 /* synopsis: if r[P3]=null halt */ -+#define OP_Halt 69 -+#define OP_Integer 70 /* synopsis: r[P2]=P1 */ -+#define OP_Int64 71 /* synopsis: r[P2]=P4 */ -+#define OP_String 72 /* synopsis: r[P2]='P4' (len=P1) */ -+#define OP_Null 73 /* synopsis: r[P2..P3]=NULL */ -+#define OP_SoftNull 74 /* synopsis: r[P1]=NULL */ -+#define OP_Blob 75 /* synopsis: r[P2]=P4 (len=P1) */ -+#define OP_Variable 76 /* synopsis: r[P2]=parameter(P1,P4) */ -+#define OP_Move 77 /* synopsis: r[P2@P3]=r[P1@P3] */ -+#define OP_Copy 78 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ -+#define OP_SCopy 79 /* synopsis: r[P2]=r[P1] */ -+#define OP_IntCopy 80 /* synopsis: r[P2]=r[P1] */ -+#define OP_ResultRow 81 /* synopsis: output=r[P1@P2] */ -+#define OP_CollSeq 82 -+#define OP_AddImm 83 /* synopsis: r[P1]=r[P1]+P2 */ -+#define OP_RealAffinity 84 -+#define OP_Cast 85 /* synopsis: affinity(r[P1]) */ -+#define OP_Permutation 86 -+#define OP_Compare 87 /* synopsis: r[P1@P3] <-> r[P2@P3] */ -+#define OP_IsTrue 88 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ -+#define OP_Offset 89 /* synopsis: r[P3] = sqlite_offset(P1) */ -+#define OP_Column 90 /* synopsis: r[P3]=PX */ -+#define OP_Affinity 91 /* synopsis: affinity(r[P1@P2]) */ -+#define OP_BitAnd 92 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ -+#define OP_BitOr 93 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ -+#define OP_ShiftLeft 94 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ -+#define OP_ShiftRight 95 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ -+#define OP_Add 96 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ -+#define OP_Subtract 97 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ -+#define OP_Multiply 98 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ -+#define OP_Divide 99 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ -+#define OP_Remainder 100 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ -+#define OP_Concat 101 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ -+#define OP_MakeRecord 102 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ -+#define OP_BitNot 103 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ -+#define OP_Count 104 /* synopsis: r[P2]=count() */ -+#define OP_ReadCookie 105 -+#define OP_String8 106 /* same as TK_STRING, synopsis: r[P2]='P4' */ -+#define OP_SetCookie 107 -+#define OP_ReopenIdx 108 /* synopsis: root=P2 iDb=P3 */ -+#define OP_OpenRead 109 /* synopsis: root=P2 iDb=P3 */ -+#define OP_OpenWrite 110 /* synopsis: root=P2 iDb=P3 */ -+#define OP_OpenDup 111 -+#define OP_OpenAutoindex 112 /* synopsis: nColumn=P2 */ -+#define OP_OpenEphemeral 113 /* synopsis: nColumn=P2 */ -+#define OP_SorterOpen 114 -+#define OP_SequenceTest 115 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ -+#define OP_OpenPseudo 116 /* synopsis: P3 columns in r[P2] */ -+#define OP_Close 117 -+#define OP_ColumnsUsed 118 -+#define OP_SeekHit 119 /* synopsis: seekHit=P2 */ -+#define OP_Sequence 120 /* synopsis: r[P2]=cursor[P1].ctr++ */ -+#define OP_NewRowid 121 /* synopsis: r[P2]=rowid */ -+#define OP_Insert 122 /* synopsis: intkey=r[P3] data=r[P2] */ -+#define OP_InsertInt 123 /* synopsis: intkey=P3 data=r[P2] */ -+#define OP_Delete 124 -+#define OP_ResetCount 125 -+#define OP_SorterCompare 126 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ -+#define OP_SorterData 127 /* synopsis: r[P2]=data */ -+#define OP_RowData 128 /* synopsis: r[P2]=data */ -+#define OP_Rowid 129 /* synopsis: r[P2]=rowid */ -+#define OP_NullRow 130 -+#define OP_SeekEnd 131 -+#define OP_SorterInsert 132 /* synopsis: key=r[P2] */ -+#define OP_IdxInsert 133 /* synopsis: key=r[P2] */ -+#define OP_IdxDelete 134 /* synopsis: key=r[P2@P3] */ -+#define OP_DeferredSeek 135 /* synopsis: Move P3 to P1.rowid if needed */ -+#define OP_IdxRowid 136 /* synopsis: r[P2]=rowid */ -+#define OP_Destroy 137 -+#define OP_Clear 138 -+#define OP_ResetSorter 139 -+#define OP_CreateBtree 140 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ -+#define OP_Real 141 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ -+#define OP_SqlExec 142 -+#define OP_ParseSchema 143 -+#define OP_LoadAnalysis 144 -+#define OP_DropTable 145 -+#define OP_DropIndex 146 -+#define OP_DropTrigger 147 -+#define OP_IntegrityCk 148 -+#define OP_RowSetAdd 149 /* synopsis: rowset(P1)=r[P2] */ -+#define OP_Param 150 -+#define OP_FkCounter 151 /* synopsis: fkctr[P1]+=P2 */ -+#define OP_MemMax 152 /* synopsis: r[P1]=max(r[P1],r[P2]) */ -+#define OP_OffsetLimit 153 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ -+#define OP_AggInverse 154 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ -+#define OP_AggStep 155 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -+#define OP_AggStep1 156 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -+#define OP_AggValue 157 /* synopsis: r[P3]=value N=P2 */ -+#define OP_AggFinal 158 /* synopsis: accum=r[P1] N=P2 */ -+#define OP_Expire 159 -+#define OP_TableLock 160 /* synopsis: iDb=P1 root=P2 write=P3 */ -+#define OP_VBegin 161 -+#define OP_VCreate 162 -+#define OP_VDestroy 163 -+#define OP_VOpen 164 -+#define OP_VColumn 165 /* synopsis: r[P3]=vcolumn(P2) */ -+#define OP_VRename 166 -+#define OP_Pagecount 167 -+#define OP_MaxPgcnt 168 -+#define OP_Trace 169 -+#define OP_CursorHint 170 -+#define OP_Noop 171 -+#define OP_Explain 172 -+#define OP_Abortable 173 - - /* Properties such as "out2" or "jump" that are specified in - ** comments following the "case" for each opcode in the vdbe.c -@@ -13868,28 +14975,28 @@ - #define OPFLG_OUT2 0x10 /* out2: P2 is an output */ - #define OPFLG_OUT3 0x20 /* out3: P3 is an output */ - #define OPFLG_INITIALIZER {\ --/* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,\ --/* 8 */ 0x00, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01,\ --/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x03, 0x03, 0x01,\ -+/* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x10,\ -+/* 8 */ 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,\ -+/* 16 */ 0x01, 0x01, 0x03, 0x12, 0x03, 0x01, 0x09, 0x09,\ - /* 24 */ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,\ --/* 32 */ 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\ --/* 40 */ 0x01, 0x01, 0x23, 0x0b, 0x01, 0x01, 0x03, 0x03,\ --/* 48 */ 0x03, 0x01, 0x01, 0x01, 0x02, 0x02, 0x08, 0x00,\ --/* 56 */ 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00,\ --/* 64 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x02, 0x26, 0x26,\ --/* 72 */ 0x02, 0x02, 0x00, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\ --/* 80 */ 0x0b, 0x0b, 0x0b, 0x01, 0x26, 0x26, 0x26, 0x26,\ --/* 88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00, 0x12,\ --/* 96 */ 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\ --/* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ --/* 112 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,\ --/* 120 */ 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x04, 0x00,\ --/* 128 */ 0x00, 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10,\ --/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,\ --/* 144 */ 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00,\ --/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\ --/* 160 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ --} -+/* 32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\ -+/* 40 */ 0x01, 0x23, 0x0b, 0x26, 0x26, 0x01, 0x01, 0x03,\ -+/* 48 */ 0x03, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ -+/* 56 */ 0x0b, 0x0b, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,\ -+/* 64 */ 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10, 0x10,\ -+/* 72 */ 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10,\ -+/* 80 */ 0x10, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,\ -+/* 88 */ 0x12, 0x20, 0x00, 0x00, 0x26, 0x26, 0x26, 0x26,\ -+/* 96 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00, 0x12,\ -+/* 104 */ 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ -+/* 112 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -+/* 120 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -+/* 128 */ 0x00, 0x10, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00,\ -+/* 136 */ 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\ -+/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x00,\ -+/* 152 */ 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -+/* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\ -+/* 168 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,} - - /* The sqlite3P2Values() routine is able to run faster if it knows - ** the value of the largest JUMP opcode. The smaller the maximum -@@ -13897,7 +15004,7 @@ - ** generated this include file strives to group all JUMP opcodes - ** together near the beginning of the list. - */ --#define SQLITE_MX_JUMP_OPCODE 83 /* Maximum JUMP opcode */ -+#define SQLITE_MX_JUMP_OPCODE 61 /* Maximum JUMP opcode */ - - /************** End of opcodes.h *********************************************/ - /************** Continuing where we left off in vdbe.h ***********************/ -@@ -13931,7 +15038,24 @@ - # define sqlite3VdbeVerifyNoMallocRequired(A,B) - # define sqlite3VdbeVerifyNoResultRow(A) - #endif --SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno); -+#if defined(SQLITE_DEBUG) -+SQLITE_PRIVATE void sqlite3VdbeVerifyAbortable(Vdbe *p, int); -+#else -+# define sqlite3VdbeVerifyAbortable(A,B) -+#endif -+SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno); -+#ifndef SQLITE_OMIT_EXPLAIN -+SQLITE_PRIVATE void sqlite3VdbeExplain(Parse*,u8,const char*,...); -+SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse*); -+SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse*); -+# define ExplainQueryPlan(P) sqlite3VdbeExplain P -+# define ExplainQueryPlanPop(P) sqlite3VdbeExplainPop(P) -+# define ExplainQueryPlanParent(P) sqlite3VdbeExplainParent(P) -+#else -+# define ExplainQueryPlan(P) -+# define ExplainQueryPlanPop(P) -+# define ExplainQueryPlanParent(P) 0 -+#endif - SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); - SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8); - SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1); -@@ -13975,6 +15099,7 @@ - SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); - #endif - SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); -+SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*); - - SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); - SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); -@@ -14030,17 +15155,43 @@ - ** - ** VdbeCoverageNeverTaken(v) // Previous branch is never taken - ** -+** VdbeCoverageNeverNull(v) // Previous three-way branch is only -+** // taken on the first two ways. The -+** // NULL option is not possible -+** -+** VdbeCoverageEqNe(v) // Previous OP_Jump is only interested -+** // in distingishing equal and not-equal. -+** - ** Every VDBE branch operation must be tagged with one of the macros above. - ** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and - ** -DSQLITE_DEBUG then an ALWAYS() will fail in the vdbeTakeBranch() - ** routine in vdbe.c, alerting the developer to the missed tag. -+** -+** During testing, the test application will invoke -+** sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE,...) to set a callback -+** routine that is invoked as each bytecode branch is taken. The callback -+** contains the sqlite3.c source line number ov the VdbeCoverage macro and -+** flags to indicate whether or not the branch was taken. The test application -+** is responsible for keeping track of this and reporting byte-code branches -+** that are never taken. -+** -+** See the VdbeBranchTaken() macro and vdbeTakeBranch() function in the -+** vdbe.c source file for additional information. - */ - #ifdef SQLITE_VDBE_COVERAGE - SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe*,int); - # define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__) - # define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__) --# define VdbeCoverageAlwaysTaken(v) sqlite3VdbeSetLineNumber(v,2); --# define VdbeCoverageNeverTaken(v) sqlite3VdbeSetLineNumber(v,1); -+# define VdbeCoverageAlwaysTaken(v) \ -+ sqlite3VdbeSetLineNumber(v,__LINE__|0x5000000); -+# define VdbeCoverageNeverTaken(v) \ -+ sqlite3VdbeSetLineNumber(v,__LINE__|0x6000000); -+# define VdbeCoverageNeverNull(v) \ -+ sqlite3VdbeSetLineNumber(v,__LINE__|0x4000000); -+# define VdbeCoverageNeverNullIf(v,x) \ -+ if(x)sqlite3VdbeSetLineNumber(v,__LINE__|0x4000000); -+# define VdbeCoverageEqNe(v) \ -+ sqlite3VdbeSetLineNumber(v,__LINE__|0x8000000); - # define VDBE_OFFSET_LINENO(x) (__LINE__+x) - #else - # define VdbeCoverage(v) -@@ -14047,6 +15198,9 @@ - # define VdbeCoverageIf(v,x) - # define VdbeCoverageAlwaysTaken(v) - # define VdbeCoverageNeverTaken(v) -+# define VdbeCoverageNeverNull(v) -+# define VdbeCoverageNeverNullIf(v,x) -+# define VdbeCoverageEqNe(v) - # define VDBE_OFFSET_LINENO(x) 0 - #endif - -@@ -14056,6 +15210,10 @@ - # define sqlite3VdbeScanStatus(a,b,c,d,e) - #endif - -+#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) -+SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, VdbeOp*); -+#endif -+ - #endif /* SQLITE_VDBE_H */ - - /************** End of vdbe.h ************************************************/ -@@ -14190,7 +15348,7 @@ - SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); - - /* Functions used to configure a Pager object. */ --SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *); -+SQLITE_PRIVATE void sqlite3PagerSetBusyHandler(Pager*, int(*)(void *), void *); - SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int); - #ifdef SQLITE_HAS_CODEC - SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager*,Pager*); -@@ -14215,6 +15373,7 @@ - SQLITE_PRIVATE void sqlite3PagerRef(DbPage*); - SQLITE_PRIVATE void sqlite3PagerUnref(DbPage*); - SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage*); -+SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage*); - - /* Operations on page references. */ - SQLITE_PRIVATE int sqlite3PagerWrite(DbPage*); -@@ -14242,18 +15401,19 @@ - SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager); - SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); - SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*); --# ifdef SQLITE_DIRECT_OVERFLOW_READ --SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno); --# endif - # ifdef SQLITE_ENABLE_SNAPSHOT - SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot); - SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot); - SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager); -+SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot); -+SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager); - # endif --#else --# define sqlite3PagerUseWal(x,y) 0 - #endif - -+#ifdef SQLITE_DIRECT_OVERFLOW_READ -+SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno); -+#endif -+ - #ifdef SQLITE_ENABLE_ZIPVFS - SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager); - #endif -@@ -14275,6 +15435,11 @@ - SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *); - SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*); - SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *); -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+SQLITE_PRIVATE void sqlite3PagerResetLockTimeout(Pager *pPager); -+#else -+# define sqlite3PagerResetLockTimeout(X) -+#endif - - /* Functions used to truncate the database file. */ - SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno); -@@ -14351,6 +15516,8 @@ - i16 nRef; /* Number of users of this page */ - PgHdr *pDirtyNext; /* Next element in list of dirty pages */ - PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */ -+ /* NB: pDirtyNext and pDirtyPrev are undefined if the -+ ** PgHdr object is not dirty */ - }; - - /* Bit values for PgHdr.flags */ -@@ -14489,6 +15656,10 @@ - /* Number of dirty pages as a percentage of the configured cache size */ - SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache*); - -+#ifdef SQLITE_DIRECT_OVERFLOW_READ -+SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache); -+#endif -+ - #endif /* _PCACHE_H_ */ - - /************** End of pcache.h **********************************************/ -@@ -14732,10 +15903,12 @@ - #define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0 - SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id); - SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id); -+#ifndef SQLITE_OMIT_WAL - SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **); - SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int); - SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id); - SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int); -+#endif /* SQLITE_OMIT_WAL */ - SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64, int, void **); - SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *, i64, void *); - -@@ -14944,6 +16117,7 @@ - #define DB_SchemaLoaded 0x0001 /* The schema has been loaded */ - #define DB_UnresetViews 0x0002 /* Some views have defined column names */ - #define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */ -+#define DB_ResetWanted 0x0008 /* Reset the schema when nSchemaLock==0 */ - - /* - ** The number of different kinds of things that can be limited -@@ -14975,9 +16149,9 @@ - u32 bDisable; /* Only operate the lookaside when zero */ - u16 sz; /* Size of each buffer in bytes */ - u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ -- int nOut; /* Number of buffers currently checked out */ -- int mxOut; /* Highwater mark for nOut */ -- int anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ -+ 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 */ - void *pStart; /* First byte of available memory space */ - void *pEnd; /* First byte past end of available space */ -@@ -14991,12 +16165,14 @@ - ** functions use a regular table table from hash.h.) - ** - ** Hash each FuncDef structure into one of the FuncDefHash.a[] slots. --** Collisions are on the FuncDef.u.pHash chain. -+** Collisions are on the FuncDef.u.pHash chain. Use the SQLITE_FUNC_HASH() -+** macro to compute a hash on the function name. - */ - #define SQLITE_FUNC_HASH_SZ 23 - struct FuncDefHash { - FuncDef *a[SQLITE_FUNC_HASH_SZ]; /* Hash table for functions */ - }; -+#define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ) - - #ifdef SQLITE_USER_AUTHENTICATION - /* -@@ -15056,9 +16232,11 @@ - sqlite3_mutex *mutex; /* Connection mutex */ - Db *aDb; /* All backends */ - int nDb; /* Number of backends currently in use */ -- int flags; /* Miscellaneous flags. See below */ -+ u32 mDbFlags; /* flags recording internal state */ -+ u64 flags; /* flags settable by pragmas. See below */ - i64 lastRowid; /* ROWID of most recent insert (see above) */ - i64 szMmap; /* Default mmap_size setting */ -+ u32 nSchemaLock; /* Do not reset the schema when non-zero */ - unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ - int errCode; /* Most recent error code (SQLITE_*) */ - int errMask; /* & result codes with this before returning */ -@@ -15075,7 +16253,7 @@ - u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */ - u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ - u8 mTrace; /* zero or more SQLITE_TRACE flags */ -- u8 skipBtreeMutex; /* True if no shared-cache backends */ -+ u8 noSharedCache; /* True if no shared-cache backends */ - u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */ - int nextPagesize; /* Pagesize after VACUUM if >0 */ - u32 magic; /* Magic number for detect library misuse */ -@@ -15087,8 +16265,9 @@ - int newTnum; /* Rootpage of table being initialized */ - u8 iDb; /* Which db file is being initialized */ - u8 busy; /* TRUE if currently initializing */ -- u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */ -- u8 imposterTable; /* Building an imposter table */ -+ unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */ -+ unsigned imposterTable : 1; /* Building an imposter table */ -+ unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */ - } init; - int nVdbeActive; /* Number of VDBEs currently running */ - int nVdbeRead; /* Number of active VDBEs that read or write */ -@@ -15141,7 +16320,7 @@ - Hash aModule; /* populated by sqlite3_create_module() */ - VtabCtx *pVtabCtx; /* Context for active vtab connect/create */ - VTable **aVTrans; /* Virtual tables with open transactions */ -- VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */ -+ VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */ - #endif - Hash aFunc; /* Hash table of connection functions */ - Hash aCollSeq; /* All collating sequences */ -@@ -15210,27 +16389,36 @@ - #define SQLITE_ForeignKeys 0x00004000 /* Enforce foreign key constraints */ - #define SQLITE_AutoIndex 0x00008000 /* Enable automatic indexes */ - #define SQLITE_LoadExtension 0x00010000 /* Enable load_extension */ --#define SQLITE_EnableTrigger 0x00020000 /* True to enable triggers */ --#define SQLITE_DeferFKs 0x00040000 /* Defer all FK constraints */ --#define SQLITE_QueryOnly 0x00080000 /* Disable database changes */ --#define SQLITE_CellSizeCk 0x00100000 /* Check btree cell sizes on load */ --#define SQLITE_Fts3Tokenizer 0x00200000 /* Enable fts3_tokenizer(2) */ --#define SQLITE_EnableQPSG 0x00400000 /* Query Planner Stability Guarantee */ --/* The next four values are not used by PRAGMAs or by sqlite3_dbconfig() and --** could be factored out into a separate bit vector of the sqlite3 object. */ --#define SQLITE_InternChanges 0x00800000 /* Uncommitted Hash table changes */ --#define SQLITE_LoadExtFunc 0x01000000 /* Enable load_extension() SQL func */ --#define SQLITE_PreferBuiltin 0x02000000 /* Preference to built-in funcs */ --#define SQLITE_Vacuum 0x04000000 /* Currently in a VACUUM */ -+#define SQLITE_LoadExtFunc 0x00020000 /* Enable load_extension() SQL func */ -+#define SQLITE_EnableTrigger 0x00040000 /* True to enable triggers */ -+#define SQLITE_DeferFKs 0x00080000 /* Defer all FK constraints */ -+#define SQLITE_QueryOnly 0x00100000 /* Disable database changes */ -+#define SQLITE_CellSizeCk 0x00200000 /* Check btree cell sizes on load */ -+#define SQLITE_Fts3Tokenizer 0x00400000 /* Enable fts3_tokenizer(2) */ -+#define SQLITE_EnableQPSG 0x00800000 /* Query Planner Stability Guarantee*/ -+#define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */ -+#define SQLITE_ResetDatabase 0x02000000 /* Reset the database */ -+#define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */ -+#define SQLITE_NoSchemaError 0x08000000 /* Do not report schema parse errors*/ -+#define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */ -+ - /* Flags used only if debugging */ -+#define HI(X) ((u64)(X)<<32) - #ifdef SQLITE_DEBUG --#define SQLITE_SqlTrace 0x08000000 /* Debug print SQL as it executes */ --#define SQLITE_VdbeListing 0x10000000 /* Debug listings of VDBE programs */ --#define SQLITE_VdbeTrace 0x20000000 /* True to trace VDBE execution */ --#define SQLITE_VdbeAddopTrace 0x40000000 /* Trace sqlite3VdbeAddOp() calls */ --#define SQLITE_VdbeEQP 0x80000000 /* Debug EXPLAIN QUERY PLAN */ -+#define SQLITE_SqlTrace HI(0x0001) /* Debug print SQL as it executes */ -+#define SQLITE_VdbeListing HI(0x0002) /* Debug listings of VDBE progs */ -+#define SQLITE_VdbeTrace HI(0x0004) /* True to trace VDBE execution */ -+#define SQLITE_VdbeAddopTrace HI(0x0008) /* Trace sqlite3VdbeAddOp() calls */ -+#define SQLITE_VdbeEQP HI(0x0010) /* Debug EXPLAIN QUERY PLAN */ - #endif - -+/* -+** Allowed values for sqlite3.mDbFlags -+*/ -+#define DBFLAG_SchemaChange 0x0001 /* Uncommitted Hash table changes */ -+#define DBFLAG_PreferBuiltin 0x0002 /* Preference to built-in funcs */ -+#define DBFLAG_Vacuum 0x0004 /* Currently in a VACUUM */ -+#define DBFLAG_SchemaKnownOk 0x0008 /* Schema is known to be valid */ - - /* - ** Bits of the sqlite3.dbOptFlags field that are used by the -@@ -15238,19 +16426,22 @@ - ** selectively disable various optimizations. - */ - #define SQLITE_QueryFlattener 0x0001 /* Query flattening */ --#define SQLITE_ColumnCache 0x0002 /* Column cache */ -+ /* 0x0002 available for reuse */ - #define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */ - #define SQLITE_FactorOutConst 0x0008 /* Constant factoring */ --/* not used 0x0010 // Was: SQLITE_IdxRealAsInt */ --#define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */ --#define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */ --#define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */ --#define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */ --#define SQLITE_Transitive 0x0200 /* Transitive constraints */ --#define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */ -+#define SQLITE_DistinctOpt 0x0010 /* DISTINCT using indexes */ -+#define SQLITE_CoverIdxScan 0x0020 /* Covering index scans */ -+#define SQLITE_OrderByIdxJoin 0x0040 /* ORDER BY of joins via index */ -+#define SQLITE_Transitive 0x0080 /* Transitive constraints */ -+#define SQLITE_OmitNoopJoin 0x0100 /* Omit unused tables in joins */ -+#define SQLITE_CountOfView 0x0200 /* The count-of-view optimization */ -+#define SQLITE_CursorHints 0x0400 /* Add OP_CursorHint opcodes */ - #define SQLITE_Stat34 0x0800 /* Use STAT3 or STAT4 data */ --#define SQLITE_CountOfView 0x1000 /* The count-of-view optimization */ --#define SQLITE_CursorHints 0x2000 /* Add OP_CursorHint opcodes */ -+ /* TH3 expects the Stat34 ^^^^^^ value to be 0x0800. Don't change it */ -+#define SQLITE_PushDown 0x1000 /* The push-down optimization */ -+#define SQLITE_SimplifyJoin 0x2000 /* Convert LEFT JOIN to JOIN */ -+#define SQLITE_SkipScan 0x4000 /* Skip-scans */ -+#define SQLITE_PropagateConst 0x8000 /* The constant propagation opt */ - #define SQLITE_AllOpts 0xffff /* All optimizations */ - - /* -@@ -15289,11 +16480,13 @@ - */ - struct FuncDef { - i8 nArg; /* Number of arguments. -1 means unlimited */ -- u16 funcFlags; /* Some combination of SQLITE_FUNC_* */ -+ u32 funcFlags; /* Some combination of SQLITE_FUNC_* */ - void *pUserData; /* User data parameter */ - FuncDef *pNext; /* Next function with same name */ - void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */ - void (*xFinalize)(sqlite3_context*); /* Agg finalizer */ -+ void (*xValue)(sqlite3_context*); /* Current agg value */ -+ void (*xInverse)(sqlite3_context*,int,sqlite3_value**); /* inverse agg-step */ - const char *zName; /* SQL name of the function. */ - union { - FuncDef *pHash; /* Next with a different name but the same hash */ -@@ -15349,6 +16542,10 @@ - #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_OFFSET 0x8000 /* Built-in sqlite_offset() function */ -+#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */ -+#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */ -+#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ - - /* - ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are -@@ -15383,6 +16580,12 @@ - ** are interpreted in the same way as the first 4 parameters to - ** FUNCTION(). - ** -+** WFUNCTION(zName, nArg, iArg, xStep, xFinal, xValue, xInverse) -+** Used to create an aggregate function definition implemented by -+** the C functions xStep and xFinal. The first four parameters -+** are interpreted in the same way as the first 4 parameters to -+** FUNCTION(). -+** - ** LIKEFUNC(zName, nArg, pArg, flags) - ** Used to create a scalar function definition of a function zName - ** that accepts nArg arguments and is implemented by a call to C -@@ -15393,32 +16596,39 @@ - */ - #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ -- SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} } -+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } - #define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ -- SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} } -+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } - #define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \ -- 0, 0, xFunc, 0, #zName, {0} } -+ 0, 0, xFunc, 0, 0, 0, #zName, {0} } - #define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \ -- (void*)&sqlite3Config, 0, xFunc, 0, #zName, {0} } -+ (void*)&sqlite3Config, 0, xFunc, 0, 0, 0, #zName, {0} } - #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ - {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ -- SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} } -+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } - #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ -- pArg, 0, xFunc, 0, #zName, } -+ pArg, 0, xFunc, 0, 0, 0, #zName, } - #define LIKEFUNC(zName, nArg, arg, flags) \ - {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \ -- (void *)arg, 0, likeFunc, 0, #zName, {0} } --#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \ -+ (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,#zName, {0}} -+ 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,#zName, {0}} -+ 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}} -+#define INTERNAL_FUNCTION(zName, nArg, xFunc) \ -+ {nArg, SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \ -+ 0, 0, xFunc, 0, 0, 0, #zName, {0} } - -+ - /* - ** All current savepoints are stored in a linked list starting at - ** sqlite3.pSavepoint. The first element in the list is the most recently -@@ -15473,6 +16683,8 @@ - #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 */ - - /* - ** A "Collating Sequence" is defined by an instance of the following -@@ -15600,6 +16812,9 @@ - struct Table { - char *zName; /* Name of the table or view */ - Column *aCol; /* Information about each column */ -+#ifdef SQLITE_ENABLE_NORMALIZE -+ Hash *pColHash; /* All columns indexed by name */ -+#endif - Index *pIndex; /* List of SQL indexes on this table. */ - Select *pSelect; /* NULL for tables. Points to definition if a view. */ - FKey *pFKey; /* Linked list of all foreign keys in this table */ -@@ -15650,6 +16865,7 @@ - #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 */ - - /* - ** Test to see whether or not a table is a virtual table. This is -@@ -15760,15 +16976,14 @@ - #define OE_Fail 3 /* Stop the operation but leave all prior changes */ - #define OE_Ignore 4 /* Ignore the error. Do not do the INSERT or UPDATE */ - #define OE_Replace 5 /* Delete existing record, then do INSERT or UPDATE */ -+#define OE_Update 6 /* Process as a DO UPDATE in an upsert */ -+#define OE_Restrict 7 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */ -+#define OE_SetNull 8 /* Set the foreign key value to NULL */ -+#define OE_SetDflt 9 /* Set the foreign key value to its default */ -+#define OE_Cascade 10 /* Cascade the changes */ -+#define OE_Default 11 /* Do whatever the default action is */ - --#define OE_Restrict 6 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */ --#define OE_SetNull 7 /* Set the foreign key value to NULL */ --#define OE_SetDflt 8 /* Set the foreign key value to its default */ --#define OE_Cascade 9 /* Cascade the changes */ - --#define OE_Default 10 /* Do whatever the default action is */ -- -- - /* - ** An instance of the following structure is passed as the first - ** argument to sqlite3VdbeKeyCompare and is used to control the -@@ -15781,8 +16996,8 @@ - struct KeyInfo { - u32 nRef; /* Number of references to this KeyInfo object */ - u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ -- u16 nField; /* Number of key columns in the index */ -- u16 nXField; /* Number of columns beyond the key columns */ -+ u16 nKeyField; /* Number of key columns in the index */ -+ u16 nAllField; /* Total columns, including key plus others */ - sqlite3 *db; /* The database connection */ - u8 *aSortOrder; /* Sort order for each column. */ - CollSeq *aColl[1]; /* Collating sequence for each term of the key */ -@@ -15829,8 +17044,8 @@ - u16 nField; /* Number of entries in apMem[] */ - i8 default_rc; /* Comparison result if keys are equal */ - u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */ -- i8 r1; /* Value to return if (lhs > rhs) */ -- i8 r2; /* Value to return if (rhs < lhs) */ -+ i8 r1; /* Value to return if (lhs < rhs) */ -+ i8 r2; /* Value to return if (lhs > rhs) */ - u8 eqSeen; /* True if an equality comparison has been seen */ - }; - -@@ -15893,6 +17108,7 @@ - unsigned isCovering:1; /* True if this is a covering index */ - unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ - unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ -+ unsigned bNoQuery:1; /* Do not use this index to optimize queries */ - #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - int nSample; /* Number of elements in aSample[] */ - int nSampleCol; /* Size of IndexSample.anEq[] and so on */ -@@ -15901,6 +17117,7 @@ - tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this index */ - tRowcnt nRowEst0; /* Non-logarithmic number of rows in the index */ - #endif -+ Bitmask colNotIdxed; /* 0 for unindexed columns in pTab */ - }; - - /* -@@ -15936,12 +17153,20 @@ - }; - - /* -+** Possible values to use within the flags argument to sqlite3GetToken(). -+*/ -+#define SQLITE_TOKEN_QUOTED 0x1 /* Token is a quoted identifier. */ -+#define SQLITE_TOKEN_KEYWORD 0x2 /* Token is a keyword. */ -+ -+/* - ** Each token coming out of the lexer is an instance of - ** this structure. Tokens are also used as part of an expression. - ** --** Note if Token.z==0 then Token.dyn and Token.n are undefined and --** may contain random values. Do not make any assumptions about Token.dyn --** and Token.n when Token.z==0. -+** The memory that "z" points to is owned by other objects. Take care -+** that the owner of the "z" string does not deallocate the string before -+** the Token goes out of scope! Very often, the "z" points to some place -+** in the middle of the Parse.zSql text. But it might also point to a -+** static string. - */ - struct Token { - const char *z; /* Text of the token. Not NULL-terminated! */ -@@ -16114,7 +17339,11 @@ - ** 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 */ -- Table *pTab; /* Table for TK_COLUMN expressions. */ -+ union { -+ Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL -+ ** for a column of an index on an expression */ -+ Window *pWin; /* TK_FUNCTION: Window definition for the func */ -+ } y; - }; - - /* -@@ -16122,8 +17351,8 @@ - */ - #define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */ - #define EP_Agg 0x000002 /* Contains one or more aggregate functions */ -- /* 0x000004 // available for use */ -- /* 0x000008 // available for use */ -+#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */ -+#define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */ - #define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */ - #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ - #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ -@@ -16144,11 +17373,13 @@ - #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ - #define EP_Alias 0x400000 /* Is an alias for a result set column */ - #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ -+#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */ - - /* --** Combinations of two or more EP_* flags -+** The EP_Propagate mask is a set of properties that automatically propagate -+** upwards into parent nodes. - */ --#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */ -+#define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc) - - /* - ** These macros can be used to test, set, or clear bits in the -@@ -16202,7 +17433,6 @@ - */ - struct ExprList { - int nExpr; /* Number of expressions on the list */ -- int nAlloc; /* Number of a[] slots allocated */ - struct ExprList_item { /* For each expression in the list */ - Expr *pExpr; /* The parse tree for this expression */ - char *zName; /* Token associated with this expression */ -@@ -16211,6 +17441,7 @@ - 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 */ - union { - struct { - u16 iOrderByCol; /* For ORDER BY, column number in result set */ -@@ -16222,17 +17453,6 @@ - }; - - /* --** An instance of this structure is used by the parser to record both --** the parse tree for an expression and the span of input text for an --** expression. --*/ --struct ExprSpan { -- Expr *pExpr; /* The expression parse tree */ -- const char *zStart; /* First character of input text */ -- const char *zEnd; /* One character past the end of input text */ --}; -- --/* - ** An instance of this structure can hold a simple list of identifiers, - ** such as the list "a,b,c" in the following statements: - ** -@@ -16256,31 +17476,6 @@ - }; - - /* --** The bitmask datatype defined below is used for various optimizations. --** --** Changing this from a 64-bit to a 32-bit type limits the number of --** tables in a join to 32 instead of 64. But it also reduces the size --** of the library by 738 bytes on ix86. --*/ --#ifdef SQLITE_BITMASK_TYPE -- typedef SQLITE_BITMASK_TYPE Bitmask; --#else -- typedef u64 Bitmask; --#endif -- --/* --** The number of bits in a Bitmask. "BMS" means "BitMask Size". --*/ --#define BMS ((int)(sizeof(Bitmask)*8)) -- --/* --** A bit in a Bitmask --*/ --#define MASKBIT(n) (((Bitmask)1)<<(n)) --#define MASKBIT32(n) (((unsigned int)1)<<(n)) --#define ALLBITS ((Bitmask)-1) -- --/* - ** The following structure describes the FROM clause of a SELECT statement. - ** Each table or subquery in the FROM clause is a separate element of - ** the SrcList.a[] array. -@@ -16321,9 +17516,6 @@ - unsigned viaCoroutine :1; /* Implemented as a co-routine */ - unsigned isRecursive :1; /* True for recursive reference in WITH */ - } fg; --#ifndef SQLITE_OMIT_EXPLAIN -- u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */ --#endif - int iCursor; /* The VDBE cursor number used to access this table */ - Expr *pOn; /* The ON clause of a join */ - IdList *pUsing; /* The USING clause of a join */ -@@ -16405,12 +17597,16 @@ - struct NameContext { - Parse *pParse; /* The parser */ - SrcList *pSrcList; /* One or more tables used to resolve names */ -- ExprList *pEList; /* Optional list of result-set columns */ -- AggInfo *pAggInfo; /* Information about aggregates at this level */ -+ union { -+ ExprList *pEList; /* Optional list of result-set columns */ -+ AggInfo *pAggInfo; /* Information about aggregates at this level */ -+ Upsert *pUpsert; /* ON CONFLICT clause information from an upsert */ -+ } uNC; - NameContext *pNext; /* Next outer name context. NULL for outermost */ - int nRef; /* Number of names resolved by this context */ - int nErr; /* Number of errors encountered while resolving names */ - u16 ncFlags; /* Zero or more NC_* flags defined below */ -+ Select *pWinSelect; /* SELECT statement for any window functions */ - }; - - /* -@@ -16428,17 +17624,49 @@ - #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 */ - - /* -+** An instance of the following object describes a single ON CONFLICT -+** clause in an upsert. -+** -+** The pUpsertTarget field is only set if the ON CONFLICT clause includes -+** conflict-target clause. (In "ON CONFLICT(a,b)" the "(a,b)" is the -+** conflict-target clause.) The pUpsertTargetWhere is the optional -+** WHERE clause used to identify partial unique indexes. -+** -+** pUpsertSet is the list of column=expr terms of the UPDATE statement. -+** The pUpsertSet field is NULL for a ON CONFLICT DO NOTHING. The -+** pUpsertWhere is the WHERE clause for the UPDATE and is NULL if the -+** WHERE clause is omitted. -+*/ -+struct Upsert { -+ ExprList *pUpsertTarget; /* Optional description of conflicting index */ -+ Expr *pUpsertTargetWhere; /* WHERE clause for partial index targets */ -+ ExprList *pUpsertSet; /* The SET clause from an ON CONFLICT UPDATE */ -+ Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */ -+ /* The fields above comprise the parse tree for the upsert clause. -+ ** The fields below are used to transfer information from the INSERT -+ ** processing down into the UPDATE processing while generating code. -+ ** Upsert owns the memory allocated above, but not the memory below. */ -+ Index *pUpsertIdx; /* Constraint that pUpsertTarget identifies */ -+ SrcList *pUpsertSrc; /* Table to be updated */ -+ int regData; /* First register holding array of VALUES */ -+ int iDataCur; /* Index of the data cursor */ -+ int iIdxCur; /* Index of the first index cursor */ -+}; -+ -+/* - ** An instance of the following structure contains all information - ** needed to generate code for a single SELECT statement. - ** --** nLimit is set to -1 if there is no LIMIT clause. nOffset is set to 0. --** If there is a LIMIT clause, the parser sets nLimit to the value of the --** limit and nOffset to the value of the offset (or 0 if there is not --** offset). But later on, nLimit and nOffset become the memory locations --** in the VDBE that record the limit and offset counters. -+** See the header comment on the computeLimitRegisters() routine for a -+** detailed description of the meaning of the iLimit and iOffset fields. - ** - ** addrOpenEphm[] entries contain the address of OP_OpenEphemeral opcodes. - ** These addresses must be stored so that we can go back and fill in -@@ -16456,9 +17684,7 @@ - LogEst nSelectRow; /* Estimated number of result rows */ - u32 selFlags; /* Various SF_* values */ - int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ --#if SELECTTRACE_ENABLED -- char zSelName[12]; /* Symbolic name of this SELECT use for debugging */ --#endif -+ u32 selId; /* Unique identifier number for this SELECT */ - int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */ - SrcList *pSrc; /* The FROM clause */ - Expr *pWhere; /* The WHERE clause */ -@@ -16468,8 +17694,11 @@ - Select *pPrior; /* Prior select in a compound select statement */ - Select *pNext; /* Next select to the left in a compound */ - Expr *pLimit; /* LIMIT expression. NULL means not used. */ -- Expr *pOffset; /* OFFSET expression. NULL means not used. */ - With *pWith; /* WITH clause attached to this select. Or NULL. */ -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ Window *pWin; /* List of window functions */ -+ Window *pWinDefn; /* List of named window definitions */ -+#endif - }; - - /* -@@ -16499,8 +17728,8 @@ - #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 */ - -- - /* - ** The results of a SELECT can be distributed in several ways, as defined - ** by one of the following macros. The "SRT" prefix means "SELECT Result -@@ -16614,13 +17843,6 @@ - }; - - /* --** Size of the column cache --*/ --#ifndef SQLITE_N_COLCACHE --# define SQLITE_N_COLCACHE 10 --#endif -- --/* - ** At least one instance of the following structure is created for each - ** trigger that may be fired while parsing an INSERT, UPDATE or DELETE - ** statement. All such objects are stored in the linked list headed at -@@ -16695,7 +17917,6 @@ - u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ - u8 okConstFactor; /* OK to factor out constants */ - u8 disableLookaside; /* Number of times lookaside has been disabled */ -- u8 nColCache; /* Number of entries in aColCache[] */ - int nRangeReg; /* Size of the temporary register block */ - int iRangeReg; /* First register in temporary register block */ - int nErr; /* Number of errors seen */ -@@ -16703,10 +17924,8 @@ - int nMem; /* Number of memory cells used so far */ - int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */ - int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */ -- int iSelfTab; /* Table for associated with an index on expr, or negative -+ int iSelfTab; /* Table associated with an index on expr, or negative - ** of the base register during check-constraint eval */ -- int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */ -- int iCacheCnt; /* Counter used to generate aColCache[].lru values */ - int nLabel; /* Number of labels used */ - int *aLabel; /* Space to hold the labels */ - ExprList *pConstExpr;/* Constant expressions */ -@@ -16716,10 +17935,7 @@ - int regRowid; /* Register holding rowid of CREATE TABLE entry */ - int regRoot; /* Register holding root page number for new objects */ - int nMaxArg; /* Max args passed to user function by sub-program */ --#if SELECTTRACE_ENABLED -- int nSelect; /* Number of SELECT statements seen */ -- int nSelectIndent; /* How far to indent SELECTTRACE() output */ --#endif -+ int nSelect; /* Number of SELECT stmts. Counter for Select.selId */ - #ifndef SQLITE_OMIT_SHARED_CACHE - int nTableLock; /* Number of locks in aTableLock */ - TableLock *aTableLock; /* Required table locks for shared-cache mode */ -@@ -16727,7 +17943,7 @@ - AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ - Parse *pToplevel; /* Parse structure for main program (or NULL) */ - Table *pTriggerTab; /* Table triggers are being coded for */ -- int addrCrTab; /* Address of OP_CreateTable opcode on CREATE TABLE */ -+ int addrCrTab; /* Address of OP_CreateBtree opcode on CREATE TABLE */ - u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ - u32 oldmask; /* Mask of old.* columns referenced */ - u32 newmask; /* Mask of new.* columns referenced */ -@@ -16739,17 +17955,9 @@ - ** Fields above must be initialized to zero. The fields that follow, - ** down to the beginning of the recursive section, do not need to be - ** initialized as they will be set before being used. The boundary is -- ** determined by offsetof(Parse,aColCache). -+ ** determined by offsetof(Parse,aTempReg). - **************************************************************************/ - -- struct yColCache { -- int iTable; /* Table cursor number */ -- i16 iColumn; /* Table column number */ -- u8 tempReg; /* iReg is a temp register that needs to be freed */ -- int iLevel; /* Nesting level */ -- int iReg; /* Reg with value of this column. 0 means none. */ -- int lru; /* Least recently used entry has the smallest value */ -- } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ - int aTempReg[8]; /* Holding area for temporary registers */ - Token sNameToken; /* Token with unqualified schema object name */ - -@@ -16764,19 +17972,21 @@ - ynVar nVar; /* Number of '?' variables seen in the SQL so far */ - u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */ - u8 explain; /* True if the EXPLAIN flag is found on the query */ -+#if !(defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_OMIT_ALTERTABLE)) -+ u8 eParseMode; /* PARSE_MODE_XXX constant */ -+#endif - #ifndef SQLITE_OMIT_VIRTUALTABLE -- u8 declareVtab; /* True if inside sqlite3_declare_vtab() */ - int nVtabLock; /* Number of virtual tables to lock */ - #endif - int nHeight; /* Expression tree height of current sub-select */ - #ifndef SQLITE_OMIT_EXPLAIN -- int iSelectId; /* ID of current select for EXPLAIN output */ -- int iNextSelectId; /* Next available select ID for EXPLAIN output */ -+ int addrExplain; /* Address of current OP_Explain opcode */ - #endif - VList *pVList; /* Mapping between variable names and numbers */ - Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ - const char *zTail; /* All SQL text past the last semicolon parsed */ - Table *pNewTable; /* A table being constructed by CREATE TABLE */ -+ Index *pNewIndex; /* An index being constructed by CREATE INDEX */ - Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */ - const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */ - #ifndef SQLITE_OMIT_VIRTUALTABLE -@@ -16787,12 +17997,20 @@ - TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ - With *pWith; /* Current WITH clause, or NULL */ - With *pWithToFree; /* Free this WITH object at the end of the parse */ -+#ifndef SQLITE_OMIT_ALTERTABLE -+ RenameToken *pRename; /* Tokens subject to renaming by ALTER TABLE */ -+#endif - }; - -+#define PARSE_MODE_NORMAL 0 -+#define PARSE_MODE_DECLARE_VTAB 1 -+#define PARSE_MODE_RENAME_COLUMN 2 -+#define PARSE_MODE_RENAME_TABLE 3 -+ - /* - ** Sizes and pointers of various parts of the Parse object. - */ --#define PARSE_HDR_SZ offsetof(Parse,aColCache) /* Recursive part w/o aColCache*/ -+#define PARSE_HDR_SZ offsetof(Parse,aTempReg) /* Recursive part w/o aColCache*/ - #define PARSE_RECURSE_SZ offsetof(Parse,sLastToken) /* Recursive part */ - #define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */ - #define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */ -@@ -16803,9 +18021,21 @@ - #ifdef SQLITE_OMIT_VIRTUALTABLE - #define IN_DECLARE_VTAB 0 - #else -- #define IN_DECLARE_VTAB (pParse->declareVtab) -+ #define IN_DECLARE_VTAB (pParse->eParseMode==PARSE_MODE_DECLARE_VTAB) - #endif - -+#if defined(SQLITE_OMIT_ALTERTABLE) -+ #define IN_RENAME_OBJECT 0 -+#else -+ #define IN_RENAME_OBJECT (pParse->eParseMode>=PARSE_MODE_RENAME_COLUMN) -+#endif -+ -+#if defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_OMIT_ALTERTABLE) -+ #define IN_SPECIAL_PARSE 0 -+#else -+ #define IN_SPECIAL_PARSE (pParse->eParseMode!=PARSE_MODE_NORMAL) -+#endif -+ - /* - ** An instance of the following structure can be declared on a stack and used - ** to save the Parse.zAuthContext value so that it can be restored later. -@@ -16829,6 +18059,7 @@ - */ - #define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */ - /* Also used in P2 (not P5) of OP_Delete */ -+#define OPFLAG_NOCHNG 0x01 /* OP_VColumn nochange for UPDATE */ - #define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */ - #define OPFLAG_LASTROWID 0x20 /* Set to update db->lastRowid */ - #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */ -@@ -16844,6 +18075,7 @@ - #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ - #define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */ - #define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */ -+#define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */ - - /* - * Each trigger present in the database schema is stored as an instance of -@@ -16929,8 +18161,10 @@ - Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */ - char *zTarget; /* Target table for DELETE, UPDATE, INSERT */ - Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */ -- ExprList *pExprList; /* SET clause for UPDATE. */ -+ ExprList *pExprList; /* SET clause for UPDATE */ - IdList *pIdList; /* Column names for INSERT */ -+ Upsert *pUpsert; /* Upsert clauses on an INSERT */ -+ char *zSpan; /* Original SQL text of this command */ - TriggerStep *pNext; /* Next in the link-list */ - TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */ - }; -@@ -16954,18 +18188,15 @@ - ** An objected used to accumulate the text of a string where we - ** do not necessarily know how big the string will be in the end. - */ --struct StrAccum { -+struct sqlite3_str { - sqlite3 *db; /* Optional database for lookaside. Can be NULL */ -- char *zBase; /* A base allocation. Not from malloc. */ - char *zText; /* The string collected so far */ -- u32 nChar; /* Length of the string so far */ - u32 nAlloc; /* Amount of space allocated in zText */ - u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */ -- u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */ -+ u32 nChar; /* Length of the string so far */ -+ u8 accError; /* SQLITE_NOMEM or SQLITE_TOOBIG */ - u8 printfFlags; /* SQLITE_PRINTF flags below */ - }; --#define STRACCUM_NOMEM 1 --#define STRACCUM_TOOBIG 2 - #define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */ - #define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */ - #define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */ -@@ -16982,9 +18213,15 @@ - char **pzErrMsg; /* Error message stored here */ - int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */ - int rc; /* Result code stored here */ -+ u32 mInitFlags; /* Flags controlling error messages */ - } InitData; - - /* -+** Allowed values for mInitFlags -+*/ -+#define INITFLAG_AlterTable 0x0001 /* This is a reparse after ALTER TABLE */ -+ -+/* - ** Structure containing global configuration data for the SQLite library. - ** - ** This structure also contains some state information. -@@ -16995,6 +18232,7 @@ - int bFullMutex; /* True to enable full mutexing */ - int bOpenUri; /* True to interpret filenames as URIs */ - int bUseCis; /* Use covering indices for full-scans */ -+ int bSmallMalloc; /* Avoid large memory allocations if true */ - int mxStrlen; /* Maximum string length */ - int neverCorrupt; /* Database is always well-formed */ - int szLookaside; /* Default lookaside buffer size */ -@@ -17008,9 +18246,6 @@ - int mnReq, mxReq; /* Min and max heap requests sizes */ - sqlite3_int64 szMmap; /* mmap() space per open file */ - sqlite3_int64 mxMmap; /* Maximum value for szMmap */ -- void *pScratch; /* Scratch memory */ -- int szScratch; /* Size of each scratch buffer */ -- int nScratch; /* Number of scratch buffers */ - void *pPage; /* Page cache memory */ - int szPage; /* Size of each page in pPage[] */ - int nPage; /* Number of pages in pPage[] */ -@@ -17036,7 +18271,7 @@ - /* The following callback (if not NULL) is invoked on every VDBE branch - ** operation. Set the callback using SQLITE_TESTCTRL_VDBE_COVERAGE. - */ -- void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx); /* Callback */ -+ void (*xVdbeBranch)(void*,unsigned iSrcLine,u8 eThis,u8 eMx); /* Callback */ - void *pVdbeBranchArg; /* 1st argument */ - #endif - #ifndef SQLITE_UNTESTABLE -@@ -17043,7 +18278,9 @@ - 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 */ - }; - - /* -@@ -17083,9 +18320,12 @@ - struct CCurHint *pCCurHint; /* Used by codeCursorHint() */ - int *aiCol; /* array of column indexes */ - struct IdxCover *pIdxCover; /* Check for index coverage */ -- struct IdxExprTrans *pIdxTrans; /* Convert indexed expr to column */ -+ struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */ - ExprList *pGroupBy; /* GROUP BY clause */ -- struct HavingToWhereCtx *pHavingCtx; /* HAVING to WHERE clause ctx */ -+ Select *pSelect; /* HAVING to WHERE clause ctx */ -+ struct WindowRewrite *pRewrite; /* Window rewrite context */ -+ struct WhereConst *pConst; /* WHERE clause constants */ -+ struct RenameCtx *pRename; /* RENAME COLUMN context */ - } u; - }; - -@@ -17097,6 +18337,7 @@ - SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*); - SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker*, Expr*); - SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker*, Select*); -+SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker*, Select*); - #ifdef SQLITE_DEBUG - SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*); - #endif -@@ -17136,6 +18377,68 @@ - #endif /* SQLITE_DEBUG */ - - /* -+** This object is used in varioius ways, all related to window functions -+** -+** (1) A single instance of this structure is attached to the -+** the Expr.pWin field for each window function in an expression tree. -+** This object holds the information contained in the OVER clause, -+** plus additional fields used during code generation. -+** -+** (2) All window functions in a single SELECT form a linked-list -+** attached to Select.pWin. The Window.pFunc and Window.pExpr -+** fields point back to the expression that is the window function. -+** -+** (3) The terms of the WINDOW clause of a SELECT are instances of this -+** object on a linked list attached to Select.pWinDefn. -+** -+** The uses (1) and (2) are really the same Window object that just happens -+** to be accessible in two different ways. Use (3) is are separate objects. -+*/ -+struct Window { -+ char *zName; /* Name of window (may be NULL) */ -+ ExprList *pPartition; /* PARTITION BY clause */ -+ ExprList *pOrderBy; /* ORDER BY clause */ -+ u8 eType; /* TK_RANGE or TK_ROWS */ -+ u8 eStart; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */ -+ u8 eEnd; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */ -+ Expr *pStart; /* Expression for "<expr> PRECEDING" */ -+ Expr *pEnd; /* Expression for "<expr> FOLLOWING" */ -+ Window *pNextWin; /* Next window function belonging to this SELECT */ -+ Expr *pFilter; /* The FILTER expression */ -+ FuncDef *pFunc; /* The function */ -+ int iEphCsr; /* Partition buffer or Peer buffer */ -+ int regAccum; -+ int regResult; -+ int csrApp; /* Function cursor (used by min/max) */ -+ int regApp; /* Function register (also used by min/max) */ -+ int regPart; /* First in a set of registers holding PARTITION BY -+ ** and ORDER BY values for the window */ -+ Expr *pOwner; /* Expression object this window is attached to */ -+ int nBufferCol; /* Number of columns in buffer table */ -+ int iArgCol; /* Offset of first argument for this function */ -+}; -+ -+#ifndef SQLITE_OMIT_WINDOWFUNC -+SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3*, Window*); -+SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p); -+SQLITE_PRIVATE Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*); -+SQLITE_PRIVATE void sqlite3WindowAttach(Parse*, Expr*, Window*); -+SQLITE_PRIVATE int sqlite3WindowCompare(Parse*, Window*, Window*); -+SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse*, Window*); -+SQLITE_PRIVATE void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int); -+SQLITE_PRIVATE int sqlite3WindowRewrite(Parse*, Select*); -+SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse*, struct SrcList_item*); -+SQLITE_PRIVATE void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*); -+SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p); -+SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p); -+SQLITE_PRIVATE void sqlite3WindowFunctions(void); -+#else -+# define sqlite3WindowDelete(a,b) -+# define sqlite3WindowFunctions() -+# define sqlite3WindowAttach(a,b,c) -+#endif -+ -+/* - ** Assuming zIn points to the first byte of a UTF-8 character, - ** advance zIn to point to the first byte of the next UTF-8 character. - */ -@@ -17152,6 +18455,7 @@ - ** using sqlite3_log(). The routines also provide a convenient place - ** to set a debugger breakpoint. - */ -+SQLITE_PRIVATE int sqlite3ReportError(int iErr, int lineno, const char *zType); - SQLITE_PRIVATE int sqlite3CorruptError(int); - SQLITE_PRIVATE int sqlite3MisuseError(int); - SQLITE_PRIVATE int sqlite3CantopenError(int); -@@ -17221,9 +18525,7 @@ - # define sqlite3Tolower(x) tolower((unsigned char)(x)) - # define sqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`') - #endif --#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS - SQLITE_PRIVATE int sqlite3IsIdChar(u8); --#endif - - /* - ** Internal function prototypes -@@ -17230,6 +18532,7 @@ - */ - SQLITE_PRIVATE int sqlite3StrICmp(const char*,const char*); - SQLITE_PRIVATE int sqlite3Strlen30(const char*); -+#define sqlite3Strlen30NN(C) (strlen(C)&0x3fffffff) - SQLITE_PRIVATE char *sqlite3ColumnType(Column*,char*); - #define sqlite3StrNICmp sqlite3_strnicmp - -@@ -17242,6 +18545,7 @@ - SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3*, u64); - SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*); - SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, u64); -+SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3*,const char*,const char*); - SQLITE_PRIVATE void *sqlite3Realloc(void*, u64); - SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64); - SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64); -@@ -17249,8 +18553,6 @@ - SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3*, void*); - SQLITE_PRIVATE int sqlite3MallocSize(void*); - SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*); --SQLITE_PRIVATE void *sqlite3ScratchMalloc(int); --SQLITE_PRIVATE void sqlite3ScratchFree(void*); - SQLITE_PRIVATE void *sqlite3PageMalloc(int); - SQLITE_PRIVATE void sqlite3PageFree(void*); - SQLITE_PRIVATE void sqlite3MemSetDefault(void); -@@ -17306,11 +18608,18 @@ - SQLITE_PRIVATE void sqlite3StatusUp(int, int); - SQLITE_PRIVATE void sqlite3StatusDown(int, int); - SQLITE_PRIVATE void sqlite3StatusHighwater(int, int); -+SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3*,int*); - - /* Access to mutexes used by sqlite3_status() */ - SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void); - SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void); - -+#if defined(SQLITE_ENABLE_MULTITHREADED_CHECKS) && !defined(SQLITE_MUTEX_OMIT) -+SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*); -+#else -+# define sqlite3MutexWarnOnContention(x) -+#endif -+ - #ifndef SQLITE_OMIT_FLOATING_POINT - SQLITE_PRIVATE int sqlite3IsNaN(double); - #else -@@ -17327,8 +18636,6 @@ - sqlite3_value **apArg; /* The argument values */ - }; - --SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, const char*, va_list); --SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, const char*, ...); - SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...); - SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list); - #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) -@@ -17342,9 +18649,14 @@ - SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8); - SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*); - SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); -+SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*); - SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8); - SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8); -+#ifndef SQLITE_OMIT_WINDOWFUNC -+SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView*, const Window*, u8); -+SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8); - #endif -+#endif - - - SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); -@@ -17368,7 +18680,7 @@ - SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*); - SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*); - SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*); --SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*); -+SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int); - SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); - SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*); - SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); -@@ -17375,11 +18687,12 @@ - SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); - SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int); - SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); --SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*); -+SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); - SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); - SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*); - SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); - SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**); -+SQLITE_PRIVATE int sqlite3InitOne(sqlite3*, int, char**, u32); - SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); - #ifndef SQLITE_OMIT_VIRTUALTABLE - SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName); -@@ -17405,7 +18718,7 @@ - SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int); - SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int); - SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*); --SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,ExprSpan*); -+SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*); - SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*); - SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*); - SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*, -@@ -17429,8 +18742,9 @@ - SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*); - #endif - --SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int); --SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*); -+SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*); -+SQLITE_PRIVATE void sqlite3RowSetDelete(void*); -+SQLITE_PRIVATE void sqlite3RowSetClear(void*); - SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64); - SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, int iBatch, i64); - SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*); -@@ -17449,6 +18763,7 @@ - SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); - SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int); - SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); -+SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3*, Index*); - #ifndef SQLITE_OMIT_AUTOINCREMENT - SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); - SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse); -@@ -17456,9 +18771,9 @@ - # define sqlite3AutoincrementBegin(X) - # define sqlite3AutoincrementEnd(X) - #endif --SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int); -+SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upsert*); - SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*); --SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*); -+SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse*, IdList*, Token*); - SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*); - SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int); - SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*); -@@ -17477,22 +18792,23 @@ - SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int); - SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*); - SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, -- Expr*,ExprList*,u32,Expr*,Expr*); -+ Expr*,ExprList*,u32,Expr*); - SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*); - SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*); - SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int); - SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); - #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) --SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,char*); -+SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*); - #endif --SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); --SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); -+SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*); -+SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*, -+ Upsert*); - SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int); - SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); - SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*); - SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*); - SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*); --SQLITE_PRIVATE int sqlite3WhereOrderedInnerLoop(WhereInfo*); -+SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo*); - SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*); - SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*); - SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*); -@@ -17502,15 +18818,8 @@ - #define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */ - SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int); - SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); --SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg(Parse*, Table*, int, int, int); - SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); - SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); --SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int); --SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*); --SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*); --SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int); --SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*); --SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int); - SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int); - SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int); - SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int); -@@ -17541,6 +18850,7 @@ - SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr*, Expr*, int); - SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int); - SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Parse*,Expr*, Expr*, int); -+SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int); - SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); - SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); - SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx); -@@ -17558,6 +18868,8 @@ - SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*); - SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *); - SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*); -+SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr*); -+SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr*); - SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*); - SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*); - SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); -@@ -17570,13 +18882,17 @@ - SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); - SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); - SQLITE_PRIVATE int sqlite3IsRowid(const char*); -+#ifdef SQLITE_ENABLE_NORMALIZE -+SQLITE_PRIVATE int sqlite3IsRowidN(const char*, int); -+#endif - SQLITE_PRIVATE void sqlite3GenerateRowDelete( - Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int); - SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int); - SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); - SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int); -+SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(Expr*,int*,int); - SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, -- u8,u8,int,int*,int*); -+ u8,u8,int,int*,int*,Upsert*); - #ifdef SQLITE_ENABLE_NULL_TRIM - SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe*,Table*); - #else -@@ -17595,10 +18911,8 @@ - SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); - SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*); - SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int); --#if SELECTTRACE_ENABLED --SQLITE_PRIVATE void sqlite3SelectSetName(Select*,const char*); --#else --# define sqlite3SelectSetName(A,B) -+#ifdef SQLITE_ENABLE_NORMALIZE -+SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN(int,const char*,int); - #endif - SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int); - SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); -@@ -17610,7 +18924,7 @@ - SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int); - - #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) --SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, int); -+SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); - #endif - - #ifndef SQLITE_OMIT_TRIGGER -@@ -17626,11 +18940,15 @@ - SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, int, int, int); - void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*); - SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*); --SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*); --SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*, -- Select*,u8); --SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8); --SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*); -+SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*, -+ const char*,const char*); -+SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(Parse*,Token*, IdList*, -+ Select*,u8,Upsert*, -+ const char*,const char*); -+SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(Parse*,Token*,ExprList*, Expr*, u8, -+ const char*,const char*); -+SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(Parse*,Token*, Expr*, -+ const char*,const char*); - SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3*, Trigger*); - SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*); - SQLITE_PRIVATE u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int); -@@ -17737,15 +19055,23 @@ - SQLITE_PRIVATE const char *sqlite3ErrName(int); - #endif - -+#ifdef SQLITE_ENABLE_DESERIALIZE -+SQLITE_PRIVATE int sqlite3MemdbInit(void); -+#endif -+ - SQLITE_PRIVATE const char *sqlite3ErrStr(int); - SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); - SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); -+SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq*); - SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); - SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); -+SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr); -+SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*); - SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int); - SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); - SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*); - SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *); -+SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3*); - SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *); - SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int); - SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64); -@@ -17783,13 +19109,20 @@ - SQLITE_PRIVATE int sqlite3PendingByte; - #endif - #endif -+#ifdef VDBE_PROFILE -+SQLITE_PRIVATE sqlite3_uint64 sqlite3NProfileCnt; -+#endif - SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3*, int, int, int); - SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*); - SQLITE_PRIVATE void sqlite3AlterFunctions(void); - SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); -+SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*); - SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *); -+#ifdef SQLITE_ENABLE_NORMALIZE -+SQLITE_PRIVATE int sqlite3GetTokenNormalized(const unsigned char *, int *, int *); -+#endif - SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...); --SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*); -+SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int); - SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr *, int, int); - SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*); - SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); -@@ -17802,10 +19135,14 @@ - SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int); - SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *); - SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *); -+SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse*, void*, Token*); -+SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom); -+SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse*, Expr*); -+SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse*, ExprList*); - SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); --SQLITE_PRIVATE char sqlite3AffinityType(const char*, u8*); -+SQLITE_PRIVATE char sqlite3AffinityType(const char*, Column*); - SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*); --SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*); -+SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*, sqlite3_file*); - SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*); - SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *); - SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB); -@@ -17820,14 +19157,20 @@ - SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo*); - SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo*); - SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*); -+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int); -+ - #ifdef SQLITE_DEBUG - SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*); - #endif - SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, - void (*)(sqlite3_context*,int,sqlite3_value **), -- void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*), -+ void (*)(sqlite3_context*,int,sqlite3_value **), -+ void (*)(sqlite3_context*), -+ void (*)(sqlite3_context*), -+ void (*)(sqlite3_context*,int,sqlite3_value **), - FuncDestructor *pDestructor - ); -+SQLITE_PRIVATE void sqlite3NoopDestructor(void*); - SQLITE_PRIVATE void sqlite3OomFault(sqlite3*); - SQLITE_PRIVATE void sqlite3OomClear(sqlite3*); - SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); -@@ -17834,11 +19177,7 @@ - SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); - - SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); --SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int); --SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*); --SQLITE_PRIVATE void sqlite3AppendChar(StrAccum*,int,char); - SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*); --SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*); - SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int); - SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); - -@@ -17865,10 +19204,11 @@ - ** The interface to the LEMON-generated parser - */ - #ifndef SQLITE_AMALGAMATION --SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(u64)); -+SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(u64), Parse*); - SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*)); - #endif --SQLITE_PRIVATE void sqlite3Parser(void*, int, Token, Parse*); -+SQLITE_PRIVATE void sqlite3Parser(void*, int, Token); -+SQLITE_PRIVATE int sqlite3ParserFallback(int); - #ifdef YYTRACKMAXSTACKDEPTH - SQLITE_PRIVATE int sqlite3ParserStackPeak(void*); - #endif -@@ -17934,11 +19274,13 @@ - SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *); - SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *); - SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); --SQLITE_PRIVATE void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**); - SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); - SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); - SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); - SQLITE_PRIVATE void sqlite3ParserReset(Parse*); -+#ifdef SQLITE_ENABLE_NORMALIZE -+SQLITE_PRIVATE void sqlite3Normalize(Vdbe*, const char*, int, u8); -+#endif - SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*); - SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); - SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); -@@ -17956,7 +19298,19 @@ - #define sqlite3WithPush(x,y,z) - #define sqlite3WithDelete(x,y) - #endif -+#ifndef SQLITE_OMIT_UPSERT -+SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*); -+SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3*,Upsert*); -+SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3*,Upsert*); -+SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*); -+SQLITE_PRIVATE void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int); -+#else -+#define sqlite3UpsertNew(v,w,x,y,z) ((Upsert*)0) -+#define sqlite3UpsertDelete(x,y) -+#define sqlite3UpsertDup(x,y) ((Upsert*)0) -+#endif - -+ - /* Declarations for functions in fkey.c. All of these are replaced by - ** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign - ** key functionality is available. If OMIT_TRIGGER is defined but -@@ -18025,7 +19379,8 @@ - - SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); - SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *); --#ifdef SQLITE_ENABLE_ATOMIC_WRITE -+#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ -+ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) - SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *); - #endif - -@@ -18057,6 +19412,9 @@ - #ifdef SQLITE_DEBUG - SQLITE_PRIVATE void sqlite3ParserTrace(FILE*, char *); - #endif -+#if defined(YYCOVERAGE) -+SQLITE_PRIVATE int sqlite3ParserCoverage(FILE*); -+#endif - - /* - ** If the SQLITE_ENABLE IOTRACE exists then the global variable -@@ -18111,8 +19469,7 @@ - #endif - #define MEMTYPE_HEAP 0x01 /* General heap allocations */ - #define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */ --#define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */ --#define MEMTYPE_PCACHE 0x08 /* Page cache allocations */ -+#define MEMTYPE_PCACHE 0x04 /* Page cache allocations */ - - /* - ** Threading interface -@@ -18122,6 +19479,9 @@ - SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**); - #endif - -+#if defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST) -+SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3*); -+#endif - #if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST) - SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3*); - #endif -@@ -18341,6 +19701,7 @@ - SQLITE_THREADSAFE==1, /* bFullMutex */ - SQLITE_USE_URI, /* bOpenUri */ - SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ -+ 0, /* bSmallMalloc */ - 0x7ffffffe, /* mxStrlen */ - 0, /* neverCorrupt */ - SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */ -@@ -18353,9 +19714,6 @@ - 0, 0, /* mnHeap, mxHeap */ - SQLITE_DEFAULT_MMAP_SIZE, /* szMmap */ - SQLITE_MAX_MMAP_SIZE, /* mxMmap */ -- (void*)0, /* pScratch */ -- 0, /* szScratch */ -- 0, /* nScratch */ - (void*)0, /* pPage */ - 0, /* szPage */ - SQLITE_DEFAULT_PCACHE_INITSZ, /* nPage */ -@@ -18384,7 +19742,9 @@ - 0, /* xTestCallback */ - #endif - 0, /* bLocaltimeFault */ -- 0x7ffffffe /* iOnceResetThreshold */ -+ 0, /* bInternalFunctions */ -+ 0x7ffffffe, /* iOnceResetThreshold */ -+ SQLITE_DEFAULT_SORTERREF_SIZE /* szSorterRef */ - }; - - /* -@@ -18402,6 +19762,13 @@ - { "1", 1 } - }; - -+#ifdef VDBE_PROFILE -+/* -+** The following performance counter can be used in place of -+** sqlite3Hwtime() for profiling. This is a no-op on standard builds. -+*/ -+SQLITE_PRIVATE sqlite3_uint64 sqlite3NProfileCnt = 0; -+#endif - - /* - ** The value of the "pending" byte must be 0x40000000 (1 byte past the -@@ -18546,6 +19913,7 @@ - Bool isEphemeral:1; /* True for an ephemeral table */ - Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ - Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ -+ Bool seekHit:1; /* See the OP_SeekHit and OP_IfNoHope opcodes */ - Btree *pBtx; /* Separate file holding temporary table */ - i64 seqCount; /* Sequence counter */ - int *aAltMap; /* Mapping from table to index column numbers */ -@@ -18557,8 +19925,9 @@ - u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ - int seekResult; /* Result of previous sqlite3BtreeMoveto() or 0 - ** if there have been no prior seeks on the cursor. */ -- /* NB: seekResult does not distinguish between "no seeks have ever occurred -- ** on this cursor" and "the most recent seek was an exact match". */ -+ /* seekResult does not distinguish between "no seeks have ever occurred -+ ** on this cursor" and "the most recent seek was an exact match". -+ ** For CURTYPE_PSEUDO, seekResult is the register holding the record */ - - /* When a new VdbeCursor is allocated, only the fields above are zeroed. - ** The fields that follow are uninitialized, and must be individually -@@ -18565,10 +19934,9 @@ - ** initialized prior to first use. */ - VdbeCursor *pAltCursor; /* Associated index cursor from which to read */ - union { -- BtCursor *pCursor; /* CURTYPE_BTREE. Btree cursor */ -- sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ -- int pseudoTableReg; /* CURTYPE_PSEUDO. Reg holding content. */ -- VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */ -+ BtCursor *pCursor; /* CURTYPE_BTREE or _PSEUDO. Btree cursor */ -+ sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ -+ VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */ - } uc; - KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ - u32 iHdrOffset; /* Offset to next unparsed byte of the header */ -@@ -18629,6 +19997,9 @@ - void *token; /* Copy of SubProgram.token */ - i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ - AuxData *pAuxData; /* Linked list of auxdata allocations */ -+#if SQLITE_DEBUG -+ u32 iFrameMagic; /* magic number for sanity checking */ -+#endif - int nCursor; /* Number of entries in apCsr */ - int pc; /* Program Counter in parent (calling) frame */ - int nOp; /* Size of aOp array */ -@@ -18639,6 +20010,13 @@ - int nDbChange; /* Value of db->nChange */ - }; - -+/* Magic number for sanity checking on VdbeFrame objects */ -+#define SQLITE_FRAME_MAGIC 0x879fb71e -+ -+/* -+** Return a pointer to the array of registers allocated for use -+** by a VdbeFrame. -+*/ - #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))]) - - /* -@@ -18653,8 +20031,6 @@ - int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */ - const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */ - FuncDef *pDef; /* Used only when flags==MEM_Agg */ -- RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ -- VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ - } u; - u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ - u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ -@@ -18669,7 +20045,7 @@ - void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ - #ifdef SQLITE_DEBUG - Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ -- void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */ -+ u16 mScopyFlags; /* flags value immediately after the shallow copy */ - #endif - }; - -@@ -18698,8 +20074,8 @@ - #define MEM_Real 0x0008 /* Value is a real number */ - #define MEM_Blob 0x0010 /* Value is a BLOB */ - #define MEM_AffMask 0x001f /* Mask of affinity bits */ --#define MEM_RowSet 0x0020 /* Value is a RowSet object */ --#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ -+/* Available 0x0020 */ -+/* Available 0x0040 */ - #define MEM_Undefined 0x0080 /* Value is undefined */ - #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ - #define MEM_TypeMask 0xc1ff /* Mask of type bits */ -@@ -18726,7 +20102,7 @@ - ** that needs to be deallocated to avoid a leak. - */ - #define VdbeMemDynamic(X) \ -- (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0) -+ (((X)->flags&(MEM_Agg|MEM_Dyn))!=0) - - /* - ** Clear any existing type flags from a Mem and replace them with f -@@ -18778,7 +20154,6 @@ - int iOp; /* Instruction number of OP_Function */ - int isError; /* Error code returned by the function. */ - u8 skipFlag; /* Skip accumulator loading if true */ -- u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */ - u8 argc; /* Number of arguments */ - sqlite3_value *argv[1]; /* Argument set */ - }; -@@ -18841,14 +20216,15 @@ - int nOp; /* Number of instructions in the program */ - #ifdef SQLITE_DEBUG - int rcApp; /* errcode set by sqlite3_result_error_code() */ -+ u32 nWrite; /* Number of write operations that have occurred */ - #endif - u16 nResColumn; /* Number of columns in one row of the result set */ - u8 errorAction; /* Recovery action to do in case of an error */ - u8 minWriteFileFormat; /* Minimum file format for writable database files */ - u8 prepFlags; /* SQLITE_PREPARE_* flags */ -- bft expired:1; /* True if the VM needs to be recompiled */ -+ bft expired:2; /* 1: recompile VM immediately 2: when convenient */ -+ bft explain:2; /* True if EXPLAIN present on SQL command */ - bft doingRerun:1; /* True if rerunning after an auto-reprepare */ -- bft explain:2; /* True if EXPLAIN present on SQL command */ - bft changeCntOn:1; /* True to update the change-counter */ - bft runOnlyOnce:1; /* Automatically expire on reset */ - bft usesStmtJournal:1; /* True if uses a statement journal */ -@@ -18858,6 +20234,9 @@ - yDbMask lockMask; /* Subset of btreeMask that requires a lock */ - u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */ - char *zSql; /* Text of the SQL statement that generated this */ -+#ifdef SQLITE_ENABLE_NORMALIZE -+ char *zNormSql; /* Normalization of the associated SQL statement */ -+#endif - void *pFree; /* Free this when deleting the vdbe */ - VdbeFrame *pFrame; /* Parent frame */ - VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */ -@@ -18909,9 +20288,6 @@ - void sqliteVdbePopStack(Vdbe*,int); - SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor**, int*); - SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*); --#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) --SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*); --#endif - SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); - SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8); - SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int, u32*); -@@ -18923,7 +20299,9 @@ - SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*); - SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*); - SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*); -+#ifndef SQLITE_OMIT_EXPLAIN - SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*); -+#endif - SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*); - SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int); - SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*); -@@ -18942,12 +20320,16 @@ - SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); - SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*); - SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int); --SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*); -+#ifdef SQLITE_DEBUG -+SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*); -+#endif -+SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*); - SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); - SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8); - SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*); - SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*); - SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*); -+SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem*, int ifNull); - SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*); - SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*); - SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*); -@@ -18955,11 +20337,20 @@ - SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*); - SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); - SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); -+#ifndef SQLITE_OMIT_WINDOWFUNC -+SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*); -+#endif -+#ifndef SQLITE_OMIT_EXPLAIN - SQLITE_PRIVATE const char *sqlite3OpcodeName(int); -+#endif - SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); - SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n); - SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int); --SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); -+#ifdef SQLITE_DEBUG -+SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame*); -+#endif -+SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void*); /* Destructor on Mem */ -+SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); /* Actually deletes the Frame */ - SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *); - #ifdef SQLITE_ENABLE_PREUPDATE_HOOK - SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int); -@@ -18975,6 +20366,14 @@ - SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *); - SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *); - -+#ifdef SQLITE_DEBUG -+SQLITE_PRIVATE void sqlite3VdbeIncrWriteCounter(Vdbe*, VdbeCursor*); -+SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe*); -+#else -+# define sqlite3VdbeIncrWriteCounter(V,C) -+# define sqlite3VdbeAssertAbortable(V) -+#endif -+ - #if !defined(SQLITE_OMIT_SHARED_CACHE) - SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*); - #else -@@ -19126,7 +20525,6 @@ - : sqlite3MallocMutex()) ); - assert( op==SQLITE_STATUS_MALLOC_SIZE - || op==SQLITE_STATUS_PAGECACHE_SIZE -- || op==SQLITE_STATUS_SCRATCH_SIZE - || op==SQLITE_STATUS_PARSER_STACK ); - if( newValue>wsdStat.mxValue[op] ){ - wsdStat.mxValue[op] = newValue; -@@ -19176,6 +20574,28 @@ - } - - /* -+** Return the number of LookasideSlot elements on the linked list -+*/ -+static u32 countLookasideSlots(LookasideSlot *p){ -+ u32 cnt = 0; -+ while( p ){ -+ p = p->pNext; -+ cnt++; -+ } -+ return cnt; -+} -+ -+/* -+** Count the number of slots of lookaside memory that are outstanding -+*/ -+SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){ -+ u32 nInit = countLookasideSlots(db->lookaside.pInit); -+ u32 nFree = countLookasideSlots(db->lookaside.pFree); -+ if( pHighwater ) *pHighwater = db->lookaside.nSlot - nInit; -+ return db->lookaside.nSlot - (nInit+nFree); -+} -+ -+/* - ** Query status information for a single database connection - */ - SQLITE_API int sqlite3_db_status( -@@ -19194,10 +20614,15 @@ - sqlite3_mutex_enter(db->mutex); - switch( op ){ - case SQLITE_DBSTATUS_LOOKASIDE_USED: { -- *pCurrent = db->lookaside.nOut; -- *pHighwater = db->lookaside.mxOut; -+ *pCurrent = sqlite3LookasideUsed(db, pHighwater); - if( resetFlag ){ -- db->lookaside.mxOut = db->lookaside.nOut; -+ LookasideSlot *p = db->lookaside.pFree; -+ if( p ){ -+ while( p->pNext ) p = p->pNext; -+ p->pNext = db->lookaside.pInit; -+ db->lookaside.pInit = db->lookaside.pFree; -+ db->lookaside.pFree = 0; -+ } - } - break; - } -@@ -19315,6 +20740,9 @@ - ** pagers the database handle is connected to. *pHighwater is always set - ** to zero. - */ -+ case SQLITE_DBSTATUS_CACHE_SPILL: -+ op = SQLITE_DBSTATUS_CACHE_WRITE+1; -+ /* Fall through into the next case */ - case SQLITE_DBSTATUS_CACHE_HIT: - case SQLITE_DBSTATUS_CACHE_MISS: - case SQLITE_DBSTATUS_CACHE_WRITE:{ -@@ -19397,7 +20825,7 @@ - ** - ** Jean Meeus - ** Astronomical Algorithms, 2nd Edition, 1998 --** ISBM 0-943396-61-1 -+** ISBN 0-943396-61-1 - ** Willmann-Bell, Inc - ** Richmond, Virginia (USA) - */ -@@ -20708,7 +22136,7 @@ - } - SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){ - DO_OS_MALLOC_TEST(id); -- return id->pMethods->xSync(id, flags); -+ return flags ? id->pMethods->xSync(id, flags) : SQLITE_OK; - } - SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ - DO_OS_MALLOC_TEST(id); -@@ -20735,8 +22163,11 @@ - ** routine has no return value since the return value would be meaningless. - */ - SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ -+ if( id->pMethods==0 ) return SQLITE_NOTFOUND; - #ifdef SQLITE_TEST -- if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){ -+ if( op!=SQLITE_FCNTL_COMMIT_PHASETWO -+ && op!=SQLITE_FCNTL_LOCK_TIMEOUT -+ ){ - /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite - ** is using a regular VFS, it is called after the corresponding - ** transaction has been committed. Injecting a fault at this point -@@ -20753,7 +22184,7 @@ - return id->pMethods->xFileControl(id, op, pArg); - } - SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){ -- (void)id->pMethods->xFileControl(id, op, pArg); -+ if( id->pMethods ) (void)id->pMethods->xFileControl(id, op, pArg); - } - - SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){ -@@ -20763,6 +22194,7 @@ - SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){ - return id->pMethods->xDeviceCharacteristics(id); - } -+#ifndef SQLITE_OMIT_WAL - SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){ - return id->pMethods->xShmLock(id, offset, n, flags); - } -@@ -20782,6 +22214,7 @@ - DO_OS_MALLOC_TEST(id); - return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp); - } -+#endif /* SQLITE_OMIT_WAL */ - - #if SQLITE_MAX_MMAP_SIZE>0 - /* The real implementation of xFetch and xUnfetch */ -@@ -21015,9 +22448,12 @@ - ** Unregister a VFS so that it is no longer accessible. - */ - SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ --#if SQLITE_THREADSAFE -- sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); -+ MUTEX_LOGIC(sqlite3_mutex *mutex;) -+#ifndef SQLITE_OMIT_AUTOINIT -+ int rc = sqlite3_initialize(); -+ if( rc ) return rc; - #endif -+ MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) - sqlite3_mutex_enter(mutex); - vfsUnlink(pVfs); - sqlite3_mutex_leave(mutex); -@@ -23300,7 +24736,194 @@ - - - #ifndef SQLITE_MUTEX_OMIT -+ -+#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS - /* -+** This block (enclosed by SQLITE_ENABLE_MULTITHREADED_CHECKS) contains -+** the implementation of a wrapper around the system default mutex -+** implementation (sqlite3DefaultMutex()). -+** -+** Most calls are passed directly through to the underlying default -+** mutex implementation. Except, if a mutex is configured by calling -+** sqlite3MutexWarnOnContention() on it, then if contention is ever -+** encountered within xMutexEnter() a warning is emitted via sqlite3_log(). -+** -+** This type of mutex is used as the database handle mutex when testing -+** apps that usually use SQLITE_CONFIG_MULTITHREAD mode. -+*/ -+ -+/* -+** Type for all mutexes used when SQLITE_ENABLE_MULTITHREADED_CHECKS -+** is defined. Variable CheckMutex.mutex is a pointer to the real mutex -+** allocated by the system mutex implementation. Variable iType is usually set -+** to the type of mutex requested - SQLITE_MUTEX_RECURSIVE, SQLITE_MUTEX_FAST -+** or one of the static mutex identifiers. Or, if this is a recursive mutex -+** that has been configured using sqlite3MutexWarnOnContention(), it is -+** set to SQLITE_MUTEX_WARNONCONTENTION. -+*/ -+typedef struct CheckMutex CheckMutex; -+struct CheckMutex { -+ int iType; -+ sqlite3_mutex *mutex; -+}; -+ -+#define SQLITE_MUTEX_WARNONCONTENTION (-1) -+ -+/* -+** Pointer to real mutex methods object used by the CheckMutex -+** implementation. Set by checkMutexInit(). -+*/ -+static SQLITE_WSD const sqlite3_mutex_methods *pGlobalMutexMethods; -+ -+#ifdef SQLITE_DEBUG -+static int checkMutexHeld(sqlite3_mutex *p){ -+ return pGlobalMutexMethods->xMutexHeld(((CheckMutex*)p)->mutex); -+} -+static int checkMutexNotheld(sqlite3_mutex *p){ -+ return pGlobalMutexMethods->xMutexNotheld(((CheckMutex*)p)->mutex); -+} -+#endif -+ -+/* -+** Initialize and deinitialize the mutex subsystem. -+*/ -+static int checkMutexInit(void){ -+ pGlobalMutexMethods = sqlite3DefaultMutex(); -+ return SQLITE_OK; -+} -+static int checkMutexEnd(void){ -+ pGlobalMutexMethods = 0; -+ return SQLITE_OK; -+} -+ -+/* -+** Allocate a mutex. -+*/ -+static sqlite3_mutex *checkMutexAlloc(int iType){ -+ static CheckMutex staticMutexes[] = { -+ {2, 0}, {3, 0}, {4, 0}, {5, 0}, -+ {6, 0}, {7, 0}, {8, 0}, {9, 0}, -+ {10, 0}, {11, 0}, {12, 0}, {13, 0} -+ }; -+ CheckMutex *p = 0; -+ -+ assert( SQLITE_MUTEX_RECURSIVE==1 && SQLITE_MUTEX_FAST==0 ); -+ if( iType<2 ){ -+ p = sqlite3MallocZero(sizeof(CheckMutex)); -+ if( p==0 ) return 0; -+ p->iType = iType; -+ }else{ -+#ifdef SQLITE_ENABLE_API_ARMOR -+ if( iType-2>=ArraySize(staticMutexes) ){ -+ (void)SQLITE_MISUSE_BKPT; -+ return 0; -+ } -+#endif -+ p = &staticMutexes[iType-2]; -+ } -+ -+ if( p->mutex==0 ){ -+ p->mutex = pGlobalMutexMethods->xMutexAlloc(iType); -+ if( p->mutex==0 ){ -+ if( iType<2 ){ -+ sqlite3_free(p); -+ } -+ p = 0; -+ } -+ } -+ -+ return (sqlite3_mutex*)p; -+} -+ -+/* -+** Free a mutex. -+*/ -+static void checkMutexFree(sqlite3_mutex *p){ -+ assert( SQLITE_MUTEX_RECURSIVE<2 ); -+ assert( SQLITE_MUTEX_FAST<2 ); -+ assert( SQLITE_MUTEX_WARNONCONTENTION<2 ); -+ -+#if SQLITE_ENABLE_API_ARMOR -+ if( ((CheckMutex*)p)->iType<2 ) -+#endif -+ { -+ CheckMutex *pCheck = (CheckMutex*)p; -+ pGlobalMutexMethods->xMutexFree(pCheck->mutex); -+ sqlite3_free(pCheck); -+ } -+#ifdef SQLITE_ENABLE_API_ARMOR -+ else{ -+ (void)SQLITE_MISUSE_BKPT; -+ } -+#endif -+} -+ -+/* -+** Enter the mutex. -+*/ -+static void checkMutexEnter(sqlite3_mutex *p){ -+ CheckMutex *pCheck = (CheckMutex*)p; -+ if( pCheck->iType==SQLITE_MUTEX_WARNONCONTENTION ){ -+ if( SQLITE_OK==pGlobalMutexMethods->xMutexTry(pCheck->mutex) ){ -+ return; -+ } -+ sqlite3_log(SQLITE_MISUSE, -+ "illegal multi-threaded access to database connection" -+ ); -+ } -+ pGlobalMutexMethods->xMutexEnter(pCheck->mutex); -+} -+ -+/* -+** Enter the mutex (do not block). -+*/ -+static int checkMutexTry(sqlite3_mutex *p){ -+ CheckMutex *pCheck = (CheckMutex*)p; -+ return pGlobalMutexMethods->xMutexTry(pCheck->mutex); -+} -+ -+/* -+** Leave the mutex. -+*/ -+static void checkMutexLeave(sqlite3_mutex *p){ -+ CheckMutex *pCheck = (CheckMutex*)p; -+ pGlobalMutexMethods->xMutexLeave(pCheck->mutex); -+} -+ -+sqlite3_mutex_methods const *multiThreadedCheckMutex(void){ -+ static const sqlite3_mutex_methods sMutex = { -+ checkMutexInit, -+ checkMutexEnd, -+ checkMutexAlloc, -+ checkMutexFree, -+ checkMutexEnter, -+ checkMutexTry, -+ checkMutexLeave, -+#ifdef SQLITE_DEBUG -+ checkMutexHeld, -+ checkMutexNotheld -+#else -+ 0, -+ 0 -+#endif -+ }; -+ return &sMutex; -+} -+ -+/* -+** Mark the SQLITE_MUTEX_RECURSIVE mutex passed as the only argument as -+** one on which there should be no contention. -+*/ -+SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex *p){ -+ if( sqlite3GlobalConfig.mutex.xMutexAlloc==checkMutexAlloc ){ -+ CheckMutex *pCheck = (CheckMutex*)p; -+ assert( pCheck->iType==SQLITE_MUTEX_RECURSIVE ); -+ pCheck->iType = SQLITE_MUTEX_WARNONCONTENTION; -+ } -+} -+#endif /* ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS */ -+ -+/* - ** Initialize the mutex system. - */ - SQLITE_PRIVATE int sqlite3MutexInit(void){ -@@ -23315,7 +24938,11 @@ - sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex; - - if( sqlite3GlobalConfig.bCoreMutex ){ -+#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS -+ pFrom = multiThreadedCheckMutex(); -+#else - pFrom = sqlite3DefaultMutex(); -+#endif - }else{ - pFrom = sqlite3NoopMutex(); - } -@@ -23714,11 +25341,12 @@ - #endif - }; - #if SQLITE_MUTEX_NREF --#define SQLITE3_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER,0,0,(pthread_t)0,0} -+# define SQLITE3_MUTEX_INITIALIZER(id) \ -+ {PTHREAD_MUTEX_INITIALIZER,id,0,(pthread_t)0,0} - #elif defined(SQLITE_ENABLE_API_ARMOR) --#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0 } -+# define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER, id } - #else --#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER } -+#define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER } - #endif - - /* -@@ -23815,18 +25443,18 @@ - */ - static sqlite3_mutex *pthreadMutexAlloc(int iType){ - static sqlite3_mutex staticMutexes[] = { -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER -+ SQLITE3_MUTEX_INITIALIZER(2), -+ SQLITE3_MUTEX_INITIALIZER(3), -+ SQLITE3_MUTEX_INITIALIZER(4), -+ SQLITE3_MUTEX_INITIALIZER(5), -+ SQLITE3_MUTEX_INITIALIZER(6), -+ SQLITE3_MUTEX_INITIALIZER(7), -+ SQLITE3_MUTEX_INITIALIZER(8), -+ SQLITE3_MUTEX_INITIALIZER(9), -+ SQLITE3_MUTEX_INITIALIZER(10), -+ SQLITE3_MUTEX_INITIALIZER(11), -+ SQLITE3_MUTEX_INITIALIZER(12), -+ SQLITE3_MUTEX_INITIALIZER(13) - }; - sqlite3_mutex *p; - switch( iType ){ -@@ -23845,6 +25473,9 @@ - pthread_mutex_init(&p->mutex, &recursiveAttr); - pthread_mutexattr_destroy(&recursiveAttr); - #endif -+#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) -+ p->id = SQLITE_MUTEX_RECURSIVE; -+#endif - } - break; - } -@@ -23852,6 +25483,9 @@ - p = sqlite3MallocZero( sizeof(*p) ); - if( p ){ - pthread_mutex_init(&p->mutex, 0); -+#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) -+ p->id = SQLITE_MUTEX_FAST; -+#endif - } - break; - } -@@ -23867,7 +25501,7 @@ - } - } - #if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) -- if( p ) p->id = iType; -+ assert( p==0 || p->id==iType ); - #endif - return p; - } -@@ -24384,7 +26018,7 @@ - #ifdef SQLITE_DEBUG - volatile int nRef; /* Number of enterances */ - volatile DWORD owner; /* Thread holding this mutex */ -- volatile int trace; /* True to trace changes */ -+ volatile LONG trace; /* True to trace changes */ - #endif - }; - -@@ -24396,10 +26030,10 @@ - #define SQLITE_W32_MUTEX_INITIALIZER { 0 } - - #ifdef SQLITE_DEBUG --#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, \ -+#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id, \ - 0L, (DWORD)0, 0 } - #else --#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 } -+#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id } - #endif - - #ifdef SQLITE_DEBUG -@@ -24442,18 +26076,18 @@ - ** Initialize and deinitialize the mutex subsystem. - */ - static sqlite3_mutex winMutex_staticMutexes[] = { -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER, -- SQLITE3_MUTEX_INITIALIZER -+ SQLITE3_MUTEX_INITIALIZER(2), -+ SQLITE3_MUTEX_INITIALIZER(3), -+ SQLITE3_MUTEX_INITIALIZER(4), -+ SQLITE3_MUTEX_INITIALIZER(5), -+ SQLITE3_MUTEX_INITIALIZER(6), -+ SQLITE3_MUTEX_INITIALIZER(7), -+ SQLITE3_MUTEX_INITIALIZER(8), -+ SQLITE3_MUTEX_INITIALIZER(9), -+ SQLITE3_MUTEX_INITIALIZER(10), -+ SQLITE3_MUTEX_INITIALIZER(11), -+ SQLITE3_MUTEX_INITIALIZER(12), -+ SQLITE3_MUTEX_INITIALIZER(13) - }; - - static int winMutex_isInit = 0; -@@ -24583,15 +26217,15 @@ - } - #endif - p = &winMutex_staticMutexes[iType-2]; -- p->id = iType; - #ifdef SQLITE_DEBUG - #ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC -- p->trace = 1; -+ InterlockedCompareExchange(&p->trace, 1, 0); - #endif - #endif - break; - } - } -+ assert( p==0 || p->id==iType ); - return p; - } - -@@ -24779,14 +26413,6 @@ - } - - /* --** An instance of the following object records the location of --** each unused scratch buffer. --*/ --typedef struct ScratchFreeslot { -- struct ScratchFreeslot *pNext; /* Next unused scratch buffer */ --} ScratchFreeslot; -- --/* - ** State information local to the memory allocation subsystem. - */ - static SQLITE_WSD struct Mem0Global { -@@ -24794,21 +26420,11 @@ - sqlite3_int64 alarmThreshold; /* The soft heap limit */ - - /* -- ** Pointers to the end of sqlite3GlobalConfig.pScratch memory -- ** (so that a range test can be used to determine if an allocation -- ** being freed came from pScratch) and a pointer to the list of -- ** unused scratch allocations. -- */ -- void *pScratchEnd; -- ScratchFreeslot *pScratchFree; -- u32 nScratchFree; -- -- /* - ** True if heap is nearly "full" where "full" is defined by the - ** sqlite3_soft_heap_limit() setting. - */ - int nearlyFull; --} mem0 = { 0, 0, 0, 0, 0, 0 }; -+} mem0 = { 0, 0, 0 }; - - #define mem0 GLOBAL(struct Mem0Global, mem0) - -@@ -24878,28 +26494,6 @@ - } - memset(&mem0, 0, sizeof(mem0)); - mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); -- if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100 -- && sqlite3GlobalConfig.nScratch>0 ){ -- int i, n, sz; -- ScratchFreeslot *pSlot; -- sz = ROUNDDOWN8(sqlite3GlobalConfig.szScratch); -- sqlite3GlobalConfig.szScratch = sz; -- pSlot = (ScratchFreeslot*)sqlite3GlobalConfig.pScratch; -- n = sqlite3GlobalConfig.nScratch; -- mem0.pScratchFree = pSlot; -- mem0.nScratchFree = n; -- for(i=0; i<n-1; i++){ -- pSlot->pNext = (ScratchFreeslot*)(sz+(char*)pSlot); -- pSlot = pSlot->pNext; -- } -- pSlot->pNext = 0; -- mem0.pScratchEnd = (void*)&pSlot[1]; -- }else{ -- mem0.pScratchEnd = 0; -- sqlite3GlobalConfig.pScratch = 0; -- sqlite3GlobalConfig.szScratch = 0; -- sqlite3GlobalConfig.nScratch = 0; -- } - if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512 - || sqlite3GlobalConfig.nPage<=0 ){ - sqlite3GlobalConfig.pPage = 0; -@@ -25051,105 +26645,6 @@ - } - - /* --** Each thread may only have a single outstanding allocation from --** xScratchMalloc(). We verify this constraint in the single-threaded --** case by setting scratchAllocOut to 1 when an allocation --** is outstanding clearing it when the allocation is freed. --*/ --#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) --static int scratchAllocOut = 0; --#endif -- -- --/* --** Allocate memory that is to be used and released right away. --** This routine is similar to alloca() in that it is not intended --** for situations where the memory might be held long-term. This --** routine is intended to get memory to old large transient data --** structures that would not normally fit on the stack of an --** embedded processor. --*/ --SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){ -- void *p; -- assert( n>0 ); -- -- sqlite3_mutex_enter(mem0.mutex); -- sqlite3StatusHighwater(SQLITE_STATUS_SCRATCH_SIZE, n); -- if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){ -- p = mem0.pScratchFree; -- mem0.pScratchFree = mem0.pScratchFree->pNext; -- mem0.nScratchFree--; -- sqlite3StatusUp(SQLITE_STATUS_SCRATCH_USED, 1); -- sqlite3_mutex_leave(mem0.mutex); -- }else{ -- sqlite3_mutex_leave(mem0.mutex); -- p = sqlite3Malloc(n); -- if( sqlite3GlobalConfig.bMemstat && p ){ -- sqlite3_mutex_enter(mem0.mutex); -- sqlite3StatusUp(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p)); -- sqlite3_mutex_leave(mem0.mutex); -- } -- sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH); -- } -- assert( sqlite3_mutex_notheld(mem0.mutex) ); -- -- --#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) -- /* EVIDENCE-OF: R-12970-05880 SQLite will not use more than one scratch -- ** buffers per thread. -- ** -- ** This can only be checked in single-threaded mode. -- */ -- assert( scratchAllocOut==0 ); -- if( p ) scratchAllocOut++; --#endif -- -- return p; --} --SQLITE_PRIVATE void sqlite3ScratchFree(void *p){ -- if( p ){ -- --#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) -- /* Verify that no more than two scratch allocation per thread -- ** is outstanding at one time. (This is only checked in the -- ** single-threaded case since checking in the multi-threaded case -- ** would be much more complicated.) */ -- assert( scratchAllocOut>=1 && scratchAllocOut<=2 ); -- scratchAllocOut--; --#endif -- -- if( SQLITE_WITHIN(p, sqlite3GlobalConfig.pScratch, mem0.pScratchEnd) ){ -- /* Release memory from the SQLITE_CONFIG_SCRATCH allocation */ -- ScratchFreeslot *pSlot; -- pSlot = (ScratchFreeslot*)p; -- sqlite3_mutex_enter(mem0.mutex); -- pSlot->pNext = mem0.pScratchFree; -- mem0.pScratchFree = pSlot; -- mem0.nScratchFree++; -- assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch ); -- sqlite3StatusDown(SQLITE_STATUS_SCRATCH_USED, 1); -- sqlite3_mutex_leave(mem0.mutex); -- }else{ -- /* Release memory back to the heap */ -- assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) ); -- assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_SCRATCH) ); -- sqlite3MemdebugSetType(p, MEMTYPE_HEAP); -- if( sqlite3GlobalConfig.bMemstat ){ -- int iSize = sqlite3MallocSize(p); -- sqlite3_mutex_enter(mem0.mutex); -- sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize); -- sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize); -- sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); -- sqlite3GlobalConfig.m.xFree(p); -- sqlite3_mutex_leave(mem0.mutex); -- }else{ -- sqlite3GlobalConfig.m.xFree(p); -- } -- } -- } --} -- --/* - ** TRUE if p is a lookaside memory allocation from db - */ - #ifndef SQLITE_OMIT_LOOKASIDE -@@ -25239,7 +26734,6 @@ - #endif - pBuf->pNext = db->lookaside.pFree; - db->lookaside.pFree = pBuf; -- db->lookaside.nOut--; - return; - } - } -@@ -25400,16 +26894,16 @@ - assert( db->mallocFailed==0 ); - if( n>db->lookaside.sz ){ - db->lookaside.anStat[1]++; -- }else if( (pBuf = db->lookaside.pFree)==0 ){ -- db->lookaside.anStat[2]++; -- }else{ -+ }else if( (pBuf = db->lookaside.pFree)!=0 ){ - db->lookaside.pFree = pBuf->pNext; -- db->lookaside.nOut++; - db->lookaside.anStat[0]++; -- if( db->lookaside.nOut>db->lookaside.mxOut ){ -- db->lookaside.mxOut = db->lookaside.nOut; -- } - 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 if( db->mallocFailed ){ - return 0; -@@ -25514,6 +27008,19 @@ - } - - /* -+** The text between zStart and zEnd represents a phrase within a larger -+** SQL statement. Make a copy of this phrase in space obtained form -+** sqlite3DbMalloc(). Omit leading and trailing whitespace. -+*/ -+SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){ -+ int n; -+ while( sqlite3Isspace(zStart[0]) ) zStart++; -+ n = (int)(zEnd - zStart); -+ while( ALWAYS(n>0) && sqlite3Isspace(zStart[n-1]) ) n--; -+ return sqlite3DbStrNDup(db, zStart, n); -+} -+ -+/* - ** Free any prior content in *pz and replace it with a copy of zNew. - */ - SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){ -@@ -25725,7 +27232,7 @@ - ** Set the StrAccum object to an error mode. - */ - static void setStrAccumError(StrAccum *p, u8 eError){ -- assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG ); -+ assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG ); - p->accError = eError; - p->nAlloc = 0; - } -@@ -25759,8 +27266,8 @@ - /* - ** Render a string given by "fmt" into the StrAccum object. - */ --SQLITE_PRIVATE void sqlite3VXPrintf( -- StrAccum *pAccum, /* Accumulate results here */ -+SQLITE_API void sqlite3_str_vappendf( -+ sqlite3_str *pAccum, /* Accumulate results here */ - const char *fmt, /* Format string */ - va_list ap /* arguments */ - ){ -@@ -25797,6 +27304,11 @@ - PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */ - char buf[etBUFSIZE]; /* Conversion buffer */ - -+ /* pAccum never starts out with an empty buffer that was obtained from -+ ** malloc(). This precondition is required by the mprintf("%z...") -+ ** optimization. */ -+ assert( pAccum->nChar>0 || (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 ); -+ - bufpt = 0; - if( (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC)!=0 ){ - pArgList = va_arg(ap, PrintfArguments*); -@@ -25812,11 +27324,11 @@ - #else - do{ fmt++; }while( *fmt && *fmt != '%' ); - #endif -- sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt)); -+ sqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt)); - if( *fmt==0 ) break; - } - if( (c=(*++fmt))==0 ){ -- sqlite3StrAccumAppend(pAccum, "%", 1); -+ sqlite3_str_append(pAccum, "%", 1); - break; - } - /* Find out what flags are present */ -@@ -25994,7 +27506,7 @@ - u64 n = (u64)precision + 10 + precision/3; - zOut = zExtra = sqlite3Malloc( n ); - if( zOut==0 ){ -- setStrAccumError(pAccum, STRACCUM_NOMEM); -+ setStrAccumError(pAccum, SQLITE_NOMEM); - return; - } - nOut = (int)n; -@@ -26119,7 +27631,7 @@ - bufpt = zExtra - = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 ); - if( bufpt==0 ){ -- setStrAccumError(pAccum, STRACCUM_NOMEM); -+ setStrAccumError(pAccum, SQLITE_NOMEM); - return; - } - } -@@ -26215,22 +27727,52 @@ - case etCHARX: - if( bArgList ){ - bufpt = getTextArg(pArgList); -- c = bufpt ? bufpt[0] : 0; -+ length = 1; -+ if( bufpt ){ -+ buf[0] = c = *(bufpt++); -+ if( (c&0xc0)==0xc0 ){ -+ while( length<4 && (bufpt[0]&0xc0)==0x80 ){ -+ buf[length++] = *(bufpt++); -+ } -+ } -+ }else{ -+ buf[0] = 0; -+ } - }else{ -- c = va_arg(ap,int); -+ unsigned int ch = va_arg(ap,unsigned int); -+ if( ch<0x00080 ){ -+ buf[0] = ch & 0xff; -+ length = 1; -+ }else if( ch<0x00800 ){ -+ buf[0] = 0xc0 + (u8)((ch>>6)&0x1f); -+ buf[1] = 0x80 + (u8)(ch & 0x3f); -+ length = 2; -+ }else if( ch<0x10000 ){ -+ buf[0] = 0xe0 + (u8)((ch>>12)&0x0f); -+ buf[1] = 0x80 + (u8)((ch>>6) & 0x3f); -+ buf[2] = 0x80 + (u8)(ch & 0x3f); -+ length = 3; -+ }else{ -+ buf[0] = 0xf0 + (u8)((ch>>18) & 0x07); -+ buf[1] = 0x80 + (u8)((ch>>12) & 0x3f); -+ buf[2] = 0x80 + (u8)((ch>>6) & 0x3f); -+ buf[3] = 0x80 + (u8)(ch & 0x3f); -+ length = 4; -+ } - } - if( precision>1 ){ - width -= precision-1; - if( width>1 && !flag_leftjustify ){ -- sqlite3AppendChar(pAccum, width-1, ' '); -+ sqlite3_str_appendchar(pAccum, width-1, ' '); - width = 0; - } -- sqlite3AppendChar(pAccum, precision-1, c); -+ while( precision-- > 1 ){ -+ sqlite3_str_append(pAccum, buf, length); -+ } - } -- length = 1; -- buf[0] = c; - bufpt = buf; -- break; -+ flag_altform2 = 1; -+ goto adjust_width_for_utf8; - case etSTRING: - case etDYNSTRING: - if( bArgList ){ -@@ -26242,17 +27784,50 @@ - if( bufpt==0 ){ - bufpt = ""; - }else if( xtype==etDYNSTRING ){ -+ if( pAccum->nChar==0 -+ && pAccum->mxAlloc -+ && width==0 -+ && precision<0 -+ && pAccum->accError==0 -+ ){ -+ /* Special optimization for sqlite3_mprintf("%z..."): -+ ** Extend an existing memory allocation rather than creating -+ ** a new one. */ -+ assert( (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 ); -+ pAccum->zText = bufpt; -+ pAccum->nAlloc = sqlite3DbMallocSize(pAccum->db, bufpt); -+ pAccum->nChar = 0x7fffffff & (int)strlen(bufpt); -+ pAccum->printfFlags |= SQLITE_PRINTF_MALLOCED; -+ length = 0; -+ break; -+ } - zExtra = bufpt; - } - if( precision>=0 ){ -- for(length=0; length<precision && bufpt[length]; length++){} -+ if( flag_altform2 ){ -+ /* Set length to the number of bytes needed in order to display -+ ** precision characters */ -+ unsigned char *z = (unsigned char*)bufpt; -+ while( precision-- > 0 && z[0] ){ -+ SQLITE_SKIP_UTF8(z); -+ } -+ length = (int)(z - (unsigned char*)bufpt); -+ }else{ -+ for(length=0; length<precision && bufpt[length]; length++){} -+ } - }else{ -- length = sqlite3Strlen30(bufpt); -+ length = 0x7fffffff & (int)strlen(bufpt); - } -+ adjust_width_for_utf8: -+ if( flag_altform2 && width>0 ){ -+ /* Adjust width to account for extra bytes in UTF-8 characters */ -+ int ii = length - 1; -+ while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++; -+ } - break; -- case etSQLESCAPE: /* Escape ' characters */ -- case etSQLESCAPE2: /* Escape ' and enclose in '...' */ -- case etSQLESCAPE3: { /* Escape " characters */ -+ case etSQLESCAPE: /* %q: Escape ' characters */ -+ case etSQLESCAPE2: /* %Q: Escape ' and enclose in '...' */ -+ case etSQLESCAPE3: { /* %w: Escape " characters */ - int i, j, k, n, isnull; - int needQuote; - char ch; -@@ -26266,9 +27841,17 @@ - } - isnull = escarg==0; - if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); -+ /* For %q, %Q, and %w, the precision is the number of byte (or -+ ** characters if the ! flags is present) to use from the input. -+ ** Because of the extra quoting characters inserted, the number -+ ** of output characters may be larger than the precision. -+ */ - k = precision; - for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){ - if( ch==q ) n++; -+ if( flag_altform2 && (ch&0xc0)==0xc0 ){ -+ while( (escarg[i+1]&0xc0)==0x80 ){ i++; } -+ } - } - needQuote = !isnull && xtype==etSQLESCAPE2; - n += i + 3; -@@ -26275,7 +27858,7 @@ - if( n>etBUFSIZE ){ - bufpt = zExtra = sqlite3Malloc( n ); - if( bufpt==0 ){ -- setStrAccumError(pAccum, STRACCUM_NOMEM); -+ setStrAccumError(pAccum, SQLITE_NOMEM); - return; - } - }else{ -@@ -26291,10 +27874,7 @@ - if( needQuote ) bufpt[j++] = q; - bufpt[j] = 0; - length = j; -- /* The precision in %q and %Q means how many input characters to -- ** consume, not the length of the output... -- ** if( precision>=0 && precision<length ) length = precision; */ -- break; -+ goto adjust_width_for_utf8; - } - case etTOKEN: { - Token *pToken; -@@ -26302,7 +27882,7 @@ - pToken = va_arg(ap, Token*); - assert( bArgList==0 ); - if( pToken && pToken->n ){ -- sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n); -+ sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n); - } - length = width = 0; - break; -@@ -26318,10 +27898,10 @@ - assert( bArgList==0 ); - assert( k>=0 && k<pSrc->nSrc ); - if( pItem->zDatabase ){ -- sqlite3StrAccumAppendAll(pAccum, pItem->zDatabase); -- sqlite3StrAccumAppend(pAccum, ".", 1); -+ sqlite3_str_appendall(pAccum, pItem->zDatabase); -+ sqlite3_str_append(pAccum, ".", 1); - } -- sqlite3StrAccumAppendAll(pAccum, pItem->zName); -+ sqlite3_str_appendall(pAccum, pItem->zName); - length = width = 0; - break; - } -@@ -26333,15 +27913,18 @@ - /* - ** The text of the conversion is pointed to by "bufpt" and is - ** "length" characters long. The field width is "width". Do -- ** the output. -+ ** the output. Both length and width are in bytes, not characters, -+ ** at this point. If the "!" flag was present on string conversions -+ ** indicating that width and precision should be expressed in characters, -+ ** then the values have been translated prior to reaching this point. - */ - width -= length; - if( width>0 ){ -- if( !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); -- sqlite3StrAccumAppend(pAccum, bufpt, length); -- if( flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); -+ if( !flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' '); -+ sqlite3_str_append(pAccum, bufpt, length); -+ if( flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' '); - }else{ -- sqlite3StrAccumAppend(pAccum, bufpt, length); -+ sqlite3_str_append(pAccum, bufpt, length); - } - - if( zExtra ){ -@@ -26362,18 +27945,17 @@ - char *zNew; - assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */ - if( p->accError ){ -- testcase(p->accError==STRACCUM_TOOBIG); -- testcase(p->accError==STRACCUM_NOMEM); -+ testcase(p->accError==SQLITE_TOOBIG); -+ testcase(p->accError==SQLITE_NOMEM); - return 0; - } - if( p->mxAlloc==0 ){ - N = p->nAlloc - p->nChar - 1; -- setStrAccumError(p, STRACCUM_TOOBIG); -+ setStrAccumError(p, SQLITE_TOOBIG); - return N; - }else{ - char *zOld = isMalloced(p) ? p->zText : 0; - i64 szNew = p->nChar; -- assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); - szNew += N + 1; - if( szNew+p->nChar<=p->mxAlloc ){ - /* Force exponential buffer size growth as long as it does not overflow, -@@ -26381,8 +27963,8 @@ - szNew += p->nChar; - } - if( szNew > p->mxAlloc ){ -- sqlite3StrAccumReset(p); -- setStrAccumError(p, STRACCUM_TOOBIG); -+ sqlite3_str_reset(p); -+ setStrAccumError(p, SQLITE_TOOBIG); - return 0; - }else{ - p->nAlloc = (int)szNew; -@@ -26399,8 +27981,8 @@ - p->nAlloc = sqlite3DbMallocSize(p->db, zNew); - p->printfFlags |= SQLITE_PRINTF_MALLOCED; - }else{ -- sqlite3StrAccumReset(p); -- setStrAccumError(p, STRACCUM_NOMEM); -+ sqlite3_str_reset(p); -+ setStrAccumError(p, SQLITE_NOMEM); - return 0; - } - } -@@ -26410,12 +27992,11 @@ - /* - ** Append N copies of character c to the given string buffer. - */ --SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){ -+SQLITE_API void sqlite3_str_appendchar(sqlite3_str *p, int N, char c){ - testcase( p->nChar + (i64)N > 0x7fffffff ); - if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){ - return; - } -- assert( (p->zText==p->zBase)==!isMalloced(p) ); - while( (N--)>0 ) p->zText[p->nChar++] = c; - } - -@@ -26423,9 +28004,9 @@ - ** The StrAccum "p" is not large enough to accept N new bytes of z[]. - ** So enlarge if first, then do the append. - ** --** This is a helper routine to sqlite3StrAccumAppend() that does special-case -+** This is a helper routine to sqlite3_str_append() that does special-case - ** work (enlarging the buffer) using tail recursion, so that the --** sqlite3StrAccumAppend() routine can use fast calling semantics. -+** sqlite3_str_append() routine can use fast calling semantics. - */ - static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ - N = sqlite3StrAccumEnlarge(p, N); -@@ -26433,7 +28014,6 @@ - memcpy(&p->zText[p->nChar], z, N); - p->nChar += N; - } -- assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); - } - - /* -@@ -26440,7 +28020,7 @@ - ** Append N bytes of text from z to the StrAccum object. Increase the - ** size of the memory allocation for StrAccum if necessary. - */ --SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ -+SQLITE_API void sqlite3_str_append(sqlite3_str *p, const char *z, int N){ - assert( z!=0 || N==0 ); - assert( p->zText!=0 || p->nChar==0 || p->accError ); - assert( N>=0 ); -@@ -26457,8 +28037,8 @@ - /* - ** Append the complete text of zero-terminated string z[] to the p string. - */ --SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){ -- sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z)); -+SQLITE_API void sqlite3_str_appendall(sqlite3_str *p, const char *z){ -+ sqlite3_str_append(p, z, sqlite3Strlen30(z)); - } - - -@@ -26468,19 +28048,20 @@ - ** pointer if any kind of error was encountered. - */ - static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){ -+ char *zText; - assert( p->mxAlloc>0 && !isMalloced(p) ); -- p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); -- if( p->zText ){ -- memcpy(p->zText, p->zBase, p->nChar+1); -+ zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); -+ if( zText ){ -+ memcpy(zText, p->zText, p->nChar+1); - p->printfFlags |= SQLITE_PRINTF_MALLOCED; - }else{ -- setStrAccumError(p, STRACCUM_NOMEM); -+ setStrAccumError(p, SQLITE_NOMEM); - } -- return p->zText; -+ p->zText = zText; -+ return zText; - } - SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){ - if( p->zText ){ -- assert( (p->zText==p->zBase)==!isMalloced(p) ); - p->zText[p->nChar] = 0; - if( p->mxAlloc>0 && !isMalloced(p) ){ - return strAccumFinishRealloc(p); -@@ -26490,14 +28071,55 @@ - } - - /* -+** This singleton is an sqlite3_str object that is returned if -+** sqlite3_malloc() fails to provide space for a real one. This -+** sqlite3_str object accepts no new text and always returns -+** an SQLITE_NOMEM error. -+*/ -+static sqlite3_str sqlite3OomStr = { -+ 0, 0, 0, 0, 0, SQLITE_NOMEM, 0 -+}; -+ -+/* Finalize a string created using sqlite3_str_new(). -+*/ -+SQLITE_API char *sqlite3_str_finish(sqlite3_str *p){ -+ char *z; -+ if( p!=0 && p!=&sqlite3OomStr ){ -+ z = sqlite3StrAccumFinish(p); -+ sqlite3_free(p); -+ }else{ -+ z = 0; -+ } -+ return z; -+} -+ -+/* Return any error code associated with p */ -+SQLITE_API int sqlite3_str_errcode(sqlite3_str *p){ -+ return p ? p->accError : SQLITE_NOMEM; -+} -+ -+/* Return the current length of p in bytes */ -+SQLITE_API int sqlite3_str_length(sqlite3_str *p){ -+ return p ? p->nChar : 0; -+} -+ -+/* Return the current value for p */ -+SQLITE_API char *sqlite3_str_value(sqlite3_str *p){ -+ if( p==0 || p->nChar==0 ) return 0; -+ p->zText[p->nChar] = 0; -+ return p->zText; -+} -+ -+/* - ** Reset an StrAccum string. Reclaim all malloced memory. - */ --SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){ -- assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); -+SQLITE_API void sqlite3_str_reset(StrAccum *p){ - if( isMalloced(p) ){ - sqlite3DbFree(p->db, p->zText); - p->printfFlags &= ~SQLITE_PRINTF_MALLOCED; - } -+ p->nAlloc = 0; -+ p->nChar = 0; - p->zText = 0; - } - -@@ -26516,15 +28138,27 @@ - ** allocations will ever occur. - */ - SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){ -- p->zText = p->zBase = zBase; -+ p->zText = zBase; - p->db = db; -- p->nChar = 0; - p->nAlloc = n; - p->mxAlloc = mx; -+ p->nChar = 0; - p->accError = 0; - p->printfFlags = 0; - } - -+/* Allocate and initialize a new dynamic string object */ -+SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3 *db){ -+ sqlite3_str *p = sqlite3_malloc64(sizeof(*p)); -+ if( p ){ -+ sqlite3StrAccumInit(p, 0, 0, 0, -+ db ? db->aLimit[SQLITE_LIMIT_LENGTH] : SQLITE_MAX_LENGTH); -+ }else{ -+ p = &sqlite3OomStr; -+ } -+ return p; -+} -+ - /* - ** Print into memory obtained from sqliteMalloc(). Use the internal - ** %-conversion extensions. -@@ -26537,9 +28171,9 @@ - sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase), - db->aLimit[SQLITE_LIMIT_LENGTH]); - acc.printfFlags = SQLITE_PRINTF_INTERNAL; -- sqlite3VXPrintf(&acc, zFormat, ap); -+ sqlite3_str_vappendf(&acc, zFormat, ap); - z = sqlite3StrAccumFinish(&acc); -- if( acc.accError==STRACCUM_NOMEM ){ -+ if( acc.accError==SQLITE_NOMEM ){ - sqlite3OomFault(db); - } - return z; -@@ -26577,7 +28211,7 @@ - if( sqlite3_initialize() ) return 0; - #endif - sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); -- sqlite3VXPrintf(&acc, zFormat, ap); -+ sqlite3_str_vappendf(&acc, zFormat, ap); - z = sqlite3StrAccumFinish(&acc); - return z; - } -@@ -26622,7 +28256,7 @@ - } - #endif - sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); -- sqlite3VXPrintf(&acc, zFormat, ap); -+ sqlite3_str_vappendf(&acc, zFormat, ap); - zBuf[acc.nChar] = 0; - return zBuf; - } -@@ -26644,7 +28278,7 @@ - ** allocate memory because it might be called while the memory allocator - ** mutex is held. - ** --** sqlite3VXPrintf() might ask for *temporary* memory allocations for -+** sqlite3_str_vappendf() might ask for *temporary* memory allocations for - ** certain format characters (%q) or for very large precisions or widths. - ** Care must be taken that any sqlite3_log() calls that occur while the - ** memory mutex is held do not use these mechanisms. -@@ -26654,7 +28288,7 @@ - char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ - - sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); -- sqlite3VXPrintf(&acc, zFormat, ap); -+ sqlite3_str_vappendf(&acc, zFormat, ap); - sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode, - sqlite3StrAccumFinish(&acc)); - } -@@ -26683,23 +28317,30 @@ - char zBuf[500]; - sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); - va_start(ap,zFormat); -- sqlite3VXPrintf(&acc, zFormat, ap); -+ sqlite3_str_vappendf(&acc, zFormat, ap); - va_end(ap); - sqlite3StrAccumFinish(&acc); -+#ifdef SQLITE_OS_TRACE_PROC -+ { -+ extern void SQLITE_OS_TRACE_PROC(const char *zBuf, int nBuf); -+ SQLITE_OS_TRACE_PROC(zBuf, sizeof(zBuf)); -+ } -+#else - fprintf(stdout,"%s", zBuf); - fflush(stdout); -+#endif - } - #endif - - - /* --** variable-argument wrapper around sqlite3VXPrintf(). The bFlags argument -+** variable-argument wrapper around sqlite3_str_vappendf(). The bFlags argument - ** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats. - */ --SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){ -+SQLITE_API void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){ - va_list ap; - va_start(ap,zFormat); -- sqlite3VXPrintf(p, zFormat, ap); -+ sqlite3_str_vappendf(p, zFormat, ap); - va_end(ap); - } - -@@ -26765,15 +28406,17 @@ - sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); - if( p ){ - for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){ -- sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4); -+ sqlite3_str_append(&acc, p->bLine[i] ? "| " : " ", 4); - } -- sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4); -+ sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4); - } -- va_start(ap, zFormat); -- sqlite3VXPrintf(&acc, zFormat, ap); -- va_end(ap); -- assert( acc.nChar>0 ); -- if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1); -+ if( zFormat!=0 ){ -+ va_start(ap, zFormat); -+ sqlite3_str_vappendf(&acc, zFormat, ap); -+ va_end(ap); -+ assert( acc.nChar>0 ); -+ sqlite3_str_append(&acc, "\n", 1); -+ } - sqlite3StrAccumFinish(&acc); - fprintf(stdout,"%s", zBuf); - fflush(stdout); -@@ -26806,17 +28449,17 @@ - char zLine[1000]; - const struct Cte *pCte = &pWith->a[i]; - sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); -- sqlite3XPrintf(&x, "%s", pCte->zName); -+ sqlite3_str_appendf(&x, "%s", pCte->zName); - if( pCte->pCols && pCte->pCols->nExpr>0 ){ - char cSep = '('; - int j; - for(j=0; j<pCte->pCols->nExpr; j++){ -- sqlite3XPrintf(&x, "%c%s", cSep, pCte->pCols->a[j].zName); -+ sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zName); - cSep = ','; - } -- sqlite3XPrintf(&x, ")"); -+ sqlite3_str_appendf(&x, ")"); - } -- sqlite3XPrintf(&x, " AS"); -+ sqlite3_str_appendf(&x, " AS"); - sqlite3StrAccumFinish(&x); - sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1); - sqlite3TreeViewSelect(pView, pCte->pSelect, 0); -@@ -26826,6 +28469,42 @@ - } - } - -+/* -+** Generate a human-readable description of a SrcList object. -+*/ -+SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ -+ int i; -+ for(i=0; i<pSrc->nSrc; i++){ -+ const struct SrcList_item *pItem = &pSrc->a[i]; -+ StrAccum x; -+ char zLine[100]; -+ sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); -+ sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor); -+ if( pItem->zDatabase ){ -+ sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName); -+ }else if( pItem->zName ){ -+ sqlite3_str_appendf(&x, " %s", pItem->zName); -+ } -+ if( pItem->pTab ){ -+ sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName); -+ } -+ if( pItem->zAlias ){ -+ sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias); -+ } -+ if( pItem->fg.jointype & JT_LEFT ){ -+ sqlite3_str_appendf(&x, " LEFT-JOIN"); -+ } -+ sqlite3StrAccumFinish(&x); -+ sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1); -+ if( pItem->pSelect ){ -+ sqlite3TreeViewSelect(pView, pItem->pSelect, 0); -+ } -+ if( pItem->fg.isTabFunc ){ -+ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); -+ } -+ sqlite3TreeViewPop(pView); -+ } -+} - - /* - ** Generate a human-readable description of a Select object. -@@ -26844,9 +28523,11 @@ - sqlite3TreeViewPush(pView, 1); - } - do{ -- sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x nSelectRow=%d", -+ sqlite3TreeViewLine(pView, -+ "SELECT%s%s (%u/%p) selFlags=0x%x nSelectRow=%d", - ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""), -- ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags, -+ ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), -+ p->selId, p, p->selFlags, - (int)p->nSelectRow - ); - if( cnt++ ) sqlite3TreeViewPop(pView); -@@ -26860,43 +28541,27 @@ - if( p->pHaving ) n++; - if( p->pOrderBy ) n++; - if( p->pLimit ) n++; -- if( p->pOffset ) n++; -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( p->pWin ) n++; -+ if( p->pWinDefn ) n++; -+#endif - } - sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set"); -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( p->pWin ){ -+ Window *pX; -+ pView = sqlite3TreeViewPush(pView, (n--)>0); -+ sqlite3TreeViewLine(pView, "window-functions"); -+ for(pX=p->pWin; pX; pX=pX->pNextWin){ -+ sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0); -+ } -+ sqlite3TreeViewPop(pView); -+ } -+#endif - if( p->pSrc && p->pSrc->nSrc ){ -- int i; - pView = sqlite3TreeViewPush(pView, (n--)>0); - sqlite3TreeViewLine(pView, "FROM"); -- for(i=0; i<p->pSrc->nSrc; i++){ -- struct SrcList_item *pItem = &p->pSrc->a[i]; -- StrAccum x; -- char zLine[100]; -- sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); -- sqlite3XPrintf(&x, "{%d,*}", pItem->iCursor); -- if( pItem->zDatabase ){ -- sqlite3XPrintf(&x, " %s.%s", pItem->zDatabase, pItem->zName); -- }else if( pItem->zName ){ -- sqlite3XPrintf(&x, " %s", pItem->zName); -- } -- if( pItem->pTab ){ -- sqlite3XPrintf(&x, " tabname=%Q", pItem->pTab->zName); -- } -- if( pItem->zAlias ){ -- sqlite3XPrintf(&x, " (AS %s)", pItem->zAlias); -- } -- if( pItem->fg.jointype & JT_LEFT ){ -- sqlite3XPrintf(&x, " LEFT-JOIN"); -- } -- sqlite3StrAccumFinish(&x); -- sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1); -- if( pItem->pSelect ){ -- sqlite3TreeViewSelect(pView, pItem->pSelect, 0); -- } -- if( pItem->fg.isTabFunc ){ -- sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); -- } -- sqlite3TreeViewPop(pView); -- } -+ sqlite3TreeViewSrcList(pView, p->pSrc); - sqlite3TreeViewPop(pView); - } - if( p->pWhere ){ -@@ -26912,19 +28577,29 @@ - sqlite3TreeViewExpr(pView, p->pHaving, 0); - sqlite3TreeViewPop(pView); - } -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( p->pWinDefn ){ -+ Window *pX; -+ sqlite3TreeViewItem(pView, "WINDOW", (n--)>0); -+ for(pX=p->pWinDefn; pX; pX=pX->pNextWin){ -+ sqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0); -+ } -+ sqlite3TreeViewPop(pView); -+ } -+#endif - if( p->pOrderBy ){ - sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY"); - } - if( p->pLimit ){ - sqlite3TreeViewItem(pView, "LIMIT", (n--)>0); -- sqlite3TreeViewExpr(pView, p->pLimit, 0); -+ sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0); -+ if( p->pLimit->pRight ){ -+ sqlite3TreeViewItem(pView, "OFFSET", (n--)>0); -+ sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0); -+ sqlite3TreeViewPop(pView); -+ } - sqlite3TreeViewPop(pView); - } -- if( p->pOffset ){ -- sqlite3TreeViewItem(pView, "OFFSET", (n--)>0); -- sqlite3TreeViewExpr(pView, p->pOffset, 0); -- sqlite3TreeViewPop(pView); -- } - if( p->pPrior ){ - const char *zOp = "UNION"; - switch( p->op ){ -@@ -26939,7 +28614,84 @@ - sqlite3TreeViewPop(pView); - } - -+#ifndef SQLITE_OMIT_WINDOWFUNC - /* -+** Generate a description of starting or stopping bounds -+*/ -+SQLITE_PRIVATE void sqlite3TreeViewBound( -+ TreeView *pView, /* View context */ -+ u8 eBound, /* UNBOUNDED, CURRENT, PRECEDING, FOLLOWING */ -+ Expr *pExpr, /* Value for PRECEDING or FOLLOWING */ -+ u8 moreToFollow /* True if more to follow */ -+){ -+ switch( eBound ){ -+ case TK_UNBOUNDED: { -+ sqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow); -+ sqlite3TreeViewPop(pView); -+ break; -+ } -+ case TK_CURRENT: { -+ sqlite3TreeViewItem(pView, "CURRENT", moreToFollow); -+ sqlite3TreeViewPop(pView); -+ break; -+ } -+ case TK_PRECEDING: { -+ sqlite3TreeViewItem(pView, "PRECEDING", moreToFollow); -+ sqlite3TreeViewExpr(pView, pExpr, 0); -+ sqlite3TreeViewPop(pView); -+ break; -+ } -+ case TK_FOLLOWING: { -+ sqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow); -+ sqlite3TreeViewExpr(pView, pExpr, 0); -+ sqlite3TreeViewPop(pView); -+ break; -+ } -+ } -+} -+#endif /* SQLITE_OMIT_WINDOWFUNC */ -+ -+#ifndef SQLITE_OMIT_WINDOWFUNC -+/* -+** Generate a human-readable explanation for a Window object -+*/ -+SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ -+ pView = sqlite3TreeViewPush(pView, more); -+ if( pWin->zName ){ -+ sqlite3TreeViewLine(pView, "OVER %s", pWin->zName); -+ }else{ -+ sqlite3TreeViewLine(pView, "OVER"); -+ } -+ if( pWin->pPartition ){ -+ sqlite3TreeViewExprList(pView, pWin->pPartition, 1, "PARTITION-BY"); -+ } -+ if( pWin->pOrderBy ){ -+ sqlite3TreeViewExprList(pView, pWin->pOrderBy, 1, "ORDER-BY"); -+ } -+ if( pWin->eType ){ -+ sqlite3TreeViewItem(pView, pWin->eType==TK_RANGE ? "RANGE" : "ROWS", 0); -+ sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1); -+ sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0); -+ sqlite3TreeViewPop(pView); -+ } -+ sqlite3TreeViewPop(pView); -+} -+#endif /* SQLITE_OMIT_WINDOWFUNC */ -+ -+#ifndef SQLITE_OMIT_WINDOWFUNC -+/* -+** Generate a human-readable explanation for a Window Function object -+*/ -+SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){ -+ pView = sqlite3TreeViewPush(pView, more); -+ sqlite3TreeViewLine(pView, "WINFUNC %s(%d)", -+ pWin->pFunc->zName, pWin->pFunc->nArg); -+ sqlite3TreeViewWindow(pView, pWin, 0); -+ sqlite3TreeViewPop(pView); -+} -+#endif /* SQLITE_OMIT_WINDOWFUNC */ -+ -+/* - ** Generate a human-readable explanation of an expression tree. - */ - SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ -@@ -26976,6 +28728,9 @@ - sqlite3TreeViewLine(pView, "{%d:%d}%s", - pExpr->iTable, pExpr->iColumn, zFlgs); - } -+ if( ExprHasProperty(pExpr, EP_FixedCol) ){ -+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); -+ } - break; - } - case TK_INTEGER: { -@@ -27000,6 +28755,11 @@ - sqlite3TreeViewLine(pView,"NULL"); - break; - } -+ case TK_TRUEFALSE: { -+ sqlite3TreeViewLine(pView, -+ sqlite3ExprTruthValue(pExpr) ? "TRUE" : "FALSE"); -+ break; -+ } - #ifndef SQLITE_OMIT_BLOB_LITERAL - case TK_BLOB: { - sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken); -@@ -27056,6 +28816,19 @@ - case TK_ISNULL: zUniOp = "ISNULL"; break; - case TK_NOTNULL: zUniOp = "NOTNULL"; break; - -+ case TK_TRUTH: { -+ int x; -+ const char *azOp[] = { -+ "IS-FALSE", "IS-TRUE", "IS-NOT-FALSE", "IS-NOT-TRUE" -+ }; -+ assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT ); -+ assert( pExpr->pRight ); -+ assert( pExpr->pRight->op==TK_TRUEFALSE ); -+ x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight); -+ zUniOp = azOp[x]; -+ break; -+ } -+ - case TK_SPAN: { - sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken); - sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); -@@ -27071,10 +28844,17 @@ - case TK_AGG_FUNCTION: - case TK_FUNCTION: { - ExprList *pFarg; /* List of function arguments */ -+ Window *pWin; - if( ExprHasProperty(pExpr, EP_TokenOnly) ){ - pFarg = 0; -+ pWin = 0; - }else{ - pFarg = pExpr->x.pList; -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ pWin = pExpr->y.pWin; -+#else -+ pWin = 0; -+#endif - } - if( pExpr->op==TK_AGG_FUNCTION ){ - sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q", -@@ -27083,8 +28863,13 @@ - sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken); - } - if( pFarg ){ -- sqlite3TreeViewExprList(pView, pFarg, 0, 0); -+ sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0); - } -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( pWin ){ -+ sqlite3TreeViewWindow(pView, pWin, 0); -+ } -+#endif - break; - } - #ifndef SQLITE_OMIT_SUBQUERY -@@ -27215,12 +29000,25 @@ - sqlite3TreeViewLine(pView, "%s", zLabel); - for(i=0; i<pList->nExpr; i++){ - int j = pList->a[i].u.x.iOrderByCol; -- if( j ){ -- sqlite3TreeViewPush(pView, 0); -- sqlite3TreeViewLine(pView, "iOrderByCol=%d", j); -+ char *zName = pList->a[i].zName; -+ int moreToFollow = i<pList->nExpr - 1; -+ if( j || zName ){ -+ sqlite3TreeViewPush(pView, moreToFollow); -+ moreToFollow = 0; -+ sqlite3TreeViewLine(pView, 0); -+ if( zName ){ -+ fprintf(stdout, "AS %s ", zName); -+ } -+ if( j ){ -+ fprintf(stdout, "iOrderByCol=%d", j); -+ } -+ fprintf(stdout, "\n"); -+ fflush(stdout); - } -- sqlite3TreeViewExpr(pView, pList->a[i].pExpr, i<pList->nExpr-1); -- if( j ) sqlite3TreeViewPop(pView); -+ sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow); -+ if( j || zName ){ -+ sqlite3TreeViewPop(pView); -+ } - } - } - } -@@ -28511,6 +30309,45 @@ - } - - /* -+** Compute 10 to the E-th power. Examples: E==1 results in 10. -+** E==2 results in 100. E==50 results in 1.0e50. -+** -+** This routine only works for values of E between 1 and 341. -+*/ -+static LONGDOUBLE_TYPE sqlite3Pow10(int E){ -+#if defined(_MSC_VER) -+ static const LONGDOUBLE_TYPE x[] = { -+ 1.0e+001, -+ 1.0e+002, -+ 1.0e+004, -+ 1.0e+008, -+ 1.0e+016, -+ 1.0e+032, -+ 1.0e+064, -+ 1.0e+128, -+ 1.0e+256 -+ }; -+ LONGDOUBLE_TYPE r = 1.0; -+ int i; -+ assert( E>=0 && E<=307 ); -+ for(i=0; E!=0; i++, E >>=1){ -+ if( E & 1 ) r *= x[i]; -+ } -+ return r; -+#else -+ LONGDOUBLE_TYPE x = 10.0; -+ LONGDOUBLE_TYPE r = 1.0; -+ while(1){ -+ if( E & 1 ) r *= x; -+ E >>= 1; -+ if( E==0 ) break; -+ x *= x; -+ } -+ return r; -+#endif -+} -+ -+/* - ** The string z[] is an text representation of a real number. - ** Convert this string to a double and write it into *pResult. - ** -@@ -28577,12 +30414,12 @@ - /* copy max significant digits to significand */ - while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ - s = s*10 + (*z - '0'); -- z+=incr, nDigits++; -+ z+=incr; nDigits++; - } - - /* skip non-significant significand digits - ** (increase exponent by d to shift decimal left) */ -- while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++, d++; -+ while( z<zEnd && sqlite3Isdigit(*z) ){ z+=incr; nDigits++; d++; } - if( z>=zEnd ) goto do_atof_calc; - - /* if decimal point is present */ -@@ -28595,7 +30432,7 @@ - s = s*10 + (*z - '0'); - d--; - } -- z+=incr, nDigits++; -+ z+=incr; nDigits++; - } - } - if( z>=zEnd ) goto do_atof_calc; -@@ -28665,11 +30502,10 @@ - if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/ - result = (double)s; - }else{ -- LONGDOUBLE_TYPE scale = 1.0; - /* attempt to handle extremely small/large numbers better */ - if( e>307 ){ /*OPTIMIZATION-IF-TRUE*/ - if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/ -- while( e%308 ) { scale *= 1.0e+1; e -= 1; } -+ LONGDOUBLE_TYPE scale = sqlite3Pow10(e-308); - if( esign<0 ){ - result = s / scale; - result /= 1.0e+308; -@@ -28681,14 +30517,15 @@ - if( esign<0 ){ - result = 0.0*s; - }else{ -+#ifdef INFINITY -+ result = INFINITY*s; -+#else - result = 1e308*1e308*s; /* Infinity */ -+#endif - } - } - }else{ -- /* 1.0e+22 is the largest power of 10 than can be -- ** represented exactly. */ -- while( e%22 ) { scale *= 1.0e+1; e -= 1; } -- while( e>0 ) { scale *= 1.0e+22; e -= 22; } -+ LONGDOUBLE_TYPE scale = sqlite3Pow10(e); - if( esign<0 ){ - result = s / scale; - }else{ -@@ -28743,17 +30580,13 @@ - ** Convert zNum to a 64-bit signed integer. zNum must be decimal. This - ** routine does *not* accept hexadecimal notation. - ** --** If the zNum value is representable as a 64-bit twos-complement --** integer, then write that value into *pNum and return 0. -+** Returns: - ** --** If zNum is exactly 9223372036854775808, return 2. This special --** case is broken out because while 9223372036854775808 cannot be a --** signed 64-bit integer, its negative -9223372036854775808 can be. -+** 0 Successful transformation. Fits in a 64-bit signed integer. -+** 1 Excess non-space text after the integer value -+** 2 Integer too large for a 64-bit signed integer or is malformed -+** 3 Special case of 9223372036854775808 - ** --** If zNum is too big for a 64-bit integer and is not --** 9223372036854775808 or if zNum contains any non-numeric text, --** then return 1. --** - ** length is the number of bytes in the string (bytes, not characters). - ** The string is not necessarily zero-terminated. The encoding is - ** given by enc. -@@ -28765,6 +30598,7 @@ - int i; - int c = 0; - int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */ -+ int rc; /* Baseline return code */ - const char *zStart; - const char *zEnd = zNum + length; - assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); -@@ -28792,7 +30626,14 @@ - for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){ - u = u*10 + c - '0'; - } -+ testcase( i==18*incr ); -+ testcase( i==19*incr ); -+ testcase( i==20*incr ); - if( u>LARGEST_INT64 ){ -+ /* This test and assignment is needed only to suppress UB warnings -+ ** from clang and -fsanitize=undefined. This test and assignment make -+ ** the code a little larger and slower, and no harm comes from omitting -+ ** them, but we must appaise the undefined-behavior pharisees. */ - *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; - }else if( neg ){ - *pNum = -(i64)u; -@@ -28799,36 +30640,43 @@ - }else{ - *pNum = (i64)u; - } -- testcase( i==18 ); -- testcase( i==19 ); -- testcase( i==20 ); -- if( &zNum[i]<zEnd /* Extra bytes at the end */ -- || (i==0 && zStart==zNum) /* No digits */ -- || i>19*incr /* Too many digits */ -+ rc = 0; -+ if( (i==0 && zStart==zNum) /* No digits */ - || nonNum /* UTF16 with high-order bytes non-zero */ - ){ -- /* zNum is empty or contains non-numeric text or is longer -- ** than 19 digits (thus guaranteeing that it is too large) */ -- return 1; -- }else if( i<19*incr ){ -+ rc = 1; -+ }else if( &zNum[i]<zEnd ){ /* Extra bytes at the end */ -+ int jj = i; -+ do{ -+ if( !sqlite3Isspace(zNum[jj]) ){ -+ rc = 1; /* Extra non-space text after the integer */ -+ break; -+ } -+ jj += incr; -+ }while( &zNum[jj]<zEnd ); -+ } -+ if( i<19*incr ){ - /* Less than 19 digits, so we know that it fits in 64 bits */ - assert( u<=LARGEST_INT64 ); -- return 0; -+ return rc; - }else{ - /* zNum is a 19-digit numbers. Compare it against 9223372036854775808. */ -- c = compare2pow63(zNum, incr); -+ c = i>19*incr ? 1 : compare2pow63(zNum, incr); - if( c<0 ){ - /* zNum is less than 9223372036854775808 so it fits */ - assert( u<=LARGEST_INT64 ); -- return 0; -- }else if( c>0 ){ -- /* zNum is greater than 9223372036854775808 so it overflows */ -- return 1; -+ return rc; - }else{ -- /* zNum is exactly 9223372036854775808. Fits if negative. The -- ** special case 2 overflow if positive */ -- assert( u-1==LARGEST_INT64 ); -- return neg ? 0 : 2; -+ *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; -+ if( c>0 ){ -+ /* zNum is greater than 9223372036854775808 so it overflows */ -+ return 2; -+ }else{ -+ /* zNum is exactly 9223372036854775808. Fits if negative. The -+ ** special case 2 overflow if positive */ -+ assert( u-1==LARGEST_INT64 ); -+ return neg ? rc : 3; -+ } - } - } - } -@@ -28841,8 +30689,9 @@ - ** Returns: - ** - ** 0 Successful transformation. Fits in a 64-bit signed integer. --** 1 Integer too large for a 64-bit signed integer or is malformed --** 2 Special case of 9223372036854775808 -+** 1 Excess text after the integer value -+** 2 Integer too large for a 64-bit signed integer or is malformed -+** 3 Special case of 9223372036854775808 - */ - SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ - #ifndef SQLITE_OMIT_HEX_INTEGER -@@ -28856,7 +30705,7 @@ - u = u*16 + sqlite3HexToInt(z[k]); - } - memcpy(pOut, &u, 8); -- return (z[k]==0 && k-i<=16) ? 0 : 1; -+ return (z[k]==0 && k-i<=16) ? 0 : 2; - }else - #endif /* SQLITE_OMIT_HEX_INTEGER */ - { -@@ -29466,7 +31315,7 @@ - ** overflow, leave *pA unchanged and return 1. - */ - SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){ --#if GCC_VERSION>=5004000 -+#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER) - return __builtin_add_overflow(*pA, iB, pA); - #else - i64 iA = *pA; -@@ -29486,7 +31335,7 @@ - #endif - } - SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){ --#if GCC_VERSION>=5004000 -+#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER) - return __builtin_sub_overflow(*pA, iB, pA); - #else - testcase( iB==SMALLEST_INT64+1 ); -@@ -29501,7 +31350,7 @@ - #endif - } - SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){ --#if GCC_VERSION>=5004000 -+#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER) - return __builtin_mul_overflow(*pA, iB, pA); - #else - i64 iA = *pA; -@@ -29603,8 +31452,14 @@ - if( x<2 ) return 0; - while( x<8 ){ y -= 10; x <<= 1; } - }else{ -+#if GCC_VERSION>=5004000 -+ int i = 60 - __builtin_clzll(x); -+ y += i*10; -+ x >>= i; -+#else - while( x>255 ){ y += 40; x >>= 4; } /*OPTIMIZATION-IF-TRUE*/ - while( x>15 ){ y += 10; x >>= 1; } -+#endif - } - return a[x&7] + y - 10; - } -@@ -29824,6 +31679,20 @@ - } - return h; - } -+#ifdef SQLITE_ENABLE_NORMALIZE -+static unsigned int strHashN(const char *z, int n){ -+ unsigned int h = 0; -+ int i; -+ for(i=0; i<n; i++){ -+ /* Knuth multiplicative hashing. (Sorting & Searching, p. 510). -+ ** 0x9e3779b1 is 2654435761 which is the closest prime number to -+ ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */ -+ h += sqlite3UpperToLower[z[i]]; -+ h *= 0x9e3779b1; -+ } -+ return h; -+} -+#endif /* SQLITE_ENABLE_NORMALIZE */ - - - /* Link pNew element into the hash table pH. If pEntry!=0 then also -@@ -29935,7 +31804,41 @@ - } - return &nullElement; - } -+#ifdef SQLITE_ENABLE_NORMALIZE -+static HashElem *findElementWithHashN( -+ const Hash *pH, /* The pH to be searched */ -+ const char *pKey, /* The key we are searching for */ -+ int nKey, /* Number of key bytes to use */ -+ unsigned int *pHash /* Write the hash value here */ -+){ -+ HashElem *elem; /* Used to loop thru the element list */ -+ int count; /* Number of elements left to test */ -+ unsigned int h; /* The computed hash */ -+ static HashElem nullElement = { 0, 0, 0, 0 }; - -+ if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/ -+ struct _ht *pEntry; -+ h = strHashN(pKey, nKey) % pH->htsize; -+ pEntry = &pH->ht[h]; -+ elem = pEntry->chain; -+ count = pEntry->count; -+ }else{ -+ h = 0; -+ elem = pH->first; -+ count = pH->count; -+ } -+ if( pHash ) *pHash = h; -+ while( count-- ){ -+ assert( elem!=0 ); -+ if( sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){ -+ return elem; -+ } -+ elem = elem->next; -+ } -+ return &nullElement; -+} -+#endif /* SQLITE_ENABLE_NORMALIZE */ -+ - /* Remove a single entry from the hash table given a pointer to that - ** element and a hash on the element's key. - */ -@@ -29979,6 +31882,14 @@ - assert( pKey!=0 ); - return findElementWithHash(pH, pKey, 0)->data; - } -+#ifdef SQLITE_ENABLE_NORMALIZE -+SQLITE_PRIVATE void *sqlite3HashFindN(const Hash *pH, const char *pKey, int nKey){ -+ assert( pH!=0 ); -+ assert( pKey!=0 ); -+ assert( nKey>=0 ); -+ return findElementWithHashN(pH, pKey, nKey, 0)->data; -+} -+#endif /* SQLITE_ENABLE_NORMALIZE */ - - /* Insert an element into the hash table pH. The key is pKey - ** and the data is "data". -@@ -30046,170 +31957,176 @@ - /* 1 */ "AutoCommit" OpHelp(""), - /* 2 */ "Transaction" OpHelp(""), - /* 3 */ "SorterNext" OpHelp(""), -- /* 4 */ "PrevIfOpen" OpHelp(""), -- /* 5 */ "NextIfOpen" OpHelp(""), -- /* 6 */ "Prev" OpHelp(""), -- /* 7 */ "Next" OpHelp(""), -- /* 8 */ "Checkpoint" OpHelp(""), -- /* 9 */ "JournalMode" OpHelp(""), -- /* 10 */ "Vacuum" OpHelp(""), -- /* 11 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), -- /* 12 */ "VUpdate" OpHelp("data=r[P3@P2]"), -- /* 13 */ "Goto" OpHelp(""), -- /* 14 */ "Gosub" OpHelp(""), -- /* 15 */ "InitCoroutine" OpHelp(""), -- /* 16 */ "Yield" OpHelp(""), -- /* 17 */ "MustBeInt" OpHelp(""), -- /* 18 */ "Jump" OpHelp(""), -+ /* 4 */ "Prev" OpHelp(""), -+ /* 5 */ "Next" OpHelp(""), -+ /* 6 */ "Checkpoint" OpHelp(""), -+ /* 7 */ "JournalMode" OpHelp(""), -+ /* 8 */ "Vacuum" OpHelp(""), -+ /* 9 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), -+ /* 10 */ "VUpdate" OpHelp("data=r[P3@P2]"), -+ /* 11 */ "Goto" OpHelp(""), -+ /* 12 */ "Gosub" OpHelp(""), -+ /* 13 */ "InitCoroutine" OpHelp(""), -+ /* 14 */ "Yield" OpHelp(""), -+ /* 15 */ "MustBeInt" OpHelp(""), -+ /* 16 */ "Jump" OpHelp(""), -+ /* 17 */ "Once" OpHelp(""), -+ /* 18 */ "If" OpHelp(""), - /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), -- /* 20 */ "Once" OpHelp(""), -- /* 21 */ "If" OpHelp(""), -- /* 22 */ "IfNot" OpHelp(""), -- /* 23 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), -- /* 24 */ "SeekLT" OpHelp("key=r[P3@P4]"), -- /* 25 */ "SeekLE" OpHelp("key=r[P3@P4]"), -- /* 26 */ "SeekGE" OpHelp("key=r[P3@P4]"), -- /* 27 */ "SeekGT" OpHelp("key=r[P3@P4]"), -- /* 28 */ "NoConflict" OpHelp("key=r[P3@P4]"), -- /* 29 */ "NotFound" OpHelp("key=r[P3@P4]"), -- /* 30 */ "Found" OpHelp("key=r[P3@P4]"), -- /* 31 */ "SeekRowid" OpHelp("intkey=r[P3]"), -- /* 32 */ "NotExists" OpHelp("intkey=r[P3]"), -- /* 33 */ "Last" OpHelp(""), -- /* 34 */ "IfSmaller" OpHelp(""), -- /* 35 */ "SorterSort" OpHelp(""), -- /* 36 */ "Sort" OpHelp(""), -- /* 37 */ "Rewind" OpHelp(""), -- /* 38 */ "IdxLE" OpHelp("key=r[P3@P4]"), -- /* 39 */ "IdxGT" OpHelp("key=r[P3@P4]"), -- /* 40 */ "IdxLT" OpHelp("key=r[P3@P4]"), -- /* 41 */ "IdxGE" OpHelp("key=r[P3@P4]"), -- /* 42 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), -- /* 43 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), -- /* 44 */ "Program" OpHelp(""), -- /* 45 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), -- /* 46 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), -- /* 47 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), -- /* 48 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), -- /* 49 */ "IncrVacuum" OpHelp(""), -- /* 50 */ "VNext" OpHelp(""), -- /* 51 */ "Init" OpHelp("Start at P2"), -- /* 52 */ "Return" OpHelp(""), -- /* 53 */ "EndCoroutine" OpHelp(""), -- /* 54 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), -- /* 55 */ "Halt" OpHelp(""), -- /* 56 */ "Integer" OpHelp("r[P2]=P1"), -- /* 57 */ "Int64" OpHelp("r[P2]=P4"), -- /* 58 */ "String" OpHelp("r[P2]='P4' (len=P1)"), -- /* 59 */ "Null" OpHelp("r[P2..P3]=NULL"), -- /* 60 */ "SoftNull" OpHelp("r[P1]=NULL"), -- /* 61 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), -- /* 62 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), -- /* 63 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), -- /* 64 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), -- /* 65 */ "SCopy" OpHelp("r[P2]=r[P1]"), -- /* 66 */ "IntCopy" OpHelp("r[P2]=r[P1]"), -- /* 67 */ "ResultRow" OpHelp("output=r[P1@P2]"), -- /* 68 */ "CollSeq" OpHelp(""), -- /* 69 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), -- /* 70 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), -- /* 71 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), -- /* 72 */ "RealAffinity" OpHelp(""), -- /* 73 */ "Cast" OpHelp("affinity(r[P1])"), -- /* 74 */ "Permutation" OpHelp(""), -- /* 75 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), -- /* 76 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), -- /* 77 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), -- /* 78 */ "Eq" OpHelp("IF r[P3]==r[P1]"), -- /* 79 */ "Gt" OpHelp("IF r[P3]>r[P1]"), -- /* 80 */ "Le" OpHelp("IF r[P3]<=r[P1]"), -- /* 81 */ "Lt" OpHelp("IF r[P3]<r[P1]"), -- /* 82 */ "Ge" OpHelp("IF r[P3]>=r[P1]"), -- /* 83 */ "ElseNotEq" OpHelp(""), -- /* 84 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), -- /* 85 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), -- /* 86 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), -- /* 87 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), -- /* 88 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), -- /* 89 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), -- /* 90 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), -- /* 91 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), -- /* 92 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), -- /* 93 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), -- /* 94 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), -- /* 95 */ "BitNot" OpHelp("r[P1]= ~r[P1]"), -- /* 96 */ "Column" OpHelp("r[P3]=PX"), -- /* 97 */ "String8" OpHelp("r[P2]='P4'"), -- /* 98 */ "Affinity" OpHelp("affinity(r[P1@P2])"), -- /* 99 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), -- /* 100 */ "Count" OpHelp("r[P2]=count()"), -- /* 101 */ "ReadCookie" OpHelp(""), -- /* 102 */ "SetCookie" OpHelp(""), -- /* 103 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), -- /* 104 */ "OpenRead" OpHelp("root=P2 iDb=P3"), -- /* 105 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), -- /* 106 */ "OpenDup" OpHelp(""), -- /* 107 */ "OpenAutoindex" OpHelp("nColumn=P2"), -- /* 108 */ "OpenEphemeral" OpHelp("nColumn=P2"), -- /* 109 */ "SorterOpen" OpHelp(""), -- /* 110 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), -- /* 111 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), -- /* 112 */ "Close" OpHelp(""), -- /* 113 */ "ColumnsUsed" OpHelp(""), -- /* 114 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), -- /* 115 */ "NewRowid" OpHelp("r[P2]=rowid"), -- /* 116 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), -- /* 117 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), -- /* 118 */ "Delete" OpHelp(""), -- /* 119 */ "ResetCount" OpHelp(""), -- /* 120 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), -- /* 121 */ "SorterData" OpHelp("r[P2]=data"), -- /* 122 */ "RowData" OpHelp("r[P2]=data"), -- /* 123 */ "Rowid" OpHelp("r[P2]=rowid"), -- /* 124 */ "NullRow" OpHelp(""), -- /* 125 */ "SorterInsert" OpHelp("key=r[P2]"), -- /* 126 */ "IdxInsert" OpHelp("key=r[P2]"), -- /* 127 */ "IdxDelete" OpHelp("key=r[P2@P3]"), -- /* 128 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), -- /* 129 */ "IdxRowid" OpHelp("r[P2]=rowid"), -- /* 130 */ "Destroy" OpHelp(""), -- /* 131 */ "Clear" OpHelp(""), -- /* 132 */ "Real" OpHelp("r[P2]=P4"), -- /* 133 */ "ResetSorter" OpHelp(""), -- /* 134 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), -- /* 135 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), -- /* 136 */ "SqlExec" OpHelp(""), -- /* 137 */ "ParseSchema" OpHelp(""), -- /* 138 */ "LoadAnalysis" OpHelp(""), -- /* 139 */ "DropTable" OpHelp(""), -- /* 140 */ "DropIndex" OpHelp(""), -- /* 141 */ "DropTrigger" OpHelp(""), -- /* 142 */ "IntegrityCk" OpHelp(""), -- /* 143 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), -- /* 144 */ "Param" OpHelp(""), -- /* 145 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), -- /* 146 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), -- /* 147 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), -- /* 148 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"), -- /* 149 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), -- /* 150 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), -- /* 151 */ "Expire" OpHelp(""), -- /* 152 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), -- /* 153 */ "VBegin" OpHelp(""), -- /* 154 */ "VCreate" OpHelp(""), -- /* 155 */ "VDestroy" OpHelp(""), -- /* 156 */ "VOpen" OpHelp(""), -- /* 157 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), -- /* 158 */ "VRename" OpHelp(""), -- /* 159 */ "Pagecount" OpHelp(""), -- /* 160 */ "MaxPgcnt" OpHelp(""), -- /* 161 */ "PureFunc0" OpHelp(""), -- /* 162 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"), -- /* 163 */ "PureFunc" OpHelp(""), -- /* 164 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"), -- /* 165 */ "CursorHint" OpHelp(""), -- /* 166 */ "Noop" OpHelp(""), -- /* 167 */ "Explain" OpHelp(""), -+ /* 20 */ "IfNot" OpHelp(""), -+ /* 21 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), -+ /* 22 */ "SeekLT" OpHelp("key=r[P3@P4]"), -+ /* 23 */ "SeekLE" OpHelp("key=r[P3@P4]"), -+ /* 24 */ "SeekGE" OpHelp("key=r[P3@P4]"), -+ /* 25 */ "SeekGT" OpHelp("key=r[P3@P4]"), -+ /* 26 */ "IfNoHope" OpHelp("key=r[P3@P4]"), -+ /* 27 */ "NoConflict" OpHelp("key=r[P3@P4]"), -+ /* 28 */ "NotFound" OpHelp("key=r[P3@P4]"), -+ /* 29 */ "Found" OpHelp("key=r[P3@P4]"), -+ /* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"), -+ /* 31 */ "NotExists" OpHelp("intkey=r[P3]"), -+ /* 32 */ "Last" OpHelp(""), -+ /* 33 */ "IfSmaller" OpHelp(""), -+ /* 34 */ "SorterSort" OpHelp(""), -+ /* 35 */ "Sort" OpHelp(""), -+ /* 36 */ "Rewind" OpHelp(""), -+ /* 37 */ "IdxLE" OpHelp("key=r[P3@P4]"), -+ /* 38 */ "IdxGT" OpHelp("key=r[P3@P4]"), -+ /* 39 */ "IdxLT" OpHelp("key=r[P3@P4]"), -+ /* 40 */ "IdxGE" OpHelp("key=r[P3@P4]"), -+ /* 41 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), -+ /* 42 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), -+ /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), -+ /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), -+ /* 45 */ "Program" OpHelp(""), -+ /* 46 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), -+ /* 47 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), -+ /* 48 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), -+ /* 49 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), -+ /* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), -+ /* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), -+ /* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), -+ /* 53 */ "Eq" OpHelp("IF r[P3]==r[P1]"), -+ /* 54 */ "Gt" OpHelp("IF r[P3]>r[P1]"), -+ /* 55 */ "Le" OpHelp("IF r[P3]<=r[P1]"), -+ /* 56 */ "Lt" OpHelp("IF r[P3]<r[P1]"), -+ /* 57 */ "Ge" OpHelp("IF r[P3]>=r[P1]"), -+ /* 58 */ "ElseNotEq" OpHelp(""), -+ /* 59 */ "IncrVacuum" OpHelp(""), -+ /* 60 */ "VNext" OpHelp(""), -+ /* 61 */ "Init" OpHelp("Start at P2"), -+ /* 62 */ "PureFunc0" OpHelp(""), -+ /* 63 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"), -+ /* 64 */ "PureFunc" OpHelp(""), -+ /* 65 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"), -+ /* 66 */ "Return" OpHelp(""), -+ /* 67 */ "EndCoroutine" OpHelp(""), -+ /* 68 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), -+ /* 69 */ "Halt" OpHelp(""), -+ /* 70 */ "Integer" OpHelp("r[P2]=P1"), -+ /* 71 */ "Int64" OpHelp("r[P2]=P4"), -+ /* 72 */ "String" OpHelp("r[P2]='P4' (len=P1)"), -+ /* 73 */ "Null" OpHelp("r[P2..P3]=NULL"), -+ /* 74 */ "SoftNull" OpHelp("r[P1]=NULL"), -+ /* 75 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), -+ /* 76 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), -+ /* 77 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), -+ /* 78 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), -+ /* 79 */ "SCopy" OpHelp("r[P2]=r[P1]"), -+ /* 80 */ "IntCopy" OpHelp("r[P2]=r[P1]"), -+ /* 81 */ "ResultRow" OpHelp("output=r[P1@P2]"), -+ /* 82 */ "CollSeq" OpHelp(""), -+ /* 83 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), -+ /* 84 */ "RealAffinity" OpHelp(""), -+ /* 85 */ "Cast" OpHelp("affinity(r[P1])"), -+ /* 86 */ "Permutation" OpHelp(""), -+ /* 87 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), -+ /* 88 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), -+ /* 89 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), -+ /* 90 */ "Column" OpHelp("r[P3]=PX"), -+ /* 91 */ "Affinity" OpHelp("affinity(r[P1@P2])"), -+ /* 92 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), -+ /* 93 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), -+ /* 94 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), -+ /* 95 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), -+ /* 96 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), -+ /* 97 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), -+ /* 98 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), -+ /* 99 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), -+ /* 100 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), -+ /* 101 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), -+ /* 102 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), -+ /* 103 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), -+ /* 104 */ "Count" OpHelp("r[P2]=count()"), -+ /* 105 */ "ReadCookie" OpHelp(""), -+ /* 106 */ "String8" OpHelp("r[P2]='P4'"), -+ /* 107 */ "SetCookie" OpHelp(""), -+ /* 108 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), -+ /* 109 */ "OpenRead" OpHelp("root=P2 iDb=P3"), -+ /* 110 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), -+ /* 111 */ "OpenDup" OpHelp(""), -+ /* 112 */ "OpenAutoindex" OpHelp("nColumn=P2"), -+ /* 113 */ "OpenEphemeral" OpHelp("nColumn=P2"), -+ /* 114 */ "SorterOpen" OpHelp(""), -+ /* 115 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), -+ /* 116 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), -+ /* 117 */ "Close" OpHelp(""), -+ /* 118 */ "ColumnsUsed" OpHelp(""), -+ /* 119 */ "SeekHit" OpHelp("seekHit=P2"), -+ /* 120 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), -+ /* 121 */ "NewRowid" OpHelp("r[P2]=rowid"), -+ /* 122 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), -+ /* 123 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), -+ /* 124 */ "Delete" OpHelp(""), -+ /* 125 */ "ResetCount" OpHelp(""), -+ /* 126 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), -+ /* 127 */ "SorterData" OpHelp("r[P2]=data"), -+ /* 128 */ "RowData" OpHelp("r[P2]=data"), -+ /* 129 */ "Rowid" OpHelp("r[P2]=rowid"), -+ /* 130 */ "NullRow" OpHelp(""), -+ /* 131 */ "SeekEnd" OpHelp(""), -+ /* 132 */ "SorterInsert" OpHelp("key=r[P2]"), -+ /* 133 */ "IdxInsert" OpHelp("key=r[P2]"), -+ /* 134 */ "IdxDelete" OpHelp("key=r[P2@P3]"), -+ /* 135 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), -+ /* 136 */ "IdxRowid" OpHelp("r[P2]=rowid"), -+ /* 137 */ "Destroy" OpHelp(""), -+ /* 138 */ "Clear" OpHelp(""), -+ /* 139 */ "ResetSorter" OpHelp(""), -+ /* 140 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), -+ /* 141 */ "Real" OpHelp("r[P2]=P4"), -+ /* 142 */ "SqlExec" OpHelp(""), -+ /* 143 */ "ParseSchema" OpHelp(""), -+ /* 144 */ "LoadAnalysis" OpHelp(""), -+ /* 145 */ "DropTable" OpHelp(""), -+ /* 146 */ "DropIndex" OpHelp(""), -+ /* 147 */ "DropTrigger" OpHelp(""), -+ /* 148 */ "IntegrityCk" OpHelp(""), -+ /* 149 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), -+ /* 150 */ "Param" OpHelp(""), -+ /* 151 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), -+ /* 152 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), -+ /* 153 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), -+ /* 154 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), -+ /* 155 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), -+ /* 156 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), -+ /* 157 */ "AggValue" OpHelp("r[P3]=value N=P2"), -+ /* 158 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), -+ /* 159 */ "Expire" OpHelp(""), -+ /* 160 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), -+ /* 161 */ "VBegin" OpHelp(""), -+ /* 162 */ "VCreate" OpHelp(""), -+ /* 163 */ "VDestroy" OpHelp(""), -+ /* 164 */ "VOpen" OpHelp(""), -+ /* 165 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), -+ /* 166 */ "VRename" OpHelp(""), -+ /* 167 */ "Pagecount" OpHelp(""), -+ /* 168 */ "MaxPgcnt" OpHelp(""), -+ /* 169 */ "Trace" OpHelp(""), -+ /* 170 */ "CursorHint" OpHelp(""), -+ /* 171 */ "Noop" OpHelp(""), -+ /* 172 */ "Explain" OpHelp(""), -+ /* 173 */ "Abortable" OpHelp(""), - }; - return azName[i]; - } -@@ -30309,6 +32226,7 @@ - #include <sys/types.h> - #include <sys/stat.h> - #include <fcntl.h> -+#include <sys/ioctl.h> - #include <unistd.h> - /* #include <time.h> */ - #include <sys/time.h> -@@ -30318,7 +32236,7 @@ - #endif - - #if SQLITE_ENABLE_LOCKING_STYLE --# include <sys/ioctl.h> -+/* # include <sys/ioctl.h> */ - # include <sys/file.h> - # include <sys/param.h> - #endif /* SQLITE_ENABLE_LOCKING_STYLE */ -@@ -30354,12 +32272,10 @@ - #define SQLITE_FSFLAGS_IS_MSDOS 0x1 - - /* --** If we are to be thread-safe, include the pthreads header and define --** the SQLITE_UNIX_THREADS macro. -+** If we are to be thread-safe, include the pthreads header. - */ - #if SQLITE_THREADSAFE - /* # include <pthread.h> */ --# define SQLITE_UNIX_THREADS 1 - #endif - - /* -@@ -30428,7 +32344,7 @@ - unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ - int lastErrno; /* The unix errno from last I/O error */ - void *lockingContext; /* Locking style specific state */ -- UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ -+ UnixUnusedFd *pPreallocatedUnused; /* Pre-allocated UnixUnusedFd */ - const char *zPath; /* Name of the file */ - unixShm *pShm; /* Shared memory segment information */ - int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ -@@ -30439,10 +32355,8 @@ - sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ - void *pMapRegion; /* Memory mapped region */ - #endif --#ifdef __QNXNTO__ - int sectorSize; /* Device sector size */ - int deviceCharacteristics; /* Precomputed device characteristics */ --#endif - #if SQLITE_ENABLE_LOCKING_STYLE - int openFlags; /* The flags specified at open() */ - #endif -@@ -30449,6 +32363,9 @@ - #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) - unsigned fsFlags; /* cached details from statfs() */ - #endif -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ unsigned iBusyTimeout; /* Wait this many millisec on locks */ -+#endif - #if OS_VXWORKS - struct vxworksFileId *pId; /* Unique file ID */ - #endif -@@ -30745,7 +32662,21 @@ - # define lseek lseek64 - #endif - -+#ifdef __linux__ - /* -+** Linux-specific IOCTL magic numbers used for controlling F2FS -+*/ -+#define F2FS_IOCTL_MAGIC 0xf5 -+#define F2FS_IOC_START_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 1) -+#define F2FS_IOC_COMMIT_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 2) -+#define F2FS_IOC_START_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 3) -+#define F2FS_IOC_ABORT_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 5) -+#define F2FS_IOC_GET_FEATURES _IOR(F2FS_IOCTL_MAGIC, 12, u32) -+#define F2FS_FEATURE_ATOMIC_WRITE 0x0004 -+#endif /* __linux__ */ -+ -+ -+/* - ** Different Unix systems declare open() in different ways. Same use - ** open(const char*,int,mode_t). Others use open(const char*,int,...). - ** The difference is important when using a pointer to the function. -@@ -30872,7 +32803,11 @@ - #endif - #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) - -+#if defined(HAVE_FCHOWN) - { "geteuid", (sqlite3_syscall_ptr)geteuid, 0 }, -+#else -+ { "geteuid", (sqlite3_syscall_ptr)0, 0 }, -+#endif - #define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent) - - #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 -@@ -30887,7 +32822,7 @@ - #else - { "munmap", (sqlite3_syscall_ptr)0, 0 }, - #endif --#define osMunmap ((void*(*)(void*,size_t))aSyscall[23].pCurrent) -+#define osMunmap ((int(*)(void*,size_t))aSyscall[23].pCurrent) - - #if HAVE_MREMAP && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) - { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, -@@ -30917,6 +32852,17 @@ - #endif - #define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent) - -+#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) -+# ifdef __ANDROID__ -+ { "ioctl", (sqlite3_syscall_ptr)(int(*)(int, int, ...))ioctl, 0 }, -+# else -+ { "ioctl", (sqlite3_syscall_ptr)ioctl, 0 }, -+# endif -+#else -+ { "ioctl", (sqlite3_syscall_ptr)0, 0 }, -+#endif -+#define osIoctl ((int(*)(int,int,...))aSyscall[28].pCurrent) -+ - }; /* End of the overrideable system calls */ - - -@@ -31092,16 +33038,30 @@ - ** unixEnterMutex() - ** assert( unixMutexHeld() ); - ** unixEnterLeave() -+** -+** To prevent deadlock, the global unixBigLock must must be acquired -+** before the unixInodeInfo.pLockMutex mutex, if both are held. It is -+** OK to get the pLockMutex without holding unixBigLock first, but if -+** that happens, the unixBigLock mutex must not be acquired until after -+** pLockMutex is released. -+** -+** OK: enter(unixBigLock), enter(pLockInfo) -+** OK: enter(unixBigLock) -+** OK: enter(pLockInfo) -+** ERROR: enter(pLockInfo), enter(unixBigLock) - */ -+static sqlite3_mutex *unixBigLock = 0; - static void unixEnterMutex(void){ -- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); -+ assert( sqlite3_mutex_notheld(unixBigLock) ); /* Not a recursive mutex */ -+ sqlite3_mutex_enter(unixBigLock); - } - static void unixLeaveMutex(void){ -- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); -+ assert( sqlite3_mutex_held(unixBigLock) ); -+ sqlite3_mutex_leave(unixBigLock); - } - #ifdef SQLITE_DEBUG - static int unixMutexHeld(void) { -- return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); -+ return sqlite3_mutex_held(unixBigLock); - } - #endif - -@@ -31491,22 +33451,39 @@ - - /* - ** An instance of the following structure is allocated for each open --** inode. Or, on LinuxThreads, there is one of these structures for --** each inode opened by each thread. -+** inode. - ** - ** A single inode can have multiple file descriptors, so each unixFile - ** structure contains a pointer to an instance of this object and this - ** object keeps a count of the number of unixFile pointing to it. -+** -+** Mutex rules: -+** -+** (1) Only the pLockMutex mutex must be held in order to read or write -+** any of the locking fields: -+** nShared, nLock, eFileLock, bProcessLock, pUnused -+** -+** (2) When nRef>0, then the following fields are unchanging and can -+** be read (but not written) without holding any mutex: -+** fileId, pLockMutex -+** -+** (3) With the exceptions above, all the fields may only be read -+** or written while holding the global unixBigLock mutex. -+** -+** Deadlock prevention: The global unixBigLock mutex may not -+** be acquired while holding the pLockMutex mutex. If both unixBigLock -+** and pLockMutex are needed, then unixBigLock must be acquired first. - */ - struct unixInodeInfo { - struct unixFileId fileId; /* The lookup key */ -- int nShared; /* Number of SHARED locks held */ -- unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ -- unsigned char bProcessLock; /* An exclusive process lock is held */ -+ sqlite3_mutex *pLockMutex; /* Hold this mutex for... */ -+ int nShared; /* Number of SHARED locks held */ -+ int nLock; /* Number of outstanding file locks */ -+ unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ -+ unsigned char bProcessLock; /* An exclusive process lock is held */ -+ UnixUnusedFd *pUnused; /* Unused file descriptors to close */ - int nRef; /* Number of pointers to this structure */ - unixShmNode *pShmNode; /* Shared memory associated with this inode */ -- int nLock; /* Number of outstanding file locks */ -- UnixUnusedFd *pUnused; /* Unused file descriptors to close */ - unixInodeInfo *pNext; /* List of all unixInodeInfo objects */ - unixInodeInfo *pPrev; /* .... doubly linked */ - #if SQLITE_ENABLE_LOCKING_STYLE -@@ -31520,10 +33497,28 @@ - - /* - ** A lists of all unixInodeInfo objects. -+** -+** Must hold unixBigLock in order to read or write this variable. - */ --static unixInodeInfo *inodeList = 0; -+static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */ - -+#ifdef SQLITE_DEBUG - /* -+** True if the inode mutex (on the unixFile.pFileMutex field) is held, or not. -+** This routine is used only within assert() to help verify correct mutex -+** usage. -+*/ -+int unixFileMutexHeld(unixFile *pFile){ -+ assert( pFile->pInode ); -+ return sqlite3_mutex_held(pFile->pInode->pLockMutex); -+} -+int unixFileMutexNotheld(unixFile *pFile){ -+ assert( pFile->pInode ); -+ return sqlite3_mutex_notheld(pFile->pInode->pLockMutex); -+} -+#endif -+ -+/* - ** - ** This function - unixLogErrorAtLine(), is only ever called via the macro - ** unixLogError(). -@@ -31627,6 +33622,7 @@ - unixInodeInfo *pInode = pFile->pInode; - UnixUnusedFd *p; - UnixUnusedFd *pNext; -+ assert( unixFileMutexHeld(pFile) ); - for(p=pInode->pUnused; p; p=pNext){ - pNext = p->pNext; - robust_close(pFile, p->fd, __LINE__); -@@ -31638,17 +33634,20 @@ - /* - ** Release a unixInodeInfo structure previously allocated by findInodeInfo(). - ** --** The mutex entered using the unixEnterMutex() function must be held --** when this function is called. -+** The global mutex must be held when this routine is called, but the mutex -+** on the inode being deleted must NOT be held. - */ - static void releaseInodeInfo(unixFile *pFile){ - unixInodeInfo *pInode = pFile->pInode; - assert( unixMutexHeld() ); -+ assert( unixFileMutexNotheld(pFile) ); - if( ALWAYS(pInode) ){ - pInode->nRef--; - if( pInode->nRef==0 ){ - assert( pInode->pShmNode==0 ); -+ sqlite3_mutex_enter(pInode->pLockMutex); - closePendingFds(pFile); -+ sqlite3_mutex_leave(pInode->pLockMutex); - if( pInode->pPrev ){ - assert( pInode->pPrev->pNext==pInode ); - pInode->pPrev->pNext = pInode->pNext; -@@ -31660,6 +33659,7 @@ - assert( pInode->pNext->pPrev==pInode ); - pInode->pNext->pPrev = pInode->pPrev; - } -+ sqlite3_mutex_free(pInode->pLockMutex); - sqlite3_free(pInode); - } - } -@@ -31670,8 +33670,7 @@ - ** describes that file descriptor. Create a new one if necessary. The - ** return value might be uninitialized if an error occurs. - ** --** The mutex entered using the unixEnterMutex() function must be held --** when this function is called. -+** The global mutex must held when calling this routine. - ** - ** Return an appropriate error code. - */ -@@ -31732,6 +33731,7 @@ - #else - fileId.ino = (u64)statbuf.st_ino; - #endif -+ assert( unixMutexHeld() ); - pInode = inodeList; - while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){ - pInode = pInode->pNext; -@@ -31743,7 +33743,15 @@ - } - memset(pInode, 0, sizeof(*pInode)); - memcpy(&pInode->fileId, &fileId, sizeof(fileId)); -+ if( sqlite3GlobalConfig.bCoreMutex ){ -+ pInode->pLockMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); -+ if( pInode->pLockMutex==0 ){ -+ sqlite3_free(pInode); -+ return SQLITE_NOMEM_BKPT; -+ } -+ } - pInode->nRef = 1; -+ assert( unixMutexHeld() ); - pInode->pNext = inodeList; - pInode->pPrev = 0; - if( inodeList ) inodeList->pPrev = pInode; -@@ -31821,7 +33829,7 @@ - - assert( pFile ); - assert( pFile->eFileLock<=SHARED_LOCK ); -- unixEnterMutex(); /* Because pFile->pInode is shared across threads */ -+ sqlite3_mutex_enter(pFile->pInode->pLockMutex); - - /* Check if a thread in this process holds such a lock */ - if( pFile->pInode->eFileLock>SHARED_LOCK ){ -@@ -31846,7 +33854,7 @@ - } - #endif - -- unixLeaveMutex(); -+ sqlite3_mutex_leave(pFile->pInode->pLockMutex); - OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved)); - - *pResOut = reserved; -@@ -31854,6 +33862,43 @@ - } - - /* -+** Set a posix-advisory-lock. -+** -+** There are two versions of this routine. If compiled with -+** SQLITE_ENABLE_SETLK_TIMEOUT then the routine has an extra parameter -+** which is a pointer to a unixFile. If the unixFile->iBusyTimeout -+** value is set, then it is the number of milliseconds to wait before -+** failing the lock. The iBusyTimeout value is always reset back to -+** zero on each call. -+** -+** If SQLITE_ENABLE_SETLK_TIMEOUT is not defined, then do a non-blocking -+** attempt to set the lock. -+*/ -+#ifndef SQLITE_ENABLE_SETLK_TIMEOUT -+# define osSetPosixAdvisoryLock(h,x,t) osFcntl(h,F_SETLK,x) -+#else -+static int osSetPosixAdvisoryLock( -+ int h, /* The file descriptor on which to take the lock */ -+ struct flock *pLock, /* The description of the lock */ -+ unixFile *pFile /* Structure holding timeout value */ -+){ -+ int rc = osFcntl(h,F_SETLK,pLock); -+ while( rc<0 && pFile->iBusyTimeout>0 ){ -+ /* On systems that support some kind of blocking file lock with a timeout, -+ ** make appropriate changes here to invoke that blocking file lock. On -+ ** generic posix, however, there is no such API. So we simply try the -+ ** lock once every millisecond until either the timeout expires, or until -+ ** the lock is obtained. */ -+ usleep(1000); -+ rc = osFcntl(h,F_SETLK,pLock); -+ pFile->iBusyTimeout--; -+ } -+ return rc; -+} -+#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */ -+ -+ -+/* - ** Attempt to set a system-lock on the file pFile. The lock is - ** described by pLock. - ** -@@ -31875,8 +33920,8 @@ - static int unixFileLock(unixFile *pFile, struct flock *pLock){ - int rc; - unixInodeInfo *pInode = pFile->pInode; -- assert( unixMutexHeld() ); - assert( pInode!=0 ); -+ assert( sqlite3_mutex_held(pInode->pLockMutex) ); - if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){ - if( pInode->bProcessLock==0 ){ - struct flock lock; -@@ -31885,7 +33930,7 @@ - lock.l_start = SHARED_FIRST; - lock.l_len = SHARED_SIZE; - lock.l_type = F_WRLCK; -- rc = osFcntl(pFile->h, F_SETLK, &lock); -+ rc = osSetPosixAdvisoryLock(pFile->h, &lock, pFile); - if( rc<0 ) return rc; - pInode->bProcessLock = 1; - pInode->nLock++; -@@ -31893,7 +33938,7 @@ - rc = 0; - } - }else{ -- rc = osFcntl(pFile->h, F_SETLK, pLock); -+ rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile); - } - return rc; - } -@@ -31995,8 +34040,8 @@ - - /* This mutex is needed because pFile->pInode is shared across threads - */ -- unixEnterMutex(); - pInode = pFile->pInode; -+ sqlite3_mutex_enter(pInode->pLockMutex); - - /* If some thread using this PID has a lock via a different unixFile* - ** handle that precludes the requested lock, return BUSY. -@@ -32139,7 +34184,7 @@ - } - - end_lock: -- unixLeaveMutex(); -+ sqlite3_mutex_leave(pInode->pLockMutex); - OSTRACE(("LOCK %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), - rc==SQLITE_OK ? "ok" : "failed")); - return rc; -@@ -32151,11 +34196,12 @@ - */ - static void setPendingFd(unixFile *pFile){ - unixInodeInfo *pInode = pFile->pInode; -- UnixUnusedFd *p = pFile->pUnused; -+ UnixUnusedFd *p = pFile->pPreallocatedUnused; -+ assert( unixFileMutexHeld(pFile) ); - p->pNext = pInode->pUnused; - pInode->pUnused = p; - pFile->h = -1; -- pFile->pUnused = 0; -+ pFile->pPreallocatedUnused = 0; - } - - /* -@@ -32186,8 +34232,8 @@ - if( pFile->eFileLock<=eFileLock ){ - return SQLITE_OK; - } -- unixEnterMutex(); - pInode = pFile->pInode; -+ sqlite3_mutex_enter(pInode->pLockMutex); - assert( pInode->nShared!=0 ); - if( pFile->eFileLock>SHARED_LOCK ){ - assert( pInode->eFileLock==pFile->eFileLock ); -@@ -32313,14 +34359,14 @@ - */ - pInode->nLock--; - assert( pInode->nLock>=0 ); -- if( pInode->nLock==0 ){ -- closePendingFds(pFile); -- } -+ if( pInode->nLock==0 ) closePendingFds(pFile); - } - - end_unlock: -- unixLeaveMutex(); -- if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock; -+ sqlite3_mutex_leave(pInode->pLockMutex); -+ if( rc==SQLITE_OK ){ -+ pFile->eFileLock = eFileLock; -+ } - return rc; - } - -@@ -32380,7 +34426,7 @@ - #endif - OSTRACE(("CLOSE %-3d\n", pFile->h)); - OpenCounter(-1); -- sqlite3_free(pFile->pUnused); -+ sqlite3_free(pFile->pPreallocatedUnused); - memset(pFile, 0, sizeof(unixFile)); - return SQLITE_OK; - } -@@ -32391,8 +34437,12 @@ - static int unixClose(sqlite3_file *id){ - int rc = SQLITE_OK; - unixFile *pFile = (unixFile *)id; -+ unixInodeInfo *pInode = pFile->pInode; -+ -+ assert( pInode!=0 ); - verifyDbFile(pFile); - unixUnlock(id, NO_LOCK); -+ assert( unixFileMutexNotheld(pFile) ); - unixEnterMutex(); - - /* unixFile.pInode is always valid here. Otherwise, a different close -@@ -32399,7 +34449,8 @@ - ** routine (e.g. nolockClose()) would be called instead. - */ - assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 ); -- if( ALWAYS(pFile->pInode) && pFile->pInode->nLock ){ -+ sqlite3_mutex_enter(pInode->pLockMutex); -+ if( pInode->nLock ){ - /* If there are outstanding locks, do not actually close the file just - ** yet because that would clear those locks. Instead, add the file - ** descriptor to pInode->pUnused list. It will be automatically closed -@@ -32407,6 +34458,7 @@ - */ - setPendingFd(pFile); - } -+ sqlite3_mutex_leave(pInode->pLockMutex); - releaseInodeInfo(pFile); - rc = closeUnixFile(id); - unixLeaveMutex(); -@@ -32717,7 +34769,7 @@ - OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved)); - - #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS -- if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ -+ if( (rc & 0xff) == SQLITE_IOERR ){ - rc = SQLITE_OK; - reserved=1; - } -@@ -32784,7 +34836,7 @@ - OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), - rc==SQLITE_OK ? "ok" : "failed")); - #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS -- if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ -+ if( (rc & 0xff) == SQLITE_IOERR ){ - rc = SQLITE_BUSY; - } - #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ -@@ -33004,6 +35056,7 @@ - unixFile *pFile = (unixFile*)id; - semXUnlock(id, NO_LOCK); - assert( pFile ); -+ assert( unixFileMutexNotheld(pFile) ); - unixEnterMutex(); - releaseInodeInfo(pFile); - unixLeaveMutex(); -@@ -33118,8 +35171,7 @@ - *pResOut = 1; - return SQLITE_OK; - } -- unixEnterMutex(); /* Because pFile->pInode is shared across threads */ -- -+ sqlite3_mutex_enter(pFile->pInode->pLockMutex); - /* Check if a thread in this process holds such a lock */ - if( pFile->pInode->eFileLock>SHARED_LOCK ){ - reserved = 1; -@@ -33143,7 +35195,7 @@ - } - } - -- unixLeaveMutex(); -+ sqlite3_mutex_leave(pFile->pInode->pLockMutex); - OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved)); - - *pResOut = reserved; -@@ -33206,8 +35258,8 @@ - - /* This mutex is needed because pFile->pInode is shared across threads - */ -- unixEnterMutex(); - pInode = pFile->pInode; -+ sqlite3_mutex_enter(pInode->pLockMutex); - - /* If some thread using this PID has a lock via a different unixFile* - ** handle that precludes the requested lock, return BUSY. -@@ -33321,7 +35373,7 @@ - /* Can't reestablish the shared lock. Sqlite can't deal, this is - ** a critical I/O error - */ -- rc = ((failed & SQLITE_IOERR) == SQLITE_IOERR) ? failed2 : -+ rc = ((failed & 0xff) == SQLITE_IOERR) ? failed2 : - SQLITE_IOERR_LOCK; - goto afp_end_lock; - } -@@ -33343,7 +35395,7 @@ - } - - afp_end_lock: -- unixLeaveMutex(); -+ sqlite3_mutex_leave(pInode->pLockMutex); - OSTRACE(("LOCK %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock), - rc==SQLITE_OK ? "ok" : "failed")); - return rc; -@@ -33375,8 +35427,8 @@ - if( pFile->eFileLock<=eFileLock ){ - return SQLITE_OK; - } -- unixEnterMutex(); - pInode = pFile->pInode; -+ sqlite3_mutex_enter(pInode->pLockMutex); - assert( pInode->nShared!=0 ); - if( pFile->eFileLock>SHARED_LOCK ){ - assert( pInode->eFileLock==pFile->eFileLock ); -@@ -33445,14 +35497,14 @@ - if( rc==SQLITE_OK ){ - pInode->nLock--; - assert( pInode->nLock>=0 ); -- if( pInode->nLock==0 ){ -- closePendingFds(pFile); -- } -+ if( pInode->nLock==0 ) closePendingFds(pFile); - } - } - -- unixLeaveMutex(); -- if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock; -+ sqlite3_mutex_leave(pInode->pLockMutex); -+ if( rc==SQLITE_OK ){ -+ pFile->eFileLock = eFileLock; -+ } - return rc; - } - -@@ -33464,14 +35516,20 @@ - unixFile *pFile = (unixFile*)id; - assert( id!=0 ); - afpUnlock(id, NO_LOCK); -+ assert( unixFileMutexNotheld(pFile) ); - unixEnterMutex(); -- if( pFile->pInode && pFile->pInode->nLock ){ -- /* If there are outstanding locks, do not actually close the file just -- ** yet because that would clear those locks. Instead, add the file -- ** descriptor to pInode->aPending. It will be automatically closed when -- ** the last lock is cleared. -- */ -- setPendingFd(pFile); -+ if( pFile->pInode ){ -+ unixInodeInfo *pInode = pFile->pInode; -+ sqlite3_mutex_enter(pInode->pLockMutex); -+ if( pInode->nLock ){ -+ /* If there are outstanding locks, do not actually close the file just -+ ** yet because that would clear those locks. Instead, add the file -+ ** descriptor to pInode->aPending. It will be automatically closed when -+ ** the last lock is cleared. -+ */ -+ setPendingFd(pFile); -+ } -+ sqlite3_mutex_leave(pInode->pLockMutex); - } - releaseInodeInfo(pFile); - sqlite3_free(pFile->lockingContext); -@@ -33601,7 +35659,7 @@ - /* If this is a database file (not a journal, master-journal or temp - ** file), the bytes in the locking range should never be read or written. */ - #if 0 -- assert( pFile->pUnused==0 -+ assert( pFile->pPreallocatedUnused==0 - || offset>=PENDING_BYTE+512 - || offset+amt<=PENDING_BYTE - ); -@@ -33714,7 +35772,7 @@ - /* If this is a database file (not a journal, master-journal or temp - ** file), the bytes in the locking range should never be read or written. */ - #if 0 -- assert( pFile->pUnused==0 -+ assert( pFile->pPreallocatedUnused==0 - || offset>=PENDING_BYTE+512 - || offset+amt<=PENDING_BYTE - ); -@@ -34126,7 +36184,7 @@ - do{ - err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size); - }while( err==EINTR ); -- if( err ) return SQLITE_IOERR_WRITE; -+ if( err && err!=EINVAL ) return SQLITE_IOERR_WRITE; - #else - /* If the OS does not have posix_fallocate(), fake it. Write a - ** single byte to the last byte in each block that falls entirely -@@ -34194,6 +36252,21 @@ - static int unixFileControl(sqlite3_file *id, int op, void *pArg){ - unixFile *pFile = (unixFile*)id; - switch( op ){ -+#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) -+ case SQLITE_FCNTL_BEGIN_ATOMIC_WRITE: { -+ int rc = osIoctl(pFile->h, F2FS_IOC_START_ATOMIC_WRITE); -+ return rc ? SQLITE_IOERR_BEGIN_ATOMIC : SQLITE_OK; -+ } -+ case SQLITE_FCNTL_COMMIT_ATOMIC_WRITE: { -+ int rc = osIoctl(pFile->h, F2FS_IOC_COMMIT_ATOMIC_WRITE); -+ return rc ? SQLITE_IOERR_COMMIT_ATOMIC : SQLITE_OK; -+ } -+ case SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE: { -+ int rc = osIoctl(pFile->h, F2FS_IOC_ABORT_VOLATILE_WRITE); -+ return rc ? SQLITE_IOERR_ROLLBACK_ATOMIC : SQLITE_OK; -+ } -+#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */ -+ - case SQLITE_FCNTL_LOCKSTATE: { - *(int*)pArg = pFile->eFileLock; - return SQLITE_OK; -@@ -34237,6 +36310,12 @@ - *(int*)pArg = fileHasMoved(pFile); - return SQLITE_OK; - } -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ case SQLITE_FCNTL_LOCK_TIMEOUT: { -+ pFile->iBusyTimeout = *(int*)pArg; -+ return SQLITE_OK; -+ } -+#endif - #if SQLITE_MAX_MMAP_SIZE>0 - case SQLITE_FCNTL_MMAP_SIZE: { - i64 newLimit = *(i64*)pArg; -@@ -34244,6 +36323,14 @@ - if( newLimit>sqlite3GlobalConfig.mxMmap ){ - newLimit = sqlite3GlobalConfig.mxMmap; - } -+ -+ /* The value of newLimit may be eventually cast to (size_t) and passed -+ ** to mmap(). Restrict its value to 2GB if (size_t) is not at least a -+ ** 64-bit type. */ -+ if( newLimit>0 && sizeof(size_t)<8 ){ -+ newLimit = (newLimit & 0x7FFFFFFF); -+ } -+ - *(i64*)pArg = pFile->mmapSizeMax; - if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ - pFile->mmapSizeMax = newLimit; -@@ -34277,30 +36364,41 @@ - } - - /* --** Return the sector size in bytes of the underlying block device for --** the specified file. This is almost always 512 bytes, but may be --** larger for some devices. -+** If pFd->sectorSize is non-zero when this function is called, it is a -+** no-op. Otherwise, the values of pFd->sectorSize and -+** pFd->deviceCharacteristics are set according to the file-system -+** characteristics. - ** --** SQLite code assumes this function cannot fail. It also assumes that --** if two files are created in the same file-system directory (i.e. --** a database and its journal file) that the sector size will be the --** same for both. -+** There are two versions of this function. One for QNX and one for all -+** other systems. - */ --#ifndef __QNXNTO__ --static int unixSectorSize(sqlite3_file *NotUsed){ -- UNUSED_PARAMETER(NotUsed); -- return SQLITE_DEFAULT_SECTOR_SIZE; -+#ifndef __QNXNTO__ -+static void setDeviceCharacteristics(unixFile *pFd){ -+ assert( pFd->deviceCharacteristics==0 || pFd->sectorSize!=0 ); -+ if( pFd->sectorSize==0 ){ -+#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) -+ int res; -+ u32 f = 0; -+ -+ /* Check for support for F2FS atomic batch writes. */ -+ res = osIoctl(pFd->h, F2FS_IOC_GET_FEATURES, &f); -+ if( res==0 && (f & F2FS_FEATURE_ATOMIC_WRITE) ){ -+ pFd->deviceCharacteristics = SQLITE_IOCAP_BATCH_ATOMIC; -+ } -+#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */ -+ -+ /* Set the POWERSAFE_OVERWRITE flag if requested. */ -+ if( pFd->ctrlFlags & UNIXFILE_PSOW ){ -+ pFd->deviceCharacteristics |= SQLITE_IOCAP_POWERSAFE_OVERWRITE; -+ } -+ -+ pFd->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; -+ } - } --#endif -- --/* --** The following version of unixSectorSize() is optimized for QNX. --*/ --#ifdef __QNXNTO__ -+#else - #include <sys/dcmd_blk.h> - #include <sys/statvfs.h> --static int unixSectorSize(sqlite3_file *id){ -- unixFile *pFile = (unixFile*)id; -+static void setDeviceCharacteristics(unixFile *pFile){ - if( pFile->sectorSize == 0 ){ - struct statvfs fsInfo; - -@@ -34308,7 +36406,7 @@ - pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; - pFile->deviceCharacteristics = 0; - if( fstatvfs(pFile->h, &fsInfo) == -1 ) { -- return pFile->sectorSize; -+ return; - } - - if( !strcmp(fsInfo.f_basetype, "tmp") ) { -@@ -34369,11 +36467,26 @@ - pFile->deviceCharacteristics = 0; - pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; - } -- return pFile->sectorSize; - } --#endif /* __QNXNTO__ */ -+#endif - - /* -+** Return the sector size in bytes of the underlying block device for -+** the specified file. This is almost always 512 bytes, but may be -+** larger for some devices. -+** -+** SQLite code assumes this function cannot fail. It also assumes that -+** if two files are created in the same file-system directory (i.e. -+** a database and its journal file) that the sector size will be the -+** same for both. -+*/ -+static int unixSectorSize(sqlite3_file *id){ -+ unixFile *pFd = (unixFile*)id; -+ setDeviceCharacteristics(pFd); -+ return pFd->sectorSize; -+} -+ -+/* - ** Return the device characteristics for the file. - ** - ** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default. -@@ -34387,16 +36500,9 @@ - ** available to turn it off and URI query parameter available to turn it off. - */ - static int unixDeviceCharacteristics(sqlite3_file *id){ -- unixFile *p = (unixFile*)id; -- int rc = 0; --#ifdef __QNXNTO__ -- if( p->sectorSize==0 ) unixSectorSize(id); -- rc = p->deviceCharacteristics; --#endif -- if( p->ctrlFlags & UNIXFILE_PSOW ){ -- rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE; -- } -- return rc; -+ unixFile *pFd = (unixFile*)id; -+ setDeviceCharacteristics(pFd); -+ return pFd->deviceCharacteristics; - } - - #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 -@@ -34443,21 +36549,22 @@ - ** - ** The following fields are read-only after the object is created: - ** --** fid -+** hShm - ** zFilename - ** --** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and -+** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and - ** unixMutexHeld() is true when reading or writing any other field - ** in this structure. - */ - struct unixShmNode { - unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ -- sqlite3_mutex *mutex; /* Mutex to access this object */ -+ sqlite3_mutex *pShmMutex; /* Mutex to access this object */ - char *zFilename; /* Name of the mmapped file */ -- int h; /* Open file descriptor */ -+ int hShm; /* Open file descriptor */ - int szRegion; /* Size of shared-memory regions */ - u16 nRegion; /* Size of array apRegion */ - u8 isReadonly; /* True if read-only */ -+ u8 isUnlocked; /* True if no DMS lock held */ - char **apRegion; /* Array of mapped shared-memory regions */ - int nRef; /* Number of unixShm objects pointing to this */ - unixShm *pFirst; /* All unixShm objects pointing to this */ -@@ -34475,16 +36582,16 @@ - ** The following fields are initialized when this object is created and - ** are read-only thereafter: - ** --** unixShm.pFile -+** unixShm.pShmNode - ** unixShm.id - ** --** All other fields are read/write. The unixShm.pFile->mutex must be held --** while accessing any read/write fields. -+** All other fields are read/write. The unixShm.pShmNode->pShmMutex must -+** be held while accessing any read/write fields. - */ - struct unixShm { - unixShmNode *pShmNode; /* The underlying unixShmNode object */ - unixShm *pNext; /* Next unixShm with the same unixShmNode */ -- u8 hasMutex; /* True if holding the unixShmNode mutex */ -+ u8 hasMutex; /* True if holding the unixShmNode->pShmMutex */ - u8 id; /* Id of this connection within its unixShmNode */ - u16 sharedMask; /* Mask of shared locks held */ - u16 exclMask; /* Mask of exclusive locks held */ -@@ -34514,7 +36621,8 @@ - - /* Access to the unixShmNode object is serialized by the caller */ - pShmNode = pFile->pInode->pShmNode; -- assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 ); -+ assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) ); -+ assert( pShmNode->nRef>0 || unixMutexHeld() ); - - /* Shared locks never span more than one byte */ - assert( n==1 || lockType!=F_RDLCK ); -@@ -34522,15 +36630,13 @@ - /* Locks are within range */ - assert( n>=1 && n<=SQLITE_SHM_NLOCK ); - -- if( pShmNode->h>=0 ){ -+ if( pShmNode->hShm>=0 ){ - /* Initialize the locking parameters */ -- memset(&f, 0, sizeof(f)); - f.l_type = lockType; - f.l_whence = SEEK_SET; - f.l_start = ofst; - f.l_len = n; -- -- rc = osFcntl(pShmNode->h, F_SETLK, &f); -+ rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile); - rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; - } - -@@ -34602,9 +36708,9 @@ - int nShmPerMap = unixShmRegionPerMap(); - int i; - assert( p->pInode==pFd->pInode ); -- sqlite3_mutex_free(p->mutex); -+ sqlite3_mutex_free(p->pShmMutex); - for(i=0; i<p->nRegion; i+=nShmPerMap){ -- if( p->h>=0 ){ -+ if( p->hShm>=0 ){ - osMunmap(p->apRegion[i], p->szRegion); - }else{ - sqlite3_free(p->apRegion[i]); -@@ -34611,9 +36717,9 @@ - } - } - sqlite3_free(p->apRegion); -- if( p->h>=0 ){ -- robust_close(pFd, p->h, __LINE__); -- p->h = -1; -+ if( p->hShm>=0 ){ -+ robust_close(pFd, p->hShm, __LINE__); -+ p->hShm = -1; - } - p->pInode->pShmNode = 0; - sqlite3_free(p); -@@ -34621,6 +36727,69 @@ - } - - /* -+** The DMS lock has not yet been taken on shm file pShmNode. Attempt to -+** take it now. Return SQLITE_OK if successful, or an SQLite error -+** code otherwise. -+** -+** If the DMS cannot be locked because this is a readonly_shm=1 -+** connection and no other process already holds a lock, return -+** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1. -+*/ -+static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){ -+ struct flock lock; -+ int rc = SQLITE_OK; -+ -+ /* Use F_GETLK to determine the locks other processes are holding -+ ** on the DMS byte. If it indicates that another process is holding -+ ** a SHARED lock, then this process may also take a SHARED lock -+ ** and proceed with opening the *-shm file. -+ ** -+ ** Or, if no other process is holding any lock, then this process -+ ** is the first to open it. In this case take an EXCLUSIVE lock on the -+ ** DMS byte and truncate the *-shm file to zero bytes in size. Then -+ ** downgrade to a SHARED lock on the DMS byte. -+ ** -+ ** If another process is holding an EXCLUSIVE lock on the DMS byte, -+ ** return SQLITE_BUSY to the caller (it will try again). An earlier -+ ** version of this code attempted the SHARED lock at this point. But -+ ** this introduced a subtle race condition: if the process holding -+ ** EXCLUSIVE failed just before truncating the *-shm file, then this -+ ** process might open and use the *-shm file without truncating it. -+ ** And if the *-shm file has been corrupted by a power failure or -+ ** system crash, the database itself may also become corrupt. */ -+ lock.l_whence = SEEK_SET; -+ lock.l_start = UNIX_SHM_DMS; -+ lock.l_len = 1; -+ lock.l_type = F_WRLCK; -+ if( osFcntl(pShmNode->hShm, F_GETLK, &lock)!=0 ) { -+ rc = SQLITE_IOERR_LOCK; -+ }else if( lock.l_type==F_UNLCK ){ -+ if( pShmNode->isReadonly ){ -+ pShmNode->isUnlocked = 1; -+ rc = SQLITE_READONLY_CANTINIT; -+ }else{ -+ rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1); -+ /* The first connection to attach must truncate the -shm file. We -+ ** truncate to 3 bytes (an arbitrary small number, less than the -+ ** -shm header size) rather than 0 as a system debugging aid, to -+ ** help detect if a -shm file truncation is legitimate or is the work -+ ** or a rogue process. */ -+ if( rc==SQLITE_OK && robust_ftruncate(pShmNode->hShm, 3) ){ -+ rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename); -+ } -+ } -+ }else if( lock.l_type==F_WRLCK ){ -+ rc = SQLITE_BUSY; -+ } -+ -+ if( rc==SQLITE_OK ){ -+ assert( lock.l_type==F_UNLCK || lock.l_type==F_RDLCK ); -+ rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1); -+ } -+ return rc; -+} -+ -+/* - ** Open a shared-memory area associated with open database file pDbFd. - ** This particular implementation uses mmapped files. - ** -@@ -34658,9 +36827,9 @@ - static int unixOpenSharedMemory(unixFile *pDbFd){ - struct unixShm *p = 0; /* The connection to be opened */ - struct unixShmNode *pShmNode; /* The underlying mmapped file */ -- int rc; /* Result code */ -+ int rc = SQLITE_OK; /* Result code */ - unixInodeInfo *pInode; /* The inode of fd */ -- char *zShmFilename; /* Name of the file used for SHM */ -+ char *zShm; /* Name of the file used for SHM */ - int nShmFilename; /* Size of the SHM filename in bytes */ - - /* Allocate space for the new unixShm object. */ -@@ -34672,6 +36841,7 @@ - /* Check to see if a unixShmNode object already exists. Reuse an existing - ** one if present. Create a new one if necessary. - */ -+ assert( unixFileMutexNotheld(pDbFd) ); - unixEnterMutex(); - pInode = pDbFd->pInode; - pShmNode = pInode->pShmNode; -@@ -34701,21 +36871,21 @@ - goto shm_open_err; - } - memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename); -- zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1]; -+ zShm = pShmNode->zFilename = (char*)&pShmNode[1]; - #ifdef SQLITE_SHM_DIRECTORY -- sqlite3_snprintf(nShmFilename, zShmFilename, -+ sqlite3_snprintf(nShmFilename, zShm, - SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x", - (u32)sStat.st_ino, (u32)sStat.st_dev); - #else -- sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath); -- sqlite3FileSuffix3(pDbFd->zPath, zShmFilename); -+ sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath); -+ sqlite3FileSuffix3(pDbFd->zPath, zShm); - #endif -- pShmNode->h = -1; -+ pShmNode->hShm = -1; - pDbFd->pInode->pShmNode = pShmNode; - pShmNode->pInode = pDbFd->pInode; - if( sqlite3GlobalConfig.bCoreMutex ){ -- pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); -- if( pShmNode->mutex==0 ){ -+ pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); -+ if( pShmNode->pShmMutex==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto shm_open_err; - } -@@ -34722,36 +36892,26 @@ - } - - if( pInode->bProcessLock==0 ){ -- int openFlags = O_RDWR | O_CREAT; -- if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ -- openFlags = O_RDONLY; -+ if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ -+ pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777)); -+ } -+ if( pShmNode->hShm<0 ){ -+ pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777)); -+ if( pShmNode->hShm<0 ){ -+ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm); -+ goto shm_open_err; -+ } - pShmNode->isReadonly = 1; - } -- pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777)); -- if( pShmNode->h<0 ){ -- rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); -- goto shm_open_err; -- } - - /* If this process is running as root, make sure that the SHM file - ** is owned by the same user that owns the original database. Otherwise, - ** the original owner will not be able to connect. - */ -- robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid); -- -- /* Check to see if another process is holding the dead-man switch. -- ** If not, truncate the file to zero length. -- */ -- rc = SQLITE_OK; -- if( unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ -- if( robust_ftruncate(pShmNode->h, 0) ){ -- rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); -- } -- } -- if( rc==SQLITE_OK ){ -- rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1); -- } -- if( rc ) goto shm_open_err; -+ robustFchown(pShmNode->hShm, sStat.st_uid, sStat.st_gid); -+ -+ rc = unixLockSharedMemory(pDbFd, pShmNode); -+ if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err; - } - } - -@@ -34768,14 +36928,14 @@ - ** the cover of the unixEnterMutex() mutex and the pointer from the - ** new (struct unixShm) object to the pShmNode has been set. All that is - ** left to do is to link the new object into the linked list starting -- ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex -- ** mutex. -+ ** at pShmNode->pFirst. This must be done while holding the -+ ** pShmNode->pShmMutex. - */ -- sqlite3_mutex_enter(pShmNode->mutex); -+ sqlite3_mutex_enter(pShmNode->pShmMutex); - p->pNext = pShmNode->pFirst; - pShmNode->pFirst = p; -- sqlite3_mutex_leave(pShmNode->mutex); -- return SQLITE_OK; -+ sqlite3_mutex_leave(pShmNode->pShmMutex); -+ return rc; - - /* Jump here on any error */ - shm_open_err: -@@ -34826,11 +36986,16 @@ - - p = pDbFd->pShm; - pShmNode = p->pShmNode; -- sqlite3_mutex_enter(pShmNode->mutex); -+ sqlite3_mutex_enter(pShmNode->pShmMutex); -+ if( pShmNode->isUnlocked ){ -+ rc = unixLockSharedMemory(pDbFd, pShmNode); -+ if( rc!=SQLITE_OK ) goto shmpage_out; -+ pShmNode->isUnlocked = 0; -+ } - assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); - assert( pShmNode->pInode==pDbFd->pInode ); -- assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); -- assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); -+ assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 ); -+ assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); - - /* Minimum number of regions required to be mapped. */ - nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap; -@@ -34842,12 +37007,12 @@ - - pShmNode->szRegion = szRegion; - -- if( pShmNode->h>=0 ){ -+ if( pShmNode->hShm>=0 ){ - /* The requested region is not mapped into this processes address space. - ** Check to see if it has been allocated (i.e. if the wal-index file is - ** large enough to contain the requested region). - */ -- if( osFstat(pShmNode->h, &sStat) ){ -+ if( osFstat(pShmNode->hShm, &sStat) ){ - rc = SQLITE_IOERR_SHMSIZE; - goto shmpage_out; - } -@@ -34875,7 +37040,7 @@ - assert( (nByte % pgsz)==0 ); - for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){ - int x = 0; -- if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){ -+ if( seekAndWriteFd(pShmNode->hShm, iPg*pgsz + pgsz-1,"",1,&x)!=1 ){ - const char *zFile = pShmNode->zFilename; - rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile); - goto shmpage_out; -@@ -34898,10 +37063,10 @@ - int nMap = szRegion*nShmPerMap; - int i; - void *pMem; -- if( pShmNode->h>=0 ){ -+ if( pShmNode->hShm>=0 ){ - pMem = osMmap(0, nMap, - pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, -- MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion -+ MAP_SHARED, pShmNode->hShm, szRegion*(i64)pShmNode->nRegion - ); - if( pMem==MAP_FAILED ){ - rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); -@@ -34908,12 +37073,12 @@ - goto shmpage_out; - } - }else{ -- pMem = sqlite3_malloc64(szRegion); -+ pMem = sqlite3_malloc64(nMap); - if( pMem==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto shmpage_out; - } -- memset(pMem, 0, szRegion); -+ memset(pMem, 0, nMap); - } - - for(i=0; i<nShmPerMap; i++){ -@@ -34930,7 +37095,7 @@ - *pp = 0; - } - if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; -- sqlite3_mutex_leave(pShmNode->mutex); -+ sqlite3_mutex_leave(pShmNode->pShmMutex); - return rc; - } - -@@ -34964,12 +37129,12 @@ - || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) - || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); - assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); -- assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); -- assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); -+ assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 ); -+ assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); - - mask = (1<<(ofst+n)) - (1<<ofst); - assert( n>1 || mask==(1<<ofst) ); -- sqlite3_mutex_enter(pShmNode->mutex); -+ sqlite3_mutex_enter(pShmNode->pShmMutex); - if( flags & SQLITE_SHM_UNLOCK ){ - u16 allMask = 0; /* Mask of locks held by siblings */ - -@@ -35042,7 +37207,7 @@ - } - } - } -- sqlite3_mutex_leave(pShmNode->mutex); -+ sqlite3_mutex_leave(pShmNode->pShmMutex); - OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", - p->id, osGetpid(0), p->sharedMask, p->exclMask)); - return rc; -@@ -35059,6 +37224,9 @@ - ){ - UNUSED_PARAMETER(fd); - sqlite3MemoryBarrier(); /* compiler-defined memory barrier */ -+ assert( fd->pMethods->xLock==nolockLock -+ || unixFileMutexNotheld((unixFile*)fd) -+ ); - unixEnterMutex(); /* Also mutex, for redundancy */ - unixLeaveMutex(); - } -@@ -35089,7 +37257,7 @@ - - /* Remove connection p from the set of connections associated - ** with pShmNode */ -- sqlite3_mutex_enter(pShmNode->mutex); -+ sqlite3_mutex_enter(pShmNode->pShmMutex); - for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} - *pp = p->pNext; - -@@ -35096,15 +37264,16 @@ - /* Free the connection p */ - sqlite3_free(p); - pDbFd->pShm = 0; -- sqlite3_mutex_leave(pShmNode->mutex); -+ sqlite3_mutex_leave(pShmNode->pShmMutex); - - /* If pShmNode->nRef has reached 0, then close the underlying - ** shared-memory file, too */ -+ assert( unixFileMutexNotheld(pDbFd) ); - unixEnterMutex(); - assert( pShmNode->nRef>0 ); - pShmNode->nRef--; - if( pShmNode->nRef==0 ){ -- if( deleteFlag && pShmNode->h>=0 ){ -+ if( deleteFlag && pShmNode->hShm>=0 ){ - osUnlink(pShmNode->zFilename); - } - unixShmPurge(pDbFd); -@@ -35426,7 +37595,7 @@ - IOMETHODS( - nolockIoFinder, /* Finder function name */ - nolockIoMethods, /* sqlite3_io_methods object name */ -- 3, /* shared memory is disabled */ -+ 3, /* shared memory and mmap are enabled */ - nolockClose, /* xClose method */ - nolockLock, /* xLock method */ - nolockUnlock, /* xUnlock method */ -@@ -35654,17 +37823,6 @@ - - assert( pNew->pInode==NULL ); - -- /* Usually the path zFilename should not be a relative pathname. The -- ** exception is when opening the proxy "conch" file in builds that -- ** include the special Apple locking styles. -- */ --#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE -- assert( zFilename==0 || zFilename[0]=='/' -- || pVfs->pAppData==(void*)&autolockIoFinder ); --#else -- assert( zFilename==0 || zFilename[0]=='/' ); --#endif -- - /* No locking occurs in temporary files */ - assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 ); - -@@ -35923,6 +38081,8 @@ - #if !OS_VXWORKS - struct stat sStat; /* Results of stat() call */ - -+ unixEnterMutex(); -+ - /* A stat() call may fail for various reasons. If this happens, it is - ** almost certain that an open() call on the same path will also fail. - ** For this reason, if an error occurs in the stat() call here, it is -@@ -35931,10 +38091,9 @@ - ** - ** Even if a subsequent open() call does succeed, the consequences of - ** not searching for a reusable file descriptor are not dire. */ -- if( 0==osStat(zPath, &sStat) ){ -+ if( inodeList!=0 && 0==osStat(zPath, &sStat) ){ - unixInodeInfo *pInode; - -- unixEnterMutex(); - pInode = inodeList; - while( pInode && (pInode->fileId.dev!=sStat.st_dev - || pInode->fileId.ino!=(u64)sStat.st_ino) ){ -@@ -35942,14 +38101,17 @@ - } - if( pInode ){ - UnixUnusedFd **pp; -+ assert( sqlite3_mutex_notheld(pInode->pLockMutex) ); -+ sqlite3_mutex_enter(pInode->pLockMutex); - for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext)); - pUnused = *pp; - if( pUnused ){ - *pp = pUnused->pNext; - } -+ sqlite3_mutex_leave(pInode->pLockMutex); - } -- unixLeaveMutex(); - } -+ unixLeaveMutex(); - #endif /* if !OS_VXWORKS */ - return pUnused; - } -@@ -36025,16 +38187,11 @@ - */ - nDb = sqlite3Strlen30(zPath) - 1; - while( zPath[nDb]!='-' ){ --#ifndef SQLITE_ENABLE_8_3_NAMES -- /* In the normal case (8+3 filenames disabled) the journal filename -- ** is guaranteed to contain a '-' character. */ -- assert( nDb>0 ); -- assert( sqlite3Isalnum(zPath[nDb]) ); --#else -- /* If 8+3 names are possible, then the journal file might not contain -- ** a '-' character. So check for that case and return early. */ -+ /* In normal operation, the journal file name will always contain -+ ** a '-' character. However in 8+3 filename mode, or if a corrupt -+ ** rollback journal specifies a master journal with a goofy name, then -+ ** the '-' might be missing. */ - if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK; --#endif - nDb--; - } - memcpy(zDb, zPath, nDb); -@@ -36109,7 +38266,7 @@ - ** a file-descriptor on the directory too. The first time unixSync() - ** is called the directory file descriptor will be fsync()ed and close()d. - */ -- int syncDir = (isCreate && ( -+ int isNewJrnl = (isCreate && ( - eType==SQLITE_OPEN_MASTER_JOURNAL - || eType==SQLITE_OPEN_MAIN_JOURNAL - || eType==SQLITE_OPEN_WAL -@@ -36156,7 +38313,6 @@ - randomnessPid = osGetpid(0); - sqlite3_randomness(0,0); - } -- - memset(p, 0, sizeof(unixFile)); - - if( eType==SQLITE_OPEN_MAIN_DB ){ -@@ -36170,7 +38326,7 @@ - return SQLITE_NOMEM_BKPT; - } - } -- p->pUnused = pUnused; -+ p->pPreallocatedUnused = pUnused; - - /* Database filenames are double-zero terminated if they are not - ** URIs with parameters. Hence, they can always be passed into -@@ -36179,7 +38335,7 @@ - - }else if( !zName ){ - /* If zName is NULL, the upper layer is requesting a temp file. */ -- assert(isDelete && !syncDir); -+ assert(isDelete && !isNewJrnl); - rc = unixGetTempname(pVfs->mxPathname, zTmpname); - if( rc!=SQLITE_OK ){ - return rc; -@@ -36207,7 +38363,7 @@ - gid_t gid; /* Groupid for the file */ - rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid); - if( rc!=SQLITE_OK ){ -- assert( !p->pUnused ); -+ assert( !p->pPreallocatedUnused ); - assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); - return rc; - } -@@ -36214,17 +38370,24 @@ - fd = robust_open(zName, openFlags, openMode); - OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags)); - assert( !isExclusive || (openFlags & O_CREAT)!=0 ); -- if( fd<0 && errno!=EISDIR && isReadWrite ){ -- /* Failed to open the file for read/write access. Try read-only. */ -- flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); -- openFlags &= ~(O_RDWR|O_CREAT); -- flags |= SQLITE_OPEN_READONLY; -- openFlags |= O_RDONLY; -- isReadonly = 1; -- fd = robust_open(zName, openFlags, openMode); -+ if( fd<0 ){ -+ if( isNewJrnl && errno==EACCES && osAccess(zName, F_OK) ){ -+ /* If unable to create a journal because the directory is not -+ ** writable, change the error code to indicate that. */ -+ rc = SQLITE_READONLY_DIRECTORY; -+ }else if( errno!=EISDIR && isReadWrite ){ -+ /* Failed to open the file for read/write access. Try read-only. */ -+ flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); -+ openFlags &= ~(O_RDWR|O_CREAT); -+ flags |= SQLITE_OPEN_READONLY; -+ openFlags |= O_RDONLY; -+ isReadonly = 1; -+ fd = robust_open(zName, openFlags, openMode); -+ } - } - if( fd<0 ){ -- rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName); -+ int rc2 = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName); -+ if( rc==SQLITE_OK ) rc = rc2; - goto open_finished; - } - -@@ -36241,9 +38404,9 @@ - *pOutFlags = flags; - } - -- if( p->pUnused ){ -- p->pUnused->fd = fd; -- p->pUnused->flags = flags; -+ if( p->pPreallocatedUnused ){ -+ p->pPreallocatedUnused->fd = fd; -+ p->pPreallocatedUnused->flags = flags; - } - - if( isDelete ){ -@@ -36284,7 +38447,7 @@ - if( isReadonly ) ctrlFlags |= UNIXFILE_RDONLY; - noLock = eType!=SQLITE_OPEN_MAIN_DB; - if( noLock ) ctrlFlags |= UNIXFILE_NOLOCK; -- if( syncDir ) ctrlFlags |= UNIXFILE_DIRSYNC; -+ if( isNewJrnl ) ctrlFlags |= UNIXFILE_DIRSYNC; - if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI; - - #if SQLITE_ENABLE_LOCKING_STYLE -@@ -36320,11 +38483,14 @@ - } - #endif - -+ assert( zPath==0 || zPath[0]=='/' -+ || eType==SQLITE_OPEN_MASTER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL -+ ); - rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); - - open_finished: - if( rc!=SQLITE_OK ){ -- sqlite3_free(p->pUnused); -+ sqlite3_free(p->pPreallocatedUnused); - } - return rc; - } -@@ -37065,7 +39231,7 @@ - dummyVfs.zName = "dummy"; - pUnused->fd = fd; - pUnused->flags = openFlags; -- pNew->pUnused = pUnused; -+ pNew->pPreallocatedUnused = pUnused; - - rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0); - if( rc==SQLITE_OK ){ -@@ -38015,12 +40181,13 @@ - - /* Double-check that the aSyscall[] array has been constructed - ** correctly. See ticket [bb3a86e890c8e96ab] */ -- assert( ArraySize(aSyscall)==28 ); -+ assert( ArraySize(aSyscall)==29 ); - - /* Register all VFSes defined in the aVfs[] array */ - for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ - sqlite3_vfs_register(&aVfs[i], i==0); - } -+ unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); - return SQLITE_OK; - } - -@@ -38032,6 +40199,7 @@ - ** This routine is a no-op for unix. - */ - SQLITE_API int sqlite3_os_end(void){ -+ unixBigLock = 0; - return SQLITE_OK; - } - -@@ -38523,8 +40691,7 @@ - int nFetchOut; /* Number of outstanding xFetch references */ - HANDLE hMap; /* Handle for accessing memory mapping */ - void *pMapRegion; /* Area memory mapped */ -- sqlite3_int64 mmapSize; /* Usable size of mapped region */ -- sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */ -+ sqlite3_int64 mmapSize; /* Size of mapped region */ - sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ - #endif - }; -@@ -38555,22 +40722,6 @@ - #endif - - /* -- * The value used with sqlite3_win32_set_directory() to specify that -- * the data directory should be changed. -- */ --#ifndef SQLITE_WIN32_DATA_DIRECTORY_TYPE --# define SQLITE_WIN32_DATA_DIRECTORY_TYPE (1) --#endif -- --/* -- * The value used with sqlite3_win32_set_directory() to specify that -- * the temporary directory should be changed. -- */ --#ifndef SQLITE_WIN32_TEMP_DIRECTORY_TYPE --# define SQLITE_WIN32_TEMP_DIRECTORY_TYPE (2) --#endif -- --/* - * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the - * various Win32 API heap functions instead of our own. - */ -@@ -40166,13 +42317,13 @@ - } - - /* --** This function sets the data directory or the temporary directory based on --** the provided arguments. The type argument must be 1 in order to set the --** data directory or 2 in order to set the temporary directory. The zValue --** argument is the name of the directory to use. The return value will be --** SQLITE_OK if successful. -+** This function is the same as sqlite3_win32_set_directory (below); however, -+** it accepts a UTF-8 string. - */ --SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){ -+SQLITE_API int sqlite3_win32_set_directory8( -+ unsigned long type, /* Identifier for directory being set or reset */ -+ const char *zValue /* New value for directory being set or reset */ -+){ - char **ppDirectory = 0; - #ifndef SQLITE_OMIT_AUTOINIT - int rc = sqlite3_initialize(); -@@ -40188,15 +42339,15 @@ - ); - assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) ); - if( ppDirectory ){ -- char *zValueUtf8 = 0; -+ char *zCopy = 0; - if( zValue && zValue[0] ){ -- zValueUtf8 = winUnicodeToUtf8(zValue); -- if ( zValueUtf8==0 ){ -+ zCopy = sqlite3_mprintf("%s", zValue); -+ if ( zCopy==0 ){ - return SQLITE_NOMEM_BKPT; - } - } - sqlite3_free(*ppDirectory); -- *ppDirectory = zValueUtf8; -+ *ppDirectory = zCopy; - return SQLITE_OK; - } - return SQLITE_ERROR; -@@ -40203,6 +42354,39 @@ - } - - /* -+** This function is the same as sqlite3_win32_set_directory (below); however, -+** it accepts a UTF-16 string. -+*/ -+SQLITE_API int sqlite3_win32_set_directory16( -+ unsigned long type, /* Identifier for directory being set or reset */ -+ const void *zValue /* New value for directory being set or reset */ -+){ -+ int rc; -+ char *zUtf8 = 0; -+ if( zValue ){ -+ zUtf8 = sqlite3_win32_unicode_to_utf8(zValue); -+ if( zUtf8==0 ) return SQLITE_NOMEM_BKPT; -+ } -+ rc = sqlite3_win32_set_directory8(type, zUtf8); -+ if( zUtf8 ) sqlite3_free(zUtf8); -+ return rc; -+} -+ -+/* -+** This function sets the data directory or the temporary directory based on -+** the provided arguments. The type argument must be 1 in order to set the -+** data directory or 2 in order to set the temporary directory. The zValue -+** argument is the name of the directory to use. The return value will be -+** SQLITE_OK if successful. -+*/ -+SQLITE_API int sqlite3_win32_set_directory( -+ unsigned long type, /* Identifier for directory being set or reset */ -+ void *zValue /* New value for directory being set or reset */ -+){ -+ return sqlite3_win32_set_directory16(type, zValue); -+} -+ -+/* - ** The return value of winGetLastErrorMsg - ** is zero if the error message fits in the buffer, or non-zero - ** otherwise (if the message was truncated). -@@ -41126,6 +43310,29 @@ - winFile *pFile = (winFile*)id; /* File handle object */ - int rc = SQLITE_OK; /* Return code for this function */ - DWORD lastErrno; -+#if SQLITE_MAX_MMAP_SIZE>0 -+ sqlite3_int64 oldMmapSize; -+ if( pFile->nFetchOut>0 ){ -+ /* File truncation is a no-op if there are outstanding memory mapped -+ ** pages. This is because truncating the file means temporarily unmapping -+ ** the file, and that might delete memory out from under existing cursors. -+ ** -+ ** This can result in incremental vacuum not truncating the file, -+ ** if there is an active read cursor when the incremental vacuum occurs. -+ ** No real harm comes of this - the database file is not corrupted, -+ ** though some folks might complain that the file is bigger than it -+ ** needs to be. -+ ** -+ ** The only feasible work-around is to defer the truncation until after -+ ** all references to memory-mapped content are closed. That is doable, -+ ** but involves adding a few branches in the common write code path which -+ ** could slow down normal operations slightly. Hence, we have decided for -+ ** now to simply make trancations a no-op if there are pending reads. We -+ ** can maybe revisit this decision in the future. -+ */ -+ return SQLITE_OK; -+ } -+#endif - - assert( pFile ); - SimulateIOError(return SQLITE_IOERR_TRUNCATE); -@@ -41141,6 +43348,15 @@ - nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; - } - -+#if SQLITE_MAX_MMAP_SIZE>0 -+ if( pFile->pMapRegion ){ -+ oldMmapSize = pFile->mmapSize; -+ }else{ -+ oldMmapSize = 0; -+ } -+ winUnmapfile(pFile); -+#endif -+ - /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ - if( winSeekFile(pFile, nByte) ){ - rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, -@@ -41153,12 +43369,12 @@ - } - - #if SQLITE_MAX_MMAP_SIZE>0 -- /* If the file was truncated to a size smaller than the currently -- ** mapped region, reduce the effective mapping size as well. SQLite will -- ** use read() and write() to access data beyond this point from now on. -- */ -- if( pFile->pMapRegion && nByte<pFile->mmapSize ){ -- pFile->mmapSize = nByte; -+ if( rc==SQLITE_OK && oldMmapSize>0 ){ -+ if( oldMmapSize>nByte ){ -+ winMapfile(pFile, -1); -+ }else{ -+ winMapfile(pFile, oldMmapSize); -+ } - } - #endif - -@@ -41798,6 +44014,14 @@ - if( newLimit>sqlite3GlobalConfig.mxMmap ){ - newLimit = sqlite3GlobalConfig.mxMmap; - } -+ -+ /* The value of newLimit may be eventually cast to (SIZE_T) and passed -+ ** to MapViewOfFile(). Restrict its value to 2GB if (SIZE_T) is not at -+ ** least a 64-bit type. */ -+ if( newLimit>0 && sizeof(SIZE_T)<8 ){ -+ newLimit = (newLimit & 0x7FFFFFFF); -+ } -+ - *(i64*)pArg = pFile->mmapSizeMax; - if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ - pFile->mmapSizeMax = newLimit; -@@ -41862,15 +44086,16 @@ - ** assert( winShmMutexHeld() ); - ** winShmLeaveMutex() - */ -+static sqlite3_mutex *winBigLock = 0; - static void winShmEnterMutex(void){ -- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); -+ sqlite3_mutex_enter(winBigLock); - } - static void winShmLeaveMutex(void){ -- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); -+ sqlite3_mutex_leave(winBigLock); - } - #ifndef NDEBUG - static int winShmMutexHeld(void) { -- return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); -+ return sqlite3_mutex_held(winBigLock); - } - #endif - -@@ -41904,6 +44129,9 @@ - - int szRegion; /* Size of shared-memory regions */ - int nRegion; /* Size of array apRegion */ -+ u8 isReadonly; /* True if read-only */ -+ u8 isUnlocked; /* True if no DMS lock held */ -+ - struct ShmRegion { - HANDLE hMap; /* File handle from CreateFileMapping */ - void *pMap; -@@ -41970,7 +44198,7 @@ - int rc = 0; /* Result code form Lock/UnlockFileEx() */ - - /* Access to the winShmNode object is serialized by the caller */ -- assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 ); -+ assert( pFile->nRef==0 || sqlite3_mutex_held(pFile->mutex) ); - - OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n", - pFile->hFile.h, lockType, ofst, nByte)); -@@ -42052,6 +44280,37 @@ - } - - /* -+** The DMS lock has not yet been taken on shm file pShmNode. Attempt to -+** take it now. Return SQLITE_OK if successful, or an SQLite error -+** code otherwise. -+** -+** If the DMS cannot be locked because this is a readonly_shm=1 -+** connection and no other process already holds a lock, return -+** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1. -+*/ -+static int winLockSharedMemory(winShmNode *pShmNode){ -+ int rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1); -+ -+ if( rc==SQLITE_OK ){ -+ if( pShmNode->isReadonly ){ -+ pShmNode->isUnlocked = 1; -+ winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); -+ return SQLITE_READONLY_CANTINIT; -+ }else if( winTruncate((sqlite3_file*)&pShmNode->hFile, 0) ){ -+ winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); -+ return winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), -+ "winLockSharedMemory", pShmNode->zFilename); -+ } -+ } -+ -+ if( rc==SQLITE_OK ){ -+ winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); -+ } -+ -+ return winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1); -+} -+ -+/* - ** Open the shared-memory area associated with database file pDbFd. - ** - ** When opening a new shared-memory file, if no other instances of that -@@ -42060,9 +44319,9 @@ - */ - static int winOpenSharedMemory(winFile *pDbFd){ - struct winShm *p; /* The connection to be opened */ -- struct winShmNode *pShmNode = 0; /* The underlying mmapped file */ -- int rc; /* Result code */ -- struct winShmNode *pNew; /* Newly allocated winShmNode */ -+ winShmNode *pShmNode = 0; /* The underlying mmapped file */ -+ int rc = SQLITE_OK; /* Result code */ -+ winShmNode *pNew; /* Newly allocated winShmNode */ - int nName; /* Size of zName in bytes */ - - assert( pDbFd->pShm==0 ); /* Not previously opened */ -@@ -42095,6 +44354,9 @@ - if( pShmNode ){ - sqlite3_free(pNew); - }else{ -+ int inFlags = SQLITE_OPEN_WAL; -+ int outFlags = 0; -+ - pShmNode = pNew; - pNew = 0; - ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE; -@@ -42109,30 +44371,23 @@ - } - } - -- rc = winOpen(pDbFd->pVfs, -- pShmNode->zFilename, /* Name of the file (UTF-8) */ -- (sqlite3_file*)&pShmNode->hFile, /* File handle here */ -- SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, -- 0); -- if( SQLITE_OK!=rc ){ -+ if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ -+ inFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; -+ }else{ -+ inFlags |= SQLITE_OPEN_READONLY; -+ } -+ rc = winOpen(pDbFd->pVfs, pShmNode->zFilename, -+ (sqlite3_file*)&pShmNode->hFile, -+ inFlags, &outFlags); -+ if( rc!=SQLITE_OK ){ -+ rc = winLogError(rc, osGetLastError(), "winOpenShm", -+ pShmNode->zFilename); - goto shm_open_err; - } -+ if( outFlags==SQLITE_OPEN_READONLY ) pShmNode->isReadonly = 1; - -- /* Check to see if another process is holding the dead-man switch. -- ** If not, truncate the file to zero length. -- */ -- if( winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ -- rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); -- if( rc!=SQLITE_OK ){ -- rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), -- "winOpenShm", pDbFd->zPath); -- } -- } -- if( rc==SQLITE_OK ){ -- winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); -- rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1); -- } -- if( rc ) goto shm_open_err; -+ rc = winLockSharedMemory(pShmNode); -+ if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err; - } - - /* Make the new connection a child of the winShmNode */ -@@ -42155,7 +44410,7 @@ - p->pNext = pShmNode->pFirst; - pShmNode->pFirst = p; - sqlite3_mutex_leave(pShmNode->mutex); -- return SQLITE_OK; -+ return rc; - - /* Jump here on any error */ - shm_open_err: -@@ -42359,6 +44614,8 @@ - winFile *pDbFd = (winFile*)fd; - winShm *pShm = pDbFd->pShm; - winShmNode *pShmNode; -+ DWORD protect = PAGE_READWRITE; -+ DWORD flags = FILE_MAP_WRITE | FILE_MAP_READ; - int rc = SQLITE_OK; - - if( !pShm ){ -@@ -42369,6 +44626,11 @@ - pShmNode = pShm->pShmNode; - - sqlite3_mutex_enter(pShmNode->mutex); -+ if( pShmNode->isUnlocked ){ -+ rc = winLockSharedMemory(pShmNode); -+ if( rc!=SQLITE_OK ) goto shmpage_out; -+ pShmNode->isUnlocked = 0; -+ } - assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); - - if( pShmNode->nRegion<=iRegion ){ -@@ -42415,6 +44677,11 @@ - } - pShmNode->aRegion = apNew; - -+ if( pShmNode->isReadonly ){ -+ protect = PAGE_READONLY; -+ flags = FILE_MAP_READ; -+ } -+ - while( pShmNode->nRegion<=iRegion ){ - HANDLE hMap = NULL; /* file-mapping handle */ - void *pMap = 0; /* Mapped memory region */ -@@ -42421,15 +44688,15 @@ - - #if SQLITE_OS_WINRT - hMap = osCreateFileMappingFromApp(pShmNode->hFile.h, -- NULL, PAGE_READWRITE, nByte, NULL -+ NULL, protect, nByte, NULL - ); - #elif defined(SQLITE_WIN32_HAS_WIDE) - hMap = osCreateFileMappingW(pShmNode->hFile.h, -- NULL, PAGE_READWRITE, 0, nByte, NULL -+ NULL, protect, 0, nByte, NULL - ); - #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA - hMap = osCreateFileMappingA(pShmNode->hFile.h, -- NULL, PAGE_READWRITE, 0, nByte, NULL -+ NULL, protect, 0, nByte, NULL - ); - #endif - OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", -@@ -42439,11 +44706,11 @@ - int iOffset = pShmNode->nRegion*szRegion; - int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; - #if SQLITE_OS_WINRT -- pMap = osMapViewOfFileFromApp(hMap, FILE_MAP_WRITE | FILE_MAP_READ, -+ pMap = osMapViewOfFileFromApp(hMap, flags, - iOffset - iOffsetShift, szRegion + iOffsetShift - ); - #else -- pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, -+ pMap = osMapViewOfFile(hMap, flags, - 0, iOffset - iOffsetShift, szRegion + iOffsetShift - ); - #endif -@@ -42474,6 +44741,7 @@ - }else{ - *pp = 0; - } -+ if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; - sqlite3_mutex_leave(pShmNode->mutex); - return rc; - } -@@ -42492,9 +44760,9 @@ - static int winUnmapfile(winFile *pFile){ - assert( pFile!=0 ); - OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, " -- "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n", -+ "mmapSize=%lld, mmapSizeMax=%lld\n", - osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion, -- pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax)); -+ pFile->mmapSize, pFile->mmapSizeMax)); - if( pFile->pMapRegion ){ - if( !osUnmapViewOfFile(pFile->pMapRegion) ){ - pFile->lastErrno = osGetLastError(); -@@ -42506,7 +44774,6 @@ - } - pFile->pMapRegion = 0; - pFile->mmapSize = 0; -- pFile->mmapSizeActual = 0; - } - if( pFile->hMap!=NULL ){ - if( !osCloseHandle(pFile->hMap) ){ -@@ -42617,7 +44884,6 @@ - } - pFd->pMapRegion = pNew; - pFd->mmapSize = nMap; -- pFd->mmapSizeActual = nMap; - } - - OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", -@@ -43110,6 +45376,14 @@ - return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY); - } - -+/* forward reference */ -+static int winAccess( -+ sqlite3_vfs *pVfs, /* Not used on win32 */ -+ const char *zFilename, /* Name of file to check */ -+ int flags, /* Type of test to make on this file */ -+ int *pResOut /* OUT: Result */ -+); -+ - /* - ** Open a file. - */ -@@ -43286,37 +45560,58 @@ - extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS; - extendedParameters.lpSecurityAttributes = NULL; - extendedParameters.hTemplateFile = NULL; -- while( (h = osCreateFile2((LPCWSTR)zConverted, -- dwDesiredAccess, -- dwShareMode, -- dwCreationDisposition, -- &extendedParameters))==INVALID_HANDLE_VALUE && -- winRetryIoerr(&cnt, &lastErrno) ){ -- /* Noop */ -- } -+ do{ -+ h = osCreateFile2((LPCWSTR)zConverted, -+ dwDesiredAccess, -+ dwShareMode, -+ dwCreationDisposition, -+ &extendedParameters); -+ if( h!=INVALID_HANDLE_VALUE ) break; -+ if( isReadWrite ){ -+ int rc2, isRO = 0; -+ sqlite3BeginBenignMalloc(); -+ rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); -+ sqlite3EndBenignMalloc(); -+ if( rc2==SQLITE_OK && isRO ) break; -+ } -+ }while( winRetryIoerr(&cnt, &lastErrno) ); - #else -- while( (h = osCreateFileW((LPCWSTR)zConverted, -- dwDesiredAccess, -- dwShareMode, NULL, -- dwCreationDisposition, -- dwFlagsAndAttributes, -- NULL))==INVALID_HANDLE_VALUE && -- winRetryIoerr(&cnt, &lastErrno) ){ -- /* Noop */ -- } -+ do{ -+ h = osCreateFileW((LPCWSTR)zConverted, -+ dwDesiredAccess, -+ dwShareMode, NULL, -+ dwCreationDisposition, -+ dwFlagsAndAttributes, -+ NULL); -+ if( h!=INVALID_HANDLE_VALUE ) break; -+ if( isReadWrite ){ -+ int rc2, isRO = 0; -+ sqlite3BeginBenignMalloc(); -+ rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); -+ sqlite3EndBenignMalloc(); -+ if( rc2==SQLITE_OK && isRO ) break; -+ } -+ }while( winRetryIoerr(&cnt, &lastErrno) ); - #endif - } - #ifdef SQLITE_WIN32_HAS_ANSI - else{ -- while( (h = osCreateFileA((LPCSTR)zConverted, -- dwDesiredAccess, -- dwShareMode, NULL, -- dwCreationDisposition, -- dwFlagsAndAttributes, -- NULL))==INVALID_HANDLE_VALUE && -- winRetryIoerr(&cnt, &lastErrno) ){ -- /* Noop */ -- } -+ do{ -+ h = osCreateFileA((LPCSTR)zConverted, -+ dwDesiredAccess, -+ dwShareMode, NULL, -+ dwCreationDisposition, -+ dwFlagsAndAttributes, -+ NULL); -+ if( h!=INVALID_HANDLE_VALUE ) break; -+ if( isReadWrite ){ -+ int rc2, isRO = 0; -+ sqlite3BeginBenignMalloc(); -+ rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); -+ sqlite3EndBenignMalloc(); -+ if( rc2==SQLITE_OK && isRO ) break; -+ } -+ }while( winRetryIoerr(&cnt, &lastErrno) ); - } - #endif - winLogIoerr(cnt, __LINE__); -@@ -43325,8 +45620,6 @@ - dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); - - if( h==INVALID_HANDLE_VALUE ){ -- pFile->lastErrno = lastErrno; -- winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); - sqlite3_free(zConverted); - sqlite3_free(zTmpname); - if( isReadWrite && !isExclusive ){ -@@ -43335,6 +45628,8 @@ - ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), - pOutFlags); - }else{ -+ pFile->lastErrno = lastErrno; -+ winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); - return SQLITE_CANTOPEN_BKPT; - } - } -@@ -43390,7 +45685,6 @@ - pFile->hMap = NULL; - pFile->pMapRegion = 0; - pFile->mmapSize = 0; -- pFile->mmapSizeActual = 0; - pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap; - #endif - -@@ -43927,9 +46221,6 @@ - EntropyGatherer e; - UNUSED_PARAMETER(pVfs); - memset(zBuf, 0, nBuf); --#if defined(_MSC_VER) && _MSC_VER>=1400 && !SQLITE_OS_WINCE -- rand_s((unsigned int*)zBuf); /* rand_s() is not available with MinGW */ --#endif /* defined(_MSC_VER) && _MSC_VER>=1400 */ - e.a = (unsigned char*)zBuf; - e.na = nBuf; - e.nXor = 0; -@@ -44224,6 +46515,10 @@ - sqlite3_vfs_register(&winLongPathNolockVfs, 0); - #endif - -+#ifndef SQLITE_OMIT_WAL -+ winBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); -+#endif -+ - return SQLITE_OK; - } - -@@ -44234,6 +46529,11 @@ - sleepObj = NULL; - } - #endif -+ -+#ifndef SQLITE_OMIT_WAL -+ winBigLock = 0; -+#endif -+ - return SQLITE_OK; - } - -@@ -44240,6 +46540,598 @@ - #endif /* SQLITE_OS_WIN */ - - /************** End of os_win.c **********************************************/ -+/************** Begin file memdb.c *******************************************/ -+/* -+** 2016-09-07 -+** -+** 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 an in-memory VFS. A database is held as a contiguous -+** block of memory. -+** -+** This file also implements interface sqlite3_serialize() and -+** sqlite3_deserialize(). -+*/ -+/* #include "sqliteInt.h" */ -+#ifdef SQLITE_ENABLE_DESERIALIZE -+ -+/* -+** Forward declaration of objects used by this utility -+*/ -+typedef struct sqlite3_vfs MemVfs; -+typedef struct MemFile MemFile; -+ -+/* Access to a lower-level VFS that (might) implement dynamic loading, -+** access to randomness, etc. -+*/ -+#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) -+ -+/* An open file */ -+struct MemFile { -+ sqlite3_file base; /* IO methods */ -+ sqlite3_int64 sz; /* Size of the file */ -+ sqlite3_int64 szMax; /* Space allocated to aData */ -+ unsigned char *aData; /* content of the file */ -+ int nMmap; /* Number of memory mapped pages */ -+ unsigned mFlags; /* Flags */ -+ int eLock; /* Most recent lock against this file */ -+}; -+ -+/* -+** Methods for MemFile -+*/ -+static int memdbClose(sqlite3_file*); -+static int memdbRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); -+static int memdbWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); -+static int memdbTruncate(sqlite3_file*, sqlite3_int64 size); -+static int memdbSync(sqlite3_file*, int flags); -+static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize); -+static int memdbLock(sqlite3_file*, int); -+/* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */ -+static int memdbFileControl(sqlite3_file*, int op, void *pArg); -+/* static int memdbSectorSize(sqlite3_file*); // not used */ -+static int memdbDeviceCharacteristics(sqlite3_file*); -+static int memdbFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); -+static int memdbUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p); -+ -+/* -+** Methods for MemVfs -+*/ -+static int memdbOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); -+/* static int memdbDelete(sqlite3_vfs*, const char *zName, int syncDir); */ -+static int memdbAccess(sqlite3_vfs*, const char *zName, int flags, int *); -+static int memdbFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); -+static void *memdbDlOpen(sqlite3_vfs*, const char *zFilename); -+static void memdbDlError(sqlite3_vfs*, int nByte, char *zErrMsg); -+static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void); -+static void memdbDlClose(sqlite3_vfs*, void*); -+static int memdbRandomness(sqlite3_vfs*, int nByte, char *zOut); -+static int memdbSleep(sqlite3_vfs*, int microseconds); -+/* static int memdbCurrentTime(sqlite3_vfs*, double*); */ -+static int memdbGetLastError(sqlite3_vfs*, int, char *); -+static int memdbCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); -+ -+static sqlite3_vfs memdb_vfs = { -+ 2, /* iVersion */ -+ 0, /* szOsFile (set when registered) */ -+ 1024, /* mxPathname */ -+ 0, /* pNext */ -+ "memdb", /* zName */ -+ 0, /* pAppData (set when registered) */ -+ memdbOpen, /* xOpen */ -+ 0, /* memdbDelete, */ /* xDelete */ -+ memdbAccess, /* xAccess */ -+ memdbFullPathname, /* xFullPathname */ -+ memdbDlOpen, /* xDlOpen */ -+ memdbDlError, /* xDlError */ -+ memdbDlSym, /* xDlSym */ -+ memdbDlClose, /* xDlClose */ -+ memdbRandomness, /* xRandomness */ -+ memdbSleep, /* xSleep */ -+ 0, /* memdbCurrentTime, */ /* xCurrentTime */ -+ memdbGetLastError, /* xGetLastError */ -+ memdbCurrentTimeInt64 /* xCurrentTimeInt64 */ -+}; -+ -+static const sqlite3_io_methods memdb_io_methods = { -+ 3, /* iVersion */ -+ memdbClose, /* xClose */ -+ memdbRead, /* xRead */ -+ memdbWrite, /* xWrite */ -+ memdbTruncate, /* xTruncate */ -+ memdbSync, /* xSync */ -+ memdbFileSize, /* xFileSize */ -+ memdbLock, /* xLock */ -+ memdbLock, /* xUnlock - same as xLock in this case */ -+ 0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */ -+ memdbFileControl, /* xFileControl */ -+ 0, /* memdbSectorSize,*/ /* xSectorSize */ -+ memdbDeviceCharacteristics, /* xDeviceCharacteristics */ -+ 0, /* xShmMap */ -+ 0, /* xShmLock */ -+ 0, /* xShmBarrier */ -+ 0, /* xShmUnmap */ -+ memdbFetch, /* xFetch */ -+ memdbUnfetch /* xUnfetch */ -+}; -+ -+ -+ -+/* -+** Close an memdb-file. -+** -+** The pData pointer is owned by the application, so there is nothing -+** to free. -+*/ -+static int memdbClose(sqlite3_file *pFile){ -+ MemFile *p = (MemFile *)pFile; -+ if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ) sqlite3_free(p->aData); -+ return SQLITE_OK; -+} -+ -+/* -+** Read data from an memdb-file. -+*/ -+static int memdbRead( -+ sqlite3_file *pFile, -+ void *zBuf, -+ int iAmt, -+ sqlite_int64 iOfst -+){ -+ MemFile *p = (MemFile *)pFile; -+ if( iOfst+iAmt>p->sz ){ -+ memset(zBuf, 0, iAmt); -+ if( iOfst<p->sz ) memcpy(zBuf, p->aData+iOfst, p->sz - iOfst); -+ return SQLITE_IOERR_SHORT_READ; -+ } -+ memcpy(zBuf, p->aData+iOfst, iAmt); -+ return SQLITE_OK; -+} -+ -+/* -+** Try to enlarge the memory allocation to hold at least sz bytes -+*/ -+static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){ -+ unsigned char *pNew; -+ if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){ -+ return SQLITE_FULL; -+ } -+ pNew = sqlite3_realloc64(p->aData, newSz); -+ if( pNew==0 ) return SQLITE_NOMEM; -+ p->aData = pNew; -+ p->szMax = newSz; -+ return SQLITE_OK; -+} -+ -+/* -+** Write data to an memdb-file. -+*/ -+static int memdbWrite( -+ sqlite3_file *pFile, -+ const void *z, -+ int iAmt, -+ sqlite_int64 iOfst -+){ -+ MemFile *p = (MemFile *)pFile; -+ if( iOfst+iAmt>p->sz ){ -+ int rc; -+ if( iOfst+iAmt>p->szMax -+ && (rc = memdbEnlarge(p, (iOfst+iAmt)*2))!=SQLITE_OK -+ ){ -+ return rc; -+ } -+ if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz); -+ p->sz = iOfst+iAmt; -+ } -+ memcpy(p->aData+iOfst, z, iAmt); -+ return SQLITE_OK; -+} -+ -+/* -+** Truncate an memdb-file. -+** -+** In rollback mode (which is always the case for memdb, as it does not -+** support WAL mode) the truncate() method is only used to reduce -+** the size of a file, never to increase the size. -+*/ -+static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){ -+ MemFile *p = (MemFile *)pFile; -+ if( NEVER(size>p->sz) ) return SQLITE_FULL; -+ p->sz = size; -+ return SQLITE_OK; -+} -+ -+/* -+** Sync an memdb-file. -+*/ -+static int memdbSync(sqlite3_file *pFile, int flags){ -+ return SQLITE_OK; -+} -+ -+/* -+** Return the current file-size of an memdb-file. -+*/ -+static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ -+ MemFile *p = (MemFile *)pFile; -+ *pSize = p->sz; -+ return SQLITE_OK; -+} -+ -+/* -+** Lock an memdb-file. -+*/ -+static int memdbLock(sqlite3_file *pFile, int eLock){ -+ MemFile *p = (MemFile *)pFile; -+ p->eLock = eLock; -+ return SQLITE_OK; -+} -+ -+#if 0 /* Never used because memdbAccess() always returns false */ -+/* -+** Check if another file-handle holds a RESERVED lock on an memdb-file. -+*/ -+static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){ -+ *pResOut = 0; -+ return SQLITE_OK; -+} -+#endif -+ -+/* -+** File control method. For custom operations on an memdb-file. -+*/ -+static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){ -+ MemFile *p = (MemFile *)pFile; -+ int rc = SQLITE_NOTFOUND; -+ if( op==SQLITE_FCNTL_VFSNAME ){ -+ *(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz); -+ rc = SQLITE_OK; -+ } -+ return rc; -+} -+ -+#if 0 /* Not used because of SQLITE_IOCAP_POWERSAFE_OVERWRITE */ -+/* -+** Return the sector-size in bytes for an memdb-file. -+*/ -+static int memdbSectorSize(sqlite3_file *pFile){ -+ return 1024; -+} -+#endif -+ -+/* -+** Return the device characteristic flags supported by an memdb-file. -+*/ -+static int memdbDeviceCharacteristics(sqlite3_file *pFile){ -+ return SQLITE_IOCAP_ATOMIC | -+ SQLITE_IOCAP_POWERSAFE_OVERWRITE | -+ SQLITE_IOCAP_SAFE_APPEND | -+ SQLITE_IOCAP_SEQUENTIAL; -+} -+ -+/* Fetch a page of a memory-mapped file */ -+static int memdbFetch( -+ sqlite3_file *pFile, -+ sqlite3_int64 iOfst, -+ int iAmt, -+ void **pp -+){ -+ MemFile *p = (MemFile *)pFile; -+ p->nMmap++; -+ *pp = (void*)(p->aData + iOfst); -+ return SQLITE_OK; -+} -+ -+/* Release a memory-mapped page */ -+static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ -+ MemFile *p = (MemFile *)pFile; -+ p->nMmap--; -+ return SQLITE_OK; -+} -+ -+/* -+** Open an mem file handle. -+*/ -+static int memdbOpen( -+ sqlite3_vfs *pVfs, -+ const char *zName, -+ sqlite3_file *pFile, -+ int flags, -+ int *pOutFlags -+){ -+ MemFile *p = (MemFile*)pFile; -+ if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){ -+ return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFile, flags, pOutFlags); -+ } -+ memset(p, 0, sizeof(*p)); -+ p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE; -+ assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */ -+ *pOutFlags = flags | SQLITE_OPEN_MEMORY; -+ p->base.pMethods = &memdb_io_methods; -+ return SQLITE_OK; -+} -+ -+#if 0 /* Only used to delete rollback journals, master journals, and WAL -+ ** files, none of which exist in memdb. So this routine is never used */ -+/* -+** Delete the file located at zPath. If the dirSync argument is true, -+** ensure the file-system modifications are synced to disk before -+** returning. -+*/ -+static int memdbDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ -+ return SQLITE_IOERR_DELETE; -+} -+#endif -+ -+/* -+** Test for access permissions. Return true if the requested permission -+** is available, or false otherwise. -+** -+** With memdb, no files ever exist on disk. So always return false. -+*/ -+static int memdbAccess( -+ sqlite3_vfs *pVfs, -+ const char *zPath, -+ int flags, -+ int *pResOut -+){ -+ *pResOut = 0; -+ return SQLITE_OK; -+} -+ -+/* -+** Populate buffer zOut with the full canonical pathname corresponding -+** to the pathname in zPath. zOut is guaranteed to point to a buffer -+** of at least (INST_MAX_PATHNAME+1) bytes. -+*/ -+static int memdbFullPathname( -+ sqlite3_vfs *pVfs, -+ const char *zPath, -+ int nOut, -+ char *zOut -+){ -+ sqlite3_snprintf(nOut, zOut, "%s", zPath); -+ return SQLITE_OK; -+} -+ -+/* -+** Open the dynamic library located at zPath and return a handle. -+*/ -+static void *memdbDlOpen(sqlite3_vfs *pVfs, const char *zPath){ -+ return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath); -+} -+ -+/* -+** Populate the buffer zErrMsg (size nByte bytes) with a human readable -+** utf-8 string describing the most recent error encountered associated -+** with dynamic libraries. -+*/ -+static void memdbDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ -+ ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg); -+} -+ -+/* -+** Return a pointer to the symbol zSymbol in the dynamic library pHandle. -+*/ -+static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){ -+ return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym); -+} -+ -+/* -+** Close the dynamic library handle pHandle. -+*/ -+static void memdbDlClose(sqlite3_vfs *pVfs, void *pHandle){ -+ ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle); -+} -+ -+/* -+** Populate the buffer pointed to by zBufOut with nByte bytes of -+** random data. -+*/ -+static int memdbRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ -+ return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut); -+} -+ -+/* -+** Sleep for nMicro microseconds. Return the number of microseconds -+** actually slept. -+*/ -+static int memdbSleep(sqlite3_vfs *pVfs, int nMicro){ -+ return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro); -+} -+ -+#if 0 /* Never used. Modern cores only call xCurrentTimeInt64() */ -+/* -+** Return the current time as a Julian Day number in *pTimeOut. -+*/ -+static int memdbCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ -+ return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut); -+} -+#endif -+ -+static int memdbGetLastError(sqlite3_vfs *pVfs, int a, char *b){ -+ return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b); -+} -+static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ -+ return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p); -+} -+ -+/* -+** Translate a database connection pointer and schema name into a -+** MemFile pointer. -+*/ -+static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){ -+ MemFile *p = 0; -+ int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p); -+ if( rc ) return 0; -+ if( p->base.pMethods!=&memdb_io_methods ) return 0; -+ return p; -+} -+ -+/* -+** Return the serialization of a database -+*/ -+SQLITE_API unsigned char *sqlite3_serialize( -+ sqlite3 *db, /* The database connection */ -+ const char *zSchema, /* Which database within the connection */ -+ sqlite3_int64 *piSize, /* Write size here, if not NULL */ -+ unsigned int mFlags /* Maybe SQLITE_SERIALIZE_NOCOPY */ -+){ -+ MemFile *p; -+ int iDb; -+ Btree *pBt; -+ sqlite3_int64 sz; -+ int szPage = 0; -+ sqlite3_stmt *pStmt = 0; -+ unsigned char *pOut; -+ char *zSql; -+ int rc; -+ -+#ifdef SQLITE_ENABLE_API_ARMOR -+ if( !sqlite3SafetyCheckOk(db) ){ -+ (void)SQLITE_MISUSE_BKPT; -+ return 0; -+ } -+#endif -+ -+ if( zSchema==0 ) zSchema = db->aDb[0].zDbSName; -+ p = memdbFromDbSchema(db, zSchema); -+ iDb = sqlite3FindDbName(db, zSchema); -+ if( piSize ) *piSize = -1; -+ if( iDb<0 ) return 0; -+ if( p ){ -+ if( piSize ) *piSize = p->sz; -+ if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ -+ pOut = p->aData; -+ }else{ -+ pOut = sqlite3_malloc64( p->sz ); -+ if( pOut ) memcpy(pOut, p->aData, p->sz); -+ } -+ return pOut; -+ } -+ pBt = db->aDb[iDb].pBt; -+ if( pBt==0 ) return 0; -+ szPage = sqlite3BtreeGetPageSize(pBt); -+ zSql = sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema); -+ rc = zSql ? sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM; -+ sqlite3_free(zSql); -+ if( rc ) return 0; -+ rc = sqlite3_step(pStmt); -+ if( rc!=SQLITE_ROW ){ -+ pOut = 0; -+ }else{ -+ sz = sqlite3_column_int64(pStmt, 0)*szPage; -+ if( piSize ) *piSize = sz; -+ if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ -+ pOut = 0; -+ }else{ -+ pOut = sqlite3_malloc64( sz ); -+ if( pOut ){ -+ int nPage = sqlite3_column_int(pStmt, 0); -+ Pager *pPager = sqlite3BtreePager(pBt); -+ int pgno; -+ for(pgno=1; pgno<=nPage; pgno++){ -+ DbPage *pPage = 0; -+ unsigned char *pTo = pOut + szPage*(sqlite3_int64)(pgno-1); -+ rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pPage, 0); -+ if( rc==SQLITE_OK ){ -+ memcpy(pTo, sqlite3PagerGetData(pPage), szPage); -+ }else{ -+ memset(pTo, 0, szPage); -+ } -+ sqlite3PagerUnref(pPage); -+ } -+ } -+ } -+ } -+ sqlite3_finalize(pStmt); -+ return pOut; -+} -+ -+/* Convert zSchema to a MemDB and initialize its content. -+*/ -+SQLITE_API int sqlite3_deserialize( -+ sqlite3 *db, /* The database connection */ -+ const char *zSchema, /* Which DB to reopen with the deserialization */ -+ unsigned char *pData, /* The serialized database content */ -+ sqlite3_int64 szDb, /* Number bytes in the deserialization */ -+ sqlite3_int64 szBuf, /* Total size of buffer pData[] */ -+ unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */ -+){ -+ MemFile *p; -+ char *zSql; -+ sqlite3_stmt *pStmt = 0; -+ int rc; -+ int iDb; -+ -+#ifdef SQLITE_ENABLE_API_ARMOR -+ if( !sqlite3SafetyCheckOk(db) ){ -+ return SQLITE_MISUSE_BKPT; -+ } -+ if( szDb<0 ) return SQLITE_MISUSE_BKPT; -+ if( szBuf<0 ) return SQLITE_MISUSE_BKPT; -+#endif -+ -+ sqlite3_mutex_enter(db->mutex); -+ if( zSchema==0 ) zSchema = db->aDb[0].zDbSName; -+ iDb = sqlite3FindDbName(db, zSchema); -+ if( iDb<0 ){ -+ rc = SQLITE_ERROR; -+ goto end_deserialize; -+ } -+ zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema); -+ rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); -+ sqlite3_free(zSql); -+ if( rc ) goto end_deserialize; -+ db->init.iDb = (u8)iDb; -+ db->init.reopenMemdb = 1; -+ rc = sqlite3_step(pStmt); -+ db->init.reopenMemdb = 0; -+ if( rc!=SQLITE_DONE ){ -+ rc = SQLITE_ERROR; -+ goto end_deserialize; -+ } -+ p = memdbFromDbSchema(db, zSchema); -+ if( p==0 ){ -+ rc = SQLITE_ERROR; -+ }else{ -+ p->aData = pData; -+ p->sz = szDb; -+ p->szMax = szBuf; -+ p->mFlags = mFlags; -+ rc = SQLITE_OK; -+ } -+ -+end_deserialize: -+ sqlite3_finalize(pStmt); -+ sqlite3_mutex_leave(db->mutex); -+ return rc; -+} -+ -+/* -+** This routine is called when the extension is loaded. -+** Register the new VFS. -+*/ -+SQLITE_PRIVATE int sqlite3MemdbInit(void){ -+ sqlite3_vfs *pLower = sqlite3_vfs_find(0); -+ int sz = pLower->szOsFile; -+ memdb_vfs.pAppData = pLower; -+ /* In all known configurations of SQLite, the size of a default -+ ** sqlite3_file is greater than the size of a memdb sqlite3_file. -+ ** Should that ever change, remove the following NEVER() */ -+ if( NEVER(sz<sizeof(MemFile)) ) sz = sizeof(MemFile); -+ memdb_vfs.szOsFile = sz; -+ return sqlite3_vfs_register(&memdb_vfs, 0); -+} -+#endif /* SQLITE_ENABLE_DESERIALIZE */ -+ -+/************** End of memdb.c ***********************************************/ - /************** Begin file bitvec.c ******************************************/ - /* - ** 2008 February 16 -@@ -44689,7 +47581,7 @@ - ** The PCache.pSynced variable is used to optimize searching for a dirty - ** page to eject from the cache mid-transaction. It is better to eject - ** a page that does not require a journal sync than one that does. --** Therefore, pSynced is maintained to that it *almost* always points -+** Therefore, pSynced is maintained so that it *almost* always points - ** to either the oldest page in the pDirty/pDirtyTail list that has a - ** clear PGHDR_NEED_SYNC flag or to a page that is older than this one - ** (so that the right page to eject can be found by following pDirtyPrev -@@ -44848,12 +47740,9 @@ - p->eCreate = 2; - } - } -- pPage->pDirtyNext = 0; -- pPage->pDirtyPrev = 0; - } - if( addRemove & PCACHE_DIRTYLIST_ADD ){ -- assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage ); -- -+ pPage->pDirtyPrev = 0; - pPage->pDirtyNext = p->pDirty; - if( pPage->pDirtyNext ){ - assert( pPage->pDirtyNext->pDirtyPrev==0 ); -@@ -45091,7 +47980,7 @@ - sqlite3_log(SQLITE_FULL, - "spill page %d making room for %d - cache used: %d/%d", - pPg->pgno, pgno, -- sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), -+ sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache), - numberOfCachePages(pCache)); - #endif - pcacheTrace(("%p.SPILL %d\n",pCache,pPg->pgno)); -@@ -45170,11 +48059,7 @@ - if( (--p->nRef)==0 ){ - if( p->flags&PGHDR_CLEAN ){ - pcacheUnpin(p); -- }else if( p->pDirtyPrev!=0 ){ /*OPTIMIZATION-IF-FALSE*/ -- /* Move the page to the head of the dirty list. If p->pDirtyPrev==0, -- ** then page p is already at the head of the dirty list and the -- ** following call would be a no-op. Hence the OPTIMIZATION-IF-FALSE -- ** tag above. */ -+ }else{ - pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); - } - } -@@ -45230,16 +48115,15 @@ - */ - SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){ - assert( sqlite3PcachePageSanity(p) ); -- if( ALWAYS((p->flags & PGHDR_DIRTY)!=0) ){ -- assert( (p->flags & PGHDR_CLEAN)==0 ); -- pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); -- p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE); -- p->flags |= PGHDR_CLEAN; -- pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno)); -- assert( sqlite3PcachePageSanity(p) ); -- if( p->nRef==0 ){ -- pcacheUnpin(p); -- } -+ assert( (p->flags & PGHDR_DIRTY)!=0 ); -+ assert( (p->flags & PGHDR_CLEAN)==0 ); -+ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); -+ p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE); -+ p->flags |= PGHDR_CLEAN; -+ pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno)); -+ assert( sqlite3PcachePageSanity(p) ); -+ if( p->nRef==0 ){ -+ pcacheUnpin(p); - } - } - -@@ -45521,6 +48405,15 @@ - return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0; - } - -+#ifdef SQLITE_DIRECT_OVERFLOW_READ -+/* -+** Return true if there are one or more dirty pages in the cache. Else false. -+*/ -+SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache){ -+ return (pCache->pDirty!=0); -+} -+#endif -+ - #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) - /* - ** For all dirty pages currently in the cache, invoke the specified -@@ -45635,7 +48528,6 @@ - struct PgHdr1 { - sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */ - unsigned int iKey; /* Key value (page number) */ -- u8 isPinned; /* Page in use, not on the LRU list */ - u8 isBulkLocal; /* This page from bulk local storage */ - u8 isAnchor; /* This is the PGroup.lru element */ - PgHdr1 *pNext; /* Next in hash table chain */ -@@ -45644,6 +48536,13 @@ - PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */ - }; - -+/* -+** A page is pinned if it is not on the LRU list. To be "pinned" means -+** that the page is in active use and must not be deallocated. -+*/ -+#define PAGE_IS_PINNED(p) ((p)->pLruNext==0) -+#define PAGE_IS_UNPINNED(p) ((p)->pLruNext!=0) -+ - /* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set - ** of one or more PCaches that are able to recycle each other's unpinned - ** pages when they are under memory pressure. A PGroup is an instance of -@@ -45671,7 +48570,7 @@ - unsigned int nMaxPage; /* Sum of nMax for purgeable caches */ - unsigned int nMinPage; /* Sum of nMin for purgeable caches */ - unsigned int mxPinned; /* nMaxpage + 10 - nMinPage */ -- unsigned int nCurrentPage; /* Number of purgeable pages allocated */ -+ unsigned int nPurgeable; /* Number of purgeable pages allocated */ - PgHdr1 lru; /* The beginning and end of the LRU list */ - }; - -@@ -45685,11 +48584,13 @@ - */ - struct PCache1 { - /* Cache configuration parameters. Page size (szPage) and the purgeable -- ** flag (bPurgeable) are set when the cache is created. nMax may be -+ ** flag (bPurgeable) and the pnPurgeable pointer are all set when the -+ ** cache is created and are never changed thereafter. nMax may be - ** modified at any time by a call to the pcache1Cachesize() method. - ** The PGroup mutex must be held when accessing nMax. - */ - PGroup *pGroup; /* PGroup this cache belongs to */ -+ unsigned int *pnPurgeable; /* Pointer to pGroup->nPurgeable */ - int szPage; /* Size of database content section */ - int szExtra; /* sizeof(MemPage)+sizeof(PgHdr) */ - int szAlloc; /* Total size of one pcache line */ -@@ -45784,6 +48685,7 @@ - if( pcache1.isInit ){ - PgFreeslot *p; - if( pBuf==0 ) sz = n = 0; -+ if( n==0 ) sz = 0; - sz = ROUNDDOWN8(sz); - pcache1.szSlot = sz; - pcache1.nSlot = pcache1.nFreeSlot = n; -@@ -45976,9 +48878,7 @@ - p->isBulkLocal = 0; - p->isAnchor = 0; - } -- if( pCache->bPurgeable ){ -- pCache->pGroup->nCurrentPage++; -- } -+ (*pCache->pnPurgeable)++; - return p; - } - -@@ -45999,9 +48899,7 @@ - sqlite3_free(p); - #endif - } -- if( pCache->bPurgeable ){ -- pCache->pGroup->nCurrentPage--; -- } -+ (*pCache->pnPurgeable)--; - } - - /* -@@ -46096,22 +48994,18 @@ - ** The PGroup mutex must be held when this function is called. - */ - static PgHdr1 *pcache1PinPage(PgHdr1 *pPage){ -- PCache1 *pCache; -- - assert( pPage!=0 ); -- assert( pPage->isPinned==0 ); -- pCache = pPage->pCache; -+ assert( PAGE_IS_UNPINNED(pPage) ); - assert( pPage->pLruNext ); - assert( pPage->pLruPrev ); -- assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); -+ assert( sqlite3_mutex_held(pPage->pCache->pGroup->mutex) ); - pPage->pLruPrev->pLruNext = pPage->pLruNext; - pPage->pLruNext->pLruPrev = pPage->pLruPrev; - pPage->pLruNext = 0; - pPage->pLruPrev = 0; -- pPage->isPinned = 1; - assert( pPage->isAnchor==0 ); -- assert( pCache->pGroup->lru.isAnchor==1 ); -- pCache->nRecyclable--; -+ assert( pPage->pCache->pGroup->lru.isAnchor==1 ); -+ pPage->pCache->nRecyclable--; - return pPage; - } - -@@ -46145,11 +49039,11 @@ - PGroup *pGroup = pCache->pGroup; - PgHdr1 *p; - assert( sqlite3_mutex_held(pGroup->mutex) ); -- while( pGroup->nCurrentPage>pGroup->nMaxPage -+ while( pGroup->nPurgeable>pGroup->nMaxPage - && (p=pGroup->lru.pLruPrev)->isAnchor==0 - ){ - assert( p->pCache->pGroup==pGroup ); -- assert( p->isPinned==0 ); -+ assert( PAGE_IS_UNPINNED(p) ); - pcache1PinPage(p); - pcache1RemoveFromHash(p, 1); - } -@@ -46198,7 +49092,7 @@ - if( pPage->iKey>=iLimit ){ - pCache->nPage--; - *pp = pPage->pNext; -- if( !pPage->isPinned ) pcache1PinPage(pPage); -+ if( PAGE_IS_UNPINNED(pPage) ) pcache1PinPage(pPage); - pcache1FreePage(pPage); - }else{ - pp = &pPage->pNext; -@@ -46316,6 +49210,10 @@ - pCache->nMin = 10; - pGroup->nMinPage += pCache->nMin; - pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; -+ pCache->pnPurgeable = &pGroup->nPurgeable; -+ }else{ -+ static unsigned int dummyCurrentPage; -+ pCache->pnPurgeable = &dummyCurrentPage; - } - pcache1LeaveMutex(pGroup); - if( pCache->nHash==0 ){ -@@ -46417,7 +49315,7 @@ - ){ - PCache1 *pOther; - pPage = pGroup->lru.pLruPrev; -- assert( pPage->isPinned==0 ); -+ assert( PAGE_IS_UNPINNED(pPage) ); - pcache1RemoveFromHash(pPage, 0); - pcache1PinPage(pPage); - pOther = pPage->pCache; -@@ -46425,7 +49323,7 @@ - pcache1FreePage(pPage); - pPage = 0; - }else{ -- pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable); -+ pGroup->nPurgeable -= (pOther->bPurgeable - pCache->bPurgeable); - } - } - -@@ -46444,7 +49342,6 @@ - pPage->pCache = pCache; - pPage->pLruPrev = 0; - pPage->pLruNext = 0; -- pPage->isPinned = 1; - *(void **)pPage->page.pExtra = 0; - pCache->apHash[h] = pPage; - if( iKey>pCache->iMaxKey ){ -@@ -46530,7 +49427,7 @@ - ** Otherwise (page not in hash and createFlag!=0) continue with - ** subsequent steps to try to create the page. */ - if( pPage ){ -- if( !pPage->isPinned ){ -+ if( PAGE_IS_UNPINNED(pPage) ){ - return pcache1PinPage(pPage); - }else{ - return pPage; -@@ -46605,9 +49502,9 @@ - ** part of the PGroup LRU list. - */ - assert( pPage->pLruPrev==0 && pPage->pLruNext==0 ); -- assert( pPage->isPinned==1 ); -+ assert( PAGE_IS_PINNED(pPage) ); - -- if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){ -+ if( reuseUnlikely || pGroup->nPurgeable>pGroup->nMaxPage ){ - pcache1RemoveFromHash(pPage, 1); - }else{ - /* Add the page to the PGroup LRU list. */ -@@ -46616,7 +49513,6 @@ - (pPage->pLruNext = *ppFirst)->pLruPrev = pPage; - *ppFirst = pPage; - pCache->nRecyclable++; -- pPage->isPinned = 0; - } - - pcache1LeaveMutex(pCache->pGroup); -@@ -46760,7 +49656,7 @@ - #ifdef SQLITE_PCACHE_SEPARATE_HEADER - nFree += sqlite3MemSize(p); - #endif -- assert( p->isPinned==0 ); -+ assert( PAGE_IS_UNPINNED(p) ); - pcache1PinPage(p); - pcache1RemoveFromHash(p, 1); - } -@@ -46784,10 +49680,10 @@ - PgHdr1 *p; - int nRecyclable = 0; - for(p=pcache1.grp.lru.pLruNext; p && !p->isAnchor; p=p->pLruNext){ -- assert( p->isPinned==0 ); -+ assert( PAGE_IS_UNPINNED(p) ); - nRecyclable++; - } -- *pnCurrent = pcache1.grp.nCurrentPage; -+ *pnCurrent = pcache1.grp.nPurgeable; - *pnMax = (int)pcache1.grp.nMaxPage; - *pnMin = (int)pcache1.grp.nMinPage; - *pnRecyclable = nRecyclable; -@@ -46922,30 +49818,23 @@ - #define ROWSET_NEXT 0x02 /* True if sqlite3RowSetNext() has been called */ - - /* --** Turn bulk memory into a RowSet object. N bytes of memory --** are available at pSpace. The db pointer is used as a memory context --** for any subsequent allocations that need to occur. --** Return a pointer to the new RowSet object. --** --** It must be the case that N is sufficient to make a Rowset. If not --** an assertion fault occurs. --** --** If N is larger than the minimum, use the surplus as an initial --** allocation of entries available to be filled. -+** Allocate a RowSet object. Return NULL if a memory allocation -+** error occurs. - */ --SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){ -- RowSet *p; -- assert( N >= ROUND8(sizeof(*p)) ); -- p = pSpace; -- p->pChunk = 0; -- p->db = db; -- p->pEntry = 0; -- p->pLast = 0; -- p->pForest = 0; -- p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p); -- p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry)); -- p->rsFlags = ROWSET_SORTED; -- p->iBatch = 0; -+SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db){ -+ RowSet *p = sqlite3DbMallocRawNN(db, sizeof(*p)); -+ if( p ){ -+ int N = sqlite3DbMallocSize(db, p); -+ p->pChunk = 0; -+ p->db = db; -+ p->pEntry = 0; -+ p->pLast = 0; -+ p->pForest = 0; -+ p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p); -+ p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry)); -+ p->rsFlags = ROWSET_SORTED; -+ p->iBatch = 0; -+ } - return p; - } - -@@ -46954,7 +49843,8 @@ - ** the RowSet has allocated over its lifetime. This routine is - ** the destructor for the RowSet. - */ --SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){ -+SQLITE_PRIVATE void sqlite3RowSetClear(void *pArg){ -+ RowSet *p = (RowSet*)pArg; - struct RowSetChunk *pChunk, *pNextChunk; - for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){ - pNextChunk = pChunk->pNextChunk; -@@ -46969,6 +49859,16 @@ - } - - /* -+** Deallocate all chunks from a RowSet. This frees all memory that -+** the RowSet has allocated over its lifetime. This routine is -+** the destructor for the RowSet. -+*/ -+SQLITE_PRIVATE void sqlite3RowSetDelete(void *pArg){ -+ sqlite3RowSetClear(pArg); -+ sqlite3DbFree(((RowSet*)pArg)->db, pArg); -+} -+ -+/* - ** Allocate a new RowSetEntry object that is associated with the - ** given RowSet. Return a pointer to the new and completely uninitialized - ** objected. -@@ -47342,11 +50242,11 @@ - - /* #include "sqliteInt.h" */ - --/* Additional values that can be added to the sync_flags argument of --** sqlite3WalFrames(): -+/* Macros for extracting appropriate sync flags for either transaction -+** commits (WAL_SYNC_FLAGS(X)) or for checkpoint ops (CKPT_SYNC_FLAGS(X)): - */ --#define WAL_SYNC_TRANSACTIONS 0x20 /* Sync at the end of each transaction */ --#define SQLITE_SYNC_MASK 0x13 /* Mask off the SQLITE_SYNC_* values */ -+#define WAL_SYNC_FLAGS(X) ((X)&0x03) -+#define CKPT_SYNC_FLAGS(X) (((X)>>2)&0x03) - - #ifdef SQLITE_OMIT_WAL - # define sqlite3WalOpen(x,y,z) 0 -@@ -47455,6 +50355,8 @@ - SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot); - SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot); - SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal); -+SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot); -+SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal); - #endif - - #ifdef SQLITE_ENABLE_ZIPVFS -@@ -47579,8 +50481,8 @@ - ** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file - ** struct as its argument. - */ --#define PAGERID(p) ((int)(p->fd)) --#define FILEHANDLEID(fd) ((int)fd) -+#define PAGERID(p) (SQLITE_PTR_TO_INT(p->fd)) -+#define FILEHANDLEID(fd) (SQLITE_PTR_TO_INT(fd)) - - /* - ** The Pager.eState variable stores the current 'state' of a pager. A -@@ -48067,6 +50969,18 @@ - ** is set to zero in all other states. In PAGER_ERROR state, Pager.errCode - ** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX - ** sub-codes. -+** -+** syncFlags, walSyncFlags -+** -+** syncFlags is either SQLITE_SYNC_NORMAL (0x02) or SQLITE_SYNC_FULL (0x03). -+** syncFlags is used for rollback mode. walSyncFlags is used for WAL mode -+** and contains the flags used to sync the checkpoint operations in the -+** lower two bits, and sync flags used for transaction commits in the WAL -+** file in bits 0x04 and 0x08. In other words, to get the correct sync flags -+** for checkpoint operations, use (walSyncFlags&0x03) and to get the correct -+** sync flags for transaction commit, use ((walSyncFlags>>2)&0x03). Note -+** that with synchronous=NORMAL in WAL mode, transaction commit is not synced -+** meaning that the 0x04 and 0x08 bits are both zero. - */ - struct Pager { - sqlite3_vfs *pVfs; /* OS functions to use for IO */ -@@ -48076,9 +50990,8 @@ - u8 noSync; /* Do not sync the journal if true */ - u8 fullSync; /* Do extra syncs of the journal for robustness */ - u8 extraSync; /* sync directory after journal delete */ -- u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ -- u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */ - u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ -+ u8 walSyncFlags; /* See description above */ - u8 tempFile; /* zFilename is a temporary or immutable file */ - u8 noLock; /* Do not lock (except in WAL mode) */ - u8 readOnly; /* True for a read-only database */ -@@ -48139,7 +51052,7 @@ - char *zJournal; /* Name of the journal file */ - int (*xBusyHandler)(void*); /* Function to call when busy */ - void *pBusyHandlerArg; /* Context argument for xBusyHandler */ -- int aStat[3]; /* Total cache hits, misses and writes */ -+ int aStat[4]; /* Total cache hits, misses, writes, spills */ - #ifdef SQLITE_TEST - int nRead; /* Database pages read */ - #endif -@@ -48167,6 +51080,7 @@ - #define PAGER_STAT_HIT 0 - #define PAGER_STAT_MISS 1 - #define PAGER_STAT_WRITE 2 -+#define PAGER_STAT_SPILL 3 - - /* - ** The following global variables hold counters used for -@@ -48264,19 +51178,30 @@ - */ - #define isOpen(pFd) ((pFd)->pMethods!=0) - -+#ifdef SQLITE_DIRECT_OVERFLOW_READ - /* --** Return true if this pager uses a write-ahead log to read page pgno. --** Return false if the pager reads pgno directly from the database. -+** Return true if page pgno can be read directly from the database file -+** by the b-tree layer. This is the case if: -+** -+** * the database file is open, -+** * there are no dirty pages in the cache, and -+** * the desired page is not currently in the wal file. - */ --#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_DIRECT_OVERFLOW_READ) --SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno pgno){ -- u32 iRead = 0; -- int rc; -- if( pPager->pWal==0 ) return 0; -- rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); -- return rc || iRead; -+SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ -+ if( pPager->fd->pMethods==0 ) return 0; -+ if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; -+#ifndef SQLITE_OMIT_WAL -+ if( pPager->pWal ){ -+ u32 iRead = 0; -+ int rc; -+ rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); -+ return (rc==SQLITE_OK && iRead==0); -+ } -+#endif -+ return 1; - } - #endif -+ - #ifndef SQLITE_OMIT_WAL - # define pagerUseWal(x) ((x)->pWal!=0) - #else -@@ -48398,6 +51323,7 @@ - assert( isOpen(p->jfd) - || p->journalMode==PAGER_JOURNALMODE_OFF - || p->journalMode==PAGER_JOURNALMODE_WAL -+ || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC) - ); - assert( pPager->dbOrigSize<=pPager->dbHintSize ); - break; -@@ -48409,6 +51335,7 @@ - assert( isOpen(p->jfd) - || p->journalMode==PAGER_JOURNALMODE_OFF - || p->journalMode==PAGER_JOURNALMODE_WAL -+ || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC) - ); - break; - -@@ -48434,8 +51361,12 @@ - ** to "print *pPager" in gdb: - ** - ** (gdb) printf "%s", print_pager_state(pPager) -+** -+** This routine has external linkage in order to suppress compiler warnings -+** about an unused function. It is enclosed within SQLITE_DEBUG and so does -+** not appear in normal builds. - */ --static char *print_pager_state(Pager *p){ -+char *print_pager_state(Pager *p){ - static char zRet[1024]; - - sqlite3_snprintf(1024, zRet, -@@ -48619,8 +51550,9 @@ - } - - /* --** This function determines whether or not the atomic-write optimization --** can be used with this pager. The optimization can be used if: -+** This function determines whether or not the atomic-write or -+** atomic-batch-write optimizations can be used with this pager. The -+** atomic-write optimization can be used if: - ** - ** (a) the value returned by OsDeviceCharacteristics() indicates that - ** a database page may be written atomically, and -@@ -48627,27 +51559,39 @@ - ** (b) the value returned by OsSectorSize() is less than or equal - ** to the page size. - ** --** The optimization is also always enabled for temporary files. It is --** an error to call this function if pPager is opened on an in-memory --** database. -+** If it can be used, then the value returned is the size of the journal -+** file when it contains rollback data for exactly one page. - ** --** If the optimization cannot be used, 0 is returned. If it can be used, --** then the value returned is the size of the journal file when it --** contains rollback data for exactly one page. -+** The atomic-batch-write optimization can be used if OsDeviceCharacteristics() -+** returns a value with the SQLITE_IOCAP_BATCH_ATOMIC bit set. -1 is -+** returned in this case. -+** -+** If neither optimization can be used, 0 is returned. - */ --#ifdef SQLITE_ENABLE_ATOMIC_WRITE - static int jrnlBufferSize(Pager *pPager){ - assert( !MEMDB ); -- if( !pPager->tempFile ){ -- int dc; /* Device characteristics */ -- int nSector; /* Sector size */ -- int szPage; /* Page size */ - -- assert( isOpen(pPager->fd) ); -- dc = sqlite3OsDeviceCharacteristics(pPager->fd); -- nSector = pPager->sectorSize; -- szPage = pPager->pageSize; -+#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ -+ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) -+ int dc; /* Device characteristics */ - -+ assert( isOpen(pPager->fd) ); -+ dc = sqlite3OsDeviceCharacteristics(pPager->fd); -+#else -+ UNUSED_PARAMETER(pPager); -+#endif -+ -+#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE -+ if( pPager->dbSize>0 && (dc&SQLITE_IOCAP_BATCH_ATOMIC) ){ -+ return -1; -+ } -+#endif -+ -+#ifdef SQLITE_ENABLE_ATOMIC_WRITE -+ { -+ int nSector = pPager->sectorSize; -+ int szPage = pPager->pageSize; -+ - assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); - assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); - if( 0==(dc&(SQLITE_IOCAP_ATOMIC|(szPage>>8)) || nSector>szPage) ){ -@@ -48656,11 +51600,11 @@ - } - - return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager); --} --#else --# define jrnlBufferSize(x) 0 - #endif - -+ return 0; -+} -+ - /* - ** If SQLITE_CHECK_PAGES is defined then we do some sanity checking - ** on the cache using a hash function. This is used for testing -@@ -48742,6 +51686,7 @@ - || szJ<16 - || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len)) - || len>=nMaster -+ || len>szJ-16 - || len==0 - || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum)) - || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8)) -@@ -49187,7 +52132,6 @@ - ** Return the pPager->iDataVersion value - */ - SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){ -- assert( pPager->eState>PAGER_OPEN ); - return pPager->iDataVersion; - } - -@@ -49463,7 +52407,9 @@ - } - - releaseAllSavepoints(pPager); -- assert( isOpen(pPager->jfd) || pPager->pInJournal==0 ); -+ assert( isOpen(pPager->jfd) || pPager->pInJournal==0 -+ || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_BATCH_ATOMIC) -+ ); - if( isOpen(pPager->jfd) ){ - assert( !pagerUseWal(pPager) ); - -@@ -49551,7 +52497,7 @@ - rc = pager_truncate(pPager, pPager->dbSize); - } - -- if( rc==SQLITE_OK && bCommit && isOpen(pPager->fd) ){ -+ if( rc==SQLITE_OK && bCommit ){ - rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0); - if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; - } -@@ -50231,6 +53177,7 @@ - char *zMaster = 0; /* Name of master journal file if any */ - int needPagerReset; /* True to reset page prior to first page rollback */ - int nPlayback = 0; /* Total number of pages restored from journal */ -+ u32 savedPageSize = pPager->pageSize; - - /* Figure out how many records are in the journal. Abort early if - ** the journal is empty. -@@ -50360,6 +53307,9 @@ - assert( 0 ); - - end_playback: -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3PagerSetPagesize(pPager, &savedPageSize, -1); -+ } - /* Following a rollback, the database file should be back in its original - ** state prior to the start of the transaction, so invoke the - ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the -@@ -50366,9 +53316,7 @@ - ** assertion that the transaction counter was modified. - */ - #ifdef SQLITE_DEBUG -- if( pPager->fd->pMethods ){ -- sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0); -- } -+ sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0); - #endif - - /* If this playback is happening automatically as a result of an IO or -@@ -50418,7 +53366,8 @@ - - - /* --** Read the content for page pPg out of the database file and into -+** Read the content for page pPg out of the database file (or out of -+** the WAL if that is where the most recent copy if found) into - ** pPg->pData. A shared lock or greater must be held on the database - ** file before this function is called. - ** -@@ -50428,30 +53377,33 @@ - ** If an IO error occurs, then the IO error is returned to the caller. - ** Otherwise, SQLITE_OK is returned. - */ --static int readDbPage(PgHdr *pPg, u32 iFrame){ -+static int readDbPage(PgHdr *pPg){ - Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */ -- Pgno pgno = pPg->pgno; /* Page number to read */ - int rc = SQLITE_OK; /* Return code */ -- int pgsz = pPager->pageSize; /* Number of bytes to read */ - -+#ifndef SQLITE_OMIT_WAL -+ u32 iFrame = 0; /* Frame of WAL containing pgno */ -+ - assert( pPager->eState>=PAGER_READER && !MEMDB ); - assert( isOpen(pPager->fd) ); - --#ifndef SQLITE_OMIT_WAL -+ if( pagerUseWal(pPager) ){ -+ rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame); -+ if( rc ) return rc; -+ } - if( iFrame ){ -- /* Try to pull the page from the write-ahead log. */ -- rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData); -+ rc = sqlite3WalReadFrame(pPager->pWal, iFrame,pPager->pageSize,pPg->pData); - }else - #endif - { -- i64 iOffset = (pgno-1)*(i64)pPager->pageSize; -- rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset); -+ i64 iOffset = (pPg->pgno-1)*(i64)pPager->pageSize; -+ rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset); - if( rc==SQLITE_IOERR_SHORT_READ ){ - rc = SQLITE_OK; - } - } - -- if( pgno==1 ){ -+ if( pPg->pgno==1 ){ - if( rc ){ - /* If the read is unsuccessful, set the dbFileVers[] to something - ** that will never be a valid file version. dbFileVers[] is a copy -@@ -50471,13 +53423,13 @@ - memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers)); - } - } -- CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM_BKPT); -+ CODEC1(pPager, pPg->pData, pPg->pgno, 3, rc = SQLITE_NOMEM_BKPT); - - PAGER_INCR(sqlite3_pager_readdb_count); - PAGER_INCR(pPager->nRead); -- IOTRACE(("PGIN %p %d\n", pPager, pgno)); -+ IOTRACE(("PGIN %p %d\n", pPager, pPg->pgno)); - PAGERTRACE(("FETCH %d page %d hash(%08x)\n", -- PAGERID(pPager), pgno, pager_pagehash(pPg))); -+ PAGERID(pPager), pPg->pgno, pager_pagehash(pPg))); - - return rc; - } -@@ -50528,12 +53480,8 @@ - if( sqlite3PcachePageRefcount(pPg)==1 ){ - sqlite3PcacheDrop(pPg); - }else{ -- u32 iFrame = 0; -- rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame); -+ rc = readDbPage(pPg); - if( rc==SQLITE_OK ){ -- rc = readDbPage(pPg, iFrame); -- } -- if( rc==SQLITE_OK ){ - pPager->xReiniter(pPg); - } - sqlite3PagerUnrefNotNull(pPg); -@@ -51038,21 +53986,18 @@ - } - if( pPager->noSync ){ - pPager->syncFlags = 0; -- pPager->ckptSyncFlags = 0; - }else if( pgFlags & PAGER_FULLFSYNC ){ - pPager->syncFlags = SQLITE_SYNC_FULL; -- pPager->ckptSyncFlags = SQLITE_SYNC_FULL; -- }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){ -- pPager->syncFlags = SQLITE_SYNC_NORMAL; -- pPager->ckptSyncFlags = SQLITE_SYNC_FULL; - }else{ - pPager->syncFlags = SQLITE_SYNC_NORMAL; -- pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; - } -- pPager->walSyncFlags = pPager->syncFlags; -+ pPager->walSyncFlags = (pPager->syncFlags<<2); - if( pPager->fullSync ){ -- pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS; -+ pPager->walSyncFlags |= pPager->syncFlags; - } -+ if( (pgFlags & PAGER_CKPT_FULLFSYNC) && !pPager->noSync ){ -+ pPager->walSyncFlags |= (SQLITE_SYNC_FULL<<2); -+ } - if( pgFlags & PAGER_CACHESPILL ){ - pPager->doNotSpill &= ~SPILLFLAG_OFF; - }else{ -@@ -51124,20 +54069,18 @@ - ** retried. If it returns zero, then the SQLITE_BUSY error is - ** returned to the caller of the pager API function. - */ --SQLITE_PRIVATE void sqlite3PagerSetBusyhandler( -+SQLITE_PRIVATE void sqlite3PagerSetBusyHandler( - Pager *pPager, /* Pager object */ - int (*xBusyHandler)(void *), /* Pointer to busy-handler function */ - void *pBusyHandlerArg /* Argument to pass to xBusyHandler */ - ){ -+ void **ap; - pPager->xBusyHandler = xBusyHandler; - pPager->pBusyHandlerArg = pBusyHandlerArg; -- -- if( isOpen(pPager->fd) ){ -- void **ap = (void **)&pPager->xBusyHandler; -- assert( ((int(*)(void *))(ap[0]))==xBusyHandler ); -- assert( ap[1]==pBusyHandlerArg ); -- sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap); -- } -+ ap = (void **)&pPager->xBusyHandler; -+ assert( ((int(*)(void *))(ap[0]))==xBusyHandler ); -+ assert( ap[1]==pBusyHandlerArg ); -+ sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap); - } - - /* -@@ -51523,7 +54466,31 @@ - } - } - -+/* Verify that the database file has not be deleted or renamed out from -+** under the pager. Return SQLITE_OK if the database is still where it ought -+** to be on disk. Return non-zero (SQLITE_READONLY_DBMOVED or some other error -+** code from sqlite3OsAccess()) if the database has gone missing. -+*/ -+static int databaseIsUnmoved(Pager *pPager){ -+ int bHasMoved = 0; -+ int rc; - -+ if( pPager->tempFile ) return SQLITE_OK; -+ if( pPager->dbSize==0 ) return SQLITE_OK; -+ assert( pPager->zFilename && pPager->zFilename[0] ); -+ rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved); -+ if( rc==SQLITE_NOTFOUND ){ -+ /* If the HAS_MOVED file-control is unimplemented, assume that the file -+ ** has not been moved. That is the historical behavior of SQLite: prior to -+ ** version 3.8.3, it never checked */ -+ rc = SQLITE_OK; -+ }else if( rc==SQLITE_OK && bHasMoved ){ -+ rc = SQLITE_READONLY_DBMOVED; -+ } -+ return rc; -+} -+ -+ - /* - ** Shutdown the page cache. Free all memory and close all files. - ** -@@ -51539,8 +54506,7 @@ - ** to the caller. - */ - SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){ -- u8 *pTmp = (u8 *)pPager->pTmpSpace; -- -+ u8 *pTmp = (u8*)pPager->pTmpSpace; - assert( db || pagerUseWal(pPager)==0 ); - assert( assert_pager_state(pPager) ); - disable_simulated_io_errors(); -@@ -51549,11 +54515,17 @@ - /* pPager->errCode = 0; */ - pPager->exclusiveMode = 0; - #ifndef SQLITE_OMIT_WAL -- assert( db || pPager->pWal==0 ); -- sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags, pPager->pageSize, -- (db && (db->flags & SQLITE_NoCkptOnClose) ? 0 : pTmp) -- ); -- pPager->pWal = 0; -+ { -+ u8 *a = 0; -+ assert( db || pPager->pWal==0 ); -+ if( db && 0==(db->flags & SQLITE_NoCkptOnClose) -+ && SQLITE_OK==databaseIsUnmoved(pPager) -+ ){ -+ a = pTmp; -+ } -+ sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a); -+ pPager->pWal = 0; -+ } - #endif - pager_reset(pPager); - if( MEMDB ){ -@@ -52010,6 +54982,7 @@ - return SQLITE_OK; - } - -+ pPager->aStat[PAGER_STAT_SPILL]++; - pPg->pDirty = 0; - if( pagerUseWal(pPager) ){ - /* Write a single frame for this page to the log. */ -@@ -52018,6 +54991,13 @@ - rc = pagerWalFrames(pPager, pPg, 0, 0); - } - }else{ -+ -+#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE -+ if( pPager->tempFile==0 ){ -+ rc = sqlite3JournalCreate(pPager->jfd); -+ if( rc!=SQLITE_OK ) return pager_error(pPager, rc); -+ } -+#endif - - /* Sync the journal file if required. */ - if( pPg->flags&PGHDR_NEED_SYNC -@@ -52108,6 +55088,11 @@ - int rc = SQLITE_OK; /* Return code */ - int tempFile = 0; /* True for temp files (incl. in-memory files) */ - int memDb = 0; /* True if this is an in-memory file */ -+#ifdef SQLITE_ENABLE_DESERIALIZE -+ int memJM = 0; /* Memory journal mode */ -+#else -+# define memJM 0 -+#endif - int readOnly = 0; /* True if this is a read-only file */ - int journalFileSize; /* Bytes to allocate for each journal fd */ - char *zPathname = 0; /* Full path to database file */ -@@ -52235,7 +55220,10 @@ - int fout = 0; /* VFS flags returned by xOpen() */ - rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); - assert( !memDb ); -- readOnly = (fout&SQLITE_OPEN_READONLY); -+#ifdef SQLITE_ENABLE_DESERIALIZE -+ memJM = (fout&SQLITE_OPEN_MEMORY)!=0; -+#endif -+ readOnly = (fout&SQLITE_OPEN_READONLY)!=0; - - /* If the file was successfully opened for read/write access, - ** choose a default page size in case we have to create the -@@ -52351,13 +55339,11 @@ - assert( pPager->extraSync==0 ); - assert( pPager->syncFlags==0 ); - assert( pPager->walSyncFlags==0 ); -- assert( pPager->ckptSyncFlags==0 ); - }else{ - pPager->fullSync = 1; - pPager->extraSync = 0; - pPager->syncFlags = SQLITE_SYNC_NORMAL; -- pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS; -- pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; -+ pPager->walSyncFlags = SQLITE_SYNC_NORMAL | (SQLITE_SYNC_NORMAL<<2); - } - /* pPager->pFirst = 0; */ - /* pPager->pFirstSynced = 0; */ -@@ -52368,7 +55354,7 @@ - setSectorSize(pPager); - if( !useJournal ){ - pPager->journalMode = PAGER_JOURNALMODE_OFF; -- }else if( memDb ){ -+ }else if( memDb || memJM ){ - pPager->journalMode = PAGER_JOURNALMODE_MEMORY; - } - /* pPager->xBusyHandler = 0; */ -@@ -52383,31 +55369,7 @@ - } - - --/* Verify that the database file has not be deleted or renamed out from --** under the pager. Return SQLITE_OK if the database is still were it ought --** to be on disk. Return non-zero (SQLITE_READONLY_DBMOVED or some other error --** code from sqlite3OsAccess()) if the database has gone missing. --*/ --static int databaseIsUnmoved(Pager *pPager){ -- int bHasMoved = 0; -- int rc; - -- if( pPager->tempFile ) return SQLITE_OK; -- if( pPager->dbSize==0 ) return SQLITE_OK; -- assert( pPager->zFilename && pPager->zFilename[0] ); -- rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved); -- if( rc==SQLITE_NOTFOUND ){ -- /* If the HAS_MOVED file-control is unimplemented, assume that the file -- ** has not been moved. That is the historical behavior of SQLite: prior to -- ** version 3.8.3, it never checked */ -- rc = SQLITE_OK; -- }else if( rc==SQLITE_OK && bHasMoved ){ -- rc = SQLITE_READONLY_DBMOVED; -- } -- return rc; --} -- -- - /* - ** This function is called after transitioning from PAGER_UNLOCK to - ** PAGER_SHARED state. It tests if there is a hot journal present in -@@ -52777,7 +55739,8 @@ - ** nothing to rollback, so this routine is a no-op. - */ - static void pagerUnlockIfUnused(Pager *pPager){ -- if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){ -+ if( sqlite3PcacheRefCount(pPager->pPCache)==0 ){ -+ assert( pPager->nMmapOut==0 ); /* because page1 is never memory mapped */ - pagerUnlockAndRollback(pPager); - } - } -@@ -52918,14 +55881,9 @@ - memset(pPg->pData, 0, pPager->pageSize); - IOTRACE(("ZERO %p %d\n", pPager, pgno)); - }else{ -- u32 iFrame = 0; /* Frame to read from WAL file */ -- if( pagerUseWal(pPager) ){ -- rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); -- if( rc!=SQLITE_OK ) goto pager_acquire_err; -- } - assert( pPg->pPager==pPager ); - pPager->aStat[PAGER_STAT_MISS]++; -- rc = readDbPage(pPg, iFrame); -+ rc = readDbPage(pPg); - if( rc!=SQLITE_OK ){ - goto pager_acquire_err; - } -@@ -52999,7 +55957,7 @@ - } - if( pPg==0 ){ - rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg); -- }else{ -+ }else{ - sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData); - } - if( pPg ){ -@@ -53068,25 +56026,40 @@ - /* - ** Release a page reference. - ** --** If the number of references to the page drop to zero, then the --** page is added to the LRU list. When all references to all pages --** are released, a rollback occurs and the lock on the database is --** removed. -+** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be -+** used if we know that the page being released is not the last page. -+** The btree layer always holds page1 open until the end, so these first -+** to routines can be used to release any page other than BtShared.pPage1. -+** -+** Use sqlite3PagerUnrefPageOne() to release page1. This latter routine -+** checks the total number of outstanding pages and if the number of -+** pages reaches zero it drops the database lock. - */ - SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){ -- Pager *pPager; -+ TESTONLY( Pager *pPager = pPg->pPager; ) - assert( pPg!=0 ); -- pPager = pPg->pPager; - if( pPg->flags & PGHDR_MMAP ){ -+ assert( pPg->pgno!=1 ); /* Page1 is never memory mapped */ - pagerReleaseMapPage(pPg); - }else{ - sqlite3PcacheRelease(pPg); - } -- pagerUnlockIfUnused(pPager); -+ /* Do not use this routine to release the last reference to page1 */ -+ assert( sqlite3PcacheRefCount(pPager->pPCache)>0 ); - } - SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){ - if( pPg ) sqlite3PagerUnrefNotNull(pPg); - } -+SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage *pPg){ -+ Pager *pPager; -+ assert( pPg!=0 ); -+ assert( pPg->pgno==1 ); -+ assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */ -+ pPager = pPg->pPager; -+ sqlite3PagerResetLockTimeout(pPager); -+ sqlite3PcacheRelease(pPg); -+ pagerUnlockIfUnused(pPager); -+} - - /* - ** This function is called at the start of every write transaction. -@@ -53679,12 +56652,9 @@ - */ - SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zMaster){ - int rc = SQLITE_OK; -- -- if( isOpen(pPager->fd) ){ -- void *pArg = (void*)zMaster; -- rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg); -- if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; -- } -+ void *pArg = (void*)zMaster; -+ rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg); -+ if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; - if( rc==SQLITE_OK && !pPager->noSync ){ - assert( !MEMDB ); - rc = sqlite3OsSync(pPager->fd, pPager->syncFlags); -@@ -53779,9 +56749,10 @@ - ** backup in progress needs to be restarted. */ - sqlite3BackupRestart(pPager->pBackup); - }else{ -+ PgHdr *pList; - if( pagerUseWal(pPager) ){ -- PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); - PgHdr *pPageOne = 0; -+ pList = sqlite3PcacheDirtyList(pPager->pPCache); - if( pList==0 ){ - /* Must have at least one page for the WAL commit flag. - ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */ -@@ -53798,6 +56769,21 @@ - sqlite3PcacheCleanAll(pPager->pPCache); - } - }else{ -+ /* The bBatch boolean is true if the batch-atomic-write commit method -+ ** should be used. No rollback journal is created if batch-atomic-write -+ ** is enabled. -+ */ -+#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE -+ sqlite3_file *fd = pPager->fd; -+ int bBatch = zMaster==0 /* An SQLITE_IOCAP_BATCH_ATOMIC commit */ -+ && (sqlite3OsDeviceCharacteristics(fd) & SQLITE_IOCAP_BATCH_ATOMIC) -+ && !pPager->noSync -+ && sqlite3JournalIsInMemory(pPager->jfd); -+#else -+# define bBatch 0 -+#endif -+ -+#ifdef SQLITE_ENABLE_ATOMIC_WRITE - /* The following block updates the change-counter. Exactly how it - ** does this depends on whether or not the atomic-update optimization - ** was enabled at compile time, and if this transaction meets the -@@ -53821,33 +56807,41 @@ - ** in 'direct' mode. In this case the journal file will never be - ** created for this transaction. - */ -- #ifdef SQLITE_ENABLE_ATOMIC_WRITE -- PgHdr *pPg; -- assert( isOpen(pPager->jfd) -- || pPager->journalMode==PAGER_JOURNALMODE_OFF -- || pPager->journalMode==PAGER_JOURNALMODE_WAL -- ); -- if( !zMaster && isOpen(pPager->jfd) -- && pPager->journalOff==jrnlBufferSize(pPager) -- && pPager->dbSize>=pPager->dbOrigSize -- && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) -- ){ -- /* Update the db file change counter via the direct-write method. The -- ** following call will modify the in-memory representation of page 1 -- ** to include the updated change counter and then write page 1 -- ** directly to the database file. Because of the atomic-write -- ** property of the host file-system, this is safe. -- */ -- rc = pager_incr_changecounter(pPager, 1); -- }else{ -- rc = sqlite3JournalCreate(pPager->jfd); -- if( rc==SQLITE_OK ){ -- rc = pager_incr_changecounter(pPager, 0); -+ if( bBatch==0 ){ -+ PgHdr *pPg; -+ assert( isOpen(pPager->jfd) -+ || pPager->journalMode==PAGER_JOURNALMODE_OFF -+ || pPager->journalMode==PAGER_JOURNALMODE_WAL -+ ); -+ if( !zMaster && isOpen(pPager->jfd) -+ && pPager->journalOff==jrnlBufferSize(pPager) -+ && pPager->dbSize>=pPager->dbOrigSize -+ && (!(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) -+ ){ -+ /* Update the db file change counter via the direct-write method. The -+ ** following call will modify the in-memory representation of page 1 -+ ** to include the updated change counter and then write page 1 -+ ** directly to the database file. Because of the atomic-write -+ ** property of the host file-system, this is safe. -+ */ -+ rc = pager_incr_changecounter(pPager, 1); -+ }else{ -+ rc = sqlite3JournalCreate(pPager->jfd); -+ if( rc==SQLITE_OK ){ -+ rc = pager_incr_changecounter(pPager, 0); -+ } - } - } -- #else -+#else /* SQLITE_ENABLE_ATOMIC_WRITE */ -+#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE -+ if( zMaster ){ -+ rc = sqlite3JournalCreate(pPager->jfd); -+ if( rc!=SQLITE_OK ) goto commit_phase_one_exit; -+ assert( bBatch==0 ); -+ } -+#endif - rc = pager_incr_changecounter(pPager, 0); -- #endif -+#endif /* !SQLITE_ENABLE_ATOMIC_WRITE */ - if( rc!=SQLITE_OK ) goto commit_phase_one_exit; - - /* Write the master journal name into the journal file. If a master -@@ -53870,8 +56864,37 @@ - */ - rc = syncJournal(pPager, 0); - if( rc!=SQLITE_OK ) goto commit_phase_one_exit; -- -- rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache)); -+ -+ pList = sqlite3PcacheDirtyList(pPager->pPCache); -+#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE -+ if( bBatch ){ -+ rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, 0); -+ if( rc==SQLITE_OK ){ -+ rc = pager_write_pagelist(pPager, pList); -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0); -+ } -+ if( rc!=SQLITE_OK ){ -+ sqlite3OsFileControlHint(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0); -+ } -+ } -+ -+ if( (rc&0xFF)==SQLITE_IOERR && rc!=SQLITE_IOERR_NOMEM ){ -+ rc = sqlite3JournalCreate(pPager->jfd); -+ if( rc!=SQLITE_OK ){ -+ sqlite3OsClose(pPager->jfd); -+ goto commit_phase_one_exit; -+ } -+ bBatch = 0; -+ }else{ -+ sqlite3OsClose(pPager->jfd); -+ } -+ } -+#endif /* SQLITE_ENABLE_BATCH_ATOMIC_WRITE */ -+ -+ if( bBatch==0 ){ -+ rc = pager_write_pagelist(pPager, pList); -+ } - if( rc!=SQLITE_OK ){ - assert( rc!=SQLITE_IOERR_BLOCKED ); - goto commit_phase_one_exit; -@@ -54092,8 +57115,12 @@ - #endif - - /* --** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or --** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the -+** Parameter eStat must be one of SQLITE_DBSTATUS_CACHE_HIT, _MISS, _WRITE, -+** or _WRITE+1. The SQLITE_DBSTATUS_CACHE_WRITE+1 case is a translation -+** of SQLITE_DBSTATUS_CACHE_SPILL. The _SPILL case is not contiguous because -+** it was added later. -+** -+** Before returning, *pnVal is incremented by the - ** current cache hit or miss count, according to the value of eStat. If the - ** reset parameter is non-zero, the cache hit or miss count is zeroed before - ** returning. -@@ -54103,15 +57130,18 @@ - assert( eStat==SQLITE_DBSTATUS_CACHE_HIT - || eStat==SQLITE_DBSTATUS_CACHE_MISS - || eStat==SQLITE_DBSTATUS_CACHE_WRITE -+ || eStat==SQLITE_DBSTATUS_CACHE_WRITE+1 - ); - - assert( SQLITE_DBSTATUS_CACHE_HIT+1==SQLITE_DBSTATUS_CACHE_MISS ); - assert( SQLITE_DBSTATUS_CACHE_HIT+2==SQLITE_DBSTATUS_CACHE_WRITE ); -- assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 && PAGER_STAT_WRITE==2 ); -+ assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 -+ && PAGER_STAT_WRITE==2 && PAGER_STAT_SPILL==3 ); - -- *pnVal += pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT]; -+ eStat -= SQLITE_DBSTATUS_CACHE_HIT; -+ *pnVal += pPager->aStat[eStat]; - if( reset ){ -- pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT] = 0; -+ pPager->aStat[eStat] = 0; - } - } - -@@ -54315,7 +57345,17 @@ - return pPager->fd; - } - -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - /* -+** Reset the lock timeout for pager. -+*/ -+SQLITE_PRIVATE void sqlite3PagerResetLockTimeout(Pager *pPager){ -+ int x = 0; -+ sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCK_TIMEOUT, &x); -+} -+#endif -+ -+/* - ** Return the file handle for the journal file (if it exists). - ** This will be either the rollback journal or the WAL file. - */ -@@ -54345,7 +57385,11 @@ - void (*xCodecFree)(void*), - void *pCodec - ){ -- if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec); -+ if( pPager->xCodecFree ){ -+ pPager->xCodecFree(pPager->pCodec); -+ }else{ -+ pager_reset(pPager); -+ } - pPager->xCodec = pPager->memDb ? 0 : xCodec; - pPager->xCodecSizeChng = xCodecSizeChng; - pPager->xCodecFree = xCodecFree; -@@ -54606,13 +57650,6 @@ - SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ - u8 eOld = pPager->journalMode; /* Prior journalmode */ - --#ifdef SQLITE_DEBUG -- /* The print_pager_state() routine is intended to be used by the debugger -- ** only. We invoke it once here to suppress a compiler warning. */ -- print_pager_state(pPager); --#endif -- -- - /* The eMode parameter is always valid */ - assert( eMode==PAGER_JOURNALMODE_DELETE - || eMode==PAGER_JOURNALMODE_TRUNCATE -@@ -54772,9 +57809,10 @@ - rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode, - (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler), - pPager->pBusyHandlerArg, -- pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, -+ pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, - pnLog, pnCkpt - ); -+ sqlite3PagerResetLockTimeout(pPager); - } - return rc; - } -@@ -54929,7 +57967,7 @@ - if( rc==SQLITE_OK && pPager->pWal ){ - rc = pagerExclusiveLock(pPager); - if( rc==SQLITE_OK ){ -- rc = sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags, -+ rc = sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, - pPager->pageSize, (u8*)pPager->pTmpSpace); - pPager->pWal = 0; - pagerFixMaplimit(pPager); -@@ -54980,6 +58018,38 @@ - } - return rc; - } -+ -+/* -+** The caller currently has a read transaction open on the database. -+** If this is not a WAL database, SQLITE_ERROR is returned. Otherwise, -+** this function takes a SHARED lock on the CHECKPOINTER slot and then -+** checks if the snapshot passed as the second argument is still -+** available. If so, SQLITE_OK is returned. -+** -+** If the snapshot is not available, SQLITE_ERROR is returned. Or, if -+** the CHECKPOINTER lock cannot be obtained, SQLITE_BUSY. If any error -+** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER -+** lock is released before returning. -+*/ -+SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot){ -+ int rc; -+ if( pPager->pWal ){ -+ rc = sqlite3WalSnapshotCheck(pPager->pWal, pSnapshot); -+ }else{ -+ rc = SQLITE_ERROR; -+ } -+ return rc; -+} -+ -+/* -+** Release a lock obtained by an earlier successful call to -+** sqlite3PagerSnapshotCheck(). -+*/ -+SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager){ -+ assert( pPager->pWal ); -+ return sqlite3WalSnapshotUnlock(pPager->pWal); -+} -+ - #endif /* SQLITE_ENABLE_SNAPSHOT */ - #endif /* !SQLITE_OMIT_WAL */ - -@@ -55135,6 +58205,10 @@ - ** on a network filesystem. All users of the database must be able to - ** share memory. - ** -+** In the default unix and windows implementation, the wal-index is a mmapped -+** file whose name is the database name with a "-shm" suffix added. For that -+** reason, the wal-index is sometimes called the "shm" file. -+** - ** The wal-index is transient. After a crash, the wal-index can (and should - ** be) reconstructed from the original WAL file. In fact, the VFS is required - ** to either truncate or zero the header of the wal-index when the last -@@ -55258,6 +58332,18 @@ - #endif - - /* -+** WAL mode depends on atomic aligned 32-bit loads and stores in a few -+** places. The following macros try to make this explicit. -+*/ -+#if GCC_VESRION>=5004000 -+# define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED) -+# define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED) -+#else -+# define AtomicLoad(PTR) (*(PTR)) -+# define AtomicStore(PTR,VAL) (*(PTR) = (VAL)) -+#endif -+ -+/* - ** The maximum (and only) versions of the wal and wal-index formats - ** that may be interpreted by this version of SQLite. - ** -@@ -55274,9 +58360,18 @@ - #define WALINDEX_MAX_VERSION 3007000 - - /* --** Indices of various locking bytes. WAL_NREADER is the number -+** Index numbers for various locking bytes. WAL_NREADER is the number - ** of available reader locks and should be at least 3. The default - ** is SQLITE_SHM_NLOCK==8 and WAL_NREADER==5. -+** -+** Technically, the various VFSes are free to implement these locks however -+** they see fit. However, compatibility is encouraged so that VFSes can -+** interoperate. The standard implemention used on both unix and windows -+** is for the index number to indicate a byte offset into the -+** WalCkptInfo.aLock[] array in the wal-index header. In other words, all -+** locks are on the shm file. The WALINDEX_LOCK_OFFSET constant (which -+** should be 120) is the location in the shm file for the first locking -+** byte. - */ - #define WAL_WRITE_LOCK 0 - #define WAL_ALL_BUT_WRITE 1 -@@ -55400,7 +58495,6 @@ - #define WAL_FRAME_HDRSIZE 24 - - /* Size of write ahead log header, including checksum. */ --/* #define WAL_HDRSIZE 24 */ - #define WAL_HDRSIZE 32 - - /* WAL magic value. Either this value, or the same value with the least -@@ -55446,6 +58540,7 @@ - u8 truncateOnCommit; /* True to truncate WAL file on commit */ - u8 syncHeader; /* Fsync the WAL header if true */ - u8 padToSectorBoundary; /* Pad transactions out to the next sector */ -+ u8 bShmUnreliable; /* SHM content is read-only and unreliable */ - WalIndexHdr hdr; /* Wal-index header for current transaction */ - u32 minFrame; /* Ignore wal frames before this one */ - u32 iReCksum; /* On commit, recalculate checksums from here */ -@@ -55535,11 +58630,20 @@ - ** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are - ** numbered from zero. - ** -+** If the wal-index is currently smaller the iPage pages then the size -+** of the wal-index might be increased, but only if it is safe to do -+** so. It is safe to enlarge the wal-index if pWal->writeLock is true -+** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE. -+** - ** If this call is successful, *ppPage is set to point to the wal-index - ** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs, - ** then an SQLite error code is returned and *ppPage is set to 0. - */ --static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){ -+static SQLITE_NOINLINE int walIndexPageRealloc( -+ Wal *pWal, /* The WAL context */ -+ int iPage, /* The page we seek */ -+ volatile u32 **ppPage /* Write the page pointer here */ -+){ - int rc = SQLITE_OK; - - /* Enlarge the pWal->apWiData[] array if required */ -@@ -55558,16 +58662,19 @@ - } - - /* Request a pointer to the required page from the VFS */ -- if( pWal->apWiData[iPage]==0 ){ -- if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ -- pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ); -- if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT; -- }else{ -- rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, -- pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] -- ); -+ assert( pWal->apWiData[iPage]==0 ); -+ if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ -+ pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ); -+ if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT; -+ }else{ -+ rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, -+ pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] -+ ); -+ assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 ); -+ testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK ); -+ if( (rc&0xff)==SQLITE_READONLY ){ -+ pWal->readOnly |= WAL_SHM_RDONLY; - if( rc==SQLITE_READONLY ){ -- pWal->readOnly |= WAL_SHM_RDONLY; - rc = SQLITE_OK; - } - } -@@ -55577,6 +58684,16 @@ - assert( iPage==0 || *ppPage || rc!=SQLITE_OK ); - return rc; - } -+static int walIndexPage( -+ Wal *pWal, /* The WAL context */ -+ int iPage, /* The page we seek */ -+ volatile u32 **ppPage /* Write the page pointer here */ -+){ -+ if( pWal->nWiData<=iPage || (*ppPage = pWal->apWiData[iPage])==0 ){ -+ return walIndexPageRealloc(pWal, iPage, ppPage); -+ } -+ return SQLITE_OK; -+} - - /* - ** Return a pointer to the WalCkptInfo structure in the wal-index. -@@ -55848,48 +58965,51 @@ - return (iPriorHash+1)&(HASHTABLE_NSLOT-1); - } - -+/* -+** An instance of the WalHashLoc object is used to describe the location -+** of a page hash table in the wal-index. This becomes the return value -+** from walHashGet(). -+*/ -+typedef struct WalHashLoc WalHashLoc; -+struct WalHashLoc { -+ volatile ht_slot *aHash; /* Start of the wal-index hash table */ -+ volatile u32 *aPgno; /* aPgno[1] is the page of first frame indexed */ -+ u32 iZero; /* One less than the frame number of first indexed*/ -+}; -+ - /* - ** Return pointers to the hash table and page number array stored on - ** page iHash of the wal-index. The wal-index is broken into 32KB pages - ** numbered starting from 0. - ** --** Set output variable *paHash to point to the start of the hash table --** in the wal-index file. Set *piZero to one less than the frame -+** Set output variable pLoc->aHash to point to the start of the hash table -+** in the wal-index file. Set pLoc->iZero to one less than the frame - ** number of the first frame indexed by this hash table. If a - ** slot in the hash table is set to N, it refers to frame number --** (*piZero+N) in the log. -+** (pLoc->iZero+N) in the log. - ** --** Finally, set *paPgno so that *paPgno[1] is the page number of the --** first frame indexed by the hash table, frame (*piZero+1). -+** Finally, set pLoc->aPgno so that pLoc->aPgno[1] is the page number of the -+** first frame indexed by the hash table, frame (pLoc->iZero+1). - */ - static int walHashGet( - Wal *pWal, /* WAL handle */ - int iHash, /* Find the iHash'th table */ -- volatile ht_slot **paHash, /* OUT: Pointer to hash index */ -- volatile u32 **paPgno, /* OUT: Pointer to page number array */ -- u32 *piZero /* OUT: Frame associated with *paPgno[0] */ -+ WalHashLoc *pLoc /* OUT: Hash table location */ - ){ - int rc; /* Return code */ -- volatile u32 *aPgno; - -- rc = walIndexPage(pWal, iHash, &aPgno); -+ rc = walIndexPage(pWal, iHash, &pLoc->aPgno); - assert( rc==SQLITE_OK || iHash>0 ); - - if( rc==SQLITE_OK ){ -- u32 iZero; -- volatile ht_slot *aHash; -- -- aHash = (volatile ht_slot *)&aPgno[HASHTABLE_NPAGE]; -+ pLoc->aHash = (volatile ht_slot *)&pLoc->aPgno[HASHTABLE_NPAGE]; - if( iHash==0 ){ -- aPgno = &aPgno[WALINDEX_HDR_SIZE/sizeof(u32)]; -- iZero = 0; -+ pLoc->aPgno = &pLoc->aPgno[WALINDEX_HDR_SIZE/sizeof(u32)]; -+ pLoc->iZero = 0; - }else{ -- iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE; -+ pLoc->iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE; - } -- -- *paPgno = &aPgno[-1]; -- *paHash = aHash; -- *piZero = iZero; -+ pLoc->aPgno = &pLoc->aPgno[-1]; - } - return rc; - } -@@ -55935,9 +59055,7 @@ - ** actually needed. - */ - static void walCleanupHash(Wal *pWal){ -- volatile ht_slot *aHash = 0; /* Pointer to hash table to clear */ -- volatile u32 *aPgno = 0; /* Page number array for hash table */ -- u32 iZero = 0; /* frame == (aHash[x]+iZero) */ -+ WalHashLoc sLoc; /* Hash table location */ - int iLimit = 0; /* Zero values greater than this */ - int nByte; /* Number of bytes to zero in aPgno[] */ - int i; /* Used to iterate through aHash[] */ -@@ -55955,16 +59073,16 @@ - */ - assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) ); - assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] ); -- walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &aHash, &aPgno, &iZero); -+ walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc); - - /* Zero all hash-table entries that correspond to frame numbers greater - ** than pWal->hdr.mxFrame. - */ -- iLimit = pWal->hdr.mxFrame - iZero; -+ iLimit = pWal->hdr.mxFrame - sLoc.iZero; - assert( iLimit>0 ); - for(i=0; i<HASHTABLE_NSLOT; i++){ -- if( aHash[i]>iLimit ){ -- aHash[i] = 0; -+ if( sLoc.aHash[i]>iLimit ){ -+ sLoc.aHash[i] = 0; - } - } - -@@ -55971,8 +59089,8 @@ - /* Zero the entries in the aPgno array that correspond to frames with - ** frame numbers greater than pWal->hdr.mxFrame. - */ -- nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]); -- memset((void *)&aPgno[iLimit+1], 0, nByte); -+ nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit+1]); -+ memset((void *)&sLoc.aPgno[iLimit+1], 0, nByte); - - #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT - /* Verify that the every entry in the mapping region is still reachable -@@ -55982,10 +59100,10 @@ - int j; /* Loop counter */ - int iKey; /* Hash key */ - for(j=1; j<=iLimit; j++){ -- for(iKey=walHash(aPgno[j]); aHash[iKey]; iKey=walNextHash(iKey)){ -- if( aHash[iKey]==j ) break; -+ for(iKey=walHash(sLoc.aPgno[j]);sLoc.aHash[iKey];iKey=walNextHash(iKey)){ -+ if( sLoc.aHash[iKey]==j ) break; - } -- assert( aHash[iKey]==j ); -+ assert( sLoc.aHash[iKey]==j ); - } - } - #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */ -@@ -55998,11 +59116,9 @@ - */ - static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ - int rc; /* Return code */ -- u32 iZero = 0; /* One less than frame number of aPgno[1] */ -- volatile u32 *aPgno = 0; /* Page number array */ -- volatile ht_slot *aHash = 0; /* Hash table */ -+ WalHashLoc sLoc; /* Wal-index hash table location */ - -- rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero); -+ rc = walHashGet(pWal, walFramePage(iFrame), &sLoc); - - /* Assuming the wal-index file was successfully mapped, populate the - ** page number array and hash table entry. -@@ -56012,7 +59128,7 @@ - int idx; /* Value to write to hash-table slot */ - int nCollide; /* Number of hash collisions */ - -- idx = iFrame - iZero; -+ idx = iFrame - sLoc.iZero; - assert( idx <= HASHTABLE_NSLOT/2 + 1 ); - - /* If this is the first entry to be added to this hash-table, zero the -@@ -56019,8 +59135,9 @@ - ** entire hash table and aPgno[] array before proceeding. - */ - if( idx==1 ){ -- int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]); -- memset((void*)&aPgno[1], 0, nByte); -+ int nByte = (int)((u8 *)&sLoc.aHash[HASHTABLE_NSLOT] -+ - (u8 *)&sLoc.aPgno[1]); -+ memset((void*)&sLoc.aPgno[1], 0, nByte); - } - - /* If the entry in aPgno[] is already set, then the previous writer -@@ -56029,18 +59146,18 @@ - ** Remove the remnants of that writers uncommitted transaction from - ** the hash-table before writing any new entries. - */ -- if( aPgno[idx] ){ -+ if( sLoc.aPgno[idx] ){ - walCleanupHash(pWal); -- assert( !aPgno[idx] ); -+ assert( !sLoc.aPgno[idx] ); - } - - /* Write the aPgno[] array entry and the hash-table slot. */ - nCollide = idx; -- for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){ -+ for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){ - if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT; - } -- aPgno[idx] = iPage; -- aHash[iKey] = (ht_slot)idx; -+ sLoc.aPgno[idx] = iPage; -+ sLoc.aHash[iKey] = (ht_slot)idx; - - #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT - /* Verify that the number of entries in the hash table exactly equals -@@ -56049,7 +59166,7 @@ - { - int i; /* Loop counter */ - int nEntry = 0; /* Number of entries in the hash table */ -- for(i=0; i<HASHTABLE_NSLOT; i++){ if( aHash[i] ) nEntry++; } -+ for(i=0; i<HASHTABLE_NSLOT; i++){ if( sLoc.aHash[i] ) nEntry++; } - assert( nEntry==idx ); - } - -@@ -56061,10 +59178,12 @@ - if( (idx&0x3ff)==0 ){ - int i; /* Loop counter */ - for(i=1; i<=idx; i++){ -- for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){ -- if( aHash[iKey]==i ) break; -+ for(iKey=walHash(sLoc.aPgno[i]); -+ sLoc.aHash[iKey]; -+ iKey=walNextHash(iKey)){ -+ if( sLoc.aHash[iKey]==i ) break; - } -- assert( aHash[iKey]==i ); -+ assert( sLoc.aHash[iKey]==i ); - } - } - #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */ -@@ -56090,7 +59209,6 @@ - i64 nSize; /* Size of log file */ - u32 aFrameCksum[2] = {0, 0}; - int iLock; /* Lock offset to lock for checkpoint */ -- int nLock; /* Number of locks to hold */ - - /* Obtain an exclusive lock on all byte in the locking range not already - ** locked by the caller. The caller is guaranteed to have locked the -@@ -56103,11 +59221,17 @@ - assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE ); - assert( pWal->writeLock ); - iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock; -- nLock = SQLITE_SHM_NLOCK - iLock; -- rc = walLockExclusive(pWal, iLock, nLock); -+ rc = walLockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock); -+ if( rc==SQLITE_OK ){ -+ rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); -+ if( rc!=SQLITE_OK ){ -+ walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock); -+ } -+ } - if( rc ){ - return rc; - } -+ - WALTRACE(("WAL%p: recovery begin...\n", pWal)); - - memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); -@@ -56245,7 +59369,8 @@ - - recovery_error: - WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok")); -- walUnlockExclusive(pWal, iLock, nLock); -+ walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock); -+ walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); - return rc; - } - -@@ -56253,13 +59378,14 @@ - ** Close an open wal-index. - */ - static void walIndexClose(Wal *pWal, int isDelete){ -- if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ -+ if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE || pWal->bShmUnreliable ){ - int i; - for(i=0; i<pWal->nWiData; i++){ - sqlite3_free((void *)pWal->apWiData[i]); - pWal->apWiData[i] = 0; - } -- }else{ -+ } -+ if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){ - sqlite3OsShmUnmap(pWal->pDbFd, isDelete); - } - } -@@ -56546,8 +59672,9 @@ - - /* - ** Construct a WalInterator object that can be used to loop over all --** pages in the WAL in ascending order. The caller must hold the checkpoint --** lock. -+** pages in the WAL following frame nBackfill in ascending order. Frames -+** nBackfill or earlier may be included - excluding them is an optimization -+** only. The caller must hold the checkpoint lock. - ** - ** On success, make *pp point to the newly allocated WalInterator object - ** return SQLITE_OK. Otherwise, return an error code. If this routine -@@ -56556,7 +59683,7 @@ - ** The calling routine should invoke walIteratorFree() to destroy the - ** WalIterator object when it has finished with it. - */ --static int walIteratorInit(Wal *pWal, WalIterator **pp){ -+static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ - WalIterator *p; /* Return value */ - int nSegment; /* Number of segments to merge */ - u32 iLast; /* Last frame in log */ -@@ -56593,34 +59720,32 @@ - rc = SQLITE_NOMEM_BKPT; - } - -- for(i=0; rc==SQLITE_OK && i<nSegment; i++){ -- volatile ht_slot *aHash; -- u32 iZero; -- volatile u32 *aPgno; -+ for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && i<nSegment; i++){ -+ WalHashLoc sLoc; - -- rc = walHashGet(pWal, i, &aHash, &aPgno, &iZero); -+ rc = walHashGet(pWal, i, &sLoc); - if( rc==SQLITE_OK ){ - int j; /* Counter variable */ - int nEntry; /* Number of entries in this segment */ - ht_slot *aIndex; /* Sorted index for this segment */ - -- aPgno++; -+ sLoc.aPgno++; - if( (i+1)==nSegment ){ -- nEntry = (int)(iLast - iZero); -+ nEntry = (int)(iLast - sLoc.iZero); - }else{ -- nEntry = (int)((u32*)aHash - (u32*)aPgno); -+ nEntry = (int)((u32*)sLoc.aHash - (u32*)sLoc.aPgno); - } -- aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[iZero]; -- iZero++; -+ aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[sLoc.iZero]; -+ sLoc.iZero++; - - for(j=0; j<nEntry; j++){ - aIndex[j] = (ht_slot)j; - } -- walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry); -- p->aSegment[i].iZero = iZero; -+ walMergesort((u32 *)sLoc.aPgno, aTmp, aIndex, &nEntry); -+ p->aSegment[i].iZero = sLoc.iZero; - p->aSegment[i].nEntry = nEntry; - p->aSegment[i].aIndex = aIndex; -- p->aSegment[i].aPgno = (u32 *)aPgno; -+ p->aSegment[i].aPgno = (u32 *)sLoc.aPgno; - } - } - sqlite3_free(aTmp); -@@ -56627,6 +59752,7 @@ - - if( rc!=SQLITE_OK ){ - walIteratorFree(p); -+ p = 0; - } - *pp = p; - return rc; -@@ -56749,13 +59875,6 @@ - pInfo = walCkptInfo(pWal); - if( pInfo->nBackfill<pWal->hdr.mxFrame ){ - -- /* Allocate the iterator */ -- rc = walIteratorInit(pWal, &pIter); -- if( rc!=SQLITE_OK ){ -- return rc; -- } -- assert( pIter ); -- - /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked - ** in the SQLITE_CHECKPOINT_PASSIVE mode. */ - assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 ); -@@ -56792,18 +59911,21 @@ - } - } - -- if( pInfo->nBackfill<mxSafeFrame -+ /* Allocate the iterator */ -+ if( pInfo->nBackfill<mxSafeFrame ){ -+ rc = walIteratorInit(pWal, pInfo->nBackfill, &pIter); -+ assert( rc==SQLITE_OK || pIter==0 ); -+ } -+ -+ if( pIter - && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK - ){ -- i64 nSize; /* Current size of database file */ - u32 nBackfill = pInfo->nBackfill; - - pInfo->nBackfillAttempted = mxSafeFrame; - - /* Sync the WAL to disk */ -- if( sync_flags ){ -- rc = sqlite3OsSync(pWal->pWalFd, sync_flags); -- } -+ rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); - - /* If the database may grow as a result of this checkpoint, hint - ** about the eventual size of the db file to the VFS layer. -@@ -56810,6 +59932,7 @@ - */ - if( rc==SQLITE_OK ){ - i64 nReq = ((i64)mxPage * szPage); -+ i64 nSize; /* Current size of database file */ - rc = sqlite3OsFileSize(pWal->pDbFd, &nSize); - if( rc==SQLITE_OK && nSize<nReq ){ - sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq); -@@ -56844,8 +59967,8 @@ - i64 szDb = pWal->hdr.nPage*(i64)szPage; - testcase( IS_BIG_INT(szDb) ); - rc = sqlite3OsTruncate(pWal->pDbFd, szDb); -- if( rc==SQLITE_OK && sync_flags ){ -- rc = sqlite3OsSync(pWal->pDbFd, sync_flags); -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags)); - } - } - if( rc==SQLITE_OK ){ -@@ -57055,6 +60178,12 @@ - } - - /* -+** This is the value that walTryBeginRead returns when it needs to -+** be retried. -+*/ -+#define WAL_RETRY (-1) -+ -+/* - ** Read the wal-index header from the wal-index and into pWal->hdr. - ** If the wal-header appears to be corrupt, try to reconstruct the - ** wal-index from the WAL before returning. -@@ -57077,9 +60206,29 @@ - assert( pChanged ); - rc = walIndexPage(pWal, 0, &page0); - if( rc!=SQLITE_OK ){ -- return rc; -- }; -- assert( page0 || pWal->writeLock==0 ); -+ assert( rc!=SQLITE_READONLY ); /* READONLY changed to OK in walIndexPage */ -+ if( rc==SQLITE_READONLY_CANTINIT ){ -+ /* The SQLITE_READONLY_CANTINIT return means that the shared-memory -+ ** was openable but is not writable, and this thread is unable to -+ ** confirm that another write-capable connection has the shared-memory -+ ** open, and hence the content of the shared-memory is unreliable, -+ ** since the shared-memory might be inconsistent with the WAL file -+ ** and there is no writer on hand to fix it. */ -+ assert( page0==0 ); -+ assert( pWal->writeLock==0 ); -+ assert( pWal->readOnly & WAL_SHM_RDONLY ); -+ pWal->bShmUnreliable = 1; -+ pWal->exclusiveMode = WAL_HEAPMEMORY_MODE; -+ *pChanged = 1; -+ }else{ -+ return rc; /* Any other non-OK return is just an error */ -+ } -+ }else{ -+ /* page0 can be NULL if the SHM is zero bytes in size and pWal->writeLock -+ ** is zero, which prevents the SHM from growing */ -+ testcase( page0!=0 ); -+ } -+ assert( page0!=0 || pWal->writeLock==0 ); - - /* If the first page of the wal-index has been mapped, try to read the - ** wal-index header immediately, without holding any lock. This usually -@@ -57093,7 +60242,7 @@ - */ - assert( badHdr==0 || pWal->writeLock==0 ); - if( badHdr ){ -- if( pWal->readOnly & WAL_SHM_RDONLY ){ -+ if( pWal->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){ - if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){ - walUnlockShared(pWal, WAL_WRITE_LOCK); - rc = SQLITE_READONLY_RECOVERY; -@@ -57123,16 +60272,194 @@ - if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){ - rc = SQLITE_CANTOPEN_BKPT; - } -+ if( pWal->bShmUnreliable ){ -+ if( rc!=SQLITE_OK ){ -+ walIndexClose(pWal, 0); -+ pWal->bShmUnreliable = 0; -+ assert( pWal->nWiData>0 && pWal->apWiData[0]==0 ); -+ /* walIndexRecover() might have returned SHORT_READ if a concurrent -+ ** writer truncated the WAL out from under it. If that happens, it -+ ** indicates that a writer has fixed the SHM file for us, so retry */ -+ if( rc==SQLITE_IOERR_SHORT_READ ) rc = WAL_RETRY; -+ } -+ pWal->exclusiveMode = WAL_NORMAL_MODE; -+ } - - return rc; - } - - /* --** This is the value that walTryBeginRead returns when it needs to --** be retried. -+** Open a transaction in a connection where the shared-memory is read-only -+** and where we cannot verify that there is a separate write-capable connection -+** on hand to keep the shared-memory up-to-date with the WAL file. -+** -+** This can happen, for example, when the shared-memory is implemented by -+** memory-mapping a *-shm file, where a prior writer has shut down and -+** left the *-shm file on disk, and now the present connection is trying -+** to use that database but lacks write permission on the *-shm file. -+** Other scenarios are also possible, depending on the VFS implementation. -+** -+** Precondition: -+** -+** The *-wal file has been read and an appropriate wal-index has been -+** constructed in pWal->apWiData[] using heap memory instead of shared -+** memory. -+** -+** If this function returns SQLITE_OK, then the read transaction has -+** been successfully opened. In this case output variable (*pChanged) -+** is set to true before returning if the caller should discard the -+** contents of the page cache before proceeding. Or, if it returns -+** WAL_RETRY, then the heap memory wal-index has been discarded and -+** the caller should retry opening the read transaction from the -+** beginning (including attempting to map the *-shm file). -+** -+** If an error occurs, an SQLite error code is returned. - */ --#define WAL_RETRY (-1) -+static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ -+ i64 szWal; /* Size of wal file on disk in bytes */ -+ i64 iOffset; /* Current offset when reading wal file */ -+ u8 aBuf[WAL_HDRSIZE]; /* Buffer to load WAL header into */ -+ u8 *aFrame = 0; /* Malloc'd buffer to load entire frame */ -+ int szFrame; /* Number of bytes in buffer aFrame[] */ -+ u8 *aData; /* Pointer to data part of aFrame buffer */ -+ volatile void *pDummy; /* Dummy argument for xShmMap */ -+ int rc; /* Return code */ -+ u32 aSaveCksum[2]; /* Saved copy of pWal->hdr.aFrameCksum */ - -+ assert( pWal->bShmUnreliable ); -+ assert( pWal->readOnly & WAL_SHM_RDONLY ); -+ assert( pWal->nWiData>0 && pWal->apWiData[0] ); -+ -+ /* Take WAL_READ_LOCK(0). This has the effect of preventing any -+ ** writers from running a checkpoint, but does not stop them -+ ** from running recovery. */ -+ rc = walLockShared(pWal, WAL_READ_LOCK(0)); -+ if( rc!=SQLITE_OK ){ -+ if( rc==SQLITE_BUSY ) rc = WAL_RETRY; -+ goto begin_unreliable_shm_out; -+ } -+ pWal->readLock = 0; -+ -+ /* Check to see if a separate writer has attached to the shared-memory area, -+ ** thus making the shared-memory "reliable" again. Do this by invoking -+ ** the xShmMap() routine of the VFS and looking to see if the return -+ ** is SQLITE_READONLY instead of SQLITE_READONLY_CANTINIT. -+ ** -+ ** If the shared-memory is now "reliable" return WAL_RETRY, which will -+ ** cause the heap-memory WAL-index to be discarded and the actual -+ ** shared memory to be used in its place. -+ ** -+ ** This step is important because, even though this connection is holding -+ ** the WAL_READ_LOCK(0) which prevents a checkpoint, a writer might -+ ** have already checkpointed the WAL file and, while the current -+ ** is active, wrap the WAL and start overwriting frames that this -+ ** process wants to use. -+ ** -+ ** Once sqlite3OsShmMap() has been called for an sqlite3_file and has -+ ** returned any SQLITE_READONLY value, it must return only SQLITE_READONLY -+ ** or SQLITE_READONLY_CANTINIT or some error for all subsequent invocations, -+ ** even if some external agent does a "chmod" to make the shared-memory -+ ** writable by us, until sqlite3OsShmUnmap() has been called. -+ ** This is a requirement on the VFS implementation. -+ */ -+ rc = sqlite3OsShmMap(pWal->pDbFd, 0, WALINDEX_PGSZ, 0, &pDummy); -+ assert( rc!=SQLITE_OK ); /* SQLITE_OK not possible for read-only connection */ -+ if( rc!=SQLITE_READONLY_CANTINIT ){ -+ rc = (rc==SQLITE_READONLY ? WAL_RETRY : rc); -+ goto begin_unreliable_shm_out; -+ } -+ -+ /* We reach this point only if the real shared-memory is still unreliable. -+ ** Assume the in-memory WAL-index substitute is correct and load it -+ ** into pWal->hdr. -+ */ -+ memcpy(&pWal->hdr, (void*)walIndexHdr(pWal), sizeof(WalIndexHdr)); -+ -+ /* Make sure some writer hasn't come in and changed the WAL file out -+ ** from under us, then disconnected, while we were not looking. -+ */ -+ rc = sqlite3OsFileSize(pWal->pWalFd, &szWal); -+ if( rc!=SQLITE_OK ){ -+ goto begin_unreliable_shm_out; -+ } -+ if( szWal<WAL_HDRSIZE ){ -+ /* If the wal file is too small to contain a wal-header and the -+ ** wal-index header has mxFrame==0, then it must be safe to proceed -+ ** reading the database file only. However, the page cache cannot -+ ** be trusted, as a read/write connection may have connected, written -+ ** the db, run a checkpoint, truncated the wal file and disconnected -+ ** since this client's last read transaction. */ -+ *pChanged = 1; -+ rc = (pWal->hdr.mxFrame==0 ? SQLITE_OK : WAL_RETRY); -+ goto begin_unreliable_shm_out; -+ } -+ -+ /* Check the salt keys at the start of the wal file still match. */ -+ rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0); -+ if( rc!=SQLITE_OK ){ -+ goto begin_unreliable_shm_out; -+ } -+ if( memcmp(&pWal->hdr.aSalt, &aBuf[16], 8) ){ -+ /* Some writer has wrapped the WAL file while we were not looking. -+ ** Return WAL_RETRY which will cause the in-memory WAL-index to be -+ ** rebuilt. */ -+ rc = WAL_RETRY; -+ goto begin_unreliable_shm_out; -+ } -+ -+ /* Allocate a buffer to read frames into */ -+ szFrame = pWal->hdr.szPage + WAL_FRAME_HDRSIZE; -+ aFrame = (u8 *)sqlite3_malloc64(szFrame); -+ if( aFrame==0 ){ -+ rc = SQLITE_NOMEM_BKPT; -+ goto begin_unreliable_shm_out; -+ } -+ aData = &aFrame[WAL_FRAME_HDRSIZE]; -+ -+ /* Check to see if a complete transaction has been appended to the -+ ** wal file since the heap-memory wal-index was created. If so, the -+ ** heap-memory wal-index is discarded and WAL_RETRY returned to -+ ** the caller. */ -+ aSaveCksum[0] = pWal->hdr.aFrameCksum[0]; -+ aSaveCksum[1] = pWal->hdr.aFrameCksum[1]; -+ for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->hdr.szPage); -+ iOffset+szFrame<=szWal; -+ iOffset+=szFrame -+ ){ -+ u32 pgno; /* Database page number for frame */ -+ u32 nTruncate; /* dbsize field from frame header */ -+ -+ /* Read and decode the next log frame. */ -+ rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); -+ if( rc!=SQLITE_OK ) break; -+ if( !walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame) ) break; -+ -+ /* If nTruncate is non-zero, then a complete transaction has been -+ ** appended to this wal file. Set rc to WAL_RETRY and break out of -+ ** the loop. */ -+ if( nTruncate ){ -+ rc = WAL_RETRY; -+ break; -+ } -+ } -+ pWal->hdr.aFrameCksum[0] = aSaveCksum[0]; -+ pWal->hdr.aFrameCksum[1] = aSaveCksum[1]; -+ -+ begin_unreliable_shm_out: -+ sqlite3_free(aFrame); -+ if( rc!=SQLITE_OK ){ -+ int i; -+ for(i=0; i<pWal->nWiData; i++){ -+ sqlite3_free((void*)pWal->apWiData[i]); -+ pWal->apWiData[i] = 0; -+ } -+ pWal->bShmUnreliable = 0; -+ sqlite3WalEndReadTransaction(pWal); -+ *pChanged = 1; -+ } -+ return rc; -+} -+ - /* - ** Attempt to start a read transaction. This might fail due to a race or - ** other transient condition. When that happens, it returns WAL_RETRY to -@@ -57147,7 +60474,7 @@ - ** checkpointed. If useWal==0 then this routine calls walIndexReadHdr() - ** to make a copy of the wal-index header into pWal->hdr. If the - ** wal-index header has changed, *pChanged is set to 1 (as an indication --** to the caller that the local paget cache is obsolete and needs to be -+** to the caller that the local page cache is obsolete and needs to be - ** flushed.) When useWal==1, the wal-index header is assumed to already - ** be loaded and the pChanged parameter is unused. - ** -@@ -57193,6 +60520,9 @@ - - assert( pWal->readLock<0 ); /* Not currently locked */ - -+ /* useWal may only be set for read/write connections */ -+ assert( (pWal->readOnly & WAL_SHM_RDONLY)==0 || useWal==0 ); -+ - /* Take steps to avoid spinning forever if there is a protocol error. - ** - ** Circumstances that cause a RETRY should only last for the briefest -@@ -57221,7 +60551,10 @@ - } - - if( !useWal ){ -- rc = walIndexReadHdr(pWal, pChanged); -+ assert( rc==SQLITE_OK ); -+ if( pWal->bShmUnreliable==0 ){ -+ rc = walIndexReadHdr(pWal, pChanged); -+ } - if( rc==SQLITE_BUSY ){ - /* If there is not a recovery running in another thread or process - ** then convert BUSY errors to WAL_RETRY. If recovery is known to -@@ -57250,13 +60583,17 @@ - if( rc!=SQLITE_OK ){ - return rc; - } -+ else if( pWal->bShmUnreliable ){ -+ return walBeginShmUnreliable(pWal, pChanged); -+ } - } - -+ assert( pWal->nWiData>0 ); -+ assert( pWal->apWiData[0]!=0 ); - pInfo = walCkptInfo(pWal); -- if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame -+ if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame - #ifdef SQLITE_ENABLE_SNAPSHOT -- && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0 -- || 0==memcmp(&pWal->hdr, pWal->pSnapshot, sizeof(WalIndexHdr))) -+ && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0) - #endif - ){ - /* The WAL has been completely backfilled (or it is empty). -@@ -57303,7 +60640,7 @@ - } - #endif - for(i=1; i<WAL_NREADER; i++){ -- u32 thisMark = pInfo->aReadMark[i]; -+ u32 thisMark = AtomicLoad(pInfo->aReadMark+i); - if( mxReadMark<=thisMark && thisMark<=mxFrame ){ - assert( thisMark!=READMARK_NOT_USED ); - mxReadMark = thisMark; -@@ -57316,7 +60653,7 @@ - for(i=1; i<WAL_NREADER; i++){ - rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); - if( rc==SQLITE_OK ){ -- mxReadMark = pInfo->aReadMark[i] = mxFrame; -+ mxReadMark = AtomicStore(pInfo->aReadMark+i,mxFrame); - mxI = i; - walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); - break; -@@ -57327,7 +60664,7 @@ - } - if( mxI==0 ){ - assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); -- return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK; -+ return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT; - } - - rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); -@@ -57368,9 +60705,9 @@ - ** we can guarantee that the checkpointer that set nBackfill could not - ** see any pages past pWal->hdr.mxFrame, this problem does not come up. - */ -- pWal->minFrame = pInfo->nBackfill+1; -+ pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; - walShmBarrier(pWal); -- if( pInfo->aReadMark[mxI]!=mxReadMark -+ if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark - || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) - ){ - walUnlockShared(pWal, WAL_READ_LOCK(mxI)); -@@ -57421,16 +60758,14 @@ - }else{ - u32 i = pInfo->nBackfillAttempted; - for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){ -- volatile ht_slot *dummy; -- volatile u32 *aPgno; /* Array of page numbers */ -- u32 iZero; /* Frame corresponding to aPgno[0] */ -+ WalHashLoc sLoc; /* Hash table location */ - u32 pgno; /* Page number in db file */ - i64 iDbOff; /* Offset of db file entry */ - i64 iWalOff; /* Offset of wal file entry */ - -- rc = walHashGet(pWal, walFramePage(i), &dummy, &aPgno, &iZero); -+ rc = walHashGet(pWal, walFramePage(i), &sLoc); - if( rc!=SQLITE_OK ) break; -- pgno = aPgno[i-iZero]; -+ pgno = sLoc.aPgno[i-sLoc.iZero]; - iDbOff = (i64)(pgno-1) * szPage; - - if( iDbOff+szPage<=szDb ){ -@@ -57471,7 +60806,7 @@ - ** - ** If the database contents have changes since the previous read - ** transaction, then *pChanged is set to 1 before returning. The --** Pager layer will use this to know that is cache is stale and -+** Pager layer will use this to know that its cache is stale and - ** needs to be flushed. - */ - SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ -@@ -57533,7 +60868,7 @@ - /* Check that the wal file has not been wrapped. Assuming that it has - ** not, also check that no checkpointer has attempted to checkpoint any - ** frames beyond pSnapshot->mxFrame. If either of these conditions are -- ** true, return SQLITE_BUSY_SNAPSHOT. Otherwise, overwrite pWal->hdr -+ ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr - ** with *pSnapshot and set *pChanged as appropriate for opening the - ** snapshot. */ - if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)) -@@ -57543,11 +60878,12 @@ - memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr)); - *pChanged = bChanged; - }else{ -- rc = SQLITE_BUSY_SNAPSHOT; -+ rc = SQLITE_ERROR_SNAPSHOT; - } - - /* Release the shared CKPT lock obtained above. */ - walUnlockShared(pWal, WAL_CKPT_LOCK); -+ pWal->minFrame = 1; - } - - -@@ -57599,7 +60935,7 @@ - ** then the WAL is ignored by the reader so return early, as if the - ** WAL were empty. - */ -- if( iLast==0 || pWal->readLock==0 ){ -+ if( iLast==0 || (pWal->readLock==0 && pWal->bShmUnreliable==0) ){ - *piRead = 0; - return SQLITE_OK; - } -@@ -57630,22 +60966,21 @@ - ** table after the current read-transaction had started. - */ - iMinHash = walFramePage(pWal->minFrame); -- for(iHash=walFramePage(iLast); iHash>=iMinHash && iRead==0; iHash--){ -- volatile ht_slot *aHash; /* Pointer to hash table */ -- volatile u32 *aPgno; /* Pointer to array of page numbers */ -- u32 iZero; /* Frame number corresponding to aPgno[0] */ -+ for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){ -+ WalHashLoc sLoc; /* Hash table location */ - int iKey; /* Hash slot index */ - int nCollide; /* Number of hash collisions remaining */ - int rc; /* Error code */ - -- rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero); -+ rc = walHashGet(pWal, iHash, &sLoc); - if( rc!=SQLITE_OK ){ - return rc; - } - nCollide = HASHTABLE_NSLOT; -- for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){ -- u32 iFrame = aHash[iKey] + iZero; -- if( iFrame<=iLast && iFrame>=pWal->minFrame && aPgno[aHash[iKey]]==pgno ){ -+ for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){ -+ u32 iFrame = sLoc.aHash[iKey] + sLoc.iZero; -+ if( iFrame<=iLast && iFrame>=pWal->minFrame -+ && sLoc.aPgno[sLoc.aHash[iKey]]==pgno ){ - assert( iFrame>iRead || CORRUPT_DB ); - iRead = iFrame; - } -@@ -57653,6 +60988,7 @@ - return SQLITE_CORRUPT_BKPT; - } - } -+ if( iRead ) break; - } - - #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT -@@ -57662,8 +60998,8 @@ - { - u32 iRead2 = 0; - u32 iTest; -- assert( pWal->minFrame>0 ); -- for(iTest=iLast; iTest>=pWal->minFrame; iTest--){ -+ assert( pWal->bShmUnreliable || pWal->minFrame>0 ); -+ for(iTest=iLast; iTest>=pWal->minFrame && iTest>0; iTest--){ - if( walFramePgno(pWal, iTest)==pgno ){ - iRead2 = iTest; - break; -@@ -57951,8 +61287,8 @@ - iOffset += iFirstAmt; - iAmt -= iFirstAmt; - pContent = (void*)(iFirstAmt + (char*)pContent); -- assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) ); -- rc = sqlite3OsSync(p->pFd, p->syncFlags & SQLITE_SYNC_MASK); -+ assert( WAL_SYNC_FLAGS(p->syncFlags)!=0 ); -+ rc = sqlite3OsSync(p->pFd, WAL_SYNC_FLAGS(p->syncFlags)); - if( iAmt==0 || rc ) return rc; - } - rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset); -@@ -58122,10 +61458,10 @@ - ** an out-of-order write following a WAL restart could result in - ** database corruption. See the ticket: - ** -- ** http://localhost:591/sqlite/info/ff5be73dee -+ ** https://sqlite.org/src/info/ff5be73dee - */ -- if( pWal->syncHeader && sync_flags ){ -- rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK); -+ if( pWal->syncHeader ){ -+ rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); - if( rc ) return rc; - } - } -@@ -58200,7 +61536,7 @@ - ** sector boundary is synced; the part of the last frame that extends - ** past the sector boundary is written after the sync. - */ -- if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){ -+ if( isCommit && WAL_SYNC_FLAGS(sync_flags)!=0 ){ - int bSync = 1; - if( pWal->padToSectorBoundary ){ - int sectorSize = sqlite3SectorSize(pWal->pWalFd); -@@ -58216,7 +61552,7 @@ - } - if( bSync ){ - assert( rc==SQLITE_OK ); -- rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK); -+ rc = sqlite3OsSync(w.pFd, WAL_SYNC_FLAGS(sync_flags)); - } - } - -@@ -58439,24 +61775,24 @@ - assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) ); - - if( op==0 ){ -- if( pWal->exclusiveMode ){ -- pWal->exclusiveMode = 0; -+ if( pWal->exclusiveMode!=WAL_NORMAL_MODE ){ -+ pWal->exclusiveMode = WAL_NORMAL_MODE; - if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){ -- pWal->exclusiveMode = 1; -+ pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; - } -- rc = pWal->exclusiveMode==0; -+ rc = pWal->exclusiveMode==WAL_NORMAL_MODE; - }else{ - /* Already in locking_mode=NORMAL */ - rc = 0; - } - }else if( op>0 ){ -- assert( pWal->exclusiveMode==0 ); -+ assert( pWal->exclusiveMode==WAL_NORMAL_MODE ); - assert( pWal->readLock>=0 ); - walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); -- pWal->exclusiveMode = 1; -+ pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; - rc = 1; - }else{ -- rc = pWal->exclusiveMode==0; -+ rc = pWal->exclusiveMode==WAL_NORMAL_MODE; - } - return rc; - } -@@ -58519,6 +61855,43 @@ - if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1; - return 0; - } -+ -+/* -+** The caller currently has a read transaction open on the database. -+** This function takes a SHARED lock on the CHECKPOINTER slot and then -+** checks if the snapshot passed as the second argument is still -+** available. If so, SQLITE_OK is returned. -+** -+** If the snapshot is not available, SQLITE_ERROR is returned. Or, if -+** the CHECKPOINTER lock cannot be obtained, SQLITE_BUSY. If any error -+** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER -+** lock is released before returning. -+*/ -+SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot){ -+ int rc; -+ rc = walLockShared(pWal, WAL_CKPT_LOCK); -+ if( rc==SQLITE_OK ){ -+ WalIndexHdr *pNew = (WalIndexHdr*)pSnapshot; -+ if( memcmp(pNew->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)) -+ || pNew->mxFrame<walCkptInfo(pWal)->nBackfillAttempted -+ ){ -+ rc = SQLITE_ERROR_SNAPSHOT; -+ walUnlockShared(pWal, WAL_CKPT_LOCK); -+ } -+ } -+ return rc; -+} -+ -+/* -+** Release a lock obtained by an earlier successful call to -+** sqlite3WalSnapshotCheck(). -+*/ -+SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal){ -+ assert( pWal ); -+ walUnlockShared(pWal, WAL_CKPT_LOCK); -+} -+ -+ - #endif /* SQLITE_ENABLE_SNAPSHOT */ - - #ifdef SQLITE_ENABLE_ZIPVFS -@@ -59063,30 +62436,31 @@ - ** eState==FAULT: Cursor fault with skipNext as error code. - */ - struct BtCursor { -+ u8 eState; /* One of the CURSOR_XXX constants (see below) */ -+ u8 curFlags; /* zero or more BTCF_* flags defined below */ -+ u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */ -+ u8 hints; /* As configured by CursorSetHints() */ -+ int skipNext; /* Prev() is noop if negative. Next() is noop if positive. -+ ** Error code if eState==CURSOR_FAULT */ - Btree *pBtree; /* The Btree to which this cursor belongs */ -+ Pgno *aOverflow; /* Cache of overflow page locations */ -+ void *pKey; /* Saved key that was cursor last known position */ -+ /* All fields above are zeroed when the cursor is allocated. See -+ ** sqlite3BtreeCursorZero(). Fields that follow must be manually -+ ** initialized. */ -+#define BTCURSOR_FIRST_UNINIT pBt /* Name of first uninitialized field */ - BtShared *pBt; /* The BtShared this cursor points to */ - BtCursor *pNext; /* Forms a linked list of all cursors */ -- Pgno *aOverflow; /* Cache of overflow page locations */ - CellInfo info; /* A parse of the cell we are pointing at */ - i64 nKey; /* Size of pKey, or last integer key */ -- void *pKey; /* Saved key that was cursor last known position */ - Pgno pgnoRoot; /* The root page of this tree */ -- int nOvflAlloc; /* Allocated size of aOverflow[] array */ -- int skipNext; /* Prev() is noop if negative. Next() is noop if positive. -- ** Error code if eState==CURSOR_FAULT */ -- u8 curFlags; /* zero or more BTCF_* flags defined below */ -- u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */ -- u8 eState; /* One of the CURSOR_XXX constants (see below) */ -- u8 hints; /* As configured by CursorSetHints() */ -- /* All fields above are zeroed when the cursor is allocated. See -- ** sqlite3BtreeCursorZero(). Fields that follow must be manually -- ** initialized. */ - i8 iPage; /* Index of current page in apPage */ - u8 curIntKey; /* Value of apPage[0]->intKey */ - u16 ix; /* Current index for apPage[iPage] */ - u16 aiIdx[BTCURSOR_MAX_DEPTH-1]; /* Current index in apPage[i] */ - struct KeyInfo *pKeyInfo; /* Arg passed to comparison function */ -- MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ -+ MemPage *pPage; /* Current page */ -+ MemPage *apPage[BTCURSOR_MAX_DEPTH-1]; /* Stack of parents of current page */ - }; - - /* -@@ -59129,8 +62503,8 @@ - ** Do nothing else with this cursor. Any attempt to use the cursor - ** should return the error code stored in BtCursor.skipNext - */ --#define CURSOR_INVALID 0 --#define CURSOR_VALID 1 -+#define CURSOR_VALID 0 -+#define CURSOR_INVALID 1 - #define CURSOR_SKIPNEXT 2 - #define CURSOR_REQUIRESEEK 3 - #define CURSOR_FAULT 4 -@@ -59447,10 +62821,10 @@ - skipOk = 0; - } - } -- db->skipBtreeMutex = skipOk; -+ db->noSharedCache = skipOk; - } - SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){ -- if( db->skipBtreeMutex==0 ) btreeEnterAll(db); -+ if( db->noSharedCache==0 ) btreeEnterAll(db); - } - static void SQLITE_NOINLINE btreeLeaveAll(sqlite3 *db){ - int i; -@@ -59462,7 +62836,7 @@ - } - } - SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){ -- if( db->skipBtreeMutex==0 ) btreeLeaveAll(db); -+ if( db->noSharedCache==0 ) btreeLeaveAll(db); - } - - #ifndef NDEBUG -@@ -59675,6 +63049,34 @@ - #define hasReadConflicts(a, b) 0 - #endif - -+/* -+** Implementation of the SQLITE_CORRUPT_PAGE() macro. Takes a single -+** (MemPage*) as an argument. The (MemPage*) must not be NULL. -+** -+** If SQLITE_DEBUG is not defined, then this macro is equivalent to -+** SQLITE_CORRUPT_BKPT. Or, if SQLITE_DEBUG is set, then the log message -+** normally produced as a side-effect of SQLITE_CORRUPT_BKPT is augmented -+** with the page number and filename associated with the (MemPage*). -+*/ -+#ifdef SQLITE_DEBUG -+int corruptPageError(int lineno, MemPage *p){ -+ char *zMsg; -+ sqlite3BeginBenignMalloc(); -+ zMsg = sqlite3_mprintf("database corruption page %d of %s", -+ (int)p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0) -+ ); -+ sqlite3EndBenignMalloc(); -+ if( zMsg ){ -+ sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg); -+ } -+ sqlite3_free(zMsg); -+ return SQLITE_CORRUPT_BKPT; -+} -+# define SQLITE_CORRUPT_PAGE(pMemPage) corruptPageError(__LINE__, pMemPage) -+#else -+# define SQLITE_CORRUPT_PAGE(pMemPage) SQLITE_CORRUPT_PGNO(pMemPage->pgno) -+#endif -+ - #ifndef SQLITE_OMIT_SHARED_CACHE - - #ifdef SQLITE_DEBUG -@@ -60002,7 +63404,9 @@ - - #endif /* SQLITE_OMIT_SHARED_CACHE */ - --static void releasePage(MemPage *pPage); /* Forward reference */ -+static void releasePage(MemPage *pPage); /* Forward reference */ -+static void releasePageOne(MemPage *pPage); /* Forward reference */ -+static void releasePageNotNull(MemPage *pPage); /* Forward reference */ - - /* - ***** This routine is used inside of assert() only **** -@@ -60161,11 +63565,13 @@ - */ - static void btreeReleaseAllCursorPages(BtCursor *pCur){ - int i; -- for(i=0; i<=pCur->iPage; i++){ -- releasePage(pCur->apPage[i]); -- pCur->apPage[i] = 0; -+ if( pCur->iPage>=0 ){ -+ for(i=0; i<pCur->iPage; i++){ -+ releasePageNotNull(pCur->apPage[i]); -+ } -+ releasePageNotNull(pCur->pPage); -+ pCur->iPage = -1; - } -- pCur->iPage = -1; - } - - /* -@@ -60294,7 +63700,7 @@ - return rc; - } - }else{ -- testcase( p->iPage>0 ); -+ testcase( p->iPage>=0 ); - btreeReleaseAllCursorPages(p); - } - } -@@ -60334,7 +63740,7 @@ - if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; - sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey); - if( pIdxKey->nField==0 ){ -- rc = SQLITE_CORRUPT_PGNO(pCur->apPage[pCur->iPage]->pgno); -+ rc = SQLITE_CORRUPT_BKPT; - goto moveto_done; - } - }else{ -@@ -60395,10 +63801,25 @@ - ** back to where it ought to be if this routine returns true. - */ - SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){ -- return pCur->eState!=CURSOR_VALID; -+ assert( EIGHT_BYTE_ALIGNMENT(pCur) -+ || pCur==sqlite3BtreeFakeValidCursor() ); -+ assert( offsetof(BtCursor, eState)==0 ); -+ assert( sizeof(pCur->eState)==1 ); -+ return CURSOR_VALID != *(u8*)pCur; - } - - /* -+** Return a pointer to a fake BtCursor object that will always answer -+** false to the sqlite3BtreeCursorHasMoved() routine above. The fake -+** cursor returned must not be used with any other Btree interface. -+*/ -+SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void){ -+ static u8 fakeCursor = CURSOR_VALID; -+ assert( offsetof(BtCursor, eState)==0 ); -+ return (BtCursor*)&fakeCursor; -+} -+ -+/* - ** This routine restores a cursor back to its original position after it - ** has been moved by some outside activity (such as a btree rebalance or - ** a row having been deleted out from under the cursor). -@@ -60947,8 +64368,11 @@ - int sz2 = 0; - int sz = get2byte(&data[iFree+2]); - int top = get2byte(&data[hdr+5]); -+ if( top>=iFree ){ -+ return SQLITE_CORRUPT_PAGE(pPage); -+ } - if( iFree2 ){ -- if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ assert( iFree+sz<=iFree2 ); /* Verified by pageFindSlot() */ - sz2 = get2byte(&data[iFree2+2]); - assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize ); - memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); -@@ -60979,13 +64403,13 @@ - ** if PRAGMA cell_size_check=ON. - */ - if( pc<iCellFirst || pc>iCellLast ){ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - assert( pc>=iCellFirst && pc<=iCellLast ); - size = pPage->xCellSize(pPage, &src[pc]); - cbrk -= size; - if( cbrk<iCellFirst || pc+size>usableSize ){ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - assert( cbrk+size<=usableSize && cbrk>=iCellFirst ); - testcase( cbrk+size==usableSize ); -@@ -61005,7 +64429,7 @@ - - defragment_out: - if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - assert( cbrk>=iCellFirst ); - put2byte(&data[hdr+5], cbrk); -@@ -61037,16 +64461,10 @@ - int pc = get2byte(&aData[iAddr]); - int x; - int usableSize = pPg->pBt->usableSize; -+ int size; /* Size of the free slot */ - - assert( pc>0 ); -- do{ -- int size; /* Size of the free slot */ -- /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of -- ** increasing offset. */ -- if( pc>usableSize-4 || pc<iAddr+4 ){ -- *pRc = SQLITE_CORRUPT_PGNO(pPg->pgno); -- return 0; -- } -+ while( pc<=usableSize-4 ){ - /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each - ** freeblock form a big-endian integer which is the size of the freeblock - ** in bytes, including the 4-byte header. */ -@@ -61054,8 +64472,8 @@ - if( (x = size - nByte)>=0 ){ - testcase( x==4 ); - testcase( x==3 ); -- if( pc < pPg->cellOffset+2*pPg->nCell || size+pc > usableSize ){ -- *pRc = SQLITE_CORRUPT_PGNO(pPg->pgno); -+ if( size+pc > usableSize ){ -+ *pRc = SQLITE_CORRUPT_PAGE(pPg); - return 0; - }else if( x<4 ){ - /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total -@@ -61075,7 +64493,11 @@ - } - iAddr = pc; - pc = get2byte(&aData[pc]); -- }while( pc ); -+ if( pc<iAddr+size ) break; -+ } -+ if( pc ){ -+ *pRc = SQLITE_CORRUPT_PAGE(pPg); -+ } - - return 0; - } -@@ -61122,7 +64544,7 @@ - if( top==0 && pPage->pBt->usableSize==65536 ){ - top = 65536; - }else{ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - } - -@@ -61189,7 +64611,7 @@ - u8 hdr; /* Page header size. 0 or 100 */ - u8 nFrag = 0; /* Reduction in fragmentation */ - u16 iOrigSize = iSize; /* Original value of iSize */ -- u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */ -+ u16 x; /* Offset to cell content area */ - u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */ - unsigned char *data = pPage->aData; /* Page content */ - -@@ -61199,14 +64621,8 @@ - assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - assert( iSize>=4 ); /* Minimum cell size is 4 */ -- assert( iStart<=iLast ); -+ assert( iStart<=pPage->pBt->usableSize-4 ); - -- /* Overwrite deleted information with zeros when the secure_delete -- ** option is enabled */ -- if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){ -- memset(&data[iStart], 0, iSize); -- } -- - /* The list of freeblocks must be in ascending order. Find the - ** spot on the list where iStart should be inserted. - */ -@@ -61218,11 +64634,13 @@ - while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){ - if( iFreeBlk<iPtr+4 ){ - if( iFreeBlk==0 ) break; -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - iPtr = iFreeBlk; - } -- if( iFreeBlk>iLast ) return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ if( iFreeBlk>pPage->pBt->usableSize-4 ){ -+ return SQLITE_CORRUPT_PAGE(pPage); -+ } - assert( iFreeBlk>iPtr || iFreeBlk==0 ); - - /* At this point: -@@ -61233,10 +64651,10 @@ - */ - if( iFreeBlk && iEnd+3>=iFreeBlk ){ - nFrag = iFreeBlk - iEnd; -- if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PAGE(pPage); - iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]); - if( iEnd > pPage->pBt->usableSize ){ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - iSize = iEnd - iStart; - iFreeBlk = get2byte(&data[iFreeBlk]); -@@ -61249,28 +64667,34 @@ - if( iPtr>hdr+1 ){ - int iPtrEnd = iPtr + get2byte(&data[iPtr+2]); - if( iPtrEnd+3>=iStart ){ -- if( iPtrEnd>iStart ) return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ if( iPtrEnd>iStart ) return SQLITE_CORRUPT_PAGE(pPage); - nFrag += iStart - iPtrEnd; - iSize = iEnd - iPtr; - iStart = iPtr; - } - } -- if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage); - data[hdr+7] -= nFrag; - } -- if( iStart==get2byte(&data[hdr+5]) ){ -+ x = get2byte(&data[hdr+5]); -+ if( iStart<=x ){ - /* 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( iPtr!=hdr+1 ) return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ if( iStart<x || iPtr!=hdr+1 ) return SQLITE_CORRUPT_PAGE(pPage); - put2byte(&data[hdr+1], iFreeBlk); - put2byte(&data[hdr+5], iEnd); - }else{ - /* Insert the new freeblock into the freelist */ - put2byte(&data[iPtr], iStart); -- put2byte(&data[iStart], iFreeBlk); -- put2byte(&data[iStart+2], iSize); - } -+ if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){ -+ /* Overwrite deleted information with zeros when the secure_delete -+ ** option is enabled */ -+ memset(&data[iStart], 0, iSize); -+ } -+ put2byte(&data[iStart], iFreeBlk); -+ put2byte(&data[iStart+2], iSize); - pPage->nFree += iOrigSize; - return SQLITE_OK; - } -@@ -61330,7 +64754,7 @@ - }else{ - /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is - ** an error. */ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - pPage->max1bytePayload = pBt->max1bytePayload; - return SQLITE_OK; -@@ -61371,7 +64795,7 @@ - /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating - ** the b-tree page type. */ - if( decodeFlags(pPage, data[hdr]) ){ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); - pPage->maskPage = (u16)(pBt->pageSize - 1); -@@ -61390,7 +64814,7 @@ - pPage->nCell = get2byte(&data[hdr+3]); - if( pPage->nCell>MX_CELL(pBt) ){ - /* To many cells for a single page. The page must be corrupt */ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - testcase( pPage->nCell==MX_CELL(pBt) ); - /* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only -@@ -61418,12 +64842,12 @@ - testcase( pc==iCellFirst ); - testcase( pc==iCellLast ); - if( pc<iCellFirst || pc>iCellLast ){ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - sz = pPage->xCellSize(pPage, &data[pc]); - testcase( pc+sz==usableSize ); - if( pc+sz>usableSize ){ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - } - if( !pPage->leaf ) iCellLast++; -@@ -61441,12 +64865,12 @@ - /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will - ** always be at least one cell before the first freeblock. - */ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - while( 1 ){ - if( pc>iCellLast ){ - /* Freeblock off the end of the page */ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - next = get2byte(&data[pc]); - size = get2byte(&data[pc+2]); -@@ -61456,11 +64880,11 @@ - } - if( next>0 ){ - /* Freeblock not in ascending order */ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - if( pc+size>(unsigned int)usableSize ){ - /* Last freeblock extends past page end */ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - } - -@@ -61472,7 +64896,7 @@ - ** area, according to the page header, lies within the page. - */ - if( nFree>usableSize ){ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - pPage->nFree = (u16)(nFree - iCellFirst); - pPage->isInit = 1; -@@ -61585,7 +65009,7 @@ - } - SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree *p){ - assert( sqlite3BtreeHoldsMutex(p) ); -- assert( ((p->pBt->nPage)&0x8000000)==0 ); -+ assert( ((p->pBt->nPage)&0x80000000)==0 ); - return btreePagecount(p->pBt); - } - -@@ -61612,7 +65036,7 @@ - int rc; - DbPage *pDbPage; - assert( sqlite3_mutex_held(pBt->mutex) ); -- assert( pCur==0 || ppPage==&pCur->apPage[pCur->iPage] ); -+ assert( pCur==0 || ppPage==&pCur->pPage ); - assert( pCur==0 || bReadOnly==pCur->curPagerFlags ); - assert( pCur==0 || pCur->iPage>0 ); - -@@ -61646,7 +65070,10 @@ - return SQLITE_OK; - - getAndInitPage_error: -- if( pCur ) pCur->iPage--; -+ if( pCur ){ -+ pCur->iPage--; -+ pCur->pPage = pCur->apPage[pCur->iPage]; -+ } - testcase( pgno==0 ); - assert( pgno!=0 || rc==SQLITE_CORRUPT ); - return rc; -@@ -61655,6 +65082,8 @@ - /* - ** Release a MemPage. This should be called once for each prior - ** call to btreeGetPage. -+** -+** Page1 is a special case and must be released using releasePageOne(). - */ - static void releasePageNotNull(MemPage *pPage){ - assert( pPage->aData ); -@@ -61668,6 +65097,16 @@ - static void releasePage(MemPage *pPage){ - if( pPage ) releasePageNotNull(pPage); - } -+static void releasePageOne(MemPage *pPage){ -+ assert( pPage!=0 ); -+ assert( pPage->aData ); -+ assert( pPage->pBt ); -+ assert( pPage->pDbPage!=0 ); -+ assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); -+ assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); -+ assert( sqlite3_mutex_held(pPage->pBt->mutex) ); -+ sqlite3PagerUnrefPageOne(pPage->pDbPage); -+} - - /* - ** Get an unused page. -@@ -61733,7 +65172,8 @@ - BtShared *pBt = (BtShared*)pArg; - assert( pBt->db ); - assert( sqlite3_mutex_held(pBt->db->mutex) ); -- return sqlite3InvokeBusyHandler(&pBt->db->busyHandler); -+ return sqlite3InvokeBusyHandler(&pBt->db->busyHandler, -+ sqlite3PagerFile(pBt->pPager)); - } - - /* -@@ -61911,7 +65351,7 @@ - } - pBt->openFlags = (u8)flags; - pBt->db = db; -- sqlite3PagerSetBusyhandler(pBt->pPager, btreeInvokeBusyHandler, pBt); -+ sqlite3PagerSetBusyHandler(pBt->pPager, btreeInvokeBusyHandler, pBt); - p->pBt = pBt; - - pBt->pCursor = 0; -@@ -62452,7 +65892,8 @@ - ** set to the value passed to this function as the second parameter, - ** set it so. - */ --#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS -+#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS \ -+ && !defined(SQLITE_OMIT_WAL) - static void setDefaultSyncFlag(BtShared *pBt, u8 safety_level){ - sqlite3 *db; - Db *pDb; -@@ -62472,6 +65913,10 @@ - # define setDefaultSyncFlag(pBt,safety_level) - #endif - -+/* Forward declaration */ -+static int newDatabase(BtShared*); -+ -+ - /* - ** Get a reference to pPage1 of the database file. This will - ** also acquire a readlock on that file. -@@ -62503,6 +65948,9 @@ - if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){ - nPage = nPageFile; - } -+ if( (pBt->db->flags & SQLITE_ResetDatabase)!=0 ){ -+ nPage = 0; -+ } - if( nPage>0 ){ - u32 pageSize; - u32 usableSize; -@@ -62546,7 +65994,7 @@ - }else{ - setDefaultSyncFlag(pBt, SQLITE_DEFAULT_WAL_SYNCHRONOUS+1); - if( isOpen==0 ){ -- releasePage(pPage1); -+ releasePageOne(pPage1); - return SQLITE_OK; - } - } -@@ -62593,7 +66041,7 @@ - ** zero and return SQLITE_OK. The caller will call this function - ** again with the correct page-size. - */ -- releasePage(pPage1); -+ releasePageOne(pPage1); - pBt->usableSize = usableSize; - pBt->pageSize = pageSize; - freeTempSpace(pBt); -@@ -62601,7 +66049,7 @@ - pageSize-usableSize); - return rc; - } -- if( (pBt->db->flags & SQLITE_WriteSchema)==0 && nPage>nPageFile ){ -+ if( sqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){ - rc = SQLITE_CORRUPT_BKPT; - goto page1_init_failed; - } -@@ -62647,7 +66095,7 @@ - return SQLITE_OK; - - page1_init_failed: -- releasePage(pPage1); -+ releasePageOne(pPage1); - pBt->pPage1 = 0; - return rc; - } -@@ -62692,7 +66140,7 @@ - assert( pPage1->aData ); - assert( sqlite3PagerRefcount(pBt->pPager)==1 ); - pBt->pPage1 = 0; -- releasePageNotNull(pPage1); -+ releasePageOne(pPage1); - } - } - -@@ -62789,7 +66237,7 @@ - ** when A already has a read lock, we encourage A to give up and let B - ** proceed. - */ --SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ -+SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){ - BtShared *pBt = p->pBt; - int rc = SQLITE_OK; - -@@ -62805,6 +66253,12 @@ - } - assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 ); - -+ if( (p->db->flags & SQLITE_ResetDatabase) -+ && sqlite3PagerIsreadonly(pBt->pPager)==0 -+ ){ -+ pBt->btsFlags &= ~BTS_READ_ONLY; -+ } -+ - /* Write transactions are not possible on a read-only database */ - if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){ - rc = SQLITE_READONLY; -@@ -62864,6 +66318,11 @@ - rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db)); - if( rc==SQLITE_OK ){ - rc = newDatabase(pBt); -+ }else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){ -+ /* if there was no transaction opened when this function was -+ ** called and SQLITE_BUSY_SNAPSHOT is returned, change the error -+ ** code to SQLITE_BUSY. */ -+ rc = SQLITE_BUSY; - } - } - } -@@ -62873,6 +66332,7 @@ - } - }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && - btreeInvokeBusyHandler(pBt) ); -+ sqlite3PagerResetLockTimeout(pBt->pPager); - - if( rc==SQLITE_OK ){ - if( p->inTrans==TRANS_NONE ){ -@@ -62914,14 +66374,18 @@ - } - } - -- - trans_begun: -- if( rc==SQLITE_OK && wrflag ){ -- /* This call makes sure that the pager has the correct number of -- ** open savepoints. If the second parameter is greater than 0 and -- ** the sub-journal is not already open, then it will be opened here. -- */ -- rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); -+ if( rc==SQLITE_OK ){ -+ if( pSchemaVersion ){ -+ *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]); -+ } -+ if( wrflag ){ -+ /* This call makes sure that the pager has the correct number of -+ ** open savepoints. If the second parameter is greater than 0 and -+ ** the sub-journal is not already open, then it will be opened here. -+ */ -+ rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); -+ } - } - - btreeIntegrity(p); -@@ -62987,7 +66451,7 @@ - if( eType==PTRMAP_OVERFLOW2 ){ - /* The pointer is always the first 4 bytes of the page in this case. */ - if( get4byte(pPage->aData)!=iFrom ){ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - put4byte(pPage->aData, iTo); - }else{ -@@ -63006,7 +66470,7 @@ - pPage->xParseCell(pPage, pCell, &info); - if( info.nLocal<info.nPayload ){ - if( pCell+info.nSize > pPage->aData+pPage->pBt->usableSize ){ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - if( iFrom==get4byte(pCell+info.nSize-4) ){ - put4byte(pCell+info.nSize-4, iTo); -@@ -63024,7 +66488,7 @@ - if( i==nCell ){ - if( eType!=PTRMAP_BTREE || - get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - put4byte(&pPage->aData[pPage->hdrOffset+8], iTo); - } -@@ -63059,6 +66523,7 @@ - eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ); - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( pDbPage->pBt==pBt ); -+ if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT; - - /* Move page iDbPage from its current location to page number iFreePage */ - TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", -@@ -63544,7 +67009,6 @@ - if( pBtree ){ - sqlite3BtreeEnter(pBtree); - for(p=pBtree->pBt->pCursor; p; p=p->pNext){ -- int i; - if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){ - if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){ - rc = saveCursorPosition(p); -@@ -63558,10 +67022,7 @@ - p->eState = CURSOR_FAULT; - p->skipNext = errCode; - } -- for(i=0; i<=p->iPage; i++){ -- releasePage(p->apPage[i]); -- p->apPage[i] = 0; -- } -+ btreeReleaseAllCursorPages(p); - } - sqlite3BtreeLeave(pBtree); - } -@@ -63618,7 +67079,7 @@ - if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); - testcase( pBt->nPage!=nPage ); - pBt->nPage = nPage; -- releasePage(pPage1); -+ releasePageOne(pPage1); - } - assert( countValidCursors(pBt, 1)==0 ); - pBt->inTransaction = TRANS_READ; -@@ -63850,7 +67311,7 @@ - ** of run-time by skipping the initialization of those elements. - */ - SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor *p){ -- memset(p, 0, offsetof(BtCursor, iPage)); -+ memset(p, 0, offsetof(BtCursor, BTCURSOR_FIRST_UNINIT)); - } - - /* -@@ -63860,10 +67321,8 @@ - SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){ - Btree *pBtree = pCur->pBtree; - if( pBtree ){ -- int i; - BtShared *pBt = pCur->pBt; - sqlite3BtreeEnter(pBtree); -- sqlite3BtreeClearCursor(pCur); - assert( pBt->pCursor!=0 ); - if( pBt->pCursor==pCur ){ - pBt->pCursor = pCur->pNext; -@@ -63877,12 +67336,10 @@ - pPrev = pPrev->pNext; - }while( ALWAYS(pPrev) ); - } -- for(i=0; i<=pCur->iPage; i++){ -- releasePage(pCur->apPage[i]); -- } -+ btreeReleaseAllCursorPages(pCur); - unlockBtreeIfUnused(pBt); - sqlite3_free(pCur->aOverflow); -- /* sqlite3_free(pCur); */ -+ sqlite3_free(pCur->pKey); - sqlite3BtreeLeave(pBtree); - } - return SQLITE_OK; -@@ -63897,12 +67354,19 @@ - ** Using this cache reduces the number of calls to btreeParseCell(). - */ - #ifndef NDEBUG -+ static int cellInfoEqual(CellInfo *a, CellInfo *b){ -+ if( a->nKey!=b->nKey ) return 0; -+ if( a->pPayload!=b->pPayload ) return 0; -+ if( a->nPayload!=b->nPayload ) return 0; -+ if( a->nLocal!=b->nLocal ) return 0; -+ if( a->nSize!=b->nSize ) return 0; -+ return 1; -+ } - static void assertCellInfo(BtCursor *pCur){ - CellInfo info; -- int iPage = pCur->iPage; - memset(&info, 0, sizeof(info)); -- btreeParseCell(pCur->apPage[iPage], pCur->ix, &info); -- assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 ); -+ btreeParseCell(pCur->pPage, pCur->ix, &info); -+ assert( CORRUPT_DB || cellInfoEqual(&info, &pCur->info) ); - } - #else - #define assertCellInfo(x) -@@ -63909,9 +67373,8 @@ - #endif - static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){ - if( pCur->info.nSize==0 ){ -- int iPage = pCur->iPage; - pCur->curFlags |= BTCF_ValidNKey; -- btreeParseCell(pCur->apPage[iPage],pCur->ix,&pCur->info); -+ btreeParseCell(pCur->pPage,pCur->ix,&pCur->info); - }else{ - assertCellInfo(pCur); - } -@@ -63946,7 +67409,21 @@ - return pCur->info.nKey; - } - -+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC - /* -+** Return the offset into the database file for the start of the -+** payload to which the cursor is pointing. -+*/ -+SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor *pCur){ -+ assert( cursorHoldsMutex(pCur) ); -+ assert( pCur->eState==CURSOR_VALID ); -+ getCellInfo(pCur); -+ return (i64)pCur->pBt->pageSize*((i64)pCur->pPage->pgno - 1) + -+ (i64)(pCur->info.pPayload - pCur->pPage->aData); -+} -+#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */ -+ -+/* - ** Return the number of bytes of payload for the entry that pCur is - ** currently pointing to. For table btrees, this will be the amount - ** of data. For index btrees, this will be the size of the key. -@@ -64109,7 +67586,7 @@ - unsigned char *aPayload; - int rc = SQLITE_OK; - int iIdx = 0; -- MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */ -+ MemPage *pPage = pCur->pPage; /* Btree page of current entry */ - BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */ - #ifdef SQLITE_DIRECT_OVERFLOW_READ - unsigned char * const pBufStart = pBuf; /* Start of original out buffer */ -@@ -64132,7 +67609,7 @@ - ** &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] - ** but is recast into its current form to avoid integer overflow problems - */ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - - /* Check if data must be read/written to/from the btree page itself. */ -@@ -64165,7 +67642,9 @@ - */ - if( (pCur->curFlags & BTCF_ValidOvfl)==0 ){ - int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; -- if( nOvfl>pCur->nOvflAlloc ){ -+ if( pCur->aOverflow==0 -+ || nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow) -+ ){ - Pgno *aNew = (Pgno*)sqlite3Realloc( - pCur->aOverflow, nOvfl*2*sizeof(Pgno) - ); -@@ -64172,7 +67651,6 @@ - if( aNew==0 ){ - return SQLITE_NOMEM_BKPT; - }else{ -- pCur->nOvflAlloc = nOvfl*2; - pCur->aOverflow = aNew; - } - } -@@ -64217,9 +67695,6 @@ - /* Need to read this page properly. It contains some of the - ** range of data that is being read (eOp==0) or written (eOp!=0). - */ --#ifdef SQLITE_DIRECT_OVERFLOW_READ -- sqlite3_file *fd; /* File from which to do direct overflow read */ --#endif - int a = amt; - if( a + offset > ovflSize ){ - a = ovflSize - offset; -@@ -64230,7 +67705,7 @@ - ** - ** 1) this is a read operation, and - ** 2) data is required from the start of this overflow page, and -- ** 3) there is no open write-transaction, and -+ ** 3) there are no dirty pages in the page-cache - ** 4) the database is file-backed, and - ** 5) the page is not in the WAL file - ** 6) at least 4 bytes have already been read into the output buffer -@@ -64241,11 +67716,10 @@ - */ - if( eOp==0 /* (1) */ - && offset==0 /* (2) */ -- && pBt->inTransaction==TRANS_READ /* (3) */ -- && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (4) */ -- && 0==sqlite3PagerUseWal(pBt->pPager, nextPage) /* (5) */ -+ && sqlite3PagerDirectReadOk(pBt->pPager, nextPage) /* (3,4,5) */ - && &pBuf[-4]>=pBufStart /* (6) */ - ){ -+ sqlite3_file *fd = sqlite3PagerFile(pBt->pPager); - u8 aSave[4]; - u8 *aWrite = &pBuf[-4]; - assert( aWrite>=pBufStart ); /* due to (6) */ -@@ -64280,7 +67754,7 @@ - - if( rc==SQLITE_OK && amt>0 ){ - /* Overflow chain ends prematurely */ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - return rc; - } -@@ -64305,8 +67779,8 @@ - SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ - assert( cursorHoldsMutex(pCur) ); - assert( pCur->eState==CURSOR_VALID ); -- assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] ); -- assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell ); -+ assert( pCur->iPage>=0 && pCur->pPage ); -+ assert( pCur->ix<pCur->pPage->nCell ); - return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0); - } - -@@ -64363,18 +67837,23 @@ - BtCursor *pCur, /* Cursor pointing to entry to read from */ - u32 *pAmt /* Write the number of available bytes here */ - ){ -- u32 amt; -- assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]); -+ int amt; -+ assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage); - assert( pCur->eState==CURSOR_VALID ); - assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); - assert( cursorOwnsBtShared(pCur) ); -- assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell ); -+ assert( pCur->ix<pCur->pPage->nCell ); - assert( pCur->info.nSize>0 ); -- assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB ); -- assert( pCur->info.pPayload<pCur->apPage[pCur->iPage]->aDataEnd ||CORRUPT_DB); -- amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload); -- if( pCur->info.nLocal<amt ) amt = pCur->info.nLocal; -- *pAmt = amt; -+ assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB ); -+ assert( pCur->info.pPayload<pCur->pPage->aDataEnd ||CORRUPT_DB); -+ amt = pCur->info.nLocal; -+ if( amt>(int)(pCur->pPage->aDataEnd - pCur->info.pPayload) ){ -+ /* There is too little space on the page for the expected amount -+ ** of local content. Database must be corrupt. */ -+ assert( CORRUPT_DB ); -+ amt = MAX(0, (int)(pCur->pPage->aDataEnd - pCur->info.pPayload)); -+ } -+ *pAmt = (u32)amt; - return (void*)pCur->info.pPayload; - } - -@@ -64419,10 +67898,11 @@ - } - pCur->info.nSize = 0; - pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); -- pCur->aiIdx[pCur->iPage++] = pCur->ix; -+ pCur->aiIdx[pCur->iPage] = pCur->ix; -+ pCur->apPage[pCur->iPage] = pCur->pPage; - pCur->ix = 0; -- return getAndInitPage(pBt, newPgno, &pCur->apPage[pCur->iPage], -- pCur, pCur->curPagerFlags); -+ pCur->iPage++; -+ return getAndInitPage(pBt, newPgno, &pCur->pPage, pCur, pCur->curPagerFlags); - } - - #ifdef SQLITE_DEBUG -@@ -64456,20 +67936,23 @@ - ** the largest cell index. - */ - static void moveToParent(BtCursor *pCur){ -+ MemPage *pLeaf; - assert( cursorOwnsBtShared(pCur) ); - assert( pCur->eState==CURSOR_VALID ); - assert( pCur->iPage>0 ); -- assert( pCur->apPage[pCur->iPage] ); -+ assert( pCur->pPage ); - assertParentIndex( - pCur->apPage[pCur->iPage-1], - pCur->aiIdx[pCur->iPage-1], -- pCur->apPage[pCur->iPage]->pgno -+ pCur->pPage->pgno - ); - testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell ); - pCur->info.nSize = 0; - pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); - pCur->ix = pCur->aiIdx[pCur->iPage-1]; -- releasePageNotNull(pCur->apPage[pCur->iPage--]); -+ pLeaf = pCur->pPage; -+ pCur->pPage = pCur->apPage[--pCur->iPage]; -+ releasePageNotNull(pLeaf); - } - - /* -@@ -64481,9 +67964,9 @@ - ** single child page. This can only happen with the table rooted at page 1. - ** - ** If the b-tree structure is empty, the cursor state is set to --** CURSOR_INVALID. Otherwise, the cursor is set to point to the first --** cell located on the root (or virtual root) page and the cursor state --** is set to CURSOR_VALID. -+** CURSOR_INVALID and this routine returns SQLITE_EMPTY. Otherwise, -+** the cursor is set to point to the first cell located on the root -+** (or virtual root) page and the cursor state is set to CURSOR_VALID. - ** - ** If this function returns successfully, it may be assumed that the - ** page-header flags indicate that the [virtual] root-page is the expected -@@ -64501,37 +67984,40 @@ - assert( CURSOR_INVALID < CURSOR_REQUIRESEEK ); - assert( CURSOR_VALID < CURSOR_REQUIRESEEK ); - assert( CURSOR_FAULT > CURSOR_REQUIRESEEK ); -- if( pCur->eState>=CURSOR_REQUIRESEEK ){ -- if( pCur->eState==CURSOR_FAULT ){ -- assert( pCur->skipNext!=SQLITE_OK ); -- return pCur->skipNext; -- } -- sqlite3BtreeClearCursor(pCur); -- } -+ assert( pCur->eState < CURSOR_REQUIRESEEK || pCur->iPage<0 ); -+ assert( pCur->pgnoRoot>0 || pCur->iPage<0 ); - - if( pCur->iPage>=0 ){ - if( pCur->iPage ){ -- do{ -- assert( pCur->apPage[pCur->iPage]!=0 ); -- releasePageNotNull(pCur->apPage[pCur->iPage--]); -- }while( pCur->iPage); -+ releasePageNotNull(pCur->pPage); -+ while( --pCur->iPage ){ -+ releasePageNotNull(pCur->apPage[pCur->iPage]); -+ } -+ pCur->pPage = pCur->apPage[0]; - goto skip_init; - } - }else if( pCur->pgnoRoot==0 ){ - pCur->eState = CURSOR_INVALID; -- return SQLITE_OK; -+ return SQLITE_EMPTY; - }else{ - assert( pCur->iPage==(-1) ); -- rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0], -+ if( pCur->eState>=CURSOR_REQUIRESEEK ){ -+ if( pCur->eState==CURSOR_FAULT ){ -+ assert( pCur->skipNext!=SQLITE_OK ); -+ return pCur->skipNext; -+ } -+ sqlite3BtreeClearCursor(pCur); -+ } -+ rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->pPage, - 0, pCur->curPagerFlags); - if( rc!=SQLITE_OK ){ - pCur->eState = CURSOR_INVALID; -- return rc; -+ return rc; - } - pCur->iPage = 0; -- pCur->curIntKey = pCur->apPage[0]->intKey; -+ pCur->curIntKey = pCur->pPage->intKey; - } -- pRoot = pCur->apPage[0]; -+ pRoot = pCur->pPage; - assert( pRoot->pgno==pCur->pgnoRoot ); - - /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor -@@ -64546,7 +68032,7 @@ - ** (or the freelist). */ - assert( pRoot->intKey==1 || pRoot->intKey==0 ); - if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){ -- return SQLITE_CORRUPT_PGNO(pCur->apPage[pCur->iPage]->pgno); -+ return SQLITE_CORRUPT_PAGE(pCur->pPage); - } - - skip_init: -@@ -64554,7 +68040,7 @@ - pCur->info.nSize = 0; - pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl); - -- pRoot = pCur->apPage[0]; -+ pRoot = pCur->pPage; - if( pRoot->nCell>0 ){ - pCur->eState = CURSOR_VALID; - }else if( !pRoot->leaf ){ -@@ -64565,6 +68051,7 @@ - rc = moveToChild(pCur, subpage); - }else{ - pCur->eState = CURSOR_INVALID; -+ rc = SQLITE_EMPTY; - } - return rc; - } -@@ -64583,7 +68070,7 @@ - - assert( cursorOwnsBtShared(pCur) ); - assert( pCur->eState==CURSOR_VALID ); -- while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){ -+ while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){ - assert( pCur->ix<pPage->nCell ); - pgno = get4byte(findCell(pPage, pCur->ix)); - rc = moveToChild(pCur, pgno); -@@ -64608,7 +68095,7 @@ - - assert( cursorOwnsBtShared(pCur) ); - assert( pCur->eState==CURSOR_VALID ); -- while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){ -+ while( !(pPage = pCur->pPage)->leaf ){ - pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); - pCur->ix = pPage->nCell; - rc = moveToChild(pCur, pgno); -@@ -64631,18 +68118,34 @@ - assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); - rc = moveToRoot(pCur); - if( rc==SQLITE_OK ){ -- if( pCur->eState==CURSOR_INVALID ){ -- assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); -- *pRes = 1; -- }else{ -- assert( pCur->apPage[pCur->iPage]->nCell>0 ); -- *pRes = 0; -- rc = moveToLeftmost(pCur); -- } -+ assert( pCur->pPage->nCell>0 ); -+ *pRes = 0; -+ rc = moveToLeftmost(pCur); -+ }else if( rc==SQLITE_EMPTY ){ -+ assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); -+ *pRes = 1; -+ rc = SQLITE_OK; - } - return rc; - } - -+/* -+** This function is a no-op if cursor pCur does not point to a valid row. -+** Otherwise, if pCur is valid, configure it so that the next call to -+** sqlite3BtreeNext() is a no-op. -+*/ -+#ifndef SQLITE_OMIT_WINDOWFUNC -+SQLITE_PRIVATE void sqlite3BtreeSkipNext(BtCursor *pCur){ -+ /* We believe that the cursor must always be in the valid state when -+ ** this routine is called, but the proof is difficult, so we add an -+ ** ALWaYS() test just in case we are wrong. */ -+ if( ALWAYS(pCur->eState==CURSOR_VALID) ){ -+ pCur->eState = CURSOR_SKIPNEXT; -+ pCur->skipNext = 1; -+ } -+} -+#endif /* SQLITE_OMIT_WINDOWFUNC */ -+ - /* Move the cursor to the last entry in the table. Return SQLITE_OK - ** on success. Set *pRes to 0 if the cursor actually points to something - ** or set *pRes to 1 if the table is empty. -@@ -64662,8 +68165,8 @@ - for(ii=0; ii<pCur->iPage; ii++){ - assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell ); - } -- assert( pCur->ix==pCur->apPage[pCur->iPage]->nCell-1 ); -- assert( pCur->apPage[pCur->iPage]->leaf ); -+ assert( pCur->ix==pCur->pPage->nCell-1 ); -+ assert( pCur->pPage->leaf ); - #endif - return SQLITE_OK; - } -@@ -64670,20 +68173,18 @@ - - rc = moveToRoot(pCur); - if( rc==SQLITE_OK ){ -- if( CURSOR_INVALID==pCur->eState ){ -- assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); -- *pRes = 1; -+ assert( pCur->eState==CURSOR_VALID ); -+ *pRes = 0; -+ rc = moveToRightmost(pCur); -+ if( rc==SQLITE_OK ){ -+ pCur->curFlags |= BTCF_AtLast; - }else{ -- assert( pCur->eState==CURSOR_VALID ); -- *pRes = 0; -- rc = moveToRightmost(pCur); -- if( rc==SQLITE_OK ){ -- pCur->curFlags |= BTCF_AtLast; -- }else{ -- pCur->curFlags &= ~BTCF_AtLast; -- } -- -+ pCur->curFlags &= ~BTCF_AtLast; - } -+ }else if( rc==SQLITE_EMPTY ){ -+ assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); -+ *pRes = 1; -+ rc = SQLITE_OK; - } - return rc; - } -@@ -64782,22 +68283,23 @@ - - rc = moveToRoot(pCur); - if( rc ){ -+ if( rc==SQLITE_EMPTY ){ -+ assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); -+ *pRes = -1; -+ return SQLITE_OK; -+ } - return rc; - } -- assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage] ); -- assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->isInit ); -- assert( pCur->eState==CURSOR_INVALID || pCur->apPage[pCur->iPage]->nCell>0 ); -- if( pCur->eState==CURSOR_INVALID ){ -- *pRes = -1; -- assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); -- return SQLITE_OK; -- } -- assert( pCur->apPage[0]->intKey==pCur->curIntKey ); -+ assert( pCur->pPage ); -+ assert( pCur->pPage->isInit ); -+ assert( pCur->eState==CURSOR_VALID ); -+ assert( pCur->pPage->nCell > 0 ); -+ assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey ); - assert( pCur->curIntKey || pIdxKey ); - for(;;){ - int lwr, upr, idx, c; - Pgno chldPg; -- MemPage *pPage = pCur->apPage[pCur->iPage]; -+ MemPage *pPage = pCur->pPage; - u8 *pCell; /* Pointer to current cell in pPage */ - - /* pPage->nCell must be greater than zero. If this is the root-page -@@ -64820,7 +68322,7 @@ - if( pPage->intKeyLeaf ){ - while( 0x80 <= *(pCell++) ){ - if( pCell>=pPage->aDataEnd ){ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - } - } -@@ -64894,7 +68396,7 @@ - testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */ - testcase( nCell==2 ); /* Minimum legal index key size */ - if( nCell<2 ){ -- rc = SQLITE_CORRUPT_PGNO(pPage->pgno); -+ rc = SQLITE_CORRUPT_PAGE(pPage); - goto moveto_finish; - } - pCellKey = sqlite3Malloc( nCell+18 ); -@@ -64925,7 +68427,7 @@ - *pRes = 0; - rc = SQLITE_OK; - pCur->ix = (u16)idx; -- if( pIdxKey->errCode ) rc = SQLITE_CORRUPT; -+ if( pIdxKey->errCode ) rc = SQLITE_CORRUPT_BKPT; - goto moveto_finish; - } - if( lwr>upr ) break; -@@ -64936,7 +68438,7 @@ - assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); - assert( pPage->isInit ); - if( pPage->leaf ){ -- assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell ); -+ assert( pCur->ix<pCur->pPage->nCell ); - pCur->ix = (u16)idx; - *pRes = c; - rc = SQLITE_OK; -@@ -64990,9 +68492,10 @@ - ** opcode, and it that case the cursor will always be valid and - ** will always point to a leaf node. */ - if( NEVER(pCur->eState!=CURSOR_VALID) ) return -1; -- if( NEVER(pCur->apPage[pCur->iPage]->leaf==0) ) return -1; -+ if( NEVER(pCur->pPage->leaf==0) ) return -1; - -- for(n=1, i=0; i<=pCur->iPage; i++){ -+ n = pCur->pPage->nCell; -+ for(i=0; i<pCur->iPage; i++){ - n *= pCur->apPage[i]->nCell; - } - return n; -@@ -65045,9 +68548,18 @@ - } - } - -- pPage = pCur->apPage[pCur->iPage]; -+ pPage = pCur->pPage; - idx = ++pCur->ix; -- assert( pPage->isInit ); -+ if( !pPage->isInit ){ -+ /* The only known way for this to happen is for there to be a -+ ** recursive SQL function that does a DELETE operation as part of a -+ ** SELECT which deletes content out from under an active cursor -+ ** in a corrupt database file where the table being DELETE-ed from -+ ** has pages in common with the table being queried. See TH3 -+ ** module cov1/btree78.test testcase 220 (2018-06-08) for an -+ ** example. */ -+ return SQLITE_CORRUPT_BKPT; -+ } - - /* If the database file is corrupt, it is possible for the value of idx - ** to be invalid here. This can only occur if a second cursor modifies -@@ -65068,7 +68580,7 @@ - return SQLITE_DONE; - } - moveToParent(pCur); -- pPage = pCur->apPage[pCur->iPage]; -+ pPage = pCur->pPage; - }while( pCur->ix>=pPage->nCell ); - if( pPage->intKey ){ - return sqlite3BtreeNext(pCur, 0); -@@ -65091,7 +68603,7 @@ - pCur->info.nSize = 0; - pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); - if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur); -- pPage = pCur->apPage[pCur->iPage]; -+ pPage = pCur->pPage; - if( (++pCur->ix)>=pPage->nCell ){ - pCur->ix--; - return btreeNext(pCur); -@@ -65150,7 +68662,7 @@ - } - } - -- pPage = pCur->apPage[pCur->iPage]; -+ pPage = pCur->pPage; - assert( pPage->isInit ); - if( !pPage->leaf ){ - int idx = pCur->ix; -@@ -65169,7 +68681,7 @@ - assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 ); - - pCur->ix--; -- pPage = pCur->apPage[pCur->iPage]; -+ pPage = pCur->pPage; - if( pPage->intKey && !pPage->leaf ){ - rc = sqlite3BtreePrevious(pCur, 0); - }else{ -@@ -65187,7 +68699,7 @@ - pCur->info.nSize = 0; - if( pCur->eState!=CURSOR_VALID - || pCur->ix==0 -- || pCur->apPage[pCur->iPage]->leaf==0 -+ || pCur->pPage->leaf==0 - ){ - return btreePrevious(pCur); - } -@@ -65674,9 +69186,8 @@ - } - - /* --** Free any overflow pages associated with the given Cell. Write the --** local Cell size (the number of bytes on the original page, omitting --** overflow) into *pnSize. -+** Free any overflow pages associated with the given Cell. Store -+** size information about the cell in pInfo. - */ - static int clearCell( - MemPage *pPage, /* The page that contains the Cell */ -@@ -65683,7 +69194,7 @@ - unsigned char *pCell, /* First byte of the Cell */ - CellInfo *pInfo /* Size information about the cell */ - ){ -- BtShared *pBt = pPage->pBt; -+ BtShared *pBt; - Pgno ovflPgno; - int rc; - int nOvfl; -@@ -65694,11 +69205,14 @@ - if( pInfo->nLocal==pInfo->nPayload ){ - return SQLITE_OK; /* No overflow pages. Return without doing anything */ - } -- if( pCell+pInfo->nSize-1 > pPage->aData+pPage->maskPage ){ -+ testcase( pCell + pInfo->nSize == pPage->aDataEnd ); -+ testcase( pCell + (pInfo->nSize-1) == pPage->aDataEnd ); -+ if( pCell + pInfo->nSize > pPage->aDataEnd ){ - /* Cell extends past end of page */ -- return SQLITE_CORRUPT_PGNO(pPage->pgno); -+ return SQLITE_CORRUPT_PAGE(pPage); - } - ovflPgno = get4byte(pCell + pInfo->nSize - 4); -+ pBt = pPage->pBt; - assert( pBt->usableSize > 4 ); - ovflPageSize = pBt->usableSize - 4; - nOvfl = (pInfo->nPayload - pInfo->nLocal + ovflPageSize - 1)/ovflPageSize; -@@ -65766,14 +69280,13 @@ - ){ - int nPayload; - const u8 *pSrc; -- int nSrc, n, rc; -+ int nSrc, n, rc, mn; - int spaceLeft; -- MemPage *pOvfl = 0; -- MemPage *pToRelease = 0; -+ MemPage *pToRelease; - unsigned char *pPrior; - unsigned char *pPayload; -- BtShared *pBt = pPage->pBt; -- Pgno pgnoOvfl = 0; -+ BtShared *pBt; -+ Pgno pgnoOvfl; - int nHeader; - - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); -@@ -65780,7 +69293,7 @@ - - /* pPage is not necessarily writeable since pCell might be auxiliary - ** buffer space that is separate from the pPage buffer area */ -- assert( pCell<pPage->aData || pCell>=&pPage->aData[pBt->pageSize] -+ assert( pCell<pPage->aData || pCell>=&pPage->aData[pPage->pBt->pageSize] - || sqlite3PagerIswriteable(pPage->pDbPage) ); - - /* Fill in the header. */ -@@ -65800,26 +69313,37 @@ - } - - /* Fill in the payload */ -+ pPayload = &pCell[nHeader]; - if( nPayload<=pPage->maxLocal ){ -+ /* This is the common case where everything fits on the btree page -+ ** and no overflow pages are required. */ - n = nHeader + nPayload; - testcase( n==3 ); - testcase( n==4 ); - if( n<4 ) n = 4; - *pnSize = n; -- spaceLeft = nPayload; -- pPrior = pCell; -- }else{ -- int mn = pPage->minLocal; -- n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4); -- testcase( n==pPage->maxLocal ); -- testcase( n==pPage->maxLocal+1 ); -- if( n > pPage->maxLocal ) n = mn; -- spaceLeft = n; -- *pnSize = n + nHeader + 4; -- pPrior = &pCell[nHeader+n]; -+ assert( nSrc<=nPayload ); -+ testcase( nSrc<nPayload ); -+ memcpy(pPayload, pSrc, nSrc); -+ memset(pPayload+nSrc, 0, nPayload-nSrc); -+ return SQLITE_OK; - } -- pPayload = &pCell[nHeader]; - -+ /* If we reach this point, it means that some of the content will need -+ ** to spill onto overflow pages. -+ */ -+ mn = pPage->minLocal; -+ n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4); -+ testcase( n==pPage->maxLocal ); -+ testcase( n==pPage->maxLocal+1 ); -+ if( n > pPage->maxLocal ) n = mn; -+ spaceLeft = n; -+ *pnSize = n + nHeader + 4; -+ pPrior = &pCell[nHeader+n]; -+ pToRelease = 0; -+ pgnoOvfl = 0; -+ pBt = pPage->pBt; -+ - /* At this point variables should be set as follows: - ** - ** nPayload Total payload size in bytes -@@ -65844,8 +69368,35 @@ - #endif - - /* Write the payload into the local Cell and any extra into overflow pages */ -- while( nPayload>0 ){ -+ while( 1 ){ -+ n = nPayload; -+ if( n>spaceLeft ) n = spaceLeft; -+ -+ /* If pToRelease is not zero than pPayload points into the data area -+ ** of pToRelease. Make sure pToRelease is still writeable. */ -+ assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); -+ -+ /* If pPayload is part of the data area of pPage, then make sure pPage -+ ** is still writeable */ -+ assert( pPayload<pPage->aData || pPayload>=&pPage->aData[pBt->pageSize] -+ || sqlite3PagerIswriteable(pPage->pDbPage) ); -+ -+ if( nSrc>=n ){ -+ memcpy(pPayload, pSrc, n); -+ }else if( nSrc>0 ){ -+ n = nSrc; -+ memcpy(pPayload, pSrc, n); -+ }else{ -+ memset(pPayload, 0, n); -+ } -+ nPayload -= n; -+ if( nPayload<=0 ) break; -+ pPayload += n; -+ pSrc += n; -+ nSrc -= n; -+ spaceLeft -= n; - if( spaceLeft==0 ){ -+ MemPage *pOvfl = 0; - #ifndef SQLITE_OMIT_AUTOVACUUM - Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */ - if( pBt->autoVacuum ){ -@@ -65898,30 +69449,6 @@ - pPayload = &pOvfl->aData[4]; - spaceLeft = pBt->usableSize - 4; - } -- n = nPayload; -- if( n>spaceLeft ) n = spaceLeft; -- -- /* If pToRelease is not zero than pPayload points into the data area -- ** of pToRelease. Make sure pToRelease is still writeable. */ -- assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); -- -- /* If pPayload is part of the data area of pPage, then make sure pPage -- ** is still writeable */ -- assert( pPayload<pPage->aData || pPayload>=&pPage->aData[pBt->pageSize] -- || sqlite3PagerIswriteable(pPage->pDbPage) ); -- -- if( nSrc>0 ){ -- if( n>nSrc ) n = nSrc; -- assert( pSrc ); -- memcpy(pPayload, pSrc, n); -- }else{ -- memset(pPayload, 0, n); -- } -- nPayload -= n; -- pPayload += n; -- pSrc += n; -- nSrc -= n; -- spaceLeft -= n; - } - releasePage(pToRelease); - return SQLITE_OK; -@@ -65953,7 +69480,7 @@ - hdr = pPage->hdrOffset; - testcase( pc==get2byte(&data[hdr+5]) ); - testcase( pc+sz==pPage->pBt->usableSize ); -- if( pc < (u32)get2byte(&data[hdr+5]) || pc+sz > pPage->pBt->usableSize ){ -+ if( pc+sz > pPage->pBt->usableSize ){ - *pRC = SQLITE_CORRUPT_BKPT; - return; - } -@@ -66820,10 +70347,8 @@ - + nMaxCells*sizeof(u16) /* b.szCell */ - + pBt->pageSize; /* aSpace1 */ - -- /* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer -- ** that is more than 6 times the database page size. */ - assert( szScratch<=6*(int)pBt->pageSize ); -- b.apCell = sqlite3ScratchMalloc( szScratch ); -+ b.apCell = sqlite3StackAllocRaw(0, szScratch ); - if( b.apCell==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto balance_cleanup; -@@ -66868,7 +70393,7 @@ - } - - /* Load b.apCell[] with pointers to all cells in pOld. If pOld -- ** constains overflow cells, include them in the b.apCell[] array -+ ** contains overflow cells, include them in the b.apCell[] array - ** in the correct spot. - ** - ** Note that when there are multiple overflow cells, it is always the -@@ -67401,7 +70926,7 @@ - ** Cleanup before returning. - */ - balance_cleanup: -- sqlite3ScratchFree(b.apCell); -+ sqlite3StackFree(0, b.apCell); - for(i=0; i<nOld; i++){ - releasePage(apOld[i]); - } -@@ -67500,7 +71025,7 @@ - - do { - int iPage = pCur->iPage; -- MemPage *pPage = pCur->apPage[iPage]; -+ MemPage *pPage = pCur->pPage; - - if( iPage==0 ){ - if( pPage->nOverflow ){ -@@ -67516,7 +71041,9 @@ - pCur->iPage = 1; - pCur->ix = 0; - pCur->aiIdx[0] = 0; -- assert( pCur->apPage[1]->nOverflow ); -+ pCur->apPage[0] = pPage; -+ pCur->pPage = pCur->apPage[1]; -+ assert( pCur->pPage->nOverflow ); - } - }else{ - break; -@@ -67596,6 +71123,7 @@ - releasePage(pPage); - pCur->iPage--; - assert( pCur->iPage>=0 ); -+ pCur->pPage = pCur->apPage[pCur->iPage]; - } - }while( rc==SQLITE_OK ); - -@@ -67605,8 +71133,96 @@ - return rc; - } - -+/* Overwrite content from pX into pDest. Only do the write if the -+** content is different from what is already there. -+*/ -+static int btreeOverwriteContent( -+ MemPage *pPage, /* MemPage on which writing will occur */ -+ u8 *pDest, /* Pointer to the place to start writing */ -+ const BtreePayload *pX, /* Source of data to write */ -+ int iOffset, /* Offset of first byte to write */ -+ int iAmt /* Number of bytes to be written */ -+){ -+ int nData = pX->nData - iOffset; -+ if( nData<=0 ){ -+ /* Overwritting with zeros */ -+ int i; -+ for(i=0; i<iAmt && pDest[i]==0; i++){} -+ if( i<iAmt ){ -+ int rc = sqlite3PagerWrite(pPage->pDbPage); -+ if( rc ) return rc; -+ memset(pDest + i, 0, iAmt - i); -+ } -+ }else{ -+ if( nData<iAmt ){ -+ /* Mixed read data and zeros at the end. Make a recursive call -+ ** to write the zeros then fall through to write the real data */ -+ int rc = btreeOverwriteContent(pPage, pDest+nData, pX, iOffset+nData, -+ iAmt-nData); -+ if( rc ) return rc; -+ iAmt = nData; -+ } -+ if( memcmp(pDest, ((u8*)pX->pData) + iOffset, iAmt)!=0 ){ -+ int rc = sqlite3PagerWrite(pPage->pDbPage); -+ if( rc ) return rc; -+ memcpy(pDest, ((u8*)pX->pData) + iOffset, iAmt); -+ } -+ } -+ return SQLITE_OK; -+} - - /* -+** Overwrite the cell that cursor pCur is pointing to with fresh content -+** contained in pX. -+*/ -+static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ -+ int iOffset; /* Next byte of pX->pData to write */ -+ int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */ -+ int rc; /* Return code */ -+ MemPage *pPage = pCur->pPage; /* Page being written */ -+ BtShared *pBt; /* Btree */ -+ Pgno ovflPgno; /* Next overflow page to write */ -+ u32 ovflPageSize; /* Size to write on overflow page */ -+ -+ if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd ){ -+ return SQLITE_CORRUPT_BKPT; -+ } -+ /* Overwrite the local portion first */ -+ rc = btreeOverwriteContent(pPage, pCur->info.pPayload, pX, -+ 0, pCur->info.nLocal); -+ if( rc ) return rc; -+ if( pCur->info.nLocal==nTotal ) return SQLITE_OK; -+ -+ /* Now overwrite the overflow pages */ -+ iOffset = pCur->info.nLocal; -+ assert( nTotal>=0 ); -+ assert( iOffset>=0 ); -+ ovflPgno = get4byte(pCur->info.pPayload + iOffset); -+ pBt = pPage->pBt; -+ ovflPageSize = pBt->usableSize - 4; -+ do{ -+ rc = btreeGetPage(pBt, ovflPgno, &pPage, 0); -+ if( rc ) return rc; -+ if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 ){ -+ rc = SQLITE_CORRUPT_BKPT; -+ }else{ -+ if( iOffset+ovflPageSize<(u32)nTotal ){ -+ ovflPgno = get4byte(pPage->aData); -+ }else{ -+ ovflPageSize = nTotal - iOffset; -+ } -+ rc = btreeOverwriteContent(pPage, pPage->aData+4, pX, -+ iOffset, ovflPageSize); -+ } -+ sqlite3PagerUnref(pPage->pDbPage); -+ if( rc ) return rc; -+ iOffset += ovflPageSize; -+ }while( iOffset<nTotal ); -+ return SQLITE_OK; -+} -+ -+ -+/* - ** Insert a new record into the BTree. The content of the new record - ** is described by the pX object. The pCur cursor is used only to - ** define what table the record should be inserted into, and is left -@@ -67695,39 +71311,90 @@ - invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0); - - /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing -- ** to a row with the same key as the new entry being inserted. */ -- assert( (flags & BTREE_SAVEPOSITION)==0 || -- ((pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey) ); -+ ** to a row with the same key as the new entry being inserted. -+ */ -+#ifdef SQLITE_DEBUG -+ if( flags & BTREE_SAVEPOSITION ){ -+ assert( pCur->curFlags & BTCF_ValidNKey ); -+ assert( pX->nKey==pCur->info.nKey ); -+ assert( pCur->info.nSize!=0 ); -+ assert( loc==0 ); -+ } -+#endif - -- /* If the cursor is currently on the last row and we are appending a -- ** new row onto the end, set the "loc" to avoid an unnecessary -- ** btreeMoveto() call */ -+ /* On the other hand, BTREE_SAVEPOSITION==0 does not imply -+ ** that the cursor is not pointing to a row to be overwritten. -+ ** So do a complete check. -+ */ - if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){ -- loc = 0; -+ /* The cursor is pointing to the entry that is to be -+ ** overwritten */ -+ assert( pX->nData>=0 && pX->nZero>=0 ); -+ if( pCur->info.nSize!=0 -+ && pCur->info.nPayload==(u32)pX->nData+pX->nZero -+ ){ -+ /* New entry is the same size as the old. Do an overwrite */ -+ return btreeOverwriteCell(pCur, pX); -+ } -+ assert( loc==0 ); - }else if( loc==0 ){ -+ /* The cursor is *not* pointing to the cell to be overwritten, nor -+ ** to an adjacent cell. Move the cursor so that it is pointing either -+ ** to the cell to be overwritten or an adjacent cell. -+ */ - rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc); - if( rc ) return rc; - } -- }else if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){ -- if( pX->nMem ){ -- UnpackedRecord r; -- r.pKeyInfo = pCur->pKeyInfo; -- r.aMem = pX->aMem; -- r.nField = pX->nMem; -- r.default_rc = 0; -- r.errCode = 0; -- r.r1 = 0; -- r.r2 = 0; -- r.eqSeen = 0; -- rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc); -- }else{ -- rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc); -+ }else{ -+ /* This is an index or a WITHOUT ROWID table */ -+ -+ /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing -+ ** to a row with the same key as the new entry being inserted. -+ */ -+ assert( (flags & BTREE_SAVEPOSITION)==0 || loc==0 ); -+ -+ /* If the cursor is not already pointing either to the cell to be -+ ** overwritten, or if a new cell is being inserted, if the cursor is -+ ** not pointing to an immediately adjacent cell, then move the cursor -+ ** so that it does. -+ */ -+ if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){ -+ if( pX->nMem ){ -+ UnpackedRecord r; -+ r.pKeyInfo = pCur->pKeyInfo; -+ r.aMem = pX->aMem; -+ r.nField = pX->nMem; -+ r.default_rc = 0; -+ r.errCode = 0; -+ r.r1 = 0; -+ r.r2 = 0; -+ r.eqSeen = 0; -+ rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc); -+ }else{ -+ rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc); -+ } -+ if( rc ) return rc; - } -- if( rc ) return rc; -+ -+ /* If the cursor is currently pointing to an entry to be overwritten -+ ** and the new content is the same as as the old, then use the -+ ** overwrite optimization. -+ */ -+ if( loc==0 ){ -+ getCellInfo(pCur); -+ if( pCur->info.nKey==pX->nKey ){ -+ BtreePayload x2; -+ x2.pData = pX->pKey; -+ x2.nData = pX->nKey; -+ x2.nZero = 0; -+ return btreeOverwriteCell(pCur, &x2); -+ } -+ } -+ - } - assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) ); - -- pPage = pCur->apPage[pCur->iPage]; -+ pPage = pCur->pPage; - assert( pPage->intKey || pX->nKey>=0 ); - assert( pPage->leaf || !pPage->intKey ); - -@@ -67814,10 +71481,10 @@ - ** fails. Internal data structure corruption will result otherwise. - ** Also, set the cursor state to invalid. This stops saveCursorPosition() - ** from trying to save the current position of the cursor. */ -- pCur->apPage[pCur->iPage]->nOverflow = 0; -+ pCur->pPage->nOverflow = 0; - pCur->eState = CURSOR_INVALID; - if( (flags & BTREE_SAVEPOSITION) && rc==SQLITE_OK ){ -- rc = moveToRoot(pCur); -+ btreeReleaseAllCursorPages(pCur); - if( pCur->pKeyInfo ){ - assert( pCur->pKey==0 ); - pCur->pKey = sqlite3Malloc( pX->nKey ); -@@ -67831,7 +71498,7 @@ - pCur->nKey = pX->nKey; - } - } -- assert( pCur->apPage[pCur->iPage]->nOverflow==0 ); -+ assert( pCur->iPage<0 || pCur->pPage->nOverflow==0 ); - - end_insert: - return rc; -@@ -67872,13 +71539,13 @@ - assert( pCur->curFlags & BTCF_WriteFlag ); - assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); - assert( !hasReadConflicts(p, pCur->pgnoRoot) ); -- assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell ); -+ assert( pCur->ix<pCur->pPage->nCell ); - assert( pCur->eState==CURSOR_VALID ); - assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 ); - - iCellDepth = pCur->iPage; - iCellIdx = pCur->ix; -- pPage = pCur->apPage[iCellDepth]; -+ pPage = pCur->pPage; - pCell = findCell(pPage, iCellIdx); - - /* If the bPreserve flag is set to true, then the cursor position must -@@ -67944,11 +71611,16 @@ - ** node. The cell from the leaf node needs to be moved to the internal - ** node to replace the deleted cell. */ - if( !pPage->leaf ){ -- MemPage *pLeaf = pCur->apPage[pCur->iPage]; -+ MemPage *pLeaf = pCur->pPage; - int nCell; -- Pgno n = pCur->apPage[iCellDepth+1]->pgno; -+ Pgno n; - unsigned char *pTmp; - -+ if( iCellDepth<pCur->iPage-1 ){ -+ n = pCur->apPage[iCellDepth+1]->pgno; -+ }else{ -+ n = pCur->pPage->pgno; -+ } - pCell = findCell(pLeaf, pLeaf->nCell-1); - if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT; - nCell = pLeaf->xCellSize(pLeaf, pCell); -@@ -67980,9 +71652,12 @@ - ** well. */ - rc = balance(pCur); - if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){ -+ releasePageNotNull(pCur->pPage); -+ pCur->iPage--; - while( pCur->iPage>iCellDepth ){ - releasePage(pCur->apPage[pCur->iPage--]); - } -+ pCur->pPage = pCur->apPage[pCur->iPage]; - rc = balance(pCur); - } - -@@ -67989,7 +71664,7 @@ - if( rc==SQLITE_OK ){ - if( bSkipnext ){ - assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) ); -- assert( pPage==pCur->apPage[pCur->iPage] || CORRUPT_DB ); -+ assert( pPage==pCur->pPage || CORRUPT_DB ); - assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell ); - pCur->eState = CURSOR_SKIPNEXT; - if( iCellIdx>=pPage->nCell ){ -@@ -68001,8 +71676,10 @@ - }else{ - rc = moveToRoot(pCur); - if( bPreserve ){ -+ btreeReleaseAllCursorPages(pCur); - pCur->eState = CURSOR_REQUIRESEEK; - } -+ if( rc==SQLITE_EMPTY ) rc = SQLITE_OK; - } - } - return rc; -@@ -68467,11 +72144,11 @@ - i64 nEntry = 0; /* Value to return in *pnEntry */ - int rc; /* Return code */ - -- if( pCur->pgnoRoot==0 ){ -+ rc = moveToRoot(pCur); -+ if( rc==SQLITE_EMPTY ){ - *pnEntry = 0; - return SQLITE_OK; - } -- rc = moveToRoot(pCur); - - /* Unless an error occurs, the following loop runs one iteration for each - ** page in the B-Tree structure (not including overflow pages). -@@ -68484,7 +72161,7 @@ - ** this page contains countable entries. Increment the entry counter - ** accordingly. - */ -- pPage = pCur->apPage[pCur->iPage]; -+ pPage = pCur->pPage; - if( pPage->leaf || !pPage->intKey ){ - nEntry += pPage->nCell; - } -@@ -68507,10 +72184,10 @@ - return moveToRoot(pCur); - } - moveToParent(pCur); -- }while ( pCur->ix>=pCur->apPage[pCur->iPage]->nCell ); -+ }while ( pCur->ix>=pCur->pPage->nCell ); - - pCur->ix++; -- pPage = pCur->apPage[pCur->iPage]; -+ pPage = pCur->pPage; - } - - /* Descend to the child node of the cell that the cursor currently -@@ -68552,14 +72229,14 @@ - pCheck->nErr++; - va_start(ap, zFormat); - if( pCheck->errMsg.nChar ){ -- sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1); -+ sqlite3_str_append(&pCheck->errMsg, "\n", 1); - } - if( pCheck->zPfx ){ -- sqlite3XPrintf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2); -+ sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2); - } -- sqlite3VXPrintf(&pCheck->errMsg, zFormat, ap); -+ sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap); - va_end(ap); -- if( pCheck->errMsg.accError==STRACCUM_NOMEM ){ -+ if( pCheck->errMsg.accError==SQLITE_NOMEM ){ - pCheck->mallocFailed = 1; - } - } -@@ -68594,8 +72271,7 @@ - ** Also check that the page number is in bounds. - */ - static int checkRef(IntegrityCk *pCheck, Pgno iPage){ -- if( iPage==0 ) return 1; -- if( iPage>pCheck->nPage ){ -+ if( iPage>pCheck->nPage || iPage==0 ){ - checkAppendMsg(pCheck, "invalid page number %d", iPage); - return 1; - } -@@ -68650,17 +72326,12 @@ - ){ - int i; - int expected = N; -- int iFirst = iPage; -- while( N-- > 0 && pCheck->mxErr ){ -+ int nErrAtStart = pCheck->nErr; -+ while( iPage!=0 && pCheck->mxErr ){ - DbPage *pOvflPage; - unsigned char *pOvflData; -- if( iPage<1 ){ -- checkAppendMsg(pCheck, -- "%d of %d pages missing from overflow list starting at %d", -- N+1, expected, iFirst); -- break; -- } - if( checkRef(pCheck, iPage) ) break; -+ N--; - if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){ - checkAppendMsg(pCheck, "failed to get page %d", iPage); - break; -@@ -68704,11 +72375,13 @@ - #endif - iPage = get4byte(pOvflData); - sqlite3PagerUnref(pOvflPage); -- -- if( isFreeList && N<(iPage!=0) ){ -- checkAppendMsg(pCheck, "free-page count in header is too small"); -- } - } -+ if( N && nErrAtStart==pCheck->nErr ){ -+ checkAppendMsg(pCheck, -+ "%s is %d but should be %d", -+ isFreeList ? "size" : "overflow list length", -+ expected-N, expected); -+ } - } - #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ - -@@ -69101,6 +72774,24 @@ - - /* Check all the tables. - */ -+#ifndef SQLITE_OMIT_AUTOVACUUM -+ if( pBt->autoVacuum ){ -+ int mx = 0; -+ int mxInHdr; -+ for(i=0; (int)i<nRoot; i++) if( mx<aRoot[i] ) mx = aRoot[i]; -+ mxInHdr = get4byte(&pBt->pPage1->aData[52]); -+ if( mx!=mxInHdr ){ -+ checkAppendMsg(&sCheck, -+ "max rootpage (%d) disagrees with header (%d)", -+ mx, mxInHdr -+ ); -+ } -+ }else if( get4byte(&pBt->pPage1->aData[64])!=0 ){ -+ checkAppendMsg(&sCheck, -+ "incremental_vacuum enabled with a max rootpage of zero" -+ ); -+ } -+#endif - testcase( pBt->db->flags & SQLITE_CellSizeCk ); - pBt->db->flags &= ~SQLITE_CellSizeCk; - for(i=0; (int)i<nRoot && sCheck.mxErr; i++){ -@@ -69143,11 +72834,11 @@ - sqlite3PageFree(sCheck.heap); - sqlite3_free(sCheck.aPgRef); - if( sCheck.mallocFailed ){ -- sqlite3StrAccumReset(&sCheck.errMsg); -+ sqlite3_str_reset(&sCheck.errMsg); - sCheck.nErr++; - } - *pnErr = sCheck.nErr; -- if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg); -+ if( sCheck.nErr==0 ) sqlite3_str_reset(&sCheck.errMsg); - /* Make sure this analysis did not leave any unref() pages. */ - assert( nRef==sqlite3PagerRefcount(pBt->pPager) ); - sqlite3BtreeLeave(p); -@@ -69351,7 +73042,7 @@ - && pCsr->pBt->inTransaction==TRANS_WRITE ); - assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) ); - assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) ); -- assert( pCsr->apPage[pCsr->iPage]->intKey ); -+ assert( pCsr->pPage->intKey ); - - return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1); - } -@@ -69382,11 +73073,11 @@ - pBt->btsFlags &= ~BTS_NO_WAL; - if( iVersion==1 ) pBt->btsFlags |= BTS_NO_WAL; - -- rc = sqlite3BtreeBeginTrans(pBtree, 0); -+ rc = sqlite3BtreeBeginTrans(pBtree, 0, 0); - if( rc==SQLITE_OK ){ - u8 *aData = pBt->pPage1->aData; - if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){ -- rc = sqlite3BtreeBeginTrans(pBtree, 2); -+ rc = sqlite3BtreeBeginTrans(pBtree, 2, 0); - if( rc==SQLITE_OK ){ - rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); - if( rc==SQLITE_OK ){ -@@ -69826,7 +73517,7 @@ - ** before this function exits. - */ - if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){ -- rc = sqlite3BtreeBeginTrans(p->pSrc, 0); -+ rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0); - bCloseTrans = 1; - } - -@@ -69842,10 +73533,10 @@ - - /* Lock the destination database, if it is not locked already. */ - if( SQLITE_OK==rc && p->bDestLocked==0 -- && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) -+ && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2, -+ (int*)&p->iDestSchema)) - ){ - p->bDestLocked = 1; -- sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema); - } - - /* Do not allow backup if the destination database is in WAL mode -@@ -70289,8 +73980,7 @@ - - if( p->flags & MEM_Null ){ - /* Cannot be both MEM_Null and some other type */ -- assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob -- |MEM_RowSet|MEM_Frame|MEM_Agg|MEM_Zero))==0 ); -+ assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 ); - - /* If MEM_Null is set, then either the value is a pure NULL (the usual - ** case) or it is a pointer set using sqlite3_bind_pointer() or -@@ -70340,6 +74030,51 @@ - } - #endif - -+#ifdef SQLITE_DEBUG -+/* -+** Check that string value of pMem agrees with its integer or real value. -+** -+** A single int or real value always converts to the same strings. But -+** many different strings can be converted into the same int or real. -+** If a table contains a numeric value and an index is based on the -+** corresponding string value, then it is important that the string be -+** derived from the numeric value, not the other way around, to ensure -+** that the index and table are consistent. See ticket -+** https://www.sqlite.org/src/info/343634942dd54ab (2018-01-31) for -+** an example. -+** -+** This routine looks at pMem to verify that if it has both a numeric -+** representation and a string representation then the string rep has -+** been derived from the numeric and not the other way around. It returns -+** true if everything is ok and false if there is a problem. -+** -+** This routine is for use inside of assert() statements only. -+*/ -+SQLITE_PRIVATE int sqlite3VdbeMemConsistentDualRep(Mem *p){ -+ char zBuf[100]; -+ char *z; -+ int i, j, incr; -+ if( (p->flags & MEM_Str)==0 ) return 1; -+ if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1; -+ if( p->flags & MEM_Int ){ -+ sqlite3_snprintf(sizeof(zBuf),zBuf,"%lld",p->u.i); -+ }else{ -+ sqlite3_snprintf(sizeof(zBuf),zBuf,"%!.15g",p->u.r); -+ } -+ z = p->z; -+ i = j = 0; -+ incr = 1; -+ if( p->enc!=SQLITE_UTF8 ){ -+ incr = 2; -+ if( p->enc==SQLITE_UTF16BE ) z++; -+ } -+ while( zBuf[j] ){ -+ if( zBuf[j++]!=z[i] ) return 0; -+ i += incr; -+ } -+ return 1; -+} -+#endif /* SQLITE_DEBUG */ - - /* - ** If pMem is an object with a valid string representation, this routine -@@ -70358,7 +74093,7 @@ - #ifndef SQLITE_OMIT_UTF16 - int rc; - #endif -- assert( (pMem->flags&MEM_RowSet)==0 ); -+ assert( !sqlite3VdbeMemIsRowSet(pMem) ); - assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE - || desiredEnc==SQLITE_UTF16BE ); - if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ -@@ -70391,7 +74126,7 @@ - */ - SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ - assert( sqlite3VdbeCheckMemInvariants(pMem) ); -- assert( (pMem->flags&MEM_RowSet)==0 ); -+ assert( !sqlite3VdbeMemIsRowSet(pMem) ); - testcase( pMem->db==0 ); - - /* If the bPreserve flag is set to true, then the memory cell must already -@@ -70402,7 +74137,7 @@ - assert( pMem->szMalloc==0 - || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) ); - if( n<32 ) n = 32; -- if( bPreserve && pMem->szMalloc>0 && pMem->z==pMem->zMalloc ){ -+ if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){ - pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); - bPreserve = 0; - }else{ -@@ -70418,7 +74153,8 @@ - pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); - } - -- if( bPreserve && pMem->z && ALWAYS(pMem->z!=pMem->zMalloc) ){ -+ if( bPreserve && pMem->z ){ -+ assert( pMem->z!=pMem->zMalloc ); - memcpy(pMem->zMalloc, pMem->z, pMem->n); - } - if( (pMem->flags&MEM_Dyn)!=0 ){ -@@ -70457,6 +74193,20 @@ - } - - /* -+** It is already known that pMem contains an unterminated string. -+** Add the zero terminator. -+*/ -+static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){ -+ if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){ -+ return SQLITE_NOMEM_BKPT; -+ } -+ pMem->z[pMem->n] = 0; -+ pMem->z[pMem->n+1] = 0; -+ pMem->flags |= MEM_Term; -+ return SQLITE_OK; -+} -+ -+/* - ** Change pMem so that its MEM_Str or MEM_Blob value is stored in - ** MEM.zMalloc, where it can be safely written. - ** -@@ -70464,16 +74214,12 @@ - */ - SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){ - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); -- assert( (pMem->flags&MEM_RowSet)==0 ); -+ assert( !sqlite3VdbeMemIsRowSet(pMem) ); - if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){ - if( ExpandBlob(pMem) ) return SQLITE_NOMEM; - if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){ -- if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){ -- return SQLITE_NOMEM_BKPT; -- } -- pMem->z[pMem->n] = 0; -- pMem->z[pMem->n+1] = 0; -- pMem->flags |= MEM_Term; -+ int rc = vdbeMemAddTerminator(pMem); -+ if( rc ) return rc; - } - } - pMem->flags &= ~MEM_Ephem; -@@ -70493,7 +74239,7 @@ - int nByte; - assert( pMem->flags & MEM_Zero ); - assert( pMem->flags&MEM_Blob ); -- assert( (pMem->flags&MEM_RowSet)==0 ); -+ assert( !sqlite3VdbeMemIsRowSet(pMem) ); - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - - /* Set nByte to the number of bytes required to store the expanded blob. */ -@@ -70513,20 +74259,6 @@ - #endif - - /* --** It is already known that pMem contains an unterminated string. --** Add the zero terminator. --*/ --static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){ -- if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){ -- return SQLITE_NOMEM_BKPT; -- } -- pMem->z[pMem->n] = 0; -- pMem->z[pMem->n+1] = 0; -- pMem->flags |= MEM_Term; -- return SQLITE_OK; --} -- --/* - ** Make sure the given Mem is \u0000 terminated. - */ - SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){ -@@ -70562,7 +74294,7 @@ - assert( !(fg&MEM_Zero) ); - assert( !(fg&(MEM_Str|MEM_Blob)) ); - assert( fg&(MEM_Int|MEM_Real) ); -- assert( (pMem->flags&MEM_RowSet)==0 ); -+ assert( !sqlite3VdbeMemIsRowSet(pMem) ); - assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - - -@@ -70583,7 +74315,8 @@ - assert( fg & MEM_Real ); - sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r); - } -- pMem->n = sqlite3Strlen30(pMem->z); -+ assert( pMem->z!=0 ); -+ pMem->n = sqlite3Strlen30NN(pMem->z); - pMem->enc = SQLITE_UTF8; - pMem->flags |= MEM_Str|MEM_Term; - if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real); -@@ -70600,29 +74333,56 @@ - ** otherwise. - */ - SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ -- int rc = SQLITE_OK; -- if( ALWAYS(pFunc && pFunc->xFinalize) ){ -- sqlite3_context ctx; -- Mem t; -- assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); -- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); -- memset(&ctx, 0, sizeof(ctx)); -- memset(&t, 0, sizeof(t)); -- t.flags = MEM_Null; -- t.db = pMem->db; -- ctx.pOut = &t; -- ctx.pMem = pMem; -- ctx.pFunc = pFunc; -- pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ -- assert( (pMem->flags & MEM_Dyn)==0 ); -- if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); -- memcpy(pMem, &t, sizeof(t)); -- rc = ctx.isError; -- } -- return rc; -+ sqlite3_context ctx; -+ Mem t; -+ assert( pFunc!=0 ); -+ assert( pFunc->xFinalize!=0 ); -+ assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); -+ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); -+ memset(&ctx, 0, sizeof(ctx)); -+ memset(&t, 0, sizeof(t)); -+ t.flags = MEM_Null; -+ t.db = pMem->db; -+ ctx.pOut = &t; -+ ctx.pMem = pMem; -+ ctx.pFunc = pFunc; -+ pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ -+ assert( (pMem->flags & MEM_Dyn)==0 ); -+ if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); -+ memcpy(pMem, &t, sizeof(t)); -+ return ctx.isError; - } - - /* -+** Memory cell pAccum contains the context of an aggregate function. -+** This routine calls the xValue method for that function and stores -+** the results in memory cell pMem. -+** -+** SQLITE_ERROR is returned if xValue() reports an error. SQLITE_OK -+** otherwise. -+*/ -+#ifndef SQLITE_OMIT_WINDOWFUNC -+SQLITE_PRIVATE 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; -+ ctx.pFunc = pFunc; -+ pFunc->xValue(&ctx); -+ return ctx.isError; -+} -+#endif /* SQLITE_OMIT_WINDOWFUNC */ -+ -+/* - ** If the memory cell contains a value that must be freed by - ** invoking the external callback in Mem.xDel, then this routine - ** will free that value. It also sets Mem.flags to MEM_Null. -@@ -70640,15 +74400,8 @@ - testcase( p->flags & MEM_Dyn ); - } - if( p->flags&MEM_Dyn ){ -- assert( (p->flags&MEM_RowSet)==0 ); - assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 ); - p->xDel((void *)p->z); -- }else if( p->flags&MEM_RowSet ){ -- sqlite3RowSetClear(p->u.pRowSet); -- }else if( p->flags&MEM_Frame ){ -- VdbeFrame *pFrame = p->u.pFrame; -- pFrame->pParent = pFrame->v->pDelFrame; -- pFrame->v->pDelFrame = pFrame; - } - p->flags = MEM_Null; - } -@@ -70780,6 +74533,16 @@ - } - - /* -+** Return 1 if pMem represents true, and return 0 if pMem represents false. -+** Return the value ifNull if pMem is NULL. -+*/ -+SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){ -+ if( pMem->flags & MEM_Int ) return pMem->u.i!=0; -+ if( pMem->flags & MEM_Null ) return ifNull; -+ return sqlite3VdbeRealValue(pMem)!=0.0; -+} -+ -+/* - ** The MEM structure is already a MEM_Real. Try to also make it a - ** MEM_Int if we can. - */ -@@ -70786,7 +74549,7 @@ - SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ - i64 ix; - assert( pMem->flags & MEM_Real ); -- assert( (pMem->flags & MEM_RowSet)==0 ); -+ assert( !sqlite3VdbeMemIsRowSet(pMem) ); - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - -@@ -70813,7 +74576,7 @@ - */ - SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){ - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); -- assert( (pMem->flags & MEM_RowSet)==0 ); -+ assert( !sqlite3VdbeMemIsRowSet(pMem) ); - assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - - pMem->u.i = sqlite3VdbeIntValue(pMem); -@@ -70834,6 +74597,18 @@ - return SQLITE_OK; - } - -+/* Compare a floating point value to an integer. Return true if the two -+** values are the same within the precision of the floating point value. -+** -+** For some versions of GCC on 32-bit machines, if you do the more obvious -+** comparison of "r1==(double)i" you sometimes get an answer of false even -+** though the r1 and (double)i values are bit-for-bit the same. -+*/ -+static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){ -+ double r2 = (double)i; -+ return memcmp(&r1, &r2, sizeof(r1))==0; -+} -+ - /* - ** Convert pMem so that it has types MEM_Real or MEM_Int or both. - ** Invalidate any prior representations. -@@ -70844,14 +74619,21 @@ - */ - SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){ - if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){ -+ int rc; - assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); -- if( 0==sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){ -+ rc = sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc); -+ if( rc==0 ){ - MemSetTypeFlag(pMem, MEM_Int); - }else{ -- pMem->u.r = sqlite3VdbeRealValue(pMem); -- MemSetTypeFlag(pMem, MEM_Real); -- sqlite3VdbeIntegerAffinity(pMem); -+ i64 i = pMem->u.i; -+ sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); -+ if( rc==1 && sqlite3RealSameAsInt(pMem->u.r, i) ){ -+ pMem->u.i = i; -+ MemSetTypeFlag(pMem, MEM_Int); -+ }else{ -+ MemSetTypeFlag(pMem, MEM_Real); -+ } - } - } - assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 ); -@@ -70978,7 +74760,7 @@ - } - - /* A no-op destructor */ --static void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); } -+SQLITE_PRIVATE void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); } - - /* - ** Set the value stored in *pMem should already be a NULL. -@@ -71012,26 +74794,36 @@ - } - #endif - -+#ifdef SQLITE_DEBUG - /* -+** Return true if the Mem holds a RowSet object. This routine is intended -+** for use inside of assert() statements. -+*/ -+SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem *pMem){ -+ return (pMem->flags&(MEM_Blob|MEM_Dyn))==(MEM_Blob|MEM_Dyn) -+ && pMem->xDel==sqlite3RowSetDelete; -+} -+#endif -+ -+/* - ** Delete any previous value and set the value of pMem to be an - ** empty boolean index. -+** -+** Return SQLITE_OK on success and SQLITE_NOMEM if a memory allocation -+** error occurs. - */ --SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem *pMem){ -+SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem *pMem){ - sqlite3 *db = pMem->db; -+ RowSet *p; - assert( db!=0 ); -- assert( (pMem->flags & MEM_RowSet)==0 ); -+ assert( !sqlite3VdbeMemIsRowSet(pMem) ); - sqlite3VdbeMemRelease(pMem); -- pMem->zMalloc = sqlite3DbMallocRawNN(db, 64); -- if( db->mallocFailed ){ -- pMem->flags = MEM_Null; -- pMem->szMalloc = 0; -- }else{ -- assert( pMem->zMalloc ); -- pMem->szMalloc = sqlite3DbMallocSize(db, pMem->zMalloc); -- pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, pMem->szMalloc); -- assert( pMem->u.pRowSet!=0 ); -- pMem->flags = MEM_RowSet; -- } -+ p = sqlite3RowSetInit(db); -+ if( p==0 ) return SQLITE_NOMEM; -+ pMem->z = (char*)p; -+ pMem->flags = MEM_Blob|MEM_Dyn; -+ pMem->xDel = sqlite3RowSetDelete; -+ return SQLITE_OK; - } - - /* -@@ -71064,7 +74856,21 @@ - Mem *pX; - for(i=0, pX=pVdbe->aMem; i<pVdbe->nMem; i++, pX++){ - if( pX->pScopyFrom==pMem ){ -- pX->flags |= MEM_Undefined; -+ /* 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; -+ assert( (mFlags&MEM_Int)==0 || pMem->u.i==pX->u.i ); -+ assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r ); -+ assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) ); -+ assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 ); -+ -+ /* pMem is the register that is changing. But also mark pX as -+ ** undefined so that we can quickly detect the shallow-copy error */ -+ pX->flags = MEM_Undefined; - pX->pScopyFrom = 0; - } - } -@@ -71085,7 +74891,7 @@ - sqlite3VdbeMemShallowCopy(pTo, pFrom, eType); - } - SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ -- assert( (pFrom->flags & MEM_RowSet)==0 ); -+ assert( !sqlite3VdbeMemIsRowSet(pFrom) ); - assert( pTo->db==pFrom->db ); - if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; } - memcpy(pTo, pFrom, MEMCELLSIZE); -@@ -71103,7 +74909,7 @@ - SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ - int rc = SQLITE_OK; - -- assert( (pFrom->flags & MEM_RowSet)==0 ); -+ assert( !sqlite3VdbeMemIsRowSet(pFrom) ); - if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo); - memcpy(pTo, pFrom, MEMCELLSIZE); - pTo->flags &= ~MEM_Dyn; -@@ -71161,7 +74967,7 @@ - u16 flags = 0; /* New value for pMem->flags */ - - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); -- assert( (pMem->flags & MEM_RowSet)==0 ); -+ assert( !sqlite3VdbeMemIsRowSet(pMem) ); - - /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ - if( !z ){ -@@ -71178,7 +74984,7 @@ - if( nByte<0 ){ - assert( enc!=0 ); - if( enc==SQLITE_UTF8 ){ -- nByte = sqlite3Strlen30(z); -+ nByte = 0x7fffffff & (int)strlen(z); - if( nByte>iLimit ) nByte = iLimit+1; - }else{ - for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){} -@@ -71256,12 +75062,11 @@ - ){ - int rc; - pMem->flags = MEM_Null; -- if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+2)) ){ -+ if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+1)) ){ - rc = sqlite3BtreePayload(pCur, offset, amt, pMem->z); - if( rc==SQLITE_OK ){ -- pMem->z[amt] = 0; -- pMem->z[amt+1] = 0; -- pMem->flags = MEM_Blob|MEM_Term; -+ pMem->z[amt] = 0; /* Overrun area used when reading malformed records */ -+ pMem->flags = MEM_Blob; - pMem->n = (int)amt; - }else{ - sqlite3VdbeMemRelease(pMem); -@@ -71284,7 +75089,7 @@ - - /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() - ** that both the BtShared and database handle mutexes are held. */ -- assert( (pMem->flags & MEM_RowSet)==0 ); -+ assert( !sqlite3VdbeMemIsRowSet(pMem) ); - zData = (char *)sqlite3BtreePayloadFetch(pCur, &available); - assert( zData!=0 ); - -@@ -71308,7 +75113,7 @@ - assert( pVal!=0 ); - assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); - assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); -- assert( (pVal->flags & MEM_RowSet)==0 ); -+ assert( !sqlite3VdbeMemIsRowSet(pVal) ); - assert( (pVal->flags & (MEM_Null))==0 ); - if( pVal->flags & (MEM_Blob|MEM_Str) ){ - if( ExpandBlob(pVal) ) return 0; -@@ -71330,6 +75135,7 @@ - assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0 - || pVal->db->mallocFailed ); - if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){ -+ assert( sqlite3VdbeMemConsistentDualRep(pVal) ); - return pVal->z; - }else{ - return 0; -@@ -71350,8 +75156,9 @@ - if( !pVal ) return 0; - assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); - assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); -- assert( (pVal->flags & MEM_RowSet)==0 ); -+ assert( !sqlite3VdbeMemIsRowSet(pVal) ); - if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){ -+ assert( sqlite3VdbeMemConsistentDualRep(pVal) ); - return pVal->z; - } - if( pVal->flags&MEM_Null ){ -@@ -71410,7 +75217,7 @@ - if( pRec ){ - pRec->pKeyInfo = sqlite3KeyInfoOfIndex(p->pParse, pIdx); - if( pRec->pKeyInfo ){ -- assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol ); -+ assert( pRec->pKeyInfo->nAllField==nCol ); - assert( pRec->pKeyInfo->enc==ENC(db) ); - pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord))); - for(i=0; i<nCol; i++){ -@@ -71567,7 +75374,11 @@ - - assert( pExpr!=0 ); - while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft; -+#if defined(SQLITE_ENABLE_STAT3_OR_STAT4) -+ if( op==TK_REGISTER ) op = pExpr->op2; -+#else - if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; -+#endif - - /* Compressed expressions only appear when parsing the DEFAULT clause - ** on a table column definition, and hence only when pCtx==0. This -@@ -71651,18 +75462,25 @@ - 0, SQLITE_DYNAMIC); - } - #endif -- - #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - else if( op==TK_FUNCTION && pCtx!=0 ){ - rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx); - } - #endif -+ else if( op==TK_TRUEFALSE ){ -+ pVal = valueNew(db, pCtx); -+ pVal->flags = MEM_Int; -+ pVal->u.i = pExpr->u.zToken[4]==0; -+ } - - *ppVal = pVal; - return rc; - - no_mem: -- sqlite3OomFault(db); -+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 -+ if( pCtx==0 || pCtx->pParse->nErr==0 ) -+#endif -+ sqlite3OomFault(db); - sqlite3DbFree(db, zVal); - assert( *ppVal==0 ); - #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 -@@ -71905,11 +75723,11 @@ - int iCol, /* Column to extract */ - sqlite3_value **ppVal /* OUT: Extracted value */ - ){ -- u32 t; /* a column type code */ -+ u32 t = 0; /* a column type code */ - int nHdr; /* Size of the header in the record */ - int iHdr; /* Next unread header byte */ - int iField; /* Next unread data byte */ -- int szField; /* Size of the current data field */ -+ int szField = 0; /* Size of the current data field */ - int i; /* Column index */ - u8 *a = (u8*)pRec; /* Typecast byte array */ - Mem *pMem = *ppVal; /* Write result into this Mem object */ -@@ -71946,7 +75764,7 @@ - SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){ - if( pRec ){ - int i; -- int nCol = pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField; -+ int nCol = pRec->pKeyInfo->nAllField; - Mem *aMem = pRec->aMem; - sqlite3 *db = aMem[0].db; - for(i=0; i<nCol; i++){ -@@ -72042,10 +75860,12 @@ - db->pVdbe = p; - p->magic = VDBE_MAGIC_INIT; - p->pParse = pParse; -+ pParse->pVdbe = p; - assert( pParse->aLabel==0 ); - assert( pParse->nLabel==0 ); - assert( pParse->nOpAlloc==0 ); - assert( pParse->szOpAlloc==0 ); -+ sqlite3VdbeAddOp2(p, OP_Init, 0, 1); - return p; - } - -@@ -72071,6 +75891,13 @@ - } - assert( p->zSql==0 ); - p->zSql = sqlite3DbStrNDup(p->db, z, n); -+#ifdef SQLITE_ENABLE_NORMALIZE -+ assert( p->zNormSql==0 ); -+ if( p->zSql && (prepFlags & SQLITE_PREPARE_NORMALIZE)!=0 ){ -+ sqlite3Normalize(p, p->zSql, n, prepFlags); -+ assert( p->zNormSql!=0 || p->db->mallocFailed ); -+ } -+#endif - } - - /* -@@ -72092,6 +75919,11 @@ - zTmp = pA->zSql; - pA->zSql = pB->zSql; - pB->zSql = zTmp; -+#ifdef SQLITE_ENABLE_NORMALIZE -+ zTmp = pA->zNormSql; -+ pA->zNormSql = pB->zNormSql; -+ pB->zNormSql = zTmp; -+#endif - pB->expmask = pA->expmask; - pB->prepFlags = pA->prepFlags; - memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter)); -@@ -72200,14 +76032,6 @@ - #endif - #ifdef SQLITE_DEBUG - if( p->db->flags & SQLITE_VdbeAddopTrace ){ -- int jj, kk; -- Parse *pParse = p->pParse; -- for(jj=kk=0; jj<pParse->nColCache; jj++){ -- struct yColCache *x = pParse->aColCache + jj; -- printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn); -- kk++; -- } -- if( kk ) printf("\n"); - sqlite3VdbePrintOp(0, i, &p->aOp[i]); - test_addop_breakpoint(); - } -@@ -72310,7 +76134,50 @@ - return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type); - } - -+#ifndef SQLITE_OMIT_EXPLAIN - /* -+** Return the address of the current EXPLAIN QUERY PLAN baseline. -+** 0 means "none". -+*/ -+SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse *pParse){ -+ VdbeOp *pOp; -+ if( pParse->addrExplain==0 ) return 0; -+ pOp = sqlite3VdbeGetOp(pParse->pVdbe, pParse->addrExplain); -+ return pOp->p2; -+} -+ -+/* -+** Add a new OP_Explain opcode. -+** -+** If the bPush flag is true, then make this opcode the parent for -+** subsequent Explains until sqlite3VdbeExplainPop() is called. -+*/ -+SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ -+ if( pParse->explain==2 ){ -+ char *zMsg; -+ Vdbe *v; -+ va_list ap; -+ int iThis; -+ va_start(ap, zFmt); -+ zMsg = sqlite3VMPrintf(pParse->db, zFmt, ap); -+ va_end(ap); -+ v = pParse->pVdbe; -+ iThis = v->nOp; -+ sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0, -+ zMsg, P4_DYNAMIC); -+ if( bPush) pParse->addrExplain = iThis; -+ } -+} -+ -+/* -+** Pop the EXPLAIN QUERY PLAN stack one level. -+*/ -+SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse *pParse){ -+ pParse->addrExplain = sqlite3VdbeExplainParent(pParse); -+} -+#endif /* SQLITE_OMIT_EXPLAIN */ -+ -+/* - ** Add an OP_ParseSchema opcode. This routine is broken out from - ** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees - ** as having been used. -@@ -72399,6 +76266,12 @@ - assert( j<p->nLabel ); - assert( j>=0 ); - if( p->aLabel ){ -+#ifdef SQLITE_DEBUG -+ if( p->db->flags & SQLITE_VdbeAddopTrace ){ -+ printf("RESOLVE LABEL %d to %d\n", x, v->nOp); -+ } -+#endif -+ assert( p->aLabel[j]==(-1) ); /* Labels may only be resolved once */ - p->aLabel[j] = v->nOp; - } - } -@@ -72499,7 +76372,8 @@ - ** * OP_VUpdate - ** * OP_VRename - ** * OP_FkCounter with P2==0 (immediate foreign key constraint) --** * OP_CreateTable and OP_InitCoroutine (for CREATE TABLE AS SELECT ...) -+** * OP_CreateBtree/BTREE_INTKEY and OP_InitCoroutine -+** (for CREATE TABLE AS SELECT ...) - ** - ** Then check that the value of Parse.mayAbort is true if an - ** ABORT may be thrown, or false otherwise. Return true if it does -@@ -72527,7 +76401,7 @@ - hasAbort = 1; - break; - } -- if( opcode==OP_CreateTable ) hasCreateTable = 1; -+ if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1; - if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1; - #ifndef SQLITE_OMIT_FOREIGN_KEY - if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){ -@@ -72547,7 +76421,33 @@ - } - #endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */ - -+#ifdef SQLITE_DEBUG - /* -+** Increment the nWrite counter in the VDBE if the cursor is not an -+** ephemeral cursor, or if the cursor argument is NULL. -+*/ -+SQLITE_PRIVATE void sqlite3VdbeIncrWriteCounter(Vdbe *p, VdbeCursor *pC){ -+ if( pC==0 -+ || (pC->eCurType!=CURTYPE_SORTER -+ && pC->eCurType!=CURTYPE_PSEUDO -+ && !pC->isEphemeral) -+ ){ -+ p->nWrite++; -+ } -+} -+#endif -+ -+#ifdef SQLITE_DEBUG -+/* -+** Assert if an Abort at this point in time might result in a corrupt -+** database. -+*/ -+SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe *p){ -+ assert( p->nWrite==0 || p->usesStmtJournal ); -+} -+#endif -+ -+/* - ** This routine is called after all opcodes have been inserted. It loops - ** through all the opcodes and fixes up some details. - ** -@@ -72606,6 +76506,25 @@ - p->bIsReader = 1; - break; - } -+ case OP_Next: -+ case OP_SorterNext: { -+ pOp->p4.xAdvance = sqlite3BtreeNext; -+ pOp->p4type = P4_ADVANCE; -+ /* The code generator never codes any of these opcodes as a jump -+ ** to a label. They are always coded as a jump backwards to a -+ ** known address */ -+ assert( pOp->p2>=0 ); -+ break; -+ } -+ case OP_Prev: { -+ pOp->p4.xAdvance = sqlite3BtreePrevious; -+ pOp->p4type = P4_ADVANCE; -+ /* The code generator never codes any of these opcodes as a jump -+ ** to a label. They are always coded as a jump backwards to a -+ ** known address */ -+ assert( pOp->p2>=0 ); -+ break; -+ } - #ifndef SQLITE_OMIT_VIRTUALTABLE - case OP_VUpdate: { - if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; -@@ -72617,27 +76536,25 @@ - assert( pOp[-1].opcode==OP_Integer ); - n = pOp[-1].p1; - if( n>nMaxArgs ) nMaxArgs = n; -- break; -+ /* Fall through into the default case */ - } - #endif -- case OP_Next: -- case OP_NextIfOpen: -- case OP_SorterNext: { -- pOp->p4.xAdvance = sqlite3BtreeNext; -- pOp->p4type = P4_ADVANCE; -+ default: { -+ if( pOp->p2<0 ){ -+ /* The mkopcodeh.tcl script has so arranged things that the only -+ ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to -+ ** have non-negative values for P2. */ -+ assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 ); -+ assert( ADDR(pOp->p2)<pParse->nLabel ); -+ pOp->p2 = aLabel[ADDR(pOp->p2)]; -+ } - break; - } -- case OP_Prev: -- case OP_PrevIfOpen: { -- pOp->p4.xAdvance = sqlite3BtreePrevious; -- pOp->p4type = P4_ADVANCE; -- break; -- } - } -- if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 && pOp->p2<0 ){ -- assert( ADDR(pOp->p2)<pParse->nLabel ); -- pOp->p2 = aLabel[ADDR(pOp->p2)]; -- } -+ /* The mkopcodeh.tcl script has so arranged things that the only -+ ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to -+ ** have non-negative values for P2. */ -+ assert( (sqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0); - } - if( pOp==p->aOp ) break; - pOp--; -@@ -72688,6 +76605,17 @@ - #endif - - /* -+** Generate code (a single OP_Abortable opcode) that will -+** verify that the VDBE program can safely call Abort in the current -+** context. -+*/ -+#if defined(SQLITE_DEBUG) -+SQLITE_PRIVATE void sqlite3VdbeVerifyAbortable(Vdbe *p, int onError){ -+ if( onError==OE_Abort ) sqlite3VdbeAddOp0(p, OP_Abortable); -+} -+#endif -+ -+/* - ** This function returns a pointer to the array of opcodes associated with - ** the Vdbe passed as the first argument. It is the callers responsibility - ** to arrange for the returned array to be eventually freed using the -@@ -72853,6 +76781,7 @@ - case P4_REAL: - case P4_INT64: - case P4_DYNAMIC: -+ case P4_DYNBLOB: - case P4_INTARRAY: { - sqlite3DbFree(db, p4); - break; -@@ -73230,23 +77159,23 @@ - const char *zOp = 0; - switch( pExpr->op ){ - case TK_STRING: -- sqlite3XPrintf(p, "%Q", pExpr->u.zToken); -+ sqlite3_str_appendf(p, "%Q", pExpr->u.zToken); - break; - case TK_INTEGER: -- sqlite3XPrintf(p, "%d", pExpr->u.iValue); -+ sqlite3_str_appendf(p, "%d", pExpr->u.iValue); - break; - case TK_NULL: -- sqlite3XPrintf(p, "NULL"); -+ sqlite3_str_appendf(p, "NULL"); - break; - case TK_REGISTER: { -- sqlite3XPrintf(p, "r[%d]", pExpr->iTable); -+ sqlite3_str_appendf(p, "r[%d]", pExpr->iTable); - break; - } - case TK_COLUMN: { - if( pExpr->iColumn<0 ){ -- sqlite3XPrintf(p, "rowid"); -+ sqlite3_str_appendf(p, "rowid"); - }else{ -- sqlite3XPrintf(p, "c%d", (int)pExpr->iColumn); -+ sqlite3_str_appendf(p, "c%d", (int)pExpr->iColumn); - } - break; - } -@@ -73278,18 +77207,18 @@ - case TK_NOTNULL: zOp = "NOTNULL"; break; - - default: -- sqlite3XPrintf(p, "%s", "expr"); -+ sqlite3_str_appendf(p, "%s", "expr"); - break; - } - - if( zOp ){ -- sqlite3XPrintf(p, "%s(", zOp); -+ sqlite3_str_appendf(p, "%s(", zOp); - displayP4Expr(p, pExpr->pLeft); - if( pExpr->pRight ){ -- sqlite3StrAccumAppend(p, ",", 1); -+ sqlite3_str_append(p, ",", 1); - displayP4Expr(p, pExpr->pRight); - } -- sqlite3StrAccumAppend(p, ")", 1); -+ sqlite3_str_append(p, ")", 1); - } - } - #endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */ -@@ -73310,14 +77239,15 @@ - int j; - KeyInfo *pKeyInfo = pOp->p4.pKeyInfo; - assert( pKeyInfo->aSortOrder!=0 ); -- sqlite3XPrintf(&x, "k(%d", pKeyInfo->nField); -- for(j=0; j<pKeyInfo->nField; j++){ -+ sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField); -+ for(j=0; j<pKeyInfo->nKeyField; j++){ - CollSeq *pColl = pKeyInfo->aColl[j]; - const char *zColl = pColl ? pColl->zName : ""; - if( strcmp(zColl, "BINARY")==0 ) zColl = "B"; -- sqlite3XPrintf(&x, ",%s%s", pKeyInfo->aSortOrder[j] ? "-" : "", zColl); -+ sqlite3_str_appendf(&x, ",%s%s", -+ pKeyInfo->aSortOrder[j] ? "-" : "", zColl); - } -- sqlite3StrAccumAppend(&x, ")", 1); -+ sqlite3_str_append(&x, ")", 1); - break; - } - #ifdef SQLITE_ENABLE_CURSOR_HINTS -@@ -73328,31 +77258,31 @@ - #endif - case P4_COLLSEQ: { - CollSeq *pColl = pOp->p4.pColl; -- sqlite3XPrintf(&x, "(%.20s)", pColl->zName); -+ sqlite3_str_appendf(&x, "(%.20s)", pColl->zName); - break; - } - case P4_FUNCDEF: { - FuncDef *pDef = pOp->p4.pFunc; -- sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg); -+ 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; -- sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg); -+ sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg); - break; - } - #endif - case P4_INT64: { -- sqlite3XPrintf(&x, "%lld", *pOp->p4.pI64); -+ sqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64); - break; - } - case P4_INT32: { -- sqlite3XPrintf(&x, "%d", pOp->p4.i); -+ sqlite3_str_appendf(&x, "%d", pOp->p4.i); - break; - } - case P4_REAL: { -- sqlite3XPrintf(&x, "%.16g", *pOp->p4.pReal); -+ sqlite3_str_appendf(&x, "%.16g", *pOp->p4.pReal); - break; - } - case P4_MEM: { -@@ -73360,9 +77290,9 @@ - if( pMem->flags & MEM_Str ){ - zP4 = pMem->z; - }else if( pMem->flags & MEM_Int ){ -- sqlite3XPrintf(&x, "%lld", pMem->u.i); -+ sqlite3_str_appendf(&x, "%lld", pMem->u.i); - }else if( pMem->flags & MEM_Real ){ -- sqlite3XPrintf(&x, "%.16g", pMem->u.r); -+ sqlite3_str_appendf(&x, "%.16g", pMem->u.r); - }else if( pMem->flags & MEM_Null ){ - zP4 = "NULL"; - }else{ -@@ -73374,7 +77304,7 @@ - #ifndef SQLITE_OMIT_VIRTUALTABLE - case P4_VTAB: { - sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab; -- sqlite3XPrintf(&x, "vtab:%p", pVtab); -+ sqlite3_str_appendf(&x, "vtab:%p", pVtab); - break; - } - #endif -@@ -73383,23 +77313,24 @@ - int *ai = pOp->p4.ai; - int n = ai[0]; /* The first element of an INTARRAY is always the - ** count of the number of elements to follow */ -- for(i=1; i<n; i++){ -- sqlite3XPrintf(&x, ",%d", ai[i]); -+ for(i=1; i<=n; i++){ -+ sqlite3_str_appendf(&x, ",%d", ai[i]); - } - zTemp[0] = '['; -- sqlite3StrAccumAppend(&x, "]", 1); -+ sqlite3_str_append(&x, "]", 1); - break; - } - case P4_SUBPROGRAM: { -- sqlite3XPrintf(&x, "program"); -+ sqlite3_str_appendf(&x, "program"); - break; - } -+ case P4_DYNBLOB: - case P4_ADVANCE: { - zTemp[0] = 0; - break; - } - case P4_TABLE: { -- sqlite3XPrintf(&x, "%s", pOp->p4.pTab->zName); -+ sqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName); - break; - } - default: { -@@ -73500,7 +77431,7 @@ - /* - ** Print a single opcode. This routine is used for debugging only. - */ --SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){ -+SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){ - char *zP4; - char zPtr[50]; - char zCom[100]; -@@ -73569,9 +77500,8 @@ - */ - testcase( p->flags & MEM_Agg ); - testcase( p->flags & MEM_Dyn ); -- testcase( p->flags & MEM_Frame ); -- testcase( p->flags & MEM_RowSet ); -- if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){ -+ testcase( p->xDel==sqlite3VdbeFrameMemDel ); -+ if( p->flags&(MEM_Agg|MEM_Dyn) ){ - sqlite3VdbeMemRelease(p); - }else if( p->szMalloc ){ - sqlite3DbFreeNN(db, p->zMalloc); -@@ -73583,7 +77513,36 @@ - } - } - -+#ifdef SQLITE_DEBUG - /* -+** Verify that pFrame is a valid VdbeFrame pointer. Return true if it is -+** and false if something is wrong. -+** -+** This routine is intended for use inside of assert() statements only. -+*/ -+SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame *pFrame){ -+ if( pFrame->iFrameMagic!=SQLITE_FRAME_MAGIC ) return 0; -+ return 1; -+} -+#endif -+ -+ -+/* -+** This is a destructor on a Mem object (which is really an sqlite3_value) -+** that deletes the Frame object that is attached to it as a blob. -+** -+** This routine does not delete the Frame right away. It merely adds the -+** frame to a list of frames to be deleted when the Vdbe halts. -+*/ -+SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void *pArg){ -+ VdbeFrame *pFrame = (VdbeFrame*)pArg; -+ assert( sqlite3VdbeFrameIsValid(pFrame) ); -+ pFrame->pParent = pFrame->v->pDelFrame; -+ pFrame->v->pDelFrame = pFrame; -+} -+ -+ -+/* - ** Delete a VdbeFrame object and its contents. VdbeFrame objects are - ** allocated by the OP_Program opcode in sqlite3VdbeExec(). - */ -@@ -73591,6 +77550,7 @@ - int i; - Mem *aMem = VdbeFrameMem(p); - VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem]; -+ assert( sqlite3VdbeFrameIsValid(p) ); - for(i=0; i<p->nChildCsr; i++){ - sqlite3VdbeFreeCursor(p->v, apCsr[i]); - } -@@ -73611,6 +77571,9 @@ - ** p->explain==2, only OP_Explain instructions are listed and these - ** are shown in a different format. p->explain==2 is used to implement - ** EXPLAIN QUERY PLAN. -+** 2018-04-24: In p->explain==2 mode, the OP_Init opcodes of triggers -+** are also shown, so that the boundaries between the main program and -+** each trigger are clear. - ** - ** When p->explain==1, first the main program is listed, then each of - ** the trigger subprograms are listed one by one. -@@ -73626,6 +77589,8 @@ - int i; /* Loop counter */ - int rc = SQLITE_OK; /* Return code */ - Mem *pMem = &p->aMem[1]; /* First Mem of result set */ -+ int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0); -+ Op *pOp = 0; - - assert( p->explain ); - assert( p->magic==VDBE_MAGIC_RUN ); -@@ -73638,7 +77603,7 @@ - releaseMemArray(pMem, 8); - p->pResultSet = 0; - -- if( p->rc==SQLITE_NOMEM_BKPT ){ -+ if( p->rc==SQLITE_NOMEM ){ - /* This happens if a malloc() inside a call to sqlite3_column_text() or - ** sqlite3_column_text16() failed. */ - sqlite3OomFault(db); -@@ -73653,7 +77618,7 @@ - ** encountered, but p->pc will eventually catch up to nRow. - */ - nRow = p->nOp; -- if( p->explain==1 ){ -+ if( bListSubprogs ){ - /* The first 8 memory cells are used for the result set. So we will - ** commandeer the 9th cell to use as storage for an array of pointers - ** to trigger subprograms. The VDBE is guaranteed to have at least 9 -@@ -73671,19 +77636,13 @@ - } - } - -- do{ -+ while(1){ /* Loop exits via break */ - i = p->pc++; -- }while( i<nRow && p->explain==2 && p->aOp[i].opcode!=OP_Explain ); -- if( i>=nRow ){ -- p->rc = SQLITE_OK; -- rc = SQLITE_DONE; -- }else if( db->u1.isInterrupted ){ -- p->rc = SQLITE_INTERRUPT; -- rc = SQLITE_ERROR; -- sqlite3VdbeError(p, sqlite3ErrStr(p->rc)); -- }else{ -- char *zP4; -- Op *pOp; -+ if( i>=nRow ){ -+ p->rc = SQLITE_OK; -+ rc = SQLITE_DONE; -+ break; -+ } - if( i<p->nOp ){ - /* The output line number is small enough that we are still in the - ** main program. */ -@@ -73698,94 +77657,113 @@ - } - pOp = &apSub[j]->aOp[i]; - } -- if( p->explain==1 ){ -- pMem->flags = MEM_Int; -- pMem->u.i = i; /* Program counter */ -- pMem++; -- -- pMem->flags = MEM_Static|MEM_Str|MEM_Term; -- pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */ -- assert( pMem->z!=0 ); -- pMem->n = sqlite3Strlen30(pMem->z); -- pMem->enc = SQLITE_UTF8; -- pMem++; - -- /* When an OP_Program opcode is encounter (the only opcode that has -- ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms -- ** kept in p->aMem[9].z to hold the new program - assuming this subprogram -- ** has not already been seen. -- */ -- if( pOp->p4type==P4_SUBPROGRAM ){ -- int nByte = (nSub+1)*sizeof(SubProgram*); -- int j; -- for(j=0; j<nSub; j++){ -- if( apSub[j]==pOp->p4.pProgram ) break; -+ /* When an OP_Program opcode is encounter (the only opcode that has -+ ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms -+ ** kept in p->aMem[9].z to hold the new program - assuming this subprogram -+ ** has not already been seen. -+ */ -+ if( bListSubprogs && pOp->p4type==P4_SUBPROGRAM ){ -+ int nByte = (nSub+1)*sizeof(SubProgram*); -+ int j; -+ for(j=0; j<nSub; j++){ -+ if( apSub[j]==pOp->p4.pProgram ) break; -+ } -+ if( j==nSub ){ -+ p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0); -+ if( p->rc!=SQLITE_OK ){ -+ rc = SQLITE_ERROR; -+ break; - } -- if( j==nSub && SQLITE_OK==sqlite3VdbeMemGrow(pSub, nByte, nSub!=0) ){ -- apSub = (SubProgram **)pSub->z; -- apSub[nSub++] = pOp->p4.pProgram; -- pSub->flags |= MEM_Blob; -- pSub->n = nSub*sizeof(SubProgram*); -- } -+ apSub = (SubProgram **)pSub->z; -+ apSub[nSub++] = pOp->p4.pProgram; -+ pSub->flags |= MEM_Blob; -+ pSub->n = nSub*sizeof(SubProgram*); -+ nRow += pOp->p4.pProgram->nOp; - } - } -+ if( p->explain<2 ) break; -+ if( pOp->opcode==OP_Explain ) break; -+ if( pOp->opcode==OP_Init && p->pc>1 ) break; -+ } - -- pMem->flags = MEM_Int; -- pMem->u.i = pOp->p1; /* P1 */ -- pMem++; -+ if( rc==SQLITE_OK ){ -+ if( db->u1.isInterrupted ){ -+ p->rc = SQLITE_INTERRUPT; -+ rc = SQLITE_ERROR; -+ sqlite3VdbeError(p, sqlite3ErrStr(p->rc)); -+ }else{ -+ char *zP4; -+ if( p->explain==1 ){ -+ pMem->flags = MEM_Int; -+ pMem->u.i = i; /* Program counter */ -+ pMem++; -+ -+ pMem->flags = MEM_Static|MEM_Str|MEM_Term; -+ pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */ -+ assert( pMem->z!=0 ); -+ pMem->n = sqlite3Strlen30(pMem->z); -+ pMem->enc = SQLITE_UTF8; -+ pMem++; -+ } - -- pMem->flags = MEM_Int; -- pMem->u.i = pOp->p2; /* P2 */ -- pMem++; -+ pMem->flags = MEM_Int; -+ pMem->u.i = pOp->p1; /* P1 */ -+ pMem++; - -- pMem->flags = MEM_Int; -- pMem->u.i = pOp->p3; /* P3 */ -- pMem++; -+ pMem->flags = MEM_Int; -+ pMem->u.i = pOp->p2; /* P2 */ -+ pMem++; - -- if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */ -- assert( p->db->mallocFailed ); -- return SQLITE_ERROR; -- } -- pMem->flags = MEM_Str|MEM_Term; -- zP4 = displayP4(pOp, pMem->z, pMem->szMalloc); -- if( zP4!=pMem->z ){ -- pMem->n = 0; -- sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0); -- }else{ -- assert( pMem->z!=0 ); -- pMem->n = sqlite3Strlen30(pMem->z); -- pMem->enc = SQLITE_UTF8; -- } -- pMem++; -+ pMem->flags = MEM_Int; -+ pMem->u.i = pOp->p3; /* P3 */ -+ pMem++; - -- if( p->explain==1 ){ -- if( sqlite3VdbeMemClearAndResize(pMem, 4) ){ -+ if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */ - assert( p->db->mallocFailed ); - return SQLITE_ERROR; - } - pMem->flags = MEM_Str|MEM_Term; -- pMem->n = 2; -- sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */ -- pMem->enc = SQLITE_UTF8; -+ zP4 = displayP4(pOp, pMem->z, pMem->szMalloc); -+ if( zP4!=pMem->z ){ -+ pMem->n = 0; -+ sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0); -+ }else{ -+ assert( pMem->z!=0 ); -+ pMem->n = sqlite3Strlen30(pMem->z); -+ pMem->enc = SQLITE_UTF8; -+ } - pMem++; -- -+ -+ if( p->explain==1 ){ -+ if( sqlite3VdbeMemClearAndResize(pMem, 4) ){ -+ assert( p->db->mallocFailed ); -+ return SQLITE_ERROR; -+ } -+ pMem->flags = MEM_Str|MEM_Term; -+ pMem->n = 2; -+ sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */ -+ pMem->enc = SQLITE_UTF8; -+ pMem++; -+ - #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS -- if( sqlite3VdbeMemClearAndResize(pMem, 500) ){ -- assert( p->db->mallocFailed ); -- return SQLITE_ERROR; -- } -- pMem->flags = MEM_Str|MEM_Term; -- pMem->n = displayComment(pOp, zP4, pMem->z, 500); -- pMem->enc = SQLITE_UTF8; -+ if( sqlite3VdbeMemClearAndResize(pMem, 500) ){ -+ assert( p->db->mallocFailed ); -+ return SQLITE_ERROR; -+ } -+ pMem->flags = MEM_Str|MEM_Term; -+ pMem->n = displayComment(pOp, zP4, pMem->z, 500); -+ pMem->enc = SQLITE_UTF8; - #else -- pMem->flags = MEM_Null; /* Comment */ -+ pMem->flags = MEM_Null; /* Comment */ - #endif -+ } -+ -+ p->nResColumn = 8 - 4*(p->explain-1); -+ p->pResultSet = &p->aMem[1]; -+ p->rc = SQLITE_OK; -+ rc = SQLITE_ROW; - } -- -- p->nResColumn = 8 - 4*(p->explain-1); -- p->pResultSet = &p->aMem[1]; -- p->rc = SQLITE_OK; -- rc = SQLITE_ROW; - } - return rc; - } -@@ -74148,27 +78126,6 @@ - } - - /* --** Clean up the VM after a single run. --*/ --static void Cleanup(Vdbe *p){ -- sqlite3 *db = p->db; -- --#ifdef SQLITE_DEBUG -- /* Execute assert() statements to ensure that the Vdbe.apCsr[] and -- ** Vdbe.aMem[] arrays have already been cleaned up. */ -- int i; -- if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 ); -- if( p->aMem ){ -- for(i=0; i<p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined ); -- } --#endif -- -- sqlite3DbFree(db, p->zErrMsg); -- p->zErrMsg = 0; -- p->pResultSet = 0; --} -- --/* - ** Set the number of result columns that will be returned by this SQL - ** statement. This is now set at compile time, rather than during - ** execution of the vdbe program so that sqlite3_column_count() can -@@ -74276,6 +78233,7 @@ - pPager = sqlite3BtreePager(pBt); - if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF - && aMJNeeded[sqlite3PagerGetJournalMode(pPager)] -+ && sqlite3PagerIsMemdb(pPager)==0 - ){ - assert( i!=1 ); - nTrans++; -@@ -74876,6 +78834,10 @@ - ** VDBE_MAGIC_INIT. - */ - SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ -+#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) -+ int i; -+#endif -+ - sqlite3 *db; - db = p->db; - -@@ -74885,7 +78847,7 @@ - */ - sqlite3VdbeHalt(p); - -- /* If the VDBE has be run even partially, then transfer the error code -+ /* If the VDBE has been run even partially, then transfer the error code - ** and error message from the VDBE into the main database structure. But - ** if the VDBE has just been set to run but has not actually executed any - ** instructions yet, leave the main database error information unchanged. -@@ -74893,8 +78855,6 @@ - if( p->pc>=0 ){ - vdbeInvokeSqllog(p); - sqlite3VdbeTransferError(p); -- sqlite3DbFree(db, p->zErrMsg); -- p->zErrMsg = 0; - if( p->runOnlyOnce ) p->expired = 1; - }else if( p->rc && p->expired ){ - /* The expired flag was set on the VDBE before the first call -@@ -74902,13 +78862,24 @@ - ** called), set the database error in this case as well. - */ - sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg); -- sqlite3DbFree(db, p->zErrMsg); -- p->zErrMsg = 0; - } - -- /* Reclaim all memory used by the VDBE -+ /* Reset register contents and reclaim error message memory. - */ -- Cleanup(p); -+#ifdef SQLITE_DEBUG -+ /* Execute assert() statements to ensure that the Vdbe.apCsr[] and -+ ** Vdbe.aMem[] arrays have already been cleaned up. */ -+ if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 ); -+ if( p->aMem ){ -+ for(i=0; i<p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined ); -+ } -+#endif -+ sqlite3DbFree(db, p->zErrMsg); -+ p->zErrMsg = 0; -+ p->pResultSet = 0; -+#ifdef SQLITE_DEBUG -+ p->nWrite = 0; -+#endif - - /* Save profiling information from this VDBE run. - */ -@@ -74916,7 +78887,6 @@ - { - FILE *out = fopen("vdbe_profile.out", "a"); - if( out ){ -- int i; - fprintf(out, "---- "); - for(i=0; i<p->nOp; i++){ - fprintf(out, "%02x", p->aOp[i].opcode); -@@ -75025,6 +78995,9 @@ - vdbeFreeOpArray(db, p->aOp, p->nOp); - sqlite3DbFree(db, p->aColName); - sqlite3DbFree(db, p->zSql); -+#ifdef SQLITE_ENABLE_NORMALIZE -+ sqlite3DbFree(db, p->zNormSql); -+#endif - #ifdef SQLITE_ENABLE_STMT_SCANSTATUS - { - int i; -@@ -75042,7 +79015,7 @@ - SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ - sqlite3 *db; - -- if( NEVER(p==0) ) return; -+ assert( p!=0 ); - db = p->db; - assert( sqlite3_mutex_held(db->mutex) ); - sqlite3VdbeClearObject(db, p); -@@ -75129,20 +79102,19 @@ - */ - SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){ - VdbeCursor *p = *pp; -- if( p->eCurType==CURTYPE_BTREE ){ -- if( p->deferredMoveto ){ -- int iMap; -- if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){ -- *pp = p->pAltCursor; -- *piCol = iMap - 1; -- return SQLITE_OK; -- } -- return handleDeferredMoveto(p); -+ assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO ); -+ if( p->deferredMoveto ){ -+ int iMap; -+ if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){ -+ *pp = p->pAltCursor; -+ *piCol = iMap - 1; -+ return SQLITE_OK; - } -- if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ -- return handleMovedCursor(p); -- } -+ return handleDeferredMoveto(p); - } -+ if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ -+ return handleMovedCursor(p); -+ } - return SQLITE_OK; - } - -@@ -75439,7 +79411,13 @@ - Mem *pMem /* Memory cell to write value into */ - ){ - switch( serial_type ){ -- case 10: /* Reserved for future use */ -+ case 10: { /* Internal use only: NULL with virtual table -+ ** UPDATE no-change flag set */ -+ pMem->flags = MEM_Null|MEM_Zero; -+ pMem->n = 0; -+ pMem->u.nZero = 0; -+ break; -+ } - case 11: /* Reserved for future use */ - case 0: { /* Null */ - /* EVIDENCE-OF: R-24078-09375 Value is a NULL. */ -@@ -75537,13 +79515,13 @@ - ){ - UnpackedRecord *p; /* Unpacked record to return */ - int nByte; /* Number of bytes required for *p */ -- nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1); -+ nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); - p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); - if( !p ) return 0; - p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))]; - assert( pKeyInfo->aSortOrder!=0 ); - p->pKeyInfo = pKeyInfo; -- p->nField = pKeyInfo->nField + 1; -+ p->nField = pKeyInfo->nKeyField + 1; - return p; - } - -@@ -75583,7 +79561,7 @@ - pMem++; - if( (++u)>=p->nField ) break; - } -- assert( u<=pKeyInfo->nField + 1 ); -+ assert( u<=pKeyInfo->nKeyField + 1 ); - p->nField = u; - } - -@@ -75632,9 +79610,9 @@ - idx1 = getVarint32(aKey1, szHdr1); - if( szHdr1>98307 ) return SQLITE_CORRUPT; - d1 = szHdr1; -- assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField || CORRUPT_DB ); -+ assert( pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB ); - assert( pKeyInfo->aSortOrder!=0 ); -- assert( pKeyInfo->nField>0 ); -+ assert( pKeyInfo->nKeyField>0 ); - assert( idx1<=szHdr1 || CORRUPT_DB ); - do{ - u32 serial_type1; -@@ -75696,12 +79674,12 @@ - /* - ** Count the number of fields (a.k.a. columns) in the record given by - ** pKey,nKey. The verify that this count is less than or equal to the --** limit given by pKeyInfo->nField + pKeyInfo->nXField. -+** limit given by pKeyInfo->nAllField. - ** - ** If this constraint is not satisfied, it means that the high-speed - ** vdbeRecordCompareInt() and vdbeRecordCompareString() routines will - ** not work correctly. If this assert() ever fires, it probably means --** that the KeyInfo.nField or KeyInfo.nXField values were computed -+** that the KeyInfo.nKeyField or KeyInfo.nAllField values were computed - ** incorrectly. - */ - static void vdbeAssertFieldCountWithinLimits( -@@ -75722,7 +79700,7 @@ - idx += getVarint32(aKey+idx, notUsed); - nField++; - } -- assert( nField <= pKeyInfo->nField+pKeyInfo->nXField ); -+ assert( nField <= pKeyInfo->nAllField ); - } - #else - # define vdbeAssertFieldCountWithinLimits(A,B,C) -@@ -75784,7 +79762,7 @@ - ** is less than, equal to, or greater than the second, respectively. - ** If one blob is a prefix of the other, then the shorter is the lessor. - */ --static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){ -+SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){ - int c; - int n1 = pB1->n; - int n2 = pB2->n; -@@ -75827,13 +79805,10 @@ - i64 y; - double s; - if( r<-9223372036854775808.0 ) return +1; -- if( r>9223372036854775807.0 ) return -1; -+ if( r>=9223372036854775808.0 ) return -1; - y = (i64)r; - if( i<y ) return -1; -- if( i>y ){ -- if( y==SMALLEST_INT64 && r>0.0 ) return -1; -- return +1; -- } -+ if( i>y ) return +1; - s = (double)i; - if( s<r ) return -1; - if( s>r ) return +1; -@@ -75857,7 +79832,7 @@ - f1 = pMem1->flags; - f2 = pMem2->flags; - combined_flags = f1|f2; -- assert( (combined_flags & MEM_RowSet)==0 ); -+ assert( !sqlite3VdbeMemIsRowSet(pMem1) && !sqlite3VdbeMemIsRowSet(pMem2) ); - - /* If one value is NULL, it is less than the other. If both values - ** are NULL, return 0. -@@ -76002,7 +79977,7 @@ - u32 idx1; /* Offset of first type in header */ - int rc = 0; /* Return value */ - Mem *pRhs = pPKey2->aMem; /* Next field of pPKey2 to compare */ -- KeyInfo *pKeyInfo = pPKey2->pKeyInfo; -+ KeyInfo *pKeyInfo; - const unsigned char *aKey1 = (const unsigned char *)pKey1; - Mem mem1; - -@@ -76027,10 +80002,10 @@ - } - - VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */ -- assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField -+ assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField - || CORRUPT_DB ); - assert( pPKey2->pKeyInfo->aSortOrder!=0 ); -- assert( pPKey2->pKeyInfo->nField>0 ); -+ assert( pPKey2->pKeyInfo->nKeyField>0 ); - assert( idx1<=szHdr1 || CORRUPT_DB ); - do{ - u32 serial_type; -@@ -76097,7 +80072,7 @@ - if( (d1+mem1.n) > (unsigned)nKey1 ){ - pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; - return 0; /* Corruption */ -- }else if( pKeyInfo->aColl[i] ){ -+ }else if( (pKeyInfo = pPKey2->pKeyInfo)->aColl[i] ){ - mem1.enc = pKeyInfo->enc; - mem1.db = pKeyInfo->db; - mem1.flags = MEM_Str; -@@ -76148,7 +80123,7 @@ - } - - if( rc!=0 ){ -- if( pKeyInfo->aSortOrder[i] ){ -+ if( pPKey2->pKeyInfo->aSortOrder[i] ){ - rc = -rc; - } - assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) ); -@@ -76157,10 +80132,11 @@ - } - - i++; -+ if( i==pPKey2->nField ) break; - pRhs++; - d1 += sqlite3VdbeSerialTypeLen(serial_type); - idx1 += sqlite3VarintLen(serial_type); -- }while( idx1<(unsigned)szHdr1 && i<pPKey2->nField && d1<=(unsigned)nKey1 ); -+ }while( idx1<(unsigned)szHdr1 && d1<=(unsigned)nKey1 ); - - /* No memory allocation is ever used on mem1. Prove this using - ** the following assert(). If the assert() fails, it indicates a -@@ -76172,7 +80148,7 @@ - ** value. */ - assert( CORRUPT_DB - || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) -- || pKeyInfo->db->mallocFailed -+ || pPKey2->pKeyInfo->db->mallocFailed - ); - pPKey2->eqSeen = 1; - return pPKey2->default_rc; -@@ -76363,7 +80339,7 @@ - ** The easiest way to enforce this limit is to consider only records with - ** 13 fields or less. If the first field is an integer, the maximum legal - ** header size is (12*5 + 1 + 1) bytes. */ -- if( (p->pKeyInfo->nField + p->pKeyInfo->nXField)<=13 ){ -+ if( p->pKeyInfo->nAllField<=13 ){ - int flags = p->aMem[0].flags; - if( p->pKeyInfo->aSortOrder[0] ){ - p->r1 = 1; -@@ -76423,7 +80399,9 @@ - (void)getVarint32((u8*)m.z, szHdr); - testcase( szHdr==3 ); - testcase( szHdr==m.n ); -- if( unlikely(szHdr<3 || (int)szHdr>m.n) ){ -+ testcase( szHdr>0x7fffffff ); -+ assert( m.n>=0 ); -+ if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){ - goto idx_rowid_corruption; - } - -@@ -76498,7 +80476,7 @@ - if( rc ){ - return rc; - } -- *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked); -+ *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0); - sqlite3VdbeMemRelease(&m); - return SQLITE_OK; - } -@@ -76530,11 +80508,19 @@ - ** programs obsolete. Removing user-defined functions or collating - ** sequences, or changing an authorization function are the types of - ** things that make prepared statements obsolete. -+** -+** If iCode is 1, then expiration is advisory. The statement should -+** be reprepared before being restarted, but if it is already running -+** it is allowed to run to completion. -+** -+** Internally, this function just sets the Vdbe.expired flag on all -+** prepared statements. The flag is set to 1 for an immediate expiration -+** and set to 2 for an advisory expiration. - */ --SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db){ -+SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db, int iCode){ - Vdbe *p; - for(p = db->pVdbe; p; p=p->pNext){ -- p->expired = 1; -+ p->expired = iCode+1; - } - } - -@@ -76698,7 +80684,7 @@ - preupdate.iNewReg = iReg; - preupdate.keyinfo.db = db; - preupdate.keyinfo.enc = ENC(db); -- preupdate.keyinfo.nField = pTab->nCol; -+ preupdate.keyinfo.nKeyField = pTab->nCol; - preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder; - preupdate.iKey1 = iKey1; - preupdate.iKey2 = iKey2; -@@ -76708,8 +80694,8 @@ - db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); - db->pPreUpdate = 0; - sqlite3DbFree(db, preupdate.aRecord); -- vdbeFreeUnpacked(db, preupdate.keyinfo.nField+1, preupdate.pUnpacked); -- vdbeFreeUnpacked(db, preupdate.keyinfo.nField+1, preupdate.pNewUnpacked); -+ vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pUnpacked); -+ vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pNewUnpacked); - if( preupdate.aNew ){ - int i; - for(i=0; i<pCsr->nField; i++){ -@@ -76992,6 +80978,11 @@ - return aType[pVal->flags&MEM_AffMask]; - } - -+/* Return true if a parameter to xUpdate represents an unchanged column */ -+SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){ -+ return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero); -+} -+ - /* Make a copy of an sqlite3_value object - */ - SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){ -@@ -77091,7 +81082,6 @@ - SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - pCtx->isError = SQLITE_ERROR; -- pCtx->fErrorOrAux = 1; - sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); - } - #ifndef SQLITE_OMIT_UTF16 -@@ -77098,7 +81088,6 @@ - SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - pCtx->isError = SQLITE_ERROR; -- pCtx->fErrorOrAux = 1; - sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); - } - #endif -@@ -77122,7 +81111,8 @@ - ){ - Mem *pOut = pCtx->pOut; - assert( sqlite3_mutex_held(pOut->db->mutex) ); -- sqlite3VdbeMemSetNull(pOut); -+ sqlite3VdbeMemRelease(pOut); -+ pOut->flags = MEM_Null; - sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor); - } - SQLITE_API void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ -@@ -77203,8 +81193,7 @@ - return SQLITE_OK; - } - SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ -- pCtx->isError = errCode; -- pCtx->fErrorOrAux = 1; -+ pCtx->isError = errCode ? errCode : -1; - #ifdef SQLITE_DEBUG - if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode; - #endif -@@ -77218,7 +81207,6 @@ - SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - pCtx->isError = SQLITE_TOOBIG; -- pCtx->fErrorOrAux = 1; - sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, - SQLITE_UTF8, SQLITE_STATIC); - } -@@ -77228,7 +81216,6 @@ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - sqlite3VdbeMemSetNull(pCtx->pOut); - pCtx->isError = SQLITE_NOMEM_BKPT; -- pCtx->fErrorOrAux = 1; - sqlite3OomFault(pCtx->pOut->db); - } - -@@ -77247,7 +81234,7 @@ - sqlite3BtreeEnter(pBt); - nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt)); - sqlite3BtreeLeave(pBt); -- if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){ -+ if( nEntry>0 && db->xWalCallback && rc==SQLITE_OK ){ - rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry); - } - } -@@ -77357,7 +81344,7 @@ - if( rc!=SQLITE_ROW ) checkProfileCallback(db, p); - #endif - -- if( rc==SQLITE_DONE ){ -+ if( rc==SQLITE_DONE && db->autoCommit ){ - assert( p->rc==SQLITE_OK ); - p->rc = doWalCallbacks(db); - if( p->rc!=SQLITE_OK ){ -@@ -77401,7 +81388,6 @@ - */ - SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ - int rc = SQLITE_OK; /* Result from sqlite3Step() */ -- int rc2 = SQLITE_OK; /* Result from sqlite3Reprepare() */ - Vdbe *v = (Vdbe*)pStmt; /* the prepared statement */ - int cnt = 0; /* Counter to prevent infinite loop of reprepares */ - sqlite3 *db; /* The database connection */ -@@ -77415,32 +81401,31 @@ - while( (rc = sqlite3Step(v))==SQLITE_SCHEMA - && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){ - int savedPc = v->pc; -- rc2 = rc = sqlite3Reprepare(v); -- if( rc!=SQLITE_OK) break; -+ rc = sqlite3Reprepare(v); -+ if( rc!=SQLITE_OK ){ -+ /* This case occurs after failing to recompile an sql statement. -+ ** The error message from the SQL compiler has already been loaded -+ ** into the database handle. This block copies the error message -+ ** from the database handle into the statement and sets the statement -+ ** program counter to 0 to ensure that when the statement is -+ ** finalized or reset the parser error message is available via -+ ** sqlite3_errmsg() and sqlite3_errcode(). -+ */ -+ const char *zErr = (const char *)sqlite3_value_text(db->pErr); -+ sqlite3DbFree(db, v->zErrMsg); -+ if( !db->mallocFailed ){ -+ v->zErrMsg = sqlite3DbStrDup(db, zErr); -+ v->rc = rc = sqlite3ApiExit(db, rc); -+ } else { -+ v->zErrMsg = 0; -+ v->rc = rc = SQLITE_NOMEM_BKPT; -+ } -+ break; -+ } - sqlite3_reset(pStmt); - if( savedPc>=0 ) v->doingRerun = 1; - assert( v->expired==0 ); - } -- if( rc2!=SQLITE_OK ){ -- /* This case occurs after failing to recompile an sql statement. -- ** The error message from the SQL compiler has already been loaded -- ** into the database handle. This block copies the error message -- ** from the database handle into the statement and sets the statement -- ** program counter to 0 to ensure that when the statement is -- ** finalized or reset the parser error message is available via -- ** sqlite3_errmsg() and sqlite3_errcode(). -- */ -- const char *zErr = (const char *)sqlite3_value_text(db->pErr); -- sqlite3DbFree(db, v->zErrMsg); -- if( !db->mallocFailed ){ -- v->zErrMsg = sqlite3DbStrDup(db, zErr); -- v->rc = rc2; -- } else { -- v->zErrMsg = 0; -- v->rc = rc = SQLITE_NOMEM_BKPT; -- } -- } -- rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; - } -@@ -77471,6 +81456,25 @@ - } - - /* -+** If this routine is invoked from within an xColumn method of a virtual -+** table, then it returns true if and only if the the call is during an -+** UPDATE operation and the value of the column will not be modified -+** by the UPDATE. -+** -+** If this routine is called from any context other than within the -+** xColumn method of a virtual table, then the return value is meaningless -+** and arbitrary. -+** -+** Virtual table implements might use this routine to optimize their -+** performance by substituting a NULL result, or some other light-weight -+** value, as a signal to the xUpdate routine that the column is unchanged. -+*/ -+SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){ -+ assert( p ); -+ return sqlite3_value_nochange(p->pOut); -+} -+ -+/* - ** Return the current time for a statement. If the current time - ** is requested more than once within the same run of a single prepared - ** statement, the exact same time is returned for each invocation regardless -@@ -77494,28 +81498,6 @@ - } - - /* --** The following is the implementation of an SQL function that always --** fails with an error message stating that the function is used in the --** wrong context. The sqlite3_overload_function() API might construct --** SQL function that use this routine so that the functions will exist --** for name resolution but are actually overloaded by the xFindFunction --** method of virtual tables. --*/ --SQLITE_PRIVATE void sqlite3InvalidFunction( -- sqlite3_context *context, /* The function calling context */ -- int NotUsed, /* Number of arguments to the function */ -- sqlite3_value **NotUsed2 /* Value of each argument */ --){ -- const char *zName = context->pFunc->zName; -- char *zErr; -- UNUSED_PARAMETER2(NotUsed, NotUsed2); -- zErr = sqlite3_mprintf( -- "unable to use function %s in the requested context", zName); -- sqlite3_result_error(context, zErr, -1); -- sqlite3_free(zErr); --} -- --/* - ** Create a new aggregate context for p and return a pointer to - ** its pMem->z element. - */ -@@ -77618,10 +81600,7 @@ - pAuxData->iAuxArg = iArg; - pAuxData->pNextAux = pVdbe->pAuxData; - pVdbe->pAuxData = pAuxData; -- if( pCtx->fErrorOrAux==0 ){ -- pCtx->isError = 0; -- pCtx->fErrorOrAux = 1; -- } -+ if( pCtx->isError==0 ) pCtx->isError = -1; - }else if( pAuxData->xDeleteAux ){ - pAuxData->xDeleteAux(pAuxData->pAux); - } -@@ -77701,7 +81680,7 @@ - /* .xDel = */ (void(*)(void*))0, - #ifdef SQLITE_DEBUG - /* .pScopyFrom = */ (Mem*)0, -- /* .pFiller = */ (void*)0, -+ /* .mScopyFlags= */ 0, - #endif - }; - return &nullMem; -@@ -78377,7 +82356,9 @@ - Vdbe *pVdbe = (Vdbe*)pStmt; - u32 v; - #ifdef SQLITE_ENABLE_API_ARMOR -- if( !pStmt ){ -+ if( !pStmt -+ || (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||op>=ArraySize(pVdbe->aCounter))) -+ ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -@@ -78431,6 +82412,16 @@ - #endif - } - -+#ifdef SQLITE_ENABLE_NORMALIZE -+/* -+** Return the normalized SQL associated with a prepared statement. -+*/ -+SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt){ -+ Vdbe *p = (Vdbe *)pStmt; -+ return p ? p->zNormSql : 0; -+} -+#endif /* SQLITE_ENABLE_NORMALIZE */ -+ - #ifdef SQLITE_ENABLE_PREUPDATE_HOOK - /* - ** Allocate and populate an UnpackedRecord structure based on the serialized -@@ -78446,7 +82437,7 @@ - - pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); - if( pRet ){ -- memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nField+1)); -+ memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1)); - sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet); - } - return pRet; -@@ -78519,7 +82510,7 @@ - */ - SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){ - PreUpdate *p = db->pPreUpdate; -- return (p ? p->keyinfo.nField : 0); -+ return (p ? p->keyinfo.nKeyField : 0); - } - #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ - -@@ -78772,7 +82763,7 @@ - Mem *pVar; /* Value of a host parameter */ - StrAccum out; /* Accumulate the output here */ - #ifndef SQLITE_OMIT_UTF16 -- Mem utf8; /* Used to convert UTF16 parameters into UTF8 for display */ -+ Mem utf8; /* Used to convert UTF16 into UTF8 for display */ - #endif - char zBase[100]; /* Initial working space */ - -@@ -78783,17 +82774,17 @@ - while( *zRawSql ){ - const char *zStart = zRawSql; - while( *(zRawSql++)!='\n' && *zRawSql ); -- sqlite3StrAccumAppend(&out, "-- ", 3); -+ sqlite3_str_append(&out, "-- ", 3); - assert( (zRawSql - zStart) > 0 ); -- sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart)); -+ sqlite3_str_append(&out, zStart, (int)(zRawSql-zStart)); - } - }else if( p->nVar==0 ){ -- sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql)); -+ sqlite3_str_append(&out, zRawSql, sqlite3Strlen30(zRawSql)); - }else{ - while( zRawSql[0] ){ - n = findNextHostParameter(zRawSql, &nToken); - assert( n>0 ); -- sqlite3StrAccumAppend(&out, zRawSql, n); -+ sqlite3_str_append(&out, zRawSql, n); - zRawSql += n; - assert( zRawSql[0] || nToken==0 ); - if( nToken==0 ) break; -@@ -78819,11 +82810,11 @@ - assert( idx>0 && idx<=p->nVar ); - pVar = &p->aVar[idx-1]; - if( pVar->flags & MEM_Null ){ -- sqlite3StrAccumAppend(&out, "NULL", 4); -+ sqlite3_str_append(&out, "NULL", 4); - }else if( pVar->flags & MEM_Int ){ -- sqlite3XPrintf(&out, "%lld", pVar->u.i); -+ sqlite3_str_appendf(&out, "%lld", pVar->u.i); - }else if( pVar->flags & MEM_Real ){ -- sqlite3XPrintf(&out, "%!.15g", pVar->u.r); -+ sqlite3_str_appendf(&out, "%!.15g", pVar->u.r); - }else if( pVar->flags & MEM_Str ){ - int nOut; /* Number of bytes of the string text to include in output */ - #ifndef SQLITE_OMIT_UTF16 -@@ -78833,7 +82824,7 @@ - utf8.db = db; - sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); - if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){ -- out.accError = STRACCUM_NOMEM; -+ out.accError = SQLITE_NOMEM; - out.nAlloc = 0; - } - pVar = &utf8; -@@ -78846,10 +82837,10 @@ - while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; } - } - #endif -- sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z); -+ sqlite3_str_appendf(&out, "'%.*q'", nOut, pVar->z); - #ifdef SQLITE_TRACE_SIZE_LIMIT - if( nOut<pVar->n ){ -- sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); -+ sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut); - } - #endif - #ifndef SQLITE_OMIT_UTF16 -@@ -78856,28 +82847,28 @@ - if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8); - #endif - }else if( pVar->flags & MEM_Zero ){ -- sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero); -+ sqlite3_str_appendf(&out, "zeroblob(%d)", pVar->u.nZero); - }else{ - int nOut; /* Number of bytes of the blob to include in output */ - assert( pVar->flags & MEM_Blob ); -- sqlite3StrAccumAppend(&out, "x'", 2); -+ sqlite3_str_append(&out, "x'", 2); - nOut = pVar->n; - #ifdef SQLITE_TRACE_SIZE_LIMIT - if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT; - #endif - for(i=0; i<nOut; i++){ -- sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff); -+ sqlite3_str_appendf(&out, "%02x", pVar->z[i]&0xff); - } -- sqlite3StrAccumAppend(&out, "'", 1); -+ sqlite3_str_append(&out, "'", 1); - #ifdef SQLITE_TRACE_SIZE_LIMIT - if( nOut<pVar->n ){ -- sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); -+ sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut); - } - #endif - } - } - } -- if( out.accError ) sqlite3StrAccumReset(&out); -+ if( out.accError ) sqlite3_str_reset(&out); - return sqlite3StrAccumFinish(&out); - } - -@@ -79009,32 +83000,56 @@ - ** feature is used for test suite validation only and does not appear an - ** production builds. - ** --** M is an integer, 2 or 3, that indices how many different ways the --** branch can go. It is usually 2. "I" is the direction the branch --** goes. 0 means falls through. 1 means branch is taken. 2 means the --** second alternative branch is taken. -+** M is an integer between 2 and 4. 2 indicates a ordinary two-way -+** branch (I=0 means fall through and I=1 means taken). 3 indicates -+** a 3-way branch where the third way is when one of the operands is -+** NULL. 4 indicates the OP_Jump instruction which has three destinations -+** depending on whether the first operand is less than, equal to, or greater -+** than the second. - ** - ** iSrcLine is the source code line (from the __LINE__ macro) that --** generated the VDBE instruction. This instrumentation assumes that all --** source code is in a single file (the amalgamation). Special values 1 --** and 2 for the iSrcLine parameter mean that this particular branch is --** always taken or never taken, respectively. -+** generated the VDBE instruction combined with flag bits. The source -+** code line number is in the lower 24 bits of iSrcLine and the upper -+** 8 bytes are flags. The lower three bits of the flags indicate -+** values for I that should never occur. For example, if the branch is -+** always taken, the flags should be 0x05 since the fall-through and -+** alternate branch are never taken. If a branch is never taken then -+** flags should be 0x06 since only the fall-through approach is allowed. -+** -+** Bit 0x04 of the flags indicates an OP_Jump opcode that is only -+** interested in equal or not-equal. In other words, I==0 and I==2 -+** should be treated the same. -+** -+** Since only a line number is retained, not the filename, this macro -+** only works for amalgamation builds. But that is ok, since these macros -+** should be no-ops except for special builds used to measure test coverage. - */ - #if !defined(SQLITE_VDBE_COVERAGE) - # define VdbeBranchTaken(I,M) - #else - # define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M) -- static void vdbeTakeBranch(int iSrcLine, u8 I, u8 M){ -- if( iSrcLine<=2 && ALWAYS(iSrcLine>0) ){ -- M = iSrcLine; -- /* Assert the truth of VdbeCoverageAlwaysTaken() and -- ** VdbeCoverageNeverTaken() */ -- assert( (M & I)==I ); -- }else{ -- if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/ -- sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg, -- iSrcLine,I,M); -+ static void vdbeTakeBranch(u32 iSrcLine, u8 I, u8 M){ -+ u8 mNever; -+ assert( I<=2 ); /* 0: fall through, 1: taken, 2: alternate taken */ -+ assert( M<=4 ); /* 2: two-way branch, 3: three-way branch, 4: OP_Jump */ -+ assert( I<M ); /* I can only be 2 if M is 3 or 4 */ -+ /* Transform I from a integer [0,1,2] into a bitmask of [1,2,4] */ -+ I = 1<<I; -+ /* The upper 8 bits of iSrcLine are flags. The lower three bits of -+ ** the flags indicate directions that the branch can never go. If -+ ** a branch really does go in one of those directions, assert right -+ ** away. */ -+ mNever = iSrcLine >> 24; -+ assert( (I & mNever)==0 ); -+ if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/ -+ I |= mNever; -+ if( M==2 ) I |= 0x04; -+ if( M==4 ){ -+ I |= 0x08; -+ if( (mNever&0x08)!=0 && (I&0x05)!=0) I |= 0x05; /*NO_TEST*/ - } -+ sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg, -+ iSrcLine&0xffffff, I, M); - } - #endif - -@@ -79151,6 +83166,11 @@ - pRec->flags |= MEM_Real; - if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec); - } -+ /* TEXT->NUMERIC is many->one. Hence, it is important to invalidate the -+ ** string representation after computing a numeric equivalent, because the -+ ** string representation might not be the canonical representation for the -+ ** numeric value. Ticket [343634942dd54ab57b7024] 2018-01-31. */ -+ pRec->flags &= ~MEM_Str; - } - - /* -@@ -79241,7 +83261,7 @@ - if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){ - return 0; - } -- if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){ -+ if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==0 ){ - return MEM_Int; - } - return MEM_Real; -@@ -79351,7 +83371,7 @@ - if( p->flags & MEM_Undefined ){ - printf(" undefined"); - }else if( p->flags & MEM_Null ){ -- printf(" NULL"); -+ printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL"); - }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ - printf(" si:%lld", p->u.i); - }else if( p->flags & MEM_Int ){ -@@ -79360,7 +83380,7 @@ - }else if( p->flags & MEM_Real ){ - printf(" r:%g", p->u.r); - #endif -- }else if( p->flags & MEM_RowSet ){ -+ }else if( sqlite3VdbeMemIsRowSet(p) ){ - printf(" (rowset)"); - }else{ - char zBuf[200]; -@@ -79619,7 +83639,7 @@ - - assert( pOp>=aOp && pOp<&aOp[p->nOp]); - #ifdef VDBE_PROFILE -- start = sqlite3Hwtime(); -+ start = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); - #endif - nVmStep++; - #ifdef SQLITE_ENABLE_STMT_SCANSTATUS -@@ -79886,6 +83906,9 @@ - */ - case OP_HaltIfNull: { /* in3 */ - pIn3 = &aMem[pOp->p3]; -+#ifdef SQLITE_DEBUG -+ if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } -+#endif - if( (pIn3->flags & MEM_Null)==0 ) break; - /* Fall through into OP_Halt */ - } -@@ -79925,6 +83948,9 @@ - int pcx; - - pcx = (int)(pOp - aOp); -+#ifdef SQLITE_DEBUG -+ if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } -+#endif - if( pOp->p1==SQLITE_OK && p->pFrame ){ - /* Halt the sub-program. Return control to the parent frame. */ - pFrame = p->pFrame; -@@ -80108,6 +84134,9 @@ - assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); - pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; - pOut->n = 0; -+#ifdef SQLITE_DEBUG -+ pOut->uTemp = 0; -+#endif - while( cnt>0 ){ - pOut++; - memAboutToChange(p, pOut); -@@ -80229,6 +84258,7 @@ - pOut = &aMem[pOp->p2]; - assert( pOut!=pIn1 ); - while( 1 ){ -+ memAboutToChange(p, pOut); - sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); - Deephemeralize(pOut); - #ifdef SQLITE_DEBUG -@@ -80261,7 +84291,8 @@ - assert( pOut!=pIn1 ); - sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); - #ifdef SQLITE_DEBUG -- if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1; -+ pOut->pScopyFrom = pIn1; -+ pOut->mScopyFlags = pIn1->flags; - #endif - break; - } -@@ -80895,7 +84926,12 @@ - if( (flags1 | flags3)&MEM_Str ){ - if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ - applyNumericAffinity(pIn1,0); -- testcase( flags3!=pIn3->flags ); /* Possible if pIn1==pIn3 */ -+ 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. */ - flags3 = pIn3->flags; - } - if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ -@@ -80931,13 +84967,23 @@ - res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); - } - compare_op: -- switch( pOp->opcode ){ -- case OP_Eq: res2 = res==0; break; -- case OP_Ne: res2 = res; break; -- case OP_Lt: res2 = res<0; break; -- case OP_Le: res2 = res<=0; break; -- case OP_Gt: res2 = res>0; break; -- default: res2 = res>=0; break; -+ /* At this point, res is negative, zero, or positive if reg[P1] is -+ ** less than, equal to, or greater than reg[P3], respectively. Compute -+ ** the answer to this operator in res2, depending on what the comparison -+ ** operator actually is. The next block of code depends on the fact -+ ** that the 6 comparison operators are consecutive integers in this -+ ** order: NE, EQ, GT, LE, LT, GE */ -+ assert( OP_Eq==OP_Ne+1 ); assert( OP_Gt==OP_Ne+2 ); assert( OP_Le==OP_Ne+3 ); -+ assert( OP_Lt==OP_Ne+4 ); assert( OP_Ge==OP_Ne+5 ); -+ if( res<0 ){ /* ne, eq, gt, le, lt, ge */ -+ static const unsigned char aLTb[] = { 1, 0, 0, 1, 1, 0 }; -+ res2 = aLTb[pOp->opcode - OP_Ne]; -+ }else if( res==0 ){ -+ static const unsigned char aEQb[] = { 0, 1, 0, 1, 0, 1 }; -+ res2 = aEQb[pOp->opcode - OP_Ne]; -+ }else{ -+ static const unsigned char aGTb[] = { 1, 0, 1, 0, 0, 1 }; -+ res2 = aGTb[pOp->opcode - OP_Ne]; - } - - /* Undo any changes made by applyAffinity() to the input registers. */ -@@ -80949,7 +84995,6 @@ - if( pOp->p5 & SQLITE_STOREP2 ){ - pOut = &aMem[pOp->p2]; - iCompare = res; -- res2 = res2!=0; /* For this path res2 must be exactly 0 or 1 */ - if( (pOp->p5 & SQLITE_KEEPNULL)!=0 ){ - /* The KEEPNULL flag prevents OP_Eq from overwriting a NULL with 1 - ** and prevents OP_Ne from overwriting NULL with 0. This flag -@@ -81080,7 +85125,7 @@ - assert( memIsValid(&aMem[p2+idx]) ); - REGISTER_TRACE(p1+idx, &aMem[p1+idx]); - REGISTER_TRACE(p2+idx, &aMem[p2+idx]); -- assert( i<pKeyInfo->nField ); -+ assert( i<pKeyInfo->nKeyField ); - pColl = pKeyInfo->aColl[i]; - bRev = pKeyInfo->aSortOrder[i]; - iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl); -@@ -81100,11 +85145,11 @@ - */ - case OP_Jump: { /* jump */ - if( iCompare<0 ){ -- VdbeBranchTaken(0,3); pOp = &aOp[pOp->p1 - 1]; -+ VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1]; - }else if( iCompare==0 ){ -- VdbeBranchTaken(1,3); pOp = &aOp[pOp->p2 - 1]; -+ VdbeBranchTaken(1,4); pOp = &aOp[pOp->p2 - 1]; - }else{ -- VdbeBranchTaken(2,3); pOp = &aOp[pOp->p3 - 1]; -+ VdbeBranchTaken(2,4); pOp = &aOp[pOp->p3 - 1]; - } - break; - } -@@ -81134,18 +85179,8 @@ - int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ - int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ - -- pIn1 = &aMem[pOp->p1]; -- if( pIn1->flags & MEM_Null ){ -- v1 = 2; -- }else{ -- v1 = sqlite3VdbeIntValue(pIn1)!=0; -- } -- pIn2 = &aMem[pOp->p2]; -- if( pIn2->flags & MEM_Null ){ -- v2 = 2; -- }else{ -- v2 = sqlite3VdbeIntValue(pIn2)!=0; -- } -+ v1 = sqlite3VdbeBooleanValue(&aMem[pOp->p1], 2); -+ v2 = sqlite3VdbeBooleanValue(&aMem[pOp->p2], 2); - if( pOp->opcode==OP_And ){ - static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 }; - v1 = and_logic[v1*3+v2]; -@@ -81163,6 +85198,35 @@ - break; - } - -+/* Opcode: IsTrue P1 P2 P3 P4 * -+** Synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 -+** -+** This opcode implements the IS TRUE, IS FALSE, IS NOT TRUE, and -+** IS NOT FALSE operators. -+** -+** Interpret the value in register P1 as a boolean value. Store that -+** boolean (a 0 or 1) in register P2. Or if the value in register P1 is -+** NULL, then the P3 is stored in register P2. Invert the answer if P4 -+** is 1. -+** -+** The logic is summarized like this: -+** -+** <ul> -+** <li> If P3==0 and P4==0 then r[P2] := r[P1] IS TRUE -+** <li> If P3==1 and P4==1 then r[P2] := r[P1] IS FALSE -+** <li> If P3==0 and P4==1 then r[P2] := r[P1] IS NOT TRUE -+** <li> If P3==1 and P4==0 then r[P2] := r[P1] IS NOT FALSE -+** </ul> -+*/ -+case OP_IsTrue: { /* in1, out2 */ -+ assert( pOp->p4type==P4_INT32 ); -+ assert( pOp->p4.i==0 || pOp->p4.i==1 ); -+ assert( pOp->p3==0 || pOp->p3==1 ); -+ sqlite3VdbeMemSetInt64(&aMem[pOp->p2], -+ sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3) ^ pOp->p4.i); -+ break; -+} -+ - /* Opcode: Not P1 P2 * * * - ** Synopsis: r[P2]= !r[P1] - ** -@@ -81173,16 +85237,16 @@ - case OP_Not: { /* same as TK_NOT, in1, out2 */ - pIn1 = &aMem[pOp->p1]; - pOut = &aMem[pOp->p2]; -- sqlite3VdbeMemSetNull(pOut); - if( (pIn1->flags & MEM_Null)==0 ){ -- pOut->flags = MEM_Int; -- pOut->u.i = !sqlite3VdbeIntValue(pIn1); -+ sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeBooleanValue(pIn1,0)); -+ }else{ -+ sqlite3VdbeMemSetNull(pOut); - } - break; - } - - /* Opcode: BitNot P1 P2 * * * --** Synopsis: r[P1]= ~r[P1] -+** Synopsis: r[P2]= ~r[P1] - ** - ** Interpret the content of register P1 as an integer. Store the - ** ones-complement of the P1 value into register P2. If P1 holds -@@ -81243,6 +85307,14 @@ - ** is considered true if it is numeric and non-zero. If the value - ** in P1 is NULL then take the jump if and only if P3 is non-zero. - */ -+case OP_If: { /* jump, in1 */ -+ int c; -+ c = sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3); -+ VdbeBranchTaken(c!=0, 2); -+ if( c ) goto jump_to_p2; -+ break; -+} -+ - /* Opcode: IfNot P1 P2 P3 * * - ** - ** Jump to P2 if the value in register P1 is False. The value -@@ -81249,24 +85321,11 @@ - ** is considered false if it has a numeric value of zero. If the value - ** in P1 is NULL then take the jump if and only if P3 is non-zero. - */ --case OP_If: /* jump, in1 */ - case OP_IfNot: { /* jump, in1 */ - int c; -- pIn1 = &aMem[pOp->p1]; -- if( pIn1->flags & MEM_Null ){ -- c = pOp->p3; -- }else{ --#ifdef SQLITE_OMIT_FLOATING_POINT -- c = sqlite3VdbeIntValue(pIn1)!=0; --#else -- c = sqlite3VdbeRealValue(pIn1)!=0.0; --#endif -- if( pOp->opcode==OP_IfNot ) c = !c; -- } -+ c = !sqlite3VdbeBooleanValue(&aMem[pOp->p1], !pOp->p3); - VdbeBranchTaken(c!=0, 2); -- if( c ){ -- goto jump_to_p2; -- } -+ if( c ) goto jump_to_p2; - break; - } - -@@ -81316,6 +85375,36 @@ - break; - } - -+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC -+/* Opcode: Offset P1 P2 P3 * * -+** Synopsis: r[P3] = sqlite_offset(P1) -+** -+** Store in register r[P3] the byte offset into the database file that is the -+** start of the payload for the record at which that cursor P1 is currently -+** pointing. -+** -+** P2 is the column number for the argument to the sqlite_offset() function. -+** This opcode does not use P2 itself, but the P2 value is used by the -+** code generator. The P1, P2, and P3 operands to this opcode are the -+** same as for OP_Column. -+** -+** This opcode is only available if SQLite is compiled with the -+** -DSQLITE_ENABLE_OFFSET_SQL_FUNC option. -+*/ -+case OP_Offset: { /* out3 */ -+ VdbeCursor *pC; /* The VDBE cursor */ -+ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); -+ pC = p->apCsr[pOp->p1]; -+ pOut = &p->aMem[pOp->p3]; -+ if( NEVER(pC==0) || pC->eCurType!=CURTYPE_BTREE ){ -+ sqlite3VdbeMemSetNull(pOut); -+ }else{ -+ sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor)); -+ } -+ break; -+} -+#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */ -+ - /* Opcode: Column P1 P2 P3 P4 P5 - ** Synopsis: r[P3]=PX - ** -@@ -81353,9 +85442,7 @@ - const u8 *zData; /* Part of the record being decoded */ - const u8 *zHdr; /* Next unparsed byte of the header */ - const u8 *zEndHdr; /* Pointer to first byte after the header */ -- u32 offset; /* Offset into the data */ - u64 offset64; /* 64-bit offset */ -- u32 avail; /* Number of bytes of available data */ - u32 t; /* A type code from the record header */ - Mem *pReg; /* PseudoTable input register */ - -@@ -81382,11 +85469,13 @@ - if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/ - if( pC->nullRow ){ - if( pC->eCurType==CURTYPE_PSEUDO ){ -- assert( pC->uc.pseudoTableReg>0 ); -- pReg = &aMem[pC->uc.pseudoTableReg]; -+ /* For the special case of as pseudo-cursor, the seekResult field -+ ** identifies the register that holds the record */ -+ assert( pC->seekResult>0 ); -+ pReg = &aMem[pC->seekResult]; - assert( pReg->flags & MEM_Blob ); - assert( memIsValid(pReg) ); -- pC->payloadSize = pC->szRow = avail = pReg->n; -+ pC->payloadSize = pC->szRow = pReg->n; - pC->aRow = (u8*)pReg->z; - }else{ - sqlite3VdbeMemSetNull(pDest); -@@ -81398,23 +85487,19 @@ - assert( pCrsr ); - assert( sqlite3BtreeCursorIsValid(pCrsr) ); - pC->payloadSize = sqlite3BtreePayloadSize(pCrsr); -- pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &avail); -- assert( avail<=65536 ); /* Maximum page size is 64KiB */ -- if( pC->payloadSize <= (u32)avail ){ -- pC->szRow = pC->payloadSize; -- }else if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ -+ pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow); -+ assert( pC->szRow<=pC->payloadSize ); -+ assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */ -+ if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ - goto too_big; -- }else{ -- pC->szRow = avail; - } - } - pC->cacheStatus = p->cacheCtr; -- pC->iHdrOffset = getVarint32(pC->aRow, offset); -+ pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]); - pC->nHdrParsed = 0; -- aOffset[0] = offset; - - -- if( avail<offset ){ /*OPTIMIZATION-IF-FALSE*/ -+ if( pC->szRow<aOffset[0] ){ /*OPTIMIZATION-IF-FALSE*/ - /* pC->aRow does not have to hold the entire row, but it does at least - ** need to cover the header of the record. If pC->aRow does not contain - ** the complete header, then set it to zero, forcing the header to be -@@ -81431,17 +85516,26 @@ - ** 3-byte type for each of the maximum of 32768 columns plus three - ** extra bytes for the header length itself. 32768*3 + 3 = 98307. - */ -- if( offset > 98307 || offset > pC->payloadSize ){ -- rc = SQLITE_CORRUPT_BKPT; -- goto abort_due_to_error; -+ if( aOffset[0] > 98307 || aOffset[0] > pC->payloadSize ){ -+ goto op_column_corrupt; - } -- }else if( offset>0 ){ /*OPTIMIZATION-IF-TRUE*/ -- /* The following goto is an optimization. It can be omitted and -- ** everything will still work. But OP_Column is measurably faster -- ** by skipping the subsequent conditional, which is always true. -+ }else{ -+ /* This is an optimization. By skipping over the first few tests -+ ** (ex: pC->nHdrParsed<=p2) in the next section, we achieve a -+ ** measurable performance gain. -+ ** -+ ** This branch is taken even if aOffset[0]==0. Such a record is never -+ ** generated by SQLite, and could be considered corruption, but we -+ ** accept it for historical reasons. When aOffset[0]==0, the code this -+ ** branch jumps to reads past the end of the record, but never more -+ ** than a few bytes. Even if the record occurs at the end of the page -+ ** content area, the "page header" comes after the page content and so -+ ** this overread is harmless. Similar overreads can occur for a corrupt -+ ** database file. - */ - zData = pC->aRow; - assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */ -+ testcase( aOffset[0]==0 ); - goto op_column_read_header; - } - } -@@ -81470,6 +85564,7 @@ - offset64 = aOffset[i]; - zHdr = zData + pC->iHdrOffset; - zEndHdr = zData + aOffset[0]; -+ testcase( zHdr>=zEndHdr ); - do{ - if( (t = zHdr[0])<0x80 ){ - zHdr++; -@@ -81490,9 +85585,13 @@ - if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize)) - || (offset64 > pC->payloadSize) - ){ -- if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); -- rc = SQLITE_CORRUPT_BKPT; -- goto abort_due_to_error; -+ if( aOffset[0]==0 ){ -+ i = 0; -+ zHdr = zEndHdr; -+ }else{ -+ if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); -+ goto op_column_corrupt; -+ } - } - - pC->nHdrParsed = i; -@@ -81586,6 +85685,15 @@ - UPDATE_MAX_BLOBSIZE(pDest); - REGISTER_TRACE(pOp->p3, pDest); - break; -+ -+op_column_corrupt: -+ if( aOp[0].p3>0 ){ -+ pOp = &aOp[aOp[0].p3-1]; -+ break; -+ }else{ -+ rc = SQLITE_CORRUPT_BKPT; -+ goto abort_due_to_error; -+ } - } - - /* Opcode: Affinity P1 P2 * P4 * -@@ -81710,9 +85818,18 @@ - pRec = pLast; - do{ - assert( memIsValid(pRec) ); -- pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format, &len); -+ serial_type = sqlite3VdbeSerialType(pRec, file_format, &len); - if( pRec->flags & MEM_Zero ){ -- if( nData ){ -+ if( serial_type==0 ){ -+ /* Values with MEM_Null and MEM_Zero are created by xColumn virtual -+ ** table methods that never invoke sqlite3_result_xxxxx() while -+ ** computing an unchanging column value in an UPDATE statement. -+ ** Give such values a special internal-use-only serial-type of 10 -+ ** so that they can be passed through to xUpdate and have -+ ** a true sqlite3_value_nochange(). */ -+ assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB ); -+ serial_type = 10; -+ }else if( nData ){ - if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem; - }else{ - nZero += pRec->u.nZero; -@@ -81723,6 +85840,7 @@ - testcase( serial_type==127 ); - testcase( serial_type==128 ); - nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type); -+ pRec->uTemp = serial_type; - if( pRec==pData0 ) break; - pRec--; - }while(1); -@@ -81743,9 +85861,6 @@ - if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++; - } - nByte = nHdr+nData; -- if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){ -- goto too_big; -- } - - /* Make sure the output register has a buffer large enough to store - ** the new record. The output register (pOp->p3) is not allowed to -@@ -81752,8 +85867,19 @@ - ** be one of the input registers (because the following call to - ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used). - */ -- if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){ -- goto no_mem; -+ if( nByte+nZero<=pOut->szMalloc ){ -+ /* The output register is already large enough to hold the record. -+ ** No error checks or buffer enlargement is required */ -+ pOut->z = pOut->zMalloc; -+ }else{ -+ /* Need to make sure that the output is not too big and then enlarge -+ ** the output register to hold the full result */ -+ if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){ -+ goto too_big; -+ } -+ if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){ -+ goto no_mem; -+ } - } - zNewRecord = (u8 *)pOut->z; - -@@ -81926,7 +86052,7 @@ - int isSchemaChange; - iSavepoint = db->nSavepoint - iSavepoint - 1; - if( p1==SAVEPOINT_ROLLBACK ){ -- isSchemaChange = (db->flags & SQLITE_InternChanges)!=0; -+ isSchemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0; - for(ii=0; ii<db->nDb; ii++){ - rc = sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, - SQLITE_ABORT_ROLLBACK, -@@ -81943,9 +86069,9 @@ - } - } - if( isSchemaChange ){ -- sqlite3ExpirePreparedStatements(db); -+ sqlite3ExpirePreparedStatements(db, 0); - sqlite3ResetAllSchemasOfConnection(db); -- db->flags = (db->flags | SQLITE_InternChanges); -+ db->mDbFlags |= DBFLAG_SchemaChange; - } - } - -@@ -82085,8 +86211,7 @@ - */ - case OP_Transaction: { - Btree *pBt; -- int iMeta; -- int iGen; -+ int iMeta = 0; - - assert( p->bIsReader ); - assert( p->readOnly==0 || pOp->p2==0 ); -@@ -82099,7 +86224,7 @@ - pBt = db->aDb[pOp->p1].pBt; - - if( pBt ){ -- rc = sqlite3BtreeBeginTrans(pBt, pOp->p2); -+ rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta); - testcase( rc==SQLITE_BUSY_SNAPSHOT ); - testcase( rc==SQLITE_BUSY_RECOVERY ); - if( rc!=SQLITE_OK ){ -@@ -82132,19 +86257,17 @@ - p->nStmtDefCons = db->nDeferredCons; - p->nStmtDefImmCons = db->nDeferredImmCons; - } -- -- /* Gather the schema version number for checking: -+ } -+ assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); -+ if( pOp->p5 -+ && (iMeta!=pOp->p3 -+ || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i) -+ ){ -+ /* - ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema - ** version is checked to ensure that the schema has not changed since the - ** SQL statement was prepared. - */ -- sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta); -- iGen = db->aDb[pOp->p1].pSchema->iGeneration; -- }else{ -- iGen = iMeta = 0; -- } -- assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); -- if( pOp->p5 && (iMeta!=pOp->p3 || iGen!=pOp->p4.i) ){ - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); - /* If the schema-cookie from the database file matches the cookie -@@ -82213,6 +86336,8 @@ - */ - case OP_SetCookie: { - Db *pDb; -+ -+ sqlite3VdbeIncrWriteCounter(p, 0); - assert( pOp->p2<SQLITE_N_BTREE_META ); - assert( pOp->p1>=0 && pOp->p1<db->nDb ); - assert( DbMaskTest(p->btreeMask, pOp->p1) ); -@@ -82225,7 +86350,7 @@ - if( pOp->p2==BTREE_SCHEMA_VERSION ){ - /* When the schema cookie changes, record the new cookie internally */ - pDb->pSchema->schema_cookie = pOp->p3; -- db->flags |= SQLITE_InternChanges; -+ db->mDbFlags |= DBFLAG_SchemaChange; - }else if( pOp->p2==BTREE_FILE_FORMAT ){ - /* Record changes in the file format */ - pDb->pSchema->file_format = pOp->p3; -@@ -82233,7 +86358,7 @@ - if( pOp->p1==1 ){ - /* Invalidate all prepared statements whenever the TEMP database - ** schema is changed. Ticket #1644 */ -- sqlite3ExpirePreparedStatements(db); -+ sqlite3ExpirePreparedStatements(db, 0); - p->expired = 0; - } - if( rc ) goto abort_due_to_error; -@@ -82251,23 +86376,20 @@ - ** values need not be contiguous but all P1 values should be small integers. - ** It is an error for P1 to be negative. - ** --** If P5!=0 then use the content of register P2 as the root page, not --** the value of P2 itself. -+** Allowed P5 bits: -+** <ul> -+** <li> <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for -+** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT -+** of OP_SeekLE/OP_IdxGT) -+** </ul> - ** --** There will be a read lock on the database whenever there is an --** open cursor. If the database was unlocked prior to this instruction --** then a read lock is acquired as part of this instruction. A read --** lock allows other processes to read the database but prohibits --** any other process from modifying the database. The read lock is --** released when all cursors are closed. If this instruction attempts --** to get a read lock but fails, the script terminates with an --** SQLITE_BUSY error code. --** - ** The P4 value may be either an integer (P4_INT32) or a pointer to - ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo --** structure, then said structure defines the content and collating --** sequence of the index being opened. Otherwise, if P4 is an integer --** value, it is set to the number of columns in the table. -+** object, then table being opened must be an [index b-tree] where the -+** KeyInfo object defines the content and collating -+** sequence of that index b-tree. Otherwise, if P4 is an integer -+** value, then the table being opened must be a [table b-tree] with a -+** number of columns no less than the value of P4. - ** - ** See also: OpenWrite, ReopenIdx - */ -@@ -82274,36 +86396,58 @@ - /* Opcode: ReopenIdx P1 P2 P3 P4 P5 - ** Synopsis: root=P2 iDb=P3 - ** --** The ReopenIdx opcode works exactly like ReadOpen except that it first --** checks to see if the cursor on P1 is already open with a root page --** number of P2 and if it is this opcode becomes a no-op. In other words, -+** The ReopenIdx opcode works like OP_OpenRead except that it first -+** checks to see if the cursor on P1 is already open on the same -+** b-tree and if it is this opcode becomes a no-op. In other words, - ** if the cursor is already open, do not reopen it. - ** --** The ReopenIdx opcode may only be used with P5==0 and with P4 being --** a P4_KEYINFO object. Furthermore, the P3 value must be the same as --** every other ReopenIdx or OpenRead for the same cursor number. -+** The ReopenIdx opcode may only be used with P5==0 or P5==OPFLAG_SEEKEQ -+** and with P4 being a P4_KEYINFO object. Furthermore, the P3 value must -+** be the same as every other ReopenIdx or OpenRead for the same cursor -+** number. - ** --** See the OpenRead opcode documentation for additional information. -+** Allowed P5 bits: -+** <ul> -+** <li> <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for -+** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT -+** of OP_SeekLE/OP_IdxGT) -+** </ul> -+** -+** See also: OP_OpenRead, OP_OpenWrite - */ - /* Opcode: OpenWrite P1 P2 P3 P4 P5 - ** Synopsis: root=P2 iDb=P3 - ** - ** Open a read/write cursor named P1 on the table or index whose root --** page is P2. Or if P5!=0 use the content of register P2 to find the --** root page. -+** page is P2 (or whose root page is held in register P2 if the -+** OPFLAG_P2ISREG bit is set in P5 - see below). - ** - ** The P4 value may be either an integer (P4_INT32) or a pointer to - ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo --** structure, then said structure defines the content and collating --** sequence of the index being opened. Otherwise, if P4 is an integer --** value, it is set to the number of columns in the table, or to the --** largest index of any column of the table that is actually used. -+** object, then table being opened must be an [index b-tree] where the -+** KeyInfo object defines the content and collating -+** sequence of that index b-tree. Otherwise, if P4 is an integer -+** value, then the table being opened must be a [table b-tree] with a -+** number of columns no less than the value of P4. - ** --** This instruction works just like OpenRead except that it opens the cursor --** in read/write mode. For a given table, there can be one or more read-only --** cursors or a single read/write cursor but not both. -+** Allowed P5 bits: -+** <ul> -+** <li> <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for -+** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT -+** of OP_SeekLE/OP_IdxGT) -+** <li> <b>0x08 OPFLAG_FORDELETE</b>: This cursor is used only to seek -+** and subsequently delete entries in an index btree. This is a -+** hint to the storage engine that the storage engine is allowed to -+** ignore. The hint is not used by the official SQLite b*tree storage -+** engine, but is used by COMDB2. -+** <li> <b>0x10 OPFLAG_P2ISREG</b>: Use the content of register P2 -+** as the root page, not the value of P2 itself. -+** </ul> - ** --** See also OpenRead. -+** This instruction works like OpenRead except that it opens the cursor -+** in read/write mode. -+** -+** See also: OP_OpenRead, OP_ReopenIdx - */ - case OP_ReopenIdx: { - int nField; -@@ -82332,7 +86476,7 @@ - assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx - || p->readOnly==0 ); - -- if( p->expired ){ -+ if( p->expired==1 ){ - rc = SQLITE_ABORT_ROLLBACK; - goto abort_due_to_error; - } -@@ -82359,12 +86503,13 @@ - if( pOp->p5 & OPFLAG_P2ISREG ){ - assert( p2>0 ); - assert( p2<=(p->nMem+1 - p->nCursor) ); -+ assert( pOp->opcode==OP_OpenWrite ); - pIn2 = &aMem[p2]; - assert( memIsValid(pIn2) ); - assert( (pIn2->flags & MEM_Int)!=0 ); - sqlite3VdbeMemIntegerify(pIn2); - p2 = (int)pIn2->u.i; -- /* The p2 value always comes from a prior OP_CreateTable opcode and -+ /* The p2 value always comes from a prior OP_CreateBtree opcode and - ** that opcode will always set the p2 value to 2 or more or else fail. - ** If there were a failure, the prepared statement would have halted - ** before reaching this instruction. */ -@@ -82374,7 +86519,7 @@ - pKeyInfo = pOp->p4.pKeyInfo; - assert( pKeyInfo->enc==ENC(db) ); - assert( pKeyInfo->db==db ); -- nField = pKeyInfo->nField+pKeyInfo->nXField; -+ nField = pKeyInfo->nAllField; - }else if( pOp->p4type==P4_INT32 ){ - nField = pOp->p4.i; - } -@@ -82487,7 +86632,7 @@ - rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, - BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); - if( rc==SQLITE_OK ){ -- rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1); -+ rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0); - } - if( rc==SQLITE_OK ){ - /* If a transient index is required, create it by calling -@@ -82585,8 +86730,13 @@ - pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, CURTYPE_PSEUDO); - if( pCx==0 ) goto no_mem; - pCx->nullRow = 1; -- pCx->uc.pseudoTableReg = pOp->p2; -+ pCx->seekResult = pOp->p2; - pCx->isTable = 1; -+ /* Give this pseudo-cursor a fake BtCursor pointer so that pCx -+ ** can be safely passed to sqlite3VdbeCursorMoveto(). This avoids a test -+ ** for pCx->eCurType==CURTYPE_BTREE inside of sqlite3VdbeCursorMoveto() -+ ** which is a performance optimization */ -+ pCx->uc.pCursor = sqlite3BtreeFakeValidCursor(); - assert( pOp->p5==0 ); - break; - } -@@ -82709,10 +86859,10 @@ - ** - ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt - */ --case OP_SeekLT: /* jump, in3 */ --case OP_SeekLE: /* jump, in3 */ --case OP_SeekGE: /* jump, in3 */ --case OP_SeekGT: { /* jump, in3 */ -+case OP_SeekLT: /* jump, in3, group */ -+case OP_SeekLE: /* jump, in3, group */ -+case OP_SeekGE: /* jump, in3, group */ -+case OP_SeekGT: { /* jump, in3, group */ - int res; /* Comparison result */ - int oc; /* Opcode */ - VdbeCursor *pC; /* The cursor to seek */ -@@ -82890,6 +87040,25 @@ - break; - } - -+/* Opcode: SeekHit P1 P2 * * * -+** Synopsis: seekHit=P2 -+** -+** Set the seekHit flag on cursor P1 to the value in P2. -+** 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. -+*/ -+case OP_SeekHit: { -+ VdbeCursor *pC; -+ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); -+ pC = p->apCsr[pOp->p1]; -+ assert( pC!=0 ); -+ assert( pOp->p2==0 || pOp->p2==1 ); -+ pC->seekHit = pOp->p2 & 1; -+ break; -+} -+ - /* Opcode: Found P1 P2 P3 P4 * - ** Synopsis: key=r[P3@P4] - ** -@@ -82924,8 +87093,35 @@ - ** advanced in either direction. In other words, the Next and Prev - ** opcodes do not work after this operation. - ** --** See also: Found, NotExists, NoConflict -+** See also: Found, NotExists, NoConflict, IfNoHope - */ -+/* Opcode: IfNoHope P1 P2 P3 P4 * -+** Synopsis: key=r[P3@P4] -+** -+** Register P3 is the first of P4 registers that form an unpacked -+** record. -+** -+** Cursor P1 is on an index btree. If the seekHit flag is set on P1, then -+** this opcode is a no-op. But if the seekHit flag of P1 is clear, then -+** check to see if there is any entry in P1 that matches the -+** prefix identified by P3 and P4. If no entry matches the prefix, -+** jump to P2. Otherwise fall through. -+** -+** This opcode behaves like OP_NotFound if the seekHit -+** flag is clear and it behaves like OP_Noop if the seekHit flag is set. -+** -+** This opcode is used in IN clause processing for a multi-column key. -+** If an IN clause is attached to an element of the key other than the -+** left-most element, and if there are no matches on the most recent -+** seek over the whole key, then it might be that one of the key element -+** to the left is prohibiting a match, and hence there is "no hope" of -+** any match regardless of how many IN clause elements are checked. -+** In such a case, we abandon the IN clause search early, using this -+** opcode. The opcode name comes from the fact that the -+** jump is taken if there is "no hope" of achieving a match. -+** -+** See also: NotFound, SeekHit -+*/ - /* Opcode: NoConflict P1 P2 P3 P4 * - ** Synopsis: key=r[P3@P4] - ** -@@ -82949,6 +87145,14 @@ - ** - ** See also: NotFound, Found, NotExists - */ -+case OP_IfNoHope: { /* jump, in3 */ -+ VdbeCursor *pC; -+ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); -+ pC = p->apCsr[pOp->p1]; -+ assert( pC!=0 ); -+ if( pC->seekHit ) break; -+ /* Fall through into OP_NotFound */ -+} - case OP_NoConflict: /* jump, in3 */ - case OP_NotFound: /* jump, in3 */ - case OP_Found: { /* jump, in3 */ -@@ -83086,18 +87290,26 @@ - - pIn3 = &aMem[pOp->p3]; - if( (pIn3->flags & MEM_Int)==0 ){ -+ /* Make sure pIn3->u.i contains a valid integer representation of -+ ** the key value, but do not change the datatype of the register, as -+ ** other parts of the perpared statement might be depending on the -+ ** current datatype. */ -+ u16 origFlags = pIn3->flags; -+ int isNotInt; - applyAffinity(pIn3, SQLITE_AFF_NUMERIC, encoding); -- if( (pIn3->flags & MEM_Int)==0 ) goto jump_to_p2; -+ isNotInt = (pIn3->flags & MEM_Int)==0; -+ pIn3->flags = origFlags; -+ if( isNotInt ) goto jump_to_p2; - } - /* Fall through into OP_NotExists */ - case OP_NotExists: /* jump, in3 */ - pIn3 = &aMem[pOp->p3]; -- assert( pIn3->flags & MEM_Int ); -+ assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid ); - assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - #ifdef SQLITE_DEBUG -- pC->seekOp = 0; -+ pC->seekOp = OP_SeekRowid; - #endif - assert( pC->isTable ); - assert( pC->eCurType==CURTYPE_BTREE ); -@@ -83172,6 +87384,7 @@ - assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); -+ assert( pC->isTable ); - assert( pC->eCurType==CURTYPE_BTREE ); - assert( pC->uc.pCursor!=0 ); - { -@@ -83328,10 +87541,8 @@ - int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ - const char *zDb; /* database name - used by the update hook */ - Table *pTab; /* Table structure - used by update and pre-update hooks */ -- int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ - BtreePayload x; /* Payload to be inserted */ - -- op = 0; - pData = &aMem[pOp->p2]; - assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - assert( memIsValid(pData) ); -@@ -83342,6 +87553,7 @@ - assert( (pOp->p5 & OPFLAG_ISNOOP) || pC->isTable ); - assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC ); - REGISTER_TRACE(pOp->p2, pData); -+ sqlite3VdbeIncrWriteCounter(p, pC); - - if( pOp->opcode==OP_Insert ){ - pKey = &aMem[pOp->p3]; -@@ -83359,19 +87571,21 @@ - zDb = db->aDb[pC->iDb].zDbSName; - pTab = pOp->p4.pTab; - assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) ); -- op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); - }else{ -- pTab = 0; /* Not needed. Silence a compiler warning. */ -+ pTab = 0; - zDb = 0; /* Not needed. Silence a compiler warning. */ - } - - #ifdef SQLITE_ENABLE_PREUPDATE_HOOK - /* Invoke the pre-update hook, if any */ -- if( db->xPreUpdateCallback -- && pOp->p4type==P4_TABLE -- && !(pOp->p5 & OPFLAG_ISUPDATE) -- ){ -- sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey, pOp->p2); -+ if( pTab ){ -+ if( db->xPreUpdateCallback && !(pOp->p5 & OPFLAG_ISUPDATE) ){ -+ sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey,pOp->p2); -+ } -+ if( db->xUpdateCallback==0 || pTab->aCol==0 ){ -+ /* Prevent post-update hook from running in cases when it should not */ -+ pTab = 0; -+ } - } - if( pOp->p5 & OPFLAG_ISNOOP ) break; - #endif -@@ -83378,14 +87592,9 @@ - - if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; - if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey; -- if( pData->flags & MEM_Null ){ -- x.pData = 0; -- x.nData = 0; -- }else{ -- assert( pData->flags & (MEM_Blob|MEM_Str) ); -- x.pData = pData->z; -- x.nData = pData->n; -- } -+ assert( pData->flags & (MEM_Blob|MEM_Str) ); -+ x.pData = pData->z; -+ x.nData = pData->n; - seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0); - if( pData->flags & MEM_Zero ){ - x.nZero = pData->u.nZero; -@@ -83401,8 +87610,12 @@ - - /* Invoke the update-hook if required. */ - if( rc ) goto abort_due_to_error; -- if( db->xUpdateCallback && op ){ -- db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, x.nKey); -+ if( pTab ){ -+ assert( db->xUpdateCallback!=0 ); -+ assert( pTab->aCol!=0 ); -+ db->xUpdateCallback(db->pUpdateArg, -+ (pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT, -+ zDb, pTab->zName, x.nKey); - } - break; - } -@@ -83455,6 +87668,7 @@ - assert( pC->eCurType==CURTYPE_BTREE ); - assert( pC->uc.pCursor!=0 ); - assert( pC->deferredMoveto==0 ); -+ sqlite3VdbeIncrWriteCounter(p, pC); - - #ifdef SQLITE_DEBUG - if( pOp->p4type==P4_TABLE && HasRowid(pOp->p4.pTab) && pOp->p5==0 ){ -@@ -83623,10 +87837,10 @@ - ** If the P1 cursor must be pointing to a valid row (not a NULL row) - ** of a real table, not a pseudo-table. - ** --** If P3!=0 then this opcode is allowed to make an ephermeral pointer -+** If P3!=0 then this opcode is allowed to make an ephemeral pointer - ** into the database page. That means that the content of the output - ** register will be invalidated as soon as the cursor moves - including --** moves caused by other cursors that "save" the the current cursors -+** moves caused by other cursors that "save" the current cursors - ** position in order that they can write to the same table. If P3==0 - ** then a copy of the data is made into memory. P3!=0 is faster, but - ** P3==0 is safer. -@@ -83749,11 +87963,24 @@ - assert( pC->uc.pCursor!=0 ); - sqlite3BtreeClearCursor(pC->uc.pCursor); - } -+#ifdef SQLITE_DEBUG -+ if( pC->seekOp==0 ) pC->seekOp = OP_NullRow; -+#endif - break; - } - --/* Opcode: Last P1 P2 P3 * * -+/* Opcode: SeekEnd P1 * * * * - ** -+** Position cursor P1 at the end of the btree for the purpose of -+** appending a new entry onto the btree. -+** -+** It is assumed that the cursor is used only for appending and so -+** if the cursor is valid, then the cursor must already be pointing -+** at the end of the btree and so no changes are made to -+** the cursor. -+*/ -+/* Opcode: Last P1 P2 * * * -+** - ** The next use of the Rowid or Column or Prev instruction for P1 - ** will refer to the last entry in the database table or index. - ** If the table or index is empty and P2>0, then jump immediately to P2. -@@ -83763,14 +87990,8 @@ - ** This opcode leaves the cursor configured to move in reverse order, - ** from the end toward the beginning. In other words, the cursor is - ** configured to use Prev, not Next. --** --** If P3 is -1, then the cursor is positioned at the end of the btree --** for the purpose of appending a new entry onto the btree. In that --** case P2 must be 0. It is assumed that the cursor is used only for --** appending and so if the cursor is valid, then the cursor must already --** be pointing at the end of the btree and so no changes are made to --** the cursor. - */ -+case OP_SeekEnd: - case OP_Last: { /* jump */ - VdbeCursor *pC; - BtCursor *pCrsr; -@@ -83783,23 +88004,25 @@ - pCrsr = pC->uc.pCursor; - res = 0; - assert( pCrsr!=0 ); -- pC->seekResult = pOp->p3; - #ifdef SQLITE_DEBUG -- pC->seekOp = OP_Last; -+ pC->seekOp = pOp->opcode; - #endif -- if( pOp->p3==0 || !sqlite3BtreeCursorIsValidNN(pCrsr) ){ -- rc = sqlite3BtreeLast(pCrsr, &res); -- pC->nullRow = (u8)res; -- pC->deferredMoveto = 0; -- pC->cacheStatus = CACHE_STALE; -- if( rc ) goto abort_due_to_error; -- if( pOp->p2>0 ){ -- VdbeBranchTaken(res!=0,2); -- if( res ) goto jump_to_p2; -+ if( pOp->opcode==OP_SeekEnd ){ -+ assert( pOp->p2==0 ); -+ pC->seekResult = -1; -+ if( sqlite3BtreeCursorIsValidNN(pCrsr) ){ -+ break; - } -- }else{ -- assert( pOp->p2==0 ); - } -+ rc = sqlite3BtreeLast(pCrsr, &res); -+ pC->nullRow = (u8)res; -+ pC->deferredMoveto = 0; -+ pC->cacheStatus = CACHE_STALE; -+ if( rc ) goto abort_due_to_error; -+ if( pOp->p2>0 ){ -+ VdbeBranchTaken(res!=0,2); -+ if( res ) goto jump_to_p2; -+ } - break; - } - -@@ -83861,7 +88084,7 @@ - p->aCounter[SQLITE_STMTSTATUS_SORT]++; - /* Fall through into OP_Rewind */ - } --/* Opcode: Rewind P1 P2 * * * -+/* Opcode: Rewind P1 P2 * * P5 - ** - ** The next use of the Rowid or Column or Next instruction for P1 - ** will refer to the first entry in the database table or index. -@@ -83869,6 +88092,10 @@ - ** If the table or index is not empty, fall through to the following - ** instruction. - ** -+** If P5 is non-zero and the table is not empty, then the "skip-next" -+** flag is set on the cursor so that the next OP_Next instruction -+** executed on it is a no-op. -+** - ** This opcode leaves the cursor configured to move in forward order, - ** from the beginning toward the end. In other words, the cursor is - ** configured to use Next, not Prev. -@@ -83893,6 +88120,9 @@ - pCrsr = pC->uc.pCursor; - assert( pCrsr ); - rc = sqlite3BtreeFirst(pCrsr, &res); -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( pOp->p5 ) sqlite3BtreeSkipNext(pCrsr); -+#endif - pC->deferredMoveto = 0; - pC->cacheStatus = CACHE_STALE; - } -@@ -83929,13 +88159,8 @@ - ** If P5 is positive and the jump is taken, then event counter - ** number P5-1 in the prepared statement is incremented. - ** --** See also: Prev, NextIfOpen -+** See also: Prev - */ --/* Opcode: NextIfOpen P1 P2 P3 P4 P5 --** --** This opcode works just like Next except that if cursor P1 is not --** open it behaves a no-op. --*/ - /* Opcode: Prev P1 P2 P3 P4 P5 - ** - ** Back up cursor P1 so that it points to the previous key/data pair in its -@@ -83962,11 +88187,6 @@ - ** If P5 is positive and the jump is taken, then event counter - ** number P5-1 in the prepared statement is incremented. - */ --/* Opcode: PrevIfOpen P1 P2 P3 P4 P5 --** --** This opcode works just like Prev except that if cursor P1 is not --** open it behaves a no-op. --*/ - /* Opcode: SorterNext P1 P2 * * P5 - ** - ** This opcode works just like OP_Next except that P1 must be a -@@ -83981,10 +88201,6 @@ - assert( isSorter(pC) ); - rc = sqlite3VdbeSorterNext(db, pC); - goto next_tail; --case OP_PrevIfOpen: /* jump */ --case OP_NextIfOpen: /* jump */ -- if( p->apCsr[pOp->p1]==0 ) break; -- /* Fall through */ - case OP_Prev: /* jump */ - case OP_Next: /* jump */ - assert( pOp->p1>=0 && pOp->p1<p->nCursor ); -@@ -83995,17 +88211,17 @@ - assert( pC->eCurType==CURTYPE_BTREE ); - assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); - assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); -- assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext ); -- assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious); - -- /* The Next opcode is only used after SeekGT, SeekGE, and Rewind. -+ /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found. - ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ -- assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen -+ assert( pOp->opcode!=OP_Next - || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE -- || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found); -- assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen -+ || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found -+ || pC->seekOp==OP_NullRow); -+ assert( pOp->opcode!=OP_Prev - || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE -- || pC->seekOp==OP_Last ); -+ || pC->seekOp==OP_Last -+ || pC->seekOp==OP_NullRow); - - rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3); - next_tail: -@@ -84067,6 +88283,7 @@ - - assert( pOp->p1>=0 && pOp->p1<p->nCursor ); - pC = p->apCsr[pOp->p1]; -+ sqlite3VdbeIncrWriteCounter(p, pC); - assert( pC!=0 ); - assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) ); - pIn2 = &aMem[pOp->p2]; -@@ -84113,6 +88330,7 @@ - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( pC->eCurType==CURTYPE_BTREE ); -+ sqlite3VdbeIncrWriteCounter(p, pC); - pCrsr = pC->uc.pCursor; - assert( pCrsr!=0 ); - assert( pOp->p5==0 ); -@@ -84286,7 +88504,13 @@ - } - r.aMem = &aMem[pOp->p3]; - #ifdef SQLITE_DEBUG -- { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); } -+ { -+ int i; -+ for(i=0; i<r.nField; i++){ -+ assert( memIsValid(&r.aMem[i]) ); -+ REGISTER_TRACE(pOp->p3+i, &aMem[pOp->p3+i]); -+ } -+ } - #endif - res = 0; /* Not needed. Only used to silence a warning. */ - rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res); -@@ -84335,6 +88559,7 @@ - int iMoved; - int iDb; - -+ sqlite3VdbeIncrWriteCounter(p, 0); - assert( p->readOnly==0 ); - assert( pOp->p1>1 ); - pOut = out2Prerelease(p, pOp); -@@ -84384,6 +88609,7 @@ - case OP_Clear: { - int nChange; - -+ sqlite3VdbeIncrWriteCounter(p, 0); - nChange = 0; - assert( p->readOnly==0 ); - assert( DbMaskTest(p->btreeMask, pOp->p2) ); -@@ -84427,50 +88653,29 @@ - break; - } - --/* Opcode: CreateTable P1 P2 * * * --** Synopsis: r[P2]=root iDb=P1 -+/* Opcode: CreateBtree P1 P2 P3 * * -+** Synopsis: r[P2]=root iDb=P1 flags=P3 - ** --** Allocate a new table in the main database file if P1==0 or in the --** auxiliary database file if P1==1 or in an attached database if --** P1>1. Write the root page number of the new table into --** register P2 --** --** The difference between a table and an index is this: A table must --** have a 4-byte integer key and can have arbitrary data. An index --** has an arbitrary key but no data. --** --** See also: CreateIndex -+** Allocate a new b-tree in the main database file if P1==0 or in the -+** TEMP database file if P1==1 or in an attached database if -+** P1>1. The P3 argument must be 1 (BTREE_INTKEY) for a rowid table -+** it must be 2 (BTREE_BLOBKEY) for an index or WITHOUT ROWID table. -+** The root page number of the new b-tree is stored in register P2. - */ --/* Opcode: CreateIndex P1 P2 * * * --** Synopsis: r[P2]=root iDb=P1 --** --** Allocate a new index in the main database file if P1==0 or in the --** auxiliary database file if P1==1 or in an attached database if --** P1>1. Write the root page number of the new table into --** register P2. --** --** See documentation on OP_CreateTable for additional information. --*/ --case OP_CreateIndex: /* out2 */ --case OP_CreateTable: { /* out2 */ -+case OP_CreateBtree: { /* out2 */ - int pgno; -- int flags; - Db *pDb; - -+ sqlite3VdbeIncrWriteCounter(p, 0); - pOut = out2Prerelease(p, pOp); - pgno = 0; -+ assert( pOp->p3==BTREE_INTKEY || pOp->p3==BTREE_BLOBKEY ); - assert( pOp->p1>=0 && pOp->p1<db->nDb ); - assert( DbMaskTest(p->btreeMask, pOp->p1) ); - assert( p->readOnly==0 ); - pDb = &db->aDb[pOp->p1]; - assert( pDb->pBt!=0 ); -- if( pOp->opcode==OP_CreateTable ){ -- /* flags = BTREE_INTKEY; */ -- flags = BTREE_INTKEY; -- }else{ -- flags = BTREE_BLOBKEY; -- } -- rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags); -+ rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, pOp->p3); - if( rc ) goto abort_due_to_error; - pOut->u.i = pgno; - break; -@@ -84481,6 +88686,7 @@ - ** Run the SQL statement or statements specified in the P4 string. - */ - case OP_SqlExec: { -+ sqlite3VdbeIncrWriteCounter(p, 0); - db->nSqlExec++; - rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0); - db->nSqlExec--; -@@ -84491,7 +88697,8 @@ - /* Opcode: ParseSchema P1 * * P4 * - ** - ** Read and parse all entries from the SQLITE_MASTER table of database P1 --** that match the WHERE clause P4. -+** that match the WHERE clause P4. If P4 is a NULL pointer, then the -+** entire schema for P1 is reparsed. - ** - ** This opcode invokes the parser to create a new virtual machine, - ** then runs the new virtual machine. It is thus a re-entrant opcode. -@@ -84515,11 +88722,22 @@ - iDb = pOp->p1; - assert( iDb>=0 && iDb<db->nDb ); - assert( DbHasProperty(db, iDb, DB_SchemaLoaded) ); -- /* Used to be a conditional */ { -+ -+#ifndef SQLITE_OMIT_ALTERTABLE -+ if( pOp->p4.z==0 ){ -+ sqlite3SchemaClear(db->aDb[iDb].pSchema); -+ db->mDbFlags &= ~DBFLAG_SchemaKnownOk; -+ rc = sqlite3InitOne(db, iDb, &p->zErrMsg, INITFLAG_AlterTable); -+ db->mDbFlags |= DBFLAG_SchemaChange; -+ p->expired = 0; -+ }else -+#endif -+ { - zMaster = MASTER_NAME; - initData.db = db; -- initData.iDb = pOp->p1; -+ initData.iDb = iDb; - initData.pzErrMsg = &p->zErrMsg; -+ initData.mInitFlags = 0; - zSql = sqlite3MPrintf(db, - "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid", - db->aDb[iDb].zDbSName, zMaster, pOp->p4.z); -@@ -84570,6 +88788,7 @@ - ** schema consistent with what is on disk. - */ - case OP_DropTable: { -+ sqlite3VdbeIncrWriteCounter(p, 0); - sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z); - break; - } -@@ -84583,6 +88802,7 @@ - ** schema consistent with what is on disk. - */ - case OP_DropIndex: { -+ sqlite3VdbeIncrWriteCounter(p, 0); - sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z); - break; - } -@@ -84596,6 +88816,7 @@ - ** schema consistent with what is on disk. - */ - case OP_DropTrigger: { -+ sqlite3VdbeIncrWriteCounter(p, 0); - sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z); - break; - } -@@ -84632,7 +88853,7 @@ - nRoot = pOp->p2; - aRoot = pOp->p4.ai; - assert( nRoot>0 ); -- assert( aRoot[nRoot]==0 ); -+ assert( aRoot[0]==nRoot ); - assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); - pnErr = &aMem[pOp->p3]; - assert( (pnErr->flags & MEM_Int)!=0 ); -@@ -84640,7 +88861,7 @@ - pIn1 = &aMem[pOp->p1]; - assert( pOp->p5<db->nDb ); - assert( DbMaskTest(p->btreeMask, pOp->p5) ); -- z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, -+ z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, &aRoot[1], nRoot, - (int)pnErr->u.i+1, &nErr); - sqlite3VdbeMemSetNull(pIn1); - if( nErr==0 ){ -@@ -84669,11 +88890,11 @@ - pIn1 = &aMem[pOp->p1]; - pIn2 = &aMem[pOp->p2]; - assert( (pIn2->flags & MEM_Int)!=0 ); -- if( (pIn1->flags & MEM_RowSet)==0 ){ -- sqlite3VdbeMemSetRowSet(pIn1); -- if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; -+ if( (pIn1->flags & MEM_Blob)==0 ){ -+ if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem; - } -- sqlite3RowSetInsert(pIn1->u.pRowSet, pIn2->u.i); -+ assert( sqlite3VdbeMemIsRowSet(pIn1) ); -+ sqlite3RowSetInsert((RowSet*)pIn1->z, pIn2->u.i); - break; - } - -@@ -84689,8 +88910,9 @@ - i64 val; - - pIn1 = &aMem[pOp->p1]; -- if( (pIn1->flags & MEM_RowSet)==0 -- || sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0 -+ assert( (pIn1->flags & MEM_Blob)==0 || sqlite3VdbeMemIsRowSet(pIn1) ); -+ if( (pIn1->flags & MEM_Blob)==0 -+ || sqlite3RowSetNext((RowSet*)pIn1->z, &val)==0 - ){ - /* The boolean index is empty */ - sqlite3VdbeMemSetNull(pIn1); -@@ -84739,20 +88961,19 @@ - /* If there is anything other than a rowset object in memory cell P1, - ** delete it now and initialize P1 with an empty rowset - */ -- if( (pIn1->flags & MEM_RowSet)==0 ){ -- sqlite3VdbeMemSetRowSet(pIn1); -- if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; -+ if( (pIn1->flags & MEM_Blob)==0 ){ -+ if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem; - } -- -+ assert( sqlite3VdbeMemIsRowSet(pIn1) ); - assert( pOp->p4type==P4_INT32 ); - assert( iSet==-1 || iSet>=0 ); - if( iSet ){ -- exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i); -+ exists = sqlite3RowSetTest((RowSet*)pIn1->z, iSet, pIn3->u.i); - VdbeBranchTaken(exists!=0,2); - if( exists ) goto jump_to_p2; - } - if( iSet>=0 ){ -- sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); -+ sqlite3RowSetInsert((RowSet*)pIn1->z, pIn3->u.i); - } - break; - } -@@ -84816,7 +89037,7 @@ - ** of the current program, and the memory required at runtime to execute - ** the trigger program. If this trigger has been fired before, then pRt - ** is already allocated. Otherwise, it must be initialized. */ -- if( (pRt->flags&MEM_Frame)==0 ){ -+ if( (pRt->flags&MEM_Blob)==0 ){ - /* SubProgram.nMem is set to the number of memory cells used by the - ** program stored in SubProgram.aOp. As well as these, one memory - ** cell is required for each cursor used by the program. Set local -@@ -84834,8 +89055,10 @@ - goto no_mem; - } - sqlite3VdbeMemRelease(pRt); -- pRt->flags = MEM_Frame; -- pRt->u.pFrame = pFrame; -+ pRt->flags = MEM_Blob|MEM_Dyn; -+ pRt->z = (char*)pFrame; -+ pRt->n = nByte; -+ pRt->xDel = sqlite3VdbeFrameMemDel; - - pFrame->v = p; - pFrame->nChildMem = nMem; -@@ -84851,6 +89074,9 @@ - #ifdef SQLITE_ENABLE_STMT_SCANSTATUS - pFrame->anExec = p->anExec; - #endif -+#ifdef SQLITE_DEBUG -+ pFrame->iFrameMagic = SQLITE_FRAME_MAGIC; -+#endif - - pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; - for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){ -@@ -84858,7 +89084,8 @@ - pMem->db = db; - } - }else{ -- pFrame = pRt->u.pFrame; -+ pFrame = (VdbeFrame*)pRt->z; -+ assert( pRt->xDel==sqlite3VdbeFrameMemDel ); - assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem - || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) ); - assert( pProgram->nCsr==pFrame->nChildCsr ); -@@ -85087,24 +89314,35 @@ - } - - --/* Opcode: AggStep0 * P2 P3 P4 P5 -+/* Opcode: AggStep * P2 P3 P4 P5 - ** Synopsis: accum=r[P3] step(r[P2@P5]) - ** --** Execute the step function for an aggregate. The --** function has P5 arguments. P4 is a pointer to the FuncDef --** structure that specifies the function. Register P3 is the -+** Execute the xStep function for an aggregate. -+** The function has P5 arguments. P4 is a pointer to the -+** FuncDef structure that specifies the function. Register P3 is the - ** accumulator. - ** - ** The P5 arguments are taken from register P2 and its - ** successors. - */ --/* Opcode: AggStep * P2 P3 P4 P5 -+/* Opcode: AggInverse * P2 P3 P4 P5 -+** Synopsis: accum=r[P3] inverse(r[P2@P5]) -+** -+** Execute the xInverse function for an aggregate. -+** The function has P5 arguments. P4 is a pointer to the -+** FuncDef structure that specifies the function. Register P3 is the -+** accumulator. -+** -+** The P5 arguments are taken from register P2 and its -+** successors. -+*/ -+/* Opcode: AggStep1 P1 P2 P3 P4 P5 - ** Synopsis: accum=r[P3] step(r[P2@P5]) - ** --** Execute the step function for an aggregate. The --** function has P5 arguments. P4 is a pointer to an sqlite3_context --** object that is used to run the function. Register P3 is --** as the accumulator. -+** Execute the xStep (if P1==0) or xInverse (if P1!=0) function for an -+** aggregate. The function has P5 arguments. P4 is a pointer to the -+** FuncDef structure that specifies the function. Register P3 is the -+** accumulator. - ** - ** The P5 arguments are taken from register P2 and its - ** successors. -@@ -85115,7 +89353,8 @@ - ** sqlite3_context only happens once, instead of on each call to the - ** step function. - */ --case OP_AggStep0: { -+case OP_AggInverse: -+case OP_AggStep: { - int n; - sqlite3_context *pCtx; - -@@ -85124,28 +89363,47 @@ - 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->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); -- pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); -+ pCtx = sqlite3DbMallocRawNN(db, n*sizeof(sqlite3_value*) + -+ (sizeof(pCtx[0]) + sizeof(Mem) - sizeof(sqlite3_value*))); - if( pCtx==0 ) goto no_mem; - pCtx->pMem = 0; -+ pCtx->pOut = (Mem*)&(pCtx->argv[n]); -+ sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null); - pCtx->pFunc = pOp->p4.pFunc; - pCtx->iOp = (int)(pOp - aOp); - pCtx->pVdbe = p; -+ pCtx->skipFlag = 0; -+ pCtx->isError = 0; - pCtx->argc = n; - pOp->p4type = P4_FUNCCTX; - pOp->p4.pCtx = pCtx; -- pOp->opcode = OP_AggStep; -+ -+ /* OP_AggInverse must have P1==1 and OP_AggStep must have P1==0 */ -+ assert( pOp->p1==(pOp->opcode==OP_AggInverse) ); -+ -+ pOp->opcode = OP_AggStep1; - /* Fall through into OP_AggStep */ - } --case OP_AggStep: { -+case OP_AggStep1: { - int i; - sqlite3_context *pCtx; - Mem *pMem; -- Mem t; - - assert( pOp->p4type==P4_FUNCCTX ); - pCtx = pOp->p4.pCtx; - pMem = &aMem[pOp->p3]; - -+#ifdef SQLITE_DEBUG -+ if( pOp->p1 ){ -+ /* This is an OP_AggInverse call. Verify that xStep has always -+ ** been called at least once prior to any xInverse call. */ -+ assert( pMem->uTemp==0x1122e0e3 ); -+ }else{ -+ /* This is an OP_AggStep call. Mark it as such. */ -+ pMem->uTemp = 0x1122e0e3; -+ } -+#endif -+ - /* If this function is inside of a trigger, the register array in aMem[] - ** might change from one evaluation to the next. The next block of code - ** checks to see if the register array has changed, and if so it -@@ -85163,26 +89421,34 @@ - #endif - - pMem->n++; -- sqlite3VdbeMemInit(&t, db, MEM_Null); -- pCtx->pOut = &t; -- pCtx->fErrorOrAux = 0; -- pCtx->skipFlag = 0; -+ assert( pCtx->pOut->flags==MEM_Null ); -+ assert( pCtx->isError==0 ); -+ assert( pCtx->skipFlag==0 ); -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( pOp->p1 ){ -+ (pCtx->pFunc->xInverse)(pCtx,pCtx->argc,pCtx->argv); -+ }else -+#endif - (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */ -- if( pCtx->fErrorOrAux ){ -- if( pCtx->isError ){ -- sqlite3VdbeError(p, "%s", sqlite3_value_text(&t)); -+ -+ if( pCtx->isError ){ -+ if( pCtx->isError>0 ){ -+ sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut)); - rc = pCtx->isError; - } -- sqlite3VdbeMemRelease(&t); -+ if( pCtx->skipFlag ){ -+ assert( pOp[-1].opcode==OP_CollSeq ); -+ i = pOp[-1].p1; -+ if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1); -+ pCtx->skipFlag = 0; -+ } -+ sqlite3VdbeMemRelease(pCtx->pOut); -+ pCtx->pOut->flags = MEM_Null; -+ pCtx->isError = 0; - if( rc ) goto abort_due_to_error; -- }else{ -- assert( t.flags==MEM_Null ); - } -- if( pCtx->skipFlag ){ -- assert( pOp[-1].opcode==OP_CollSeq ); -- i = pOp[-1].p1; -- if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1); -- } -+ assert( pCtx->pOut->flags==MEM_Null ); -+ assert( pCtx->skipFlag==0 ); - break; - } - -@@ -85189,22 +89455,46 @@ - /* Opcode: AggFinal P1 P2 * P4 * - ** Synopsis: accum=r[P1] N=P2 - ** --** Execute the finalizer function for an aggregate. P1 is --** the memory location that is the accumulator for the aggregate. -+** P1 is the memory location that is the accumulator for an aggregate -+** or window function. Execute the finalizer function -+** for an aggregate and store the result in P1. - ** - ** P2 is the number of arguments that the step function takes and - ** P4 is a pointer to the FuncDef for this function. The P2 - ** argument is not used by this opcode. It is only there to disambiguate - ** functions that can take varying numbers of arguments. The --** P4 argument is only needed for the degenerate case where -+** P4 argument is only needed for the case where - ** the step function was not previously called. - */ -+/* Opcode: AggValue * P2 P3 P4 * -+** Synopsis: r[P3]=value N=P2 -+** -+** Invoke the xValue() function and store the result in register P3. -+** -+** P2 is the number of arguments that the step function takes and -+** P4 is a pointer to the FuncDef for this function. The P2 -+** argument is not used by this opcode. It is only there to disambiguate -+** functions that can take varying numbers of arguments. The -+** P4 argument is only needed for the case where -+** the step function was not previously called. -+*/ -+case OP_AggValue: - case OP_AggFinal: { - Mem *pMem; - assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); -+ assert( pOp->p3==0 || pOp->opcode==OP_AggValue ); - pMem = &aMem[pOp->p1]; - assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); -- rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( pOp->p3 ){ -+ rc = sqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc); -+ pMem = &aMem[pOp->p3]; -+ }else -+#endif -+ { -+ rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); -+ } -+ - if( rc ){ - sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem)); - goto abort_due_to_error; -@@ -85399,7 +89689,7 @@ - } - #endif - --/* Opcode: Expire P1 * * * * -+/* Opcode: Expire P1 P2 * * * - ** - ** Cause precompiled statements to expire. When an expired statement - ** is executed using sqlite3_step() it will either automatically -@@ -85408,12 +89698,19 @@ - ** - ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, - ** then only the currently executing statement is expired. -+** -+** If P2 is 0, then SQL statements are expired immediately. If P2 is 1, -+** then running SQL statements are allowed to continue to run to completion. -+** The P2==1 case occurs when a CREATE INDEX or similar schema change happens -+** that might help the statement run faster but which does not affect the -+** correctness of operation. - */ - case OP_Expire: { -+ assert( pOp->p2==0 || pOp->p2==1 ); - if( !pOp->p1 ){ -- sqlite3ExpirePreparedStatements(db); -+ sqlite3ExpirePreparedStatements(db, pOp->p2); - }else{ -- p->expired = 1; -+ p->expired = pOp->p2+1; - } - break; - } -@@ -85627,12 +89924,19 @@ - #endif /* SQLITE_OMIT_VIRTUALTABLE */ - - #ifndef SQLITE_OMIT_VIRTUALTABLE --/* Opcode: VColumn P1 P2 P3 * * -+/* Opcode: VColumn P1 P2 P3 * P5 - ** Synopsis: r[P3]=vcolumn(P2) - ** --** Store the value of the P2-th column of --** the row of the virtual-table that the --** P1 cursor is pointing to into register P3. -+** Store in register P3 the value of the P2-th column of -+** the current row of the virtual-table of cursor P1. -+** -+** If the VColumn opcode is being used to fetch the value of -+** an unchanging column during an UPDATE operation, then the P5 -+** value is OPFLAG_NOCHNG. This will cause the sqlite3_vtab_nochange() -+** function to return true inside the xColumn method of the virtual -+** table implementation. The P5 column might also contain other -+** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are -+** unused by OP_VColumn. - */ - case OP_VColumn: { - sqlite3_vtab *pVtab; -@@ -85654,10 +89958,18 @@ - assert( pModule->xColumn ); - memset(&sContext, 0, sizeof(sContext)); - sContext.pOut = pDest; -- MemSetTypeFlag(pDest, MEM_Null); -+ testcase( (pOp->p5 & OPFLAG_NOCHNG)==0 && pOp->p5!=0 ); -+ if( pOp->p5 & OPFLAG_NOCHNG ){ -+ sqlite3VdbeMemSetNull(pDest); -+ pDest->flags = MEM_Null|MEM_Zero; -+ pDest->u.nZero = 0; -+ }else{ -+ MemSetTypeFlag(pDest, MEM_Null); -+ } - rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2); - sqlite3VtabImportErrmsg(p, pVtab); -- if( sContext.isError ){ -+ if( sContext.isError>0 ){ -+ sqlite3VdbeError(p, "%s", sqlite3_value_text(pDest)); - rc = sContext.isError; - } - sqlite3VdbeChangeEncoding(pDest, encoding); -@@ -85724,7 +90036,10 @@ - case OP_VRename: { - sqlite3_vtab *pVtab; - Mem *pName; -- -+ int isLegacy; -+ -+ isLegacy = (db->flags & SQLITE_LegacyAlter); -+ db->flags |= SQLITE_LegacyAlter; - pVtab = pOp->p4.pVtab->pVtab; - pName = &aMem[pOp->p1]; - assert( pVtab->pModule->xRename ); -@@ -85738,6 +90053,7 @@ - rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8); - if( rc ) goto abort_due_to_error; - rc = pVtab->pModule->xRename(pVtab, pName->z); -+ if( isLegacy==0 ) db->flags &= ~SQLITE_LegacyAlter; - sqlite3VtabImportErrmsg(p, pVtab); - p->expired = 0; - if( rc ) goto abort_due_to_error; -@@ -85786,6 +90102,8 @@ - || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace - ); - assert( p->readOnly==0 ); -+ if( db->mallocFailed ) goto no_mem; -+ sqlite3VdbeIncrWriteCounter(p, 0); - pVtab = pOp->p4.pVtab->pVtab; - if( pVtab==0 || NEVER(pVtab->pModule==0) ){ - rc = SQLITE_LOCKED; -@@ -85906,8 +90224,8 @@ - ** - ** See also: Function0, AggStep, AggFinal - */ --case OP_PureFunc0: --case OP_Function0: { -+case OP_PureFunc0: /* group */ -+case OP_Function0: { /* group */ - int n; - sqlite3_context *pCtx; - -@@ -85922,6 +90240,7 @@ - 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; -@@ -85930,8 +90249,8 @@ - pOp->opcode += 2; - /* Fall through into OP_Function */ - } --case OP_PureFunc: --case OP_Function: { -+case OP_PureFunc: /* group */ -+case OP_Function: { /* group */ - int i; - sqlite3_context *pCtx; - -@@ -85956,16 +90275,17 @@ - } - #endif - MemSetTypeFlag(pOut, MEM_Null); -- pCtx->fErrorOrAux = 0; -+ assert( pCtx->isError==0 ); - (*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */ - - /* If the function returned an error, throw an exception */ -- if( pCtx->fErrorOrAux ){ -- if( pCtx->isError ){ -+ if( pCtx->isError ){ -+ if( pCtx->isError>0 ){ - sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut)); - rc = pCtx->isError; - } - sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1); -+ pCtx->isError = 0; - if( rc ) goto abort_due_to_error; - } - -@@ -85980,8 +90300,14 @@ - break; - } - -- --/* Opcode: Init P1 P2 * P4 * -+/* Opcode: Trace P1 P2 * P4 * -+** -+** Write P4 on the statement trace output if statement tracing is -+** enabled. -+** -+** Operand P1 must be 0x7fffffff and P2 must positive. -+*/ -+/* Opcode: Init P1 P2 P3 P4 * - ** Synopsis: Start at P2 - ** - ** Programs contain a single instance of this opcode as the very first -@@ -85995,10 +90321,16 @@ - ** - ** Increment the value of P1 so that OP_Once opcodes will jump the - ** first time they are evaluated for this run. -+** -+** If P3 is not zero, then it is an address to jump to if an SQLITE_CORRUPT -+** error is encountered. - */ -+case OP_Trace: - case OP_Init: { /* jump */ -+ int i; -+#ifndef SQLITE_OMIT_TRACE - char *zTrace; -- int i; -+#endif - - /* If the P4 argument is not NULL, then it must be an SQL comment string. - ** The "--" string is broken up to prevent false-positives with srcck1.c. -@@ -86010,8 +90342,10 @@ - ** sqlite3_expanded_sql(P) otherwise. - */ - assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 ); -- assert( pOp==p->aOp ); /* Always instruction 0 */ - -+ /* OP_Init is always instruction 0 */ -+ assert( pOp==p->aOp || pOp->opcode==OP_Trace ); -+ - #ifndef SQLITE_OMIT_TRACE - if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0 - && !p->doingRerun -@@ -86053,6 +90387,7 @@ - #endif /* SQLITE_OMIT_TRACE */ - assert( pOp->p2>0 ); - if( pOp->p1>=sqlite3GlobalConfig.iOnceResetThreshold ){ -+ if( pOp->opcode==OP_Trace ) break; - for(i=1; i<p->nOp; i++){ - if( p->aOp[i].opcode==OP_Once ) p->aOp[i].p1 = 0; - } -@@ -86086,6 +90421,22 @@ - } - #endif /* SQLITE_ENABLE_CURSOR_HINTS */ - -+#ifdef SQLITE_DEBUG -+/* Opcode: Abortable * * * * * -+** -+** Verify that an Abort can happen. Assert if an Abort at this point -+** might cause database corruption. This opcode only appears in debugging -+** builds. -+** -+** An Abort is safe if either there have been no writes, or if there is -+** an active statement journal. -+*/ -+case OP_Abortable: { -+ sqlite3VdbeAssertAbortable(p); -+ break; -+} -+#endif -+ - /* Opcode: Noop * * * * * - ** - ** Do nothing. This instruction is often useful as a jump -@@ -86097,8 +90448,9 @@ - ** This opcode records information from the optimizer. It is the - ** the same as a no-op. This opcodesnever appears in a real VM program. - */ --default: { /* This is really OP_Noop and OP_Explain */ -+default: { /* This is really OP_Noop, OP_Explain */ - assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain ); -+ - break; - } - -@@ -86112,7 +90464,7 @@ - - #ifdef VDBE_PROFILE - { -- u64 endTime = sqlite3Hwtime(); -+ u64 endTime = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); - if( endTime>start ) pOrigOp->cycles += endTime - start; - pOrigOp->cnt++; - } -@@ -86269,11 +90621,12 @@ - v->aMem[1].u.i = iRow; - - /* If the statement has been run before (and is paused at the OP_ResultRow) -- ** then back it up to the point where it does the OP_SeekRowid. This could -+ ** then back it up to the point where it does the OP_NotExists. This could - ** have been down with an extra OP_Goto, but simply setting the program - ** counter is faster. */ -- if( v->pc>3 ){ -- v->pc = 3; -+ if( v->pc>4 ){ -+ v->pc = 4; -+ assert( v->aOp[v->pc].opcode==OP_NotExists ); - rc = sqlite3VdbeExec(v); - }else{ - rc = sqlite3_step(p->pStmt); -@@ -86335,8 +90688,8 @@ - int rc = SQLITE_OK; - char *zErr = 0; - Table *pTab; -- Parse *pParse = 0; - Incrblob *pBlob = 0; -+ Parse sParse; - - #ifdef SQLITE_ENABLE_API_ARMOR - if( ppBlob==0 ){ -@@ -86354,37 +90707,34 @@ - sqlite3_mutex_enter(db->mutex); - - pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); -- if( !pBlob ) goto blob_open_out; -- pParse = sqlite3StackAllocRaw(db, sizeof(*pParse)); -- if( !pParse ) goto blob_open_out; -- - do { -- memset(pParse, 0, sizeof(Parse)); -- pParse->db = db; -+ memset(&sParse, 0, sizeof(Parse)); -+ if( !pBlob ) goto blob_open_out; -+ sParse.db = db; - sqlite3DbFree(db, zErr); - zErr = 0; - - sqlite3BtreeEnterAll(db); -- pTab = sqlite3LocateTable(pParse, 0, zTable, zDb); -+ pTab = sqlite3LocateTable(&sParse, 0, zTable, zDb); - if( pTab && IsVirtual(pTab) ){ - pTab = 0; -- sqlite3ErrorMsg(pParse, "cannot open virtual table: %s", zTable); -+ sqlite3ErrorMsg(&sParse, "cannot open virtual table: %s", zTable); - } - if( pTab && !HasRowid(pTab) ){ - pTab = 0; -- sqlite3ErrorMsg(pParse, "cannot open table without rowid: %s", zTable); -+ sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable); - } - #ifndef SQLITE_OMIT_VIEW - if( pTab && pTab->pSelect ){ - pTab = 0; -- sqlite3ErrorMsg(pParse, "cannot open view: %s", zTable); -+ sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable); - } - #endif - if( !pTab ){ -- if( pParse->zErrMsg ){ -+ if( sParse.zErrMsg ){ - sqlite3DbFree(db, zErr); -- zErr = pParse->zErrMsg; -- pParse->zErrMsg = 0; -+ zErr = sParse.zErrMsg; -+ sParse.zErrMsg = 0; - } - rc = SQLITE_ERROR; - sqlite3BtreeLeaveAll(db); -@@ -86448,7 +90798,7 @@ - } - } - -- pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(pParse); -+ pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(&sParse); - assert( pBlob->pStmt || db->mallocFailed ); - if( pBlob->pStmt ){ - -@@ -86484,7 +90834,8 @@ - sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, wrFlag, - pTab->pSchema->schema_cookie, - pTab->pSchema->iGeneration); -- sqlite3VdbeChangeP5(v, 1); -+ sqlite3VdbeChangeP5(v, 1); -+ assert( sqlite3VdbeCurrentAddr(v)==2 || db->mallocFailed ); - aOp = sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn); - - /* Make sure a mutex is held on the table to be accessed */ -@@ -86499,7 +90850,7 @@ - aOp[0].p1 = iDb; - aOp[0].p2 = pTab->tnum; - aOp[0].p3 = wrFlag; -- sqlite3VdbeChangeP4(v, 1, pTab->zName, P4_TRANSIENT); -+ sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT); - } - if( db->mallocFailed==0 ){ - #endif -@@ -86521,10 +90872,10 @@ - aOp[1].p4.i = pTab->nCol+1; - aOp[3].p2 = pTab->nCol; - -- pParse->nVar = 0; -- pParse->nMem = 1; -- pParse->nTab = 1; -- sqlite3VdbeMakeReady(v, pParse); -+ sParse.nVar = 0; -+ sParse.nMem = 1; -+ sParse.nTab = 1; -+ sqlite3VdbeMakeReady(v, &sParse); - } - } - -@@ -86546,8 +90897,7 @@ - } - sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); - sqlite3DbFree(db, zErr); -- sqlite3ParserReset(pParse); -- sqlite3StackFree(db, pParse); -+ sqlite3ParserReset(&sParse); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -@@ -87541,7 +91891,7 @@ - } - - if( res==0 ){ -- if( pTask->pSorter->pKeyInfo->nField>1 ){ -+ if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ - res = vdbeSorterCompareTail( - pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 - ); -@@ -87610,7 +91960,7 @@ - } - - if( res==0 ){ -- if( pTask->pSorter->pKeyInfo->nField>1 ){ -+ if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ - res = vdbeSorterCompareTail( - pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 - ); -@@ -87625,7 +91975,7 @@ - /* - ** Initialize the temporary index cursor just opened as a sorter cursor. - ** --** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nField) -+** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nKeyField) - ** to determine the number of fields that should be compared from the - ** records being sorted. However, if the value passed as argument nField - ** is non-zero and the sorter is able to guarantee a stable sort, nField -@@ -87678,7 +92028,7 @@ - - assert( pCsr->pKeyInfo && pCsr->pBtx==0 ); - assert( pCsr->eCurType==CURTYPE_SORTER ); -- szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*); -+ szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nKeyField-1)*sizeof(CollSeq*); - sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask); - - pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); -@@ -87690,8 +92040,7 @@ - memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo); - pKeyInfo->db = 0; - if( nField && nWorker==0 ){ -- pKeyInfo->nXField += (pKeyInfo->nField - nField); -- pKeyInfo->nField = nField; -+ pKeyInfo->nKeyField = nField; - } - pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); - pSorter->nTask = nWorker + 1; -@@ -87719,11 +92068,9 @@ - mxCache = MIN(mxCache, SQLITE_MAX_PMASZ); - pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache); - -- /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of -- ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary -- ** large heap allocations. -- */ -- if( sqlite3GlobalConfig.pScratch==0 ){ -+ /* Avoid large memory allocations if the application has requested -+ ** SQLITE_CONFIG_SMALL_MALLOC. */ -+ if( sqlite3GlobalConfig.bSmallMalloc==0 ){ - assert( pSorter->iMemory==0 ); - pSorter->nMemory = pgsz; - pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz); -@@ -87731,7 +92078,7 @@ - } - } - -- if( (pKeyInfo->nField+pKeyInfo->nXField)<13 -+ if( pKeyInfo->nAllField<13 - && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl) - ){ - pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT; -@@ -88046,7 +92393,7 @@ - if( pTask->pUnpacked==0 ){ - pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pTask->pSorter->pKeyInfo); - if( pTask->pUnpacked==0 ) return SQLITE_NOMEM_BKPT; -- pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField; -+ pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nKeyField; - pTask->pUnpacked->errCode = 0; - } - return SQLITE_OK; -@@ -88828,8 +93175,12 @@ - ){ - int rc = SQLITE_OK; /* Return code */ - int i; /* For looping over PmaReader objects */ -- int nTree = pMerger->nTree; -+ int nTree; /* Number of subtrees to merge */ - -+ /* Failure to allocate the merge would have been detected prior to -+ ** invoking this routine */ -+ assert( pMerger!=0 ); -+ - /* eMode is always INCRINIT_NORMAL in single-threaded mode */ - assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); - -@@ -88837,6 +93188,7 @@ - assert( pMerger->pTask==0 ); - pMerger->pTask = pTask; - -+ nTree = pMerger->nTree; - for(i=0; i<nTree; i++){ - if( SQLITE_MAX_WORKER_THREADS>0 && eMode==INCRINIT_ROOT ){ - /* PmaReaders should be normally initialized in order, as if they are -@@ -89570,7 +93922,8 @@ - int iChunkOffset; - FileChunk *pChunk; - --#ifdef SQLITE_ENABLE_ATOMIC_WRITE -+#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ -+ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) - if( (iAmt+iOfst)>p->endpoint.iOffset ){ - return SQLITE_IOERR_SHORT_READ; - } -@@ -89689,7 +94042,8 @@ - ** atomic-write optimization. In this case the first 28 bytes of the - ** journal file may be written as part of committing the transaction. */ - assert( iOfst==p->endpoint.iOffset || iOfst==0 ); --#ifdef SQLITE_ENABLE_ATOMIC_WRITE -+#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ -+ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) - if( iOfst==0 && p->pFirst ){ - assert( p->nChunkSize>iAmt ); - memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt); -@@ -89858,17 +94212,31 @@ - sqlite3JournalOpen(0, 0, pJfd, 0, -1); - } - --#ifdef SQLITE_ENABLE_ATOMIC_WRITE -+#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ -+ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) - /* - ** If the argument p points to a MemJournal structure that is not an - ** in-memory-only journal file (i.e. is one that was opened with a +ve --** nSpill parameter), and the underlying file has not yet been created, --** create it now. -+** nSpill parameter or as SQLITE_OPEN_MAIN_JOURNAL), and the underlying -+** file has not yet been created, create it now. - */ --SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *p){ -+SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *pJfd){ - int rc = SQLITE_OK; -- if( p->pMethods==&MemJournalMethods && ((MemJournal*)p)->nSpill>0 ){ -- rc = memjrnlCreateFile((MemJournal*)p); -+ MemJournal *p = (MemJournal*)pJfd; -+ if( p->pMethod==&MemJournalMethods && ( -+#ifdef SQLITE_ENABLE_ATOMIC_WRITE -+ p->nSpill>0 -+#else -+ /* While this appears to not be possible without ATOMIC_WRITE, the -+ ** paths are complex, so it seems prudent to leave the test in as -+ ** a NEVER(), in case our analysis is subtly flawed. */ -+ NEVER(p->nSpill>0) -+#endif -+#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE -+ || (p->flags & SQLITE_OPEN_MAIN_JOURNAL) -+#endif -+ )){ -+ rc = memjrnlCreateFile(p); - } - return rc; - } -@@ -89935,18 +94303,30 @@ - int rc; - testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); - testcase( ExprHasProperty(pExpr, EP_Reduced) ); -- rc = pWalker->xExprCallback(pWalker, pExpr); -- if( rc ) return rc & WRC_Abort; -- if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ -- if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; -- assert( pExpr->x.pList==0 || pExpr->pRight==0 ); -- if( pExpr->pRight ){ -- if( walkExpr(pWalker, pExpr->pRight) ) return WRC_Abort; -- }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ -- if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; -- }else if( pExpr->x.pList ){ -- if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; -+ while(1){ -+ rc = pWalker->xExprCallback(pWalker, pExpr); -+ if( rc ) return rc & WRC_Abort; -+ if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ -+ if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; -+ assert( pExpr->x.pList==0 || pExpr->pRight==0 ); -+ if( pExpr->pRight ){ -+ pExpr = pExpr->pRight; -+ continue; -+ }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ -+ if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; -+ }else if( pExpr->x.pList ){ -+ if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; -+ } -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( ExprHasProperty(pExpr, EP_WinFunc) ){ -+ Window *pWin = pExpr->y.pWin; -+ if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort; -+ if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort; -+ if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort; -+ } -+#endif - } -+ break; - } - return WRC_Continue; - } -@@ -89982,7 +94362,6 @@ - if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort; - if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort; - if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort; -- if( sqlite3WalkExpr(pWalker, p->pOffset) ) return WRC_Abort; - return WRC_Continue; - } - -@@ -89999,17 +94378,16 @@ - struct SrcList_item *pItem; - - pSrc = p->pSrc; -- if( ALWAYS(pSrc) ){ -- for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ -- if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){ -- return WRC_Abort; -- } -- if( pItem->fg.isTabFunc -- && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg) -- ){ -- return WRC_Abort; -- } -+ assert( pSrc!=0 ); -+ for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ -+ if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){ -+ return WRC_Abort; - } -+ if( pItem->fg.isTabFunc -+ && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg) -+ ){ -+ return WRC_Abort; -+ } - } - return WRC_Continue; - } -@@ -90130,29 +94508,31 @@ - assert( pOrig!=0 ); - db = pParse->db; - pDup = sqlite3ExprDup(db, pOrig, 0); -- if( pDup==0 ) return; -- if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery); -- if( pExpr->op==TK_COLLATE ){ -- pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); -- } -- ExprSetProperty(pDup, EP_Alias); -+ if( pDup!=0 ){ -+ if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery); -+ if( pExpr->op==TK_COLLATE ){ -+ pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); -+ } -+ ExprSetProperty(pDup, EP_Alias); - -- /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This -- ** prevents ExprDelete() from deleting the Expr structure itself, -- ** allowing it to be repopulated by the memcpy() on the following line. -- ** The pExpr->u.zToken might point into memory that will be freed by the -- ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to -- ** make a copy of the token before doing the sqlite3DbFree(). -- */ -- ExprSetProperty(pExpr, EP_Static); -- sqlite3ExprDelete(db, pExpr); -- memcpy(pExpr, pDup, sizeof(*pExpr)); -- if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){ -- assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 ); -- pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken); -- pExpr->flags |= EP_MemToken; -+ /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This -+ ** prevents ExprDelete() from deleting the Expr structure itself, -+ ** allowing it to be repopulated by the memcpy() on the following line. -+ ** The pExpr->u.zToken might point into memory that will be freed by the -+ ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to -+ ** make a copy of the token before doing the sqlite3DbFree(). -+ */ -+ ExprSetProperty(pExpr, EP_Static); -+ sqlite3ExprDelete(db, pExpr); -+ memcpy(pExpr, pDup, sizeof(*pExpr)); -+ if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){ -+ assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 ); -+ pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken); -+ pExpr->flags |= EP_MemToken; -+ } -+ sqlite3DbFree(db, pDup); - } -- sqlite3DbFree(db, pDup); -+ ExprSetProperty(pExpr, EP_Alias); - } - - -@@ -90212,7 +94592,7 @@ - ** (even if X is implied). - ** pExpr->iTable Set to the cursor number for the table obtained - ** from pSrcList. --** pExpr->pTab Points to the Table structure of X.Y (even if -+** pExpr->y.pTab Points to the Table structure of X.Y (even if - ** X and/or Y are implied.) - ** pExpr->iColumn Set to the column number within the table. - ** pExpr->op Set to TK_COLUMN. -@@ -90246,7 +94626,7 @@ - struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ - NameContext *pTopNC = pNC; /* First namecontext in the list */ - Schema *pSchema = 0; /* Schema of the expression */ -- int isTrigger = 0; /* True if resolved to a trigger column */ -+ int eNewExprOp = TK_COLUMN; /* New value for pExpr->op on success */ - Table *pTab = 0; /* Table hold the row */ - Column *pCol; /* A column of pTab */ - -@@ -90256,7 +94636,6 @@ - - /* Initialize the node to no-match */ - pExpr->iTable = -1; -- pExpr->pTab = 0; - ExprSetVVAProperty(pExpr, EP_NoReduce); - - /* Translate the schema name in zDb into a pointer to the corresponding -@@ -90317,6 +94696,9 @@ - if( sqlite3StrICmp(zTabName, zTab)!=0 ){ - continue; - } -+ if( IN_RENAME_OBJECT && pItem->zAlias ){ -+ sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab); -+ } - } - if( 0==(cntTab++) ){ - pMatch = pItem; -@@ -90341,32 +94723,45 @@ - } - if( pMatch ){ - pExpr->iTable = pMatch->iCursor; -- pExpr->pTab = pMatch->pTab; -+ pExpr->y.pTab = pMatch->pTab; - /* RIGHT JOIN not (yet) supported */ - assert( (pMatch->fg.jointype & JT_RIGHT)==0 ); - if( (pMatch->fg.jointype & JT_LEFT)!=0 ){ - ExprSetProperty(pExpr, EP_CanBeNull); - } -- pSchema = pExpr->pTab->pSchema; -+ pSchema = pExpr->y.pTab->pSchema; - } - } /* if( pSrcList ) */ - --#ifndef SQLITE_OMIT_TRIGGER -+#if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT) - /* If we have not already resolved the name, then maybe -- ** it is a new.* or old.* trigger argument reference -+ ** it is a new.* or old.* trigger argument reference. Or -+ ** maybe it is an excluded.* from an upsert. - */ -- if( zDb==0 && zTab!=0 && cntTab==0 && pParse->pTriggerTab!=0 ){ -- int op = pParse->eTriggerOp; -- assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); -- if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){ -- pExpr->iTable = 1; -- pTab = pParse->pTriggerTab; -- }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){ -- pExpr->iTable = 0; -- pTab = pParse->pTriggerTab; -- }else{ -- pTab = 0; -+ if( zDb==0 && zTab!=0 && cntTab==0 ){ -+ pTab = 0; -+#ifndef SQLITE_OMIT_TRIGGER -+ if( pParse->pTriggerTab!=0 ){ -+ int op = pParse->eTriggerOp; -+ assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); -+ if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){ -+ pExpr->iTable = 1; -+ pTab = pParse->pTriggerTab; -+ }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){ -+ pExpr->iTable = 0; -+ pTab = pParse->pTriggerTab; -+ } - } -+#endif /* SQLITE_OMIT_TRIGGER */ -+#ifndef SQLITE_OMIT_UPSERT -+ if( (pNC->ncFlags & NC_UUpsert)!=0 ){ -+ Upsert *pUpsert = pNC->uNC.pUpsert; -+ if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){ -+ pTab = pUpsert->pUpsertSrc->a[0].pTab; -+ pExpr->iTable = 2; -+ } -+ } -+#endif /* SQLITE_OMIT_UPSERT */ - - if( pTab ){ - int iCol; -@@ -90386,24 +94781,42 @@ - } - if( iCol<pTab->nCol ){ - cnt++; -- if( iCol<0 ){ -- pExpr->affinity = SQLITE_AFF_INTEGER; -- }else if( pExpr->iTable==0 ){ -- testcase( iCol==31 ); -- testcase( iCol==32 ); -- pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol)); -- }else{ -- testcase( iCol==31 ); -- testcase( iCol==32 ); -- pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol)); -+#ifndef SQLITE_OMIT_UPSERT -+ if( pExpr->iTable==2 ){ -+ testcase( iCol==(-1) ); -+ if( IN_RENAME_OBJECT ){ -+ pExpr->iColumn = iCol; -+ pExpr->y.pTab = pTab; -+ eNewExprOp = TK_COLUMN; -+ }else{ -+ pExpr->iTable = pNC->uNC.pUpsert->regData + iCol; -+ eNewExprOp = TK_REGISTER; -+ ExprSetProperty(pExpr, EP_Alias); -+ } -+ }else -+#endif /* SQLITE_OMIT_UPSERT */ -+ { -+#ifndef SQLITE_OMIT_TRIGGER -+ if( iCol<0 ){ -+ pExpr->affinity = SQLITE_AFF_INTEGER; -+ }else if( pExpr->iTable==0 ){ -+ testcase( iCol==31 ); -+ testcase( iCol==32 ); -+ pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol)); -+ }else{ -+ testcase( iCol==31 ); -+ testcase( iCol==32 ); -+ pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol)); -+ } -+ pExpr->y.pTab = pTab; -+ pExpr->iColumn = (i16)iCol; -+ eNewExprOp = TK_TRIGGER; -+#endif /* SQLITE_OMIT_TRIGGER */ - } -- pExpr->iColumn = (i16)iCol; -- pExpr->pTab = pTab; -- isTrigger = 1; - } - } - } --#endif /* !defined(SQLITE_OMIT_TRIGGER) */ -+#endif /* !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT) */ - - /* - ** Perhaps the name is a reference to the ROWID -@@ -90438,10 +94851,12 @@ - ** is supported for backwards compatibility only. Hence, we issue a warning - ** on sqlite3_log() whenever the capability is used. - */ -- if( (pEList = pNC->pEList)!=0 -+ if( (pNC->ncFlags & NC_UEList)!=0 -+ && cnt==0 - && zTab==0 -- && cnt==0 - ){ -+ pEList = pNC->uNC.pEList; -+ assert( pEList!=0 ); - for(j=0; j<pEList->nExpr; j++){ - char *zAs = pEList->a[j].zName; - if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ -@@ -90462,6 +94877,9 @@ - cnt = 1; - pMatch = 0; - assert( zTab==0 && zDb==0 ); -+ if( IN_RENAME_OBJECT ){ -+ sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr); -+ } - goto lookupname_end; - } - } -@@ -90486,10 +94904,16 @@ - ** Because no reference was made to outer contexts, the pNC->nRef - ** fields are not changed in any context. - */ -- if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){ -- pExpr->op = TK_STRING; -- pExpr->pTab = 0; -- return WRC_Prune; -+ if( cnt==0 && zTab==0 ){ -+ assert( pExpr->op==TK_ID ); -+ if( ExprHasProperty(pExpr,EP_DblQuoted) ){ -+ pExpr->op = TK_STRING; -+ pExpr->y.pTab = 0; -+ return WRC_Prune; -+ } -+ if( sqlite3ExprIdToTrueFalse(pExpr) ){ -+ return WRC_Prune; -+ } - } - - /* -@@ -90532,7 +94956,7 @@ - pExpr->pLeft = 0; - sqlite3ExprDelete(db, pExpr->pRight); - pExpr->pRight = 0; -- pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN); -+ pExpr->op = eNewExprOp; - ExprSetProperty(pExpr, EP_Leaf); - lookupname_end: - if( cnt==1 ){ -@@ -90562,9 +94986,9 @@ - Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); - if( p ){ - struct SrcList_item *pItem = &pSrc->a[iSrc]; -- p->pTab = pItem->pTab; -+ p->y.pTab = pItem->pTab; - p->iTable = pItem->iCursor; -- if( p->pTab->iPKey==iCol ){ -+ if( p->y.pTab->iPKey==iCol ){ - p->iColumn = -1; - }else{ - p->iColumn = (ynVar)iCol; -@@ -90651,9 +95075,10 @@ - SrcList *pSrcList = pNC->pSrcList; - struct SrcList_item *pItem; - assert( pSrcList && pSrcList->nSrc==1 ); -- pItem = pSrcList->a; -+ pItem = pSrcList->a; -+ assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 ); - pExpr->op = TK_COLUMN; -- pExpr->pTab = pItem->pTab; -+ pExpr->y.pTab = pItem->pTab; - pExpr->iTable = pItem->iCursor; - pExpr->iColumn = -1; - pExpr->affinity = SQLITE_AFF_INTEGER; -@@ -90682,18 +95107,23 @@ - zTable = 0; - zColumn = pExpr->u.zToken; - }else{ -+ Expr *pLeft = pExpr->pLeft; - notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr); - pRight = pExpr->pRight; - if( pRight->op==TK_ID ){ - zDb = 0; -- zTable = pExpr->pLeft->u.zToken; -- zColumn = pRight->u.zToken; - }else{ - assert( pRight->op==TK_DOT ); -- zDb = pExpr->pLeft->u.zToken; -- zTable = pRight->pLeft->u.zToken; -- zColumn = pRight->pRight->u.zToken; -+ zDb = pLeft->u.zToken; -+ pLeft = pRight->pLeft; -+ pRight = pRight->pRight; - } -+ zTable = pLeft->u.zToken; -+ zColumn = pRight->u.zToken; -+ if( IN_RENAME_OBJECT ){ -+ sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight); -+ sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft); -+ } - } - return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); - } -@@ -90774,41 +95204,105 @@ - notValid(pParse, pNC, "non-deterministic functions", - NC_IdxExpr|NC_PartIdx); - } -+ if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0 -+ && pParse->nested==0 -+ && sqlite3Config.bInternalFunctions==0 -+ ){ -+ /* Internal-use-only functions are disallowed unless the -+ ** SQL is being compiled using sqlite3NestedParse() */ -+ no_such_func = 1; -+ pDef = 0; -+ } - } -- if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){ -- sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); -- pNC->nErr++; -- is_agg = 0; -- }else if( no_such_func && pParse->db->init.busy==0 -+ -+ if( 0==IN_RENAME_OBJECT ){ -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ assert( is_agg==0 || (pDef->funcFlags & SQLITE_FUNC_MINMAX) -+ || (pDef->xValue==0 && pDef->xInverse==0) -+ || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize) -+ ); -+ if( pDef && pDef->xValue==0 && ExprHasProperty(pExpr, EP_WinFunc) ){ -+ sqlite3ErrorMsg(pParse, -+ "%.*s() may not be used as a window function", nId, zId -+ ); -+ pNC->nErr++; -+ }else if( -+ (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) -+ || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pExpr->y.pWin) -+ || (is_agg && pExpr->y.pWin && (pNC->ncFlags & NC_AllowWin)==0) -+ ){ -+ const char *zType; -+ if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->y.pWin ){ -+ zType = "window"; -+ }else{ -+ zType = "aggregate"; -+ } -+ sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId); -+ pNC->nErr++; -+ is_agg = 0; -+ } -+#else -+ if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){ -+ sqlite3ErrorMsg(pParse,"misuse of aggregate function %.*s()",nId,zId); -+ pNC->nErr++; -+ is_agg = 0; -+ } -+#endif -+ else if( no_such_func && pParse->db->init.busy==0 - #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION -- && pParse->explain==0 -+ && pParse->explain==0 - #endif -- ){ -- sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); -- pNC->nErr++; -- }else if( wrong_num_args ){ -- sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", -- nId, zId); -- pNC->nErr++; -+ ){ -+ sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); -+ pNC->nErr++; -+ }else if( wrong_num_args ){ -+ sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", -+ nId, zId); -+ pNC->nErr++; -+ } -+ if( is_agg ){ -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ pNC->ncFlags &= ~(pExpr->y.pWin ? NC_AllowWin : NC_AllowAgg); -+#else -+ pNC->ncFlags &= ~NC_AllowAgg; -+#endif -+ } - } -- if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg; - sqlite3WalkExprList(pWalker, pList); - if( is_agg ){ -- NameContext *pNC2 = pNC; -- pExpr->op = TK_AGG_FUNCTION; -- pExpr->op2 = 0; -- while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){ -- pExpr->op2++; -- pNC2 = pNC2->pNext; -- } -- assert( pDef!=0 ); -- if( pNC2 ){ -- assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); -- testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); -- pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX); -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( pExpr->y.pWin ){ -+ Select *pSel = pNC->pWinSelect; -+ sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition); -+ sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy); -+ sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter); -+ sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef); -+ if( 0==pSel->pWin -+ || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin) -+ ){ -+ pExpr->y.pWin->pNextWin = pSel->pWin; -+ pSel->pWin = pExpr->y.pWin; -+ } -+ pNC->ncFlags |= NC_AllowWin; -+ }else -+#endif /* SQLITE_OMIT_WINDOWFUNC */ -+ { -+ NameContext *pNC2 = pNC; -+ pExpr->op = TK_AGG_FUNCTION; -+ pExpr->op2 = 0; -+ while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){ -+ pExpr->op2++; -+ pNC2 = pNC2->pNext; -+ } -+ assert( pDef!=0 ); -+ if( pNC2 ){ -+ assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); -+ testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); -+ pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX); - -+ } -+ pNC->ncFlags |= NC_AllowAgg; - } -- pNC->ncFlags |= NC_AllowAgg; - } - /* FIX ME: Compute pExpr->affinity based on the expected return - ** type of the function -@@ -90837,6 +95331,23 @@ - notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr); - break; - } -+ case TK_IS: -+ case TK_ISNOT: { -+ Expr *pRight; -+ assert( !ExprHasProperty(pExpr, EP_Reduced) ); -+ /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE", -+ ** and "x IS NOT FALSE". */ -+ if( (pRight = pExpr->pRight)->op==TK_ID ){ -+ int rc = resolveExprStep(pWalker, pRight); -+ if( rc==WRC_Abort ) return WRC_Abort; -+ if( pRight->op==TK_TRUEFALSE ){ -+ pExpr->op2 = pExpr->op; -+ pExpr->op = TK_TRUTH; -+ return WRC_Continue; -+ } -+ } -+ /* Fall thru */ -+ } - case TK_BETWEEN: - case TK_EQ: - case TK_NE: -@@ -90843,9 +95354,7 @@ - case TK_LT: - case TK_LE: - case TK_GT: -- case TK_GE: -- case TK_IS: -- case TK_ISNOT: { -+ case TK_GE: { - int nLeft, nRight; - if( pParse->db->mallocFailed ) break; - assert( pExpr->pLeft!=0 ); -@@ -90948,8 +95457,8 @@ - memset(&nc, 0, sizeof(nc)); - nc.pParse = pParse; - nc.pSrcList = pSelect->pSrc; -- nc.pEList = pEList; -- nc.ncFlags = NC_AllowAgg; -+ nc.uNC.pEList = pEList; -+ nc.ncFlags = NC_AllowAgg|NC_UEList; - nc.nErr = 0; - db = pParse->db; - savedSuppErr = db->suppressErr; -@@ -91014,12 +95523,10 @@ - pOrderBy = pSelect->pOrderBy; - if( pOrderBy==0 ) return 0; - db = pParse->db; --#if SQLITE_MAX_COLUMN - if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ - sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause"); - return 1; - } --#endif - for(i=0; i<pOrderBy->nExpr; i++){ - pOrderBy->a[i].done = 0; - } -@@ -91111,12 +95618,10 @@ - struct ExprList_item *pItem; - - if( pOrderBy==0 || pParse->db->mallocFailed ) return 0; --#if SQLITE_MAX_COLUMN - if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ - sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType); - return 1; - } --#endif - pEList = pSelect->pEList; - assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */ - for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){ -@@ -91198,6 +95703,19 @@ - } - for(j=0; j<pSelect->pEList->nExpr; j++){ - if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( ExprHasProperty(pE, EP_WinFunc) ){ -+ /* Since this window function is being changed into a reference -+ ** to the same window function the result set, remove the instance -+ ** of this window function from the Select.pWin list. */ -+ Window **pp; -+ for(pp=&pSelect->pWin; *pp; pp=&(*pp)->pNextWin){ -+ if( *pp==pE->y.pWin ){ -+ *pp = (*pp)->pNextWin; -+ } -+ } -+ } -+#endif - pItem->u.x.iOrderByCol = j+1; - } - } -@@ -91254,8 +95772,8 @@ - */ - memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pParse; -- if( sqlite3ResolveExprNames(&sNC, p->pLimit) || -- sqlite3ResolveExprNames(&sNC, p->pOffset) ){ -+ sNC.pWinSelect = p; -+ if( sqlite3ResolveExprNames(&sNC, p->pLimit) ){ - return WRC_Abort; - } - -@@ -91303,12 +95821,13 @@ - /* Set up the local name-context to pass to sqlite3ResolveExprNames() to - ** resolve the result-set expression list. - */ -- sNC.ncFlags = NC_AllowAgg; -+ sNC.ncFlags = NC_AllowAgg|NC_AllowWin; - sNC.pSrcList = p->pSrc; - sNC.pNext = pOuterNC; - - /* Resolve names in the result set. */ - if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort; -+ sNC.ncFlags &= ~NC_AllowWin; - - /* If there are no aggregate functions in the result-set, and no GROUP BY - ** expression, do not allow aggregates in any of the other expressions. -@@ -91337,7 +95856,9 @@ - ** Minor point: If this is the case, then the expression will be - ** re-evaluated for each reference to it. - */ -- sNC.pEList = p->pEList; -+ assert( (sNC.ncFlags & (NC_UAggInfo|NC_UUpsert))==0 ); -+ sNC.uNC.pEList = p->pEList; -+ sNC.ncFlags |= NC_UEList; - if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; - if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; - -@@ -91355,7 +95876,7 @@ - ** outer queries - */ - sNC.pNext = 0; -- sNC.ncFlags |= NC_AllowAgg; -+ sNC.ncFlags |= NC_AllowAgg|NC_AllowWin; - - /* If this is a converted compound query, move the ORDER BY clause from - ** the sub-query back to the parent query. At this point each term -@@ -91386,6 +95907,7 @@ - if( db->mallocFailed ){ - return WRC_Abort; - } -+ sNC.ncFlags &= ~NC_AllowWin; - - /* Resolve the GROUP BY clause. At the same time, make sure - ** the GROUP BY clause does not contain aggregate functions. -@@ -91570,7 +96092,7 @@ - Table *pTab, /* The table being referenced */ - int type, /* NC_IsCheck or NC_PartIdx or NC_IdxExpr */ - Expr *pExpr, /* Expression to resolve. May be NULL. */ -- ExprList *pList /* Expression list to resolve. May be NUL. */ -+ ExprList *pList /* Expression list to resolve. May be NULL. */ - ){ - SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ - NameContext sNC; /* Name context for pParse->pNewTable */ -@@ -91651,8 +96173,8 @@ - return sqlite3AffinityType(pExpr->u.zToken, 0); - } - #endif -- if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){ -- return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn); -+ if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->y.pTab ){ -+ return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); - } - if( op==TK_SELECT_COLUMN ){ - assert( pExpr->pLeft->flags&EP_xIsSelect ); -@@ -91717,6 +96239,11 @@ - ** Return the collation sequence for the expression pExpr. If - ** there is no defined collating sequence, return NULL. - ** -+** See also: sqlite3ExprNNCollSeq() -+** -+** The sqlite3ExprNNCollSeq() works the same exact that it returns the -+** default collation if pExpr has no defined collation. -+** - ** The collating sequence might be determined by a COLLATE operator - ** or by the presence of a column with a defined collating sequence. - ** COLLATE operators take first precedence. Left operands take -@@ -91729,27 +96256,27 @@ - while( p ){ - int op = p->op; - if( p->flags & EP_Generic ) break; -- if( op==TK_CAST || op==TK_UPLUS ){ -- p = p->pLeft; -- continue; -- } -- if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){ -- pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); -- break; -- } - if( (op==TK_AGG_COLUMN || op==TK_COLUMN - || op==TK_REGISTER || op==TK_TRIGGER) -- && p->pTab!=0 -+ && p->y.pTab!=0 - ){ -- /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally -+ /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally - ** a TK_COLUMN but was previously evaluated and cached in a register */ - int j = p->iColumn; - if( j>=0 ){ -- const char *zColl = p->pTab->aCol[j].zColl; -+ const char *zColl = p->y.pTab->aCol[j].zColl; - pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); - } - break; - } -+ if( op==TK_CAST || op==TK_UPLUS ){ -+ p = p->pLeft; -+ continue; -+ } -+ if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){ -+ pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); -+ break; -+ } - if( p->flags & EP_Collate ){ - if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){ - p = p->pLeft; -@@ -91782,6 +96309,32 @@ - } - - /* -+** Return the collation sequence for the expression pExpr. If -+** there is no defined collating sequence, return a pointer to the -+** defautl collation sequence. -+** -+** See also: sqlite3ExprCollSeq() -+** -+** The sqlite3ExprCollSeq() routine works the same except that it -+** returns NULL if there is no defined collation. -+*/ -+SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr){ -+ CollSeq *p = sqlite3ExprCollSeq(pParse, pExpr); -+ if( p==0 ) p = pParse->db->pDfltColl; -+ assert( p!=0 ); -+ return p; -+} -+ -+/* -+** Return TRUE if the two expressions have equivalent collating sequences. -+*/ -+SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2){ -+ CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1); -+ CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2); -+ return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0; -+} -+ -+/* - ** pExpr is an operand of a comparison operator. aff2 is the - ** type affinity of the other operand. This routine returns the - ** type affinity that should be used for the comparison operator. -@@ -92143,7 +96696,6 @@ - Expr *pL, *pR; - int r1, r2; - assert( i>=0 && i<nLeft ); -- if( i>0 ) sqlite3ExprCachePush(pParse); - r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, ®Free1); - r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, ®Free2); - codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5); -@@ -92155,7 +96707,6 @@ - testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); - sqlite3ReleaseTempReg(pParse, regFree1); - sqlite3ReleaseTempReg(pParse, regFree2); -- if( i>0 ) sqlite3ExprCachePop(pParse); - if( i==nLeft-1 ){ - break; - } -@@ -92220,16 +96771,15 @@ - } - } - } --static void heightOfSelect(Select *p, int *pnHeight){ -- if( p ){ -+static void heightOfSelect(Select *pSelect, int *pnHeight){ -+ Select *p; -+ for(p=pSelect; p; p=p->pPrior){ - heightOfExpr(p->pWhere, pnHeight); - heightOfExpr(p->pHaving, pnHeight); - heightOfExpr(p->pLimit, pnHeight); -- heightOfExpr(p->pOffset, pnHeight); - heightOfExprList(p->pEList, pnHeight); - heightOfExprList(p->pGroupBy, pnHeight); - heightOfExprList(p->pOrderBy, pnHeight); -- heightOfSelect(p->pPrior, pnHeight); - } - } - -@@ -92368,7 +96918,7 @@ - ){ - Token x; - x.z = zToken; -- x.n = zToken ? sqlite3Strlen30(zToken) : 0; -+ x.n = sqlite3Strlen30(zToken); - return sqlite3ExprAlloc(db, op, &x, 0); - } - -@@ -92504,7 +97054,12 @@ - ** Construct a new expression node for a function with multiple - ** arguments. - */ --SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ -+SQLITE_PRIVATE Expr *sqlite3ExprFunction( -+ Parse *pParse, /* Parsing context */ -+ ExprList *pList, /* Argument list */ -+ Token *pToken, /* Name of the function */ -+ int eDistinct /* SF_Distinct or SF_ALL or 0 */ -+){ - Expr *pNew; - sqlite3 *db = pParse->db; - assert( pToken ); -@@ -92513,9 +97068,14 @@ - sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */ - return 0; - } -+ if( pList && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ -+ sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken); -+ } - pNew->x.pList = pList; -+ ExprSetProperty(pNew, EP_HasFunc); - assert( !ExprHasProperty(pNew, EP_xIsSelect) ); - sqlite3ExprSetHeightAndFlags(pParse, pNew); -+ if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct); - return pNew; - } - -@@ -92607,6 +97167,10 @@ - assert( p!=0 ); - /* Sanity check: Assert that the IntValue is non-negative if it exists */ - assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 ); -+ -+ assert( !ExprHasProperty(p, EP_WinFunc) || p->y.pWin!=0 || db->mallocFailed ); -+ assert( p->op!=TK_FUNCTION || ExprHasProperty(p, EP_TokenOnly|EP_Reduced) -+ || p->y.pWin==0 || ExprHasProperty(p, EP_WinFunc) ); - #ifdef SQLITE_DEBUG - if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){ - assert( p->pLeft==0 ); -@@ -92625,6 +97189,10 @@ - }else{ - sqlite3ExprListDelete(db, p->x.pList); - } -+ if( ExprHasProperty(p, EP_WinFunc) ){ -+ assert( p->op==TK_FUNCTION ); -+ sqlite3WindowDelete(db, p->y.pWin); -+ } - } - if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken); - if( !ExprHasProperty(p, EP_Static) ){ -@@ -92673,7 +97241,7 @@ - ** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size - ** (unreduced) Expr objects as they or originally constructed by the parser. - ** During expression analysis, extra information is computed and moved into --** later parts of teh Expr object and that extra information might get chopped -+** later parts of the Expr object and that extra information might get chopped - ** off if the expression is reduced. Note also that it does not work to - ** make an EXPRDUP_REDUCE copy of a reduced expression. It is only legal - ** to reduce a pristine expression tree from the parser. The implementation -@@ -92685,7 +97253,11 @@ - assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ - assert( EXPR_FULLSIZE<=0xfff ); - assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); -- if( 0==flags || p->op==TK_SELECT_COLUMN ){ -+ if( 0==flags || p->op==TK_SELECT_COLUMN -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ || ExprHasProperty(p, EP_WinFunc) -+#endif -+ ){ - nSize = EXPR_FULLSIZE; - }else{ - assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); -@@ -92710,7 +97282,7 @@ - static int dupedExprNodeSize(Expr *p, int flags){ - int nByte = dupedExprStructSize(p, flags) & 0xfff; - if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ -- nByte += sqlite3Strlen30(p->u.zToken)+1; -+ nByte += sqlite3Strlen30NN(p->u.zToken)+1; - } - return ROUND8(nByte); - } -@@ -92813,7 +97385,7 @@ - } - - /* Fill in pNew->pLeft and pNew->pRight. */ -- if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){ -+ if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly|EP_WinFunc) ){ - zAlloc += dupedExprNodeSize(p, dupFlags); - if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){ - pNew->pLeft = p->pLeft ? -@@ -92821,6 +97393,12 @@ - pNew->pRight = p->pRight ? - exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0; - } -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( ExprHasProperty(p, EP_WinFunc) ){ -+ pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin); -+ assert( ExprHasProperty(pNew, EP_WinFunc) ); -+ } -+#endif /* SQLITE_OMIT_WINDOWFUNC */ - if( pzBuffer ){ - *pzBuffer = zAlloc; - } -@@ -92895,10 +97473,9 @@ - Expr *pPriorSelectCol = 0; - assert( db!=0 ); - if( p==0 ) return 0; -- pNew = sqlite3DbMallocRawNN(db, -- sizeof(*pNew)+sizeof(pNew->a[0])*(p->nExpr-1) ); -+ pNew = sqlite3DbMallocRawNN(db, sqlite3DbMallocSize(db, p)); - if( pNew==0 ) return 0; -- pNew->nAlloc = pNew->nExpr = p->nExpr; -+ pNew->nExpr = p->nExpr; - pItem = pNew->a; - pOldItem = p->a; - for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){ -@@ -92926,6 +97503,7 @@ - pItem->sortOrder = pOldItem->sortOrder; - pItem->done = 0; - pItem->bSpanIsTab = pOldItem->bSpanIsTab; -+ pItem->bSorterRef = pOldItem->bSorterRef; - pItem->u = pOldItem->u; - } - return pNew; -@@ -93024,7 +97602,6 @@ - pNew->pNext = pNext; - pNew->pPrior = 0; - pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); -- pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags); - pNew->iLimit = 0; - pNew->iOffset = 0; - pNew->selFlags = p->selFlags & ~SF_UsesEphemeral; -@@ -93032,7 +97609,11 @@ - pNew->addrOpenEphm[1] = -1; - pNew->nSelectRow = p->nSelectRow; - pNew->pWith = withDup(db, p->pWith); -- sqlite3SelectSetName(pNew, p->zSelName); -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ pNew->pWin = 0; -+ pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn); -+#endif -+ pNew->selId = p->selId; - *pp = pNew; - pp = &pNew->pPrior; - pNext = pNew; -@@ -93052,6 +97633,13 @@ - ** Add a new element to the end of an expression list. If pList is - ** initially NULL, then create a new expression list. - ** -+** The pList argument must be either NULL or a pointer to an ExprList -+** obtained from a prior call to sqlite3ExprListAppend(). This routine -+** may not be used with an ExprList obtained from sqlite3ExprListDup(). -+** Reason: This routine assumes that the number of slots in pList->a[] -+** is a power of two. That is true for sqlite3ExprListAppend() returns -+** but is not necessarily true from the return value of sqlite3ExprListDup(). -+** - ** If a memory allocation error occurs, the entire list is freed and - ** NULL is returned. If non-NULL is returned, then it is guaranteed - ** that the new entry was successfully appended. -@@ -93070,16 +97658,14 @@ - goto no_mem; - } - pList->nExpr = 0; -- pList->nAlloc = 1; -- }else if( pList->nExpr==pList->nAlloc ){ -+ }else if( (pList->nExpr & (pList->nExpr-1))==0 ){ - ExprList *pNew; - pNew = sqlite3DbRealloc(db, pList, -- sizeof(*pList)+(2*pList->nAlloc - 1)*sizeof(pList->a[0])); -+ sizeof(*pList)+(2*pList->nExpr - 1)*sizeof(pList->a[0])); - if( pNew==0 ){ - goto no_mem; - } - pList = pNew; -- pList->nAlloc *= 2; - } - pItem = &pList->a[pList->nExpr++]; - assert( offsetof(struct ExprList_item,zName)==sizeof(pItem->pExpr) ); -@@ -93199,6 +97785,9 @@ - assert( pItem->zName==0 ); - pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n); - if( dequote ) sqlite3Dequote(pItem->zName); -+ if( IN_RENAME_OBJECT ){ -+ sqlite3RenameTokenMap(pParse, (void*)pItem->zName, pName); -+ } - } - } - -@@ -93213,7 +97802,8 @@ - SQLITE_PRIVATE void sqlite3ExprListSetSpan( - Parse *pParse, /* Parsing context */ - ExprList *pList, /* List to which to add the span. */ -- ExprSpan *pSpan /* The span to be added */ -+ const char *zStart, /* Start of the span */ -+ const char *zEnd /* End of the span */ - ){ - sqlite3 *db = pParse->db; - assert( pList!=0 || db->mallocFailed!=0 ); -@@ -93220,10 +97810,8 @@ - if( pList ){ - struct ExprList_item *pItem = &pList->a[pList->nExpr-1]; - assert( pList->nExpr>0 ); -- assert( db->mallocFailed || pItem->pExpr==pSpan->pExpr ); - sqlite3DbFree(db, pItem->zSpan); -- pItem->zSpan = sqlite3DbStrNDup(db, (char*)pSpan->zStart, -- (int)(pSpan->zEnd - pSpan->zStart)); -+ pItem->zSpan = sqlite3DbSpanDup(db, zStart, zEnd); - } - } - -@@ -93270,17 +97858,57 @@ - SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList *pList){ - int i; - u32 m = 0; -- if( pList ){ -- for(i=0; i<pList->nExpr; i++){ -- Expr *pExpr = pList->a[i].pExpr; -- assert( pExpr!=0 ); -- m |= pExpr->flags; -- } -+ assert( pList!=0 ); -+ for(i=0; i<pList->nExpr; i++){ -+ Expr *pExpr = pList->a[i].pExpr; -+ assert( pExpr!=0 ); -+ m |= pExpr->flags; - } - return m; - } - - /* -+** This is a SELECT-node callback for the expression walker that -+** always "fails". By "fail" in this case, we mean set -+** pWalker->eCode to zero and abort. -+** -+** This callback is used by multiple expression walkers. -+*/ -+SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){ -+ UNUSED_PARAMETER(NotUsed); -+ pWalker->eCode = 0; -+ return WRC_Abort; -+} -+ -+/* -+** 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. -+*/ -+SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){ -+ assert( pExpr->op==TK_ID || pExpr->op==TK_STRING ); -+ if( sqlite3StrICmp(pExpr->u.zToken, "true")==0 -+ || sqlite3StrICmp(pExpr->u.zToken, "false")==0 -+ ){ -+ pExpr->op = TK_TRUEFALSE; -+ return 1; -+ } -+ return 0; -+} -+ -+/* -+** The argument must be a TK_TRUEFALSE Expr node. Return 1 if it is TRUE -+** and 0 if it is FALSE. -+*/ -+SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr *pExpr){ -+ assert( pExpr->op==TK_TRUEFALSE ); -+ assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0 -+ || sqlite3StrICmp(pExpr->u.zToken,"false")==0 ); -+ return pExpr->u.zToken[4]==0; -+} -+ -+ -+/* - ** These routines are Walker callbacks used to check expressions to - ** see if they are "constant" for some definition of constant. The - ** Walker.eCode value determines the type of "constant" we are looking -@@ -93327,6 +97955,12 @@ - return WRC_Abort; - } - case TK_ID: -+ /* Convert "true" or "false" in a DEFAULT clause into the -+ ** appropriate TK_TRUEFALSE operator */ -+ if( sqlite3ExprIdToTrueFalse(pExpr) ){ -+ return WRC_Prune; -+ } -+ /* Fall thru */ - case TK_COLUMN: - case TK_AGG_FUNCTION: - case TK_AGG_COLUMN: -@@ -93334,11 +97968,16 @@ - testcase( pExpr->op==TK_COLUMN ); - testcase( pExpr->op==TK_AGG_FUNCTION ); - testcase( pExpr->op==TK_AGG_COLUMN ); -+ if( ExprHasProperty(pExpr, EP_FixedCol) && pWalker->eCode!=2 ){ -+ return WRC_Continue; -+ } - if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){ - return WRC_Continue; - } - /* Fall through */ - case TK_IF_NULL_ROW: -+ case TK_REGISTER: -+ testcase( pExpr->op==TK_REGISTER ); - testcase( pExpr->op==TK_IF_NULL_ROW ); - pWalker->eCode = 0; - return WRC_Abort; -@@ -93356,21 +97995,16 @@ - } - /* Fall through */ - default: -- testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */ -- testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */ -+ testcase( pExpr->op==TK_SELECT ); /* sqlite3SelectWalkFail() disallows */ -+ testcase( pExpr->op==TK_EXISTS ); /* sqlite3SelectWalkFail() disallows */ - return WRC_Continue; - } - } --static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){ -- UNUSED_PARAMETER(NotUsed); -- pWalker->eCode = 0; -- return WRC_Abort; --} - static int exprIsConst(Expr *p, int initFlag, int iCur){ - Walker w; - w.eCode = initFlag; - w.xExprCallback = exprNodeIsConstant; -- w.xSelectCallback = selectNodeIsConstant; -+ w.xSelectCallback = sqlite3SelectWalkFail; - #ifdef SQLITE_DEBUG - w.xSelectCallback2 = sqlite3SelectWalkAssert2; - #endif -@@ -93392,10 +98026,17 @@ - } - - /* --** Walk an expression tree. Return non-zero if the expression is constant --** that does no originate from the ON or USING clauses of a join. --** Return 0 if it involves variables or function calls or terms from --** an ON or USING clause. -+** Walk an expression tree. Return non-zero if -+** -+** (1) the expression is constant, and -+** (2) the expression does originate in the ON or USING clause -+** of a LEFT JOIN, and -+** (3) the expression does not contain any EP_FixedCol TK_COLUMN -+** operands created by the constant propagation optimization. -+** -+** When this routine returns true, it indicates that the expression -+** can be added to the pParse->pConstExpr list and evaluated once when -+** the prepared statement starts up. See sqlite3ExprCodeAtInit(). - */ - SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){ - return exprIsConst(p, 2, 0); -@@ -93424,8 +98065,8 @@ - for(i=0; i<pGroupBy->nExpr; i++){ - Expr *p = pGroupBy->a[i].pExpr; - if( sqlite3ExprCompare(0, pExpr, p, -1)<2 ){ -- CollSeq *pColl = sqlite3ExprCollSeq(pWalker->pParse, p); -- if( pColl==0 || sqlite3_stricmp("BINARY", pColl->zName)==0 ){ -+ CollSeq *pColl = sqlite3ExprNNCollSeq(pWalker->pParse, p); -+ if( sqlite3IsBinary(pColl) ){ - return WRC_Prune; - } - } -@@ -93493,7 +98134,7 @@ - Walker w; - w.eCode = 1; - w.xExprCallback = sqlite3ExprWalkNoop; -- w.xSelectCallback = selectNodeIsConstant; -+ w.xSelectCallback = sqlite3SelectWalkFail; - #ifdef SQLITE_DEBUG - w.xSelectCallback2 = sqlite3SelectWalkAssert2; - #endif -@@ -93566,9 +98207,9 @@ - case TK_BLOB: - return 0; - case TK_COLUMN: -- assert( p->pTab!=0 ); - return ExprHasProperty(p, EP_CanBeNull) || -- (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0); -+ p->y.pTab==0 || /* Reference to column of index on expression */ -+ (p->iColumn>=0 && p->y.pTab->aCol[p->iColumn].notNull==0); - default: - return 1; - } -@@ -93623,6 +98264,14 @@ - if( sqlite3StrICmp(z, "OID")==0 ) return 1; - return 0; - } -+#ifdef SQLITE_ENABLE_NORMALIZE -+SQLITE_PRIVATE int sqlite3IsRowidN(const char *z, int n){ -+ if( sqlite3StrNICmp(z, "_ROWID_", n)==0 ) return 1; -+ if( sqlite3StrNICmp(z, "ROWID", n)==0 ) return 1; -+ if( sqlite3StrNICmp(z, "OID", n)==0 ) return 1; -+ return 0; -+} -+#endif - - /* - ** pX is the RHS of an IN operator. If pX is a SELECT statement -@@ -93649,7 +98298,6 @@ - } - assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */ - if( p->pLimit ) return 0; /* Has no LIMIT clause */ -- assert( p->pOffset==0 ); /* No LIMIT means no OFFSET */ - if( p->pWhere ) return 0; /* Has no WHERE clause */ - pSrc = p->pSrc; - assert( pSrc!=0 ); -@@ -93739,16 +98387,15 @@ - ** pX->iTable made to point to the ephemeral table instead of an - ** existing table. - ** --** The inFlags parameter must contain exactly one of the bits --** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP. If inFlags contains --** IN_INDEX_MEMBERSHIP, then the generated table will be used for a --** fast membership test. When the IN_INDEX_LOOP bit is set, the --** IN index will be used to loop over all values of the RHS of the --** IN operator. -+** The inFlags parameter must contain, at a minimum, one of the bits -+** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both. If inFlags contains -+** IN_INDEX_MEMBERSHIP, then the generated table will be used for a fast -+** membership test. When the IN_INDEX_LOOP bit is set, the IN index will -+** be used to loop over all values of the RHS of the IN operator. - ** - ** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate - ** through the set members) then the b-tree must not contain duplicates. --** An epheremal table must be used unless the selected columns are guaranteed -+** An epheremal table will be created unless the selected columns are guaranteed - ** to be unique - either because it is an INTEGER PRIMARY KEY or due to - ** a UNIQUE constraint or index. - ** -@@ -93849,7 +98496,8 @@ - - sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); - eType = IN_INDEX_ROWID; -- -+ ExplainQueryPlan((pParse, 0, -+ "USING ROWID SEARCH ON TABLE %s FOR IN-OPERATOR",pTab->zName)); - sqlite3VdbeJumpHere(v, iAddr); - }else{ - Index *pIdx; /* Iterator variable */ -@@ -93928,11 +98576,8 @@ - if( colUsed==(MASKBIT(nExpr)-1) ){ - /* If we reach this point, that means the index pIdx is usable */ - int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); --#ifndef SQLITE_OMIT_EXPLAIN -- sqlite3VdbeAddOp4(v, OP_Explain, 0, 0, 0, -- sqlite3MPrintf(db, "USING INDEX %s FOR IN-OPERATOR",pIdx->zName), -- P4_DYNAMIC); --#endif -+ ExplainQueryPlan((pParse, 0, -+ "USING INDEX %s FOR IN-OPERATOR",pIdx->zName)); - sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb); - sqlite3VdbeSetP4KeyInfo(pParse, pIdx); - VdbeComment((v, "%s", pIdx->zName)); -@@ -94111,7 +98756,6 @@ - int rReg = 0; /* Register storing resulting */ - Vdbe *v = sqlite3GetVdbe(pParse); - if( NEVER(v==0) ) return 0; -- sqlite3ExprCachePush(pParse); - - /* The evaluation of the IN/EXISTS/SELECT must be repeated every time it - ** is encountered if any of the following is true: -@@ -94127,17 +98771,6 @@ - jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); - } - --#ifndef SQLITE_OMIT_EXPLAIN -- if( pParse->explain==2 ){ -- char *zMsg = sqlite3MPrintf(pParse->db, "EXECUTE %s%s SUBQUERY %d", -- jmpIfDynamic>=0?"":"CORRELATED ", -- pExpr->op==TK_IN?"LIST":"SCALAR", -- pParse->iNextSelectId -- ); -- sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); -- } --#endif -- - switch( pExpr->op ){ - case TK_IN: { - int addr; /* Address of OP_OpenEphemeral instruction */ -@@ -94175,6 +98808,9 @@ - Select *pSelect = pExpr->x.pSelect; - ExprList *pEList = pSelect->pEList; - -+ ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY", -+ jmpIfDynamic>=0?"":"CORRELATED " -+ )); - assert( !isRowid ); - /* If the LHS and RHS of the IN operator do not match, that - ** error will have been caught long before we reach this point. */ -@@ -94216,7 +98852,6 @@ - ExprList *pList = pExpr->x.pList; - struct ExprList_item *pItem; - int r1, r2, r3; -- - affinity = sqlite3ExprAffinity(pLeft); - if( !affinity ){ - affinity = SQLITE_AFF_BLOB; -@@ -94229,7 +98864,7 @@ - /* Loop through each expression in <exprlist>. */ - r1 = sqlite3GetTempReg(pParse); - r2 = sqlite3GetTempReg(pParse); -- if( isRowid ) sqlite3VdbeAddOp2(v, OP_Null, 0, r2); -+ if( isRowid ) sqlite3VdbeAddOp4(v, OP_Blob, 0, r2, 0, "", P4_STATIC); - for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){ - Expr *pE2 = pItem->pExpr; - int iValToIns; -@@ -94256,7 +98891,6 @@ - sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3); - }else{ - sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1); -- sqlite3ExprCacheAffinityChange(pParse, r3, 1); - sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1); - } - } -@@ -94289,6 +98923,7 @@ - Select *pSel; /* SELECT statement to encode */ - SelectDest dest; /* How to deal with SELECT result */ - int nReg; /* Registers to allocate */ -+ Expr *pLimit; /* New limit expression */ - - testcase( pExpr->op==TK_EXISTS ); - testcase( pExpr->op==TK_SELECT ); -@@ -94296,6 +98931,8 @@ - assert( ExprHasProperty(pExpr, EP_xIsSelect) ); - - pSel = pExpr->x.pSelect; -+ ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY", -+ jmpIfDynamic>=0?"":"CORRELATED ")); - nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1; - sqlite3SelectDestInit(&dest, 0, pParse->nMem+1); - pParse->nMem += nReg; -@@ -94310,11 +98947,14 @@ - sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); - VdbeComment((v, "Init EXISTS result")); - } -- sqlite3ExprDelete(pParse->db, pSel->pLimit); -- pSel->pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER, -- &sqlite3IntTokens[1], 0); -+ pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0); -+ if( pSel->pLimit ){ -+ sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft); -+ pSel->pLimit->pLeft = pLimit; -+ }else{ -+ pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0); -+ } - pSel->iLimit = 0; -- pSel->selFlags &= ~SF_MultiValue; - if( sqlite3Select(pParse, pSel, &dest) ){ - return 0; - } -@@ -94331,7 +98971,6 @@ - if( jmpIfDynamic>=0 ){ - sqlite3VdbeJumpHere(v, jmpIfDynamic); - } -- sqlite3ExprCachePop(pParse); - - return rReg; - } -@@ -94450,7 +99089,6 @@ - ** aiMap[] array contains a mapping from the original LHS field order to - ** the field order that matches the RHS index. - */ -- sqlite3ExprCachePush(pParse); - rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy); - for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */ - if( i==nVector ){ -@@ -94609,7 +99247,6 @@ - - sqlite3ExprCodeIN_finished: - if( rLhs!=rLhsOrig ) sqlite3ReleaseTempReg(pParse, rLhs); -- sqlite3ExprCachePop(pParse); - VdbeComment((v, "end IN expr")); - sqlite3ExprCodeIN_oom_error: - sqlite3DbFree(pParse->db, aiMap); -@@ -94657,7 +99294,7 @@ - const char *z = pExpr->u.zToken; - assert( z!=0 ); - c = sqlite3DecOrHexToI64(z, &value); -- if( c==1 || (c==2 && !negFlag) || (negFlag && value==SMALLEST_INT64)){ -+ if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){ - #ifdef SQLITE_OMIT_FLOATING_POINT - sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); - #else -@@ -94671,152 +99308,13 @@ - } - #endif - }else{ -- if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } -+ if( negFlag ){ value = c==3 ? SMALLEST_INT64 : -value; } - sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64); - } - } - } - --/* --** Erase column-cache entry number i --*/ --static void cacheEntryClear(Parse *pParse, int i){ -- if( pParse->aColCache[i].tempReg ){ -- if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){ -- pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg; -- } -- } -- pParse->nColCache--; -- if( i<pParse->nColCache ){ -- pParse->aColCache[i] = pParse->aColCache[pParse->nColCache]; -- } --} - -- --/* --** Record in the column cache that a particular column from a --** particular table is stored in a particular register. --*/ --SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){ -- int i; -- int minLru; -- int idxLru; -- struct yColCache *p; -- -- /* Unless an error has occurred, register numbers are always positive. */ -- assert( iReg>0 || pParse->nErr || pParse->db->mallocFailed ); -- assert( iCol>=-1 && iCol<32768 ); /* Finite column numbers */ -- -- /* The SQLITE_ColumnCache flag disables the column cache. This is used -- ** for testing only - to verify that SQLite always gets the same answer -- ** with and without the column cache. -- */ -- if( OptimizationDisabled(pParse->db, SQLITE_ColumnCache) ) return; -- -- /* First replace any existing entry. -- ** -- ** Actually, the way the column cache is currently used, we are guaranteed -- ** that the object will never already be in cache. Verify this guarantee. -- */ --#ifndef NDEBUG -- for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){ -- assert( p->iTable!=iTab || p->iColumn!=iCol ); -- } --#endif -- -- /* If the cache is already full, delete the least recently used entry */ -- if( pParse->nColCache>=SQLITE_N_COLCACHE ){ -- minLru = 0x7fffffff; -- idxLru = -1; -- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){ -- if( p->lru<minLru ){ -- idxLru = i; -- minLru = p->lru; -- } -- } -- p = &pParse->aColCache[idxLru]; -- }else{ -- p = &pParse->aColCache[pParse->nColCache++]; -- } -- -- /* Add the new entry to the end of the cache */ -- p->iLevel = pParse->iCacheLevel; -- p->iTable = iTab; -- p->iColumn = iCol; -- p->iReg = iReg; -- p->tempReg = 0; -- p->lru = pParse->iCacheCnt++; --} -- --/* --** Indicate that registers between iReg..iReg+nReg-1 are being overwritten. --** Purge the range of registers from the column cache. --*/ --SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){ -- int i = 0; -- while( i<pParse->nColCache ){ -- struct yColCache *p = &pParse->aColCache[i]; -- if( p->iReg >= iReg && p->iReg < iReg+nReg ){ -- cacheEntryClear(pParse, i); -- }else{ -- i++; -- } -- } --} -- --/* --** Remember the current column cache context. Any new entries added --** added to the column cache after this call are removed when the --** corresponding pop occurs. --*/ --SQLITE_PRIVATE void sqlite3ExprCachePush(Parse *pParse){ -- pParse->iCacheLevel++; --#ifdef SQLITE_DEBUG -- if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ -- printf("PUSH to %d\n", pParse->iCacheLevel); -- } --#endif --} -- --/* --** Remove from the column cache any entries that were added since the --** the previous sqlite3ExprCachePush operation. In other words, restore --** the cache to the state it was in prior the most recent Push. --*/ --SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){ -- int i = 0; -- assert( pParse->iCacheLevel>=1 ); -- pParse->iCacheLevel--; --#ifdef SQLITE_DEBUG -- if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ -- printf("POP to %d\n", pParse->iCacheLevel); -- } --#endif -- while( i<pParse->nColCache ){ -- if( pParse->aColCache[i].iLevel>pParse->iCacheLevel ){ -- cacheEntryClear(pParse, i); -- }else{ -- i++; -- } -- } --} -- --/* --** When a cached column is reused, make sure that its register is --** no longer available as a temp register. ticket #3879: that same --** register might be in the cache in multiple places, so be sure to --** get them all. --*/ --static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){ -- int i; -- struct yColCache *p; -- for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){ -- if( p->iReg==iReg ){ -- p->tempReg = 0; -- } -- } --} -- - /* Generate code that will load into register regOut a value that is - ** appropriate for the iIdxCol-th column of index pIdx. - */ -@@ -94871,13 +99369,8 @@ - - /* - ** Generate code that will extract the iColumn-th column from --** table pTab and store the column value in a register. -+** table pTab and store the column value in register iReg. - ** --** An effort is made to store the column value in register iReg. This --** is not garanteeed for GetColumn() - the result can be stored in --** any register. But the result is guaranteed to land in register iReg --** for GetColumnToReg(). --** - ** There must be an open cursor to pTab in iTable when this routine - ** is called. If iColumn<0 then code is generated that extracts the rowid. - */ -@@ -94890,97 +99383,24 @@ - u8 p5 /* P5 value for OP_Column + FLAGS */ - ){ - Vdbe *v = pParse->pVdbe; -- int i; -- struct yColCache *p; -- -- for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){ -- if( p->iTable==iTable && p->iColumn==iColumn ){ -- p->lru = pParse->iCacheCnt++; -- sqlite3ExprCachePinRegister(pParse, p->iReg); -- return p->iReg; -- } -- } - assert( v!=0 ); - sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg); - if( p5 ){ - sqlite3VdbeChangeP5(v, p5); -- }else{ -- sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg); - } - return iReg; - } --SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg( -- Parse *pParse, /* Parsing and code generating context */ -- Table *pTab, /* Description of the table we are reading from */ -- int iColumn, /* Index of the table column */ -- int iTable, /* The cursor pointing to the table */ -- int iReg /* Store results here */ --){ -- int r1 = sqlite3ExprCodeGetColumn(pParse, pTab, iColumn, iTable, iReg, 0); -- if( r1!=iReg ) sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, r1, iReg); --} - -- - /* --** Clear all column cache entries. --*/ --SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){ -- int i; -- --#ifdef SQLITE_DEBUG -- if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ -- printf("CLEAR\n"); -- } --#endif -- for(i=0; i<pParse->nColCache; i++){ -- if( pParse->aColCache[i].tempReg -- && pParse->nTempReg<ArraySize(pParse->aTempReg) -- ){ -- pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg; -- } -- } -- pParse->nColCache = 0; --} -- --/* --** Record the fact that an affinity change has occurred on iCount --** registers starting with iStart. --*/ --SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){ -- sqlite3ExprCacheRemove(pParse, iStart, iCount); --} -- --/* - ** Generate code to move content from registers iFrom...iFrom+nReg-1 --** over to iTo..iTo+nReg-1. Keep the column cache up-to-date. -+** over to iTo..iTo+nReg-1. - */ - SQLITE_PRIVATE 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); -- sqlite3ExprCacheRemove(pParse, iFrom, nReg); - } - --#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) - /* --** Return true if any register in the range iFrom..iTo (inclusive) --** is used as part of the column cache. --** --** This routine is used within assert() and testcase() macros only --** and does not appear in a normal build. --*/ --static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){ -- int i; -- struct yColCache *p; -- for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){ -- int r = p->iReg; -- if( r>=iFrom && r<=iTo ) return 1; /*NO_TEST*/ -- } -- return 0; --} --#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */ -- -- --/* - ** Convert a scalar expression node to a TK_REGISTER referencing - ** register iReg. The caller must ensure that iReg already contains - ** the correct value for the expression. -@@ -95055,6 +99475,7 @@ - return 0; - } - -+expr_code_doover: - if( pExpr==0 ){ - op = TK_NULL; - }else{ -@@ -95076,6 +99497,28 @@ - } - case TK_COLUMN: { - int iTab = pExpr->iTable; -+ 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 -+ ** expresssion. However, make sure the constant has the correct -+ ** 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); -+ if( aff!=SQLITE_AFF_BLOB ){ -+ static const char zAff[] = "B\000C\000D\000E"; -+ assert( SQLITE_AFF_BLOB=='A' ); -+ assert( SQLITE_AFF_TEXT=='B' ); -+ if( iReg!=target ){ -+ sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target); -+ iReg = target; -+ } -+ sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0, -+ &zAff[(aff-'B')*2], P4_STATIC); -+ } -+ return iReg; -+ } - if( iTab<0 ){ - if( pParse->iSelfTab<0 ){ - /* Generating CHECK constraints or inserting into partial index */ -@@ -95086,7 +99529,7 @@ - iTab = pParse->iSelfTab - 1; - } - } -- return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab, -+ return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, - pExpr->iColumn, iTab, target, - pExpr->op2); - } -@@ -95094,6 +99537,10 @@ - codeInteger(pParse, pExpr, 0, target); - return target; - } -+ case TK_TRUEFALSE: { -+ sqlite3VdbeAddOp2(v, OP_Integer, sqlite3ExprTruthValue(pExpr), target); -+ return target; -+ } - #ifndef SQLITE_OMIT_FLOATING_POINT - case TK_FLOAT: { - assert( !ExprHasProperty(pExpr, EP_IntValue) ); -@@ -95152,8 +99599,6 @@ - } - sqlite3VdbeAddOp2(v, OP_Cast, target, - sqlite3AffinityType(pExpr->u.zToken, 0)); -- testcase( usedAsColumnCache(pParse, inReg, inReg) ); -- sqlite3ExprCacheAffinityChange(pParse, inReg, 1); - return inReg; - } - #endif /* SQLITE_OMIT_CAST */ -@@ -95249,6 +99694,18 @@ - sqlite3VdbeAddOp2(v, op, r1, inReg); - break; - } -+ case TK_TRUTH: { -+ int isTrue; /* IS TRUE or IS NOT TRUE */ -+ int bNormal; /* IS TRUE or IS FALSE */ -+ r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); -+ testcase( regFree1==0 ); -+ isTrue = sqlite3ExprTruthValue(pExpr->pRight); -+ bNormal = pExpr->op2==TK_IS; -+ testcase( isTrue && bNormal); -+ testcase( !isTrue && bNormal); -+ sqlite3VdbeAddOp4Int(v, OP_IsTrue, r1, inReg, !isTrue, isTrue ^ bNormal); -+ break; -+ } - case TK_ISNULL: - case TK_NOTNULL: { - int addr; -@@ -95285,6 +99742,12 @@ - u8 enc = ENC(db); /* The text encoding used by this database */ - CollSeq *pColl = 0; /* A collating sequence */ - -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( ExprHasProperty(pExpr, EP_WinFunc) ){ -+ return pExpr->y.pWin->regResult; -+ } -+#endif -+ - if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){ - /* SQL functions can be expensive. So try to move constant functions - ** out of the inner loop, even if that means an extra OP_Copy. */ -@@ -95321,10 +99784,7 @@ - for(i=1; i<nFarg; i++){ - sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce); - VdbeCoverage(v); -- sqlite3ExprCacheRemove(pParse, target, 1); -- sqlite3ExprCachePush(pParse); - sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target); -- sqlite3ExprCachePop(pParse); - } - sqlite3VdbeResolveLabel(v, endCoalesce); - break; -@@ -95390,10 +99850,8 @@ - } - } - -- sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */ - sqlite3ExprCodeExprList(pParse, pFarg, r1, 0, - SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR); -- sqlite3ExprCachePop(pParse); /* Ticket 2ea2425d34be */ - }else{ - r1 = 0; - } -@@ -95410,7 +99868,7 @@ - ** "glob(B,A). We want to use the A in "A glob B" to test - ** for function overloading. But we use the B term in "glob(B,A)". - */ -- if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){ -+ if( nFarg>=2 && ExprHasProperty(pExpr, EP_InfixFunc) ){ - pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr); - }else if( nFarg>0 ){ - pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr); -@@ -95420,9 +99878,21 @@ - if( !pColl ) pColl = db->pDfltColl; - sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); - } -- sqlite3VdbeAddOp4(v, pParse->iSelfTab ? OP_PureFunc0 : OP_Function0, -- constMask, r1, target, (char*)pDef, P4_FUNCDEF); -- sqlite3VdbeChangeP5(v, (u8)nFarg); -+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC -+ if( pDef->funcFlags & SQLITE_FUNC_OFFSET ){ -+ Expr *pArg = pFarg->a[0].pExpr; -+ if( pArg->op==TK_COLUMN ){ -+ sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target); -+ }else{ -+ sqlite3VdbeAddOp2(v, OP_Null, 0, target); -+ } -+ }else -+#endif -+ { -+ sqlite3VdbeAddOp4(v, pParse->iSelfTab ? OP_PureFunc0 : OP_Function0, -+ constMask, r1, target, (char*)pDef, P4_FUNCDEF); -+ sqlite3VdbeChangeP5(v, (u8)nFarg); -+ } - if( nFarg && constMask==0 ){ - sqlite3ReleaseTempRange(pParse, r1, nFarg); - } -@@ -95487,7 +99957,8 @@ - case TK_SPAN: - case TK_COLLATE: - case TK_UPLUS: { -- return sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); -+ pExpr = pExpr->pLeft; -+ goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. OSSFuzz. */ - } - - case TK_TRIGGER: { -@@ -95516,7 +99987,7 @@ - ** p1==1 -> old.a p1==4 -> new.a - ** p1==2 -> old.b p1==5 -> new.b - */ -- Table *pTab = pExpr->pTab; -+ Table *pTab = pExpr->y.pTab; - int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn; - - assert( pExpr->iTable==0 || pExpr->iTable==1 ); -@@ -95525,10 +99996,9 @@ - assert( p1>=0 && p1<(pTab->nCol*2+2) ); - - sqlite3VdbeAddOp2(v, OP_Param, p1, target); -- VdbeComment((v, "%s.%s -> $%d", -+ VdbeComment((v, "r[%d]=%s.%s", target, - (pExpr->iTable ? "new" : "old"), -- (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName), -- target -+ (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[pExpr->iColumn].zName) - )); - - #ifndef SQLITE_OMIT_FLOATING_POINT -@@ -95554,9 +100024,7 @@ - case TK_IF_NULL_ROW: { - int addrINR; - addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable); -- sqlite3ExprCachePush(pParse); - inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); -- sqlite3ExprCachePop(pParse); - sqlite3VdbeJumpHere(v, addrINR); - sqlite3VdbeChangeP3(v, addrINR, inReg); - break; -@@ -95593,7 +100061,6 @@ - Expr opCompare; /* The X==Ei expression */ - Expr *pX; /* The X expression */ - Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */ -- VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; ) - - assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList ); - assert(pExpr->x.pList->nExpr > 0); -@@ -95617,7 +100084,6 @@ - regFree1 = 0; - } - for(i=0; i<nExpr-1; i=i+2){ -- sqlite3ExprCachePush(pParse); - if( pX ){ - assert( pTest!=0 ); - opCompare.pRight = aListelem[i].pExpr; -@@ -95630,18 +100096,13 @@ - testcase( aListelem[i+1].pExpr->op==TK_COLUMN ); - sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); - sqlite3VdbeGoto(v, endLabel); -- sqlite3ExprCachePop(pParse); - sqlite3VdbeResolveLabel(v, nextCase); - } - if( (nExpr&1)!=0 ){ -- sqlite3ExprCachePush(pParse); - sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target); -- sqlite3ExprCachePop(pParse); - }else{ - sqlite3VdbeAddOp2(v, OP_Null, 0, target); - } -- assert( pParse->db->mallocFailed || pParse->nErr>0 -- || pParse->iCacheLevel==iCacheLevel ); - sqlite3VdbeResolveLabel(v, endLabel); - break; - } -@@ -95791,7 +100252,7 @@ - ** might choose to code the expression at initialization time. - */ - SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ -- if( pParse->okConstFactor && sqlite3ExprIsConstant(pExpr) ){ -+ if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){ - sqlite3ExprCodeAtInit(pParse, pExpr, target); - }else{ - sqlite3ExprCode(pParse, pExpr, target); -@@ -95826,7 +100287,9 @@ - ** Generate code that pushes the value of every element of the given - ** expression list into a sequence of registers beginning at target. - ** --** Return the number of elements evaluated. -+** Return the number of elements evaluated. The number returned will -+** usually be pList->nExpr but might be reduced if SQLITE_ECEL_OMITREF -+** is defined. - ** - ** The SQLITE_ECEL_DUP flag prevents the arguments from being - ** filled using OP_SCopy. OP_Copy must be used instead. -@@ -95837,6 +100300,8 @@ - ** The SQLITE_ECEL_REF flag means that expressions in the list with - ** ExprList.a[].u.x.iOrderByCol>0 have already been evaluated and stored - ** in registers at srcReg, and so the value can be copied from there. -+** If SQLITE_ECEL_OMITREF is also set, then the values with u.x.iOrderByCol>0 -+** are simply omitted rather than being copied from srcReg. - */ - SQLITE_PRIVATE int sqlite3ExprCodeExprList( - Parse *pParse, /* Parsing context */ -@@ -95856,6 +100321,12 @@ - if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR; - for(pItem=pList->a, i=0; i<n; i++, pItem++){ - Expr *pExpr = pItem->pExpr; -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ if( pItem->bSorterRef ){ -+ i--; -+ n--; -+ }else -+#endif - if( (flags & SQLITE_ECEL_REF)!=0 && (j = pItem->u.x.iOrderByCol)>0 ){ - if( flags & SQLITE_ECEL_OMITREF ){ - i--; -@@ -95863,7 +100334,9 @@ - }else{ - sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i); - } -- }else if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){ -+ }else if( (flags & SQLITE_ECEL_FACTOR)!=0 -+ && sqlite3ExprIsConstantNotJoin(pExpr) -+ ){ - sqlite3ExprCodeAtInit(pParse, pExpr, target+i); - }else{ - int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); -@@ -95989,18 +100462,14 @@ - int d2 = sqlite3VdbeMakeLabel(v); - testcase( jumpIfNull==0 ); - sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL); -- sqlite3ExprCachePush(pParse); - sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3VdbeResolveLabel(v, d2); -- sqlite3ExprCachePop(pParse); - break; - } - case TK_OR: { - testcase( jumpIfNull==0 ); - sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); -- sqlite3ExprCachePush(pParse); - sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); -- sqlite3ExprCachePop(pParse); - break; - } - case TK_NOT: { -@@ -96008,6 +100477,23 @@ - sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); - break; - } -+ case TK_TRUTH: { -+ int isNot; /* IS NOT TRUE or IS NOT FALSE */ -+ int isTrue; /* IS TRUE or IS NOT TRUE */ -+ testcase( jumpIfNull==0 ); -+ isNot = pExpr->op2==TK_ISNOT; -+ isTrue = sqlite3ExprTruthValue(pExpr->pRight); -+ testcase( isTrue && isNot ); -+ testcase( !isTrue && isNot ); -+ if( isTrue ^ isNot ){ -+ sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, -+ isNot ? SQLITE_JUMPIFNULL : 0); -+ }else{ -+ sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, -+ isNot ? SQLITE_JUMPIFNULL : 0); -+ } -+ break; -+ } - case TK_IS: - case TK_ISNOT: - testcase( op==TK_IS ); -@@ -96142,9 +100628,7 @@ - case TK_AND: { - testcase( jumpIfNull==0 ); - sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); -- sqlite3ExprCachePush(pParse); - sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); -- sqlite3ExprCachePop(pParse); - break; - } - case TK_OR: { -@@ -96151,10 +100635,8 @@ - int d2 = sqlite3VdbeMakeLabel(v); - testcase( jumpIfNull==0 ); - sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL); -- sqlite3ExprCachePush(pParse); - sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3VdbeResolveLabel(v, d2); -- sqlite3ExprCachePop(pParse); - break; - } - case TK_NOT: { -@@ -96162,6 +100644,26 @@ - sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); - break; - } -+ case TK_TRUTH: { -+ int isNot; /* IS NOT TRUE or IS NOT FALSE */ -+ int isTrue; /* IS TRUE or IS NOT TRUE */ -+ testcase( jumpIfNull==0 ); -+ isNot = pExpr->op2==TK_ISNOT; -+ isTrue = sqlite3ExprTruthValue(pExpr->pRight); -+ testcase( isTrue && isNot ); -+ testcase( !isTrue && isNot ); -+ if( isTrue ^ isNot ){ -+ /* IS TRUE and IS NOT FALSE */ -+ sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, -+ isNot ? 0 : SQLITE_JUMPIFNULL); -+ -+ }else{ -+ /* IS FALSE and IS NOT TRUE */ -+ sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, -+ isNot ? 0 : SQLITE_JUMPIFNULL); -+ } -+ break; -+ } - case TK_IS: - case TK_ISNOT: - testcase( pExpr->op==TK_IS ); -@@ -96347,17 +100849,35 @@ - if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){ - if( pA->op==TK_FUNCTION ){ - if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ /* Justification for the assert(): -+ ** window functions have p->op==TK_FUNCTION but aggregate functions -+ ** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate -+ ** function and a window function should have failed before reaching -+ ** this point. And, it is not possible to have a window function and -+ ** a scalar function with the same name and number of arguments. So -+ ** if we reach this point, either A and B both window functions or -+ ** neither are a window functions. */ -+ assert( ExprHasProperty(pA,EP_WinFunc)==ExprHasProperty(pB,EP_WinFunc) ); -+ if( ExprHasProperty(pA,EP_WinFunc) ){ -+ if( sqlite3WindowCompare(pParse,pA->y.pWin,pB->y.pWin)!=0 ) return 2; -+ } -+#endif -+ }else if( pA->op==TK_COLLATE ){ -+ if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; - }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ -- return pA->op==TK_COLLATE ? 1 : 2; -+ return 2; - } - } - if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; - if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){ - if( combinedFlags & EP_xIsSelect ) return 2; -- if( sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2; -+ if( (combinedFlags & EP_FixedCol)==0 -+ && sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2; - if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2; - if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; -- if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){ -+ assert( (combinedFlags & EP_Reduced)==0 ); -+ if( pA->op!=TK_STRING && pA->op!=TK_TRUEFALSE ){ - if( pA->iColumn!=pB->iColumn ) return 2; - if( pA->iTable!=pB->iTable - && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2; -@@ -96450,6 +100970,102 @@ - } - - /* -+** This is the Expr node callback for sqlite3ExprImpliesNotNullRow(). -+** 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. -+** -+** This routine controls an optimization. False positives (setting -+** pWalker->eCode to 1 when it should not be) are deadly, but false-negatives -+** (never setting pWalker->eCode) is a harmless missed optimization. -+*/ -+static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ -+ testcase( pExpr->op==TK_AGG_COLUMN ); -+ testcase( pExpr->op==TK_AGG_FUNCTION ); -+ if( ExprHasProperty(pExpr, EP_FromJoin) ) return WRC_Prune; -+ switch( pExpr->op ){ -+ case TK_ISNOT: -+ case TK_NOT: -+ case TK_ISNULL: -+ case TK_IS: -+ case TK_OR: -+ case TK_CASE: -+ case TK_IN: -+ case TK_FUNCTION: -+ testcase( pExpr->op==TK_ISNOT ); -+ testcase( pExpr->op==TK_NOT ); -+ testcase( pExpr->op==TK_ISNULL ); -+ testcase( pExpr->op==TK_IS ); -+ testcase( pExpr->op==TK_OR ); -+ testcase( pExpr->op==TK_CASE ); -+ testcase( pExpr->op==TK_IN ); -+ testcase( pExpr->op==TK_FUNCTION ); -+ return WRC_Prune; -+ case TK_COLUMN: -+ if( pWalker->u.iCur==pExpr->iTable ){ -+ pWalker->eCode = 1; -+ return WRC_Abort; -+ } -+ return WRC_Prune; -+ -+ /* Virtual tables are allowed to use constraints like x=NULL. So -+ ** a term of the form x=y does not prove that y is not null if x -+ ** is the column of a virtual table */ -+ case TK_EQ: -+ case TK_NE: -+ case TK_LT: -+ case TK_LE: -+ case TK_GT: -+ case TK_GE: -+ testcase( pExpr->op==TK_EQ ); -+ testcase( pExpr->op==TK_NE ); -+ testcase( pExpr->op==TK_LT ); -+ testcase( pExpr->op==TK_LE ); -+ testcase( pExpr->op==TK_GT ); -+ testcase( pExpr->op==TK_GE ); -+ if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab)) -+ || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab)) -+ ){ -+ return WRC_Prune; -+ } -+ default: -+ return WRC_Continue; -+ } -+} -+ -+/* -+** Return true (non-zero) if expression p can only be true if at least -+** one column of table iTab is non-null. In other words, return true -+** if expression p will always be NULL or false if every column of iTab -+** is NULL. -+** -+** False negatives are acceptable. In other words, it is ok to return -+** zero even if expression p will never be true of every column of iTab -+** is NULL. A false negative is merely a missed optimization opportunity. -+** -+** False positives are not allowed, however. A false positive may result -+** in an incorrect answer. -+** -+** Terms of p that are marked with EP_FromJoin (and hence that come from -+** the ON or USING clauses of LEFT JOINS) are excluded from the analysis. -+** -+** This routine is used to check if a LEFT JOIN can be converted into -+** an ordinary JOIN. The p argument is the WHERE clause. If the WHERE -+** clause requires that some column of the right table of the LEFT JOIN -+** be non-NULL, then the LEFT JOIN can be safely converted into an -+** ordinary join. -+*/ -+SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){ -+ Walker w; -+ w.xExprCallback = impliesNotNullRow; -+ w.xSelectCallback = 0; -+ w.xSelectCallback2 = 0; -+ w.eCode = 0; -+ w.u.iCur = iTab; -+ sqlite3WalkExpr(&w, p); -+ return w.eCode; -+} -+ -+/* - ** An instance of the following structure is used by the tree walker - ** to determine if an expression can be evaluated by reference to the - ** index only, without having to do a search for the corresponding -@@ -96604,8 +101220,9 @@ - NameContext *pNC = pWalker->u.pNC; - Parse *pParse = pNC->pParse; - SrcList *pSrcList = pNC->pSrcList; -- AggInfo *pAggInfo = pNC->pAggInfo; -+ AggInfo *pAggInfo = pNC->uNC.pAggInfo; - -+ assert( pNC->ncFlags & NC_UAggInfo ); - switch( pExpr->op ){ - case TK_AGG_COLUMN: - case TK_COLUMN: { -@@ -96637,7 +101254,7 @@ - && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 - ){ - pCol = &pAggInfo->aCol[k]; -- pCol->pTab = pExpr->pTab; -+ pCol->pTab = pExpr->y.pTab; - pCol->iTable = pExpr->iTable; - pCol->iColumn = pExpr->iColumn; - pCol->iMem = ++pParse->nMem; -@@ -96783,21 +101400,9 @@ - /* - ** Deallocate a register, making available for reuse for some other - ** purpose. --** --** If a register is currently being used by the column cache, then --** the deallocation is deferred until the column cache line that uses --** the register becomes stale. - */ - SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){ - if( iReg && pParse->nTempReg<ArraySize(pParse->aTempReg) ){ -- int i; -- struct yColCache *p; -- for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){ -- if( p->iReg==iReg ){ -- p->tempReg = 1; -- return; -- } -- } - pParse->aTempReg[pParse->nTempReg++] = iReg; - } - } -@@ -96811,7 +101416,6 @@ - i = pParse->iRangeReg; - n = pParse->nRangeReg; - if( nReg<=n ){ -- assert( !usedAsColumnCache(pParse, i, i+n-1) ); - pParse->iRangeReg += nReg; - pParse->nRangeReg -= nReg; - }else{ -@@ -96825,7 +101429,6 @@ - sqlite3ReleaseTempReg(pParse, iReg); - return; - } -- sqlite3ExprCacheRemove(pParse, iReg, nReg); - if( nReg>pParse->nRangeReg ){ - pParse->nRangeReg = nReg; - pParse->iRangeReg = iReg; -@@ -96887,369 +101490,66 @@ - */ - #ifndef SQLITE_OMIT_ALTERTABLE - -- - /* --** This function is used by SQL generated to implement the --** ALTER TABLE command. The first argument is the text of a CREATE TABLE or --** CREATE INDEX command. The second is a table name. The table name in --** the CREATE TABLE or CREATE INDEX statement is replaced with the third --** argument and the result returned. Examples: -+** Parameter zName is the name of a table that is about to be altered -+** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN). -+** If the table is a system table, this function leaves an error message -+** in pParse->zErr (system tables may not be altered) and returns non-zero. - ** --** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def') --** -> 'CREATE TABLE def(a, b, c)' --** --** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def') --** -> 'CREATE INDEX i ON def(a, b, c)' -+** Or, if zName is not a system table, zero is returned. - */ --static void renameTableFunc( -- sqlite3_context *context, -- int NotUsed, -- sqlite3_value **argv --){ -- unsigned char const *zSql = sqlite3_value_text(argv[0]); -- unsigned char const *zTableName = sqlite3_value_text(argv[1]); -- -- int token; -- Token tname; -- unsigned char const *zCsr = zSql; -- int len = 0; -- char *zRet; -- -- sqlite3 *db = sqlite3_context_db_handle(context); -- -- UNUSED_PARAMETER(NotUsed); -- -- /* The principle used to locate the table name in the CREATE TABLE -- ** statement is that the table name is the first non-space token that -- ** is immediately followed by a TK_LP or TK_USING token. -- */ -- if( zSql ){ -- do { -- if( !*zCsr ){ -- /* Ran out of input before finding an opening bracket. Return NULL. */ -- return; -- } -- -- /* Store the token that zCsr points to in tname. */ -- tname.z = (char*)zCsr; -- tname.n = len; -- -- /* Advance zCsr to the next token. Store that token type in 'token', -- ** and its length in 'len' (to be used next iteration of this loop). -- */ -- do { -- zCsr += len; -- len = sqlite3GetToken(zCsr, &token); -- } while( token==TK_SPACE ); -- assert( len>0 ); -- } while( token!=TK_LP && token!=TK_USING ); -- -- zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql), -- zSql, zTableName, tname.z+tname.n); -- sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); -+static int isSystemTable(Parse *pParse, const char *zName){ -+ if( 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ -+ sqlite3ErrorMsg(pParse, "table %s may not be altered", zName); -+ return 1; - } -+ return 0; - } - - /* --** This C function implements an SQL user function that is used by SQL code --** generated by the ALTER TABLE ... RENAME command to modify the definition --** of any foreign key constraints that use the table being renamed as the --** parent table. It is passed three arguments: --** --** 1) The complete text of the CREATE TABLE statement being modified, --** 2) The old name of the table being renamed, and --** 3) The new name of the table being renamed. --** --** It returns the new CREATE TABLE statement. For example: --** --** sqlite_rename_parent('CREATE TABLE t1(a REFERENCES t2)', 't2', 't3') --** -> 'CREATE TABLE t1(a REFERENCES t3)' -+** Generate code to verify that the schemas of database zDb and, if -+** bTemp is not true, database "temp", can still be parsed. This is -+** called at the end of the generation of an ALTER TABLE ... RENAME ... -+** statement to ensure that the operation has not rendered any schema -+** objects unusable. - */ --#ifndef SQLITE_OMIT_FOREIGN_KEY --static void renameParentFunc( -- sqlite3_context *context, -- int NotUsed, -- sqlite3_value **argv --){ -- sqlite3 *db = sqlite3_context_db_handle(context); -- char *zOutput = 0; -- char *zResult; -- unsigned char const *zInput = sqlite3_value_text(argv[0]); -- unsigned char const *zOld = sqlite3_value_text(argv[1]); -- unsigned char const *zNew = sqlite3_value_text(argv[2]); -+static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ -+ sqlite3NestedParse(pParse, -+ "SELECT 1 " -+ "FROM \"%w\".%s " -+ "WHERE name NOT LIKE 'sqlite_%%'" -+ " AND sql NOT LIKE 'create virtual%%'" -+ " AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ", -+ zDb, MASTER_NAME, -+ zDb, bTemp -+ ); - -- unsigned const char *z; /* Pointer to token */ -- int n; /* Length of token z */ -- int token; /* Type of token */ -- -- UNUSED_PARAMETER(NotUsed); -- if( zInput==0 || zOld==0 ) return; -- for(z=zInput; *z; z=z+n){ -- n = sqlite3GetToken(z, &token); -- if( token==TK_REFERENCES ){ -- char *zParent; -- do { -- z += n; -- n = sqlite3GetToken(z, &token); -- }while( token==TK_SPACE ); -- -- if( token==TK_ILLEGAL ) break; -- zParent = sqlite3DbStrNDup(db, (const char *)z, n); -- if( zParent==0 ) break; -- sqlite3Dequote(zParent); -- if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){ -- char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"", -- (zOutput?zOutput:""), (int)(z-zInput), zInput, (const char *)zNew -- ); -- sqlite3DbFree(db, zOutput); -- zOutput = zOut; -- zInput = &z[n]; -- } -- sqlite3DbFree(db, zParent); -- } -+ if( bTemp==0 ){ -+ sqlite3NestedParse(pParse, -+ "SELECT 1 " -+ "FROM temp.%s " -+ "WHERE name NOT LIKE 'sqlite_%%'" -+ " AND sql NOT LIKE 'create virtual%%'" -+ " AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ", -+ MASTER_NAME, zDb -+ ); - } -- -- zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), -- sqlite3_result_text(context, zResult, -1, SQLITE_DYNAMIC); -- sqlite3DbFree(db, zOutput); - } --#endif - --#ifndef SQLITE_OMIT_TRIGGER --/* This function is used by SQL generated to implement the --** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER --** statement. The second is a table name. The table name in the CREATE --** TRIGGER statement is replaced with the third argument and the result --** returned. This is analagous to renameTableFunc() above, except for CREATE --** TRIGGER, not CREATE INDEX and CREATE TABLE. --*/ --static void renameTriggerFunc( -- sqlite3_context *context, -- int NotUsed, -- sqlite3_value **argv --){ -- unsigned char const *zSql = sqlite3_value_text(argv[0]); -- unsigned char const *zTableName = sqlite3_value_text(argv[1]); -- -- int token; -- Token tname; -- int dist = 3; -- unsigned char const *zCsr = zSql; -- int len = 0; -- char *zRet; -- sqlite3 *db = sqlite3_context_db_handle(context); -- -- UNUSED_PARAMETER(NotUsed); -- -- /* The principle used to locate the table name in the CREATE TRIGGER -- ** statement is that the table name is the first token that is immediately -- ** preceded by either TK_ON or TK_DOT and immediately followed by one -- ** of TK_WHEN, TK_BEGIN or TK_FOR. -- */ -- if( zSql ){ -- do { -- -- if( !*zCsr ){ -- /* Ran out of input before finding the table name. Return NULL. */ -- return; -- } -- -- /* Store the token that zCsr points to in tname. */ -- tname.z = (char*)zCsr; -- tname.n = len; -- -- /* Advance zCsr to the next token. Store that token type in 'token', -- ** and its length in 'len' (to be used next iteration of this loop). -- */ -- do { -- zCsr += len; -- len = sqlite3GetToken(zCsr, &token); -- }while( token==TK_SPACE ); -- assert( len>0 ); -- -- /* Variable 'dist' stores the number of tokens read since the most -- ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN -- ** token is read and 'dist' equals 2, the condition stated above -- ** to be met. -- ** -- ** Note that ON cannot be a database, table or column name, so -- ** there is no need to worry about syntax like -- ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc. -- */ -- dist++; -- if( token==TK_DOT || token==TK_ON ){ -- dist = 0; -- } -- } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) ); -- -- /* Variable tname now contains the token that is the old table-name -- ** in the CREATE TRIGGER statement. -- */ -- zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql), -- zSql, zTableName, tname.z+tname.n); -- sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); -- } --} --#endif /* !SQLITE_OMIT_TRIGGER */ -- - /* --** Register built-in functions used to help implement ALTER TABLE -+** Generate code to reload the schema for database iDb. And, if iDb!=1, for -+** the temp database as well. - */ --SQLITE_PRIVATE void sqlite3AlterFunctions(void){ -- static FuncDef aAlterTableFuncs[] = { -- FUNCTION(sqlite_rename_table, 2, 0, 0, renameTableFunc), --#ifndef SQLITE_OMIT_TRIGGER -- FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc), --#endif --#ifndef SQLITE_OMIT_FOREIGN_KEY -- FUNCTION(sqlite_rename_parent, 3, 0, 0, renameParentFunc), --#endif -- }; -- sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); --} -- --/* --** This function is used to create the text of expressions of the form: --** --** name=<constant1> OR name=<constant2> OR ... --** --** If argument zWhere is NULL, then a pointer string containing the text --** "name=<constant>" is returned, where <constant> is the quoted version --** of the string passed as argument zConstant. The returned buffer is --** allocated using sqlite3DbMalloc(). It is the responsibility of the --** caller to ensure that it is eventually freed. --** --** If argument zWhere is not NULL, then the string returned is --** "<where> OR name=<constant>", where <where> is the contents of zWhere. --** In this case zWhere is passed to sqlite3DbFree() before returning. --** --*/ --static char *whereOrName(sqlite3 *db, char *zWhere, char *zConstant){ -- char *zNew; -- if( !zWhere ){ -- zNew = sqlite3MPrintf(db, "name=%Q", zConstant); -- }else{ -- zNew = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, zConstant); -- sqlite3DbFree(db, zWhere); -+static void renameReloadSchema(Parse *pParse, int iDb){ -+ Vdbe *v = pParse->pVdbe; -+ if( v ){ -+ sqlite3ChangeCookie(pParse, iDb); -+ sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0); -+ if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0); - } -- return zNew; - } - --#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - /* --** Generate the text of a WHERE expression which can be used to select all --** tables that have foreign key constraints that refer to table pTab (i.e. --** constraints for which pTab is the parent table) from the sqlite_master --** table. --*/ --static char *whereForeignKeys(Parse *pParse, Table *pTab){ -- FKey *p; -- char *zWhere = 0; -- for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ -- zWhere = whereOrName(pParse->db, zWhere, p->pFrom->zName); -- } -- return zWhere; --} --#endif -- --/* --** Generate the text of a WHERE expression which can be used to select all --** temporary triggers on table pTab from the sqlite_temp_master table. If --** table pTab has no temporary triggers, or is itself stored in the --** temporary database, NULL is returned. --*/ --static char *whereTempTriggers(Parse *pParse, Table *pTab){ -- Trigger *pTrig; -- char *zWhere = 0; -- const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */ -- -- /* If the table is not located in the temp-db (in which case NULL is -- ** returned, loop through the tables list of triggers. For each trigger -- ** that is not part of the temp-db schema, add a clause to the WHERE -- ** expression being built up in zWhere. -- */ -- if( pTab->pSchema!=pTempSchema ){ -- sqlite3 *db = pParse->db; -- for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){ -- if( pTrig->pSchema==pTempSchema ){ -- zWhere = whereOrName(db, zWhere, pTrig->zName); -- } -- } -- } -- if( zWhere ){ -- char *zNew = sqlite3MPrintf(pParse->db, "type='trigger' AND (%s)", zWhere); -- sqlite3DbFree(pParse->db, zWhere); -- zWhere = zNew; -- } -- return zWhere; --} -- --/* --** Generate code to drop and reload the internal representation of table --** pTab from the database, including triggers and temporary triggers. --** Argument zName is the name of the table in the database schema at --** the time the generated code is executed. This can be different from --** pTab->zName if this function is being called to code part of an --** "ALTER TABLE RENAME TO" statement. --*/ --static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){ -- Vdbe *v; -- char *zWhere; -- int iDb; /* Index of database containing pTab */ --#ifndef SQLITE_OMIT_TRIGGER -- Trigger *pTrig; --#endif -- -- v = sqlite3GetVdbe(pParse); -- if( NEVER(v==0) ) return; -- assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); -- iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); -- assert( iDb>=0 ); -- --#ifndef SQLITE_OMIT_TRIGGER -- /* Drop any table triggers from the internal schema. */ -- for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){ -- int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); -- assert( iTrigDb==iDb || iTrigDb==1 ); -- sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0); -- } --#endif -- -- /* Drop the table and index from the internal schema. */ -- sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); -- -- /* Reload the table, index and permanent trigger schemas. */ -- zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName); -- if( !zWhere ) return; -- sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); -- --#ifndef SQLITE_OMIT_TRIGGER -- /* Now, if the table is not stored in the temp database, reload any temp -- ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. -- */ -- if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ -- sqlite3VdbeAddParseSchemaOp(v, 1, zWhere); -- } --#endif --} -- --/* --** Parameter zName is the name of a table that is about to be altered --** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN). --** If the table is a system table, this function leaves an error message --** in pParse->zErr (system tables may not be altered) and returns non-zero. --** --** Or, if zName is not a system table, zero is returned. --*/ --static int isSystemTable(Parse *pParse, const char *zName){ -- if( 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ -- sqlite3ErrorMsg(pParse, "table %s may not be altered", zName); -- return 1; -- } -- return 0; --} -- --/* - ** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" - ** command. - */ -@@ -97266,13 +101566,10 @@ - int nTabName; /* Number of UTF-8 characters in zTabName */ - const char *zTabName; /* Original name of the table */ - Vdbe *v; --#ifndef SQLITE_OMIT_TRIGGER -- char *zWhere = 0; /* Where clause to locate temp triggers */ --#endif - VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */ -- int savedDbFlags; /* Saved value of db->flags */ -+ u32 savedDbFlags; /* Saved value of db->mDbFlags */ - -- savedDbFlags = db->flags; -+ savedDbFlags = db->mDbFlags; - if( NEVER(db->mallocFailed) ) goto exit_rename_table; - assert( pSrc->nSrc==1 ); - assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); -@@ -97281,7 +101578,7 @@ - if( !pTab ) goto exit_rename_table; - iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - zDb = db->aDb[iDb].zDbSName; -- db->flags |= SQLITE_PreferBuiltin; -+ db->mDbFlags |= DBFLAG_PreferBuiltin; - - /* Get a NULL terminated version of the new table name. */ - zName = sqlite3NameFromToken(db, pName); -@@ -97341,52 +101638,25 @@ - if( v==0 ){ - goto exit_rename_table; - } -- sqlite3BeginWriteOperation(pParse, pVTab!=0, iDb); -- sqlite3ChangeCookie(pParse, iDb); - -- /* If this is a virtual table, invoke the xRename() function if -- ** one is defined. The xRename() callback will modify the names -- ** of any resources used by the v-table implementation (including other -- ** SQLite tables) that are identified by the name of the virtual table. -- */ --#ifndef SQLITE_OMIT_VIRTUALTABLE -- if( pVTab ){ -- int i = ++pParse->nMem; -- sqlite3VdbeLoadString(v, i, zName); -- sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB); -- sqlite3MayAbort(pParse); -- } --#endif -- - /* figure out how many UTF-8 characters are in zName */ - zTabName = pTab->zName; - nTabName = sqlite3Utf8CharLen(zTabName, -1); - --#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) -- if( db->flags&SQLITE_ForeignKeys ){ -- /* If foreign-key support is enabled, rewrite the CREATE TABLE -- ** statements corresponding to all child tables of foreign key constraints -- ** for which the renamed table is the parent table. */ -- if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){ -- sqlite3NestedParse(pParse, -- "UPDATE \"%w\".%s SET " -- "sql = sqlite_rename_parent(sql, %Q, %Q) " -- "WHERE %s;", zDb, MASTER_NAME, zTabName, zName, zWhere); -- sqlite3DbFree(db, zWhere); -- } -- } --#endif -+ /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in -+ ** the schema to use the new table name. */ -+ sqlite3NestedParse(pParse, -+ "UPDATE \"%w\".%s SET " -+ "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) " -+ "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)" -+ "AND name NOT LIKE 'sqlite_%%'" -+ , zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName -+ ); - -- /* Modify the sqlite_master table to use the new table name. */ -+ /* Update the tbl_name and name columns of the sqlite_master table -+ ** as required. */ - sqlite3NestedParse(pParse, - "UPDATE %Q.%s SET " --#ifdef SQLITE_OMIT_TRIGGER -- "sql = sqlite_rename_table(sql, %Q), " --#else -- "sql = CASE " -- "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)" -- "ELSE sqlite_rename_table(sql, %Q) END, " --#endif - "tbl_name = %Q, " - "name = CASE " - "WHEN type='table' THEN %Q " -@@ -97395,11 +101665,9 @@ - "ELSE name END " - "WHERE tbl_name=%Q COLLATE nocase AND " - "(type='table' OR type='index' OR type='trigger');", -- zDb, MASTER_NAME, zName, zName, zName, --#ifndef SQLITE_OMIT_TRIGGER -- zName, --#endif -- zName, nTabName, zTabName -+ zDb, MASTER_NAME, -+ zName, zName, zName, -+ nTabName, zTabName - ); - - #ifndef SQLITE_OMIT_AUTOINCREMENT -@@ -97413,40 +101681,42 @@ - } - #endif - --#ifndef SQLITE_OMIT_TRIGGER -- /* If there are TEMP triggers on this table, modify the sqlite_temp_master -- ** table. Don't do this if the table being ALTERed is itself located in -- ** the temp database. -- */ -- if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ -+ /* If the table being renamed is not itself part of the temp database, -+ ** edit view and trigger definitions within the temp database -+ ** as required. */ -+ if( iDb!=1 ){ - sqlite3NestedParse(pParse, - "UPDATE sqlite_temp_master SET " -- "sql = sqlite_rename_trigger(sql, %Q), " -- "tbl_name = %Q " -- "WHERE %s;", zName, zName, zWhere); -- sqlite3DbFree(db, zWhere); -+ "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), " -+ "tbl_name = " -+ "CASE WHEN tbl_name=%Q COLLATE nocase AND " -+ " sqlite_rename_test(%Q, sql, type, name, 1) " -+ "THEN %Q ELSE tbl_name END " -+ "WHERE type IN ('view', 'trigger')" -+ , zDb, zTabName, zName, zTabName, zDb, zName); - } --#endif - --#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) -- if( db->flags&SQLITE_ForeignKeys ){ -- FKey *p; -- for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ -- Table *pFrom = p->pFrom; -- if( pFrom!=pTab ){ -- reloadTableSchema(pParse, p->pFrom, pFrom->zName); -- } -- } -+ /* If this is a virtual table, invoke the xRename() function if -+ ** one is defined. The xRename() callback will modify the names -+ ** of any resources used by the v-table implementation (including other -+ ** SQLite tables) that are identified by the name of the virtual table. -+ */ -+#ifndef SQLITE_OMIT_VIRTUALTABLE -+ if( pVTab ){ -+ int i = ++pParse->nMem; -+ sqlite3VdbeLoadString(v, i, zName); -+ sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB); -+ sqlite3MayAbort(pParse); - } - #endif - -- /* Drop and reload the internal table schema. */ -- reloadTableSchema(pParse, pTab, zName); -+ renameReloadSchema(pParse, iDb); -+ renameTestSchema(pParse, zDb, iDb==1); - - exit_rename_table: - sqlite3SrcListDelete(db, pSrc); - sqlite3DbFree(db, zName); -- db->flags = savedDbFlags; -+ db->mDbFlags = savedDbFlags; - } - - /* -@@ -97467,12 +101737,11 @@ - Column *pCol; /* The new column */ - Expr *pDflt; /* Default value for the new column */ - sqlite3 *db; /* The database connection; */ -- Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */ -+ Vdbe *v; /* The prepared statement under construction */ - int r1; /* Temporary registers */ - - db = pParse->db; - if( pParse->nErr || db->mallocFailed ) return; -- assert( v!=0 ); - pNew = pParse->pNewTable; - assert( pNew ); - -@@ -97547,11 +101816,11 @@ - zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n); - if( zCol ){ - char *zEnd = &zCol[pColDef->n-1]; -- int savedDbFlags = db->flags; -+ u32 savedDbFlags = db->mDbFlags; - while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){ - *zEnd-- = '\0'; - } -- db->flags |= SQLITE_PreferBuiltin; -+ db->mDbFlags |= DBFLAG_PreferBuiltin; - sqlite3NestedParse(pParse, - "UPDATE \"%w\".%s SET " - "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " -@@ -97560,7 +101829,7 @@ - zTab - ); - sqlite3DbFree(db, zCol); -- db->flags = savedDbFlags; -+ db->mDbFlags = savedDbFlags; - } - - /* Make sure the schema version is at least 3. But do not upgrade -@@ -97567,17 +101836,20 @@ - ** from less than 3 to 4, as that will corrupt any preexisting DESC - ** index. - */ -- r1 = sqlite3GetTempReg(pParse); -- sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); -- sqlite3VdbeUsesBtree(v, iDb); -- sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2); -- sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2); -- VdbeCoverage(v); -- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3); -- sqlite3ReleaseTempReg(pParse, r1); -+ v = sqlite3GetVdbe(pParse); -+ if( v ){ -+ r1 = sqlite3GetTempReg(pParse); -+ sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); -+ sqlite3VdbeUsesBtree(v, iDb); -+ sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2); -+ sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2); -+ VdbeCoverage(v); -+ sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3); -+ sqlite3ReleaseTempReg(pParse, r1); -+ } - -- /* Reload the schema of the modified table. */ -- reloadTableSchema(pParse, pTab, pTab->zName); -+ /* Reload the table definition */ -+ renameReloadSchema(pParse, iDb); - } - - /* -@@ -97598,7 +101870,6 @@ - SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ - Table *pNew; - Table *pTab; -- Vdbe *v; - int iDb; - int i; - int nAlloc; -@@ -97662,16 +101933,1146 @@ - pNew->addColOffset = pTab->addColOffset; - pNew->nTabRef = 1; - -- /* Begin a transaction and increment the schema cookie. */ -- sqlite3BeginWriteOperation(pParse, 0, iDb); -- v = sqlite3GetVdbe(pParse); -- if( !v ) goto exit_begin_add_column; -- sqlite3ChangeCookie(pParse, iDb); -- - exit_begin_add_column: - sqlite3SrcListDelete(db, pSrc); - return; - } -+ -+/* -+** Parameter pTab is the subject of an ALTER TABLE ... RENAME COLUMN -+** command. This function checks if the table is a view or virtual -+** table (columns of views or virtual tables may not be renamed). If so, -+** it loads an error message into pParse and returns non-zero. -+** -+** Or, if pTab is not a view or virtual table, zero is returned. -+*/ -+#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) -+static int isRealTable(Parse *pParse, Table *pTab){ -+ const char *zType = 0; -+#ifndef SQLITE_OMIT_VIEW -+ if( pTab->pSelect ){ -+ zType = "view"; -+ } -+#endif -+#ifndef SQLITE_OMIT_VIRTUALTABLE -+ if( IsVirtual(pTab) ){ -+ zType = "virtual table"; -+ } -+#endif -+ if( zType ){ -+ sqlite3ErrorMsg( -+ pParse, "cannot rename columns of %s \"%s\"", zType, pTab->zName -+ ); -+ return 1; -+ } -+ return 0; -+} -+#else /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ -+# define isRealTable(x,y) (0) -+#endif -+ -+/* -+** Handles the following parser reduction: -+** -+** cmd ::= ALTER TABLE pSrc RENAME COLUMN pOld TO pNew -+*/ -+SQLITE_PRIVATE void sqlite3AlterRenameColumn( -+ Parse *pParse, /* Parsing context */ -+ SrcList *pSrc, /* Table being altered. pSrc->nSrc==1 */ -+ Token *pOld, /* Name of column being changed */ -+ Token *pNew /* New column name */ -+){ -+ sqlite3 *db = pParse->db; /* Database connection */ -+ Table *pTab; /* Table being updated */ -+ int iCol; /* Index of column being renamed */ -+ char *zOld = 0; /* Old column name */ -+ char *zNew = 0; /* New column name */ -+ const char *zDb; /* Name of schema containing the table */ -+ int iSchema; /* Index of the schema */ -+ int bQuote; /* True to quote the new name */ -+ -+ /* Locate the table to be altered */ -+ pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); -+ if( !pTab ) goto exit_rename_column; -+ -+ /* Cannot alter a system table */ -+ if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ) goto exit_rename_column; -+ if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column; -+ -+ /* Which schema holds the table to be altered */ -+ iSchema = sqlite3SchemaToIndex(db, pTab->pSchema); -+ assert( iSchema>=0 ); -+ zDb = db->aDb[iSchema].zDbSName; -+ -+#ifndef SQLITE_OMIT_AUTHORIZATION -+ /* Invoke the authorization callback. */ -+ if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ -+ goto exit_rename_column; -+ } -+#endif -+ -+ /* Make sure the old name really is a column name in the table to be -+ ** altered. Set iCol to be the index of the column being renamed */ -+ zOld = sqlite3NameFromToken(db, pOld); -+ if( !zOld ) goto exit_rename_column; -+ for(iCol=0; iCol<pTab->nCol; iCol++){ -+ if( 0==sqlite3StrICmp(pTab->aCol[iCol].zName, zOld) ) break; -+ } -+ if( iCol==pTab->nCol ){ -+ sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld); -+ goto exit_rename_column; -+ } -+ -+ /* Do the rename operation using a recursive UPDATE statement that -+ ** uses the sqlite_rename_column() SQL function to compute the new -+ ** CREATE statement text for the sqlite_master table. -+ */ -+ zNew = sqlite3NameFromToken(db, pNew); -+ if( !zNew ) goto exit_rename_column; -+ assert( pNew->n>0 ); -+ bQuote = sqlite3Isquote(pNew->z[0]); -+ sqlite3NestedParse(pParse, -+ "UPDATE \"%w\".%s SET " -+ "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) " -+ "WHERE name NOT LIKE 'sqlite_%%' AND (type != 'index' OR tbl_name = %Q)" -+ " AND sql NOT LIKE 'create virtual%%'", -+ zDb, MASTER_NAME, -+ zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1, -+ pTab->zName -+ ); -+ -+ sqlite3NestedParse(pParse, -+ "UPDATE temp.%s SET " -+ "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) " -+ "WHERE type IN ('trigger', 'view')", -+ MASTER_NAME, -+ zDb, pTab->zName, iCol, zNew, bQuote -+ ); -+ -+ /* Drop and reload the database schema. */ -+ renameReloadSchema(pParse, iSchema); -+ renameTestSchema(pParse, zDb, iSchema==1); -+ -+ exit_rename_column: -+ sqlite3SrcListDelete(db, pSrc); -+ sqlite3DbFree(db, zOld); -+ sqlite3DbFree(db, zNew); -+ return; -+} -+ -+/* -+** Each RenameToken object maps an element of the parse tree into -+** the token that generated that element. The parse tree element -+** might be one of: -+** -+** * A pointer to an Expr that represents an ID -+** * The name of a table column in Column.zName -+** -+** A list of RenameToken objects can be constructed during parsing. -+** Each new object is created by sqlite3RenameTokenMap(). -+** As the parse tree is transformed, the sqlite3RenameTokenRemap() -+** routine is used to keep the mapping current. -+** -+** After the parse finishes, renameTokenFind() routine can be used -+** to look up the actual token value that created some element in -+** the parse tree. -+*/ -+struct RenameToken { -+ void *p; /* Parse tree element created by token t */ -+ Token t; /* The token that created parse tree element p */ -+ RenameToken *pNext; /* Next is a list of all RenameToken objects */ -+}; -+ -+/* -+** The context of an ALTER TABLE RENAME COLUMN operation that gets passed -+** down into the Walker. -+*/ -+typedef struct RenameCtx RenameCtx; -+struct RenameCtx { -+ RenameToken *pList; /* List of tokens to overwrite */ -+ int nList; /* Number of tokens in pList */ -+ int iCol; /* Index of column being renamed */ -+ Table *pTab; /* Table being ALTERed */ -+ const char *zOld; /* Old column name */ -+}; -+ -+#ifdef SQLITE_DEBUG -+/* -+** This function is only for debugging. It performs two tasks: -+** -+** 1. Checks that pointer pPtr does not already appear in the -+** rename-token list. -+** -+** 2. Dereferences each pointer in the rename-token list. -+** -+** The second is most effective when debugging under valgrind or -+** address-sanitizer or similar. If any of these pointers no longer -+** point to valid objects, an exception is raised by the memory-checking -+** tool. -+** -+** The point of this is to prevent comparisons of invalid pointer values. -+** Even though this always seems to work, it is undefined according to the -+** C standard. Example of undefined comparison: -+** -+** sqlite3_free(x); -+** if( x==y ) ... -+** -+** Technically, as x no longer points into a valid object or to the byte -+** following a valid object, it may not be used in comparison operations. -+*/ -+static void renameTokenCheckAll(Parse *pParse, void *pPtr){ -+ if( pParse->nErr==0 && pParse->db->mallocFailed==0 ){ -+ RenameToken *p; -+ u8 i = 0; -+ for(p=pParse->pRename; p; p=p->pNext){ -+ if( p->p ){ -+ assert( p->p!=pPtr ); -+ i += *(u8*)(p->p); -+ } -+ } -+ } -+} -+#else -+# define renameTokenCheckAll(x,y) -+#endif -+ -+/* -+** Remember that the parser tree element pPtr was created using -+** the token pToken. -+** -+** In other words, construct a new RenameToken object and add it -+** to the list of RenameToken objects currently being built up -+** in pParse->pRename. -+** -+** The pPtr argument is returned so that this routine can be used -+** with tail recursion in tokenExpr() routine, for a small performance -+** improvement. -+*/ -+SQLITE_PRIVATE 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; -+ } -+ -+ return pPtr; -+} -+ -+/* -+** It is assumed that there is already a RenameToken object associated -+** with parse tree element pFrom. This function remaps the associated token -+** to parse tree element pTo. -+*/ -+SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse *pParse, void *pTo, void *pFrom){ -+ RenameToken *p; -+ renameTokenCheckAll(pParse, pTo); -+ for(p=pParse->pRename; p; p=p->pNext){ -+ if( p->p==pFrom ){ -+ p->p = pTo; -+ break; -+ } -+ } -+} -+ -+/* -+** Walker callback used by sqlite3RenameExprUnmap(). -+*/ -+static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){ -+ Parse *pParse = pWalker->pParse; -+ sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr); -+ return WRC_Continue; -+} -+ -+/* -+** Remove all nodes that are part of expression pExpr from the rename list. -+*/ -+SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){ -+ Walker sWalker; -+ memset(&sWalker, 0, sizeof(Walker)); -+ sWalker.pParse = pParse; -+ sWalker.xExprCallback = renameUnmapExprCb; -+ sqlite3WalkExpr(&sWalker, pExpr); -+} -+ -+/* -+** Remove all nodes that are part of expression-list pEList from the -+** rename list. -+*/ -+SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){ -+ if( pEList ){ -+ int i; -+ Walker sWalker; -+ memset(&sWalker, 0, sizeof(Walker)); -+ sWalker.pParse = pParse; -+ sWalker.xExprCallback = renameUnmapExprCb; -+ sqlite3WalkExprList(&sWalker, pEList); -+ for(i=0; i<pEList->nExpr; i++){ -+ sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zName); -+ } -+ } -+} -+ -+/* -+** Free the list of RenameToken objects given in the second argument -+*/ -+static void renameTokenFree(sqlite3 *db, RenameToken *pToken){ -+ RenameToken *pNext; -+ RenameToken *p; -+ for(p=pToken; p; p=pNext){ -+ pNext = p->pNext; -+ sqlite3DbFree(db, p); -+ } -+} -+ -+/* -+** Search the Parse object passed as the first argument for a RenameToken -+** object associated with parse tree element pPtr. If found, remove it -+** from the Parse object and add it to the list maintained by the -+** RenameCtx object passed as the second argument. -+*/ -+static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){ -+ RenameToken **pp; -+ assert( pPtr!=0 ); -+ for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){ -+ if( (*pp)->p==pPtr ){ -+ RenameToken *pToken = *pp; -+ *pp = pToken->pNext; -+ pToken->pNext = pCtx->pList; -+ pCtx->pList = pToken; -+ pCtx->nList++; -+ break; -+ } -+ } -+} -+ -+/* -+** 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){ -+ UNUSED_PARAMETER(pWalker); -+ UNUSED_PARAMETER(p); -+ return WRC_Continue; -+} -+ -+/* -+** This is a Walker expression callback. -+** -+** For every TK_COLUMN node in the expression tree, search to see -+** if the column being references is the column being renamed by an -+** ALTER TABLE statement. If it is, then attach its associated -+** RenameToken object to the list of RenameToken objects being -+** constructed in RenameCtx object at pWalker->u.pRename. -+*/ -+static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){ -+ RenameCtx *p = pWalker->u.pRename; -+ if( pExpr->op==TK_TRIGGER -+ && pExpr->iColumn==p->iCol -+ && pWalker->pParse->pTriggerTab==p->pTab -+ ){ -+ renameTokenFind(pWalker->pParse, p, (void*)pExpr); -+ }else if( pExpr->op==TK_COLUMN -+ && pExpr->iColumn==p->iCol -+ && p->pTab==pExpr->y.pTab -+ ){ -+ renameTokenFind(pWalker->pParse, p, (void*)pExpr); -+ } -+ return WRC_Continue; -+} -+ -+/* -+** The RenameCtx contains a list of tokens that reference a column that -+** is being renamed by an ALTER TABLE statement. Return the "last" -+** RenameToken in the RenameCtx and remove that RenameToken from the -+** RenameContext. "Last" means the last RenameToken encountered when -+** the input SQL is parsed from left to right. Repeated calls to this routine -+** return all column name tokens in the order that they are encountered -+** in the SQL statement. -+*/ -+static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){ -+ RenameToken *pBest = pCtx->pList; -+ RenameToken *pToken; -+ RenameToken **pp; -+ -+ for(pToken=pBest->pNext; pToken; pToken=pToken->pNext){ -+ if( pToken->t.z>pBest->t.z ) pBest = pToken; -+ } -+ for(pp=&pCtx->pList; *pp!=pBest; pp=&(*pp)->pNext); -+ *pp = pBest->pNext; -+ -+ return pBest; -+} -+ -+/* -+** An error occured while parsing or otherwise processing a database -+** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an -+** ALTER TABLE RENAME COLUMN program. The error message emitted by the -+** sub-routine is currently stored in pParse->zErrMsg. This function -+** adds context to the error message and then stores it in pCtx. -+*/ -+static void renameColumnParseError( -+ sqlite3_context *pCtx, -+ int bPost, -+ sqlite3_value *pType, -+ sqlite3_value *pObject, -+ Parse *pParse -+){ -+ const char *zT = (const char*)sqlite3_value_text(pType); -+ const char *zN = (const char*)sqlite3_value_text(pObject); -+ char *zErr; -+ -+ zErr = sqlite3_mprintf("error in %s %s%s: %s", -+ zT, zN, (bPost ? " after rename" : ""), -+ pParse->zErrMsg -+ ); -+ sqlite3_result_error(pCtx, zErr, -1); -+ sqlite3_free(zErr); -+} -+ -+/* -+** For each name in the the expression-list pEList (i.e. each -+** pEList->a[i].zName) that matches the string in zOld, extract the -+** corresponding rename-token from Parse object pParse and add it -+** to the RenameCtx pCtx. -+*/ -+static void renameColumnElistNames( -+ Parse *pParse, -+ RenameCtx *pCtx, -+ ExprList *pEList, -+ const char *zOld -+){ -+ if( pEList ){ -+ int i; -+ for(i=0; i<pEList->nExpr; i++){ -+ char *zName = pEList->a[i].zName; -+ if( 0==sqlite3_stricmp(zName, zOld) ){ -+ renameTokenFind(pParse, pCtx, (void*)zName); -+ } -+ } -+ } -+} -+ -+/* -+** For each name in the the id-list pIdList (i.e. each pIdList->a[i].zName) -+** that matches the string in zOld, extract the corresponding rename-token -+** from Parse object pParse and add it to the RenameCtx pCtx. -+*/ -+static void renameColumnIdlistNames( -+ Parse *pParse, -+ RenameCtx *pCtx, -+ IdList *pIdList, -+ const char *zOld -+){ -+ if( pIdList ){ -+ int i; -+ for(i=0; i<pIdList->nId; i++){ -+ char *zName = pIdList->a[i].zName; -+ if( 0==sqlite3_stricmp(zName, zOld) ){ -+ renameTokenFind(pParse, pCtx, (void*)zName); -+ } -+ } -+ } -+} -+ -+/* -+** Parse the SQL statement zSql using Parse object (*p). The Parse object -+** is initialized by this function before it is used. -+*/ -+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 */ -+){ -+ int rc; -+ char *zErr = 0; -+ -+ db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb); -+ -+ /* Parse the SQL statement passed as the first argument. If no error -+ ** 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->db = db; -+ p->nQueryLoop = 1; -+ rc = sqlite3RunParser(p, zSql, &zErr); -+ assert( p->zErrMsg==0 ); -+ assert( rc!=SQLITE_OK || zErr==0 ); -+ assert( (0!=p->pNewTable) + (0!=p->pNewIndex) + (0!=p->pNewTrigger)<2 ); -+ p->zErrMsg = zErr; -+ if( db->mallocFailed ) rc = SQLITE_NOMEM; -+ if( rc==SQLITE_OK -+ && p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0 -+ ){ -+ rc = SQLITE_CORRUPT_BKPT; -+ } -+ -+#ifdef SQLITE_DEBUG -+ /* Ensure that all mappings in the Parse.pRename list really do map to -+ ** a part of the input string. */ -+ if( rc==SQLITE_OK ){ -+ int nSql = sqlite3Strlen30(zSql); -+ RenameToken *pToken; -+ for(pToken=p->pRename; pToken; pToken=pToken->pNext){ -+ assert( pToken->t.z>=zSql && &pToken->t.z[pToken->t.n]<=&zSql[nSql] ); -+ } -+ } -+#endif -+ -+ db->init.iDb = 0; -+ return rc; -+} -+ -+/* -+** This function edits SQL statement zSql, replacing each token identified -+** by the linked list pRename with the text of zNew. If argument bQuote is -+** true, then zNew is always quoted first. If no error occurs, the result -+** is loaded into context object pCtx as the result. -+** -+** Or, if an error occurs (i.e. an OOM condition), an error is left in -+** pCtx and an SQLite error code returned. -+*/ -+static int renameEditSql( -+ sqlite3_context *pCtx, /* Return result here */ -+ RenameCtx *pRename, /* Rename context */ -+ const char *zSql, /* SQL statement to edit */ -+ const char *zNew, /* New token text */ -+ int bQuote /* True to always quote token */ -+){ -+ int nNew = sqlite3Strlen30(zNew); -+ int nSql = sqlite3Strlen30(zSql); -+ sqlite3 *db = sqlite3_context_db_handle(pCtx); -+ int rc = SQLITE_OK; -+ char *zQuot; -+ char *zOut; -+ int nQuot; -+ -+ /* Set zQuot to point to a buffer containing a quoted copy of the -+ ** identifier zNew. If the corresponding identifier in the original -+ ** ALTER TABLE statement was quoted (bQuote==1), then set zNew to -+ ** point to zQuot so that all substitutions are made using the -+ ** quoted version of the new column name. */ -+ zQuot = sqlite3MPrintf(db, "\"%w\"", zNew); -+ if( zQuot==0 ){ -+ return SQLITE_NOMEM; -+ }else{ -+ nQuot = sqlite3Strlen30(zQuot); -+ } -+ if( bQuote ){ -+ zNew = zQuot; -+ nNew = nQuot; -+ } -+ -+ /* At this point pRename->pList contains a list of RenameToken objects -+ ** corresponding to all tokens in the input SQL that must be replaced -+ ** with the new column name. All that remains is to construct and -+ ** return the edited SQL string. */ -+ assert( nQuot>=nNew ); -+ zOut = sqlite3DbMallocZero(db, nSql + pRename->nList*nQuot + 1); -+ if( zOut ){ -+ int nOut = nSql; -+ memcpy(zOut, zSql, nSql); -+ while( pRename->pList ){ -+ int iOff; /* Offset of token to replace in zOut */ -+ RenameToken *pBest = renameColumnTokenNext(pRename); -+ -+ u32 nReplace; -+ const char *zReplace; -+ if( sqlite3IsIdChar(*pBest->t.z) ){ -+ nReplace = nNew; -+ zReplace = zNew; -+ }else{ -+ nReplace = nQuot; -+ zReplace = zQuot; -+ } -+ -+ iOff = pBest->t.z - zSql; -+ if( pBest->t.n!=nReplace ){ -+ memmove(&zOut[iOff + nReplace], &zOut[iOff + pBest->t.n], -+ nOut - (iOff + pBest->t.n) -+ ); -+ nOut += nReplace - pBest->t.n; -+ zOut[nOut] = '\0'; -+ } -+ memcpy(&zOut[iOff], zReplace, nReplace); -+ sqlite3DbFree(db, pBest); -+ } -+ -+ sqlite3_result_text(pCtx, zOut, -1, SQLITE_TRANSIENT); -+ sqlite3DbFree(db, zOut); -+ }else{ -+ rc = SQLITE_NOMEM; -+ } -+ -+ sqlite3_free(zQuot); -+ return rc; -+} -+ -+/* -+** Resolve all symbols in the trigger at pParse->pNewTrigger, assuming -+** it was read from the schema of database zDb. Return SQLITE_OK if -+** successful. Otherwise, return an SQLite error code and leave an error -+** message in the Parse object. -+*/ -+static int renameResolveTrigger(Parse *pParse, const char *zDb){ -+ sqlite3 *db = pParse->db; -+ Trigger *pNew = pParse->pNewTrigger; -+ TriggerStep *pStep; -+ NameContext sNC; -+ int rc = SQLITE_OK; -+ -+ memset(&sNC, 0, sizeof(sNC)); -+ sNC.pParse = pParse; -+ assert( pNew->pTabSchema ); -+ pParse->pTriggerTab = sqlite3FindTable(db, pNew->table, -+ db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName -+ ); -+ pParse->eTriggerOp = pNew->op; -+ /* ALWAYS() because if the table of the trigger does not exist, the -+ ** error would have been hit before this point */ -+ if( ALWAYS(pParse->pTriggerTab) ){ -+ rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab); -+ } -+ -+ /* Resolve symbols in WHEN clause */ -+ if( rc==SQLITE_OK && pNew->pWhen ){ -+ rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen); -+ } -+ -+ for(pStep=pNew->step_list; rc==SQLITE_OK && pStep; pStep=pStep->pNext){ -+ if( pStep->pSelect ){ -+ sqlite3SelectPrep(pParse, pStep->pSelect, &sNC); -+ if( pParse->nErr ) rc = pParse->rc; -+ } -+ if( rc==SQLITE_OK && pStep->zTarget ){ -+ Table *pTarget = sqlite3LocateTable(pParse, 0, pStep->zTarget, zDb); -+ if( pTarget==0 ){ -+ rc = SQLITE_ERROR; -+ }else if( SQLITE_OK==(rc = sqlite3ViewGetColumnNames(pParse, pTarget)) ){ -+ SrcList sSrc; -+ memset(&sSrc, 0, sizeof(sSrc)); -+ sSrc.nSrc = 1; -+ sSrc.a[0].zName = pStep->zTarget; -+ sSrc.a[0].pTab = pTarget; -+ sNC.pSrcList = &sSrc; -+ if( pStep->pWhere ){ -+ rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere); -+ } -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList); -+ } -+ assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) ); -+ if( pStep->pUpsert ){ -+ Upsert *pUpsert = pStep->pUpsert; -+ assert( rc==SQLITE_OK ); -+ pUpsert->pUpsertSrc = &sSrc; -+ sNC.uNC.pUpsert = pUpsert; -+ sNC.ncFlags = NC_UUpsert; -+ rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); -+ if( rc==SQLITE_OK ){ -+ ExprList *pUpsertSet = pUpsert->pUpsertSet; -+ rc = sqlite3ResolveExprListNames(&sNC, pUpsertSet); -+ } -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertWhere); -+ } -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); -+ } -+ sNC.ncFlags = 0; -+ } -+ } -+ } -+ } -+ return rc; -+} -+ -+/* -+** Invoke sqlite3WalkExpr() or sqlite3WalkSelect() on all Select or Expr -+** objects that are part of the trigger passed as the second argument. -+*/ -+static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){ -+ TriggerStep *pStep; -+ -+ /* Find tokens to edit in WHEN clause */ -+ sqlite3WalkExpr(pWalker, pTrigger->pWhen); -+ -+ /* Find tokens to edit in trigger steps */ -+ for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){ -+ sqlite3WalkSelect(pWalker, pStep->pSelect); -+ sqlite3WalkExpr(pWalker, pStep->pWhere); -+ sqlite3WalkExprList(pWalker, pStep->pExprList); -+ if( pStep->pUpsert ){ -+ Upsert *pUpsert = pStep->pUpsert; -+ sqlite3WalkExprList(pWalker, pUpsert->pUpsertTarget); -+ sqlite3WalkExprList(pWalker, pUpsert->pUpsertSet); -+ sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere); -+ sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere); -+ } -+ } -+} -+ -+/* -+** Free the contents of Parse object (*pParse). Do not free the memory -+** occupied by the Parse object itself. -+*/ -+static void renameParseCleanup(Parse *pParse){ -+ sqlite3 *db = pParse->db; -+ if( pParse->pVdbe ){ -+ sqlite3VdbeFinalize(pParse->pVdbe); -+ } -+ sqlite3DeleteTable(db, pParse->pNewTable); -+ if( pParse->pNewIndex ) sqlite3FreeIndex(db, pParse->pNewIndex); -+ sqlite3DeleteTrigger(db, pParse->pNewTrigger); -+ sqlite3DbFree(db, pParse->zErrMsg); -+ renameTokenFree(db, pParse->pRename); -+ sqlite3ParserReset(pParse); -+} -+ -+/* -+** SQL function: -+** -+** sqlite_rename_column(zSql, iCol, bQuote, zNew, zTable, zOld) -+** -+** 0. zSql: SQL statement to rewrite -+** 1. type: Type of object ("table", "view" etc.) -+** 2. object: Name of object -+** 3. Database: Database name (e.g. "main") -+** 4. Table: Table name -+** 5. iCol: Index of column to rename -+** 6. zNew: New column name -+** 7. bQuote: Non-zero if the new column name should be quoted. -+** 8. bTemp: True if zSql comes from temp schema -+** -+** Do a column rename operation on the CREATE statement given in zSql. -+** The iCol-th column (left-most is 0) of table zTable is renamed from zCol -+** into zNew. The name should be quoted if bQuote is true. -+** -+** This function is used internally by the ALTER TABLE RENAME COLUMN command. -+** It is only accessible to SQL created using sqlite3NestedParse(). It is -+** not reachable from ordinary SQL passed into sqlite3_prepare(). -+*/ -+static void renameColumnFunc( -+ sqlite3_context *context, -+ int NotUsed, -+ sqlite3_value **argv -+){ -+ sqlite3 *db = sqlite3_context_db_handle(context); -+ RenameCtx sCtx; -+ const char *zSql = (const char*)sqlite3_value_text(argv[0]); -+ const char *zDb = (const char*)sqlite3_value_text(argv[3]); -+ const char *zTable = (const char*)sqlite3_value_text(argv[4]); -+ int iCol = sqlite3_value_int(argv[5]); -+ const char *zNew = (const char*)sqlite3_value_text(argv[6]); -+ int bQuote = sqlite3_value_int(argv[7]); -+ int bTemp = sqlite3_value_int(argv[8]); -+ const char *zOld; -+ int rc; -+ Parse sParse; -+ Walker sWalker; -+ Index *pIdx; -+ int i; -+ Table *pTab; -+#ifndef SQLITE_OMIT_AUTHORIZATION -+ sqlite3_xauth xAuth = db->xAuth; -+#endif -+ -+ UNUSED_PARAMETER(NotUsed); -+ if( zSql==0 ) return; -+ if( zTable==0 ) return; -+ if( zNew==0 ) return; -+ if( iCol<0 ) return; -+ sqlite3BtreeEnterAll(db); -+ pTab = sqlite3FindTable(db, zTable, zDb); -+ if( pTab==0 || iCol>=pTab->nCol ){ -+ sqlite3BtreeLeaveAll(db); -+ return; -+ } -+ zOld = pTab->aCol[iCol].zName; -+ memset(&sCtx, 0, sizeof(sCtx)); -+ sCtx.iCol = ((iCol==pTab->iPKey) ? -1 : iCol); -+ -+#ifndef SQLITE_OMIT_AUTHORIZATION -+ db->xAuth = 0; -+#endif -+ rc = renameParseSql(&sParse, zDb, 0, db, zSql, bTemp); -+ -+ /* Find tokens that need to be replaced. */ -+ memset(&sWalker, 0, sizeof(Walker)); -+ sWalker.pParse = &sParse; -+ sWalker.xExprCallback = renameColumnExprCb; -+ sWalker.xSelectCallback = renameColumnSelectCb; -+ sWalker.u.pRename = &sCtx; -+ -+ sCtx.pTab = pTab; -+ if( rc!=SQLITE_OK ) goto renameColumnFunc_done; -+ if( sParse.pNewTable ){ -+ Select *pSelect = sParse.pNewTable->pSelect; -+ if( pSelect ){ -+ sParse.rc = SQLITE_OK; -+ sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, 0); -+ rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); -+ if( rc==SQLITE_OK ){ -+ sqlite3WalkSelect(&sWalker, pSelect); -+ } -+ if( rc!=SQLITE_OK ) goto renameColumnFunc_done; -+ }else{ -+ /* A regular table */ -+ int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName); -+ FKey *pFKey; -+ assert( sParse.pNewTable->pSelect==0 ); -+ sCtx.pTab = sParse.pNewTable; -+ if( bFKOnly==0 ){ -+ renameTokenFind( -+ &sParse, &sCtx, (void*)sParse.pNewTable->aCol[iCol].zName -+ ); -+ if( sCtx.iCol<0 ){ -+ renameTokenFind(&sParse, &sCtx, (void*)&sParse.pNewTable->iPKey); -+ } -+ sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck); -+ for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){ -+ sqlite3WalkExprList(&sWalker, pIdx->aColExpr); -+ } -+ } -+ -+ for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){ -+ for(i=0; i<pFKey->nCol; i++){ -+ if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){ -+ renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]); -+ } -+ if( 0==sqlite3_stricmp(pFKey->zTo, zTable) -+ && 0==sqlite3_stricmp(pFKey->aCol[i].zCol, zOld) -+ ){ -+ renameTokenFind(&sParse, &sCtx, (void*)pFKey->aCol[i].zCol); -+ } -+ } -+ } -+ } -+ }else if( sParse.pNewIndex ){ -+ sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr); -+ sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); -+ }else{ -+ /* A trigger */ -+ TriggerStep *pStep; -+ rc = renameResolveTrigger(&sParse, (bTemp ? 0 : zDb)); -+ if( rc!=SQLITE_OK ) goto renameColumnFunc_done; -+ -+ for(pStep=sParse.pNewTrigger->step_list; pStep; pStep=pStep->pNext){ -+ if( pStep->zTarget ){ -+ Table *pTarget = sqlite3LocateTable(&sParse, 0, pStep->zTarget, zDb); -+ if( pTarget==pTab ){ -+ if( pStep->pUpsert ){ -+ ExprList *pUpsertSet = pStep->pUpsert->pUpsertSet; -+ renameColumnElistNames(&sParse, &sCtx, pUpsertSet, zOld); -+ } -+ renameColumnIdlistNames(&sParse, &sCtx, pStep->pIdList, zOld); -+ renameColumnElistNames(&sParse, &sCtx, pStep->pExprList, zOld); -+ } -+ } -+ } -+ -+ -+ /* Find tokens to edit in UPDATE OF clause */ -+ if( sParse.pTriggerTab==pTab ){ -+ renameColumnIdlistNames(&sParse, &sCtx,sParse.pNewTrigger->pColumns,zOld); -+ } -+ -+ /* Find tokens to edit in various expressions and selects */ -+ renameWalkTrigger(&sWalker, sParse.pNewTrigger); -+ } -+ -+ assert( rc==SQLITE_OK ); -+ rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote); -+ -+renameColumnFunc_done: -+ if( rc!=SQLITE_OK ){ -+ if( sParse.zErrMsg ){ -+ renameColumnParseError(context, 0, argv[1], argv[2], &sParse); -+ }else{ -+ sqlite3_result_error_code(context, rc); -+ } -+ } -+ -+ renameParseCleanup(&sParse); -+ renameTokenFree(db, sCtx.pList); -+#ifndef SQLITE_OMIT_AUTHORIZATION -+ db->xAuth = xAuth; -+#endif -+ sqlite3BtreeLeaveAll(db); -+} -+ -+/* -+** Walker expression callback used by "RENAME TABLE". -+*/ -+static int renameTableExprCb(Walker *pWalker, Expr *pExpr){ -+ RenameCtx *p = pWalker->u.pRename; -+ if( pExpr->op==TK_COLUMN && p->pTab==pExpr->y.pTab ){ -+ renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab); -+ } -+ return WRC_Continue; -+} -+ -+/* -+** Walker select callback used by "RENAME TABLE". -+*/ -+static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ -+ int i; -+ RenameCtx *p = pWalker->u.pRename; -+ SrcList *pSrc = pSelect->pSrc; -+ for(i=0; i<pSrc->nSrc; i++){ -+ struct SrcList_item *pItem = &pSrc->a[i]; -+ if( pItem->pTab==p->pTab ){ -+ renameTokenFind(pWalker->pParse, p, pItem->zName); -+ } -+ } -+ -+ return WRC_Continue; -+} -+ -+ -+/* -+** This C function implements an SQL user function that is used by SQL code -+** generated by the ALTER TABLE ... RENAME command to modify the definition -+** of any foreign key constraints that use the table being renamed as the -+** parent table. It is passed three arguments: -+** -+** 0: The database containing the table being renamed. -+** 1. type: Type of object ("table", "view" etc.) -+** 2. object: Name of object -+** 3: The complete text of the schema statement being modified, -+** 4: The old name of the table being renamed, and -+** 5: The new name of the table being renamed. -+** 6: True if the schema statement comes from the temp db. -+** -+** It returns the new schema statement. For example: -+** -+** sqlite_rename_table('main', 'CREATE TABLE t1(a REFERENCES t2)','t2','t3',0) -+** -> 'CREATE TABLE t1(a REFERENCES t3)' -+*/ -+static void renameTableFunc( -+ sqlite3_context *context, -+ int NotUsed, -+ sqlite3_value **argv -+){ -+ sqlite3 *db = sqlite3_context_db_handle(context); -+ const char *zDb = (const char*)sqlite3_value_text(argv[0]); -+ const char *zInput = (const char*)sqlite3_value_text(argv[3]); -+ const char *zOld = (const char*)sqlite3_value_text(argv[4]); -+ const char *zNew = (const char*)sqlite3_value_text(argv[5]); -+ int bTemp = sqlite3_value_int(argv[6]); -+ UNUSED_PARAMETER(NotUsed); -+ -+ if( zInput && zOld && zNew ){ -+ Parse sParse; -+ int rc; -+ int bQuote = 1; -+ RenameCtx sCtx; -+ Walker sWalker; -+ -+#ifndef SQLITE_OMIT_AUTHORIZATION -+ sqlite3_xauth xAuth = db->xAuth; -+ db->xAuth = 0; -+#endif -+ -+ sqlite3BtreeEnterAll(db); -+ -+ memset(&sCtx, 0, sizeof(RenameCtx)); -+ sCtx.pTab = sqlite3FindTable(db, zOld, zDb); -+ memset(&sWalker, 0, sizeof(Walker)); -+ sWalker.pParse = &sParse; -+ sWalker.xExprCallback = renameTableExprCb; -+ sWalker.xSelectCallback = renameTableSelectCb; -+ sWalker.u.pRename = &sCtx; -+ -+ rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp); -+ -+ if( rc==SQLITE_OK ){ -+ int isLegacy = (db->flags & SQLITE_LegacyAlter); -+ if( sParse.pNewTable ){ -+ Table *pTab = sParse.pNewTable; -+ -+ if( pTab->pSelect ){ -+ if( isLegacy==0 ){ -+ NameContext sNC; -+ memset(&sNC, 0, sizeof(sNC)); -+ sNC.pParse = &sParse; -+ -+ sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC); -+ if( sParse.nErr ) rc = sParse.rc; -+ sqlite3WalkSelect(&sWalker, pTab->pSelect); -+ } -+ }else{ -+ /* Modify any FK definitions to point to the new table. */ -+#ifndef SQLITE_OMIT_FOREIGN_KEY -+ if( isLegacy==0 || (db->flags & SQLITE_ForeignKeys) ){ -+ FKey *pFKey; -+ for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ -+ if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){ -+ renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo); -+ } -+ } -+ } -+#endif -+ -+ /* If this is the table being altered, fix any table refs in CHECK -+ ** expressions. Also update the name that appears right after the -+ ** "CREATE [VIRTUAL] TABLE" bit. */ -+ if( sqlite3_stricmp(zOld, pTab->zName)==0 ){ -+ sCtx.pTab = pTab; -+ if( isLegacy==0 ){ -+ sqlite3WalkExprList(&sWalker, pTab->pCheck); -+ } -+ renameTokenFind(&sParse, &sCtx, pTab->zName); -+ } -+ } -+ } -+ -+ else if( sParse.pNewIndex ){ -+ renameTokenFind(&sParse, &sCtx, sParse.pNewIndex->zName); -+ if( isLegacy==0 ){ -+ sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); -+ } -+ } -+ -+#ifndef SQLITE_OMIT_TRIGGER -+ else{ -+ Trigger *pTrigger = sParse.pNewTrigger; -+ TriggerStep *pStep; -+ if( 0==sqlite3_stricmp(sParse.pNewTrigger->table, zOld) -+ && sCtx.pTab->pSchema==pTrigger->pTabSchema -+ ){ -+ renameTokenFind(&sParse, &sCtx, sParse.pNewTrigger->table); -+ } -+ -+ if( isLegacy==0 ){ -+ rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb); -+ if( rc==SQLITE_OK ){ -+ renameWalkTrigger(&sWalker, pTrigger); -+ for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){ -+ if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){ -+ renameTokenFind(&sParse, &sCtx, pStep->zTarget); -+ } -+ } -+ } -+ } -+ } -+#endif -+ } -+ -+ if( rc==SQLITE_OK ){ -+ rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote); -+ } -+ if( rc!=SQLITE_OK ){ -+ if( sParse.zErrMsg ){ -+ renameColumnParseError(context, 0, argv[1], argv[2], &sParse); -+ }else{ -+ sqlite3_result_error_code(context, rc); -+ } -+ } -+ -+ renameParseCleanup(&sParse); -+ renameTokenFree(db, sCtx.pList); -+ sqlite3BtreeLeaveAll(db); -+#ifndef SQLITE_OMIT_AUTHORIZATION -+ db->xAuth = xAuth; -+#endif -+ } -+ -+ return; -+} -+ -+/* -+** An SQL user function that checks that there are no parse or symbol -+** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement. -+** After an ALTER TABLE .. RENAME operation is performed and the schema -+** reloaded, this function is called on each SQL statement in the schema -+** to ensure that it is still usable. -+** -+** 0: Database name ("main", "temp" etc.). -+** 1: SQL statement. -+** 2: Object type ("view", "table", "trigger" or "index"). -+** 3: Object name. -+** 4: True if object is from temp schema. -+** -+** Unless it finds an error, this function normally returns NULL. However, it -+** returns integer value 1 if: -+** -+** * the SQL argument creates a trigger, and -+** * the table that the trigger is attached to is in database zDb. -+*/ -+static void renameTableTest( -+ sqlite3_context *context, -+ int NotUsed, -+ sqlite3_value **argv -+){ -+ sqlite3 *db = sqlite3_context_db_handle(context); -+ char const *zDb = (const char*)sqlite3_value_text(argv[0]); -+ char const *zInput = (const char*)sqlite3_value_text(argv[1]); -+ int bTemp = sqlite3_value_int(argv[4]); -+ int isLegacy = (db->flags & SQLITE_LegacyAlter); -+ -+#ifndef SQLITE_OMIT_AUTHORIZATION -+ sqlite3_xauth xAuth = db->xAuth; -+ db->xAuth = 0; -+#endif -+ -+ UNUSED_PARAMETER(NotUsed); -+ if( zDb && zInput ){ -+ int rc; -+ Parse sParse; -+ rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp); -+ if( rc==SQLITE_OK ){ -+ if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){ -+ NameContext sNC; -+ memset(&sNC, 0, sizeof(sNC)); -+ sNC.pParse = &sParse; -+ sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, &sNC); -+ if( sParse.nErr ) rc = sParse.rc; -+ } -+ -+ else if( sParse.pNewTrigger ){ -+ if( isLegacy==0 ){ -+ rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb); -+ } -+ if( rc==SQLITE_OK ){ -+ int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema); -+ int i2 = sqlite3FindDbName(db, zDb); -+ if( i1==i2 ) sqlite3_result_int(context, 1); -+ } -+ } -+ } -+ -+ if( rc!=SQLITE_OK ){ -+ renameColumnParseError(context, 1, argv[2], argv[3], &sParse); -+ } -+ renameParseCleanup(&sParse); -+ } -+ -+#ifndef SQLITE_OMIT_AUTHORIZATION -+ db->xAuth = xAuth; -+#endif -+} -+ -+/* -+** Register built-in functions used to help implement ALTER TABLE -+*/ -+SQLITE_PRIVATE void sqlite3AlterFunctions(void){ -+ static FuncDef aAlterTableFuncs[] = { -+ INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc), -+ INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc), -+ INTERNAL_FUNCTION(sqlite_rename_test, 5, renameTableTest), -+ }; -+ sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); -+} - #endif /* SQLITE_ALTER_TABLE */ - - /************** End of alter.c ***********************************************/ -@@ -97912,6 +103313,10 @@ - "DELETE FROM %Q.%s WHERE %s=%Q", - pDb->zDbSName, zTab, zWhereType, zWhere - ); -+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK -+ }else if( db->xPreUpdateCallback ){ -+ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s", pDb->zDbSName, zTab); -+#endif - }else{ - /* The sqlite_stat[134] table already exists. Delete all rows. */ - sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb); -@@ -98159,6 +103564,7 @@ - 0, /* pNext */ - statInit, /* xSFunc */ - 0, /* xFinalize */ -+ 0, 0, /* xValue, xInverse */ - "stat_init", /* zName */ - {0} - }; -@@ -98475,6 +103881,7 @@ - 0, /* pNext */ - statPush, /* xSFunc */ - 0, /* xFinalize */ -+ 0, 0, /* xValue, xInverse */ - "stat_push", /* zName */ - {0} - }; -@@ -98626,6 +104033,7 @@ - 0, /* pNext */ - statGet, /* xSFunc */ - 0, /* xFinalize */ -+ 0, 0, /* xValue, xInverse */ - "stat_get", /* zName */ - {0} - }; -@@ -98676,6 +104084,9 @@ - int regIdxname = iMem++; /* Register containing index name */ - int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */ - int regPrev = iMem; /* MUST BE LAST (see below) */ -+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK -+ Table *pStat1 = 0; -+#endif - - pParse->nMem = MAX(pParse->nMem, iMem); - v = sqlite3GetVdbe(pParse); -@@ -98686,7 +104097,7 @@ - /* Do not gather statistics on views or virtual tables */ - return; - } -- if( sqlite3_strlike("sqlite_%", pTab->zName, 0)==0 ){ -+ if( sqlite3_strlike("sqlite\\_%", pTab->zName, '\\')==0 ){ - /* Do not gather statistics on system tables */ - return; - } -@@ -98701,6 +104112,18 @@ - } - #endif - -+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK -+ if( db->xPreUpdateCallback ){ -+ pStat1 = (Table*)sqlite3DbMallocZero(db, sizeof(Table) + 13); -+ if( pStat1==0 ) return; -+ pStat1->zName = (char*)&pStat1[1]; -+ memcpy(pStat1->zName, "sqlite_stat1", 13); -+ pStat1->nCol = 3; -+ pStat1->iPKey = -1; -+ sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNBLOB); -+ } -+#endif -+ - /* Establish a read-lock on the table at the shared-cache level. - ** Open a read-only cursor on the table. Also allocate a cursor number - ** to use for scanning indexes (iIdxCur). No index cursor is opened at -@@ -98902,6 +104325,9 @@ - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); - sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); - sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); -+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK -+ sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE); -+#endif - sqlite3VdbeChangeP5(v, OPFLAG_APPEND); - - /* Add the entries to the stat3 or stat4 table. */ -@@ -98927,10 +104353,7 @@ - callStatGet(v, regStat4, STAT_GET_NLT, regLt); - callStatGet(v, regStat4, STAT_GET_NDLT, regDLt); - sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0); -- /* We know that the regSampleRowid row exists because it was read by -- ** the previous loop. Thus the not-found jump of seekOp will never -- ** be taken */ -- VdbeCoverageNeverTaken(v); -+ VdbeCoverage(v); - #ifdef SQLITE_ENABLE_STAT3 - sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, 0, regSample); - #else -@@ -98965,6 +104388,9 @@ - sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); - sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); - sqlite3VdbeChangeP5(v, OPFLAG_APPEND); -+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK -+ sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE); -+#endif - sqlite3VdbeJumpHere(v, jZeroRows); - } - } -@@ -99567,7 +104993,7 @@ - - /* Load the statistics from the sqlite_stat4 table. */ - #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 -- if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){ -+ if( rc==SQLITE_OK ){ - db->lookaside.bDisable++; - rc = loadStat4(db, sInfo.zDatabase); - db->lookaside.bDisable--; -@@ -99647,6 +105073,10 @@ - ** - ** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the - ** third argument. -+** -+** If the db->init.reopenMemdb flags is set, then instead of attaching a -+** new database, close the database on db->init.iDb and reopen it as an -+** empty MemDB. - */ - static void attachFunc( - sqlite3_context *context, -@@ -99667,70 +105097,86 @@ - sqlite3_vfs *pVfs; - - UNUSED_PARAMETER(NotUsed); -- - zFile = (const char *)sqlite3_value_text(argv[0]); - zName = (const char *)sqlite3_value_text(argv[1]); - if( zFile==0 ) zFile = ""; - if( zName==0 ) zName = ""; - -- /* Check for the following errors: -- ** -- ** * Too many attached databases, -- ** * Transaction currently open -- ** * Specified database name already being used. -- */ -- if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){ -- zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", -- db->aLimit[SQLITE_LIMIT_ATTACHED] -- ); -- goto attach_error; -- } -- if( !db->autoCommit ){ -- zErrDyn = sqlite3MPrintf(db, "cannot ATTACH database within transaction"); -- goto attach_error; -- } -- for(i=0; i<db->nDb; i++){ -- char *z = db->aDb[i].zDbSName; -- assert( z && zName ); -- if( sqlite3StrICmp(z, zName)==0 ){ -- zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); -+#ifdef SQLITE_ENABLE_DESERIALIZE -+# define REOPEN_AS_MEMDB(db) (db->init.reopenMemdb) -+#else -+# define REOPEN_AS_MEMDB(db) (0) -+#endif -+ -+ if( REOPEN_AS_MEMDB(db) ){ -+ /* This is not a real ATTACH. Instead, this routine is being called -+ ** from sqlite3_deserialize() to close database db->init.iDb and -+ ** reopen it as a MemDB */ -+ pVfs = sqlite3_vfs_find("memdb"); -+ if( pVfs==0 ) return; -+ pNew = &db->aDb[db->init.iDb]; -+ if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); -+ pNew->pBt = 0; -+ pNew->pSchema = 0; -+ rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB); -+ }else{ -+ /* This is a real ATTACH -+ ** -+ ** Check for the following errors: -+ ** -+ ** * Too many attached databases, -+ ** * Transaction currently open -+ ** * Specified database name already being used. -+ */ -+ if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){ -+ zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", -+ db->aLimit[SQLITE_LIMIT_ATTACHED] -+ ); - goto attach_error; - } -+ for(i=0; i<db->nDb; i++){ -+ char *z = db->aDb[i].zDbSName; -+ assert( z && zName ); -+ if( sqlite3StrICmp(z, zName)==0 ){ -+ zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); -+ goto attach_error; -+ } -+ } -+ -+ /* Allocate the new entry in the db->aDb[] array and initialize the schema -+ ** hash tables. -+ */ -+ if( db->aDb==db->aDbStatic ){ -+ aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 ); -+ if( aNew==0 ) return; -+ memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); -+ }else{ -+ aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); -+ if( aNew==0 ) return; -+ } -+ db->aDb = aNew; -+ pNew = &db->aDb[db->nDb]; -+ memset(pNew, 0, sizeof(*pNew)); -+ -+ /* Open the database file. If the btree is successfully opened, use -+ ** it to obtain the database schema. At this point the schema may -+ ** or may not be initialized. -+ */ -+ flags = db->openFlags; -+ rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); -+ if( rc!=SQLITE_OK ){ -+ if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); -+ sqlite3_result_error(context, zErr, -1); -+ sqlite3_free(zErr); -+ return; -+ } -+ assert( pVfs ); -+ flags |= SQLITE_OPEN_MAIN_DB; -+ rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags); -+ sqlite3_free( zPath ); -+ db->nDb++; - } -- -- /* Allocate the new entry in the db->aDb[] array and initialize the schema -- ** hash tables. -- */ -- if( db->aDb==db->aDbStatic ){ -- aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 ); -- if( aNew==0 ) return; -- memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); -- }else{ -- aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); -- if( aNew==0 ) return; -- } -- db->aDb = aNew; -- pNew = &db->aDb[db->nDb]; -- memset(pNew, 0, sizeof(*pNew)); -- -- /* Open the database file. If the btree is successfully opened, use -- ** it to obtain the database schema. At this point the schema may -- ** or may not be initialized. -- */ -- flags = db->openFlags; -- rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); -- if( rc!=SQLITE_OK ){ -- if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); -- sqlite3_result_error(context, zErr, -1); -- sqlite3_free(zErr); -- return; -- } -- assert( pVfs ); -- flags |= SQLITE_OPEN_MAIN_DB; -- rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags); -- sqlite3_free( zPath ); -- db->nDb++; -- db->skipBtreeMutex = 0; -+ db->noSharedCache = 0; - if( rc==SQLITE_CONSTRAINT ){ - rc = SQLITE_ERROR; - zErrDyn = sqlite3MPrintf(db, "database is already attached"); -@@ -99756,7 +105202,7 @@ - sqlite3BtreeLeave(pNew->pBt); - } - pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; -- pNew->zDbSName = sqlite3DbStrDup(db, zName); -+ if( !REOPEN_AS_MEMDB(db) ) pNew->zDbSName = sqlite3DbStrDup(db, zName); - if( rc==SQLITE_OK && pNew->zDbSName==0 ){ - rc = SQLITE_NOMEM_BKPT; - } -@@ -99796,13 +105242,16 @@ - - /* If the file was opened successfully, read the schema for the new database. - ** If this fails, or if opening the file failed, then close the file and -- ** remove the entry from the db->aDb[] array. i.e. put everything back the way -- ** we found it. -+ ** remove the entry from the db->aDb[] array. i.e. put everything back the -+ ** way we found it. - */ - if( rc==SQLITE_OK ){ - sqlite3BtreeEnterAll(db); -+ db->init.iDb = 0; -+ db->mDbFlags &= ~(DBFLAG_SchemaKnownOk); - rc = sqlite3Init(db, &zErrDyn); - sqlite3BtreeLeaveAll(db); -+ assert( zErrDyn==0 || rc!=SQLITE_OK ); - } - #ifdef SQLITE_USER_AUTHENTICATION - if( rc==SQLITE_OK ){ -@@ -99814,22 +105263,24 @@ - } - #endif - if( rc ){ -- int iDb = db->nDb - 1; -- assert( iDb>=2 ); -- if( db->aDb[iDb].pBt ){ -- sqlite3BtreeClose(db->aDb[iDb].pBt); -- db->aDb[iDb].pBt = 0; -- db->aDb[iDb].pSchema = 0; -+ if( !REOPEN_AS_MEMDB(db) ){ -+ int iDb = db->nDb - 1; -+ assert( iDb>=2 ); -+ if( db->aDb[iDb].pBt ){ -+ sqlite3BtreeClose(db->aDb[iDb].pBt); -+ db->aDb[iDb].pBt = 0; -+ db->aDb[iDb].pSchema = 0; -+ } -+ sqlite3ResetAllSchemasOfConnection(db); -+ db->nDb = iDb; -+ if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ -+ sqlite3OomFault(db); -+ sqlite3DbFree(db, zErrDyn); -+ zErrDyn = sqlite3MPrintf(db, "out of memory"); -+ }else if( zErrDyn==0 ){ -+ zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile); -+ } - } -- sqlite3ResetAllSchemasOfConnection(db); -- db->nDb = iDb; -- if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ -- sqlite3OomFault(db); -- sqlite3DbFree(db, zErrDyn); -- zErrDyn = sqlite3MPrintf(db, "out of memory"); -- }else if( zErrDyn==0 ){ -- zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile); -- } - goto attach_error; - } - -@@ -99880,11 +105331,6 @@ - sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName); - goto detach_error; - } -- if( !db->autoCommit ){ -- sqlite3_snprintf(sizeof(zErr), zErr, -- "cannot DETACH database within transaction"); -- goto detach_error; -- } - if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){ - sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName); - goto detach_error; -@@ -99986,6 +105432,7 @@ - 0, /* pNext */ - detachFunc, /* xSFunc */ - 0, /* xFinalize */ -+ 0, 0, /* xValue, xInverse */ - "sqlite_detach", /* zName */ - {0} - }; -@@ -100005,6 +105452,7 @@ - 0, /* pNext */ - attachFunc, /* xSFunc */ - 0, /* xFinalize */ -+ 0, 0, /* xValue, xInverse */ - "sqlite_attach", /* zName */ - {0} - }; -@@ -100075,6 +105523,9 @@ - if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; - if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; - #endif -+ if( pItem->fg.isTabFunc && sqlite3FixExprList(pFix, pItem->u1.pFuncArg) ){ -+ return 1; -+ } - } - return 0; - } -@@ -100105,8 +105556,13 @@ - if( sqlite3FixExpr(pFix, pSelect->pLimit) ){ - return 1; - } -- if( sqlite3FixExpr(pFix, pSelect->pOffset) ){ -- return 1; -+ if( pSelect->pWith ){ -+ int i; -+ for(i=0; i<pSelect->pWith->nCte; i++){ -+ if( sqlite3FixSelect(pFix, pSelect->pWith->a[i].pSelect) ){ -+ return 1; -+ } -+ } - } - pSelect = pSelect->pPrior; - } -@@ -100169,6 +105625,18 @@ - if( sqlite3FixExprList(pFix, pStep->pExprList) ){ - return 1; - } -+#ifndef SQLITE_OMIT_UPSERT -+ if( pStep->pUpsert ){ -+ Upsert *pUp = pStep->pUpsert; -+ if( sqlite3FixExprList(pFix, pUp->pUpsertTarget) -+ || sqlite3FixExpr(pFix, pUp->pUpsertTargetWhere) -+ || sqlite3FixExprList(pFix, pUp->pUpsertSet) -+ || sqlite3FixExpr(pFix, pUp->pUpsertWhere) -+ ){ -+ return 1; -+ } -+ } -+#endif - pStep = pStep->pNext; - } - return 0; -@@ -100257,7 +105725,7 @@ - sqlite3_mutex_enter(db->mutex); - db->xAuth = (sqlite3_xauth)xAuth; - db->pAuthArg = pArg; -- sqlite3ExpirePreparedStatements(db); -+ sqlite3ExpirePreparedStatements(db, 0); - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; - } -@@ -100297,11 +105765,9 @@ - #endif - ); - if( rc==SQLITE_DENY ){ -- if( db->nDb>2 || iDb!=0 ){ -- sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol); -- }else{ -- sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol); -- } -+ char *z = sqlite3_mprintf("%s.%s", zTab, zCol); -+ if( db->nDb>2 || iDb!=0 ) z = sqlite3_mprintf("%s.%z", zDb, z); -+ sqlite3ErrorMsg(pParse, "access to %z is prohibited", z); - pParse->rc = SQLITE_AUTH; - }else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){ - sqliteAuthBadReturnCode(pParse); -@@ -100331,6 +105797,8 @@ - int iDb; /* The index of the database the expression refers to */ - int iCol; /* Index of column in table */ - -+ assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); -+ assert( !IN_RENAME_OBJECT || db->xAuth==0 ); - if( db->xAuth==0 ) return; - iDb = sqlite3SchemaToIndex(pParse->db, pSchema); - if( iDb<0 ){ -@@ -100339,7 +105807,6 @@ - return; - } - -- assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); - if( pExpr->op==TK_TRIGGER ){ - pTab = pParse->pTriggerTab; - }else{ -@@ -100388,7 +105855,8 @@ - /* Don't do any authorization checks if the database is initialising - ** or if the parser is being invoked from within sqlite3_declare_vtab. - */ -- if( db->init.busy || IN_DECLARE_VTAB ){ -+ assert( !IN_RENAME_OBJECT || db->xAuth==0 ); -+ if( db->init.busy || IN_SPECIAL_PARSE ){ - return SQLITE_OK; - } - -@@ -100680,7 +106148,6 @@ - /* Get the VDBE program ready for execution - */ - if( v && pParse->nErr==0 && !db->mallocFailed ){ -- assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */ - /* A minimum of one cursor is required if autoincrement is used - * See ticket [a696379c1f08866] */ - if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; -@@ -100798,29 +106265,30 @@ - const char *zDbase /* Name of the database. Might be NULL */ - ){ - Table *p; -+ sqlite3 *db = pParse->db; - - /* Read the database schema. If an error occurs, leave an error message - ** and code in pParse and return NULL. */ -- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ -+ if( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 -+ && SQLITE_OK!=sqlite3ReadSchema(pParse) -+ ){ - return 0; - } - -- p = sqlite3FindTable(pParse->db, zName, zDbase); -+ p = sqlite3FindTable(db, zName, zDbase); - if( p==0 ){ - const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table"; - #ifndef SQLITE_OMIT_VIRTUALTABLE -- if( sqlite3FindDbName(pParse->db, zDbase)<1 ){ -- /* If zName is the not the name of a table in the schema created using -- ** CREATE, then check to see if it is the name of an virtual table that -- ** can be an eponymous virtual table. */ -- Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName); -- if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ -- pMod = sqlite3PragmaVtabRegister(pParse->db, zName); -- } -- if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ -- return pMod->pEpoTab; -- } -+ /* If zName is the not the name of a table in the schema created using -+ ** CREATE, then check to see if it is the name of an virtual table that -+ ** can be an eponymous virtual table. */ -+ Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); -+ if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ -+ pMod = sqlite3PragmaVtabRegister(db, zName); - } -+ if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ -+ return pMod->pEpoTab; -+ } - #endif - if( (flags & LOCATE_NOERR)==0 ){ - if( zDbase ){ -@@ -100892,7 +106360,7 @@ - /* - ** Reclaim the memory used by an index - */ --static void freeIndex(sqlite3 *db, Index *p){ -+SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3 *db, Index *p){ - #ifndef SQLITE_OMIT_ANALYZE - sqlite3DeleteIndexSamples(db, p); - #endif -@@ -100932,9 +106400,9 @@ - p->pNext = pIndex->pNext; - } - } -- freeIndex(db, pIndex); -+ sqlite3FreeIndex(db, pIndex); - } -- db->flags |= SQLITE_InternChanges; -+ db->mDbFlags |= DBFLAG_SchemaChange; - } - - /* -@@ -100969,28 +106437,27 @@ - - /* - ** Reset the schema for the database at index iDb. Also reset the --** TEMP schema. -+** TEMP schema. The reset is deferred if db->nSchemaLock is not zero. -+** Deferred resets may be run by calling with iDb<0. - */ - SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){ -- Db *pDb; -+ int i; - assert( iDb<db->nDb ); - -- /* Case 1: Reset the single schema identified by iDb */ -- pDb = &db->aDb[iDb]; -- assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); -- assert( pDb->pSchema!=0 ); -- sqlite3SchemaClear(pDb->pSchema); -+ if( iDb>=0 ){ -+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); -+ DbSetProperty(db, iDb, DB_ResetWanted); -+ DbSetProperty(db, 1, DB_ResetWanted); -+ db->mDbFlags &= ~DBFLAG_SchemaKnownOk; -+ } - -- /* If any database other than TEMP is reset, then also reset TEMP -- ** since TEMP might be holding triggers that reference tables in the -- ** other database. -- */ -- if( iDb!=1 ){ -- pDb = &db->aDb[1]; -- assert( pDb->pSchema!=0 ); -- sqlite3SchemaClear(pDb->pSchema); -+ if( db->nSchemaLock==0 ){ -+ for(i=0; i<db->nDb; i++){ -+ if( DbHasProperty(db, i, DB_ResetWanted) ){ -+ sqlite3SchemaClear(db->aDb[i].pSchema); -+ } -+ } - } -- return; - } - - /* -@@ -101003,13 +106470,19 @@ - for(i=0; i<db->nDb; i++){ - Db *pDb = &db->aDb[i]; - if( pDb->pSchema ){ -- sqlite3SchemaClear(pDb->pSchema); -+ if( db->nSchemaLock==0 ){ -+ sqlite3SchemaClear(pDb->pSchema); -+ }else{ -+ DbSetProperty(db, i, DB_ResetWanted); -+ } - } - } -- db->flags &= ~SQLITE_InternChanges; -+ db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk); - sqlite3VtabUnlockList(db); - sqlite3BtreeLeaveAll(db); -- sqlite3CollapseDatabaseArray(db); -+ if( db->nSchemaLock==0 ){ -+ sqlite3CollapseDatabaseArray(db); -+ } - } - - /* -@@ -101016,7 +106489,7 @@ - ** This routine is called when a commit occurs. - */ - SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3 *db){ -- db->flags &= ~SQLITE_InternChanges; -+ db->mDbFlags &= ~DBFLAG_SchemaChange; - } - - /* -@@ -101054,13 +106527,16 @@ - */ - static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ - Index *pIndex, *pNext; -- TESTONLY( int nLookaside; ) /* Used to verify lookaside not used for schema */ - -+#ifdef SQLITE_DEBUG - /* Record the number of outstanding lookaside allocations in schema Tables - ** prior to doing any free() operations. Since schema Tables do not use - ** lookaside, this number should not change. */ -- TESTONLY( nLookaside = (db && (pTable->tabFlags & TF_Ephemeral)==0) ? -- db->lookaside.nOut : 0 ); -+ int nLookaside = 0; -+ if( db && (pTable->tabFlags & TF_Ephemeral)==0 ){ -+ nLookaside = sqlite3LookasideUsed(db, 0); -+ } -+#endif - - /* Delete all indices associated with this table. */ - for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){ -@@ -101075,7 +106551,7 @@ - assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); - assert( pOld==pIndex || pOld==0 ); - } -- freeIndex(db, pIndex); -+ sqlite3FreeIndex(db, pIndex); - } - - /* Delete any foreign keys attached to this table. */ -@@ -101083,6 +106559,12 @@ - - /* Delete the Table structure itself. - */ -+#ifdef SQLITE_ENABLE_NORMALIZE -+ if( pTable->pColHash ){ -+ sqlite3HashClear(pTable->pColHash); -+ sqlite3_free(pTable->pColHash); -+ } -+#endif - sqlite3DeleteColumnNames(db, pTable); - sqlite3DbFree(db, pTable->zName); - sqlite3DbFree(db, pTable->zColAff); -@@ -101094,7 +106576,7 @@ - sqlite3DbFree(db, pTable); - - /* Verify that no lookaside memory was used by schema tables */ -- assert( nLookaside==0 || nLookaside==db->lookaside.nOut ); -+ assert( nLookaside==0 || nLookaside==sqlite3LookasideUsed(db,0) ); - } - SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ - /* Do not delete the table until the reference count reaches zero. */ -@@ -101120,7 +106602,7 @@ - pDb = &db->aDb[iDb]; - p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0); - sqlite3DeleteTable(db, p); -- db->flags |= SQLITE_InternChanges; -+ db->mDbFlags |= DBFLAG_SchemaChange; - } - - /* -@@ -101233,7 +106715,8 @@ - return -1; - } - }else{ -- assert( db->init.iDb==0 || db->init.busy || (db->flags & SQLITE_Vacuum)!=0); -+ assert( db->init.iDb==0 || db->init.busy || IN_RENAME_OBJECT -+ || (db->mDbFlags & DBFLAG_Vacuum)!=0); - iDb = db->init.iDb; - *pUnqual = pName1; - } -@@ -101241,6 +106724,20 @@ - } - - /* -+** True if PRAGMA writable_schema is ON -+*/ -+SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3 *db){ -+ testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==0 ); -+ testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))== -+ SQLITE_WriteSchema ); -+ testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))== -+ SQLITE_Defensive ); -+ testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))== -+ (SQLITE_WriteSchema|SQLITE_Defensive) ); -+ return (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==SQLITE_WriteSchema; -+} -+ -+/* - ** This routine is used to check if the UTF-8 string zName is a legal - ** unqualified name for a new schema object (table, index, view or - ** trigger). All names are legal except those that begin with the string -@@ -101249,7 +106746,7 @@ - */ - SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *pParse, const char *zName){ - if( !pParse->db->init.busy && pParse->nested==0 -- && (pParse->db->flags & SQLITE_WriteSchema)==0 -+ && sqlite3WritableSchema(pParse->db)==0 - && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ - sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName); - return SQLITE_ERROR; -@@ -101327,6 +106824,9 @@ - } - if( !OMIT_TEMPDB && isTemp ) iDb = 1; - zName = sqlite3NameFromToken(db, pName); -+ if( IN_RENAME_OBJECT ){ -+ sqlite3RenameTokenMap(pParse, (void*)zName, pName); -+ } - } - pParse->sNameToken = *pName; - if( zName==0 ) return; -@@ -101362,7 +106862,7 @@ - ** and types will be used, so there is no need to test for namespace - ** collisions. - */ -- if( !IN_DECLARE_VTAB ){ -+ if( !IN_SPECIAL_PARSE ){ - char *zDb = db->aDb[iDb].zDbSName; - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ - goto begin_table_error; -@@ -101465,7 +106965,8 @@ - }else - #endif - { -- pParse->addrCrTab = sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2); -+ pParse->addrCrTab = -+ sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY); - } - sqlite3OpenMasterTable(pParse, iDb); - sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1); -@@ -101514,14 +107015,13 @@ - Column *pCol; - sqlite3 *db = pParse->db; - if( (p = pParse->pNewTable)==0 ) return; --#if SQLITE_MAX_COLUMN - if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){ - sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); - return; - } --#endif - z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2); - if( z==0 ) return; -+ if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, pName); - memcpy(z, pName->z, pName->n); - z[pName->n] = 0; - sqlite3Dequote(z); -@@ -101548,15 +107048,20 @@ - - if( pType->n==0 ){ - /* If there is no type specified, columns have the default affinity -- ** 'BLOB'. */ -+ ** 'BLOB' with a default size of 4 bytes. */ - pCol->affinity = SQLITE_AFF_BLOB; - pCol->szEst = 1; -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ if( 4>=sqlite3GlobalConfig.szSorterRef ){ -+ pCol->colFlags |= COLFLAG_SORTERREF; -+ } -+#endif - }else{ - zType = z + sqlite3Strlen30(z) + 1; - memcpy(zType, pType->z, pType->n); - zType[pType->n] = 0; - sqlite3Dequote(zType); -- pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst); -+ pCol->affinity = sqlite3AffinityType(zType, pCol); - pCol->colFlags |= COLFLAG_HASTYPE; - } - p->nCol++; -@@ -101571,10 +107076,24 @@ - */ - SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){ - Table *p; -+ Column *pCol; - p = pParse->pNewTable; - if( p==0 || NEVER(p->nCol<1) ) return; -- p->aCol[p->nCol-1].notNull = (u8)onError; -+ pCol = &p->aCol[p->nCol-1]; -+ pCol->notNull = (u8)onError; - p->tabFlags |= TF_HasNotNull; -+ -+ /* Set the uniqNotNull flag on any UNIQUE or PK indexes already created -+ ** on this column. */ -+ if( pCol->colFlags & COLFLAG_UNIQUE ){ -+ Index *pIdx; -+ for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ -+ assert( pIdx->nKeyCol==1 && pIdx->onError!=OE_None ); -+ if( pIdx->aiColumn[0]==p->nCol-1 ){ -+ pIdx->uniqNotNull = 1; -+ } -+ } -+ } - } - - /* -@@ -101602,7 +107121,7 @@ - ** If none of the substrings in the above table are found, - ** SQLITE_AFF_NUMERIC is returned. - */ --SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, u8 *pszEst){ -+SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, Column *pCol){ - u32 h = 0; - char aff = SQLITE_AFF_NUMERIC; - const char *zChar = 0; -@@ -101639,27 +107158,32 @@ - } - } - -- /* If pszEst is not NULL, store an estimate of the field size. The -+ /* If pCol is not NULL, store an estimate of the field size. The - ** estimate is scaled so that the size of an integer is 1. */ -- if( pszEst ){ -- *pszEst = 1; /* default size is approx 4 bytes */ -+ if( pCol ){ -+ int v = 0; /* default size is approx 4 bytes */ - if( aff<SQLITE_AFF_NUMERIC ){ - if( zChar ){ - while( zChar[0] ){ - if( sqlite3Isdigit(zChar[0]) ){ -- int v = 0; -+ /* BLOB(k), VARCHAR(k), CHAR(k) -> r=(k/4+1) */ - sqlite3GetInt32(zChar, &v); -- v = v/4 + 1; -- if( v>255 ) v = 255; -- *pszEst = v; /* BLOB(k), VARCHAR(k), CHAR(k) -> r=(k/4+1) */ - break; - } - zChar++; - } - }else{ -- *pszEst = 5; /* BLOB, TEXT, CLOB -> r=5 (approx 20 bytes)*/ -+ v = 16; /* BLOB, TEXT, CLOB -> r=5 (approx 20 bytes)*/ - } - } -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ if( v>=sqlite3GlobalConfig.szSorterRef ){ -+ pCol->colFlags |= COLFLAG_SORTERREF; -+ } -+#endif -+ v = v/4 + 1; -+ if( v>255 ) v = 255; -+ pCol->szEst = v; - } - return aff; - } -@@ -101674,7 +107198,12 @@ - ** This routine is called by the parser while in the middle of - ** parsing a CREATE TABLE statement. - */ --SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){ -+SQLITE_PRIVATE void sqlite3AddDefaultValue( -+ Parse *pParse, /* Parsing context */ -+ Expr *pExpr, /* The parsed expression of the default value */ -+ const char *zStart, /* Start of the default value text */ -+ const char *zEnd /* First character past end of defaut value text */ -+){ - Table *p; - Column *pCol; - sqlite3 *db = pParse->db; -@@ -101681,27 +107210,28 @@ - p = pParse->pNewTable; - if( p!=0 ){ - pCol = &(p->aCol[p->nCol-1]); -- if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr, db->init.busy) ){ -+ if( !sqlite3ExprIsConstantOrFunction(pExpr, db->init.busy) ){ - sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", - pCol->zName); - }else{ - /* A copy of pExpr is used instead of the original, as pExpr contains -- ** tokens that point to volatile memory. The 'span' of the expression -- ** is required by pragma table_info. -+ ** tokens that point to volatile memory. - */ - Expr x; - sqlite3ExprDelete(db, pCol->pDflt); - memset(&x, 0, sizeof(x)); - x.op = TK_SPAN; -- x.u.zToken = sqlite3DbStrNDup(db, (char*)pSpan->zStart, -- (int)(pSpan->zEnd - pSpan->zStart)); -- x.pLeft = pSpan->pExpr; -+ x.u.zToken = sqlite3DbSpanDup(db, zStart, zEnd); -+ x.pLeft = pExpr; - x.flags = EP_Skip; - pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE); - sqlite3DbFree(db, x.u.zToken); - } - } -- sqlite3ExprDelete(db, pSpan->pExpr); -+ if( IN_RENAME_OBJECT ){ -+ sqlite3RenameExprUnmap(pParse, pExpr); -+ } -+ sqlite3ExprDelete(db, pExpr); - } - - /* -@@ -101792,6 +107322,9 @@ - && sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0 - && sortOrder!=SQLITE_SO_DESC - ){ -+ if( IN_RENAME_OBJECT && pList ){ -+ sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pList->a[0].pExpr); -+ } - pTab->iPKey = iCol; - pTab->keyConf = (u8)onError; - assert( autoInc==0 || autoInc==1 ); -@@ -101932,7 +107465,7 @@ - Vdbe *v = pParse->pVdbe; - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, -- db->aDb[iDb].pSchema->schema_cookie+1); -+ (int)(1+(unsigned)db->aDb[iDb].pSchema->schema_cookie)); - } - - /* -@@ -102117,6 +107650,31 @@ - return 0; - } - -+/* Recompute the colNotIdxed field of the Index. -+** -+** colNotIdxed is a bitmask that has a 0 bit representing each indexed -+** columns that are within the first 63 columns of the table. The -+** high-order bit of colNotIdxed is always 1. All unindexed columns -+** of the table have a 1. -+** -+** 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; -+ for(j=pIdx->nColumn-1; j>=0; j--){ -+ int x = pIdx->aiColumn[j]; -+ if( x>=0 ){ -+ testcase( x==BMS-1 ); -+ testcase( x==BMS-2 ); -+ if( x<BMS-1 ) m |= MASKBIT(x); -+ } -+ } -+ pIdx->colNotIdxed = ~m; -+ assert( (pIdx->colNotIdxed>>63)==1 ); -+} -+ - /* - ** This routine runs at the end of parsing a CREATE TABLE statement that - ** has a WITHOUT ROWID clause. The job of this routine is to convert both -@@ -102125,9 +107683,8 @@ - ** Changes include: - ** - ** (1) Set all columns of the PRIMARY KEY schema object to be NOT NULL. --** (2) Convert the OP_CreateTable into an OP_CreateIndex. There is --** no rowid btree for a WITHOUT ROWID. Instead, the canonical --** data storage is a covering index btree. -+** (2) Convert P3 parameter of the OP_CreateBtree from BTREE_INTKEY -+** into BTREE_BLOBKEY. - ** (3) Bypass the creation of the sqlite_master table entry - ** for the PRIMARY KEY as the primary key index is now - ** identified by the sqlite_master table entry of the table itself. -@@ -102135,7 +107692,7 @@ - ** schema to the rootpage from the main table. - ** (5) Add all table columns to the PRIMARY KEY Index object - ** so that the PRIMARY KEY is a covering index. The surplus --** columns are part of KeyInfo.nXField and are not used for -+** columns are part of KeyInfo.nAllField and are not used for - ** sorting or lookup or uniqueness checks. - ** (6) Replace the rowid tail on all automatically generated UNIQUE - ** indices with the PRIMARY KEY columns. -@@ -102160,17 +107717,12 @@ - } - } - -- /* The remaining transformations only apply to b-tree tables, not to -- ** virtual tables */ -- if( IN_DECLARE_VTAB ) return; -- -- /* Convert the OP_CreateTable opcode that would normally create the -- ** root-page for the table into an OP_CreateIndex opcode. The index -- ** created will become the PRIMARY KEY index. -+ /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY -+ ** into BTREE_BLOBKEY. - */ - if( pParse->addrCrTab ){ - assert( v ); -- sqlite3VdbeChangeOpcode(v, pParse->addrCrTab, OP_CreateIndex); -+ sqlite3VdbeChangeP3(v, pParse->addrCrTab, BTREE_BLOBKEY); - } - - /* Locate the PRIMARY KEY index. Or, if this table was originally -@@ -102187,7 +107739,7 @@ - assert( pParse->pNewTable==pTab ); - sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0, - SQLITE_IDXTYPE_PRIMARYKEY); -- if( db->mallocFailed ) return; -+ if( db->mallocFailed || pParse->nErr ) return; - pPk = sqlite3PrimaryKeyIndex(pTab); - pTab->iPKey = -1; - }else{ -@@ -102267,9 +107819,40 @@ - }else{ - pPk->nColumn = pTab->nCol; - } -+ recomputeColumnsNotIndexed(pPk); - } - -+#ifndef SQLITE_OMIT_VIRTUALTABLE - /* -+** Return true if zName is a shadow table name in the current database -+** connection. -+** -+** 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){ -+ char *zTail; /* Pointer to the last "_" in zName */ -+ Table *pTab; /* Table that zName is a shadow of */ -+ Module *pMod; /* Module for the virtual table */ -+ -+ zTail = strrchr(zName, '_'); -+ if( zTail==0 ) return 0; -+ *zTail = 0; -+ pTab = sqlite3FindTable(db, zName, 0); -+ *zTail = '_'; -+ if( pTab==0 ) return 0; -+ if( !IsVirtual(pTab) ) return 0; -+ pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]); -+ if( pMod==0 ) return 0; -+ if( pMod->pModule->iVersion<3 ) return 0; -+ if( pMod->pModule->xShadowName==0 ) return 0; -+ return pMod->pModule->xShadowName(zTail+1); -+} -+#else -+# define isShadowTableName(x,y) 0 -+#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ -+ -+/* - ** This routine is called to report the final ")" that terminates - ** a CREATE TABLE statement. - ** -@@ -102308,7 +107891,9 @@ - p = pParse->pNewTable; - if( p==0 ) return; - -- assert( !db->init.busy || !pSelect ); -+ if( pSelect==0 && isShadowTableName(db, p->zName) ){ -+ p->tabFlags |= TF_Shadow; -+ } - - /* If the db->init.busy is 1 it means we are reading the SQL off the - ** "sqlite_master" or "sqlite_temp_master" table on the disk. -@@ -102320,6 +107905,10 @@ - ** table itself. So mark it read-only. - */ - if( db->init.busy ){ -+ if( pSelect ){ -+ sqlite3ErrorMsg(pParse, ""); -+ return; -+ } - p->tnum = db->init.newTnum; - if( p->tnum==1 ) p->tabFlags |= TF_Readonly; - } -@@ -102420,10 +108009,6 @@ - pParse->nTab = 2; - addrTop = sqlite3VdbeCurrentAddr(v) + 1; - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); -- sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); -- sqlite3Select(pParse, pSelect, &dest); -- sqlite3VdbeEndCoroutine(v, regYield); -- sqlite3VdbeJumpHere(v, addrTop - 1); - if( pParse->nErr ) return; - pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect); - if( pSelTab==0 ) return; -@@ -102433,6 +108018,11 @@ - pSelTab->nCol = 0; - pSelTab->aCol = 0; - sqlite3DeleteTable(db, pSelTab); -+ sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); -+ sqlite3Select(pParse, pSelect, &dest); -+ if( pParse->nErr ) return; -+ sqlite3VdbeEndCoroutine(v, regYield); -+ sqlite3VdbeJumpHere(v, addrTop - 1); - addrInsLoop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); - VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec); -@@ -102510,7 +108100,7 @@ - return; - } - pParse->pNewTable = 0; -- db->flags |= SQLITE_InternChanges; -+ db->mDbFlags |= DBFLAG_SchemaChange; - - #ifndef SQLITE_OMIT_ALTERTABLE - if( !p->pSelect ){ -@@ -102567,7 +108157,12 @@ - ** allocated rather than point to the input string - which means that - ** they will persist after the current sqlite3_exec() call returns. - */ -- p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); -+ if( IN_RENAME_OBJECT ){ -+ p->pSelect = pSelect; -+ pSelect = 0; -+ }else{ -+ p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); -+ } - p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE); - if( db->mallocFailed ) goto create_view_fail; - -@@ -102575,7 +108170,7 @@ - ** the end. - */ - sEnd = pParse->sLastToken; -- assert( sEnd.z[0]!=0 ); -+ assert( sEnd.z[0]!=0 || sEnd.n==0 ); - if( sEnd.z[0]!=';' ){ - sEnd.z += sEnd.n; - } -@@ -102592,6 +108187,9 @@ - - create_view_fail: - sqlite3SelectDelete(db, pSelect); -+ if( IN_RENAME_OBJECT ){ -+ sqlite3RenameExprlistUnmap(pParse, pCNames); -+ } - sqlite3ExprListDelete(db, pCNames); - return; - } -@@ -102609,6 +108207,9 @@ - int nErr = 0; /* Number of errors encountered */ - int n; /* Temporarily holds the number of cursors assigned */ - sqlite3 *db = pParse->db; /* Database connection for malloc errors */ -+#ifndef SQLITE_OMIT_VIRTUALTABLE -+ int rc; -+#endif - #ifndef SQLITE_OMIT_AUTHORIZATION - sqlite3_xauth xAuth; /* Saved xAuth pointer */ - #endif -@@ -102616,8 +108217,11 @@ - assert( pTable ); - - #ifndef SQLITE_OMIT_VIRTUALTABLE -- if( sqlite3VtabCallConnect(pParse, pTable) ){ -- return SQLITE_ERROR; -+ db->nSchemaLock++; -+ rc = sqlite3VtabCallConnect(pParse, pTable); -+ db->nSchemaLock--; -+ if( rc ){ -+ return 1; - } - if( IsVirtual(pTable) ) return 0; - #endif -@@ -102659,6 +108263,10 @@ - assert( pTable->pSelect ); - pSel = sqlite3SelectDup(db, pTable->pSelect, 0); - if( pSel ){ -+#ifndef SQLITE_OMIT_ALTERTABLE -+ u8 eParseMode = pParse->eParseMode; -+ pParse->eParseMode = PARSE_MODE_NORMAL; -+#endif - n = pParse->nTab; - sqlite3SrcListAssignCursors(pParse, pSel->pSrc); - pTable->nCol = -1; -@@ -102704,10 +108312,18 @@ - sqlite3DeleteTable(db, pSelTab); - sqlite3SelectDelete(db, pSel); - db->lookaside.bDisable--; -+#ifndef SQLITE_OMIT_ALTERTABLE -+ pParse->eParseMode = eParseMode; -+#endif - } else { - nErr++; - } - pTable->pSchema->schemaFlags |= DB_UnresetViews; -+ if( db->mallocFailed ){ -+ sqlite3DeleteColumnNames(db, pTable); -+ pTable->aCol = 0; -+ pTable->nCol = 0; -+ } - #endif /* SQLITE_OMIT_VIEW */ - return nErr; - } -@@ -102786,7 +108402,7 @@ - static void destroyRootPage(Parse *pParse, int iTable, int iDb){ - Vdbe *v = sqlite3GetVdbe(pParse); - int r1 = sqlite3GetTempReg(pParse); -- assert( iTable>1 ); -+ if( iTable<2 ) sqlite3ErrorMsg(pParse, "corrupt schema"); - sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb); - sqlite3MayAbort(pParse); - #ifndef SQLITE_OMIT_AUTOVACUUM -@@ -102813,14 +108429,6 @@ - ** is also added (this can happen with an auto-vacuum database). - */ - static void destroyTable(Parse *pParse, Table *pTab){ --#ifdef SQLITE_OMIT_AUTOVACUUM -- Index *pIdx; -- int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); -- destroyRootPage(pParse, pTab->tnum, iDb); -- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ -- destroyRootPage(pParse, pIdx->tnum, iDb); -- } --#else - /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM - ** is not defined), then it is important to call OP_Destroy on the - ** table and index root-pages in order, starting with the numerically -@@ -102863,7 +108471,6 @@ - iDestroyed = iLargest; - } - } --#endif - } - - /* -@@ -103055,8 +108662,10 @@ - v = sqlite3GetVdbe(pParse); - if( v ){ - sqlite3BeginWriteOperation(pParse, 1, iDb); -- sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); -- sqlite3FkDropTable(pParse, pName, pTab); -+ if( !isView ){ -+ sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); -+ sqlite3FkDropTable(pParse, pName, pTab); -+ } - sqlite3CodeDropTable(pParse, pTab, iDb, isView); - } - -@@ -103131,6 +108740,9 @@ - pFKey->pNextFrom = p->pFKey; - z = (char*)&pFKey->aCol[nCol]; - pFKey->zTo = z; -+ if( IN_RENAME_OBJECT ){ -+ sqlite3RenameTokenMap(pParse, (void*)z, pTo); -+ } - memcpy(z, pTo->z, pTo->n); - z[pTo->n] = 0; - sqlite3Dequote(z); -@@ -103153,6 +108765,9 @@ - pFromCol->a[i].zName); - goto fk_end; - } -+ if( IN_RENAME_OBJECT ){ -+ sqlite3RenameTokenRemap(pParse, &pFKey->aCol[i], pFromCol->a[i].zName); -+ } - } - } - if( pToCol ){ -@@ -103159,6 +108774,9 @@ - for(i=0; i<nCol; i++){ - int n = sqlite3Strlen30(pToCol->a[i].zName); - pFKey->aCol[i].zCol = z; -+ if( IN_RENAME_OBJECT ){ -+ sqlite3RenameTokenRemap(pParse, z, pToCol->a[i].zName); -+ } - memcpy(z, pToCol->a[i].zName, n); - z[n] = 0; - z += n+1; -@@ -103267,6 +108885,7 @@ - sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); - addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v); - regRecord = sqlite3GetTempReg(pParse); -+ sqlite3MultiWrite(pParse); - - sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0); - sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); -@@ -103280,17 +108899,18 @@ - - addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v); - if( IsUniqueIndex(pIndex) ){ -- int j2 = sqlite3VdbeCurrentAddr(v) + 3; -- sqlite3VdbeGoto(v, j2); -+ int j2 = sqlite3VdbeGoto(v, 1); - addr2 = sqlite3VdbeCurrentAddr(v); -+ sqlite3VdbeVerifyAbortable(v, OE_Abort); - sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, - pIndex->nKeyCol); VdbeCoverage(v); - sqlite3UniqueConstraint(pParse, OE_Abort, pIndex); -+ sqlite3VdbeJumpHere(v, j2); - }else{ - addr2 = sqlite3VdbeCurrentAddr(v); - } - sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx); -- sqlite3VdbeAddOp3(v, OP_Last, iIdx, 0, -1); -+ sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord); - sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); - sqlite3ReleaseTempReg(pParse, regRecord); -@@ -103448,7 +109068,11 @@ - #if SQLITE_USER_AUTHENTICATION - && sqlite3UserAuthTable(pTab->zName)==0 - #endif -- && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 ){ -+#ifdef SQLITE_ALLOW_SQLITE_MASTER_INDEX -+ && sqlite3StrICmp(&pTab->zName[7],"master")!=0 -+#endif -+ && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 -+ ){ - sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); - goto exit_create_index; - } -@@ -103485,21 +109109,23 @@ - if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ - goto exit_create_index; - } -- if( !db->init.busy ){ -- if( sqlite3FindTable(db, zName, 0)!=0 ){ -- sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); -+ if( !IN_RENAME_OBJECT ){ -+ if( !db->init.busy ){ -+ if( sqlite3FindTable(db, zName, 0)!=0 ){ -+ sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); -+ goto exit_create_index; -+ } -+ } -+ if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){ -+ if( !ifNotExist ){ -+ sqlite3ErrorMsg(pParse, "index %s already exists", zName); -+ }else{ -+ assert( !db->init.busy ); -+ sqlite3CodeVerifySchema(pParse, iDb); -+ } - goto exit_create_index; - } - } -- if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){ -- if( !ifNotExist ){ -- sqlite3ErrorMsg(pParse, "index %s already exists", zName); -- }else{ -- assert( !db->init.busy ); -- sqlite3CodeVerifySchema(pParse, iDb); -- } -- goto exit_create_index; -- } - }else{ - int n; - Index *pLoop; -@@ -103514,13 +109140,13 @@ - ** The following statement converts "sqlite3_autoindex..." into - ** "sqlite3_butoindex..." in order to make the names distinct. - ** The "vtab_err.test" test demonstrates the need of this statement. */ -- if( IN_DECLARE_VTAB ) zName[7]++; -+ if( IN_SPECIAL_PARSE ) zName[7]++; - } - - /* Check for authorization to create an index. - */ - #ifndef SQLITE_OMIT_AUTHORIZATION -- { -+ if( !IN_RENAME_OBJECT ){ - const char *zDb = pDb->zDbSName; - if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){ - goto exit_create_index; -@@ -103539,7 +109165,9 @@ - */ - if( pList==0 ){ - Token prevCol; -- sqlite3TokenInit(&prevCol, pTab->aCol[pTab->nCol-1].zName); -+ Column *pCol = &pTab->aCol[pTab->nCol-1]; -+ pCol->colFlags |= COLFLAG_UNIQUE; -+ sqlite3TokenInit(&prevCol, pCol->zName); - pList = sqlite3ExprListAppend(pParse, 0, - sqlite3ExprAlloc(db, TK_ID, &prevCol, 0)); - if( pList==0 ) goto exit_create_index; -@@ -103605,7 +109233,12 @@ - ** TODO: Issue a warning if the table primary key is used as part of the - ** index key. - */ -- for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){ -+ pListItem = pList->a; -+ if( IN_RENAME_OBJECT ){ -+ pIndex->aColExpr = pList; -+ pList = 0; -+ } -+ for(i=0; i<pIndex->nKeyCol; i++, pListItem++){ - Expr *pCExpr; /* The i-th index expression */ - int requestedSortOrder; /* ASC or DESC on the i-th expression */ - const char *zColl; /* Collation sequence name */ -@@ -103621,12 +109254,8 @@ - goto exit_create_index; - } - if( pIndex->aColExpr==0 ){ -- ExprList *pCopy = sqlite3ExprListDup(db, pList, 0); -- pIndex->aColExpr = pCopy; -- if( !db->mallocFailed ){ -- assert( pCopy!=0 ); -- pListItem = &pCopy->a[i]; -- } -+ pIndex->aColExpr = pList; -+ pList = 0; - } - j = XN_EXPR; - pIndex->aiColumn[i] = XN_EXPR; -@@ -103692,6 +109321,7 @@ - ** it as a covering index */ - assert( HasRowid(pTab) - || pTab->iPKey<0 || sqlite3ColumnOfIndex(pIndex, pTab->iPKey)>=0 ); -+ recomputeColumnsNotIndexed(pIndex); - if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){ - pIndex->isCovering = 1; - for(j=0; j<pTab->nCol; j++){ -@@ -103764,98 +109394,101 @@ - } - } - -- /* Link the new Index structure to its table and to the other -- ** in-memory database structures. -- */ -- assert( pParse->nErr==0 ); -- if( db->init.busy ){ -- Index *p; -- assert( !IN_DECLARE_VTAB ); -- assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); -- p = sqlite3HashInsert(&pIndex->pSchema->idxHash, -- pIndex->zName, pIndex); -- if( p ){ -- assert( p==pIndex ); /* Malloc must have failed */ -- sqlite3OomFault(db); -- goto exit_create_index; -+ if( !IN_RENAME_OBJECT ){ -+ -+ /* Link the new Index structure to its table and to the other -+ ** in-memory database structures. -+ */ -+ assert( pParse->nErr==0 ); -+ if( db->init.busy ){ -+ Index *p; -+ assert( !IN_SPECIAL_PARSE ); -+ assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); -+ p = sqlite3HashInsert(&pIndex->pSchema->idxHash, -+ pIndex->zName, pIndex); -+ if( p ){ -+ assert( p==pIndex ); /* Malloc must have failed */ -+ sqlite3OomFault(db); -+ goto exit_create_index; -+ } -+ db->mDbFlags |= DBFLAG_SchemaChange; -+ if( pTblName!=0 ){ -+ pIndex->tnum = db->init.newTnum; -+ } - } -- db->flags |= SQLITE_InternChanges; -- if( pTblName!=0 ){ -- pIndex->tnum = db->init.newTnum; -- } -- } - -- /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the -- ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then -- ** emit code to allocate the index rootpage on disk and make an entry for -- ** the index in the sqlite_master table and populate the index with -- ** content. But, do not do this if we are simply reading the sqlite_master -- ** table to parse the schema, or if this index is the PRIMARY KEY index -- ** of a WITHOUT ROWID table. -- ** -- ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY -- ** or UNIQUE index in a CREATE TABLE statement. Since the table -- ** has just been created, it contains no data and the index initialization -- ** step can be skipped. -- */ -- else if( HasRowid(pTab) || pTblName!=0 ){ -- Vdbe *v; -- char *zStmt; -- int iMem = ++pParse->nMem; -+ /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the -+ ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then -+ ** emit code to allocate the index rootpage on disk and make an entry for -+ ** the index in the sqlite_master table and populate the index with -+ ** content. But, do not do this if we are simply reading the sqlite_master -+ ** table to parse the schema, or if this index is the PRIMARY KEY index -+ ** of a WITHOUT ROWID table. -+ ** -+ ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY -+ ** or UNIQUE index in a CREATE TABLE statement. Since the table -+ ** has just been created, it contains no data and the index initialization -+ ** step can be skipped. -+ */ -+ else if( HasRowid(pTab) || pTblName!=0 ){ -+ Vdbe *v; -+ char *zStmt; -+ int iMem = ++pParse->nMem; - -- v = sqlite3GetVdbe(pParse); -- if( v==0 ) goto exit_create_index; -+ v = sqlite3GetVdbe(pParse); -+ if( v==0 ) goto exit_create_index; - -- sqlite3BeginWriteOperation(pParse, 1, iDb); -+ sqlite3BeginWriteOperation(pParse, 1, iDb); - -- /* Create the rootpage for the index using CreateIndex. But before -- ** doing so, code a Noop instruction and store its address in -- ** Index.tnum. This is required in case this index is actually a -- ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In -- ** that case the convertToWithoutRowidTable() routine will replace -- ** the Noop with a Goto to jump over the VDBE code generated below. */ -- pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop); -- sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem); -+ /* Create the rootpage for the index using CreateIndex. But before -+ ** doing so, code a Noop instruction and store its address in -+ ** Index.tnum. This is required in case this index is actually a -+ ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In -+ ** that case the convertToWithoutRowidTable() routine will replace -+ ** the Noop with a Goto to jump over the VDBE code generated below. */ -+ pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop); -+ sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, iMem, BTREE_BLOBKEY); - -- /* Gather the complete text of the CREATE INDEX statement into -- ** the zStmt variable -- */ -- if( pStart ){ -- int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n; -- if( pName->z[n-1]==';' ) n--; -- /* A named index with an explicit CREATE INDEX statement */ -- zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", -- onError==OE_None ? "" : " UNIQUE", n, pName->z); -- }else{ -- /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ -- /* zStmt = sqlite3MPrintf(""); */ -- zStmt = 0; -- } -+ /* Gather the complete text of the CREATE INDEX statement into -+ ** the zStmt variable -+ */ -+ if( pStart ){ -+ int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n; -+ if( pName->z[n-1]==';' ) n--; -+ /* A named index with an explicit CREATE INDEX statement */ -+ zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", -+ onError==OE_None ? "" : " UNIQUE", n, pName->z); -+ }else{ -+ /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ -+ /* zStmt = sqlite3MPrintf(""); */ -+ zStmt = 0; -+ } - -- /* Add an entry in sqlite_master for this index -- */ -- sqlite3NestedParse(pParse, -- "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", -- db->aDb[iDb].zDbSName, MASTER_NAME, -- pIndex->zName, -- pTab->zName, -- iMem, -- zStmt -- ); -- sqlite3DbFree(db, zStmt); -+ /* Add an entry in sqlite_master for this index -+ */ -+ sqlite3NestedParse(pParse, -+ "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", -+ db->aDb[iDb].zDbSName, MASTER_NAME, -+ pIndex->zName, -+ pTab->zName, -+ iMem, -+ zStmt -+ ); -+ sqlite3DbFree(db, zStmt); - -- /* Fill the index with data and reparse the schema. Code an OP_Expire -- ** to invalidate all pre-compiled statements. -- */ -- if( pTblName ){ -- sqlite3RefillIndex(pParse, pIndex, iMem); -- sqlite3ChangeCookie(pParse, iDb); -- sqlite3VdbeAddParseSchemaOp(v, iDb, -- sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName)); -- sqlite3VdbeAddOp0(v, OP_Expire); -+ /* Fill the index with data and reparse the schema. Code an OP_Expire -+ ** to invalidate all pre-compiled statements. -+ */ -+ if( pTblName ){ -+ sqlite3RefillIndex(pParse, pIndex, iMem); -+ sqlite3ChangeCookie(pParse, iDb); -+ sqlite3VdbeAddParseSchemaOp(v, iDb, -+ sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName)); -+ sqlite3VdbeAddOp2(v, OP_Expire, 0, 1); -+ } -+ -+ sqlite3VdbeJumpHere(v, pIndex->tnum); - } -- -- sqlite3VdbeJumpHere(v, pIndex->tnum); - } - - /* When adding an index to the list of indices for a table, make -@@ -103879,10 +109512,15 @@ - } - pIndex = 0; - } -+ else if( IN_RENAME_OBJECT ){ -+ assert( pParse->pNewIndex==0 ); -+ pParse->pNewIndex = pIndex; -+ pIndex = 0; -+ } - - /* Clean up before exiting */ - exit_create_index: -- if( pIndex ) freeIndex(db, pIndex); -+ if( pIndex ) sqlite3FreeIndex(db, pIndex); - sqlite3ExprDelete(db, pPIWhere); - sqlite3ExprListDelete(db, pList); - sqlite3SrcListDelete(db, pTblName); -@@ -104051,7 +109689,8 @@ - ** - ** A new IdList is returned, or NULL if malloc() fails. - */ --SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){ -+SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *pToken){ -+ sqlite3 *db = pParse->db; - int i; - if( pList==0 ){ - pList = sqlite3DbMallocZero(db, sizeof(IdList) ); -@@ -104069,6 +109708,9 @@ - return 0; - } - pList->a[i].zName = sqlite3NameFromToken(db, pToken); -+ if( IN_RENAME_OBJECT && pList->a[i].zName ){ -+ sqlite3RenameTokenMap(pParse, (void*)pList->a[i].zName, pToken); -+ } - return pList; - } - -@@ -104310,10 +109952,17 @@ - goto append_from_error; - } - p = sqlite3SrcListAppend(db, p, pTable, pDatabase); -- if( p==0 || NEVER(p->nSrc==0) ){ -+ if( p==0 ){ - goto append_from_error; - } -+ assert( p->nSrc>0 ); - pItem = &p->a[p->nSrc-1]; -+ assert( (pTable==0)==(pDatabase==0) ); -+ assert( pItem->zName==0 || pDatabase!=0 ); -+ if( IN_RENAME_OBJECT && pItem->zName ){ -+ Token *pToken = (ALWAYS(pDatabase) && pDatabase->z) ? pDatabase : pTable; -+ sqlite3RenameTokenMap(pParse, pItem->zName, pToken); -+ } - assert( pAlias!=0 ); - if( pAlias->n ){ - pItem->zAlias = sqlite3NameFromToken(db, pAlias); -@@ -104337,8 +109986,10 @@ - */ - SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ - assert( pIndexedBy!=0 ); -- if( p && ALWAYS(p->nSrc>0) ){ -- struct SrcList_item *pItem = &p->a[p->nSrc-1]; -+ if( p && pIndexedBy->n>0 ){ -+ struct SrcList_item *pItem; -+ assert( p->nSrc>0 ); -+ pItem = &p->a[p->nSrc-1]; - assert( pItem->fg.notIndexed==0 ); - assert( pItem->fg.isIndexedBy==0 ); - assert( pItem->fg.isTabFunc==0 ); -@@ -104348,7 +109999,7 @@ - pItem->fg.notIndexed = 1; - }else{ - pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy); -- pItem->fg.isIndexedBy = (pItem->u1.zIndexedBy!=0); -+ pItem->fg.isIndexedBy = 1; - } - } - } -@@ -104622,16 +110273,16 @@ - - sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200); - if( pIdx->aColExpr ){ -- sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName); -+ sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName); - }else{ - for(j=0; j<pIdx->nKeyCol; j++){ - char *zCol; - assert( pIdx->aiColumn[j]>=0 ); - zCol = pTab->aCol[pIdx->aiColumn[j]].zName; -- if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2); -- sqlite3StrAccumAppendAll(&errMsg, pTab->zName); -- sqlite3StrAccumAppend(&errMsg, ".", 1); -- sqlite3StrAccumAppendAll(&errMsg, zCol); -+ if( j ) sqlite3_str_append(&errMsg, ", ", 2); -+ sqlite3_str_appendall(&errMsg, pTab->zName); -+ sqlite3_str_append(&errMsg, ".", 1); -+ sqlite3_str_appendall(&errMsg, zCol); - } - } - zErr = sqlite3StrAccumFinish(&errMsg); -@@ -104819,6 +110470,18 @@ - pKey->aSortOrder[i] = pIdx->aSortOrder[i]; - } - if( pParse->nErr ){ -+ assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ ); -+ if( pIdx->bNoQuery==0 ){ -+ /* Deactivate the index because it contains an unknown collating -+ ** sequence. The only way to reactive the index is to reload the -+ ** schema. Adding the missing collating sequence later does not -+ ** reactive the index. The application had the chance to register -+ ** the missing index using the collation-needed callback. For -+ ** simplicity, SQLite will not give the application a second chance. -+ */ -+ pIdx->bNoQuery = 1; -+ pParse->rc = SQLITE_ERROR_RETRY; -+ } - sqlite3KeyInfoUnref(pKey); - pKey = 0; - } -@@ -105004,6 +110667,7 @@ - assert( !p || p->xCmp ); - if( p==0 ){ - sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); -+ pParse->rc = SQLITE_ERROR_MISSING_COLLSEQ; - } - return p; - } -@@ -105193,6 +110857,21 @@ - } - return 0; - } -+#ifdef SQLITE_ENABLE_NORMALIZE -+SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN( -+ int h, /* Hash of the name */ -+ const char *zFunc, /* Name of function */ -+ int nFunc /* Length of the name */ -+){ -+ FuncDef *p; -+ for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){ -+ if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 ){ -+ return p; -+ } -+ } -+ return 0; -+} -+#endif /* SQLITE_ENABLE_NORMALIZE */ - - /* - ** Insert a new FuncDef into a FuncDefHash hash table. -@@ -105206,7 +110885,7 @@ - FuncDef *pOther; - const char *zName = aDef[i].zName; - int nName = sqlite3Strlen30(zName); -- int h = (zName[0] + nName) % SQLITE_FUNC_HASH_SZ; -+ int h = SQLITE_FUNC_HASH(zName[0], nName); - assert( zName[0]>='a' && zName[0]<='z' ); - pOther = functionSearch(h, zName); - if( pOther ){ -@@ -105273,7 +110952,7 @@ - - /* If no match is found, search the built-in functions. - ** -- ** If the SQLITE_PreferBuiltin flag is set, then search the built-in -+ ** If the DBFLAG_PreferBuiltin flag is set, then search the built-in - ** functions even if a prior app-defined function was found. And give - ** priority to built-in functions. - ** -@@ -105283,9 +110962,9 @@ - ** new function. But the FuncDefs for built-in functions are read-only. - ** So we must not search for built-ins when creating a new function. - */ -- if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){ -+ if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){ - bestScore = 0; -- h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ; -+ h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName); - p = functionSearch(h, zName); - while( p ){ - int score = matchQuality(p, nArg, enc); -@@ -105304,10 +110983,12 @@ - if( createFlag && bestScore<FUNC_PERFECT_MATCH && - (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){ - FuncDef *pOther; -+ u8 *z; - pBest->zName = (const char*)&pBest[1]; - pBest->nArg = (u16)nArg; - pBest->funcFlags = enc; - memcpy((char*)&pBest[1], zName, nName+1); -+ for(z=(u8*)pBest->zName; *z; z++) *z = sqlite3UpperToLower[*z]; - pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest); - if( pOther==pBest ){ - sqlite3DbFree(db, pBest); -@@ -105356,8 +111037,8 @@ - pSchema->pSeqTab = 0; - if( pSchema->schemaFlags & DB_SchemaLoaded ){ - pSchema->iGeneration++; -- pSchema->schemaFlags &= ~DB_SchemaLoaded; - } -+ pSchema->schemaFlags &= ~(DB_SchemaLoaded|DB_ResetWanted); - } - - /* -@@ -105431,6 +111112,39 @@ - return pTab; - } - -+/* Return true if table pTab is read-only. -+** -+** A table is read-only if any of the following are true: -+** -+** 1) It is a virtual table and no implementation of the xUpdate method -+** has been provided -+** -+** 2) It is a system table (i.e. sqlite_master), this call is not -+** part of a nested parse and writable_schema pragma has not -+** been specified -+** -+** 3) The table is a shadow table, the database connection is in -+** defensive mode, and the current sqlite3_prepare() -+** is for a top-level SQL statement. -+*/ -+static int tabIsReadOnly(Parse *pParse, Table *pTab){ -+ sqlite3 *db; -+ if( IsVirtual(pTab) ){ -+ return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0; -+ } -+ if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0; -+ db = pParse->db; -+ if( (pTab->tabFlags & TF_Readonly)!=0 ){ -+ 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; -+} -+ - /* - ** Check to make sure the given table is writable. If it is not - ** writable, generate an error message and return 1. If it is -@@ -105437,26 +111151,10 @@ - ** writable return 0; - */ - SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ -- /* A table is not writable under the following circumstances: -- ** -- ** 1) It is a virtual table and no implementation of the xUpdate method -- ** has been provided, or -- ** 2) It is a system table (i.e. sqlite_master), this call is not -- ** part of a nested parse and writable_schema pragma has not -- ** been specified. -- ** -- ** In either case leave an error message in pParse and return non-zero. -- */ -- if( ( IsVirtual(pTab) -- && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ) -- || ( (pTab->tabFlags & TF_Readonly)!=0 -- && (pParse->db->flags & SQLITE_WriteSchema)==0 -- && pParse->nested==0 ) -- ){ -+ if( tabIsReadOnly(pParse, pTab) ){ - sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); - return 1; - } -- - #ifndef SQLITE_OMIT_VIEW - if( !viewOk && pTab->pSelect ){ - sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); -@@ -105477,6 +111175,8 @@ - Parse *pParse, /* Parsing context */ - Table *pView, /* View definition */ - Expr *pWhere, /* Optional WHERE clause to be added */ -+ ExprList *pOrderBy, /* Optional ORDER BY clause */ -+ Expr *pLimit, /* Optional LIMIT clause */ - int iCur /* Cursor number for ephemeral table */ - ){ - SelectDest dest; -@@ -105493,8 +111193,8 @@ - assert( pFrom->a[0].pOn==0 ); - assert( pFrom->a[0].pUsing==0 ); - } -- pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, -- SF_IncludeHidden, 0, 0); -+ pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy, -+ SF_IncludeHidden, pLimit); - sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); - sqlite3Select(pParse, pSel, &dest); - sqlite3SelectDelete(db, pSel); -@@ -105516,21 +111216,23 @@ - Expr *pWhere, /* The WHERE clause. May be null */ - ExprList *pOrderBy, /* The ORDER BY clause. May be null */ - Expr *pLimit, /* The LIMIT clause. May be null */ -- Expr *pOffset, /* The OFFSET clause. May be null */ - char *zStmtType /* Either DELETE or UPDATE. For err msgs. */ - ){ -- Expr *pWhereRowid = NULL; /* WHERE rowid .. */ -+ sqlite3 *db = pParse->db; -+ Expr *pLhs = NULL; /* LHS of IN(SELECT...) operator */ - Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */ -- Expr *pSelectRowid = NULL; /* SELECT rowid ... */ - ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */ - SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */ - Select *pSelect = NULL; /* Complete SELECT tree */ -+ Table *pTab; - - /* Check that there isn't an ORDER BY without a LIMIT clause. - */ -- if( pOrderBy && (pLimit == 0) ) { -+ if( pOrderBy && pLimit==0 ) { - sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType); -- goto limit_where_cleanup; -+ sqlite3ExprDelete(pParse->db, pWhere); -+ sqlite3ExprListDelete(pParse->db, pOrderBy); -+ return 0; - } - - /* We only need to generate a select expression if there -@@ -105537,8 +111239,6 @@ - ** is a limit/offset term to enforce. - */ - if( pLimit == 0 ) { -- /* if pLimit is null, pOffset will always be null as well. */ -- assert( pOffset == 0 ); - return pWhere; - } - -@@ -105551,36 +111251,47 @@ - ** ); - */ - -- pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0); -- if( pSelectRowid == 0 ) goto limit_where_cleanup; -- pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid); -- if( pEList == 0 ) goto limit_where_cleanup; -+ pTab = pSrc->a[0].pTab; -+ if( HasRowid(pTab) ){ -+ pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0); -+ pEList = sqlite3ExprListAppend( -+ pParse, 0, sqlite3PExpr(pParse, TK_ROW, 0, 0) -+ ); -+ }else{ -+ Index *pPk = sqlite3PrimaryKeyIndex(pTab); -+ if( pPk->nKeyCol==1 ){ -+ const char *zName = pTab->aCol[pPk->aiColumn[0]].zName; -+ pLhs = sqlite3Expr(db, TK_ID, zName); -+ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, zName)); -+ }else{ -+ int i; -+ for(i=0; i<pPk->nKeyCol; i++){ -+ Expr *p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zName); -+ pEList = sqlite3ExprListAppend(pParse, pEList, p); -+ } -+ pLhs = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); -+ if( pLhs ){ -+ pLhs->x.pList = sqlite3ExprListDup(db, pEList, 0); -+ } -+ } -+ } - - /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree - ** and the SELECT subtree. */ -+ pSrc->a[0].pTab = 0; - pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0); -- if( pSelectSrc == 0 ) { -- sqlite3ExprListDelete(pParse->db, pEList); -- goto limit_where_cleanup; -- } -+ pSrc->a[0].pTab = pTab; -+ pSrc->a[0].pIBIndex = 0; - - /* generate the SELECT expression tree. */ -- pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0, -- pOrderBy,0,pLimit,pOffset); -- if( pSelect == 0 ) return 0; -+ pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0, -+ pOrderBy,0,pLimit -+ ); - - /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */ -- pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0); -- pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0) : 0; -+ pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0); - sqlite3PExprAddSelect(pParse, pInClause, pSelect); - return pInClause; -- --limit_where_cleanup: -- sqlite3ExprDelete(pParse->db, pWhere); -- sqlite3ExprListDelete(pParse->db, pOrderBy); -- sqlite3ExprDelete(pParse->db, pLimit); -- sqlite3ExprDelete(pParse->db, pOffset); -- return 0; - } - #endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */ - /* && !defined(SQLITE_OMIT_SUBQUERY) */ -@@ -105595,7 +111306,9 @@ - SQLITE_PRIVATE void sqlite3DeleteFrom( - Parse *pParse, /* The parser context */ - SrcList *pTabList, /* The table from which we should delete things */ -- Expr *pWhere /* The WHERE clause. May be null */ -+ Expr *pWhere, /* The WHERE clause. May be null */ -+ ExprList *pOrderBy, /* ORDER BY clause. May be null */ -+ Expr *pLimit /* LIMIT clause. May be null */ - ){ - Vdbe *v; /* The virtual database engine */ - Table *pTab; /* The table from which records will be deleted */ -@@ -105610,7 +111323,7 @@ - AuthContext sContext; /* Authorization context */ - NameContext sNC; /* Name context to resolve expressions in */ - int iDb; /* Database number */ -- int memCnt = -1; /* Memory cell used for change counting */ -+ int memCnt = 0; /* Memory cell used for change counting */ - int rcauth; /* Value returned by authorization callback */ - int eOnePass; /* ONEPASS_OFF or _SINGLE or _MULTI */ - int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */ -@@ -105640,6 +111353,7 @@ - } - assert( pTabList->nSrc==1 ); - -+ - /* Locate the table which we want to delete. This table has to be - ** put in an SrcList structure because some of the subroutines we - ** will be calling are designed to work with multiple tables and expect -@@ -105654,16 +111368,26 @@ - #ifndef SQLITE_OMIT_TRIGGER - pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); - isView = pTab->pSelect!=0; -- bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0); - #else - # define pTrigger 0 - # define isView 0 - #endif -+ bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0); - #ifdef SQLITE_OMIT_VIEW - # undef isView - # define isView 0 - #endif - -+#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT -+ if( !isView ){ -+ pWhere = sqlite3LimitWhere( -+ pParse, pTabList, pWhere, pOrderBy, pLimit, "DELETE" -+ ); -+ pOrderBy = 0; -+ pLimit = 0; -+ } -+#endif -+ - /* If pTab is really a view, make sure it has been initialized. - */ - if( sqlite3ViewGetColumnNames(pParse, pTab) ){ -@@ -105704,7 +111428,7 @@ - goto delete_from_cleanup; - } - if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); -- sqlite3BeginWriteOperation(pParse, 1, iDb); -+ sqlite3BeginWriteOperation(pParse, bComplex, iDb); - - /* If we are trying to delete from a view, realize that view into - ** an ephemeral table. -@@ -105711,8 +111435,12 @@ - */ - #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) - if( isView ){ -- sqlite3MaterializeView(pParse, pTab, pWhere, iTabCur); -+ sqlite3MaterializeView(pParse, pTab, -+ pWhere, pOrderBy, pLimit, iTabCur -+ ); - iDataCur = iIdxCur = iTabCur; -+ pOrderBy = 0; -+ pLimit = 0; - } - #endif - -@@ -105728,7 +111456,10 @@ - /* Initialize the counter of the number of rows deleted, if - ** we are counting rows. - */ -- if( db->flags & SQLITE_CountRows ){ -+ if( (db->flags & SQLITE_CountRows)!=0 -+ && !pParse->nested -+ && !pParse->pTriggerTab -+ ){ - memCnt = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt); - } -@@ -105756,7 +111487,7 @@ - assert( !isView ); - sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); - if( HasRowid(pTab) ){ -- sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt, -+ sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt ? memCnt : -1, - pTab->zName, P4_STATIC); - } - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ -@@ -105801,9 +111532,10 @@ - eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); - assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI ); - assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF ); -+ if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse); - - /* Keep track of the number of rows to be deleted */ -- if( db->flags & SQLITE_CountRows ){ -+ if( memCnt ){ - sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); - } - -@@ -105816,9 +111548,8 @@ - } - iKey = iPk; - }else{ -- iKey = pParse->nMem + 1; -- iKey = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iKey, 0); -- if( iKey>pParse->nMem ) pParse->nMem = iKey; -+ iKey = ++pParse->nMem; -+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, -1, iKey); - } - - if( eOnePass!=ONEPASS_OFF ){ -@@ -105889,7 +111620,11 @@ - } - }else if( pPk ){ - addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v); -- sqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey); -+ if( IsVirtual(pTab) ){ -+ sqlite3VdbeAddOp3(v, OP_Column, iEphCur, 0, iKey); -+ }else{ -+ sqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey); -+ } - assert( nKey==0 ); /* OP_Found will use a composite key */ - }else{ - addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey); -@@ -105902,13 +111637,16 @@ - if( IsVirtual(pTab) ){ - const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); - sqlite3VtabMakeWritable(pParse, pTab); -- sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB); -- sqlite3VdbeChangeP5(v, OE_Abort); - assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE ); - sqlite3MayAbort(pParse); -- if( eOnePass==ONEPASS_SINGLE && sqlite3IsToplevel(pParse) ){ -- pParse->isMultiWrite = 0; -+ if( eOnePass==ONEPASS_SINGLE ){ -+ sqlite3VdbeAddOp1(v, OP_Close, iTabCur); -+ if( sqlite3IsToplevel(pParse) ){ -+ pParse->isMultiWrite = 0; -+ } - } -+ sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB); -+ sqlite3VdbeChangeP5(v, OE_Abort); - }else - #endif - { -@@ -105942,7 +111680,7 @@ - ** generating code because of a call to sqlite3NestedParse(), do not - ** invoke the callback function. - */ -- if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){ -+ if( memCnt ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); -@@ -105952,6 +111690,10 @@ - sqlite3AuthContextPop(&sContext); - sqlite3SrcListDelete(db, pTabList); - sqlite3ExprDelete(db, pWhere); -+#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) -+ sqlite3ExprListDelete(db, pOrderBy); -+ sqlite3ExprDelete(db, pLimit); -+#endif - sqlite3DbFree(db, aToOpen); - return; - } -@@ -106109,7 +111851,7 @@ - u8 p5 = 0; - sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek); - sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0)); -- if( pParse->nested==0 ){ -+ if( pParse->nested==0 || 0==sqlite3_stricmp(pTab->zName, "sqlite_stat1") ){ - sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE); - } - if( eMode!=ONEPASS_OFF ){ -@@ -106240,7 +111982,6 @@ - if( pIdx->pPartIdxWhere ){ - *piPartIdxLabel = sqlite3VdbeMakeLabel(v); - pParse->iSelfTab = iDataCur + 1; -- sqlite3ExprCachePush(pParse); - sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, - SQLITE_JUMPIFNULL); - pParse->iSelfTab = 0; -@@ -106287,7 +112028,6 @@ - SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ - if( iLabel ){ - sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel); -- sqlite3ExprCachePop(pParse); - } - } - -@@ -106330,6 +112070,8 @@ - ** iteration of the aggregate loop. - */ - static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){ -+ assert( context->isError<=0 ); -+ context->isError = -1; - context->skipFlag = 1; - } - -@@ -106396,8 +112138,6 @@ - int argc, - sqlite3_value **argv - ){ -- int len; -- - assert( argc==1 ); - UNUSED_PARAMETER(argc); - switch( sqlite3_value_type(argv[0]) ){ -@@ -106409,13 +112149,17 @@ - } - case SQLITE_TEXT: { - const unsigned char *z = sqlite3_value_text(argv[0]); -+ const unsigned char *z0; -+ unsigned char c; - if( z==0 ) return; -- len = 0; -- while( *z ){ -- len++; -- SQLITE_SKIP_UTF8(z); -+ z0 = z; -+ while( (c = *z)!=0 ){ -+ z++; -+ if( c>=0xc0 ){ -+ while( (*z & 0xc0)==0x80 ){ z++; z0++; } -+ } - } -- sqlite3_result_int(context, len); -+ sqlite3_result_int(context, (int)(z-z0)); - break; - } - default: { -@@ -106542,7 +112286,7 @@ - x.apArg = argv+1; - sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); - str.printfFlags = SQLITE_PRINTF_SQLFUNC; -- sqlite3XPrintf(&str, zFormat, &x); -+ sqlite3_str_appendf(&str, zFormat, &x); - n = str.nChar; - sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n, - SQLITE_DYNAMIC); -@@ -106993,16 +112737,20 @@ - ** c or cx. - */ - if( c<=0x80 ){ -- u32 cx; -+ char zStop[3]; - int bMatch; - if( noCase ){ -- cx = sqlite3Toupper(c); -- c = sqlite3Tolower(c); -+ zStop[0] = sqlite3Toupper(c); -+ zStop[1] = sqlite3Tolower(c); -+ zStop[2] = 0; - }else{ -- cx = c; -+ zStop[0] = c; -+ zStop[1] = 0; - } -- while( (c2 = *(zString++))!=0 ){ -- if( c2!=c && c2!=cx ) continue; -+ while(1){ -+ zString += strcspn((const char*)zString, zStop); -+ if( zString[0]==0 ) break; -+ zString++; - bMatch = patternCompare(zPattern,zString,pInfo,matchOther); - if( bMatch!=SQLITE_NOMATCH ) return bMatch; - } -@@ -107160,7 +112908,8 @@ - #ifdef SQLITE_TEST - sqlite3_like_count++; - #endif -- sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH); -+ sqlite3_result_int(context, -+ patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH); - } - } - -@@ -107485,6 +113234,8 @@ - i64 nOut; /* Maximum size of zOut */ - int loopLimit; /* Last zStr[] that might match zPattern[] */ - int i, j; /* Loop counters */ -+ unsigned cntExpand; /* Number zOut expansions */ -+ sqlite3 *db = sqlite3_context_db_handle(context); - - assert( argc==3 ); - UNUSED_PARAMETER(argc); -@@ -107516,33 +113267,40 @@ - return; - } - loopLimit = nStr - nPattern; -+ cntExpand = 0; - for(i=j=0; i<=loopLimit; i++){ - if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){ - zOut[j++] = zStr[i]; - }else{ -- u8 *zOld; -- sqlite3 *db = sqlite3_context_db_handle(context); -- nOut += nRep - nPattern; -- testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] ); -- testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] ); -- if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ -- sqlite3_result_error_toobig(context); -- sqlite3_free(zOut); -- return; -+ if( nRep>nPattern ){ -+ nOut += nRep - nPattern; -+ testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] ); -+ testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] ); -+ if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ -+ sqlite3_result_error_toobig(context); -+ sqlite3_free(zOut); -+ return; -+ } -+ cntExpand++; -+ if( (cntExpand&(cntExpand-1))==0 ){ -+ /* Grow the size of the output buffer only on substitutions -+ ** whose index is a power of two: 1, 2, 4, 8, 16, 32, ... */ -+ u8 *zOld; -+ zOld = zOut; -+ zOut = sqlite3_realloc64(zOut, (int)nOut + (nOut - nStr - 1)); -+ if( zOut==0 ){ -+ sqlite3_result_error_nomem(context); -+ sqlite3_free(zOld); -+ return; -+ } -+ } - } -- zOld = zOut; -- zOut = sqlite3_realloc64(zOut, (int)nOut); -- if( zOut==0 ){ -- sqlite3_result_error_nomem(context); -- sqlite3_free(zOld); -- return; -- } - memcpy(&zOut[j], zRep, nRep); - j += nRep; - i += nPattern-1; - } - } -- assert( j+nStr-i+1==nOut ); -+ assert( j+nStr-i+1<=nOut ); - memcpy(&zOut[j], &zStr[i], nStr-i); - j += nStr - i; - assert( j<=nOut ); -@@ -107782,7 +113540,7 @@ - i64 v = sqlite3_value_int64(argv[0]); - p->rSum += v; - if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){ -- p->overflow = 1; -+ p->approx = p->overflow = 1; - } - }else{ - p->rSum += sqlite3_value_double(argv[0]); -@@ -107790,6 +113548,32 @@ - } - } - } -+#ifndef SQLITE_OMIT_WINDOWFUNC -+static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){ -+ SumCtx *p; -+ int type; -+ assert( argc==1 ); -+ UNUSED_PARAMETER(argc); -+ p = sqlite3_aggregate_context(context, sizeof(*p)); -+ type = sqlite3_value_numeric_type(argv[0]); -+ /* p is always non-NULL because sumStep() will have been called first -+ ** to initialize it */ -+ if( ALWAYS(p) && type!=SQLITE_NULL ){ -+ assert( p->cnt>0 ); -+ p->cnt--; -+ assert( type==SQLITE_INTEGER || p->approx ); -+ if( type==SQLITE_INTEGER && p->approx==0 ){ -+ i64 v = sqlite3_value_int64(argv[0]); -+ p->rSum -= v; -+ p->iSum -= v; -+ }else{ -+ p->rSum -= sqlite3_value_double(argv[0]); -+ } -+ } -+} -+#else -+# define sumInverse 0 -+#endif /* SQLITE_OMIT_WINDOWFUNC */ - static void sumFinalize(sqlite3_context *context){ - SumCtx *p; - p = sqlite3_aggregate_context(context, 0); -@@ -107824,6 +113608,9 @@ - typedef struct CountCtx CountCtx; - struct CountCtx { - i64 n; -+#ifdef SQLITE_DEBUG -+ int bInverse; /* True if xInverse() ever called */ -+#endif - }; - - /* -@@ -107841,7 +113628,7 @@ - ** sure it still operates correctly, verify that its count agrees with our - ** internal count when using count(*) and when the total count can be - ** expressed as a 32-bit integer. */ -- assert( argc==1 || p==0 || p->n>0x7fffffff -+ assert( argc==1 || p==0 || p->n>0x7fffffff || p->bInverse - || p->n==sqlite3_aggregate_count(context) ); - #endif - } -@@ -107850,6 +113637,21 @@ - p = sqlite3_aggregate_context(context, 0); - sqlite3_result_int64(context, p ? p->n : 0); - } -+#ifndef SQLITE_OMIT_WINDOWFUNC -+static void countInverse(sqlite3_context *ctx, int argc, sqlite3_value **argv){ -+ CountCtx *p; -+ p = sqlite3_aggregate_context(ctx, sizeof(*p)); -+ /* p is always non-NULL since countStep() will have been called first */ -+ if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && ALWAYS(p) ){ -+ p->n--; -+#ifdef SQLITE_DEBUG -+ p->bInverse = 1; -+#endif -+ } -+} -+#else -+# define countInverse 0 -+#endif /* SQLITE_OMIT_WINDOWFUNC */ - - /* - ** Routines to implement min() and max() aggregate functions. -@@ -107866,7 +113668,7 @@ - pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest)); - if( !pBest ) return; - -- if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ -+ if( sqlite3_value_type(pArg)==SQLITE_NULL ){ - if( pBest->flags ) sqlite3SkipAccumulatorLoad(context); - }else if( pBest->flags ){ - int max; -@@ -107892,7 +113694,7 @@ - sqlite3VdbeMemCopy(pBest, pArg); - } - } --static void minMaxFinalize(sqlite3_context *context){ -+static void minMaxValueFinalize(sqlite3_context *context, int bValue){ - sqlite3_value *pRes; - pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0); - if( pRes ){ -@@ -107899,9 +113701,19 @@ - if( pRes->flags ){ - sqlite3_result_value(context, pRes); - } -- sqlite3VdbeMemRelease(pRes); -+ if( bValue==0 ) sqlite3VdbeMemRelease(pRes); - } - } -+#ifndef SQLITE_OMIT_WINDOWFUNC -+static void minMaxValue(sqlite3_context *context){ -+ minMaxValueFinalize(context, 1); -+} -+#else -+# define minMaxValue 0 -+#endif /* SQLITE_OMIT_WINDOWFUNC */ -+static void minMaxFinalize(sqlite3_context *context){ -+ minMaxValueFinalize(context, 0); -+} - - /* - ** group_concat(EXPR, ?SEPARATOR?) -@@ -107931,20 +113743,52 @@ - zSep = ","; - nSep = 1; - } -- if( zSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep); -+ if( zSep ) sqlite3_str_append(pAccum, zSep, nSep); - } - zVal = (char*)sqlite3_value_text(argv[0]); - nVal = sqlite3_value_bytes(argv[0]); -- if( zVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal); -+ if( zVal ) sqlite3_str_append(pAccum, zVal, nVal); - } - } -+#ifndef SQLITE_OMIT_WINDOWFUNC -+static void groupConcatInverse( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ int n; -+ StrAccum *pAccum; -+ assert( argc==1 || argc==2 ); -+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; -+ pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum)); -+ /* pAccum is always non-NULL since groupConcatStep() will have always -+ ** run frist to initialize it */ -+ if( ALWAYS(pAccum) ){ -+ n = sqlite3_value_bytes(argv[0]); -+ if( argc==2 ){ -+ n += sqlite3_value_bytes(argv[1]); -+ }else{ -+ n++; -+ } -+ if( n>=(int)pAccum->nChar ){ -+ pAccum->nChar = 0; -+ }else{ -+ pAccum->nChar -= n; -+ memmove(pAccum->zText, &pAccum->zText[n], pAccum->nChar); -+ } -+ if( pAccum->nChar==0 ) pAccum->mxAlloc = 0; -+ } -+} -+#else -+# define groupConcatInverse 0 -+#endif /* SQLITE_OMIT_WINDOWFUNC */ - static void groupConcatFinalize(sqlite3_context *context){ - StrAccum *pAccum; - pAccum = sqlite3_aggregate_context(context, 0); - if( pAccum ){ -- if( pAccum->accError==STRACCUM_TOOBIG ){ -+ if( pAccum->accError==SQLITE_TOOBIG ){ - sqlite3_result_error_toobig(context); -- }else if( pAccum->accError==STRACCUM_NOMEM ){ -+ }else if( pAccum->accError==SQLITE_NOMEM ){ - sqlite3_result_error_nomem(context); - }else{ - sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, -@@ -107952,6 +113796,24 @@ - } - } - } -+#ifndef SQLITE_OMIT_WINDOWFUNC -+static void groupConcatValue(sqlite3_context *context){ -+ sqlite3_str *pAccum; -+ pAccum = (sqlite3_str*)sqlite3_aggregate_context(context, 0); -+ if( pAccum ){ -+ if( pAccum->accError==SQLITE_TOOBIG ){ -+ sqlite3_result_error_toobig(context); -+ }else if( pAccum->accError==SQLITE_NOMEM ){ -+ sqlite3_result_error_nomem(context); -+ }else{ -+ const char *zText = sqlite3_str_value(pAccum); -+ sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT); -+ } -+ } -+} -+#else -+# define groupConcatValue 0 -+#endif /* SQLITE_OMIT_WINDOWFUNC */ - - /* - ** This routine does per-connection function registration. Most -@@ -107989,10 +113851,10 @@ - }else{ - pInfo = (struct compareInfo*)&likeInfoNorm; - } -- sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0); -- sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0); -+ sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); -+ sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); - sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, -- (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0); -+ (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0, 0, 0); - setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE); - setLikeOptFlag(db, "like", - caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE); -@@ -108001,10 +113863,15 @@ - /* - ** pExpr points to an expression which implements a function. If - ** it is appropriate to apply the LIKE optimization to that function --** then set aWc[0] through aWc[2] to the wildcard characters and --** return TRUE. If the function is not a LIKE-style function then --** return FALSE. -+** then set aWc[0] through aWc[2] to the wildcard characters and the -+** escape character and then return TRUE. If the function is not a -+** LIKE-style function then return FALSE. - ** -+** The expression "a LIKE b ESCAPE c" is only considered a valid LIKE -+** operator if c is a string literal that is exactly one byte in length. -+** That one byte is stored in aWc[3]. aWc[3] is set to zero if there is -+** no ESCAPE clause. -+** - ** *pIsNocase is set to true if uppercase and lowercase are equivalent for - ** the function (default for LIKE). If the function makes the distinction - ** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to -@@ -108012,17 +113879,26 @@ - */ - SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ - FuncDef *pDef; -- if( pExpr->op!=TK_FUNCTION -- || !pExpr->x.pList -- || pExpr->x.pList->nExpr!=2 -- ){ -+ int nExpr; -+ if( pExpr->op!=TK_FUNCTION || !pExpr->x.pList ){ - return 0; - } - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); -- pDef = sqlite3FindFunction(db, pExpr->u.zToken, 2, SQLITE_UTF8, 0); -+ nExpr = pExpr->x.pList->nExpr; -+ pDef = sqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0); - if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){ - return 0; - } -+ if( nExpr<3 ){ -+ aWc[3] = 0; -+ }else{ -+ Expr *pEscape = pExpr->x.pList->a[2].pExpr; -+ char *zEscape; -+ if( pEscape->op!=TK_STRING ) return 0; -+ zEscape = pEscape->u.zToken; -+ if( zEscape[0]==0 || zEscape[1]!=0 ) return 0; -+ aWc[3] = zEscape[0]; -+ } - - /* The memcpy() statement assumes that the wildcard characters are - ** the first three statements in the compareInfo structure. The -@@ -108075,6 +113951,10 @@ - #ifdef SQLITE_DEBUG - FUNCTION2(affinity, 1, 0, 0, noopFunc, SQLITE_FUNC_AFFINITY), - #endif -+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC -+ FUNCTION2(sqlite_offset, 1, 0, 0, noopFunc, SQLITE_FUNC_OFFSET| -+ SQLITE_FUNC_TYPEOF), -+#endif - FUNCTION(ltrim, 1, 1, 0, trimFunc ), - FUNCTION(ltrim, 2, 1, 0, trimFunc ), - FUNCTION(rtrim, 1, 2, 0, trimFunc ), -@@ -108083,11 +113963,11 @@ - FUNCTION(trim, 2, 3, 0, trimFunc ), - FUNCTION(min, -1, 0, 1, minmaxFunc ), - FUNCTION(min, 0, 0, 1, 0 ), -- AGGREGATE2(min, 1, 0, 1, minmaxStep, minMaxFinalize, -+ WAGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize, minMaxValue, 0, - SQLITE_FUNC_MINMAX ), - FUNCTION(max, -1, 1, 1, minmaxFunc ), - FUNCTION(max, 0, 1, 1, 0 ), -- AGGREGATE2(max, 1, 1, 1, minmaxStep, minMaxFinalize, -+ WAGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize, minMaxValue, 0, - SQLITE_FUNC_MINMAX ), - FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), - FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), -@@ -108118,14 +113998,17 @@ - FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ), - FUNCTION(substr, 2, 0, 0, substrFunc ), - FUNCTION(substr, 3, 0, 0, substrFunc ), -- AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ), -- AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ), -- AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ), -- AGGREGATE2(count, 0, 0, 0, countStep, countFinalize, -- SQLITE_FUNC_COUNT ), -- AGGREGATE(count, 1, 0, 0, countStep, countFinalize ), -- AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize), -- AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize), -+ WAGGREGATE(sum, 1,0,0, sumStep, sumFinalize, sumFinalize, sumInverse, 0), -+ WAGGREGATE(total, 1,0,0, sumStep,totalFinalize,totalFinalize,sumInverse, 0), -+ WAGGREGATE(avg, 1,0,0, sumStep, avgFinalize, avgFinalize, sumInverse, 0), -+ WAGGREGATE(count, 0,0,0, countStep, -+ countFinalize, countFinalize, countInverse, SQLITE_FUNC_COUNT ), -+ WAGGREGATE(count, 1,0,0, countStep, -+ countFinalize, countFinalize, countInverse, 0 ), -+ WAGGREGATE(group_concat, 1, 0, 0, groupConcatStep, -+ groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), -+ WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep, -+ groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), - - LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), - #ifdef SQLITE_CASE_SENSITIVE_LIKE -@@ -108145,6 +114028,7 @@ - #ifndef SQLITE_OMIT_ALTERTABLE - sqlite3AlterFunctions(); - #endif -+ sqlite3WindowFunctions(); - #if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4) - sqlite3AnalyzeFunctions(); - #endif -@@ -108503,6 +114387,12 @@ - int iCur = pParse->nTab - 1; /* Cursor number to use */ - int iOk = sqlite3VdbeMakeLabel(v); /* jump here if parent key found */ - -+ sqlite3VdbeVerifyAbortable(v, -+ (!pFKey->isDeferred -+ && !(pParse->db->flags & SQLITE_DeferFKs) -+ && !pParse->pToplevel -+ && !pParse->isMultiWrite) ? OE_Abort : OE_Ignore); -+ - /* If nIncr is less than zero, then check at runtime if there are any - ** outstanding constraints to resolve. If there are not, there is no need - ** to check if deleting this row resolves any outstanding violations. -@@ -108668,7 +114558,7 @@ - ){ - Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0); - if( pExpr ){ -- pExpr->pTab = pTab; -+ pExpr->y.pTab = pTab; - pExpr->iTable = iCursor; - pExpr->iColumn = iCol; - } -@@ -108876,11 +114766,12 @@ - */ - SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ - sqlite3 *db = pParse->db; -- if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) && !pTab->pSelect ){ -+ if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) ){ - int iSkip = 0; - Vdbe *v = sqlite3GetVdbe(pParse); - - assert( v ); /* VDBE has already been allocated */ -+ assert( pTab->pSelect==0 ); /* Not a view */ - if( sqlite3FkReferences(pTab)==0 ){ - /* Search for a deferred foreign key constraint for which this table - ** is the child table. If one cannot be found, return without -@@ -108897,7 +114788,7 @@ - } - - pParse->disableTriggers = 1; -- sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0); -+ sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0); - pParse->disableTriggers = 0; - - /* If the DELETE has generated immediate foreign key constraint -@@ -108910,6 +114801,7 @@ - ** constraints are violated. - */ - if( (db->flags & SQLITE_DeferFKs)==0 ){ -+ sqlite3VdbeVerifyAbortable(v, OE_Abort); - sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2); - VdbeCoverage(v); - sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, -@@ -109455,7 +115347,7 @@ - sqlite3ExprListAppend(pParse, 0, pRaise), - sqlite3SrcListAppend(db, 0, &tFrom, 0), - pWhere, -- 0, 0, 0, 0, 0, 0 -+ 0, 0, 0, 0, 0 - ); - pWhere = 0; - } -@@ -109742,7 +115634,8 @@ - }while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB ); - pTab->zColAff = zColAff; - } -- i = sqlite3Strlen30(zColAff); -+ assert( zColAff!=0 ); -+ i = sqlite3Strlen30NN(zColAff); - if( i ){ - if( iReg ){ - sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i); -@@ -109806,11 +115699,12 @@ - ** first use of table pTab. On 2nd and subsequent uses, the original - ** AutoincInfo structure is used. - ** --** Three memory locations are allocated: -+** Four consecutive registers are allocated: - ** --** (1) Register to hold the name of the pTab table. --** (2) Register to hold the maximum ROWID of pTab. --** (3) Register to hold the rowid in sqlite_sequence of pTab -+** (1) The name of the pTab table. -+** (2) The maximum ROWID of pTab. -+** (3) The rowid in sqlite_sequence of pTab -+** (4) The original value of the max ROWID in pTab, or NULL if none - ** - ** The 2nd register is the one that is returned. That is all the - ** insert routine needs to know about. -@@ -109821,12 +115715,27 @@ - Table *pTab /* The table we are writing to */ - ){ - int memId = 0; /* Register holding maximum rowid */ -+ assert( pParse->db->aDb[iDb].pSchema!=0 ); - if( (pTab->tabFlags & TF_Autoincrement)!=0 -- && (pParse->db->flags & SQLITE_Vacuum)==0 -+ && (pParse->db->mDbFlags & DBFLAG_Vacuum)==0 - ){ - Parse *pToplevel = sqlite3ParseToplevel(pParse); - AutoincInfo *pInfo; -+ Table *pSeqTab = pParse->db->aDb[iDb].pSchema->pSeqTab; - -+ /* Verify that the sqlite_sequence table exists and is an ordinary -+ ** rowid table with exactly two columns. -+ ** Ticket d8dc2b3a58cd5dc2918a1d4acb 2018-05-23 */ -+ if( pSeqTab==0 -+ || !HasRowid(pSeqTab) -+ || IsVirtual(pSeqTab) -+ || pSeqTab->nCol!=2 -+ ){ -+ pParse->nErr++; -+ pParse->rc = SQLITE_CORRUPT_SEQUENCE; -+ return 0; -+ } -+ - pInfo = pToplevel->pAinc; - while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } - if( pInfo==0 ){ -@@ -109838,7 +115747,7 @@ - pInfo->iDb = iDb; - pToplevel->nMem++; /* Register to hold name of table */ - pInfo->regCtr = ++pToplevel->nMem; /* Max rowid register */ -- pToplevel->nMem++; /* Rowid in sqlite_sequence */ -+ pToplevel->nMem +=2; /* Rowid in sqlite_sequence + orig max val */ - } - memId = pInfo->regCtr; - } -@@ -109866,15 +115775,17 @@ - static const int iLn = VDBE_OFFSET_LINENO(2); - static const VdbeOpList autoInc[] = { - /* 0 */ {OP_Null, 0, 0, 0}, -- /* 1 */ {OP_Rewind, 0, 9, 0}, -+ /* 1 */ {OP_Rewind, 0, 10, 0}, - /* 2 */ {OP_Column, 0, 0, 0}, -- /* 3 */ {OP_Ne, 0, 7, 0}, -+ /* 3 */ {OP_Ne, 0, 9, 0}, - /* 4 */ {OP_Rowid, 0, 0, 0}, - /* 5 */ {OP_Column, 0, 1, 0}, -- /* 6 */ {OP_Goto, 0, 9, 0}, -- /* 7 */ {OP_Next, 0, 2, 0}, -- /* 8 */ {OP_Integer, 0, 0, 0}, -- /* 9 */ {OP_Close, 0, 0, 0} -+ /* 6 */ {OP_AddImm, 0, 0, 0}, -+ /* 7 */ {OP_Copy, 0, 0, 0}, -+ /* 8 */ {OP_Goto, 0, 11, 0}, -+ /* 9 */ {OP_Next, 0, 2, 0}, -+ /* 10 */ {OP_Integer, 0, 0, 0}, -+ /* 11 */ {OP_Close, 0, 0, 0} - }; - VdbeOp *aOp; - pDb = &db->aDb[p->iDb]; -@@ -109885,7 +115796,7 @@ - aOp = sqlite3VdbeAddOpList(v, ArraySize(autoInc), autoInc, iLn); - if( aOp==0 ) break; - aOp[0].p2 = memId; -- aOp[0].p3 = memId+1; -+ aOp[0].p3 = memId+2; - aOp[2].p3 = memId; - aOp[3].p1 = memId-1; - aOp[3].p3 = memId; -@@ -109892,7 +115803,10 @@ - aOp[3].p5 = SQLITE_JUMPIFNULL; - aOp[4].p2 = memId+1; - aOp[5].p3 = memId; -- aOp[8].p2 = memId; -+ aOp[6].p1 = memId; -+ aOp[7].p2 = memId+2; -+ aOp[7].p1 = memId; -+ aOp[10].p2 = memId; - } - } - -@@ -109939,6 +115853,8 @@ - - iRec = sqlite3GetTempReg(pParse); - assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); -+ sqlite3VdbeAddOp3(v, OP_Le, memId+2, sqlite3VdbeCurrentAddr(v)+7, memId); -+ VdbeCoverage(v); - sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); - aOp = sqlite3VdbeAddOpList(v, ArraySize(autoIncEnd), autoIncEnd, iLn); - if( aOp==0 ) break; -@@ -110076,11 +115992,11 @@ - 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. */ -- int onError /* How to handle constraint errors */ -+ int onError, /* How to handle constraint errors */ -+ Upsert *pUpsert /* ON CONFLICT clauses for upsert, or NULL */ - ){ - sqlite3 *db; /* The main database structure */ - Table *pTab; /* The table to insert into. aka TABLE */ -- char *zTab; /* Name of the table into which we are inserting */ - int i, j; /* Loop counters */ - Vdbe *v; /* Generate code into this virtual machine */ - Index *pIdx; /* For looping over indices of the table */ -@@ -110136,8 +116052,6 @@ - /* Locate the table into which we will be inserting new information. - */ - assert( pTabList->nSrc==1 ); -- zTab = pTabList->a[0].zName; -- if( NEVER(zTab==0) ) goto insert_cleanup; - pTab = sqlite3SrcListLookup(pParse, pTabList); - if( pTab==0 ){ - goto insert_cleanup; -@@ -110374,7 +116288,10 @@ - - /* Initialize the count of rows to be inserted - */ -- if( db->flags & SQLITE_CountRows ){ -+ if( (db->flags & SQLITE_CountRows)!=0 -+ && !pParse->nested -+ && !pParse->pTriggerTab -+ ){ - regRowCount = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); - } -@@ -110394,7 +116311,20 @@ - pParse->nMem += pIdx->nColumn; - } - } -+#ifndef SQLITE_OMIT_UPSERT -+ if( pUpsert ){ -+ pTabList->a[0].iCursor = iDataCur; -+ pUpsert->pUpsertSrc = pTabList; -+ pUpsert->regData = regData; -+ pUpsert->iDataCur = iDataCur; -+ pUpsert->iIdxCur = iIdxCur; -+ if( pUpsert->pUpsertTarget ){ -+ sqlite3UpsertAnalyzeTarget(pParse, pTabList, pUpsert); -+ } -+ } -+#endif - -+ - /* This is the top of the main insertion loop */ - if( useTempTable ){ - /* This block codes the top of loop only. The complete loop is the -@@ -110508,7 +116438,8 @@ - VdbeOp *pOp; - sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid); - pOp = sqlite3VdbeGetOp(v, -1); -- if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){ -+ assert( pOp!=0 ); -+ if( pOp->opcode==OP_Null && !IsVirtual(pTab) ){ - appendFlag = 1; - pOp->opcode = OP_NewRowid; - pOp->p1 = iDataCur; -@@ -110595,7 +116526,7 @@ - int isReplace; /* Set to true if constraints may cause a replace */ - int bUseSeek; /* True to use OPFLAG_SEEKRESULT */ - sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, -- regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0 -+ regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0, pUpsert - ); - sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0); - -@@ -110618,7 +116549,7 @@ - - /* Update the count of rows that are inserted - */ -- if( (db->flags & SQLITE_CountRows)!=0 ){ -+ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); - } - -@@ -110655,7 +116586,7 @@ - ** generating code because of a call to sqlite3NestedParse(), do not - ** invoke the callback function. - */ -- if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){ -+ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC); -@@ -110664,6 +116595,7 @@ - insert_cleanup: - sqlite3SrcListDelete(db, pTabList); - sqlite3ExprListDelete(db, pList); -+ sqlite3UpsertDelete(db, pUpsert); - sqlite3SelectDelete(db, pSelect); - sqlite3IdListDelete(db, pColumn); - sqlite3DbFree(db, aRegIdx); -@@ -110683,14 +116615,15 @@ - #endif - - /* --** Meanings of bits in of pWalker->eCode for checkConstraintUnchanged() -+** Meanings of bits in of pWalker->eCode for -+** sqlite3ExprReferencesUpdatedColumn() - */ - #define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */ - #define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */ - --/* This is the Walker callback from checkConstraintUnchanged(). Set --** bit 0x01 of pWalker->eCode if --** pWalker->eCode to 0 if this expression node references any of the -+/* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn(). -+* Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this -+** expression node references any of the - ** columns that are being modifed by an UPDATE statement. - */ - static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){ -@@ -110712,12 +116645,21 @@ - ** only columns that are modified by the UPDATE are those for which - ** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true. - ** --** Return true if CHECK constraint pExpr does not use any of the -+** Return true if CHECK constraint pExpr uses any of the - ** changing columns (or the rowid if it is changing). In other words, --** return true if this CHECK constraint can be skipped when validating -+** return true if this CHECK constraint must be validated for - ** the new row in the UPDATE statement. -+** -+** 2018-09-15: pExpr might also be an expression for an index-on-expressions. -+** The operation of this routine is the same - return true if an only if -+** the expression uses one or more of columns identified by the second and -+** third arguments. - */ --static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){ -+SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn( -+ Expr *pExpr, /* The expression to be checked */ -+ int *aiChng, /* aiChng[x]>=0 if column x changed by the UPDATE */ -+ int chngRowid /* True if UPDATE changes the rowid */ -+){ - Walker w; - memset(&w, 0, sizeof(w)); - w.eCode = 0; -@@ -110732,7 +116674,7 @@ - testcase( w.eCode==CKCNSTRNT_COLUMN ); - testcase( w.eCode==CKCNSTRNT_ROWID ); - testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) ); -- return !w.eCode; -+ return w.eCode!=0; - } - - /* -@@ -110830,7 +116772,8 @@ - u8 overrideError, /* Override onError to this if not OE_Default */ - int ignoreDest, /* Jump to this label on an OE_Ignore resolution */ - int *pbMayReplace, /* OUT: Set to true if constraint may cause a replace */ -- int *aiChng /* column i is unchanged if aiChng[i]<0 */ -+ int *aiChng, /* column i is unchanged if aiChng[i]<0 */ -+ Upsert *pUpsert /* ON CONFLICT clauses, if any. NULL otherwise */ - ){ - Vdbe *v; /* VDBE under constrution */ - Index *pIdx; /* Pointer to one of the indices */ -@@ -110843,10 +116786,13 @@ - 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 */ -- int ipkTop = 0; /* Top of the rowid change constraint check */ -- int ipkBottom = 0; /* Bottom of the rowid change constraint check */ -+ Index *pUpIdx = 0; /* Index to which to apply the upsert */ - u8 isUpdate; /* True if this is an UPDATE operation */ - u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */ -+ int upsertBypass = 0; /* Address of Goto to bypass upsert subroutine */ -+ 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 */ - - isUpdate = regOldData!=0; - db = pParse->db; -@@ -110934,8 +116880,15 @@ - for(i=0; i<pCheck->nExpr; i++){ - int allOk; - Expr *pExpr = pCheck->a[i].pExpr; -- if( aiChng && checkConstraintUnchanged(pExpr, aiChng, pkChng) ) continue; -+ if( aiChng -+ && !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng) -+ ){ -+ /* The check constraints do not reference any of the columns being -+ ** updated so there is no point it verifying the check constraint */ -+ continue; -+ } - allOk = sqlite3VdbeMakeLabel(v); -+ sqlite3VdbeVerifyAbortable(v, onError); - sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL); - if( onError==OE_Ignore ){ - sqlite3VdbeGoto(v, ignoreDest); -@@ -110953,6 +116906,50 @@ - } - #endif /* !defined(SQLITE_OMIT_CHECK) */ - -+ /* UNIQUE and PRIMARY KEY constraints should be handled in the following -+ ** order: -+ ** -+ ** (1) OE_Update -+ ** (2) OE_Abort, OE_Fail, OE_Rollback, OE_Ignore -+ ** (3) OE_Replace -+ ** -+ ** OE_Fail and OE_Ignore must happen before any changes are made. -+ ** OE_Update guarantees that only a single row will change, so it -+ ** must happen before OE_Replace. Technically, OE_Abort and OE_Rollback -+ ** could happen in any order, but they are grouped up front for -+ ** convenience. -+ ** -+ ** 2018-08-14: Ticket https://www.sqlite.org/src/info/908f001483982c43 -+ ** The order of constraints used to have OE_Update as (2) and OE_Abort -+ ** and so forth as (1). But apparently PostgreSQL checks the OE_Update -+ ** constraint before any others, so it had to be moved. -+ ** -+ ** Constraint checking code is generated in this order: -+ ** (A) The rowid constraint -+ ** (B) Unique index constraints that do not have OE_Replace as their -+ ** default conflict resolution strategy -+ ** (C) Unique index that do use OE_Replace by default. -+ ** -+ ** The ordering of (2) and (3) is accomplished by making sure the linked -+ ** list of indexes attached to a table puts all OE_Replace indexes last -+ ** in the list. See sqlite3CreateIndex() for where that happens. -+ */ -+ -+ if( pUpsert ){ -+ if( pUpsert->pUpsertTarget==0 ){ -+ /* An ON CONFLICT DO NOTHING clause, without a constraint-target. -+ ** Make all unique constraint resolution be OE_Ignore */ -+ assert( pUpsert->pUpsertSet==0 ); -+ overrideError = OE_Ignore; -+ pUpsert = 0; -+ }else if( (pUpIdx = pUpsert->pUpsertIdx)!=0 ){ -+ /* If the constraint-target uniqueness check must be run first. -+ ** Jump to that uniqueness check now */ -+ upsertJump = sqlite3VdbeAddOp0(v, OP_Goto); -+ VdbeComment((v, "UPSERT constraint goes first")); -+ } -+ } -+ - /* If rowid is changing, make sure the new rowid does not previously - ** exist in the table. - */ -@@ -110967,6 +116964,28 @@ - onError = OE_Abort; - } - -+ /* figure out whether or not upsert applies in this case */ -+ if( pUpsert && pUpsert->pUpsertIdx==0 ){ -+ if( pUpsert->pUpsertSet==0 ){ -+ onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ -+ }else{ -+ onError = OE_Update; /* DO UPDATE */ -+ } -+ } -+ -+ /* If the response to a rowid conflict is REPLACE but the response -+ ** to some other UNIQUE constraint is FAIL or IGNORE, then we need -+ ** to defer the running of the rowid conflict checking until after -+ ** the UNIQUE constraints have run. -+ */ -+ if( onError==OE_Replace /* IPK rule is REPLACE */ -+ && onError!=overrideError /* Rules for other contraints are different */ -+ && pTab->pIndex /* There exist other constraints */ -+ ){ -+ ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1; -+ VdbeComment((v, "defer IPK REPLACE until last")); -+ } -+ - if( isUpdate ){ - /* pkChng!=0 does not mean that the rowid has changed, only that - ** it might have changed. Skip the conflict logic below if the rowid -@@ -110976,26 +116995,13 @@ - VdbeCoverage(v); - } - -- /* If the response to a rowid conflict is REPLACE but the response -- ** to some other UNIQUE constraint is FAIL or IGNORE, then we need -- ** to defer the running of the rowid conflict checking until after -- ** the UNIQUE constraints have run. -- */ -- if( onError==OE_Replace && overrideError!=OE_Replace ){ -- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ -- if( pIdx->onError==OE_Ignore || pIdx->onError==OE_Fail ){ -- ipkTop = sqlite3VdbeAddOp0(v, OP_Goto); -- break; -- } -- } -- } -- - /* Check to see if the new rowid already exists in the table. Skip - ** the following conflict logic if it does not. */ -+ VdbeNoopComment((v, "uniqueness check for ROWID")); -+ sqlite3VdbeVerifyAbortable(v, onError); - sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData); - VdbeCoverage(v); - -- /* Generate code that deals with a rowid collision */ - switch( onError ){ - default: { - onError = OE_Abort; -@@ -111004,6 +117010,9 @@ - case OE_Rollback: - case OE_Abort: - case OE_Fail: { -+ testcase( onError==OE_Rollback ); -+ testcase( onError==OE_Abort ); -+ testcase( onError==OE_Fail ); - sqlite3RowidConstraint(pParse, onError, pTab); - break; - } -@@ -111040,14 +117049,13 @@ - regNewData, 1, 0, OE_Replace, 1, -1); - }else{ - #ifdef SQLITE_ENABLE_PREUPDATE_HOOK -- if( HasRowid(pTab) ){ -- /* This OP_Delete opcode fires the pre-update-hook only. It does -- ** not modify the b-tree. It is more efficient to let the coming -- ** OP_Insert replace the existing entry than it is to delete the -- ** existing entry and then insert a new one. */ -- sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP); -- sqlite3VdbeAppendP4(v, pTab, P4_TABLE); -- } -+ assert( HasRowid(pTab) ); -+ /* This OP_Delete opcode fires the pre-update-hook only. It does -+ ** not modify the b-tree. It is more efficient to let the coming -+ ** OP_Insert replace the existing entry than it is to delete the -+ ** existing entry and then insert a new one. */ -+ sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP); -+ sqlite3VdbeAppendP4(v, pTab, P4_TABLE); - #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ - if( pTab->pIndex ){ - sqlite3MultiWrite(pParse); -@@ -111057,8 +117065,14 @@ - seenReplace = 1; - break; - } -+#ifndef SQLITE_OMIT_UPSERT -+ case OE_Update: { -+ sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, 0, iDataCur); -+ /* Fall through */ -+ } -+#endif - case OE_Ignore: { -- /*assert( seenReplace==0 );*/ -+ testcase( onError==OE_Ignore ); - sqlite3VdbeGoto(v, ignoreDest); - break; - } -@@ -111066,7 +117080,7 @@ - sqlite3VdbeResolveLabel(v, addrRowidOk); - if( ipkTop ){ - ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto); -- sqlite3VdbeJumpHere(v, ipkTop); -+ sqlite3VdbeJumpHere(v, ipkTop-1); - } - } - -@@ -111084,13 +117098,22 @@ - int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */ - - if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ -- if( bAffinityDone==0 ){ -+ if( pUpIdx==pIdx ){ -+ addrUniqueOk = upsertJump+1; -+ upsertBypass = sqlite3VdbeGoto(v, 0); -+ VdbeComment((v, "Skip upsert subroutine")); -+ sqlite3VdbeJumpHere(v, upsertJump); -+ }else{ -+ addrUniqueOk = sqlite3VdbeMakeLabel(v); -+ } -+ if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){ - sqlite3TableAffinity(v, pTab, regNewData+1); - bAffinityDone = 1; - } -+ VdbeNoopComment((v, "uniqueness check for %s", pIdx->zName)); - iThisCur = iIdxCur+ix; -- addrUniqueOk = sqlite3VdbeMakeLabel(v); - -+ - /* Skip partial indices for which the WHERE clause is not true */ - if( pIdx->pPartIdxWhere ){ - sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]); -@@ -111149,6 +117172,15 @@ - onError = OE_Abort; - } - -+ /* Figure out if the upsert clause applies to this index */ -+ if( pUpIdx==pIdx ){ -+ if( pUpsert->pUpsertSet==0 ){ -+ onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ -+ }else{ -+ onError = OE_Update; /* DO UPDATE */ -+ } -+ } -+ - /* Collision detection may be omitted if all of the following are true: - ** (1) The conflict resolution algorithm is REPLACE - ** (2) The table is a WITHOUT ROWID table -@@ -111169,6 +117201,7 @@ - } - - /* 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); - -@@ -111230,15 +117263,25 @@ - - /* Generate code that executes if the new index entry is not unique */ - assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail -- || onError==OE_Ignore || onError==OE_Replace ); -+ || onError==OE_Ignore || onError==OE_Replace || onError==OE_Update ); - switch( onError ){ - case OE_Rollback: - case OE_Abort: - case OE_Fail: { -+ testcase( onError==OE_Rollback ); -+ testcase( onError==OE_Abort ); -+ testcase( onError==OE_Fail ); - sqlite3UniqueConstraint(pParse, onError, pIdx); - break; - } -+#ifndef SQLITE_OMIT_UPSERT -+ case OE_Update: { -+ sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, pIdx, iIdxCur+ix); -+ /* Fall through */ -+ } -+#endif - case OE_Ignore: { -+ testcase( onError==OE_Ignore ); - sqlite3VdbeGoto(v, ignoreDest); - break; - } -@@ -111245,10 +117288,12 @@ - default: { - Trigger *pTrigger = 0; - assert( onError==OE_Replace ); -- sqlite3MultiWrite(pParse); - if( db->flags&SQLITE_RecTriggers ){ - pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); - } -+ if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){ -+ sqlite3MultiWrite(pParse); -+ } - sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, - regR, nPkField, 0, OE_Replace, - (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur); -@@ -111256,14 +117301,22 @@ - break; - } - } -- sqlite3VdbeResolveLabel(v, addrUniqueOk); -+ if( pUpIdx==pIdx ){ -+ sqlite3VdbeGoto(v, upsertJump+1); -+ sqlite3VdbeJumpHere(v, upsertBypass); -+ }else{ -+ sqlite3VdbeResolveLabel(v, addrUniqueOk); -+ } - if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); - } -+ -+ /* If the IPK constraint is a REPLACE, run it last */ - if( ipkTop ){ - sqlite3VdbeGoto(v, ipkTop+1); -+ VdbeComment((v, "Do IPK REPLACE")); - sqlite3VdbeJumpHere(v, ipkBottom); - } -- -+ - *pbMayReplace = seenReplace; - VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace)); - } -@@ -111359,7 +117412,6 @@ - sqlite3SetMakeRecordP5(v, pTab); - if( !bAffinityDone ){ - sqlite3TableAffinity(v, pTab, 0); -- sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol); - } - if( pParse->nested ){ - pik_flags = 0; -@@ -111605,7 +117657,6 @@ - if( pSelect->pLimit ){ - return 0; /* SELECT may not have a LIMIT clause */ - } -- assert( pSelect->pOffset==0 ); /* Must be so if pLimit==0 */ - if( pSelect->pPrior ){ - return 0; /* SELECT may not be a compound query */ - } -@@ -111655,7 +117706,7 @@ - Column *pDestCol = &pDest->aCol[i]; - Column *pSrcCol = &pSrc->aCol[i]; - #ifdef SQLITE_ENABLE_HIDDEN_COLUMNS -- if( (db->flags & SQLITE_Vacuum)==0 -+ if( (db->mDbFlags & DBFLAG_Vacuum)==0 - && (pDestCol->colFlags | pSrcCol->colFlags) & COLFLAG_HIDDEN - ){ - return 0; /* Neither table may have __hidden__ columns */ -@@ -111731,7 +117782,7 @@ - regRowid = sqlite3GetTempReg(pParse); - sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); - assert( HasRowid(pDest) || destHasUniqueIdx ); -- if( (db->flags & SQLITE_Vacuum)==0 && ( -+ if( (db->mDbFlags & DBFLAG_Vacuum)==0 && ( - (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */ - || destHasUniqueIdx /* (2) */ - || (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */ -@@ -111738,8 +117789,8 @@ - )){ - /* In some circumstances, we are able to run the xfer optimization - ** only if the destination table is initially empty. Unless the -- ** SQLITE_Vacuum flag is set, this block generates code to make -- ** that determination. If SQLITE_Vacuum is set, then the destination -+ ** DBFLAG_Vacuum flag is set, this block generates code to make -+ ** that determination. If DBFLAG_Vacuum is set, then the destination - ** table is always empty. - ** - ** Conditions under which the destination must be empty: -@@ -111763,6 +117814,7 @@ - emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); - if( pDest->iPKey>=0 ){ - addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); -+ sqlite3VdbeVerifyAbortable(v, onError); - addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); - VdbeCoverage(v); - sqlite3RowidConstraint(pParse, onError, pDest); -@@ -111775,8 +117827,8 @@ - assert( (pDest->tabFlags & TF_Autoincrement)==0 ); - } - sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); -- if( db->flags & SQLITE_Vacuum ){ -- sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1); -+ if( db->mDbFlags & DBFLAG_Vacuum ){ -+ sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); - insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID| - OPFLAG_APPEND|OPFLAG_USESEEKRESULT; - }else{ -@@ -111807,13 +117859,13 @@ - VdbeComment((v, "%s", pDestIdx->zName)); - addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); -- if( db->flags & SQLITE_Vacuum ){ -+ if( db->mDbFlags & DBFLAG_Vacuum ){ - /* This INSERT command is part of a VACUUM operation, which guarantees - ** that the destination table is empty. If all indexed columns use - ** collation sequence BINARY, then it can also be assumed that the - ** index will be populated by inserting keys in strictly sorted - ** order. In this case, instead of seeking within the b-tree as part -- ** of every OP_IdxInsert opcode, an OP_Last is added before the -+ ** of every OP_IdxInsert opcode, an OP_SeekEnd is added before the - ** OP_IdxInsert to seek to the point within the b-tree where each key - ** should be inserted. This is faster. - ** -@@ -111828,7 +117880,7 @@ - } - if( i==pSrcIdx->nColumn ){ - idxInsFlags = OPFLAG_USESEEKRESULT; -- sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1); -+ sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); - } - } - if( !HasRowid(pSrc) && pDestIdx->idxType==2 ){ -@@ -112159,7 +118211,7 @@ - int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*, - const char*,const char*),void*); - void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); -- char * (*snprintf)(int,char*,const char*,...); -+ char * (*xsnprintf)(int,char*,const char*,...); - int (*step)(sqlite3_stmt*); - int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*, - char const**,char const**,int*,int*,int*); -@@ -112271,7 +118323,7 @@ - int (*uri_boolean)(const char*,const char*,int); - sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64); - const char *(*uri_parameter)(const char*,const char*); -- char *(*vsnprintf)(int,char*,const char*,va_list); -+ char *(*xvsnprintf)(int,char*,const char*,va_list); - int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*); - /* Version 3.8.7 and later */ - int (*auto_extension)(void(*)(void)); -@@ -112317,6 +118369,33 @@ - int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*)); - void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*)); - void *(*value_pointer)(sqlite3_value*,const char*); -+ int (*vtab_nochange)(sqlite3_context*); -+ int (*value_nochange)(sqlite3_value*); -+ const char *(*vtab_collation)(sqlite3_index_info*,int); -+ /* Version 3.24.0 and later */ -+ int (*keyword_count)(void); -+ int (*keyword_name)(int,const char**,int*); -+ int (*keyword_check)(const char*,int); -+ sqlite3_str *(*str_new)(sqlite3*); -+ char *(*str_finish)(sqlite3_str*); -+ void (*str_appendf)(sqlite3_str*, const char *zFormat, ...); -+ void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list); -+ void (*str_append)(sqlite3_str*, const char *zIn, int N); -+ void (*str_appendall)(sqlite3_str*, const char *zIn); -+ void (*str_appendchar)(sqlite3_str*, int N, char C); -+ void (*str_reset)(sqlite3_str*); -+ int (*str_errcode)(sqlite3_str*); -+ int (*str_length)(sqlite3_str*); -+ char *(*str_value)(sqlite3_str*); -+ /* Version 3.25.0 and later */ -+ int (*create_window_function)(sqlite3*,const char*,int,int,void*, -+ void (*xStep)(sqlite3_context*,int,sqlite3_value**), -+ void (*xFinal)(sqlite3_context*), -+ void (*xValue)(sqlite3_context*), -+ void (*xInv)(sqlite3_context*,int,sqlite3_value**), -+ void(*xDestroy)(void*)); -+ /* Version 3.26.0 and later */ -+ const char *(*normalized_sql)(sqlite3_stmt*); - }; - - /* -@@ -112443,7 +118522,7 @@ - #define sqlite3_rollback_hook sqlite3_api->rollback_hook - #define sqlite3_set_authorizer sqlite3_api->set_authorizer - #define sqlite3_set_auxdata sqlite3_api->set_auxdata --#define sqlite3_snprintf sqlite3_api->snprintf -+#define sqlite3_snprintf sqlite3_api->xsnprintf - #define sqlite3_step sqlite3_api->step - #define sqlite3_table_column_metadata sqlite3_api->table_column_metadata - #define sqlite3_thread_cleanup sqlite3_api->thread_cleanup -@@ -112467,7 +118546,7 @@ - #define sqlite3_value_text16le sqlite3_api->value_text16le - #define sqlite3_value_type sqlite3_api->value_type - #define sqlite3_vmprintf sqlite3_api->vmprintf --#define sqlite3_vsnprintf sqlite3_api->vsnprintf -+#define sqlite3_vsnprintf sqlite3_api->xvsnprintf - #define sqlite3_overload_function sqlite3_api->overload_function - #define sqlite3_prepare_v2 sqlite3_api->prepare_v2 - #define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 -@@ -112543,7 +118622,7 @@ - #define sqlite3_uri_boolean sqlite3_api->uri_boolean - #define sqlite3_uri_int64 sqlite3_api->uri_int64 - #define sqlite3_uri_parameter sqlite3_api->uri_parameter --#define sqlite3_uri_vsnprintf sqlite3_api->vsnprintf -+#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf - #define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2 - /* Version 3.8.7 and later */ - #define sqlite3_auto_extension sqlite3_api->auto_extension -@@ -112583,6 +118662,29 @@ - #define sqlite3_bind_pointer sqlite3_api->bind_pointer - #define sqlite3_result_pointer sqlite3_api->result_pointer - #define sqlite3_value_pointer sqlite3_api->value_pointer -+/* Version 3.22.0 and later */ -+#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange -+#define sqlite3_value_nochange sqlite3_api->value_nochange -+#define sqlite3_vtab_collation sqlite3_api->vtab_collation -+/* Version 3.24.0 and later */ -+#define sqlite3_keyword_count sqlite3_api->keyword_count -+#define sqlite3_keyword_name sqlite3_api->keyword_name -+#define sqlite3_keyword_check sqlite3_api->keyword_check -+#define sqlite3_str_new sqlite3_api->str_new -+#define sqlite3_str_finish sqlite3_api->str_finish -+#define sqlite3_str_appendf sqlite3_api->str_appendf -+#define sqlite3_str_vappendf sqlite3_api->str_vappendf -+#define sqlite3_str_append sqlite3_api->str_append -+#define sqlite3_str_appendall sqlite3_api->str_appendall -+#define sqlite3_str_appendchar sqlite3_api->str_appendchar -+#define sqlite3_str_reset sqlite3_api->str_reset -+#define sqlite3_str_errcode sqlite3_api->str_errcode -+#define sqlite3_str_length sqlite3_api->str_length -+#define sqlite3_str_value sqlite3_api->str_value -+/* Version 3.25.0 and later */ -+#define sqlite3_create_window_function sqlite3_api->create_window_function -+/* Version 3.26.0 and later */ -+#define sqlite3_normalized_sql sqlite3_api->normalized_sql - #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ - - #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) -@@ -112671,6 +118773,7 @@ - # define sqlite3_declare_vtab 0 - # define sqlite3_vtab_config 0 - # define sqlite3_vtab_on_conflict 0 -+# define sqlite3_vtab_collation 0 - #endif - - #ifdef SQLITE_OMIT_SHARED_CACHE -@@ -113017,7 +119120,34 @@ - sqlite3_prepare16_v3, - sqlite3_bind_pointer, - sqlite3_result_pointer, -- sqlite3_value_pointer -+ sqlite3_value_pointer, -+ /* Version 3.22.0 and later */ -+ sqlite3_vtab_nochange, -+ sqlite3_value_nochange, -+ sqlite3_vtab_collation, -+ /* Version 3.24.0 and later */ -+ sqlite3_keyword_count, -+ sqlite3_keyword_name, -+ sqlite3_keyword_check, -+ sqlite3_str_new, -+ sqlite3_str_finish, -+ sqlite3_str_appendf, -+ sqlite3_str_vappendf, -+ sqlite3_str_append, -+ sqlite3_str_appendall, -+ sqlite3_str_appendchar, -+ sqlite3_str_reset, -+ sqlite3_str_errcode, -+ sqlite3_str_length, -+ sqlite3_str_value, -+ /* Version 3.25.0 and later */ -+ sqlite3_create_window_function, -+ /* Version 3.26.0 and later */ -+#ifdef SQLITE_ENABLE_NORMALIZE -+ sqlite3_normalized_sql -+#else -+ 0 -+#endif - }; - - /* -@@ -113467,10 +119597,9 @@ - #define PragTyp_ACTIVATE_EXTENSIONS 40 - #define PragTyp_HEXKEY 41 - #define PragTyp_KEY 42 --#define PragTyp_REKEY 43 --#define PragTyp_LOCK_STATUS 44 --#define PragTyp_PARSER_TRACE 45 --#define PragTyp_STATS 46 -+#define PragTyp_LOCK_STATUS 43 -+#define PragTyp_PARSER_TRACE 44 -+#define PragTyp_STATS 45 - - /* Property flags associated with various pragma. */ - #define PragFlg_NeedSchema 0x01 /* Force schema load before running */ -@@ -113487,21 +119616,22 @@ - ** result column is different from the name of the pragma - */ - static const char *const pragCName[] = { -- /* 0 */ "cache_size", /* Used by: default_cache_size */ -- /* 1 */ "cid", /* Used by: table_info */ -- /* 2 */ "name", -- /* 3 */ "type", -- /* 4 */ "notnull", -- /* 5 */ "dflt_value", -- /* 6 */ "pk", -- /* 7 */ "tbl", /* Used by: stats */ -- /* 8 */ "idx", -- /* 9 */ "wdth", -- /* 10 */ "hght", -- /* 11 */ "flgs", -- /* 12 */ "seqno", /* Used by: index_info */ -- /* 13 */ "cid", -- /* 14 */ "name", -+ /* 0 */ "id", /* Used by: foreign_key_list */ -+ /* 1 */ "seq", -+ /* 2 */ "table", -+ /* 3 */ "from", -+ /* 4 */ "to", -+ /* 5 */ "on_update", -+ /* 6 */ "on_delete", -+ /* 7 */ "match", -+ /* 8 */ "cid", /* Used by: table_xinfo */ -+ /* 9 */ "name", -+ /* 10 */ "type", -+ /* 11 */ "notnull", -+ /* 12 */ "dflt_value", -+ /* 13 */ "pk", -+ /* 14 */ "hidden", -+ /* table_info reuses 8 */ - /* 15 */ "seqno", /* Used by: index_xinfo */ - /* 16 */ "cid", - /* 17 */ "name", -@@ -113508,37 +119638,35 @@ - /* 18 */ "desc", - /* 19 */ "coll", - /* 20 */ "key", -- /* 21 */ "seq", /* Used by: index_list */ -- /* 22 */ "name", -- /* 23 */ "unique", -- /* 24 */ "origin", -- /* 25 */ "partial", -- /* 26 */ "seq", /* Used by: database_list */ -+ /* 21 */ "tbl", /* Used by: stats */ -+ /* 22 */ "idx", -+ /* 23 */ "wdth", -+ /* 24 */ "hght", -+ /* 25 */ "flgs", -+ /* 26 */ "seq", /* Used by: index_list */ - /* 27 */ "name", -- /* 28 */ "file", -- /* 29 */ "name", /* Used by: function_list */ -- /* 30 */ "builtin", -- /* 31 */ "name", /* Used by: module_list pragma_list */ -- /* 32 */ "seq", /* Used by: collation_list */ -- /* 33 */ "name", -- /* 34 */ "id", /* Used by: foreign_key_list */ -- /* 35 */ "seq", -- /* 36 */ "table", -- /* 37 */ "from", -- /* 38 */ "to", -- /* 39 */ "on_update", -- /* 40 */ "on_delete", -- /* 41 */ "match", -- /* 42 */ "table", /* Used by: foreign_key_check */ -- /* 43 */ "rowid", -- /* 44 */ "parent", -- /* 45 */ "fkid", -- /* 46 */ "busy", /* Used by: wal_checkpoint */ -- /* 47 */ "log", -- /* 48 */ "checkpointed", -- /* 49 */ "timeout", /* Used by: busy_timeout */ -- /* 50 */ "database", /* Used by: lock_status */ -- /* 51 */ "status", -+ /* 28 */ "unique", -+ /* 29 */ "origin", -+ /* 30 */ "partial", -+ /* 31 */ "table", /* Used by: foreign_key_check */ -+ /* 32 */ "rowid", -+ /* 33 */ "parent", -+ /* 34 */ "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 */ -+ /* module_list pragma_list reuses 9 */ -+ /* 46 */ "timeout", /* Used by: busy_timeout */ - }; - - /* Definitions of all built-in pragmas */ -@@ -113548,7 +119676,7 @@ - u8 mPragFlg; /* Zero or more PragFlg_XXX values */ - u8 iPragCName; /* Start of column names in pragCName[] */ - u8 nPragCName; /* Num of col names. 0 means use pragma name */ -- u32 iArg; /* Extra argument */ -+ u64 iArg; /* Extra argument */ - } PragmaName; - static const PragmaName aPragmaName[] = { - #if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) -@@ -113584,7 +119712,7 @@ - {/* zName: */ "busy_timeout", - /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, - /* ePragFlg: */ PragFlg_Result0, -- /* ColNames: */ 49, 1, -+ /* ColNames: */ 46, 1, - /* iArg: */ 0 }, - #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - {/* zName: */ "cache_size", -@@ -113621,7 +119749,7 @@ - {/* zName: */ "collation_list", - /* ePragTyp: */ PragTyp_COLLATION_LIST, - /* ePragFlg: */ PragFlg_Result0, -- /* ColNames: */ 32, 2, -+ /* ColNames: */ 26, 2, - /* iArg: */ 0 }, - #endif - #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) -@@ -113656,7 +119784,7 @@ - {/* zName: */ "database_list", - /* ePragTyp: */ PragTyp_DATABASE_LIST, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0, -- /* ColNames: */ 26, 3, -+ /* ColNames: */ 35, 3, - /* iArg: */ 0 }, - #endif - #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) -@@ -113663,7 +119791,7 @@ - {/* zName: */ "default_cache_size", - /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, -- /* ColNames: */ 0, 1, -+ /* ColNames: */ 45, 1, - /* iArg: */ 0 }, - #endif - #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) -@@ -113693,7 +119821,7 @@ - {/* zName: */ "foreign_key_check", - /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0, -- /* ColNames: */ 42, 4, -+ /* ColNames: */ 31, 4, - /* iArg: */ 0 }, - #endif - #if !defined(SQLITE_OMIT_FOREIGN_KEY) -@@ -113700,7 +119828,7 @@ - {/* zName: */ "foreign_key_list", - /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, -- /* ColNames: */ 34, 8, -+ /* ColNames: */ 0, 8, - /* iArg: */ 0 }, - #endif - #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) -@@ -113736,7 +119864,7 @@ - {/* zName: */ "function_list", - /* ePragTyp: */ PragTyp_FUNCTION_LIST, - /* ePragFlg: */ PragFlg_Result0, -- /* ColNames: */ 29, 2, -+ /* ColNames: */ 41, 2, - /* iArg: */ 0 }, - #endif - #endif -@@ -113745,12 +119873,12 @@ - /* ePragTyp: */ PragTyp_HEXKEY, - /* ePragFlg: */ 0, - /* ColNames: */ 0, 0, -- /* iArg: */ 0 }, -+ /* iArg: */ 2 }, - {/* zName: */ "hexrekey", - /* ePragTyp: */ PragTyp_HEXKEY, - /* ePragFlg: */ 0, - /* ColNames: */ 0, 0, -- /* iArg: */ 0 }, -+ /* iArg: */ 3 }, - #endif - #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - #if !defined(SQLITE_OMIT_CHECK) -@@ -113772,12 +119900,12 @@ - {/* zName: */ "index_info", - /* ePragTyp: */ PragTyp_INDEX_INFO, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, -- /* ColNames: */ 12, 3, -+ /* ColNames: */ 15, 3, - /* iArg: */ 0 }, - {/* zName: */ "index_list", - /* ePragTyp: */ PragTyp_INDEX_LIST, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, -- /* ColNames: */ 21, 5, -+ /* ColNames: */ 26, 5, - /* iArg: */ 0 }, - {/* zName: */ "index_xinfo", - /* ePragTyp: */ PragTyp_INDEX_INFO, -@@ -113812,6 +119940,11 @@ - /* iArg: */ 0 }, - #endif - #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) -+ {/* zName: */ "legacy_alter_table", -+ /* ePragTyp: */ PragTyp_FLAG, -+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, -+ /* ColNames: */ 0, 0, -+ /* iArg: */ SQLITE_LegacyAlter }, - {/* zName: */ "legacy_file_format", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, -@@ -113829,7 +119962,7 @@ - {/* zName: */ "lock_status", - /* ePragTyp: */ PragTyp_LOCK_STATUS, - /* ePragFlg: */ PragFlg_Result0, -- /* ColNames: */ 50, 2, -+ /* ColNames: */ 43, 2, - /* iArg: */ 0 }, - #endif - #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) -@@ -113855,7 +119988,7 @@ - {/* zName: */ "module_list", - /* ePragTyp: */ PragTyp_MODULE_LIST, - /* ePragFlg: */ PragFlg_Result0, -- /* ColNames: */ 31, 1, -+ /* ColNames: */ 9, 1, - /* iArg: */ 0 }, - #endif - #endif -@@ -113888,7 +120021,7 @@ - {/* zName: */ "pragma_list", - /* ePragTyp: */ PragTyp_PRAGMA_LIST, - /* ePragFlg: */ PragFlg_Result0, -- /* ColNames: */ 31, 1, -+ /* ColNames: */ 9, 1, - /* iArg: */ 0 }, - #endif - #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) -@@ -113919,10 +120052,10 @@ - #endif - #if defined(SQLITE_HAS_CODEC) - {/* zName: */ "rekey", -- /* ePragTyp: */ PragTyp_REKEY, -+ /* ePragTyp: */ PragTyp_KEY, - /* ePragFlg: */ 0, - /* ColNames: */ 0, 0, -- /* iArg: */ 0 }, -+ /* iArg: */ 1 }, - #endif - #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - {/* zName: */ "reverse_unordered_selects", -@@ -113975,7 +120108,7 @@ - {/* zName: */ "stats", - /* ePragTyp: */ PragTyp_STATS, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, -- /* ColNames: */ 7, 5, -+ /* ColNames: */ 21, 5, - /* iArg: */ 0 }, - #endif - #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) -@@ -113989,8 +120122,13 @@ - {/* zName: */ "table_info", - /* ePragTyp: */ PragTyp_TABLE_INFO, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, -- /* ColNames: */ 1, 6, -+ /* ColNames: */ 8, 6, - /* iArg: */ 0 }, -+ {/* zName: */ "table_xinfo", -+ /* ePragTyp: */ PragTyp_TABLE_INFO, -+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, -+ /* ColNames: */ 8, 7, -+ /* iArg: */ 1 }, - #endif - #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - {/* zName: */ "temp_store", -@@ -114004,6 +120142,18 @@ - /* ColNames: */ 0, 0, - /* iArg: */ 0 }, - #endif -+#if defined(SQLITE_HAS_CODEC) -+ {/* zName: */ "textkey", -+ /* ePragTyp: */ PragTyp_KEY, -+ /* ePragFlg: */ 0, -+ /* ColNames: */ 0, 0, -+ /* iArg: */ 4 }, -+ {/* zName: */ "textrekey", -+ /* ePragTyp: */ PragTyp_KEY, -+ /* ePragFlg: */ 0, -+ /* ColNames: */ 0, 0, -+ /* iArg: */ 5 }, -+#endif - {/* zName: */ "threads", - /* ePragTyp: */ PragTyp_THREADS, - /* ePragFlg: */ PragFlg_Result0, -@@ -114054,7 +120204,7 @@ - {/* zName: */ "wal_checkpoint", - /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, - /* ePragFlg: */ PragFlg_NeedSchema, -- /* ColNames: */ 46, 3, -+ /* ColNames: */ 38, 3, - /* iArg: */ 0 }, - #endif - #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) -@@ -114062,10 +120212,10 @@ - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, - /* ColNames: */ 0, 0, -- /* iArg: */ SQLITE_WriteSchema }, -+ /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError }, - #endif - }; --/* Number of pragmas: 60 on by default, 77 total. */ -+/* Number of pragmas: 62 on by default, 81 total. */ - - /************** End of pragma.h **********************************************/ - /************** Continuing where we left off in pragma.c *********************/ -@@ -114338,16 +120488,16 @@ - /* - ** Helper subroutine for PRAGMA integrity_check: - ** --** Generate code to output a single-column result row with the result --** held in register regResult. Decrement the result count and halt if --** the maximum number of result rows have been issued. -+** Generate code to output a single-column result row with a value of the -+** string held in register 3. Decrement the result count in register 1 -+** and halt if the maximum number of result rows have been issued. - */ --static int integrityCheckResultRow(Vdbe *v, int regResult){ -+static int integrityCheckResultRow(Vdbe *v){ - int addr; -- sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 1); -+ sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); - addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1); - VdbeCoverage(v); -- sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); -+ sqlite3VdbeAddOp0(v, OP_Halt); - return addr; - } - -@@ -115077,7 +121227,7 @@ - setPragmaResultColumnNames(v, pPragma); - returnSingleInt(v, (db->flags & pPragma->iArg)!=0 ); - }else{ -- int mask = pPragma->iArg; /* Mask of bits to set or clear. */ -+ u64 mask = pPragma->iArg; /* Mask of bits to set or clear. */ - if( db->autoCommit==0 ){ - /* Foreign key support may not be enabled or disabled while not - ** in auto-commit mode. */ -@@ -115120,20 +121270,23 @@ - ** type: Column declaration type. - ** notnull: True if 'NOT NULL' is part of column declaration - ** dflt_value: The default value for the column, if any. -+ ** pk: Non-zero for PK fields. - */ - case PragTyp_TABLE_INFO: if( zRight ){ - Table *pTab; - pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb); - if( pTab ){ -+ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); - int i, k; - int nHidden = 0; - Column *pCol; - Index *pPk = sqlite3PrimaryKeyIndex(pTab); -- pParse->nMem = 6; -- sqlite3CodeVerifySchema(pParse, iDb); -+ pParse->nMem = 7; -+ sqlite3CodeVerifySchema(pParse, iTabDb); - sqlite3ViewGetColumnNames(pParse, pTab); - for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ -- if( IsHiddenColumn(pCol) ){ -+ int isHidden = IsHiddenColumn(pCol); -+ if( isHidden && pPragma->iArg==0 ){ - nHidden++; - continue; - } -@@ -115145,13 +121298,14 @@ - for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){} - } - assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN ); -- sqlite3VdbeMultiLoad(v, 1, "issisi", -+ sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi", - i-nHidden, - pCol->zName, - sqlite3ColumnType(pCol,""), - pCol->notNull ? 1 : 0, - pCol->pDflt ? pCol->pDflt->u.zToken : 0, -- k); -+ k, -+ isHidden); - } - } - } -@@ -115189,6 +121343,7 @@ - Table *pTab; - pIdx = sqlite3FindIndex(db, zRight, zDb); - if( pIdx ){ -+ int iIdxDb = sqlite3SchemaToIndex(db, pIdx->pSchema); - int i; - int mx; - if( pPragma->iArg ){ -@@ -115201,7 +121356,7 @@ - pParse->nMem = 3; - } - pTab = pIdx->pTable; -- sqlite3CodeVerifySchema(pParse, iDb); -+ sqlite3CodeVerifySchema(pParse, iIdxDb); - assert( pParse->nMem<=pPragma->nPragCName ); - for(i=0; i<mx; i++){ - i16 cnum = pIdx->aiColumn[i]; -@@ -115225,8 +121380,9 @@ - int i; - pTab = sqlite3FindTable(db, zRight, zDb); - if( pTab ){ -+ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); - pParse->nMem = 5; -- sqlite3CodeVerifySchema(pParse, iDb); -+ sqlite3CodeVerifySchema(pParse, iTabDb); - for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){ - const char *azOrigin[] = { "c", "u", "pk" }; - sqlite3VdbeMultiLoad(v, 1, "isisi", -@@ -115273,14 +121429,13 @@ - pParse->nMem = 2; - for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){ - for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){ -+ if( p->funcFlags & SQLITE_FUNC_INTERNAL ) continue; - sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1); -- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); - } - } - for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){ - p = (FuncDef*)sqliteHashData(j); - sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 0); -- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); - } - } - break; -@@ -115292,7 +121447,6 @@ - for(j=sqliteHashFirst(&db->aModule); j; j=sqliteHashNext(j)){ - Module *pMod = (Module*)sqliteHashData(j); - sqlite3VdbeMultiLoad(v, 1, "s", pMod->zName); -- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); - } - } - break; -@@ -115302,7 +121456,6 @@ - int i; - for(i=0; i<ArraySize(aPragmaName); i++){ - sqlite3VdbeMultiLoad(v, 1, "s", aPragmaName[i].zName); -- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); - } - } - break; -@@ -115318,9 +121471,10 @@ - if( pTab ){ - pFK = pTab->pFKey; - if( pFK ){ -+ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); - int i = 0; - pParse->nMem = 8; -- sqlite3CodeVerifySchema(pParse, iDb); -+ sqlite3CodeVerifySchema(pParse, iTabDb); - while(pFK){ - int j; - for(j=0; j<pFK->nCol; j++){ -@@ -115365,9 +121519,9 @@ - pParse->nMem += 4; - regKey = ++pParse->nMem; - regRow = ++pParse->nMem; -- sqlite3CodeVerifySchema(pParse, iDb); - k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash); - while( k ){ -+ int iTabDb; - if( zRight ){ - pTab = sqlite3LocateTable(pParse, 0, zRight, zDb); - k = 0; -@@ -115376,21 +121530,23 @@ - k = sqliteHashNext(k); - } - if( pTab==0 || pTab->pFKey==0 ) continue; -- sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); -+ iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); -+ sqlite3CodeVerifySchema(pParse, iTabDb); -+ sqlite3TableLock(pParse, iTabDb, pTab->tnum, 0, pTab->zName); - if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow; -- sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead); -+ sqlite3OpenTable(pParse, 0, iTabDb, pTab, OP_OpenRead); - sqlite3VdbeLoadString(v, regResult, pTab->zName); - for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ - pParent = sqlite3FindTable(db, pFK->zTo, zDb); - if( pParent==0 ) continue; - pIdx = 0; -- sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName); -+ sqlite3TableLock(pParse, iTabDb, pParent->tnum, 0, pParent->zName); - x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0); - if( x==0 ){ - if( pIdx==0 ){ -- sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead); -+ sqlite3OpenTable(pParse, i, iTabDb, pParent, OP_OpenRead); - }else{ -- sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb); -+ sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iTabDb); - sqlite3VdbeSetP4KeyInfo(pParse, pIdx); - } - }else{ -@@ -115528,12 +121684,11 @@ - - /* Do an integrity check on each database file */ - for(i=0; i<db->nDb; i++){ -- HashElem *x; -- Hash *pTbls; -- int *aRoot; -- int cnt = 0; -- int mxIdx = 0; -- int nIdx; -+ HashElem *x; /* For looping over tables in the schema */ -+ Hash *pTbls; /* Set of all tables in the schema */ -+ int *aRoot; /* Array of root page numbers of all btrees */ -+ int cnt = 0; /* Number of entries in aRoot[] */ -+ int mxIdx = 0; /* Maximum number of indexes for any table */ - - if( OMIT_TEMPDB && i==1 ) continue; - if( iDb>=0 && i!=iDb ) continue; -@@ -115548,8 +121703,9 @@ - assert( sqlite3SchemaMutexHeld(db, i, 0) ); - pTbls = &db->aDb[i].pSchema->tblHash; - for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ -- Table *pTab = sqliteHashData(x); -- Index *pIdx; -+ Table *pTab = sqliteHashData(x); /* Current table */ -+ Index *pIdx; /* An index on pTab */ -+ int nIdx; /* Number of indexes on pTab */ - if( HasRowid(pTab) ) cnt++; - for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; } - if( nIdx>mxIdx ) mxIdx = nIdx; -@@ -115559,12 +121715,12 @@ - for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ - Table *pTab = sqliteHashData(x); - Index *pIdx; -- if( HasRowid(pTab) ) aRoot[cnt++] = pTab->tnum; -+ if( HasRowid(pTab) ) aRoot[++cnt] = pTab->tnum; - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ -- aRoot[cnt++] = pIdx->tnum; -+ aRoot[++cnt] = pIdx->tnum; - } - } -- aRoot[cnt] = 0; -+ aRoot[0] = cnt; - - /* Make sure sufficient number of registers have been allocated */ - pParse->nMem = MAX( pParse->nMem, 8+mxIdx ); -@@ -115577,9 +121733,8 @@ - sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, - sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName), - P4_DYNAMIC); -- sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1); -- sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2); -- integrityCheckResultRow(v, 2); -+ sqlite3VdbeAddOp3(v, OP_Concat, 2, 3, 3); -+ integrityCheckResultRow(v); - sqlite3VdbeJumpHere(v, addr); - - /* Make sure all the indices are constructed correctly. -@@ -115593,16 +121748,12 @@ - int r1 = -1; - - if( pTab->tnum<1 ) continue; /* Skip VIEWs or VIRTUAL TABLEs */ -- if( pTab->pCheck==0 -- && (pTab->tabFlags & TF_HasNotNull)==0 -- && (pTab->pIndex==0 || isQuick) -- ){ -- continue; /* No additional checks needed for this table */ -- } - pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); -- sqlite3ExprCacheClear(pParse); - sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, - 1, 0, &iDataCur, &iIdxCur); -+ /* reg[7] counts the number of entries in the table. -+ ** reg[8+i] counts the number of entries in the i-th index -+ */ - sqlite3VdbeAddOp2(v, OP_Integer, 0, 7); - for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ -@@ -115611,6 +121762,11 @@ - assert( sqlite3NoTempsInRange(pParse,1,7+j) ); - sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); - loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); -+ if( !isQuick ){ -+ /* Sanity check on record header decoding */ -+ sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-1, 3); -+ sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); -+ } - /* Verify that all NOT NULL columns really are NOT NULL */ - for(j=0; j<pTab->nCol; j++){ - char *zErr; -@@ -115623,7 +121779,7 @@ - zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, - pTab->aCol[j].zName); - sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); -- integrityCheckResultRow(v, 3); -+ integrityCheckResultRow(v); - sqlite3VdbeJumpHere(v, jmp2); - } - /* Verify CHECK constraints */ -@@ -115635,7 +121791,6 @@ - char *zErr; - int k; - pParse->iSelfTab = iDataCur + 1; -- sqlite3ExprCachePush(pParse); - for(k=pCheck->nExpr-1; k>0; k--){ - sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0); - } -@@ -115646,57 +121801,58 @@ - zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s", - pTab->zName); - sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); -- integrityCheckResultRow(v, 3); -+ integrityCheckResultRow(v); - sqlite3VdbeResolveLabel(v, addrCkOk); -- sqlite3ExprCachePop(pParse); - } - sqlite3ExprListDelete(db, pCheck); - } -- /* Validate index entries for the current row */ -- for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; pIdx=pIdx->pNext, j++){ -- int jmp2, jmp3, jmp4, jmp5; -- int ckUniq = sqlite3VdbeMakeLabel(v); -- if( pPk==pIdx ) continue; -- r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, -- pPrior, r1); -- pPrior = pIdx; -- sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */ -- /* Verify that an index entry exists for the current table row */ -- jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, -- pIdx->nColumn); VdbeCoverage(v); -- sqlite3VdbeLoadString(v, 3, "row "); -- sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); -- sqlite3VdbeLoadString(v, 4, " missing from index "); -- sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); -- jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName); -- sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); -- jmp4 = integrityCheckResultRow(v, 3); -- sqlite3VdbeJumpHere(v, jmp2); -- /* For UNIQUE indexes, verify that only one entry exists with the -- ** current key. The entry is unique if (1) any column is NULL -- ** or (2) the next entry has a different key */ -- if( IsUniqueIndex(pIdx) ){ -- int uniqOk = sqlite3VdbeMakeLabel(v); -- int jmp6; -- int kk; -- for(kk=0; kk<pIdx->nKeyCol; kk++){ -- int iCol = pIdx->aiColumn[kk]; -- assert( iCol!=XN_ROWID && iCol<pTab->nCol ); -- if( iCol>=0 && pTab->aCol[iCol].notNull ) continue; -- sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk); -- VdbeCoverage(v); -+ if( !isQuick ){ /* Omit the remaining tests for quick_check */ -+ /* Validate index entries for the current row */ -+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ -+ int jmp2, jmp3, jmp4, jmp5; -+ int ckUniq = sqlite3VdbeMakeLabel(v); -+ if( pPk==pIdx ) continue; -+ r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, -+ pPrior, r1); -+ pPrior = pIdx; -+ sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1);/* increment entry count */ -+ /* Verify that an index entry exists for the current table row */ -+ jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, -+ pIdx->nColumn); VdbeCoverage(v); -+ sqlite3VdbeLoadString(v, 3, "row "); -+ sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); -+ sqlite3VdbeLoadString(v, 4, " missing from index "); -+ sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); -+ jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName); -+ sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); -+ jmp4 = integrityCheckResultRow(v); -+ sqlite3VdbeJumpHere(v, jmp2); -+ /* For UNIQUE indexes, verify that only one entry exists with the -+ ** current key. The entry is unique if (1) any column is NULL -+ ** or (2) the next entry has a different key */ -+ if( IsUniqueIndex(pIdx) ){ -+ int uniqOk = sqlite3VdbeMakeLabel(v); -+ int jmp6; -+ int kk; -+ for(kk=0; kk<pIdx->nKeyCol; kk++){ -+ int iCol = pIdx->aiColumn[kk]; -+ assert( iCol!=XN_ROWID && iCol<pTab->nCol ); -+ if( iCol>=0 && pTab->aCol[iCol].notNull ) continue; -+ sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk); -+ VdbeCoverage(v); -+ } -+ jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v); -+ sqlite3VdbeGoto(v, uniqOk); -+ sqlite3VdbeJumpHere(v, jmp6); -+ sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1, -+ pIdx->nKeyCol); VdbeCoverage(v); -+ sqlite3VdbeLoadString(v, 3, "non-unique entry in index "); -+ sqlite3VdbeGoto(v, jmp5); -+ sqlite3VdbeResolveLabel(v, uniqOk); - } -- jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v); -- sqlite3VdbeGoto(v, uniqOk); -- sqlite3VdbeJumpHere(v, jmp6); -- sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1, -- pIdx->nKeyCol); VdbeCoverage(v); -- sqlite3VdbeLoadString(v, 3, "non-unique entry in index "); -- sqlite3VdbeGoto(v, jmp5); -- sqlite3VdbeResolveLabel(v, uniqOk); -+ sqlite3VdbeJumpHere(v, jmp4); -+ sqlite3ResolvePartIdxLabel(pParse, jmp3); - } -- sqlite3VdbeJumpHere(v, jmp4); -- sqlite3ResolvePartIdxLabel(pParse, jmp3); - } - sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); - sqlite3VdbeJumpHere(v, loopTop-1); -@@ -115708,9 +121864,9 @@ - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); - addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v); - sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); -- sqlite3VdbeLoadString(v, 3, pIdx->zName); -- sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7); -- integrityCheckResultRow(v, 7); -+ sqlite3VdbeLoadString(v, 4, pIdx->zName); -+ sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3); -+ integrityCheckResultRow(v); - sqlite3VdbeJumpHere(v, addr); - } - } -@@ -115724,6 +121880,9 @@ - { OP_IfNotZero, 1, 4, 0}, /* 1 */ - { OP_String8, 0, 3, 0}, /* 2 */ - { OP_ResultRow, 3, 1, 0}, /* 3 */ -+ { OP_Halt, 0, 0, 0}, /* 4 */ -+ { OP_String8, 0, 3, 0}, /* 5 */ -+ { OP_Goto, 0, 3, 0}, /* 6 */ - }; - VdbeOp *aOp; - -@@ -115732,7 +121891,10 @@ - aOp[0].p2 = 1-mxErr; - aOp[2].p4type = P4_STATIC; - aOp[2].p4.z = "ok"; -+ aOp[5].p4type = P4_STATIC; -+ aOp[5].p4.z = (char*)sqlite3ErrStr(SQLITE_CORRUPT); - } -+ sqlite3VdbeChangeP3(v, 0, sqlite3VdbeCurrentAddr(v)-2); - } - } - break; -@@ -116153,14 +122315,26 @@ - #endif - - #ifdef SQLITE_HAS_CODEC -+ /* Pragma iArg -+ ** ---------- ------ -+ ** key 0 -+ ** rekey 1 -+ ** hexkey 2 -+ ** hexrekey 3 -+ ** textkey 4 -+ ** textrekey 5 -+ */ - case PragTyp_KEY: { -- if( zRight ) sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); -+ if( zRight ){ -+ int n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1; -+ if( (pPragma->iArg & 1)==0 ){ -+ sqlite3_key_v2(db, zDb, zRight, n); -+ }else{ -+ sqlite3_rekey_v2(db, zDb, zRight, n); -+ } -+ } - break; - } -- case PragTyp_REKEY: { -- if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); -- break; -- } - case PragTyp_HEXKEY: { - if( zRight ){ - u8 iByte; -@@ -116170,7 +122344,7 @@ - iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]); - if( (i&1)!=0 ) zKey[i/2] = iByte; - } -- if( (zLeft[3] & 0xf)==0xb ){ -+ if( (pPragma->iArg & 1)==0 ){ - sqlite3_key_v2(db, zDb, zKey, i/2); - }else{ - sqlite3_rekey_v2(db, zDb, zKey, i/2); -@@ -116252,26 +122426,25 @@ - UNUSED_PARAMETER(argc); - UNUSED_PARAMETER(argv); - sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); -- sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x"); -+ sqlite3_str_appendall(&acc, "CREATE TABLE x"); - for(i=0, j=pPragma->iPragCName; i<pPragma->nPragCName; i++, j++){ -- sqlite3XPrintf(&acc, "%c\"%s\"", cSep, pragCName[j]); -+ sqlite3_str_appendf(&acc, "%c\"%s\"", cSep, pragCName[j]); - cSep = ','; - } - if( i==0 ){ -- sqlite3XPrintf(&acc, "(\"%s\"", pPragma->zName); -- cSep = ','; -+ sqlite3_str_appendf(&acc, "(\"%s\"", pPragma->zName); - i++; - } - j = 0; - if( pPragma->mPragFlg & PragFlg_Result1 ){ -- sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN"); -+ sqlite3_str_appendall(&acc, ",arg HIDDEN"); - j++; - } - if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){ -- sqlite3StrAccumAppendAll(&acc, ",schema HIDDEN"); -+ sqlite3_str_appendall(&acc, ",schema HIDDEN"); - j++; - } -- sqlite3StrAccumAppend(&acc, ")", 1); -+ sqlite3_str_append(&acc, ")", 1); - sqlite3StrAccumFinish(&acc); - assert( strlen(zBuf) < sizeof(zBuf)-1 ); - rc = sqlite3_declare_vtab(db, zBuf); -@@ -116423,13 +122596,13 @@ - } - } - sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]); -- sqlite3StrAccumAppendAll(&acc, "PRAGMA "); -+ sqlite3_str_appendall(&acc, "PRAGMA "); - if( pCsr->azArg[1] ){ -- sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]); -+ sqlite3_str_appendf(&acc, "%Q.", pCsr->azArg[1]); - } -- sqlite3StrAccumAppendAll(&acc, pTab->pName->zName); -+ sqlite3_str_appendall(&acc, pTab->pName->zName); - if( pCsr->azArg[0] ){ -- sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]); -+ sqlite3_str_appendf(&acc, "=%Q", pCsr->azArg[0]); - } - zSql = sqlite3StrAccumFinish(&acc); - if( zSql==0 ) return SQLITE_NOMEM; -@@ -116501,7 +122674,8 @@ - 0, /* xRename - rename the table */ - 0, /* xSavepoint */ - 0, /* xRelease */ -- 0 /* xRollbackTo */ -+ 0, /* xRollbackTo */ -+ 0 /* xShadowName */ - }; - - /* -@@ -116552,15 +122726,23 @@ - const char *zExtra /* Error information */ - ){ - sqlite3 *db = pData->db; -- if( !db->mallocFailed && (db->flags & SQLITE_WriteSchema)==0 ){ -+ if( db->mallocFailed ){ -+ pData->rc = SQLITE_NOMEM_BKPT; -+ }else if( pData->pzErrMsg[0]!=0 ){ -+ /* A error message has already been generated. Do not overwrite it */ -+ }else if( pData->mInitFlags & INITFLAG_AlterTable ){ -+ *pData->pzErrMsg = sqlite3DbStrDup(db, zExtra); -+ pData->rc = SQLITE_ERROR; -+ }else if( db->flags & SQLITE_WriteSchema ){ -+ pData->rc = SQLITE_CORRUPT_BKPT; -+ }else{ - char *z; - if( zObj==0 ) zObj = "?"; - z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj); -- if( zExtra ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); -- sqlite3DbFree(db, *pData->pzErrMsg); -+ if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); - *pData->pzErrMsg = z; -+ pData->rc = SQLITE_CORRUPT_BKPT; - } -- pData->rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_CORRUPT_BKPT; - } - - /* -@@ -116612,7 +122794,7 @@ - rc = db->errCode; - assert( (rc&0xFF)==(rcp&0xFF) ); - db->init.iDb = saved_iDb; -- assert( saved_iDb==0 || (db->flags & SQLITE_Vacuum)!=0 ); -+ /* assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 ); */ - if( SQLITE_OK!=rc ){ - if( db->init.orphanTrigger ){ - assert( iDb==1 ); -@@ -116659,7 +122841,7 @@ - ** auxiliary databases. Return one of the SQLITE_ error codes to - ** indicate success or failure. - */ --static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ -+SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){ - int rc; - int i; - #ifndef SQLITE_OMIT_DEPRECATED -@@ -116672,11 +122854,14 @@ - const char *zMasterName; - int openedTransaction = 0; - -+ assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ); - assert( iDb>=0 && iDb<db->nDb ); - assert( db->aDb[iDb].pSchema ); - assert( sqlite3_mutex_held(db->mutex) ); - assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); - -+ db->init.busy = 1; -+ - /* Construct the in-memory representation schema tables (sqlite_master or - ** sqlite_temp_master) by invoking the parser directly. The appropriate - ** table name will be inserted automatically by the parser so we can just -@@ -116685,12 +122870,13 @@ - azArg[0] = zMasterName = SCHEMA_TABLE(iDb); - azArg[1] = "1"; - azArg[2] = "CREATE TABLE x(type text,name text,tbl_name text," -- "rootpage integer,sql text)"; -+ "rootpage int,sql text)"; - azArg[3] = 0; - initData.db = db; - initData.iDb = iDb; - initData.rc = SQLITE_OK; - initData.pzErrMsg = pzErrMsg; -+ initData.mInitFlags = mFlags; - sqlite3InitCallback(&initData, 3, (char **)azArg, 0); - if( initData.rc ){ - rc = initData.rc; -@@ -116701,10 +122887,10 @@ - */ - pDb = &db->aDb[iDb]; - if( pDb->pBt==0 ){ -- if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){ -- DbSetProperty(db, 1, DB_SchemaLoaded); -- } -- return SQLITE_OK; -+ assert( iDb==1 ); -+ DbSetProperty(db, 1, DB_SchemaLoaded); -+ rc = SQLITE_OK; -+ goto error_out; - } - - /* If there is not already a read-only (or read-write) transaction opened -@@ -116712,7 +122898,7 @@ - ** will be closed before this function returns. */ - sqlite3BtreeEnter(pDb->pBt); - if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){ -- rc = sqlite3BtreeBeginTrans(pDb->pBt, 0); -+ rc = sqlite3BtreeBeginTrans(pDb->pBt, 0, 0); - if( rc!=SQLITE_OK ){ - sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc)); - goto initone_error_out; -@@ -116740,6 +122926,9 @@ - for(i=0; i<ArraySize(meta); i++){ - sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]); - } -+ if( (db->flags & SQLITE_ResetDatabase)!=0 ){ -+ memset(meta, 0, sizeof(meta)); -+ } - pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1]; - - /* If opening a non-empty database, check the text encoding. For the -@@ -116839,8 +123028,8 @@ - rc = SQLITE_NOMEM_BKPT; - sqlite3ResetAllSchemasOfConnection(db); - } -- if( rc==SQLITE_OK || (db->flags&SQLITE_WriteSchema)){ -- /* Black magic: If the SQLITE_WriteSchema flag is set, then consider -+ if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){ -+ /* Black magic: If the SQLITE_NoSchemaError flag is set, then consider - ** the schema loaded, even if errors occurred. In this situation the - ** current sqlite3_prepare() operation will fail, but the following one - ** will attempt to compile the supplied statement against whatever subset -@@ -116863,9 +123052,13 @@ - sqlite3BtreeLeave(pDb->pBt); - - error_out: -- if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ -- sqlite3OomFault(db); -+ if( rc ){ -+ if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ -+ sqlite3OomFault(db); -+ } -+ sqlite3ResetOneSchema(db, iDb); - } -+ db->init.busy = 0; - return rc; - } - -@@ -116881,42 +123074,30 @@ - */ - SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){ - int i, rc; -- int commit_internal = !(db->flags&SQLITE_InternChanges); -+ int commit_internal = !(db->mDbFlags&DBFLAG_SchemaChange); - - assert( sqlite3_mutex_held(db->mutex) ); - assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) ); - assert( db->init.busy==0 ); -- rc = SQLITE_OK; -- db->init.busy = 1; - ENC(db) = SCHEMA_ENC(db); -- for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ -- if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue; -- rc = sqlite3InitOne(db, i, pzErrMsg); -- if( rc ){ -- sqlite3ResetOneSchema(db, i); -- } -+ assert( db->nDb>0 ); -+ /* Do the main schema first */ -+ if( !DbHasProperty(db, 0, DB_SchemaLoaded) ){ -+ rc = sqlite3InitOne(db, 0, pzErrMsg, 0); -+ if( rc ) return rc; - } -- -- /* Once all the other databases have been initialized, load the schema -- ** for the TEMP database. This is loaded last, as the TEMP database -- ** schema may contain references to objects in other databases. -- */ --#ifndef SQLITE_OMIT_TEMPDB -- assert( db->nDb>1 ); -- if( rc==SQLITE_OK && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ -- rc = sqlite3InitOne(db, 1, pzErrMsg); -- if( rc ){ -- sqlite3ResetOneSchema(db, 1); -+ /* All other schemas after the main schema. The "temp" schema must be last */ -+ for(i=db->nDb-1; i>0; i--){ -+ assert( i==1 || sqlite3BtreeHoldsMutex(db->aDb[i].pBt) ); -+ if( !DbHasProperty(db, i, DB_SchemaLoaded) ){ -+ rc = sqlite3InitOne(db, i, pzErrMsg, 0); -+ if( rc ) return rc; - } - } --#endif -- -- db->init.busy = 0; -- if( rc==SQLITE_OK && commit_internal ){ -+ if( commit_internal ){ - sqlite3CommitInternalChanges(db); - } -- -- return rc; -+ return SQLITE_OK; - } - - /* -@@ -116929,11 +123110,13 @@ - assert( sqlite3_mutex_held(db->mutex) ); - if( !db->init.busy ){ - rc = sqlite3Init(db, &pParse->zErrMsg); -+ if( rc!=SQLITE_OK ){ -+ pParse->rc = rc; -+ pParse->nErr++; -+ }else if( db->noSharedCache ){ -+ db->mDbFlags |= DBFLAG_SchemaKnownOk; -+ } - } -- if( rc!=SQLITE_OK ){ -- pParse->rc = rc; -- pParse->nErr++; -- } - return rc; - } - -@@ -116960,7 +123143,7 @@ - ** on the b-tree database, open one now. If a transaction is opened, it - ** will be closed immediately after reading the meta-value. */ - if( !sqlite3BtreeIsInReadTrans(pBt) ){ -- rc = sqlite3BtreeBeginTrans(pBt, 0); -+ rc = sqlite3BtreeBeginTrans(pBt, 0, 0); - if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - sqlite3OomFault(db); - } -@@ -117007,7 +123190,8 @@ - */ - assert( sqlite3_mutex_held(db->mutex) ); - if( pSchema ){ -- for(i=0; ALWAYS(i<db->nDb); i++){ -+ for(i=0; 1; i++){ -+ assert( i<db->nDb ); - if( db->aDb[i].pSchema==pSchema ){ - break; - } -@@ -117021,16 +123205,14 @@ - ** Free all memory allocations in the pParse object - */ - SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ -- if( pParse ){ -- sqlite3 *db = pParse->db; -- sqlite3DbFree(db, pParse->aLabel); -- sqlite3ExprListDelete(db, pParse->pConstExpr); -- if( db ){ -- assert( db->lookaside.bDisable >= pParse->disableLookaside ); -- db->lookaside.bDisable -= pParse->disableLookaside; -- } -- pParse->disableLookaside = 0; -+ sqlite3 *db = pParse->db; -+ sqlite3DbFree(db, pParse->aLabel); -+ sqlite3ExprListDelete(db, pParse->pConstExpr); -+ if( db ){ -+ assert( db->lookaside.bDisable >= pParse->disableLookaside ); -+ db->lookaside.bDisable -= pParse->disableLookaside; - } -+ pParse->disableLookaside = 0; - } - - /* -@@ -117144,7 +123326,7 @@ - if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){ - static const char * const azColName[] = { - "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", -- "selectid", "order", "from", "detail" -+ "id", "parent", "notused", "detail" - }; - int iFirst, mx; - if( sParse.explain==2 ){ -@@ -117190,8 +123372,6 @@ - end_prepare: - - sqlite3ParserReset(&sParse); -- rc = sqlite3ApiExit(db, rc); -- assert( (rc&db->errMask)==rc ); - return rc; - } - static int sqlite3LockAndPrepare( -@@ -117204,6 +123384,7 @@ - const char **pzTail /* OUT: End of parsed string */ - ){ - int rc; -+ int cnt = 0; - - #ifdef SQLITE_ENABLE_API_ARMOR - if( ppStmt==0 ) return SQLITE_MISUSE_BKPT; -@@ -117214,18 +123395,310 @@ - } - sqlite3_mutex_enter(db->mutex); - sqlite3BtreeEnterAll(db); -- rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); -- if( rc==SQLITE_SCHEMA ){ -- sqlite3_finalize(*ppStmt); -+ do{ -+ /* Make multiple attempts to compile the SQL, until it either succeeds -+ ** or encounters a permanent error. A schema problem after one schema -+ ** reset is considered a permanent error. */ - rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); -- } -+ assert( rc==SQLITE_OK || *ppStmt==0 ); -+ }while( rc==SQLITE_ERROR_RETRY -+ || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) ); - sqlite3BtreeLeaveAll(db); -+ rc = sqlite3ApiExit(db, rc); -+ assert( (rc&db->errMask)==rc ); - sqlite3_mutex_leave(db->mutex); -- assert( rc==SQLITE_OK || *ppStmt==0 ); - return rc; - } - -+#ifdef SQLITE_ENABLE_NORMALIZE - /* -+** Checks if the specified token is a table, column, or function name, -+** based on the databases associated with the statement being prepared. -+** If the function fails, zero is returned and pRc is filled with the -+** error code. -+*/ -+static int shouldTreatAsIdentifier( -+ sqlite3 *db, /* Database handle. */ -+ const char *zToken, /* Pointer to start of token to be checked */ -+ int nToken, /* Length of token to be checked */ -+ int *pRc /* Pointer to error code upon failure */ -+){ -+ int bFound = 0; /* Non-zero if token is an identifier name. */ -+ int i, j; /* Database and column loop indexes. */ -+ Schema *pSchema; /* Schema for current database. */ -+ Hash *pHash; /* Hash table of tables for current database. */ -+ HashElem *e; /* Hash element for hash table iteration. */ -+ Table *pTab; /* Database table for columns being checked. */ -+ -+ if( sqlite3IsRowidN(zToken, nToken) ){ -+ return 1; -+ } -+ if( nToken>0 ){ -+ int hash = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zToken[0]], nToken); -+ if( sqlite3FunctionSearchN(hash, zToken, nToken) ) return 1; -+ } -+ assert( db!=0 ); -+ sqlite3_mutex_enter(db->mutex); -+ sqlite3BtreeEnterAll(db); -+ for(i=0; i<db->nDb; i++){ -+ pHash = &db->aFunc; -+ if( sqlite3HashFindN(pHash, zToken, nToken) ){ -+ bFound = 1; -+ break; -+ } -+ pSchema = db->aDb[i].pSchema; -+ if( pSchema==0 ) continue; -+ pHash = &pSchema->tblHash; -+ if( sqlite3HashFindN(pHash, zToken, nToken) ){ -+ bFound = 1; -+ break; -+ } -+ for(e=sqliteHashFirst(pHash); e; e=sqliteHashNext(e)){ -+ pTab = sqliteHashData(e); -+ if( pTab==0 ) continue; -+ pHash = pTab->pColHash; -+ if( pHash==0 ){ -+ pTab->pColHash = pHash = sqlite3_malloc(sizeof(Hash)); -+ if( pHash ){ -+ sqlite3HashInit(pHash); -+ for(j=0; j<pTab->nCol; j++){ -+ Column *pCol = &pTab->aCol[j]; -+ sqlite3HashInsert(pHash, pCol->zName, pCol); -+ } -+ }else{ -+ *pRc = SQLITE_NOMEM_BKPT; -+ bFound = 0; -+ goto done; -+ } -+ } -+ if( pHash && sqlite3HashFindN(pHash, zToken, nToken) ){ -+ bFound = 1; -+ goto done; -+ } -+ } -+ } -+done: -+ sqlite3BtreeLeaveAll(db); -+ sqlite3_mutex_leave(db->mutex); -+ return bFound; -+} -+ -+/* -+** Attempt to estimate the final output buffer size needed for the fully -+** normalized version of the specified SQL string. This should take into -+** account any potential expansion that could occur (e.g. via IN clauses -+** being expanded, etc). This size returned is the total number of bytes -+** including the NUL terminator. -+*/ -+static int estimateNormalizedSize( -+ const char *zSql, /* The original SQL string */ -+ int nSql, /* Length of original SQL string */ -+ u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */ -+){ -+ int nOut = nSql + 4; -+ const char *z = zSql; -+ while( nOut<nSql*5 ){ -+ while( z[0]!=0 && z[0]!='I' && z[0]!='i' ){ z++; } -+ if( z[0]==0 ) break; -+ z++; -+ if( z[0]!='N' && z[0]!='n' ) break; -+ z++; -+ while( sqlite3Isspace(z[0]) ){ z++; } -+ if( z[0]!='(' ) break; -+ z++; -+ nOut += 5; /* ?,?,? */ -+ } -+ return nOut; -+} -+ -+/* -+** Copy the current token into the output buffer while dealing with quoted -+** identifiers. By default, all letters will be converted into lowercase. -+** If the bUpper flag is set, uppercase will be used. The piOut argument -+** will be used to update the target index into the output string. -+*/ -+static void copyNormalizedToken( -+ const char *zSql, /* The original SQL string */ -+ int iIn, /* Current index into the original SQL string */ -+ int nToken, /* Number of bytes in the current token */ -+ int tokenFlags, /* Flags returned by the tokenizer */ -+ char *zOut, /* The output string */ -+ int *piOut /* Pointer to target index into the output string */ -+){ -+ int bQuoted = tokenFlags & SQLITE_TOKEN_QUOTED; -+ int bKeyword = tokenFlags & SQLITE_TOKEN_KEYWORD; -+ int j = *piOut, k = 0; -+ for(; k<nToken; k++){ -+ if( bQuoted ){ -+ if( k==0 && iIn>0 ){ -+ zOut[j++] = '"'; -+ continue; -+ }else if( k==nToken-1 ){ -+ zOut[j++] = '"'; -+ continue; -+ } -+ } -+ if( bKeyword ){ -+ zOut[j++] = sqlite3Toupper(zSql[iIn+k]); -+ }else{ -+ zOut[j++] = sqlite3Tolower(zSql[iIn+k]); -+ } -+ } -+ *piOut = j; -+} -+ -+/* -+** Perform normalization of the SQL contained in the prepared statement and -+** store the result in the zNormSql field. The schema for the associated -+** databases are consulted while performing the normalization in order to -+** determine if a token appears to be an identifier. All identifiers are -+** left intact in the normalized SQL and all literals are replaced with a -+** single '?'. -+*/ -+SQLITE_PRIVATE void sqlite3Normalize( -+ Vdbe *pVdbe, /* VM being reprepared */ -+ const char *zSql, /* The original SQL string */ -+ int nSql, /* Size of the input string in bytes */ -+ u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */ -+){ -+ sqlite3 *db; /* Database handle. */ -+ char *z; /* The output string */ -+ int nZ; /* Size of the output string in bytes */ -+ int i; /* Next character to read from zSql[] */ -+ int j; /* Next character to fill in on z[] */ -+ int tokenType = 0; /* Type of the next token */ -+ int prevTokenType = 0; /* Type of the previous token, except spaces */ -+ int n; /* Size of the next token */ -+ int nParen = 0; /* Nesting level of parenthesis */ -+ Hash inHash; /* Table of parenthesis levels to output index. */ -+ -+ db = sqlite3VdbeDb(pVdbe); -+ assert( db!=0 ); -+ assert( pVdbe->zNormSql==0 ); -+ if( zSql==0 ) return; -+ nZ = estimateNormalizedSize(zSql, nSql, prepFlags); -+ z = sqlite3DbMallocRawNN(db, nZ); -+ if( z==0 ) return; -+ sqlite3HashInit(&inHash); -+ for(i=j=0; i<nSql && zSql[i]; i+=n){ -+ int flags = 0; -+ if( tokenType!=TK_SPACE ) prevTokenType = tokenType; -+ n = sqlite3GetTokenNormalized((unsigned char*)zSql+i, &tokenType, &flags); -+ switch( tokenType ){ -+ case TK_SPACE: { -+ break; -+ } -+ case TK_ILLEGAL: { -+ sqlite3DbFree(db, z); -+ sqlite3HashClear(&inHash); -+ return; -+ } -+ case TK_STRING: -+ case TK_INTEGER: -+ case TK_FLOAT: -+ case TK_VARIABLE: -+ case TK_BLOB: { -+ z[j++] = '?'; -+ break; -+ } -+ case TK_LP: -+ case TK_RP: { -+ if( tokenType==TK_LP ){ -+ nParen++; -+ if( prevTokenType==TK_IN ){ -+ assert( nParen<nSql ); -+ sqlite3HashInsert(&inHash, zSql+nParen, SQLITE_INT_TO_PTR(j)); -+ } -+ }else{ -+ int jj; -+ assert( nParen<nSql ); -+ jj = SQLITE_PTR_TO_INT(sqlite3HashFind(&inHash, zSql+nParen)); -+ if( jj>0 ){ -+ sqlite3HashInsert(&inHash, zSql+nParen, 0); -+ assert( jj+6<nZ ); -+ memcpy(z+jj+1, "?,?,?", 5); -+ j = jj+6; -+ assert( nZ-1-j>=0 ); -+ assert( nZ-1-j<nZ ); -+ memset(z+j, 0, nZ-1-j); -+ } -+ nParen--; -+ } -+ assert( nParen>=0 ); -+ /* Fall through */ -+ } -+ case TK_MINUS: -+ case TK_SEMI: -+ case TK_PLUS: -+ case TK_STAR: -+ case TK_SLASH: -+ case TK_REM: -+ case TK_EQ: -+ case TK_LE: -+ case TK_NE: -+ case TK_LSHIFT: -+ case TK_LT: -+ case TK_RSHIFT: -+ case TK_GT: -+ case TK_GE: -+ case TK_BITOR: -+ case TK_CONCAT: -+ case TK_COMMA: -+ case TK_BITAND: -+ case TK_BITNOT: -+ case TK_DOT: -+ case TK_IN: -+ case TK_IS: -+ case TK_NOT: -+ case TK_NULL: -+ case TK_ID: { -+ if( tokenType==TK_NULL ){ -+ if( prevTokenType==TK_IS || prevTokenType==TK_NOT ){ -+ /* NULL is a keyword in this case, not a literal value */ -+ }else{ -+ /* Here the NULL is a literal value */ -+ z[j++] = '?'; -+ break; -+ } -+ } -+ if( j>0 && sqlite3IsIdChar(z[j-1]) && sqlite3IsIdChar(zSql[i]) ){ -+ z[j++] = ' '; -+ } -+ if( tokenType==TK_ID ){ -+ int i2 = i, n2 = n, rc = SQLITE_OK; -+ if( nParen>0 ){ -+ assert( nParen<nSql ); -+ sqlite3HashInsert(&inHash, zSql+nParen, 0); -+ } -+ if( flags&SQLITE_TOKEN_QUOTED ){ i2++; n2-=2; } -+ if( shouldTreatAsIdentifier(db, zSql+i2, n2, &rc)==0 ){ -+ if( rc!=SQLITE_OK ){ -+ sqlite3DbFree(db, z); -+ sqlite3HashClear(&inHash); -+ return; -+ } -+ if( sqlite3_keyword_check(zSql+i2, n2)==0 ){ -+ z[j++] = '?'; -+ break; -+ } -+ } -+ } -+ copyNormalizedToken(zSql, i, n, flags, z, &j); -+ break; -+ } -+ } -+ } -+ assert( j<nZ && "one" ); -+ while( j>0 && z[j-1]==' ' ){ j--; } -+ if( j>0 && z[j-1]!=';' ){ z[j++] = ';'; } -+ z[j] = 0; -+ assert( j<nZ && "two" ); -+ pVdbe->zNormSql = z; -+ sqlite3HashClear(&inHash); -+} -+#endif /* SQLITE_ENABLE_NORMALIZE */ -+ -+/* - ** Rerun the compilation of a statement after a schema change. - ** - ** If the statement is successfully recompiled, return SQLITE_OK. Otherwise, -@@ -117455,8 +123928,7 @@ - /***/ int sqlite3SelectTrace = 0; - # define SELECTTRACE(K,P,S,X) \ - if(sqlite3SelectTrace&(K)) \ -- sqlite3DebugPrintf("%*s%s.%p: ",(P)->nSelectIndent*2-2,"",\ -- (S)->zSelName,(S)),\ -+ sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\ - sqlite3DebugPrintf X - #else - # define SELECTTRACE(K,P,S,X) -@@ -117479,6 +123951,20 @@ - /* - ** An instance of the following object is used to record information about - ** the ORDER BY (or GROUP BY) clause of query is being coded. -+** -+** The aDefer[] array is used by the sorter-references optimization. For -+** example, assuming there is no index that can be used for the ORDER BY, -+** for the query: -+** -+** SELECT a, bigblob FROM t1 ORDER BY a LIMIT 10; -+** -+** it may be more efficient to add just the "a" values to the sorter, and -+** retrieve the associated "bigblob" values directly from table t1 as the -+** 10 smallest "a" values are extracted from the sorter. -+** -+** When the sorter-reference optimization is used, there is one entry in the -+** aDefer[] array for each database table that may be read as values are -+** extracted from the sorter. - */ - typedef struct SortCtx SortCtx; - struct SortCtx { -@@ -117489,8 +123975,17 @@ - int labelBkOut; /* Start label for the block-output subroutine */ - int addrSortIndex; /* Address of the OP_SorterOpen or OP_OpenEphemeral */ - int labelDone; /* Jump here when done, ex: LIMIT reached */ -+ int labelOBLopt; /* Jump here when sorter is full */ - u8 sortFlags; /* Zero or more SORTFLAG_* bits */ -- u8 bOrderedInnerLoop; /* ORDER BY correctly sorts the inner loop */ -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ u8 nDefer; /* Number of valid entries in aDefer[] */ -+ struct DeferredCsr { -+ Table *pTab; /* Table definition */ -+ int iCsr; /* Cursor number for table */ -+ int nKey; /* Number of PK columns for table pTab (>=1) */ -+ } aDefer[4]; -+#endif -+ struct RowLoadInfo *pDeferredRowLoad; /* Deferred row loading info or NULL */ - }; - #define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */ - -@@ -117508,8 +124003,12 @@ - sqlite3ExprDelete(db, p->pHaving); - sqlite3ExprListDelete(db, p->pOrderBy); - sqlite3ExprDelete(db, p->pLimit); -- sqlite3ExprDelete(db, p->pOffset); -- if( p->pWith ) sqlite3WithDelete(db, p->pWith); -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){ -+ sqlite3WindowListDelete(db, p->pWinDefn); -+ } -+#endif -+ if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith); - if( bFree ) sqlite3DbFreeNN(db, p); - p = pPrior; - bFree = 1; -@@ -117541,8 +124040,7 @@ - Expr *pHaving, /* the HAVING clause */ - ExprList *pOrderBy, /* the ORDER BY clause */ - u32 selFlags, /* Flag parameters, such as SF_Distinct */ -- Expr *pLimit, /* LIMIT value. NULL means not used */ -- Expr *pOffset /* OFFSET value. NULL means no offset */ -+ Expr *pLimit /* LIMIT value. NULL means not used */ - ){ - Select *pNew; - Select standin; -@@ -117552,7 +124050,8 @@ - pNew = &standin; - } - if( pEList==0 ){ -- pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(pParse->db,TK_ASTERISK,0)); -+ pEList = sqlite3ExprListAppend(pParse, 0, -+ sqlite3Expr(pParse->db,TK_ASTERISK,0)); - } - pNew->pEList = pEList; - pNew->op = TK_SELECT; -@@ -117559,9 +124058,7 @@ - pNew->selFlags = selFlags; - pNew->iLimit = 0; - pNew->iOffset = 0; --#if SELECTTRACE_ENABLED -- pNew->zSelName[0] = 0; --#endif -+ pNew->selId = ++pParse->nSelect; - pNew->addrOpenEphm[0] = -1; - pNew->addrOpenEphm[1] = -1; - pNew->nSelectRow = 0; -@@ -117574,9 +124071,11 @@ - pNew->pPrior = 0; - pNew->pNext = 0; - pNew->pLimit = pLimit; -- pNew->pOffset = pOffset; - pNew->pWith = 0; -- assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || pParse->db->mallocFailed!=0 ); -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ pNew->pWin = 0; -+ pNew->pWinDefn = 0; -+#endif - if( pParse->db->mallocFailed ) { - clearSelect(pParse->db, pNew, pNew!=&standin); - pNew = 0; -@@ -117587,23 +124086,12 @@ - return pNew; - } - --#if SELECTTRACE_ENABLED --/* --** Set the name of a Select object --*/ --SQLITE_PRIVATE void sqlite3SelectSetName(Select *p, const char *zName){ -- if( p && zName ){ -- sqlite3_snprintf(sizeof(p->zSelName), p->zSelName, "%s", zName); -- } --} --#endif - -- - /* - ** Delete the given Select structure and all of its substructures. - */ - SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){ -- if( p ) clearSelect(db, p, 1); -+ if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1); - } - - /* -@@ -117820,6 +124308,29 @@ - } - } - -+/* Undo the work of setJoinExpr(). In the expression tree p, convert every -+** term that is marked with EP_FromJoin and iRightJoinTable==iTable into -+** an ordinary term that omits the EP_FromJoin mark. -+** -+** This happens when a LEFT JOIN is simplified into an ordinary JOIN. -+*/ -+static void unsetJoinExpr(Expr *p, int iTable){ -+ while( p ){ -+ if( ExprHasProperty(p, EP_FromJoin) -+ && (iTable<0 || p->iRightJoinTable==iTable) ){ -+ ExprClearProperty(p, EP_FromJoin); -+ } -+ if( p->op==TK_FUNCTION && p->x.pList ){ -+ int i; -+ for(i=0; i<p->x.pList->nExpr; i++){ -+ unsetJoinExpr(p->x.pList->a[i].pExpr, iTable); -+ } -+ } -+ unsetJoinExpr(p->pLeft, iTable); -+ p = p->pRight; -+ } -+} -+ - /* - ** This routine processes the join information for a SELECT statement. - ** ON and USING clauses are converted into extra terms of the WHERE clause. -@@ -117844,11 +124355,10 @@ - pLeft = &pSrc->a[0]; - pRight = &pLeft[1]; - for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){ -- Table *pLeftTab = pLeft->pTab; - Table *pRightTab = pRight->pTab; - int isOuter; - -- if( NEVER(pLeftTab==0 || pRightTab==0) ) continue; -+ if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue; - isOuter = (pRight->fg.jointype & JT_OUTER)!=0; - - /* When the NATURAL keyword is present, add WHERE clause terms for -@@ -117922,15 +124432,63 @@ - return 0; - } - --/* Forward reference */ --static KeyInfo *keyInfoFromExprList( -- Parse *pParse, /* Parsing context */ -- ExprList *pList, /* Form the KeyInfo object from this ExprList */ -- int iStart, /* Begin with this column of pList */ -- int nExtra /* Add this many extra columns to the end */ --); -+/* -+** An instance of this object holds information (beyond pParse and pSelect) -+** needed to load the next result row that is to be added to the sorter. -+*/ -+typedef struct RowLoadInfo RowLoadInfo; -+struct RowLoadInfo { -+ int regResult; /* Store results in array of registers here */ -+ u8 ecelFlags; /* Flag argument to ExprCodeExprList() */ -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ ExprList *pExtra; /* Extra columns needed by sorter refs */ -+ int regExtraResult; /* Where to load the extra columns */ -+#endif -+}; - - /* -+** This routine does the work of loading query data into an array of -+** registers so that it can be added to the sorter. -+*/ -+static void innerLoopLoadRow( -+ Parse *pParse, /* Statement under construction */ -+ Select *pSelect, /* The query being coded */ -+ RowLoadInfo *pInfo /* Info needed to complete the row load */ -+){ -+ sqlite3ExprCodeExprList(pParse, pSelect->pEList, pInfo->regResult, -+ 0, pInfo->ecelFlags); -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ if( pInfo->pExtra ){ -+ sqlite3ExprCodeExprList(pParse, pInfo->pExtra, pInfo->regExtraResult, 0, 0); -+ sqlite3ExprListDelete(pParse->db, pInfo->pExtra); -+ } -+#endif -+} -+ -+/* -+** Code the OP_MakeRecord instruction that generates the entry to be -+** added into the sorter. -+** -+** Return the register in which the result is stored. -+*/ -+static int makeSorterRecord( -+ Parse *pParse, -+ SortCtx *pSort, -+ Select *pSelect, -+ int regBase, -+ int nBase -+){ -+ int nOBSat = pSort->nOBSat; -+ Vdbe *v = pParse->pVdbe; -+ int regOut = ++pParse->nMem; -+ if( pSort->pDeferredRowLoad ){ -+ innerLoopLoadRow(pParse, pSelect, pSort->pDeferredRowLoad); -+ } -+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regOut); -+ return regOut; -+} -+ -+/* - ** Generate code that will push the record in registers regData - ** through regData+nData-1 onto the sorter. - */ -@@ -117940,7 +124498,7 @@ - Select *pSelect, /* The whole SELECT statement */ - int regData, /* First register holding data to be sorted */ - int regOrigData, /* First register holding data before packing */ -- int nData, /* Number of elements in the data array */ -+ int nData, /* Number of elements in the regData data array */ - int nPrefixReg /* No. of reg prior to regData available for use */ - ){ - Vdbe *v = pParse->pVdbe; /* Stmt under construction */ -@@ -117948,16 +124506,32 @@ - int nExpr = pSort->pOrderBy->nExpr; /* No. of ORDER BY terms */ - int nBase = nExpr + bSeq + nData; /* Fields in sorter record */ - int regBase; /* Regs for sorter record */ -- int regRecord = ++pParse->nMem; /* Assembled sorter record */ -+ int regRecord = 0; /* Assembled sorter record */ - int nOBSat = pSort->nOBSat; /* ORDER BY terms to skip */ - int op; /* Opcode to add sorter record to sorter */ - int iLimit; /* LIMIT counter */ -+ int iSkip = 0; /* End of the sorter insert loop */ - - assert( bSeq==0 || bSeq==1 ); -+ -+ /* Three cases: -+ ** (1) The data to be sorted has already been packed into a Record -+ ** by a prior OP_MakeRecord. In this case nData==1 and regData -+ ** will be completely unrelated to regOrigData. -+ ** (2) All output columns are included in the sort record. In that -+ ** case regData==regOrigData. -+ ** (3) Some output columns are omitted from the sort record due to -+ ** the SQLITE_ENABLE_SORTER_REFERENCE optimization, or due to the -+ ** SQLITE_ECEL_OMITREF optimization, or due to the -+ ** SortCtx.pDeferredRowLoad optimiation. In any of these cases -+ ** regOrigData is 0 to prevent this routine from trying to copy -+ ** values that might not yet exist. -+ */ - assert( nData==1 || regData==regOrigData || regOrigData==0 ); -+ - if( nPrefixReg ){ - assert( nPrefixReg==nExpr+bSeq ); -- regBase = regData - nExpr - bSeq; -+ regBase = regData - nPrefixReg; - }else{ - regBase = pParse->nMem + 1; - pParse->nMem += nBase; -@@ -117973,7 +124547,6 @@ - if( nPrefixReg==0 && nData>0 ){ - sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData); - } -- sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord); - if( nOBSat>0 ){ - int regPrevKey; /* The first nOBSat columns of the previous row */ - int addrFirst; /* Address of the OP_IfNot opcode */ -@@ -117982,6 +124555,7 @@ - int nKey; /* Number of sorting key columns, including OP_Sequence */ - KeyInfo *pKI; /* Original KeyInfo on the sorter table */ - -+ regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase); - regPrevKey = pParse->nMem+1; - pParse->nMem += pSort->nOBSat; - nKey = nExpr - pSort->nOBSat + bSeq; -@@ -117996,11 +124570,11 @@ - if( pParse->db->mallocFailed ) return; - pOp->p2 = nKey + nData; - pKI = pOp->p4.pKeyInfo; -- memset(pKI->aSortOrder, 0, pKI->nField); /* Makes OP_Jump below testable */ -+ memset(pKI->aSortOrder, 0, pKI->nKeyField); /* Makes OP_Jump testable */ - sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO); -- testcase( pKI->nXField>2 ); -- pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat, -- pKI->nXField-1); -+ testcase( pKI->nAllField > pKI->nKeyField+2 ); -+ pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat, -+ pKI->nAllField-pKI->nKeyField-1); - addrJmp = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); - pSort->labelBkOut = sqlite3VdbeMakeLabel(v); -@@ -118015,6 +124589,34 @@ - sqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat); - sqlite3VdbeJumpHere(v, addrJmp); - } -+ if( iLimit ){ -+ /* At this point the values for the new sorter entry are stored -+ ** in an array of registers. They need to be composed into a record -+ ** and inserted into the sorter if either (a) there are currently -+ ** less than LIMIT+OFFSET items or (b) the new record is smaller than -+ ** the largest record currently in the sorter. If (b) is true and there -+ ** are already LIMIT+OFFSET items in the sorter, delete the largest -+ ** entry before inserting the new one. This way there are never more -+ ** than LIMIT+OFFSET items in the sorter. -+ ** -+ ** If the new record does not need to be inserted into the sorter, -+ ** jump to the next iteration of the loop. If the pSort->labelOBLopt -+ ** value is not zero, then it is a label of where to jump. Otherwise, -+ ** just bypass the row insert logic. See the header comment on the -+ ** sqlite3WhereOrderByLimitOptLabel() function for additional info. -+ */ -+ int iCsr = pSort->iECursor; -+ sqlite3VdbeAddOp2(v, OP_IfNotZero, iLimit, sqlite3VdbeCurrentAddr(v)+4); -+ VdbeCoverage(v); -+ sqlite3VdbeAddOp2(v, OP_Last, iCsr, 0); -+ iSkip = sqlite3VdbeAddOp4Int(v, OP_IdxLE, -+ iCsr, 0, regBase+nOBSat, nExpr-nOBSat); -+ VdbeCoverage(v); -+ sqlite3VdbeAddOp1(v, OP_Delete, iCsr); -+ } -+ if( regRecord==0 ){ -+ regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase); -+ } - if( pSort->sortFlags & SORTFLAG_UseSorter ){ - op = OP_SorterInsert; - }else{ -@@ -118022,33 +124624,9 @@ - } - sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord, - regBase+nOBSat, nBase-nOBSat); -- if( iLimit ){ -- int addr; -- int r1 = 0; -- /* Fill the sorter until it contains LIMIT+OFFSET entries. (The iLimit -- ** register is initialized with value of LIMIT+OFFSET.) After the sorter -- ** fills up, delete the least entry in the sorter after each insert. -- ** Thus we never hold more than the LIMIT+OFFSET rows in memory at once */ -- addr = sqlite3VdbeAddOp1(v, OP_IfNotZero, iLimit); VdbeCoverage(v); -- sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor); -- if( pSort->bOrderedInnerLoop ){ -- r1 = ++pParse->nMem; -- sqlite3VdbeAddOp3(v, OP_Column, pSort->iECursor, nExpr, r1); -- VdbeComment((v, "seq")); -- } -- sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor); -- if( pSort->bOrderedInnerLoop ){ -- /* If the inner loop is driven by an index such that values from -- ** the same iteration of the inner loop are in sorted order, then -- ** immediately jump to the next iteration of an inner loop if the -- ** entry from the current iteration does not fit into the top -- ** LIMIT+OFFSET entries of the sorter. */ -- int iBrk = sqlite3VdbeCurrentAddr(v) + 2; -- sqlite3VdbeAddOp3(v, OP_Eq, regBase+nExpr, iBrk, r1); -- sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); -- VdbeCoverage(v); -- } -- sqlite3VdbeJumpHere(v, addr); -+ if( iSkip ){ -+ sqlite3VdbeChangeP2(v, iSkip, -+ pSort->labelOBLopt ? pSort->labelOBLopt : sqlite3VdbeCurrentAddr(v)); - } - } - -@@ -118094,20 +124672,100 @@ - sqlite3ReleaseTempReg(pParse, r1); - } - -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES - /* -+** This function is called as part of inner-loop generation for a SELECT -+** statement with an ORDER BY that is not optimized by an index. It -+** determines the expressions, if any, that the sorter-reference -+** optimization should be used for. The sorter-reference optimization -+** is used for SELECT queries like: -+** -+** SELECT a, bigblob FROM t1 ORDER BY a LIMIT 10 -+** -+** If the optimization is used for expression "bigblob", then instead of -+** storing values read from that column in the sorter records, the PK of -+** the row from table t1 is stored instead. Then, as records are extracted from -+** the sorter to return to the user, the required value of bigblob is -+** retrieved directly from table t1. If the values are very large, this -+** can be more efficient than storing them directly in the sorter records. -+** -+** The ExprList_item.bSorterRef flag is set for each expression in pEList -+** for which the sorter-reference optimization should be enabled. -+** Additionally, the pSort->aDefer[] array is populated with entries -+** for all cursors required to evaluate all selected expressions. Finally. -+** output variable (*ppExtra) is set to an expression list containing -+** expressions for all extra PK values that should be stored in the -+** sorter records. -+*/ -+static void selectExprDefer( -+ Parse *pParse, /* Leave any error here */ -+ SortCtx *pSort, /* Sorter context */ -+ ExprList *pEList, /* Expressions destined for sorter */ -+ ExprList **ppExtra /* Expressions to append to sorter record */ -+){ -+ int i; -+ int nDefer = 0; -+ ExprList *pExtra = 0; -+ for(i=0; i<pEList->nExpr; i++){ -+ struct ExprList_item *pItem = &pEList->a[i]; -+ if( pItem->u.x.iOrderByCol==0 ){ -+ Expr *pExpr = pItem->pExpr; -+ Table *pTab = pExpr->y.pTab; -+ if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab) -+ && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF) -+ ){ -+ int j; -+ for(j=0; j<nDefer; j++){ -+ if( pSort->aDefer[j].iCsr==pExpr->iTable ) break; -+ } -+ if( j==nDefer ){ -+ if( nDefer==ArraySize(pSort->aDefer) ){ -+ continue; -+ }else{ -+ int nKey = 1; -+ int k; -+ Index *pPk = 0; -+ if( !HasRowid(pTab) ){ -+ pPk = sqlite3PrimaryKeyIndex(pTab); -+ nKey = pPk->nKeyCol; -+ } -+ for(k=0; k<nKey; k++){ -+ Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0); -+ if( pNew ){ -+ pNew->iTable = pExpr->iTable; -+ pNew->y.pTab = pExpr->y.pTab; -+ pNew->iColumn = pPk ? pPk->aiColumn[k] : -1; -+ pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew); -+ } -+ } -+ pSort->aDefer[nDefer].pTab = pExpr->y.pTab; -+ pSort->aDefer[nDefer].iCsr = pExpr->iTable; -+ pSort->aDefer[nDefer].nKey = nKey; -+ nDefer++; -+ } -+ } -+ pItem->bSorterRef = 1; -+ } -+ } -+ } -+ pSort->nDefer = (u8)nDefer; -+ *ppExtra = pExtra; -+} -+#endif -+ -+/* - ** This routine generates the code for the inside of the inner loop - ** of a SELECT. - ** --** If srcTab is negative, then the pEList expressions -+** If srcTab is negative, then the p->pEList expressions - ** are evaluated in order to get the data for this row. If srcTab is --** zero or more, then data is pulled from srcTab and pEList is used only -+** zero or more, then data is pulled from srcTab and p->pEList is used only - ** to get the number of columns and the collation sequence for each column. - */ - static void selectInnerLoop( - Parse *pParse, /* The parser context */ - Select *p, /* The complete select statement being coded */ -- ExprList *pEList, /* List of values being extracted */ -- int srcTab, /* Pull data from this table */ -+ int srcTab, /* Pull data from this table if non-negative */ - SortCtx *pSort, /* If not NULL, info on how to process ORDER BY */ - DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */ - SelectDest *pDest, /* How to dispose of the results */ -@@ -118121,6 +124779,7 @@ - int iParm = pDest->iSDParm; /* First argument to disposal method */ - int nResultCol; /* Number of result columns */ - int nPrefixReg = 0; /* Number of extra registers before regResult */ -+ RowLoadInfo sRowLoadInfo; /* Info for deferred row loading */ - - /* Usually, regResult is the first cell in an array of memory cells - ** containing the current result row. In this case regOrig is set to the -@@ -118131,7 +124790,7 @@ - int regOrig; /* Start of memory holding full result (or 0) */ - - assert( v ); -- assert( pEList!=0 ); -+ assert( p->pEList!=0 ); - hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP; - if( pSort && pSort->pOrderBy==0 ) pSort = 0; - if( pSort==0 && !hasDistinct ){ -@@ -118141,7 +124800,7 @@ - - /* Pull the requested columns. - */ -- nResultCol = pEList->nExpr; -+ nResultCol = p->pEList->nExpr; - - if( pDest->iSdst==0 ){ - if( pSort ){ -@@ -118164,13 +124823,17 @@ - if( srcTab>=0 ){ - for(i=0; i<nResultCol; i++){ - sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i); -- VdbeComment((v, "%s", pEList->a[i].zName)); -+ VdbeComment((v, "%s", p->pEList->a[i].zName)); - } - }else if( eDest!=SRT_Exists ){ -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ ExprList *pExtra = 0; -+#endif - /* If the destination is an EXISTS(...) expression, the actual - ** values returned by the SELECT are not required. - */ -- u8 ecelFlags; -+ u8 ecelFlags; /* "ecel" is an abbreviation of "ExprCodeExprList" */ -+ ExprList *pEList; - if( eDest==SRT_Mem || eDest==SRT_Output || eDest==SRT_Coroutine ){ - ecelFlags = SQLITE_ECEL_DUP; - }else{ -@@ -118177,24 +124840,75 @@ - ecelFlags = 0; - } - if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){ -- /* For each expression in pEList that is a copy of an expression in -+ /* For each expression in p->pEList that is a copy of an expression in - ** the ORDER BY clause (pSort->pOrderBy), set the associated - ** iOrderByCol value to one more than the index of the ORDER BY - ** expression within the sort-key that pushOntoSorter() will generate. -- ** This allows the pEList field to be omitted from the sorted record, -+ ** This allows the p->pEList field to be omitted from the sorted record, - ** saving space and CPU cycles. */ - ecelFlags |= (SQLITE_ECEL_OMITREF|SQLITE_ECEL_REF); -+ - for(i=pSort->nOBSat; i<pSort->pOrderBy->nExpr; i++){ - int j; - if( (j = pSort->pOrderBy->a[i].u.x.iOrderByCol)>0 ){ -- pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat; -+ p->pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat; - } - } -- regOrig = 0; -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ selectExprDefer(pParse, pSort, p->pEList, &pExtra); -+ if( pExtra && pParse->db->mallocFailed==0 ){ -+ /* If there are any extra PK columns to add to the sorter records, -+ ** allocate extra memory cells and adjust the OpenEphemeral -+ ** instruction to account for the larger records. This is only -+ ** required if there are one or more WITHOUT ROWID tables with -+ ** composite primary keys in the SortCtx.aDefer[] array. */ -+ VdbeOp *pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex); -+ pOp->p2 += (pExtra->nExpr - pSort->nDefer); -+ pOp->p4.pKeyInfo->nAllField += (pExtra->nExpr - pSort->nDefer); -+ pParse->nMem += pExtra->nExpr; -+ } -+#endif -+ -+ /* Adjust nResultCol to account for columns that are omitted -+ ** from the sorter by the optimizations in this branch */ -+ pEList = p->pEList; -+ for(i=0; i<pEList->nExpr; i++){ -+ if( pEList->a[i].u.x.iOrderByCol>0 -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ || pEList->a[i].bSorterRef -+#endif -+ ){ -+ nResultCol--; -+ regOrig = 0; -+ } -+ } -+ -+ testcase( regOrig ); -+ testcase( eDest==SRT_Set ); -+ testcase( eDest==SRT_Mem ); -+ testcase( eDest==SRT_Coroutine ); -+ testcase( eDest==SRT_Output ); - assert( eDest==SRT_Set || eDest==SRT_Mem - || eDest==SRT_Coroutine || eDest==SRT_Output ); - } -- nResultCol = sqlite3ExprCodeExprList(pParse,pEList,regResult,0,ecelFlags); -+ sRowLoadInfo.regResult = regResult; -+ sRowLoadInfo.ecelFlags = ecelFlags; -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ sRowLoadInfo.pExtra = pExtra; -+ sRowLoadInfo.regExtraResult = regResult + nResultCol; -+ if( pExtra ) nResultCol += pExtra->nExpr; -+#endif -+ if( p->iLimit -+ && (ecelFlags & SQLITE_ECEL_OMITREF)!=0 -+ && nPrefixReg>0 -+ ){ -+ assert( pSort!=0 ); -+ assert( hasDistinct==0 ); -+ pSort->pDeferredRowLoad = &sRowLoadInfo; -+ regOrig = 0; -+ }else{ -+ innerLoopLoadRow(pParse, p, &sRowLoadInfo); -+ } - } - - /* If the DISTINCT keyword was present on the SELECT statement -@@ -118226,7 +124940,7 @@ - - iJump = sqlite3VdbeCurrentAddr(v) + nResultCol; - for(i=0; i<nResultCol; i++){ -- CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[i].pExpr); -+ CollSeq *pColl = sqlite3ExprCollSeq(pParse, p->pEList->a[i].pExpr); - if( i<nResultCol-1 ){ - sqlite3VdbeAddOp3(v, OP_Ne, regResult+i, iJump, regPrev+i); - VdbeCoverage(v); -@@ -118310,7 +125024,8 @@ - } - #endif - if( pSort ){ -- pushOntoSorter(pParse, pSort, p, r1+nPrefixReg,regResult,1,nPrefixReg); -+ assert( regResult==regOrig ); -+ pushOntoSorter(pParse, pSort, p, r1+nPrefixReg, regOrig, 1, nPrefixReg); - }else{ - int r2 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2); -@@ -118340,7 +125055,6 @@ - assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, - r1, pDest->zAffSdst, nResultCol); -- sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol); - sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); - sqlite3ReleaseTempReg(pParse, r1); - } -@@ -118384,7 +125098,6 @@ - sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); - }else{ - sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol); -- sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol); - } - break; - } -@@ -118469,8 +125182,8 @@ - KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra); - if( p ){ - p->aSortOrder = (u8*)&p->aColl[N+X]; -- p->nField = (u16)N; -- p->nXField = (u16)X; -+ p->nKeyField = (u16)N; -+ p->nAllField = (u16)(N+X); - p->enc = ENC(db); - p->db = db; - p->nRef = 1; -@@ -118527,7 +125240,7 @@ - ** function is responsible for seeing that this structure is eventually - ** freed. - */ --static KeyInfo *keyInfoFromExprList( -+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList( - Parse *pParse, /* Parsing context */ - ExprList *pList, /* Form the KeyInfo object from this ExprList */ - int iStart, /* Begin with this column of pList */ -@@ -118544,10 +125257,7 @@ - if( pInfo ){ - assert( sqlite3KeyInfoIsWriteable(pInfo) ); - for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){ -- CollSeq *pColl; -- pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr); -- if( !pColl ) pColl = db->pDfltColl; -- pInfo->aColl[i-iStart] = pColl; -+ pInfo->aColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr); - pInfo->aSortOrder[i-iStart] = pItem->sortOrder; - } - } -@@ -118580,11 +125290,7 @@ - ** is determined by the zUsage argument. - */ - static void explainTempTable(Parse *pParse, const char *zUsage){ -- if( pParse->explain==2 ){ -- Vdbe *v = pParse->pVdbe; -- char *zMsg = sqlite3MPrintf(pParse->db, "USE TEMP B-TREE FOR %s", zUsage); -- sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); -- } -+ ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s", zUsage)); - } - - /* -@@ -118602,42 +125308,6 @@ - # define explainSetInteger(y,z) - #endif - --#if !defined(SQLITE_OMIT_EXPLAIN) && !defined(SQLITE_OMIT_COMPOUND_SELECT) --/* --** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function --** is a no-op. Otherwise, it adds a single row of output to the EQP result, --** where the caption is of one of the two forms: --** --** "COMPOSITE SUBQUERIES iSub1 and iSub2 (op)" --** "COMPOSITE SUBQUERIES iSub1 and iSub2 USING TEMP B-TREE (op)" --** --** where iSub1 and iSub2 are the integers passed as the corresponding --** function parameters, and op is the text representation of the parameter --** of the same name. The parameter "op" must be one of TK_UNION, TK_EXCEPT, --** TK_INTERSECT or TK_ALL. The first form is used if argument bUseTmp is --** false, or the second form if it is true. --*/ --static void explainComposite( -- Parse *pParse, /* Parse context */ -- int op, /* One of TK_UNION, TK_EXCEPT etc. */ -- int iSub1, /* Subquery id 1 */ -- int iSub2, /* Subquery id 2 */ -- int bUseTmp /* True if a temp table was used */ --){ -- assert( op==TK_UNION || op==TK_EXCEPT || op==TK_INTERSECT || op==TK_ALL ); -- if( pParse->explain==2 ){ -- Vdbe *v = pParse->pVdbe; -- char *zMsg = sqlite3MPrintf( -- pParse->db, "COMPOUND SUBQUERIES %d AND %d %s(%s)", iSub1, iSub2, -- bUseTmp?"USING TEMP B-TREE ":"", selectOpName(op) -- ); -- sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); -- } --} --#else --/* No-op versions of the explainXXX() functions and macros. */ --# define explainComposite(v,w,x,y,z) --#endif - - /* - ** If the inner loop was generated using a non-null pOrderBy argument, -@@ -118655,7 +125325,7 @@ - Vdbe *v = pParse->pVdbe; /* The prepared statement */ - int addrBreak = pSort->labelDone; /* Jump here to exit loop */ - int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */ -- int addr; -+ int addr; /* Top of output loop. Jump for Next. */ - int addrOnce = 0; - int iTab; - ExprList *pOrderBy = pSort->pOrderBy; -@@ -118664,11 +125334,11 @@ - int regRow; - int regRowid; - int iCol; -- int nKey; -+ int nKey; /* Number of key columns in sorter record */ - int iSortTab; /* Sorter cursor to read from */ -- int nSortData; /* Trailing values to read from sorter */ - int i; - int bSeq; /* True if sorter record includes seq. no. */ -+ int nRefKey = 0; - struct ExprList_item *aOutEx = p->pEList->a; - - assert( addrBreak<0 ); -@@ -118677,15 +125347,24 @@ - sqlite3VdbeGoto(v, addrBreak); - sqlite3VdbeResolveLabel(v, pSort->labelBkOut); - } -+ -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ /* Open any cursors needed for sorter-reference expressions */ -+ for(i=0; i<pSort->nDefer; i++){ -+ Table *pTab = pSort->aDefer[i].pTab; -+ int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); -+ sqlite3OpenTable(pParse, pSort->aDefer[i].iCsr, iDb, pTab, OP_OpenRead); -+ nRefKey = MAX(nRefKey, pSort->aDefer[i].nKey); -+ } -+#endif -+ - iTab = pSort->iECursor; - if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){ - regRowid = 0; - regRow = pDest->iSdst; -- nSortData = nColumn; - }else{ - regRowid = sqlite3GetTempReg(pParse); - regRow = sqlite3GetTempRange(pParse, nColumn); -- nSortData = nColumn; - } - nKey = pOrderBy->nExpr - pSort->nOBSat; - if( pSort->sortFlags & SORTFLAG_UseSorter ){ -@@ -118694,7 +125373,8 @@ - if( pSort->labelBkOut ){ - addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); - } -- sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData); -+ sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, -+ nKey+1+nColumn+nRefKey); - if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); - addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); - VdbeCoverage(v); -@@ -118707,16 +125387,60 @@ - iSortTab = iTab; - bSeq = 1; - } -- for(i=0, iCol=nKey+bSeq; i<nSortData; i++){ -- int iRead; -- if( aOutEx[i].u.x.iOrderByCol ){ -- iRead = aOutEx[i].u.x.iOrderByCol-1; -- }else{ -- iRead = iCol++; -+ for(i=0, iCol=nKey+bSeq-1; i<nColumn; i++){ -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ if( aOutEx[i].bSorterRef ) continue; -+#endif -+ if( aOutEx[i].u.x.iOrderByCol==0 ) iCol++; -+ } -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ if( pSort->nDefer ){ -+ int iKey = iCol+1; -+ int regKey = sqlite3GetTempRange(pParse, nRefKey); -+ -+ for(i=0; i<pSort->nDefer; i++){ -+ int iCsr = pSort->aDefer[i].iCsr; -+ Table *pTab = pSort->aDefer[i].pTab; -+ int nKey = pSort->aDefer[i].nKey; -+ -+ sqlite3VdbeAddOp1(v, OP_NullRow, iCsr); -+ if( HasRowid(pTab) ){ -+ sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iKey++, regKey); -+ sqlite3VdbeAddOp3(v, OP_SeekRowid, iCsr, -+ sqlite3VdbeCurrentAddr(v)+1, regKey); -+ }else{ -+ int k; -+ int iJmp; -+ assert( sqlite3PrimaryKeyIndex(pTab)->nKeyCol==nKey ); -+ for(k=0; k<nKey; k++){ -+ sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iKey++, regKey+k); -+ } -+ iJmp = sqlite3VdbeCurrentAddr(v); -+ sqlite3VdbeAddOp4Int(v, OP_SeekGE, iCsr, iJmp+2, regKey, nKey); -+ sqlite3VdbeAddOp4Int(v, OP_IdxLE, iCsr, iJmp+3, regKey, nKey); -+ sqlite3VdbeAddOp1(v, OP_NullRow, iCsr); -+ } - } -- sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i); -- VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan)); -+ sqlite3ReleaseTempRange(pParse, regKey, nRefKey); - } -+#endif -+ for(i=nColumn-1; i>=0; i--){ -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ if( aOutEx[i].bSorterRef ){ -+ sqlite3ExprCode(pParse, aOutEx[i].pExpr, regRow+i); -+ }else -+#endif -+ { -+ int iRead; -+ if( aOutEx[i].u.x.iOrderByCol ){ -+ iRead = aOutEx[i].u.x.iOrderByCol-1; -+ }else{ -+ iRead = iCol--; -+ } -+ sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i); -+ VdbeComment((v, "%s", aOutEx[i].zName?aOutEx[i].zName : aOutEx[i].zSpan)); -+ } -+ } - switch( eDest ){ - case SRT_Table: - case SRT_EphemTab: { -@@ -118730,7 +125454,6 @@ - assert( nColumn==sqlite3Strlen30(pDest->zAffSdst) ); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid, - pDest->zAffSdst, nColumn); -- sqlite3ExprCacheAffinityChange(pParse, regRow, nColumn); - sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, regRowid, regRow, nColumn); - break; - } -@@ -118745,7 +125468,6 @@ - testcase( eDest==SRT_Coroutine ); - if( eDest==SRT_Output ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn); -- sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn); - }else{ - sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); - } -@@ -118797,23 +125519,23 @@ - ** the SQLITE_ENABLE_COLUMN_METADATA compile-time option is used. - */ - #ifdef SQLITE_ENABLE_COLUMN_METADATA --# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,C,D,E,F) -+# define columnType(A,B,C,D,E) columnTypeImpl(A,B,C,D,E) - #else /* if !defined(SQLITE_ENABLE_COLUMN_METADATA) */ --# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,F) -+# define columnType(A,B,C,D,E) columnTypeImpl(A,B) - #endif - static const char *columnTypeImpl( - NameContext *pNC, -+#ifndef SQLITE_ENABLE_COLUMN_METADATA -+ Expr *pExpr -+#else - Expr *pExpr, --#ifdef SQLITE_ENABLE_COLUMN_METADATA - const char **pzOrigDb, - const char **pzOrigTab, -- const char **pzOrigCol, -+ const char **pzOrigCol - #endif -- u8 *pEstWidth - ){ - char const *zType = 0; - int j; -- u8 estWidth = 1; - #ifdef SQLITE_ENABLE_COLUMN_METADATA - char const *zOrigDb = 0; - char const *zOrigTab = 0; -@@ -118822,8 +125544,9 @@ - - assert( pExpr!=0 ); - assert( pNC->pSrcList!=0 ); -+ assert( pExpr->op!=TK_AGG_COLUMN ); /* This routine runes before aggregates -+ ** are processed */ - switch( pExpr->op ){ -- case TK_AGG_COLUMN: - case TK_COLUMN: { - /* The expression is a column. Locate the table the column is being - ** extracted from in NameContext.pSrcList. This table may be real -@@ -118832,8 +125555,6 @@ - Table *pTab = 0; /* Table structure column is extracted from */ - Select *pS = 0; /* Select the column is extracted from */ - int iCol = pExpr->iColumn; /* Index of column in pTab */ -- testcase( pExpr->op==TK_AGG_COLUMN ); -- testcase( pExpr->op==TK_COLUMN ); - while( pNC && !pTab ){ - SrcList *pTabList = pNC->pSrcList; - for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); -@@ -118866,7 +125587,7 @@ - break; - } - -- assert( pTab && pExpr->pTab==pTab ); -+ assert( pTab && pExpr->y.pTab==pTab ); - if( pS ){ - /* The "table" is actually a sub-select or a view in the FROM clause - ** of the SELECT statement. Return the declaration type and origin -@@ -118882,14 +125603,14 @@ - sNC.pSrcList = pS->pSrc; - sNC.pNext = pNC; - sNC.pParse = pNC->pParse; -- zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol, &estWidth); -+ zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol); - } -- }else if( pTab->pSchema ){ -- /* A real table */ -+ }else{ -+ /* A real table or a CTE table */ - assert( !pS ); -+#ifdef SQLITE_ENABLE_COLUMN_METADATA - if( iCol<0 ) iCol = pTab->iPKey; -- assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) ); --#ifdef SQLITE_ENABLE_COLUMN_METADATA -+ assert( iCol==XN_ROWID || (iCol>=0 && iCol<pTab->nCol) ); - if( iCol<0 ){ - zType = "INTEGER"; - zOrigCol = "rowid"; -@@ -118896,19 +125617,18 @@ - }else{ - zOrigCol = pTab->aCol[iCol].zName; - zType = sqlite3ColumnType(&pTab->aCol[iCol],0); -- estWidth = pTab->aCol[iCol].szEst; - } - zOrigTab = pTab->zName; -- if( pNC->pParse ){ -+ if( pNC->pParse && pTab->pSchema ){ - int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema); - zOrigDb = pNC->pParse->db->aDb[iDb].zDbSName; - } - #else -+ assert( iCol==XN_ROWID || (iCol>=0 && iCol<pTab->nCol) ); - if( iCol<0 ){ - zType = "INTEGER"; - }else{ - zType = sqlite3ColumnType(&pTab->aCol[iCol],0); -- estWidth = pTab->aCol[iCol].szEst; - } - #endif - } -@@ -118927,7 +125647,7 @@ - sNC.pSrcList = pS->pSrc; - sNC.pNext = pNC; - sNC.pParse = pNC->pParse; -- zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, &estWidth); -+ zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); - break; - } - #endif -@@ -118941,7 +125661,6 @@ - *pzOrigCol = zOrigCol; - } - #endif -- if( pEstWidth ) *pEstWidth = estWidth; - return zType; - } - -@@ -118968,7 +125687,7 @@ - const char *zOrigDb = 0; - const char *zOrigTab = 0; - const char *zOrigCol = 0; -- zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, 0); -+ zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); - - /* The vdbe must make its own copy of the column-type and other - ** column specific strings, in case the schema is reset before this -@@ -118978,7 +125697,7 @@ - sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT); - sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT); - #else -- zType = columnType(&sNC, p, 0, 0, 0, 0); -+ zType = columnType(&sNC, p, 0, 0, 0); - #endif - sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); - } -@@ -119008,9 +125727,9 @@ - ** other words, the zSpan of the result expression. - ** - ** short=ON, full=OFF: (This is the default setting). If the result --** refers directly to a table column, then the result --** column name is just the table column name: COLUMN. --** Otherwise use zSpan. -+** refers directly to a table column, then the -+** result column name is just the table column -+** name: COLUMN. Otherwise use zSpan. - ** - ** full=ON, short=ANY: If the result refers directly to a table column, - ** then the result column name with the table name -@@ -119036,9 +125755,10 @@ - } - #endif - -- if( pParse->colNamesSet || db->mallocFailed ) return; -+ if( pParse->colNamesSet ) return; - /* Column names are determined by the left-most term of a compound select */ - while( pSelect->pPrior ) pSelect = pSelect->pPrior; -+ SELECTTRACE(1,pParse,pSelect,("generating column names\n")); - pTabList = pSelect->pSrc; - pEList = pSelect->pEList; - assert( v!=0 ); -@@ -119051,6 +125771,8 @@ - Expr *p = pEList->a[i].pExpr; - - assert( p!=0 ); -+ assert( p->op!=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 ){ - /* An AS clause always takes first priority */ - char *zName = pEList->a[i].zName; -@@ -119058,7 +125780,7 @@ - }else if( srcName && p->op==TK_COLUMN ){ - char *zCol; - int iCol = p->iColumn; -- pTab = p->pTab; -+ pTab = p->y.pTab; - assert( pTab!=0 ); - if( iCol<0 ) iCol = pTab->iPKey; - assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) ); -@@ -119125,6 +125847,7 @@ - nCol = pEList->nExpr; - aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol); - testcase( aCol==0 ); -+ if( nCol>32767 ) nCol = 32767; - }else{ - nCol = 0; - aCol = 0; -@@ -119144,10 +125867,12 @@ - pColExpr = pColExpr->pRight; - assert( pColExpr!=0 ); - } -- if( pColExpr->op==TK_COLUMN && pColExpr->pTab!=0 ){ -+ assert( pColExpr->op!=TK_AGG_COLUMN ); -+ if( pColExpr->op==TK_COLUMN ){ - /* For columns use the column name name */ - int iCol = pColExpr->iColumn; -- Table *pTab = pColExpr->pTab; -+ Table *pTab = pColExpr->y.pTab; -+ assert( pTab!=0 ); - if( iCol<0 ) iCol = pTab->iPKey; - zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid"; - }else if( pColExpr->op==TK_ID ){ -@@ -119219,7 +125944,6 @@ - int i; - Expr *p; - struct ExprList_item *a; -- u64 szAll = 0; - - assert( pSelect!=0 ); - assert( (pSelect->selFlags & SF_Resolved)!=0 ); -@@ -119232,10 +125956,11 @@ - const char *zType; - int n, m; - p = a[i].pExpr; -- zType = columnType(&sNC, p, 0, 0, 0, &pCol->szEst); -- szAll += pCol->szEst; -+ zType = columnType(&sNC, p, 0, 0, 0); -+ /* pCol->szEst = ... // Column size est for SELECT tables never used */ - pCol->affinity = sqlite3ExprAffinity(p); -- if( zType && (m = sqlite3Strlen30(zType))>0 ){ -+ if( zType ){ -+ m = sqlite3Strlen30(zType); - n = sqlite3Strlen30(pCol->zName); - pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2); - if( pCol->zName ){ -@@ -119249,7 +125974,7 @@ - pCol->zColl = sqlite3DbStrDup(db, pColl->zName); - } - } -- pTab->szTabRow = sqlite3LogEst(szAll*4); -+ pTab->szTabRow = 1; /* Any non-zero value works */ - } - - /* -@@ -119292,25 +126017,22 @@ - ** Get a VDBE for the given parser context. Create a new one if necessary. - ** If an error occurs, return NULL and leave a message in pParse. - */ --static SQLITE_NOINLINE Vdbe *allocVdbe(Parse *pParse){ -- Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(pParse); -- if( v ) sqlite3VdbeAddOp2(v, OP_Init, 0, 1); -+SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){ -+ if( pParse->pVdbe ){ -+ return pParse->pVdbe; -+ } - if( pParse->pToplevel==0 - && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst) - ){ - pParse->okConstFactor = 1; - } -- return v; -+ return sqlite3VdbeCreate(pParse); - } --SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){ -- Vdbe *v = pParse->pVdbe; -- return v ? v : allocVdbe(pParse); --} - - - /* - ** Compute the iLimit and iOffset fields of the SELECT based on the --** pLimit and pOffset expressions. pLimit and pOffset hold the expressions -+** pLimit expressions. pLimit->pLeft and pLimit->pRight hold the expressions - ** that appear in the original SQL statement after the LIMIT and OFFSET - ** keywords. Or NULL if those keywords are omitted. iLimit and iOffset - ** are the integer memory register numbers for counters used to compute -@@ -119318,8 +126040,8 @@ - ** iLimit and iOffset are negative. - ** - ** This routine changes the values of iLimit and iOffset only if --** a limit or offset is defined by pLimit and pOffset. iLimit and --** iOffset should have been preset to appropriate default values (zero) -+** a limit or offset is defined by pLimit->pLeft and pLimit->pRight. iLimit -+** and iOffset should have been preset to appropriate default values (zero) - ** prior to calling this routine. - ** - ** The iOffset register (if it exists) is initialized to the value -@@ -119326,7 +126048,7 @@ - ** of the OFFSET. The iLimit register is initialized to LIMIT. Register - ** iOffset+1 is initialized to LIMIT+OFFSET. - ** --** Only if pLimit!=0 or pOffset!=0 do the limit registers get -+** Only if pLimit->pLeft!=0 do the limit registers get - ** redefined. The UNION ALL operator uses this property to force - ** the reuse of the same limit and offset registers across multiple - ** SELECT statements. -@@ -119336,6 +126058,8 @@ - int iLimit = 0; - int iOffset; - int n; -+ Expr *pLimit = p->pLimit; -+ - if( p->iLimit ) return; - - /* -@@ -119344,13 +126068,13 @@ - ** The current implementation interprets "LIMIT 0" to mean - ** no rows. - */ -- sqlite3ExprCacheClear(pParse); -- assert( p->pOffset==0 || p->pLimit!=0 ); -- if( p->pLimit ){ -+ if( pLimit ){ -+ assert( pLimit->op==TK_LIMIT ); -+ assert( pLimit->pLeft!=0 ); - p->iLimit = iLimit = ++pParse->nMem; - v = sqlite3GetVdbe(pParse); - assert( v!=0 ); -- if( sqlite3ExprIsInteger(p->pLimit, &n) ){ -+ if( sqlite3ExprIsInteger(pLimit->pLeft, &n) ){ - sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); - VdbeComment((v, "LIMIT counter")); - if( n==0 ){ -@@ -119360,15 +126084,15 @@ - p->selFlags |= SF_FixedLimit; - } - }else{ -- sqlite3ExprCode(pParse, p->pLimit, iLimit); -+ sqlite3ExprCode(pParse, pLimit->pLeft, iLimit); - sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v); - VdbeComment((v, "LIMIT counter")); - sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v); - } -- if( p->pOffset ){ -+ if( pLimit->pRight ){ - p->iOffset = iOffset = ++pParse->nMem; - pParse->nMem++; /* Allocate an extra register for limit+offset */ -- sqlite3ExprCode(pParse, p->pOffset, iOffset); -+ sqlite3ExprCode(pParse, pLimit->pRight, iOffset); - sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v); - VdbeComment((v, "OFFSET counter")); - sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset); -@@ -119498,9 +126222,16 @@ - int i; /* Loop counter */ - int rc; /* Result code */ - ExprList *pOrderBy; /* The ORDER BY clause */ -- Expr *pLimit, *pOffset; /* Saved LIMIT and OFFSET */ -+ Expr *pLimit; /* Saved LIMIT and OFFSET */ - int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */ - -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( p->pWin ){ -+ sqlite3ErrorMsg(pParse, "cannot use window functions in recursive queries"); -+ return; -+ } -+#endif -+ - /* Obtain authorization to do a recursive query */ - if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return; - -@@ -119509,10 +126240,9 @@ - p->nSelectRow = 320; /* 4 billion rows */ - computeLimitRegisters(pParse, p, addrBreak); - pLimit = p->pLimit; -- pOffset = p->pOffset; - regLimit = p->iLimit; - regOffset = p->iOffset; -- p->pLimit = p->pOffset = 0; -+ p->pLimit = 0; - p->iLimit = p->iOffset = 0; - pOrderBy = p->pOrderBy; - -@@ -119558,6 +126288,7 @@ - - /* Store the results of the setup-query in Queue. */ - pSetup->pNext = 0; -+ ExplainQueryPlan((pParse, 1, "SETUP")); - rc = sqlite3Select(pParse, pSetup, &destQueue); - pSetup->pNext = p; - if( rc ) goto end_of_recursive_query; -@@ -119577,7 +126308,7 @@ - /* Output the single row in Current */ - addrCont = sqlite3VdbeMakeLabel(v); - codeOffset(v, regOffset, addrCont); -- selectInnerLoop(pParse, p, p->pEList, iCurrent, -+ selectInnerLoop(pParse, p, iCurrent, - 0, 0, pDest, addrCont, addrBreak); - if( regLimit ){ - sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak); -@@ -119592,6 +126323,7 @@ - sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported"); - }else{ - p->pPrior = 0; -+ ExplainQueryPlan((pParse, 1, "RECURSIVE STEP")); - sqlite3Select(pParse, p, &destQueue); - assert( p->pPrior==0 ); - p->pPrior = pSetup; -@@ -119605,7 +126337,6 @@ - sqlite3ExprListDelete(pParse->db, p->pOrderBy); - p->pOrderBy = pOrderBy; - p->pLimit = pLimit; -- p->pOffset = pOffset; - return; - } - #endif /* SQLITE_OMIT_CTE */ -@@ -119624,9 +126355,14 @@ - ** on a VALUES clause. - ** - ** Because the Select object originates from a VALUES clause: --** (1) It has no LIMIT or OFFSET -+** (1) There is no LIMIT or OFFSET or else there is a LIMIT of exactly 1 - ** (2) All terms are UNION ALL - ** (3) There is no ORDER BY clause -+** -+** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES -+** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))"). -+** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case. -+** Since the limit is exactly 1, we only need to evalutes the left-most VALUES. - */ - static int multiSelectValues( - Parse *pParse, /* Parsing context */ -@@ -119633,27 +126369,24 @@ - Select *p, /* The right-most of SELECTs to be coded */ - SelectDest *pDest /* What to do with query results */ - ){ -- Select *pPrior; - int nRow = 1; - int rc = 0; -+ int bShowAll = p->pLimit==0; - assert( p->selFlags & SF_MultiValue ); - do{ - assert( p->selFlags & SF_Values ); - assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) ); -- assert( p->pLimit==0 ); -- assert( p->pOffset==0 ); - assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr ); - if( p->pPrior==0 ) break; - assert( p->pPrior->pNext==p ); - p = p->pPrior; -- nRow++; -+ nRow += bShowAll; - }while(1); -+ ExplainQueryPlan((pParse, 0, "SCAN %d CONSTANT ROW%s", nRow, -+ nRow==1 ? "" : "S")); - while( p ){ -- pPrior = p->pPrior; -- p->pPrior = 0; -- rc = sqlite3Select(pParse, p, pDest); -- p->pPrior = pPrior; -- if( rc ) break; -+ selectInnerLoop(pParse, p, -1, 0, 0, pDest, 1, 1); -+ if( !bShowAll ) break; - p->nSelectRow = nRow; - p = p->pNext; - } -@@ -119702,10 +126435,6 @@ - SelectDest dest; /* Alternative data destination */ - Select *pDelete = 0; /* Chain of simple selects to delete */ - sqlite3 *db; /* Database connection */ --#ifndef SQLITE_OMIT_EXPLAIN -- int iSub1 = 0; /* EQP id of left-hand query */ -- int iSub2 = 0; /* EQP id of right-hand query */ --#endif - - /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only - ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT. -@@ -119715,18 +126444,12 @@ - db = pParse->db; - pPrior = p->pPrior; - dest = *pDest; -- if( pPrior->pOrderBy ){ -- sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before", -- selectOpName(p->op)); -+ if( pPrior->pOrderBy || pPrior->pLimit ){ -+ sqlite3ErrorMsg(pParse,"%s clause should come after %s not before", -+ pPrior->pOrderBy!=0 ? "ORDER BY" : "LIMIT", selectOpName(p->op)); - rc = 1; - goto multi_select_end; - } -- if( pPrior->pLimit ){ -- sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before", -- selectOpName(p->op)); -- rc = 1; -- goto multi_select_end; -- } - - v = sqlite3GetVdbe(pParse); - assert( v!=0 ); /* The VDBE already created by calling function */ -@@ -119762,226 +126485,231 @@ - */ - if( p->pOrderBy ){ - return multiSelectOrderBy(pParse, p, pDest); -- }else -+ }else{ - -- /* Generate code for the left and right SELECT statements. -- */ -- switch( p->op ){ -- case TK_ALL: { -- int addr = 0; -- int nLimit; -- assert( !pPrior->pLimit ); -- pPrior->iLimit = p->iLimit; -- pPrior->iOffset = p->iOffset; -- pPrior->pLimit = p->pLimit; -- pPrior->pOffset = p->pOffset; -- explainSetInteger(iSub1, pParse->iNextSelectId); -- rc = sqlite3Select(pParse, pPrior, &dest); -- p->pLimit = 0; -- p->pOffset = 0; -- if( rc ){ -- goto multi_select_end; -+#ifndef SQLITE_OMIT_EXPLAIN -+ if( pPrior->pPrior==0 ){ -+ ExplainQueryPlan((pParse, 1, "COMPOUND QUERY")); -+ ExplainQueryPlan((pParse, 1, "LEFT-MOST SUBQUERY")); -+ } -+#endif -+ -+ /* Generate code for the left and right SELECT statements. -+ */ -+ switch( p->op ){ -+ case TK_ALL: { -+ int addr = 0; -+ int nLimit; -+ assert( !pPrior->pLimit ); -+ pPrior->iLimit = p->iLimit; -+ pPrior->iOffset = p->iOffset; -+ pPrior->pLimit = p->pLimit; -+ rc = sqlite3Select(pParse, pPrior, &dest); -+ p->pLimit = 0; -+ if( rc ){ -+ goto multi_select_end; -+ } -+ p->pPrior = 0; -+ p->iLimit = pPrior->iLimit; -+ p->iOffset = pPrior->iOffset; -+ if( p->iLimit ){ -+ addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v); -+ VdbeComment((v, "Jump ahead if LIMIT reached")); -+ if( p->iOffset ){ -+ sqlite3VdbeAddOp3(v, OP_OffsetLimit, -+ p->iLimit, p->iOffset+1, p->iOffset); -+ } -+ } -+ ExplainQueryPlan((pParse, 1, "UNION ALL")); -+ rc = sqlite3Select(pParse, p, &dest); -+ testcase( rc!=SQLITE_OK ); -+ pDelete = p->pPrior; -+ p->pPrior = pPrior; -+ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); -+ if( pPrior->pLimit -+ && sqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit) -+ && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) -+ ){ -+ p->nSelectRow = sqlite3LogEst((u64)nLimit); -+ } -+ if( addr ){ -+ sqlite3VdbeJumpHere(v, addr); -+ } -+ break; - } -- p->pPrior = 0; -- p->iLimit = pPrior->iLimit; -- p->iOffset = pPrior->iOffset; -- if( p->iLimit ){ -- addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v); -- VdbeComment((v, "Jump ahead if LIMIT reached")); -- if( p->iOffset ){ -- sqlite3VdbeAddOp3(v, OP_OffsetLimit, -- p->iLimit, p->iOffset+1, p->iOffset); -+ case TK_EXCEPT: -+ case TK_UNION: { -+ int unionTab; /* Cursor number of the temp table holding result */ -+ u8 op = 0; /* One of the SRT_ operations to apply to self */ -+ int priorOp; /* The SRT_ operation to apply to prior selects */ -+ Expr *pLimit; /* Saved values of p->nLimit */ -+ int addr; -+ SelectDest uniondest; -+ -+ testcase( p->op==TK_EXCEPT ); -+ testcase( p->op==TK_UNION ); -+ priorOp = SRT_Union; -+ if( dest.eDest==priorOp ){ -+ /* We can reuse a temporary table generated by a SELECT to our -+ ** right. -+ */ -+ assert( p->pLimit==0 ); /* Not allowed on leftward elements */ -+ unionTab = dest.iSDParm; -+ }else{ -+ /* We will need to create our own temporary table to hold the -+ ** intermediate results. -+ */ -+ unionTab = pParse->nTab++; -+ assert( p->pOrderBy==0 ); -+ addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0); -+ assert( p->addrOpenEphm[0] == -1 ); -+ p->addrOpenEphm[0] = addr; -+ findRightmost(p)->selFlags |= SF_UsesEphemeral; -+ assert( p->pEList ); - } -+ -+ /* Code the SELECT statements to our left -+ */ -+ assert( !pPrior->pOrderBy ); -+ sqlite3SelectDestInit(&uniondest, priorOp, unionTab); -+ rc = sqlite3Select(pParse, pPrior, &uniondest); -+ if( rc ){ -+ goto multi_select_end; -+ } -+ -+ /* Code the current SELECT statement -+ */ -+ if( p->op==TK_EXCEPT ){ -+ op = SRT_Except; -+ }else{ -+ assert( p->op==TK_UNION ); -+ op = SRT_Union; -+ } -+ p->pPrior = 0; -+ pLimit = p->pLimit; -+ p->pLimit = 0; -+ uniondest.eDest = op; -+ ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", -+ selectOpName(p->op))); -+ rc = sqlite3Select(pParse, p, &uniondest); -+ testcase( rc!=SQLITE_OK ); -+ /* Query flattening in sqlite3Select() might refill p->pOrderBy. -+ ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */ -+ sqlite3ExprListDelete(db, p->pOrderBy); -+ pDelete = p->pPrior; -+ p->pPrior = pPrior; -+ p->pOrderBy = 0; -+ if( p->op==TK_UNION ){ -+ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); -+ } -+ sqlite3ExprDelete(db, p->pLimit); -+ p->pLimit = pLimit; -+ p->iLimit = 0; -+ p->iOffset = 0; -+ -+ /* Convert the data in the temporary table into whatever form -+ ** it is that we currently need. -+ */ -+ assert( unionTab==dest.iSDParm || dest.eDest!=priorOp ); -+ if( dest.eDest!=priorOp ){ -+ int iCont, iBreak, iStart; -+ assert( p->pEList ); -+ iBreak = sqlite3VdbeMakeLabel(v); -+ iCont = sqlite3VdbeMakeLabel(v); -+ computeLimitRegisters(pParse, p, iBreak); -+ sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v); -+ iStart = sqlite3VdbeCurrentAddr(v); -+ selectInnerLoop(pParse, p, unionTab, -+ 0, 0, &dest, iCont, iBreak); -+ sqlite3VdbeResolveLabel(v, iCont); -+ sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v); -+ sqlite3VdbeResolveLabel(v, iBreak); -+ sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0); -+ } -+ break; - } -- explainSetInteger(iSub2, pParse->iNextSelectId); -- rc = sqlite3Select(pParse, p, &dest); -- testcase( rc!=SQLITE_OK ); -- pDelete = p->pPrior; -- p->pPrior = pPrior; -- p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); -- if( pPrior->pLimit -- && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit) -- && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) -- ){ -- p->nSelectRow = sqlite3LogEst((u64)nLimit); -- } -- if( addr ){ -- sqlite3VdbeJumpHere(v, addr); -- } -- break; -- } -- case TK_EXCEPT: -- case TK_UNION: { -- int unionTab; /* Cursor number of the temporary table holding result */ -- u8 op = 0; /* One of the SRT_ operations to apply to self */ -- int priorOp; /* The SRT_ operation to apply to prior selects */ -- Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */ -- int addr; -- SelectDest uniondest; -- -- testcase( p->op==TK_EXCEPT ); -- testcase( p->op==TK_UNION ); -- priorOp = SRT_Union; -- if( dest.eDest==priorOp ){ -- /* We can reuse a temporary table generated by a SELECT to our -- ** right. -+ default: assert( p->op==TK_INTERSECT ); { -+ int tab1, tab2; -+ int iCont, iBreak, iStart; -+ Expr *pLimit; -+ int addr; -+ SelectDest intersectdest; -+ int r1; -+ -+ /* INTERSECT is different from the others since it requires -+ ** two temporary tables. Hence it has its own case. Begin -+ ** by allocating the tables we will need. - */ -- assert( p->pLimit==0 ); /* Not allowed on leftward elements */ -- assert( p->pOffset==0 ); /* Not allowed on leftward elements */ -- unionTab = dest.iSDParm; -- }else{ -- /* We will need to create our own temporary table to hold the -- ** intermediate results. -- */ -- unionTab = pParse->nTab++; -+ tab1 = pParse->nTab++; -+ tab2 = pParse->nTab++; - assert( p->pOrderBy==0 ); -- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0); -+ -+ addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0); - assert( p->addrOpenEphm[0] == -1 ); - p->addrOpenEphm[0] = addr; - findRightmost(p)->selFlags |= SF_UsesEphemeral; - assert( p->pEList ); -- } -- -- /* Code the SELECT statements to our left -- */ -- assert( !pPrior->pOrderBy ); -- sqlite3SelectDestInit(&uniondest, priorOp, unionTab); -- explainSetInteger(iSub1, pParse->iNextSelectId); -- rc = sqlite3Select(pParse, pPrior, &uniondest); -- if( rc ){ -- goto multi_select_end; -- } -- -- /* Code the current SELECT statement -- */ -- if( p->op==TK_EXCEPT ){ -- op = SRT_Except; -- }else{ -- assert( p->op==TK_UNION ); -- op = SRT_Union; -- } -- p->pPrior = 0; -- pLimit = p->pLimit; -- p->pLimit = 0; -- pOffset = p->pOffset; -- p->pOffset = 0; -- uniondest.eDest = op; -- explainSetInteger(iSub2, pParse->iNextSelectId); -- rc = sqlite3Select(pParse, p, &uniondest); -- testcase( rc!=SQLITE_OK ); -- /* Query flattening in sqlite3Select() might refill p->pOrderBy. -- ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */ -- sqlite3ExprListDelete(db, p->pOrderBy); -- pDelete = p->pPrior; -- p->pPrior = pPrior; -- p->pOrderBy = 0; -- if( p->op==TK_UNION ){ -- p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); -- } -- sqlite3ExprDelete(db, p->pLimit); -- p->pLimit = pLimit; -- p->pOffset = pOffset; -- p->iLimit = 0; -- p->iOffset = 0; -- -- /* Convert the data in the temporary table into whatever form -- ** it is that we currently need. -- */ -- assert( unionTab==dest.iSDParm || dest.eDest!=priorOp ); -- if( dest.eDest!=priorOp ){ -- int iCont, iBreak, iStart; -+ -+ /* Code the SELECTs to our left into temporary table "tab1". -+ */ -+ sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); -+ rc = sqlite3Select(pParse, pPrior, &intersectdest); -+ if( rc ){ -+ goto multi_select_end; -+ } -+ -+ /* Code the current SELECT into temporary table "tab2" -+ */ -+ addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0); -+ assert( p->addrOpenEphm[1] == -1 ); -+ p->addrOpenEphm[1] = addr; -+ p->pPrior = 0; -+ pLimit = p->pLimit; -+ p->pLimit = 0; -+ intersectdest.iSDParm = tab2; -+ ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", -+ selectOpName(p->op))); -+ rc = sqlite3Select(pParse, p, &intersectdest); -+ testcase( rc!=SQLITE_OK ); -+ pDelete = p->pPrior; -+ p->pPrior = pPrior; -+ if( p->nSelectRow>pPrior->nSelectRow ){ -+ p->nSelectRow = pPrior->nSelectRow; -+ } -+ sqlite3ExprDelete(db, p->pLimit); -+ p->pLimit = pLimit; -+ -+ /* Generate code to take the intersection of the two temporary -+ ** tables. -+ */ - assert( p->pEList ); - iBreak = sqlite3VdbeMakeLabel(v); - iCont = sqlite3VdbeMakeLabel(v); - computeLimitRegisters(pParse, p, iBreak); -- sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v); -- iStart = sqlite3VdbeCurrentAddr(v); -- selectInnerLoop(pParse, p, p->pEList, unionTab, -+ sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v); -+ r1 = sqlite3GetTempReg(pParse); -+ iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1); -+ sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); -+ VdbeCoverage(v); -+ sqlite3ReleaseTempReg(pParse, r1); -+ selectInnerLoop(pParse, p, tab1, - 0, 0, &dest, iCont, iBreak); - sqlite3VdbeResolveLabel(v, iCont); -- sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v); -+ sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v); - sqlite3VdbeResolveLabel(v, iBreak); -- sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0); -+ sqlite3VdbeAddOp2(v, OP_Close, tab2, 0); -+ sqlite3VdbeAddOp2(v, OP_Close, tab1, 0); -+ break; - } -- break; - } -- default: assert( p->op==TK_INTERSECT ); { -- int tab1, tab2; -- int iCont, iBreak, iStart; -- Expr *pLimit, *pOffset; -- int addr; -- SelectDest intersectdest; -- int r1; -- -- /* INTERSECT is different from the others since it requires -- ** two temporary tables. Hence it has its own case. Begin -- ** by allocating the tables we will need. -- */ -- tab1 = pParse->nTab++; -- tab2 = pParse->nTab++; -- assert( p->pOrderBy==0 ); -- -- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0); -- assert( p->addrOpenEphm[0] == -1 ); -- p->addrOpenEphm[0] = addr; -- findRightmost(p)->selFlags |= SF_UsesEphemeral; -- assert( p->pEList ); -- -- /* Code the SELECTs to our left into temporary table "tab1". -- */ -- sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); -- explainSetInteger(iSub1, pParse->iNextSelectId); -- rc = sqlite3Select(pParse, pPrior, &intersectdest); -- if( rc ){ -- goto multi_select_end; -- } -- -- /* Code the current SELECT into temporary table "tab2" -- */ -- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0); -- assert( p->addrOpenEphm[1] == -1 ); -- p->addrOpenEphm[1] = addr; -- p->pPrior = 0; -- pLimit = p->pLimit; -- p->pLimit = 0; -- pOffset = p->pOffset; -- p->pOffset = 0; -- intersectdest.iSDParm = tab2; -- explainSetInteger(iSub2, pParse->iNextSelectId); -- rc = sqlite3Select(pParse, p, &intersectdest); -- testcase( rc!=SQLITE_OK ); -- pDelete = p->pPrior; -- p->pPrior = pPrior; -- if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; -- sqlite3ExprDelete(db, p->pLimit); -- p->pLimit = pLimit; -- p->pOffset = pOffset; -- -- /* Generate code to take the intersection of the two temporary -- ** tables. -- */ -- assert( p->pEList ); -- iBreak = sqlite3VdbeMakeLabel(v); -- iCont = sqlite3VdbeMakeLabel(v); -- computeLimitRegisters(pParse, p, iBreak); -- sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v); -- r1 = sqlite3GetTempReg(pParse); -- iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1); -- sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v); -- sqlite3ReleaseTempReg(pParse, r1); -- selectInnerLoop(pParse, p, p->pEList, tab1, -- 0, 0, &dest, iCont, iBreak); -- sqlite3VdbeResolveLabel(v, iCont); -- sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v); -- sqlite3VdbeResolveLabel(v, iBreak); -- sqlite3VdbeAddOp2(v, OP_Close, tab2, 0); -- sqlite3VdbeAddOp2(v, OP_Close, tab1, 0); -- break; -+ -+ #ifndef SQLITE_OMIT_EXPLAIN -+ if( p->pNext==0 ){ -+ ExplainQueryPlanPop(pParse); - } -+ #endif - } -- -- explainComposite(pParse, p->op, iSub1, iSub2, p->op!=TK_ALL); -- -+ - /* Compute collating sequences used by - ** temporary tables needed to implement the compound select. - ** Attach the KeyInfo structure to all temporary tables. -@@ -120132,7 +126860,6 @@ - r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, - r1, pDest->zAffSdst, pIn->nSdst); -- sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst); - sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, - pIn->iSdst, pIn->nSdst); - sqlite3ReleaseTempReg(pParse, r1); -@@ -120175,7 +126902,6 @@ - default: { - assert( pDest->eDest==SRT_Output ); - sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst); -- sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst); - break; - } - } -@@ -120319,10 +127045,6 @@ - ExprList *pOrderBy; /* The ORDER BY clause */ - int nOrderBy; /* Number of terms in the ORDER BY clause */ - int *aPermute; /* Mapping from ORDER BY terms to result set columns */ --#ifndef SQLITE_OMIT_EXPLAIN -- int iSub1; /* EQP id of left-hand query */ -- int iSub2; /* EQP id of right-hand query */ --#endif - - assert( p->pOrderBy!=0 ); - assert( pKeyDup==0 ); /* "Managed" code needs this. Ticket #3382. */ -@@ -120434,8 +127156,6 @@ - } - sqlite3ExprDelete(db, p->pLimit); - p->pLimit = 0; -- sqlite3ExprDelete(db, p->pOffset); -- p->pOffset = 0; - - regAddrA = ++pParse->nMem; - regAddrB = ++pParse->nMem; -@@ -120444,6 +127164,8 @@ - sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA); - sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB); - -+ ExplainQueryPlan((pParse, 1, "MERGE (%s)", selectOpName(p->op))); -+ - /* Generate a coroutine to evaluate the SELECT statement to the - ** left of the compound operator - the "A" select. - */ -@@ -120451,7 +127173,7 @@ - addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA); - VdbeComment((v, "left SELECT")); - pPrior->iLimit = regLimitA; -- explainSetInteger(iSub1, pParse->iNextSelectId); -+ ExplainQueryPlan((pParse, 1, "LEFT")); - sqlite3Select(pParse, pPrior, &destA); - sqlite3VdbeEndCoroutine(v, regAddrA); - sqlite3VdbeJumpHere(v, addr1); -@@ -120466,7 +127188,7 @@ - savedOffset = p->iOffset; - p->iLimit = regLimitB; - p->iOffset = 0; -- explainSetInteger(iSub2, pParse->iNextSelectId); -+ ExplainQueryPlan((pParse, 1, "RIGHT")); - sqlite3Select(pParse, p, &destB); - p->iLimit = savedLimit; - p->iOffset = savedOffset; -@@ -120578,7 +127300,7 @@ - - /*** TBD: Insert subroutine calls to close cursors on incomplete - **** subqueries ****/ -- explainComposite(pParse, p->op, iSub1, iSub2, 0); -+ ExplainQueryPlanPop(pParse); - return pParse->nErr!=0; - } - #endif -@@ -120621,7 +127343,9 @@ - Expr *pExpr /* Expr in which substitution occurs */ - ){ - if( pExpr==0 ) return 0; -- if( ExprHasProperty(pExpr, EP_FromJoin) && pExpr->iRightJoinTable==pSubst->iTable ){ -+ if( ExprHasProperty(pExpr, EP_FromJoin) -+ && pExpr->iRightJoinTable==pSubst->iTable -+ ){ - pExpr->iRightJoinTable = pSubst->iNewTable; - } - if( pExpr->op==TK_COLUMN && pExpr->iTable==pSubst->iTable ){ -@@ -120632,7 +127356,7 @@ - Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr; - Expr ifNullRow; - assert( pSubst->pEList!=0 && pExpr->iColumn<pSubst->pEList->nExpr ); -- assert( pExpr->pLeft==0 && pExpr->pRight==0 ); -+ assert( pExpr->pRight==0 ); - if( sqlite3ExprIsVector(pCopy) ){ - sqlite3VectorErrorMsg(pSubst->pParse, pCopy); - }else{ -@@ -120734,69 +127458,75 @@ - ** exist on the table t1, a complete scan of the data might be - ** avoided. - ** --** Flattening is only attempted if all of the following are true: -+** Flattening is subject to the following constraints: - ** --** (1) The subquery and the outer query do not both use aggregates. -+** (**) We no longer attempt to flatten aggregate subqueries. Was: -+** The subquery and the outer query cannot both be aggregates. - ** --** (2) The subquery is not an aggregate or (2a) the outer query is not a join --** and (2b) the outer query does not use subqueries other than the one --** FROM-clause subquery that is a candidate for flattening. (2b is --** due to ticket [2f7170d73bf9abf80] from 2015-02-09.) -+** (**) We no longer attempt to flatten aggregate subqueries. Was: -+** (2) If the subquery is an aggregate then -+** (2a) the outer query must not be a join and -+** (2b) the outer query must not use subqueries -+** other than the one FROM-clause subquery that is a candidate -+** for flattening. (This is due to ticket [2f7170d73bf9abf80] -+** from 2015-02-09.) - ** --** (3) The subquery is not the right operand of a LEFT JOIN --** or (a) the subquery is not itself a join and (b) the FROM clause --** of the subquery does not contain a virtual table and (c) the --** outer query is not an aggregate. -+** (3) If the subquery is the right operand of a LEFT JOIN then -+** (3a) the subquery may not be a join and -+** (3b) the FROM clause of the subquery may not contain a virtual -+** table and -+** (3c) the outer query may not be an aggregate. - ** --** (4) The subquery is not DISTINCT. -+** (4) The subquery can not be DISTINCT. - ** - ** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT - ** sub-queries that were excluded from this optimization. Restriction - ** (4) has since been expanded to exclude all DISTINCT subqueries. - ** --** (6) The subquery does not use aggregates or the outer query is not --** DISTINCT. -+** (**) We no longer attempt to flatten aggregate subqueries. Was: -+** If the subquery is aggregate, the outer query may not be DISTINCT. - ** --** (7) The subquery has a FROM clause. TODO: For subqueries without -+** (7) The subquery must have a FROM clause. TODO: For subqueries without - ** A FROM clause, consider adding a FROM clause with the special - ** table sqlite_once that consists of a single row containing a - ** single NULL. - ** --** (8) The subquery does not use LIMIT or the outer query is not a join. -+** (8) If the subquery uses LIMIT then the outer query may not be a join. - ** --** (9) The subquery does not use LIMIT or the outer query does not use --** aggregates. -+** (9) If the subquery uses LIMIT then the outer query may not be aggregate. - ** - ** (**) Restriction (10) was removed from the code on 2005-02-05 but we - ** accidently carried the comment forward until 2014-09-15. Original --** text: "The subquery does not use aggregates or the outer query --** does not use LIMIT." -+** constraint: "If the subquery is aggregate then the outer query -+** may not use LIMIT." - ** --** (11) The subquery and the outer query do not both have ORDER BY clauses. -+** (11) The subquery and the outer query may not both have ORDER BY clauses. - ** - ** (**) Not implemented. Subsumed into restriction (3). Was previously - ** a separate restriction deriving from ticket #350. - ** --** (13) The subquery and outer query do not both use LIMIT. -+** (13) The subquery and outer query may not both use LIMIT. - ** --** (14) The subquery does not use OFFSET. -+** (14) The subquery may not use OFFSET. - ** --** (15) The outer query is not part of a compound select or the --** subquery does not have a LIMIT clause. -+** (15) If the outer query is part of a compound select, then the -+** subquery may not use LIMIT. - ** (See ticket #2339 and ticket [02a8e81d44]). - ** --** (16) The outer query is not an aggregate or the subquery does --** not contain ORDER BY. (Ticket #2942) This used to not matter -+** (16) If the outer query is aggregate, then the subquery may not -+** use ORDER BY. (Ticket #2942) This used to not matter - ** until we introduced the group_concat() function. - ** --** (17) The sub-query is not a compound select, or it is a UNION ALL --** compound clause made up entirely of non-aggregate queries, and --** the parent query: -+** (17) If the subquery is a compound select, then -+** (17a) all compound operators must be a UNION ALL, and -+** (17b) no terms within the subquery compound may be aggregate -+** or DISTINCT, and -+** (17c) every term within the subquery compound must have a FROM clause -+** (17d) the outer query may not be -+** (17d1) aggregate, or -+** (17d2) DISTINCT, or -+** (17d3) a join. - ** --** * is not itself part of a compound select, --** * is not an aggregate or DISTINCT query, and --** * is not a join --** - ** The parent and sub-query may contain WHERE clauses. Subject to - ** rules (11), (13) and (14), they may also contain ORDER BY, - ** LIMIT and OFFSET clauses. The subquery cannot use any compound -@@ -120811,10 +127541,10 @@ - ** syntax error and return a detailed message. - ** - ** (18) If the sub-query is a compound select, then all terms of the --** ORDER by clause of the parent must be simple references to -+** ORDER BY clause of the parent must be simple references to - ** columns of the sub-query. - ** --** (19) The subquery does not use LIMIT or the outer query does not -+** (19) If the subquery uses LIMIT then the outer query may not - ** have a WHERE clause. - ** - ** (20) If the sub-query is a compound select, then it must not use -@@ -120823,25 +127553,31 @@ - ** appear as unmodified result columns in the outer query. But we - ** have other optimizations in mind to deal with that case. - ** --** (21) The subquery does not use LIMIT or the outer query is not -+** (21) If the subquery uses LIMIT then the outer query may not be - ** DISTINCT. (See ticket [752e1646fc]). - ** --** (22) The subquery is not a recursive CTE. -+** (22) The subquery may not be a recursive CTE. - ** --** (23) The parent is not a recursive CTE, or the sub-query is not a --** compound query. This restriction is because transforming the -+** (**) Subsumed into restriction (17d3). Was: If the outer query is -+** a recursive CTE, then the sub-query may not be a compound query. -+** This restriction is because transforming the - ** parent to a compound query confuses the code that handles - ** recursive queries in multiSelect(). - ** --** (24) The subquery is not an aggregate that uses the built-in min() or -+** (**) We no longer attempt to flatten aggregate subqueries. Was: -+** The subquery may not be an aggregate that uses the built-in min() or - ** or max() functions. (Without this restriction, a query like: - ** "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily - ** return the value X for which Y was maximal.) - ** -+** (25) If either the subquery or the parent query contains a window -+** function in the select list or ORDER BY clause, flattening -+** is not attempted. - ** -+** - ** In this routine, the "p" parameter is a pointer to the outer query. - ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query --** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates. -+** uses aggregates. - ** - ** If flattening is not attempted, this routine is a no-op and returns 0. - ** If flattening is attempted this routine returns 1. -@@ -120853,8 +127589,7 @@ - Parse *pParse, /* Parsing context */ - Select *p, /* The parent or outer SELECT statement */ - int iFrom, /* Index in p->pSrc->a[] of the inner subquery */ -- int isAgg, /* True if outer SELECT uses aggregate functions */ -- int subqueryIsAgg /* True if the subquery uses aggregate functions */ -+ int isAgg /* True if outer SELECT uses aggregate functions */ - ){ - const char *zSavedAuthContext = pParse->zAuthContext; - Select *pParent; /* Current UNION ALL term of the other query */ -@@ -120873,7 +127608,7 @@ - /* Check to see if flattening is permitted. Return 0 if not. - */ - assert( p!=0 ); -- assert( p->pPrior==0 ); /* Unable to flatten compound queries */ -+ assert( p->pPrior==0 ); - if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0; - pSrc = p->pSrc; - assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc ); -@@ -120881,17 +127616,11 @@ - iParent = pSubitem->iCursor; - pSub = pSubitem->pSelect; - assert( pSub!=0 ); -- if( subqueryIsAgg ){ -- if( isAgg ) return 0; /* Restriction (1) */ -- if( pSrc->nSrc>1 ) return 0; /* Restriction (2a) */ -- if( (p->pWhere && ExprHasProperty(p->pWhere,EP_Subquery)) -- || (sqlite3ExprListFlags(p->pEList) & EP_Subquery)!=0 -- || (sqlite3ExprListFlags(p->pOrderBy) & EP_Subquery)!=0 -- ){ -- return 0; /* Restriction (2b) */ -- } -- } - -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( p->pWin || pSub->pWin ) return 0; /* Restriction (25) */ -+#endif -+ - pSubSrc = pSub->pSrc; - assert( pSubSrc ); - /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants, -@@ -120900,18 +127629,15 @@ - ** became arbitrary expressions, we were forced to add restrictions (13) - ** and (14). */ - if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */ -- if( pSub->pOffset ) return 0; /* Restriction (14) */ -+ if( pSub->pLimit && pSub->pLimit->pRight ) return 0; /* Restriction (14) */ - if( (p->selFlags & SF_Compound)!=0 && pSub->pLimit ){ - return 0; /* Restriction (15) */ - } - if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */ -- if( pSub->selFlags & SF_Distinct ) return 0; /* Restriction (5) */ -+ if( pSub->selFlags & SF_Distinct ) return 0; /* Restriction (4) */ - if( pSub->pLimit && (pSrc->nSrc>1 || isAgg) ){ - return 0; /* Restrictions (8)(9) */ - } -- if( (p->selFlags & SF_Distinct)!=0 && subqueryIsAgg ){ -- return 0; /* Restriction (6) */ -- } - if( p->pOrderBy && pSub->pOrderBy ){ - return 0; /* Restriction (11) */ - } -@@ -120920,18 +127646,14 @@ - if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){ - return 0; /* Restriction (21) */ - } -- testcase( pSub->selFlags & SF_Recursive ); -- testcase( pSub->selFlags & SF_MinMaxAgg ); -- if( pSub->selFlags & (SF_Recursive|SF_MinMaxAgg) ){ -- return 0; /* Restrictions (22) and (24) */ -+ if( pSub->selFlags & (SF_Recursive) ){ -+ return 0; /* Restrictions (22) */ - } -- if( (p->selFlags & SF_Recursive) && pSub->pPrior ){ -- return 0; /* Restriction (23) */ -- } - - /* - ** If the subquery is the right operand of a LEFT JOIN, then the -- ** subquery may not be a join itself. Example of why this is not allowed: -+ ** subquery may not be a join itself (3a). Example of why this is not -+ ** allowed: - ** - ** t1 LEFT OUTER JOIN (t2 JOIN t3) - ** -@@ -120942,9 +127664,9 @@ - ** which is not at all the same thing. - ** - ** If the subquery is the right operand of a LEFT JOIN, then the outer -- ** query cannot be an aggregate. This is an artifact of the way aggregates -- ** are processed - there is no mechanism to determine if the LEFT JOIN -- ** table should be all-NULL. -+ ** query cannot be an aggregate. (3c) This is an artifact of the way -+ ** aggregates are processed - there is no mechanism to determine if -+ ** the LEFT JOIN table should be all-NULL. - ** - ** See also tickets #306, #350, and #3300. - */ -@@ -120951,19 +127673,21 @@ - if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){ - isLeftJoin = 1; - if( pSubSrc->nSrc>1 || isAgg || IsVirtual(pSubSrc->a[0].pTab) ){ -- return 0; /* Restriction (3) */ -+ /* (3a) (3c) (3b) */ -+ return 0; - } - } - #ifdef SQLITE_EXTRA_IFNULLROW - else if( iFrom>0 && !isAgg ){ - /* Setting isLeftJoin to -1 causes OP_IfNullRow opcodes to be generated for -- ** every reference to any result column from subquery in a join, even though -- ** they are not necessary. This will stress-test the OP_IfNullRow opcode. */ -+ ** every reference to any result column from subquery in a join, even -+ ** though they are not necessary. This will stress-test the OP_IfNullRow -+ ** opcode. */ - isLeftJoin = -1; - } - #endif - -- /* Restriction 17: If the sub-query is a compound SELECT, then it must -+ /* Restriction (17): If the sub-query is a compound SELECT, then it must - ** use only the UNION ALL operator. And none of the simple select queries - ** that make up the compound SELECT are allowed to be aggregate or distinct - ** queries. -@@ -120970,10 +127694,10 @@ - */ - if( pSub->pPrior ){ - if( pSub->pOrderBy ){ -- return 0; /* Restriction 20 */ -+ return 0; /* Restriction (20) */ - } - if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){ -- return 0; -+ return 0; /* (17d1), (17d2), or (17d3) */ - } - for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){ - testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); -@@ -120980,9 +127704,9 @@ - testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); - assert( pSub->pSrc!=0 ); - assert( pSub->pEList->nExpr==pSub1->pEList->nExpr ); -- if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 -- || (pSub1->pPrior && pSub1->op!=TK_ALL) -- || pSub1->pSrc->nSrc<1 -+ if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 /* (17b) */ -+ || (pSub1->pPrior && pSub1->op!=TK_ALL) /* (17a) */ -+ || pSub1->pSrc->nSrc<1 /* (17c) */ - ){ - return 0; - } -@@ -120989,7 +127713,7 @@ - testcase( pSub1->pSrc->nSrc>1 ); - } - -- /* Restriction 18. */ -+ /* Restriction (18). */ - if( p->pOrderBy ){ - int ii; - for(ii=0; ii<p->pOrderBy->nExpr; ii++){ -@@ -120998,9 +127722,17 @@ - } - } - -+ /* Ex-restriction (23): -+ ** The only way that the recursive part of a CTE can contain a compound -+ ** subquery is for the subquery to be one term of a join. But if the -+ ** subquery is a join, then the flattening has already been stopped by -+ ** restriction (17d3) -+ */ -+ assert( (p->selFlags & SF_Recursive)==0 || pSub->pPrior==0 ); -+ - /***** If we reach this point, flattening is permitted. *****/ -- SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n", -- pSub->zSelName, pSub, iFrom)); -+ SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n", -+ pSub->selId, pSub, iFrom)); - - /* Authorize the subquery */ - pParse->zAuthContext = pSubitem->zName; -@@ -121045,16 +127777,12 @@ - Select *pNew; - ExprList *pOrderBy = p->pOrderBy; - Expr *pLimit = p->pLimit; -- Expr *pOffset = p->pOffset; - Select *pPrior = p->pPrior; - p->pOrderBy = 0; - p->pSrc = 0; - p->pPrior = 0; - p->pLimit = 0; -- p->pOffset = 0; - pNew = sqlite3SelectDup(db, p, 0); -- sqlite3SelectSetName(pNew, pSub->zSelName); -- p->pOffset = pOffset; - p->pLimit = pLimit; - p->pOrderBy = pOrderBy; - p->pSrc = pSrc; -@@ -121066,9 +127794,8 @@ - if( pPrior ) pPrior->pNext = pNew; - pNew->pNext = p; - p->pPrior = pNew; -- SELECTTRACE(2,pParse,p, -- ("compound-subquery flattener creates %s.%p as peer\n", -- pNew->zSelName, pNew)); -+ SELECTTRACE(2,pParse,p,("compound-subquery flattener" -+ " creates %u as peer\n",pNew->selId)); - } - if( db->mallocFailed ) return 1; - } -@@ -121202,7 +127929,6 @@ - pOrderBy->a[i].u.x.iOrderByCol = 0; - } - assert( pParent->pOrderBy==0 ); -- assert( pSub->pPrior==0 ); - pParent->pOrderBy = pOrderBy; - pSub->pOrderBy = 0; - } -@@ -121210,18 +127936,7 @@ - if( isLeftJoin>0 ){ - setJoinExpr(pWhere, iNewParent); - } -- if( subqueryIsAgg ){ -- assert( pParent->pHaving==0 ); -- pParent->pHaving = pParent->pWhere; -- pParent->pWhere = pWhere; -- pParent->pHaving = sqlite3ExprAnd(db, -- sqlite3ExprDup(db, pSub->pHaving, 0), pParent->pHaving -- ); -- assert( pParent->pGroupBy==0 ); -- pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0); -- }else{ -- pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere); -- } -+ pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere); - if( db->mallocFailed==0 ){ - SubstContext x; - x.pParse = pParse; -@@ -121265,8 +127980,184 @@ - } - #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ - -+/* -+** A structure to keep track of all of the column values that are fixed to -+** a known value due to WHERE clause constraints of the form COLUMN=VALUE. -+*/ -+typedef struct WhereConst WhereConst; -+struct WhereConst { -+ Parse *pParse; /* Parsing context */ -+ int nConst; /* Number for COLUMN=CONSTANT terms */ -+ int nChng; /* Number of times a constant is propagated */ -+ Expr **apExpr; /* [i*2] is COLUMN and [i*2+1] is VALUE */ -+}; - -+/* -+** Add a new entry to the pConst object. Except, do not add duplicate -+** pColumn entires. -+*/ -+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 */ -+){ -+ int i; -+ assert( pColumn->op==TK_COLUMN ); - -+ /* 2018-10-25 ticket [cf5ed20f] -+ ** Make sure the same pColumn is not inserted more than once */ -+ for(i=0; i<pConst->nConst; i++){ -+ const Expr *pExpr = pConst->apExpr[i*2]; -+ assert( pExpr->op==TK_COLUMN ); -+ if( pExpr->iTable==pColumn->iTable -+ && pExpr->iColumn==pColumn->iColumn -+ ){ -+ return; /* Already present. Return without doing anything. */ -+ } -+ } -+ -+ pConst->nConst++; -+ pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr, -+ pConst->nConst*2*sizeof(Expr*)); -+ if( pConst->apExpr==0 ){ -+ pConst->nConst = 0; -+ }else{ -+ if( ExprHasProperty(pValue, EP_FixedCol) ) pValue = pValue->pLeft; -+ pConst->apExpr[pConst->nConst*2-2] = pColumn; -+ pConst->apExpr[pConst->nConst*2-1] = pValue; -+ } -+} -+ -+/* -+** Find all terms of COLUMN=VALUE or VALUE=COLUMN in pExpr where VALUE -+** is a constant expression and where the term must be true because it -+** is part of the AND-connected terms of the expression. For each term -+** found, add it to the pConst structure. -+*/ -+static void findConstInWhere(WhereConst *pConst, Expr *pExpr){ -+ Expr *pRight, *pLeft; -+ if( pExpr==0 ) return; -+ if( ExprHasProperty(pExpr, EP_FromJoin) ) return; -+ if( pExpr->op==TK_AND ){ -+ findConstInWhere(pConst, pExpr->pRight); -+ findConstInWhere(pConst, pExpr->pLeft); -+ return; -+ } -+ if( pExpr->op!=TK_EQ ) return; -+ pRight = pExpr->pRight; -+ 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); -+ } -+} -+ -+/* -+** This is a Walker expression callback. pExpr is a candidate expression -+** to be replaced by a value. If pExpr is equivalent to one of the -+** columns named in pWalker->u.pConst, then overwrite it with its -+** corresponding value. -+*/ -+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; -+ pConst = pWalker->u.pConst; -+ for(i=0; i<pConst->nConst; i++){ -+ Expr *pColumn = pConst->apExpr[i*2]; -+ if( pColumn==pExpr ) continue; -+ if( pColumn->iTable!=pExpr->iTable ) continue; -+ if( pColumn->iColumn!=pExpr->iColumn ) continue; -+ /* A match is found. Add the EP_FixedCol property */ -+ pConst->nChng++; -+ ExprClearProperty(pExpr, EP_Leaf); -+ ExprSetProperty(pExpr, EP_FixedCol); -+ assert( pExpr->pLeft==0 ); -+ pExpr->pLeft = sqlite3ExprDup(pConst->pParse->db, pConst->apExpr[i*2+1], 0); -+ break; -+ } -+ return WRC_Prune; -+} -+ -+/* -+** 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. -+** -+** For example, the query: -+** -+** SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=t1.a AND t3.c=t2.b -+** -+** Is transformed into -+** -+** SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=39 AND t3.c=39 -+** -+** Return true if any transformations where made and false if not. -+** -+** Implementation note: Constant propagation is tricky due to affinity -+** and collating sequence interactions. Consider this example: -+** -+** CREATE TABLE t1(a INT,b TEXT); -+** INSERT INTO t1 VALUES(123,'0123'); -+** SELECT * FROM t1 WHERE a=123 AND b=a; -+** SELECT * FROM t1 WHERE a=123 AND b=123; -+** -+** The two SELECT statements above should return different answers. b=a -+** is alway true because the comparison uses numeric affinity, but b=123 -+** is false because it uses text affinity and '0123' is not the same as '123'. -+** To work around this, the expression tree is not actually changed from -+** "b=a" to "b=123" but rather the "a" in "b=a" is tagged with EP_FixedCol -+** and the "123" value is hung off of the pLeft pointer. Code generator -+** routines know to generate the constant "123" instead of looking up the -+** column value. Also, to avoid collation problems, this optimization is -+** only attempted if the "a=123" term uses the default BINARY collation. -+*/ -+static int propagateConstants( -+ Parse *pParse, /* The parsing context */ -+ Select *p /* The query in which to propagate constants */ -+){ -+ WhereConst x; -+ Walker w; -+ int nChng = 0; -+ x.pParse = pParse; -+ do{ -+ x.nConst = 0; -+ x.nChng = 0; -+ x.apExpr = 0; -+ findConstInWhere(&x, p->pWhere); -+ if( x.nConst ){ -+ memset(&w, 0, sizeof(w)); -+ w.pParse = pParse; -+ w.xExprCallback = propagateConstantExprRewrite; -+ w.xSelectCallback = sqlite3SelectWalkNoop; -+ w.xSelectCallback2 = 0; -+ w.walkerDepth = 0; -+ w.u.pConst = &x; -+ sqlite3WalkExpr(&w, p->pWhere); -+ sqlite3DbFree(x.pParse->db, x.apExpr); -+ nChng += x.nChng; -+ } -+ }while( x.nChng ); -+ return nChng; -+} -+ - #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) - /* - ** Make copies of relevant WHERE clause terms of the outer query into -@@ -121284,22 +128175,40 @@ - ** - ** Do not attempt this optimization if: - ** --** (1) The inner query is an aggregate. (In that case, we'd really want --** to copy the outer WHERE-clause terms onto the HAVING clause of the --** inner query. But they probably won't help there so do not bother.) -+** (1) (** This restriction was removed on 2017-09-29. We used to -+** disallow this optimization for aggregate subqueries, but now -+** it is allowed by putting the extra terms on the HAVING clause. -+** The added HAVING clause is pointless if the subquery lacks -+** a GROUP BY clause. But such a HAVING clause is also harmless -+** so there does not appear to be any reason to add extra logic -+** to suppress it. **) - ** - ** (2) The inner query is the recursive part of a common table expression. - ** - ** (3) The inner query has a LIMIT clause (since the changes to the WHERE --** close would change the meaning of the LIMIT). -+** clause would change the meaning of the LIMIT). - ** --** (4) The inner query is the right operand of a LEFT JOIN. (The caller --** enforces this restriction since this routine does not have enough --** information to know.) -+** (4) The inner query is the right operand of a LEFT JOIN and the -+** expression to be pushed down does not come from the ON clause -+** on that LEFT JOIN. - ** - ** (5) The WHERE clause expression originates in the ON or USING clause --** of a LEFT JOIN. -+** of a LEFT JOIN where iCursor is not the right-hand table of that -+** left join. An example: - ** -+** SELECT * -+** FROM (SELECT 1 AS a1 UNION ALL SELECT 2) AS aa -+** JOIN (SELECT 1 AS b2 UNION ALL SELECT 2) AS bb ON (a1=b2) -+** LEFT JOIN (SELECT 8 AS c3 UNION ALL SELECT 9) AS cc ON (b2=2); -+** -+** The correct answer is three rows: (1,1,NULL),(2,2,8),(2,2,9). -+** But if the (b2=2) term were to be pushed down into the bb subquery, -+** then the (1,1,NULL) row would be suppressed. -+** -+** (6) The inner query features one or more window-functions (since -+** changes to the WHERE clause of the inner query could change the -+** window over which window functions are calculated). -+** - ** Return 0 if no changes are made and non-zero if one or more WHERE clause - ** terms are duplicated into the subquery. - */ -@@ -121307,33 +128216,54 @@ - Parse *pParse, /* Parse context (for malloc() and error reporting) */ - Select *pSubq, /* The subquery whose WHERE clause is to be augmented */ - Expr *pWhere, /* The WHERE clause of the outer query */ -- int iCursor /* Cursor number of the subquery */ -+ int iCursor, /* Cursor number of the subquery */ -+ int isLeftJoin /* True if pSubq is the right term of a LEFT JOIN */ - ){ - Expr *pNew; - int nChng = 0; -- Select *pX; /* For looping over compound SELECTs in pSubq */ - if( pWhere==0 ) return 0; -- for(pX=pSubq; pX; pX=pX->pPrior){ -- if( (pX->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){ -- testcase( pX->selFlags & SF_Aggregate ); -- testcase( pX->selFlags & SF_Recursive ); -- testcase( pX!=pSubq ); -- return 0; /* restrictions (1) and (2) */ -+ if( pSubq->selFlags & SF_Recursive ) return 0; /* restriction (2) */ -+ -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( pSubq->pWin ) return 0; /* restriction (6) */ -+#endif -+ -+#ifdef SQLITE_DEBUG -+ /* Only the first term of a compound can have a WITH clause. But make -+ ** sure no other terms are marked SF_Recursive in case something changes -+ ** in the future. -+ */ -+ { -+ Select *pX; -+ for(pX=pSubq; pX; pX=pX->pPrior){ -+ assert( (pX->selFlags & (SF_Recursive))==0 ); - } - } -+#endif -+ - if( pSubq->pLimit!=0 ){ - return 0; /* restriction (3) */ - } - while( pWhere->op==TK_AND ){ -- nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, iCursor); -+ nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, -+ iCursor, isLeftJoin); - pWhere = pWhere->pLeft; - } -- if( ExprHasProperty(pWhere,EP_FromJoin) ) return 0; /* restriction 5 */ -+ if( isLeftJoin -+ && (ExprHasProperty(pWhere,EP_FromJoin)==0 -+ || pWhere->iRightJoinTable!=iCursor) -+ ){ -+ return 0; /* restriction (4) */ -+ } -+ if( ExprHasProperty(pWhere,EP_FromJoin) && pWhere->iRightJoinTable!=iCursor ){ -+ return 0; /* restriction (5) */ -+ } - if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){ - nChng++; - while( pSubq ){ - SubstContext x; - pNew = sqlite3ExprDup(pParse->db, pWhere, 0); -+ unsetJoinExpr(pNew, -1); - x.pParse = pParse; - x.iTable = iCursor; - x.iNewTable = iCursor; -@@ -121340,7 +128270,11 @@ - x.isLeftJoin = 0; - x.pEList = pSubq->pEList; - pNew = substExpr(&x, pNew); -- pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew); -+ if( pSubq->selFlags & SF_Aggregate ){ -+ pSubq->pHaving = sqlite3ExprAnd(pParse->db, pSubq->pHaving, pNew); -+ }else{ -+ pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew); -+ } - pSubq = pSubq->pPrior; - } - } -@@ -121349,42 +128283,44 @@ - #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ - - /* --** Based on the contents of the AggInfo structure indicated by the first --** argument, this function checks if the following are true: -+** The pFunc is the only aggregate function in the query. Check to see -+** if the query is a candidate for the min/max optimization. - ** --** * the query contains just a single aggregate function, --** * the aggregate function is either min() or max(), and --** * the argument to the aggregate function is a column value. -+** If the query is a candidate for the min/max optimization, then set -+** *ppMinMax to be an ORDER BY clause to be used for the optimization -+** and return either WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX depending on -+** whether pFunc is a min() or max() function. - ** --** If all of the above are true, then WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX --** is returned as appropriate. Also, *ppMinMax is set to point to the --** list of arguments passed to the aggregate before returning. -+** If the query is not a candidate for the min/max optimization, return -+** WHERE_ORDERBY_NORMAL (which must be zero). - ** --** Or, if the conditions above are not met, *ppMinMax is set to 0 and --** WHERE_ORDERBY_NORMAL is returned. -+** This routine must be called after aggregate functions have been -+** located but before their arguments have been subjected to aggregate -+** analysis. - */ --static u8 minMaxQuery(AggInfo *pAggInfo, ExprList **ppMinMax){ -- int eRet = WHERE_ORDERBY_NORMAL; /* Return value */ -+static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ -+ int eRet = WHERE_ORDERBY_NORMAL; /* Return value */ -+ ExprList *pEList = pFunc->x.pList; /* Arguments to agg function */ -+ const char *zFunc; /* Name of aggregate function pFunc */ -+ ExprList *pOrderBy; -+ u8 sortOrder; - -- *ppMinMax = 0; -- if( pAggInfo->nFunc==1 ){ -- Expr *pExpr = pAggInfo->aFunc[0].pExpr; /* Aggregate function */ -- ExprList *pEList = pExpr->x.pList; /* Arguments to agg function */ -- -- assert( pExpr->op==TK_AGG_FUNCTION ); -- if( pEList && pEList->nExpr==1 && pEList->a[0].pExpr->op==TK_AGG_COLUMN ){ -- const char *zFunc = pExpr->u.zToken; -- if( sqlite3StrICmp(zFunc, "min")==0 ){ -- eRet = WHERE_ORDERBY_MIN; -- *ppMinMax = pEList; -- }else if( sqlite3StrICmp(zFunc, "max")==0 ){ -- eRet = WHERE_ORDERBY_MAX; -- *ppMinMax = pEList; -- } -- } -+ assert( *ppMinMax==0 ); -+ assert( pFunc->op==TK_AGG_FUNCTION ); -+ if( pEList==0 || pEList->nExpr!=1 ) return eRet; -+ zFunc = pFunc->u.zToken; -+ if( sqlite3StrICmp(zFunc, "min")==0 ){ -+ eRet = WHERE_ORDERBY_MIN; -+ sortOrder = SQLITE_SO_ASC; -+ }else if( sqlite3StrICmp(zFunc, "max")==0 ){ -+ eRet = WHERE_ORDERBY_MAX; -+ sortOrder = SQLITE_SO_DESC; -+ }else{ -+ return eRet; - } -- -- assert( *ppMinMax==0 || (*ppMinMax)->nExpr==1 ); -+ *ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0); -+ assert( pOrderBy!=0 || db->mallocFailed ); -+ if( pOrderBy ) pOrderBy->a[0].sortOrder = sortOrder; - return eRet; - } - -@@ -121515,7 +128451,6 @@ - assert( pNew->pPrior!=0 ); - pNew->pPrior->pNext = pNew; - pNew->pLimit = 0; -- pNew->pOffset = 0; - return WRC_Continue; - } - -@@ -121668,7 +128603,8 @@ - ); - return SQLITE_ERROR; - } -- assert( pTab->nTabRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 )); -+ assert( pTab->nTabRef==1 || -+ ((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 )); - - pCte->zCteErr = "circular reference: %s"; - pSavedWith = pParse->pWith; -@@ -121725,7 +128661,7 @@ - */ - static void selectPopWith(Walker *pWalker, Select *p){ - Parse *pParse = pWalker->pParse; -- if( pParse->pWith && p->pPrior==0 ){ -+ if( OK_IF_ALWAYS_TRUE(pParse->pWith) && p->pPrior==0 ){ - With *pWith = findRightmost(p)->pWith; - if( pWith!=0 ){ - assert( pParse->pWith==pWith ); -@@ -121738,6 +128674,35 @@ - #endif - - /* -+** The SrcList_item structure passed as the second argument represents a -+** sub-query in the FROM clause of a SELECT statement. This function -+** allocates and populates the SrcList_item.pTab object. If successful, -+** SQLITE_OK is returned. Otherwise, if an OOM error is encountered, -+** SQLITE_NOMEM. -+*/ -+SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){ -+ Select *pSel = pFrom->pSelect; -+ Table *pTab; -+ -+ assert( pSel ); -+ pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table)); -+ if( pTab==0 ) return SQLITE_NOMEM; -+ pTab->nTabRef = 1; -+ if( pFrom->zAlias ){ -+ pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias); -+ }else{ -+ pTab->zName = sqlite3MPrintf(pParse->db, "subquery_%u", pSel->selId); -+ } -+ while( pSel->pPrior ){ pSel = pSel->pPrior; } -+ sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); -+ pTab->iPKey = -1; -+ pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); -+ pTab->tabFlags |= TF_Ephemeral; -+ -+ return SQLITE_OK; -+} -+ -+/* - ** This routine is a Walker callback for "expanding" a SELECT statement. - ** "Expanding" means to do the following: - ** -@@ -121770,19 +128735,19 @@ - sqlite3 *db = pParse->db; - Expr *pE, *pRight, *pExpr; - u16 selFlags = p->selFlags; -+ u32 elistFlags = 0; - - p->selFlags |= SF_Expanded; - if( db->mallocFailed ){ - return WRC_Abort; - } -- if( NEVER(p->pSrc==0) || (selFlags & SF_Expanded)!=0 ){ -+ assert( p->pSrc!=0 ); -+ if( (selFlags & SF_Expanded)!=0 ){ - return WRC_Prune; - } - pTabList = p->pSrc; - pEList = p->pEList; -- if( p->pWith ){ -- sqlite3WithPush(pParse, p->pWith, 0); -- } -+ sqlite3WithPush(pParse, p->pWith, 0); - - /* Make sure cursor numbers have been assigned to all entries in - ** the FROM clause of the SELECT statement. -@@ -121809,15 +128774,7 @@ - assert( pSel!=0 ); - assert( pFrom->pTab==0 ); - if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; -- pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); -- if( pTab==0 ) return WRC_Abort; -- pTab->nTabRef = 1; -- pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab); -- while( pSel->pPrior ){ pSel = pSel->pPrior; } -- sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); -- pTab->iPKey = -1; -- pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); -- pTab->tabFlags |= TF_Ephemeral; -+ if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort; - #endif - }else{ - /* An ordinary table or view name in the FROM clause */ -@@ -121840,7 +128797,6 @@ - if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; - assert( pFrom->pSelect==0 ); - pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); -- sqlite3SelectSetName(pFrom->pSelect, pTab->zName); - nCol = pTab->nCol; - pTab->nCol = -1; - sqlite3WalkSelect(pWalker, pFrom->pSelect); -@@ -121878,6 +128834,7 @@ - assert( pE->op!=TK_DOT || pE->pRight!=0 ); - assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) ); - if( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break; -+ elistFlags |= pE->flags; - } - if( k<pEList->nExpr ){ - /* -@@ -121893,6 +128850,7 @@ - - for(k=0; k<pEList->nExpr; k++){ - pE = a[k].pExpr; -+ elistFlags |= pE->flags; - pRight = pE->pRight; - assert( pE->op!=TK_DOT || pRight!=0 ); - if( pE->op!=TK_ASTERISK -@@ -122022,12 +128980,15 @@ - sqlite3ExprListDelete(db, pEList); - p->pEList = pNew; - } --#if SQLITE_MAX_COLUMN -- if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ -- sqlite3ErrorMsg(pParse, "too many columns in result set"); -- return WRC_Abort; -+ if( p->pEList ){ -+ if( p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ -+ sqlite3ErrorMsg(pParse, "too many columns in result set"); -+ return WRC_Abort; -+ } -+ if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){ -+ p->selFlags |= SF_ComplexResult; -+ } - } --#endif - return WRC_Continue; - } - -@@ -122081,7 +129042,7 @@ - Walker w; - w.xExprCallback = sqlite3ExprWalkNoop; - w.pParse = pParse; -- if( pParse->hasCompound ){ -+ if( OK_IF_ALWAYS_TRUE(pParse->hasCompound) ){ - w.xSelectCallback = convertCompoundSelectToSubquery; - w.xSelectCallback2 = 0; - sqlite3WalkSelect(&w, pSelect); -@@ -122113,7 +129074,7 @@ - struct SrcList_item *pFrom; - - assert( p->selFlags & SF_Resolved ); -- assert( (p->selFlags & SF_HasTypeInfo)==0 ); -+ if( p->selFlags & SF_HasTypeInfo ) return; - p->selFlags |= SF_HasTypeInfo; - pParse = pWalker->pParse; - pTabList = p->pSrc; -@@ -122169,15 +129130,13 @@ - Select *p, /* The SELECT statement being coded. */ - NameContext *pOuterNC /* Name context for container */ - ){ -- sqlite3 *db; -- if( NEVER(p==0) ) return; -- db = pParse->db; -- if( db->mallocFailed ) return; -+ assert( p!=0 || pParse->db->mallocFailed ); -+ if( pParse->db->mallocFailed ) return; - if( p->selFlags & SF_HasTypeInfo ) return; - sqlite3SelectExpand(pParse, p); -- if( pParse->nErr || db->mallocFailed ) return; -+ if( pParse->nErr || pParse->db->mallocFailed ) return; - sqlite3ResolveSelectNames(pParse, p, pOuterNC); -- if( pParse->nErr || db->mallocFailed ) return; -+ if( pParse->nErr || pParse->db->mallocFailed ) return; - sqlite3SelectAddTypeInfo(pParse, p); - } - -@@ -122218,7 +129177,7 @@ - "argument"); - pFunc->iDistinct = -1; - }else{ -- KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0, 0); -+ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pE->x.pList,0,0); - sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0, - (char*)pKeyInfo, P4_KEYINFO); - } -@@ -122242,11 +129201,17 @@ - } - } - -+ - /* - ** Update the accumulator memory cells for an aggregate based on - ** the current cursor position. -+** -+** If regAcc is non-zero and there are no min() or max() aggregates -+** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator -+** registers i register regAcc contains 0. The caller will take care -+** of setting and clearing regAcc. - */ --static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ -+static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){ - Vdbe *v = pParse->pVdbe; - int i; - int regHit = 0; -@@ -122289,36 +129254,24 @@ - if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; - sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); - } -- sqlite3VdbeAddOp3(v, OP_AggStep0, 0, regAgg, pF->iMem); -+ sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, pF->iMem); - sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); -- sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg); - sqlite3ReleaseTempRange(pParse, regAgg, nArg); - if( addrNext ){ - sqlite3VdbeResolveLabel(v, addrNext); -- sqlite3ExprCacheClear(pParse); - } - } -- -- /* Before populating the accumulator registers, clear the column cache. -- ** Otherwise, if any of the required column values are already present -- ** in registers, sqlite3ExprCode() may use OP_SCopy to copy the value -- ** to pC->iMem. But by the time the value is used, the original register -- ** may have been used, invalidating the underlying buffer holding the -- ** text or blob value. See ticket [883034dcb5]. -- ** -- ** Another solution would be to change the OP_SCopy used to copy cached -- ** values to an OP_Copy. -- */ -+ if( regHit==0 && pAggInfo->nAccumulator ){ -+ regHit = regAcc; -+ } - if( regHit ){ - addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); - } -- sqlite3ExprCacheClear(pParse); - for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){ - sqlite3ExprCode(pParse, pC->pExpr, pC->iMem); - } - pAggInfo->directMode = 0; -- sqlite3ExprCacheClear(pParse); - if( addrHitTest ){ - sqlite3VdbeJumpHere(v, addrHitTest); - } -@@ -122336,14 +129289,11 @@ - ){ - if( pParse->explain==2 ){ - int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx))); -- char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s", -+ sqlite3VdbeExplain(pParse, 0, "SCAN TABLE %s%s%s", - pTab->zName, - bCover ? " USING COVERING INDEX " : "", - bCover ? pIdx->zName : "" - ); -- sqlite3VdbeAddOp4( -- pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC -- ); - } - } - #else -@@ -122351,14 +129301,6 @@ - #endif - - /* --** Context object for havingToWhereExprCb(). --*/ --struct HavingToWhereCtx { -- Expr **ppWhere; -- ExprList *pGroupBy; --}; -- --/* - ** sqlite3WalkExpr() callback used by havingToWhere(). - ** - ** If the node passed to the callback is a TK_AND node, return -@@ -122371,15 +129313,16 @@ - */ - static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){ - if( pExpr->op!=TK_AND ){ -- struct HavingToWhereCtx *p = pWalker->u.pHavingCtx; -- if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, p->pGroupBy) ){ -+ Select *pS = pWalker->u.pSelect; -+ if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) ){ - sqlite3 *db = pWalker->pParse->db; - Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0); - if( pNew ){ -- Expr *pWhere = *(p->ppWhere); -+ Expr *pWhere = pS->pWhere; - SWAP(Expr, *pNew, *pExpr); - pNew = sqlite3ExprAnd(db, pWhere, pNew); -- *(p->ppWhere) = pNew; -+ pS->pWhere = pNew; -+ pWalker->eCode = 1; - } - } - return WRC_Prune; -@@ -122402,23 +129345,19 @@ - ** entirely of constants and expressions that are also GROUP BY terms that - ** use the "BINARY" collation sequence. - */ --static void havingToWhere( -- Parse *pParse, -- ExprList *pGroupBy, -- Expr *pHaving, -- Expr **ppWhere --){ -- struct HavingToWhereCtx sCtx; -+static void havingToWhere(Parse *pParse, Select *p){ - Walker sWalker; -- -- sCtx.ppWhere = ppWhere; -- sCtx.pGroupBy = pGroupBy; -- - memset(&sWalker, 0, sizeof(sWalker)); - sWalker.pParse = pParse; - sWalker.xExprCallback = havingToWhereExprCb; -- sWalker.u.pHavingCtx = &sCtx; -- sqlite3WalkExpr(&sWalker, pHaving); -+ sWalker.u.pSelect = p; -+ sqlite3WalkExpr(&sWalker, p->pHaving); -+#if SELECTTRACE_ENABLED -+ if( sWalker.eCode && (sqlite3SelectTrace & 0x100)!=0 ){ -+ SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n")); -+ sqlite3TreeViewSelect(0, p, 0); -+ } -+#endif - } - - /* -@@ -122462,6 +129401,7 @@ - ** The transformation only works if all of the following are true: - ** - ** * The subquery is a UNION ALL of two or more terms -+** * The subquery does not have a LIMIT clause - ** * There is no WHERE or GROUP BY or HAVING clauses on the subqueries - ** * The outer query is a simple count(*) - ** -@@ -122472,24 +129412,25 @@ - Expr *pExpr; - Expr *pCount; - sqlite3 *db; -- if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate query */ -+ if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */ - if( p->pEList->nExpr!=1 ) return 0; /* Single result column */ - pExpr = p->pEList->a[0].pExpr; - if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */ -- if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Must be count() */ -+ if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */ - if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */ -- if( p->pSrc->nSrc!=1 ) return 0; /* One table in the FROM clause */ -+ if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */ - pSub = p->pSrc->a[0].pSelect; - if( pSub==0 ) return 0; /* The FROM is a subquery */ -- if( pSub->pPrior==0 ) return 0; /* Must be a compound subquery */ -+ if( pSub->pPrior==0 ) return 0; /* Must be a compound ry */ - do{ - if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */ - if( pSub->pWhere ) return 0; /* No WHERE clause */ -+ if( pSub->pLimit ) return 0; /* No LIMIT clause */ - if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */ -- pSub = pSub->pPrior; /* Repeat over compound terms */ -+ pSub = pSub->pPrior; /* Repeat over compound */ - }while( pSub ); - -- /* If we reach this point, that means it is OK to perform the transformation */ -+ /* If we reach this point then it is OK to perform the transformation */ - - db = pParse->db; - pCount = pExpr; -@@ -122564,13 +129505,11 @@ - AggInfo sAggInfo; /* Information used by aggregate queries */ - int iEnd; /* Address of the end of the query */ - sqlite3 *db; /* The database connection */ -+ ExprList *pMinMaxOrderBy = 0; /* Added ORDER BY for min/max queries */ -+ u8 minMaxFlag; /* Flag for min/max queries */ - --#ifndef SQLITE_OMIT_EXPLAIN -- int iRestoreSelectId = pParse->iSelectId; -- pParse->iSelectId = pParse->iNextSelectId++; --#endif -- - db = pParse->db; -+ v = sqlite3GetVdbe(pParse); - if( p==0 || db->mallocFailed || pParse->nErr ){ - return 1; - } -@@ -122577,8 +129516,7 @@ - if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; - memset(&sAggInfo, 0, sizeof(sAggInfo)); - #if SELECTTRACE_ENABLED -- pParse->nSelectIndent++; -- SELECTTRACE(1,pParse,p, ("begin processing:\n")); -+ SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain)); - if( sqlite3SelectTrace & 0x100 ){ - sqlite3TreeViewSelect(0, p, 0); - } -@@ -122600,37 +129538,60 @@ - p->selFlags &= ~SF_Distinct; - } - sqlite3SelectPrep(pParse, p, 0); -- memset(&sSort, 0, sizeof(sSort)); -- sSort.pOrderBy = p->pOrderBy; -- pTabList = p->pSrc; - if( pParse->nErr || db->mallocFailed ){ - goto select_end; - } - assert( p->pEList!=0 ); -- isAgg = (p->selFlags & SF_Aggregate)!=0; - #if SELECTTRACE_ENABLED -- if( sqlite3SelectTrace & 0x100 ){ -- SELECTTRACE(0x100,pParse,p, ("after name resolution:\n")); -+ if( sqlite3SelectTrace & 0x104 ){ -+ SELECTTRACE(0x104,pParse,p, ("after name resolution:\n")); - sqlite3TreeViewSelect(0, p, 0); - } - #endif - -- /* Get a pointer the VDBE under construction, allocating a new VDBE if one -- ** does not already exist */ -- v = sqlite3GetVdbe(pParse); -- if( v==0 ) goto select_end; - if( pDest->eDest==SRT_Output ){ - generateColumnNames(pParse, p); - } - -- /* Try to flatten subqueries in the FROM clause up into the main query -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( sqlite3WindowRewrite(pParse, p) ){ -+ goto select_end; -+ } -+#if SELECTTRACE_ENABLED -+ if( sqlite3SelectTrace & 0x108 ){ -+ SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n")); -+ sqlite3TreeViewSelect(0, p, 0); -+ } -+#endif -+#endif /* SQLITE_OMIT_WINDOWFUNC */ -+ pTabList = p->pSrc; -+ isAgg = (p->selFlags & SF_Aggregate)!=0; -+ memset(&sSort, 0, sizeof(sSort)); -+ sSort.pOrderBy = p->pOrderBy; -+ -+ /* Try to various optimizations (flattening subqueries, and strength -+ ** reduction of join operators) in the FROM clause up into the main query - */ - #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) - for(i=0; !p->pPrior && i<pTabList->nSrc; i++){ - struct SrcList_item *pItem = &pTabList->a[i]; - Select *pSub = pItem->pSelect; -- int isAggSub; - Table *pTab = pItem->pTab; -+ -+ /* Convert LEFT JOIN into JOIN if there are terms of the right table -+ ** of the LEFT JOIN used in the WHERE clause. -+ */ -+ if( (pItem->fg.jointype & JT_LEFT)!=0 -+ && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor) -+ && OptimizationEnabled(db, SQLITE_SimplifyJoin) -+ ){ -+ SELECTTRACE(0x100,pParse,p, -+ ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); -+ pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); -+ unsetJoinExpr(p->pWhere, pItem->iCursor); -+ } -+ -+ /* No futher action if this term of the FROM clause is no a subquery */ - if( pSub==0 ) continue; - - /* Catch mismatch in the declared columns of a view and the number of -@@ -122641,13 +129602,45 @@ - goto select_end; - } - -- isAggSub = (pSub->selFlags & SF_Aggregate)!=0; -- if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){ -+ /* Do not try to flatten an aggregate subquery. -+ ** -+ ** Flattening an aggregate subquery is only possible if the outer query -+ ** is not a join. But if the outer query is not a join, then the subquery -+ ** will be implemented as a co-routine and there is no advantage to -+ ** flattening in that case. -+ */ -+ if( (pSub->selFlags & SF_Aggregate)!=0 ) continue; -+ assert( pSub->pGroupBy==0 ); -+ -+ /* If the outer query contains a "complex" result set (that is, -+ ** if the result set of the outer query uses functions or subqueries) -+ ** and if the subquery contains an ORDER BY clause and if -+ ** it will be implemented as a co-routine, then do not flatten. This -+ ** restriction allows SQL constructs like this: -+ ** -+ ** SELECT expensive_function(x) -+ ** FROM (SELECT x FROM tab ORDER BY y LIMIT 10); -+ ** -+ ** The expensive_function() is only computed on the 10 rows that -+ ** are output, rather than every row of the table. -+ ** -+ ** The requirement that the outer query have a complex result set -+ ** means that flattening does occur on simpler SQL constraints without -+ ** the expensive_function() like: -+ ** -+ ** SELECT x FROM (SELECT x FROM tab ORDER BY y LIMIT 10); -+ */ -+ if( pSub->pOrderBy!=0 -+ && i==0 -+ && (p->selFlags & SF_ComplexResult)!=0 -+ && (pTabList->nSrc==1 -+ || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) -+ ){ -+ continue; -+ } -+ -+ if( flattenSubquery(pParse, p, i, isAgg) ){ - /* This subquery can be absorbed into its parent. */ -- if( isAggSub ){ -- isAgg = 1; -- p->selFlags |= SF_Aggregate; -- } - i = -1; - } - pTabList = p->pSrc; -@@ -122664,15 +129657,46 @@ - */ - if( p->pPrior ){ - rc = multiSelect(pParse, p, pDest); -- explainSetInteger(pParse->iSelectId, iRestoreSelectId); - #if SELECTTRACE_ENABLED -- SELECTTRACE(1,pParse,p,("end compound-select processing\n")); -- pParse->nSelectIndent--; -+ SELECTTRACE(0x1,pParse,p,("end compound-select processing\n")); -+ if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ -+ sqlite3TreeViewSelect(0, p, 0); -+ } - #endif -+ if( p->pNext==0 ) ExplainQueryPlanPop(pParse); - return rc; - } - #endif - -+ /* Do the WHERE-clause constant propagation optimization if this is -+ ** a join. No need to speed time on this operation for non-join queries -+ ** as the equivalent optimization will be handled by query planner in -+ ** sqlite3WhereBegin(). -+ */ -+ if( pTabList->nSrc>1 -+ && OptimizationEnabled(db, SQLITE_PropagateConst) -+ && propagateConstants(pParse, p) -+ ){ -+#if SELECTTRACE_ENABLED -+ if( sqlite3SelectTrace & 0x100 ){ -+ SELECTTRACE(0x100,pParse,p,("After constant propagation:\n")); -+ sqlite3TreeViewSelect(0, p, 0); -+ } -+#endif -+ }else{ -+ SELECTTRACE(0x100,pParse,p,("Constant propagation not helpful\n")); -+ } -+ -+#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION -+ if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) -+ && countOfViewOptimization(pParse, p) -+ ){ -+ if( db->mallocFailed ) goto select_end; -+ pEList = p->pEList; -+ pTabList = p->pSrc; -+ } -+#endif -+ - /* For each term in the FROM clause, do two things: - ** (1) Authorized unreferenced tables - ** (2) Generate code for all sub-queries -@@ -122681,10 +129705,14 @@ - struct SrcList_item *pItem = &pTabList->a[i]; - SelectDest dest; - Select *pSub; -+#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) -+ const char *zSavedAuthContext; -+#endif - -- /* Issue SQLITE_READ authorizations with a fake column name for any tables that -- ** are referenced but from which no values are extracted. Examples of where these -- ** kinds of null SQLITE_READ authorizations would occur: -+ /* Issue SQLITE_READ authorizations with a fake column name for any -+ ** tables that are referenced but from which no values are extracted. -+ ** Examples of where these kinds of null SQLITE_READ authorizations -+ ** would occur: - ** - ** SELECT count(*) FROM t1; -- SQLITE_READ t1."" - ** SELECT t1.* FROM t1, t2; -- SQLITE_READ t2."" -@@ -122692,10 +129720,10 @@ - ** The fake column name is an empty string. It is possible for a table to - ** have a column named by the empty string, in which case there is no way to - ** distinguish between an unreferenced table and an actual reference to the -- ** "" column. The original design was for the fake column name to be a NULL, -+ ** "" column. The original design was for the fake column name to be a NULL, - ** which would be unambiguous. But legacy authorization callbacks might -- ** assume the column name is non-NULL and segfault. The use of an empty string -- ** for the fake column name seems safer. -+ ** assume the column name is non-NULL and segfault. The use of an empty -+ ** string for the fake column name seems safer. - */ - if( pItem->colUsed==0 ){ - sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase); -@@ -122736,27 +129764,29 @@ - /* Make copies of constant WHERE-clause terms in the outer query down - ** inside the subquery. This can help the subquery to run more efficiently. - */ -- if( (pItem->fg.jointype & JT_OUTER)==0 -- && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor) -+ if( OptimizationEnabled(db, SQLITE_PushDown) -+ && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor, -+ (pItem->fg.jointype & JT_OUTER)!=0) - ){ - #if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x100 ){ -- SELECTTRACE(0x100,pParse,p,("After WHERE-clause push-down:\n")); -+ SELECTTRACE(0x100,pParse,p, -+ ("After WHERE-clause push-down into subquery %d:\n", pSub->selId)); - sqlite3TreeViewSelect(0, p, 0); - } - #endif -+ }else{ -+ SELECTTRACE(0x100,pParse,p,("Push-down not possible\n")); - } - -+ zSavedAuthContext = pParse->zAuthContext; -+ pParse->zAuthContext = pItem->zName; -+ - /* Generate code to implement the subquery - ** -- ** The subquery is implemented as a co-routine if all of these are true: -- ** (1) The subquery is guaranteed to be the outer loop (so that it -- ** does not need to be computed more than once) -- ** (2) The ALL keyword after SELECT is omitted. (Applications are -- ** allowed to say "SELECT ALL" instead of just "SELECT" to disable -- ** the use of co-routines.) -- ** (3) Co-routines are not disabled using sqlite3_test_control() -- ** with SQLITE_TESTCTRL_OPTIMIZATIONS. -+ ** The subquery is implemented as a co-routine if the subquery is -+ ** guaranteed to be the outer loop (so that it does not need to be -+ ** computed more than once) - ** - ** TODO: Are there other reasons beside (1) to use a co-routine - ** implementation? -@@ -122764,19 +129794,18 @@ - if( i==0 - && (pTabList->nSrc==1 - || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */ -- && (p->selFlags & SF_All)==0 /* (2) */ -- && OptimizationEnabled(db, SQLITE_SubqCoroutine) /* (3) */ - ){ - /* Implement a co-routine that will return a single row of the result - ** set on each invocation. - */ - int addrTop = sqlite3VdbeCurrentAddr(v)+1; -+ - pItem->regReturn = ++pParse->nMem; - sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop); - VdbeComment((v, "%s", pItem->pTab->zName)); - pItem->addrFillSub = addrTop; - sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); -- explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); -+ ExplainQueryPlan((pParse, 1, "CO-ROUTINE %u", pSub->selId)); - sqlite3Select(pParse, pSub, &dest); - pItem->pTab->nRowLogEst = pSub->nSelectRow; - pItem->fg.viaCoroutine = 1; -@@ -122811,12 +129840,11 @@ - pPrior = isSelfJoinView(pTabList, pItem); - if( pPrior ){ - sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); -- explainSetInteger(pItem->iSelectId, pPrior->iSelectId); - assert( pPrior->pSelect!=0 ); - pSub->nSelectRow = pPrior->pSelect->nSelectRow; - }else{ - sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); -- explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); -+ ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId)); - sqlite3Select(pParse, pSub, &dest); - } - pItem->pTab->nRowLogEst = pSub->nSelectRow; -@@ -122828,6 +129856,7 @@ - } - if( db->mallocFailed ) goto select_end; - pParse->nHeight -= sqlite3SelectExprHeight(p); -+ pParse->zAuthContext = zSavedAuthContext; - #endif - } - -@@ -122846,16 +129875,6 @@ - } - #endif - --#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION -- if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) -- && countOfViewOptimization(pParse, p) -- ){ -- if( db->mallocFailed ) goto select_end; -- pEList = p->pEList; -- pTabList = p->pSrc; -- } --#endif -- - /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and - ** if the select-list is the same as the ORDER BY list, then this query - ** can be rewritten as a GROUP BY. In other words, this: -@@ -122899,7 +129918,8 @@ - */ - if( sSort.pOrderBy ){ - KeyInfo *pKeyInfo; -- pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, pEList->nExpr); -+ pKeyInfo = sqlite3KeyInfoFromExprList( -+ pParse, sSort.pOrderBy, 0, pEList->nExpr); - sSort.iECursor = pParse->nTab++; - sSort.addrSortIndex = - sqlite3VdbeAddOp4(v, OP_OpenEphemeral, -@@ -122933,9 +129953,9 @@ - if( p->selFlags & SF_Distinct ){ - sDistinct.tabTnct = pParse->nTab++; - sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, -- sDistinct.tabTnct, 0, 0, -- (char*)keyInfoFromExprList(pParse, p->pEList,0,0), -- P4_KEYINFO); -+ sDistinct.tabTnct, 0, 0, -+ (char*)sqlite3KeyInfoFromExprList(pParse, p->pEList,0,0), -+ P4_KEYINFO); - sqlite3VdbeChangeP5(v, BTREE_UNORDERED); - sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED; - }else{ -@@ -122944,11 +129964,19 @@ - - if( !isAgg && pGroupBy==0 ){ - /* No aggregate functions and no GROUP BY clause */ -- u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0); -+ u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0) -+ | (p->selFlags & SF_FixedLimit); -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ Window *pWin = p->pWin; /* Master window object (or NULL) */ -+ if( pWin ){ -+ sqlite3WindowCodeInit(pParse, pWin); -+ } -+#endif - assert( WHERE_USE_LIMIT==SF_FixedLimit ); -- wctrlFlags |= p->selFlags & SF_FixedLimit; - -+ - /* Begin the database scan. */ -+ SELECTTRACE(1,pParse,p,("WhereBegin\n")); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, - p->pEList, wctrlFlags, p->nSelectRow); - if( pWInfo==0 ) goto select_end; -@@ -122960,7 +129988,7 @@ - } - if( sSort.pOrderBy ){ - sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo); -- sSort.bOrderedInnerLoop = sqlite3WhereOrderedInnerLoop(pWInfo); -+ sSort.labelOBLopt = sqlite3WhereOrderByLimitOptLabel(pWInfo); - if( sSort.nOBSat==sSort.pOrderBy->nExpr ){ - sSort.pOrderBy = 0; - } -@@ -122974,14 +130002,37 @@ - sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); - } - -- /* Use the standard inner loop. */ -- selectInnerLoop(pParse, p, pEList, -1, &sSort, &sDistinct, pDest, -- sqlite3WhereContinueLabel(pWInfo), -- sqlite3WhereBreakLabel(pWInfo)); -+ assert( p->pEList==pEList ); -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( pWin ){ -+ int addrGosub = sqlite3VdbeMakeLabel(v); -+ int iCont = sqlite3VdbeMakeLabel(v); -+ int iBreak = sqlite3VdbeMakeLabel(v); -+ int regGosub = ++pParse->nMem; - -- /* End the database scan loop. -- */ -- sqlite3WhereEnd(pWInfo); -+ sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub); -+ -+ sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak); -+ sqlite3VdbeResolveLabel(v, addrGosub); -+ VdbeNoopComment((v, "inner-loop subroutine")); -+ sSort.labelOBLopt = 0; -+ selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, iCont, iBreak); -+ sqlite3VdbeResolveLabel(v, iCont); -+ sqlite3VdbeAddOp1(v, OP_Return, regGosub); -+ VdbeComment((v, "end inner-loop subroutine")); -+ sqlite3VdbeResolveLabel(v, iBreak); -+ }else -+#endif /* SQLITE_OMIT_WINDOWFUNC */ -+ { -+ /* Use the standard inner loop. */ -+ selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, -+ sqlite3WhereContinueLabel(pWInfo), -+ sqlite3WhereBreakLabel(pWInfo)); -+ -+ /* End the database scan loop. -+ */ -+ sqlite3WhereEnd(pWInfo); -+ } - }else{ - /* This case when there exist aggregate functions or a GROUP BY clause - ** or both */ -@@ -123040,7 +130091,8 @@ - memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pParse; - sNC.pSrcList = pTabList; -- sNC.pAggInfo = &sAggInfo; -+ sNC.uNC.pAggInfo = &sAggInfo; -+ VVA_ONLY( sNC.ncFlags = NC_UAggInfo; ) - sAggInfo.mnReg = pParse->nMem+1; - sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0; - sAggInfo.pGroupBy = pGroupBy; -@@ -123049,12 +130101,19 @@ - if( pHaving ){ - if( pGroupBy ){ - assert( pWhere==p->pWhere ); -- havingToWhere(pParse, pGroupBy, pHaving, &p->pWhere); -+ assert( pHaving==p->pHaving ); -+ assert( pGroupBy==p->pGroupBy ); -+ havingToWhere(pParse, p); - pWhere = p->pWhere; - } - sqlite3ExprAnalyzeAggregates(&sNC, pHaving); - } - sAggInfo.nAccumulator = sAggInfo.nColumn; -+ if( p->pGroupBy==0 && p->pHaving==0 && sAggInfo.nFunc==1 ){ -+ minMaxFlag = minMaxQuery(db, sAggInfo.aFunc[0].pExpr, &pMinMaxOrderBy); -+ }else{ -+ minMaxFlag = WHERE_ORDERBY_NORMAL; -+ } - for(i=0; i<sAggInfo.nFunc; i++){ - assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) ); - sNC.ncFlags |= NC_InAggFunc; -@@ -123063,7 +130122,25 @@ - } - sAggInfo.mxReg = pParse->nMem; - if( db->mallocFailed ) goto select_end; -+#if SELECTTRACE_ENABLED -+ if( sqlite3SelectTrace & 0x400 ){ -+ int ii; -+ SELECTTRACE(0x400,pParse,p,("After aggregate analysis:\n")); -+ sqlite3TreeViewSelect(0, p, 0); -+ for(ii=0; ii<sAggInfo.nColumn; ii++){ -+ sqlite3DebugPrintf("agg-column[%d] iMem=%d\n", -+ ii, sAggInfo.aCol[ii].iMem); -+ sqlite3TreeViewExpr(0, sAggInfo.aCol[ii].pExpr, 0); -+ } -+ for(ii=0; ii<sAggInfo.nFunc; ii++){ -+ sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n", -+ ii, sAggInfo.aFunc[ii].iMem); -+ sqlite3TreeViewExpr(0, sAggInfo.aFunc[ii].pExpr, 0); -+ } -+ } -+#endif - -+ - /* Processing for aggregates with GROUP BY is very different and - ** much more complex than aggregates without a GROUP BY. - */ -@@ -123084,7 +130161,7 @@ - ** will be converted into a Noop. - */ - sAggInfo.sortingIdx = pParse->nTab++; -- pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, sAggInfo.nColumn); -+ pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pGroupBy,0,sAggInfo.nColumn); - addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, - sAggInfo.sortingIdx, sAggInfo.nSortingColumn, - 0, (char*)pKeyInfo, P4_KEYINFO); -@@ -123103,8 +130180,6 @@ - pParse->nMem += pGroupBy->nExpr; - sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag); - VdbeComment((v, "clear abort flag")); -- sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); -- VdbeComment((v, "indicate accumulator empty")); - sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1); - - /* Begin a loop that will extract all source rows in GROUP BY order. -@@ -123113,6 +130188,7 @@ - ** in the right order to begin with. - */ - sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); -+ SELECTTRACE(1,pParse,p,("WhereBegin\n")); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, - WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0 - ); -@@ -123149,7 +130225,6 @@ - } - } - regBase = sqlite3GetTempRange(pParse, nCol); -- sqlite3ExprCacheClear(pParse); - sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0); - j = nGroupBy; - for(i=0; i<sAggInfo.nColumn; i++){ -@@ -123156,8 +130231,8 @@ - struct AggInfo_col *pCol = &sAggInfo.aCol[i]; - if( pCol->iSorterColumn>=j ){ - int r1 = j + regBase; -- sqlite3ExprCodeGetColumnToReg(pParse, -- pCol->pTab, pCol->iColumn, pCol->iTable, r1); -+ sqlite3ExprCodeGetColumnOfTable(v, -+ pCol->pTab, pCol->iTable, pCol->iColumn, r1); - j++; - } - } -@@ -123173,8 +130248,6 @@ - sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd); - VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); - sAggInfo.useSortingIdx = 1; -- sqlite3ExprCacheClear(pParse); -- - } - - /* If the index or temporary table used by the GROUP BY sort -@@ -123197,7 +130270,6 @@ - ** from the previous row currently stored in a0, a1, a2... - */ - addrTopOfLoop = sqlite3VdbeCurrentAddr(v); -- sqlite3ExprCacheClear(pParse); - if( groupBySort ){ - sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, - sortOut, sortPTab); -@@ -123236,7 +130308,7 @@ - ** the current row - */ - sqlite3VdbeJumpHere(v, addr1); -- updateAccumulator(pParse, &sAggInfo); -+ updateAccumulator(pParse, iUseFlag, &sAggInfo); - sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); - VdbeComment((v, "indicate data in accumulator")); - -@@ -123278,7 +130350,7 @@ - sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); - finalizeAggFunctions(pParse, &sAggInfo); - sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); -- selectInnerLoop(pParse, p, p->pEList, -1, &sSort, -+ selectInnerLoop(pParse, p, -1, &sSort, - &sDistinct, pDest, - addrOutputRow+1, addrSetAbort); - sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); -@@ -123288,11 +130360,12 @@ - */ - sqlite3VdbeResolveLabel(v, addrReset); - resetAccumulator(pParse, &sAggInfo); -+ sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); -+ VdbeComment((v, "indicate accumulator empty")); - sqlite3VdbeAddOp1(v, OP_Return, regReset); - - } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ - else { -- ExprList *pDel = 0; - #ifndef SQLITE_OMIT_BTREECOUNT - Table *pTab; - if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){ -@@ -123354,67 +130427,50 @@ - }else - #endif /* SQLITE_OMIT_BTREECOUNT */ - { -- /* Check if the query is of one of the following forms: -- ** -- ** SELECT min(x) FROM ... -- ** SELECT max(x) FROM ... -- ** -- ** If it is, then ask the code in where.c to attempt to sort results -- ** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause. -- ** If where.c is able to produce results sorted in this order, then -- ** add vdbe code to break out of the processing loop after the -- ** first iteration (since the first iteration of the loop is -- ** guaranteed to operate on the row with the minimum or maximum -- ** value of x, the only row required). -- ** -- ** A special flag must be passed to sqlite3WhereBegin() to slightly -- ** modify behavior as follows: -- ** -- ** + If the query is a "SELECT min(x)", then the loop coded by -- ** where.c should not iterate over any values with a NULL value -- ** for x. -- ** -- ** + The optimizer code in where.c (the thing that decides which -- ** index or indices to use) should place a different priority on -- ** satisfying the 'ORDER BY' clause than it does in other cases. -- ** Refer to code and comments in where.c for details. -- */ -- ExprList *pMinMax = 0; -- u8 flag = WHERE_ORDERBY_NORMAL; -- -- assert( p->pGroupBy==0 ); -- assert( flag==0 ); -- if( p->pHaving==0 ){ -- flag = minMaxQuery(&sAggInfo, &pMinMax); -- } -- assert( flag==0 || (pMinMax!=0 && pMinMax->nExpr==1) ); -+ int regAcc = 0; /* "populate accumulators" flag */ - -- if( flag ){ -- pMinMax = sqlite3ExprListDup(db, pMinMax, 0); -- pDel = pMinMax; -- assert( db->mallocFailed || pMinMax!=0 ); -- if( !db->mallocFailed ){ -- pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0; -- pMinMax->a[0].pExpr->op = TK_COLUMN; -+ /* If there are accumulator registers but no min() or max() functions, -+ ** allocate register regAcc. Register regAcc will contain 0 the first -+ ** time the inner loop runs, and 1 thereafter. The code generated -+ ** by updateAccumulator() only updates the accumulator registers if -+ ** regAcc contains 0. */ -+ if( sAggInfo.nAccumulator ){ -+ for(i=0; i<sAggInfo.nFunc; i++){ -+ if( sAggInfo.aFunc[i].pFunc->funcFlags&SQLITE_FUNC_NEEDCOLL ) break; - } -+ if( i==sAggInfo.nFunc ){ -+ regAcc = ++pParse->nMem; -+ sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc); -+ } - } -- -+ - /* This case runs if the aggregate has no GROUP BY clause. The - ** processing is much simpler since there is only a single row - ** of output. - */ -+ assert( p->pGroupBy==0 ); - resetAccumulator(pParse, &sAggInfo); -- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax, 0,flag,0); -+ -+ /* If this query is a candidate for the min/max optimization, then -+ ** minMaxFlag will have been previously set to either -+ ** WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX and pMinMaxOrderBy will -+ ** be an appropriate ORDER BY expression for the optimization. -+ */ -+ assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 ); -+ assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 ); -+ -+ SELECTTRACE(1,pParse,p,("WhereBegin\n")); -+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy, -+ 0, minMaxFlag, 0); - if( pWInfo==0 ){ -- sqlite3ExprListDelete(db, pDel); - goto select_end; - } -- updateAccumulator(pParse, &sAggInfo); -- assert( pMinMax==0 || pMinMax->nExpr==1 ); -+ updateAccumulator(pParse, regAcc, &sAggInfo); -+ if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc); - if( sqlite3WhereIsOrdered(pWInfo)>0 ){ - sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo)); - VdbeComment((v, "%s() by index", -- (flag==WHERE_ORDERBY_MIN?"min":"max"))); -+ (minMaxFlag==WHERE_ORDERBY_MIN?"min":"max"))); - } - sqlite3WhereEnd(pWInfo); - finalizeAggFunctions(pParse, &sAggInfo); -@@ -123422,9 +130478,8 @@ - - sSort.pOrderBy = 0; - sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); -- selectInnerLoop(pParse, p, p->pEList, -1, 0, 0, -+ selectInnerLoop(pParse, p, -1, 0, 0, - pDest, addrEnd, addrEnd); -- sqlite3ExprListDelete(db, pDel); - } - sqlite3VdbeResolveLabel(v, addrEnd); - -@@ -123440,6 +130495,7 @@ - if( sSort.pOrderBy ){ - explainTempTable(pParse, - sSort.nOBSat>0 ? "RIGHT PART OF ORDER BY":"ORDER BY"); -+ assert( p->pEList==pEList ); - generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest); - } - -@@ -123455,14 +130511,16 @@ - ** successful coding of the SELECT. - */ - select_end: -- explainSetInteger(pParse->iSelectId, iRestoreSelectId); -- -+ sqlite3ExprListDelete(db, pMinMaxOrderBy); - sqlite3DbFree(db, sAggInfo.aCol); - sqlite3DbFree(db, sAggInfo.aFunc); - #if SELECTTRACE_ENABLED -- SELECTTRACE(1,pParse,p,("end processing\n")); -- pParse->nSelectIndent--; -+ SELECTTRACE(0x1,pParse,p,("end processing\n")); -+ if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ -+ sqlite3TreeViewSelect(0, p, 0); -+ } - #endif -+ ExplainQueryPlanPop(pParse); - return rc; - } - -@@ -123696,6 +130754,8 @@ - sqlite3ExprListDelete(db, pTmp->pExprList); - sqlite3SelectDelete(db, pTmp->pSelect); - sqlite3IdListDelete(db, pTmp->pIdList); -+ sqlite3UpsertDelete(db, pTmp->pUpsert); -+ sqlite3DbFree(db, pTmp->zSpan); - - sqlite3DbFree(db, pTmp); - } -@@ -123850,14 +130910,16 @@ - goto trigger_cleanup; - } - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); -- if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){ -- if( !noErr ){ -- sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); -- }else{ -- assert( !db->init.busy ); -- sqlite3CodeVerifySchema(pParse, iDb); -+ if( !IN_RENAME_OBJECT ){ -+ if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){ -+ if( !noErr ){ -+ sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); -+ }else{ -+ assert( !db->init.busy ); -+ sqlite3CodeVerifySchema(pParse, iDb); -+ } -+ goto trigger_cleanup; - } -- goto trigger_cleanup; - } - - /* Do not create a trigger on a system table */ -@@ -123881,7 +130943,7 @@ - } - - #ifndef SQLITE_OMIT_AUTHORIZATION -- { -+ if( !IN_RENAME_OBJECT ){ - int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); - int code = SQLITE_CREATE_TRIGGER; - const char *zDb = db->aDb[iTabDb].zDbSName; -@@ -123915,8 +130977,15 @@ - pTrigger->pTabSchema = pTab->pSchema; - pTrigger->op = (u8)op; - pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER; -- pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); -- pTrigger->pColumns = sqlite3IdListDup(db, pColumns); -+ if( IN_RENAME_OBJECT ){ -+ sqlite3RenameTokenRemap(pParse, pTrigger->table, pTableName->a[0].zName); -+ pTrigger->pWhen = pWhen; -+ pWhen = 0; -+ }else{ -+ pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); -+ } -+ pTrigger->pColumns = pColumns; -+ pColumns = 0; - assert( pParse->pNewTrigger==0 ); - pParse->pNewTrigger = pTrigger; - -@@ -123965,6 +131034,14 @@ - goto triggerfinish_cleanup; - } - -+#ifndef SQLITE_OMIT_ALTERTABLE -+ if( IN_RENAME_OBJECT ){ -+ assert( !db->init.busy ); -+ pParse->pNewTrigger = pTrig; -+ pTrig = 0; -+ }else -+#endif -+ - /* if we are not initializing, - ** build the sqlite_master entry - */ -@@ -124006,11 +131083,22 @@ - - triggerfinish_cleanup: - sqlite3DeleteTrigger(db, pTrig); -- assert( !pParse->pNewTrigger ); -+ assert( IN_RENAME_OBJECT || !pParse->pNewTrigger ); - sqlite3DeleteTriggerStep(db, pStepList); - } - - /* -+** Duplicate a range of text from an SQL statement, then convert all -+** whitespace characters into ordinary space characters. -+*/ -+static char *triggerSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){ -+ char *z = sqlite3DbSpanDup(db, zStart, zEnd); -+ int i; -+ if( z ) for(i=0; z[i]; i++) if( sqlite3Isspace(z[i]) ) z[i] = ' '; -+ return z; -+} -+ -+/* - ** Turn a SELECT statement (that the pSelect parameter points to) into - ** a trigger step. Return a pointer to a TriggerStep structure. - ** -@@ -124017,7 +131105,12 @@ - ** The parser calls this routine when it finds a SELECT statement in - ** body of a TRIGGER. - */ --SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){ -+SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep( -+ sqlite3 *db, /* Database connection */ -+ Select *pSelect, /* The SELECT statement */ -+ const char *zStart, /* Start of SQL text */ -+ const char *zEnd /* End of SQL text */ -+){ - TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep)); - if( pTriggerStep==0 ) { - sqlite3SelectDelete(db, pSelect); -@@ -124026,6 +131119,7 @@ - pTriggerStep->op = TK_SELECT; - pTriggerStep->pSelect = pSelect; - pTriggerStep->orconf = OE_Default; -+ pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd); - return pTriggerStep; - } - -@@ -124036,10 +131130,13 @@ - ** If an OOM error occurs, NULL is returned and db->mallocFailed is set. - */ - static TriggerStep *triggerStepAllocate( -- sqlite3 *db, /* Database connection */ -+ Parse *pParse, /* Parser context */ - u8 op, /* Trigger opcode */ -- Token *pName /* The target name */ -+ Token *pName, /* The target name */ -+ const char *zStart, /* Start of SQL text */ -+ const char *zEnd /* End of SQL text */ - ){ -+ sqlite3 *db = pParse->db; - TriggerStep *pTriggerStep; - - pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1); -@@ -124049,6 +131146,10 @@ - sqlite3Dequote(z); - pTriggerStep->zTarget = z; - pTriggerStep->op = op; -+ pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd); -+ if( IN_RENAME_OBJECT ){ -+ sqlite3RenameTokenMap(pParse, pTriggerStep->zTarget, pName); -+ } - } - return pTriggerStep; - } -@@ -124061,23 +131162,36 @@ - ** body of a trigger. - */ - SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep( -- sqlite3 *db, /* The database connection */ -+ Parse *pParse, /* Parser */ - Token *pTableName, /* Name of the table into which we insert */ - IdList *pColumn, /* List of columns in pTableName to insert into */ - Select *pSelect, /* A SELECT statement that supplies values */ -- u8 orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */ -+ u8 orconf, /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */ -+ Upsert *pUpsert, /* ON CONFLICT clauses for upsert */ -+ const char *zStart, /* Start of SQL text */ -+ const char *zEnd /* End of SQL text */ - ){ -+ sqlite3 *db = pParse->db; - TriggerStep *pTriggerStep; - - assert(pSelect != 0 || db->mallocFailed); - -- pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName); -+ pTriggerStep = triggerStepAllocate(pParse, TK_INSERT, pTableName,zStart,zEnd); - if( pTriggerStep ){ -- pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); -+ if( IN_RENAME_OBJECT ){ -+ pTriggerStep->pSelect = pSelect; -+ pSelect = 0; -+ }else{ -+ pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); -+ } - pTriggerStep->pIdList = pColumn; -+ pTriggerStep->pUpsert = pUpsert; - pTriggerStep->orconf = orconf; - }else{ -+ testcase( pColumn ); - sqlite3IdListDelete(db, pColumn); -+ testcase( pUpsert ); -+ sqlite3UpsertDelete(db, pUpsert); - } - sqlite3SelectDelete(db, pSelect); - -@@ -124090,18 +131204,28 @@ - ** sees an UPDATE statement inside the body of a CREATE TRIGGER. - */ - SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep( -- sqlite3 *db, /* The database connection */ -+ Parse *pParse, /* Parser */ - Token *pTableName, /* Name of the table to be updated */ - ExprList *pEList, /* The SET clause: list of column and new values */ - Expr *pWhere, /* The WHERE clause */ -- u8 orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */ -+ u8 orconf, /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */ -+ const char *zStart, /* Start of SQL text */ -+ const char *zEnd /* End of SQL text */ - ){ -+ sqlite3 *db = pParse->db; - TriggerStep *pTriggerStep; - -- pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName); -+ pTriggerStep = triggerStepAllocate(pParse, TK_UPDATE, pTableName,zStart,zEnd); - if( pTriggerStep ){ -- pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE); -- pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); -+ if( IN_RENAME_OBJECT ){ -+ pTriggerStep->pExprList = pEList; -+ pTriggerStep->pWhere = pWhere; -+ pEList = 0; -+ pWhere = 0; -+ }else{ -+ pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE); -+ pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); -+ } - pTriggerStep->orconf = orconf; - } - sqlite3ExprListDelete(db, pEList); -@@ -124115,15 +131239,23 @@ - ** sees a DELETE statement inside the body of a CREATE TRIGGER. - */ - SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep( -- sqlite3 *db, /* Database connection */ -+ Parse *pParse, /* Parser */ - Token *pTableName, /* The table from which rows are deleted */ -- Expr *pWhere /* The WHERE clause */ -+ Expr *pWhere, /* The WHERE clause */ -+ const char *zStart, /* Start of SQL text */ -+ const char *zEnd /* End of SQL text */ - ){ -+ sqlite3 *db = pParse->db; - TriggerStep *pTriggerStep; - -- pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName); -+ pTriggerStep = triggerStepAllocate(pParse, TK_DELETE, pTableName,zStart,zEnd); - if( pTriggerStep ){ -- pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); -+ if( IN_RENAME_OBJECT ){ -+ pTriggerStep->pWhere = pWhere; -+ pWhere = 0; -+ }else{ -+ pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); -+ } - pTriggerStep->orconf = OE_Default; - } - sqlite3ExprDelete(db, pWhere); -@@ -124256,7 +131388,7 @@ - *pp = (*pp)->pNext; - } - sqlite3DeleteTrigger(db, pTrigger); -- db->flags |= SQLITE_InternChanges; -+ db->mDbFlags |= DBFLAG_SchemaChange; - } - } - -@@ -124376,6 +131508,14 @@ - pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf; - assert( pParse->okConstFactor==0 ); - -+#ifndef SQLITE_OMIT_TRACE -+ if( pStep->zSpan ){ -+ sqlite3VdbeAddOp4(v, OP_Trace, 0x7fffffff, 1, 0, -+ sqlite3MPrintf(db, "-- %s", pStep->zSpan), -+ P4_DYNAMIC); -+ } -+#endif -+ - switch( pStep->op ){ - case TK_UPDATE: { - sqlite3Update(pParse, -@@ -124382,7 +131522,7 @@ - targetSrcList(pParse, pStep), - sqlite3ExprListDup(db, pStep->pExprList, 0), - sqlite3ExprDup(db, pStep->pWhere, 0), -- pParse->eOrconf -+ pParse->eOrconf, 0, 0, 0 - ); - break; - } -@@ -124391,7 +131531,8 @@ - targetSrcList(pParse, pStep), - sqlite3SelectDup(db, pStep->pSelect, 0), - sqlite3IdListDup(db, pStep->pIdList), -- pParse->eOrconf -+ pParse->eOrconf, -+ sqlite3UpsertDup(db, pStep->pUpsert) - ); - break; - } -@@ -124398,7 +131539,7 @@ - case TK_DELETE: { - sqlite3DeleteFrom(pParse, - targetSrcList(pParse, pStep), -- sqlite3ExprDup(db, pStep->pWhere, 0) -+ sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0 - ); - break; - } -@@ -124516,9 +131657,11 @@ - pTab->zName - )); - #ifndef SQLITE_OMIT_TRACE -- sqlite3VdbeChangeP4(v, -1, -- sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC -- ); -+ if( pTrigger->zName ){ -+ sqlite3VdbeChangeP4(v, -1, -+ sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC -+ ); -+ } - #endif - - /* If one was specified, code the WHEN clause. If it evaluates to false -@@ -124546,7 +131689,7 @@ - VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf))); - - transferParseError(pParse, pSubParse); -- if( db->mallocFailed==0 ){ -+ if( db->mallocFailed==0 && pParse->nErr==0 ){ - pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg); - } - pProgram->nMem = pSubParse->nMem; -@@ -124854,6 +131997,57 @@ - } - - /* -+** Check to see if column iCol of index pIdx references any of the -+** columns defined by aXRef and chngRowid. Return true if it does -+** and false if not. This is an optimization. False-positives are a -+** performance degradation, but false-negatives can result in a corrupt -+** index and incorrect answers. -+** -+** aXRef[j] will be non-negative if column j of the original table is -+** being updated. chngRowid will be true if the rowid of the table is -+** being updated. -+*/ -+static int indexColumnIsBeingUpdated( -+ Index *pIdx, /* The index to check */ -+ int iCol, /* Which column of the index to check */ -+ int *aXRef, /* aXRef[j]>=0 if column j is being updated */ -+ int chngRowid /* true if the rowid is being updated */ -+){ -+ i16 iIdxCol = pIdx->aiColumn[iCol]; -+ assert( iIdxCol!=XN_ROWID ); /* Cannot index rowid */ -+ if( iIdxCol>=0 ){ -+ return aXRef[iIdxCol]>=0; -+ } -+ assert( iIdxCol==XN_EXPR ); -+ assert( pIdx->aColExpr!=0 ); -+ assert( pIdx->aColExpr->a[iCol].pExpr!=0 ); -+ return sqlite3ExprReferencesUpdatedColumn(pIdx->aColExpr->a[iCol].pExpr, -+ aXRef,chngRowid); -+} -+ -+/* -+** Check to see if index pIdx is a partial index whose conditional -+** expression might change values due to an UPDATE. Return true if -+** the index is subject to change and false if the index is guaranteed -+** to be unchanged. This is an optimization. False-positives are a -+** performance degradation, but false-negatives can result in a corrupt -+** index and incorrect answers. -+** -+** aXRef[j] will be non-negative if column j of the original table is -+** being updated. chngRowid will be true if the rowid of the table is -+** being updated. -+*/ -+static int indexWhereClauseMightChange( -+ Index *pIdx, /* The index to check */ -+ int *aXRef, /* aXRef[j]>=0 if column j is being updated */ -+ int chngRowid /* true if the rowid is being updated */ -+){ -+ if( pIdx->pPartIdxWhere==0 ) return 0; -+ return sqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere, -+ aXRef, chngRowid); -+} -+ -+/* - ** Process an UPDATE statement. - ** - ** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL; -@@ -124865,7 +132059,10 @@ - SrcList *pTabList, /* The table in which we should change things */ - ExprList *pChanges, /* Things to be changed */ - Expr *pWhere, /* The WHERE clause. May be null */ -- int onError /* How to handle constraint errors */ -+ int onError, /* How to handle constraint errors */ -+ ExprList *pOrderBy, /* ORDER BY clause. May be null */ -+ Expr *pLimit, /* LIMIT clause. May be null */ -+ Upsert *pUpsert /* ON CONFLICT clause, or null */ - ){ - int i, j; /* Loop counters */ - Table *pTab; /* The table to be updated */ -@@ -124950,6 +132147,16 @@ - # define isView 0 - #endif - -+#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT -+ if( !isView ){ -+ pWhere = sqlite3LimitWhere( -+ pParse, pTabList, pWhere, pOrderBy, pLimit, "UPDATE" -+ ); -+ pOrderBy = 0; -+ pLimit = 0; -+ } -+#endif -+ - if( sqlite3ViewGetColumnNames(pParse, pTab) ){ - goto update_cleanup; - } -@@ -124962,16 +132169,23 @@ - ** need to occur right after the database cursor. So go ahead and - ** allocate enough space, just in case. - */ -- pTabList->a[0].iCursor = iBaseCur = iDataCur = pParse->nTab++; -+ iBaseCur = iDataCur = pParse->nTab++; - iIdxCur = iDataCur+1; - pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); -+ testcase( pPk!=0 && pPk!=pTab->pIndex ); - for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ -- if( IsPrimaryKeyIndex(pIdx) && pPk!=0 ){ -+ if( pPk==pIdx ){ - iDataCur = pParse->nTab; -- pTabList->a[0].iCursor = iDataCur; - } - pParse->nTab++; - } -+ if( pUpsert ){ -+ /* On an UPSERT, reuse the same cursors already opened by INSERT */ -+ iDataCur = pUpsert->iDataCur; -+ iIdxCur = pUpsert->iIdxCur; -+ pParse->nTab = iBaseCur; -+ } -+ pTabList->a[0].iCursor = iDataCur; - - /* Allocate space for aXRef[], aRegIdx[], and aToOpen[]. - ** Initialize aXRef[] and aToOpen[] to their default values. -@@ -124988,6 +132202,8 @@ - memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pParse; - sNC.pSrcList = pTabList; -+ sNC.uNC.pUpsert = pUpsert; -+ sNC.ncFlags = NC_UUpsert; - - /* Resolve the column names in all the expressions of the - ** of the UPDATE statement. Also find the column index -@@ -125054,19 +132270,18 @@ - /* There is one entry in the aRegIdx[] array for each index on the table - ** being updated. Fill in aRegIdx[] with a register number that will hold - ** the key for accessing each index. -- ** -- ** FIXME: Be smarter about omitting indexes that use expressions. - */ - for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - int reg; -- if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){ -+ if( chngKey || hasFK>1 || pIdx==pPk -+ || indexWhereClauseMightChange(pIdx,aXRef,chngRowid) -+ ){ - reg = ++pParse->nMem; - pParse->nMem += pIdx->nColumn; - }else{ - reg = 0; - for(i=0; i<pIdx->nKeyCol; i++){ -- i16 iIdxCol = pIdx->aiColumn[i]; -- if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){ -+ if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){ - reg = ++pParse->nMem; - pParse->nMem += pIdx->nColumn; - if( (onError==OE_Replace) -@@ -125091,7 +132306,7 @@ - v = sqlite3GetVdbe(pParse); - if( v==0 ) goto update_cleanup; - if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); -- sqlite3BeginWriteOperation(pParse, 1, iDb); -+ sqlite3BeginWriteOperation(pParse, pTrigger || hasFK, iDb); - - /* Allocate required registers. */ - if( !IsVirtual(pTab) ){ -@@ -125118,7 +132333,11 @@ - */ - #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) - if( isView ){ -- sqlite3MaterializeView(pParse, pTab, pWhere, iDataCur); -+ sqlite3MaterializeView(pParse, pTab, -+ pWhere, pOrderBy, pLimit, iDataCur -+ ); -+ pOrderBy = 0; -+ pLimit = 0; - } - #endif - -@@ -125138,8 +132357,16 @@ - } - #endif - -- /* Initialize the count of updated rows */ -- if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){ -+ /* Jump to labelBreak to abandon further processing of this UPDATE */ -+ labelContinue = labelBreak = sqlite3VdbeMakeLabel(v); -+ -+ /* Not an UPSERT. Normal processing. Begin by -+ ** initialize the count of updated rows */ -+ if( (db->flags&SQLITE_CountRows)!=0 -+ && !pParse->pTriggerTab -+ && !pParse->nested -+ && pUpsert==0 -+ ){ - regRowCount = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); - } -@@ -125152,46 +132379,61 @@ - iPk = pParse->nMem+1; - pParse->nMem += nPk; - regKey = ++pParse->nMem; -- iEph = pParse->nTab++; -- -- sqlite3VdbeAddOp2(v, OP_Null, 0, iPk); -- addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk); -- sqlite3VdbeSetP4KeyInfo(pParse, pPk); -+ if( pUpsert==0 ){ -+ iEph = pParse->nTab++; -+ sqlite3VdbeAddOp3(v, OP_Null, 0, iPk, iPk+nPk-1); -+ addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk); -+ sqlite3VdbeSetP4KeyInfo(pParse, pPk); -+ } - } -- -- /* Begin the database scan. -- ** -- ** Do not consider a single-pass strategy for a multi-row update if -- ** there are any triggers or foreign keys to process, or rows may -- ** be deleted as a result of REPLACE conflict handling. Any of these -- ** things might disturb a cursor being used to scan through the table -- ** or index, causing a single-pass approach to malfunction. */ -- flags = WHERE_ONEPASS_DESIRED|WHERE_SEEK_UNIQ_TABLE; -- if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){ -- flags |= WHERE_ONEPASS_MULTIROW; -+ -+ if( pUpsert ){ -+ /* If this is an UPSERT, then all cursors have already been opened by -+ ** the outer INSERT and the data cursor should be pointing at the row -+ ** that is to be updated. So bypass the code that searches for the -+ ** row(s) to be updated. -+ */ -+ pWInfo = 0; -+ eOnePass = ONEPASS_SINGLE; -+ sqlite3ExprIfFalse(pParse, pWhere, labelBreak, SQLITE_JUMPIFNULL); -+ }else{ -+ /* Begin the database scan. -+ ** -+ ** Do not consider a single-pass strategy for a multi-row update if -+ ** there are any triggers or foreign keys to process, or rows may -+ ** be deleted as a result of REPLACE conflict handling. Any of these -+ ** things might disturb a cursor being used to scan through the table -+ ** or index, causing a single-pass approach to malfunction. */ -+ flags = WHERE_ONEPASS_DESIRED|WHERE_SEEK_UNIQ_TABLE; -+ if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){ -+ flags |= WHERE_ONEPASS_MULTIROW; -+ } -+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur); -+ if( pWInfo==0 ) goto update_cleanup; -+ -+ /* A one-pass strategy that might update more than one row may not -+ ** be used if any column of the index used for the scan is being -+ ** updated. Otherwise, if there is an index on "b", statements like -+ ** the following could create an infinite loop: -+ ** -+ ** UPDATE t1 SET b=b+1 WHERE b>? -+ ** -+ ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI -+ ** strategy that uses an index for which one or more columns are being -+ ** updated. */ -+ eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); -+ if( eOnePass!=ONEPASS_SINGLE ){ -+ sqlite3MultiWrite(pParse); -+ if( eOnePass==ONEPASS_MULTI ){ -+ int iCur = aiCurOnePass[1]; -+ if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){ -+ eOnePass = ONEPASS_OFF; -+ } -+ assert( iCur!=iDataCur || !HasRowid(pTab) ); -+ } -+ } - } -- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur); -- if( pWInfo==0 ) goto update_cleanup; - -- /* A one-pass strategy that might update more than one row may not -- ** be used if any column of the index used for the scan is being -- ** updated. Otherwise, if there is an index on "b", statements like -- ** the following could create an infinite loop: -- ** -- ** UPDATE t1 SET b=b+1 WHERE b>? -- ** -- ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI -- ** strategy that uses an index for which one or more columns are being -- ** updated. */ -- eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); -- if( eOnePass==ONEPASS_MULTI ){ -- int iCur = aiCurOnePass[1]; -- if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){ -- eOnePass = ONEPASS_OFF; -- } -- assert( iCur!=iDataCur || !HasRowid(pTab) ); -- } -- - if( HasRowid(pTab) ){ - /* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF - ** mode, write the rowid into the FIFO. In either of the one-pass modes, -@@ -125211,7 +132453,7 @@ - sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur,pPk->aiColumn[i],iPk+i); - } - if( eOnePass ){ -- sqlite3VdbeChangeToNoop(v, addrOpen); -+ if( addrOpen ) sqlite3VdbeChangeToNoop(v, addrOpen); - nKey = nPk; - regKey = iPk; - }else{ -@@ -125221,59 +132463,58 @@ - } - } - -- if( eOnePass!=ONEPASS_MULTI ){ -- sqlite3WhereEnd(pWInfo); -- } -- -- labelBreak = sqlite3VdbeMakeLabel(v); -- if( !isView ){ -- int addrOnce = 0; -- -- /* Open every index that needs updating. */ -- if( eOnePass!=ONEPASS_OFF ){ -- if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0; -- if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0; -+ if( pUpsert==0 ){ -+ if( eOnePass!=ONEPASS_MULTI ){ -+ sqlite3WhereEnd(pWInfo); - } -- -- if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){ -- addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); -+ -+ if( !isView ){ -+ int addrOnce = 0; -+ -+ /* Open every index that needs updating. */ -+ if( eOnePass!=ONEPASS_OFF ){ -+ if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0; -+ if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0; -+ } -+ -+ if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){ -+ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); -+ } -+ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, -+ aToOpen, 0, 0); -+ if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); - } -- sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, aToOpen, -- 0, 0); -- if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); -- } -- -- /* Top of the update loop */ -- if( eOnePass!=ONEPASS_OFF ){ -- if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){ -- assert( pPk ); -- sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey); -- VdbeCoverageNeverTaken(v); -- } -- if( eOnePass==ONEPASS_SINGLE ){ -- labelContinue = labelBreak; -+ -+ /* Top of the update loop */ -+ if( eOnePass!=ONEPASS_OFF ){ -+ if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){ -+ assert( pPk ); -+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey,nKey); -+ VdbeCoverage(v); -+ } -+ if( eOnePass!=ONEPASS_SINGLE ){ -+ labelContinue = sqlite3VdbeMakeLabel(v); -+ } -+ sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); -+ VdbeCoverageIf(v, pPk==0); -+ VdbeCoverageIf(v, pPk!=0); -+ }else if( pPk ){ -+ labelContinue = sqlite3VdbeMakeLabel(v); -+ sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); -+ addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey); -+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0); -+ VdbeCoverage(v); - }else{ -- labelContinue = sqlite3VdbeMakeLabel(v); -+ labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet,labelBreak, -+ regOldRowid); -+ VdbeCoverage(v); -+ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); -+ VdbeCoverage(v); - } -- sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); -- VdbeCoverageIf(v, pPk==0); -- VdbeCoverageIf(v, pPk!=0); -- }else if( pPk ){ -- labelContinue = sqlite3VdbeMakeLabel(v); -- sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); -- addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey); -- sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0); -- VdbeCoverage(v); -- }else{ -- labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak, -- regOldRowid); -- VdbeCoverage(v); -- sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); -- VdbeCoverage(v); - } - -- /* If the record number will change, set register regNewRowid to -- ** contain the new value. If the record number is not being modified, -+ /* If the rowid value will change, set register regNewRowid to -+ ** contain the new value. If the rowid is not being modified, - ** then regNewRowid is the same register as regOldRowid, which is - ** already populated. */ - assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid ); -@@ -125336,7 +132577,7 @@ - */ - testcase( i==31 ); - testcase( i==32 ); -- sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, iDataCur, regNew+i); -+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i); - }else{ - sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i); - } -@@ -125365,10 +132606,14 @@ - VdbeCoverage(v); - } - -- /* If it did not delete it, the row-trigger may still have modified -+ /* After-BEFORE-trigger-reload-loop: -+ ** If it did not delete it, the BEFORE trigger may still have modified - ** some of the columns of the row being updated. Load the values for -- ** all columns not modified by the update statement into their -- ** registers in case this has happened. -+ ** all columns not modified by the update statement into their registers -+ ** in case this has happened. Only unmodified columns are reloaded. -+ ** The values computed for modified columns use the values before the -+ ** BEFORE trigger runs. See test case trigger1-18.0 (added 2018-04-26) -+ ** for an example. - */ - for(i=0; i<pTab->nCol; i++){ - if( aXRef[i]<0 && i!=pTab->iPKey ){ -@@ -125384,7 +132629,7 @@ - assert( regOldRowid>0 ); - sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, - regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace, -- aXRef); -+ aXRef, 0); - - /* Do FK constraint checks. */ - if( hasFK ){ -@@ -125454,7 +132699,7 @@ - - /* Increment the row counter - */ -- if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){ -+ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); - } - -@@ -125481,16 +132726,15 @@ - ** maximum rowid counter values recorded while inserting into - ** autoincrement tables. - */ -- if( pParse->nested==0 && pParse->pTriggerTab==0 ){ -+ if( pParse->nested==0 && pParse->pTriggerTab==0 && pUpsert==0 ){ - sqlite3AutoincrementEnd(pParse); - } - - /* -- ** Return the number of rows that were changed. If this routine is -- ** generating code because of a call to sqlite3NestedParse(), do not -- ** invoke the callback function. -+ ** Return the number of rows that were changed, if we are tracking -+ ** that information. - */ -- if( (db->flags&SQLITE_CountRows) && !pParse->pTriggerTab && !pParse->nested ){ -+ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC); -@@ -125502,6 +132746,10 @@ - sqlite3SrcListDelete(db, pTabList); - sqlite3ExprListDelete(db, pChanges); - sqlite3ExprDelete(db, pWhere); -+#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) -+ sqlite3ExprListDelete(db, pOrderBy); -+ sqlite3ExprDelete(db, pLimit); -+#endif - return; - } - /* Make sure "isView" and other macros defined above are undefined. Otherwise -@@ -125558,10 +132806,10 @@ - int regRowid; /* Register for ephem table rowid */ - int iCsr = pSrc->a[0].iCursor; /* Cursor used for virtual table scan */ - int aDummy[2]; /* Unused arg for sqlite3WhereOkOnePass() */ -- int bOnePass; /* True to use onepass strategy */ -+ int eOnePass; /* True to use onepass strategy */ - int addr; /* Address of OP_OpenEphemeral */ - -- /* Allocate nArg registers to martial the arguments to VUpdate. Then -+ /* Allocate nArg registers in which to gather the arguments for VUpdate. Then - ** create and open the ephemeral table in which the records created from - ** these arguments will be temporarily stored. */ - assert( v ); -@@ -125577,40 +132825,58 @@ - if( pWInfo==0 ) return; - - /* Populate the argument registers. */ -- sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg); -- if( pRowid ){ -- sqlite3ExprCode(pParse, pRowid, regArg+1); -- }else{ -- sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1); -- } - for(i=0; i<pTab->nCol; i++){ - if( aXRef[i]>=0 ){ - sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i); - }else{ - sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i); -+ sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG);/* Enable sqlite3_vtab_nochange() */ - } - } -+ if( HasRowid(pTab) ){ -+ sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg); -+ if( pRowid ){ -+ sqlite3ExprCode(pParse, pRowid, regArg+1); -+ }else{ -+ sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1); -+ } -+ }else{ -+ Index *pPk; /* PRIMARY KEY index */ -+ i16 iPk; /* PRIMARY KEY column */ -+ pPk = sqlite3PrimaryKeyIndex(pTab); -+ assert( pPk!=0 ); -+ assert( pPk->nKeyCol==1 ); -+ iPk = pPk->aiColumn[0]; -+ sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, iPk, regArg); -+ sqlite3VdbeAddOp2(v, OP_SCopy, regArg+2+iPk, regArg+1); -+ } - -- bOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy); -+ eOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy); - -- if( bOnePass ){ -+ /* There is no ONEPASS_MULTI on virtual tables */ -+ assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE ); -+ -+ if( eOnePass ){ - /* If using the onepass strategy, no-op out the OP_OpenEphemeral coded -- ** above. Also, if this is a top-level parse (not a trigger), clear the -- ** multi-write flag so that the VM does not open a statement journal */ -+ ** above. */ - sqlite3VdbeChangeToNoop(v, addr); -- if( sqlite3IsToplevel(pParse) ){ -- pParse->isMultiWrite = 0; -- } -+ sqlite3VdbeAddOp1(v, OP_Close, iCsr); - }else{ - /* Create a record from the argument register contents and insert it into - ** the ephemeral table. */ -+ sqlite3MultiWrite(pParse); - sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec); -+#ifdef SQLITE_DEBUG -+ /* Signal an assert() within OP_MakeRecord that it is allowed to -+ ** accept no-change records with serial_type 10 */ -+ sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC); -+#endif - sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid); - sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid); - } - - -- if( bOnePass==0 ){ -+ if( eOnePass==ONEPASS_OFF ){ - /* End the virtual table scan */ - sqlite3WhereEnd(pWInfo); - -@@ -125630,7 +132896,7 @@ - - /* End of the ephemeral table scan. Or, if using the onepass strategy, - ** jump to here if the scan visited zero rows. */ -- if( bOnePass==0 ){ -+ if( eOnePass==ONEPASS_OFF ){ - sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v); - sqlite3VdbeJumpHere(v, addr); - sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0); -@@ -125641,6 +132907,261 @@ - #endif /* SQLITE_OMIT_VIRTUALTABLE */ - - /************** End of update.c **********************************************/ -+/************** Begin file upsert.c ******************************************/ -+/* -+** 2018-04-12 -+** -+** 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 contains code to implement various aspects of UPSERT -+** processing and handling of the Upsert object. -+*/ -+/* #include "sqliteInt.h" */ -+ -+#ifndef SQLITE_OMIT_UPSERT -+/* -+** Free a list of Upsert objects -+*/ -+SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){ -+ if( p ){ -+ sqlite3ExprListDelete(db, p->pUpsertTarget); -+ sqlite3ExprDelete(db, p->pUpsertTargetWhere); -+ sqlite3ExprListDelete(db, p->pUpsertSet); -+ sqlite3ExprDelete(db, p->pUpsertWhere); -+ sqlite3DbFree(db, p); -+ } -+} -+ -+/* -+** Duplicate an Upsert object. -+*/ -+SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3 *db, Upsert *p){ -+ if( p==0 ) return 0; -+ return sqlite3UpsertNew(db, -+ sqlite3ExprListDup(db, p->pUpsertTarget, 0), -+ sqlite3ExprDup(db, p->pUpsertTargetWhere, 0), -+ sqlite3ExprListDup(db, p->pUpsertSet, 0), -+ sqlite3ExprDup(db, p->pUpsertWhere, 0) -+ ); -+} -+ -+/* -+** Create a new Upsert object. -+*/ -+SQLITE_PRIVATE Upsert *sqlite3UpsertNew( -+ sqlite3 *db, /* Determines which memory allocator to use */ -+ ExprList *pTarget, /* Target argument to ON CONFLICT, or NULL */ -+ Expr *pTargetWhere, /* Optional WHERE clause on the target */ -+ ExprList *pSet, /* UPDATE columns, or NULL for a DO NOTHING */ -+ Expr *pWhere /* WHERE clause for the ON CONFLICT UPDATE */ -+){ -+ Upsert *pNew; -+ pNew = sqlite3DbMallocRaw(db, sizeof(Upsert)); -+ if( pNew==0 ){ -+ sqlite3ExprListDelete(db, pTarget); -+ sqlite3ExprDelete(db, pTargetWhere); -+ sqlite3ExprListDelete(db, pSet); -+ sqlite3ExprDelete(db, pWhere); -+ return 0; -+ }else{ -+ pNew->pUpsertTarget = pTarget; -+ pNew->pUpsertTargetWhere = pTargetWhere; -+ pNew->pUpsertSet = pSet; -+ pNew->pUpsertWhere = pWhere; -+ pNew->pUpsertIdx = 0; -+ } -+ return pNew; -+} -+ -+/* -+** Analyze the ON CONFLICT clause described by pUpsert. Resolve all -+** symbols in the conflict-target. -+** -+** Return SQLITE_OK if everything works, or an error code is something -+** is wrong. -+*/ -+SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( -+ Parse *pParse, /* The parsing context */ -+ SrcList *pTabList, /* Table into which we are inserting */ -+ Upsert *pUpsert /* The ON CONFLICT clauses */ -+){ -+ Table *pTab; /* That table into which we are inserting */ -+ int rc; /* Result code */ -+ int iCursor; /* Cursor used by pTab */ -+ Index *pIdx; /* One of the indexes of pTab */ -+ ExprList *pTarget; /* The conflict-target clause */ -+ Expr *pTerm; /* One term of the conflict-target clause */ -+ NameContext sNC; /* Context for resolving symbolic names */ -+ Expr sCol[2]; /* Index column converted into an Expr */ -+ -+ assert( pTabList->nSrc==1 ); -+ assert( pTabList->a[0].pTab!=0 ); -+ assert( pUpsert!=0 ); -+ assert( pUpsert->pUpsertTarget!=0 ); -+ -+ /* Resolve all symbolic names in the conflict-target clause, which -+ ** includes both the list of columns and the optional partial-index -+ ** WHERE clause. -+ */ -+ memset(&sNC, 0, sizeof(sNC)); -+ sNC.pParse = pParse; -+ sNC.pSrcList = pTabList; -+ rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); -+ if( rc ) return rc; -+ rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); -+ if( rc ) return rc; -+ -+ /* Check to see if the conflict target matches the rowid. */ -+ pTab = pTabList->a[0].pTab; -+ pTarget = pUpsert->pUpsertTarget; -+ iCursor = pTabList->a[0].iCursor; -+ if( HasRowid(pTab) -+ && pTarget->nExpr==1 -+ && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN -+ && pTerm->iColumn==XN_ROWID -+ ){ -+ /* The conflict-target is the rowid of the primary table */ -+ assert( pUpsert->pUpsertIdx==0 ); -+ return SQLITE_OK; -+ } -+ -+ /* Initialize sCol[0..1] to be an expression parse tree for a -+ ** single column of an index. The sCol[0] node will be the TK_COLLATE -+ ** operator and sCol[1] will be the TK_COLUMN operator. Code below -+ ** will populate the specific collation and column number values -+ ** prior to comparing against the conflict-target expression. -+ */ -+ memset(sCol, 0, sizeof(sCol)); -+ sCol[0].op = TK_COLLATE; -+ sCol[0].pLeft = &sCol[1]; -+ sCol[1].op = TK_COLUMN; -+ sCol[1].iTable = pTabList->a[0].iCursor; -+ -+ /* Check for matches against other indexes */ -+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ -+ int ii, jj, nn; -+ if( !IsUniqueIndex(pIdx) ) continue; -+ if( pTarget->nExpr!=pIdx->nKeyCol ) continue; -+ if( pIdx->pPartIdxWhere ){ -+ if( pUpsert->pUpsertTargetWhere==0 ) continue; -+ if( sqlite3ExprCompare(pParse, pUpsert->pUpsertTargetWhere, -+ pIdx->pPartIdxWhere, iCursor)!=0 ){ -+ continue; -+ } -+ } -+ nn = pIdx->nKeyCol; -+ for(ii=0; ii<nn; ii++){ -+ Expr *pExpr; -+ sCol[0].u.zToken = (char*)pIdx->azColl[ii]; -+ if( pIdx->aiColumn[ii]==XN_EXPR ){ -+ assert( pIdx->aColExpr!=0 ); -+ assert( pIdx->aColExpr->nExpr>ii ); -+ pExpr = pIdx->aColExpr->a[ii].pExpr; -+ if( pExpr->op!=TK_COLLATE ){ -+ sCol[0].pLeft = pExpr; -+ pExpr = &sCol[0]; -+ } -+ }else{ -+ sCol[0].pLeft = &sCol[1]; -+ sCol[1].iColumn = pIdx->aiColumn[ii]; -+ pExpr = &sCol[0]; -+ } -+ for(jj=0; jj<nn; jj++){ -+ if( sqlite3ExprCompare(pParse, pTarget->a[jj].pExpr, pExpr,iCursor)<2 ){ -+ break; /* Column ii of the index matches column jj of target */ -+ } -+ } -+ if( jj>=nn ){ -+ /* The target contains no match for column jj of the index */ -+ break; -+ } -+ } -+ if( ii<nn ){ -+ /* Column ii of the index did not match any term of the conflict target. -+ ** Continue the search with the next index. */ -+ continue; -+ } -+ pUpsert->pUpsertIdx = pIdx; -+ return SQLITE_OK; -+ } -+ sqlite3ErrorMsg(pParse, "ON CONFLICT clause does not match any " -+ "PRIMARY KEY or UNIQUE constraint"); -+ return SQLITE_ERROR; -+} -+ -+/* -+** Generate bytecode that does an UPDATE as part of an upsert. -+** -+** If pIdx is NULL, then the UNIQUE constraint that failed was the IPK. -+** In this case parameter iCur is a cursor open on the table b-tree that -+** currently points to the conflicting table row. Otherwise, if pIdx -+** is not NULL, then pIdx is the constraint that failed and iCur is a -+** cursor points to the conflicting row. -+*/ -+SQLITE_PRIVATE void sqlite3UpsertDoUpdate( -+ Parse *pParse, /* The parsing and code-generating context */ -+ Upsert *pUpsert, /* The ON CONFLICT clause for the upsert */ -+ Table *pTab, /* The table being updated */ -+ Index *pIdx, /* The UNIQUE constraint that failed */ -+ int iCur /* Cursor for pIdx (or pTab if pIdx==NULL) */ -+){ -+ Vdbe *v = pParse->pVdbe; -+ sqlite3 *db = pParse->db; -+ SrcList *pSrc; /* FROM clause for the UPDATE */ -+ int iDataCur; -+ -+ assert( v!=0 ); -+ assert( pUpsert!=0 ); -+ VdbeNoopComment((v, "Begin DO UPDATE of UPSERT")); -+ iDataCur = pUpsert->iDataCur; -+ if( pIdx && iCur!=iDataCur ){ -+ if( HasRowid(pTab) ){ -+ int regRowid = sqlite3GetTempReg(pParse); -+ sqlite3VdbeAddOp2(v, OP_IdxRowid, iCur, regRowid); -+ sqlite3VdbeAddOp3(v, OP_SeekRowid, iDataCur, 0, regRowid); -+ VdbeCoverage(v); -+ sqlite3ReleaseTempReg(pParse, regRowid); -+ }else{ -+ Index *pPk = sqlite3PrimaryKeyIndex(pTab); -+ int nPk = pPk->nKeyCol; -+ int iPk = pParse->nMem+1; -+ int i; -+ pParse->nMem += nPk; -+ for(i=0; i<nPk; i++){ -+ int k; -+ assert( pPk->aiColumn[i]>=0 ); -+ k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]); -+ sqlite3VdbeAddOp3(v, OP_Column, iCur, k, iPk+i); -+ VdbeComment((v, "%s.%s", pIdx->zName, -+ pTab->aCol[pPk->aiColumn[i]].zName)); -+ } -+ sqlite3VdbeVerifyAbortable(v, OE_Abort); -+ i = sqlite3VdbeAddOp4Int(v, OP_Found, iDataCur, 0, iPk, nPk); -+ VdbeCoverage(v); -+ sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CORRUPT, OE_Abort, 0, -+ "corrupt database", P4_STATIC); -+ sqlite3VdbeJumpHere(v, i); -+ } -+ } -+ /* pUpsert does not own pUpsertSrc - the outer INSERT statement does. So -+ ** we have to make a copy before passing it down into sqlite3Update() */ -+ pSrc = sqlite3SrcListDup(db, pUpsert->pUpsertSrc, 0); -+ sqlite3Update(pParse, pSrc, pUpsert->pUpsertSet, -+ pUpsert->pUpsertWhere, OE_Abort, 0, 0, pUpsert); -+ pUpsert->pUpsertSet = 0; /* Will have been deleted by sqlite3Update() */ -+ pUpsert->pUpsertWhere = 0; /* Will have been deleted by sqlite3Update() */ -+ VdbeNoopComment((v, "End DO UPDATE of UPSERT")); -+} -+ -+#endif /* SQLITE_OMIT_UPSERT */ -+ -+/************** End of upsert.c **********************************************/ - /************** Begin file vacuum.c ******************************************/ - /* - ** 2003 April 6 -@@ -125683,8 +133204,14 @@ - while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ - const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0); - assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 ); -- if( zSubSql ){ -- assert( zSubSql[0]!='S' ); -+ /* The secondary SQL must be one of CREATE TABLE, CREATE INDEX, -+ ** or INSERT. Historically there have been attacks that first -+ ** corrupt the sqlite_master.sql field with other kinds of statements -+ ** then run VACUUM to get those statements to execute at inappropriate -+ ** times. */ -+ if( zSubSql -+ && (strncmp(zSubSql,"CRE",3)==0 || strncmp(zSubSql,"INS",3)==0) -+ ){ - rc = execSql(db, pzErrMsg, zSubSql); - if( rc!=SQLITE_OK ) break; - } -@@ -125774,7 +133301,8 @@ - int rc = SQLITE_OK; /* Return code from service routines */ - Btree *pMain; /* The database being vacuumed */ - Btree *pTemp; /* The temporary database we vacuum into */ -- int saved_flags; /* Saved value of the db->flags */ -+ u16 saved_mDbFlags; /* Saved value of db->mDbFlags */ -+ u32 saved_flags; /* Saved value of db->flags */ - int saved_nChange; /* Saved value of db->nChange */ - int saved_nTotalChange; /* Saved value of db->nTotalChange */ - u8 saved_mTrace; /* Saved trace settings */ -@@ -125797,12 +133325,14 @@ - ** restored before returning. Then set the writable-schema flag, and - ** disable CHECK and foreign key constraints. */ - saved_flags = db->flags; -+ saved_mDbFlags = db->mDbFlags; - saved_nChange = db->nChange; - saved_nTotalChange = db->nTotalChange; - saved_mTrace = db->mTrace; -- db->flags |= (SQLITE_WriteSchema | SQLITE_IgnoreChecks -- | SQLITE_PreferBuiltin | SQLITE_Vacuum); -- db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows); -+ db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks; -+ db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum; -+ db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder -+ | SQLITE_Defensive | SQLITE_CountRows); - db->mTrace = 0; - - zDbMain = db->aDb[iDb].zDbSName; -@@ -125860,7 +133390,7 @@ - */ - rc = execSql(db, pzErrMsg, "BEGIN"); - if( rc!=SQLITE_OK ) goto end_of_vacuum; -- rc = sqlite3BtreeBeginTrans(pMain, 2); -+ rc = sqlite3BtreeBeginTrans(pMain, 2, 0); - if( rc!=SQLITE_OK ) goto end_of_vacuum; - - /* Do not attempt to change the page size for a WAL database */ -@@ -125895,7 +133425,7 @@ - if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = execSqlF(db, pzErrMsg, - "SELECT sql FROM \"%w\".sqlite_master" -- " WHERE type='index' AND length(sql)>10", -+ " WHERE type='index'", - zDbMain - ); - if( rc!=SQLITE_OK ) goto end_of_vacuum; -@@ -125912,8 +133442,8 @@ - "WHERE type='table'AND coalesce(rootpage,1)>0", - zDbMain - ); -- assert( (db->flags & SQLITE_Vacuum)!=0 ); -- db->flags &= ~SQLITE_Vacuum; -+ assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 ); -+ db->mDbFlags &= ~DBFLAG_Vacuum; - if( rc!=SQLITE_OK ) goto end_of_vacuum; - - /* Copy the triggers, views, and virtual tables from the main database -@@ -125981,6 +133511,7 @@ - end_of_vacuum: - /* Restore the original value of db->flags */ - db->init.iDb = 0; -+ db->mDbFlags = saved_mDbFlags; - db->flags = saved_flags; - db->nChange = saved_nChange; - db->nTotalChange = saved_nTotalChange; -@@ -126057,8 +133588,10 @@ - ){ - Module *pMod; - int nName = sqlite3Strlen30(zName); -- pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1); -- if( pMod ){ -+ pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1); -+ if( pMod==0 ){ -+ sqlite3OomFault(db); -+ }else{ - Module *pDel; - char *zCopy = (char *)(&pMod[1]); - memcpy(zCopy, zName, nName+1); -@@ -126275,7 +133808,7 @@ - assert( sqlite3_mutex_held(db->mutex) ); - - if( p ){ -- sqlite3ExpirePreparedStatements(db); -+ sqlite3ExpirePreparedStatements(db, 0); - do { - VTable *pNext = p->pNext; - sqlite3VtabUnlock(p); -@@ -126341,7 +133874,6 @@ - Token *pModuleName, /* Name of the module for the virtual table */ - int ifNotExists /* No error if the table already exists */ - ){ -- int iDb; /* The database the table is being created in */ - Table *pTable; /* The new virtual table */ - sqlite3 *db; /* Database connection */ - -@@ -126351,8 +133883,6 @@ - assert( 0==pTable->pIndex ); - - db = pParse->db; -- iDb = sqlite3SchemaToIndex(db, pTable->pSchema); -- assert( iDb>=0 ); - - assert( pTable->nModuleArg==0 ); - addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName)); -@@ -126372,6 +133902,8 @@ - ** The second call, to obtain permission to create the table, is made now. - */ - if( pTable->azModuleArg ){ -+ int iDb = sqlite3SchemaToIndex(db, pTable->pSchema); -+ assert( iDb>=0 ); /* The database the table is being created in */ - sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, - pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName); - } -@@ -126533,13 +134065,14 @@ - } - } - -- zModuleName = sqlite3MPrintf(db, "%s", pTab->zName); -+ zModuleName = sqlite3DbStrDup(db, pTab->zName); - if( !zModuleName ){ - return SQLITE_NOMEM_BKPT; - } - -- pVTable = sqlite3DbMallocZero(db, sizeof(VTable)); -+ pVTable = sqlite3MallocZero(sizeof(VTable)); - if( !pVTable ){ -+ sqlite3OomFault(db); - sqlite3DbFree(db, zModuleName); - return SQLITE_NOMEM_BKPT; - } -@@ -126659,6 +134192,7 @@ - rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr); - if( rc!=SQLITE_OK ){ - sqlite3ErrorMsg(pParse, "%s", zErr); -+ pParse->rc = rc; - } - sqlite3DbFree(db, zErr); - } -@@ -126748,10 +134282,10 @@ - */ - SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ - VtabCtx *pCtx; -- Parse *pParse; - int rc = SQLITE_OK; - Table *pTab; - char *zErr = 0; -+ Parse sParse; - - #ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){ -@@ -126768,56 +134302,56 @@ - pTab = pCtx->pTab; - assert( IsVirtual(pTab) ); - -- pParse = sqlite3StackAllocZero(db, sizeof(*pParse)); -- if( pParse==0 ){ -- rc = SQLITE_NOMEM_BKPT; -- }else{ -- pParse->declareVtab = 1; -- pParse->db = db; -- pParse->nQueryLoop = 1; -- -- if( SQLITE_OK==sqlite3RunParser(pParse, zCreateTable, &zErr) -- && pParse->pNewTable -- && !db->mallocFailed -- && !pParse->pNewTable->pSelect -- && !IsVirtual(pParse->pNewTable) -- ){ -- if( !pTab->aCol ){ -- Table *pNew = pParse->pNewTable; -- Index *pIdx; -- pTab->aCol = pNew->aCol; -- pTab->nCol = pNew->nCol; -- pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); -- pNew->nCol = 0; -- pNew->aCol = 0; -- assert( pTab->pIndex==0 ); -- if( !HasRowid(pNew) && pCtx->pVTable->pMod->pModule->xUpdate!=0 ){ -- rc = SQLITE_ERROR; -- } -- pIdx = pNew->pIndex; -- if( pIdx ){ -- assert( pIdx->pNext==0 ); -- pTab->pIndex = pIdx; -- pNew->pIndex = 0; -- pIdx->pTable = pTab; -- } -+ memset(&sParse, 0, sizeof(sParse)); -+ sParse.eParseMode = PARSE_MODE_DECLARE_VTAB; -+ sParse.db = db; -+ sParse.nQueryLoop = 1; -+ if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable, &zErr) -+ && sParse.pNewTable -+ && !db->mallocFailed -+ && !sParse.pNewTable->pSelect -+ && !IsVirtual(sParse.pNewTable) -+ ){ -+ if( !pTab->aCol ){ -+ Table *pNew = sParse.pNewTable; -+ Index *pIdx; -+ pTab->aCol = pNew->aCol; -+ pTab->nCol = pNew->nCol; -+ pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); -+ pNew->nCol = 0; -+ pNew->aCol = 0; -+ assert( pTab->pIndex==0 ); -+ assert( HasRowid(pNew) || sqlite3PrimaryKeyIndex(pNew)!=0 ); -+ if( !HasRowid(pNew) -+ && pCtx->pVTable->pMod->pModule->xUpdate!=0 -+ && sqlite3PrimaryKeyIndex(pNew)->nKeyCol!=1 -+ ){ -+ /* WITHOUT ROWID virtual tables must either be read-only (xUpdate==0) -+ ** or else must have a single-column PRIMARY KEY */ -+ rc = SQLITE_ERROR; - } -- pCtx->bDeclared = 1; -- }else{ -- sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr); -- sqlite3DbFree(db, zErr); -- rc = SQLITE_ERROR; -+ pIdx = pNew->pIndex; -+ if( pIdx ){ -+ assert( pIdx->pNext==0 ); -+ pTab->pIndex = pIdx; -+ pNew->pIndex = 0; -+ pIdx->pTable = pTab; -+ } - } -- pParse->declareVtab = 0; -- -- if( pParse->pVdbe ){ -- sqlite3VdbeFinalize(pParse->pVdbe); -- } -- sqlite3DeleteTable(db, pParse->pNewTable); -- sqlite3ParserReset(pParse); -- sqlite3StackFree(db, pParse); -+ pCtx->bDeclared = 1; -+ }else{ -+ sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr); -+ sqlite3DbFree(db, zErr); -+ rc = SQLITE_ERROR; - } -+ sParse.eParseMode = PARSE_MODE_NORMAL; - -+ if( sParse.pVdbe ){ -+ sqlite3VdbeFinalize(sParse.pVdbe); -+ } -+ sqlite3DeleteTable(db, sParse.pNewTable); -+ sqlite3ParserReset(&sParse); -+ - assert( (rc&0xff)==rc ); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); -@@ -127060,14 +134594,11 @@ - void *pArg = 0; - FuncDef *pNew; - int rc = 0; -- char *zLowerName; -- unsigned char *z; - -- - /* Check to see the left operand is a column in a virtual table */ - if( NEVER(pExpr==0) ) return pDef; - if( pExpr->op!=TK_COLUMN ) return pDef; -- pTab = pExpr->pTab; -+ pTab = pExpr->y.pTab; - if( pTab==0 ) return pDef; - if( !IsVirtual(pTab) ) return pDef; - pVtab = sqlite3GetVTable(db, pTab)->pVtab; -@@ -127077,16 +134608,22 @@ - if( pMod->xFindFunction==0 ) return pDef; - - /* Call the xFindFunction method on the virtual table implementation -- ** to see if the implementation wants to overload this function -+ ** to see if the implementation wants to overload this function. -+ ** -+ ** Though undocumented, we have historically always invoked xFindFunction -+ ** with an all lower-case function name. Continue in this tradition to -+ ** avoid any chance of an incompatibility. - */ -- zLowerName = sqlite3DbStrDup(db, pDef->zName); -- if( zLowerName ){ -- for(z=(unsigned char*)zLowerName; *z; z++){ -- *z = sqlite3UpperToLower[*z]; -+#ifdef SQLITE_DEBUG -+ { -+ int i; -+ for(i=0; pDef->zName[i]; i++){ -+ unsigned char x = (unsigned char)pDef->zName[i]; -+ assert( x==sqlite3UpperToLower[x] ); - } -- rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xSFunc, &pArg); -- sqlite3DbFree(db, zLowerName); - } -+#endif -+ rc = pMod->xFindFunction(pVtab, nArg, pDef->zName, &xSFunc, &pArg); - if( rc==0 ){ - return pDef; - } -@@ -127298,7 +134835,7 @@ - ** Trace output macros - */ - #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) --/***/ int sqlite3WhereTrace; -+/***/ extern int sqlite3WhereTrace; - #endif - #if defined(SQLITE_DEBUG) \ - && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) -@@ -127361,6 +134898,8 @@ - struct InLoop { - int iCur; /* The VDBE cursor used by this IN operator */ - int addrInTop; /* Top of the IN loop */ -+ int iBase; /* Base register of multi-key index record */ -+ int nPrefix; /* Number of prior entires in the key */ - u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */ - } *aInLoop; /* Information about each nested IN operator */ - } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */ -@@ -127599,6 +135138,7 @@ - WhereInfo *pWInfo; /* WHERE clause processing context */ - WhereClause *pOuter; /* Outer conjunction */ - u8 op; /* Split operator. TK_AND or TK_OR */ -+ u8 hasOr; /* True if any a[].eOperator is WO_OR */ - int nTerm; /* Number of terms */ - int nSlot; /* Number of entries in a[] */ - WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */ -@@ -127678,6 +135218,7 @@ - int nRecValid; /* Number of valid fields currently in pRec */ - #endif - unsigned int bldFlags; /* SQLITE_BLDF_* flags */ -+ unsigned int iPlanLimit; /* Search limiter */ - }; - - /* Allowed values for WhereLoopBuider.bldFlags */ -@@ -127684,6 +135225,26 @@ - #define SQLITE_BLDF_INDEXED 0x0001 /* An index is used */ - #define SQLITE_BLDF_UNIQUE 0x0002 /* All keys of a UNIQUE index used */ - -+/* The WhereLoopBuilder.iPlanLimit is used to limit the number of -+** index+constraint combinations the query planner will consider for a -+** particular query. If this parameter is unlimited, then certain -+** pathological queries can spend excess time in the sqlite3WhereBegin() -+** routine. The limit is high enough that is should not impact real-world -+** queries. -+** -+** SQLITE_QUERY_PLANNER_LIMIT is the baseline limit. The limit is -+** increased by SQLITE_QUERY_PLANNER_LIMIT_INCR before each term of the FROM -+** clause is processed, so that every table in a join is guaranteed to be -+** able to propose a some index+constraint combinations even if the initial -+** baseline limit was exhausted by prior tables of the join. -+*/ -+#ifndef SQLITE_QUERY_PLANNER_LIMIT -+# define SQLITE_QUERY_PLANNER_LIMIT 20000 -+#endif -+#ifndef SQLITE_QUERY_PLANNER_LIMIT_INCR -+# define SQLITE_QUERY_PLANNER_LIMIT_INCR 1000 -+#endif -+ - /* - ** The WHERE clause processing routine has two halves. The - ** first part does the start of the WHERE loop and the second -@@ -127746,12 +135307,10 @@ - Parse *pParse, /* Parse context */ - SrcList *pTabList, /* Table list this loop refers to */ - WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ -- int iLevel, /* Value for "level" column of output */ -- int iFrom, /* Value for "from" column of output */ - u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ - ); - #else --# define sqlite3WhereExplainOneScan(u,v,w,x,y,z) 0 -+# define sqlite3WhereExplainOneScan(u,v,w,x) 0 - #endif /* SQLITE_OMIT_EXPLAIN */ - #ifdef SQLITE_ENABLE_STMT_SCANSTATUS - SQLITE_PRIVATE void sqlite3WhereAddScanStatus( -@@ -127774,6 +135333,7 @@ - SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*); - SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8); - SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*); -+SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*); - SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*); - SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*); - SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); -@@ -127794,7 +135354,6 @@ - ** WO_LE == SQLITE_INDEX_CONSTRAINT_LE - ** WO_GT == SQLITE_INDEX_CONSTRAINT_GT - ** WO_GE == SQLITE_INDEX_CONSTRAINT_GE --** WO_MATCH == SQLITE_INDEX_CONSTRAINT_MATCH - */ - #define WO_IN 0x0001 - #define WO_EQ 0x0002 -@@ -127802,7 +135361,7 @@ - #define WO_LE (WO_EQ<<(TK_LE-TK_EQ)) - #define WO_GT (WO_EQ<<(TK_GT-TK_EQ)) - #define WO_GE (WO_EQ<<(TK_GE-TK_EQ)) --#define WO_MATCH 0x0040 -+#define WO_AUX 0x0040 /* Op useful to virtual tables only */ - #define WO_IS 0x0080 - #define WO_ISNULL 0x0100 - #define WO_OR 0x0200 /* Two or more OR-connected terms */ -@@ -127837,6 +135396,7 @@ - #define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */ - #define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/ - #define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */ -+#define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */ - - /************** End of whereInt.h ********************************************/ - /************** Continuing where we left off in wherecode.c ******************/ -@@ -127872,23 +135432,23 @@ - int i; - - assert( nTerm>=1 ); -- if( bAnd ) sqlite3StrAccumAppend(pStr, " AND ", 5); -+ if( bAnd ) sqlite3_str_append(pStr, " AND ", 5); - -- if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1); -+ if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1); - for(i=0; i<nTerm; i++){ -- if( i ) sqlite3StrAccumAppend(pStr, ",", 1); -- sqlite3StrAccumAppendAll(pStr, explainIndexColumnName(pIdx, iTerm+i)); -+ if( i ) sqlite3_str_append(pStr, ",", 1); -+ sqlite3_str_appendall(pStr, explainIndexColumnName(pIdx, iTerm+i)); - } -- if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1); -+ if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1); - -- sqlite3StrAccumAppend(pStr, zOp, 1); -+ sqlite3_str_append(pStr, zOp, 1); - -- if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1); -+ if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1); - for(i=0; i<nTerm; i++){ -- if( i ) sqlite3StrAccumAppend(pStr, ",", 1); -- sqlite3StrAccumAppend(pStr, "?", 1); -+ if( i ) sqlite3_str_append(pStr, ",", 1); -+ sqlite3_str_append(pStr, "?", 1); - } -- if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1); -+ if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1); - } - - /* -@@ -127912,11 +135472,11 @@ - int i, j; - - if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return; -- sqlite3StrAccumAppend(pStr, " (", 2); -+ sqlite3_str_append(pStr, " (", 2); - for(i=0; i<nEq; i++){ - const char *z = explainIndexColumnName(pIndex, i); -- if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5); -- sqlite3XPrintf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z); -+ if( i ) sqlite3_str_append(pStr, " AND ", 5); -+ sqlite3_str_appendf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z); - } - - j = i; -@@ -127927,7 +135487,7 @@ - if( pLoop->wsFlags&WHERE_TOP_LIMIT ){ - explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<"); - } -- sqlite3StrAccumAppend(pStr, ")", 1); -+ sqlite3_str_append(pStr, ")", 1); - } - - /* -@@ -127943,19 +135503,16 @@ - Parse *pParse, /* Parse context */ - SrcList *pTabList, /* Table list this loop refers to */ - WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ -- int iLevel, /* Value for "level" column of output */ -- int iFrom, /* Value for "from" column of output */ - u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ - ){ - int ret = 0; - #if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS) -- if( pParse->explain==2 ) -+ if( sqlite3ParseToplevel(pParse)->explain==2 ) - #endif - { - struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; - Vdbe *v = pParse->pVdbe; /* VM being constructed */ - sqlite3 *db = pParse->db; /* Database handle */ -- int iId = pParse->iSelectId; /* Select id (left-most output column) */ - int isSearch; /* True for a SEARCH. False for SCAN. */ - WhereLoop *pLoop; /* The controlling WhereLoop object */ - u32 flags; /* Flags that describe this loop */ -@@ -127972,15 +135529,15 @@ - || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); - - sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); -- sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN"); -+ sqlite3_str_appendall(&str, isSearch ? "SEARCH" : "SCAN"); - if( pItem->pSelect ){ -- sqlite3XPrintf(&str, " SUBQUERY %d", pItem->iSelectId); -+ sqlite3_str_appendf(&str, " SUBQUERY %u", pItem->pSelect->selId); - }else{ -- sqlite3XPrintf(&str, " TABLE %s", pItem->zName); -+ sqlite3_str_appendf(&str, " TABLE %s", pItem->zName); - } - - if( pItem->zAlias ){ -- sqlite3XPrintf(&str, " AS %s", pItem->zAlias); -+ sqlite3_str_appendf(&str, " AS %s", pItem->zAlias); - } - if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ - const char *zFmt = 0; -@@ -128003,8 +135560,8 @@ - zFmt = "INDEX %s"; - } - if( zFmt ){ -- sqlite3StrAccumAppend(&str, " USING ", 7); -- sqlite3XPrintf(&str, zFmt, pIdx->zName); -+ sqlite3_str_append(&str, " USING ", 7); -+ sqlite3_str_appendf(&str, zFmt, pIdx->zName); - explainIndexRange(&str, pLoop); - } - }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ -@@ -128019,23 +135576,26 @@ - assert( flags&WHERE_TOP_LIMIT); - zRangeOp = "<"; - } -- sqlite3XPrintf(&str, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp); -+ sqlite3_str_appendf(&str, -+ " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp); - } - #ifndef SQLITE_OMIT_VIRTUALTABLE - else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ -- sqlite3XPrintf(&str, " VIRTUAL TABLE INDEX %d:%s", -+ sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s", - pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); - } - #endif - #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS - if( pLoop->nOut>=10 ){ -- sqlite3XPrintf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut)); -+ sqlite3_str_appendf(&str, " (~%llu rows)", -+ sqlite3LogEstToInt(pLoop->nOut)); - }else{ -- sqlite3StrAccumAppend(&str, " (~1 row)", 9); -+ sqlite3_str_append(&str, " (~1 row)", 9); - } - #endif - zMsg = sqlite3StrAccumFinish(&str); -- ret = sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg,P4_DYNAMIC); -+ ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), -+ pParse->addrExplain, 0, zMsg,P4_DYNAMIC); - } - return ret; - } -@@ -128115,8 +135675,8 @@ - */ - static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ - int nLoop = 0; -- while( ALWAYS(pTerm!=0) -- && (pTerm->wtFlags & TERM_CODED)==0 -+ assert( pTerm!=0 ); -+ while( (pTerm->wtFlags & TERM_CODED)==0 - && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin)) - && (pLevel->notReady & pTerm->prereqAll)==0 - ){ -@@ -128127,6 +135687,7 @@ - } - if( pTerm->iParent<0 ) break; - pTerm = &pTerm->pWC->a[pTerm->iParent]; -+ assert( pTerm!=0 ); - pTerm->nChild--; - if( pTerm->nChild!=0 ) break; - nLoop++; -@@ -128167,7 +135728,6 @@ - /* Code the OP_Affinity opcode if there is anything left to do. */ - if( n>0 ){ - sqlite3VdbeAddOp4(v, OP_Affinity, base, n, 0, zAff, n); -- sqlite3ExprCacheAffinityChange(pParse, base, n); - } - } - -@@ -128197,7 +135757,103 @@ - } - } - -+ - /* -+** pX is an expression of the form: (vector) IN (SELECT ...) -+** In other words, it is a vector IN operator with a SELECT clause on the -+** LHS. But not all terms in the vector are indexable and the terms might -+** not be in the correct order for indexing. -+** -+** This routine makes a copy of the input pX expression and then adjusts -+** the vector on the LHS with corresponding changes to the SELECT so that -+** the vector contains only index terms and those terms are in the correct -+** order. The modified IN expression is returned. The caller is responsible -+** for deleting the returned expression. -+** -+** Example: -+** -+** CREATE TABLE t1(a,b,c,d,e,f); -+** CREATE INDEX t1x1 ON t1(e,c); -+** SELECT * FROM t1 WHERE (a,b,c,d,e) IN (SELECT v,w,x,y,z FROM t2) -+** \_______________________________________/ -+** The pX expression -+** -+** Since only columns e and c can be used with the index, in that order, -+** the modified IN expression that is returned will be: -+** -+** (e,c) IN (SELECT z,x FROM t2) -+** -+** The reduced pX is different from the original (obviously) and thus is -+** only used for indexing, to improve performance. The original unaltered -+** IN expression must also be run on each output row for correctness. -+*/ -+static Expr *removeUnindexableInClauseTerms( -+ Parse *pParse, /* The parsing context */ -+ int iEq, /* Look at loop terms starting here */ -+ WhereLoop *pLoop, /* The current loop */ -+ Expr *pX /* The IN expression to be reduced */ -+){ -+ sqlite3 *db = pParse->db; -+ Expr *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 */ -+ ExprList *pRhs = 0; /* New RHS after modifications */ -+ ExprList *pLhs = 0; /* New LHS after mods */ -+ int i; /* Loop counter */ -+ Select *pSelect; /* Pointer to the SELECT on the RHS */ -+ -+ for(i=iEq; i<pLoop->nLTerm; i++){ -+ if( pLoop->aLTerm[i]->pExpr==pX ){ -+ int iField = pLoop->aLTerm[i]->iField - 1; -+ if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ -+ pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); -+ pOrigRhs->a[iField].pExpr = 0; -+ assert( pOrigLhs->a[iField].pExpr!=0 ); -+ pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr); -+ pOrigLhs->a[iField].pExpr = 0; -+ } -+ } -+ sqlite3ExprListDelete(db, pOrigRhs); -+ sqlite3ExprListDelete(db, pOrigLhs); -+ pNew->pLeft->x.pList = pLhs; -+ pNew->x.pSelect->pEList = pRhs; -+ if( pLhs && pLhs->nExpr==1 ){ -+ /* Take care here not to generate a TK_VECTOR containing only a -+ ** single value. Since the parser never creates such a vector, some -+ ** of the subroutines do not handle this case. */ -+ Expr *p = pLhs->a[0].pExpr; -+ pLhs->a[0].pExpr = 0; -+ sqlite3ExprDelete(db, pNew->pLeft); -+ pNew->pLeft = p; -+ } -+ pSelect = pNew->x.pSelect; -+ if( pSelect->pOrderBy ){ -+ /* If the SELECT statement has an ORDER BY clause, zero the -+ ** iOrderByCol variables. These are set to non-zero when an -+ ** ORDER BY term exactly matches one of the terms of the -+ ** result-set. Since the result-set of the SELECT statement may -+ ** have been modified or reordered, these variables are no longer -+ ** set correctly. Since setting them is just an optimization, -+ ** it's easiest just to zero them here. */ -+ ExprList *pOrderBy = pSelect->pOrderBy; -+ for(i=0; i<pOrderBy->nExpr; i++){ -+ pOrderBy->a[i].u.x.iOrderByCol = 0; -+ } -+ } -+ -+#if 0 -+ printf("For indexing, change the IN expr:\n"); -+ sqlite3TreeViewExpr(0, pX, 0); -+ printf("Into:\n"); -+ sqlite3TreeViewExpr(0, pNew, 0); -+#endif -+ } -+ return pNew; -+} -+ -+ -+/* - ** Generate code for a single equality term of the WHERE clause. An equality - ** term can be either X=expr or X IN (...). pTerm is the term to be - ** coded. -@@ -128259,68 +135915,23 @@ - } - } - for(i=iEq;i<pLoop->nLTerm; i++){ -- if( ALWAYS(pLoop->aLTerm[i]) && pLoop->aLTerm[i]->pExpr==pX ) nEq++; -+ assert( pLoop->aLTerm[i]!=0 ); -+ if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; - } - - if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){ - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0); - }else{ -- Select *pSelect = pX->x.pSelect; - sqlite3 *db = pParse->db; -- u16 savedDbOptFlags = db->dbOptFlags; -- ExprList *pOrigRhs = pSelect->pEList; -- ExprList *pOrigLhs = pX->pLeft->x.pList; -- ExprList *pRhs = 0; /* New Select.pEList for RHS */ -- ExprList *pLhs = 0; /* New pX->pLeft vector */ -+ pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); - -- for(i=iEq;i<pLoop->nLTerm; i++){ -- if( pLoop->aLTerm[i]->pExpr==pX ){ -- int iField = pLoop->aLTerm[i]->iField - 1; -- Expr *pNewRhs = sqlite3ExprDup(db, pOrigRhs->a[iField].pExpr, 0); -- Expr *pNewLhs = sqlite3ExprDup(db, pOrigLhs->a[iField].pExpr, 0); -- -- pRhs = sqlite3ExprListAppend(pParse, pRhs, pNewRhs); -- pLhs = sqlite3ExprListAppend(pParse, pLhs, pNewLhs); -- } -- } - if( !db->mallocFailed ){ -- Expr *pLeft = pX->pLeft; -- -- if( pSelect->pOrderBy ){ -- /* If the SELECT statement has an ORDER BY clause, zero the -- ** iOrderByCol variables. These are set to non-zero when an -- ** ORDER BY term exactly matches one of the terms of the -- ** result-set. Since the result-set of the SELECT statement may -- ** have been modified or reordered, these variables are no longer -- ** set correctly. Since setting them is just an optimization, -- ** it's easiest just to zero them here. */ -- ExprList *pOrderBy = pSelect->pOrderBy; -- for(i=0; i<pOrderBy->nExpr; i++){ -- pOrderBy->a[i].u.x.iOrderByCol = 0; -- } -- } -- -- /* Take care here not to generate a TK_VECTOR containing only a -- ** single value. Since the parser never creates such a vector, some -- ** of the subroutines do not handle this case. */ -- if( pLhs->nExpr==1 ){ -- pX->pLeft = pLhs->a[0].pExpr; -- }else{ -- pLeft->x.pList = pLhs; -- aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int) * nEq); -- testcase( aiMap==0 ); -- } -- pSelect->pEList = pRhs; -- db->dbOptFlags |= SQLITE_QueryFlattener; -+ aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap); -- db->dbOptFlags = savedDbOptFlags; -- testcase( aiMap!=0 && aiMap[0]!=0 ); -- pSelect->pEList = pOrigRhs; -- pLeft->x.pList = pOrigLhs; -- pX->pLeft = pLeft; -+ pTerm->pExpr->iTable = pX->iTable; - } -- sqlite3ExprListDelete(pParse->db, pLhs); -- sqlite3ExprListDelete(pParse->db, pRhs); -+ sqlite3ExprDelete(db, pX); -+ pX = pTerm->pExpr; - } - - if( eType==IN_INDEX_INDEX_DESC ){ -@@ -128360,7 +135971,14 @@ - sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); - if( i==iEq ){ - pIn->iCur = iTab; -- pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen; -+ pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; -+ if( iEq>0 && (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){ -+ pIn->iBase = iReg - i; -+ pIn->nPrefix = i; -+ pLoop->wsFlags |= WHERE_IN_EARLYOUT; -+ }else{ -+ pIn->nPrefix = 0; -+ } - }else{ - pIn->eEndLoopOp = OP_Noop; - } -@@ -128615,7 +136233,7 @@ - pWalker->eCode = 1; - }else if( pExpr->op==TK_FUNCTION ){ - int d1; -- char d2[3]; -+ char d2[4]; - if( 0==sqlite3IsLikeFunction(pWalker->pParse->db, pExpr, &d1, d2) ){ - pWalker->eCode = 1; - } -@@ -128647,11 +136265,8 @@ - struct CCurHint *pHint = pWalker->u.pCCurHint; - if( pExpr->op==TK_COLUMN ){ - if( pExpr->iTable!=pHint->iTabCur ){ -- Vdbe *v = pWalker->pParse->pVdbe; - int reg = ++pWalker->pParse->nMem; /* Register for column value */ -- sqlite3ExprCodeGetColumnOfTable( -- v, pExpr->pTab, pExpr->iTable, pExpr->iColumn, reg -- ); -+ sqlite3ExprCode(pWalker->pParse, pExpr, reg); - pExpr->op = TK_REGISTER; - pExpr->iTable = reg; - }else if( pHint->pIdx!=0 ){ -@@ -128838,7 +136453,7 @@ - */ - static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ - assert( nReg>0 ); -- if( sqlite3ExprIsVector(p) ){ -+ if( p && sqlite3ExprIsVector(p) ){ - #ifndef SQLITE_OMIT_SUBQUERY - if( (p->flags & EP_xIsSelect) ){ - Vdbe *v = pParse->pVdbe; -@@ -128883,7 +136498,7 @@ - pExpr->op = TK_COLUMN; - pExpr->iTable = pX->iIdxCur; - pExpr->iColumn = pX->iIdxCol; -- pExpr->pTab = 0; -+ pExpr->y.pTab = 0; - return WRC_Prune; - }else{ - return WRC_Continue; -@@ -128891,9 +136506,9 @@ - } - - /* --** 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. -+** 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. - */ - static void whereIndexExprTrans( - Index *pIdx, /* The Index */ -@@ -128984,6 +136599,9 @@ - ** initialize a memory cell that records if this table matches any - ** row of the left table of the join. - */ -+ assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE) -+ || pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0 -+ ); - if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ - pLevel->iLeftJoin = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); -@@ -129001,7 +136619,7 @@ - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); - pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); - VdbeCoverage(v); -- VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName)); -+ VdbeComment((v, "next row of %s", pTabItem->pTab->zName)); - pLevel->op = OP_Goto; - }else - -@@ -129015,7 +136633,6 @@ - int nConstraint = pLoop->nLTerm; - int iIn; /* Counter for IN constraints */ - -- sqlite3ExprCachePush(pParse); - iReg = sqlite3GetTempRange(pParse, nConstraint+2); - addrNotFound = pLevel->addrBrk; - for(j=0; j<nConstraint; j++){ -@@ -129088,7 +136705,6 @@ - ** - ** sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2); - */ -- sqlite3ExprCachePop(pParse); - }else - #endif /* SQLITE_OMIT_VIRTUALTABLE */ - -@@ -129112,9 +136728,6 @@ - addrNxt = pLevel->addrNxt; - sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg); - VdbeCoverage(v); -- sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1); -- sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); -- VdbeComment((v, "pk")); - pLevel->op = OP_Noop; - }else if( (pLoop->wsFlags & WHERE_IPK)!=0 - && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0 -@@ -129164,7 +136777,15 @@ - if( sqlite3ExprIsVector(pX->pRight) ){ - r1 = rTemp = sqlite3GetTempReg(pParse); - codeExprOrVector(pParse, pX->pRight, r1, 1); -- op = aMoveOp[(pX->op - TK_GT) | 0x0001]; -+ testcase( pX->op==TK_GT ); -+ testcase( pX->op==TK_GE ); -+ testcase( pX->op==TK_LT ); -+ testcase( pX->op==TK_LE ); -+ op = aMoveOp[((pX->op - TK_GT - 1) & 0x3) | 0x1]; -+ assert( pX->op!=TK_GT || op==OP_SeekGE ); -+ assert( pX->op!=TK_GE || op==OP_SeekGE ); -+ assert( pX->op!=TK_LT || op==OP_SeekLE ); -+ assert( pX->op!=TK_LE || op==OP_SeekLE ); - }else{ - r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp); - disableTerm(pLevel, pStart); -@@ -129176,7 +136797,6 @@ - VdbeCoverageIf(v, pX->op==TK_LE); - VdbeCoverageIf(v, pX->op==TK_LT); - VdbeCoverageIf(v, pX->op==TK_GE); -- sqlite3ExprCacheAffinityChange(pParse, r1, 1); - sqlite3ReleaseTempReg(pParse, rTemp); - }else{ - sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt); -@@ -129211,7 +136831,6 @@ - if( testOp!=OP_Noop ){ - iRowidReg = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg); -- sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); - sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg); - VdbeCoverageIf(v, testOp==OP_Le); - VdbeCoverageIf(v, testOp==OP_Lt); -@@ -129416,6 +137035,9 @@ - ** above has already left the cursor sitting on the correct row, - ** so no further seeking is needed */ - }else{ -+ if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ -+ sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur); -+ } - op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; - assert( op!=0 ); - sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); -@@ -129434,7 +137056,6 @@ - nConstraint = nEq; - if( pRangeEnd ){ - Expr *pRight = pRangeEnd->pExpr->pRight; -- sqlite3ExprCacheRemove(pParse, regBase+nEq, 1); - codeExprOrVector(pParse, pRight, regBase+nEq, nTop); - whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd); - if( (pRangeEnd->wtFlags & TERM_VNULL)==0 -@@ -129478,6 +137099,10 @@ - testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); - } - -+ if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ -+ sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1); -+ } -+ - /* Seek the table cursor, if required */ - if( omitTable ){ - /* pIdx is a covering index. No need to access the main table. */ -@@ -129488,7 +137113,6 @@ - )){ - iRowidReg = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); -- sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); - sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg); - VdbeCoverage(v); - }else{ -@@ -129508,10 +137132,17 @@ - /* 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 - */ -- whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo); -+ if( pLevel->iLeftJoin==0 ){ -+ whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo); -+ } - -- - /* Record the instruction used to terminate the loop. */ - if( pLoop->wsFlags & WHERE_ONEROW ){ - pLevel->op = OP_Noop; -@@ -129666,7 +137297,6 @@ - for(iTerm=0; iTerm<pWC->nTerm; iTerm++){ - Expr *pExpr = pWC->a[iTerm].pExpr; - if( &pWC->a[iTerm] == pTerm ) continue; -- if( ExprHasProperty(pExpr, EP_FromJoin) ) continue; - testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL ); - testcase( pWC->a[iTerm].wtFlags & TERM_CODED ); - if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue; -@@ -129685,6 +137315,7 @@ - ** sub-WHERE clause is to to invoke the main loop body as a subroutine. - */ - wctrlFlags = WHERE_OR_SUBCLAUSE | (pWInfo->wctrlFlags & WHERE_SEEK_TABLE); -+ ExplainQueryPlan((pParse, 1, "MULTI-INDEX OR")); - for(ii=0; ii<pOrWc->nTerm; ii++){ - WhereTerm *pOrTerm = &pOrWc->a[ii]; - if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ -@@ -129691,7 +137322,10 @@ - WhereInfo *pSubWInfo; /* Info for single OR-term scan */ - Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ - int jmp1 = 0; /* Address of jump operation */ -- if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){ -+ assert( (pTabItem[0].fg.jointype & JT_LEFT)==0 -+ || ExprHasProperty(pOrExpr, EP_FromJoin) -+ ); -+ if( pAndExpr ){ - pAndExpr->pLeft = pOrExpr; - pOrExpr = pAndExpr; - } -@@ -129703,7 +137337,7 @@ - if( pSubWInfo ){ - WhereLoop *pSubLoop; - int addrExplain = sqlite3WhereExplainOneScan( -- pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 -+ pParse, pOrTab, &pSubWInfo->a[0], 0 - ); - sqlite3WhereAddScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain); - -@@ -129713,23 +137347,23 @@ - ** row will be skipped in subsequent sub-WHERE clauses. - */ - if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ -- int r; - int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); - if( HasRowid(pTab) ){ -- r = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, regRowid, 0); -+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, regRowid); - jmp1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0, -- r,iSet); -+ regRowid, iSet); - VdbeCoverage(v); - }else{ - Index *pPk = sqlite3PrimaryKeyIndex(pTab); - int nPk = pPk->nKeyCol; - int iPk; -+ int r; - - /* Read the PK into an array of temp registers. */ - r = sqlite3GetTempRange(pParse, nPk); - for(iPk=0; iPk<nPk; iPk++){ - int iCol = pPk->aiColumn[iPk]; -- sqlite3ExprCodeGetColumnToReg(pParse, pTab, iCol, iCur, r+iPk); -+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol, r+iPk); - } - - /* Check if the temp table already contains this key. If so, -@@ -129802,6 +137436,7 @@ - } - } - } -+ ExplainQueryPlanPop(pParse); - pLevel->u.pCovidx = pCov; - if( pCov ) pLevel->iIdxCur = iCovCur; - if( pAndExpr ){ -@@ -129874,7 +137509,7 @@ - } - pE = pTerm->pExpr; - assert( pE!=0 ); -- if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){ -+ if( (pTabItem->fg.jointype&JT_LEFT) && !ExprHasProperty(pE,EP_FromJoin) ){ - continue; - } - -@@ -129887,7 +137522,7 @@ - continue; - } - -- if( pTerm->wtFlags & TERM_LIKECOND ){ -+ if( (pTerm->wtFlags & TERM_LIKECOND)!=0 ){ - /* If the TERM_LIKECOND flag is set, that means that the range search - ** is sufficient to guarantee that the LIKE operator is true, so we - ** can skip the call to the like(A,B) function. But this only works -@@ -129897,8 +137532,9 @@ - continue; - #else - u32 x = pLevel->iLikeRepCntr; -- assert( x>0 ); -- skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If, (int)(x>>1)); -+ if( x>0 ){ -+ skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If,(int)(x>>1)); -+ } - VdbeCoverage(v); - #endif - } -@@ -129938,6 +137574,12 @@ - WO_EQ|WO_IN|WO_IS, 0); - if( pAlt==0 ) continue; - if( pAlt->wtFlags & (TERM_CODED) ) continue; -+ if( (pAlt->eOperator & WO_IN) -+ && (pAlt->pExpr->flags & EP_xIsSelect) -+ && (pAlt->pExpr->x.pSelect->pEList->nExpr>1) -+ ){ -+ continue; -+ } - testcase( pAlt->eOperator & WO_EQ ); - testcase( pAlt->eOperator & WO_IS ); - testcase( pAlt->eOperator & WO_IN ); -@@ -129954,7 +137596,6 @@ - pLevel->addrFirst = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); - VdbeComment((v, "record LEFT JOIN hit")); -- sqlite3ExprCacheClear(pParse); - for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){ - testcase( pTerm->wtFlags & TERM_VIRTUAL ); - testcase( pTerm->wtFlags & TERM_CODED ); -@@ -130170,18 +137811,18 @@ - int *pisComplete, /* True if the only wildcard is % in the last character */ - int *pnoCase /* True if uppercase is equivalent to lowercase */ - ){ -- const char *z = 0; /* String on RHS of LIKE operator */ -+ const u8 *z = 0; /* String on RHS of LIKE operator */ - Expr *pRight, *pLeft; /* Right and left size of LIKE operator */ - ExprList *pList; /* List of operands to the LIKE operator */ -- int c; /* One character in z[] */ -+ u8 c; /* One character in z[] */ - int cnt; /* Number of non-wildcard prefix characters */ -- char wc[3]; /* Wildcard characters */ -+ u8 wc[4]; /* Wildcard characters */ - sqlite3 *db = pParse->db; /* Database connection */ - sqlite3_value *pVal = 0; - int op; /* Opcode of pRight */ - int rc; /* Result code to return */ - -- if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){ -+ if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, (char*)wc) ){ - return 0; - } - #ifdef SQLITE_EBCDIC -@@ -130197,41 +137838,78 @@ - int iCol = pRight->iColumn; - pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_BLOB); - if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){ -- z = (char *)sqlite3_value_text(pVal); -+ z = sqlite3_value_text(pVal); - } - sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); - assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER ); - }else if( op==TK_STRING ){ -- z = pRight->u.zToken; -+ z = (u8*)pRight->u.zToken; - } - if( z ){ - -- /* If the RHS begins with a digit or a minus sign, then the LHS must -- ** be an ordinary column (not a virtual table column) with TEXT affinity. -- ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false -- ** even though "lhs LIKE rhs" is true. But if the RHS does not start -- ** with a digit or '-', then "lhs LIKE rhs" will always be false if -- ** the LHS is numeric and so the optimization still works. -- */ -- if( sqlite3Isdigit(z[0]) || z[0]=='-' ){ -- if( pLeft->op!=TK_COLUMN -- || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT -- || IsVirtual(pLeft->pTab) /* Value might be numeric */ -- ){ -- sqlite3ValueFree(pVal); -- return 0; -- } -- } -+ /* Count the number of prefix characters prior to the first wildcard */ - cnt = 0; - while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ - cnt++; -+ if( c==wc[3] && z[cnt]!=0 ) cnt++; - } -- if( cnt!=0 && 255!=(u8)z[cnt-1] ){ -+ -+ /* The optimization is possible only if (1) the pattern does not begin -+ ** with a wildcard and if (2) the non-wildcard prefix does not end with -+ ** an (illegal 0xff) character, or (3) the pattern does not consist of -+ ** a single escape character. The second condition is necessary so -+ ** that we can increment the prefix key to find an upper bound for the -+ ** range search. The third is because the caller assumes that the pattern -+ ** consists of at least one character after all escapes have been -+ ** removed. */ -+ if( cnt!=0 && 255!=(u8)z[cnt-1] && (cnt>1 || z[0]!=wc[3]) ){ - Expr *pPrefix; -+ -+ /* A "complete" match if the pattern ends with "*" or "%" */ - *pisComplete = c==wc[0] && z[cnt+1]==0; -- pPrefix = sqlite3Expr(db, TK_STRING, z); -- if( pPrefix ) pPrefix->u.zToken[cnt] = 0; -+ -+ /* Get the pattern prefix. Remove all escapes from the prefix. */ -+ pPrefix = sqlite3Expr(db, TK_STRING, (char*)z); -+ if( pPrefix ){ -+ int iFrom, iTo; -+ char *zNew = pPrefix->u.zToken; -+ zNew[cnt] = 0; -+ for(iFrom=iTo=0; iFrom<cnt; iFrom++){ -+ if( zNew[iFrom]==wc[3] ) iFrom++; -+ zNew[iTo++] = zNew[iFrom]; -+ } -+ zNew[iTo] = 0; -+ -+ /* If the RHS begins with a digit or a minus sign, then the LHS must be -+ ** an ordinary column (not a virtual table column) with TEXT affinity. -+ ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false -+ ** even though "lhs LIKE rhs" is true. But if the RHS does not start -+ ** with a digit or '-', then "lhs LIKE rhs" will always be false if -+ ** the LHS is numeric and so the optimization still works. -+ ** -+ ** 2018-09-10 ticket c94369cae9b561b1f996d0054bfab11389f9d033 -+ ** The RHS pattern must not be '/%' because the termination condition -+ ** will then become "x<'0'" and if the affinity is numeric, will then -+ ** be converted into "x<0", which is incorrect. -+ */ -+ if( sqlite3Isdigit(zNew[0]) -+ || zNew[0]=='-' -+ || (zNew[0]+1=='0' && iTo==1) -+ ){ -+ if( pLeft->op!=TK_COLUMN -+ || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT -+ || IsVirtual(pLeft->y.pTab) /* Value might be numeric */ -+ ){ -+ sqlite3ExprDelete(db, pPrefix); -+ sqlite3ValueFree(pVal); -+ return 0; -+ } -+ } -+ } - *ppPrefix = pPrefix; -+ -+ /* If the RHS pattern is a bound parameter, make arrangements to -+ ** reprepare the statement when that parameter is rebound */ - if( op==TK_VARIABLE ){ - Vdbe *v = pParse->pVdbe; - sqlite3VdbeSetVarmask(v, pRight->iColumn); -@@ -130262,48 +137940,123 @@ - - #ifndef SQLITE_OMIT_VIRTUALTABLE - /* --** Check to see if the given expression is of the form -+** Check to see if the pExpr expression is a form that needs to be passed -+** to the xBestIndex method of virtual tables. Forms of interest include: - ** --** column OP expr -+** Expression Virtual Table Operator -+** ----------------------- --------------------------------- -+** 1. column MATCH expr SQLITE_INDEX_CONSTRAINT_MATCH -+** 2. column GLOB expr SQLITE_INDEX_CONSTRAINT_GLOB -+** 3. column LIKE expr SQLITE_INDEX_CONSTRAINT_LIKE -+** 4. column REGEXP expr SQLITE_INDEX_CONSTRAINT_REGEXP -+** 5. column != expr SQLITE_INDEX_CONSTRAINT_NE -+** 6. expr != column SQLITE_INDEX_CONSTRAINT_NE -+** 7. column IS NOT expr SQLITE_INDEX_CONSTRAINT_ISNOT -+** 8. expr IS NOT column SQLITE_INDEX_CONSTRAINT_ISNOT -+** 9. column IS NOT NULL SQLITE_INDEX_CONSTRAINT_ISNOTNULL - ** --** where OP is one of MATCH, GLOB, LIKE or REGEXP and "column" is a --** column of a virtual table. -+** In every case, "column" must be a column of a virtual table. If there -+** is a match, set *ppLeft to the "column" expression, set *ppRight to the -+** "expr" expression (even though in forms (6) and (8) the column is on the -+** right and the expression is on the left). Also set *peOp2 to the -+** appropriate virtual table operator. The return value is 1 or 2 if there -+** is a match. The usual return is 1, but if the RHS is also a column -+** of virtual table in forms (5) or (7) then return 2. - ** --** If it is then return TRUE. If not, return FALSE. -+** If the expression matches none of the patterns above, return 0. - */ --static int isMatchOfColumn( -+static int isAuxiliaryVtabOperator( -+ sqlite3 *db, /* Parsing context */ - Expr *pExpr, /* Test this expression */ -- unsigned char *peOp2 /* OUT: 0 for MATCH, or else an op2 value */ -+ unsigned char *peOp2, /* OUT: 0 for MATCH, or else an op2 value */ -+ Expr **ppLeft, /* Column expression to left of MATCH/op2 */ -+ Expr **ppRight /* Expression to left of MATCH/op2 */ - ){ -- static const struct Op2 { -- const char *zOp; -- unsigned char eOp2; -- } aOp[] = { -- { "match", SQLITE_INDEX_CONSTRAINT_MATCH }, -- { "glob", SQLITE_INDEX_CONSTRAINT_GLOB }, -- { "like", SQLITE_INDEX_CONSTRAINT_LIKE }, -- { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP } -- }; -- ExprList *pList; -- Expr *pCol; /* Column reference */ -- int i; -+ if( pExpr->op==TK_FUNCTION ){ -+ static const struct Op2 { -+ const char *zOp; -+ unsigned char eOp2; -+ } aOp[] = { -+ { "match", SQLITE_INDEX_CONSTRAINT_MATCH }, -+ { "glob", SQLITE_INDEX_CONSTRAINT_GLOB }, -+ { "like", SQLITE_INDEX_CONSTRAINT_LIKE }, -+ { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP } -+ }; -+ ExprList *pList; -+ Expr *pCol; /* Column reference */ -+ int i; - -- if( pExpr->op!=TK_FUNCTION ){ -- return 0; -- } -- pList = pExpr->x.pList; -- if( pList==0 || pList->nExpr!=2 ){ -- return 0; -- } -- pCol = pList->a[1].pExpr; -- if( pCol->op!=TK_COLUMN || !IsVirtual(pCol->pTab) ){ -- return 0; -- } -- for(i=0; i<ArraySize(aOp); i++){ -- if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){ -- *peOp2 = aOp[i].eOp2; -- return 1; -+ pList = pExpr->x.pList; -+ if( pList==0 || pList->nExpr!=2 ){ -+ return 0; - } -+ -+ /* Built-in operators MATCH, GLOB, LIKE, and REGEXP attach to a -+ ** virtual table on their second argument, which is the same as -+ ** the left-hand side operand in their in-fix form. -+ ** -+ ** vtab_column MATCH expression -+ ** MATCH(expression,vtab_column) -+ */ -+ pCol = pList->a[1].pExpr; -+ if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ -+ for(i=0; i<ArraySize(aOp); i++){ -+ if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){ -+ *peOp2 = aOp[i].eOp2; -+ *ppRight = pList->a[0].pExpr; -+ *ppLeft = pCol; -+ return 1; -+ } -+ } -+ } -+ -+ /* We can also match against the first column of overloaded -+ ** functions where xFindFunction returns a value of at least -+ ** SQLITE_INDEX_CONSTRAINT_FUNCTION. -+ ** -+ ** OVERLOADED(vtab_column,expression) -+ ** -+ ** Historically, xFindFunction expected to see lower-case function -+ ** names. But for this use case, xFindFunction is expected to deal -+ ** with function names in an arbitrary case. -+ */ -+ pCol = pList->a[0].pExpr; -+ if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ -+ sqlite3_vtab *pVtab; -+ sqlite3_module *pMod; -+ void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**); -+ void *pNotUsed; -+ pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab; -+ assert( pVtab!=0 ); -+ assert( pVtab->pModule!=0 ); -+ pMod = (sqlite3_module *)pVtab->pModule; -+ if( pMod->xFindFunction!=0 ){ -+ i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed); -+ if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){ -+ *peOp2 = i; -+ *ppRight = pList->a[1].pExpr; -+ *ppLeft = pCol; -+ return 1; -+ } -+ } -+ } -+ }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ -+ int res = 0; -+ Expr *pLeft = pExpr->pLeft; -+ Expr *pRight = pExpr->pRight; -+ if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){ -+ res++; -+ } -+ if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){ -+ res++; -+ SWAP(Expr*, pLeft, pRight); -+ } -+ *ppLeft = pLeft; -+ *ppRight = pRight; -+ if( pExpr->op==TK_NE ) *peOp2 = SQLITE_INDEX_CONSTRAINT_NE; -+ if( pExpr->op==TK_ISNOT ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOT; -+ if( pExpr->op==TK_NOTNULL ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOTNULL; -+ return res; - } - return 0; - } -@@ -130554,7 +138307,7 @@ - for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){ - assert( pAndTerm->pExpr ); - if( allowedOp(pAndTerm->pExpr->op) -- || pAndTerm->eOperator==WO_MATCH -+ || pAndTerm->eOperator==WO_AUX - ){ - b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor); - } -@@ -130586,7 +138339,12 @@ - ** empty. - */ - pOrInfo->indexable = indexable; -- pTerm->eOperator = indexable==0 ? 0 : WO_OR; -+ if( indexable ){ -+ pTerm->eOperator = WO_OR; -+ pWC->hasOr = 1; -+ }else{ -+ pTerm->eOperator = WO_OR; -+ } - - /* For a two-way OR, attempt to implementation case 2. - */ -@@ -130727,12 +138485,11 @@ - idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); - testcase( idxNew==0 ); - exprAnalyze(pSrc, pWC, idxNew); -- pTerm = &pWC->a[idxTerm]; -+ /* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where used again */ - markTermAsChild(pWC, idxNew, idxTerm); - }else{ - sqlite3ExprListDelete(db, pList); - } -- pTerm->eOperator = WO_NOOP; /* case 1 trumps case 3 */ - } - } - } -@@ -130756,7 +138513,6 @@ - static int termIsEquivalence(Parse *pParse, Expr *pExpr){ - char aff1, aff2; - CollSeq *pColl; -- const char *zColl1, *zColl2; - if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; - if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; - if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0; -@@ -130768,12 +138524,8 @@ - return 0; - } - pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight); -- if( pColl==0 || sqlite3StrICmp(pColl->zName, "BINARY")==0 ) return 1; -- pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); -- zColl1 = pColl ? pColl->zName : 0; -- pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight); -- zColl2 = pColl ? pColl->zName : 0; -- return sqlite3_stricmp(zColl1, zColl2)==0; -+ if( sqlite3IsBinary(pColl) ) return 1; -+ return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight); - } - - /* -@@ -130795,6 +138547,9 @@ - for(i=0; i<pSrc->nSrc; i++){ - mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect); - mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].pOn); -+ if( pSrc->a[i].fg.isTabFunc ){ -+ mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg); -+ } - } - } - pS = pS->pPrior; -@@ -130902,7 +138657,7 @@ - int op; /* Top-level operator. pExpr->op */ - Parse *pParse = pWInfo->pParse; /* Parsing context */ - sqlite3 *db = pParse->db; /* Database connection */ -- unsigned char eOp2; /* op2 value for LIKE/REGEXP/GLOB */ -+ unsigned char eOp2 = 0; /* op2 value for LIKE/REGEXP/GLOB */ - int nLeft; /* Number of elements on left side vector */ - - if( db->mallocFailed ){ -@@ -130928,7 +138683,7 @@ - pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight); - } - pMaskSet->bVarSelect = 0; -- prereqAll = sqlite3WhereExprUsage(pMaskSet, pExpr); -+ prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr); - if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT; - if( ExprHasProperty(pExpr, EP_FromJoin) ){ - Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable); -@@ -131110,7 +138865,7 @@ - } - *pC = c + 1; - } -- zCollSeqName = noCase ? "NOCASE" : "BINARY"; -+ zCollSeqName = noCase ? "NOCASE" : sqlite3StrBINARY; - pNewExpr1 = sqlite3ExprDup(db, pLeft, 0); - pNewExpr1 = sqlite3PExpr(pParse, TK_GE, - sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName), -@@ -131136,41 +138891,46 @@ - #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ - - #ifndef SQLITE_OMIT_VIRTUALTABLE -- /* Add a WO_MATCH auxiliary term to the constraint set if the -- ** current expression is of the form: column MATCH expr. -+ /* Add a WO_AUX auxiliary term to the constraint set if the -+ ** current expression is of the form "column OP expr" where OP -+ ** is an operator that gets passed into virtual tables but which is -+ ** not normally optimized for ordinary tables. In other words, OP -+ ** is one of MATCH, LIKE, GLOB, REGEXP, !=, IS, IS NOT, or NOT NULL. - ** This information is used by the xBestIndex methods of - ** virtual tables. The native query optimizer does not attempt - ** to do anything with MATCH functions. - */ -- if( pWC->op==TK_AND && isMatchOfColumn(pExpr, &eOp2) ){ -- int idxNew; -- Expr *pRight, *pLeft; -- WhereTerm *pNewTerm; -- Bitmask prereqColumn, prereqExpr; -+ if( pWC->op==TK_AND ){ -+ Expr *pRight = 0, *pLeft = 0; -+ int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight); -+ while( res-- > 0 ){ -+ int idxNew; -+ WhereTerm *pNewTerm; -+ Bitmask prereqColumn, prereqExpr; - -- pRight = pExpr->x.pList->a[0].pExpr; -- pLeft = pExpr->x.pList->a[1].pExpr; -- prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight); -- prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft); -- if( (prereqExpr & prereqColumn)==0 ){ -- Expr *pNewExpr; -- pNewExpr = sqlite3PExpr(pParse, TK_MATCH, -- 0, sqlite3ExprDup(db, pRight, 0)); -- if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){ -- ExprSetProperty(pNewExpr, EP_FromJoin); -+ prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight); -+ prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft); -+ if( (prereqExpr & prereqColumn)==0 ){ -+ Expr *pNewExpr; -+ pNewExpr = sqlite3PExpr(pParse, TK_MATCH, -+ 0, sqlite3ExprDup(db, pRight, 0)); -+ if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){ -+ ExprSetProperty(pNewExpr, EP_FromJoin); -+ } -+ idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); -+ testcase( idxNew==0 ); -+ pNewTerm = &pWC->a[idxNew]; -+ pNewTerm->prereqRight = prereqExpr; -+ pNewTerm->leftCursor = pLeft->iTable; -+ pNewTerm->u.leftColumn = pLeft->iColumn; -+ pNewTerm->eOperator = WO_AUX; -+ pNewTerm->eMatchOp = eOp2; -+ markTermAsChild(pWC, idxNew, idxTerm); -+ pTerm = &pWC->a[idxTerm]; -+ pTerm->wtFlags |= TERM_COPIED; -+ pNewTerm->prereqAll = pTerm->prereqAll; - } -- idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); -- testcase( idxNew==0 ); -- pNewTerm = &pWC->a[idxNew]; -- pNewTerm->prereqRight = prereqExpr; -- pNewTerm->leftCursor = pLeft->iTable; -- pNewTerm->u.leftColumn = pLeft->iColumn; -- pNewTerm->eOperator = WO_MATCH; -- pNewTerm->eMatchOp = eOp2; -- markTermAsChild(pWC, idxNew, idxTerm); -- pTerm = &pWC->a[idxTerm]; -- pTerm->wtFlags |= TERM_COPIED; -- pNewTerm->prereqAll = pTerm->prereqAll; -+ SWAP(Expr*, pLeft, pRight); - } - } - #endif /* SQLITE_OMIT_VIRTUALTABLE */ -@@ -131202,7 +138962,7 @@ - exprAnalyze(pSrc, pWC, idxNew); - } - pTerm = &pWC->a[idxTerm]; -- pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL; /* Disable the original */ -+ pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */ - pTerm->eOperator = 0; - } - -@@ -131239,6 +138999,7 @@ - if( pExpr->op==TK_NOTNULL - && pExpr->pLeft->op==TK_COLUMN - && pExpr->pLeft->iColumn>=0 -+ && !ExprHasProperty(pExpr, EP_FromJoin) - && OptimizationEnabled(db, SQLITE_Stat34) - ){ - Expr *pNewExpr; -@@ -131316,6 +139077,7 @@ - WhereInfo *pWInfo /* The WHERE processing context */ - ){ - pWC->pWInfo = pWInfo; -+ pWC->hasOr = 0; - pWC->pOuter = 0; - pWC->nTerm = 0; - pWC->nSlot = ArraySize(pWC->aStatic); -@@ -131352,17 +139114,18 @@ - ** a bitmask indicating which tables are used in that expression - ** tree. - */ --SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ -+SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){ - Bitmask mask; -- if( p==0 ) return 0; -- if( p->op==TK_COLUMN ){ -+ if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){ - return sqlite3WhereGetMask(pMaskSet, p->iTable); -+ }else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ -+ assert( p->op!=TK_IF_NULL_ROW ); -+ return 0; - } - mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0; -- assert( !ExprHasProperty(p, EP_TokenOnly) ); -- if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft); -+ if( p->pLeft ) mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pLeft); - if( p->pRight ){ -- mask |= sqlite3WhereExprUsage(pMaskSet, p->pRight); -+ mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pRight); - assert( p->x.pList==0 ); - }else if( ExprHasProperty(p, EP_xIsSelect) ){ - if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1; -@@ -131372,6 +139135,9 @@ - } - return mask; - } -+SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ -+ return p ? sqlite3WhereExprUsageNN(pMaskSet,p) : 0; -+} - SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprList *pList){ - int i; - Bitmask mask = 0; -@@ -131425,6 +139191,7 @@ - pArgs = pItem->u1.pFuncArg; - if( pArgs==0 ) return; - for(j=k=0; j<pArgs->nExpr; j++){ -+ Expr *pRhs; - while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;} - if( k>=pTab->nCol ){ - sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d", -@@ -131435,9 +139202,10 @@ - if( pColRef==0 ) return; - pColRef->iTable = pItem->iCursor; - pColRef->iColumn = k++; -- pColRef->pTab = pTab; -- pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, -- sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0)); -+ pColRef->y.pTab = pTab; -+ pRhs = sqlite3PExpr(pParse, TK_UPLUS, -+ sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); -+ pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs); - whereClauseInsert(pWC, pTerm, TERM_DYNAMIC); - } - } -@@ -131465,6 +139233,21 @@ - /* #include "sqliteInt.h" */ - /* #include "whereInt.h" */ - -+/* -+** Extra information appended to the end of sqlite3_index_info but not -+** visible to the xBestIndex function, at least not directly. The -+** sqlite3_vtab_collation() interface knows how to reach it, however. -+** -+** This object is not an API and can be changed from one release to the -+** next. As long as allocateIndexInfo() and sqlite3_vtab_collation() -+** agree on the structure, all will be well. -+*/ -+typedef struct HiddenIndexInfo HiddenIndexInfo; -+struct HiddenIndexInfo { -+ WhereClause *pWC; /* The Where clause being analyzed */ -+ Parse *pParse; /* The parsing context */ -+}; -+ - /* Forward declaration of methods */ - static int whereLoopResize(sqlite3*, WhereLoop*, int); - -@@ -131498,15 +139281,38 @@ - } - - /* --** Return TRUE if the innermost loop of the WHERE clause implementation --** returns rows in ORDER BY order for complete run of the inner loop. -+** In the ORDER BY LIMIT optimization, if the inner-most loop is known -+** to emit rows in increasing order, and if the last row emitted by the -+** inner-most loop did not fit within the sorter, then we can skip all -+** subsequent rows for the current iteration of the inner loop (because they -+** will not fit in the sorter either) and continue with the second inner -+** loop - the loop immediately outside the inner-most. - ** --** Across multiple iterations of outer loops, the output rows need not be --** sorted. As long as rows are sorted for just the innermost loop, this --** routine can return TRUE. -+** When a row does not fit in the sorter (because the sorter already -+** holds LIMIT+OFFSET rows that are smaller), then a jump is made to the -+** label returned by this function. -+** -+** If the ORDER BY LIMIT optimization applies, the jump destination should -+** be the continuation for the second-inner-most loop. If the ORDER BY -+** LIMIT optimization does not apply, then the jump destination should -+** be the continuation for the inner-most loop. -+** -+** It is always safe for this routine to return the continuation of the -+** inner-most loop, in the sense that a correct answer will result. -+** Returning the continuation the second inner loop is an optimization -+** that might make the code run a little faster, but should not change -+** the final answer. - */ --SQLITE_PRIVATE int sqlite3WhereOrderedInnerLoop(WhereInfo *pWInfo){ -- return pWInfo->bOrderedInnerLoop; -+SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){ -+ WhereLevel *pInner; -+ if( !pWInfo->bOrderedInnerLoop ){ -+ /* The ORDER BY LIMIT optimization does not apply. Jump to the -+ ** continuation of the inner-most loop. */ -+ return pWInfo->iContinue; -+ } -+ pInner = &pWInfo->a[pWInfo->nLevel-1]; -+ assert( pInner->addrNxt!=0 ); -+ return pInner->addrNxt; - } - - /* -@@ -131849,8 +139655,8 @@ - && p->iColumn==pIdx->aiColumn[iCol] - && p->iTable==iBase - ){ -- CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr); -- if( pColl && 0==sqlite3StrICmp(pColl->zName, zColl) ){ -+ CollSeq *pColl = sqlite3ExprNNCollSeq(pParse, pList->a[i].pExpr); -+ if( 0==sqlite3StrICmp(pColl->zName, zColl) ){ - return i; - } - } -@@ -132233,7 +140039,6 @@ - VdbeComment((v, "for %s", pTable->zName)); - - /* Fill the automatic index with content */ -- sqlite3ExprCachePush(pParse); - pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom]; - if( pTabItem->fg.viaCoroutine ){ - int regYield = pTabItem->regReturn; -@@ -132241,7 +140046,7 @@ - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); - addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); - VdbeCoverage(v); -- VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName)); -+ VdbeComment((v, "next row of %s", pTabItem->pTab->zName)); - }else{ - addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); - } -@@ -132263,7 +140068,6 @@ - translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, - pTabItem->regResult, 1); - sqlite3VdbeGoto(v, addrTop); -- pTabItem->fg.viaCoroutine = 0; - }else{ - sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); - } -@@ -132270,7 +140074,6 @@ - sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); - sqlite3VdbeJumpHere(v, addrTop); - sqlite3ReleaseTempReg(pParse, regRecord); -- sqlite3ExprCachePop(pParse); - - /* Jump here when skipping the initialization */ - sqlite3VdbeJumpHere(v, addrInit); -@@ -132287,11 +140090,11 @@ - ** by passing the pointer returned by this function to sqlite3_free(). - */ - static sqlite3_index_info *allocateIndexInfo( -- Parse *pParse, -- WhereClause *pWC, -+ Parse *pParse, /* The parsing context */ -+ WhereClause *pWC, /* The WHERE clause being analyzed */ - Bitmask mUnusable, /* Ignore terms with these prereqs */ -- struct SrcList_item *pSrc, -- ExprList *pOrderBy, -+ struct SrcList_item *pSrc, /* The FROM clause term that is the vtab */ -+ ExprList *pOrderBy, /* The ORDER BY clause */ - u16 *pmNoOmit /* Mask of terms not to omit */ - ){ - int i, j; -@@ -132299,6 +140102,7 @@ - struct sqlite3_index_constraint *pIdxCons; - struct sqlite3_index_orderby *pIdxOrderBy; - struct sqlite3_index_constraint_usage *pUsage; -+ struct HiddenIndexInfo *pHidden; - WhereTerm *pTerm; - int nOrderBy; - sqlite3_index_info *pIdxInfo; -@@ -132314,7 +140118,7 @@ - testcase( pTerm->eOperator & WO_ISNULL ); - testcase( pTerm->eOperator & WO_IS ); - testcase( pTerm->eOperator & WO_ALL ); -- if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue; -+ if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; - if( pTerm->wtFlags & TERM_VNULL ) continue; - assert( pTerm->u.leftColumn>=(-1) ); - nTerm++; -@@ -132340,7 +140144,7 @@ - */ - pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo) - + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm -- + sizeof(*pIdxOrderBy)*nOrderBy ); -+ + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) ); - if( pIdxInfo==0 ){ - sqlite3ErrorMsg(pParse, "out of memory"); - return 0; -@@ -132351,7 +140155,8 @@ - ** changing them. We have to do some funky casting in order to - ** initialize those fields. - */ -- pIdxCons = (struct sqlite3_index_constraint*)&pIdxInfo[1]; -+ 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; -@@ -132361,8 +140166,10 @@ - *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage = - pUsage; - -+ pHidden->pWC = pWC; -+ pHidden->pParse = pParse; - for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ -- u8 op; -+ u16 op; - if( pTerm->leftCursor != pSrc->iCursor ) continue; - if( pTerm->prereqRight & mUnusable ) continue; - assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); -@@ -132370,34 +140177,54 @@ - testcase( pTerm->eOperator & WO_IS ); - testcase( pTerm->eOperator & WO_ISNULL ); - testcase( pTerm->eOperator & WO_ALL ); -- if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue; -+ if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; - if( pTerm->wtFlags & TERM_VNULL ) continue; -+ 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) ); - pIdxCons[j].iColumn = pTerm->u.leftColumn; - pIdxCons[j].iTermOffset = i; -- op = (u8)pTerm->eOperator & WO_ALL; -+ op = pTerm->eOperator & WO_ALL; - if( op==WO_IN ) op = WO_EQ; -- if( op==WO_MATCH ){ -- op = pTerm->eMatchOp; -- } -- pIdxCons[j].op = op; -- /* The direct assignment in the previous line is possible only because -- ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The -- ** following asserts verify this fact. */ -- assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); -- assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); -- assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); -- assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); -- assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); -- assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH ); -- assert( pTerm->eOperator & (WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) ); -+ if( op==WO_AUX ){ -+ pIdxCons[j].op = pTerm->eMatchOp; -+ }else if( op & (WO_ISNULL|WO_IS) ){ -+ if( op==WO_ISNULL ){ -+ pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL; -+ }else{ -+ pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS; -+ } -+ }else{ -+ pIdxCons[j].op = (u8)op; -+ /* The direct assignment in the previous line is possible only because -+ ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The -+ ** following asserts verify this fact. */ -+ assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); -+ assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); -+ assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); -+ assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); -+ assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); -+ assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) ); - -- if( op & (WO_LT|WO_LE|WO_GT|WO_GE) -- && sqlite3ExprIsVector(pTerm->pExpr->pRight) -- ){ -- if( i<16 ) mNoOmit |= (1 << i); -- if( op==WO_LT ) pIdxCons[j].op = WO_LE; -- if( op==WO_GT ) pIdxCons[j].op = WO_GE; -+ if( op & (WO_LT|WO_LE|WO_GT|WO_GE) -+ && sqlite3ExprIsVector(pTerm->pExpr->pRight) -+ ){ -+ if( i<16 ) mNoOmit |= (1 << i); -+ if( op==WO_LT ) pIdxCons[j].op = WO_LE; -+ if( op==WO_GT ) pIdxCons[j].op = WO_GE; -+ } - } - - j++; -@@ -132418,9 +140245,11 @@ - ** method of the virtual table with the sqlite3_index_info object that - ** comes in as the 3rd argument to this function. - ** --** If an error occurs, pParse is populated with an error message and a --** non-zero value is returned. Otherwise, 0 is returned and the output --** part of the sqlite3_index_info structure is left populated. -+** If an error occurs, pParse is populated with an error message and an -+** appropriate error code is returned. A return of SQLITE_CONSTRAINT from -+** xBestIndex is not considered an error. SQLITE_CONSTRAINT indicates that -+** the current configuration of "unusable" flags in sqlite3_index_info can -+** not result in a valid plan. - ** - ** Whether or not an error is returned, it is the responsibility of the - ** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates -@@ -132434,7 +140263,7 @@ - rc = pVtab->pModule->xBestIndex(pVtab, p); - TRACE_IDX_OUTPUTS(p); - -- if( rc!=SQLITE_OK ){ -+ if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){ - if( rc==SQLITE_NOMEM ){ - sqlite3OomFault(pParse->db); - }else if( !pVtab->zErrMsg ){ -@@ -132445,19 +140274,7 @@ - } - sqlite3_free(pVtab->zErrMsg); - pVtab->zErrMsg = 0; -- --#if 0 -- /* This error is now caught by the caller. -- ** Search for "xBestIndex malfunction" below */ -- for(i=0; i<p->nConstraint; i++){ -- if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){ -- sqlite3ErrorMsg(pParse, -- "table %s: xBestIndex returned an invalid plan", pTab->zName); -- } -- } --#endif -- -- return pParse->nErr; -+ return rc; - } - #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ - -@@ -132857,7 +140674,9 @@ - Index *p = pLoop->u.btree.pIndex; - int nEq = pLoop->u.btree.nEq; - -- if( p->nSample>0 && nEq<p->nSampleCol ){ -+ if( p->nSample>0 && nEq<p->nSampleCol -+ && OptimizationEnabled(pParse->db, SQLITE_Stat34) -+ ){ - if( nEq==pBuilder->nRecValid ){ - UnpackedRecord *pRec = pBuilder->pRec; - tRowcnt a[2]; -@@ -133303,22 +141122,21 @@ - ** Free a WhereInfo structure - */ - static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ -- if( ALWAYS(pWInfo) ){ -- int i; -- for(i=0; i<pWInfo->nLevel; i++){ -- WhereLevel *pLevel = &pWInfo->a[i]; -- if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){ -- sqlite3DbFree(db, pLevel->u.in.aInLoop); -- } -+ int i; -+ assert( pWInfo!=0 ); -+ for(i=0; i<pWInfo->nLevel; i++){ -+ WhereLevel *pLevel = &pWInfo->a[i]; -+ if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){ -+ sqlite3DbFree(db, pLevel->u.in.aInLoop); - } -- sqlite3WhereClauseClear(&pWInfo->sWC); -- while( pWInfo->pLoops ){ -- WhereLoop *p = pWInfo->pLoops; -- pWInfo->pLoops = p->pNextLoop; -- whereLoopDelete(db, p); -- } -- sqlite3DbFreeNN(db, pWInfo); - } -+ sqlite3WhereClauseClear(&pWInfo->sWC); -+ while( pWInfo->pLoops ){ -+ WhereLoop *p = pWInfo->pLoops; -+ pWInfo->pLoops = p->pNextLoop; -+ whereLoopDelete(db, p); -+ } -+ sqlite3DbFreeNN(db, pWInfo); - } - - /* -@@ -133325,18 +141143,19 @@ - ** Return TRUE if all of the following are true: - ** - ** (1) X has the same or lower cost that Y --** (2) X is a proper subset of Y --** (3) X skips at least as many columns as Y -+** (2) X uses fewer WHERE clause terms than Y -+** (3) Every WHERE clause term used by X is also used by Y -+** (4) X skips at least as many columns as Y -+** (5) If X is a covering index, than Y is too - ** --** By "proper subset" we mean that X uses fewer WHERE clause terms --** than Y and that every WHERE clause term used by X is also used --** by Y. --** -+** Conditions (2) and (3) mean that X is a "proper subset" of Y. - ** If X is a proper subset of Y then Y is a better choice and ought - ** to have a lower cost. This routine returns TRUE when that cost --** relationship is inverted and needs to be adjusted. The third rule -+** relationship is inverted and needs to be adjusted. Constraint (4) - ** was added because if X uses skip-scan less than Y it still might --** deserve a lower cost even if it is a proper subset of Y. -+** deserve a lower cost even if it is a proper subset of Y. Constraint (5) -+** was added because a covering index probably deserves to have a lower cost -+** than a non-covering index even if it is a proper subset. - */ - static int whereLoopCheaperProperSubset( - const WhereLoop *pX, /* First WhereLoop to compare */ -@@ -133358,6 +141177,10 @@ - } - if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */ - } -+ if( (pX->wsFlags&WHERE_IDX_ONLY)!=0 -+ && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){ -+ return 0; /* Constraint (5) */ -+ } - return 1; /* All conditions meet */ - } - -@@ -133506,6 +141329,14 @@ - sqlite3 *db = pWInfo->pParse->db; - int rc; - -+ /* Stop the search once we hit the query planner search limit */ -+ if( pBuilder->iPlanLimit==0 ){ -+ WHERETRACE(0xffffffff,("=== query planner search limit reached ===\n")); -+ if( pBuilder->pOrSet ) pBuilder->pOrSet->n = 0; -+ return SQLITE_DONE; -+ } -+ pBuilder->iPlanLimit--; -+ - /* If pBuilder->pOrSet is defined, then only keep track of the costs - ** and prereqs. - */ -@@ -133790,8 +141621,8 @@ - - pNew = pBuilder->pNew; - if( db->mallocFailed ) return SQLITE_NOMEM_BKPT; -- WHERETRACE(0x800, ("BEGIN addBtreeIdx(%s), nEq=%d\n", -- pProbe->zName, pNew->u.btree.nEq)); -+ WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d\n", -+ pProbe->pTable->zName,pProbe->zName, pNew->u.btree.nEq)); - - assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 ); - assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 ); -@@ -133837,15 +141668,12 @@ - ** to mix with a lower range bound from some other source */ - if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue; - -- /* Do not allow IS constraints from the WHERE clause to be used by the -+ /* 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 */ - if( (pSrc->fg.jointype & JT_LEFT)!=0 - && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) -- && (eOp & (WO_IS|WO_ISNULL))!=0 - ){ -- testcase( eOp & WO_IS ); -- testcase( eOp & WO_ISNULL ); - continue; - } - -@@ -133871,7 +141699,6 @@ - - if( eOp & WO_IN ){ - Expr *pExpr = pTerm->pExpr; -- pNew->wsFlags |= WHERE_COLUMN_IN; - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ - int i; -@@ -133891,17 +141718,55 @@ - assert( nIn>0 ); /* RHS always has 2 or more terms... The parser - ** changes "x IN (?)" into "x=?". */ - } -+ if( pProbe->hasStat1 ){ -+ LogEst M, logK, safetyMargin; -+ /* Let: -+ ** N = the total number of rows in the table -+ ** K = the number of entries on the RHS of the IN operator -+ ** M = the number of rows in the table that match terms to the -+ ** to the left in the same index. If the IN operator is on -+ ** the left-most index column, M==N. -+ ** -+ ** Given the definitions above, it is better to omit the IN operator -+ ** from the index lookup and instead do a scan of the M elements, -+ ** testing each scanned row against the IN operator separately, if: -+ ** -+ ** M*log(K) < K*log(N) -+ ** -+ ** Our estimates for M, K, and N might be inaccurate, so we build in -+ ** a safety margin of 2 (LogEst: 10) that favors using the IN operator -+ ** with the index, as using an index has better worst-case behavior. -+ ** If we do not have real sqlite_stat1 data, always prefer to use -+ ** the index. -+ */ -+ M = pProbe->aiRowLogEst[saved_nEq]; -+ logK = estLog(nIn); -+ safetyMargin = 10; /* TUNING: extra weight for indexed IN */ -+ if( M + logK + safetyMargin < nIn + rLogSize ){ -+ WHERETRACE(0x40, -+ ("Scan preferred over IN operator on column %d of \"%s\" (%d<%d)\n", -+ saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize)); -+ continue; -+ }else{ -+ WHERETRACE(0x40, -+ ("IN operator preferred on column %d of \"%s\" (%d>=%d)\n", -+ saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize)); -+ } -+ } -+ pNew->wsFlags |= WHERE_COLUMN_IN; - }else if( eOp & (WO_EQ|WO_IS) ){ - int iCol = pProbe->aiColumn[saved_nEq]; - pNew->wsFlags |= WHERE_COLUMN_EQ; - assert( saved_nEq==pNew->u.btree.nEq ); - if( iCol==XN_ROWID -- || (iCol>0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) -+ || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) - ){ -- if( iCol>=0 && pProbe->uniqNotNull==0 ){ -+ if( iCol==XN_ROWID || pProbe->uniqNotNull -+ || (pProbe->nKeyCol==1 && pProbe->onError && eOp==WO_EQ) -+ ){ -+ pNew->wsFlags |= WHERE_ONEROW; -+ }else{ - pNew->wsFlags |= WHERE_UNQ_WANTED; -- }else{ -- pNew->wsFlags |= WHERE_ONEROW; - } - } - }else if( eOp & WO_ISNULL ){ -@@ -133967,6 +141832,7 @@ - && pProbe->nSample - && pNew->u.btree.nEq<=pProbe->nSampleCol - && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect)) -+ && OptimizationEnabled(db, SQLITE_Stat34) - ){ - Expr *pExpr = pTerm->pExpr; - if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){ -@@ -134055,6 +141921,7 @@ - if( saved_nEq==saved_nSkip - && saved_nEq+1<pProbe->nKeyCol - && pProbe->noSkipScan==0 -+ && OptimizationEnabled(db, SQLITE_SkipScan) - && pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */ - && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK - ){ -@@ -134075,8 +141942,8 @@ - pNew->wsFlags = saved_wsFlags; - } - -- WHERETRACE(0x800, ("END addBtreeIdx(%s), nEq=%d, rc=%d\n", -- pProbe->zName, saved_nEq, rc)); -+ WHERETRACE(0x800, ("END %s.addBtreeIdx(%s), nEq=%d, rc=%d\n", -+ pProbe->pTable->zName, pProbe->zName, saved_nEq, rc)); - return rc; - } - -@@ -134109,7 +141976,7 @@ - }else if( (aColExpr = pIndex->aColExpr)!=0 ){ - for(jj=0; jj<pIndex->nKeyCol; jj++){ - if( pIndex->aiColumn[jj]!=XN_EXPR ) continue; -- if( sqlite3ExprCompare(0, pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){ -+ if( sqlite3ExprCompareSkip(pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){ - return 1; - } - } -@@ -134118,24 +141985,6 @@ - return 0; - } - --/* --** Return a bitmask where 1s indicate that the corresponding column of --** the table is used by an index. Only the first 63 columns are considered. --*/ --static Bitmask columnsInIndex(Index *pIdx){ -- Bitmask m = 0; -- int j; -- for(j=pIdx->nColumn-1; j>=0; j--){ -- int x = pIdx->aiColumn[j]; -- if( x>=0 ){ -- testcase( x==BMS-1 ); -- testcase( x==BMS-2 ); -- if( x<BMS-1 ) m |= MASKBIT(x); -- } -- } -- return m; --} -- - /* 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. - */ -@@ -134280,14 +142129,16 @@ - /* TUNING: One-time cost for computing the automatic index is - ** estimated to be X*N*log2(N) where N is the number of rows in - ** the table being indexed and where X is 7 (LogEst=28) for normal -- ** tables or 1.375 (LogEst=4) for views and subqueries. The value -+ ** tables or 0.5 (LogEst=-10) for views and subqueries. The value - ** of X is smaller for views and subqueries so that the query planner - ** will be more aggressive about generating automatic indexes for - ** those objects, since there is no opportunity to add schema - ** indexes on subqueries and views. */ -- pNew->rSetup = rLogSize + rSize + 4; -+ pNew->rSetup = rLogSize + rSize; - if( pTab->pSelect==0 && (pTab->tabFlags & TF_Ephemeral)==0 ){ -- pNew->rSetup += 24; -+ pNew->rSetup += 28; -+ }else{ -+ pNew->rSetup -= 10; - } - ApplyCostMultiplier(pNew->rSetup, pTab->costMult); - if( pNew->rSetup<0 ) pNew->rSetup = 0; -@@ -134305,14 +142156,17 @@ - } - #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ - -- /* Loop over all indices -- */ -- for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){ -+ /* Loop over all indices. If there was an INDEXED BY clause, then only -+ ** consider index pProbe. */ -+ for(; rc==SQLITE_OK && pProbe; -+ pProbe=(pSrc->pIBIndex ? 0 : pProbe->pNext), iSortIdx++ -+ ){ - if( pProbe->pPartIdxWhere!=0 - && !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){ - testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */ - continue; /* Partial index inappropriate for this query */ - } -+ if( pProbe->bNoQuery ) continue; - rSize = pProbe->aiRowLogEst[0]; - pNew->u.btree.nEq = 0; - pNew->u.btree.nBtm = 0; -@@ -134346,7 +142200,7 @@ - pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; - m = 0; - }else{ -- m = pSrc->colUsed & ~columnsInIndex(pProbe); -+ m = pSrc->colUsed & pProbe->colNotIdxed; - pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED; - } - -@@ -134417,10 +142271,6 @@ - pBuilder->nRecValid = 0; - pBuilder->pRec = 0; - #endif -- -- /* If there was an INDEXED BY clause, then only that one index is -- ** considered. */ -- if( pSrc->pIBIndex ) break; - } - return rc; - } -@@ -134497,7 +142347,17 @@ - - /* Invoke the virtual table xBestIndex() method */ - rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo); -- if( rc ) return rc; -+ if( rc ){ -+ if( rc==SQLITE_CONSTRAINT ){ -+ /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means -+ ** that the particular combination of parameters provided is unusable. -+ ** Make no entries in the loop table. -+ */ -+ WHERETRACE(0xffff, (" ^^^^--- non-viable plan rejected!\n")); -+ return SQLITE_OK; -+ } -+ return rc; -+ } - - mxTerm = -1; - assert( pNew->nLSlot>=nConstraint ); -@@ -134515,9 +142375,9 @@ - || pNew->aLTerm[iTerm]!=0 - || pIdxCons->usable==0 - ){ -- rc = SQLITE_ERROR; - sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); -- return rc; -+ testcase( pIdxInfo->needToFreeIdxStr ); -+ return SQLITE_ERROR; - } - testcase( iTerm==nConstraint-1 ); - testcase( j==0 ); -@@ -134545,6 +142405,15 @@ - pNew->u.vtab.omitMask &= ~mNoOmit; - - pNew->nLTerm = mxTerm+1; -+ for(i=0; i<=mxTerm; i++){ -+ if( pNew->aLTerm[i]==0 ){ -+ /* The non-zero argvIdx values must be contiguous. Raise an -+ ** error if they are not */ -+ sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); -+ testcase( pIdxInfo->needToFreeIdxStr ); -+ return SQLITE_ERROR; -+ } -+ } - assert( pNew->nLTerm<=pNew->nLSlot ); - pNew->u.vtab.idxNum = pIdxInfo->idxNum; - pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr; -@@ -134575,6 +142444,27 @@ - return rc; - } - -+/* -+** If this function is invoked from within an xBestIndex() callback, it -+** returns a pointer to a buffer containing the name of the collation -+** sequence associated with element iCons of the sqlite3_index_info.aConstraint -+** array. Or, if iCons is out of range or there is no active xBestIndex -+** call, return NULL. -+*/ -+SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){ -+ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; -+ const char *zRet = 0; -+ if( iCons>=0 && iCons<pIdxInfo->nConstraint ){ -+ CollSeq *pC = 0; -+ int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset; -+ Expr *pX = pHidden->pWC->a[iTerm].pExpr; -+ if( pX->pLeft ){ -+ pC = sqlite3BinaryCompareCollSeq(pHidden->pParse, pX->pLeft, pX->pRight); -+ } -+ zRet = (pC ? pC->zName : sqlite3StrBINARY); -+ } -+ return zRet; -+} - - /* - ** Add all WhereLoop objects for a table of the join identified by -@@ -134639,6 +142529,7 @@ - } - - /* First call xBestIndex() with all constraints usable. */ -+ WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName)); - WHERETRACE(0x40, (" VirtualOne: all usable\n")); - rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn); - -@@ -134714,6 +142605,7 @@ - - if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr); - sqlite3DbFreeNN(pParse->db, p); -+ WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc)); - return rc; - } - #endif /* SQLITE_OMIT_VIRTUALTABLE */ -@@ -134861,9 +142753,11 @@ - /* Loop over the tables in the join, from left to right */ - pNew = pBuilder->pNew; - whereLoopInit(pNew); -+ pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT; - for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){ - Bitmask mUnusable = 0; - pNew->iTab = iTab; -+ pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR; - pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor); - if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){ - /* This condition is true when pItem is the FROM clause term on the -@@ -134885,11 +142779,19 @@ - { - rc = whereLoopAddBtree(pBuilder, mPrereq); - } -- if( rc==SQLITE_OK ){ -+ if( rc==SQLITE_OK && pBuilder->pWC->hasOr ){ - rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable); - } - mPrior |= pNew->maskSelf; -- if( rc || db->mallocFailed ) break; -+ if( rc || db->mallocFailed ){ -+ if( rc==SQLITE_DONE ){ -+ /* We hit the query planner search limit set by iPlanLimit */ -+ sqlite3_log(SQLITE_WARNING, "abbreviated query algorithm search"); -+ rc = SQLITE_OK; -+ }else{ -+ break; -+ } -+ } - } - - whereLoopClear(db, pNew); -@@ -135019,14 +142921,10 @@ - if( j>=pLoop->nLTerm ) continue; - } - if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){ -- const char *z1, *z2; -- pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); -- if( !pColl ) pColl = db->pDfltColl; -- z1 = pColl->zName; -- pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr); -- if( !pColl ) pColl = db->pDfltColl; -- z2 = pColl->zName; -- if( sqlite3StrICmp(z1, z2)!=0 ) continue; -+ if( sqlite3ExprCollSeqMatch(pWInfo->pParse, -+ pOrderBy->a[i].pExpr, pTerm->pExpr)==0 ){ -+ continue; -+ } - testcase( pTerm->pExpr->op==TK_IS ); - } - obSat |= MASKBIT(i); -@@ -135098,7 +142996,7 @@ - if( pIndex ){ - iColumn = pIndex->aiColumn[j]; - revIdx = pIndex->aSortOrder[j]; -- if( iColumn==pIndex->pTable->iPKey ) iColumn = -1; -+ if( iColumn==pIndex->pTable->iPKey ) iColumn = XN_ROWID; - }else{ - iColumn = XN_ROWID; - revIdx = 0; -@@ -135125,19 +143023,18 @@ - testcase( wctrlFlags & WHERE_GROUPBY ); - testcase( wctrlFlags & WHERE_DISTINCTBY ); - if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0; -- if( iColumn>=(-1) ){ -+ if( iColumn>=XN_ROWID ){ - if( pOBExpr->op!=TK_COLUMN ) continue; - if( pOBExpr->iTable!=iCur ) continue; - if( pOBExpr->iColumn!=iColumn ) continue; - }else{ -- if( sqlite3ExprCompare(0, -- pOBExpr,pIndex->aColExpr->a[j].pExpr,iCur) ){ -+ Expr *pIdxExpr = pIndex->aColExpr->a[j].pExpr; -+ if( sqlite3ExprCompareSkip(pOBExpr, pIdxExpr, iCur) ){ - continue; - } - } -- if( iColumn>=0 ){ -- pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); -- if( !pColl ) pColl = db->pDfltColl; -+ if( iColumn!=XN_ROWID ){ -+ pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); - if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; - } - pLoop->u.btree.nIdxCol = j+1; -@@ -135397,12 +143294,15 @@ - - if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue; - if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue; -- if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<10 ){ -+ if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<3 ){ - /* Do not use an automatic index if the this loop is expected -- ** to run less than 2 times. */ -+ ** to run less than 1.25 times. It is tempting to also exclude -+ ** automatic index usage on an outer loop, but sometimes an automatic -+ ** index is useful in the outer loop of a correlated subquery. */ - assert( 10==sqlite3LogEst(2) ); - continue; - } -+ - /* At this point, pWLoop is a candidate to be the next loop. - ** Compute its cost */ - rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); -@@ -135422,7 +143322,11 @@ - pWInfo, nRowEst, nOrderBy, isOrdered - ); - } -- rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]); -+ /* TUNING: Add a small extra penalty (5) to sorting as an -+ ** extra encouragment to the query planner to select a plan -+ ** where the rows emerge in the correct order without any sorting -+ ** required. */ -+ rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 5; - - WHERETRACE(0x002, - ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n", -@@ -135612,6 +143516,7 @@ - pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; - } - } -+ pWInfo->bOrderedInnerLoop = 0; - if( pWInfo->pOrderBy ){ - if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){ - if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){ -@@ -135723,7 +143628,7 @@ - } - if( j!=pIdx->nKeyCol ) continue; - pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED; -- if( pIdx->isCovering || (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){ -+ if( pIdx->isCovering || (pItem->colUsed & pIdx->colNotIdxed)==0 ){ - pLoop->wsFlags |= WHERE_IDX_ONLY; - } - pLoop->nLTerm = j; -@@ -135774,6 +143679,7 @@ - memset(&w, 0, sizeof(w)); - w.eCode = 1; - w.xExprCallback = exprNodeIsDeterministic; -+ w.xSelectCallback = sqlite3SelectWalkFail; - sqlite3WalkExpr(&w, p); - return w.eCode; - } -@@ -135983,37 +143889,39 @@ - if( wctrlFlags & WHERE_WANT_DISTINCT ){ - pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; - } -- } -- -- /* Assign a bit from the bitmask to every term in the FROM clause. -- ** -- ** The N-th term of the FROM clause is assigned a bitmask of 1<<N. -- ** -- ** The rule of the previous sentence ensures thta if X is the bitmask for -- ** a table T, then X-1 is the bitmask for all other tables to the left of T. -- ** Knowing the bitmask for all tables to the left of a left join is -- ** important. Ticket #3015. -- ** -- ** Note that bitmasks are created for all pTabList->nSrc tables in -- ** pTabList, not just the first nTabList tables. nTabList is normally -- ** equal to pTabList->nSrc but might be shortened to 1 if the -- ** WHERE_OR_SUBCLAUSE flag is set. -- */ -- for(ii=0; ii<pTabList->nSrc; ii++){ -- createMask(pMaskSet, pTabList->a[ii].iCursor); -- sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC); -- } --#ifdef SQLITE_DEBUG -- { -- Bitmask mx = 0; -- for(ii=0; ii<pTabList->nSrc; ii++){ -- Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor); -- assert( m>=mx ); -- mx = m; -+ ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW")); -+ }else{ -+ /* Assign a bit from the bitmask to every term in the FROM clause. -+ ** -+ ** The N-th term of the FROM clause is assigned a bitmask of 1<<N. -+ ** -+ ** The rule of the previous sentence ensures thta if X is the bitmask for -+ ** a table T, then X-1 is the bitmask for all other tables to the left of T. -+ ** Knowing the bitmask for all tables to the left of a left join is -+ ** important. Ticket #3015. -+ ** -+ ** Note that bitmasks are created for all pTabList->nSrc tables in -+ ** pTabList, not just the first nTabList tables. nTabList is normally -+ ** equal to pTabList->nSrc but might be shortened to 1 if the -+ ** WHERE_OR_SUBCLAUSE flag is set. -+ */ -+ ii = 0; -+ do{ -+ createMask(pMaskSet, pTabList->a[ii].iCursor); -+ sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC); -+ }while( (++ii)<pTabList->nSrc ); -+ #ifdef SQLITE_DEBUG -+ { -+ Bitmask mx = 0; -+ for(ii=0; ii<pTabList->nSrc; ii++){ -+ Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor); -+ assert( m>=mx ); -+ mx = m; -+ } - } -+ #endif - } --#endif -- -+ - /* Analyze all of the subexpressions. */ - sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC); - if( db->mallocFailed ) goto whereBeginError; -@@ -136031,6 +143939,7 @@ - */ - for(ii=0; ii<sWLB.pWC->nTerm; ii++){ - WhereTerm *pT = &sWLB.pWC->a[ii]; -+ if( pT->wtFlags & TERM_VIRTUAL ) continue; - if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){ - sqlite3ExprIfFalse(pParse, pT->pExpr, pWInfo->iBreak, SQLITE_JUMPIFNULL); - pT->wtFlags |= TERM_CODED; -@@ -136118,35 +144027,80 @@ - } - } - #endif -- /* Attempt to omit tables from the join that do not effect the result */ -+ -+ /* Attempt to omit tables from the join that do not affect the result. -+ ** For a table to not affect the result, the following must be true: -+ ** -+ ** 1) The query must not be an aggregate. -+ ** 2) The table must be the RHS of a LEFT JOIN. -+ ** 3) Either the query must be DISTINCT, or else the ON or USING clause -+ ** must contain a constraint that limits the scan of the table to -+ ** at most a single row. -+ ** 4) The table must not be referenced by any part of the query apart -+ ** from its own USING or ON clause. -+ ** -+ ** For example, given: -+ ** -+ ** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1); -+ ** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2); -+ ** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3); -+ ** -+ ** 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) -+ ** -+ ** or from: -+ ** -+ ** SELECT DISTINCT v1, v3 FROM t1 -+ ** LEFT JOIN t2 -+ ** LEFT JOIN t3 USING (t1.ipk=t3.ipk) -+ */ -+ notReady = ~(Bitmask)0; - if( pWInfo->nLevel>=2 -- && pResultSet!=0 -+ && pResultSet!=0 /* guarantees condition (1) above */ - && OptimizationEnabled(db, SQLITE_OmitNoopJoin) - ){ -+ int i; - Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet); - if( sWLB.pOrderBy ){ - tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy); - } -- while( pWInfo->nLevel>=2 ){ -+ for(i=pWInfo->nLevel-1; i>=1; i--){ - WhereTerm *pTerm, *pEnd; -- pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop; -- if( (pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0 ) break; -+ struct SrcList_item *pItem; -+ pLoop = pWInfo->a[i].pWLoop; -+ pItem = &pWInfo->pTabList->a[pLoop->iTab]; -+ if( (pItem->fg.jointype & JT_LEFT)==0 ) continue; - if( (wctrlFlags & WHERE_WANT_DISTINCT)==0 - && (pLoop->wsFlags & WHERE_ONEROW)==0 - ){ -- break; -+ continue; - } -- if( (tabUsed & pLoop->maskSelf)!=0 ) break; -+ if( (tabUsed & pLoop->maskSelf)!=0 ) continue; - pEnd = sWLB.pWC->a + sWLB.pWC->nTerm; - for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){ -- if( (pTerm->prereqAll & pLoop->maskSelf)!=0 -- && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) -- ){ -- break; -+ if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){ -+ if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin) -+ || pTerm->pExpr->iRightJoinTable!=pItem->iCursor -+ ){ -+ break; -+ } - } - } -- if( pTerm<pEnd ) break; -+ if( pTerm<pEnd ) continue; - WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId)); -+ notReady &= ~pLoop->maskSelf; -+ for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){ -+ if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){ -+ pTerm->wtFlags |= TERM_CODED; -+ } -+ } -+ if( i!=pWInfo->nLevel-1 ){ -+ int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel); -+ memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte); -+ } - pWInfo->nLevel--; - nTabList--; - } -@@ -136156,15 +144110,32 @@ - - /* If the caller is an UPDATE or DELETE statement that is requesting - ** to use a one-pass algorithm, determine if this is appropriate. -+ ** -+ ** A one-pass approach can be used if the caller has requested one -+ ** and either (a) the scan visits at most one row or (b) each -+ ** of the following are true: -+ ** -+ ** * the caller has indicated that a one-pass approach can be used -+ ** with multiple rows (by setting WHERE_ONEPASS_MULTIROW), and -+ ** * the table is not a virtual table, and -+ ** * either the scan does not use the OR optimization or the caller -+ ** is a DELETE operation (WHERE_DUPLICATES_OK is only specified -+ ** for DELETE). -+ ** -+ ** The last qualification is because an UPDATE statement uses -+ ** WhereInfo.aiCurOnePass[1] to determine whether or not it really can -+ ** use a one-pass approach, and this is not set accurately for scans -+ ** that use the OR optimization. - */ - assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 ); - if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){ - int wsFlags = pWInfo->a[0].pWLoop->wsFlags; - int bOnerow = (wsFlags & WHERE_ONEROW)!=0; -- if( bOnerow -- || ((wctrlFlags & WHERE_ONEPASS_MULTIROW)!=0 -- && 0==(wsFlags & WHERE_VIRTUALTABLE)) -- ){ -+ if( bOnerow || ( -+ 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW) -+ && 0==(wsFlags & WHERE_VIRTUALTABLE) -+ && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK)) -+ )){ - pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; - if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){ - if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){ -@@ -136236,7 +144207,7 @@ - Index *pIx = pLoop->u.btree.pIndex; - int iIndexCur; - int op = OP_OpenRead; -- /* iAuxArg is always set if to a positive value if ONEPASS is possible */ -+ /* iAuxArg is always set to a positive value if ONEPASS is possible */ - assert( iAuxArg!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 ); - if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIx) - && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 -@@ -136301,7 +144272,6 @@ - ** loop below generates code for a single nested loop of the VM - ** program. - */ -- notReady = ~(Bitmask)0; - for(ii=0; ii<nTabList; ii++){ - int addrExplain; - int wsFlags; -@@ -136315,7 +144285,7 @@ - } - #endif - addrExplain = sqlite3WhereExplainOneScan( -- pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags -+ pParse, pTabList, pLevel, wctrlFlags - ); - pLevel->addrBody = sqlite3VdbeCurrentAddr(v); - notReady = sqlite3WhereCodeOneLoopStart(pWInfo, ii, notReady); -@@ -136339,6 +144309,26 @@ - } - - /* -+** Part of sqlite3WhereEnd() will rewrite opcodes to reference the -+** index rather than the main table. In SQLITE_DEBUG mode, we want -+** to trace those changes if PRAGMA vdbe_addoptrace=on. This routine -+** does that. -+*/ -+#ifndef SQLITE_DEBUG -+# define OpcodeRewriteTrace(D,K,P) /* no-op */ -+#else -+# define OpcodeRewriteTrace(D,K,P) sqlite3WhereOpcodeRewriteTrace(D,K,P) -+ static void sqlite3WhereOpcodeRewriteTrace( -+ sqlite3 *db, -+ int pc, -+ VdbeOp *pOp -+ ){ -+ if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return; -+ sqlite3VdbePrintOp(0, pc, pOp); -+ } -+#endif -+ -+/* - ** Generate the end of the WHERE loop. See comments on - ** sqlite3WhereBegin() for additional information. - */ -@@ -136354,7 +144344,6 @@ - /* Generate loop termination code. - */ - VdbeModuleComment((v, "End WHERE-core")); -- sqlite3ExprCacheClear(pParse); - for(i=pWInfo->nLevel-1; i>=0; i--){ - int addr; - pLevel = &pWInfo->a[i]; -@@ -136365,6 +144354,7 @@ - Index *pIdx; - int n; - if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED -+ && i==pWInfo->nLevel-1 /* Ticket [ef9318757b152e3] 2017-10-21 */ - && (pLoop->wsFlags & WHERE_INDEXED)!=0 - && (pIdx = pLoop->u.btree.pIndex)->hasStat1 - && (n = pLoop->u.btree.nIdxCol)>0 -@@ -136404,10 +144394,17 @@ - for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){ - sqlite3VdbeJumpHere(v, pIn->addrInTop+1); - 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); -+ } - sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); - VdbeCoverage(v); -- VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen); -- VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen); -+ VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Prev); -+ VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Next); - } - sqlite3VdbeJumpHere(v, pIn->addrInTop-1); - } -@@ -136431,7 +144428,8 @@ - addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); - assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 ); - if( (ws & WHERE_IDX_ONLY)==0 ){ -- sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor); -+ assert( pLevel->iTabCur==pTabList->a[pLevel->iFrom].iCursor ); -+ sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur); - } - if( (ws & WHERE_INDEXED) - || ((ws & WHERE_MULTI_OR) && pLevel->u.pCovidx) -@@ -136497,10 +144495,19 @@ - ){ - last = sqlite3VdbeCurrentAddr(v); - k = pLevel->addrBody; -+#ifdef SQLITE_DEBUG -+ if( db->flags & SQLITE_VdbeAddopTrace ){ -+ printf("TRANSLATE opcodes in range %d..%d\n", k, last-1); -+ } -+#endif - pOp = sqlite3VdbeGetOp(v, k); - for(; k<last; k++, pOp++){ - if( pOp->p1!=pLevel->iTabCur ) continue; -- if( pOp->opcode==OP_Column ){ -+ if( pOp->opcode==OP_Column -+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC -+ || pOp->opcode==OP_Offset -+#endif -+ ){ - int x = pOp->p2; - assert( pIdx->pTable==pTab ); - if( !HasRowid(pTab) ){ -@@ -136512,6 +144519,7 @@ - if( x>=0 ){ - pOp->p2 = x; - pOp->p1 = pLevel->iIdxCur; -+ OpcodeRewriteTrace(db, k, pOp); - } - assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 - || pWInfo->eOnePass ); -@@ -136518,10 +144526,15 @@ - }else if( pOp->opcode==OP_Rowid ){ - pOp->p1 = pLevel->iIdxCur; - pOp->opcode = OP_IdxRowid; -+ OpcodeRewriteTrace(db, k, pOp); - }else if( pOp->opcode==OP_IfNullRow ){ - pOp->p1 = pLevel->iIdxCur; -+ OpcodeRewriteTrace(db, k, pOp); - } - } -+#ifdef SQLITE_DEBUG -+ if( db->flags & SQLITE_VdbeAddopTrace ) printf("TRANSLATE complete\n"); -+#endif - } - } - -@@ -136533,6 +144546,2263 @@ - } - - /************** End of where.c ***********************************************/ -+/************** Begin file window.c ******************************************/ -+/* -+** 2018 May 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. -+** -+************************************************************************* -+*/ -+/* #include "sqliteInt.h" */ -+ -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ -+/* -+** SELECT REWRITING -+** -+** Any SELECT statement that contains one or more window functions in -+** either the select list or ORDER BY clause (the only two places window -+** functions may be used) is transformed by function sqlite3WindowRewrite() -+** in order to support window function processing. For example, with the -+** schema: -+** -+** CREATE TABLE t1(a, b, c, d, e, f, g); -+** -+** the statement: -+** -+** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM t1 ORDER BY e; -+** -+** is transformed to: -+** -+** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM ( -+** SELECT a, e, c, d, b FROM t1 ORDER BY c, d -+** ) ORDER BY e; -+** -+** The flattening optimization is disabled when processing this transformed -+** SELECT statement. This allows the implementation of the window function -+** (in this case max()) to process rows sorted in order of (c, d), which -+** makes things easier for obvious reasons. More generally: -+** -+** * FROM, WHERE, GROUP BY and HAVING clauses are all moved to -+** the sub-query. -+** -+** * ORDER BY, LIMIT and OFFSET remain part of the parent query. -+** -+** * Terminals from each of the expression trees that make up the -+** select-list and ORDER BY expressions in the parent query are -+** selected by the sub-query. For the purposes of the transformation, -+** terminals are column references and aggregate functions. -+** -+** If there is more than one window function in the SELECT that uses -+** the same window declaration (the OVER bit), then a single scan may -+** be used to process more than one window function. For example: -+** -+** SELECT max(b) OVER (PARTITION BY c ORDER BY d), -+** min(e) OVER (PARTITION BY c ORDER BY d) -+** FROM t1; -+** -+** is transformed in the same way as the example above. However: -+** -+** SELECT max(b) OVER (PARTITION BY c ORDER BY d), -+** min(e) OVER (PARTITION BY a ORDER BY b) -+** FROM t1; -+** -+** Must be transformed to: -+** -+** SELECT max(b) OVER (PARTITION BY c ORDER BY d) FROM ( -+** SELECT e, min(e) OVER (PARTITION BY a ORDER BY b), c, d, b FROM -+** SELECT a, e, c, d, b FROM t1 ORDER BY a, b -+** ) ORDER BY c, d -+** ) ORDER BY e; -+** -+** so that both min() and max() may process rows in the order defined by -+** their respective window declarations. -+** -+** INTERFACE WITH SELECT.C -+** -+** When processing the rewritten SELECT statement, code in select.c calls -+** sqlite3WhereBegin() to begin iterating through the results of the -+** sub-query, which is always implemented as a co-routine. It then calls -+** sqlite3WindowCodeStep() to process rows and finish the scan by calling -+** sqlite3WhereEnd(). -+** -+** sqlite3WindowCodeStep() generates VM code so that, for each row returned -+** by the sub-query a sub-routine (OP_Gosub) coded by select.c is invoked. -+** When the sub-routine is invoked: -+** -+** * The results of all window-functions for the row are stored -+** in the associated Window.regResult registers. -+** -+** * The required terminal values are stored in the current row of -+** temp table Window.iEphCsr. -+** -+** In some cases, depending on the window frame and the specific window -+** functions invoked, sqlite3WindowCodeStep() caches each entire partition -+** in a temp table before returning any rows. In other cases it does not. -+** This detail is encapsulated within this file, the code generated by -+** select.c is the same in either case. -+** -+** BUILT-IN WINDOW FUNCTIONS -+** -+** This implementation features the following built-in window functions: -+** -+** row_number() -+** rank() -+** dense_rank() -+** percent_rank() -+** cume_dist() -+** ntile(N) -+** lead(expr [, offset [, default]]) -+** lag(expr [, offset [, default]]) -+** first_value(expr) -+** last_value(expr) -+** nth_value(expr, N) -+** -+** These are the same built-in window functions supported by Postgres. -+** Although the behaviour of aggregate window functions (functions that -+** can be used as either aggregates or window funtions) allows them to -+** be implemented using an API, built-in window functions are much more -+** esoteric. Additionally, some window functions (e.g. nth_value()) -+** may only be implemented by caching the entire partition in memory. -+** As such, some built-in window functions use the same API as aggregate -+** window functions and some are implemented directly using VDBE -+** instructions. Additionally, for those functions that use the API, the -+** window frame is sometimes modified before the SELECT statement is -+** rewritten. For example, regardless of the specified window frame, the -+** row_number() function always uses: -+** -+** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -+** -+** See sqlite3WindowUpdate() for details. -+** -+** As well as some of the built-in window functions, aggregate window -+** functions min() and max() are implemented using VDBE instructions if -+** the start of the window frame is declared as anything other than -+** UNBOUNDED PRECEDING. -+*/ -+ -+/* -+** Implementation of built-in window function row_number(). Assumes that the -+** window frame has been coerced to: -+** -+** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -+*/ -+static void row_numberStepFunc( -+ sqlite3_context *pCtx, -+ int nArg, -+ sqlite3_value **apArg -+){ -+ i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p)); -+ if( p ) (*p)++; -+ UNUSED_PARAMETER(nArg); -+ UNUSED_PARAMETER(apArg); -+} -+static void row_numberValueFunc(sqlite3_context *pCtx){ -+ i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p)); -+ sqlite3_result_int64(pCtx, (p ? *p : 0)); -+} -+ -+/* -+** Context object type used by rank(), dense_rank(), percent_rank() and -+** cume_dist(). -+*/ -+struct CallCount { -+ i64 nValue; -+ i64 nStep; -+ i64 nTotal; -+}; -+ -+/* -+** Implementation of built-in window function dense_rank(). Assumes that -+** the window frame has been set to: -+** -+** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -+*/ -+static void dense_rankStepFunc( -+ sqlite3_context *pCtx, -+ int nArg, -+ sqlite3_value **apArg -+){ -+ struct CallCount *p; -+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); -+ if( p ) p->nStep = 1; -+ UNUSED_PARAMETER(nArg); -+ UNUSED_PARAMETER(apArg); -+} -+static void dense_rankValueFunc(sqlite3_context *pCtx){ -+ struct CallCount *p; -+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); -+ if( p ){ -+ if( p->nStep ){ -+ p->nValue++; -+ p->nStep = 0; -+ } -+ sqlite3_result_int64(pCtx, p->nValue); -+ } -+} -+ -+/* -+** Implementation of built-in window function rank(). Assumes that -+** the window frame has been set to: -+** -+** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -+*/ -+static void rankStepFunc( -+ sqlite3_context *pCtx, -+ int nArg, -+ sqlite3_value **apArg -+){ -+ struct CallCount *p; -+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); -+ if( p ){ -+ p->nStep++; -+ if( p->nValue==0 ){ -+ p->nValue = p->nStep; -+ } -+ } -+ UNUSED_PARAMETER(nArg); -+ UNUSED_PARAMETER(apArg); -+} -+static void rankValueFunc(sqlite3_context *pCtx){ -+ struct CallCount *p; -+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); -+ if( p ){ -+ sqlite3_result_int64(pCtx, p->nValue); -+ p->nValue = 0; -+ } -+} -+ -+/* -+** Implementation of built-in window function percent_rank(). Assumes that -+** the window frame has been set to: -+** -+** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -+*/ -+static void percent_rankStepFunc( -+ sqlite3_context *pCtx, -+ int nArg, -+ sqlite3_value **apArg -+){ -+ struct CallCount *p; -+ UNUSED_PARAMETER(nArg); assert( nArg==1 ); -+ -+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); -+ if( p ){ -+ if( p->nTotal==0 ){ -+ p->nTotal = sqlite3_value_int64(apArg[0]); -+ } -+ p->nStep++; -+ if( p->nValue==0 ){ -+ p->nValue = p->nStep; -+ } -+ } -+} -+static void percent_rankValueFunc(sqlite3_context *pCtx){ -+ struct CallCount *p; -+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); -+ if( p ){ -+ if( p->nTotal>1 ){ -+ double r = (double)(p->nValue-1) / (double)(p->nTotal-1); -+ sqlite3_result_double(pCtx, r); -+ }else{ -+ sqlite3_result_double(pCtx, 0.0); -+ } -+ p->nValue = 0; -+ } -+} -+ -+/* -+** Implementation of built-in window function cume_dist(). Assumes that -+** the window frame has been set to: -+** -+** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -+*/ -+static void cume_distStepFunc( -+ sqlite3_context *pCtx, -+ int nArg, -+ sqlite3_value **apArg -+){ -+ struct CallCount *p; -+ assert( nArg==1 ); UNUSED_PARAMETER(nArg); -+ -+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); -+ if( p ){ -+ if( p->nTotal==0 ){ -+ p->nTotal = sqlite3_value_int64(apArg[0]); -+ } -+ p->nStep++; -+ } -+} -+static void cume_distValueFunc(sqlite3_context *pCtx){ -+ struct CallCount *p; -+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); -+ if( p && p->nTotal ){ -+ double r = (double)(p->nStep) / (double)(p->nTotal); -+ sqlite3_result_double(pCtx, r); -+ } -+} -+ -+/* -+** Context object for ntile() window function. -+*/ -+struct NtileCtx { -+ i64 nTotal; /* Total rows in partition */ -+ i64 nParam; /* Parameter passed to ntile(N) */ -+ i64 iRow; /* Current row */ -+}; -+ -+/* -+** Implementation of ntile(). This assumes that the window frame has -+** been coerced to: -+** -+** ROWS UNBOUNDED PRECEDING AND CURRENT ROW -+*/ -+static void ntileStepFunc( -+ sqlite3_context *pCtx, -+ int nArg, -+ sqlite3_value **apArg -+){ -+ struct NtileCtx *p; -+ assert( nArg==2 ); UNUSED_PARAMETER(nArg); -+ p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); -+ if( p ){ -+ if( p->nTotal==0 ){ -+ p->nParam = sqlite3_value_int64(apArg[0]); -+ p->nTotal = sqlite3_value_int64(apArg[1]); -+ if( p->nParam<=0 ){ -+ sqlite3_result_error( -+ pCtx, "argument of ntile must be a positive integer", -1 -+ ); -+ } -+ } -+ p->iRow++; -+ } -+} -+static void ntileValueFunc(sqlite3_context *pCtx){ -+ struct NtileCtx *p; -+ p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); -+ if( p && p->nParam>0 ){ -+ int nSize = (p->nTotal / p->nParam); -+ if( nSize==0 ){ -+ sqlite3_result_int64(pCtx, p->iRow); -+ }else{ -+ i64 nLarge = p->nTotal - p->nParam*nSize; -+ i64 iSmall = nLarge*(nSize+1); -+ i64 iRow = p->iRow-1; -+ -+ assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal ); -+ -+ if( iRow<iSmall ){ -+ sqlite3_result_int64(pCtx, 1 + iRow/(nSize+1)); -+ }else{ -+ sqlite3_result_int64(pCtx, 1 + nLarge + (iRow-iSmall)/nSize); -+ } -+ } -+ } -+} -+ -+/* -+** Context object for last_value() window function. -+*/ -+struct LastValueCtx { -+ sqlite3_value *pVal; -+ int nVal; -+}; -+ -+/* -+** Implementation of last_value(). -+*/ -+static void last_valueStepFunc( -+ sqlite3_context *pCtx, -+ int nArg, -+ sqlite3_value **apArg -+){ -+ struct LastValueCtx *p; -+ UNUSED_PARAMETER(nArg); -+ p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); -+ if( p ){ -+ sqlite3_value_free(p->pVal); -+ p->pVal = sqlite3_value_dup(apArg[0]); -+ if( p->pVal==0 ){ -+ sqlite3_result_error_nomem(pCtx); -+ }else{ -+ p->nVal++; -+ } -+ } -+} -+static void last_valueInvFunc( -+ sqlite3_context *pCtx, -+ int nArg, -+ sqlite3_value **apArg -+){ -+ struct LastValueCtx *p; -+ UNUSED_PARAMETER(nArg); -+ UNUSED_PARAMETER(apArg); -+ p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); -+ if( ALWAYS(p) ){ -+ p->nVal--; -+ if( p->nVal==0 ){ -+ sqlite3_value_free(p->pVal); -+ p->pVal = 0; -+ } -+ } -+} -+static void last_valueValueFunc(sqlite3_context *pCtx){ -+ struct LastValueCtx *p; -+ p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); -+ if( p && p->pVal ){ -+ sqlite3_result_value(pCtx, p->pVal); -+ } -+} -+static void last_valueFinalizeFunc(sqlite3_context *pCtx){ -+ struct LastValueCtx *p; -+ p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); -+ if( p && p->pVal ){ -+ sqlite3_result_value(pCtx, p->pVal); -+ sqlite3_value_free(p->pVal); -+ p->pVal = 0; -+ } -+} -+ -+/* -+** Static names for the built-in window function names. These static -+** names are used, rather than string literals, so that FuncDef objects -+** can be associated with a particular window function by direct -+** comparison of the zName pointer. Example: -+** -+** if( pFuncDef->zName==row_valueName ){ ... } -+*/ -+static const char row_numberName[] = "row_number"; -+static const char dense_rankName[] = "dense_rank"; -+static const char rankName[] = "rank"; -+static const char percent_rankName[] = "percent_rank"; -+static const char cume_distName[] = "cume_dist"; -+static const char ntileName[] = "ntile"; -+static const char last_valueName[] = "last_value"; -+static const char nth_valueName[] = "nth_value"; -+static const char first_valueName[] = "first_value"; -+static const char leadName[] = "lead"; -+static const char lagName[] = "lag"; -+ -+/* -+** No-op implementations of xStep() and xFinalize(). Used as place-holders -+** for built-in window functions that never call those interfaces. -+** -+** The noopValueFunc() is called but is expected to do nothing. The -+** noopStepFunc() is never called, and so it is marked with NO_TEST to -+** let the test coverage routine know not to expect this function to be -+** invoked. -+*/ -+static void noopStepFunc( /*NO_TEST*/ -+ sqlite3_context *p, /*NO_TEST*/ -+ int n, /*NO_TEST*/ -+ sqlite3_value **a /*NO_TEST*/ -+){ /*NO_TEST*/ -+ UNUSED_PARAMETER(p); /*NO_TEST*/ -+ UNUSED_PARAMETER(n); /*NO_TEST*/ -+ UNUSED_PARAMETER(a); /*NO_TEST*/ -+ assert(0); /*NO_TEST*/ -+} /*NO_TEST*/ -+static void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ } -+ -+/* Window functions that use all window interfaces: xStep, xFinal, -+** xValue, and xInverse */ -+#define WINDOWFUNCALL(name,nArg,extra) { \ -+ nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ -+ name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc, \ -+ name ## InvFunc, name ## Name, {0} \ -+} -+ -+/* Window functions that are implemented using bytecode and thus have -+** no-op routines for their methods */ -+#define WINDOWFUNCNOOP(name,nArg,extra) { \ -+ nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ -+ noopStepFunc, noopValueFunc, noopValueFunc, \ -+ noopStepFunc, name ## Name, {0} \ -+} -+ -+/* Window functions that use all window interfaces: xStep, the -+** same routine for xFinalize and xValue and which never call -+** xInverse. */ -+#define WINDOWFUNCX(name,nArg,extra) { \ -+ nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ -+ name ## StepFunc, name ## ValueFunc, name ## ValueFunc, \ -+ noopStepFunc, name ## Name, {0} \ -+} -+ -+ -+/* -+** Register those built-in window functions that are not also aggregates. -+*/ -+SQLITE_PRIVATE void sqlite3WindowFunctions(void){ -+ static FuncDef aWindowFuncs[] = { -+ WINDOWFUNCX(row_number, 0, 0), -+ WINDOWFUNCX(dense_rank, 0, 0), -+ WINDOWFUNCX(rank, 0, 0), -+ WINDOWFUNCX(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE), -+ WINDOWFUNCX(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE), -+ WINDOWFUNCX(ntile, 1, SQLITE_FUNC_WINDOW_SIZE), -+ WINDOWFUNCALL(last_value, 1, 0), -+ WINDOWFUNCNOOP(nth_value, 2, 0), -+ WINDOWFUNCNOOP(first_value, 1, 0), -+ WINDOWFUNCNOOP(lead, 1, 0), -+ WINDOWFUNCNOOP(lead, 2, 0), -+ WINDOWFUNCNOOP(lead, 3, 0), -+ WINDOWFUNCNOOP(lag, 1, 0), -+ WINDOWFUNCNOOP(lag, 2, 0), -+ WINDOWFUNCNOOP(lag, 3, 0), -+ }; -+ sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs)); -+} -+ -+/* -+** This function is called immediately after resolving the function name -+** for a window function within a SELECT statement. Argument pList is a -+** linked list of WINDOW definitions for the current SELECT statement. -+** Argument pFunc is the function definition just resolved and pWin -+** is the Window object representing the associated OVER clause. This -+** function updates the contents of pWin as follows: -+** -+** * If the OVER clause refered to a named window (as in "max(x) OVER win"), -+** search list pList for a matching WINDOW definition, and update pWin -+** accordingly. If no such WINDOW clause can be found, leave an error -+** in pParse. -+** -+** * If the function is a built-in window function that requires the -+** window to be coerced (see "BUILT-IN WINDOW FUNCTIONS" at the top -+** of this file), pWin is updated here. -+*/ -+SQLITE_PRIVATE void sqlite3WindowUpdate( -+ Parse *pParse, -+ Window *pList, /* List of named windows for this SELECT */ -+ Window *pWin, /* Window frame to update */ -+ FuncDef *pFunc /* Window function definition */ -+){ -+ if( pWin->zName && pWin->eType==0 ){ -+ Window *p; -+ for(p=pList; p; p=p->pNextWin){ -+ if( sqlite3StrICmp(p->zName, pWin->zName)==0 ) break; -+ } -+ if( p==0 ){ -+ sqlite3ErrorMsg(pParse, "no such window: %s", pWin->zName); -+ return; -+ } -+ pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0); -+ pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0); -+ pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0); -+ pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0); -+ pWin->eStart = p->eStart; -+ pWin->eEnd = p->eEnd; -+ pWin->eType = p->eType; -+ } -+ if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){ -+ sqlite3 *db = pParse->db; -+ if( pWin->pFilter ){ -+ sqlite3ErrorMsg(pParse, -+ "FILTER clause may only be used with aggregate window functions" -+ ); -+ }else -+ if( pFunc->zName==row_numberName || pFunc->zName==ntileName ){ -+ sqlite3ExprDelete(db, pWin->pStart); -+ sqlite3ExprDelete(db, pWin->pEnd); -+ pWin->pStart = pWin->pEnd = 0; -+ pWin->eType = TK_ROWS; -+ pWin->eStart = TK_UNBOUNDED; -+ pWin->eEnd = TK_CURRENT; -+ }else -+ -+ if( pFunc->zName==dense_rankName || pFunc->zName==rankName -+ || pFunc->zName==percent_rankName || pFunc->zName==cume_distName -+ ){ -+ sqlite3ExprDelete(db, pWin->pStart); -+ sqlite3ExprDelete(db, pWin->pEnd); -+ pWin->pStart = pWin->pEnd = 0; -+ pWin->eType = TK_RANGE; -+ pWin->eStart = TK_UNBOUNDED; -+ pWin->eEnd = TK_CURRENT; -+ } -+ } -+ pWin->pFunc = pFunc; -+} -+ -+/* -+** Context object passed through sqlite3WalkExprList() to -+** selectWindowRewriteExprCb() by selectWindowRewriteEList(). -+*/ -+typedef struct WindowRewrite WindowRewrite; -+struct WindowRewrite { -+ Window *pWin; -+ SrcList *pSrc; -+ ExprList *pSub; -+ Select *pSubSelect; /* Current sub-select, if any */ -+}; -+ -+/* -+** Callback function used by selectWindowRewriteEList(). If necessary, -+** this function appends to the output expression-list and updates -+** expression (*ppExpr) in place. -+*/ -+static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){ -+ struct WindowRewrite *p = pWalker->u.pRewrite; -+ Parse *pParse = pWalker->pParse; -+ -+ /* If this function is being called from within a scalar sub-select -+ ** that used by the SELECT statement being processed, only process -+ ** TK_COLUMN expressions that refer to it (the outer SELECT). Do -+ ** not process aggregates or window functions at all, as they belong -+ ** to the scalar sub-select. */ -+ if( p->pSubSelect ){ -+ if( pExpr->op!=TK_COLUMN ){ -+ return WRC_Continue; -+ }else{ -+ int nSrc = p->pSrc->nSrc; -+ int i; -+ for(i=0; i<nSrc; i++){ -+ if( pExpr->iTable==p->pSrc->a[i].iCursor ) break; -+ } -+ if( i==nSrc ) return WRC_Continue; -+ } -+ } -+ -+ switch( pExpr->op ){ -+ -+ case TK_FUNCTION: -+ if( !ExprHasProperty(pExpr, EP_WinFunc) ){ -+ break; -+ }else{ -+ Window *pWin; -+ for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){ -+ if( pExpr->y.pWin==pWin ){ -+ assert( pWin->pOwner==pExpr ); -+ return WRC_Prune; -+ } -+ } -+ } -+ /* Fall through. */ -+ -+ case TK_AGG_FUNCTION: -+ case TK_COLUMN: { -+ Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0); -+ p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup); -+ if( p->pSub ){ -+ assert( ExprHasProperty(pExpr, EP_Static)==0 ); -+ ExprSetProperty(pExpr, EP_Static); -+ sqlite3ExprDelete(pParse->db, pExpr); -+ ExprClearProperty(pExpr, EP_Static); -+ memset(pExpr, 0, sizeof(Expr)); -+ -+ pExpr->op = TK_COLUMN; -+ pExpr->iColumn = p->pSub->nExpr-1; -+ pExpr->iTable = p->pWin->iEphCsr; -+ } -+ -+ break; -+ } -+ -+ default: /* no-op */ -+ break; -+ } -+ -+ return WRC_Continue; -+} -+static int selectWindowRewriteSelectCb(Walker *pWalker, Select *pSelect){ -+ struct WindowRewrite *p = pWalker->u.pRewrite; -+ Select *pSave = p->pSubSelect; -+ if( pSave==pSelect ){ -+ return WRC_Continue; -+ }else{ -+ p->pSubSelect = pSelect; -+ sqlite3WalkSelect(pWalker, pSelect); -+ p->pSubSelect = pSave; -+ } -+ return WRC_Prune; -+} -+ -+ -+/* -+** Iterate through each expression in expression-list pEList. For each: -+** -+** * TK_COLUMN, -+** * aggregate function, or -+** * window function with a Window object that is not a member of the -+** Window list passed as the second argument (pWin). -+** -+** Append the node to output expression-list (*ppSub). And replace it -+** with a TK_COLUMN that reads the (N-1)th element of table -+** pWin->iEphCsr, where N is the number of elements in (*ppSub) after -+** appending the new one. -+*/ -+static void selectWindowRewriteEList( -+ Parse *pParse, -+ Window *pWin, -+ SrcList *pSrc, -+ ExprList *pEList, /* Rewrite expressions in this list */ -+ ExprList **ppSub /* IN/OUT: Sub-select expression-list */ -+){ -+ Walker sWalker; -+ WindowRewrite sRewrite; -+ -+ memset(&sWalker, 0, sizeof(Walker)); -+ memset(&sRewrite, 0, sizeof(WindowRewrite)); -+ -+ sRewrite.pSub = *ppSub; -+ sRewrite.pWin = pWin; -+ sRewrite.pSrc = pSrc; -+ -+ sWalker.pParse = pParse; -+ sWalker.xExprCallback = selectWindowRewriteExprCb; -+ sWalker.xSelectCallback = selectWindowRewriteSelectCb; -+ sWalker.u.pRewrite = &sRewrite; -+ -+ (void)sqlite3WalkExprList(&sWalker, pEList); -+ -+ *ppSub = sRewrite.pSub; -+} -+ -+/* -+** Append a copy of each expression in expression-list pAppend to -+** expression list pList. Return a pointer to the result list. -+*/ -+static ExprList *exprListAppendList( -+ Parse *pParse, /* Parsing context */ -+ ExprList *pList, /* List to which to append. Might be NULL */ -+ ExprList *pAppend /* List of values to append. Might be NULL */ -+){ -+ if( pAppend ){ -+ int i; -+ int nInit = pList ? pList->nExpr : 0; -+ for(i=0; i<pAppend->nExpr; i++){ -+ Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0); -+ pList = sqlite3ExprListAppend(pParse, pList, pDup); -+ if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder; -+ } -+ } -+ return pList; -+} -+ -+/* -+** If the SELECT statement passed as the second argument does not invoke -+** any SQL window functions, this function is a no-op. Otherwise, it -+** rewrites the SELECT statement so that window function xStep functions -+** are invoked in the correct order as described under "SELECT REWRITING" -+** at the top of this file. -+*/ -+SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ -+ int rc = SQLITE_OK; -+ if( p->pWin && p->pPrior==0 ){ -+ Vdbe *v = sqlite3GetVdbe(pParse); -+ sqlite3 *db = pParse->db; -+ Select *pSub = 0; /* The subquery */ -+ SrcList *pSrc = p->pSrc; -+ Expr *pWhere = p->pWhere; -+ ExprList *pGroupBy = p->pGroupBy; -+ Expr *pHaving = p->pHaving; -+ ExprList *pSort = 0; -+ -+ ExprList *pSublist = 0; /* Expression list for sub-query */ -+ Window *pMWin = p->pWin; /* Master window object */ -+ Window *pWin; /* Window object iterator */ -+ -+ p->pSrc = 0; -+ p->pWhere = 0; -+ p->pGroupBy = 0; -+ p->pHaving = 0; -+ -+ /* 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, pSort, pMWin->pOrderBy); -+ if( pSort && p->pOrderBy ){ -+ if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){ -+ sqlite3ExprListDelete(db, p->pOrderBy); -+ p->pOrderBy = 0; -+ } -+ } -+ -+ /* Assign a cursor number for the ephemeral table used to buffer rows. -+ ** The OpenEphemeral instruction is coded later, after it is known how -+ ** many columns the table will have. */ -+ pMWin->iEphCsr = pParse->nTab++; -+ -+ selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist); -+ selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist); -+ pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0); -+ -+ /* Append the PARTITION BY and ORDER BY expressions to the to the -+ ** sub-select expression list. They are required to figure out where -+ ** boundaries for partitions and sets of peer rows lie. */ -+ pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition); -+ pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy); -+ -+ /* Append the arguments passed to each window function to the -+ ** sub-select expression list. Also allocate two registers for each -+ ** window function - one for the accumulator, another for interim -+ ** results. */ -+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ -+ pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); -+ pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList); -+ if( pWin->pFilter ){ -+ Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0); -+ pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter); -+ } -+ pWin->regAccum = ++pParse->nMem; -+ pWin->regResult = ++pParse->nMem; -+ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); -+ } -+ -+ /* If there is no ORDER BY or PARTITION BY clause, and the window -+ ** function accepts zero arguments, and there are no other columns -+ ** selected (e.g. "SELECT row_number() OVER () FROM t1"), it is possible -+ ** that pSublist is still NULL here. Add a constant expression here to -+ ** keep everything legal in this case. -+ */ -+ if( pSublist==0 ){ -+ pSublist = sqlite3ExprListAppend(pParse, 0, -+ sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0) -+ ); -+ } -+ -+ pSub = sqlite3SelectNew( -+ pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0 -+ ); -+ p->pSrc = sqlite3SrcListAppend(db, 0, 0, 0); -+ assert( p->pSrc || db->mallocFailed ); -+ if( p->pSrc ){ -+ p->pSrc->a[0].pSelect = pSub; -+ sqlite3SrcListAssignCursors(pParse, p->pSrc); -+ if( sqlite3ExpandSubquery(pParse, &p->pSrc->a[0]) ){ -+ rc = SQLITE_NOMEM; -+ }else{ -+ pSub->selFlags |= SF_Expanded; -+ p->selFlags &= ~SF_Aggregate; -+ sqlite3SelectPrep(pParse, pSub, 0); -+ } -+ -+ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr); -+ }else{ -+ sqlite3SelectDelete(db, pSub); -+ } -+ if( db->mallocFailed ) rc = SQLITE_NOMEM; -+ } -+ -+ return rc; -+} -+ -+/* -+** Free the Window object passed as the second argument. -+*/ -+SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3 *db, Window *p){ -+ if( p ){ -+ sqlite3ExprDelete(db, p->pFilter); -+ sqlite3ExprListDelete(db, p->pPartition); -+ sqlite3ExprListDelete(db, p->pOrderBy); -+ sqlite3ExprDelete(db, p->pEnd); -+ sqlite3ExprDelete(db, p->pStart); -+ sqlite3DbFree(db, p->zName); -+ sqlite3DbFree(db, p); -+ } -+} -+ -+/* -+** Free the linked list of Window objects starting at the second argument. -+*/ -+SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p){ -+ while( p ){ -+ Window *pNext = p->pNextWin; -+ sqlite3WindowDelete(db, p); -+ p = pNext; -+ } -+} -+ -+/* -+** The argument expression is an PRECEDING or FOLLOWING offset. The -+** value should be a non-negative integer. If the value is not a -+** constant, change it to NULL. The fact that it is then a non-negative -+** integer will be caught later. But it is important not to leave -+** variable values in the expression tree. -+*/ -+static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){ -+ if( 0==sqlite3ExprIsConstant(pExpr) ){ -+ sqlite3ExprDelete(pParse->db, pExpr); -+ pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0); -+ } -+ return pExpr; -+} -+ -+/* -+** Allocate and return a new Window object describing a Window Definition. -+*/ -+SQLITE_PRIVATE Window *sqlite3WindowAlloc( -+ Parse *pParse, /* Parsing context */ -+ int eType, /* Frame type. TK_RANGE or TK_ROWS */ -+ int eStart, /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */ -+ Expr *pStart, /* Start window size if TK_PRECEDING or FOLLOWING */ -+ int eEnd, /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */ -+ Expr *pEnd /* End window size if TK_FOLLOWING or PRECEDING */ -+){ -+ Window *pWin = 0; -+ -+ /* Parser assures the following: */ -+ assert( eType==TK_RANGE || eType==TK_ROWS ); -+ assert( eStart==TK_CURRENT || eStart==TK_PRECEDING -+ || eStart==TK_UNBOUNDED || eStart==TK_FOLLOWING ); -+ assert( eEnd==TK_CURRENT || eEnd==TK_FOLLOWING -+ || eEnd==TK_UNBOUNDED || eEnd==TK_PRECEDING ); -+ assert( (eStart==TK_PRECEDING || eStart==TK_FOLLOWING)==(pStart!=0) ); -+ assert( (eEnd==TK_FOLLOWING || eEnd==TK_PRECEDING)==(pEnd!=0) ); -+ -+ -+ /* If a frame is declared "RANGE" (not "ROWS"), then it may not use -+ ** either "<expr> PRECEDING" or "<expr> FOLLOWING". -+ */ -+ if( eType==TK_RANGE && (pStart!=0 || pEnd!=0) ){ -+ sqlite3ErrorMsg(pParse, "RANGE must use only UNBOUNDED or CURRENT ROW"); -+ goto windowAllocErr; -+ } -+ -+ /* Additionally, the -+ ** starting boundary type may not occur earlier in the following list than -+ ** the ending boundary type: -+ ** -+ ** UNBOUNDED PRECEDING -+ ** <expr> PRECEDING -+ ** CURRENT ROW -+ ** <expr> FOLLOWING -+ ** UNBOUNDED FOLLOWING -+ ** -+ ** The parser ensures that "UNBOUNDED PRECEDING" cannot be used as an ending -+ ** boundary, and than "UNBOUNDED FOLLOWING" cannot be used as a starting -+ ** frame boundary. -+ */ -+ if( (eStart==TK_CURRENT && eEnd==TK_PRECEDING) -+ || (eStart==TK_FOLLOWING && (eEnd==TK_PRECEDING || eEnd==TK_CURRENT)) -+ ){ -+ sqlite3ErrorMsg(pParse, "unsupported frame delimiter for ROWS"); -+ goto windowAllocErr; -+ } -+ -+ pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); -+ if( pWin==0 ) goto windowAllocErr; -+ pWin->eType = eType; -+ pWin->eStart = eStart; -+ pWin->eEnd = eEnd; -+ pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd); -+ pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart); -+ return pWin; -+ -+windowAllocErr: -+ sqlite3ExprDelete(pParse->db, pEnd); -+ sqlite3ExprDelete(pParse->db, pStart); -+ return 0; -+} -+ -+/* -+** Attach window object pWin to expression p. -+*/ -+SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ -+ if( p ){ -+ assert( p->op==TK_FUNCTION ); -+ /* This routine is only called for the parser. If pWin was not -+ ** allocated due to an OOM, then the parser would fail before ever -+ ** invoking this routine */ -+ if( ALWAYS(pWin) ){ -+ p->y.pWin = pWin; -+ ExprSetProperty(p, EP_WinFunc); -+ pWin->pOwner = p; -+ if( p->flags & EP_Distinct ){ -+ sqlite3ErrorMsg(pParse, -+ "DISTINCT is not supported for window functions"); -+ } -+ } -+ }else{ -+ sqlite3WindowDelete(pParse->db, pWin); -+ } -+} -+ -+/* -+** Return 0 if the two window objects are identical, or non-zero otherwise. -+** Identical window objects can be processed in a single scan. -+*/ -+SQLITE_PRIVATE int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){ -+ if( p1->eType!=p2->eType ) return 1; -+ if( p1->eStart!=p2->eStart ) return 1; -+ if( p1->eEnd!=p2->eEnd ) 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; -+ return 0; -+} -+ -+ -+/* -+** This is called by code in select.c before it calls sqlite3WhereBegin() -+** to begin iterating through the sub-query results. It is used to allocate -+** and initialize registers and cursors used by sqlite3WindowCodeStep(). -+*/ -+SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){ -+ Window *pWin; -+ Vdbe *v = sqlite3GetVdbe(pParse); -+ int nPart = (pMWin->pPartition ? pMWin->pPartition->nExpr : 0); -+ nPart += (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0); -+ if( nPart ){ -+ pMWin->regPart = pParse->nMem+1; -+ pParse->nMem += nPart; -+ sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nPart-1); -+ } -+ -+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ -+ FuncDef *p = pWin->pFunc; -+ if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){ -+ /* The inline versions of min() and max() require a single ephemeral -+ ** table and 3 registers. The registers are used as follows: -+ ** -+ ** regApp+0: slot to copy min()/max() argument to for MakeRecord -+ ** regApp+1: integer value used to ensure keys are unique -+ ** regApp+2: output of MakeRecord -+ */ -+ ExprList *pList = pWin->pOwner->x.pList; -+ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0); -+ pWin->csrApp = pParse->nTab++; -+ pWin->regApp = pParse->nMem+1; -+ pParse->nMem += 3; -+ if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){ -+ assert( pKeyInfo->aSortOrder[0]==0 ); -+ pKeyInfo->aSortOrder[0] = 1; -+ } -+ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2); -+ sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO); -+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); -+ } -+ else if( p->zName==nth_valueName || p->zName==first_valueName ){ -+ /* Allocate two registers at pWin->regApp. These will be used to -+ ** store the start and end index of the current frame. */ -+ assert( pMWin->iEphCsr ); -+ pWin->regApp = pParse->nMem+1; -+ pWin->csrApp = pParse->nTab++; -+ pParse->nMem += 2; -+ sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr); -+ } -+ else if( p->zName==leadName || p->zName==lagName ){ -+ assert( pMWin->iEphCsr ); -+ pWin->csrApp = pParse->nTab++; -+ sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr); -+ } -+ } -+} -+ -+/* -+** A "PRECEDING <expr>" (eCond==0) or "FOLLOWING <expr>" (eCond==1) or the -+** value of the second argument to nth_value() (eCond==2) has just been -+** evaluated and the result left in register reg. This function generates VM -+** code to check that the value is a non-negative integer and throws an -+** exception if it is not. -+*/ -+static void windowCheckIntValue(Parse *pParse, int reg, int eCond){ -+ static const char *azErr[] = { -+ "frame starting offset must be a non-negative integer", -+ "frame ending offset must be a non-negative integer", -+ "second argument to nth_value must be a positive integer" -+ }; -+ static int aOp[] = { OP_Ge, OP_Ge, OP_Gt }; -+ Vdbe *v = sqlite3GetVdbe(pParse); -+ int regZero = sqlite3GetTempReg(pParse); -+ assert( eCond==0 || eCond==1 || eCond==2 ); -+ sqlite3VdbeAddOp2(v, OP_Integer, 0, regZero); -+ sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2); -+ VdbeCoverageIf(v, eCond==0); -+ VdbeCoverageIf(v, eCond==1); -+ VdbeCoverageIf(v, eCond==2); -+ sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg); -+ VdbeCoverageNeverNullIf(v, eCond==0); -+ VdbeCoverageNeverNullIf(v, eCond==1); -+ VdbeCoverageNeverNullIf(v, eCond==2); -+ sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort); -+ sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC); -+ sqlite3ReleaseTempReg(pParse, regZero); -+} -+ -+/* -+** Return the number of arguments passed to the window-function associated -+** with the object passed as the only argument to this function. -+*/ -+static int windowArgCount(Window *pWin){ -+ ExprList *pList = pWin->pOwner->x.pList; -+ return (pList ? pList->nExpr : 0); -+} -+ -+/* -+** Generate VM code to invoke either xStep() (if bInverse is 0) or -+** xInverse (if bInverse is non-zero) for each window function in the -+** linked list starting at pMWin. Or, for built-in window functions -+** that do not use the standard function API, generate the required -+** inline VM code. -+** -+** If argument csr is greater than or equal to 0, then argument reg is -+** the first register in an array of registers guaranteed to be large -+** enough to hold the array of arguments for each function. In this case -+** the arguments are extracted from the current row of csr into the -+** array of registers before invoking OP_AggStep or OP_AggInverse -+** -+** Or, if csr is less than zero, then the array of registers at reg is -+** already populated with all columns from the current row of the sub-query. -+** -+** If argument regPartSize is non-zero, then it is a register containing the -+** number of rows in the current partition. -+*/ -+static void windowAggStep( -+ Parse *pParse, -+ Window *pMWin, /* Linked list of window functions */ -+ int csr, /* Read arguments from this cursor */ -+ int bInverse, /* True to invoke xInverse instead of xStep */ -+ int reg, /* Array of registers */ -+ int regPartSize /* Register containing size of partition */ -+){ -+ Vdbe *v = sqlite3GetVdbe(pParse); -+ Window *pWin; -+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ -+ int flags = pWin->pFunc->funcFlags; -+ int regArg; -+ int nArg = windowArgCount(pWin); -+ -+ if( csr>=0 ){ -+ int i; -+ for(i=0; i<nArg; i++){ -+ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i); -+ } -+ regArg = reg; -+ if( flags & SQLITE_FUNC_WINDOW_SIZE ){ -+ if( nArg==0 ){ -+ regArg = regPartSize; -+ }else{ -+ sqlite3VdbeAddOp2(v, OP_SCopy, regPartSize, reg+nArg); -+ } -+ nArg++; -+ } -+ }else{ -+ assert( !(flags & SQLITE_FUNC_WINDOW_SIZE) ); -+ regArg = reg + pWin->iArgCol; -+ } -+ -+ if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) -+ && pWin->eStart!=TK_UNBOUNDED -+ ){ -+ int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg); -+ VdbeCoverage(v); -+ if( bInverse==0 ){ -+ sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1); -+ sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp); -+ sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2); -+ sqlite3VdbeAddOp2(v, OP_IdxInsert, pWin->csrApp, pWin->regApp+2); -+ }else{ -+ sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1); -+ VdbeCoverageNeverTaken(v); -+ sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp); -+ sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); -+ } -+ sqlite3VdbeJumpHere(v, addrIsNull); -+ }else if( pWin->regApp ){ -+ assert( pWin->pFunc->zName==nth_valueName -+ || pWin->pFunc->zName==first_valueName -+ ); -+ assert( bInverse==0 || bInverse==1 ); -+ sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1); -+ }else if( pWin->pFunc->zName==leadName -+ || pWin->pFunc->zName==lagName -+ ){ -+ /* no-op */ -+ }else{ -+ int addrIf = 0; -+ if( pWin->pFilter ){ -+ int regTmp; -+ assert( nArg==0 || nArg==pWin->pOwner->x.pList->nExpr ); -+ assert( nArg || pWin->pOwner->x.pList==0 ); -+ if( csr>0 ){ -+ regTmp = sqlite3GetTempReg(pParse); -+ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); -+ }else{ -+ regTmp = regArg + nArg; -+ } -+ addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); -+ VdbeCoverage(v); -+ if( csr>0 ){ -+ sqlite3ReleaseTempReg(pParse, regTmp); -+ } -+ } -+ if( pWin->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ -+ CollSeq *pColl; -+ assert( nArg>0 ); -+ pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr); -+ sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ); -+ } -+ sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, -+ bInverse, regArg, pWin->regAccum); -+ sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF); -+ sqlite3VdbeChangeP5(v, (u8)nArg); -+ if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); -+ } -+ } -+} -+ -+/* -+** Generate VM code to invoke either xValue() (bFinal==0) or xFinalize() -+** (bFinal==1) for each window function in the linked list starting at -+** pMWin. Or, for built-in window-functions that do not use the standard -+** API, generate the equivalent VM code. -+*/ -+static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){ -+ Vdbe *v = sqlite3GetVdbe(pParse); -+ Window *pWin; -+ -+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ -+ if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) -+ && pWin->eStart!=TK_UNBOUNDED -+ ){ -+ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); -+ sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp); -+ VdbeCoverage(v); -+ sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult); -+ sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); -+ if( bFinal ){ -+ sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp); -+ } -+ }else if( pWin->regApp ){ -+ }else{ -+ if( bFinal ){ -+ sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin)); -+ sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF); -+ sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult); -+ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); -+ }else{ -+ sqlite3VdbeAddOp3(v, OP_AggValue, pWin->regAccum, windowArgCount(pWin), -+ pWin->regResult); -+ sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF); -+ } -+ } -+ } -+} -+ -+/* -+** This function generates VM code to invoke the sub-routine at address -+** lblFlushPart once for each partition with the entire partition cached in -+** the Window.iEphCsr temp table. -+*/ -+static void windowPartitionCache( -+ Parse *pParse, -+ Select *p, /* The rewritten SELECT statement */ -+ WhereInfo *pWInfo, /* WhereInfo to call WhereEnd() on */ -+ int regFlushPart, /* Register to use with Gosub lblFlushPart */ -+ int lblFlushPart, /* Subroutine to Gosub to */ -+ int *pRegSize /* OUT: Register containing partition size */ -+){ -+ Window *pMWin = p->pWin; -+ Vdbe *v = sqlite3GetVdbe(pParse); -+ int iSubCsr = p->pSrc->a[0].iCursor; -+ int nSub = p->pSrc->a[0].pTab->nCol; -+ int k; -+ -+ int reg = pParse->nMem+1; -+ int regRecord = reg+nSub; -+ int regRowid = regRecord+1; -+ -+ *pRegSize = regRowid; -+ pParse->nMem += nSub + 2; -+ -+ /* Load the column values for the row returned by the sub-select -+ ** into an array of registers starting at reg. */ -+ for(k=0; k<nSub; k++){ -+ sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k); -+ } -+ sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, nSub, regRecord); -+ -+ /* Check if this is the start of a new partition. If so, call the -+ ** flush_partition sub-routine. */ -+ if( pMWin->pPartition ){ -+ int addr; -+ ExprList *pPart = pMWin->pPartition; -+ int nPart = pPart->nExpr; -+ int regNewPart = reg + pMWin->nBufferCol; -+ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0); -+ -+ addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart); -+ sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); -+ sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2); -+ VdbeCoverageEqNe(v); -+ sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1); -+ sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart); -+ VdbeComment((v, "call flush_partition")); -+ } -+ -+ /* Buffer the current row in the ephemeral table. */ -+ sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid); -+ sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid); -+ -+ /* End of the input loop */ -+ sqlite3WhereEnd(pWInfo); -+ -+ /* Invoke "flush_partition" to deal with the final (or only) partition */ -+ sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart); -+ VdbeComment((v, "call flush_partition")); -+} -+ -+/* -+** Invoke the sub-routine at regGosub (generated by code in select.c) to -+** return the current row of Window.iEphCsr. If all window functions are -+** aggregate window functions that use the standard API, a single -+** OP_Gosub instruction is all that this routine generates. Extra VM code -+** for per-row processing is only generated for the following built-in window -+** functions: -+** -+** nth_value() -+** first_value() -+** lag() -+** lead() -+*/ -+static void windowReturnOneRow( -+ Parse *pParse, -+ Window *pMWin, -+ int regGosub, -+ int addrGosub -+){ -+ Vdbe *v = sqlite3GetVdbe(pParse); -+ Window *pWin; -+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ -+ FuncDef *pFunc = pWin->pFunc; -+ if( pFunc->zName==nth_valueName -+ || pFunc->zName==first_valueName -+ ){ -+ int csr = pWin->csrApp; -+ int lbl = sqlite3VdbeMakeLabel(v); -+ int tmpReg = sqlite3GetTempReg(pParse); -+ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); -+ -+ if( pFunc->zName==nth_valueName ){ -+ sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+1,tmpReg); -+ windowCheckIntValue(pParse, tmpReg, 2); -+ }else{ -+ sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg); -+ } -+ sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg); -+ sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg); -+ VdbeCoverageNeverNull(v); -+ sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg); -+ VdbeCoverageNeverTaken(v); -+ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult); -+ sqlite3VdbeResolveLabel(v, lbl); -+ sqlite3ReleaseTempReg(pParse, tmpReg); -+ } -+ else if( pFunc->zName==leadName || pFunc->zName==lagName ){ -+ int nArg = pWin->pOwner->x.pList->nExpr; -+ int iEph = pMWin->iEphCsr; -+ int csr = pWin->csrApp; -+ int lbl = sqlite3VdbeMakeLabel(v); -+ int tmpReg = sqlite3GetTempReg(pParse); -+ -+ if( nArg<3 ){ -+ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); -+ }else{ -+ sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult); -+ } -+ sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg); -+ if( nArg<2 ){ -+ int val = (pFunc->zName==leadName ? 1 : -1); -+ sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val); -+ }else{ -+ int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract); -+ int tmpReg2 = sqlite3GetTempReg(pParse); -+ sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2); -+ sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg); -+ sqlite3ReleaseTempReg(pParse, tmpReg2); -+ } -+ -+ sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg); -+ VdbeCoverage(v); -+ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult); -+ sqlite3VdbeResolveLabel(v, lbl); -+ sqlite3ReleaseTempReg(pParse, tmpReg); -+ } -+ } -+ sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub); -+} -+ -+/* -+** Invoke the code generated by windowReturnOneRow() and, optionally, the -+** xInverse() function for each window function, for one or more rows -+** from the Window.iEphCsr temp table. This routine generates VM code -+** similar to: -+** -+** while( regCtr>0 ){ -+** regCtr--; -+** windowReturnOneRow() -+** if( bInverse ){ -+** AggInverse -+** } -+** Next (Window.iEphCsr) -+** } -+*/ -+static void windowReturnRows( -+ Parse *pParse, -+ Window *pMWin, /* List of window functions */ -+ int regCtr, /* Register containing number of rows */ -+ int regGosub, /* Register for Gosub addrGosub */ -+ int addrGosub, /* Address of sub-routine for ReturnOneRow */ -+ int regInvArg, /* Array of registers for xInverse args */ -+ int regInvSize /* Register containing size of partition */ -+){ -+ int addr; -+ Vdbe *v = sqlite3GetVdbe(pParse); -+ windowAggFinal(pParse, pMWin, 0); -+ addr = sqlite3VdbeAddOp3(v, OP_IfPos, regCtr, sqlite3VdbeCurrentAddr(v)+2 ,1); -+ VdbeCoverage(v); -+ sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); -+ windowReturnOneRow(pParse, pMWin, regGosub, addrGosub); -+ if( regInvArg ){ -+ windowAggStep(pParse, pMWin, pMWin->iEphCsr, 1, regInvArg, regInvSize); -+ } -+ sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, addr); -+ VdbeCoverage(v); -+ sqlite3VdbeJumpHere(v, addr+1); /* The OP_Goto */ -+} -+ -+/* -+** Generate code to set the accumulator register for each window function -+** in the linked list passed as the second argument to NULL. And perform -+** any equivalent initialization required by any built-in window functions -+** in the list. -+*/ -+static int windowInitAccum(Parse *pParse, Window *pMWin){ -+ Vdbe *v = sqlite3GetVdbe(pParse); -+ int regArg; -+ int nArg = 0; -+ Window *pWin; -+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ -+ FuncDef *pFunc = pWin->pFunc; -+ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); -+ nArg = MAX(nArg, windowArgCount(pWin)); -+ if( pFunc->zName==nth_valueName -+ || pFunc->zName==first_valueName -+ ){ -+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp); -+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); -+ } -+ -+ if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){ -+ assert( pWin->eStart!=TK_UNBOUNDED ); -+ sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp); -+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); -+ } -+ } -+ regArg = pParse->nMem+1; -+ pParse->nMem += nArg; -+ return regArg; -+} -+ -+ -+/* -+** This function does the work of sqlite3WindowCodeStep() for all "ROWS" -+** window frame types except for "BETWEEN UNBOUNDED PRECEDING AND CURRENT -+** ROW". Pseudo-code for each follows. -+** -+** ROWS BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING -+** -+** ... -+** if( new partition ){ -+** Gosub flush_partition -+** } -+** Insert (record in eph-table) -+** sqlite3WhereEnd() -+** Gosub flush_partition -+** -+** flush_partition: -+** Once { -+** OpenDup (iEphCsr -> csrStart) -+** OpenDup (iEphCsr -> csrEnd) -+** } -+** regStart = <expr1> // PRECEDING expression -+** regEnd = <expr2> // FOLLOWING expression -+** if( regStart<0 || regEnd<0 ){ error! } -+** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done -+** Next(csrEnd) // if EOF skip Aggstep -+** Aggstep (csrEnd) -+** if( (regEnd--)<=0 ){ -+** AggFinal (xValue) -+** Gosub addrGosub -+** Next(csr) // if EOF goto flush_partition_done -+** if( (regStart--)<=0 ){ -+** AggInverse (csrStart) -+** Next(csrStart) -+** } -+** } -+** flush_partition_done: -+** ResetSorter (csr) -+** Return -+** -+** ROWS BETWEEN <expr> PRECEDING AND CURRENT ROW -+** ROWS BETWEEN CURRENT ROW AND <expr> FOLLOWING -+** ROWS BETWEEN UNBOUNDED PRECEDING AND <expr> FOLLOWING -+** -+** These are similar to the above. For "CURRENT ROW", intialize the -+** register to 0. For "UNBOUNDED PRECEDING" to infinity. -+** -+** ROWS BETWEEN <expr> PRECEDING AND UNBOUNDED FOLLOWING -+** ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING -+** -+** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done -+** while( 1 ){ -+** Next(csrEnd) // Exit while(1) at EOF -+** Aggstep (csrEnd) -+** } -+** while( 1 ){ -+** AggFinal (xValue) -+** Gosub addrGosub -+** Next(csr) // if EOF goto flush_partition_done -+** if( (regStart--)<=0 ){ -+** AggInverse (csrStart) -+** Next(csrStart) -+** } -+** } -+** -+** For the "CURRENT ROW AND UNBOUNDED FOLLOWING" case, the final if() -+** condition is always true (as if regStart were initialized to 0). -+** -+** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING -+** -+** This is the only RANGE case handled by this routine. It modifies the -+** second while( 1 ) loop in "ROWS BETWEEN CURRENT ... UNBOUNDED..." to -+** be: -+** -+** while( 1 ){ -+** AggFinal (xValue) -+** while( 1 ){ -+** regPeer++ -+** Gosub addrGosub -+** Next(csr) // if EOF goto flush_partition_done -+** if( new peer ) break; -+** } -+** while( (regPeer--)>0 ){ -+** AggInverse (csrStart) -+** Next(csrStart) -+** } -+** } -+** -+** ROWS BETWEEN <expr> FOLLOWING AND <expr> FOLLOWING -+** -+** regEnd = regEnd - regStart -+** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done -+** Aggstep (csrEnd) -+** Next(csrEnd) // if EOF fall-through -+** if( (regEnd--)<=0 ){ -+** if( (regStart--)<=0 ){ -+** AggFinal (xValue) -+** Gosub addrGosub -+** Next(csr) // if EOF goto flush_partition_done -+** } -+** AggInverse (csrStart) -+** Next (csrStart) -+** } -+** -+** ROWS BETWEEN <expr> PRECEDING AND <expr> PRECEDING -+** -+** Replace the bit after "Rewind" in the above with: -+** -+** if( (regEnd--)<=0 ){ -+** AggStep (csrEnd) -+** Next (csrEnd) -+** } -+** AggFinal (xValue) -+** Gosub addrGosub -+** Next(csr) // if EOF goto flush_partition_done -+** if( (regStart--)<=0 ){ -+** AggInverse (csr2) -+** Next (csr2) -+** } -+** -+*/ -+static void windowCodeRowExprStep( -+ Parse *pParse, -+ Select *p, -+ WhereInfo *pWInfo, -+ int regGosub, -+ int addrGosub -+){ -+ Window *pMWin = p->pWin; -+ Vdbe *v = sqlite3GetVdbe(pParse); -+ int regFlushPart; /* Register for "Gosub flush_partition" */ -+ int lblFlushPart; /* Label for "Gosub flush_partition" */ -+ int lblFlushDone; /* Label for "Gosub flush_partition_done" */ -+ -+ int regArg; -+ int addr; -+ int csrStart = pParse->nTab++; -+ int csrEnd = pParse->nTab++; -+ int regStart; /* Value of <expr> PRECEDING */ -+ int regEnd; /* Value of <expr> FOLLOWING */ -+ int addrGoto; -+ int addrTop; -+ int addrIfPos1 = 0; -+ int addrIfPos2 = 0; -+ int regSize = 0; -+ -+ assert( pMWin->eStart==TK_PRECEDING -+ || pMWin->eStart==TK_CURRENT -+ || pMWin->eStart==TK_FOLLOWING -+ || pMWin->eStart==TK_UNBOUNDED -+ ); -+ assert( pMWin->eEnd==TK_FOLLOWING -+ || pMWin->eEnd==TK_CURRENT -+ || pMWin->eEnd==TK_UNBOUNDED -+ || pMWin->eEnd==TK_PRECEDING -+ ); -+ -+ /* Allocate register and label for the "flush_partition" sub-routine. */ -+ regFlushPart = ++pParse->nMem; -+ lblFlushPart = sqlite3VdbeMakeLabel(v); -+ lblFlushDone = sqlite3VdbeMakeLabel(v); -+ -+ regStart = ++pParse->nMem; -+ regEnd = ++pParse->nMem; -+ -+ windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, ®Size); -+ -+ addrGoto = sqlite3VdbeAddOp0(v, OP_Goto); -+ -+ /* Start of "flush_partition" */ -+ sqlite3VdbeResolveLabel(v, lblFlushPart); -+ sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+3); -+ VdbeCoverage(v); -+ VdbeComment((v, "Flush_partition subroutine")); -+ sqlite3VdbeAddOp2(v, OP_OpenDup, csrStart, pMWin->iEphCsr); -+ sqlite3VdbeAddOp2(v, OP_OpenDup, csrEnd, pMWin->iEphCsr); -+ -+ /* If either regStart or regEnd are not non-negative integers, throw -+ ** an exception. */ -+ if( pMWin->pStart ){ -+ sqlite3ExprCode(pParse, pMWin->pStart, regStart); -+ windowCheckIntValue(pParse, regStart, 0); -+ } -+ if( pMWin->pEnd ){ -+ sqlite3ExprCode(pParse, pMWin->pEnd, regEnd); -+ windowCheckIntValue(pParse, regEnd, 1); -+ } -+ -+ /* If this is "ROWS <expr1> FOLLOWING AND ROWS <expr2> FOLLOWING", do: -+ ** -+ ** if( regEnd<regStart ){ -+ ** // The frame always consists of 0 rows -+ ** regStart = regSize; -+ ** } -+ ** regEnd = regEnd - regStart; -+ */ -+ if( pMWin->pEnd && pMWin->eStart==TK_FOLLOWING ){ -+ assert( pMWin->pStart!=0 ); -+ assert( pMWin->eEnd==TK_FOLLOWING ); -+ sqlite3VdbeAddOp3(v, OP_Ge, regStart, sqlite3VdbeCurrentAddr(v)+2, regEnd); -+ VdbeCoverageNeverNull(v); -+ sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart); -+ sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd); -+ } -+ -+ if( pMWin->pStart && pMWin->eEnd==TK_PRECEDING ){ -+ assert( pMWin->pEnd!=0 ); -+ assert( pMWin->eStart==TK_PRECEDING ); -+ sqlite3VdbeAddOp3(v, OP_Le, regStart, sqlite3VdbeCurrentAddr(v)+3, regEnd); -+ VdbeCoverageNeverNull(v); -+ sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart); -+ sqlite3VdbeAddOp2(v, OP_Copy, regSize, regEnd); -+ } -+ -+ /* Initialize the accumulator register for each window function to NULL */ -+ regArg = windowInitAccum(pParse, pMWin); -+ -+ sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblFlushDone); -+ VdbeCoverage(v); -+ sqlite3VdbeAddOp2(v, OP_Rewind, csrStart, lblFlushDone); -+ VdbeCoverageNeverTaken(v); -+ sqlite3VdbeChangeP5(v, 1); -+ sqlite3VdbeAddOp2(v, OP_Rewind, csrEnd, lblFlushDone); -+ VdbeCoverageNeverTaken(v); -+ sqlite3VdbeChangeP5(v, 1); -+ -+ /* Invoke AggStep function for each window function using the row that -+ ** csrEnd currently points to. Or, if csrEnd is already at EOF, -+ ** do nothing. */ -+ addrTop = sqlite3VdbeCurrentAddr(v); -+ if( pMWin->eEnd==TK_PRECEDING ){ -+ addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1); -+ VdbeCoverage(v); -+ } -+ sqlite3VdbeAddOp2(v, OP_Next, csrEnd, sqlite3VdbeCurrentAddr(v)+2); -+ VdbeCoverage(v); -+ addr = sqlite3VdbeAddOp0(v, OP_Goto); -+ windowAggStep(pParse, pMWin, csrEnd, 0, regArg, regSize); -+ if( pMWin->eEnd==TK_UNBOUNDED ){ -+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); -+ sqlite3VdbeJumpHere(v, addr); -+ addrTop = sqlite3VdbeCurrentAddr(v); -+ }else{ -+ sqlite3VdbeJumpHere(v, addr); -+ if( pMWin->eEnd==TK_PRECEDING ){ -+ sqlite3VdbeJumpHere(v, addrIfPos1); -+ } -+ } -+ -+ if( pMWin->eEnd==TK_FOLLOWING ){ -+ addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1); -+ VdbeCoverage(v); -+ } -+ if( pMWin->eStart==TK_FOLLOWING ){ -+ addrIfPos2 = sqlite3VdbeAddOp3(v, OP_IfPos, regStart, 0 , 1); -+ VdbeCoverage(v); -+ } -+ windowAggFinal(pParse, pMWin, 0); -+ windowReturnOneRow(pParse, pMWin, regGosub, addrGosub); -+ sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)+2); -+ VdbeCoverage(v); -+ sqlite3VdbeAddOp2(v, OP_Goto, 0, lblFlushDone); -+ if( pMWin->eStart==TK_FOLLOWING ){ -+ sqlite3VdbeJumpHere(v, addrIfPos2); -+ } -+ -+ if( pMWin->eStart==TK_CURRENT -+ || pMWin->eStart==TK_PRECEDING -+ || pMWin->eStart==TK_FOLLOWING -+ ){ -+ int lblSkipInverse = sqlite3VdbeMakeLabel(v);; -+ if( pMWin->eStart==TK_PRECEDING ){ -+ sqlite3VdbeAddOp3(v, OP_IfPos, regStart, lblSkipInverse, 1); -+ VdbeCoverage(v); -+ } -+ if( pMWin->eStart==TK_FOLLOWING ){ -+ sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+2); -+ VdbeCoverage(v); -+ sqlite3VdbeAddOp2(v, OP_Goto, 0, lblSkipInverse); -+ }else{ -+ sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+1); -+ VdbeCoverageAlwaysTaken(v); -+ } -+ windowAggStep(pParse, pMWin, csrStart, 1, regArg, regSize); -+ sqlite3VdbeResolveLabel(v, lblSkipInverse); -+ } -+ if( pMWin->eEnd==TK_FOLLOWING ){ -+ sqlite3VdbeJumpHere(v, addrIfPos1); -+ } -+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); -+ -+ /* flush_partition_done: */ -+ sqlite3VdbeResolveLabel(v, lblFlushDone); -+ sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr); -+ sqlite3VdbeAddOp1(v, OP_Return, regFlushPart); -+ VdbeComment((v, "end flush_partition subroutine")); -+ -+ /* Jump to here to skip over flush_partition */ -+ sqlite3VdbeJumpHere(v, addrGoto); -+} -+ -+/* -+** This function does the work of sqlite3WindowCodeStep() for cases that -+** would normally be handled by windowCodeDefaultStep() when there are -+** one or more built-in window-functions that require the entire partition -+** to be cached in a temp table before any rows can be returned. Additionally. -+** "RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING" is always handled by -+** this function. -+** -+** Pseudo-code corresponding to the VM code generated by this function -+** for each type of window follows. -+** -+** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -+** -+** flush_partition: -+** Once { -+** OpenDup (iEphCsr -> csrLead) -+** } -+** Integer ctr 0 -+** foreach row (csrLead){ -+** if( new peer ){ -+** AggFinal (xValue) -+** for(i=0; i<ctr; i++){ -+** Gosub addrGosub -+** Next iEphCsr -+** } -+** Integer ctr 0 -+** } -+** AggStep (csrLead) -+** Incr ctr -+** } -+** -+** AggFinal (xFinalize) -+** for(i=0; i<ctr; i++){ -+** Gosub addrGosub -+** Next iEphCsr -+** } -+** -+** ResetSorter (csr) -+** Return -+** -+** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -+** -+** As above, except that the "if( new peer )" branch is always taken. -+** -+** RANGE BETWEEN CURRENT ROW AND CURRENT ROW -+** -+** As above, except that each of the for() loops becomes: -+** -+** for(i=0; i<ctr; i++){ -+** Gosub addrGosub -+** AggInverse (iEphCsr) -+** Next iEphCsr -+** } -+** -+** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING -+** -+** flush_partition: -+** Once { -+** OpenDup (iEphCsr -> csrLead) -+** } -+** foreach row (csrLead) { -+** AggStep (csrLead) -+** } -+** foreach row (iEphCsr) { -+** Gosub addrGosub -+** } -+** -+** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING -+** -+** flush_partition: -+** Once { -+** OpenDup (iEphCsr -> csrLead) -+** } -+** foreach row (csrLead){ -+** AggStep (csrLead) -+** } -+** Rewind (csrLead) -+** Integer ctr 0 -+** foreach row (csrLead){ -+** if( new peer ){ -+** AggFinal (xValue) -+** for(i=0; i<ctr; i++){ -+** Gosub addrGosub -+** AggInverse (iEphCsr) -+** Next iEphCsr -+** } -+** Integer ctr 0 -+** } -+** Incr ctr -+** } -+** -+** AggFinal (xFinalize) -+** for(i=0; i<ctr; i++){ -+** Gosub addrGosub -+** Next iEphCsr -+** } -+** -+** ResetSorter (csr) -+** Return -+*/ -+static void windowCodeCacheStep( -+ Parse *pParse, -+ Select *p, -+ WhereInfo *pWInfo, -+ int regGosub, -+ int addrGosub -+){ -+ Window *pMWin = p->pWin; -+ Vdbe *v = sqlite3GetVdbe(pParse); -+ int k; -+ int addr; -+ ExprList *pPart = pMWin->pPartition; -+ ExprList *pOrderBy = pMWin->pOrderBy; -+ int nPeer = pOrderBy ? pOrderBy->nExpr : 0; -+ int regNewPeer; -+ -+ int addrGoto; /* Address of Goto used to jump flush_par.. */ -+ int addrNext; /* Jump here for next iteration of loop */ -+ int regFlushPart; -+ int lblFlushPart; -+ int csrLead; -+ int regCtr; -+ int regArg; /* Register array to martial function args */ -+ int regSize; -+ int lblEmpty; -+ int bReverse = pMWin->pOrderBy && pMWin->eStart==TK_CURRENT -+ && pMWin->eEnd==TK_UNBOUNDED; -+ -+ assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) -+ || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED) -+ || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT) -+ || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED) -+ ); -+ -+ lblEmpty = sqlite3VdbeMakeLabel(v); -+ regNewPeer = pParse->nMem+1; -+ pParse->nMem += nPeer; -+ -+ /* Allocate register and label for the "flush_partition" sub-routine. */ -+ regFlushPart = ++pParse->nMem; -+ lblFlushPart = sqlite3VdbeMakeLabel(v); -+ -+ csrLead = pParse->nTab++; -+ regCtr = ++pParse->nMem; -+ -+ windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, ®Size); -+ addrGoto = sqlite3VdbeAddOp0(v, OP_Goto); -+ -+ /* Start of "flush_partition" */ -+ sqlite3VdbeResolveLabel(v, lblFlushPart); -+ sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+2); -+ VdbeCoverage(v); -+ sqlite3VdbeAddOp2(v, OP_OpenDup, csrLead, pMWin->iEphCsr); -+ -+ /* Initialize the accumulator register for each window function to NULL */ -+ regArg = windowInitAccum(pParse, pMWin); -+ -+ sqlite3VdbeAddOp2(v, OP_Integer, 0, regCtr); -+ sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty); -+ VdbeCoverage(v); -+ sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblEmpty); -+ VdbeCoverageNeverTaken(v); -+ -+ if( bReverse ){ -+ int addr2 = sqlite3VdbeCurrentAddr(v); -+ windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize); -+ sqlite3VdbeAddOp2(v, OP_Next, csrLead, addr2); -+ VdbeCoverage(v); -+ sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty); -+ VdbeCoverageNeverTaken(v); -+ } -+ addrNext = sqlite3VdbeCurrentAddr(v); -+ -+ if( pOrderBy && (pMWin->eEnd==TK_CURRENT || pMWin->eStart==TK_CURRENT) ){ -+ int bCurrent = (pMWin->eStart==TK_CURRENT); -+ int addrJump = 0; /* Address of OP_Jump below */ -+ if( pMWin->eType==TK_RANGE ){ -+ int iOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0); -+ int regPeer = pMWin->regPart + (pPart ? pPart->nExpr : 0); -+ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0); -+ for(k=0; k<nPeer; k++){ -+ sqlite3VdbeAddOp3(v, OP_Column, csrLead, iOff+k, regNewPeer+k); -+ } -+ addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer); -+ sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); -+ addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2); -+ VdbeCoverage(v); -+ sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, nPeer-1); -+ } -+ -+ windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub, -+ (bCurrent ? regArg : 0), (bCurrent ? regSize : 0) -+ ); -+ if( addrJump ) sqlite3VdbeJumpHere(v, addrJump); -+ } -+ -+ if( bReverse==0 ){ -+ windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize); -+ } -+ sqlite3VdbeAddOp2(v, OP_AddImm, regCtr, 1); -+ sqlite3VdbeAddOp2(v, OP_Next, csrLead, addrNext); -+ VdbeCoverage(v); -+ -+ windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub, 0, 0); -+ -+ sqlite3VdbeResolveLabel(v, lblEmpty); -+ sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr); -+ sqlite3VdbeAddOp1(v, OP_Return, regFlushPart); -+ -+ /* Jump to here to skip over flush_partition */ -+ sqlite3VdbeJumpHere(v, addrGoto); -+} -+ -+ -+/* -+** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -+** -+** ... -+** if( new partition ){ -+** AggFinal (xFinalize) -+** Gosub addrGosub -+** ResetSorter eph-table -+** } -+** else if( new peer ){ -+** AggFinal (xValue) -+** Gosub addrGosub -+** ResetSorter eph-table -+** } -+** AggStep -+** Insert (record into eph-table) -+** sqlite3WhereEnd() -+** AggFinal (xFinalize) -+** Gosub addrGosub -+** -+** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING -+** -+** As above, except take no action for a "new peer". Invoke -+** the sub-routine once only for each partition. -+** -+** RANGE BETWEEN CURRENT ROW AND CURRENT ROW -+** -+** As above, except that the "new peer" condition is handled in the -+** same way as "new partition" (so there is no "else if" block). -+** -+** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -+** -+** As above, except assume every row is a "new peer". -+*/ -+static void windowCodeDefaultStep( -+ Parse *pParse, -+ Select *p, -+ WhereInfo *pWInfo, -+ int regGosub, -+ int addrGosub -+){ -+ Window *pMWin = p->pWin; -+ Vdbe *v = sqlite3GetVdbe(pParse); -+ int k; -+ int iSubCsr = p->pSrc->a[0].iCursor; -+ int nSub = p->pSrc->a[0].pTab->nCol; -+ int reg = pParse->nMem+1; -+ int regRecord = reg+nSub; -+ int regRowid = regRecord+1; -+ int addr; -+ ExprList *pPart = pMWin->pPartition; -+ ExprList *pOrderBy = pMWin->pOrderBy; -+ -+ assert( pMWin->eType==TK_RANGE -+ || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) -+ ); -+ -+ assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) -+ || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED) -+ || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT) -+ || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED && !pOrderBy) -+ ); -+ -+ if( pMWin->eEnd==TK_UNBOUNDED ){ -+ pOrderBy = 0; -+ } -+ -+ pParse->nMem += nSub + 2; -+ -+ /* Load the individual column values of the row returned by -+ ** the sub-select into an array of registers. */ -+ for(k=0; k<nSub; k++){ -+ sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k); -+ } -+ -+ /* Check if this is the start of a new partition or peer group. */ -+ if( pPart || pOrderBy ){ -+ int nPart = (pPart ? pPart->nExpr : 0); -+ int addrGoto = 0; -+ int addrJump = 0; -+ int nPeer = (pOrderBy ? pOrderBy->nExpr : 0); -+ -+ if( pPart ){ -+ int regNewPart = reg + pMWin->nBufferCol; -+ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0); -+ addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart); -+ sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); -+ addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2); -+ VdbeCoverageEqNe(v); -+ windowAggFinal(pParse, pMWin, 1); -+ if( pOrderBy ){ -+ addrGoto = sqlite3VdbeAddOp0(v, OP_Goto); -+ } -+ } -+ -+ if( pOrderBy ){ -+ int regNewPeer = reg + pMWin->nBufferCol + nPart; -+ int regPeer = pMWin->regPart + nPart; -+ -+ if( addrJump ) sqlite3VdbeJumpHere(v, addrJump); -+ if( pMWin->eType==TK_RANGE ){ -+ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0); -+ addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer); -+ sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); -+ addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2); -+ VdbeCoverage(v); -+ }else{ -+ addrJump = 0; -+ } -+ windowAggFinal(pParse, pMWin, pMWin->eStart==TK_CURRENT); -+ if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto); -+ } -+ -+ sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3); -+ VdbeCoverage(v); -+ sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub); -+ sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1); -+ VdbeCoverage(v); -+ -+ sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr); -+ sqlite3VdbeAddOp3( -+ v, OP_Copy, reg+pMWin->nBufferCol, pMWin->regPart, nPart+nPeer-1 -+ ); -+ -+ if( addrJump ) sqlite3VdbeJumpHere(v, addrJump); -+ } -+ -+ /* Invoke step function for window functions */ -+ windowAggStep(pParse, pMWin, -1, 0, reg, 0); -+ -+ /* Buffer the current row in the ephemeral table. */ -+ if( pMWin->nBufferCol>0 ){ -+ sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, pMWin->nBufferCol, regRecord); -+ }else{ -+ sqlite3VdbeAddOp2(v, OP_Blob, 0, regRecord); -+ sqlite3VdbeAppendP4(v, (void*)"", 0); -+ } -+ sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid); -+ sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid); -+ -+ /* End the database scan loop. */ -+ sqlite3WhereEnd(pWInfo); -+ -+ windowAggFinal(pParse, pMWin, 1); -+ sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3); -+ VdbeCoverage(v); -+ sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub); -+ sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1); -+ VdbeCoverage(v); -+} -+ -+/* -+** Allocate and return a duplicate of the Window object indicated by the -+** third argument. Set the Window.pOwner field of the new object to -+** pOwner. -+*/ -+SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){ -+ Window *pNew = 0; -+ if( ALWAYS(p) ){ -+ pNew = sqlite3DbMallocZero(db, sizeof(Window)); -+ if( pNew ){ -+ pNew->zName = sqlite3DbStrDup(db, p->zName); -+ pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0); -+ pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0); -+ pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0); -+ pNew->eType = p->eType; -+ pNew->eEnd = p->eEnd; -+ pNew->eStart = p->eStart; -+ pNew->pStart = sqlite3ExprDup(db, p->pStart, 0); -+ pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0); -+ pNew->pOwner = pOwner; -+ } -+ } -+ return pNew; -+} -+ -+/* -+** Return a copy of the linked list of Window objects passed as the -+** second argument. -+*/ -+SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p){ -+ Window *pWin; -+ Window *pRet = 0; -+ Window **pp = &pRet; -+ -+ for(pWin=p; pWin; pWin=pWin->pNextWin){ -+ *pp = sqlite3WindowDup(db, 0, pWin); -+ if( *pp==0 ) break; -+ pp = &((*pp)->pNextWin); -+ } -+ -+ return pRet; -+} -+ -+/* -+** sqlite3WhereBegin() has already been called for the SELECT statement -+** passed as the second argument when this function is invoked. It generates -+** code to populate the Window.regResult register for each window function and -+** invoke the sub-routine at instruction addrGosub once for each row. -+** This function calls sqlite3WhereEnd() before returning. -+*/ -+SQLITE_PRIVATE void sqlite3WindowCodeStep( -+ Parse *pParse, /* Parse context */ -+ Select *p, /* Rewritten SELECT statement */ -+ WhereInfo *pWInfo, /* Context returned by sqlite3WhereBegin() */ -+ int regGosub, /* Register for OP_Gosub */ -+ int addrGosub /* OP_Gosub here to return each row */ -+){ -+ Window *pMWin = p->pWin; -+ -+ /* There are three different functions that may be used to do the work -+ ** of this one, depending on the window frame and the specific built-in -+ ** window functions used (if any). -+ ** -+ ** windowCodeRowExprStep() handles all "ROWS" window frames, except for: -+ ** -+ ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -+ ** -+ ** The exception is because windowCodeRowExprStep() implements all window -+ ** frame types by caching the entire partition in a temp table, and -+ ** "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" is easy enough to -+ ** implement without such a cache. -+ ** -+ ** windowCodeCacheStep() is used for: -+ ** -+ ** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING -+ ** -+ ** It is also used for anything not handled by windowCodeRowExprStep() -+ ** that invokes a built-in window function that requires the entire -+ ** partition to be cached in a temp table before any rows are returned -+ ** (e.g. nth_value() or percent_rank()). -+ ** -+ ** Finally, assuming there is no built-in window function that requires -+ ** the partition to be cached, windowCodeDefaultStep() is used for: -+ ** -+ ** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -+ ** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING -+ ** RANGE BETWEEN CURRENT ROW AND CURRENT ROW -+ ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -+ ** -+ ** windowCodeDefaultStep() is the only one of the three functions that -+ ** does not cache each partition in a temp table before beginning to -+ ** return rows. -+ */ -+ if( pMWin->eType==TK_ROWS -+ && (pMWin->eStart!=TK_UNBOUNDED||pMWin->eEnd!=TK_CURRENT||!pMWin->pOrderBy) -+ ){ -+ VdbeModuleComment((pParse->pVdbe, "Begin RowExprStep()")); -+ windowCodeRowExprStep(pParse, p, pWInfo, regGosub, addrGosub); -+ }else{ -+ Window *pWin; -+ int bCache = 0; /* True to use CacheStep() */ -+ -+ if( pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED ){ -+ bCache = 1; -+ }else{ -+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ -+ FuncDef *pFunc = pWin->pFunc; -+ if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE) -+ || (pFunc->zName==nth_valueName) -+ || (pFunc->zName==first_valueName) -+ || (pFunc->zName==leadName) -+ || (pFunc->zName==lagName) -+ ){ -+ bCache = 1; -+ break; -+ } -+ } -+ } -+ -+ /* Otherwise, call windowCodeDefaultStep(). */ -+ if( bCache ){ -+ VdbeModuleComment((pParse->pVdbe, "Begin CacheStep()")); -+ windowCodeCacheStep(pParse, p, pWInfo, regGosub, addrGosub); -+ }else{ -+ VdbeModuleComment((pParse->pVdbe, "Begin DefaultStep()")); -+ windowCodeDefaultStep(pParse, p, pWInfo, regGosub, addrGosub); -+ } -+ } -+} -+ -+#endif /* SQLITE_OMIT_WINDOWFUNC */ -+ -+/************** End of window.c **********************************************/ - /************** Begin file parse.c *******************************************/ - /* - ** 2000-05-29 -@@ -136559,6 +146829,7 @@ - ** input grammar file: - */ - /* #include <stdio.h> */ -+/* #include <assert.h> */ - /************ Begin %include sections from the grammar ************************/ - - /* #include "sqliteInt.h" */ -@@ -136600,15 +146871,6 @@ - #define YYMALLOCARGTYPE u64 - - /* --** An instance of this structure holds information about the --** LIMIT clause of a SELECT statement. --*/ --struct LimitVal { -- Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */ -- Expr *pOffset; /* The OFFSET expression. NULL if there is none */ --}; -- --/* - ** An instance of the following structure describes the event of a - ** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT, - ** TK_DELETE, or TK_INSTEAD. If the event is of the form -@@ -136619,6 +146881,8 @@ - */ - struct TrigEvent { int a; IdList * b; }; - -+struct FrameBound { int eType; Expr *pExpr; }; -+ - /* - ** Disable lookaside memory allocation for objects that might be - ** shared across database connections. -@@ -136651,26 +146915,26 @@ - } - } - -- /* This is a utility routine used to set the ExprSpan.zStart and -- ** ExprSpan.zEnd values of pOut so that the span covers the complete -- ** range of text beginning with pStart and going to the end of pEnd. -- */ -- static void spanSet(ExprSpan *pOut, Token *pStart, Token *pEnd){ -- pOut->zStart = pStart->z; -- pOut->zEnd = &pEnd->z[pEnd->n]; -- } - - /* Construct a new Expr object from a single identifier. Use the - ** new Expr to populate pOut. Set the span of pOut to be the identifier - ** that created the expression. - */ -- static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token t){ -+ static Expr *tokenExpr(Parse *pParse, int op, Token t){ - Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1); - if( p ){ -- memset(p, 0, sizeof(Expr)); -+ /* memset(p, 0, sizeof(Expr)); */ - p->op = (u8)op; -+ p->affinity = 0; - p->flags = EP_Leaf; - p->iAgg = -1; -+ p->pLeft = p->pRight = 0; -+ p->x.pList = 0; -+ p->pAggInfo = 0; -+ p->y.pTab = 0; -+ p->op2 = 0; -+ p->iTable = 0; -+ p->iColumn = 0; - p->u.zToken = (char*)&p[1]; - memcpy(p->u.zToken, t.z, t.n); - p->u.zToken[t.n] = 0; -@@ -136681,51 +146945,19 @@ - #if SQLITE_MAX_EXPR_DEPTH>0 - p->nHeight = 1; - #endif -+ if( IN_RENAME_OBJECT ){ -+ return (Expr*)sqlite3RenameTokenMap(pParse, (void*)p, &t); -+ } - } -- pOut->pExpr = p; -- pOut->zStart = t.z; -- pOut->zEnd = &t.z[t.n]; -+ return p; - } - -- /* This routine constructs a binary expression node out of two ExprSpan -- ** objects and uses the result to populate a new ExprSpan object. -- */ -- static void spanBinaryExpr( -- Parse *pParse, /* The parsing context. Errors accumulate here */ -- int op, /* The binary operation */ -- ExprSpan *pLeft, /* The left operand, and output */ -- ExprSpan *pRight /* The right operand */ -- ){ -- pLeft->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr); -- pLeft->zEnd = pRight->zEnd; -- } - -- /* If doNot is true, then add a TK_NOT Expr-node wrapper around the -- ** outside of *ppExpr. -- */ -- static void exprNot(Parse *pParse, int doNot, ExprSpan *pSpan){ -- if( doNot ){ -- pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0); -- } -- } -- -- /* Construct an expression node for a unary postfix operator -- */ -- static void spanUnaryPostfix( -- Parse *pParse, /* Parsing context to record errors */ -- int op, /* The operator */ -- ExprSpan *pOperand, /* The operand, and output */ -- Token *pPostOp /* The operand token for setting the span */ -- ){ -- pOperand->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0); -- pOperand->zEnd = &pPostOp->z[pPostOp->n]; -- } -- - /* A routine to convert a binary TK_IS or TK_ISNOT expression into a - ** unary TK_ISNULL or TK_NOTNULL expression. */ - static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){ - sqlite3 *db = pParse->db; -- if( pA && pY && pY->op==TK_NULL ){ -+ if( pA && pY && pY->op==TK_NULL && !IN_RENAME_OBJECT ){ - pA->op = (u8)op; - sqlite3ExprDelete(db, pA->pRight); - pA->pRight = 0; -@@ -136732,20 +146964,6 @@ - } - } - -- /* Construct an expression node for a unary prefix operator -- */ -- static void spanUnaryPrefix( -- ExprSpan *pOut, /* Write the new expression node here */ -- Parse *pParse, /* Parsing context to record errors */ -- int op, /* The operator */ -- ExprSpan *pOperand, /* The operand */ -- Token *pPreOp /* The operand token for setting the span */ -- ){ -- pOut->zStart = pPreOp->z; -- pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0); -- pOut->zEnd = pOperand->zEnd; -- } -- - /* Add a single new term to an ExprList that is used to store a - ** list of identifiers. Report an error if the ID list contains - ** a COLLATE clause or an ASC or DESC keyword, except ignore the -@@ -136808,64 +147026,78 @@ - ** zero the stack is dynamically sized using realloc() - ** sqlite3ParserARG_SDECL A static variable declaration for the %extra_argument - ** sqlite3ParserARG_PDECL A parameter declaration for the %extra_argument -+** sqlite3ParserARG_PARAM Code to pass %extra_argument as a subroutine parameter - ** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser - ** sqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser -+** sqlite3ParserCTX_* As sqlite3ParserARG_ except for %extra_context - ** YYERRORSYMBOL is the code number of the error symbol. If not - ** defined, then do no error processing. - ** YYNSTATE the combined number of states. - ** YYNRULE the number of rules in the grammar -+** YYNTOKEN Number of terminal symbols - ** YY_MAX_SHIFT Maximum value for shift actions - ** YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions - ** YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions --** YY_MIN_REDUCE Maximum value for reduce actions - ** YY_ERROR_ACTION The yy_action[] code for syntax error - ** YY_ACCEPT_ACTION The yy_action[] code for accept - ** YY_NO_ACTION The yy_action[] code for no-op -+** YY_MIN_REDUCE Minimum value for reduce actions -+** YY_MAX_REDUCE Maximum value for reduce actions - */ - #ifndef INTERFACE - # define INTERFACE 1 - #endif - /************* Begin control #defines *****************************************/ --#define YYCODETYPE unsigned char --#define YYNOCODE 252 -+#define YYCODETYPE unsigned short int -+#define YYNOCODE 277 - #define YYACTIONTYPE unsigned short int --#define YYWILDCARD 69 -+#define YYWILDCARD 91 - #define sqlite3ParserTOKENTYPE Token - typedef union { - int yyinit; - sqlite3ParserTOKENTYPE yy0; -- Expr* yy72; -- TriggerStep* yy145; -- ExprList* yy148; -- SrcList* yy185; -- ExprSpan yy190; -- int yy194; -- Select* yy243; -- IdList* yy254; -- With* yy285; -- struct TrigEvent yy332; -- struct LimitVal yy354; -- struct {int value; int mask;} yy497; -+ Expr* yy18; -+ struct TrigEvent yy34; -+ IdList* yy48; -+ int yy70; -+ struct {int value; int mask;} yy111; -+ struct FrameBound yy119; -+ SrcList* yy135; -+ TriggerStep* yy207; -+ Window* yy327; -+ Upsert* yy340; -+ const char* yy392; -+ ExprList* yy420; -+ With* yy449; -+ Select* yy489; - } YYMINORTYPE; - #ifndef YYSTACKDEPTH - #define YYSTACKDEPTH 100 - #endif --#define sqlite3ParserARG_SDECL Parse *pParse; --#define sqlite3ParserARG_PDECL ,Parse *pParse --#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse --#define sqlite3ParserARG_STORE yypParser->pParse = pParse -+#define sqlite3ParserARG_SDECL -+#define sqlite3ParserARG_PDECL -+#define sqlite3ParserARG_PARAM -+#define sqlite3ParserARG_FETCH -+#define sqlite3ParserARG_STORE -+#define sqlite3ParserCTX_SDECL Parse *pParse; -+#define sqlite3ParserCTX_PDECL ,Parse *pParse -+#define sqlite3ParserCTX_PARAM ,pParse -+#define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; -+#define sqlite3ParserCTX_STORE yypParser->pParse=pParse; - #define YYFALLBACK 1 --#define YYNSTATE 455 --#define YYNRULE 329 --#define YY_MAX_SHIFT 454 --#define YY_MIN_SHIFTREDUCE 664 --#define YY_MAX_SHIFTREDUCE 992 --#define YY_MIN_REDUCE 993 --#define YY_MAX_REDUCE 1321 --#define YY_ERROR_ACTION 1322 --#define YY_ACCEPT_ACTION 1323 --#define YY_NO_ACTION 1324 -+#define YYNSTATE 521 -+#define YYNRULE 367 -+#define YYNTOKEN 155 -+#define YY_MAX_SHIFT 520 -+#define YY_MIN_SHIFTREDUCE 756 -+#define YY_MAX_SHIFTREDUCE 1122 -+#define YY_ERROR_ACTION 1123 -+#define YY_ACCEPT_ACTION 1124 -+#define YY_NO_ACTION 1125 -+#define YY_MIN_REDUCE 1126 -+#define YY_MAX_REDUCE 1492 - /************* End control #defines *******************************************/ -+#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) - - /* Define the yytestcase() macro to be a no-op if is not already defined - ** otherwise. -@@ -136894,9 +147126,6 @@ - ** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then - ** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE. - ** --** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE --** and YY_MAX_REDUCE --** - ** N == YY_ERROR_ACTION A syntax error has occurred. - ** - ** N == YY_ACCEPT_ACTION The parser accepts its input. -@@ -136904,6 +147133,9 @@ - ** N == YY_NO_ACTION No such action. Denotes unused - ** slots in the yy_action[] table. - ** -+** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE -+** and YY_MAX_REDUCE -+** - ** The action table is constructed as a single large table named yy_action[]. - ** Given state S and lookahead X, the action is computed as either: - ** -@@ -136910,19 +147142,13 @@ - ** (A) N = yy_action[ yy_shift_ofst[S] + X ] - ** (B) N = yy_default[S] - ** --** The (A) formula is preferred. The B formula is used instead if: --** (1) The yy_shift_ofst[S]+X value is out of range, or --** (2) yy_lookahead[yy_shift_ofst[S]+X] is not equal to X, or --** (3) yy_shift_ofst[S] equal YY_SHIFT_USE_DFLT. --** (Implementation note: YY_SHIFT_USE_DFLT is chosen so that --** YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X. --** Hence only tests (1) and (2) need to be evaluated.) -+** The (A) formula is preferred. The B formula is used instead if -+** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X. - ** - ** The formulas above are for computing the action when the lookahead is - ** a terminal symbol. If the lookahead is a non-terminal (as occurs after - ** a reduce action) then the yy_reduce_ofst[] array is used in place of --** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of --** YY_SHIFT_USE_DFLT. -+** the yy_shift_ofst[] array. - ** - ** The following are the tables generated in this section: - ** -@@ -136936,463 +147162,568 @@ - ** yy_default[] Default action for each state. - ** - *********** Begin parsing tables **********************************************/ --#define YY_ACTTAB_COUNT (1565) -+#define YY_ACTTAB_COUNT (2009) - static const YYACTIONTYPE yy_action[] = { -- /* 0 */ 324, 410, 342, 747, 747, 203, 939, 353, 969, 98, -- /* 10 */ 98, 98, 98, 91, 96, 96, 96, 96, 95, 95, -- /* 20 */ 94, 94, 94, 93, 350, 1323, 155, 155, 2, 808, -- /* 30 */ 971, 971, 98, 98, 98, 98, 20, 96, 96, 96, -- /* 40 */ 96, 95, 95, 94, 94, 94, 93, 350, 92, 89, -- /* 50 */ 178, 99, 100, 90, 847, 850, 839, 839, 97, 97, -- /* 60 */ 98, 98, 98, 98, 350, 96, 96, 96, 96, 95, -- /* 70 */ 95, 94, 94, 94, 93, 350, 324, 339, 969, 262, -- /* 80 */ 364, 251, 212, 169, 287, 404, 282, 403, 199, 786, -- /* 90 */ 242, 411, 21, 950, 378, 280, 93, 350, 787, 95, -- /* 100 */ 95, 94, 94, 94, 93, 350, 971, 971, 96, 96, -- /* 110 */ 96, 96, 95, 95, 94, 94, 94, 93, 350, 808, -- /* 120 */ 328, 242, 411, 1235, 826, 1235, 132, 99, 100, 90, -- /* 130 */ 847, 850, 839, 839, 97, 97, 98, 98, 98, 98, -- /* 140 */ 449, 96, 96, 96, 96, 95, 95, 94, 94, 94, -- /* 150 */ 93, 350, 324, 819, 348, 347, 120, 818, 120, 75, -- /* 160 */ 52, 52, 950, 951, 952, 1084, 977, 146, 360, 262, -- /* 170 */ 369, 261, 950, 975, 954, 976, 92, 89, 178, 370, -- /* 180 */ 230, 370, 971, 971, 1141, 360, 359, 101, 818, 818, -- /* 190 */ 820, 383, 24, 1286, 380, 427, 412, 368, 978, 379, -- /* 200 */ 978, 1032, 324, 99, 100, 90, 847, 850, 839, 839, -- /* 210 */ 97, 97, 98, 98, 98, 98, 372, 96, 96, 96, -- /* 220 */ 96, 95, 95, 94, 94, 94, 93, 350, 950, 132, -- /* 230 */ 890, 449, 971, 971, 890, 60, 94, 94, 94, 93, -- /* 240 */ 350, 950, 951, 952, 954, 103, 360, 950, 384, 333, -- /* 250 */ 697, 52, 52, 99, 100, 90, 847, 850, 839, 839, -- /* 260 */ 97, 97, 98, 98, 98, 98, 1022, 96, 96, 96, -- /* 270 */ 96, 95, 95, 94, 94, 94, 93, 350, 324, 454, -- /* 280 */ 995, 449, 227, 61, 157, 243, 343, 114, 1025, 1211, -- /* 290 */ 147, 826, 950, 372, 1071, 950, 319, 950, 951, 952, -- /* 300 */ 194, 10, 10, 401, 398, 397, 1211, 1213, 971, 971, -- /* 310 */ 757, 171, 170, 157, 396, 336, 950, 951, 952, 697, -- /* 320 */ 819, 310, 153, 950, 818, 320, 82, 23, 80, 99, -- /* 330 */ 100, 90, 847, 850, 839, 839, 97, 97, 98, 98, -- /* 340 */ 98, 98, 888, 96, 96, 96, 96, 95, 95, 94, -- /* 350 */ 94, 94, 93, 350, 324, 818, 818, 820, 277, 231, -- /* 360 */ 300, 950, 951, 952, 950, 951, 952, 1211, 194, 25, -- /* 370 */ 449, 401, 398, 397, 950, 354, 300, 449, 950, 74, -- /* 380 */ 449, 1, 396, 132, 971, 971, 950, 224, 224, 808, -- /* 390 */ 10, 10, 950, 951, 952, 1290, 132, 52, 52, 414, -- /* 400 */ 52, 52, 1063, 1063, 338, 99, 100, 90, 847, 850, -- /* 410 */ 839, 839, 97, 97, 98, 98, 98, 98, 1114, 96, -- /* 420 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 350, -- /* 430 */ 324, 1113, 427, 417, 701, 427, 426, 1260, 1260, 262, -- /* 440 */ 369, 261, 950, 950, 951, 952, 752, 950, 951, 952, -- /* 450 */ 449, 751, 449, 1058, 1037, 950, 951, 952, 442, 706, -- /* 460 */ 971, 971, 1058, 393, 92, 89, 178, 446, 446, 446, -- /* 470 */ 51, 51, 52, 52, 438, 773, 1024, 92, 89, 178, -- /* 480 */ 172, 99, 100, 90, 847, 850, 839, 839, 97, 97, -- /* 490 */ 98, 98, 98, 98, 198, 96, 96, 96, 96, 95, -- /* 500 */ 95, 94, 94, 94, 93, 350, 324, 427, 407, 909, -- /* 510 */ 694, 950, 951, 952, 92, 89, 178, 224, 224, 157, -- /* 520 */ 241, 221, 418, 299, 771, 910, 415, 374, 449, 414, -- /* 530 */ 58, 323, 1061, 1061, 1242, 378, 971, 971, 378, 772, -- /* 540 */ 448, 911, 362, 735, 296, 681, 9, 9, 52, 52, -- /* 550 */ 234, 329, 234, 256, 416, 736, 280, 99, 100, 90, -- /* 560 */ 847, 850, 839, 839, 97, 97, 98, 98, 98, 98, -- /* 570 */ 449, 96, 96, 96, 96, 95, 95, 94, 94, 94, -- /* 580 */ 93, 350, 324, 422, 72, 449, 827, 120, 367, 449, -- /* 590 */ 10, 10, 5, 301, 203, 449, 177, 969, 253, 419, -- /* 600 */ 255, 771, 200, 175, 233, 10, 10, 836, 836, 36, -- /* 610 */ 36, 1289, 971, 971, 724, 37, 37, 348, 347, 424, -- /* 620 */ 203, 260, 771, 969, 232, 930, 1316, 870, 337, 1316, -- /* 630 */ 421, 848, 851, 99, 100, 90, 847, 850, 839, 839, -- /* 640 */ 97, 97, 98, 98, 98, 98, 268, 96, 96, 96, -- /* 650 */ 96, 95, 95, 94, 94, 94, 93, 350, 324, 840, -- /* 660 */ 449, 978, 813, 978, 1200, 449, 909, 969, 715, 349, -- /* 670 */ 349, 349, 928, 177, 449, 930, 1317, 254, 198, 1317, -- /* 680 */ 12, 12, 910, 402, 449, 27, 27, 250, 971, 971, -- /* 690 */ 118, 716, 162, 969, 38, 38, 268, 176, 911, 771, -- /* 700 */ 432, 1265, 939, 353, 39, 39, 316, 991, 324, 99, -- /* 710 */ 100, 90, 847, 850, 839, 839, 97, 97, 98, 98, -- /* 720 */ 98, 98, 928, 96, 96, 96, 96, 95, 95, 94, -- /* 730 */ 94, 94, 93, 350, 449, 329, 449, 357, 971, 971, -- /* 740 */ 1041, 316, 929, 340, 893, 893, 386, 669, 670, 671, -- /* 750 */ 275, 1318, 317, 992, 40, 40, 41, 41, 268, 99, -- /* 760 */ 100, 90, 847, 850, 839, 839, 97, 97, 98, 98, -- /* 770 */ 98, 98, 449, 96, 96, 96, 96, 95, 95, 94, -- /* 780 */ 94, 94, 93, 350, 324, 449, 355, 449, 992, 449, -- /* 790 */ 1016, 330, 42, 42, 786, 270, 449, 273, 449, 228, -- /* 800 */ 449, 298, 449, 787, 449, 28, 28, 29, 29, 31, -- /* 810 */ 31, 449, 1141, 449, 971, 971, 43, 43, 44, 44, -- /* 820 */ 45, 45, 11, 11, 46, 46, 887, 78, 887, 268, -- /* 830 */ 268, 105, 105, 47, 47, 99, 100, 90, 847, 850, -- /* 840 */ 839, 839, 97, 97, 98, 98, 98, 98, 449, 96, -- /* 850 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 350, -- /* 860 */ 324, 449, 117, 449, 1073, 158, 449, 691, 48, 48, -- /* 870 */ 229, 1241, 449, 1250, 449, 414, 449, 334, 449, 245, -- /* 880 */ 449, 33, 33, 49, 49, 449, 50, 50, 246, 1141, -- /* 890 */ 971, 971, 34, 34, 122, 122, 123, 123, 124, 124, -- /* 900 */ 56, 56, 268, 81, 249, 35, 35, 197, 196, 195, -- /* 910 */ 324, 99, 100, 90, 847, 850, 839, 839, 97, 97, -- /* 920 */ 98, 98, 98, 98, 449, 96, 96, 96, 96, 95, -- /* 930 */ 95, 94, 94, 94, 93, 350, 449, 691, 449, 1141, -- /* 940 */ 971, 971, 968, 1207, 106, 106, 268, 1209, 268, 1266, -- /* 950 */ 2, 886, 268, 886, 335, 1040, 53, 53, 107, 107, -- /* 960 */ 324, 99, 100, 90, 847, 850, 839, 839, 97, 97, -- /* 970 */ 98, 98, 98, 98, 449, 96, 96, 96, 96, 95, -- /* 980 */ 95, 94, 94, 94, 93, 350, 449, 1070, 449, 1066, -- /* 990 */ 971, 971, 1039, 267, 108, 108, 445, 330, 331, 133, -- /* 1000 */ 223, 175, 301, 225, 385, 1255, 104, 104, 121, 121, -- /* 1010 */ 324, 99, 88, 90, 847, 850, 839, 839, 97, 97, -- /* 1020 */ 98, 98, 98, 98, 1141, 96, 96, 96, 96, 95, -- /* 1030 */ 95, 94, 94, 94, 93, 350, 449, 346, 449, 167, -- /* 1040 */ 971, 971, 925, 810, 371, 318, 202, 202, 373, 263, -- /* 1050 */ 394, 202, 74, 208, 721, 722, 119, 119, 112, 112, -- /* 1060 */ 324, 406, 100, 90, 847, 850, 839, 839, 97, 97, -- /* 1070 */ 98, 98, 98, 98, 449, 96, 96, 96, 96, 95, -- /* 1080 */ 95, 94, 94, 94, 93, 350, 449, 752, 449, 344, -- /* 1090 */ 971, 971, 751, 278, 111, 111, 74, 714, 713, 704, -- /* 1100 */ 286, 877, 749, 1279, 257, 77, 109, 109, 110, 110, -- /* 1110 */ 1230, 285, 1134, 90, 847, 850, 839, 839, 97, 97, -- /* 1120 */ 98, 98, 98, 98, 1233, 96, 96, 96, 96, 95, -- /* 1130 */ 95, 94, 94, 94, 93, 350, 86, 444, 449, 3, -- /* 1140 */ 1193, 449, 1069, 132, 351, 120, 1013, 86, 444, 780, -- /* 1150 */ 3, 1091, 202, 376, 447, 351, 1229, 120, 55, 55, -- /* 1160 */ 449, 57, 57, 822, 873, 447, 449, 208, 449, 704, -- /* 1170 */ 449, 877, 237, 433, 435, 120, 439, 428, 361, 120, -- /* 1180 */ 54, 54, 132, 449, 433, 826, 52, 52, 26, 26, -- /* 1190 */ 30, 30, 381, 132, 408, 443, 826, 689, 264, 389, -- /* 1200 */ 116, 269, 272, 32, 32, 83, 84, 120, 274, 120, -- /* 1210 */ 120, 276, 85, 351, 451, 450, 83, 84, 818, 1054, -- /* 1220 */ 1038, 427, 429, 85, 351, 451, 450, 120, 120, 818, -- /* 1230 */ 377, 218, 281, 822, 1107, 1140, 86, 444, 409, 3, -- /* 1240 */ 1087, 1098, 430, 431, 351, 302, 303, 1146, 1021, 818, -- /* 1250 */ 818, 820, 821, 19, 447, 1015, 1004, 1003, 1005, 1273, -- /* 1260 */ 818, 818, 820, 821, 19, 289, 159, 291, 293, 7, -- /* 1270 */ 315, 173, 259, 433, 1129, 363, 252, 1232, 375, 1037, -- /* 1280 */ 295, 434, 168, 986, 399, 826, 284, 1204, 1203, 205, -- /* 1290 */ 1276, 308, 1249, 86, 444, 983, 3, 1247, 332, 144, -- /* 1300 */ 130, 351, 72, 135, 59, 83, 84, 756, 137, 365, -- /* 1310 */ 1126, 447, 85, 351, 451, 450, 139, 226, 818, 140, -- /* 1320 */ 156, 62, 314, 314, 313, 215, 311, 366, 392, 678, -- /* 1330 */ 433, 185, 141, 1234, 142, 160, 148, 1136, 1198, 382, -- /* 1340 */ 189, 67, 826, 180, 388, 248, 1218, 1099, 219, 818, -- /* 1350 */ 818, 820, 821, 19, 247, 190, 266, 154, 390, 271, -- /* 1360 */ 191, 192, 83, 84, 1006, 405, 1057, 182, 321, 85, -- /* 1370 */ 351, 451, 450, 1056, 183, 818, 341, 132, 181, 706, -- /* 1380 */ 1055, 420, 76, 444, 1029, 3, 322, 1028, 283, 1048, -- /* 1390 */ 351, 1095, 1027, 1288, 1047, 71, 204, 6, 288, 290, -- /* 1400 */ 447, 1096, 1094, 1093, 79, 292, 818, 818, 820, 821, -- /* 1410 */ 19, 294, 297, 437, 345, 441, 102, 1184, 1077, 433, -- /* 1420 */ 238, 425, 73, 305, 239, 304, 325, 240, 423, 306, -- /* 1430 */ 307, 826, 213, 1012, 22, 945, 452, 214, 216, 217, -- /* 1440 */ 453, 1001, 115, 996, 125, 126, 235, 127, 665, 352, -- /* 1450 */ 326, 83, 84, 358, 166, 244, 179, 327, 85, 351, -- /* 1460 */ 451, 450, 134, 356, 818, 113, 885, 806, 883, 136, -- /* 1470 */ 128, 138, 738, 258, 184, 899, 143, 145, 63, 64, -- /* 1480 */ 65, 66, 129, 902, 187, 186, 898, 8, 13, 188, -- /* 1490 */ 265, 891, 149, 202, 980, 818, 818, 820, 821, 19, -- /* 1500 */ 150, 387, 161, 680, 285, 391, 151, 395, 400, 193, -- /* 1510 */ 68, 14, 236, 279, 15, 69, 717, 825, 131, 824, -- /* 1520 */ 853, 70, 746, 16, 413, 750, 4, 174, 220, 222, -- /* 1530 */ 152, 779, 857, 774, 201, 77, 74, 868, 17, 854, -- /* 1540 */ 852, 908, 18, 907, 207, 206, 934, 163, 436, 210, -- /* 1550 */ 935, 164, 209, 165, 440, 856, 823, 690, 87, 211, -- /* 1560 */ 309, 312, 1281, 940, 1280, -+ /* 0 */ 368, 105, 102, 197, 105, 102, 197, 515, 1124, 1, -+ /* 10 */ 1, 520, 2, 1128, 515, 1192, 1171, 1456, 275, 370, -+ /* 20 */ 127, 1389, 1197, 1197, 1192, 1166, 178, 1205, 64, 64, -+ /* 30 */ 477, 887, 322, 428, 348, 37, 37, 808, 362, 888, -+ /* 40 */ 509, 509, 509, 112, 113, 103, 1100, 1100, 953, 956, -+ /* 50 */ 946, 946, 110, 110, 111, 111, 111, 111, 365, 252, -+ /* 60 */ 252, 515, 252, 252, 497, 515, 309, 515, 459, 515, -+ /* 70 */ 1079, 491, 512, 478, 6, 512, 809, 134, 498, 228, -+ /* 80 */ 194, 428, 37, 37, 515, 208, 64, 64, 64, 64, -+ /* 90 */ 13, 13, 109, 109, 109, 109, 108, 108, 107, 107, -+ /* 100 */ 107, 106, 401, 258, 381, 13, 13, 398, 397, 428, -+ /* 110 */ 252, 252, 370, 476, 405, 1104, 1079, 1080, 1081, 386, -+ /* 120 */ 1106, 390, 497, 512, 497, 1423, 1419, 304, 1105, 307, -+ /* 130 */ 1256, 496, 370, 499, 16, 16, 112, 113, 103, 1100, -+ /* 140 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111, -+ /* 150 */ 111, 262, 1107, 495, 1107, 401, 112, 113, 103, 1100, -+ /* 160 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111, -+ /* 170 */ 111, 129, 1425, 343, 1420, 339, 1059, 492, 1057, 263, -+ /* 180 */ 73, 105, 102, 197, 994, 109, 109, 109, 109, 108, -+ /* 190 */ 108, 107, 107, 107, 106, 401, 370, 111, 111, 111, -+ /* 200 */ 111, 104, 492, 89, 1432, 109, 109, 109, 109, 108, -+ /* 210 */ 108, 107, 107, 107, 106, 401, 111, 111, 111, 111, -+ /* 220 */ 112, 113, 103, 1100, 1100, 953, 956, 946, 946, 110, -+ /* 230 */ 110, 111, 111, 111, 111, 109, 109, 109, 109, 108, -+ /* 240 */ 108, 107, 107, 107, 106, 401, 114, 108, 108, 107, -+ /* 250 */ 107, 107, 106, 401, 109, 109, 109, 109, 108, 108, -+ /* 260 */ 107, 107, 107, 106, 401, 152, 399, 399, 399, 109, -+ /* 270 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 401, -+ /* 280 */ 178, 493, 1412, 434, 1037, 1486, 1079, 515, 1486, 370, -+ /* 290 */ 421, 297, 357, 412, 74, 1079, 109, 109, 109, 109, -+ /* 300 */ 108, 108, 107, 107, 107, 106, 401, 1413, 37, 37, -+ /* 310 */ 1431, 274, 506, 112, 113, 103, 1100, 1100, 953, 956, -+ /* 320 */ 946, 946, 110, 110, 111, 111, 111, 111, 1436, 520, -+ /* 330 */ 2, 1128, 1079, 1080, 1081, 430, 275, 1079, 127, 366, -+ /* 340 */ 933, 1079, 1080, 1081, 220, 1205, 913, 458, 455, 454, -+ /* 350 */ 392, 167, 515, 1035, 152, 445, 924, 453, 152, 874, -+ /* 360 */ 923, 289, 109, 109, 109, 109, 108, 108, 107, 107, -+ /* 370 */ 107, 106, 401, 13, 13, 261, 853, 252, 252, 227, -+ /* 380 */ 106, 401, 370, 1079, 1080, 1081, 311, 388, 1079, 296, -+ /* 390 */ 512, 923, 923, 925, 231, 323, 1255, 1388, 1423, 490, -+ /* 400 */ 274, 506, 12, 208, 274, 506, 112, 113, 103, 1100, -+ /* 410 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111, -+ /* 420 */ 111, 1440, 286, 1128, 288, 1079, 1097, 247, 275, 1098, -+ /* 430 */ 127, 387, 405, 389, 1079, 1080, 1081, 1205, 159, 238, -+ /* 440 */ 255, 321, 461, 316, 460, 225, 790, 105, 102, 197, -+ /* 450 */ 513, 314, 842, 842, 445, 109, 109, 109, 109, 108, -+ /* 460 */ 108, 107, 107, 107, 106, 401, 515, 514, 515, 252, -+ /* 470 */ 252, 1079, 1080, 1081, 435, 370, 1098, 933, 1460, 794, -+ /* 480 */ 274, 506, 512, 105, 102, 197, 336, 63, 63, 64, -+ /* 490 */ 64, 27, 790, 924, 287, 208, 1354, 923, 515, 112, -+ /* 500 */ 113, 103, 1100, 1100, 953, 956, 946, 946, 110, 110, -+ /* 510 */ 111, 111, 111, 111, 107, 107, 107, 106, 401, 49, -+ /* 520 */ 49, 515, 28, 1079, 405, 497, 421, 297, 923, 923, -+ /* 530 */ 925, 186, 468, 1079, 467, 999, 999, 442, 515, 1079, -+ /* 540 */ 334, 515, 45, 45, 1083, 342, 173, 168, 109, 109, -+ /* 550 */ 109, 109, 108, 108, 107, 107, 107, 106, 401, 13, -+ /* 560 */ 13, 205, 13, 13, 252, 252, 1195, 1195, 370, 1079, -+ /* 570 */ 1080, 1081, 787, 265, 5, 359, 494, 512, 469, 1079, -+ /* 580 */ 1080, 1081, 398, 397, 1079, 1079, 1080, 1081, 3, 282, -+ /* 590 */ 1079, 1083, 112, 113, 103, 1100, 1100, 953, 956, 946, -+ /* 600 */ 946, 110, 110, 111, 111, 111, 111, 252, 252, 1015, -+ /* 610 */ 220, 1079, 873, 458, 455, 454, 943, 943, 954, 957, -+ /* 620 */ 512, 252, 252, 453, 1016, 1079, 445, 1107, 1209, 1107, -+ /* 630 */ 1079, 1080, 1081, 515, 512, 426, 1079, 1080, 1081, 1017, -+ /* 640 */ 512, 109, 109, 109, 109, 108, 108, 107, 107, 107, -+ /* 650 */ 106, 401, 1052, 515, 50, 50, 515, 1079, 1080, 1081, -+ /* 660 */ 828, 370, 1051, 379, 411, 1064, 1358, 207, 408, 773, -+ /* 670 */ 829, 1079, 1080, 1081, 64, 64, 322, 64, 64, 1302, -+ /* 680 */ 947, 411, 410, 1358, 1360, 112, 113, 103, 1100, 1100, -+ /* 690 */ 953, 956, 946, 946, 110, 110, 111, 111, 111, 111, -+ /* 700 */ 294, 482, 515, 1037, 1487, 515, 434, 1487, 354, 1120, -+ /* 710 */ 483, 996, 913, 485, 466, 996, 132, 178, 33, 450, -+ /* 720 */ 1203, 136, 406, 64, 64, 479, 64, 64, 419, 369, -+ /* 730 */ 283, 1146, 252, 252, 109, 109, 109, 109, 108, 108, -+ /* 740 */ 107, 107, 107, 106, 401, 512, 224, 440, 411, 266, -+ /* 750 */ 1358, 266, 252, 252, 370, 296, 416, 284, 934, 396, -+ /* 760 */ 976, 470, 400, 252, 252, 512, 9, 473, 231, 500, -+ /* 770 */ 354, 1036, 1035, 1488, 355, 374, 512, 1121, 112, 113, -+ /* 780 */ 103, 1100, 1100, 953, 956, 946, 946, 110, 110, 111, -+ /* 790 */ 111, 111, 111, 252, 252, 1015, 515, 1347, 295, 252, -+ /* 800 */ 252, 252, 252, 1098, 375, 249, 512, 445, 872, 322, -+ /* 810 */ 1016, 480, 512, 195, 512, 434, 273, 15, 15, 515, -+ /* 820 */ 314, 515, 95, 515, 93, 1017, 367, 109, 109, 109, -+ /* 830 */ 109, 108, 108, 107, 107, 107, 106, 401, 515, 1121, -+ /* 840 */ 39, 39, 51, 51, 52, 52, 503, 370, 515, 1204, -+ /* 850 */ 1098, 918, 439, 341, 133, 436, 223, 222, 221, 53, -+ /* 860 */ 53, 322, 1400, 761, 762, 763, 515, 370, 88, 54, -+ /* 870 */ 54, 112, 113, 103, 1100, 1100, 953, 956, 946, 946, -+ /* 880 */ 110, 110, 111, 111, 111, 111, 407, 55, 55, 196, -+ /* 890 */ 515, 112, 113, 103, 1100, 1100, 953, 956, 946, 946, -+ /* 900 */ 110, 110, 111, 111, 111, 111, 135, 264, 1149, 376, -+ /* 910 */ 515, 40, 40, 515, 872, 515, 993, 515, 993, 116, -+ /* 920 */ 109, 109, 109, 109, 108, 108, 107, 107, 107, 106, -+ /* 930 */ 401, 41, 41, 515, 43, 43, 44, 44, 56, 56, -+ /* 940 */ 109, 109, 109, 109, 108, 108, 107, 107, 107, 106, -+ /* 950 */ 401, 515, 379, 515, 57, 57, 515, 799, 515, 379, -+ /* 960 */ 515, 445, 200, 515, 323, 515, 1397, 515, 1459, 515, -+ /* 970 */ 1287, 817, 58, 58, 14, 14, 515, 59, 59, 118, -+ /* 980 */ 118, 60, 60, 515, 46, 46, 61, 61, 62, 62, -+ /* 990 */ 47, 47, 515, 190, 189, 91, 515, 140, 140, 515, -+ /* 1000 */ 394, 515, 277, 1200, 141, 141, 515, 1115, 515, 992, -+ /* 1010 */ 515, 992, 515, 69, 69, 370, 278, 48, 48, 259, -+ /* 1020 */ 65, 65, 119, 119, 246, 246, 260, 66, 66, 120, -+ /* 1030 */ 120, 121, 121, 117, 117, 370, 515, 512, 383, 112, -+ /* 1040 */ 113, 103, 1100, 1100, 953, 956, 946, 946, 110, 110, -+ /* 1050 */ 111, 111, 111, 111, 515, 872, 515, 139, 139, 112, -+ /* 1060 */ 113, 103, 1100, 1100, 953, 956, 946, 946, 110, 110, -+ /* 1070 */ 111, 111, 111, 111, 1287, 138, 138, 125, 125, 515, -+ /* 1080 */ 12, 515, 281, 1287, 515, 445, 131, 1287, 109, 109, -+ /* 1090 */ 109, 109, 108, 108, 107, 107, 107, 106, 401, 515, -+ /* 1100 */ 124, 124, 122, 122, 515, 123, 123, 515, 109, 109, -+ /* 1110 */ 109, 109, 108, 108, 107, 107, 107, 106, 401, 515, -+ /* 1120 */ 68, 68, 463, 783, 515, 70, 70, 302, 67, 67, -+ /* 1130 */ 1032, 253, 253, 356, 1287, 191, 196, 1433, 465, 1301, -+ /* 1140 */ 38, 38, 384, 94, 512, 42, 42, 177, 848, 274, -+ /* 1150 */ 506, 385, 420, 847, 1356, 441, 508, 376, 377, 153, -+ /* 1160 */ 423, 872, 432, 370, 224, 251, 194, 887, 182, 293, -+ /* 1170 */ 783, 848, 88, 254, 466, 888, 847, 915, 807, 806, -+ /* 1180 */ 230, 1241, 910, 370, 17, 413, 797, 112, 113, 103, -+ /* 1190 */ 1100, 1100, 953, 956, 946, 946, 110, 110, 111, 111, -+ /* 1200 */ 111, 111, 395, 814, 815, 1175, 983, 112, 101, 103, -+ /* 1210 */ 1100, 1100, 953, 956, 946, 946, 110, 110, 111, 111, -+ /* 1220 */ 111, 111, 375, 422, 427, 429, 298, 230, 230, 88, -+ /* 1230 */ 1240, 451, 312, 797, 226, 88, 109, 109, 109, 109, -+ /* 1240 */ 108, 108, 107, 107, 107, 106, 401, 86, 433, 979, -+ /* 1250 */ 927, 881, 226, 983, 230, 415, 109, 109, 109, 109, -+ /* 1260 */ 108, 108, 107, 107, 107, 106, 401, 320, 845, 781, -+ /* 1270 */ 846, 100, 130, 100, 1403, 290, 370, 319, 1377, 1376, -+ /* 1280 */ 437, 1449, 299, 1237, 303, 306, 308, 310, 1188, 1174, -+ /* 1290 */ 1173, 1172, 315, 324, 325, 1228, 370, 927, 1249, 271, -+ /* 1300 */ 1286, 113, 103, 1100, 1100, 953, 956, 946, 946, 110, -+ /* 1310 */ 110, 111, 111, 111, 111, 1224, 1235, 502, 501, 1292, -+ /* 1320 */ 1221, 1155, 103, 1100, 1100, 953, 956, 946, 946, 110, -+ /* 1330 */ 110, 111, 111, 111, 111, 1148, 1137, 1136, 1138, 1443, -+ /* 1340 */ 446, 244, 184, 98, 507, 188, 4, 353, 327, 109, -+ /* 1350 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 401, -+ /* 1360 */ 510, 329, 331, 199, 414, 456, 292, 285, 318, 109, -+ /* 1370 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 401, -+ /* 1380 */ 11, 1271, 1279, 402, 361, 192, 1171, 1351, 431, 505, -+ /* 1390 */ 346, 1350, 333, 98, 507, 504, 4, 187, 1446, 1115, -+ /* 1400 */ 233, 1396, 155, 1394, 1112, 152, 72, 75, 378, 425, -+ /* 1410 */ 510, 165, 149, 157, 933, 1276, 86, 30, 1268, 417, -+ /* 1420 */ 96, 96, 8, 160, 161, 162, 163, 97, 418, 402, -+ /* 1430 */ 517, 516, 449, 402, 923, 210, 358, 424, 1282, 438, -+ /* 1440 */ 169, 214, 360, 1345, 80, 504, 31, 444, 1365, 301, -+ /* 1450 */ 245, 274, 506, 216, 174, 305, 488, 447, 217, 462, -+ /* 1460 */ 1139, 487, 218, 363, 933, 923, 923, 925, 926, 24, -+ /* 1470 */ 96, 96, 1191, 1190, 1189, 391, 1182, 97, 1163, 402, -+ /* 1480 */ 517, 516, 799, 364, 923, 1162, 317, 1161, 98, 507, -+ /* 1490 */ 1181, 4, 1458, 472, 393, 269, 270, 475, 481, 1232, -+ /* 1500 */ 85, 1233, 326, 328, 232, 510, 495, 1231, 330, 98, -+ /* 1510 */ 507, 1230, 4, 486, 335, 923, 923, 925, 926, 24, -+ /* 1520 */ 1435, 1068, 404, 181, 336, 256, 510, 115, 402, 332, -+ /* 1530 */ 352, 352, 351, 241, 349, 1214, 1414, 770, 338, 10, -+ /* 1540 */ 504, 340, 272, 92, 1331, 1213, 87, 183, 484, 402, -+ /* 1550 */ 201, 488, 280, 239, 344, 345, 489, 1145, 29, 933, -+ /* 1560 */ 279, 504, 1074, 518, 240, 96, 96, 242, 243, 519, -+ /* 1570 */ 1134, 1129, 97, 154, 402, 517, 516, 372, 373, 923, -+ /* 1580 */ 933, 142, 143, 128, 1381, 267, 96, 96, 852, 757, -+ /* 1590 */ 203, 144, 403, 97, 1382, 402, 517, 516, 204, 1380, -+ /* 1600 */ 923, 146, 1379, 1159, 1158, 71, 1156, 276, 202, 185, -+ /* 1610 */ 923, 923, 925, 926, 24, 198, 257, 126, 991, 989, -+ /* 1620 */ 907, 98, 507, 156, 4, 145, 158, 206, 831, 209, -+ /* 1630 */ 291, 923, 923, 925, 926, 24, 1005, 911, 510, 164, -+ /* 1640 */ 147, 380, 371, 382, 166, 76, 77, 274, 506, 148, -+ /* 1650 */ 78, 79, 1008, 211, 212, 1004, 137, 213, 18, 300, -+ /* 1660 */ 230, 402, 997, 1109, 443, 215, 32, 170, 171, 772, -+ /* 1670 */ 409, 448, 319, 504, 219, 172, 452, 81, 19, 457, -+ /* 1680 */ 313, 20, 82, 268, 488, 150, 810, 179, 83, 487, -+ /* 1690 */ 464, 151, 933, 180, 959, 84, 1040, 34, 96, 96, -+ /* 1700 */ 471, 1041, 35, 474, 193, 97, 248, 402, 517, 516, -+ /* 1710 */ 1068, 404, 923, 250, 256, 880, 229, 175, 875, 352, -+ /* 1720 */ 352, 351, 241, 349, 100, 21, 770, 22, 1054, 1056, -+ /* 1730 */ 7, 98, 507, 1045, 4, 337, 1058, 23, 974, 201, -+ /* 1740 */ 176, 280, 88, 923, 923, 925, 926, 24, 510, 279, -+ /* 1750 */ 960, 958, 962, 1014, 963, 1013, 235, 234, 25, 36, -+ /* 1760 */ 99, 90, 507, 928, 4, 511, 350, 782, 26, 841, -+ /* 1770 */ 236, 402, 347, 1069, 237, 1125, 1125, 1451, 510, 203, -+ /* 1780 */ 1450, 1125, 1125, 504, 1125, 1125, 1125, 204, 1125, 1125, -+ /* 1790 */ 146, 1125, 1125, 1125, 1125, 1125, 1125, 202, 1125, 1125, -+ /* 1800 */ 1125, 402, 933, 1125, 1125, 1125, 1125, 1125, 96, 96, -+ /* 1810 */ 1125, 1125, 1125, 504, 1125, 97, 1125, 402, 517, 516, -+ /* 1820 */ 1125, 1125, 923, 1125, 1125, 1125, 1125, 1125, 1125, 1125, -+ /* 1830 */ 1125, 371, 933, 1125, 1125, 1125, 274, 506, 96, 96, -+ /* 1840 */ 1125, 1125, 1125, 1125, 1125, 97, 1125, 402, 517, 516, -+ /* 1850 */ 1125, 1125, 923, 923, 923, 925, 926, 24, 1125, 409, -+ /* 1860 */ 1125, 1125, 1125, 256, 1125, 1125, 1125, 1125, 352, 352, -+ /* 1870 */ 351, 241, 349, 1125, 1125, 770, 1125, 1125, 1125, 1125, -+ /* 1880 */ 1125, 1125, 1125, 923, 923, 925, 926, 24, 201, 1125, -+ /* 1890 */ 280, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 279, 1125, -+ /* 1900 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, -+ /* 1910 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, -+ /* 1920 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 203, 1125, -+ /* 1930 */ 1125, 1125, 1125, 1125, 1125, 1125, 204, 1125, 1125, 146, -+ /* 1940 */ 1125, 1125, 1125, 1125, 1125, 1125, 202, 1125, 1125, 1125, -+ /* 1950 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, -+ /* 1960 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, -+ /* 1970 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, -+ /* 1980 */ 371, 1125, 1125, 1125, 1125, 274, 506, 1125, 1125, 1125, -+ /* 1990 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, -+ /* 2000 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 409, - }; - static const YYCODETYPE yy_lookahead[] = { -- /* 0 */ 19, 115, 19, 117, 118, 24, 1, 2, 27, 79, -- /* 10 */ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, -- /* 20 */ 90, 91, 92, 93, 94, 144, 145, 146, 147, 58, -- /* 30 */ 49, 50, 79, 80, 81, 82, 22, 84, 85, 86, -- /* 40 */ 87, 88, 89, 90, 91, 92, 93, 94, 221, 222, -- /* 50 */ 223, 70, 71, 72, 73, 74, 75, 76, 77, 78, -- /* 60 */ 79, 80, 81, 82, 94, 84, 85, 86, 87, 88, -- /* 70 */ 89, 90, 91, 92, 93, 94, 19, 94, 97, 108, -- /* 80 */ 109, 110, 99, 100, 101, 102, 103, 104, 105, 32, -- /* 90 */ 119, 120, 78, 27, 152, 112, 93, 94, 41, 88, -- /* 100 */ 89, 90, 91, 92, 93, 94, 49, 50, 84, 85, -- /* 110 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 58, -- /* 120 */ 157, 119, 120, 163, 68, 163, 65, 70, 71, 72, -- /* 130 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, -- /* 140 */ 152, 84, 85, 86, 87, 88, 89, 90, 91, 92, -- /* 150 */ 93, 94, 19, 97, 88, 89, 196, 101, 196, 26, -- /* 160 */ 172, 173, 96, 97, 98, 210, 100, 22, 152, 108, -- /* 170 */ 109, 110, 27, 107, 27, 109, 221, 222, 223, 219, -- /* 180 */ 238, 219, 49, 50, 152, 169, 170, 54, 132, 133, -- /* 190 */ 134, 228, 232, 171, 231, 207, 208, 237, 132, 237, -- /* 200 */ 134, 179, 19, 70, 71, 72, 73, 74, 75, 76, -- /* 210 */ 77, 78, 79, 80, 81, 82, 152, 84, 85, 86, -- /* 220 */ 87, 88, 89, 90, 91, 92, 93, 94, 27, 65, -- /* 230 */ 30, 152, 49, 50, 34, 52, 90, 91, 92, 93, -- /* 240 */ 94, 96, 97, 98, 97, 22, 230, 27, 48, 217, -- /* 250 */ 27, 172, 173, 70, 71, 72, 73, 74, 75, 76, -- /* 260 */ 77, 78, 79, 80, 81, 82, 172, 84, 85, 86, -- /* 270 */ 87, 88, 89, 90, 91, 92, 93, 94, 19, 148, -- /* 280 */ 149, 152, 218, 24, 152, 154, 207, 156, 172, 152, -- /* 290 */ 22, 68, 27, 152, 163, 27, 164, 96, 97, 98, -- /* 300 */ 99, 172, 173, 102, 103, 104, 169, 170, 49, 50, -- /* 310 */ 90, 88, 89, 152, 113, 186, 96, 97, 98, 96, -- /* 320 */ 97, 160, 57, 27, 101, 164, 137, 196, 139, 70, -- /* 330 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, -- /* 340 */ 81, 82, 11, 84, 85, 86, 87, 88, 89, 90, -- /* 350 */ 91, 92, 93, 94, 19, 132, 133, 134, 23, 218, -- /* 360 */ 152, 96, 97, 98, 96, 97, 98, 230, 99, 22, -- /* 370 */ 152, 102, 103, 104, 27, 244, 152, 152, 27, 26, -- /* 380 */ 152, 22, 113, 65, 49, 50, 27, 194, 195, 58, -- /* 390 */ 172, 173, 96, 97, 98, 185, 65, 172, 173, 206, -- /* 400 */ 172, 173, 190, 191, 186, 70, 71, 72, 73, 74, -- /* 410 */ 75, 76, 77, 78, 79, 80, 81, 82, 175, 84, -- /* 420 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, -- /* 430 */ 19, 175, 207, 208, 23, 207, 208, 119, 120, 108, -- /* 440 */ 109, 110, 27, 96, 97, 98, 116, 96, 97, 98, -- /* 450 */ 152, 121, 152, 179, 180, 96, 97, 98, 250, 106, -- /* 460 */ 49, 50, 188, 19, 221, 222, 223, 168, 169, 170, -- /* 470 */ 172, 173, 172, 173, 250, 124, 172, 221, 222, 223, -- /* 480 */ 26, 70, 71, 72, 73, 74, 75, 76, 77, 78, -- /* 490 */ 79, 80, 81, 82, 50, 84, 85, 86, 87, 88, -- /* 500 */ 89, 90, 91, 92, 93, 94, 19, 207, 208, 12, -- /* 510 */ 23, 96, 97, 98, 221, 222, 223, 194, 195, 152, -- /* 520 */ 199, 23, 19, 225, 26, 28, 152, 152, 152, 206, -- /* 530 */ 209, 164, 190, 191, 241, 152, 49, 50, 152, 124, -- /* 540 */ 152, 44, 219, 46, 152, 21, 172, 173, 172, 173, -- /* 550 */ 183, 107, 185, 16, 163, 58, 112, 70, 71, 72, -- /* 560 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, -- /* 570 */ 152, 84, 85, 86, 87, 88, 89, 90, 91, 92, -- /* 580 */ 93, 94, 19, 207, 130, 152, 23, 196, 64, 152, -- /* 590 */ 172, 173, 22, 152, 24, 152, 98, 27, 61, 96, -- /* 600 */ 63, 26, 211, 212, 186, 172, 173, 49, 50, 172, -- /* 610 */ 173, 23, 49, 50, 26, 172, 173, 88, 89, 186, -- /* 620 */ 24, 238, 124, 27, 238, 22, 23, 103, 187, 26, -- /* 630 */ 152, 73, 74, 70, 71, 72, 73, 74, 75, 76, -- /* 640 */ 77, 78, 79, 80, 81, 82, 152, 84, 85, 86, -- /* 650 */ 87, 88, 89, 90, 91, 92, 93, 94, 19, 101, -- /* 660 */ 152, 132, 23, 134, 140, 152, 12, 97, 36, 168, -- /* 670 */ 169, 170, 69, 98, 152, 22, 23, 140, 50, 26, -- /* 680 */ 172, 173, 28, 51, 152, 172, 173, 193, 49, 50, -- /* 690 */ 22, 59, 24, 97, 172, 173, 152, 152, 44, 124, -- /* 700 */ 46, 0, 1, 2, 172, 173, 22, 23, 19, 70, -- /* 710 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, -- /* 720 */ 81, 82, 69, 84, 85, 86, 87, 88, 89, 90, -- /* 730 */ 91, 92, 93, 94, 152, 107, 152, 193, 49, 50, -- /* 740 */ 181, 22, 23, 111, 108, 109, 110, 7, 8, 9, -- /* 750 */ 16, 247, 248, 69, 172, 173, 172, 173, 152, 70, -- /* 760 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, -- /* 770 */ 81, 82, 152, 84, 85, 86, 87, 88, 89, 90, -- /* 780 */ 91, 92, 93, 94, 19, 152, 242, 152, 69, 152, -- /* 790 */ 166, 167, 172, 173, 32, 61, 152, 63, 152, 193, -- /* 800 */ 152, 152, 152, 41, 152, 172, 173, 172, 173, 172, -- /* 810 */ 173, 152, 152, 152, 49, 50, 172, 173, 172, 173, -- /* 820 */ 172, 173, 172, 173, 172, 173, 132, 138, 134, 152, -- /* 830 */ 152, 172, 173, 172, 173, 70, 71, 72, 73, 74, -- /* 840 */ 75, 76, 77, 78, 79, 80, 81, 82, 152, 84, -- /* 850 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, -- /* 860 */ 19, 152, 22, 152, 195, 24, 152, 27, 172, 173, -- /* 870 */ 193, 193, 152, 152, 152, 206, 152, 217, 152, 152, -- /* 880 */ 152, 172, 173, 172, 173, 152, 172, 173, 152, 152, -- /* 890 */ 49, 50, 172, 173, 172, 173, 172, 173, 172, 173, -- /* 900 */ 172, 173, 152, 138, 152, 172, 173, 108, 109, 110, -- /* 910 */ 19, 70, 71, 72, 73, 74, 75, 76, 77, 78, -- /* 920 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88, -- /* 930 */ 89, 90, 91, 92, 93, 94, 152, 97, 152, 152, -- /* 940 */ 49, 50, 26, 193, 172, 173, 152, 152, 152, 146, -- /* 950 */ 147, 132, 152, 134, 217, 181, 172, 173, 172, 173, -- /* 960 */ 19, 70, 71, 72, 73, 74, 75, 76, 77, 78, -- /* 970 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88, -- /* 980 */ 89, 90, 91, 92, 93, 94, 152, 193, 152, 193, -- /* 990 */ 49, 50, 181, 193, 172, 173, 166, 167, 245, 246, -- /* 1000 */ 211, 212, 152, 22, 217, 152, 172, 173, 172, 173, -- /* 1010 */ 19, 70, 71, 72, 73, 74, 75, 76, 77, 78, -- /* 1020 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88, -- /* 1030 */ 89, 90, 91, 92, 93, 94, 152, 187, 152, 123, -- /* 1040 */ 49, 50, 23, 23, 23, 26, 26, 26, 23, 23, -- /* 1050 */ 23, 26, 26, 26, 7, 8, 172, 173, 172, 173, -- /* 1060 */ 19, 90, 71, 72, 73, 74, 75, 76, 77, 78, -- /* 1070 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88, -- /* 1080 */ 89, 90, 91, 92, 93, 94, 152, 116, 152, 217, -- /* 1090 */ 49, 50, 121, 23, 172, 173, 26, 100, 101, 27, -- /* 1100 */ 101, 27, 23, 122, 152, 26, 172, 173, 172, 173, -- /* 1110 */ 152, 112, 163, 72, 73, 74, 75, 76, 77, 78, -- /* 1120 */ 79, 80, 81, 82, 163, 84, 85, 86, 87, 88, -- /* 1130 */ 89, 90, 91, 92, 93, 94, 19, 20, 152, 22, -- /* 1140 */ 23, 152, 163, 65, 27, 196, 163, 19, 20, 23, -- /* 1150 */ 22, 213, 26, 19, 37, 27, 152, 196, 172, 173, -- /* 1160 */ 152, 172, 173, 27, 23, 37, 152, 26, 152, 97, -- /* 1170 */ 152, 97, 210, 56, 163, 196, 163, 163, 100, 196, -- /* 1180 */ 172, 173, 65, 152, 56, 68, 172, 173, 172, 173, -- /* 1190 */ 172, 173, 152, 65, 163, 163, 68, 23, 152, 234, -- /* 1200 */ 26, 152, 152, 172, 173, 88, 89, 196, 152, 196, -- /* 1210 */ 196, 152, 95, 96, 97, 98, 88, 89, 101, 152, -- /* 1220 */ 152, 207, 208, 95, 96, 97, 98, 196, 196, 101, -- /* 1230 */ 96, 233, 152, 97, 152, 152, 19, 20, 207, 22, -- /* 1240 */ 152, 152, 152, 191, 27, 152, 152, 152, 152, 132, -- /* 1250 */ 133, 134, 135, 136, 37, 152, 152, 152, 152, 152, -- /* 1260 */ 132, 133, 134, 135, 136, 210, 197, 210, 210, 198, -- /* 1270 */ 150, 184, 239, 56, 201, 214, 214, 201, 239, 180, -- /* 1280 */ 214, 227, 198, 38, 176, 68, 175, 175, 175, 122, -- /* 1290 */ 155, 200, 159, 19, 20, 40, 22, 159, 159, 22, -- /* 1300 */ 70, 27, 130, 243, 240, 88, 89, 90, 189, 18, -- /* 1310 */ 201, 37, 95, 96, 97, 98, 192, 5, 101, 192, -- /* 1320 */ 220, 240, 10, 11, 12, 13, 14, 159, 18, 17, -- /* 1330 */ 56, 158, 192, 201, 192, 220, 189, 189, 201, 159, -- /* 1340 */ 158, 137, 68, 31, 45, 33, 236, 159, 159, 132, -- /* 1350 */ 133, 134, 135, 136, 42, 158, 235, 22, 177, 159, -- /* 1360 */ 158, 158, 88, 89, 159, 107, 174, 55, 177, 95, -- /* 1370 */ 96, 97, 98, 174, 62, 101, 47, 65, 66, 106, -- /* 1380 */ 174, 125, 19, 20, 174, 22, 177, 176, 174, 182, -- /* 1390 */ 27, 216, 174, 174, 182, 107, 159, 22, 215, 215, -- /* 1400 */ 37, 216, 216, 216, 137, 215, 132, 133, 134, 135, -- /* 1410 */ 136, 215, 159, 177, 94, 177, 129, 224, 205, 56, -- /* 1420 */ 226, 126, 128, 203, 229, 204, 114, 229, 127, 202, -- /* 1430 */ 201, 68, 25, 162, 26, 13, 161, 153, 153, 6, -- /* 1440 */ 151, 151, 178, 151, 165, 165, 178, 165, 4, 3, -- /* 1450 */ 249, 88, 89, 141, 22, 142, 15, 249, 95, 96, -- /* 1460 */ 97, 98, 246, 67, 101, 16, 23, 120, 23, 131, -- /* 1470 */ 111, 123, 20, 16, 125, 1, 123, 131, 78, 78, -- /* 1480 */ 78, 78, 111, 96, 122, 35, 1, 5, 22, 107, -- /* 1490 */ 140, 53, 53, 26, 60, 132, 133, 134, 135, 136, -- /* 1500 */ 107, 43, 24, 20, 112, 19, 22, 52, 52, 105, -- /* 1510 */ 22, 22, 52, 23, 22, 22, 29, 23, 39, 23, -- /* 1520 */ 23, 26, 116, 22, 26, 23, 22, 122, 23, 23, -- /* 1530 */ 22, 96, 11, 124, 35, 26, 26, 23, 35, 23, -- /* 1540 */ 23, 23, 35, 23, 22, 26, 23, 22, 24, 122, -- /* 1550 */ 23, 22, 26, 22, 24, 23, 23, 23, 22, 122, -- /* 1560 */ 23, 15, 122, 1, 122, -+ /* 0 */ 184, 238, 239, 240, 238, 239, 240, 163, 155, 156, -+ /* 10 */ 157, 158, 159, 160, 163, 191, 192, 183, 165, 19, -+ /* 20 */ 167, 258, 202, 203, 200, 191, 163, 174, 184, 185, -+ /* 30 */ 174, 31, 163, 163, 171, 184, 185, 35, 175, 39, -+ /* 40 */ 179, 180, 181, 43, 44, 45, 46, 47, 48, 49, -+ /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 184, 206, -+ /* 60 */ 207, 163, 206, 207, 220, 163, 16, 163, 66, 163, -+ /* 70 */ 59, 270, 219, 229, 273, 219, 74, 208, 174, 223, -+ /* 80 */ 224, 163, 184, 185, 163, 232, 184, 185, 184, 185, -+ /* 90 */ 184, 185, 92, 93, 94, 95, 96, 97, 98, 99, -+ /* 100 */ 100, 101, 102, 233, 198, 184, 185, 96, 97, 163, -+ /* 110 */ 206, 207, 19, 163, 261, 104, 105, 106, 107, 198, -+ /* 120 */ 109, 119, 220, 219, 220, 274, 275, 77, 117, 79, -+ /* 130 */ 187, 229, 19, 229, 184, 185, 43, 44, 45, 46, -+ /* 140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, -+ /* 150 */ 57, 233, 141, 134, 143, 102, 43, 44, 45, 46, -+ /* 160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, -+ /* 170 */ 57, 152, 274, 216, 276, 218, 83, 163, 85, 233, -+ /* 180 */ 67, 238, 239, 240, 11, 92, 93, 94, 95, 96, -+ /* 190 */ 97, 98, 99, 100, 101, 102, 19, 54, 55, 56, -+ /* 200 */ 57, 58, 163, 26, 163, 92, 93, 94, 95, 96, -+ /* 210 */ 97, 98, 99, 100, 101, 102, 54, 55, 56, 57, -+ /* 220 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, -+ /* 230 */ 53, 54, 55, 56, 57, 92, 93, 94, 95, 96, -+ /* 240 */ 97, 98, 99, 100, 101, 102, 69, 96, 97, 98, -+ /* 250 */ 99, 100, 101, 102, 92, 93, 94, 95, 96, 97, -+ /* 260 */ 98, 99, 100, 101, 102, 81, 179, 180, 181, 92, -+ /* 270 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, -+ /* 280 */ 163, 267, 268, 163, 22, 23, 59, 163, 26, 19, -+ /* 290 */ 117, 118, 175, 109, 24, 59, 92, 93, 94, 95, -+ /* 300 */ 96, 97, 98, 99, 100, 101, 102, 268, 184, 185, -+ /* 310 */ 269, 127, 128, 43, 44, 45, 46, 47, 48, 49, -+ /* 320 */ 50, 51, 52, 53, 54, 55, 56, 57, 157, 158, -+ /* 330 */ 159, 160, 105, 106, 107, 163, 165, 59, 167, 184, -+ /* 340 */ 90, 105, 106, 107, 108, 174, 73, 111, 112, 113, -+ /* 350 */ 19, 22, 163, 91, 81, 163, 106, 121, 81, 132, -+ /* 360 */ 110, 16, 92, 93, 94, 95, 96, 97, 98, 99, -+ /* 370 */ 100, 101, 102, 184, 185, 255, 98, 206, 207, 26, -+ /* 380 */ 101, 102, 19, 105, 106, 107, 23, 198, 59, 116, -+ /* 390 */ 219, 141, 142, 143, 24, 163, 187, 205, 274, 275, -+ /* 400 */ 127, 128, 182, 232, 127, 128, 43, 44, 45, 46, -+ /* 410 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, -+ /* 420 */ 57, 158, 77, 160, 79, 59, 26, 182, 165, 59, -+ /* 430 */ 167, 199, 261, 102, 105, 106, 107, 174, 72, 108, -+ /* 440 */ 109, 110, 111, 112, 113, 114, 59, 238, 239, 240, -+ /* 450 */ 123, 120, 125, 126, 163, 92, 93, 94, 95, 96, -+ /* 460 */ 97, 98, 99, 100, 101, 102, 163, 163, 163, 206, -+ /* 470 */ 207, 105, 106, 107, 254, 19, 106, 90, 197, 23, -+ /* 480 */ 127, 128, 219, 238, 239, 240, 22, 184, 185, 184, -+ /* 490 */ 185, 22, 105, 106, 149, 232, 205, 110, 163, 43, -+ /* 500 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, -+ /* 510 */ 54, 55, 56, 57, 98, 99, 100, 101, 102, 184, -+ /* 520 */ 185, 163, 53, 59, 261, 220, 117, 118, 141, 142, -+ /* 530 */ 143, 131, 174, 59, 229, 116, 117, 118, 163, 59, -+ /* 540 */ 163, 163, 184, 185, 59, 242, 72, 22, 92, 93, -+ /* 550 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 184, -+ /* 560 */ 185, 24, 184, 185, 206, 207, 202, 203, 19, 105, -+ /* 570 */ 106, 107, 23, 198, 22, 174, 198, 219, 220, 105, -+ /* 580 */ 106, 107, 96, 97, 59, 105, 106, 107, 22, 174, -+ /* 590 */ 59, 106, 43, 44, 45, 46, 47, 48, 49, 50, -+ /* 600 */ 51, 52, 53, 54, 55, 56, 57, 206, 207, 12, -+ /* 610 */ 108, 59, 132, 111, 112, 113, 46, 47, 48, 49, -+ /* 620 */ 219, 206, 207, 121, 27, 59, 163, 141, 207, 143, -+ /* 630 */ 105, 106, 107, 163, 219, 234, 105, 106, 107, 42, -+ /* 640 */ 219, 92, 93, 94, 95, 96, 97, 98, 99, 100, -+ /* 650 */ 101, 102, 76, 163, 184, 185, 163, 105, 106, 107, -+ /* 660 */ 63, 19, 86, 163, 163, 23, 163, 130, 205, 21, -+ /* 670 */ 73, 105, 106, 107, 184, 185, 163, 184, 185, 237, -+ /* 680 */ 110, 180, 181, 180, 181, 43, 44, 45, 46, 47, -+ /* 690 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -+ /* 700 */ 174, 163, 163, 22, 23, 163, 163, 26, 22, 23, -+ /* 710 */ 220, 29, 73, 220, 272, 33, 22, 163, 24, 19, -+ /* 720 */ 174, 208, 259, 184, 185, 19, 184, 185, 80, 175, -+ /* 730 */ 230, 174, 206, 207, 92, 93, 94, 95, 96, 97, -+ /* 740 */ 98, 99, 100, 101, 102, 219, 46, 65, 247, 195, -+ /* 750 */ 247, 197, 206, 207, 19, 116, 117, 118, 23, 220, -+ /* 760 */ 112, 174, 220, 206, 207, 219, 22, 174, 24, 174, -+ /* 770 */ 22, 23, 91, 264, 265, 168, 219, 91, 43, 44, -+ /* 780 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, -+ /* 790 */ 55, 56, 57, 206, 207, 12, 163, 149, 255, 206, -+ /* 800 */ 207, 206, 207, 59, 104, 23, 219, 163, 26, 163, -+ /* 810 */ 27, 105, 219, 163, 219, 163, 211, 184, 185, 163, -+ /* 820 */ 120, 163, 146, 163, 148, 42, 221, 92, 93, 94, -+ /* 830 */ 95, 96, 97, 98, 99, 100, 101, 102, 163, 91, -+ /* 840 */ 184, 185, 184, 185, 184, 185, 63, 19, 163, 205, -+ /* 850 */ 106, 23, 245, 163, 208, 248, 116, 117, 118, 184, -+ /* 860 */ 185, 163, 163, 7, 8, 9, 163, 19, 26, 184, -+ /* 870 */ 185, 43, 44, 45, 46, 47, 48, 49, 50, 51, -+ /* 880 */ 52, 53, 54, 55, 56, 57, 163, 184, 185, 107, -+ /* 890 */ 163, 43, 44, 45, 46, 47, 48, 49, 50, 51, -+ /* 900 */ 52, 53, 54, 55, 56, 57, 208, 255, 177, 178, -+ /* 910 */ 163, 184, 185, 163, 132, 163, 141, 163, 143, 22, -+ /* 920 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, -+ /* 930 */ 102, 184, 185, 163, 184, 185, 184, 185, 184, 185, -+ /* 940 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, -+ /* 950 */ 102, 163, 163, 163, 184, 185, 163, 115, 163, 163, -+ /* 960 */ 163, 163, 15, 163, 163, 163, 163, 163, 23, 163, -+ /* 970 */ 163, 26, 184, 185, 184, 185, 163, 184, 185, 184, -+ /* 980 */ 185, 184, 185, 163, 184, 185, 184, 185, 184, 185, -+ /* 990 */ 184, 185, 163, 96, 97, 147, 163, 184, 185, 163, -+ /* 1000 */ 199, 163, 163, 205, 184, 185, 163, 60, 163, 141, -+ /* 1010 */ 163, 143, 163, 184, 185, 19, 163, 184, 185, 230, -+ /* 1020 */ 184, 185, 184, 185, 206, 207, 230, 184, 185, 184, -+ /* 1030 */ 185, 184, 185, 184, 185, 19, 163, 219, 231, 43, -+ /* 1040 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, -+ /* 1050 */ 54, 55, 56, 57, 163, 26, 163, 184, 185, 43, -+ /* 1060 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, -+ /* 1070 */ 54, 55, 56, 57, 163, 184, 185, 184, 185, 163, -+ /* 1080 */ 182, 163, 163, 163, 163, 163, 22, 163, 92, 93, -+ /* 1090 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 163, -+ /* 1100 */ 184, 185, 184, 185, 163, 184, 185, 163, 92, 93, -+ /* 1110 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 163, -+ /* 1120 */ 184, 185, 98, 59, 163, 184, 185, 205, 184, 185, -+ /* 1130 */ 23, 206, 207, 26, 163, 26, 107, 153, 154, 237, -+ /* 1140 */ 184, 185, 231, 147, 219, 184, 185, 249, 124, 127, -+ /* 1150 */ 128, 231, 254, 129, 163, 231, 177, 178, 262, 263, -+ /* 1160 */ 118, 132, 19, 19, 46, 223, 224, 31, 24, 23, -+ /* 1170 */ 106, 124, 26, 22, 272, 39, 129, 23, 109, 110, -+ /* 1180 */ 26, 163, 140, 19, 22, 234, 59, 43, 44, 45, -+ /* 1190 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, -+ /* 1200 */ 56, 57, 231, 7, 8, 193, 59, 43, 44, 45, -+ /* 1210 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, -+ /* 1220 */ 56, 57, 104, 61, 23, 23, 23, 26, 26, 26, -+ /* 1230 */ 163, 23, 23, 106, 26, 26, 92, 93, 94, 95, -+ /* 1240 */ 96, 97, 98, 99, 100, 101, 102, 138, 105, 23, -+ /* 1250 */ 59, 23, 26, 106, 26, 163, 92, 93, 94, 95, -+ /* 1260 */ 96, 97, 98, 99, 100, 101, 102, 110, 23, 23, -+ /* 1270 */ 23, 26, 26, 26, 163, 163, 19, 120, 163, 163, -+ /* 1280 */ 163, 130, 163, 163, 163, 163, 163, 163, 163, 193, -+ /* 1290 */ 193, 163, 163, 163, 163, 225, 19, 106, 163, 222, -+ /* 1300 */ 163, 44, 45, 46, 47, 48, 49, 50, 51, 52, -+ /* 1310 */ 53, 54, 55, 56, 57, 163, 163, 203, 163, 163, -+ /* 1320 */ 222, 163, 45, 46, 47, 48, 49, 50, 51, 52, -+ /* 1330 */ 53, 54, 55, 56, 57, 163, 163, 163, 163, 163, -+ /* 1340 */ 251, 250, 209, 19, 20, 182, 22, 161, 222, 92, -+ /* 1350 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, -+ /* 1360 */ 36, 222, 222, 260, 226, 188, 256, 226, 187, 92, -+ /* 1370 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, -+ /* 1380 */ 210, 213, 213, 59, 213, 196, 192, 187, 256, 244, -+ /* 1390 */ 212, 187, 226, 19, 20, 71, 22, 210, 166, 60, -+ /* 1400 */ 130, 170, 260, 170, 38, 81, 257, 257, 170, 104, -+ /* 1410 */ 36, 22, 43, 201, 90, 236, 138, 235, 213, 18, -+ /* 1420 */ 96, 97, 48, 204, 204, 204, 204, 103, 170, 105, -+ /* 1430 */ 106, 107, 18, 59, 110, 169, 213, 213, 201, 170, -+ /* 1440 */ 201, 169, 236, 213, 146, 71, 235, 62, 253, 252, -+ /* 1450 */ 170, 127, 128, 169, 22, 170, 82, 189, 169, 104, -+ /* 1460 */ 170, 87, 169, 189, 90, 141, 142, 143, 144, 145, -+ /* 1470 */ 96, 97, 186, 186, 186, 64, 194, 103, 186, 105, -+ /* 1480 */ 106, 107, 115, 189, 110, 188, 186, 186, 19, 20, -+ /* 1490 */ 194, 22, 186, 189, 102, 246, 246, 189, 133, 228, -+ /* 1500 */ 104, 228, 227, 227, 170, 36, 134, 228, 227, 19, -+ /* 1510 */ 20, 228, 22, 84, 271, 141, 142, 143, 144, 145, -+ /* 1520 */ 0, 1, 2, 216, 22, 5, 36, 137, 59, 227, -+ /* 1530 */ 10, 11, 12, 13, 14, 217, 269, 17, 216, 22, -+ /* 1540 */ 71, 170, 243, 146, 241, 217, 136, 215, 135, 59, -+ /* 1550 */ 30, 82, 32, 25, 214, 213, 87, 173, 26, 90, -+ /* 1560 */ 40, 71, 13, 172, 164, 96, 97, 164, 6, 162, -+ /* 1570 */ 162, 162, 103, 263, 105, 106, 107, 266, 266, 110, -+ /* 1580 */ 90, 176, 176, 190, 182, 190, 96, 97, 98, 4, -+ /* 1590 */ 70, 176, 3, 103, 182, 105, 106, 107, 78, 182, -+ /* 1600 */ 110, 81, 182, 182, 182, 182, 182, 151, 88, 22, -+ /* 1610 */ 141, 142, 143, 144, 145, 15, 89, 16, 23, 23, -+ /* 1620 */ 128, 19, 20, 139, 22, 119, 131, 24, 20, 133, -+ /* 1630 */ 16, 141, 142, 143, 144, 145, 1, 140, 36, 131, -+ /* 1640 */ 119, 61, 122, 37, 139, 53, 53, 127, 128, 119, -+ /* 1650 */ 53, 53, 105, 34, 130, 1, 5, 104, 22, 149, -+ /* 1660 */ 26, 59, 68, 75, 41, 130, 24, 68, 104, 20, -+ /* 1670 */ 150, 19, 120, 71, 114, 22, 67, 22, 22, 67, -+ /* 1680 */ 23, 22, 22, 67, 82, 37, 28, 23, 138, 87, -+ /* 1690 */ 22, 153, 90, 23, 23, 26, 23, 22, 96, 97, -+ /* 1700 */ 24, 23, 22, 24, 130, 103, 23, 105, 106, 107, -+ /* 1710 */ 1, 2, 110, 23, 5, 105, 34, 22, 132, 10, -+ /* 1720 */ 11, 12, 13, 14, 26, 34, 17, 34, 85, 83, -+ /* 1730 */ 44, 19, 20, 23, 22, 24, 75, 34, 23, 30, -+ /* 1740 */ 26, 32, 26, 141, 142, 143, 144, 145, 36, 40, -+ /* 1750 */ 23, 23, 23, 23, 11, 23, 22, 26, 22, 22, -+ /* 1760 */ 22, 19, 20, 23, 22, 26, 15, 23, 22, 124, -+ /* 1770 */ 130, 59, 23, 1, 130, 277, 277, 130, 36, 70, -+ /* 1780 */ 130, 277, 277, 71, 277, 277, 277, 78, 277, 277, -+ /* 1790 */ 81, 277, 277, 277, 277, 277, 277, 88, 277, 277, -+ /* 1800 */ 277, 59, 90, 277, 277, 277, 277, 277, 96, 97, -+ /* 1810 */ 277, 277, 277, 71, 277, 103, 277, 105, 106, 107, -+ /* 1820 */ 277, 277, 110, 277, 277, 277, 277, 277, 277, 277, -+ /* 1830 */ 277, 122, 90, 277, 277, 277, 127, 128, 96, 97, -+ /* 1840 */ 277, 277, 277, 277, 277, 103, 277, 105, 106, 107, -+ /* 1850 */ 277, 277, 110, 141, 142, 143, 144, 145, 277, 150, -+ /* 1860 */ 277, 277, 277, 5, 277, 277, 277, 277, 10, 11, -+ /* 1870 */ 12, 13, 14, 277, 277, 17, 277, 277, 277, 277, -+ /* 1880 */ 277, 277, 277, 141, 142, 143, 144, 145, 30, 277, -+ /* 1890 */ 32, 277, 277, 277, 277, 277, 277, 277, 40, 277, -+ /* 1900 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, -+ /* 1910 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, -+ /* 1920 */ 277, 277, 277, 277, 277, 277, 277, 277, 70, 277, -+ /* 1930 */ 277, 277, 277, 277, 277, 277, 78, 277, 277, 81, -+ /* 1940 */ 277, 277, 277, 277, 277, 277, 88, 277, 277, 277, -+ /* 1950 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, -+ /* 1960 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, -+ /* 1970 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, -+ /* 1980 */ 122, 277, 277, 277, 277, 127, 128, 277, 277, 277, -+ /* 1990 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, -+ /* 2000 */ 277, 277, 277, 277, 277, 277, 277, 277, 150, 277, -+ /* 2010 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, - }; --#define YY_SHIFT_USE_DFLT (1565) --#define YY_SHIFT_COUNT (454) --#define YY_SHIFT_MIN (-114) --#define YY_SHIFT_MAX (1562) --static const short yy_shift_ofst[] = { -- /* 0 */ 5, 1117, 1312, 1128, 1274, 1274, 1274, 1274, 61, -19, -- /* 10 */ 57, 57, 183, 1274, 1274, 1274, 1274, 1274, 1274, 1274, -- /* 20 */ 66, 66, 201, -29, 331, 318, 133, 259, 335, 411, -- /* 30 */ 487, 563, 639, 689, 765, 841, 891, 891, 891, 891, -- /* 40 */ 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, -- /* 50 */ 891, 891, 891, 941, 891, 991, 1041, 1041, 1217, 1274, -- /* 60 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, -- /* 70 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, -- /* 80 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, -- /* 90 */ 1363, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, -- /* 100 */ 1274, 1274, 1274, 1274, -70, -47, -47, -47, -47, -47, -- /* 110 */ 24, 11, 146, 296, 524, 444, 529, 529, 296, 3, -- /* 120 */ 2, -30, 1565, 1565, 1565, -17, -17, -17, 145, 145, -- /* 130 */ 497, 497, 265, 603, 653, 296, 296, 296, 296, 296, -- /* 140 */ 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, -- /* 150 */ 296, 296, 296, 296, 296, 701, 1078, 147, 147, 2, -- /* 160 */ 164, 164, 164, 164, 164, 164, 1565, 1565, 1565, 223, -- /* 170 */ 56, 56, 268, 269, 220, 347, 351, 415, 359, 296, -- /* 180 */ 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, -- /* 190 */ 296, 296, 296, 296, 296, 632, 632, 632, 296, 296, -- /* 200 */ 498, 296, 296, 296, 570, 296, 296, 654, 296, 296, -- /* 210 */ 296, 296, 296, 296, 296, 296, 296, 296, 636, 200, -- /* 220 */ 596, 596, 596, 575, -114, 971, 740, 454, 503, 503, -- /* 230 */ 1134, 454, 1134, 353, 588, 628, 762, 503, 189, 762, -- /* 240 */ 762, 916, 330, 668, 1245, 1167, 1167, 1255, 1255, 1167, -- /* 250 */ 1277, 1230, 1172, 1291, 1291, 1291, 1291, 1167, 1310, 1172, -- /* 260 */ 1277, 1230, 1230, 1172, 1167, 1310, 1204, 1299, 1167, 1167, -- /* 270 */ 1310, 1335, 1167, 1310, 1167, 1310, 1335, 1258, 1258, 1258, -- /* 280 */ 1329, 1335, 1258, 1273, 1258, 1329, 1258, 1258, 1256, 1288, -- /* 290 */ 1256, 1288, 1256, 1288, 1256, 1288, 1167, 1375, 1167, 1267, -- /* 300 */ 1335, 1320, 1320, 1335, 1287, 1295, 1294, 1301, 1172, 1407, -- /* 310 */ 1408, 1422, 1422, 1433, 1433, 1433, 1565, 1565, 1565, 1565, -- /* 320 */ 1565, 1565, 1565, 1565, 558, 537, 684, 719, 734, 799, -- /* 330 */ 840, 1019, 14, 1020, 1021, 1025, 1026, 1027, 1070, 1072, -- /* 340 */ 997, 1047, 999, 1079, 1126, 1074, 1141, 694, 819, 1174, -- /* 350 */ 1136, 981, 1444, 1446, 1432, 1313, 1441, 1396, 1449, 1443, -- /* 360 */ 1445, 1347, 1338, 1359, 1348, 1452, 1349, 1457, 1474, 1353, -- /* 370 */ 1346, 1400, 1401, 1402, 1403, 1371, 1387, 1450, 1362, 1485, -- /* 380 */ 1482, 1466, 1382, 1350, 1438, 1467, 1439, 1434, 1458, 1393, -- /* 390 */ 1478, 1483, 1486, 1392, 1404, 1484, 1455, 1488, 1489, 1490, -- /* 400 */ 1492, 1456, 1487, 1493, 1460, 1479, 1494, 1496, 1497, 1495, -- /* 410 */ 1406, 1501, 1502, 1504, 1498, 1405, 1505, 1506, 1435, 1499, -- /* 420 */ 1508, 1409, 1509, 1503, 1510, 1507, 1514, 1509, 1516, 1517, -- /* 430 */ 1518, 1519, 1520, 1522, 1521, 1523, 1525, 1524, 1526, 1527, -- /* 440 */ 1529, 1530, 1526, 1532, 1531, 1533, 1534, 1536, 1427, 1437, -- /* 450 */ 1440, 1442, 1537, 1546, 1562, -+#define YY_SHIFT_COUNT (520) -+#define YY_SHIFT_MIN (0) -+#define YY_SHIFT_MAX (1858) -+static const unsigned short int yy_shift_ofst[] = { -+ /* 0 */ 1709, 1520, 1858, 1324, 1324, 277, 1374, 1469, 1602, 1712, -+ /* 10 */ 1712, 1712, 273, 0, 0, 113, 1016, 1712, 1712, 1712, -+ /* 20 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 11, 11, 236, -+ /* 30 */ 184, 277, 277, 277, 277, 277, 277, 93, 177, 270, -+ /* 40 */ 363, 456, 549, 642, 735, 828, 848, 996, 1144, 1016, -+ /* 50 */ 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, -+ /* 60 */ 1016, 1016, 1016, 1016, 1016, 1016, 1164, 1016, 1257, 1277, -+ /* 70 */ 1277, 1490, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, -+ /* 80 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, -+ /* 90 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, -+ /* 100 */ 1712, 1712, 1712, 1742, 1712, 1712, 1712, 1712, 1712, 1712, -+ /* 110 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 143, 162, 162, -+ /* 120 */ 162, 162, 162, 204, 151, 416, 531, 648, 700, 531, -+ /* 130 */ 486, 486, 531, 353, 353, 353, 353, 409, 279, 53, -+ /* 140 */ 2009, 2009, 331, 331, 331, 329, 366, 329, 329, 597, -+ /* 150 */ 597, 464, 474, 262, 681, 531, 531, 531, 531, 531, -+ /* 160 */ 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, -+ /* 170 */ 531, 531, 531, 531, 531, 531, 531, 173, 485, 984, -+ /* 180 */ 984, 576, 485, 19, 1022, 2009, 2009, 2009, 387, 250, -+ /* 190 */ 250, 525, 502, 278, 552, 227, 480, 566, 531, 531, -+ /* 200 */ 531, 531, 531, 531, 531, 531, 531, 531, 639, 531, -+ /* 210 */ 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, -+ /* 220 */ 531, 2, 2, 2, 531, 531, 531, 531, 782, 531, -+ /* 230 */ 531, 531, 744, 531, 531, 783, 531, 531, 531, 531, -+ /* 240 */ 531, 531, 531, 531, 419, 682, 327, 370, 370, 370, -+ /* 250 */ 370, 1029, 327, 327, 1024, 897, 856, 947, 1109, 706, -+ /* 260 */ 706, 1143, 1109, 1109, 1143, 842, 945, 1118, 1136, 1136, -+ /* 270 */ 1136, 706, 676, 400, 1047, 694, 1339, 1270, 1270, 1366, -+ /* 280 */ 1366, 1270, 1305, 1389, 1369, 1278, 1401, 1401, 1401, 1401, -+ /* 290 */ 1270, 1414, 1278, 1278, 1305, 1389, 1369, 1369, 1278, 1270, -+ /* 300 */ 1414, 1298, 1385, 1270, 1414, 1432, 1270, 1414, 1270, 1414, -+ /* 310 */ 1432, 1355, 1355, 1355, 1411, 1432, 1355, 1367, 1355, 1411, -+ /* 320 */ 1355, 1355, 1432, 1392, 1392, 1432, 1365, 1396, 1365, 1396, -+ /* 330 */ 1365, 1396, 1365, 1396, 1270, 1372, 1429, 1502, 1390, 1372, -+ /* 340 */ 1517, 1270, 1397, 1390, 1410, 1413, 1278, 1528, 1532, 1549, -+ /* 350 */ 1549, 1562, 1562, 1562, 2009, 2009, 2009, 2009, 2009, 2009, -+ /* 360 */ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, -+ /* 370 */ 570, 345, 686, 748, 50, 740, 1064, 1107, 469, 537, -+ /* 380 */ 1042, 1146, 1162, 1154, 1201, 1202, 1203, 1208, 1209, 1127, -+ /* 390 */ 1069, 1196, 1157, 1147, 1226, 1228, 1245, 775, 868, 1246, -+ /* 400 */ 1247, 1191, 1151, 1585, 1589, 1587, 1456, 1600, 1527, 1601, -+ /* 410 */ 1595, 1596, 1492, 1484, 1506, 1603, 1495, 1608, 1496, 1614, -+ /* 420 */ 1635, 1508, 1497, 1521, 1580, 1606, 1505, 1592, 1593, 1597, -+ /* 430 */ 1598, 1530, 1547, 1619, 1524, 1654, 1651, 1636, 1553, 1510, -+ /* 440 */ 1594, 1634, 1599, 1588, 1623, 1535, 1564, 1642, 1649, 1652, -+ /* 450 */ 1552, 1560, 1653, 1609, 1655, 1656, 1657, 1659, 1612, 1658, -+ /* 460 */ 1660, 1616, 1648, 1664, 1550, 1668, 1538, 1670, 1671, 1669, -+ /* 470 */ 1673, 1675, 1676, 1678, 1680, 1679, 1574, 1683, 1690, 1610, -+ /* 480 */ 1682, 1695, 1586, 1698, 1691, 1698, 1693, 1643, 1661, 1646, -+ /* 490 */ 1686, 1710, 1711, 1714, 1716, 1703, 1715, 1698, 1727, 1728, -+ /* 500 */ 1729, 1730, 1731, 1732, 1734, 1743, 1736, 1737, 1740, 1744, -+ /* 510 */ 1738, 1746, 1739, 1645, 1640, 1644, 1647, 1650, 1749, 1751, -+ /* 520 */ 1772, - }; --#define YY_REDUCE_USE_DFLT (-174) --#define YY_REDUCE_COUNT (323) --#define YY_REDUCE_MIN (-173) --#define YY_REDUCE_MAX (1292) -+#define YY_REDUCE_COUNT (369) -+#define YY_REDUCE_MIN (-237) -+#define YY_REDUCE_MAX (1424) - static const short yy_reduce_ofst[] = { -- /* 0 */ -119, 1014, 131, 1031, -12, 225, 228, 300, -40, -45, -- /* 10 */ 243, 256, 293, 129, 218, 418, 79, 376, 433, 298, -- /* 20 */ 16, 137, 367, 323, -38, 391, -173, -173, -173, -173, -- /* 30 */ -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -- /* 40 */ -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, -- /* 50 */ -173, -173, -173, -173, -173, -173, -173, -173, 374, 437, -- /* 60 */ 443, 508, 513, 522, 532, 582, 584, 620, 633, 635, -- /* 70 */ 637, 644, 646, 648, 650, 652, 659, 661, 696, 709, -- /* 80 */ 711, 714, 720, 722, 724, 726, 728, 733, 772, 784, -- /* 90 */ 786, 822, 834, 836, 884, 886, 922, 934, 936, 986, -- /* 100 */ 989, 1008, 1016, 1018, -173, -173, -173, -173, -173, -173, -- /* 110 */ -173, -173, -173, 544, -37, 274, 299, 501, 161, -173, -- /* 120 */ 193, -173, -173, -173, -173, 22, 22, 22, 64, 141, -- /* 130 */ 212, 342, 208, 504, 504, 132, 494, 606, 677, 678, -- /* 140 */ 750, 794, 796, -58, 32, 383, 660, 737, 386, 787, -- /* 150 */ 800, 441, 872, 224, 850, 803, 949, 624, 830, 669, -- /* 160 */ 961, 979, 983, 1011, 1013, 1032, 753, 789, 321, 94, -- /* 170 */ 116, 304, 375, 210, 388, 392, 478, 545, 649, 721, -- /* 180 */ 727, 736, 752, 795, 853, 952, 958, 1004, 1040, 1046, -- /* 190 */ 1049, 1050, 1056, 1059, 1067, 559, 774, 811, 1068, 1080, -- /* 200 */ 938, 1082, 1083, 1088, 962, 1089, 1090, 1052, 1093, 1094, -- /* 210 */ 1095, 388, 1096, 1103, 1104, 1105, 1106, 1107, 965, 998, -- /* 220 */ 1055, 1057, 1058, 938, 1069, 1071, 1120, 1073, 1061, 1062, -- /* 230 */ 1033, 1076, 1039, 1108, 1087, 1099, 1111, 1066, 1054, 1112, -- /* 240 */ 1113, 1091, 1084, 1135, 1060, 1133, 1138, 1064, 1081, 1139, -- /* 250 */ 1100, 1119, 1109, 1124, 1127, 1140, 1142, 1168, 1173, 1132, -- /* 260 */ 1115, 1147, 1148, 1137, 1180, 1182, 1110, 1121, 1188, 1189, -- /* 270 */ 1197, 1181, 1200, 1202, 1205, 1203, 1191, 1192, 1199, 1206, -- /* 280 */ 1207, 1209, 1210, 1211, 1214, 1212, 1218, 1219, 1175, 1183, -- /* 290 */ 1185, 1184, 1186, 1190, 1187, 1196, 1237, 1193, 1253, 1194, -- /* 300 */ 1236, 1195, 1198, 1238, 1213, 1221, 1220, 1227, 1229, 1271, -- /* 310 */ 1275, 1284, 1285, 1289, 1290, 1292, 1201, 1208, 1216, 1279, -- /* 320 */ 1280, 1264, 1268, 1282, -+ /* 0 */ -147, 171, 263, -96, 358, -144, -149, -102, 124, -156, -+ /* 10 */ -98, 305, 401, -57, 209, -237, 245, -94, -79, 189, -+ /* 20 */ 375, 490, 493, 378, 303, 539, 542, 501, 503, 554, -+ /* 30 */ 415, 526, 546, 557, 587, 593, 595, -234, -234, -234, -+ /* 40 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -+ /* 50 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -+ /* 60 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, -+ /* 70 */ -234, -50, 335, 470, 633, 656, 658, 660, 675, 685, -+ /* 80 */ 703, 727, 747, 750, 752, 754, 770, 788, 790, 793, -+ /* 90 */ 795, 797, 800, 802, 804, 806, 813, 820, 829, 833, -+ /* 100 */ 836, 838, 843, 845, 847, 849, 873, 891, 893, 916, -+ /* 110 */ 918, 921, 936, 941, 944, 956, 961, -234, -234, -234, -+ /* 120 */ -234, -234, -234, -234, -234, -234, 463, 607, -176, 14, -+ /* 130 */ -139, 87, -137, 818, 925, 818, 925, 898, -234, -234, -+ /* 140 */ -234, -234, -166, -166, -166, -130, -131, -82, -54, -180, -+ /* 150 */ 364, 41, 513, 509, 509, 117, 500, 789, 796, 646, -+ /* 160 */ 192, 291, 644, 798, 120, 807, 543, 911, 920, 652, -+ /* 170 */ 924, 922, 232, 698, 801, 971, 39, 220, 731, 442, -+ /* 180 */ 902, -199, 979, -43, 421, 896, 942, 605, -184, -126, -+ /* 190 */ 155, 172, 281, 304, 377, 538, 650, 690, 699, 723, -+ /* 200 */ 803, 839, 853, 919, 991, 1018, 1067, 1092, 951, 1111, -+ /* 210 */ 1112, 1115, 1116, 1117, 1119, 1120, 1121, 1122, 1123, 1124, -+ /* 220 */ 1125, 1012, 1096, 1097, 1128, 1129, 1130, 1131, 1070, 1135, -+ /* 230 */ 1137, 1152, 1077, 1153, 1155, 1114, 1156, 304, 1158, 1172, -+ /* 240 */ 1173, 1174, 1175, 1176, 1089, 1091, 1133, 1098, 1126, 1139, -+ /* 250 */ 1140, 1070, 1133, 1133, 1170, 1163, 1186, 1103, 1168, 1138, -+ /* 260 */ 1141, 1110, 1169, 1171, 1132, 1177, 1189, 1194, 1181, 1200, -+ /* 270 */ 1204, 1166, 1145, 1178, 1187, 1232, 1142, 1231, 1233, 1149, -+ /* 280 */ 1150, 1238, 1179, 1182, 1212, 1205, 1219, 1220, 1221, 1222, -+ /* 290 */ 1258, 1266, 1223, 1224, 1206, 1211, 1237, 1239, 1230, 1269, -+ /* 300 */ 1272, 1195, 1197, 1280, 1284, 1268, 1285, 1289, 1290, 1293, -+ /* 310 */ 1274, 1286, 1287, 1288, 1282, 1294, 1292, 1297, 1300, 1296, -+ /* 320 */ 1301, 1306, 1304, 1249, 1250, 1308, 1271, 1275, 1273, 1276, -+ /* 330 */ 1279, 1281, 1283, 1302, 1334, 1307, 1243, 1267, 1318, 1322, -+ /* 340 */ 1303, 1371, 1299, 1328, 1332, 1340, 1342, 1384, 1391, 1400, -+ /* 350 */ 1403, 1407, 1408, 1409, 1311, 1312, 1310, 1405, 1402, 1412, -+ /* 360 */ 1417, 1420, 1406, 1393, 1395, 1421, 1422, 1423, 1424, 1415, - }; - static const YYACTIONTYPE yy_default[] = { -- /* 0 */ 1270, 1260, 1260, 1260, 1193, 1193, 1193, 1193, 1260, 1088, -- /* 10 */ 1117, 1117, 1244, 1322, 1322, 1322, 1322, 1322, 1322, 1192, -- /* 20 */ 1322, 1322, 1322, 1322, 1260, 1092, 1123, 1322, 1322, 1322, -- /* 30 */ 1322, 1194, 1195, 1322, 1322, 1322, 1243, 1245, 1133, 1132, -- /* 40 */ 1131, 1130, 1226, 1104, 1128, 1121, 1125, 1194, 1188, 1189, -- /* 50 */ 1187, 1191, 1195, 1322, 1124, 1158, 1172, 1157, 1322, 1322, -- /* 60 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, -- /* 70 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, -- /* 80 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, -- /* 90 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, -- /* 100 */ 1322, 1322, 1322, 1322, 1166, 1171, 1178, 1170, 1167, 1160, -- /* 110 */ 1159, 1161, 1162, 1322, 1011, 1059, 1322, 1322, 1322, 1163, -- /* 120 */ 1322, 1164, 1175, 1174, 1173, 1251, 1278, 1277, 1322, 1322, -- /* 130 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, -- /* 140 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, -- /* 150 */ 1322, 1322, 1322, 1322, 1322, 1270, 1260, 1017, 1017, 1322, -- /* 160 */ 1260, 1260, 1260, 1260, 1260, 1260, 1256, 1092, 1083, 1322, -- /* 170 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, -- /* 180 */ 1248, 1246, 1322, 1208, 1322, 1322, 1322, 1322, 1322, 1322, -- /* 190 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, -- /* 200 */ 1322, 1322, 1322, 1322, 1088, 1322, 1322, 1322, 1322, 1322, -- /* 210 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1272, 1322, 1221, -- /* 220 */ 1088, 1088, 1088, 1090, 1072, 1082, 997, 1127, 1106, 1106, -- /* 230 */ 1311, 1127, 1311, 1034, 1292, 1031, 1117, 1106, 1190, 1117, -- /* 240 */ 1117, 1089, 1082, 1322, 1314, 1097, 1097, 1313, 1313, 1097, -- /* 250 */ 1138, 1062, 1127, 1068, 1068, 1068, 1068, 1097, 1008, 1127, -- /* 260 */ 1138, 1062, 1062, 1127, 1097, 1008, 1225, 1308, 1097, 1097, -- /* 270 */ 1008, 1201, 1097, 1008, 1097, 1008, 1201, 1060, 1060, 1060, -- /* 280 */ 1049, 1201, 1060, 1034, 1060, 1049, 1060, 1060, 1110, 1105, -- /* 290 */ 1110, 1105, 1110, 1105, 1110, 1105, 1097, 1196, 1097, 1322, -- /* 300 */ 1201, 1205, 1205, 1201, 1122, 1111, 1120, 1118, 1127, 1014, -- /* 310 */ 1052, 1275, 1275, 1271, 1271, 1271, 1319, 1319, 1256, 1287, -- /* 320 */ 1287, 1036, 1036, 1287, 1322, 1322, 1322, 1322, 1322, 1322, -- /* 330 */ 1282, 1322, 1210, 1322, 1322, 1322, 1322, 1322, 1322, 1322, -- /* 340 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, -- /* 350 */ 1322, 1143, 1322, 993, 1253, 1322, 1322, 1252, 1322, 1322, -- /* 360 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, -- /* 370 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1310, 1322, -- /* 380 */ 1322, 1322, 1322, 1322, 1322, 1224, 1223, 1322, 1322, 1322, -- /* 390 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, -- /* 400 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, -- /* 410 */ 1074, 1322, 1322, 1322, 1296, 1322, 1322, 1322, 1322, 1322, -- /* 420 */ 1322, 1322, 1119, 1322, 1112, 1322, 1322, 1301, 1322, 1322, -- /* 430 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1262, 1322, -- /* 440 */ 1322, 1322, 1261, 1322, 1322, 1322, 1322, 1322, 1145, 1322, -- /* 450 */ 1144, 1148, 1322, 1002, 1322, -+ /* 0 */ 1492, 1492, 1492, 1340, 1123, 1229, 1123, 1123, 1123, 1340, -+ /* 10 */ 1340, 1340, 1123, 1259, 1259, 1391, 1154, 1123, 1123, 1123, -+ /* 20 */ 1123, 1123, 1123, 1123, 1339, 1123, 1123, 1123, 1123, 1123, -+ /* 30 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1265, 1123, -+ /* 40 */ 1123, 1123, 1123, 1123, 1341, 1342, 1123, 1123, 1123, 1390, -+ /* 50 */ 1392, 1275, 1274, 1273, 1272, 1373, 1246, 1270, 1263, 1267, -+ /* 60 */ 1335, 1336, 1334, 1338, 1342, 1341, 1123, 1266, 1306, 1320, -+ /* 70 */ 1305, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, -+ /* 80 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, -+ /* 90 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, -+ /* 100 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, -+ /* 110 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1314, 1319, 1325, -+ /* 120 */ 1318, 1315, 1308, 1307, 1309, 1310, 1123, 1144, 1193, 1123, -+ /* 130 */ 1123, 1123, 1123, 1409, 1408, 1123, 1123, 1154, 1311, 1312, -+ /* 140 */ 1322, 1321, 1398, 1448, 1447, 1123, 1123, 1123, 1123, 1123, -+ /* 150 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, -+ /* 160 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, -+ /* 170 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1154, 1150, 1300, -+ /* 180 */ 1299, 1418, 1150, 1253, 1123, 1404, 1229, 1220, 1123, 1123, -+ /* 190 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, -+ /* 200 */ 1123, 1395, 1393, 1123, 1355, 1123, 1123, 1123, 1123, 1123, -+ /* 210 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, -+ /* 220 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, -+ /* 230 */ 1123, 1123, 1225, 1123, 1123, 1123, 1123, 1123, 1123, 1123, -+ /* 240 */ 1123, 1123, 1123, 1442, 1123, 1368, 1207, 1225, 1225, 1225, -+ /* 250 */ 1225, 1227, 1208, 1206, 1219, 1154, 1130, 1484, 1269, 1248, -+ /* 260 */ 1248, 1481, 1269, 1269, 1481, 1168, 1462, 1165, 1259, 1259, -+ /* 270 */ 1259, 1248, 1337, 1226, 1219, 1123, 1484, 1234, 1234, 1483, -+ /* 280 */ 1483, 1234, 1278, 1284, 1196, 1269, 1202, 1202, 1202, 1202, -+ /* 290 */ 1234, 1141, 1269, 1269, 1278, 1284, 1196, 1196, 1269, 1234, -+ /* 300 */ 1141, 1372, 1478, 1234, 1141, 1348, 1234, 1141, 1234, 1141, -+ /* 310 */ 1348, 1194, 1194, 1194, 1183, 1348, 1194, 1168, 1194, 1183, -+ /* 320 */ 1194, 1194, 1348, 1352, 1352, 1348, 1252, 1247, 1252, 1247, -+ /* 330 */ 1252, 1247, 1252, 1247, 1234, 1253, 1417, 1123, 1264, 1253, -+ /* 340 */ 1343, 1234, 1123, 1264, 1262, 1260, 1269, 1147, 1186, 1445, -+ /* 350 */ 1445, 1441, 1441, 1441, 1489, 1489, 1404, 1457, 1154, 1154, -+ /* 360 */ 1154, 1154, 1457, 1170, 1170, 1154, 1154, 1154, 1154, 1457, -+ /* 370 */ 1123, 1123, 1123, 1123, 1123, 1123, 1452, 1123, 1357, 1238, -+ /* 380 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, -+ /* 390 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, -+ /* 400 */ 1123, 1123, 1289, 1123, 1126, 1401, 1123, 1123, 1399, 1123, -+ /* 410 */ 1123, 1123, 1123, 1123, 1123, 1239, 1123, 1123, 1123, 1123, -+ /* 420 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, -+ /* 430 */ 1123, 1123, 1123, 1123, 1480, 1123, 1123, 1123, 1123, 1123, -+ /* 440 */ 1123, 1371, 1370, 1123, 1123, 1236, 1123, 1123, 1123, 1123, -+ /* 450 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, -+ /* 460 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, -+ /* 470 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, -+ /* 480 */ 1123, 1123, 1123, 1261, 1123, 1416, 1123, 1123, 1123, 1123, -+ /* 490 */ 1123, 1123, 1123, 1430, 1254, 1123, 1123, 1471, 1123, 1123, -+ /* 500 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, -+ /* 510 */ 1123, 1123, 1466, 1210, 1291, 1123, 1290, 1294, 1123, 1135, -+ /* 520 */ 1123, - }; - /********** End of lemon-generated parsing tables *****************************/ - -@@ -137414,73 +147745,95 @@ - static const YYCODETYPE yyFallback[] = { - 0, /* $ => nothing */ - 0, /* SEMI => nothing */ -- 27, /* EXPLAIN => ID */ -- 27, /* QUERY => ID */ -- 27, /* PLAN => ID */ -- 27, /* BEGIN => ID */ -+ 59, /* EXPLAIN => ID */ -+ 59, /* QUERY => ID */ -+ 59, /* PLAN => ID */ -+ 59, /* BEGIN => ID */ - 0, /* TRANSACTION => nothing */ -- 27, /* DEFERRED => ID */ -- 27, /* IMMEDIATE => ID */ -- 27, /* EXCLUSIVE => ID */ -+ 59, /* DEFERRED => ID */ -+ 59, /* IMMEDIATE => ID */ -+ 59, /* EXCLUSIVE => ID */ - 0, /* COMMIT => nothing */ -- 27, /* END => ID */ -- 27, /* ROLLBACK => ID */ -- 27, /* SAVEPOINT => ID */ -- 27, /* RELEASE => ID */ -+ 59, /* END => ID */ -+ 59, /* ROLLBACK => ID */ -+ 59, /* SAVEPOINT => ID */ -+ 59, /* RELEASE => ID */ - 0, /* TO => nothing */ - 0, /* TABLE => nothing */ - 0, /* CREATE => nothing */ -- 27, /* IF => ID */ -+ 59, /* IF => ID */ - 0, /* NOT => nothing */ - 0, /* EXISTS => nothing */ -- 27, /* TEMP => ID */ -+ 59, /* TEMP => ID */ - 0, /* LP => nothing */ - 0, /* RP => nothing */ - 0, /* AS => nothing */ -- 27, /* WITHOUT => ID */ -+ 59, /* WITHOUT => ID */ - 0, /* COMMA => nothing */ -+ 59, /* ABORT => ID */ -+ 59, /* ACTION => ID */ -+ 59, /* AFTER => ID */ -+ 59, /* ANALYZE => ID */ -+ 59, /* ASC => ID */ -+ 59, /* ATTACH => ID */ -+ 59, /* BEFORE => ID */ -+ 59, /* BY => ID */ -+ 59, /* CASCADE => ID */ -+ 59, /* CAST => ID */ -+ 59, /* CONFLICT => ID */ -+ 59, /* DATABASE => ID */ -+ 59, /* DESC => ID */ -+ 59, /* DETACH => ID */ -+ 59, /* EACH => ID */ -+ 59, /* FAIL => ID */ -+ 0, /* OR => nothing */ -+ 0, /* AND => nothing */ -+ 0, /* IS => nothing */ -+ 59, /* MATCH => ID */ -+ 59, /* LIKE_KW => ID */ -+ 0, /* BETWEEN => nothing */ -+ 0, /* IN => nothing */ -+ 0, /* ISNULL => nothing */ -+ 0, /* NOTNULL => nothing */ -+ 0, /* NE => nothing */ -+ 0, /* EQ => nothing */ -+ 0, /* GT => nothing */ -+ 0, /* LE => nothing */ -+ 0, /* LT => nothing */ -+ 0, /* GE => nothing */ -+ 0, /* ESCAPE => nothing */ - 0, /* ID => nothing */ -- 27, /* ABORT => ID */ -- 27, /* ACTION => ID */ -- 27, /* AFTER => ID */ -- 27, /* ANALYZE => ID */ -- 27, /* ASC => ID */ -- 27, /* ATTACH => ID */ -- 27, /* BEFORE => ID */ -- 27, /* BY => ID */ -- 27, /* CASCADE => ID */ -- 27, /* CAST => ID */ -- 27, /* COLUMNKW => ID */ -- 27, /* CONFLICT => ID */ -- 27, /* DATABASE => ID */ -- 27, /* DESC => ID */ -- 27, /* DETACH => ID */ -- 27, /* EACH => ID */ -- 27, /* FAIL => ID */ -- 27, /* FOR => ID */ -- 27, /* IGNORE => ID */ -- 27, /* INITIALLY => ID */ -- 27, /* INSTEAD => ID */ -- 27, /* LIKE_KW => ID */ -- 27, /* MATCH => ID */ -- 27, /* NO => ID */ -- 27, /* KEY => ID */ -- 27, /* OF => ID */ -- 27, /* OFFSET => ID */ -- 27, /* PRAGMA => ID */ -- 27, /* RAISE => ID */ -- 27, /* RECURSIVE => ID */ -- 27, /* REPLACE => ID */ -- 27, /* RESTRICT => ID */ -- 27, /* ROW => ID */ -- 27, /* TRIGGER => ID */ -- 27, /* VACUUM => ID */ -- 27, /* VIEW => ID */ -- 27, /* VIRTUAL => ID */ -- 27, /* WITH => ID */ -- 27, /* REINDEX => ID */ -- 27, /* RENAME => ID */ -- 27, /* CTIME_KW => ID */ -+ 59, /* COLUMNKW => ID */ -+ 59, /* DO => ID */ -+ 59, /* FOR => ID */ -+ 59, /* IGNORE => ID */ -+ 59, /* INITIALLY => ID */ -+ 59, /* INSTEAD => ID */ -+ 59, /* NO => ID */ -+ 59, /* KEY => ID */ -+ 59, /* OF => ID */ -+ 59, /* OFFSET => ID */ -+ 59, /* PRAGMA => ID */ -+ 59, /* RAISE => ID */ -+ 59, /* RECURSIVE => ID */ -+ 59, /* REPLACE => ID */ -+ 59, /* RESTRICT => ID */ -+ 59, /* ROW => ID */ -+ 59, /* ROWS => ID */ -+ 59, /* TRIGGER => ID */ -+ 59, /* VACUUM => ID */ -+ 59, /* VIEW => ID */ -+ 59, /* VIRTUAL => ID */ -+ 59, /* WITH => ID */ -+ 59, /* CURRENT => ID */ -+ 59, /* FOLLOWING => ID */ -+ 59, /* PARTITION => ID */ -+ 59, /* PRECEDING => ID */ -+ 59, /* RANGE => ID */ -+ 59, /* UNBOUNDED => ID */ -+ 59, /* REINDEX => ID */ -+ 59, /* RENAME => ID */ -+ 59, /* CTIME_KW => ID */ - }; - #endif /* YYFALLBACK */ - -@@ -137520,6 +147873,7 @@ - int yyerrcnt; /* Shifts left before out of the error */ - #endif - sqlite3ParserARG_SDECL /* A place to hold %extra_argument */ -+ sqlite3ParserCTX_SDECL /* A place to hold %extra_context */ - #if YYSTACKDEPTH<=0 - int yystksz; /* Current side of the stack */ - yyStackEntry *yystack; /* The parser's stack */ -@@ -137563,75 +147917,289 @@ - } - #endif /* NDEBUG */ - --#ifndef NDEBUG -+#if defined(YYCOVERAGE) || !defined(NDEBUG) - /* For tracing shifts, the names of all terminals and nonterminals - ** are required. The following table supplies these names */ - static const char *const yyTokenName[] = { -- "$", "SEMI", "EXPLAIN", "QUERY", -- "PLAN", "BEGIN", "TRANSACTION", "DEFERRED", -- "IMMEDIATE", "EXCLUSIVE", "COMMIT", "END", -- "ROLLBACK", "SAVEPOINT", "RELEASE", "TO", -- "TABLE", "CREATE", "IF", "NOT", -- "EXISTS", "TEMP", "LP", "RP", -- "AS", "WITHOUT", "COMMA", "ID", -- "ABORT", "ACTION", "AFTER", "ANALYZE", -- "ASC", "ATTACH", "BEFORE", "BY", -- "CASCADE", "CAST", "COLUMNKW", "CONFLICT", -- "DATABASE", "DESC", "DETACH", "EACH", -- "FAIL", "FOR", "IGNORE", "INITIALLY", -- "INSTEAD", "LIKE_KW", "MATCH", "NO", -- "KEY", "OF", "OFFSET", "PRAGMA", -- "RAISE", "RECURSIVE", "REPLACE", "RESTRICT", -- "ROW", "TRIGGER", "VACUUM", "VIEW", -- "VIRTUAL", "WITH", "REINDEX", "RENAME", -- "CTIME_KW", "ANY", "OR", "AND", -- "IS", "BETWEEN", "IN", "ISNULL", -- "NOTNULL", "NE", "EQ", "GT", -- "LE", "LT", "GE", "ESCAPE", -- "BITAND", "BITOR", "LSHIFT", "RSHIFT", -- "PLUS", "MINUS", "STAR", "SLASH", -- "REM", "CONCAT", "COLLATE", "BITNOT", -- "INDEXED", "STRING", "JOIN_KW", "CONSTRAINT", -- "DEFAULT", "NULL", "PRIMARY", "UNIQUE", -- "CHECK", "REFERENCES", "AUTOINCR", "ON", -- "INSERT", "DELETE", "UPDATE", "SET", -- "DEFERRABLE", "FOREIGN", "DROP", "UNION", -- "ALL", "EXCEPT", "INTERSECT", "SELECT", -- "VALUES", "DISTINCT", "DOT", "FROM", -- "JOIN", "USING", "ORDER", "GROUP", -- "HAVING", "LIMIT", "WHERE", "INTO", -- "FLOAT", "BLOB", "INTEGER", "VARIABLE", -- "CASE", "WHEN", "THEN", "ELSE", -- "INDEX", "ALTER", "ADD", "error", -- "input", "cmdlist", "ecmd", "explain", -- "cmdx", "cmd", "transtype", "trans_opt", -- "nm", "savepoint_opt", "create_table", "create_table_args", -- "createkw", "temp", "ifnotexists", "dbnm", -- "columnlist", "conslist_opt", "table_options", "select", -- "columnname", "carglist", "typetoken", "typename", -- "signed", "plus_num", "minus_num", "ccons", -- "term", "expr", "onconf", "sortorder", -- "autoinc", "eidlist_opt", "refargs", "defer_subclause", -- "refarg", "refact", "init_deferred_pred_opt", "conslist", -- "tconscomma", "tcons", "sortlist", "eidlist", -- "defer_subclause_opt", "orconf", "resolvetype", "raisetype", -- "ifexists", "fullname", "selectnowith", "oneselect", -- "with", "multiselect_op", "distinct", "selcollist", -- "from", "where_opt", "groupby_opt", "having_opt", -- "orderby_opt", "limit_opt", "values", "nexprlist", -- "exprlist", "sclp", "as", "seltablist", -- "stl_prefix", "joinop", "indexed_opt", "on_opt", -- "using_opt", "idlist", "setlist", "insert_cmd", -- "idlist_opt", "likeop", "between_op", "in_op", -- "paren_exprlist", "case_operand", "case_exprlist", "case_else", -- "uniqueflag", "collate", "nmnum", "trigger_decl", -- "trigger_cmd_list", "trigger_time", "trigger_event", "foreach_clause", -- "when_clause", "trigger_cmd", "trnm", "tridxby", -- "database_kw_opt", "key_opt", "add_column_fullname", "kwcolumn_opt", -- "create_vtab", "vtabarglist", "vtabarg", "vtabargtoken", -- "lp", "anylist", "wqlist", -+ /* 0 */ "$", -+ /* 1 */ "SEMI", -+ /* 2 */ "EXPLAIN", -+ /* 3 */ "QUERY", -+ /* 4 */ "PLAN", -+ /* 5 */ "BEGIN", -+ /* 6 */ "TRANSACTION", -+ /* 7 */ "DEFERRED", -+ /* 8 */ "IMMEDIATE", -+ /* 9 */ "EXCLUSIVE", -+ /* 10 */ "COMMIT", -+ /* 11 */ "END", -+ /* 12 */ "ROLLBACK", -+ /* 13 */ "SAVEPOINT", -+ /* 14 */ "RELEASE", -+ /* 15 */ "TO", -+ /* 16 */ "TABLE", -+ /* 17 */ "CREATE", -+ /* 18 */ "IF", -+ /* 19 */ "NOT", -+ /* 20 */ "EXISTS", -+ /* 21 */ "TEMP", -+ /* 22 */ "LP", -+ /* 23 */ "RP", -+ /* 24 */ "AS", -+ /* 25 */ "WITHOUT", -+ /* 26 */ "COMMA", -+ /* 27 */ "ABORT", -+ /* 28 */ "ACTION", -+ /* 29 */ "AFTER", -+ /* 30 */ "ANALYZE", -+ /* 31 */ "ASC", -+ /* 32 */ "ATTACH", -+ /* 33 */ "BEFORE", -+ /* 34 */ "BY", -+ /* 35 */ "CASCADE", -+ /* 36 */ "CAST", -+ /* 37 */ "CONFLICT", -+ /* 38 */ "DATABASE", -+ /* 39 */ "DESC", -+ /* 40 */ "DETACH", -+ /* 41 */ "EACH", -+ /* 42 */ "FAIL", -+ /* 43 */ "OR", -+ /* 44 */ "AND", -+ /* 45 */ "IS", -+ /* 46 */ "MATCH", -+ /* 47 */ "LIKE_KW", -+ /* 48 */ "BETWEEN", -+ /* 49 */ "IN", -+ /* 50 */ "ISNULL", -+ /* 51 */ "NOTNULL", -+ /* 52 */ "NE", -+ /* 53 */ "EQ", -+ /* 54 */ "GT", -+ /* 55 */ "LE", -+ /* 56 */ "LT", -+ /* 57 */ "GE", -+ /* 58 */ "ESCAPE", -+ /* 59 */ "ID", -+ /* 60 */ "COLUMNKW", -+ /* 61 */ "DO", -+ /* 62 */ "FOR", -+ /* 63 */ "IGNORE", -+ /* 64 */ "INITIALLY", -+ /* 65 */ "INSTEAD", -+ /* 66 */ "NO", -+ /* 67 */ "KEY", -+ /* 68 */ "OF", -+ /* 69 */ "OFFSET", -+ /* 70 */ "PRAGMA", -+ /* 71 */ "RAISE", -+ /* 72 */ "RECURSIVE", -+ /* 73 */ "REPLACE", -+ /* 74 */ "RESTRICT", -+ /* 75 */ "ROW", -+ /* 76 */ "ROWS", -+ /* 77 */ "TRIGGER", -+ /* 78 */ "VACUUM", -+ /* 79 */ "VIEW", -+ /* 80 */ "VIRTUAL", -+ /* 81 */ "WITH", -+ /* 82 */ "CURRENT", -+ /* 83 */ "FOLLOWING", -+ /* 84 */ "PARTITION", -+ /* 85 */ "PRECEDING", -+ /* 86 */ "RANGE", -+ /* 87 */ "UNBOUNDED", -+ /* 88 */ "REINDEX", -+ /* 89 */ "RENAME", -+ /* 90 */ "CTIME_KW", -+ /* 91 */ "ANY", -+ /* 92 */ "BITAND", -+ /* 93 */ "BITOR", -+ /* 94 */ "LSHIFT", -+ /* 95 */ "RSHIFT", -+ /* 96 */ "PLUS", -+ /* 97 */ "MINUS", -+ /* 98 */ "STAR", -+ /* 99 */ "SLASH", -+ /* 100 */ "REM", -+ /* 101 */ "CONCAT", -+ /* 102 */ "COLLATE", -+ /* 103 */ "BITNOT", -+ /* 104 */ "ON", -+ /* 105 */ "INDEXED", -+ /* 106 */ "STRING", -+ /* 107 */ "JOIN_KW", -+ /* 108 */ "CONSTRAINT", -+ /* 109 */ "DEFAULT", -+ /* 110 */ "NULL", -+ /* 111 */ "PRIMARY", -+ /* 112 */ "UNIQUE", -+ /* 113 */ "CHECK", -+ /* 114 */ "REFERENCES", -+ /* 115 */ "AUTOINCR", -+ /* 116 */ "INSERT", -+ /* 117 */ "DELETE", -+ /* 118 */ "UPDATE", -+ /* 119 */ "SET", -+ /* 120 */ "DEFERRABLE", -+ /* 121 */ "FOREIGN", -+ /* 122 */ "DROP", -+ /* 123 */ "UNION", -+ /* 124 */ "ALL", -+ /* 125 */ "EXCEPT", -+ /* 126 */ "INTERSECT", -+ /* 127 */ "SELECT", -+ /* 128 */ "VALUES", -+ /* 129 */ "DISTINCT", -+ /* 130 */ "DOT", -+ /* 131 */ "FROM", -+ /* 132 */ "JOIN", -+ /* 133 */ "USING", -+ /* 134 */ "ORDER", -+ /* 135 */ "GROUP", -+ /* 136 */ "HAVING", -+ /* 137 */ "LIMIT", -+ /* 138 */ "WHERE", -+ /* 139 */ "INTO", -+ /* 140 */ "NOTHING", -+ /* 141 */ "FLOAT", -+ /* 142 */ "BLOB", -+ /* 143 */ "INTEGER", -+ /* 144 */ "VARIABLE", -+ /* 145 */ "CASE", -+ /* 146 */ "WHEN", -+ /* 147 */ "THEN", -+ /* 148 */ "ELSE", -+ /* 149 */ "INDEX", -+ /* 150 */ "ALTER", -+ /* 151 */ "ADD", -+ /* 152 */ "WINDOW", -+ /* 153 */ "OVER", -+ /* 154 */ "FILTER", -+ /* 155 */ "input", -+ /* 156 */ "cmdlist", -+ /* 157 */ "ecmd", -+ /* 158 */ "cmdx", -+ /* 159 */ "explain", -+ /* 160 */ "cmd", -+ /* 161 */ "transtype", -+ /* 162 */ "trans_opt", -+ /* 163 */ "nm", -+ /* 164 */ "savepoint_opt", -+ /* 165 */ "create_table", -+ /* 166 */ "create_table_args", -+ /* 167 */ "createkw", -+ /* 168 */ "temp", -+ /* 169 */ "ifnotexists", -+ /* 170 */ "dbnm", -+ /* 171 */ "columnlist", -+ /* 172 */ "conslist_opt", -+ /* 173 */ "table_options", -+ /* 174 */ "select", -+ /* 175 */ "columnname", -+ /* 176 */ "carglist", -+ /* 177 */ "typetoken", -+ /* 178 */ "typename", -+ /* 179 */ "signed", -+ /* 180 */ "plus_num", -+ /* 181 */ "minus_num", -+ /* 182 */ "scanpt", -+ /* 183 */ "ccons", -+ /* 184 */ "term", -+ /* 185 */ "expr", -+ /* 186 */ "onconf", -+ /* 187 */ "sortorder", -+ /* 188 */ "autoinc", -+ /* 189 */ "eidlist_opt", -+ /* 190 */ "refargs", -+ /* 191 */ "defer_subclause", -+ /* 192 */ "refarg", -+ /* 193 */ "refact", -+ /* 194 */ "init_deferred_pred_opt", -+ /* 195 */ "conslist", -+ /* 196 */ "tconscomma", -+ /* 197 */ "tcons", -+ /* 198 */ "sortlist", -+ /* 199 */ "eidlist", -+ /* 200 */ "defer_subclause_opt", -+ /* 201 */ "orconf", -+ /* 202 */ "resolvetype", -+ /* 203 */ "raisetype", -+ /* 204 */ "ifexists", -+ /* 205 */ "fullname", -+ /* 206 */ "selectnowith", -+ /* 207 */ "oneselect", -+ /* 208 */ "wqlist", -+ /* 209 */ "multiselect_op", -+ /* 210 */ "distinct", -+ /* 211 */ "selcollist", -+ /* 212 */ "from", -+ /* 213 */ "where_opt", -+ /* 214 */ "groupby_opt", -+ /* 215 */ "having_opt", -+ /* 216 */ "orderby_opt", -+ /* 217 */ "limit_opt", -+ /* 218 */ "window_clause", -+ /* 219 */ "values", -+ /* 220 */ "nexprlist", -+ /* 221 */ "sclp", -+ /* 222 */ "as", -+ /* 223 */ "seltablist", -+ /* 224 */ "stl_prefix", -+ /* 225 */ "joinop", -+ /* 226 */ "indexed_opt", -+ /* 227 */ "on_opt", -+ /* 228 */ "using_opt", -+ /* 229 */ "exprlist", -+ /* 230 */ "xfullname", -+ /* 231 */ "idlist", -+ /* 232 */ "with", -+ /* 233 */ "setlist", -+ /* 234 */ "insert_cmd", -+ /* 235 */ "idlist_opt", -+ /* 236 */ "upsert", -+ /* 237 */ "over_clause", -+ /* 238 */ "likeop", -+ /* 239 */ "between_op", -+ /* 240 */ "in_op", -+ /* 241 */ "paren_exprlist", -+ /* 242 */ "case_operand", -+ /* 243 */ "case_exprlist", -+ /* 244 */ "case_else", -+ /* 245 */ "uniqueflag", -+ /* 246 */ "collate", -+ /* 247 */ "nmnum", -+ /* 248 */ "trigger_decl", -+ /* 249 */ "trigger_cmd_list", -+ /* 250 */ "trigger_time", -+ /* 251 */ "trigger_event", -+ /* 252 */ "foreach_clause", -+ /* 253 */ "when_clause", -+ /* 254 */ "trigger_cmd", -+ /* 255 */ "trnm", -+ /* 256 */ "tridxby", -+ /* 257 */ "database_kw_opt", -+ /* 258 */ "key_opt", -+ /* 259 */ "add_column_fullname", -+ /* 260 */ "kwcolumn_opt", -+ /* 261 */ "create_vtab", -+ /* 262 */ "vtabarglist", -+ /* 263 */ "vtabarg", -+ /* 264 */ "vtabargtoken", -+ /* 265 */ "lp", -+ /* 266 */ "anylist", -+ /* 267 */ "windowdefn_list", -+ /* 268 */ "windowdefn", -+ /* 269 */ "window", -+ /* 270 */ "frame_opt", -+ /* 271 */ "part_opt", -+ /* 272 */ "filter_opt", -+ /* 273 */ "range_or_rows", -+ /* 274 */ "frame_bound", -+ /* 275 */ "frame_bound_s", -+ /* 276 */ "frame_bound_e", - }; --#endif /* NDEBUG */ -+#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ - - #ifndef NDEBUG - /* For tracing reduce actions, the names of all rules are required. -@@ -137665,307 +148233,345 @@ - /* 25 */ "typetoken ::= typename LP signed RP", - /* 26 */ "typetoken ::= typename LP signed COMMA signed RP", - /* 27 */ "typename ::= typename ID|STRING", -- /* 28 */ "ccons ::= CONSTRAINT nm", -- /* 29 */ "ccons ::= DEFAULT term", -- /* 30 */ "ccons ::= DEFAULT LP expr RP", -- /* 31 */ "ccons ::= DEFAULT PLUS term", -- /* 32 */ "ccons ::= DEFAULT MINUS term", -- /* 33 */ "ccons ::= DEFAULT ID|INDEXED", -- /* 34 */ "ccons ::= NOT NULL onconf", -- /* 35 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", -- /* 36 */ "ccons ::= UNIQUE onconf", -- /* 37 */ "ccons ::= CHECK LP expr RP", -- /* 38 */ "ccons ::= REFERENCES nm eidlist_opt refargs", -- /* 39 */ "ccons ::= defer_subclause", -- /* 40 */ "ccons ::= COLLATE ID|STRING", -- /* 41 */ "autoinc ::=", -- /* 42 */ "autoinc ::= AUTOINCR", -- /* 43 */ "refargs ::=", -- /* 44 */ "refargs ::= refargs refarg", -- /* 45 */ "refarg ::= MATCH nm", -- /* 46 */ "refarg ::= ON INSERT refact", -- /* 47 */ "refarg ::= ON DELETE refact", -- /* 48 */ "refarg ::= ON UPDATE refact", -- /* 49 */ "refact ::= SET NULL", -- /* 50 */ "refact ::= SET DEFAULT", -- /* 51 */ "refact ::= CASCADE", -- /* 52 */ "refact ::= RESTRICT", -- /* 53 */ "refact ::= NO ACTION", -- /* 54 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", -- /* 55 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", -- /* 56 */ "init_deferred_pred_opt ::=", -- /* 57 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", -- /* 58 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", -- /* 59 */ "conslist_opt ::=", -- /* 60 */ "tconscomma ::= COMMA", -- /* 61 */ "tcons ::= CONSTRAINT nm", -- /* 62 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf", -- /* 63 */ "tcons ::= UNIQUE LP sortlist RP onconf", -- /* 64 */ "tcons ::= CHECK LP expr RP onconf", -- /* 65 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt", -- /* 66 */ "defer_subclause_opt ::=", -- /* 67 */ "onconf ::=", -- /* 68 */ "onconf ::= ON CONFLICT resolvetype", -- /* 69 */ "orconf ::=", -- /* 70 */ "orconf ::= OR resolvetype", -- /* 71 */ "resolvetype ::= IGNORE", -- /* 72 */ "resolvetype ::= REPLACE", -- /* 73 */ "cmd ::= DROP TABLE ifexists fullname", -- /* 74 */ "ifexists ::= IF EXISTS", -- /* 75 */ "ifexists ::=", -- /* 76 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select", -- /* 77 */ "cmd ::= DROP VIEW ifexists fullname", -- /* 78 */ "cmd ::= select", -- /* 79 */ "select ::= with selectnowith", -- /* 80 */ "selectnowith ::= selectnowith multiselect_op oneselect", -- /* 81 */ "multiselect_op ::= UNION", -- /* 82 */ "multiselect_op ::= UNION ALL", -- /* 83 */ "multiselect_op ::= EXCEPT|INTERSECT", -- /* 84 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", -- /* 85 */ "values ::= VALUES LP nexprlist RP", -- /* 86 */ "values ::= values COMMA LP exprlist RP", -- /* 87 */ "distinct ::= DISTINCT", -- /* 88 */ "distinct ::= ALL", -- /* 89 */ "distinct ::=", -- /* 90 */ "sclp ::=", -- /* 91 */ "selcollist ::= sclp expr as", -- /* 92 */ "selcollist ::= sclp STAR", -- /* 93 */ "selcollist ::= sclp nm DOT STAR", -- /* 94 */ "as ::= AS nm", -- /* 95 */ "as ::=", -- /* 96 */ "from ::=", -- /* 97 */ "from ::= FROM seltablist", -- /* 98 */ "stl_prefix ::= seltablist joinop", -- /* 99 */ "stl_prefix ::=", -- /* 100 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt", -- /* 101 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt", -- /* 102 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt", -- /* 103 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt", -- /* 104 */ "dbnm ::=", -- /* 105 */ "dbnm ::= DOT nm", -- /* 106 */ "fullname ::= nm dbnm", -- /* 107 */ "joinop ::= COMMA|JOIN", -- /* 108 */ "joinop ::= JOIN_KW JOIN", -- /* 109 */ "joinop ::= JOIN_KW nm JOIN", -- /* 110 */ "joinop ::= JOIN_KW nm nm JOIN", -- /* 111 */ "on_opt ::= ON expr", -- /* 112 */ "on_opt ::=", -- /* 113 */ "indexed_opt ::=", -- /* 114 */ "indexed_opt ::= INDEXED BY nm", -- /* 115 */ "indexed_opt ::= NOT INDEXED", -- /* 116 */ "using_opt ::= USING LP idlist RP", -- /* 117 */ "using_opt ::=", -- /* 118 */ "orderby_opt ::=", -- /* 119 */ "orderby_opt ::= ORDER BY sortlist", -- /* 120 */ "sortlist ::= sortlist COMMA expr sortorder", -- /* 121 */ "sortlist ::= expr sortorder", -- /* 122 */ "sortorder ::= ASC", -- /* 123 */ "sortorder ::= DESC", -- /* 124 */ "sortorder ::=", -- /* 125 */ "groupby_opt ::=", -- /* 126 */ "groupby_opt ::= GROUP BY nexprlist", -- /* 127 */ "having_opt ::=", -- /* 128 */ "having_opt ::= HAVING expr", -- /* 129 */ "limit_opt ::=", -- /* 130 */ "limit_opt ::= LIMIT expr", -- /* 131 */ "limit_opt ::= LIMIT expr OFFSET expr", -- /* 132 */ "limit_opt ::= LIMIT expr COMMA expr", -- /* 133 */ "cmd ::= with DELETE FROM fullname indexed_opt where_opt", -- /* 134 */ "where_opt ::=", -- /* 135 */ "where_opt ::= WHERE expr", -- /* 136 */ "cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt", -- /* 137 */ "setlist ::= setlist COMMA nm EQ expr", -- /* 138 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", -- /* 139 */ "setlist ::= nm EQ expr", -- /* 140 */ "setlist ::= LP idlist RP EQ expr", -- /* 141 */ "cmd ::= with insert_cmd INTO fullname idlist_opt select", -- /* 142 */ "cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES", -- /* 143 */ "insert_cmd ::= INSERT orconf", -- /* 144 */ "insert_cmd ::= REPLACE", -- /* 145 */ "idlist_opt ::=", -- /* 146 */ "idlist_opt ::= LP idlist RP", -- /* 147 */ "idlist ::= idlist COMMA nm", -- /* 148 */ "idlist ::= nm", -- /* 149 */ "expr ::= LP expr RP", -- /* 150 */ "expr ::= ID|INDEXED", -- /* 151 */ "expr ::= JOIN_KW", -- /* 152 */ "expr ::= nm DOT nm", -- /* 153 */ "expr ::= nm DOT nm DOT nm", -- /* 154 */ "term ::= NULL|FLOAT|BLOB", -- /* 155 */ "term ::= STRING", -- /* 156 */ "term ::= INTEGER", -- /* 157 */ "expr ::= VARIABLE", -- /* 158 */ "expr ::= expr COLLATE ID|STRING", -- /* 159 */ "expr ::= CAST LP expr AS typetoken RP", -- /* 160 */ "expr ::= ID|INDEXED LP distinct exprlist RP", -- /* 161 */ "expr ::= ID|INDEXED LP STAR RP", -- /* 162 */ "term ::= CTIME_KW", -- /* 163 */ "expr ::= LP nexprlist COMMA expr RP", -- /* 164 */ "expr ::= expr AND expr", -- /* 165 */ "expr ::= expr OR expr", -- /* 166 */ "expr ::= expr LT|GT|GE|LE expr", -- /* 167 */ "expr ::= expr EQ|NE expr", -- /* 168 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", -- /* 169 */ "expr ::= expr PLUS|MINUS expr", -- /* 170 */ "expr ::= expr STAR|SLASH|REM expr", -- /* 171 */ "expr ::= expr CONCAT expr", -- /* 172 */ "likeop ::= NOT LIKE_KW|MATCH", -- /* 173 */ "expr ::= expr likeop expr", -- /* 174 */ "expr ::= expr likeop expr ESCAPE expr", -- /* 175 */ "expr ::= expr ISNULL|NOTNULL", -- /* 176 */ "expr ::= expr NOT NULL", -- /* 177 */ "expr ::= expr IS expr", -- /* 178 */ "expr ::= expr IS NOT expr", -- /* 179 */ "expr ::= NOT expr", -- /* 180 */ "expr ::= BITNOT expr", -- /* 181 */ "expr ::= MINUS expr", -- /* 182 */ "expr ::= PLUS expr", -- /* 183 */ "between_op ::= BETWEEN", -- /* 184 */ "between_op ::= NOT BETWEEN", -- /* 185 */ "expr ::= expr between_op expr AND expr", -- /* 186 */ "in_op ::= IN", -- /* 187 */ "in_op ::= NOT IN", -- /* 188 */ "expr ::= expr in_op LP exprlist RP", -- /* 189 */ "expr ::= LP select RP", -- /* 190 */ "expr ::= expr in_op LP select RP", -- /* 191 */ "expr ::= expr in_op nm dbnm paren_exprlist", -- /* 192 */ "expr ::= EXISTS LP select RP", -- /* 193 */ "expr ::= CASE case_operand case_exprlist case_else END", -- /* 194 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", -- /* 195 */ "case_exprlist ::= WHEN expr THEN expr", -- /* 196 */ "case_else ::= ELSE expr", -- /* 197 */ "case_else ::=", -- /* 198 */ "case_operand ::= expr", -- /* 199 */ "case_operand ::=", -- /* 200 */ "exprlist ::=", -- /* 201 */ "nexprlist ::= nexprlist COMMA expr", -- /* 202 */ "nexprlist ::= expr", -- /* 203 */ "paren_exprlist ::=", -- /* 204 */ "paren_exprlist ::= LP exprlist RP", -- /* 205 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", -- /* 206 */ "uniqueflag ::= UNIQUE", -- /* 207 */ "uniqueflag ::=", -- /* 208 */ "eidlist_opt ::=", -- /* 209 */ "eidlist_opt ::= LP eidlist RP", -- /* 210 */ "eidlist ::= eidlist COMMA nm collate sortorder", -- /* 211 */ "eidlist ::= nm collate sortorder", -- /* 212 */ "collate ::=", -- /* 213 */ "collate ::= COLLATE ID|STRING", -- /* 214 */ "cmd ::= DROP INDEX ifexists fullname", -- /* 215 */ "cmd ::= VACUUM", -- /* 216 */ "cmd ::= VACUUM nm", -- /* 217 */ "cmd ::= PRAGMA nm dbnm", -- /* 218 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", -- /* 219 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", -- /* 220 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", -- /* 221 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", -- /* 222 */ "plus_num ::= PLUS INTEGER|FLOAT", -- /* 223 */ "minus_num ::= MINUS INTEGER|FLOAT", -- /* 224 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", -- /* 225 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", -- /* 226 */ "trigger_time ::= BEFORE|AFTER", -- /* 227 */ "trigger_time ::= INSTEAD OF", -- /* 228 */ "trigger_time ::=", -- /* 229 */ "trigger_event ::= DELETE|INSERT", -- /* 230 */ "trigger_event ::= UPDATE", -- /* 231 */ "trigger_event ::= UPDATE OF idlist", -- /* 232 */ "when_clause ::=", -- /* 233 */ "when_clause ::= WHEN expr", -- /* 234 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", -- /* 235 */ "trigger_cmd_list ::= trigger_cmd SEMI", -- /* 236 */ "trnm ::= nm DOT nm", -- /* 237 */ "tridxby ::= INDEXED BY nm", -- /* 238 */ "tridxby ::= NOT INDEXED", -- /* 239 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt", -- /* 240 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select", -- /* 241 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt", -- /* 242 */ "trigger_cmd ::= select", -- /* 243 */ "expr ::= RAISE LP IGNORE RP", -- /* 244 */ "expr ::= RAISE LP raisetype COMMA nm RP", -- /* 245 */ "raisetype ::= ROLLBACK", -- /* 246 */ "raisetype ::= ABORT", -- /* 247 */ "raisetype ::= FAIL", -- /* 248 */ "cmd ::= DROP TRIGGER ifexists fullname", -- /* 249 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", -- /* 250 */ "cmd ::= DETACH database_kw_opt expr", -- /* 251 */ "key_opt ::=", -- /* 252 */ "key_opt ::= KEY expr", -- /* 253 */ "cmd ::= REINDEX", -- /* 254 */ "cmd ::= REINDEX nm dbnm", -- /* 255 */ "cmd ::= ANALYZE", -- /* 256 */ "cmd ::= ANALYZE nm dbnm", -- /* 257 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", -- /* 258 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", -- /* 259 */ "add_column_fullname ::= fullname", -- /* 260 */ "cmd ::= create_vtab", -- /* 261 */ "cmd ::= create_vtab LP vtabarglist RP", -- /* 262 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", -- /* 263 */ "vtabarg ::=", -- /* 264 */ "vtabargtoken ::= ANY", -- /* 265 */ "vtabargtoken ::= lp anylist RP", -- /* 266 */ "lp ::= LP", -- /* 267 */ "with ::=", -- /* 268 */ "with ::= WITH wqlist", -- /* 269 */ "with ::= WITH RECURSIVE wqlist", -- /* 270 */ "wqlist ::= nm eidlist_opt AS LP select RP", -- /* 271 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP", -- /* 272 */ "input ::= cmdlist", -- /* 273 */ "cmdlist ::= cmdlist ecmd", -- /* 274 */ "cmdlist ::= ecmd", -- /* 275 */ "ecmd ::= SEMI", -- /* 276 */ "ecmd ::= explain cmdx SEMI", -- /* 277 */ "explain ::=", -- /* 278 */ "trans_opt ::=", -- /* 279 */ "trans_opt ::= TRANSACTION", -- /* 280 */ "trans_opt ::= TRANSACTION nm", -- /* 281 */ "savepoint_opt ::= SAVEPOINT", -- /* 282 */ "savepoint_opt ::=", -- /* 283 */ "cmd ::= create_table create_table_args", -- /* 284 */ "columnlist ::= columnlist COMMA columnname carglist", -- /* 285 */ "columnlist ::= columnname carglist", -- /* 286 */ "nm ::= ID|INDEXED", -- /* 287 */ "nm ::= STRING", -- /* 288 */ "nm ::= JOIN_KW", -- /* 289 */ "typetoken ::= typename", -- /* 290 */ "typename ::= ID|STRING", -- /* 291 */ "signed ::= plus_num", -- /* 292 */ "signed ::= minus_num", -- /* 293 */ "carglist ::= carglist ccons", -- /* 294 */ "carglist ::=", -- /* 295 */ "ccons ::= NULL onconf", -- /* 296 */ "conslist_opt ::= COMMA conslist", -- /* 297 */ "conslist ::= conslist tconscomma tcons", -- /* 298 */ "conslist ::= tcons", -- /* 299 */ "tconscomma ::=", -- /* 300 */ "defer_subclause_opt ::= defer_subclause", -- /* 301 */ "resolvetype ::= raisetype", -- /* 302 */ "selectnowith ::= oneselect", -- /* 303 */ "oneselect ::= values", -- /* 304 */ "sclp ::= selcollist COMMA", -- /* 305 */ "as ::= ID|STRING", -- /* 306 */ "expr ::= term", -- /* 307 */ "likeop ::= LIKE_KW|MATCH", -- /* 308 */ "exprlist ::= nexprlist", -- /* 309 */ "nmnum ::= plus_num", -- /* 310 */ "nmnum ::= nm", -- /* 311 */ "nmnum ::= ON", -- /* 312 */ "nmnum ::= DELETE", -- /* 313 */ "nmnum ::= DEFAULT", -- /* 314 */ "plus_num ::= INTEGER|FLOAT", -- /* 315 */ "foreach_clause ::=", -- /* 316 */ "foreach_clause ::= FOR EACH ROW", -- /* 317 */ "trnm ::= nm", -- /* 318 */ "tridxby ::=", -- /* 319 */ "database_kw_opt ::= DATABASE", -- /* 320 */ "database_kw_opt ::=", -- /* 321 */ "kwcolumn_opt ::=", -- /* 322 */ "kwcolumn_opt ::= COLUMNKW", -- /* 323 */ "vtabarglist ::= vtabarg", -- /* 324 */ "vtabarglist ::= vtabarglist COMMA vtabarg", -- /* 325 */ "vtabarg ::= vtabarg vtabargtoken", -- /* 326 */ "anylist ::=", -- /* 327 */ "anylist ::= anylist LP anylist RP", -- /* 328 */ "anylist ::= anylist ANY", -+ /* 28 */ "scanpt ::=", -+ /* 29 */ "ccons ::= CONSTRAINT nm", -+ /* 30 */ "ccons ::= DEFAULT scanpt term scanpt", -+ /* 31 */ "ccons ::= DEFAULT LP expr RP", -+ /* 32 */ "ccons ::= DEFAULT PLUS term scanpt", -+ /* 33 */ "ccons ::= DEFAULT MINUS term scanpt", -+ /* 34 */ "ccons ::= DEFAULT scanpt ID|INDEXED", -+ /* 35 */ "ccons ::= NOT NULL onconf", -+ /* 36 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", -+ /* 37 */ "ccons ::= UNIQUE onconf", -+ /* 38 */ "ccons ::= CHECK LP expr RP", -+ /* 39 */ "ccons ::= REFERENCES nm eidlist_opt refargs", -+ /* 40 */ "ccons ::= defer_subclause", -+ /* 41 */ "ccons ::= COLLATE ID|STRING", -+ /* 42 */ "autoinc ::=", -+ /* 43 */ "autoinc ::= AUTOINCR", -+ /* 44 */ "refargs ::=", -+ /* 45 */ "refargs ::= refargs refarg", -+ /* 46 */ "refarg ::= MATCH nm", -+ /* 47 */ "refarg ::= ON INSERT refact", -+ /* 48 */ "refarg ::= ON DELETE refact", -+ /* 49 */ "refarg ::= ON UPDATE refact", -+ /* 50 */ "refact ::= SET NULL", -+ /* 51 */ "refact ::= SET DEFAULT", -+ /* 52 */ "refact ::= CASCADE", -+ /* 53 */ "refact ::= RESTRICT", -+ /* 54 */ "refact ::= NO ACTION", -+ /* 55 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", -+ /* 56 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", -+ /* 57 */ "init_deferred_pred_opt ::=", -+ /* 58 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", -+ /* 59 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", -+ /* 60 */ "conslist_opt ::=", -+ /* 61 */ "tconscomma ::= COMMA", -+ /* 62 */ "tcons ::= CONSTRAINT nm", -+ /* 63 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf", -+ /* 64 */ "tcons ::= UNIQUE LP sortlist RP onconf", -+ /* 65 */ "tcons ::= CHECK LP expr RP onconf", -+ /* 66 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt", -+ /* 67 */ "defer_subclause_opt ::=", -+ /* 68 */ "onconf ::=", -+ /* 69 */ "onconf ::= ON CONFLICT resolvetype", -+ /* 70 */ "orconf ::=", -+ /* 71 */ "orconf ::= OR resolvetype", -+ /* 72 */ "resolvetype ::= IGNORE", -+ /* 73 */ "resolvetype ::= REPLACE", -+ /* 74 */ "cmd ::= DROP TABLE ifexists fullname", -+ /* 75 */ "ifexists ::= IF EXISTS", -+ /* 76 */ "ifexists ::=", -+ /* 77 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select", -+ /* 78 */ "cmd ::= DROP VIEW ifexists fullname", -+ /* 79 */ "cmd ::= select", -+ /* 80 */ "select ::= WITH wqlist selectnowith", -+ /* 81 */ "select ::= WITH RECURSIVE wqlist selectnowith", -+ /* 82 */ "select ::= selectnowith", -+ /* 83 */ "selectnowith ::= selectnowith multiselect_op oneselect", -+ /* 84 */ "multiselect_op ::= UNION", -+ /* 85 */ "multiselect_op ::= UNION ALL", -+ /* 86 */ "multiselect_op ::= EXCEPT|INTERSECT", -+ /* 87 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", -+ /* 88 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt", -+ /* 89 */ "values ::= VALUES LP nexprlist RP", -+ /* 90 */ "values ::= values COMMA LP nexprlist RP", -+ /* 91 */ "distinct ::= DISTINCT", -+ /* 92 */ "distinct ::= ALL", -+ /* 93 */ "distinct ::=", -+ /* 94 */ "sclp ::=", -+ /* 95 */ "selcollist ::= sclp scanpt expr scanpt as", -+ /* 96 */ "selcollist ::= sclp scanpt STAR", -+ /* 97 */ "selcollist ::= sclp scanpt nm DOT STAR", -+ /* 98 */ "as ::= AS nm", -+ /* 99 */ "as ::=", -+ /* 100 */ "from ::=", -+ /* 101 */ "from ::= FROM seltablist", -+ /* 102 */ "stl_prefix ::= seltablist joinop", -+ /* 103 */ "stl_prefix ::=", -+ /* 104 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt", -+ /* 105 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt", -+ /* 106 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt", -+ /* 107 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt", -+ /* 108 */ "dbnm ::=", -+ /* 109 */ "dbnm ::= DOT nm", -+ /* 110 */ "fullname ::= nm", -+ /* 111 */ "fullname ::= nm DOT nm", -+ /* 112 */ "xfullname ::= nm", -+ /* 113 */ "xfullname ::= nm DOT nm", -+ /* 114 */ "xfullname ::= nm DOT nm AS nm", -+ /* 115 */ "xfullname ::= nm AS nm", -+ /* 116 */ "joinop ::= COMMA|JOIN", -+ /* 117 */ "joinop ::= JOIN_KW JOIN", -+ /* 118 */ "joinop ::= JOIN_KW nm JOIN", -+ /* 119 */ "joinop ::= JOIN_KW nm nm JOIN", -+ /* 120 */ "on_opt ::= ON expr", -+ /* 121 */ "on_opt ::=", -+ /* 122 */ "indexed_opt ::=", -+ /* 123 */ "indexed_opt ::= INDEXED BY nm", -+ /* 124 */ "indexed_opt ::= NOT INDEXED", -+ /* 125 */ "using_opt ::= USING LP idlist RP", -+ /* 126 */ "using_opt ::=", -+ /* 127 */ "orderby_opt ::=", -+ /* 128 */ "orderby_opt ::= ORDER BY sortlist", -+ /* 129 */ "sortlist ::= sortlist COMMA expr sortorder", -+ /* 130 */ "sortlist ::= expr sortorder", -+ /* 131 */ "sortorder ::= ASC", -+ /* 132 */ "sortorder ::= DESC", -+ /* 133 */ "sortorder ::=", -+ /* 134 */ "groupby_opt ::=", -+ /* 135 */ "groupby_opt ::= GROUP BY nexprlist", -+ /* 136 */ "having_opt ::=", -+ /* 137 */ "having_opt ::= HAVING expr", -+ /* 138 */ "limit_opt ::=", -+ /* 139 */ "limit_opt ::= LIMIT expr", -+ /* 140 */ "limit_opt ::= LIMIT expr OFFSET expr", -+ /* 141 */ "limit_opt ::= LIMIT expr COMMA expr", -+ /* 142 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt", -+ /* 143 */ "where_opt ::=", -+ /* 144 */ "where_opt ::= WHERE expr", -+ /* 145 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt", -+ /* 146 */ "setlist ::= setlist COMMA nm EQ expr", -+ /* 147 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", -+ /* 148 */ "setlist ::= nm EQ expr", -+ /* 149 */ "setlist ::= LP idlist RP EQ expr", -+ /* 150 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", -+ /* 151 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES", -+ /* 152 */ "upsert ::=", -+ /* 153 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt", -+ /* 154 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING", -+ /* 155 */ "upsert ::= ON CONFLICT DO NOTHING", -+ /* 156 */ "insert_cmd ::= INSERT orconf", -+ /* 157 */ "insert_cmd ::= REPLACE", -+ /* 158 */ "idlist_opt ::=", -+ /* 159 */ "idlist_opt ::= LP idlist RP", -+ /* 160 */ "idlist ::= idlist COMMA nm", -+ /* 161 */ "idlist ::= nm", -+ /* 162 */ "expr ::= LP expr RP", -+ /* 163 */ "expr ::= ID|INDEXED", -+ /* 164 */ "expr ::= JOIN_KW", -+ /* 165 */ "expr ::= nm DOT nm", -+ /* 166 */ "expr ::= nm DOT nm DOT nm", -+ /* 167 */ "term ::= NULL|FLOAT|BLOB", -+ /* 168 */ "term ::= STRING", -+ /* 169 */ "term ::= INTEGER", -+ /* 170 */ "expr ::= VARIABLE", -+ /* 171 */ "expr ::= expr COLLATE ID|STRING", -+ /* 172 */ "expr ::= CAST LP expr AS typetoken RP", -+ /* 173 */ "expr ::= ID|INDEXED LP distinct exprlist RP", -+ /* 174 */ "expr ::= ID|INDEXED LP STAR RP", -+ /* 175 */ "expr ::= ID|INDEXED LP distinct exprlist RP over_clause", -+ /* 176 */ "expr ::= ID|INDEXED LP STAR RP over_clause", -+ /* 177 */ "term ::= CTIME_KW", -+ /* 178 */ "expr ::= LP nexprlist COMMA expr RP", -+ /* 179 */ "expr ::= expr AND expr", -+ /* 180 */ "expr ::= expr OR expr", -+ /* 181 */ "expr ::= expr LT|GT|GE|LE expr", -+ /* 182 */ "expr ::= expr EQ|NE expr", -+ /* 183 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", -+ /* 184 */ "expr ::= expr PLUS|MINUS expr", -+ /* 185 */ "expr ::= expr STAR|SLASH|REM expr", -+ /* 186 */ "expr ::= expr CONCAT expr", -+ /* 187 */ "likeop ::= NOT LIKE_KW|MATCH", -+ /* 188 */ "expr ::= expr likeop expr", -+ /* 189 */ "expr ::= expr likeop expr ESCAPE expr", -+ /* 190 */ "expr ::= expr ISNULL|NOTNULL", -+ /* 191 */ "expr ::= expr NOT NULL", -+ /* 192 */ "expr ::= expr IS expr", -+ /* 193 */ "expr ::= expr IS NOT expr", -+ /* 194 */ "expr ::= NOT expr", -+ /* 195 */ "expr ::= BITNOT expr", -+ /* 196 */ "expr ::= PLUS|MINUS expr", -+ /* 197 */ "between_op ::= BETWEEN", -+ /* 198 */ "between_op ::= NOT BETWEEN", -+ /* 199 */ "expr ::= expr between_op expr AND expr", -+ /* 200 */ "in_op ::= IN", -+ /* 201 */ "in_op ::= NOT IN", -+ /* 202 */ "expr ::= expr in_op LP exprlist RP", -+ /* 203 */ "expr ::= LP select RP", -+ /* 204 */ "expr ::= expr in_op LP select RP", -+ /* 205 */ "expr ::= expr in_op nm dbnm paren_exprlist", -+ /* 206 */ "expr ::= EXISTS LP select RP", -+ /* 207 */ "expr ::= CASE case_operand case_exprlist case_else END", -+ /* 208 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", -+ /* 209 */ "case_exprlist ::= WHEN expr THEN expr", -+ /* 210 */ "case_else ::= ELSE expr", -+ /* 211 */ "case_else ::=", -+ /* 212 */ "case_operand ::= expr", -+ /* 213 */ "case_operand ::=", -+ /* 214 */ "exprlist ::=", -+ /* 215 */ "nexprlist ::= nexprlist COMMA expr", -+ /* 216 */ "nexprlist ::= expr", -+ /* 217 */ "paren_exprlist ::=", -+ /* 218 */ "paren_exprlist ::= LP exprlist RP", -+ /* 219 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", -+ /* 220 */ "uniqueflag ::= UNIQUE", -+ /* 221 */ "uniqueflag ::=", -+ /* 222 */ "eidlist_opt ::=", -+ /* 223 */ "eidlist_opt ::= LP eidlist RP", -+ /* 224 */ "eidlist ::= eidlist COMMA nm collate sortorder", -+ /* 225 */ "eidlist ::= nm collate sortorder", -+ /* 226 */ "collate ::=", -+ /* 227 */ "collate ::= COLLATE ID|STRING", -+ /* 228 */ "cmd ::= DROP INDEX ifexists fullname", -+ /* 229 */ "cmd ::= VACUUM", -+ /* 230 */ "cmd ::= VACUUM nm", -+ /* 231 */ "cmd ::= PRAGMA nm dbnm", -+ /* 232 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", -+ /* 233 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", -+ /* 234 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", -+ /* 235 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", -+ /* 236 */ "plus_num ::= PLUS INTEGER|FLOAT", -+ /* 237 */ "minus_num ::= MINUS INTEGER|FLOAT", -+ /* 238 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", -+ /* 239 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", -+ /* 240 */ "trigger_time ::= BEFORE|AFTER", -+ /* 241 */ "trigger_time ::= INSTEAD OF", -+ /* 242 */ "trigger_time ::=", -+ /* 243 */ "trigger_event ::= DELETE|INSERT", -+ /* 244 */ "trigger_event ::= UPDATE", -+ /* 245 */ "trigger_event ::= UPDATE OF idlist", -+ /* 246 */ "when_clause ::=", -+ /* 247 */ "when_clause ::= WHEN expr", -+ /* 248 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", -+ /* 249 */ "trigger_cmd_list ::= trigger_cmd SEMI", -+ /* 250 */ "trnm ::= nm DOT nm", -+ /* 251 */ "tridxby ::= INDEXED BY nm", -+ /* 252 */ "tridxby ::= NOT INDEXED", -+ /* 253 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt", -+ /* 254 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", -+ /* 255 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", -+ /* 256 */ "trigger_cmd ::= scanpt select scanpt", -+ /* 257 */ "expr ::= RAISE LP IGNORE RP", -+ /* 258 */ "expr ::= RAISE LP raisetype COMMA nm RP", -+ /* 259 */ "raisetype ::= ROLLBACK", -+ /* 260 */ "raisetype ::= ABORT", -+ /* 261 */ "raisetype ::= FAIL", -+ /* 262 */ "cmd ::= DROP TRIGGER ifexists fullname", -+ /* 263 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", -+ /* 264 */ "cmd ::= DETACH database_kw_opt expr", -+ /* 265 */ "key_opt ::=", -+ /* 266 */ "key_opt ::= KEY expr", -+ /* 267 */ "cmd ::= REINDEX", -+ /* 268 */ "cmd ::= REINDEX nm dbnm", -+ /* 269 */ "cmd ::= ANALYZE", -+ /* 270 */ "cmd ::= ANALYZE nm dbnm", -+ /* 271 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", -+ /* 272 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", -+ /* 273 */ "add_column_fullname ::= fullname", -+ /* 274 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", -+ /* 275 */ "cmd ::= create_vtab", -+ /* 276 */ "cmd ::= create_vtab LP vtabarglist RP", -+ /* 277 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", -+ /* 278 */ "vtabarg ::=", -+ /* 279 */ "vtabargtoken ::= ANY", -+ /* 280 */ "vtabargtoken ::= lp anylist RP", -+ /* 281 */ "lp ::= LP", -+ /* 282 */ "with ::= WITH wqlist", -+ /* 283 */ "with ::= WITH RECURSIVE wqlist", -+ /* 284 */ "wqlist ::= nm eidlist_opt AS LP select RP", -+ /* 285 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP", -+ /* 286 */ "windowdefn_list ::= windowdefn", -+ /* 287 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", -+ /* 288 */ "windowdefn ::= nm AS window", -+ /* 289 */ "window ::= LP part_opt orderby_opt frame_opt RP", -+ /* 290 */ "part_opt ::= PARTITION BY nexprlist", -+ /* 291 */ "part_opt ::=", -+ /* 292 */ "frame_opt ::=", -+ /* 293 */ "frame_opt ::= range_or_rows frame_bound_s", -+ /* 294 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e", -+ /* 295 */ "range_or_rows ::= RANGE", -+ /* 296 */ "range_or_rows ::= ROWS", -+ /* 297 */ "frame_bound_s ::= frame_bound", -+ /* 298 */ "frame_bound_s ::= UNBOUNDED PRECEDING", -+ /* 299 */ "frame_bound_e ::= frame_bound", -+ /* 300 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", -+ /* 301 */ "frame_bound ::= expr PRECEDING", -+ /* 302 */ "frame_bound ::= CURRENT ROW", -+ /* 303 */ "frame_bound ::= expr FOLLOWING", -+ /* 304 */ "window_clause ::= WINDOW windowdefn_list", -+ /* 305 */ "over_clause ::= filter_opt OVER window", -+ /* 306 */ "over_clause ::= filter_opt OVER nm", -+ /* 307 */ "filter_opt ::=", -+ /* 308 */ "filter_opt ::= FILTER LP WHERE expr RP", -+ /* 309 */ "input ::= cmdlist", -+ /* 310 */ "cmdlist ::= cmdlist ecmd", -+ /* 311 */ "cmdlist ::= ecmd", -+ /* 312 */ "ecmd ::= SEMI", -+ /* 313 */ "ecmd ::= cmdx SEMI", -+ /* 314 */ "ecmd ::= explain cmdx", -+ /* 315 */ "trans_opt ::=", -+ /* 316 */ "trans_opt ::= TRANSACTION", -+ /* 317 */ "trans_opt ::= TRANSACTION nm", -+ /* 318 */ "savepoint_opt ::= SAVEPOINT", -+ /* 319 */ "savepoint_opt ::=", -+ /* 320 */ "cmd ::= create_table create_table_args", -+ /* 321 */ "columnlist ::= columnlist COMMA columnname carglist", -+ /* 322 */ "columnlist ::= columnname carglist", -+ /* 323 */ "nm ::= ID|INDEXED", -+ /* 324 */ "nm ::= STRING", -+ /* 325 */ "nm ::= JOIN_KW", -+ /* 326 */ "typetoken ::= typename", -+ /* 327 */ "typename ::= ID|STRING", -+ /* 328 */ "signed ::= plus_num", -+ /* 329 */ "signed ::= minus_num", -+ /* 330 */ "carglist ::= carglist ccons", -+ /* 331 */ "carglist ::=", -+ /* 332 */ "ccons ::= NULL onconf", -+ /* 333 */ "conslist_opt ::= COMMA conslist", -+ /* 334 */ "conslist ::= conslist tconscomma tcons", -+ /* 335 */ "conslist ::= tcons", -+ /* 336 */ "tconscomma ::=", -+ /* 337 */ "defer_subclause_opt ::= defer_subclause", -+ /* 338 */ "resolvetype ::= raisetype", -+ /* 339 */ "selectnowith ::= oneselect", -+ /* 340 */ "oneselect ::= values", -+ /* 341 */ "sclp ::= selcollist COMMA", -+ /* 342 */ "as ::= ID|STRING", -+ /* 343 */ "expr ::= term", -+ /* 344 */ "likeop ::= LIKE_KW|MATCH", -+ /* 345 */ "exprlist ::= nexprlist", -+ /* 346 */ "nmnum ::= plus_num", -+ /* 347 */ "nmnum ::= nm", -+ /* 348 */ "nmnum ::= ON", -+ /* 349 */ "nmnum ::= DELETE", -+ /* 350 */ "nmnum ::= DEFAULT", -+ /* 351 */ "plus_num ::= INTEGER|FLOAT", -+ /* 352 */ "foreach_clause ::=", -+ /* 353 */ "foreach_clause ::= FOR EACH ROW", -+ /* 354 */ "trnm ::= nm", -+ /* 355 */ "tridxby ::=", -+ /* 356 */ "database_kw_opt ::= DATABASE", -+ /* 357 */ "database_kw_opt ::=", -+ /* 358 */ "kwcolumn_opt ::=", -+ /* 359 */ "kwcolumn_opt ::= COLUMNKW", -+ /* 360 */ "vtabarglist ::= vtabarg", -+ /* 361 */ "vtabarglist ::= vtabarglist COMMA vtabarg", -+ /* 362 */ "vtabarg ::= vtabarg vtabargtoken", -+ /* 363 */ "anylist ::=", -+ /* 364 */ "anylist ::= anylist LP anylist RP", -+ /* 365 */ "anylist ::= anylist ANY", -+ /* 366 */ "with ::=", - }; - #endif /* NDEBUG */ - -@@ -138014,28 +148620,29 @@ - - /* Initialize a new parser that has already been allocated. - */ --SQLITE_PRIVATE void sqlite3ParserInit(void *yypParser){ -- yyParser *pParser = (yyParser*)yypParser; -+SQLITE_PRIVATE void sqlite3ParserInit(void *yypRawParser sqlite3ParserCTX_PDECL){ -+ yyParser *yypParser = (yyParser*)yypRawParser; -+ sqlite3ParserCTX_STORE - #ifdef YYTRACKMAXSTACKDEPTH -- pParser->yyhwm = 0; -+ yypParser->yyhwm = 0; - #endif - #if YYSTACKDEPTH<=0 -- pParser->yytos = NULL; -- pParser->yystack = NULL; -- pParser->yystksz = 0; -- if( yyGrowStack(pParser) ){ -- pParser->yystack = &pParser->yystk0; -- pParser->yystksz = 1; -+ yypParser->yytos = NULL; -+ yypParser->yystack = NULL; -+ yypParser->yystksz = 0; -+ if( yyGrowStack(yypParser) ){ -+ yypParser->yystack = &yypParser->yystk0; -+ yypParser->yystksz = 1; - } - #endif - #ifndef YYNOERRORRECOVERY -- pParser->yyerrcnt = -1; -+ yypParser->yyerrcnt = -1; - #endif -- pParser->yytos = pParser->yystack; -- pParser->yystack[0].stateno = 0; -- pParser->yystack[0].major = 0; -+ yypParser->yytos = yypParser->yystack; -+ yypParser->yystack[0].stateno = 0; -+ yypParser->yystack[0].major = 0; - #if YYSTACKDEPTH>0 -- pParser->yystackEnd = &pParser->yystack[YYSTACKDEPTH-1]; -+ yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1]; - #endif - } - -@@ -138052,11 +148659,14 @@ - ** A pointer to a parser. This pointer is used in subsequent calls - ** to sqlite3Parser and sqlite3ParserFree. - */ --SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){ -- yyParser *pParser; -- pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); -- if( pParser ) sqlite3ParserInit(pParser); -- return pParser; -+SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE) sqlite3ParserCTX_PDECL){ -+ yyParser *yypParser; -+ yypParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); -+ if( yypParser ){ -+ sqlite3ParserCTX_STORE -+ sqlite3ParserInit(yypParser sqlite3ParserCTX_PARAM); -+ } -+ return (void*)yypParser; - } - #endif /* sqlite3Parser_ENGINEALWAYSONSTACK */ - -@@ -138073,7 +148683,8 @@ - YYCODETYPE yymajor, /* Type code for object to destroy */ - YYMINORTYPE *yypminor /* The object to be destroyed */ - ){ -- sqlite3ParserARG_FETCH; -+ sqlite3ParserARG_FETCH -+ sqlite3ParserCTX_FETCH - switch( yymajor ){ - /* Here is inserted the actions which take place when a - ** terminal or non-terminal is destroyed. This can happen -@@ -138086,79 +148697,98 @@ - ** inside the C code. - */ - /********* Begin destructor definitions ***************************************/ -- case 163: /* select */ -- case 194: /* selectnowith */ -- case 195: /* oneselect */ -- case 206: /* values */ -+ case 174: /* select */ -+ case 206: /* selectnowith */ -+ case 207: /* oneselect */ -+ case 219: /* values */ - { --sqlite3SelectDelete(pParse->db, (yypminor->yy243)); -+sqlite3SelectDelete(pParse->db, (yypminor->yy489)); - } - break; -- case 172: /* term */ -- case 173: /* expr */ -+ case 184: /* term */ -+ case 185: /* expr */ -+ case 213: /* where_opt */ -+ case 215: /* having_opt */ -+ case 227: /* on_opt */ -+ case 242: /* case_operand */ -+ case 244: /* case_else */ -+ case 253: /* when_clause */ -+ case 258: /* key_opt */ -+ case 272: /* filter_opt */ - { --sqlite3ExprDelete(pParse->db, (yypminor->yy190).pExpr); -+sqlite3ExprDelete(pParse->db, (yypminor->yy18)); - } - break; -- case 177: /* eidlist_opt */ -- case 186: /* sortlist */ -- case 187: /* eidlist */ -- case 199: /* selcollist */ -- case 202: /* groupby_opt */ -- case 204: /* orderby_opt */ -- case 207: /* nexprlist */ -- case 208: /* exprlist */ -- case 209: /* sclp */ -- case 218: /* setlist */ -- case 224: /* paren_exprlist */ -- case 226: /* case_exprlist */ -+ case 189: /* eidlist_opt */ -+ case 198: /* sortlist */ -+ case 199: /* eidlist */ -+ case 211: /* selcollist */ -+ case 214: /* groupby_opt */ -+ case 216: /* orderby_opt */ -+ case 220: /* nexprlist */ -+ case 221: /* sclp */ -+ case 229: /* exprlist */ -+ case 233: /* setlist */ -+ case 241: /* paren_exprlist */ -+ case 243: /* case_exprlist */ -+ case 271: /* part_opt */ - { --sqlite3ExprListDelete(pParse->db, (yypminor->yy148)); -+sqlite3ExprListDelete(pParse->db, (yypminor->yy420)); - } - break; -- case 193: /* fullname */ -- case 200: /* from */ -- case 211: /* seltablist */ -- case 212: /* stl_prefix */ -+ case 205: /* fullname */ -+ case 212: /* from */ -+ case 223: /* seltablist */ -+ case 224: /* stl_prefix */ -+ case 230: /* xfullname */ - { --sqlite3SrcListDelete(pParse->db, (yypminor->yy185)); -+sqlite3SrcListDelete(pParse->db, (yypminor->yy135)); - } - break; -- case 196: /* with */ -- case 250: /* wqlist */ -+ case 208: /* wqlist */ - { --sqlite3WithDelete(pParse->db, (yypminor->yy285)); -+sqlite3WithDelete(pParse->db, (yypminor->yy449)); - } - break; -- case 201: /* where_opt */ -- case 203: /* having_opt */ -- case 215: /* on_opt */ -- case 225: /* case_operand */ -- case 227: /* case_else */ -- case 236: /* when_clause */ -- case 241: /* key_opt */ -+ case 218: /* window_clause */ -+ case 267: /* windowdefn_list */ - { --sqlite3ExprDelete(pParse->db, (yypminor->yy72)); -+sqlite3WindowListDelete(pParse->db, (yypminor->yy327)); - } - break; -- case 216: /* using_opt */ -- case 217: /* idlist */ -- case 220: /* idlist_opt */ -+ case 228: /* using_opt */ -+ case 231: /* idlist */ -+ case 235: /* idlist_opt */ - { --sqlite3IdListDelete(pParse->db, (yypminor->yy254)); -+sqlite3IdListDelete(pParse->db, (yypminor->yy48)); - } - break; -- case 232: /* trigger_cmd_list */ -- case 237: /* trigger_cmd */ -+ case 237: /* over_clause */ -+ case 268: /* windowdefn */ -+ case 269: /* window */ -+ case 270: /* frame_opt */ - { --sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy145)); -+sqlite3WindowDelete(pParse->db, (yypminor->yy327)); - } - break; -- case 234: /* trigger_event */ -+ case 249: /* trigger_cmd_list */ -+ case 254: /* trigger_cmd */ - { --sqlite3IdListDelete(pParse->db, (yypminor->yy332).b); -+sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy207)); - } - break; -+ case 251: /* trigger_event */ -+{ -+sqlite3IdListDelete(pParse->db, (yypminor->yy34).b); -+} -+ break; -+ case 274: /* frame_bound */ -+ case 275: /* frame_bound_s */ -+ case 276: /* frame_bound_e */ -+{ -+sqlite3ExprDelete(pParse->db, (yypminor->yy119).pExpr); -+} -+ break; - /********* End destructor definitions *****************************************/ - default: break; /* If no destructor action specified: do nothing */ - } -@@ -138227,24 +148857,66 @@ - } - #endif - -+/* This array of booleans keeps track of the parser statement -+** coverage. The element yycoverage[X][Y] is set when the parser -+** is in state X and has a lookahead token Y. In a well-tested -+** systems, every element of this matrix should end up being set. -+*/ -+#if defined(YYCOVERAGE) -+static unsigned char yycoverage[YYNSTATE][YYNTOKEN]; -+#endif -+ - /* -+** Write into out a description of every state/lookahead combination that -+** -+** (1) has not been used by the parser, and -+** (2) is not a syntax error. -+** -+** Return the number of missed state/lookahead combinations. -+*/ -+#if defined(YYCOVERAGE) -+SQLITE_PRIVATE int sqlite3ParserCoverage(FILE *out){ -+ int stateno, iLookAhead, i; -+ int nMissed = 0; -+ for(stateno=0; stateno<YYNSTATE; stateno++){ -+ i = yy_shift_ofst[stateno]; -+ for(iLookAhead=0; iLookAhead<YYNTOKEN; iLookAhead++){ -+ if( yy_lookahead[i+iLookAhead]!=iLookAhead ) continue; -+ if( yycoverage[stateno][iLookAhead]==0 ) nMissed++; -+ if( out ){ -+ fprintf(out,"State %d lookahead %s %s\n", stateno, -+ yyTokenName[iLookAhead], -+ yycoverage[stateno][iLookAhead] ? "ok" : "missed"); -+ } -+ } -+ } -+ return nMissed; -+} -+#endif -+ -+/* - ** Find the appropriate action for a parser given the terminal - ** look-ahead token iLookAhead. - */ --static unsigned int yy_find_shift_action( -- yyParser *pParser, /* The parser */ -- YYCODETYPE iLookAhead /* The look-ahead token */ -+static YYACTIONTYPE yy_find_shift_action( -+ YYCODETYPE iLookAhead, /* The look-ahead token */ -+ YYACTIONTYPE stateno /* Current state number */ - ){ - int i; -- int stateno = pParser->yytos->stateno; -- -- if( stateno>=YY_MIN_REDUCE ) return stateno; -+ -+ if( stateno>YY_MAX_SHIFT ) return stateno; - assert( stateno <= YY_SHIFT_COUNT ); -+#if defined(YYCOVERAGE) -+ yycoverage[stateno][iLookAhead] = 1; -+#endif - do{ - i = yy_shift_ofst[stateno]; -+ assert( i>=0 ); -+ /* assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); */ - assert( iLookAhead!=YYNOCODE ); -+ assert( iLookAhead < YYNTOKEN ); - i += iLookAhead; -- if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ -+ if( i>=YY_NLOOKAHEAD || yy_lookahead[i]!=iLookAhead ){ - #ifdef YYFALLBACK - YYCODETYPE iFallback; /* Fallback token */ - if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0]) -@@ -138270,6 +148942,7 @@ - #if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT - j<YY_ACTTAB_COUNT && - #endif -+ j<(int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])) && - yy_lookahead[j]==YYWILDCARD && iLookAhead>0 - ){ - #ifndef NDEBUG -@@ -138294,8 +148967,8 @@ - ** Find the appropriate action for a parser given the non-terminal - ** look-ahead token iLookAhead. - */ --static int yy_find_reduce_action( -- int stateno, /* Current state number */ -+static YYACTIONTYPE yy_find_reduce_action( -+ YYACTIONTYPE stateno, /* Current state number */ - YYCODETYPE iLookAhead /* The look-ahead token */ - ){ - int i; -@@ -138307,7 +148980,6 @@ - assert( stateno<=YY_REDUCE_COUNT ); - #endif - i = yy_reduce_ofst[stateno]; -- assert( i!=YY_REDUCE_USE_DFLT ); - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; - #ifdef YYERRORSYMBOL -@@ -138325,7 +148997,8 @@ - ** The following routine is called if the stack overflows. - */ - static void yyStackOverflow(yyParser *yypParser){ -- sqlite3ParserARG_FETCH; -+ sqlite3ParserARG_FETCH -+ sqlite3ParserCTX_FETCH - #ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); -@@ -138338,7 +149011,8 @@ - - sqlite3ErrorMsg(pParse, "parser stack overflow"); - /******** End %stack_overflow code ********************************************/ -- sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */ -+ sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */ -+ sqlite3ParserCTX_STORE - } - - /* -@@ -138345,20 +149019,21 @@ - ** Print tracing information for a SHIFT action - */ - #ifndef NDEBUG --static void yyTraceShift(yyParser *yypParser, int yyNewState){ -+static void yyTraceShift(yyParser *yypParser, int yyNewState, const char *zTag){ - if( yyTraceFILE ){ - if( yyNewState<YYNSTATE ){ -- fprintf(yyTraceFILE,"%sShift '%s', go to state %d\n", -- yyTracePrompt,yyTokenName[yypParser->yytos->major], -+ fprintf(yyTraceFILE,"%s%s '%s', go to state %d\n", -+ yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major], - yyNewState); - }else{ -- fprintf(yyTraceFILE,"%sShift '%s'\n", -- yyTracePrompt,yyTokenName[yypParser->yytos->major]); -+ fprintf(yyTraceFILE,"%s%s '%s', pending reduce %d\n", -+ yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major], -+ yyNewState - YY_MIN_REDUCE); - } - } - } - #else --# define yyTraceShift(X,Y) -+# define yyTraceShift(X,Y,Z) - #endif - - /* -@@ -138366,8 +149041,8 @@ - */ - static void yy_shift( - yyParser *yypParser, /* The parser to be shifted */ -- int yyNewState, /* The new state to shift in */ -- int yyMajor, /* The major token to shift in */ -+ YYACTIONTYPE yyNewState, /* The new state to shift in */ -+ YYCODETYPE yyMajor, /* The major token to shift in */ - sqlite3ParserTOKENTYPE yyMinor /* The minor token to shift in */ - ){ - yyStackEntry *yytos; -@@ -138397,10 +149072,10 @@ - yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; - } - yytos = yypParser->yytos; -- yytos->stateno = (YYACTIONTYPE)yyNewState; -- yytos->major = (YYCODETYPE)yyMajor; -+ yytos->stateno = yyNewState; -+ yytos->major = yyMajor; - yytos->minor.yy0 = yyMinor; -- yyTraceShift(yypParser, yyNewState); -+ yyTraceShift(yypParser, yyNewState, "Shift"); - } - - /* The following table contains information about every rule that -@@ -138410,335 +149085,373 @@ - YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ - signed char nrhs; /* Negative of the number of RHS symbols in the rule */ - } yyRuleInfo[] = { -- { 147, -1 }, -- { 147, -3 }, -- { 148, -1 }, -- { 149, -3 }, -- { 150, 0 }, -- { 150, -1 }, -- { 150, -1 }, -- { 150, -1 }, -- { 149, -2 }, -- { 149, -2 }, -- { 149, -2 }, -- { 149, -3 }, -- { 149, -5 }, -- { 154, -6 }, -- { 156, -1 }, -- { 158, 0 }, -- { 158, -3 }, -- { 157, -1 }, -- { 157, 0 }, -- { 155, -5 }, -- { 155, -2 }, -- { 162, 0 }, -- { 162, -2 }, -- { 164, -2 }, -- { 166, 0 }, -- { 166, -4 }, -- { 166, -6 }, -- { 167, -2 }, -- { 171, -2 }, -- { 171, -2 }, -- { 171, -4 }, -- { 171, -3 }, -- { 171, -3 }, -- { 171, -2 }, -- { 171, -3 }, -- { 171, -5 }, -- { 171, -2 }, -- { 171, -4 }, -- { 171, -4 }, -- { 171, -1 }, -- { 171, -2 }, -- { 176, 0 }, -- { 176, -1 }, -- { 178, 0 }, -- { 178, -2 }, -- { 180, -2 }, -- { 180, -3 }, -- { 180, -3 }, -- { 180, -3 }, -- { 181, -2 }, -- { 181, -2 }, -- { 181, -1 }, -- { 181, -1 }, -- { 181, -2 }, -- { 179, -3 }, -- { 179, -2 }, -- { 182, 0 }, -- { 182, -2 }, -- { 182, -2 }, -- { 161, 0 }, -- { 184, -1 }, -- { 185, -2 }, -- { 185, -7 }, -- { 185, -5 }, -- { 185, -5 }, -- { 185, -10 }, -- { 188, 0 }, -- { 174, 0 }, -- { 174, -3 }, -- { 189, 0 }, -- { 189, -2 }, -- { 190, -1 }, -- { 190, -1 }, -- { 149, -4 }, -- { 192, -2 }, -- { 192, 0 }, -- { 149, -9 }, -- { 149, -4 }, -- { 149, -1 }, -- { 163, -2 }, -- { 194, -3 }, -- { 197, -1 }, -- { 197, -2 }, -- { 197, -1 }, -- { 195, -9 }, -- { 206, -4 }, -- { 206, -5 }, -- { 198, -1 }, -- { 198, -1 }, -- { 198, 0 }, -- { 209, 0 }, -- { 199, -3 }, -- { 199, -2 }, -- { 199, -4 }, -- { 210, -2 }, -- { 210, 0 }, -- { 200, 0 }, -- { 200, -2 }, -- { 212, -2 }, -- { 212, 0 }, -- { 211, -7 }, -- { 211, -9 }, -- { 211, -7 }, -- { 211, -7 }, -- { 159, 0 }, -- { 159, -2 }, -- { 193, -2 }, -- { 213, -1 }, -- { 213, -2 }, -- { 213, -3 }, -- { 213, -4 }, -- { 215, -2 }, -- { 215, 0 }, -- { 214, 0 }, -- { 214, -3 }, -- { 214, -2 }, -- { 216, -4 }, -- { 216, 0 }, -- { 204, 0 }, -- { 204, -3 }, -- { 186, -4 }, -- { 186, -2 }, -- { 175, -1 }, -- { 175, -1 }, -- { 175, 0 }, -- { 202, 0 }, -- { 202, -3 }, -- { 203, 0 }, -- { 203, -2 }, -- { 205, 0 }, -- { 205, -2 }, -- { 205, -4 }, -- { 205, -4 }, -- { 149, -6 }, -- { 201, 0 }, -- { 201, -2 }, -- { 149, -8 }, -- { 218, -5 }, -- { 218, -7 }, -- { 218, -3 }, -- { 218, -5 }, -- { 149, -6 }, -- { 149, -7 }, -- { 219, -2 }, -- { 219, -1 }, -- { 220, 0 }, -- { 220, -3 }, -- { 217, -3 }, -- { 217, -1 }, -- { 173, -3 }, -- { 173, -1 }, -- { 173, -1 }, -- { 173, -3 }, -- { 173, -5 }, -- { 172, -1 }, -- { 172, -1 }, -- { 172, -1 }, -- { 173, -1 }, -- { 173, -3 }, -- { 173, -6 }, -- { 173, -5 }, -- { 173, -4 }, -- { 172, -1 }, -- { 173, -5 }, -- { 173, -3 }, -- { 173, -3 }, -- { 173, -3 }, -- { 173, -3 }, -- { 173, -3 }, -- { 173, -3 }, -- { 173, -3 }, -- { 173, -3 }, -- { 221, -2 }, -- { 173, -3 }, -- { 173, -5 }, -- { 173, -2 }, -- { 173, -3 }, -- { 173, -3 }, -- { 173, -4 }, -- { 173, -2 }, -- { 173, -2 }, -- { 173, -2 }, -- { 173, -2 }, -- { 222, -1 }, -- { 222, -2 }, -- { 173, -5 }, -- { 223, -1 }, -- { 223, -2 }, -- { 173, -5 }, -- { 173, -3 }, -- { 173, -5 }, -- { 173, -5 }, -- { 173, -4 }, -- { 173, -5 }, -- { 226, -5 }, -- { 226, -4 }, -- { 227, -2 }, -- { 227, 0 }, -- { 225, -1 }, -- { 225, 0 }, -- { 208, 0 }, -- { 207, -3 }, -- { 207, -1 }, -- { 224, 0 }, -- { 224, -3 }, -- { 149, -12 }, -- { 228, -1 }, -- { 228, 0 }, -- { 177, 0 }, -- { 177, -3 }, -- { 187, -5 }, -- { 187, -3 }, -- { 229, 0 }, -- { 229, -2 }, -- { 149, -4 }, -- { 149, -1 }, -- { 149, -2 }, -- { 149, -3 }, -- { 149, -5 }, -- { 149, -6 }, -- { 149, -5 }, -- { 149, -6 }, -- { 169, -2 }, -- { 170, -2 }, -- { 149, -5 }, -- { 231, -11 }, -- { 233, -1 }, -- { 233, -2 }, -- { 233, 0 }, -- { 234, -1 }, -- { 234, -1 }, -- { 234, -3 }, -- { 236, 0 }, -- { 236, -2 }, -- { 232, -3 }, -- { 232, -2 }, -- { 238, -3 }, -- { 239, -3 }, -- { 239, -2 }, -- { 237, -7 }, -- { 237, -5 }, -- { 237, -5 }, -- { 237, -1 }, -- { 173, -4 }, -- { 173, -6 }, -- { 191, -1 }, -- { 191, -1 }, -- { 191, -1 }, -- { 149, -4 }, -- { 149, -6 }, -- { 149, -3 }, -- { 241, 0 }, -- { 241, -2 }, -- { 149, -1 }, -- { 149, -3 }, -- { 149, -1 }, -- { 149, -3 }, -- { 149, -6 }, -- { 149, -7 }, -- { 242, -1 }, -- { 149, -1 }, -- { 149, -4 }, -- { 244, -8 }, -- { 246, 0 }, -- { 247, -1 }, -- { 247, -3 }, -- { 248, -1 }, -- { 196, 0 }, -- { 196, -2 }, -- { 196, -3 }, -- { 250, -6 }, -- { 250, -8 }, -- { 144, -1 }, -- { 145, -2 }, -- { 145, -1 }, -- { 146, -1 }, -- { 146, -3 }, -- { 147, 0 }, -- { 151, 0 }, -- { 151, -1 }, -- { 151, -2 }, -- { 153, -1 }, -- { 153, 0 }, -- { 149, -2 }, -- { 160, -4 }, -- { 160, -2 }, -- { 152, -1 }, -- { 152, -1 }, -- { 152, -1 }, -- { 166, -1 }, -- { 167, -1 }, -- { 168, -1 }, -- { 168, -1 }, -- { 165, -2 }, -- { 165, 0 }, -- { 171, -2 }, -- { 161, -2 }, -- { 183, -3 }, -- { 183, -1 }, -- { 184, 0 }, -- { 188, -1 }, -- { 190, -1 }, -- { 194, -1 }, -- { 195, -1 }, -- { 209, -2 }, -- { 210, -1 }, -- { 173, -1 }, -- { 221, -1 }, -- { 208, -1 }, -- { 230, -1 }, -- { 230, -1 }, -- { 230, -1 }, -- { 230, -1 }, -- { 230, -1 }, -- { 169, -1 }, -- { 235, 0 }, -- { 235, -3 }, -- { 238, -1 }, -- { 239, 0 }, -- { 240, -1 }, -- { 240, 0 }, -- { 243, 0 }, -- { 243, -1 }, -- { 245, -1 }, -- { 245, -3 }, -- { 246, -2 }, -- { 249, 0 }, -- { 249, -4 }, -- { 249, -2 }, -+ { 159, -1 }, /* (0) explain ::= EXPLAIN */ -+ { 159, -3 }, /* (1) explain ::= EXPLAIN QUERY PLAN */ -+ { 158, -1 }, /* (2) cmdx ::= cmd */ -+ { 160, -3 }, /* (3) cmd ::= BEGIN transtype trans_opt */ -+ { 161, 0 }, /* (4) transtype ::= */ -+ { 161, -1 }, /* (5) transtype ::= DEFERRED */ -+ { 161, -1 }, /* (6) transtype ::= IMMEDIATE */ -+ { 161, -1 }, /* (7) transtype ::= EXCLUSIVE */ -+ { 160, -2 }, /* (8) cmd ::= COMMIT|END trans_opt */ -+ { 160, -2 }, /* (9) cmd ::= ROLLBACK trans_opt */ -+ { 160, -2 }, /* (10) cmd ::= SAVEPOINT nm */ -+ { 160, -3 }, /* (11) cmd ::= RELEASE savepoint_opt nm */ -+ { 160, -5 }, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ -+ { 165, -6 }, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ -+ { 167, -1 }, /* (14) createkw ::= CREATE */ -+ { 169, 0 }, /* (15) ifnotexists ::= */ -+ { 169, -3 }, /* (16) ifnotexists ::= IF NOT EXISTS */ -+ { 168, -1 }, /* (17) temp ::= TEMP */ -+ { 168, 0 }, /* (18) temp ::= */ -+ { 166, -5 }, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */ -+ { 166, -2 }, /* (20) create_table_args ::= AS select */ -+ { 173, 0 }, /* (21) table_options ::= */ -+ { 173, -2 }, /* (22) table_options ::= WITHOUT nm */ -+ { 175, -2 }, /* (23) columnname ::= nm typetoken */ -+ { 177, 0 }, /* (24) typetoken ::= */ -+ { 177, -4 }, /* (25) typetoken ::= typename LP signed RP */ -+ { 177, -6 }, /* (26) typetoken ::= typename LP signed COMMA signed RP */ -+ { 178, -2 }, /* (27) typename ::= typename ID|STRING */ -+ { 182, 0 }, /* (28) scanpt ::= */ -+ { 183, -2 }, /* (29) ccons ::= CONSTRAINT nm */ -+ { 183, -4 }, /* (30) ccons ::= DEFAULT scanpt term scanpt */ -+ { 183, -4 }, /* (31) ccons ::= DEFAULT LP expr RP */ -+ { 183, -4 }, /* (32) ccons ::= DEFAULT PLUS term scanpt */ -+ { 183, -4 }, /* (33) ccons ::= DEFAULT MINUS term scanpt */ -+ { 183, -3 }, /* (34) ccons ::= DEFAULT scanpt ID|INDEXED */ -+ { 183, -3 }, /* (35) ccons ::= NOT NULL onconf */ -+ { 183, -5 }, /* (36) ccons ::= PRIMARY KEY sortorder onconf autoinc */ -+ { 183, -2 }, /* (37) ccons ::= UNIQUE onconf */ -+ { 183, -4 }, /* (38) ccons ::= CHECK LP expr RP */ -+ { 183, -4 }, /* (39) ccons ::= REFERENCES nm eidlist_opt refargs */ -+ { 183, -1 }, /* (40) ccons ::= defer_subclause */ -+ { 183, -2 }, /* (41) ccons ::= COLLATE ID|STRING */ -+ { 188, 0 }, /* (42) autoinc ::= */ -+ { 188, -1 }, /* (43) autoinc ::= AUTOINCR */ -+ { 190, 0 }, /* (44) refargs ::= */ -+ { 190, -2 }, /* (45) refargs ::= refargs refarg */ -+ { 192, -2 }, /* (46) refarg ::= MATCH nm */ -+ { 192, -3 }, /* (47) refarg ::= ON INSERT refact */ -+ { 192, -3 }, /* (48) refarg ::= ON DELETE refact */ -+ { 192, -3 }, /* (49) refarg ::= ON UPDATE refact */ -+ { 193, -2 }, /* (50) refact ::= SET NULL */ -+ { 193, -2 }, /* (51) refact ::= SET DEFAULT */ -+ { 193, -1 }, /* (52) refact ::= CASCADE */ -+ { 193, -1 }, /* (53) refact ::= RESTRICT */ -+ { 193, -2 }, /* (54) refact ::= NO ACTION */ -+ { 191, -3 }, /* (55) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ -+ { 191, -2 }, /* (56) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ -+ { 194, 0 }, /* (57) init_deferred_pred_opt ::= */ -+ { 194, -2 }, /* (58) init_deferred_pred_opt ::= INITIALLY DEFERRED */ -+ { 194, -2 }, /* (59) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ -+ { 172, 0 }, /* (60) conslist_opt ::= */ -+ { 196, -1 }, /* (61) tconscomma ::= COMMA */ -+ { 197, -2 }, /* (62) tcons ::= CONSTRAINT nm */ -+ { 197, -7 }, /* (63) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ -+ { 197, -5 }, /* (64) tcons ::= UNIQUE LP sortlist RP onconf */ -+ { 197, -5 }, /* (65) tcons ::= CHECK LP expr RP onconf */ -+ { 197, -10 }, /* (66) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ -+ { 200, 0 }, /* (67) defer_subclause_opt ::= */ -+ { 186, 0 }, /* (68) onconf ::= */ -+ { 186, -3 }, /* (69) onconf ::= ON CONFLICT resolvetype */ -+ { 201, 0 }, /* (70) orconf ::= */ -+ { 201, -2 }, /* (71) orconf ::= OR resolvetype */ -+ { 202, -1 }, /* (72) resolvetype ::= IGNORE */ -+ { 202, -1 }, /* (73) resolvetype ::= REPLACE */ -+ { 160, -4 }, /* (74) cmd ::= DROP TABLE ifexists fullname */ -+ { 204, -2 }, /* (75) ifexists ::= IF EXISTS */ -+ { 204, 0 }, /* (76) ifexists ::= */ -+ { 160, -9 }, /* (77) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ -+ { 160, -4 }, /* (78) cmd ::= DROP VIEW ifexists fullname */ -+ { 160, -1 }, /* (79) cmd ::= select */ -+ { 174, -3 }, /* (80) select ::= WITH wqlist selectnowith */ -+ { 174, -4 }, /* (81) select ::= WITH RECURSIVE wqlist selectnowith */ -+ { 174, -1 }, /* (82) select ::= selectnowith */ -+ { 206, -3 }, /* (83) selectnowith ::= selectnowith multiselect_op oneselect */ -+ { 209, -1 }, /* (84) multiselect_op ::= UNION */ -+ { 209, -2 }, /* (85) multiselect_op ::= UNION ALL */ -+ { 209, -1 }, /* (86) multiselect_op ::= EXCEPT|INTERSECT */ -+ { 207, -9 }, /* (87) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ -+ { 207, -10 }, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ -+ { 219, -4 }, /* (89) values ::= VALUES LP nexprlist RP */ -+ { 219, -5 }, /* (90) values ::= values COMMA LP nexprlist RP */ -+ { 210, -1 }, /* (91) distinct ::= DISTINCT */ -+ { 210, -1 }, /* (92) distinct ::= ALL */ -+ { 210, 0 }, /* (93) distinct ::= */ -+ { 221, 0 }, /* (94) sclp ::= */ -+ { 211, -5 }, /* (95) selcollist ::= sclp scanpt expr scanpt as */ -+ { 211, -3 }, /* (96) selcollist ::= sclp scanpt STAR */ -+ { 211, -5 }, /* (97) selcollist ::= sclp scanpt nm DOT STAR */ -+ { 222, -2 }, /* (98) as ::= AS nm */ -+ { 222, 0 }, /* (99) as ::= */ -+ { 212, 0 }, /* (100) from ::= */ -+ { 212, -2 }, /* (101) from ::= FROM seltablist */ -+ { 224, -2 }, /* (102) stl_prefix ::= seltablist joinop */ -+ { 224, 0 }, /* (103) stl_prefix ::= */ -+ { 223, -7 }, /* (104) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ -+ { 223, -9 }, /* (105) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ -+ { 223, -7 }, /* (106) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ -+ { 223, -7 }, /* (107) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ -+ { 170, 0 }, /* (108) dbnm ::= */ -+ { 170, -2 }, /* (109) dbnm ::= DOT nm */ -+ { 205, -1 }, /* (110) fullname ::= nm */ -+ { 205, -3 }, /* (111) fullname ::= nm DOT nm */ -+ { 230, -1 }, /* (112) xfullname ::= nm */ -+ { 230, -3 }, /* (113) xfullname ::= nm DOT nm */ -+ { 230, -5 }, /* (114) xfullname ::= nm DOT nm AS nm */ -+ { 230, -3 }, /* (115) xfullname ::= nm AS nm */ -+ { 225, -1 }, /* (116) joinop ::= COMMA|JOIN */ -+ { 225, -2 }, /* (117) joinop ::= JOIN_KW JOIN */ -+ { 225, -3 }, /* (118) joinop ::= JOIN_KW nm JOIN */ -+ { 225, -4 }, /* (119) joinop ::= JOIN_KW nm nm JOIN */ -+ { 227, -2 }, /* (120) on_opt ::= ON expr */ -+ { 227, 0 }, /* (121) on_opt ::= */ -+ { 226, 0 }, /* (122) indexed_opt ::= */ -+ { 226, -3 }, /* (123) indexed_opt ::= INDEXED BY nm */ -+ { 226, -2 }, /* (124) indexed_opt ::= NOT INDEXED */ -+ { 228, -4 }, /* (125) using_opt ::= USING LP idlist RP */ -+ { 228, 0 }, /* (126) using_opt ::= */ -+ { 216, 0 }, /* (127) orderby_opt ::= */ -+ { 216, -3 }, /* (128) orderby_opt ::= ORDER BY sortlist */ -+ { 198, -4 }, /* (129) sortlist ::= sortlist COMMA expr sortorder */ -+ { 198, -2 }, /* (130) sortlist ::= expr sortorder */ -+ { 187, -1 }, /* (131) sortorder ::= ASC */ -+ { 187, -1 }, /* (132) sortorder ::= DESC */ -+ { 187, 0 }, /* (133) sortorder ::= */ -+ { 214, 0 }, /* (134) groupby_opt ::= */ -+ { 214, -3 }, /* (135) groupby_opt ::= GROUP BY nexprlist */ -+ { 215, 0 }, /* (136) having_opt ::= */ -+ { 215, -2 }, /* (137) having_opt ::= HAVING expr */ -+ { 217, 0 }, /* (138) limit_opt ::= */ -+ { 217, -2 }, /* (139) limit_opt ::= LIMIT expr */ -+ { 217, -4 }, /* (140) limit_opt ::= LIMIT expr OFFSET expr */ -+ { 217, -4 }, /* (141) limit_opt ::= LIMIT expr COMMA expr */ -+ { 160, -6 }, /* (142) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ -+ { 213, 0 }, /* (143) where_opt ::= */ -+ { 213, -2 }, /* (144) where_opt ::= WHERE expr */ -+ { 160, -8 }, /* (145) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */ -+ { 233, -5 }, /* (146) setlist ::= setlist COMMA nm EQ expr */ -+ { 233, -7 }, /* (147) setlist ::= setlist COMMA LP idlist RP EQ expr */ -+ { 233, -3 }, /* (148) setlist ::= nm EQ expr */ -+ { 233, -5 }, /* (149) setlist ::= LP idlist RP EQ expr */ -+ { 160, -7 }, /* (150) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ -+ { 160, -7 }, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ -+ { 236, 0 }, /* (152) upsert ::= */ -+ { 236, -11 }, /* (153) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ -+ { 236, -8 }, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ -+ { 236, -4 }, /* (155) upsert ::= ON CONFLICT DO NOTHING */ -+ { 234, -2 }, /* (156) insert_cmd ::= INSERT orconf */ -+ { 234, -1 }, /* (157) insert_cmd ::= REPLACE */ -+ { 235, 0 }, /* (158) idlist_opt ::= */ -+ { 235, -3 }, /* (159) idlist_opt ::= LP idlist RP */ -+ { 231, -3 }, /* (160) idlist ::= idlist COMMA nm */ -+ { 231, -1 }, /* (161) idlist ::= nm */ -+ { 185, -3 }, /* (162) expr ::= LP expr RP */ -+ { 185, -1 }, /* (163) expr ::= ID|INDEXED */ -+ { 185, -1 }, /* (164) expr ::= JOIN_KW */ -+ { 185, -3 }, /* (165) expr ::= nm DOT nm */ -+ { 185, -5 }, /* (166) expr ::= nm DOT nm DOT nm */ -+ { 184, -1 }, /* (167) term ::= NULL|FLOAT|BLOB */ -+ { 184, -1 }, /* (168) term ::= STRING */ -+ { 184, -1 }, /* (169) term ::= INTEGER */ -+ { 185, -1 }, /* (170) expr ::= VARIABLE */ -+ { 185, -3 }, /* (171) expr ::= expr COLLATE ID|STRING */ -+ { 185, -6 }, /* (172) expr ::= CAST LP expr AS typetoken RP */ -+ { 185, -5 }, /* (173) expr ::= ID|INDEXED LP distinct exprlist RP */ -+ { 185, -4 }, /* (174) expr ::= ID|INDEXED LP STAR RP */ -+ { 185, -6 }, /* (175) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */ -+ { 185, -5 }, /* (176) expr ::= ID|INDEXED LP STAR RP over_clause */ -+ { 184, -1 }, /* (177) term ::= CTIME_KW */ -+ { 185, -5 }, /* (178) expr ::= LP nexprlist COMMA expr RP */ -+ { 185, -3 }, /* (179) expr ::= expr AND expr */ -+ { 185, -3 }, /* (180) expr ::= expr OR expr */ -+ { 185, -3 }, /* (181) expr ::= expr LT|GT|GE|LE expr */ -+ { 185, -3 }, /* (182) expr ::= expr EQ|NE expr */ -+ { 185, -3 }, /* (183) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ -+ { 185, -3 }, /* (184) expr ::= expr PLUS|MINUS expr */ -+ { 185, -3 }, /* (185) expr ::= expr STAR|SLASH|REM expr */ -+ { 185, -3 }, /* (186) expr ::= expr CONCAT expr */ -+ { 238, -2 }, /* (187) likeop ::= NOT LIKE_KW|MATCH */ -+ { 185, -3 }, /* (188) expr ::= expr likeop expr */ -+ { 185, -5 }, /* (189) expr ::= expr likeop expr ESCAPE expr */ -+ { 185, -2 }, /* (190) expr ::= expr ISNULL|NOTNULL */ -+ { 185, -3 }, /* (191) expr ::= expr NOT NULL */ -+ { 185, -3 }, /* (192) expr ::= expr IS expr */ -+ { 185, -4 }, /* (193) expr ::= expr IS NOT expr */ -+ { 185, -2 }, /* (194) expr ::= NOT expr */ -+ { 185, -2 }, /* (195) expr ::= BITNOT expr */ -+ { 185, -2 }, /* (196) expr ::= PLUS|MINUS expr */ -+ { 239, -1 }, /* (197) between_op ::= BETWEEN */ -+ { 239, -2 }, /* (198) between_op ::= NOT BETWEEN */ -+ { 185, -5 }, /* (199) expr ::= expr between_op expr AND expr */ -+ { 240, -1 }, /* (200) in_op ::= IN */ -+ { 240, -2 }, /* (201) in_op ::= NOT IN */ -+ { 185, -5 }, /* (202) expr ::= expr in_op LP exprlist RP */ -+ { 185, -3 }, /* (203) expr ::= LP select RP */ -+ { 185, -5 }, /* (204) expr ::= expr in_op LP select RP */ -+ { 185, -5 }, /* (205) expr ::= expr in_op nm dbnm paren_exprlist */ -+ { 185, -4 }, /* (206) expr ::= EXISTS LP select RP */ -+ { 185, -5 }, /* (207) expr ::= CASE case_operand case_exprlist case_else END */ -+ { 243, -5 }, /* (208) case_exprlist ::= case_exprlist WHEN expr THEN expr */ -+ { 243, -4 }, /* (209) case_exprlist ::= WHEN expr THEN expr */ -+ { 244, -2 }, /* (210) case_else ::= ELSE expr */ -+ { 244, 0 }, /* (211) case_else ::= */ -+ { 242, -1 }, /* (212) case_operand ::= expr */ -+ { 242, 0 }, /* (213) case_operand ::= */ -+ { 229, 0 }, /* (214) exprlist ::= */ -+ { 220, -3 }, /* (215) nexprlist ::= nexprlist COMMA expr */ -+ { 220, -1 }, /* (216) nexprlist ::= expr */ -+ { 241, 0 }, /* (217) paren_exprlist ::= */ -+ { 241, -3 }, /* (218) paren_exprlist ::= LP exprlist RP */ -+ { 160, -12 }, /* (219) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ -+ { 245, -1 }, /* (220) uniqueflag ::= UNIQUE */ -+ { 245, 0 }, /* (221) uniqueflag ::= */ -+ { 189, 0 }, /* (222) eidlist_opt ::= */ -+ { 189, -3 }, /* (223) eidlist_opt ::= LP eidlist RP */ -+ { 199, -5 }, /* (224) eidlist ::= eidlist COMMA nm collate sortorder */ -+ { 199, -3 }, /* (225) eidlist ::= nm collate sortorder */ -+ { 246, 0 }, /* (226) collate ::= */ -+ { 246, -2 }, /* (227) collate ::= COLLATE ID|STRING */ -+ { 160, -4 }, /* (228) cmd ::= DROP INDEX ifexists fullname */ -+ { 160, -1 }, /* (229) cmd ::= VACUUM */ -+ { 160, -2 }, /* (230) cmd ::= VACUUM nm */ -+ { 160, -3 }, /* (231) cmd ::= PRAGMA nm dbnm */ -+ { 160, -5 }, /* (232) cmd ::= PRAGMA nm dbnm EQ nmnum */ -+ { 160, -6 }, /* (233) cmd ::= PRAGMA nm dbnm LP nmnum RP */ -+ { 160, -5 }, /* (234) cmd ::= PRAGMA nm dbnm EQ minus_num */ -+ { 160, -6 }, /* (235) cmd ::= PRAGMA nm dbnm LP minus_num RP */ -+ { 180, -2 }, /* (236) plus_num ::= PLUS INTEGER|FLOAT */ -+ { 181, -2 }, /* (237) minus_num ::= MINUS INTEGER|FLOAT */ -+ { 160, -5 }, /* (238) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ -+ { 248, -11 }, /* (239) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ -+ { 250, -1 }, /* (240) trigger_time ::= BEFORE|AFTER */ -+ { 250, -2 }, /* (241) trigger_time ::= INSTEAD OF */ -+ { 250, 0 }, /* (242) trigger_time ::= */ -+ { 251, -1 }, /* (243) trigger_event ::= DELETE|INSERT */ -+ { 251, -1 }, /* (244) trigger_event ::= UPDATE */ -+ { 251, -3 }, /* (245) trigger_event ::= UPDATE OF idlist */ -+ { 253, 0 }, /* (246) when_clause ::= */ -+ { 253, -2 }, /* (247) when_clause ::= WHEN expr */ -+ { 249, -3 }, /* (248) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ -+ { 249, -2 }, /* (249) trigger_cmd_list ::= trigger_cmd SEMI */ -+ { 255, -3 }, /* (250) trnm ::= nm DOT nm */ -+ { 256, -3 }, /* (251) tridxby ::= INDEXED BY nm */ -+ { 256, -2 }, /* (252) tridxby ::= NOT INDEXED */ -+ { 254, -8 }, /* (253) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */ -+ { 254, -8 }, /* (254) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ -+ { 254, -6 }, /* (255) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ -+ { 254, -3 }, /* (256) trigger_cmd ::= scanpt select scanpt */ -+ { 185, -4 }, /* (257) expr ::= RAISE LP IGNORE RP */ -+ { 185, -6 }, /* (258) expr ::= RAISE LP raisetype COMMA nm RP */ -+ { 203, -1 }, /* (259) raisetype ::= ROLLBACK */ -+ { 203, -1 }, /* (260) raisetype ::= ABORT */ -+ { 203, -1 }, /* (261) raisetype ::= FAIL */ -+ { 160, -4 }, /* (262) cmd ::= DROP TRIGGER ifexists fullname */ -+ { 160, -6 }, /* (263) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ -+ { 160, -3 }, /* (264) cmd ::= DETACH database_kw_opt expr */ -+ { 258, 0 }, /* (265) key_opt ::= */ -+ { 258, -2 }, /* (266) key_opt ::= KEY expr */ -+ { 160, -1 }, /* (267) cmd ::= REINDEX */ -+ { 160, -3 }, /* (268) cmd ::= REINDEX nm dbnm */ -+ { 160, -1 }, /* (269) cmd ::= ANALYZE */ -+ { 160, -3 }, /* (270) cmd ::= ANALYZE nm dbnm */ -+ { 160, -6 }, /* (271) cmd ::= ALTER TABLE fullname RENAME TO nm */ -+ { 160, -7 }, /* (272) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ -+ { 259, -1 }, /* (273) add_column_fullname ::= fullname */ -+ { 160, -8 }, /* (274) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ -+ { 160, -1 }, /* (275) cmd ::= create_vtab */ -+ { 160, -4 }, /* (276) cmd ::= create_vtab LP vtabarglist RP */ -+ { 261, -8 }, /* (277) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ -+ { 263, 0 }, /* (278) vtabarg ::= */ -+ { 264, -1 }, /* (279) vtabargtoken ::= ANY */ -+ { 264, -3 }, /* (280) vtabargtoken ::= lp anylist RP */ -+ { 265, -1 }, /* (281) lp ::= LP */ -+ { 232, -2 }, /* (282) with ::= WITH wqlist */ -+ { 232, -3 }, /* (283) with ::= WITH RECURSIVE wqlist */ -+ { 208, -6 }, /* (284) wqlist ::= nm eidlist_opt AS LP select RP */ -+ { 208, -8 }, /* (285) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ -+ { 267, -1 }, /* (286) windowdefn_list ::= windowdefn */ -+ { 267, -3 }, /* (287) windowdefn_list ::= windowdefn_list COMMA windowdefn */ -+ { 268, -3 }, /* (288) windowdefn ::= nm AS window */ -+ { 269, -5 }, /* (289) window ::= LP part_opt orderby_opt frame_opt RP */ -+ { 271, -3 }, /* (290) part_opt ::= PARTITION BY nexprlist */ -+ { 271, 0 }, /* (291) part_opt ::= */ -+ { 270, 0 }, /* (292) frame_opt ::= */ -+ { 270, -2 }, /* (293) frame_opt ::= range_or_rows frame_bound_s */ -+ { 270, -5 }, /* (294) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */ -+ { 273, -1 }, /* (295) range_or_rows ::= RANGE */ -+ { 273, -1 }, /* (296) range_or_rows ::= ROWS */ -+ { 275, -1 }, /* (297) frame_bound_s ::= frame_bound */ -+ { 275, -2 }, /* (298) frame_bound_s ::= UNBOUNDED PRECEDING */ -+ { 276, -1 }, /* (299) frame_bound_e ::= frame_bound */ -+ { 276, -2 }, /* (300) frame_bound_e ::= UNBOUNDED FOLLOWING */ -+ { 274, -2 }, /* (301) frame_bound ::= expr PRECEDING */ -+ { 274, -2 }, /* (302) frame_bound ::= CURRENT ROW */ -+ { 274, -2 }, /* (303) frame_bound ::= expr FOLLOWING */ -+ { 218, -2 }, /* (304) window_clause ::= WINDOW windowdefn_list */ -+ { 237, -3 }, /* (305) over_clause ::= filter_opt OVER window */ -+ { 237, -3 }, /* (306) over_clause ::= filter_opt OVER nm */ -+ { 272, 0 }, /* (307) filter_opt ::= */ -+ { 272, -5 }, /* (308) filter_opt ::= FILTER LP WHERE expr RP */ -+ { 155, -1 }, /* (309) input ::= cmdlist */ -+ { 156, -2 }, /* (310) cmdlist ::= cmdlist ecmd */ -+ { 156, -1 }, /* (311) cmdlist ::= ecmd */ -+ { 157, -1 }, /* (312) ecmd ::= SEMI */ -+ { 157, -2 }, /* (313) ecmd ::= cmdx SEMI */ -+ { 157, -2 }, /* (314) ecmd ::= explain cmdx */ -+ { 162, 0 }, /* (315) trans_opt ::= */ -+ { 162, -1 }, /* (316) trans_opt ::= TRANSACTION */ -+ { 162, -2 }, /* (317) trans_opt ::= TRANSACTION nm */ -+ { 164, -1 }, /* (318) savepoint_opt ::= SAVEPOINT */ -+ { 164, 0 }, /* (319) savepoint_opt ::= */ -+ { 160, -2 }, /* (320) cmd ::= create_table create_table_args */ -+ { 171, -4 }, /* (321) columnlist ::= columnlist COMMA columnname carglist */ -+ { 171, -2 }, /* (322) columnlist ::= columnname carglist */ -+ { 163, -1 }, /* (323) nm ::= ID|INDEXED */ -+ { 163, -1 }, /* (324) nm ::= STRING */ -+ { 163, -1 }, /* (325) nm ::= JOIN_KW */ -+ { 177, -1 }, /* (326) typetoken ::= typename */ -+ { 178, -1 }, /* (327) typename ::= ID|STRING */ -+ { 179, -1 }, /* (328) signed ::= plus_num */ -+ { 179, -1 }, /* (329) signed ::= minus_num */ -+ { 176, -2 }, /* (330) carglist ::= carglist ccons */ -+ { 176, 0 }, /* (331) carglist ::= */ -+ { 183, -2 }, /* (332) ccons ::= NULL onconf */ -+ { 172, -2 }, /* (333) conslist_opt ::= COMMA conslist */ -+ { 195, -3 }, /* (334) conslist ::= conslist tconscomma tcons */ -+ { 195, -1 }, /* (335) conslist ::= tcons */ -+ { 196, 0 }, /* (336) tconscomma ::= */ -+ { 200, -1 }, /* (337) defer_subclause_opt ::= defer_subclause */ -+ { 202, -1 }, /* (338) resolvetype ::= raisetype */ -+ { 206, -1 }, /* (339) selectnowith ::= oneselect */ -+ { 207, -1 }, /* (340) oneselect ::= values */ -+ { 221, -2 }, /* (341) sclp ::= selcollist COMMA */ -+ { 222, -1 }, /* (342) as ::= ID|STRING */ -+ { 185, -1 }, /* (343) expr ::= term */ -+ { 238, -1 }, /* (344) likeop ::= LIKE_KW|MATCH */ -+ { 229, -1 }, /* (345) exprlist ::= nexprlist */ -+ { 247, -1 }, /* (346) nmnum ::= plus_num */ -+ { 247, -1 }, /* (347) nmnum ::= nm */ -+ { 247, -1 }, /* (348) nmnum ::= ON */ -+ { 247, -1 }, /* (349) nmnum ::= DELETE */ -+ { 247, -1 }, /* (350) nmnum ::= DEFAULT */ -+ { 180, -1 }, /* (351) plus_num ::= INTEGER|FLOAT */ -+ { 252, 0 }, /* (352) foreach_clause ::= */ -+ { 252, -3 }, /* (353) foreach_clause ::= FOR EACH ROW */ -+ { 255, -1 }, /* (354) trnm ::= nm */ -+ { 256, 0 }, /* (355) tridxby ::= */ -+ { 257, -1 }, /* (356) database_kw_opt ::= DATABASE */ -+ { 257, 0 }, /* (357) database_kw_opt ::= */ -+ { 260, 0 }, /* (358) kwcolumn_opt ::= */ -+ { 260, -1 }, /* (359) kwcolumn_opt ::= COLUMNKW */ -+ { 262, -1 }, /* (360) vtabarglist ::= vtabarg */ -+ { 262, -3 }, /* (361) vtabarglist ::= vtabarglist COMMA vtabarg */ -+ { 263, -2 }, /* (362) vtabarg ::= vtabarg vtabargtoken */ -+ { 266, 0 }, /* (363) anylist ::= */ -+ { 266, -4 }, /* (364) anylist ::= anylist LP anylist RP */ -+ { 266, -2 }, /* (365) anylist ::= anylist ANY */ -+ { 232, 0 }, /* (366) with ::= */ - }; - - static void yy_accept(yyParser*); /* Forward Declaration */ -@@ -138746,22 +149459,39 @@ - /* - ** Perform a reduce action and the shift that must immediately - ** follow the reduce. -+** -+** The yyLookahead and yyLookaheadToken parameters provide reduce actions -+** access to the lookahead token (if any). The yyLookahead will be YYNOCODE -+** if the lookahead token has already been consumed. As this procedure is -+** only called from one place, optimizing compilers will in-line it, which -+** means that the extra parameters have no performance impact. - */ --static void yy_reduce( -+static YYACTIONTYPE yy_reduce( - yyParser *yypParser, /* The parser */ -- unsigned int yyruleno /* Number of the rule by which to reduce */ -+ unsigned int yyruleno, /* Number of the rule by which to reduce */ -+ int yyLookahead, /* Lookahead token, or YYNOCODE if none */ -+ sqlite3ParserTOKENTYPE yyLookaheadToken /* Value of the lookahead token */ -+ sqlite3ParserCTX_PDECL /* %extra_context */ - ){ - int yygoto; /* The next state */ -- int yyact; /* The next action */ -+ YYACTIONTYPE yyact; /* The next action */ - yyStackEntry *yymsp; /* The top of the parser's stack */ - int yysize; /* Amount to pop the stack */ -- sqlite3ParserARG_FETCH; -+ sqlite3ParserARG_FETCH -+ (void)yyLookahead; -+ (void)yyLookaheadToken; - yymsp = yypParser->yytos; - #ifndef NDEBUG - if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - yysize = yyRuleInfo[yyruleno].nrhs; -- fprintf(yyTraceFILE, "%sReduce [%s], go to state %d.\n", yyTracePrompt, -- yyRuleName[yyruleno], yymsp[yysize].stateno); -+ if( yysize ){ -+ fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n", -+ yyTracePrompt, -+ yyruleno, yyRuleName[yyruleno], yymsp[yysize].stateno); -+ }else{ -+ fprintf(yyTraceFILE, "%sReduce %d [%s].\n", -+ yyTracePrompt, yyruleno, yyRuleName[yyruleno]); -+ } - } - #endif /* NDEBUG */ - -@@ -138778,13 +149508,19 @@ - #if YYSTACKDEPTH>0 - if( yypParser->yytos>=yypParser->yystackEnd ){ - yyStackOverflow(yypParser); -- return; -+ /* The call to yyStackOverflow() above pops the stack until it is -+ ** empty, causing the main parser loop to exit. So the return value -+ ** is never used and does not matter. */ -+ return 0; - } - #else - if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ - if( yyGrowStack(yypParser) ){ - yyStackOverflow(yypParser); -- return; -+ /* The call to yyStackOverflow() above pops the stack until it is -+ ** empty, causing the main parser loop to exit. So the return value -+ ** is never used and does not matter. */ -+ return 0; - } - yymsp = yypParser->yytos; - } -@@ -138812,15 +149548,15 @@ - { sqlite3FinishCoding(pParse); } - break; - case 3: /* cmd ::= BEGIN transtype trans_opt */ --{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy194);} -+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy70);} - break; - case 4: /* transtype ::= */ --{yymsp[1].minor.yy194 = TK_DEFERRED;} -+{yymsp[1].minor.yy70 = TK_DEFERRED;} - break; - case 5: /* transtype ::= DEFERRED */ - case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); - case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); --{yymsp[0].minor.yy194 = yymsp[0].major; /*A-overwrites-X*/} -+{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/} - break; - case 8: /* cmd ::= COMMIT|END trans_opt */ - case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9); -@@ -138843,7 +149579,7 @@ - break; - case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ - { -- sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy194,0,0,yymsp[-2].minor.yy194); -+ sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy70,0,0,yymsp[-2].minor.yy70); - } - break; - case 14: /* createkw ::= CREATE */ -@@ -138852,38 +149588,38 @@ - case 15: /* ifnotexists ::= */ - case 18: /* temp ::= */ yytestcase(yyruleno==18); - case 21: /* table_options ::= */ yytestcase(yyruleno==21); -- case 41: /* autoinc ::= */ yytestcase(yyruleno==41); -- case 56: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==56); -- case 66: /* defer_subclause_opt ::= */ yytestcase(yyruleno==66); -- case 75: /* ifexists ::= */ yytestcase(yyruleno==75); -- case 89: /* distinct ::= */ yytestcase(yyruleno==89); -- case 212: /* collate ::= */ yytestcase(yyruleno==212); --{yymsp[1].minor.yy194 = 0;} -+ case 42: /* autoinc ::= */ yytestcase(yyruleno==42); -+ case 57: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==57); -+ case 67: /* defer_subclause_opt ::= */ yytestcase(yyruleno==67); -+ case 76: /* ifexists ::= */ yytestcase(yyruleno==76); -+ case 93: /* distinct ::= */ yytestcase(yyruleno==93); -+ case 226: /* collate ::= */ yytestcase(yyruleno==226); -+{yymsp[1].minor.yy70 = 0;} - break; - case 16: /* ifnotexists ::= IF NOT EXISTS */ --{yymsp[-2].minor.yy194 = 1;} -+{yymsp[-2].minor.yy70 = 1;} - break; - case 17: /* temp ::= TEMP */ -- case 42: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==42); --{yymsp[0].minor.yy194 = 1;} -+ case 43: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==43); -+{yymsp[0].minor.yy70 = 1;} - break; - case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_options */ - { -- sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy194,0); -+ sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy70,0); - } - break; - case 20: /* create_table_args ::= AS select */ - { -- sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy243); -- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy243); -+ sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy489); -+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489); - } - break; - case 22: /* table_options ::= WITHOUT nm */ - { - if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ -- yymsp[-1].minor.yy194 = TF_WithoutRowid | TF_NoVisibleRowid; -+ yymsp[-1].minor.yy70 = TF_WithoutRowid | TF_NoVisibleRowid; - }else{ -- yymsp[-1].minor.yy194 = 0; -+ yymsp[-1].minor.yy70 = 0; - sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); - } - } -@@ -138892,8 +149628,8 @@ - {sqlite3AddColumn(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);} - break; - case 24: /* typetoken ::= */ -- case 59: /* conslist_opt ::= */ yytestcase(yyruleno==59); -- case 95: /* as ::= */ yytestcase(yyruleno==95); -+ case 60: /* conslist_opt ::= */ yytestcase(yyruleno==60); -+ case 99: /* as ::= */ yytestcase(yyruleno==99); - {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;} - break; - case 25: /* typetoken ::= typename LP signed RP */ -@@ -138909,177 +149645,206 @@ - case 27: /* typename ::= typename ID|STRING */ - {yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);} - break; -- case 28: /* ccons ::= CONSTRAINT nm */ -- case 61: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==61); -+ case 28: /* scanpt ::= */ -+{ -+ assert( yyLookahead!=YYNOCODE ); -+ yymsp[1].minor.yy392 = yyLookaheadToken.z; -+} -+ break; -+ case 29: /* ccons ::= CONSTRAINT nm */ -+ case 62: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==62); - {pParse->constraintName = yymsp[0].minor.yy0;} - break; -- case 29: /* ccons ::= DEFAULT term */ -- case 31: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==31); --{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy190);} -+ case 30: /* ccons ::= DEFAULT scanpt term scanpt */ -+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy392,yymsp[0].minor.yy392);} - break; -- case 30: /* ccons ::= DEFAULT LP expr RP */ --{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy190);} -+ case 31: /* ccons ::= DEFAULT LP expr RP */ -+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} - break; -- case 32: /* ccons ::= DEFAULT MINUS term */ -+ case 32: /* ccons ::= DEFAULT PLUS term scanpt */ -+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392);} -+ break; -+ case 33: /* ccons ::= DEFAULT MINUS term scanpt */ - { -- ExprSpan v; -- v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy190.pExpr, 0); -- v.zStart = yymsp[-1].minor.yy0.z; -- v.zEnd = yymsp[0].minor.yy190.zEnd; -- sqlite3AddDefaultValue(pParse,&v); -+ Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[-1].minor.yy18, 0); -+ sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392); - } - break; -- case 33: /* ccons ::= DEFAULT ID|INDEXED */ -+ case 34: /* ccons ::= DEFAULT scanpt ID|INDEXED */ - { -- ExprSpan v; -- spanExpr(&v, pParse, TK_STRING, yymsp[0].minor.yy0); -- sqlite3AddDefaultValue(pParse,&v); -+ Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0); -+ if( p ){ -+ sqlite3ExprIdToTrueFalse(p); -+ testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) ); -+ } -+ sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n); - } - break; -- case 34: /* ccons ::= NOT NULL onconf */ --{sqlite3AddNotNull(pParse, yymsp[0].minor.yy194);} -+ case 35: /* ccons ::= NOT NULL onconf */ -+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy70);} - break; -- case 35: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ --{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy194,yymsp[0].minor.yy194,yymsp[-2].minor.yy194);} -+ case 36: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ -+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy70,yymsp[0].minor.yy70,yymsp[-2].minor.yy70);} - break; -- case 36: /* ccons ::= UNIQUE onconf */ --{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy194,0,0,0,0, -+ case 37: /* ccons ::= UNIQUE onconf */ -+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy70,0,0,0,0, - SQLITE_IDXTYPE_UNIQUE);} - break; -- case 37: /* ccons ::= CHECK LP expr RP */ --{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy190.pExpr);} -+ case 38: /* ccons ::= CHECK LP expr RP */ -+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy18);} - break; -- case 38: /* ccons ::= REFERENCES nm eidlist_opt refargs */ --{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy148,yymsp[0].minor.yy194);} -+ case 39: /* ccons ::= REFERENCES nm eidlist_opt refargs */ -+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy420,yymsp[0].minor.yy70);} - break; -- case 39: /* ccons ::= defer_subclause */ --{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy194);} -+ case 40: /* ccons ::= defer_subclause */ -+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy70);} - break; -- case 40: /* ccons ::= COLLATE ID|STRING */ -+ case 41: /* ccons ::= COLLATE ID|STRING */ - {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} - break; -- case 43: /* refargs ::= */ --{ yymsp[1].minor.yy194 = OE_None*0x0101; /* EV: R-19803-45884 */} -+ case 44: /* refargs ::= */ -+{ yymsp[1].minor.yy70 = OE_None*0x0101; /* EV: R-19803-45884 */} - break; -- case 44: /* refargs ::= refargs refarg */ --{ yymsp[-1].minor.yy194 = (yymsp[-1].minor.yy194 & ~yymsp[0].minor.yy497.mask) | yymsp[0].minor.yy497.value; } -+ case 45: /* refargs ::= refargs refarg */ -+{ yymsp[-1].minor.yy70 = (yymsp[-1].minor.yy70 & ~yymsp[0].minor.yy111.mask) | yymsp[0].minor.yy111.value; } - break; -- case 45: /* refarg ::= MATCH nm */ --{ yymsp[-1].minor.yy497.value = 0; yymsp[-1].minor.yy497.mask = 0x000000; } -+ case 46: /* refarg ::= MATCH nm */ -+{ yymsp[-1].minor.yy111.value = 0; yymsp[-1].minor.yy111.mask = 0x000000; } - break; -- case 46: /* refarg ::= ON INSERT refact */ --{ yymsp[-2].minor.yy497.value = 0; yymsp[-2].minor.yy497.mask = 0x000000; } -+ case 47: /* refarg ::= ON INSERT refact */ -+{ yymsp[-2].minor.yy111.value = 0; yymsp[-2].minor.yy111.mask = 0x000000; } - break; -- case 47: /* refarg ::= ON DELETE refact */ --{ yymsp[-2].minor.yy497.value = yymsp[0].minor.yy194; yymsp[-2].minor.yy497.mask = 0x0000ff; } -+ case 48: /* refarg ::= ON DELETE refact */ -+{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70; yymsp[-2].minor.yy111.mask = 0x0000ff; } - break; -- case 48: /* refarg ::= ON UPDATE refact */ --{ yymsp[-2].minor.yy497.value = yymsp[0].minor.yy194<<8; yymsp[-2].minor.yy497.mask = 0x00ff00; } -+ case 49: /* refarg ::= ON UPDATE refact */ -+{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70<<8; yymsp[-2].minor.yy111.mask = 0x00ff00; } - break; -- case 49: /* refact ::= SET NULL */ --{ yymsp[-1].minor.yy194 = OE_SetNull; /* EV: R-33326-45252 */} -+ case 50: /* refact ::= SET NULL */ -+{ yymsp[-1].minor.yy70 = OE_SetNull; /* EV: R-33326-45252 */} - break; -- case 50: /* refact ::= SET DEFAULT */ --{ yymsp[-1].minor.yy194 = OE_SetDflt; /* EV: R-33326-45252 */} -+ case 51: /* refact ::= SET DEFAULT */ -+{ yymsp[-1].minor.yy70 = OE_SetDflt; /* EV: R-33326-45252 */} - break; -- case 51: /* refact ::= CASCADE */ --{ yymsp[0].minor.yy194 = OE_Cascade; /* EV: R-33326-45252 */} -+ case 52: /* refact ::= CASCADE */ -+{ yymsp[0].minor.yy70 = OE_Cascade; /* EV: R-33326-45252 */} - break; -- case 52: /* refact ::= RESTRICT */ --{ yymsp[0].minor.yy194 = OE_Restrict; /* EV: R-33326-45252 */} -+ case 53: /* refact ::= RESTRICT */ -+{ yymsp[0].minor.yy70 = OE_Restrict; /* EV: R-33326-45252 */} - break; -- case 53: /* refact ::= NO ACTION */ --{ yymsp[-1].minor.yy194 = OE_None; /* EV: R-33326-45252 */} -+ case 54: /* refact ::= NO ACTION */ -+{ yymsp[-1].minor.yy70 = OE_None; /* EV: R-33326-45252 */} - break; -- case 54: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ --{yymsp[-2].minor.yy194 = 0;} -+ case 55: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ -+{yymsp[-2].minor.yy70 = 0;} - break; -- case 55: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ -- case 70: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==70); -- case 143: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==143); --{yymsp[-1].minor.yy194 = yymsp[0].minor.yy194;} -+ case 56: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ -+ case 71: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==71); -+ case 156: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==156); -+{yymsp[-1].minor.yy70 = yymsp[0].minor.yy70;} - break; -- case 57: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ -- case 74: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==74); -- case 184: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==184); -- case 187: /* in_op ::= NOT IN */ yytestcase(yyruleno==187); -- case 213: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==213); --{yymsp[-1].minor.yy194 = 1;} -+ case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ -+ case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75); -+ case 198: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==198); -+ case 201: /* in_op ::= NOT IN */ yytestcase(yyruleno==201); -+ case 227: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==227); -+{yymsp[-1].minor.yy70 = 1;} - break; -- case 58: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ --{yymsp[-1].minor.yy194 = 0;} -+ case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ -+{yymsp[-1].minor.yy70 = 0;} - break; -- case 60: /* tconscomma ::= COMMA */ -+ case 61: /* tconscomma ::= COMMA */ - {pParse->constraintName.n = 0;} - break; -- case 62: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ --{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy148,yymsp[0].minor.yy194,yymsp[-2].minor.yy194,0);} -+ case 63: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ -+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy420,yymsp[0].minor.yy70,yymsp[-2].minor.yy70,0);} - break; -- case 63: /* tcons ::= UNIQUE LP sortlist RP onconf */ --{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy148,yymsp[0].minor.yy194,0,0,0,0, -+ case 64: /* tcons ::= UNIQUE LP sortlist RP onconf */ -+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy420,yymsp[0].minor.yy70,0,0,0,0, - SQLITE_IDXTYPE_UNIQUE);} - break; -- case 64: /* tcons ::= CHECK LP expr RP onconf */ --{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy190.pExpr);} -+ case 65: /* tcons ::= CHECK LP expr RP onconf */ -+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy18);} - break; -- case 65: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ -+ case 66: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ - { -- sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy148, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy148, yymsp[-1].minor.yy194); -- sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy194); -+ sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy420, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy420, yymsp[-1].minor.yy70); -+ sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy70); - } - break; -- case 67: /* onconf ::= */ -- case 69: /* orconf ::= */ yytestcase(yyruleno==69); --{yymsp[1].minor.yy194 = OE_Default;} -+ case 68: /* onconf ::= */ -+ case 70: /* orconf ::= */ yytestcase(yyruleno==70); -+{yymsp[1].minor.yy70 = OE_Default;} - break; -- case 68: /* onconf ::= ON CONFLICT resolvetype */ --{yymsp[-2].minor.yy194 = yymsp[0].minor.yy194;} -+ case 69: /* onconf ::= ON CONFLICT resolvetype */ -+{yymsp[-2].minor.yy70 = yymsp[0].minor.yy70;} - break; -- case 71: /* resolvetype ::= IGNORE */ --{yymsp[0].minor.yy194 = OE_Ignore;} -+ case 72: /* resolvetype ::= IGNORE */ -+{yymsp[0].minor.yy70 = OE_Ignore;} - break; -- case 72: /* resolvetype ::= REPLACE */ -- case 144: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==144); --{yymsp[0].minor.yy194 = OE_Replace;} -+ case 73: /* resolvetype ::= REPLACE */ -+ case 157: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==157); -+{yymsp[0].minor.yy70 = OE_Replace;} - break; -- case 73: /* cmd ::= DROP TABLE ifexists fullname */ -+ case 74: /* cmd ::= DROP TABLE ifexists fullname */ - { -- sqlite3DropTable(pParse, yymsp[0].minor.yy185, 0, yymsp[-1].minor.yy194); -+ sqlite3DropTable(pParse, yymsp[0].minor.yy135, 0, yymsp[-1].minor.yy70); - } - break; -- case 76: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ -+ case 77: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ - { -- sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy148, yymsp[0].minor.yy243, yymsp[-7].minor.yy194, yymsp[-5].minor.yy194); -+ sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy420, yymsp[0].minor.yy489, yymsp[-7].minor.yy70, yymsp[-5].minor.yy70); - } - break; -- case 77: /* cmd ::= DROP VIEW ifexists fullname */ -+ case 78: /* cmd ::= DROP VIEW ifexists fullname */ - { -- sqlite3DropTable(pParse, yymsp[0].minor.yy185, 1, yymsp[-1].minor.yy194); -+ sqlite3DropTable(pParse, yymsp[0].minor.yy135, 1, yymsp[-1].minor.yy70); - } - break; -- case 78: /* cmd ::= select */ -+ case 79: /* cmd ::= select */ - { - SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0}; -- sqlite3Select(pParse, yymsp[0].minor.yy243, &dest); -- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy243); -+ sqlite3Select(pParse, yymsp[0].minor.yy489, &dest); -+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489); - } - break; -- case 79: /* select ::= with selectnowith */ -+ case 80: /* select ::= WITH wqlist selectnowith */ - { -- Select *p = yymsp[0].minor.yy243; -+ Select *p = yymsp[0].minor.yy489; - if( p ){ -- p->pWith = yymsp[-1].minor.yy285; -+ p->pWith = yymsp[-1].minor.yy449; - parserDoubleLinkSelect(pParse, p); - }else{ -- sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy285); -+ sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449); - } -- yymsp[-1].minor.yy243 = p; /*A-overwrites-W*/ -+ yymsp[-2].minor.yy489 = p; - } - break; -- case 80: /* selectnowith ::= selectnowith multiselect_op oneselect */ -+ case 81: /* select ::= WITH RECURSIVE wqlist selectnowith */ - { -- Select *pRhs = yymsp[0].minor.yy243; -- Select *pLhs = yymsp[-2].minor.yy243; -+ Select *p = yymsp[0].minor.yy489; -+ if( p ){ -+ p->pWith = yymsp[-1].minor.yy449; -+ parserDoubleLinkSelect(pParse, p); -+ }else{ -+ sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449); -+ } -+ yymsp[-3].minor.yy489 = p; -+} -+ break; -+ case 82: /* select ::= selectnowith */ -+{ -+ Select *p = yymsp[0].minor.yy489; -+ if( p ){ -+ parserDoubleLinkSelect(pParse, p); -+ } -+ yymsp[0].minor.yy489 = p; /*A-overwrites-X*/ -+} -+ break; -+ case 83: /* selectnowith ::= selectnowith multiselect_op oneselect */ -+{ -+ Select *pRhs = yymsp[0].minor.yy489; -+ Select *pLhs = yymsp[-2].minor.yy489; - if( pRhs && pRhs->pPrior ){ - SrcList *pFrom; - Token x; -@@ -139086,162 +149851,145 @@ - x.n = 0; - parserDoubleLinkSelect(pParse, pRhs); - pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0); -- pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0); -+ pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); - } - if( pRhs ){ -- pRhs->op = (u8)yymsp[-1].minor.yy194; -+ pRhs->op = (u8)yymsp[-1].minor.yy70; - pRhs->pPrior = pLhs; - if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue; - pRhs->selFlags &= ~SF_MultiValue; -- if( yymsp[-1].minor.yy194!=TK_ALL ) pParse->hasCompound = 1; -+ if( yymsp[-1].minor.yy70!=TK_ALL ) pParse->hasCompound = 1; - }else{ - sqlite3SelectDelete(pParse->db, pLhs); - } -- yymsp[-2].minor.yy243 = pRhs; -+ yymsp[-2].minor.yy489 = pRhs; - } - break; -- case 81: /* multiselect_op ::= UNION */ -- case 83: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==83); --{yymsp[0].minor.yy194 = yymsp[0].major; /*A-overwrites-OP*/} -+ case 84: /* multiselect_op ::= UNION */ -+ case 86: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==86); -+{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-OP*/} - break; -- case 82: /* multiselect_op ::= UNION ALL */ --{yymsp[-1].minor.yy194 = TK_ALL;} -+ case 85: /* multiselect_op ::= UNION ALL */ -+{yymsp[-1].minor.yy70 = TK_ALL;} - break; -- case 84: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ -+ case 87: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ - { --#if SELECTTRACE_ENABLED -- Token s = yymsp[-8].minor.yy0; /*A-overwrites-S*/ --#endif -- yymsp[-8].minor.yy243 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy148,yymsp[-5].minor.yy185,yymsp[-4].minor.yy72,yymsp[-3].minor.yy148,yymsp[-2].minor.yy72,yymsp[-1].minor.yy148,yymsp[-7].minor.yy194,yymsp[0].minor.yy354.pLimit,yymsp[0].minor.yy354.pOffset); --#if SELECTTRACE_ENABLED -- /* Populate the Select.zSelName[] string that is used to help with -- ** query planner debugging, to differentiate between multiple Select -- ** objects in a complex query. -- ** -- ** If the SELECT keyword is immediately followed by a C-style comment -- ** then extract the first few alphanumeric characters from within that -- ** comment to be the zSelName value. Otherwise, the label is #N where -- ** is an integer that is incremented with each SELECT statement seen. -- */ -- if( yymsp[-8].minor.yy243!=0 ){ -- const char *z = s.z+6; -- int i; -- sqlite3_snprintf(sizeof(yymsp[-8].minor.yy243->zSelName), yymsp[-8].minor.yy243->zSelName, "#%d", -- ++pParse->nSelect); -- while( z[0]==' ' ) z++; -- if( z[0]=='/' && z[1]=='*' ){ -- z += 2; -- while( z[0]==' ' ) z++; -- for(i=0; sqlite3Isalnum(z[i]); i++){} -- sqlite3_snprintf(sizeof(yymsp[-8].minor.yy243->zSelName), yymsp[-8].minor.yy243->zSelName, "%.*s", i, z); -- } -+ yymsp[-8].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy420,yymsp[-5].minor.yy135,yymsp[-4].minor.yy18,yymsp[-3].minor.yy420,yymsp[-2].minor.yy18,yymsp[-1].minor.yy420,yymsp[-7].minor.yy70,yymsp[0].minor.yy18); -+} -+ break; -+ case 88: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ -+{ -+ yymsp[-9].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy420,yymsp[-6].minor.yy135,yymsp[-5].minor.yy18,yymsp[-4].minor.yy420,yymsp[-3].minor.yy18,yymsp[-1].minor.yy420,yymsp[-8].minor.yy70,yymsp[0].minor.yy18); -+ if( yymsp[-9].minor.yy489 ){ -+ yymsp[-9].minor.yy489->pWinDefn = yymsp[-2].minor.yy327; -+ }else{ -+ sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy327); - } --#endif /* SELECTRACE_ENABLED */ - } - break; -- case 85: /* values ::= VALUES LP nexprlist RP */ -+ case 89: /* values ::= VALUES LP nexprlist RP */ - { -- yymsp[-3].minor.yy243 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy148,0,0,0,0,0,SF_Values,0,0); -+ yymsp[-3].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values,0); - } - break; -- case 86: /* values ::= values COMMA LP exprlist RP */ -+ case 90: /* values ::= values COMMA LP nexprlist RP */ - { -- Select *pRight, *pLeft = yymsp[-4].minor.yy243; -- pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy148,0,0,0,0,0,SF_Values|SF_MultiValue,0,0); -+ Select *pRight, *pLeft = yymsp[-4].minor.yy489; -+ pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values|SF_MultiValue,0); - if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; - if( pRight ){ - pRight->op = TK_ALL; - pRight->pPrior = pLeft; -- yymsp[-4].minor.yy243 = pRight; -+ yymsp[-4].minor.yy489 = pRight; - }else{ -- yymsp[-4].minor.yy243 = pLeft; -+ yymsp[-4].minor.yy489 = pLeft; - } - } - break; -- case 87: /* distinct ::= DISTINCT */ --{yymsp[0].minor.yy194 = SF_Distinct;} -+ case 91: /* distinct ::= DISTINCT */ -+{yymsp[0].minor.yy70 = SF_Distinct;} - break; -- case 88: /* distinct ::= ALL */ --{yymsp[0].minor.yy194 = SF_All;} -+ case 92: /* distinct ::= ALL */ -+{yymsp[0].minor.yy70 = SF_All;} - break; -- case 90: /* sclp ::= */ -- case 118: /* orderby_opt ::= */ yytestcase(yyruleno==118); -- case 125: /* groupby_opt ::= */ yytestcase(yyruleno==125); -- case 200: /* exprlist ::= */ yytestcase(yyruleno==200); -- case 203: /* paren_exprlist ::= */ yytestcase(yyruleno==203); -- case 208: /* eidlist_opt ::= */ yytestcase(yyruleno==208); --{yymsp[1].minor.yy148 = 0;} -+ case 94: /* sclp ::= */ -+ case 127: /* orderby_opt ::= */ yytestcase(yyruleno==127); -+ case 134: /* groupby_opt ::= */ yytestcase(yyruleno==134); -+ case 214: /* exprlist ::= */ yytestcase(yyruleno==214); -+ case 217: /* paren_exprlist ::= */ yytestcase(yyruleno==217); -+ case 222: /* eidlist_opt ::= */ yytestcase(yyruleno==222); -+{yymsp[1].minor.yy420 = 0;} - break; -- case 91: /* selcollist ::= sclp expr as */ -+ case 95: /* selcollist ::= sclp scanpt expr scanpt as */ - { -- yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy148, yymsp[-1].minor.yy190.pExpr); -- if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-2].minor.yy148, &yymsp[0].minor.yy0, 1); -- sqlite3ExprListSetSpan(pParse,yymsp[-2].minor.yy148,&yymsp[-1].minor.yy190); -+ yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy420, yymsp[-2].minor.yy18); -+ if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy420, &yymsp[0].minor.yy0, 1); -+ sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy420,yymsp[-3].minor.yy392,yymsp[-1].minor.yy392); - } - break; -- case 92: /* selcollist ::= sclp STAR */ -+ case 96: /* selcollist ::= sclp scanpt STAR */ - { - Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); -- yymsp[-1].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy148, p); -+ yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy420, p); - } - break; -- case 93: /* selcollist ::= sclp nm DOT STAR */ -+ case 97: /* selcollist ::= sclp scanpt nm DOT STAR */ - { - Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); - Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); - Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); -- yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, pDot); -+ yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, pDot); - } - break; -- case 94: /* as ::= AS nm */ -- case 105: /* dbnm ::= DOT nm */ yytestcase(yyruleno==105); -- case 222: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==222); -- case 223: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==223); -+ case 98: /* as ::= AS nm */ -+ case 109: /* dbnm ::= DOT nm */ yytestcase(yyruleno==109); -+ case 236: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==236); -+ case 237: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==237); - {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} - break; -- case 96: /* from ::= */ --{yymsp[1].minor.yy185 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy185));} -+ case 100: /* from ::= */ -+{yymsp[1].minor.yy135 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy135));} - break; -- case 97: /* from ::= FROM seltablist */ -+ case 101: /* from ::= FROM seltablist */ - { -- yymsp[-1].minor.yy185 = yymsp[0].minor.yy185; -- sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy185); -+ yymsp[-1].minor.yy135 = yymsp[0].minor.yy135; -+ sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy135); - } - break; -- case 98: /* stl_prefix ::= seltablist joinop */ -+ case 102: /* stl_prefix ::= seltablist joinop */ - { -- if( ALWAYS(yymsp[-1].minor.yy185 && yymsp[-1].minor.yy185->nSrc>0) ) yymsp[-1].minor.yy185->a[yymsp[-1].minor.yy185->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy194; -+ if( ALWAYS(yymsp[-1].minor.yy135 && yymsp[-1].minor.yy135->nSrc>0) ) yymsp[-1].minor.yy135->a[yymsp[-1].minor.yy135->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy70; - } - break; -- case 99: /* stl_prefix ::= */ --{yymsp[1].minor.yy185 = 0;} -+ case 103: /* stl_prefix ::= */ -+{yymsp[1].minor.yy135 = 0;} - break; -- case 100: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ -+ case 104: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ - { -- yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254); -- sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy185, &yymsp[-2].minor.yy0); -+ yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48); -+ sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy135, &yymsp[-2].minor.yy0); - } - break; -- case 101: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ -+ case 105: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ - { -- yymsp[-8].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy185,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254); -- sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy185, yymsp[-4].minor.yy148); -+ yymsp[-8].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy135,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48); -+ sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy135, yymsp[-4].minor.yy420); - } - break; -- case 102: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ -+ case 106: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ - { -- yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy243,yymsp[-1].minor.yy72,yymsp[0].minor.yy254); -+ yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy489,yymsp[-1].minor.yy18,yymsp[0].minor.yy48); - } - break; -- case 103: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ -+ case 107: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ - { -- if( yymsp[-6].minor.yy185==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy72==0 && yymsp[0].minor.yy254==0 ){ -- yymsp[-6].minor.yy185 = yymsp[-4].minor.yy185; -- }else if( yymsp[-4].minor.yy185->nSrc==1 ){ -- yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254); -- if( yymsp[-6].minor.yy185 ){ -- struct SrcList_item *pNew = &yymsp[-6].minor.yy185->a[yymsp[-6].minor.yy185->nSrc-1]; -- struct SrcList_item *pOld = yymsp[-4].minor.yy185->a; -+ if( yymsp[-6].minor.yy135==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy18==0 && yymsp[0].minor.yy48==0 ){ -+ yymsp[-6].minor.yy135 = yymsp[-4].minor.yy135; -+ }else if( yymsp[-4].minor.yy135->nSrc==1 ){ -+ yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48); -+ if( yymsp[-6].minor.yy135 ){ -+ struct SrcList_item *pNew = &yymsp[-6].minor.yy135->a[yymsp[-6].minor.yy135->nSrc-1]; -+ struct SrcList_item *pOld = yymsp[-4].minor.yy135->a; - pNew->zName = pOld->zName; - pNew->zDatabase = pOld->zDatabase; - pNew->pSelect = pOld->pSelect; -@@ -139248,199 +149996,240 @@ - pOld->zName = pOld->zDatabase = 0; - pOld->pSelect = 0; - } -- sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy185); -+ sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy135); - }else{ - Select *pSubquery; -- sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy185); -- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy185,0,0,0,0,SF_NestedFrom,0,0); -- yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy72,yymsp[0].minor.yy254); -+ sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy135); -+ pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy135,0,0,0,0,SF_NestedFrom,0); -+ yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy18,yymsp[0].minor.yy48); - } - } - break; -- case 104: /* dbnm ::= */ -- case 113: /* indexed_opt ::= */ yytestcase(yyruleno==113); -+ case 108: /* dbnm ::= */ -+ case 122: /* indexed_opt ::= */ yytestcase(yyruleno==122); - {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;} - break; -- case 106: /* fullname ::= nm dbnm */ --{yymsp[-1].minor.yy185 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} -+ case 110: /* fullname ::= nm */ -+{ -+ yylhsminor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0); -+ if( IN_RENAME_OBJECT && yylhsminor.yy135 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy135->a[0].zName, &yymsp[0].minor.yy0); -+} -+ yymsp[0].minor.yy135 = yylhsminor.yy135; - break; -- case 107: /* joinop ::= COMMA|JOIN */ --{ yymsp[0].minor.yy194 = JT_INNER; } -+ case 111: /* fullname ::= nm DOT nm */ -+{ -+ yylhsminor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); -+ if( IN_RENAME_OBJECT && yylhsminor.yy135 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy135->a[0].zName, &yymsp[0].minor.yy0); -+} -+ yymsp[-2].minor.yy135 = yylhsminor.yy135; - break; -- case 108: /* joinop ::= JOIN_KW JOIN */ --{yymsp[-1].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} -+ case 112: /* xfullname ::= nm */ -+{yymsp[0].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} - break; -- case 109: /* joinop ::= JOIN_KW nm JOIN */ --{yymsp[-2].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} -+ case 113: /* xfullname ::= nm DOT nm */ -+{yymsp[-2].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} - break; -- case 110: /* joinop ::= JOIN_KW nm nm JOIN */ --{yymsp[-3].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} -+ case 114: /* xfullname ::= nm DOT nm AS nm */ -+{ -+ yymsp[-4].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ -+ if( yymsp[-4].minor.yy135 ) yymsp[-4].minor.yy135->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); -+} - break; -- case 111: /* on_opt ::= ON expr */ -- case 128: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==128); -- case 135: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==135); -- case 196: /* case_else ::= ELSE expr */ yytestcase(yyruleno==196); --{yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr;} -+ case 115: /* xfullname ::= nm AS nm */ -+{ -+ yymsp[-2].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ -+ if( yymsp[-2].minor.yy135 ) yymsp[-2].minor.yy135->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); -+} - break; -- case 112: /* on_opt ::= */ -- case 127: /* having_opt ::= */ yytestcase(yyruleno==127); -- case 134: /* where_opt ::= */ yytestcase(yyruleno==134); -- case 197: /* case_else ::= */ yytestcase(yyruleno==197); -- case 199: /* case_operand ::= */ yytestcase(yyruleno==199); --{yymsp[1].minor.yy72 = 0;} -+ case 116: /* joinop ::= COMMA|JOIN */ -+{ yymsp[0].minor.yy70 = JT_INNER; } - break; -- case 114: /* indexed_opt ::= INDEXED BY nm */ -+ case 117: /* joinop ::= JOIN_KW JOIN */ -+{yymsp[-1].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} -+ break; -+ case 118: /* joinop ::= JOIN_KW nm JOIN */ -+{yymsp[-2].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} -+ break; -+ case 119: /* joinop ::= JOIN_KW nm nm JOIN */ -+{yymsp[-3].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} -+ break; -+ case 120: /* on_opt ::= ON expr */ -+ case 137: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==137); -+ case 144: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==144); -+ case 210: /* case_else ::= ELSE expr */ yytestcase(yyruleno==210); -+{yymsp[-1].minor.yy18 = yymsp[0].minor.yy18;} -+ break; -+ case 121: /* on_opt ::= */ -+ case 136: /* having_opt ::= */ yytestcase(yyruleno==136); -+ case 138: /* limit_opt ::= */ yytestcase(yyruleno==138); -+ case 143: /* where_opt ::= */ yytestcase(yyruleno==143); -+ case 211: /* case_else ::= */ yytestcase(yyruleno==211); -+ case 213: /* case_operand ::= */ yytestcase(yyruleno==213); -+{yymsp[1].minor.yy18 = 0;} -+ break; -+ case 123: /* indexed_opt ::= INDEXED BY nm */ - {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} - break; -- case 115: /* indexed_opt ::= NOT INDEXED */ -+ case 124: /* indexed_opt ::= NOT INDEXED */ - {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;} - break; -- case 116: /* using_opt ::= USING LP idlist RP */ --{yymsp[-3].minor.yy254 = yymsp[-1].minor.yy254;} -+ case 125: /* using_opt ::= USING LP idlist RP */ -+{yymsp[-3].minor.yy48 = yymsp[-1].minor.yy48;} - break; -- case 117: /* using_opt ::= */ -- case 145: /* idlist_opt ::= */ yytestcase(yyruleno==145); --{yymsp[1].minor.yy254 = 0;} -+ case 126: /* using_opt ::= */ -+ case 158: /* idlist_opt ::= */ yytestcase(yyruleno==158); -+{yymsp[1].minor.yy48 = 0;} - break; -- case 119: /* orderby_opt ::= ORDER BY sortlist */ -- case 126: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==126); --{yymsp[-2].minor.yy148 = yymsp[0].minor.yy148;} -+ case 128: /* orderby_opt ::= ORDER BY sortlist */ -+ case 135: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==135); -+{yymsp[-2].minor.yy420 = yymsp[0].minor.yy420;} - break; -- case 120: /* sortlist ::= sortlist COMMA expr sortorder */ -+ case 129: /* sortlist ::= sortlist COMMA expr sortorder */ - { -- yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148,yymsp[-1].minor.yy190.pExpr); -- sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy148,yymsp[0].minor.yy194); -+ yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy420,yymsp[-1].minor.yy18); -+ sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy420,yymsp[0].minor.yy70); - } - break; -- case 121: /* sortlist ::= expr sortorder */ -+ case 130: /* sortlist ::= expr sortorder */ - { -- yymsp[-1].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy190.pExpr); /*A-overwrites-Y*/ -- sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy148,yymsp[0].minor.yy194); -+ yymsp[-1].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy18); /*A-overwrites-Y*/ -+ sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy420,yymsp[0].minor.yy70); - } - break; -- case 122: /* sortorder ::= ASC */ --{yymsp[0].minor.yy194 = SQLITE_SO_ASC;} -+ case 131: /* sortorder ::= ASC */ -+{yymsp[0].minor.yy70 = SQLITE_SO_ASC;} - break; -- case 123: /* sortorder ::= DESC */ --{yymsp[0].minor.yy194 = SQLITE_SO_DESC;} -+ case 132: /* sortorder ::= DESC */ -+{yymsp[0].minor.yy70 = SQLITE_SO_DESC;} - break; -- case 124: /* sortorder ::= */ --{yymsp[1].minor.yy194 = SQLITE_SO_UNDEFINED;} -+ case 133: /* sortorder ::= */ -+{yymsp[1].minor.yy70 = SQLITE_SO_UNDEFINED;} - break; -- case 129: /* limit_opt ::= */ --{yymsp[1].minor.yy354.pLimit = 0; yymsp[1].minor.yy354.pOffset = 0;} -+ case 139: /* limit_opt ::= LIMIT expr */ -+{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,0);} - break; -- case 130: /* limit_opt ::= LIMIT expr */ --{yymsp[-1].minor.yy354.pLimit = yymsp[0].minor.yy190.pExpr; yymsp[-1].minor.yy354.pOffset = 0;} -+ case 140: /* limit_opt ::= LIMIT expr OFFSET expr */ -+{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);} - break; -- case 131: /* limit_opt ::= LIMIT expr OFFSET expr */ --{yymsp[-3].minor.yy354.pLimit = yymsp[-2].minor.yy190.pExpr; yymsp[-3].minor.yy354.pOffset = yymsp[0].minor.yy190.pExpr;} -+ case 141: /* limit_opt ::= LIMIT expr COMMA expr */ -+{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,yymsp[-2].minor.yy18);} - break; -- case 132: /* limit_opt ::= LIMIT expr COMMA expr */ --{yymsp[-3].minor.yy354.pOffset = yymsp[-2].minor.yy190.pExpr; yymsp[-3].minor.yy354.pLimit = yymsp[0].minor.yy190.pExpr;} -- break; -- case 133: /* cmd ::= with DELETE FROM fullname indexed_opt where_opt */ -+ case 142: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ - { -- sqlite3WithPush(pParse, yymsp[-5].minor.yy285, 1); -- sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy185, &yymsp[-1].minor.yy0); -- sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy185,yymsp[0].minor.yy72); -+ sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy135, &yymsp[-1].minor.yy0); -+ sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy135,yymsp[0].minor.yy18,0,0); - } - break; -- case 136: /* cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt */ -+ case 145: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */ - { -- sqlite3WithPush(pParse, yymsp[-7].minor.yy285, 1); -- sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy185, &yymsp[-3].minor.yy0); -- sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy148,"set list"); -- sqlite3Update(pParse,yymsp[-4].minor.yy185,yymsp[-1].minor.yy148,yymsp[0].minor.yy72,yymsp[-5].minor.yy194); -+ sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy135, &yymsp[-3].minor.yy0); -+ sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy420,"set list"); -+ sqlite3Update(pParse,yymsp[-4].minor.yy135,yymsp[-1].minor.yy420,yymsp[0].minor.yy18,yymsp[-5].minor.yy70,0,0,0); - } - break; -- case 137: /* setlist ::= setlist COMMA nm EQ expr */ -+ case 146: /* setlist ::= setlist COMMA nm EQ expr */ - { -- yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr); -- sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy148, &yymsp[-2].minor.yy0, 1); -+ yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy420, yymsp[0].minor.yy18); -+ sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy420, &yymsp[-2].minor.yy0, 1); - } - break; -- case 138: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ -+ case 147: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ - { -- yymsp[-6].minor.yy148 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy148, yymsp[-3].minor.yy254, yymsp[0].minor.yy190.pExpr); -+ yymsp[-6].minor.yy420 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy420, yymsp[-3].minor.yy48, yymsp[0].minor.yy18); - } - break; -- case 139: /* setlist ::= nm EQ expr */ -+ case 148: /* setlist ::= nm EQ expr */ - { -- yylhsminor.yy148 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy190.pExpr); -- sqlite3ExprListSetName(pParse, yylhsminor.yy148, &yymsp[-2].minor.yy0, 1); -+ yylhsminor.yy420 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy18); -+ sqlite3ExprListSetName(pParse, yylhsminor.yy420, &yymsp[-2].minor.yy0, 1); - } -- yymsp[-2].minor.yy148 = yylhsminor.yy148; -+ yymsp[-2].minor.yy420 = yylhsminor.yy420; - break; -- case 140: /* setlist ::= LP idlist RP EQ expr */ -+ case 149: /* setlist ::= LP idlist RP EQ expr */ - { -- yymsp[-4].minor.yy148 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy254, yymsp[0].minor.yy190.pExpr); -+ yymsp[-4].minor.yy420 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy48, yymsp[0].minor.yy18); - } - break; -- case 141: /* cmd ::= with insert_cmd INTO fullname idlist_opt select */ -+ case 150: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ - { -- sqlite3WithPush(pParse, yymsp[-5].minor.yy285, 1); -- sqlite3Insert(pParse, yymsp[-2].minor.yy185, yymsp[0].minor.yy243, yymsp[-1].minor.yy254, yymsp[-4].minor.yy194); -+ sqlite3Insert(pParse, yymsp[-3].minor.yy135, yymsp[-1].minor.yy489, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, yymsp[0].minor.yy340); - } - break; -- case 142: /* cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES */ -+ case 151: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ - { -- sqlite3WithPush(pParse, yymsp[-6].minor.yy285, 1); -- sqlite3Insert(pParse, yymsp[-3].minor.yy185, 0, yymsp[-2].minor.yy254, yymsp[-5].minor.yy194); -+ sqlite3Insert(pParse, yymsp[-3].minor.yy135, 0, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, 0); - } - break; -- case 146: /* idlist_opt ::= LP idlist RP */ --{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;} -+ case 152: /* upsert ::= */ -+{ yymsp[1].minor.yy340 = 0; } - break; -- case 147: /* idlist ::= idlist COMMA nm */ --{yymsp[-2].minor.yy254 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);} -+ case 153: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ -+{ yymsp[-10].minor.yy340 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy420,yymsp[-5].minor.yy18,yymsp[-1].minor.yy420,yymsp[0].minor.yy18);} - break; -- case 148: /* idlist ::= nm */ --{yymsp[0].minor.yy254 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} -+ case 154: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ -+{ yymsp[-7].minor.yy340 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy420,yymsp[-2].minor.yy18,0,0); } - break; -- case 149: /* expr ::= LP expr RP */ --{spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/ yymsp[-2].minor.yy190.pExpr = yymsp[-1].minor.yy190.pExpr;} -+ case 155: /* upsert ::= ON CONFLICT DO NOTHING */ -+{ yymsp[-3].minor.yy340 = sqlite3UpsertNew(pParse->db,0,0,0,0); } - break; -- case 150: /* expr ::= ID|INDEXED */ -- case 151: /* expr ::= JOIN_KW */ yytestcase(yyruleno==151); --{spanExpr(&yymsp[0].minor.yy190,pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} -+ case 159: /* idlist_opt ::= LP idlist RP */ -+{yymsp[-2].minor.yy48 = yymsp[-1].minor.yy48;} - break; -- case 152: /* expr ::= nm DOT nm */ -+ case 160: /* idlist ::= idlist COMMA nm */ -+{yymsp[-2].minor.yy48 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy48,&yymsp[0].minor.yy0);} -+ break; -+ case 161: /* idlist ::= nm */ -+{yymsp[0].minor.yy48 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} -+ break; -+ case 162: /* expr ::= LP expr RP */ -+{yymsp[-2].minor.yy18 = yymsp[-1].minor.yy18;} -+ break; -+ case 163: /* expr ::= ID|INDEXED */ -+ case 164: /* expr ::= JOIN_KW */ yytestcase(yyruleno==164); -+{yymsp[0].minor.yy18=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} -+ break; -+ case 165: /* expr ::= nm DOT nm */ - { - Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); - Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1); -- spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/ -- yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); -+ if( IN_RENAME_OBJECT ){ -+ sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0); -+ sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0); -+ } -+ yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); - } -+ yymsp[-2].minor.yy18 = yylhsminor.yy18; - break; -- case 153: /* expr ::= nm DOT nm DOT nm */ -+ case 166: /* expr ::= nm DOT nm DOT nm */ - { - Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1); - Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); - Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1); - Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3); -- spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/ -- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); -+ if( IN_RENAME_OBJECT ){ -+ sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0); -+ sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0); -+ } -+ yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); - } -+ yymsp[-4].minor.yy18 = yylhsminor.yy18; - break; -- case 154: /* term ::= NULL|FLOAT|BLOB */ -- case 155: /* term ::= STRING */ yytestcase(yyruleno==155); --{spanExpr(&yymsp[0].minor.yy190,pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} -+ case 167: /* term ::= NULL|FLOAT|BLOB */ -+ case 168: /* term ::= STRING */ yytestcase(yyruleno==168); -+{yymsp[0].minor.yy18=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} - break; -- case 156: /* term ::= INTEGER */ -+ case 169: /* term ::= INTEGER */ - { -- yylhsminor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); -- yylhsminor.yy190.zStart = yymsp[0].minor.yy0.z; -- yylhsminor.yy190.zEnd = yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n; -+ yylhsminor.yy18 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); - } -- yymsp[0].minor.yy190 = yylhsminor.yy190; -+ yymsp[0].minor.yy18 = yylhsminor.yy18; - break; -- case 157: /* expr ::= VARIABLE */ -+ case 170: /* expr ::= VARIABLE */ - { - if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ - u32 n = yymsp[0].minor.yy0.n; -- spanExpr(&yymsp[0].minor.yy190, pParse, TK_VARIABLE, yymsp[0].minor.yy0); -- sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy190.pExpr, n); -+ yymsp[0].minor.yy18 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); -+ sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy18, n); - }else{ - /* When doing a nested parse, one can include terms in an expression - ** that look like this: #1 #2 ... These terms refer to registers -@@ -139447,159 +150236,156 @@ - ** in the virtual machine. #N is the N-th register. */ - Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/ - assert( t.n>=2 ); -- spanSet(&yymsp[0].minor.yy190, &t, &t); - if( pParse->nested==0 ){ - sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); -- yymsp[0].minor.yy190.pExpr = 0; -+ yymsp[0].minor.yy18 = 0; - }else{ -- yymsp[0].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); -- if( yymsp[0].minor.yy190.pExpr ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy190.pExpr->iTable); -+ yymsp[0].minor.yy18 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); -+ if( yymsp[0].minor.yy18 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy18->iTable); - } - } - } - break; -- case 158: /* expr ::= expr COLLATE ID|STRING */ -+ case 171: /* expr ::= expr COLLATE ID|STRING */ - { -- yymsp[-2].minor.yy190.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy190.pExpr, &yymsp[0].minor.yy0, 1); -- yymsp[-2].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; -+ yymsp[-2].minor.yy18 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy18, &yymsp[0].minor.yy0, 1); - } - break; -- case 159: /* expr ::= CAST LP expr AS typetoken RP */ -+ case 172: /* expr ::= CAST LP expr AS typetoken RP */ - { -- spanSet(&yymsp[-5].minor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/ -- yymsp[-5].minor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); -- sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy190.pExpr, yymsp[-3].minor.yy190.pExpr, 0); -+ yymsp[-5].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); -+ sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy18, yymsp[-3].minor.yy18, 0); - } - break; -- case 160: /* expr ::= ID|INDEXED LP distinct exprlist RP */ -+ case 173: /* expr ::= ID|INDEXED LP distinct exprlist RP */ - { -- if( yymsp[-1].minor.yy148 && yymsp[-1].minor.yy148->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ -- sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0); -- } -- yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy148, &yymsp[-4].minor.yy0); -- spanSet(&yylhsminor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); -- if( yymsp[-2].minor.yy194==SF_Distinct && yylhsminor.yy190.pExpr ){ -- yylhsminor.yy190.pExpr->flags |= EP_Distinct; -- } -+ yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy420, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy70); - } -- yymsp[-4].minor.yy190 = yylhsminor.yy190; -+ yymsp[-4].minor.yy18 = yylhsminor.yy18; - break; -- case 161: /* expr ::= ID|INDEXED LP STAR RP */ -+ case 174: /* expr ::= ID|INDEXED LP STAR RP */ - { -- yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0); -- spanSet(&yylhsminor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); -+ yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); - } -- yymsp[-3].minor.yy190 = yylhsminor.yy190; -+ yymsp[-3].minor.yy18 = yylhsminor.yy18; - break; -- case 162: /* term ::= CTIME_KW */ -+ case 175: /* expr ::= ID|INDEXED LP distinct exprlist RP over_clause */ - { -- yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0); -- spanSet(&yylhsminor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); -+ yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy420, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy70); -+ sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327); - } -- yymsp[0].minor.yy190 = yylhsminor.yy190; -+ yymsp[-5].minor.yy18 = yylhsminor.yy18; - break; -- case 163: /* expr ::= LP nexprlist COMMA expr RP */ -+ case 176: /* expr ::= ID|INDEXED LP STAR RP over_clause */ - { -- ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy148, yymsp[-1].minor.yy190.pExpr); -- yylhsminor.yy190.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); -- if( yylhsminor.yy190.pExpr ){ -- yylhsminor.yy190.pExpr->x.pList = pList; -- spanSet(&yylhsminor.yy190, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0); -+ yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); -+ sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327); -+} -+ yymsp[-4].minor.yy18 = yylhsminor.yy18; -+ break; -+ case 177: /* term ::= CTIME_KW */ -+{ -+ yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); -+} -+ yymsp[0].minor.yy18 = yylhsminor.yy18; -+ break; -+ case 178: /* expr ::= LP nexprlist COMMA expr RP */ -+{ -+ ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy420, yymsp[-1].minor.yy18); -+ yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); -+ if( yymsp[-4].minor.yy18 ){ -+ yymsp[-4].minor.yy18->x.pList = pList; - }else{ - sqlite3ExprListDelete(pParse->db, pList); - } - } -- yymsp[-4].minor.yy190 = yylhsminor.yy190; - break; -- case 164: /* expr ::= expr AND expr */ -- case 165: /* expr ::= expr OR expr */ yytestcase(yyruleno==165); -- case 166: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==166); -- case 167: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==167); -- case 168: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==168); -- case 169: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==169); -- case 170: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==170); -- case 171: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==171); --{spanBinaryExpr(pParse,yymsp[-1].major,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);} -+ case 179: /* expr ::= expr AND expr */ -+ case 180: /* expr ::= expr OR expr */ yytestcase(yyruleno==180); -+ case 181: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==181); -+ case 182: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==182); -+ case 183: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==183); -+ case 184: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==184); -+ case 185: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==185); -+ case 186: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==186); -+{yymsp[-2].minor.yy18=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);} - break; -- case 172: /* likeop ::= NOT LIKE_KW|MATCH */ -+ case 187: /* likeop ::= NOT LIKE_KW|MATCH */ - {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} - break; -- case 173: /* expr ::= expr likeop expr */ -+ case 188: /* expr ::= expr likeop expr */ - { - ExprList *pList; - int bNot = yymsp[-1].minor.yy0.n & 0x80000000; - yymsp[-1].minor.yy0.n &= 0x7fffffff; -- pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy190.pExpr); -- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy190.pExpr); -- yymsp[-2].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0); -- exprNot(pParse, bNot, &yymsp[-2].minor.yy190); -- yymsp[-2].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd; -- if( yymsp[-2].minor.yy190.pExpr ) yymsp[-2].minor.yy190.pExpr->flags |= EP_InfixFunc; -+ pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy18); -+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy18); -+ yymsp[-2].minor.yy18 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); -+ if( bNot ) yymsp[-2].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy18, 0); -+ if( yymsp[-2].minor.yy18 ) yymsp[-2].minor.yy18->flags |= EP_InfixFunc; - } - break; -- case 174: /* expr ::= expr likeop expr ESCAPE expr */ -+ case 189: /* expr ::= expr likeop expr ESCAPE expr */ - { - ExprList *pList; - int bNot = yymsp[-3].minor.yy0.n & 0x80000000; - yymsp[-3].minor.yy0.n &= 0x7fffffff; -- pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr); -- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy190.pExpr); -- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr); -- yymsp[-4].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0); -- exprNot(pParse, bNot, &yymsp[-4].minor.yy190); -- yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd; -- if( yymsp[-4].minor.yy190.pExpr ) yymsp[-4].minor.yy190.pExpr->flags |= EP_InfixFunc; -+ pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18); -+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy18); -+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy18); -+ yymsp[-4].minor.yy18 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); -+ if( bNot ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0); -+ if( yymsp[-4].minor.yy18 ) yymsp[-4].minor.yy18->flags |= EP_InfixFunc; - } - break; -- case 175: /* expr ::= expr ISNULL|NOTNULL */ --{spanUnaryPostfix(pParse,yymsp[0].major,&yymsp[-1].minor.yy190,&yymsp[0].minor.yy0);} -+ case 190: /* expr ::= expr ISNULL|NOTNULL */ -+{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy18,0);} - break; -- case 176: /* expr ::= expr NOT NULL */ --{spanUnaryPostfix(pParse,TK_NOTNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);} -+ case 191: /* expr ::= expr NOT NULL */ -+{yymsp[-2].minor.yy18 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy18,0);} - break; -- case 177: /* expr ::= expr IS expr */ -+ case 192: /* expr ::= expr IS expr */ - { -- spanBinaryExpr(pParse,TK_IS,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190); -- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-2].minor.yy190.pExpr, TK_ISNULL); -+ yymsp[-2].minor.yy18 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy18,yymsp[0].minor.yy18); -+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy18, yymsp[-2].minor.yy18, TK_ISNULL); - } - break; -- case 178: /* expr ::= expr IS NOT expr */ -+ case 193: /* expr ::= expr IS NOT expr */ - { -- spanBinaryExpr(pParse,TK_ISNOT,&yymsp[-3].minor.yy190,&yymsp[0].minor.yy190); -- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-3].minor.yy190.pExpr, TK_NOTNULL); -+ yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy18,yymsp[0].minor.yy18); -+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy18, yymsp[-3].minor.yy18, TK_NOTNULL); - } - break; -- case 179: /* expr ::= NOT expr */ -- case 180: /* expr ::= BITNOT expr */ yytestcase(yyruleno==180); --{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,yymsp[-1].major,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/} -+ case 194: /* expr ::= NOT expr */ -+ case 195: /* expr ::= BITNOT expr */ yytestcase(yyruleno==195); -+{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy18, 0);/*A-overwrites-B*/} - break; -- case 181: /* expr ::= MINUS expr */ --{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UMINUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/} -+ case 196: /* expr ::= PLUS|MINUS expr */ -+{ -+ yymsp[-1].minor.yy18 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy18, 0); -+ /*A-overwrites-B*/ -+} - break; -- case 182: /* expr ::= PLUS expr */ --{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UPLUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/} -+ case 197: /* between_op ::= BETWEEN */ -+ case 200: /* in_op ::= IN */ yytestcase(yyruleno==200); -+{yymsp[0].minor.yy70 = 0;} - break; -- case 183: /* between_op ::= BETWEEN */ -- case 186: /* in_op ::= IN */ yytestcase(yyruleno==186); --{yymsp[0].minor.yy194 = 0;} -- break; -- case 185: /* expr ::= expr between_op expr AND expr */ -+ case 199: /* expr ::= expr between_op expr AND expr */ - { -- ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr); -- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr); -- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy190.pExpr, 0); -- if( yymsp[-4].minor.yy190.pExpr ){ -- yymsp[-4].minor.yy190.pExpr->x.pList = pList; -+ ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18); -+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy18); -+ yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy18, 0); -+ if( yymsp[-4].minor.yy18 ){ -+ yymsp[-4].minor.yy18->x.pList = pList; - }else{ - sqlite3ExprListDelete(pParse->db, pList); - } -- exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190); -- yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd; -+ if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0); - } - break; -- case 188: /* expr ::= expr in_op LP exprlist RP */ -+ case 202: /* expr ::= expr in_op LP exprlist RP */ - { -- if( yymsp[-1].minor.yy148==0 ){ -+ if( yymsp[-1].minor.yy420==0 ){ - /* Expressions of the form - ** - ** expr1 IN () -@@ -139608,9 +150394,9 @@ - ** simplify to constants 0 (false) and 1 (true), respectively, - ** regardless of the value of expr1. - */ -- sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy190.pExpr); -- yymsp[-4].minor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy194],1); -- }else if( yymsp[-1].minor.yy148->nExpr==1 ){ -+ sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy18); -+ yymsp[-4].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy70],1); -+ }else if( yymsp[-1].minor.yy420->nExpr==1 ){ - /* Expressions of the form: - ** - ** expr1 IN (?1) -@@ -139627,9 +150413,9 @@ - ** affinity or the collating sequence to use for comparison. Otherwise, - ** the semantics would be subtly different from IN or NOT IN. - */ -- Expr *pRHS = yymsp[-1].minor.yy148->a[0].pExpr; -- yymsp[-1].minor.yy148->a[0].pExpr = 0; -- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148); -+ Expr *pRHS = yymsp[-1].minor.yy420->a[0].pExpr; -+ yymsp[-1].minor.yy420->a[0].pExpr = 0; -+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420); - /* pRHS cannot be NULL because a malloc error would have been detected - ** before now and control would have never reached this point */ - if( ALWAYS(pRHS) ){ -@@ -139636,192 +150422,190 @@ - pRHS->flags &= ~EP_Collate; - pRHS->flags |= EP_Generic; - } -- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, yymsp[-3].minor.yy194 ? TK_NE : TK_EQ, yymsp[-4].minor.yy190.pExpr, pRHS); -+ yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, yymsp[-3].minor.yy70 ? TK_NE : TK_EQ, yymsp[-4].minor.yy18, pRHS); - }else{ -- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0); -- if( yymsp[-4].minor.yy190.pExpr ){ -- yymsp[-4].minor.yy190.pExpr->x.pList = yymsp[-1].minor.yy148; -- sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy190.pExpr); -+ yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0); -+ if( yymsp[-4].minor.yy18 ){ -+ yymsp[-4].minor.yy18->x.pList = yymsp[-1].minor.yy420; -+ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy18); - }else{ -- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148); -+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420); - } -- exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190); -+ if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0); - } -- yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; - } - break; -- case 189: /* expr ::= LP select RP */ -+ case 203: /* expr ::= LP select RP */ - { -- spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/ -- yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0); -- sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy190.pExpr, yymsp[-1].minor.yy243); -+ yymsp[-2].minor.yy18 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); -+ sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy18, yymsp[-1].minor.yy489); - } - break; -- case 190: /* expr ::= expr in_op LP select RP */ -+ case 204: /* expr ::= expr in_op LP select RP */ - { -- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0); -- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy190.pExpr, yymsp[-1].minor.yy243); -- exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190); -- yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; -+ yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0); -+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy18, yymsp[-1].minor.yy489); -+ if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0); - } - break; -- case 191: /* expr ::= expr in_op nm dbnm paren_exprlist */ -+ case 205: /* expr ::= expr in_op nm dbnm paren_exprlist */ - { - SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); -- Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); -- if( yymsp[0].minor.yy148 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy148); -- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0); -- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy190.pExpr, pSelect); -- exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190); -- yymsp[-4].minor.yy190.zEnd = yymsp[-1].minor.yy0.z ? &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n] : &yymsp[-2].minor.yy0.z[yymsp[-2].minor.yy0.n]; -+ Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); -+ if( yymsp[0].minor.yy420 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy420); -+ yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0); -+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy18, pSelect); -+ if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0); - } - break; -- case 192: /* expr ::= EXISTS LP select RP */ -+ case 206: /* expr ::= EXISTS LP select RP */ - { - Expr *p; -- spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/ -- p = yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); -- sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy243); -+ p = yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); -+ sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy489); - } - break; -- case 193: /* expr ::= CASE case_operand case_exprlist case_else END */ -+ case 207: /* expr ::= CASE case_operand case_exprlist case_else END */ - { -- spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-C*/ -- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy72, 0); -- if( yymsp[-4].minor.yy190.pExpr ){ -- yymsp[-4].minor.yy190.pExpr->x.pList = yymsp[-1].minor.yy72 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[-1].minor.yy72) : yymsp[-2].minor.yy148; -- sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy190.pExpr); -+ yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy18, 0); -+ if( yymsp[-4].minor.yy18 ){ -+ yymsp[-4].minor.yy18->x.pList = yymsp[-1].minor.yy18 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy420,yymsp[-1].minor.yy18) : yymsp[-2].minor.yy420; -+ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy18); - }else{ -- sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy148); -- sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy72); -+ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy420); -+ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy18); - } - } - break; -- case 194: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ -+ case 208: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ - { -- yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[-2].minor.yy190.pExpr); -- yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr); -+ yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, yymsp[-2].minor.yy18); -+ yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, yymsp[0].minor.yy18); - } - break; -- case 195: /* case_exprlist ::= WHEN expr THEN expr */ -+ case 209: /* case_exprlist ::= WHEN expr THEN expr */ - { -- yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr); -- yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, yymsp[0].minor.yy190.pExpr); -+ yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18); -+ yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy420, yymsp[0].minor.yy18); - } - break; -- case 198: /* case_operand ::= expr */ --{yymsp[0].minor.yy72 = yymsp[0].minor.yy190.pExpr; /*A-overwrites-X*/} -+ case 212: /* case_operand ::= expr */ -+{yymsp[0].minor.yy18 = yymsp[0].minor.yy18; /*A-overwrites-X*/} - break; -- case 201: /* nexprlist ::= nexprlist COMMA expr */ --{yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy190.pExpr);} -+ case 215: /* nexprlist ::= nexprlist COMMA expr */ -+{yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy420,yymsp[0].minor.yy18);} - break; -- case 202: /* nexprlist ::= expr */ --{yymsp[0].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy190.pExpr); /*A-overwrites-Y*/} -+ case 216: /* nexprlist ::= expr */ -+{yymsp[0].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy18); /*A-overwrites-Y*/} - break; -- case 204: /* paren_exprlist ::= LP exprlist RP */ -- case 209: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==209); --{yymsp[-2].minor.yy148 = yymsp[-1].minor.yy148;} -+ case 218: /* paren_exprlist ::= LP exprlist RP */ -+ case 223: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==223); -+{yymsp[-2].minor.yy420 = yymsp[-1].minor.yy420;} - break; -- case 205: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ -+ case 219: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - { - sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, -- sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy148, yymsp[-10].minor.yy194, -- &yymsp[-11].minor.yy0, yymsp[0].minor.yy72, SQLITE_SO_ASC, yymsp[-8].minor.yy194, SQLITE_IDXTYPE_APPDEF); -+ sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy420, yymsp[-10].minor.yy70, -+ &yymsp[-11].minor.yy0, yymsp[0].minor.yy18, SQLITE_SO_ASC, yymsp[-8].minor.yy70, SQLITE_IDXTYPE_APPDEF); -+ if( IN_RENAME_OBJECT && pParse->pNewIndex ){ -+ sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); -+ } - } - break; -- case 206: /* uniqueflag ::= UNIQUE */ -- case 246: /* raisetype ::= ABORT */ yytestcase(yyruleno==246); --{yymsp[0].minor.yy194 = OE_Abort;} -+ case 220: /* uniqueflag ::= UNIQUE */ -+ case 260: /* raisetype ::= ABORT */ yytestcase(yyruleno==260); -+{yymsp[0].minor.yy70 = OE_Abort;} - break; -- case 207: /* uniqueflag ::= */ --{yymsp[1].minor.yy194 = OE_None;} -+ case 221: /* uniqueflag ::= */ -+{yymsp[1].minor.yy70 = OE_None;} - break; -- case 210: /* eidlist ::= eidlist COMMA nm collate sortorder */ -+ case 224: /* eidlist ::= eidlist COMMA nm collate sortorder */ - { -- yymsp[-4].minor.yy148 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy148, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194); -+ yymsp[-4].minor.yy420 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy420, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70); - } - break; -- case 211: /* eidlist ::= nm collate sortorder */ -+ case 225: /* eidlist ::= nm collate sortorder */ - { -- yymsp[-2].minor.yy148 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194); /*A-overwrites-Y*/ -+ yymsp[-2].minor.yy420 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70); /*A-overwrites-Y*/ - } - break; -- case 214: /* cmd ::= DROP INDEX ifexists fullname */ --{sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);} -+ case 228: /* cmd ::= DROP INDEX ifexists fullname */ -+{sqlite3DropIndex(pParse, yymsp[0].minor.yy135, yymsp[-1].minor.yy70);} - break; -- case 215: /* cmd ::= VACUUM */ -+ case 229: /* cmd ::= VACUUM */ - {sqlite3Vacuum(pParse,0);} - break; -- case 216: /* cmd ::= VACUUM nm */ -+ case 230: /* cmd ::= VACUUM nm */ - {sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);} - break; -- case 217: /* cmd ::= PRAGMA nm dbnm */ -+ case 231: /* cmd ::= PRAGMA nm dbnm */ - {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} - break; -- case 218: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ -+ case 232: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ - {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} - break; -- case 219: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ -+ case 233: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ - {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} - break; -- case 220: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ -+ case 234: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ - {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} - break; -- case 221: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ -+ case 235: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ - {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} - break; -- case 224: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ -+ case 238: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - { - Token all; - all.z = yymsp[-3].minor.yy0.z; - all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; -- sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy145, &all); -+ sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy207, &all); - } - break; -- case 225: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ -+ case 239: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - { -- sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy194, yymsp[-4].minor.yy332.a, yymsp[-4].minor.yy332.b, yymsp[-2].minor.yy185, yymsp[0].minor.yy72, yymsp[-10].minor.yy194, yymsp[-8].minor.yy194); -+ sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy70, yymsp[-4].minor.yy34.a, yymsp[-4].minor.yy34.b, yymsp[-2].minor.yy135, yymsp[0].minor.yy18, yymsp[-10].minor.yy70, yymsp[-8].minor.yy70); - yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ - } - break; -- case 226: /* trigger_time ::= BEFORE|AFTER */ --{ yymsp[0].minor.yy194 = yymsp[0].major; /*A-overwrites-X*/ } -+ case 240: /* trigger_time ::= BEFORE|AFTER */ -+{ yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/ } - break; -- case 227: /* trigger_time ::= INSTEAD OF */ --{ yymsp[-1].minor.yy194 = TK_INSTEAD;} -+ case 241: /* trigger_time ::= INSTEAD OF */ -+{ yymsp[-1].minor.yy70 = TK_INSTEAD;} - break; -- case 228: /* trigger_time ::= */ --{ yymsp[1].minor.yy194 = TK_BEFORE; } -+ case 242: /* trigger_time ::= */ -+{ yymsp[1].minor.yy70 = TK_BEFORE; } - break; -- case 229: /* trigger_event ::= DELETE|INSERT */ -- case 230: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==230); --{yymsp[0].minor.yy332.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy332.b = 0;} -+ case 243: /* trigger_event ::= DELETE|INSERT */ -+ case 244: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==244); -+{yymsp[0].minor.yy34.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy34.b = 0;} - break; -- case 231: /* trigger_event ::= UPDATE OF idlist */ --{yymsp[-2].minor.yy332.a = TK_UPDATE; yymsp[-2].minor.yy332.b = yymsp[0].minor.yy254;} -+ case 245: /* trigger_event ::= UPDATE OF idlist */ -+{yymsp[-2].minor.yy34.a = TK_UPDATE; yymsp[-2].minor.yy34.b = yymsp[0].minor.yy48;} - break; -- case 232: /* when_clause ::= */ -- case 251: /* key_opt ::= */ yytestcase(yyruleno==251); --{ yymsp[1].minor.yy72 = 0; } -+ case 246: /* when_clause ::= */ -+ case 265: /* key_opt ::= */ yytestcase(yyruleno==265); -+ case 307: /* filter_opt ::= */ yytestcase(yyruleno==307); -+{ yymsp[1].minor.yy18 = 0; } - break; -- case 233: /* when_clause ::= WHEN expr */ -- case 252: /* key_opt ::= KEY expr */ yytestcase(yyruleno==252); --{ yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr; } -+ case 247: /* when_clause ::= WHEN expr */ -+ case 266: /* key_opt ::= KEY expr */ yytestcase(yyruleno==266); -+{ yymsp[-1].minor.yy18 = yymsp[0].minor.yy18; } - break; -- case 234: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ -+ case 248: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - { -- assert( yymsp[-2].minor.yy145!=0 ); -- yymsp[-2].minor.yy145->pLast->pNext = yymsp[-1].minor.yy145; -- yymsp[-2].minor.yy145->pLast = yymsp[-1].minor.yy145; -+ assert( yymsp[-2].minor.yy207!=0 ); -+ yymsp[-2].minor.yy207->pLast->pNext = yymsp[-1].minor.yy207; -+ yymsp[-2].minor.yy207->pLast = yymsp[-1].minor.yy207; - } - break; -- case 235: /* trigger_cmd_list ::= trigger_cmd SEMI */ -+ case 249: /* trigger_cmd_list ::= trigger_cmd SEMI */ - { -- assert( yymsp[-1].minor.yy145!=0 ); -- yymsp[-1].minor.yy145->pLast = yymsp[-1].minor.yy145; -+ assert( yymsp[-1].minor.yy207!=0 ); -+ yymsp[-1].minor.yy207->pLast = yymsp[-1].minor.yy207; - } - break; -- case 236: /* trnm ::= nm DOT nm */ -+ case 250: /* trnm ::= nm DOT nm */ - { - yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; - sqlite3ErrorMsg(pParse, -@@ -139829,7 +150613,7 @@ - "statements within triggers"); - } - break; -- case 237: /* tridxby ::= INDEXED BY nm */ -+ case 251: /* tridxby ::= INDEXED BY nm */ - { - sqlite3ErrorMsg(pParse, - "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " -@@ -139836,7 +150620,7 @@ - "within triggers"); - } - break; -- case 238: /* tridxby ::= NOT INDEXED */ -+ case 252: /* tridxby ::= NOT INDEXED */ - { - sqlite3ErrorMsg(pParse, - "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " -@@ -139843,182 +150627,292 @@ - "within triggers"); - } - break; -- case 239: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */ --{yymsp[-6].minor.yy145 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy148, yymsp[0].minor.yy72, yymsp[-5].minor.yy194);} -+ case 253: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */ -+{yylhsminor.yy207 = sqlite3TriggerUpdateStep(pParse, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy420, yymsp[-1].minor.yy18, yymsp[-6].minor.yy70, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy392);} -+ yymsp[-7].minor.yy207 = yylhsminor.yy207; - break; -- case 240: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */ --{yymsp[-4].minor.yy145 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy254, yymsp[0].minor.yy243, yymsp[-4].minor.yy194);/*A-overwrites-R*/} -+ case 254: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ -+{ -+ yylhsminor.yy207 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy48,yymsp[-2].minor.yy489,yymsp[-6].minor.yy70,yymsp[-1].minor.yy340,yymsp[-7].minor.yy392,yymsp[0].minor.yy392);/*yylhsminor.yy207-overwrites-yymsp[-6].minor.yy70*/ -+} -+ yymsp[-7].minor.yy207 = yylhsminor.yy207; - break; -- case 241: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */ --{yymsp[-4].minor.yy145 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy72);} -+ case 255: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ -+{yylhsminor.yy207 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy18, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy392);} -+ yymsp[-5].minor.yy207 = yylhsminor.yy207; - break; -- case 242: /* trigger_cmd ::= select */ --{yymsp[0].minor.yy145 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy243); /*A-overwrites-X*/} -+ case 256: /* trigger_cmd ::= scanpt select scanpt */ -+{yylhsminor.yy207 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy489, yymsp[-2].minor.yy392, yymsp[0].minor.yy392); /*yylhsminor.yy207-overwrites-yymsp[-1].minor.yy489*/} -+ yymsp[-2].minor.yy207 = yylhsminor.yy207; - break; -- case 243: /* expr ::= RAISE LP IGNORE RP */ -+ case 257: /* expr ::= RAISE LP IGNORE RP */ - { -- spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/ -- yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0); -- if( yymsp[-3].minor.yy190.pExpr ){ -- yymsp[-3].minor.yy190.pExpr->affinity = OE_Ignore; -+ yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); -+ if( yymsp[-3].minor.yy18 ){ -+ yymsp[-3].minor.yy18->affinity = OE_Ignore; - } - } - break; -- case 244: /* expr ::= RAISE LP raisetype COMMA nm RP */ -+ case 258: /* expr ::= RAISE LP raisetype COMMA nm RP */ - { -- spanSet(&yymsp[-5].minor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/ -- yymsp[-5].minor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); -- if( yymsp[-5].minor.yy190.pExpr ) { -- yymsp[-5].minor.yy190.pExpr->affinity = (char)yymsp[-3].minor.yy194; -+ yymsp[-5].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); -+ if( yymsp[-5].minor.yy18 ) { -+ yymsp[-5].minor.yy18->affinity = (char)yymsp[-3].minor.yy70; - } - } - break; -- case 245: /* raisetype ::= ROLLBACK */ --{yymsp[0].minor.yy194 = OE_Rollback;} -+ case 259: /* raisetype ::= ROLLBACK */ -+{yymsp[0].minor.yy70 = OE_Rollback;} - break; -- case 247: /* raisetype ::= FAIL */ --{yymsp[0].minor.yy194 = OE_Fail;} -+ case 261: /* raisetype ::= FAIL */ -+{yymsp[0].minor.yy70 = OE_Fail;} - break; -- case 248: /* cmd ::= DROP TRIGGER ifexists fullname */ -+ case 262: /* cmd ::= DROP TRIGGER ifexists fullname */ - { -- sqlite3DropTrigger(pParse,yymsp[0].minor.yy185,yymsp[-1].minor.yy194); -+ sqlite3DropTrigger(pParse,yymsp[0].minor.yy135,yymsp[-1].minor.yy70); - } - break; -- case 249: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ -+ case 263: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - { -- sqlite3Attach(pParse, yymsp[-3].minor.yy190.pExpr, yymsp[-1].minor.yy190.pExpr, yymsp[0].minor.yy72); -+ sqlite3Attach(pParse, yymsp[-3].minor.yy18, yymsp[-1].minor.yy18, yymsp[0].minor.yy18); - } - break; -- case 250: /* cmd ::= DETACH database_kw_opt expr */ -+ case 264: /* cmd ::= DETACH database_kw_opt expr */ - { -- sqlite3Detach(pParse, yymsp[0].minor.yy190.pExpr); -+ sqlite3Detach(pParse, yymsp[0].minor.yy18); - } - break; -- case 253: /* cmd ::= REINDEX */ -+ case 267: /* cmd ::= REINDEX */ - {sqlite3Reindex(pParse, 0, 0);} - break; -- case 254: /* cmd ::= REINDEX nm dbnm */ -+ case 268: /* cmd ::= REINDEX nm dbnm */ - {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} - break; -- case 255: /* cmd ::= ANALYZE */ -+ case 269: /* cmd ::= ANALYZE */ - {sqlite3Analyze(pParse, 0, 0);} - break; -- case 256: /* cmd ::= ANALYZE nm dbnm */ -+ case 270: /* cmd ::= ANALYZE nm dbnm */ - {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} - break; -- case 257: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ -+ case 271: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ - { -- sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy185,&yymsp[0].minor.yy0); -+ sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy135,&yymsp[0].minor.yy0); - } - break; -- case 258: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ -+ case 272: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - { - yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; - sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); - } - break; -- case 259: /* add_column_fullname ::= fullname */ -+ case 273: /* add_column_fullname ::= fullname */ - { - disableLookaside(pParse); -- sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy185); -+ sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy135); - } - break; -- case 260: /* cmd ::= create_vtab */ -+ case 274: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ -+{ -+ sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy135, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); -+} -+ break; -+ case 275: /* cmd ::= create_vtab */ - {sqlite3VtabFinishParse(pParse,0);} - break; -- case 261: /* cmd ::= create_vtab LP vtabarglist RP */ -+ case 276: /* cmd ::= create_vtab LP vtabarglist RP */ - {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} - break; -- case 262: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ -+ case 277: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - { -- sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy194); -+ sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy70); - } - break; -- case 263: /* vtabarg ::= */ -+ case 278: /* vtabarg ::= */ - {sqlite3VtabArgInit(pParse);} - break; -- case 264: /* vtabargtoken ::= ANY */ -- case 265: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==265); -- case 266: /* lp ::= LP */ yytestcase(yyruleno==266); -+ case 279: /* vtabargtoken ::= ANY */ -+ case 280: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==280); -+ case 281: /* lp ::= LP */ yytestcase(yyruleno==281); - {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} - break; -- case 267: /* with ::= */ --{yymsp[1].minor.yy285 = 0;} -+ case 282: /* with ::= WITH wqlist */ -+ case 283: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==283); -+{ sqlite3WithPush(pParse, yymsp[0].minor.yy449, 1); } - break; -- case 268: /* with ::= WITH wqlist */ --{ yymsp[-1].minor.yy285 = yymsp[0].minor.yy285; } -+ case 284: /* wqlist ::= nm eidlist_opt AS LP select RP */ -+{ -+ yymsp[-5].minor.yy449 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy420, yymsp[-1].minor.yy489); /*A-overwrites-X*/ -+} - break; -- case 269: /* with ::= WITH RECURSIVE wqlist */ --{ yymsp[-2].minor.yy285 = yymsp[0].minor.yy285; } -+ case 285: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ -+{ -+ yymsp[-7].minor.yy449 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy449, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy420, yymsp[-1].minor.yy489); -+} - break; -- case 270: /* wqlist ::= nm eidlist_opt AS LP select RP */ -+ case 286: /* windowdefn_list ::= windowdefn */ -+{ yylhsminor.yy327 = yymsp[0].minor.yy327; } -+ yymsp[0].minor.yy327 = yylhsminor.yy327; -+ break; -+ case 287: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ - { -- yymsp[-5].minor.yy285 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243); /*A-overwrites-X*/ -+ assert( yymsp[0].minor.yy327!=0 ); -+ yymsp[0].minor.yy327->pNextWin = yymsp[-2].minor.yy327; -+ yylhsminor.yy327 = yymsp[0].minor.yy327; - } -+ yymsp[-2].minor.yy327 = yylhsminor.yy327; - break; -- case 271: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ -+ case 288: /* windowdefn ::= nm AS window */ - { -- yymsp[-7].minor.yy285 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy285, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243); -+ if( ALWAYS(yymsp[0].minor.yy327) ){ -+ yymsp[0].minor.yy327->zName = sqlite3DbStrNDup(pParse->db, yymsp[-2].minor.yy0.z, yymsp[-2].minor.yy0.n); -+ } -+ yylhsminor.yy327 = yymsp[0].minor.yy327; - } -+ yymsp[-2].minor.yy327 = yylhsminor.yy327; - break; -+ case 289: /* window ::= LP part_opt orderby_opt frame_opt RP */ -+{ -+ yymsp[-4].minor.yy327 = yymsp[-1].minor.yy327; -+ if( ALWAYS(yymsp[-4].minor.yy327) ){ -+ yymsp[-4].minor.yy327->pPartition = yymsp[-3].minor.yy420; -+ yymsp[-4].minor.yy327->pOrderBy = yymsp[-2].minor.yy420; -+ } -+} -+ break; -+ case 290: /* part_opt ::= PARTITION BY nexprlist */ -+{ yymsp[-2].minor.yy420 = yymsp[0].minor.yy420; } -+ break; -+ case 291: /* part_opt ::= */ -+{ yymsp[1].minor.yy420 = 0; } -+ break; -+ case 292: /* frame_opt ::= */ -+{ -+ yymsp[1].minor.yy327 = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0); -+} -+ break; -+ case 293: /* frame_opt ::= range_or_rows frame_bound_s */ -+{ -+ yylhsminor.yy327 = sqlite3WindowAlloc(pParse, yymsp[-1].minor.yy70, yymsp[0].minor.yy119.eType, yymsp[0].minor.yy119.pExpr, TK_CURRENT, 0); -+} -+ yymsp[-1].minor.yy327 = yylhsminor.yy327; -+ break; -+ case 294: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */ -+{ -+ yylhsminor.yy327 = sqlite3WindowAlloc(pParse, yymsp[-4].minor.yy70, yymsp[-2].minor.yy119.eType, yymsp[-2].minor.yy119.pExpr, yymsp[0].minor.yy119.eType, yymsp[0].minor.yy119.pExpr); -+} -+ yymsp[-4].minor.yy327 = yylhsminor.yy327; -+ break; -+ case 295: /* range_or_rows ::= RANGE */ -+{ yymsp[0].minor.yy70 = TK_RANGE; } -+ break; -+ case 296: /* range_or_rows ::= ROWS */ -+{ yymsp[0].minor.yy70 = TK_ROWS; } -+ break; -+ case 297: /* frame_bound_s ::= frame_bound */ -+ case 299: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==299); -+{ yylhsminor.yy119 = yymsp[0].minor.yy119; } -+ yymsp[0].minor.yy119 = yylhsminor.yy119; -+ break; -+ case 298: /* frame_bound_s ::= UNBOUNDED PRECEDING */ -+ case 300: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==300); -+{yymsp[-1].minor.yy119.eType = TK_UNBOUNDED; yymsp[-1].minor.yy119.pExpr = 0;} -+ break; -+ case 301: /* frame_bound ::= expr PRECEDING */ -+{ yylhsminor.yy119.eType = TK_PRECEDING; yylhsminor.yy119.pExpr = yymsp[-1].minor.yy18; } -+ yymsp[-1].minor.yy119 = yylhsminor.yy119; -+ break; -+ case 302: /* frame_bound ::= CURRENT ROW */ -+{ yymsp[-1].minor.yy119.eType = TK_CURRENT ; yymsp[-1].minor.yy119.pExpr = 0; } -+ break; -+ case 303: /* frame_bound ::= expr FOLLOWING */ -+{ yylhsminor.yy119.eType = TK_FOLLOWING; yylhsminor.yy119.pExpr = yymsp[-1].minor.yy18; } -+ yymsp[-1].minor.yy119 = yylhsminor.yy119; -+ break; -+ case 304: /* window_clause ::= WINDOW windowdefn_list */ -+{ yymsp[-1].minor.yy327 = yymsp[0].minor.yy327; } -+ break; -+ case 305: /* over_clause ::= filter_opt OVER window */ -+{ -+ yylhsminor.yy327 = yymsp[0].minor.yy327; -+ assert( yylhsminor.yy327!=0 ); -+ yylhsminor.yy327->pFilter = yymsp[-2].minor.yy18; -+} -+ yymsp[-2].minor.yy327 = yylhsminor.yy327; -+ break; -+ case 306: /* over_clause ::= filter_opt OVER nm */ -+{ -+ yylhsminor.yy327 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); -+ if( yylhsminor.yy327 ){ -+ yylhsminor.yy327->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); -+ yylhsminor.yy327->pFilter = yymsp[-2].minor.yy18; -+ }else{ -+ sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy18); -+ } -+} -+ yymsp[-2].minor.yy327 = yylhsminor.yy327; -+ break; -+ case 308: /* filter_opt ::= FILTER LP WHERE expr RP */ -+{ yymsp[-4].minor.yy18 = yymsp[-1].minor.yy18; } -+ break; - default: -- /* (272) input ::= cmdlist */ yytestcase(yyruleno==272); -- /* (273) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==273); -- /* (274) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=274); -- /* (275) ecmd ::= SEMI */ yytestcase(yyruleno==275); -- /* (276) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==276); -- /* (277) explain ::= */ yytestcase(yyruleno==277); -- /* (278) trans_opt ::= */ yytestcase(yyruleno==278); -- /* (279) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==279); -- /* (280) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==280); -- /* (281) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==281); -- /* (282) savepoint_opt ::= */ yytestcase(yyruleno==282); -- /* (283) cmd ::= create_table create_table_args */ yytestcase(yyruleno==283); -- /* (284) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==284); -- /* (285) columnlist ::= columnname carglist */ yytestcase(yyruleno==285); -- /* (286) nm ::= ID|INDEXED */ yytestcase(yyruleno==286); -- /* (287) nm ::= STRING */ yytestcase(yyruleno==287); -- /* (288) nm ::= JOIN_KW */ yytestcase(yyruleno==288); -- /* (289) typetoken ::= typename */ yytestcase(yyruleno==289); -- /* (290) typename ::= ID|STRING */ yytestcase(yyruleno==290); -- /* (291) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=291); -- /* (292) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=292); -- /* (293) carglist ::= carglist ccons */ yytestcase(yyruleno==293); -- /* (294) carglist ::= */ yytestcase(yyruleno==294); -- /* (295) ccons ::= NULL onconf */ yytestcase(yyruleno==295); -- /* (296) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==296); -- /* (297) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==297); -- /* (298) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=298); -- /* (299) tconscomma ::= */ yytestcase(yyruleno==299); -- /* (300) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=300); -- /* (301) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=301); -- /* (302) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=302); -- /* (303) oneselect ::= values */ yytestcase(yyruleno==303); -- /* (304) sclp ::= selcollist COMMA */ yytestcase(yyruleno==304); -- /* (305) as ::= ID|STRING */ yytestcase(yyruleno==305); -- /* (306) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=306); -- /* (307) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==307); -- /* (308) exprlist ::= nexprlist */ yytestcase(yyruleno==308); -- /* (309) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=309); -- /* (310) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=310); -- /* (311) nmnum ::= ON */ yytestcase(yyruleno==311); -- /* (312) nmnum ::= DELETE */ yytestcase(yyruleno==312); -- /* (313) nmnum ::= DEFAULT */ yytestcase(yyruleno==313); -- /* (314) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==314); -- /* (315) foreach_clause ::= */ yytestcase(yyruleno==315); -- /* (316) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==316); -- /* (317) trnm ::= nm */ yytestcase(yyruleno==317); -- /* (318) tridxby ::= */ yytestcase(yyruleno==318); -- /* (319) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==319); -- /* (320) database_kw_opt ::= */ yytestcase(yyruleno==320); -- /* (321) kwcolumn_opt ::= */ yytestcase(yyruleno==321); -- /* (322) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==322); -- /* (323) vtabarglist ::= vtabarg */ yytestcase(yyruleno==323); -- /* (324) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==324); -- /* (325) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==325); -- /* (326) anylist ::= */ yytestcase(yyruleno==326); -- /* (327) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==327); -- /* (328) anylist ::= anylist ANY */ yytestcase(yyruleno==328); -+ /* (309) input ::= cmdlist */ yytestcase(yyruleno==309); -+ /* (310) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==310); -+ /* (311) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=311); -+ /* (312) ecmd ::= SEMI */ yytestcase(yyruleno==312); -+ /* (313) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==313); -+ /* (314) ecmd ::= explain cmdx */ yytestcase(yyruleno==314); -+ /* (315) trans_opt ::= */ yytestcase(yyruleno==315); -+ /* (316) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==316); -+ /* (317) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==317); -+ /* (318) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==318); -+ /* (319) savepoint_opt ::= */ yytestcase(yyruleno==319); -+ /* (320) cmd ::= create_table create_table_args */ yytestcase(yyruleno==320); -+ /* (321) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==321); -+ /* (322) columnlist ::= columnname carglist */ yytestcase(yyruleno==322); -+ /* (323) nm ::= ID|INDEXED */ yytestcase(yyruleno==323); -+ /* (324) nm ::= STRING */ yytestcase(yyruleno==324); -+ /* (325) nm ::= JOIN_KW */ yytestcase(yyruleno==325); -+ /* (326) typetoken ::= typename */ yytestcase(yyruleno==326); -+ /* (327) typename ::= ID|STRING */ yytestcase(yyruleno==327); -+ /* (328) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=328); -+ /* (329) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=329); -+ /* (330) carglist ::= carglist ccons */ yytestcase(yyruleno==330); -+ /* (331) carglist ::= */ yytestcase(yyruleno==331); -+ /* (332) ccons ::= NULL onconf */ yytestcase(yyruleno==332); -+ /* (333) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==333); -+ /* (334) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==334); -+ /* (335) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=335); -+ /* (336) tconscomma ::= */ yytestcase(yyruleno==336); -+ /* (337) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=337); -+ /* (338) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=338); -+ /* (339) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=339); -+ /* (340) oneselect ::= values */ yytestcase(yyruleno==340); -+ /* (341) sclp ::= selcollist COMMA */ yytestcase(yyruleno==341); -+ /* (342) as ::= ID|STRING */ yytestcase(yyruleno==342); -+ /* (343) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=343); -+ /* (344) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==344); -+ /* (345) exprlist ::= nexprlist */ yytestcase(yyruleno==345); -+ /* (346) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=346); -+ /* (347) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=347); -+ /* (348) nmnum ::= ON */ yytestcase(yyruleno==348); -+ /* (349) nmnum ::= DELETE */ yytestcase(yyruleno==349); -+ /* (350) nmnum ::= DEFAULT */ yytestcase(yyruleno==350); -+ /* (351) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==351); -+ /* (352) foreach_clause ::= */ yytestcase(yyruleno==352); -+ /* (353) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==353); -+ /* (354) trnm ::= nm */ yytestcase(yyruleno==354); -+ /* (355) tridxby ::= */ yytestcase(yyruleno==355); -+ /* (356) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==356); -+ /* (357) database_kw_opt ::= */ yytestcase(yyruleno==357); -+ /* (358) kwcolumn_opt ::= */ yytestcase(yyruleno==358); -+ /* (359) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==359); -+ /* (360) vtabarglist ::= vtabarg */ yytestcase(yyruleno==360); -+ /* (361) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==361); -+ /* (362) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==362); -+ /* (363) anylist ::= */ yytestcase(yyruleno==363); -+ /* (364) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==364); -+ /* (365) anylist ::= anylist ANY */ yytestcase(yyruleno==365); -+ /* (366) with ::= */ yytestcase(yyruleno==366); - break; - /********** End reduce actions ************************************************/ - }; -@@ -140034,16 +150928,12 @@ - /* It is not possible for a REDUCE to be followed by an error */ - assert( yyact!=YY_ERROR_ACTION ); - -- if( yyact==YY_ACCEPT_ACTION ){ -- yypParser->yytos += yysize; -- yy_accept(yypParser); -- }else{ -- yymsp += yysize+1; -- yypParser->yytos = yymsp; -- yymsp->stateno = (YYACTIONTYPE)yyact; -- yymsp->major = (YYCODETYPE)yygoto; -- yyTraceShift(yypParser, yyact); -- } -+ yymsp += yysize+1; -+ yypParser->yytos = yymsp; -+ yymsp->stateno = (YYACTIONTYPE)yyact; -+ yymsp->major = (YYCODETYPE)yygoto; -+ yyTraceShift(yypParser, yyact, "... then shift"); -+ return yyact; - } - - /* -@@ -140053,7 +150943,8 @@ - static void yy_parse_failed( - yyParser *yypParser /* The parser */ - ){ -- sqlite3ParserARG_FETCH; -+ sqlite3ParserARG_FETCH -+ sqlite3ParserCTX_FETCH - #ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); -@@ -140064,7 +150955,8 @@ - ** parser fails */ - /************ Begin %parse_failure code ***************************************/ - /************ End %parse_failure code *****************************************/ -- sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ -+ sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ -+ sqlite3ParserCTX_STORE - } - #endif /* YYNOERRORRECOVERY */ - -@@ -140076,15 +150968,20 @@ - int yymajor, /* The major type of the error token */ - sqlite3ParserTOKENTYPE yyminor /* The minor type of the error token */ - ){ -- sqlite3ParserARG_FETCH; -+ sqlite3ParserARG_FETCH -+ sqlite3ParserCTX_FETCH - #define TOKEN yyminor - /************ Begin %syntax_error code ****************************************/ - - UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */ -- assert( TOKEN.z[0] ); /* The tokenizer always gives us a token */ -- sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); -+ if( TOKEN.z[0] ){ -+ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); -+ }else{ -+ sqlite3ErrorMsg(pParse, "incomplete input"); -+ } - /************ End %syntax_error code ******************************************/ -- sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ -+ sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ -+ sqlite3ParserCTX_STORE - } - - /* -@@ -140093,7 +150990,8 @@ - static void yy_accept( - yyParser *yypParser /* The parser */ - ){ -- sqlite3ParserARG_FETCH; -+ sqlite3ParserARG_FETCH -+ sqlite3ParserCTX_FETCH - #ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); -@@ -140107,7 +151005,8 @@ - ** parser accepts */ - /*********** Begin %parse_accept code *****************************************/ - /*********** End %parse_accept code *******************************************/ -- sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ -+ sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ -+ sqlite3ParserCTX_STORE - } - - /* The main parser program. -@@ -140136,7 +151035,7 @@ - sqlite3ParserARG_PDECL /* Optional %extra_argument parameter */ - ){ - YYMINORTYPE yyminorunion; -- unsigned int yyact; /* The parser action. */ -+ YYACTIONTYPE yyact; /* The parser action. */ - #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) - int yyendofinput; /* True if we are at the end of input */ - #endif -@@ -140143,31 +151042,44 @@ - #ifdef YYERRORSYMBOL - int yyerrorhit = 0; /* True if yymajor has invoked an error */ - #endif -- yyParser *yypParser; /* The parser */ -+ yyParser *yypParser = (yyParser*)yyp; /* The parser */ -+ sqlite3ParserCTX_FETCH -+ sqlite3ParserARG_STORE - -- yypParser = (yyParser*)yyp; - assert( yypParser->yytos!=0 ); - #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) - yyendofinput = (yymajor==0); - #endif -- sqlite3ParserARG_STORE; - -+ yyact = yypParser->yytos->stateno; - #ifndef NDEBUG - if( yyTraceFILE ){ -- fprintf(yyTraceFILE,"%sInput '%s'\n",yyTracePrompt,yyTokenName[yymajor]); -+ if( yyact < YY_MIN_REDUCE ){ -+ fprintf(yyTraceFILE,"%sInput '%s' in state %d\n", -+ yyTracePrompt,yyTokenName[yymajor],yyact); -+ }else{ -+ fprintf(yyTraceFILE,"%sInput '%s' with pending reduce %d\n", -+ yyTracePrompt,yyTokenName[yymajor],yyact-YY_MIN_REDUCE); -+ } - } - #endif - - do{ -- yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); -- if( yyact <= YY_MAX_SHIFTREDUCE ){ -- yy_shift(yypParser,yyact,yymajor,yyminor); -+ assert( yyact==yypParser->yytos->stateno ); -+ yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact); -+ if( yyact >= YY_MIN_REDUCE ){ -+ yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor, -+ yyminor sqlite3ParserCTX_PARAM); -+ }else if( yyact <= YY_MAX_SHIFTREDUCE ){ -+ yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor); - #ifndef YYNOERRORRECOVERY - yypParser->yyerrcnt--; - #endif -- yymajor = YYNOCODE; -- }else if( yyact <= YY_MAX_REDUCE ){ -- yy_reduce(yypParser,yyact-YY_MIN_REDUCE); -+ break; -+ }else if( yyact==YY_ACCEPT_ACTION ){ -+ yypParser->yytos--; -+ yy_accept(yypParser); -+ return; - }else{ - assert( yyact == YY_ERROR_ACTION ); - yyminorunion.yy0 = yyminor; -@@ -140214,10 +151126,9 @@ - yymajor = YYNOCODE; - }else{ - while( yypParser->yytos >= yypParser->yystack -- && yymx != YYERRORSYMBOL - && (yyact = yy_find_reduce_action( - yypParser->yytos->stateno, -- YYERRORSYMBOL)) >= YY_MIN_REDUCE -+ YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE - ){ - yy_pop_parser_stack(yypParser); - } -@@ -140234,6 +151145,8 @@ - } - yypParser->yyerrcnt = 3; - yyerrorhit = 1; -+ if( yymajor==YYNOCODE ) break; -+ yyact = yypParser->yytos->stateno; - #elif defined(YYNOERRORRECOVERY) - /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to - ** do any kind of error recovery. Instead, simply invoke the syntax -@@ -140244,8 +151157,7 @@ - */ - yy_syntax_error(yypParser,yymajor, yyminor); - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); -- yymajor = YYNOCODE; -- -+ break; - #else /* YYERRORSYMBOL is not defined */ - /* This is what we do if the grammar does not define ERROR: - ** -@@ -140267,10 +151179,10 @@ - yypParser->yyerrcnt = -1; - #endif - } -- yymajor = YYNOCODE; -+ break; - #endif - } -- }while( yymajor!=YYNOCODE && yypParser->yytos>yypParser->yystack ); -+ }while( yypParser->yytos>yypParser->yystack ); - #ifndef NDEBUG - if( yyTraceFILE ){ - yyStackEntry *i; -@@ -140286,6 +151198,21 @@ - return; - } - -+/* -+** Return the fallback token corresponding to canonical token iToken, or -+** 0 if iToken has no fallback. -+*/ -+SQLITE_PRIVATE int sqlite3ParserFallback(int iToken){ -+#ifdef YYFALLBACK -+ if( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ){ -+ return yyFallback[iToken]; -+ } -+#else -+ (void)iToken; -+#endif -+ return 0; -+} -+ - /************** End of parse.c ***********************************************/ - /************** Begin file tokenize.c ****************************************/ - /* -@@ -140344,11 +151271,12 @@ - #define CC_TILDA 25 /* '~' */ - #define CC_DOT 26 /* '.' */ - #define CC_ILLEGAL 27 /* Illegal character */ -+#define CC_NUL 28 /* 0x00 */ - - static const unsigned char aiClass[] = { - #ifdef SQLITE_ASCII - /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ --/* 0x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 27, 7, 7, 27, 27, -+/* 0x */ 28, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 27, 7, 7, 27, 27, - /* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - /* 2x */ 7, 15, 8, 5, 4, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16, - /* 3x */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 19, 12, 14, 13, 6, -@@ -140447,19 +151375,20 @@ - ** is substantially reduced. This is important for embedded applications - ** on platforms with limited memory. - */ --/* Hash score: 182 */ --/* zKWText[] encodes 834 bytes of keyword text in 554 bytes */ -+/* Hash score: 208 */ -+/* zKWText[] encodes 923 bytes of keyword text in 614 bytes */ - /* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */ - /* ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE */ - /* XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY */ --/* UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERECURSIVE */ --/* BETWEENOTNULLIKECASCADELETECASECOLLATECREATECURRENT_DATEDETACH */ --/* IMMEDIATEJOINSERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMITWHEN */ --/* WHERENAMEAFTEREPLACEANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMIT */ --/* CONFLICTCROSSCURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAIL */ --/* FROMFULLGLOBYIFISNULLORDERESTRICTRIGHTROLLBACKROWUNIONUSING */ --/* VACUUMVIEWINITIALLY */ --static const char zKWText[553] = { -+/* UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERANGEBETWEEN */ -+/* OTHINGLOBYCASCADELETECASECOLLATECREATECURRENT_DATEDETACH */ -+/* IMMEDIATEJOINSERTLIKEMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMIT */ -+/* WHENOTNULLWHERECURSIVEAFTERENAMEANDEFAULTAUTOINCREMENTCAST */ -+/* COLUMNCOMMITCONFLICTCROSSCURRENT_TIMESTAMPARTITIONDEFERRED */ -+/* ISTINCTDROPRECEDINGFAILFILTEREPLACEFOLLOWINGFROMFULLIFISNULL */ -+/* ORDERESTRICTOVERIGHTROLLBACKROWSUNBOUNDEDUNIONUSINGVACUUMVIEW */ -+/* INDOWINITIALLYPRIMARY */ -+static const char zKWText[613] = { - 'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H', - 'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G', - 'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A', -@@ -140472,83 +151401,90 @@ - 'O','F','F','S','E','T','E','M','P','O','R','A','R','Y','U','N','I','Q', - 'U','E','R','Y','W','I','T','H','O','U','T','E','R','E','L','E','A','S', - 'E','A','T','T','A','C','H','A','V','I','N','G','R','O','U','P','D','A', -- 'T','E','B','E','G','I','N','N','E','R','E','C','U','R','S','I','V','E', -- 'B','E','T','W','E','E','N','O','T','N','U','L','L','I','K','E','C','A', -- 'S','C','A','D','E','L','E','T','E','C','A','S','E','C','O','L','L','A', -- 'T','E','C','R','E','A','T','E','C','U','R','R','E','N','T','_','D','A', -- 'T','E','D','E','T','A','C','H','I','M','M','E','D','I','A','T','E','J', -- 'O','I','N','S','E','R','T','M','A','T','C','H','P','L','A','N','A','L', -- 'Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U','E', -- 'S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','W','H', -- 'E','R','E','N','A','M','E','A','F','T','E','R','E','P','L','A','C','E', -- 'A','N','D','E','F','A','U','L','T','A','U','T','O','I','N','C','R','E', -- 'M','E','N','T','C','A','S','T','C','O','L','U','M','N','C','O','M','M', -- 'I','T','C','O','N','F','L','I','C','T','C','R','O','S','S','C','U','R', -- 'R','E','N','T','_','T','I','M','E','S','T','A','M','P','R','I','M','A', -- 'R','Y','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T','D', -- 'R','O','P','F','A','I','L','F','R','O','M','F','U','L','L','G','L','O', -- 'B','Y','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S','T', -- 'R','I','C','T','R','I','G','H','T','R','O','L','L','B','A','C','K','R', -- 'O','W','U','N','I','O','N','U','S','I','N','G','V','A','C','U','U','M', -- 'V','I','E','W','I','N','I','T','I','A','L','L','Y', -+ 'T','E','B','E','G','I','N','N','E','R','A','N','G','E','B','E','T','W', -+ 'E','E','N','O','T','H','I','N','G','L','O','B','Y','C','A','S','C','A', -+ 'D','E','L','E','T','E','C','A','S','E','C','O','L','L','A','T','E','C', -+ 'R','E','A','T','E','C','U','R','R','E','N','T','_','D','A','T','E','D', -+ 'E','T','A','C','H','I','M','M','E','D','I','A','T','E','J','O','I','N', -+ 'S','E','R','T','L','I','K','E','M','A','T','C','H','P','L','A','N','A', -+ 'L','Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U', -+ 'E','S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','O', -+ 'T','N','U','L','L','W','H','E','R','E','C','U','R','S','I','V','E','A', -+ 'F','T','E','R','E','N','A','M','E','A','N','D','E','F','A','U','L','T', -+ 'A','U','T','O','I','N','C','R','E','M','E','N','T','C','A','S','T','C', -+ 'O','L','U','M','N','C','O','M','M','I','T','C','O','N','F','L','I','C', -+ 'T','C','R','O','S','S','C','U','R','R','E','N','T','_','T','I','M','E', -+ 'S','T','A','M','P','A','R','T','I','T','I','O','N','D','E','F','E','R', -+ 'R','E','D','I','S','T','I','N','C','T','D','R','O','P','R','E','C','E', -+ 'D','I','N','G','F','A','I','L','F','I','L','T','E','R','E','P','L','A', -+ 'C','E','F','O','L','L','O','W','I','N','G','F','R','O','M','F','U','L', -+ 'L','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S','T','R', -+ 'I','C','T','O','V','E','R','I','G','H','T','R','O','L','L','B','A','C', -+ 'K','R','O','W','S','U','N','B','O','U','N','D','E','D','U','N','I','O', -+ 'N','U','S','I','N','G','V','A','C','U','U','M','V','I','E','W','I','N', -+ 'D','O','W','I','N','I','T','I','A','L','L','Y','P','R','I','M','A','R', -+ 'Y', - }; - /* aKWHash[i] is the hash value for the i-th keyword */ - static const unsigned char aKWHash[127] = { -- 76, 105, 117, 74, 0, 45, 0, 0, 82, 0, 77, 0, 0, -- 42, 12, 78, 15, 0, 116, 85, 54, 112, 0, 19, 0, 0, -- 121, 0, 119, 115, 0, 22, 93, 0, 9, 0, 0, 70, 71, -- 0, 69, 6, 0, 48, 90, 102, 0, 118, 101, 0, 0, 44, -- 0, 103, 24, 0, 17, 0, 122, 53, 23, 0, 5, 110, 25, -- 96, 0, 0, 124, 106, 60, 123, 57, 28, 55, 0, 91, 0, -- 100, 26, 0, 99, 0, 0, 0, 95, 92, 97, 88, 109, 14, -- 39, 108, 0, 81, 0, 18, 89, 111, 32, 0, 120, 80, 113, -- 62, 46, 84, 0, 0, 94, 40, 59, 114, 0, 36, 0, 0, -- 29, 0, 86, 63, 64, 0, 20, 61, 0, 56, -+ 74, 109, 124, 72, 106, 45, 0, 0, 81, 0, 76, 61, 0, -+ 42, 12, 77, 15, 0, 123, 84, 54, 118, 125, 19, 0, 0, -+ 130, 0, 128, 121, 0, 22, 96, 0, 9, 0, 0, 115, 69, -+ 0, 67, 6, 0, 48, 93, 136, 0, 126, 104, 0, 0, 44, -+ 0, 107, 24, 0, 17, 0, 131, 53, 23, 0, 5, 62, 132, -+ 99, 0, 0, 135, 110, 60, 134, 57, 113, 55, 0, 94, 0, -+ 103, 26, 0, 102, 0, 0, 0, 98, 95, 100, 105, 117, 14, -+ 39, 116, 0, 80, 0, 133, 114, 92, 59, 0, 129, 79, 119, -+ 86, 46, 83, 0, 0, 97, 40, 122, 120, 0, 127, 0, 0, -+ 29, 0, 89, 87, 88, 0, 20, 85, 111, 56, - }; - /* aKWNext[] forms the hash collision chain. If aKWHash[i]==0 - ** then the i-th keyword has no more hash collisions. Otherwise, - ** the next keyword with the same hash is aKWHash[i]-1. */ --static const unsigned char aKWNext[124] = { -+static const unsigned char aKWNext[136] = { - 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, - 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 33, 0, 21, 0, 0, 0, 0, 0, 50, -- 0, 43, 3, 47, 0, 0, 0, 0, 30, 0, 58, 0, 38, -- 0, 0, 0, 1, 66, 0, 0, 67, 0, 41, 0, 0, 0, -- 0, 0, 0, 49, 65, 0, 0, 0, 0, 31, 52, 16, 34, -- 10, 0, 0, 0, 0, 0, 0, 0, 11, 72, 79, 0, 8, -- 0, 104, 98, 0, 107, 0, 87, 0, 75, 51, 0, 27, 37, -- 73, 83, 0, 35, 68, 0, 0, -+ 0, 43, 3, 47, 0, 0, 32, 0, 0, 0, 0, 0, 0, -+ 0, 1, 64, 0, 0, 65, 0, 41, 0, 38, 0, 0, 0, -+ 0, 0, 49, 75, 0, 0, 30, 0, 58, 0, 0, 0, 31, -+ 63, 16, 34, 10, 0, 0, 0, 0, 0, 0, 0, 11, 70, -+ 91, 0, 0, 8, 0, 108, 0, 101, 28, 52, 68, 0, 112, -+ 0, 73, 51, 0, 90, 27, 37, 0, 71, 36, 82, 0, 35, -+ 66, 25, 18, 0, 0, 78, - }; - /* aKWLen[i] is the length (in bytes) of the i-th keyword */ --static const unsigned char aKWLen[124] = { -+static const unsigned char aKWLen[136] = { - 7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6, - 7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 6, - 11, 6, 2, 7, 5, 5, 9, 6, 9, 9, 7, 10, 10, - 4, 6, 2, 3, 9, 4, 2, 6, 5, 7, 4, 5, 7, -- 6, 6, 5, 6, 5, 5, 9, 7, 7, 3, 2, 4, 4, -- 7, 3, 6, 4, 7, 6, 12, 6, 9, 4, 6, 5, 4, -- 7, 6, 5, 6, 7, 5, 4, 5, 6, 5, 7, 3, 7, -- 13, 2, 2, 4, 6, 6, 8, 5, 17, 12, 7, 8, 8, -- 2, 4, 4, 4, 4, 4, 2, 2, 6, 5, 8, 5, 8, -- 3, 5, 5, 6, 4, 9, 3, -+ 6, 6, 5, 6, 5, 5, 5, 7, 7, 4, 2, 7, 3, -+ 6, 4, 7, 6, 12, 6, 9, 4, 6, 4, 5, 4, 7, -+ 6, 5, 6, 7, 5, 4, 7, 3, 2, 4, 5, 9, 5, -+ 6, 3, 7, 13, 2, 2, 4, 6, 6, 8, 5, 17, 12, -+ 7, 9, 8, 8, 2, 4, 9, 4, 6, 7, 9, 4, 4, -+ 2, 6, 5, 8, 4, 5, 8, 4, 3, 9, 5, 5, 6, -+ 4, 6, 2, 9, 3, 7, - }; - /* aKWOffset[i] is the index into zKWText[] of the start of - ** the text for the i-th keyword. */ --static const unsigned short int aKWOffset[124] = { -+static const unsigned short int aKWOffset[136] = { - 0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33, - 36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81, - 86, 91, 95, 96, 101, 105, 109, 117, 122, 128, 136, 142, 152, - 159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 184, 188, 192, -- 199, 204, 209, 212, 218, 221, 225, 234, 240, 240, 240, 243, 246, -- 250, 251, 255, 261, 265, 272, 278, 290, 296, 305, 307, 313, 318, -- 320, 327, 332, 337, 343, 349, 354, 358, 361, 367, 371, 378, 380, -- 387, 389, 391, 400, 404, 410, 416, 424, 429, 429, 445, 452, 459, -- 460, 467, 471, 475, 479, 483, 486, 488, 490, 496, 500, 508, 513, -- 521, 524, 529, 534, 540, 544, 549, -+ 199, 204, 209, 212, 218, 221, 225, 230, 236, 242, 245, 247, 248, -+ 252, 258, 262, 269, 275, 287, 293, 302, 304, 310, 314, 319, 321, -+ 328, 333, 338, 344, 350, 355, 358, 358, 358, 361, 365, 368, 377, -+ 381, 387, 389, 396, 398, 400, 409, 413, 419, 425, 433, 438, 438, -+ 438, 454, 463, 470, 471, 478, 481, 490, 494, 499, 506, 515, 519, -+ 523, 525, 531, 535, 543, 546, 551, 559, 559, 563, 572, 577, 582, -+ 588, 591, 594, 597, 602, 606, - }; - /* aKWCode[i] is the parser symbol code for the i-th keyword */ --static const unsigned char aKWCode[124] = { -+static const unsigned char aKWCode[136] = { - TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE, - TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN, - TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD, -@@ -140560,20 +151496,23 @@ - TK_OFFSET, TK_OF, TK_SET, TK_TEMP, TK_TEMP, - TK_OR, TK_UNIQUE, TK_QUERY, TK_WITHOUT, TK_WITH, - TK_JOIN_KW, TK_RELEASE, TK_ATTACH, TK_HAVING, TK_GROUP, -- TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RECURSIVE, TK_BETWEEN, -- TK_NOTNULL, TK_NOT, TK_NO, TK_NULL, TK_LIKE_KW, -- TK_CASCADE, TK_ASC, TK_DELETE, TK_CASE, TK_COLLATE, -- TK_CREATE, TK_CTIME_KW, TK_DETACH, TK_IMMEDIATE, TK_JOIN, -- TK_INSERT, TK_MATCH, TK_PLAN, TK_ANALYZE, TK_PRAGMA, -- TK_ABORT, TK_VALUES, TK_VIRTUAL, TK_LIMIT, TK_WHEN, -- TK_WHERE, TK_RENAME, TK_AFTER, TK_REPLACE, TK_AND, -- TK_DEFAULT, TK_AUTOINCR, TK_TO, TK_IN, TK_CAST, -- TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, -- TK_CTIME_KW, TK_PRIMARY, TK_DEFERRED, TK_DISTINCT, TK_IS, -- TK_DROP, TK_FAIL, TK_FROM, TK_JOIN_KW, TK_LIKE_KW, -- TK_BY, TK_IF, TK_ISNULL, TK_ORDER, TK_RESTRICT, -- TK_JOIN_KW, TK_ROLLBACK, TK_ROW, TK_UNION, TK_USING, -- TK_VACUUM, TK_VIEW, TK_INITIALLY, TK_ALL, -+ TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RANGE, TK_BETWEEN, -+ TK_NOTHING, TK_LIKE_KW, TK_BY, TK_CASCADE, TK_ASC, -+ TK_DELETE, TK_CASE, TK_COLLATE, TK_CREATE, TK_CTIME_KW, -+ TK_DETACH, TK_IMMEDIATE, TK_JOIN, TK_INSERT, TK_LIKE_KW, -+ TK_MATCH, TK_PLAN, TK_ANALYZE, TK_PRAGMA, TK_ABORT, -+ TK_VALUES, TK_VIRTUAL, TK_LIMIT, TK_WHEN, TK_NOTNULL, -+ TK_NOT, TK_NO, TK_NULL, TK_WHERE, TK_RECURSIVE, -+ TK_AFTER, TK_RENAME, TK_AND, TK_DEFAULT, TK_AUTOINCR, -+ TK_TO, TK_IN, TK_CAST, TK_COLUMNKW, TK_COMMIT, -+ TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, TK_CURRENT, -+ TK_PARTITION, TK_DEFERRED, TK_DISTINCT, TK_IS, TK_DROP, -+ TK_PRECEDING, TK_FAIL, TK_FILTER, TK_REPLACE, TK_FOLLOWING, -+ TK_FROM, TK_JOIN_KW, TK_IF, TK_ISNULL, TK_ORDER, -+ TK_RESTRICT, TK_OVER, TK_JOIN_KW, TK_ROLLBACK, TK_ROWS, -+ TK_ROW, TK_UNBOUNDED, TK_UNION, TK_USING, TK_VACUUM, -+ TK_VIEW, TK_WINDOW, TK_DO, TK_INITIALLY, TK_ALL, -+ TK_PRIMARY, - }; - /* Check to see if z[0..n-1] is a keyword. If it is, write the - ** parser symbol code for that keyword into *pType. Always -@@ -140652,72 +151591,84 @@ - testcase( i==55 ); /* UPDATE */ - testcase( i==56 ); /* BEGIN */ - testcase( i==57 ); /* INNER */ -- testcase( i==58 ); /* RECURSIVE */ -+ testcase( i==58 ); /* RANGE */ - testcase( i==59 ); /* BETWEEN */ -- testcase( i==60 ); /* NOTNULL */ -- testcase( i==61 ); /* NOT */ -- testcase( i==62 ); /* NO */ -- testcase( i==63 ); /* NULL */ -- testcase( i==64 ); /* LIKE */ -- testcase( i==65 ); /* CASCADE */ -- testcase( i==66 ); /* ASC */ -- testcase( i==67 ); /* DELETE */ -- testcase( i==68 ); /* CASE */ -- testcase( i==69 ); /* COLLATE */ -- testcase( i==70 ); /* CREATE */ -- testcase( i==71 ); /* CURRENT_DATE */ -- testcase( i==72 ); /* DETACH */ -- testcase( i==73 ); /* IMMEDIATE */ -- testcase( i==74 ); /* JOIN */ -- testcase( i==75 ); /* INSERT */ -- testcase( i==76 ); /* MATCH */ -- testcase( i==77 ); /* PLAN */ -- testcase( i==78 ); /* ANALYZE */ -- testcase( i==79 ); /* PRAGMA */ -- testcase( i==80 ); /* ABORT */ -- testcase( i==81 ); /* VALUES */ -- testcase( i==82 ); /* VIRTUAL */ -- testcase( i==83 ); /* LIMIT */ -- testcase( i==84 ); /* WHEN */ -- testcase( i==85 ); /* WHERE */ -- testcase( i==86 ); /* RENAME */ -- testcase( i==87 ); /* AFTER */ -- testcase( i==88 ); /* REPLACE */ -- testcase( i==89 ); /* AND */ -- testcase( i==90 ); /* DEFAULT */ -- testcase( i==91 ); /* AUTOINCREMENT */ -- testcase( i==92 ); /* TO */ -- testcase( i==93 ); /* IN */ -- testcase( i==94 ); /* CAST */ -- testcase( i==95 ); /* COLUMN */ -- testcase( i==96 ); /* COMMIT */ -- testcase( i==97 ); /* CONFLICT */ -- testcase( i==98 ); /* CROSS */ -- testcase( i==99 ); /* CURRENT_TIMESTAMP */ -- testcase( i==100 ); /* CURRENT_TIME */ -- testcase( i==101 ); /* PRIMARY */ -- testcase( i==102 ); /* DEFERRED */ -- testcase( i==103 ); /* DISTINCT */ -- testcase( i==104 ); /* IS */ -- testcase( i==105 ); /* DROP */ -- testcase( i==106 ); /* FAIL */ -- testcase( i==107 ); /* FROM */ -- testcase( i==108 ); /* FULL */ -- testcase( i==109 ); /* GLOB */ -- testcase( i==110 ); /* BY */ -- testcase( i==111 ); /* IF */ -- testcase( i==112 ); /* ISNULL */ -- testcase( i==113 ); /* ORDER */ -- testcase( i==114 ); /* RESTRICT */ -- testcase( i==115 ); /* RIGHT */ -- testcase( i==116 ); /* ROLLBACK */ -- testcase( i==117 ); /* ROW */ -- testcase( i==118 ); /* UNION */ -- testcase( i==119 ); /* USING */ -- testcase( i==120 ); /* VACUUM */ -- testcase( i==121 ); /* VIEW */ -- testcase( i==122 ); /* INITIALLY */ -- testcase( i==123 ); /* ALL */ -+ testcase( i==60 ); /* NOTHING */ -+ testcase( i==61 ); /* GLOB */ -+ testcase( i==62 ); /* BY */ -+ testcase( i==63 ); /* CASCADE */ -+ testcase( i==64 ); /* ASC */ -+ testcase( i==65 ); /* DELETE */ -+ testcase( i==66 ); /* CASE */ -+ testcase( i==67 ); /* COLLATE */ -+ testcase( i==68 ); /* CREATE */ -+ testcase( i==69 ); /* CURRENT_DATE */ -+ testcase( i==70 ); /* DETACH */ -+ testcase( i==71 ); /* IMMEDIATE */ -+ testcase( i==72 ); /* JOIN */ -+ testcase( i==73 ); /* INSERT */ -+ testcase( i==74 ); /* LIKE */ -+ testcase( i==75 ); /* MATCH */ -+ testcase( i==76 ); /* PLAN */ -+ testcase( i==77 ); /* ANALYZE */ -+ testcase( i==78 ); /* PRAGMA */ -+ testcase( i==79 ); /* ABORT */ -+ testcase( i==80 ); /* VALUES */ -+ testcase( i==81 ); /* VIRTUAL */ -+ testcase( i==82 ); /* LIMIT */ -+ testcase( i==83 ); /* WHEN */ -+ testcase( i==84 ); /* NOTNULL */ -+ testcase( i==85 ); /* NOT */ -+ testcase( i==86 ); /* NO */ -+ testcase( i==87 ); /* NULL */ -+ testcase( i==88 ); /* WHERE */ -+ testcase( i==89 ); /* RECURSIVE */ -+ testcase( i==90 ); /* AFTER */ -+ testcase( i==91 ); /* RENAME */ -+ testcase( i==92 ); /* AND */ -+ testcase( i==93 ); /* DEFAULT */ -+ testcase( i==94 ); /* AUTOINCREMENT */ -+ testcase( i==95 ); /* TO */ -+ testcase( i==96 ); /* IN */ -+ testcase( i==97 ); /* CAST */ -+ testcase( i==98 ); /* COLUMN */ -+ testcase( i==99 ); /* COMMIT */ -+ testcase( i==100 ); /* CONFLICT */ -+ testcase( i==101 ); /* CROSS */ -+ testcase( i==102 ); /* CURRENT_TIMESTAMP */ -+ testcase( i==103 ); /* CURRENT_TIME */ -+ testcase( i==104 ); /* CURRENT */ -+ testcase( i==105 ); /* PARTITION */ -+ testcase( i==106 ); /* DEFERRED */ -+ testcase( i==107 ); /* DISTINCT */ -+ testcase( i==108 ); /* IS */ -+ testcase( i==109 ); /* DROP */ -+ testcase( i==110 ); /* PRECEDING */ -+ testcase( i==111 ); /* FAIL */ -+ testcase( i==112 ); /* FILTER */ -+ testcase( i==113 ); /* REPLACE */ -+ testcase( i==114 ); /* FOLLOWING */ -+ testcase( i==115 ); /* FROM */ -+ testcase( i==116 ); /* FULL */ -+ testcase( i==117 ); /* IF */ -+ testcase( i==118 ); /* ISNULL */ -+ testcase( i==119 ); /* ORDER */ -+ testcase( i==120 ); /* RESTRICT */ -+ testcase( i==121 ); /* OVER */ -+ testcase( i==122 ); /* RIGHT */ -+ testcase( i==123 ); /* ROLLBACK */ -+ testcase( i==124 ); /* ROWS */ -+ testcase( i==125 ); /* ROW */ -+ testcase( i==126 ); /* UNBOUNDED */ -+ testcase( i==127 ); /* UNION */ -+ testcase( i==128 ); /* USING */ -+ testcase( i==129 ); /* VACUUM */ -+ testcase( i==130 ); /* VIEW */ -+ testcase( i==131 ); /* WINDOW */ -+ testcase( i==132 ); /* DO */ -+ testcase( i==133 ); /* INITIALLY */ -+ testcase( i==134 ); /* ALL */ -+ testcase( i==135 ); /* PRIMARY */ - *pType = aKWCode[i]; - break; - } -@@ -140729,7 +151680,17 @@ - keywordCode((char*)z, n, &id); - return id; - } --#define SQLITE_N_KEYWORD 124 -+#define SQLITE_N_KEYWORD 136 -+SQLITE_API int sqlite3_keyword_name(int i,const char **pzName,int *pnName){ -+ if( i<0 || i>=SQLITE_N_KEYWORD ) return SQLITE_ERROR; -+ *pzName = zKWText + aKWOffset[i]; -+ *pnName = aKWLen[i]; -+ return SQLITE_OK; -+} -+SQLITE_API int sqlite3_keyword_count(void){ return SQLITE_N_KEYWORD; } -+SQLITE_API int sqlite3_keyword_check(const char *zName, int nName){ -+ return TK_ID!=sqlite3KeywordCode((const u8*)zName, nName); -+} - - /************** End of keywordhash.h *****************************************/ - /************** Continuing where we left off in tokenize.c *******************/ -@@ -140773,13 +151734,87 @@ - #define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40])) - #endif - --/* Make the IdChar function accessible from ctime.c */ --#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS -+/* Make the IdChar function accessible from ctime.c and alter.c */ - SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); } --#endif - -+#ifndef SQLITE_OMIT_WINDOWFUNC -+/* -+** Return the id of the next token in string (*pz). Before returning, set -+** (*pz) to point to the byte following the parsed token. -+*/ -+static int getToken(const unsigned char **pz){ -+ const unsigned char *z = *pz; -+ int t; /* Token type to return */ -+ do { -+ z += sqlite3GetToken(z, &t); -+ }while( t==TK_SPACE ); -+ if( t==TK_ID -+ || t==TK_STRING -+ || t==TK_JOIN_KW -+ || t==TK_WINDOW -+ || t==TK_OVER -+ || sqlite3ParserFallback(t)==TK_ID -+ ){ -+ t = TK_ID; -+ } -+ *pz = z; -+ return t; -+} - - /* -+** The following three functions are called immediately after the tokenizer -+** reads the keywords WINDOW, OVER and FILTER, respectively, to determine -+** whether the token should be treated as a keyword or an SQL identifier. -+** This cannot be handled by the usual lemon %fallback method, due to -+** the ambiguity in some constructions. e.g. -+** -+** SELECT sum(x) OVER ... -+** -+** In the above, "OVER" might be a keyword, or it might be an alias for the -+** sum(x) expression. If a "%fallback ID OVER" directive were added to -+** grammar, then SQLite would always treat "OVER" as an alias, making it -+** impossible to call a window-function without a FILTER clause. -+** -+** WINDOW is treated as a keyword if: -+** -+** * the following token is an identifier, or a keyword that can fallback -+** to being an identifier, and -+** * the token after than one is TK_AS. -+** -+** OVER is a keyword if: -+** -+** * the previous token was TK_RP, and -+** * the next token is either TK_LP or an identifier. -+** -+** FILTER is a keyword if: -+** -+** * the previous token was TK_RP, and -+** * the next token is TK_LP. -+*/ -+static int analyzeWindowKeyword(const unsigned char *z){ -+ int t; -+ t = getToken(&z); -+ if( t!=TK_ID ) return TK_ID; -+ t = getToken(&z); -+ if( t!=TK_AS ) return TK_ID; -+ return TK_WINDOW; -+} -+static int analyzeOverKeyword(const unsigned char *z, int lastToken){ -+ if( lastToken==TK_RP ){ -+ int t = getToken(&z); -+ if( t==TK_LP || t==TK_ID ) return TK_OVER; -+ } -+ return TK_ID; -+} -+static int analyzeFilterKeyword(const unsigned char *z, int lastToken){ -+ if( lastToken==TK_RP && getToken(&z)==TK_LP ){ -+ return TK_FILTER; -+ } -+ return TK_ID; -+} -+#endif /* SQLITE_OMIT_WINDOWFUNC */ -+ -+/* - ** Return the length (in bytes) of the token that begins at z[0]. - ** Store the token type in *tokenType before returning. - */ -@@ -141046,6 +152081,10 @@ - i = 1; - break; - } -+ case CC_NUL: { -+ *tokenType = TK_ILLEGAL; -+ return 0; -+ } - default: { - *tokenType = TK_ILLEGAL; - return 1; -@@ -141056,7 +152095,74 @@ - return i; - } - -+#ifdef SQLITE_ENABLE_NORMALIZE - /* -+** Return the length (in bytes) of the token that begins at z[0]. -+** Store the token type in *tokenType before returning. If flags has -+** SQLITE_TOKEN_NORMALIZE flag enabled, use the identifier token type -+** for keywords. Add SQLITE_TOKEN_QUOTED to flags if the token was -+** actually a quoted identifier. Add SQLITE_TOKEN_KEYWORD to flags -+** if the token was recognized as a keyword; this is useful when the -+** SQLITE_TOKEN_NORMALIZE flag is used, because it enables the caller -+** to differentiate between a keyword being treated as an identifier -+** (for normalization purposes) and an actual identifier. -+*/ -+SQLITE_PRIVATE int sqlite3GetTokenNormalized( -+ const unsigned char *z, -+ int *tokenType, -+ int *flags -+){ -+ int n; -+ unsigned char iClass = aiClass[*z]; -+ if( iClass==CC_KYWD ){ -+ int i; -+ for(i=1; aiClass[z[i]]<=CC_KYWD; i++){} -+ if( IdChar(z[i]) ){ -+ /* This token started out using characters that can appear in keywords, -+ ** but z[i] is a character not allowed within keywords, so this must -+ ** be an identifier instead */ -+ i++; -+ while( IdChar(z[i]) ){ i++; } -+ *tokenType = TK_ID; -+ return i; -+ } -+ *tokenType = TK_ID; -+ n = keywordCode((char*)z, i, tokenType); -+ /* If the token is no longer considered to be an identifier, then it is a -+ ** keyword of some kind. Make the token back into an identifier and then -+ ** set the SQLITE_TOKEN_KEYWORD flag. Several non-identifier tokens are -+ ** used verbatim, including IN, IS, NOT, and NULL. */ -+ switch( *tokenType ){ -+ case TK_ID: { -+ /* do nothing, handled by caller */ -+ break; -+ } -+ case TK_IN: -+ case TK_IS: -+ case TK_NOT: -+ case TK_NULL: { -+ *flags |= SQLITE_TOKEN_KEYWORD; -+ break; -+ } -+ default: { -+ *tokenType = TK_ID; -+ *flags |= SQLITE_TOKEN_KEYWORD; -+ break; -+ } -+ } -+ }else{ -+ n = sqlite3GetToken(z, tokenType); -+ /* If the token is considered to be an identifier and the character class -+ ** of the first character is a quote, set the SQLITE_TOKEN_QUOTED flag. */ -+ if( *tokenType==TK_ID && (iClass==CC_QUOTE || iClass==CC_QUOTE2) ){ -+ *flags |= SQLITE_TOKEN_QUOTED; -+ } -+ } -+ return n; -+} -+#endif /* SQLITE_ENABLE_NORMALIZE */ -+ -+/* - ** Run the parser on the given SQL string. The parser structure is - ** passed in. An SQLITE_ status code is returned. If an error occurs - ** then an and attempt is made to write an error message into -@@ -141086,9 +152192,9 @@ - /* sqlite3ParserTrace(stdout, "parser: "); */ - #ifdef sqlite3Parser_ENGINEALWAYSONSTACK - pEngine = &sEngine; -- sqlite3ParserInit(pEngine); -+ sqlite3ParserInit(pEngine, pParse); - #else -- pEngine = sqlite3ParserAlloc(sqlite3Malloc); -+ pEngine = sqlite3ParserAlloc(sqlite3Malloc, pParse); - if( pEngine==0 ){ - sqlite3OomFault(db); - return SQLITE_NOMEM_BKPT; -@@ -141099,47 +152205,64 @@ - assert( pParse->nVar==0 ); - assert( pParse->pVList==0 ); - while( 1 ){ -- if( zSql[0]!=0 ){ -- n = sqlite3GetToken((u8*)zSql, &tokenType); -- mxSqlLen -= n; -- if( mxSqlLen<0 ){ -- pParse->rc = SQLITE_TOOBIG; -- break; -- } -- }else{ -- /* Upon reaching the end of input, call the parser two more times -- ** with tokens TK_SEMI and 0, in that order. */ -- if( lastTokenParsed==TK_SEMI ){ -- tokenType = 0; -- }else if( lastTokenParsed==0 ){ -- break; -- }else{ -- tokenType = TK_SEMI; -- } -- zSql -= n; -+ n = sqlite3GetToken((u8*)zSql, &tokenType); -+ mxSqlLen -= n; -+ if( mxSqlLen<0 ){ -+ pParse->rc = SQLITE_TOOBIG; -+ break; - } -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ if( tokenType>=TK_WINDOW ){ -+ assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER -+ || tokenType==TK_ILLEGAL || tokenType==TK_WINDOW -+ ); -+#else - if( tokenType>=TK_SPACE ){ - assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL ); -+#endif /* SQLITE_OMIT_WINDOWFUNC */ - if( db->u1.isInterrupted ){ - pParse->rc = SQLITE_INTERRUPT; - break; - } -- if( tokenType==TK_ILLEGAL ){ -+ if( tokenType==TK_SPACE ){ -+ zSql += n; -+ continue; -+ } -+ if( zSql[0]==0 ){ -+ /* Upon reaching the end of input, call the parser two more times -+ ** with tokens TK_SEMI and 0, in that order. */ -+ if( lastTokenParsed==TK_SEMI ){ -+ tokenType = 0; -+ }else if( lastTokenParsed==0 ){ -+ break; -+ }else{ -+ tokenType = TK_SEMI; -+ } -+ n = 0; -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ }else if( tokenType==TK_WINDOW ){ -+ assert( n==6 ); -+ tokenType = analyzeWindowKeyword((const u8*)&zSql[6]); -+ }else if( tokenType==TK_OVER ){ -+ assert( n==4 ); -+ tokenType = analyzeOverKeyword((const u8*)&zSql[4], lastTokenParsed); -+ }else if( tokenType==TK_FILTER ){ -+ assert( n==6 ); -+ tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed); -+#endif /* SQLITE_OMIT_WINDOWFUNC */ -+ }else{ - sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql); - break; - } -- zSql += n; -- }else{ -- pParse->sLastToken.z = zSql; -- pParse->sLastToken.n = n; -- sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse); -- lastTokenParsed = tokenType; -- zSql += n; -- if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break; - } -+ pParse->sLastToken.z = zSql; -+ pParse->sLastToken.n = n; -+ sqlite3Parser(pEngine, tokenType, pParse->sLastToken); -+ lastTokenParsed = tokenType; -+ zSql += n; -+ if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break; - } - assert( nErr==0 ); -- pParse->zTail = zSql; - #ifdef YYTRACKMAXSTACKDEPTH - sqlite3_mutex_enter(sqlite3MallocMutex()); - sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK, -@@ -141161,10 +152284,12 @@ - assert( pzErrMsg!=0 ); - if( pParse->zErrMsg ){ - *pzErrMsg = pParse->zErrMsg; -- sqlite3_log(pParse->rc, "%s", *pzErrMsg); -+ sqlite3_log(pParse->rc, "%s in \"%s\"", -+ *pzErrMsg, pParse->zTail); - pParse->zErrMsg = 0; - nErr++; - } -+ pParse->zTail = zSql; - if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){ - sqlite3VdbeDelete(pParse->pVdbe); - pParse->pVdbe = 0; -@@ -141180,7 +152305,7 @@ - sqlite3_free(pParse->apVtabLock); - #endif - -- if( !IN_DECLARE_VTAB ){ -+ if( !IN_SPECIAL_PARSE ){ - /* If the pParse->declareVtab flag is set, do not delete any table - ** structure built up in pParse->pNewTable. The calling code (see vtab.c) - ** will take responsibility for freeing the Table structure. -@@ -141187,9 +152312,11 @@ - */ - sqlite3DeleteTable(db, pParse->pNewTable); - } -+ if( !IN_RENAME_OBJECT ){ -+ sqlite3DeleteTrigger(db, pParse->pNewTrigger); -+ } - - if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree); -- sqlite3DeleteTrigger(db, pParse->pNewTrigger); - sqlite3DbFree(db, pParse->pVList); - while( pParse->pAinc ){ - AutoincInfo *p = pParse->pAinc; -@@ -141571,6 +152698,10 @@ - */ - /* #include "sqlite3.h" */ - -+#ifdef SQLITE_OMIT_VIRTUALTABLE -+# undef SQLITE_ENABLE_RTREE -+#endif -+ - #if 0 - extern "C" { - #endif /* __cplusplus */ -@@ -141584,7 +152715,7 @@ - /************** End of rtree.h ***********************************************/ - /************** Continuing where we left off in main.c ***********************/ - #endif --#ifdef SQLITE_ENABLE_ICU -+#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS) - /************** Include sqliteicu.h in the middle of main.c ******************/ - /************** Begin file sqliteicu.h ***************************************/ - /* -@@ -141640,11 +152771,13 @@ - */ - SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; } - --/* IMPLEMENTATION-OF: R-63124-39300 The sqlite3_sourceid() function returns a -+/* IMPLEMENTATION-OF: R-25063-23286 The sqlite3_sourceid() function returns a - ** pointer to a string constant whose value is the same as the --** SQLITE_SOURCE_ID C preprocessor macro. -+** SQLITE_SOURCE_ID C preprocessor macro. Except if SQLite is built using -+** an edited copy of the amalgamation, then the last four characters of -+** the hash might be different from SQLITE_SOURCE_ID. - */ --SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } -+/* SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } */ - - /* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function - ** returns an integer equal to SQLITE_VERSION_NUMBER. -@@ -141830,7 +152963,12 @@ - sqlite3GlobalConfig.isPCacheInit = 1; - rc = sqlite3OsInit(); - } -+#ifdef SQLITE_ENABLE_DESERIALIZE - if( rc==SQLITE_OK ){ -+ rc = sqlite3MemdbInit(); -+ } -+#endif -+ if( rc==SQLITE_OK ){ - sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, - sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage); - sqlite3GlobalConfig.isInit = 1; -@@ -141862,7 +153000,7 @@ - #ifndef NDEBUG - #ifndef SQLITE_OMIT_FLOATING_POINT - /* This section of code's only "output" is via assert() statements. */ -- if ( rc==SQLITE_OK ){ -+ if( rc==SQLITE_OK ){ - u64 x = (((u64)1)<<63)-1; - double y; - assert(sizeof(x)==8); -@@ -142029,14 +153167,8 @@ - sqlite3GlobalConfig.bMemstat = va_arg(ap, int); - break; - } -- case SQLITE_CONFIG_SCRATCH: { -- /* EVIDENCE-OF: R-08404-60887 There are three arguments to -- ** SQLITE_CONFIG_SCRATCH: A pointer an 8-byte aligned memory buffer from -- ** which the scratch allocations will be drawn, the size of each scratch -- ** allocation (sz), and the maximum number of scratch allocations (N). */ -- sqlite3GlobalConfig.pScratch = va_arg(ap, void*); -- sqlite3GlobalConfig.szScratch = va_arg(ap, int); -- sqlite3GlobalConfig.nScratch = va_arg(ap, int); -+ case SQLITE_CONFIG_SMALL_MALLOC: { -+ sqlite3GlobalConfig.bSmallMalloc = va_arg(ap, int); - break; - } - case SQLITE_CONFIG_PAGECACHE: { -@@ -142234,6 +153366,17 @@ - break; - } - -+#ifdef SQLITE_ENABLE_SORTER_REFERENCES -+ case SQLITE_CONFIG_SORTERREF_SIZE: { -+ int iVal = va_arg(ap, int); -+ if( iVal<0 ){ -+ iVal = SQLITE_DEFAULT_SORTERREF_SIZE; -+ } -+ sqlite3GlobalConfig.szSorterRef = (u32)iVal; -+ break; -+ } -+#endif /* SQLITE_ENABLE_SORTER_REFERENCES */ -+ - default: { - rc = SQLITE_ERROR; - break; -@@ -142257,7 +153400,8 @@ - static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ - #ifndef SQLITE_OMIT_LOOKASIDE - void *pStart; -- if( db->lookaside.nOut ){ -+ -+ if( sqlite3LookasideUsed(db,0)>0 ){ - return SQLITE_BUSY; - } - /* Free any existing lookaside buffer for this handle before -@@ -142285,6 +153429,7 @@ - pStart = pBuf; - } - db->lookaside.pStart = pStart; -+ db->lookaside.pInit = 0; - db->lookaside.pFree = 0; - db->lookaside.sz = (u16)sz; - if( pStart ){ -@@ -142291,10 +153436,11 @@ - int i; - LookasideSlot *p; - assert( sz > (int)sizeof(LookasideSlot*) ); -+ db->lookaside.nSlot = cnt; - p = (LookasideSlot*)pStart; - for(i=cnt-1; i>=0; i--){ -- p->pNext = db->lookaside.pFree; -- db->lookaside.pFree = p; -+ p->pNext = db->lookaside.pInit; -+ db->lookaside.pInit = p; - p = (LookasideSlot*)&((u8*)p)[sz]; - } - db->lookaside.pEnd = p; -@@ -142305,6 +153451,7 @@ - db->lookaside.pEnd = db; - db->lookaside.bDisable = 1; - db->lookaside.bMalloced = 0; -+ db->lookaside.nSlot = 0; - } - #endif /* SQLITE_OMIT_LOOKASIDE */ - return SQLITE_OK; -@@ -142410,6 +153557,9 @@ - { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension }, - { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose }, - { SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG }, -+ { SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP }, -+ { SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase }, -+ { SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive }, - }; - unsigned int i; - rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ -@@ -142417,7 +153567,7 @@ - if( aFlagOp[i].op==op ){ - int onoff = va_arg(ap, int); - int *pRes = va_arg(ap, int*); -- int oldFlags = db->flags; -+ u32 oldFlags = db->flags; - if( onoff>0 ){ - db->flags |= aFlagOp[i].mask; - }else if( onoff==0 ){ -@@ -142424,7 +153574,7 @@ - db->flags &= ~aFlagOp[i].mask; - } - if( oldFlags!=db->flags ){ -- sqlite3ExpirePreparedStatements(db); -+ sqlite3ExpirePreparedStatements(db, 0); - } - if( pRes ){ - *pRes = (db->flags & aFlagOp[i].mask)!=0; -@@ -142486,6 +153636,15 @@ - } - - /* -+** Return true if CollSeq is the default built-in BINARY. -+*/ -+SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq *p){ -+ assert( p==0 || p->xCmp!=binCollFunc || p->pUser!=0 -+ || strcmp(p->zName,"BINARY")==0 ); -+ return p==0 || (p->xCmp==binCollFunc && p->pUser==0); -+} -+ -+/* - ** Another built-in collating sequence: NOCASE. - ** - ** This collating sequence is intended to be used for "case independent -@@ -142606,7 +153765,7 @@ - sqlite3BtreeEnterAll(db); - for(i=0; i<db->nDb; i++){ - Schema *pSchema = db->aDb[i].pSchema; -- if( db->aDb[i].pSchema ){ -+ if( pSchema ){ - for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ - Table *pTab = (Table *)sqliteHashData(p); - if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab); -@@ -142824,7 +153983,7 @@ - sqlite3_mutex_leave(db->mutex); - db->magic = SQLITE_MAGIC_CLOSED; - sqlite3_mutex_free(db->mutex); -- assert( db->lookaside.nOut==0 ); /* Fails on a lookaside memory leak */ -+ assert( sqlite3LookasideUsed(db,0)==0 ); - if( db->lookaside.bMalloced ){ - sqlite3_free(db->lookaside.pStart); - } -@@ -142852,7 +154011,7 @@ - ** the database rollback and schema reset, which can cause false - ** corruption reports in some cases. */ - sqlite3BtreeEnterAll(db); -- schemaChange = (db->flags & SQLITE_InternChanges)!=0 && db->init.busy==0; -+ schemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0 && db->init.busy==0; - - for(i=0; i<db->nDb; i++){ - Btree *p = db->aDb[i].pBt; -@@ -142866,8 +154025,8 @@ - sqlite3VtabRollback(db); - sqlite3EndBenignMalloc(); - -- if( (db->flags&SQLITE_InternChanges)!=0 && db->init.busy==0 ){ -- sqlite3ExpirePreparedStatements(db); -+ if( schemaChange ){ -+ sqlite3ExpirePreparedStatements(db, 0); - sqlite3ResetAllSchemasOfConnection(db); - } - sqlite3BtreeLeaveAll(db); -@@ -142895,6 +154054,7 @@ - switch( rc ){ - case SQLITE_OK: zName = "SQLITE_OK"; break; - case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; -+ case SQLITE_ERROR_SNAPSHOT: zName = "SQLITE_ERROR_SNAPSHOT"; break; - case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break; - case SQLITE_PERM: zName = "SQLITE_PERM"; break; - case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; -@@ -142907,9 +154067,10 @@ - case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; - case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; - case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break; -- case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break; -+ case SQLITE_READONLY_CANTINIT: zName = "SQLITE_READONLY_CANTINIT"; break; - case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break; - case SQLITE_READONLY_DBMOVED: zName = "SQLITE_READONLY_DBMOVED"; break; -+ case SQLITE_READONLY_DIRECTORY: zName = "SQLITE_READONLY_DIRECTORY";break; - case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; - case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; - case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break; -@@ -143029,6 +154190,8 @@ - /* SQLITE_FORMAT */ 0, - /* SQLITE_RANGE */ "column index out of range", - /* SQLITE_NOTADB */ "file is not a database", -+ /* SQLITE_NOTICE */ "notification message", -+ /* SQLITE_WARNING */ "warning message", - }; - const char *zErr = "unknown error"; - switch( rc ){ -@@ -143036,6 +154199,14 @@ - zErr = "abort due to ROLLBACK"; - break; - } -+ case SQLITE_ROW: { -+ zErr = "another row available"; -+ break; -+ } -+ case SQLITE_DONE: { -+ zErr = "no more rows available"; -+ break; -+ } - default: { - rc &= 0xff; - if( ALWAYS(rc>=0) && rc<ArraySize(aMsg) && aMsg[rc]!=0 ){ -@@ -143052,12 +154223,18 @@ - ** again until a timeout value is reached. The timeout value is - ** an integer number of milliseconds passed in as the first - ** argument. -+** -+** Return non-zero to retry the lock. Return zero to stop trying -+** and cause SQLite to return SQLITE_BUSY. - */ - static int sqliteDefaultBusyCallback( -- void *ptr, /* Database connection */ -- int count /* Number of times table has been busy */ -+ void *ptr, /* Database connection */ -+ int count, /* Number of times table has been busy */ -+ sqlite3_file *pFile /* The file on which the lock occurred */ - ){ - #if SQLITE_OS_WIN || HAVE_USLEEP -+ /* This case is for systems that have support for sleeping for fractions of -+ ** a second. Examples: All windows systems, unix systems with usleep() */ - static const u8 delays[] = - { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 }; - static const u8 totals[] = -@@ -143064,9 +154241,22 @@ - { 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 }; - # define NDELAY ArraySize(delays) - sqlite3 *db = (sqlite3 *)ptr; -- int timeout = db->busyTimeout; -+ int tmout = db->busyTimeout; - int delay, prior; - -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ if( sqlite3OsFileControl(pFile,SQLITE_FCNTL_LOCK_TIMEOUT,&tmout)==SQLITE_OK ){ -+ if( count ){ -+ tmout = 0; -+ sqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout); -+ return 0; -+ }else{ -+ return 1; -+ } -+ } -+#else -+ UNUSED_PARAMETER(pFile); -+#endif - assert( count>=0 ); - if( count < NDELAY ){ - delay = delays[count]; -@@ -143075,16 +154265,19 @@ - delay = delays[NDELAY-1]; - prior = totals[NDELAY-1] + delay*(count-(NDELAY-1)); - } -- if( prior + delay > timeout ){ -- delay = timeout - prior; -+ if( prior + delay > tmout ){ -+ delay = tmout - prior; - if( delay<=0 ) return 0; - } - sqlite3OsSleep(db->pVfs, delay*1000); - return 1; - #else -+ /* This case for unix systems that lack usleep() support. Sleeping -+ ** must be done in increments of whole seconds */ - sqlite3 *db = (sqlite3 *)ptr; -- int timeout = ((sqlite3 *)ptr)->busyTimeout; -- if( (count+1)*1000 > timeout ){ -+ int tmout = ((sqlite3 *)ptr)->busyTimeout; -+ UNUSED_PARAMETER(pFile); -+ if( (count+1)*1000 > tmout ){ - return 0; - } - sqlite3OsSleep(db->pVfs, 1000000); -@@ -143095,14 +154288,25 @@ - /* - ** Invoke the given busy handler. - ** --** This routine is called when an operation failed with a lock. -+** This routine is called when an operation failed to acquire a -+** lock on VFS file pFile. -+** - ** If this routine returns non-zero, the lock is retried. If it - ** returns 0, the operation aborts with an SQLITE_BUSY error. - */ --SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){ -+SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p, sqlite3_file *pFile){ - int rc; -- if( NEVER(p==0) || p->xFunc==0 || p->nBusy<0 ) return 0; -- rc = p->xFunc(p->pArg, p->nBusy); -+ if( p->xBusyHandler==0 || p->nBusy<0 ) return 0; -+ if( p->bExtraFileArg ){ -+ /* Add an extra parameter with the pFile pointer to the end of the -+ ** callback argument list */ -+ int (*xTra)(void*,int,sqlite3_file*); -+ xTra = (int(*)(void*,int,sqlite3_file*))p->xBusyHandler; -+ rc = xTra(p->pBusyArg, p->nBusy, pFile); -+ }else{ -+ /* Legacy style busy handler callback */ -+ rc = p->xBusyHandler(p->pBusyArg, p->nBusy); -+ } - if( rc==0 ){ - p->nBusy = -1; - }else{ -@@ -143124,9 +154328,10 @@ - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; - #endif - sqlite3_mutex_enter(db->mutex); -- db->busyHandler.xFunc = xBusy; -- db->busyHandler.pArg = pArg; -+ db->busyHandler.xBusyHandler = xBusy; -+ db->busyHandler.pBusyArg = pArg; - db->busyHandler.nBusy = 0; -+ db->busyHandler.bExtraFileArg = 0; - db->busyTimeout = 0; - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; -@@ -143174,8 +154379,10 @@ - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; - #endif - if( ms>0 ){ -- sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db); -+ sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback, -+ (void*)db); - db->busyTimeout = ms; -+ db->busyHandler.bExtraFileArg = 1; - }else{ - sqlite3_busy_handler(db, 0, 0); - } -@@ -143211,6 +154418,8 @@ - void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), - void (*xStep)(sqlite3_context*,int,sqlite3_value **), - void (*xFinal)(sqlite3_context*), -+ void (*xValue)(sqlite3_context*), -+ void (*xInverse)(sqlite3_context*,int,sqlite3_value **), - FuncDestructor *pDestructor - ){ - FuncDef *p; -@@ -143218,12 +154427,14 @@ - int extraFlags; - - assert( sqlite3_mutex_held(db->mutex) ); -- if( zFunctionName==0 || -- (xSFunc && (xFinal || xStep)) || -- (!xSFunc && (xFinal && !xStep)) || -- (!xSFunc && (!xFinal && xStep)) || -- (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) || -- (255<(nName = sqlite3Strlen30( zFunctionName))) ){ -+ assert( xValue==0 || xSFunc==0 ); -+ if( zFunctionName==0 /* Must have a valid name */ -+ || (xSFunc!=0 && xFinal!=0) /* Not both xSFunc and xFinal */ -+ || ((xFinal==0)!=(xStep==0)) /* Both or neither of xFinal and xStep */ -+ || ((xValue==0)!=(xInverse==0)) /* Both or neither of xValue, xInverse */ -+ || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) -+ || (255<(nName = sqlite3Strlen30( zFunctionName))) -+ ){ - return SQLITE_MISUSE_BKPT; - } - -@@ -143244,10 +154455,10 @@ - }else if( enc==SQLITE_ANY ){ - int rc; - rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags, -- pUserData, xSFunc, xStep, xFinal, pDestructor); -+ pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); - if( rc==SQLITE_OK ){ - rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags, -- pUserData, xSFunc, xStep, xFinal, pDestructor); -+ pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); - } - if( rc!=SQLITE_OK ){ - return rc; -@@ -143264,7 +154475,7 @@ - ** operation to continue but invalidate all precompiled statements. - */ - p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0); -- if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){ -+ if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==(u32)enc && p->nArg==nArg ){ - if( db->nVdbeActive ){ - sqlite3ErrorWithMsg(db, SQLITE_BUSY, - "unable to delete/modify user-function due to active statements"); -@@ -143271,7 +154482,7 @@ - assert( !db->mallocFailed ); - return SQLITE_BUSY; - }else{ -- sqlite3ExpirePreparedStatements(db); -+ sqlite3ExpirePreparedStatements(db, 0); - } - } - -@@ -143293,6 +154504,8 @@ - testcase( p->funcFlags & SQLITE_DETERMINISTIC ); - p->xSFunc = xSFunc ? xSFunc : xStep; - p->xFinalize = xFinal; -+ p->xValue = xValue; -+ p->xInverse = xInverse; - p->pUserData = pUserData; - p->nArg = (u16)nArg; - return SQLITE_OK; -@@ -143299,32 +154512,24 @@ - } - - /* --** Create new user functions. -+** Worker function used by utf-8 APIs that create new functions: -+** -+** sqlite3_create_function() -+** sqlite3_create_function_v2() -+** sqlite3_create_window_function() - */ --SQLITE_API int sqlite3_create_function( -+static int createFunctionApi( - sqlite3 *db, - const char *zFunc, - int nArg, - int enc, - void *p, -- void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), -- void (*xStep)(sqlite3_context*,int,sqlite3_value **), -- void (*xFinal)(sqlite3_context*) --){ -- return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xSFunc, xStep, -- xFinal, 0); --} -- --SQLITE_API int sqlite3_create_function_v2( -- sqlite3 *db, -- const char *zFunc, -- int nArg, -- int enc, -- void *p, -- void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), -- void (*xStep)(sqlite3_context*,int,sqlite3_value **), -+ void (*xSFunc)(sqlite3_context*,int,sqlite3_value**), -+ void (*xStep)(sqlite3_context*,int,sqlite3_value**), - void (*xFinal)(sqlite3_context*), -- void (*xDestroy)(void *) -+ void (*xValue)(sqlite3_context*), -+ void (*xInverse)(sqlite3_context*,int,sqlite3_value**), -+ void(*xDestroy)(void*) - ){ - int rc = SQLITE_ERROR; - FuncDestructor *pArg = 0; -@@ -143336,19 +154541,23 @@ - #endif - sqlite3_mutex_enter(db->mutex); - if( xDestroy ){ -- pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor)); -+ pArg = (FuncDestructor *)sqlite3Malloc(sizeof(FuncDestructor)); - if( !pArg ){ -+ sqlite3OomFault(db); - xDestroy(p); - goto out; - } -+ pArg->nRef = 0; - pArg->xDestroy = xDestroy; - pArg->pUserData = p; - } -- rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xSFunc, xStep, xFinal, pArg); -+ rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, -+ xSFunc, xStep, xFinal, xValue, xInverse, pArg -+ ); - if( pArg && pArg->nRef==0 ){ - assert( rc!=SQLITE_OK ); - xDestroy(p); -- sqlite3DbFree(db, pArg); -+ sqlite3_free(pArg); - } - - out: -@@ -143357,6 +154566,52 @@ - return rc; - } - -+/* -+** Create new user functions. -+*/ -+SQLITE_API int sqlite3_create_function( -+ sqlite3 *db, -+ const char *zFunc, -+ int nArg, -+ int enc, -+ void *p, -+ void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), -+ void (*xStep)(sqlite3_context*,int,sqlite3_value **), -+ void (*xFinal)(sqlite3_context*) -+){ -+ return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep, -+ xFinal, 0, 0, 0); -+} -+SQLITE_API int sqlite3_create_function_v2( -+ sqlite3 *db, -+ const char *zFunc, -+ int nArg, -+ int enc, -+ void *p, -+ void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), -+ void (*xStep)(sqlite3_context*,int,sqlite3_value **), -+ void (*xFinal)(sqlite3_context*), -+ void (*xDestroy)(void *) -+){ -+ return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep, -+ xFinal, 0, 0, xDestroy); -+} -+SQLITE_API int sqlite3_create_window_function( -+ sqlite3 *db, -+ const char *zFunc, -+ int nArg, -+ int enc, -+ void *p, -+ void (*xStep)(sqlite3_context*,int,sqlite3_value **), -+ void (*xFinal)(sqlite3_context*), -+ void (*xValue)(sqlite3_context*), -+ void (*xInverse)(sqlite3_context*,int,sqlite3_value **), -+ void (*xDestroy)(void *) -+){ -+ return createFunctionApi(db, zFunc, nArg, enc, p, 0, xStep, -+ xFinal, xValue, xInverse, xDestroy); -+} -+ - #ifndef SQLITE_OMIT_UTF16 - SQLITE_API int sqlite3_create_function16( - sqlite3 *db, -@@ -143377,7 +154632,7 @@ - sqlite3_mutex_enter(db->mutex); - assert( !db->mallocFailed ); - zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE); -- rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0); -+ rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0,0,0); - sqlite3DbFree(db, zFunc8); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); -@@ -143387,6 +154642,28 @@ - - - /* -+** The following is the implementation of an SQL function that always -+** fails with an error message stating that the function is used in the -+** wrong context. The sqlite3_overload_function() API might construct -+** SQL function that use this routine so that the functions will exist -+** for name resolution but are actually overloaded by the xFindFunction -+** method of virtual tables. -+*/ -+static void sqlite3InvalidFunction( -+ sqlite3_context *context, /* The function calling context */ -+ int NotUsed, /* Number of arguments to the function */ -+ sqlite3_value **NotUsed2 /* Value of each argument */ -+){ -+ const char *zName = (const char*)sqlite3_user_data(context); -+ char *zErr; -+ UNUSED_PARAMETER2(NotUsed, NotUsed2); -+ zErr = sqlite3_mprintf( -+ "unable to use function %s in the requested context", zName); -+ sqlite3_result_error(context, zErr, -1); -+ sqlite3_free(zErr); -+} -+ -+/* - ** Declare that a function has been overloaded by a virtual table. - ** - ** If the function already exists as a regular global function, then -@@ -143403,7 +154680,8 @@ - const char *zName, - int nArg - ){ -- int rc = SQLITE_OK; -+ int rc; -+ char *zCopy; - - #ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || zName==0 || nArg<-2 ){ -@@ -143411,13 +154689,13 @@ - } - #endif - sqlite3_mutex_enter(db->mutex); -- if( sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)==0 ){ -- rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8, -- 0, sqlite3InvalidFunction, 0, 0, 0); -- } -- rc = sqlite3ApiExit(db, rc); -+ rc = sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)!=0; - sqlite3_mutex_leave(db->mutex); -- return rc; -+ if( rc ) return SQLITE_OK; -+ zCopy = sqlite3_mprintf(zName); -+ if( zCopy==0 ) return SQLITE_NOMEM; -+ return sqlite3_create_function_v2(db, zName, nArg, SQLITE_UTF8, -+ zCopy, sqlite3InvalidFunction, 0, 0, sqlite3_free); - } - - #ifndef SQLITE_OMIT_TRACE -@@ -143768,7 +155046,8 @@ - ** checkpointed. If an error is encountered it is returned immediately - - ** no attempt is made to checkpoint any remaining databases. - ** --** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. -+** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL, RESTART -+** or TRUNCATE. - */ - SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){ - int rc = SQLITE_OK; /* Return code */ -@@ -143978,7 +155257,7 @@ - "unable to delete/modify collation sequence due to active statements"); - return SQLITE_BUSY; - } -- sqlite3ExpirePreparedStatements(db); -+ sqlite3ExpirePreparedStatements(db, 0); - - /* If collation sequence pColl was created directly by a call to - ** sqlite3_create_collation, and not generated by synthCollSeq(), -@@ -144414,6 +155693,7 @@ - }else{ - isThreadsafe = sqlite3GlobalConfig.bFullMutex; - } -+ - if( flags & SQLITE_OPEN_PRIVATECACHE ){ - flags &= ~SQLITE_OPEN_SHAREDCACHE; - }else if( sqlite3GlobalConfig.sharedCacheEnabled ){ -@@ -144446,7 +155726,11 @@ - /* Allocate the sqlite data structure */ - db = sqlite3MallocZero( sizeof(sqlite3) ); - if( db==0 ) goto opendb_out; -- if( isThreadsafe ){ -+ if( isThreadsafe -+#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS -+ || sqlite3GlobalConfig.bCoreMutex -+#endif -+ ){ - db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); - if( db->mutex==0 ){ - sqlite3_free(db); -@@ -144453,6 +155737,9 @@ - db = 0; - goto opendb_out; - } -+ if( isThreadsafe==0 ){ -+ sqlite3MutexWarnOnContention(db->mutex); -+ } - } - sqlite3_mutex_enter(db->mutex); - db->errMask = 0xff; -@@ -144459,6 +155746,7 @@ - db->nDb = 2; - db->magic = SQLITE_MAGIC_BUSY; - db->aDb = db->aDbStatic; -+ db->lookaside.bDisable = 1; - - assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); - memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); -@@ -144499,6 +155787,9 @@ - #if defined(SQLITE_ENABLE_QPSG) - | SQLITE_EnableQPSG - #endif -+#if defined(SQLITE_DEFAULT_DEFENSIVE) -+ | SQLITE_Defensive -+#endif - ; - sqlite3HashInit(&db->aCollSeq); - #ifndef SQLITE_OMIT_VIRTUALTABLE -@@ -144634,7 +155925,7 @@ - } - #endif - --#ifdef SQLITE_ENABLE_ICU -+#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS) - if( !db->mallocFailed && rc==SQLITE_OK ){ - rc = sqlite3IcuInit(db); - } -@@ -144646,6 +155937,12 @@ - } - #endif - -+#ifdef SQLITE_ENABLE_DBPAGE_VTAB -+ if( !db->mallocFailed && rc==SQLITE_OK){ -+ rc = sqlite3DbpageRegister(db); -+ } -+#endif -+ - #ifdef SQLITE_ENABLE_DBSTAT_VTAB - if( !db->mallocFailed && rc==SQLITE_OK){ - rc = sqlite3DbstatRegister(db); -@@ -144930,7 +156227,7 @@ - ** 2. Invoke sqlite3_log() to provide the source code location where - ** a low-level error is first detected. - */ --static int reportError(int iErr, int lineno, const char *zType){ -+SQLITE_PRIVATE int sqlite3ReportError(int iErr, int lineno, const char *zType){ - sqlite3_log(iErr, "%s at line %d of [%.10s]", - zType, lineno, 20+sqlite3_sourceid()); - return iErr; -@@ -144937,15 +156234,15 @@ - } - SQLITE_PRIVATE int sqlite3CorruptError(int lineno){ - testcase( sqlite3GlobalConfig.xLog!=0 ); -- return reportError(SQLITE_CORRUPT, lineno, "database corruption"); -+ return sqlite3ReportError(SQLITE_CORRUPT, lineno, "database corruption"); - } - SQLITE_PRIVATE int sqlite3MisuseError(int lineno){ - testcase( sqlite3GlobalConfig.xLog!=0 ); -- return reportError(SQLITE_MISUSE, lineno, "misuse"); -+ return sqlite3ReportError(SQLITE_MISUSE, lineno, "misuse"); - } - SQLITE_PRIVATE int sqlite3CantopenError(int lineno){ - testcase( sqlite3GlobalConfig.xLog!=0 ); -- return reportError(SQLITE_CANTOPEN, lineno, "cannot open file"); -+ return sqlite3ReportError(SQLITE_CANTOPEN, lineno, "cannot open file"); - } - #ifdef SQLITE_DEBUG - SQLITE_PRIVATE int sqlite3CorruptPgnoError(int lineno, Pgno pgno){ -@@ -144952,15 +156249,15 @@ - char zMsg[100]; - sqlite3_snprintf(sizeof(zMsg), zMsg, "database corruption page %d", pgno); - testcase( sqlite3GlobalConfig.xLog!=0 ); -- return reportError(SQLITE_CORRUPT, lineno, zMsg); -+ return sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg); - } - SQLITE_PRIVATE int sqlite3NomemError(int lineno){ - testcase( sqlite3GlobalConfig.xLog!=0 ); -- return reportError(SQLITE_NOMEM, lineno, "OOM"); -+ return sqlite3ReportError(SQLITE_NOMEM, lineno, "OOM"); - } - SQLITE_PRIVATE int sqlite3IoerrnomemError(int lineno){ - testcase( sqlite3GlobalConfig.xLog!=0 ); -- return reportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error"); -+ return sqlite3ReportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error"); - } - #endif - -@@ -145153,10 +156450,11 @@ - }else if( op==SQLITE_FCNTL_JOURNAL_POINTER ){ - *(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager); - rc = SQLITE_OK; -- }else if( fd->pMethods ){ -+ }else if( op==SQLITE_FCNTL_DATA_VERSION ){ -+ *(unsigned int*)pArg = sqlite3PagerDataVersion(pPager); -+ rc = SQLITE_OK; -+ }else{ - rc = sqlite3OsFileControl(fd, op, pArg); -- }else{ -- rc = SQLITE_NOTFOUND; - } - sqlite3BtreeLeave(pBtree); - } -@@ -145305,7 +156603,7 @@ - ** This action provides a run-time test to see how the ALWAYS and - ** NEVER macros were defined at compile-time. - ** -- ** The return value is ALWAYS(X). -+ ** The return value is ALWAYS(X) if X is true, or 0 if X is false. - ** - ** The recommended test is X==2. If the return value is 2, that means - ** ALWAYS() and NEVER() are both no-op pass-through macros, which is the -@@ -145328,7 +156626,7 @@ - */ - case SQLITE_TESTCTRL_ALWAYS: { - int x = va_arg(ap,int); -- rc = ALWAYS(x); -+ rc = x ? ALWAYS(x) : 0; - break; - } - -@@ -145377,51 +156675,28 @@ - break; - } - --#ifdef SQLITE_N_KEYWORD -- /* sqlite3_test_control(SQLITE_TESTCTRL_ISKEYWORD, const char *zWord) -+ /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); - ** -- ** If zWord is a keyword recognized by the parser, then return the -- ** number of keywords. Or if zWord is not a keyword, return 0. -- ** -- ** This test feature is only available in the amalgamation since -- ** the SQLITE_N_KEYWORD macro is not defined in this file if SQLite -- ** is built using separate source files. -+ ** If parameter onoff is non-zero, subsequent calls to localtime() -+ ** and its variants fail. If onoff is zero, undo this setting. - */ -- case SQLITE_TESTCTRL_ISKEYWORD: { -- const char *zWord = va_arg(ap, const char*); -- int n = sqlite3Strlen30(zWord); -- rc = (sqlite3KeywordCode((u8*)zWord, n)!=TK_ID) ? SQLITE_N_KEYWORD : 0; -+ case SQLITE_TESTCTRL_LOCALTIME_FAULT: { -+ sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); - break; - } --#endif - -- /* sqlite3_test_control(SQLITE_TESTCTRL_SCRATCHMALLOC, sz, &pNew, pFree); -+ /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCS, int onoff); - ** -- ** Pass pFree into sqlite3ScratchFree(). -- ** If sz>0 then allocate a scratch buffer into pNew. -+ ** 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. - */ -- case SQLITE_TESTCTRL_SCRATCHMALLOC: { -- void *pFree, **ppNew; -- int sz; -- sz = va_arg(ap, int); -- ppNew = va_arg(ap, void**); -- pFree = va_arg(ap, void*); -- if( sz ) *ppNew = sqlite3ScratchMalloc(sz); -- sqlite3ScratchFree(pFree); -+ case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: { -+ sqlite3GlobalConfig.bInternalFunctions = va_arg(ap, int); - break; - } - -- /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); -- ** -- ** If parameter onoff is non-zero, configure the wrappers so that all -- ** subsequent calls to localtime() and variants fail. If onoff is zero, -- ** undo this setting. -- */ -- case SQLITE_TESTCTRL_LOCALTIME_FAULT: { -- sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); -- break; -- } -- - /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int); - ** - ** Set or clear a flag that indicates that the database file is always well- -@@ -145452,7 +156727,8 @@ - */ - case SQLITE_TESTCTRL_VDBE_COVERAGE: { - #ifdef SQLITE_VDBE_COVERAGE -- typedef void (*branch_callback)(void*,int,u8,u8); -+ typedef void (*branch_callback)(void*,unsigned int, -+ unsigned char,unsigned char); - sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback); - sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); - #endif -@@ -145504,6 +156780,22 @@ - sqlite3_mutex_leave(db->mutex); - break; - } -+ -+#if defined(YYCOVERAGE) -+ /* sqlite3_test_control(SQLITE_TESTCTRL_PARSER_COVERAGE, FILE *out) -+ ** -+ ** This test control (only available when SQLite is compiled with -+ ** -DYYCOVERAGE) writes a report onto "out" that shows all -+ ** state/lookahead combinations in the parser state machine -+ ** which are never exercised. If any state is missed, make the -+ ** return code SQLITE_ERROR. -+ */ -+ case SQLITE_TESTCTRL_PARSER_COVERAGE: { -+ FILE *out = va_arg(ap, FILE*); -+ if( sqlite3ParserCoverage(out) ) rc = SQLITE_ERROR; -+ break; -+ } -+#endif /* defined(YYCOVERAGE) */ - } - va_end(ap); - #endif /* SQLITE_UNTESTABLE */ -@@ -145552,7 +156844,7 @@ - ){ - const char *z = sqlite3_uri_parameter(zFilename, zParam); - sqlite3_int64 v; -- if( z && sqlite3DecOrHexToI64(z, &v)==SQLITE_OK ){ -+ if( z && sqlite3DecOrHexToI64(z, &v)==0 ){ - bDflt = v; - } - return bDflt; -@@ -145623,7 +156915,7 @@ - if( iDb==0 || iDb>1 ){ - Btree *pBt = db->aDb[iDb].pBt; - if( 0==sqlite3BtreeIsInTrans(pBt) ){ -- rc = sqlite3BtreeBeginTrans(pBt, 0); -+ rc = sqlite3BtreeBeginTrans(pBt, 0, 0); - if( rc==SQLITE_OK ){ - rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); - } -@@ -145658,12 +156950,30 @@ - iDb = sqlite3FindDbName(db, zDb); - if( iDb==0 || iDb>1 ){ - Btree *pBt = db->aDb[iDb].pBt; -- if( 0==sqlite3BtreeIsInReadTrans(pBt) ){ -- rc = sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), pSnapshot); -+ if( sqlite3BtreeIsInTrans(pBt)==0 ){ -+ Pager *pPager = sqlite3BtreePager(pBt); -+ int bUnlock = 0; -+ if( sqlite3BtreeIsInReadTrans(pBt) ){ -+ if( db->nVdbeActive==0 ){ -+ rc = sqlite3PagerSnapshotCheck(pPager, pSnapshot); -+ if( rc==SQLITE_OK ){ -+ bUnlock = 1; -+ rc = sqlite3BtreeCommit(pBt); -+ } -+ } -+ }else{ -+ rc = SQLITE_OK; -+ } - if( rc==SQLITE_OK ){ -- rc = sqlite3BtreeBeginTrans(pBt, 0); -- sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), 0); -+ rc = sqlite3PagerSnapshotOpen(pPager, pSnapshot); - } -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3BtreeBeginTrans(pBt, 0, 0); -+ sqlite3PagerSnapshotOpen(pPager, 0); -+ } -+ if( bUnlock ){ -+ sqlite3PagerSnapshotUnlock(pPager); -+ } - } - } - } -@@ -145693,7 +157003,7 @@ - if( iDb==0 || iDb>1 ){ - Btree *pBt = db->aDb[iDb].pBt; - if( 0==sqlite3BtreeIsInReadTrans(pBt) ){ -- rc = sqlite3BtreeBeginTrans(pBt, 0); -+ rc = sqlite3BtreeBeginTrans(pBt, 0, 0); - if( rc==SQLITE_OK ){ - rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt)); - sqlite3BtreeCommit(pBt); -@@ -147261,7 +158571,7 @@ - ); - SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *); - #ifdef SQLITE_TEST --SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db); -+SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash*); - SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db); - #endif - -@@ -148829,7 +160139,7 @@ - const char *zCsr = zNode; /* Cursor to iterate through node */ - const char *zEnd = &zCsr[nNode];/* End of interior node buffer */ - char *zBuffer = 0; /* Buffer to load terms into */ -- int nAlloc = 0; /* Size of allocated buffer */ -+ i64 nAlloc = 0; /* Size of allocated buffer */ - int isFirstTerm = 1; /* True when processing first term on page */ - sqlite3_int64 iChild; /* Block id of child node to descend to */ - -@@ -148867,14 +160177,14 @@ - zCsr += fts3GetVarint32(zCsr, &nSuffix); - - assert( nPrefix>=0 && nSuffix>=0 ); -- if( &zCsr[nSuffix]>zEnd ){ -+ if( nPrefix>zCsr-zNode || nSuffix>zEnd-zCsr ){ - rc = FTS_CORRUPT_VTAB; - goto finish_scan; - } -- if( nPrefix+nSuffix>nAlloc ){ -+ if( (i64)nPrefix+nSuffix>nAlloc ){ - char *zNew; -- nAlloc = (nPrefix+nSuffix) * 2; -- zNew = (char *)sqlite3_realloc(zBuffer, nAlloc); -+ nAlloc = ((i64)nPrefix+nSuffix) * 2; -+ zNew = (char *)sqlite3_realloc64(zBuffer, nAlloc); - if( !zNew ){ - rc = SQLITE_NOMEM; - goto finish_scan; -@@ -150816,7 +162126,7 @@ - int rc = SQLITE_OK; - UNUSED_PARAMETER(iSavepoint); - assert( ((Fts3Table *)pVtab)->inTransaction ); -- assert( ((Fts3Table *)pVtab)->mxSavepoint < iSavepoint ); -+ assert( ((Fts3Table *)pVtab)->mxSavepoint <= iSavepoint ); - TESTONLY( ((Fts3Table *)pVtab)->mxSavepoint = iSavepoint ); - if( ((Fts3Table *)pVtab)->bIgnoreSavepoint==0 ){ - rc = fts3SyncMethod(pVtab); -@@ -150854,8 +162164,23 @@ - return SQLITE_OK; - } - -+/* -+** Return true if zName is the extension on one of the shadow tables used -+** by this module. -+*/ -+static int fts3ShadowName(const char *zName){ -+ static const char *azName[] = { -+ "content", "docsize", "segdir", "segments", "stat", -+ }; -+ unsigned int i; -+ for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){ -+ if( sqlite3_stricmp(zName, azName[i])==0 ) return 1; -+ } -+ return 0; -+} -+ - static const sqlite3_module fts3Module = { -- /* iVersion */ 2, -+ /* iVersion */ 3, - /* xCreate */ fts3CreateMethod, - /* xConnect */ fts3ConnectMethod, - /* xBestIndex */ fts3BestIndexMethod, -@@ -150878,6 +162203,7 @@ - /* xSavepoint */ fts3SavepointMethod, - /* xRelease */ fts3ReleaseMethod, - /* xRollbackTo */ fts3RollbackToMethod, -+ /* xShadowName */ fts3ShadowName, - }; - - /* -@@ -150971,7 +162297,7 @@ - - #ifdef SQLITE_TEST - if( rc==SQLITE_OK ){ -- rc = sqlite3Fts3ExprInitTestInterface(db); -+ rc = sqlite3Fts3ExprInitTestInterface(db, pHash); - } - #endif - -@@ -151158,6 +162484,7 @@ - return rc; - } - -+#ifndef SQLITE_DISABLE_FTS4_DEFERRED - /* - ** This function is called on each phrase after the position lists for - ** any deferred tokens have been loaded into memory. It updates the phrases -@@ -151261,6 +162588,7 @@ - - return SQLITE_OK; - } -+#endif /* SQLITE_DISABLE_FTS4_DEFERRED */ - - /* - ** Maximum number of tokens a phrase may have to be considered for the -@@ -153509,7 +164837,8 @@ - 0, /* xRename */ - 0, /* xSavepoint */ - 0, /* xRelease */ -- 0 /* xRollbackTo */ -+ 0, /* xRollbackTo */ -+ 0 /* xShadowName */ - }; - int rc; /* Return code */ - -@@ -154632,34 +165961,6 @@ - /* #include <stdio.h> */ - - /* --** Function to query the hash-table of tokenizers (see README.tokenizers). --*/ --static int queryTestTokenizer( -- sqlite3 *db, -- const char *zName, -- const sqlite3_tokenizer_module **pp --){ -- int rc; -- sqlite3_stmt *pStmt; -- const char zSql[] = "SELECT fts3_tokenizer(?)"; -- -- *pp = 0; -- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); -- if( rc!=SQLITE_OK ){ -- return rc; -- } -- -- sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); -- if( SQLITE_ROW==sqlite3_step(pStmt) ){ -- if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){ -- memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp)); -- } -- } -- -- return sqlite3_finalize(pStmt); --} -- --/* - ** Return a pointer to a buffer containing a text representation of the - ** expression passed as the first argument. The buffer is obtained from - ** sqlite3_malloc(). It is the responsibility of the caller to use -@@ -154726,12 +166027,12 @@ - ** - ** SELECT fts3_exprtest('simple', 'Bill col2:Bloggs', 'col1', 'col2'); - */ --static void fts3ExprTest( -+static void fts3ExprTestCommon( -+ int bRebalance, - sqlite3_context *context, - int argc, - sqlite3_value **argv - ){ -- sqlite3_tokenizer_module const *pModule = 0; - sqlite3_tokenizer *pTokenizer = 0; - int rc; - char **azCol = 0; -@@ -154741,7 +166042,9 @@ - int ii; - Fts3Expr *pExpr; - char *zBuf = 0; -- sqlite3 *db = sqlite3_context_db_handle(context); -+ Fts3Hash *pHash = (Fts3Hash*)sqlite3_user_data(context); -+ const char *zTokenizer = 0; -+ char *zErr = 0; - - if( argc<3 ){ - sqlite3_result_error(context, -@@ -154750,24 +166053,18 @@ - return; - } - -- rc = queryTestTokenizer(db, -- (const char *)sqlite3_value_text(argv[0]), &pModule); -- if( rc==SQLITE_NOMEM ){ -- sqlite3_result_error_nomem(context); -- goto exprtest_out; -- }else if( !pModule ){ -- sqlite3_result_error(context, "No such tokenizer module", -1); -- goto exprtest_out; -+ zTokenizer = (const char*)sqlite3_value_text(argv[0]); -+ rc = sqlite3Fts3InitTokenizer(pHash, zTokenizer, &pTokenizer, &zErr); -+ if( rc!=SQLITE_OK ){ -+ if( rc==SQLITE_NOMEM ){ -+ sqlite3_result_error_nomem(context); -+ }else{ -+ sqlite3_result_error(context, zErr, -1); -+ } -+ sqlite3_free(zErr); -+ return; - } - -- rc = pModule->xCreate(0, 0, &pTokenizer); -- assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); -- if( rc==SQLITE_NOMEM ){ -- sqlite3_result_error_nomem(context); -- goto exprtest_out; -- } -- pTokenizer->pModule = pModule; -- - zExpr = (const char *)sqlite3_value_text(argv[1]); - nExpr = sqlite3_value_bytes(argv[1]); - nCol = argc-2; -@@ -154780,7 +166077,7 @@ - azCol[ii] = (char *)sqlite3_value_text(argv[ii+2]); - } - -- if( sqlite3_user_data(context) ){ -+ if( bRebalance ){ - char *zDummy = 0; - rc = sqlite3Fts3ExprParse( - pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr, &zDummy -@@ -154806,23 +166103,38 @@ - sqlite3Fts3ExprFree(pExpr); - - exprtest_out: -- if( pModule && pTokenizer ){ -- rc = pModule->xDestroy(pTokenizer); -+ if( pTokenizer ){ -+ rc = pTokenizer->pModule->xDestroy(pTokenizer); - } - sqlite3_free(azCol); - } - -+static void fts3ExprTest( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ fts3ExprTestCommon(0, context, argc, argv); -+} -+static void fts3ExprTestRebalance( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ fts3ExprTestCommon(1, context, argc, argv); -+} -+ - /* - ** Register the query expression parser test function fts3_exprtest() - ** with database connection db. - */ --SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3* db){ -+SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash *pHash){ - int rc = sqlite3_create_function( -- db, "fts3_exprtest", -1, SQLITE_UTF8, 0, fts3ExprTest, 0, 0 -+ db, "fts3_exprtest", -1, SQLITE_UTF8, (void*)pHash, fts3ExprTest, 0, 0 - ); - if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "fts3_exprtest_rebalance", -- -1, SQLITE_UTF8, (void *)1, fts3ExprTest, 0, 0 -+ -1, SQLITE_UTF8, (void*)pHash, fts3ExprTestRebalance, 0, 0 - ); - } - return rc; -@@ -157085,7 +168397,8 @@ - 0, /* xRename */ - 0, /* xSavepoint */ - 0, /* xRelease */ -- 0 /* xRollbackTo */ -+ 0, /* xRollbackTo */ -+ 0 /* xShadowName */ - }; - int rc; /* Return code */ - -@@ -158473,15 +169786,19 @@ - ** safe (no risk of overread) even if the node data is corrupted. */ - pNext += fts3GetVarint32(pNext, &nPrefix); - pNext += fts3GetVarint32(pNext, &nSuffix); -- if( nPrefix<0 || nSuffix<=0 -- || &pNext[nSuffix]>&pReader->aNode[pReader->nNode] -+ if( nSuffix<=0 -+ || (&pReader->aNode[pReader->nNode] - pNext)<nSuffix -+ || nPrefix>pReader->nTermAlloc - ){ - return FTS_CORRUPT_VTAB; - } - -- if( nPrefix+nSuffix>pReader->nTermAlloc ){ -- int nNew = (nPrefix+nSuffix)*2; -- char *zNew = sqlite3_realloc(pReader->zTerm, nNew); -+ /* Both nPrefix and nSuffix were read by fts3GetVarint32() and so are -+ ** between 0 and 0x7FFFFFFF. But the sum of the two may cause integer -+ ** overflow - hence the (i64) casts. */ -+ if( (i64)nPrefix+nSuffix>(i64)pReader->nTermAlloc ){ -+ i64 nNew = ((i64)nPrefix+nSuffix)*2; -+ char *zNew = sqlite3_realloc64(pReader->zTerm, nNew); - if( !zNew ){ - return SQLITE_NOMEM; - } -@@ -158503,7 +169820,7 @@ - ** b-tree node. And that the final byte of the doclist is 0x00. If either - ** of these statements is untrue, then the data structure is corrupt. - */ -- if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode] -+ if( (&pReader->aNode[pReader->nNode] - pReader->aDoclist)<pReader->nDoclist - || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1]) - ){ - return FTS_CORRUPT_VTAB; -@@ -159007,6 +170324,7 @@ - sqlite3_bind_blob(pStmt, 2, z, n, SQLITE_STATIC); - sqlite3_step(pStmt); - rc = sqlite3_reset(pStmt); -+ sqlite3_bind_null(pStmt, 2); - } - return rc; - } -@@ -159063,6 +170381,7 @@ - sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC); - sqlite3_step(pStmt); - rc = sqlite3_reset(pStmt); -+ sqlite3_bind_null(pStmt, 6); - } - return rc; - } -@@ -160542,6 +171861,7 @@ - sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, SQLITE_STATIC); - sqlite3_step(pStmt); - *pRC = sqlite3_reset(pStmt); -+ sqlite3_bind_null(pStmt, 2); - sqlite3_free(a); - } - -@@ -160826,6 +172146,9 @@ - } - p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix); - -+ if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){ -+ return SQLITE_CORRUPT_VTAB; -+ } - blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc); - if( rc==SQLITE_OK ){ - memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix); -@@ -160833,6 +172156,9 @@ - p->iOff += nSuffix; - if( p->iChild==0 ){ - p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist); -+ if( (p->nNode-p->iOff)<p->nDoclist ){ -+ return SQLITE_CORRUPT_VTAB; -+ } - p->aDoclist = &p->aNode[p->iOff]; - p->iOff += p->nDoclist; - } -@@ -160840,7 +172166,6 @@ - } - - assert( p->iOff<=p->nNode ); -- - return rc; - } - -@@ -161730,6 +173055,7 @@ - sqlite3_bind_int(pChomp, 4, iIdx); - sqlite3_step(pChomp); - rc = sqlite3_reset(pChomp); -+ sqlite3_bind_null(pChomp, 2); - } - } - -@@ -161809,6 +173135,7 @@ - sqlite3_bind_blob(pReplace, 2, pHint->a, pHint->n, SQLITE_STATIC); - sqlite3_step(pReplace); - rc = sqlite3_reset(pReplace); -+ sqlite3_bind_null(pReplace, 2); - } - - return rc; -@@ -162623,7 +173950,6 @@ - ){ - Fts3Table *p = (Fts3Table *)pVtab; - int rc = SQLITE_OK; /* Return Code */ -- int isRemove = 0; /* True for an UPDATE or DELETE */ - u32 *aSzIns = 0; /* Sizes of inserted documents */ - u32 *aSzDel = 0; /* Sizes of deleted documents */ - int nChng = 0; /* Net change in number of documents */ -@@ -162721,7 +174047,6 @@ - if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ - assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER ); - rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel); -- isRemove = 1; - } - - /* If this is an INSERT or UPDATE operation, insert the new record. */ -@@ -162733,7 +174058,7 @@ - rc = FTS_CORRUPT_VTAB; - } - } -- if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){ -+ if( rc==SQLITE_OK ){ - rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid); - } - if( rc==SQLITE_OK ){ -@@ -165253,6 +176578,2550 @@ - #endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */ - - /************** End of fts3_unicode2.c ***************************************/ -+/************** Begin file json1.c *******************************************/ -+/* -+** 2015-08-12 -+** -+** 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 JSON functions. The interface is -+** modeled after MySQL JSON functions: -+** -+** https://dev.mysql.com/doc/refman/5.7/en/json.html -+** -+** For the time being, all JSON is stored as pure text. (We might add -+** a JSONB type in the future which stores a binary encoding of JSON in -+** a BLOB, but there is no support for JSONB in the current implementation. -+** This implementation parses JSON text at 250 MB/s, so it is hard to see -+** how JSONB might improve on that.) -+*/ -+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) -+#if !defined(SQLITEINT_H) -+/* #include "sqlite3ext.h" */ -+#endif -+SQLITE_EXTENSION_INIT1 -+/* #include <assert.h> */ -+/* #include <string.h> */ -+/* #include <stdlib.h> */ -+/* #include <stdarg.h> */ -+ -+/* Mark a function parameter as unused, to suppress nuisance compiler -+** warnings. */ -+#ifndef UNUSED_PARAM -+# define UNUSED_PARAM(X) (void)(X) -+#endif -+ -+#ifndef LARGEST_INT64 -+# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) -+# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) -+#endif -+ -+/* -+** Versions of isspace(), isalnum() and isdigit() to which it is safe -+** to pass signed char values. -+*/ -+#ifdef sqlite3Isdigit -+ /* Use the SQLite core versions if this routine is part of the -+ ** SQLite amalgamation */ -+# define safe_isdigit(x) sqlite3Isdigit(x) -+# define safe_isalnum(x) sqlite3Isalnum(x) -+# define safe_isxdigit(x) sqlite3Isxdigit(x) -+#else -+ /* Use the standard library for separate compilation */ -+#include <ctype.h> /* amalgamator: keep */ -+# define safe_isdigit(x) isdigit((unsigned char)(x)) -+# define safe_isalnum(x) isalnum((unsigned char)(x)) -+# define safe_isxdigit(x) isxdigit((unsigned char)(x)) -+#endif -+ -+/* -+** Growing our own isspace() routine this way is twice as fast as -+** the library isspace() function, resulting in a 7% overall performance -+** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). -+*/ -+static const char jsonIsSpace[] = { -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+}; -+#define safe_isspace(x) (jsonIsSpace[(unsigned char)x]) -+ -+#ifndef SQLITE_AMALGAMATION -+ /* Unsigned integer types. These are already defined in the sqliteInt.h, -+ ** but the definitions need to be repeated for separate compilation. */ -+ typedef sqlite3_uint64 u64; -+ typedef unsigned int u32; -+ typedef unsigned short int u16; -+ typedef unsigned char u8; -+#endif -+ -+/* Objects */ -+typedef struct JsonString JsonString; -+typedef struct JsonNode JsonNode; -+typedef struct JsonParse JsonParse; -+ -+/* An instance of this object represents a JSON string -+** under construction. Really, this is a generic string accumulator -+** that can be and is used to create strings other than JSON. -+*/ -+struct JsonString { -+ sqlite3_context *pCtx; /* Function context - put error messages here */ -+ char *zBuf; /* Append JSON content here */ -+ u64 nAlloc; /* Bytes of storage available in zBuf[] */ -+ u64 nUsed; /* Bytes of zBuf[] currently used */ -+ u8 bStatic; /* True if zBuf is static space */ -+ u8 bErr; /* True if an error has been encountered */ -+ char zSpace[100]; /* Initial static space */ -+}; -+ -+/* JSON type values -+*/ -+#define JSON_NULL 0 -+#define JSON_TRUE 1 -+#define JSON_FALSE 2 -+#define JSON_INT 3 -+#define JSON_REAL 4 -+#define JSON_STRING 5 -+#define JSON_ARRAY 6 -+#define JSON_OBJECT 7 -+ -+/* The "subtype" set for JSON values */ -+#define JSON_SUBTYPE 74 /* Ascii for "J" */ -+ -+/* -+** Names of the various JSON types: -+*/ -+static const char * const jsonType[] = { -+ "null", "true", "false", "integer", "real", "text", "array", "object" -+}; -+ -+/* Bit values for the JsonNode.jnFlag field -+*/ -+#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */ -+#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */ -+#define JNODE_REMOVE 0x04 /* Do not output */ -+#define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */ -+#define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */ -+#define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */ -+#define JNODE_LABEL 0x40 /* Is a label of an object */ -+ -+ -+/* A single node of parsed JSON -+*/ -+struct JsonNode { -+ u8 eType; /* One of the JSON_ type values */ -+ u8 jnFlags; /* JNODE flags */ -+ u32 n; /* Bytes of content, or number of sub-nodes */ -+ union { -+ const char *zJContent; /* Content for INT, REAL, and STRING */ -+ u32 iAppend; /* More terms for ARRAY and OBJECT */ -+ u32 iKey; /* Key for ARRAY objects in json_tree() */ -+ u32 iReplace; /* Replacement content for JNODE_REPLACE */ -+ JsonNode *pPatch; /* Node chain of patch for JNODE_PATCH */ -+ } u; -+}; -+ -+/* A completely parsed JSON string -+*/ -+struct JsonParse { -+ u32 nNode; /* Number of slots of aNode[] used */ -+ u32 nAlloc; /* Number of slots of aNode[] allocated */ -+ JsonNode *aNode; /* Array of nodes containing the parse */ -+ const char *zJson; /* Original JSON string */ -+ u32 *aUp; /* Index of parent of each node */ -+ u8 oom; /* Set to true if out of memory */ -+ u8 nErr; /* Number of errors seen */ -+ u16 iDepth; /* Nesting depth */ -+ int nJson; /* Length of the zJson string in bytes */ -+ u32 iHold; /* Replace cache line with the lowest iHold value */ -+}; -+ -+/* -+** Maximum nesting depth of JSON for this implementation. -+** -+** This limit is needed to avoid a stack overflow in the recursive -+** descent parser. A depth of 2000 is far deeper than any sane JSON -+** should go. -+*/ -+#define JSON_MAX_DEPTH 2000 -+ -+/************************************************************************** -+** Utility routines for dealing with JsonString objects -+**************************************************************************/ -+ -+/* Set the JsonString object to an empty string -+*/ -+static void jsonZero(JsonString *p){ -+ p->zBuf = p->zSpace; -+ p->nAlloc = sizeof(p->zSpace); -+ p->nUsed = 0; -+ p->bStatic = 1; -+} -+ -+/* Initialize the JsonString object -+*/ -+static void jsonInit(JsonString *p, sqlite3_context *pCtx){ -+ p->pCtx = pCtx; -+ p->bErr = 0; -+ jsonZero(p); -+} -+ -+ -+/* Free all allocated memory and reset the JsonString object back to its -+** initial state. -+*/ -+static void jsonReset(JsonString *p){ -+ if( !p->bStatic ) sqlite3_free(p->zBuf); -+ jsonZero(p); -+} -+ -+ -+/* Report an out-of-memory (OOM) condition -+*/ -+static void jsonOom(JsonString *p){ -+ p->bErr = 1; -+ sqlite3_result_error_nomem(p->pCtx); -+ jsonReset(p); -+} -+ -+/* Enlarge pJson->zBuf so that it can hold at least N more bytes. -+** Return zero on success. Return non-zero on an OOM error -+*/ -+static int jsonGrow(JsonString *p, u32 N){ -+ u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10; -+ char *zNew; -+ if( p->bStatic ){ -+ if( p->bErr ) return 1; -+ zNew = sqlite3_malloc64(nTotal); -+ if( zNew==0 ){ -+ jsonOom(p); -+ return SQLITE_NOMEM; -+ } -+ memcpy(zNew, p->zBuf, (size_t)p->nUsed); -+ p->zBuf = zNew; -+ p->bStatic = 0; -+ }else{ -+ zNew = sqlite3_realloc64(p->zBuf, nTotal); -+ if( zNew==0 ){ -+ jsonOom(p); -+ return SQLITE_NOMEM; -+ } -+ p->zBuf = zNew; -+ } -+ p->nAlloc = nTotal; -+ return SQLITE_OK; -+} -+ -+/* Append N bytes from zIn onto the end of the JsonString string. -+*/ -+static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ -+ if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return; -+ memcpy(p->zBuf+p->nUsed, zIn, N); -+ p->nUsed += N; -+} -+ -+/* Append formatted text (not to exceed N bytes) to the JsonString. -+*/ -+static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ -+ va_list ap; -+ if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return; -+ va_start(ap, zFormat); -+ sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap); -+ va_end(ap); -+ p->nUsed += (int)strlen(p->zBuf+p->nUsed); -+} -+ -+/* Append a single character -+*/ -+static void jsonAppendChar(JsonString *p, char c){ -+ if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return; -+ p->zBuf[p->nUsed++] = c; -+} -+ -+/* Append a comma separator to the output buffer, if the previous -+** character is not '[' or '{'. -+*/ -+static void jsonAppendSeparator(JsonString *p){ -+ char c; -+ if( p->nUsed==0 ) return; -+ c = p->zBuf[p->nUsed-1]; -+ if( c!='[' && c!='{' ) jsonAppendChar(p, ','); -+} -+ -+/* Append the N-byte string in zIn to the end of the JsonString string -+** under construction. Enclose the string in "..." and escape -+** any double-quotes or backslash characters contained within the -+** string. -+*/ -+static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ -+ u32 i; -+ if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return; -+ p->zBuf[p->nUsed++] = '"'; -+ for(i=0; i<N; i++){ -+ unsigned char c = ((unsigned const char*)zIn)[i]; -+ if( c=='"' || c=='\\' ){ -+ json_simple_escape: -+ if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; -+ p->zBuf[p->nUsed++] = '\\'; -+ }else if( c<=0x1f ){ -+ static const char aSpecial[] = { -+ 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+ }; -+ assert( sizeof(aSpecial)==32 ); -+ assert( aSpecial['\b']=='b' ); -+ assert( aSpecial['\f']=='f' ); -+ assert( aSpecial['\n']=='n' ); -+ assert( aSpecial['\r']=='r' ); -+ assert( aSpecial['\t']=='t' ); -+ if( aSpecial[c] ){ -+ c = aSpecial[c]; -+ goto json_simple_escape; -+ } -+ if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return; -+ p->zBuf[p->nUsed++] = '\\'; -+ p->zBuf[p->nUsed++] = 'u'; -+ p->zBuf[p->nUsed++] = '0'; -+ p->zBuf[p->nUsed++] = '0'; -+ p->zBuf[p->nUsed++] = '0' + (c>>4); -+ c = "0123456789abcdef"[c&0xf]; -+ } -+ p->zBuf[p->nUsed++] = c; -+ } -+ p->zBuf[p->nUsed++] = '"'; -+ assert( p->nUsed<p->nAlloc ); -+} -+ -+/* -+** Append a function parameter value to the JSON string under -+** construction. -+*/ -+static void jsonAppendValue( -+ JsonString *p, /* Append to this JSON string */ -+ sqlite3_value *pValue /* Value to append */ -+){ -+ switch( sqlite3_value_type(pValue) ){ -+ case SQLITE_NULL: { -+ jsonAppendRaw(p, "null", 4); -+ break; -+ } -+ case SQLITE_INTEGER: -+ case SQLITE_FLOAT: { -+ const char *z = (const char*)sqlite3_value_text(pValue); -+ u32 n = (u32)sqlite3_value_bytes(pValue); -+ jsonAppendRaw(p, z, n); -+ break; -+ } -+ case SQLITE_TEXT: { -+ const char *z = (const char*)sqlite3_value_text(pValue); -+ u32 n = (u32)sqlite3_value_bytes(pValue); -+ if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){ -+ jsonAppendRaw(p, z, n); -+ }else{ -+ jsonAppendString(p, z, n); -+ } -+ break; -+ } -+ default: { -+ if( p->bErr==0 ){ -+ sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); -+ p->bErr = 2; -+ jsonReset(p); -+ } -+ break; -+ } -+ } -+} -+ -+ -+/* Make the JSON in p the result of the SQL function. -+*/ -+static void jsonResult(JsonString *p){ -+ if( p->bErr==0 ){ -+ sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, -+ p->bStatic ? SQLITE_TRANSIENT : sqlite3_free, -+ SQLITE_UTF8); -+ jsonZero(p); -+ } -+ assert( p->bStatic ); -+} -+ -+/************************************************************************** -+** Utility routines for dealing with JsonNode and JsonParse objects -+**************************************************************************/ -+ -+/* -+** Return the number of consecutive JsonNode slots need to represent -+** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and -+** OBJECT types, the number might be larger. -+** -+** Appended elements are not counted. The value returned is the number -+** by which the JsonNode counter should increment in order to go to the -+** next peer value. -+*/ -+static u32 jsonNodeSize(JsonNode *pNode){ -+ return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1; -+} -+ -+/* -+** Reclaim all memory allocated by a JsonParse object. But do not -+** delete the JsonParse object itself. -+*/ -+static void jsonParseReset(JsonParse *pParse){ -+ sqlite3_free(pParse->aNode); -+ pParse->aNode = 0; -+ pParse->nNode = 0; -+ pParse->nAlloc = 0; -+ sqlite3_free(pParse->aUp); -+ pParse->aUp = 0; -+} -+ -+/* -+** Free a JsonParse object that was obtained from sqlite3_malloc(). -+*/ -+static void jsonParseFree(JsonParse *pParse){ -+ jsonParseReset(pParse); -+ sqlite3_free(pParse); -+} -+ -+/* -+** Convert the JsonNode pNode into a pure JSON string and -+** append to pOut. Subsubstructure is also included. Return -+** the number of JsonNode objects that are encoded. -+*/ -+static void jsonRenderNode( -+ JsonNode *pNode, /* The node to render */ -+ JsonString *pOut, /* Write JSON here */ -+ sqlite3_value **aReplace /* Replacement values */ -+){ -+ if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){ -+ if( pNode->jnFlags & JNODE_REPLACE ){ -+ jsonAppendValue(pOut, aReplace[pNode->u.iReplace]); -+ return; -+ } -+ pNode = pNode->u.pPatch; -+ } -+ switch( pNode->eType ){ -+ default: { -+ assert( pNode->eType==JSON_NULL ); -+ jsonAppendRaw(pOut, "null", 4); -+ break; -+ } -+ case JSON_TRUE: { -+ jsonAppendRaw(pOut, "true", 4); -+ break; -+ } -+ case JSON_FALSE: { -+ jsonAppendRaw(pOut, "false", 5); -+ break; -+ } -+ case JSON_STRING: { -+ if( pNode->jnFlags & JNODE_RAW ){ -+ jsonAppendString(pOut, pNode->u.zJContent, pNode->n); -+ break; -+ } -+ /* Fall through into the next case */ -+ } -+ case JSON_REAL: -+ case JSON_INT: { -+ jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); -+ break; -+ } -+ case JSON_ARRAY: { -+ u32 j = 1; -+ jsonAppendChar(pOut, '['); -+ for(;;){ -+ while( j<=pNode->n ){ -+ if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){ -+ jsonAppendSeparator(pOut); -+ jsonRenderNode(&pNode[j], pOut, aReplace); -+ } -+ j += jsonNodeSize(&pNode[j]); -+ } -+ if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; -+ pNode = &pNode[pNode->u.iAppend]; -+ j = 1; -+ } -+ jsonAppendChar(pOut, ']'); -+ break; -+ } -+ case JSON_OBJECT: { -+ u32 j = 1; -+ jsonAppendChar(pOut, '{'); -+ for(;;){ -+ while( j<=pNode->n ){ -+ if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){ -+ jsonAppendSeparator(pOut); -+ jsonRenderNode(&pNode[j], pOut, aReplace); -+ jsonAppendChar(pOut, ':'); -+ jsonRenderNode(&pNode[j+1], pOut, aReplace); -+ } -+ j += 1 + jsonNodeSize(&pNode[j+1]); -+ } -+ if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; -+ pNode = &pNode[pNode->u.iAppend]; -+ j = 1; -+ } -+ jsonAppendChar(pOut, '}'); -+ break; -+ } -+ } -+} -+ -+/* -+** Return a JsonNode and all its descendents as a JSON string. -+*/ -+static void jsonReturnJson( -+ JsonNode *pNode, /* Node to return */ -+ sqlite3_context *pCtx, /* Return value for this function */ -+ sqlite3_value **aReplace /* Array of replacement values */ -+){ -+ JsonString s; -+ jsonInit(&s, pCtx); -+ jsonRenderNode(pNode, &s, aReplace); -+ jsonResult(&s); -+ sqlite3_result_subtype(pCtx, JSON_SUBTYPE); -+} -+ -+/* -+** Make the JsonNode the return value of the function. -+*/ -+static void jsonReturn( -+ JsonNode *pNode, /* Node to return */ -+ sqlite3_context *pCtx, /* Return value for this function */ -+ sqlite3_value **aReplace /* Array of replacement values */ -+){ -+ switch( pNode->eType ){ -+ default: { -+ assert( pNode->eType==JSON_NULL ); -+ sqlite3_result_null(pCtx); -+ break; -+ } -+ case JSON_TRUE: { -+ sqlite3_result_int(pCtx, 1); -+ break; -+ } -+ case JSON_FALSE: { -+ sqlite3_result_int(pCtx, 0); -+ break; -+ } -+ case JSON_INT: { -+ sqlite3_int64 i = 0; -+ const char *z = pNode->u.zJContent; -+ if( z[0]=='-' ){ z++; } -+ while( z[0]>='0' && z[0]<='9' ){ -+ unsigned v = *(z++) - '0'; -+ if( i>=LARGEST_INT64/10 ){ -+ if( i>LARGEST_INT64/10 ) goto int_as_real; -+ if( z[0]>='0' && z[0]<='9' ) goto int_as_real; -+ if( v==9 ) goto int_as_real; -+ if( v==8 ){ -+ if( pNode->u.zJContent[0]=='-' ){ -+ sqlite3_result_int64(pCtx, SMALLEST_INT64); -+ goto int_done; -+ }else{ -+ goto int_as_real; -+ } -+ } -+ } -+ i = i*10 + v; -+ } -+ if( pNode->u.zJContent[0]=='-' ){ i = -i; } -+ sqlite3_result_int64(pCtx, i); -+ int_done: -+ break; -+ int_as_real: /* fall through to real */; -+ } -+ case JSON_REAL: { -+ double r; -+#ifdef SQLITE_AMALGAMATION -+ const char *z = pNode->u.zJContent; -+ sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); -+#else -+ r = strtod(pNode->u.zJContent, 0); -+#endif -+ sqlite3_result_double(pCtx, r); -+ break; -+ } -+ case JSON_STRING: { -+#if 0 /* Never happens because JNODE_RAW is only set by json_set(), -+ ** json_insert() and json_replace() and those routines do not -+ ** call jsonReturn() */ -+ if( pNode->jnFlags & JNODE_RAW ){ -+ sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, -+ SQLITE_TRANSIENT); -+ }else -+#endif -+ assert( (pNode->jnFlags & JNODE_RAW)==0 ); -+ if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){ -+ /* JSON formatted without any backslash-escapes */ -+ sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, -+ SQLITE_TRANSIENT); -+ }else{ -+ /* Translate JSON formatted string into raw text */ -+ u32 i; -+ u32 n = pNode->n; -+ const char *z = pNode->u.zJContent; -+ char *zOut; -+ u32 j; -+ zOut = sqlite3_malloc( n+1 ); -+ if( zOut==0 ){ -+ sqlite3_result_error_nomem(pCtx); -+ break; -+ } -+ for(i=1, j=0; i<n-1; i++){ -+ char c = z[i]; -+ if( c!='\\' ){ -+ zOut[j++] = c; -+ }else{ -+ c = z[++i]; -+ if( c=='u' ){ -+ u32 v = 0, k; -+ for(k=0; k<4; i++, k++){ -+ assert( i<n-2 ); -+ c = z[i+1]; -+ assert( safe_isxdigit(c) ); -+ if( c<='9' ) v = v*16 + c - '0'; -+ else if( c<='F' ) v = v*16 + c - 'A' + 10; -+ else v = v*16 + c - 'a' + 10; -+ } -+ if( v==0 ) break; -+ if( v<=0x7f ){ -+ zOut[j++] = (char)v; -+ }else if( v<=0x7ff ){ -+ zOut[j++] = (char)(0xc0 | (v>>6)); -+ zOut[j++] = 0x80 | (v&0x3f); -+ }else{ -+ zOut[j++] = (char)(0xe0 | (v>>12)); -+ zOut[j++] = 0x80 | ((v>>6)&0x3f); -+ zOut[j++] = 0x80 | (v&0x3f); -+ } -+ }else{ -+ if( c=='b' ){ -+ c = '\b'; -+ }else if( c=='f' ){ -+ c = '\f'; -+ }else if( c=='n' ){ -+ c = '\n'; -+ }else if( c=='r' ){ -+ c = '\r'; -+ }else if( c=='t' ){ -+ c = '\t'; -+ } -+ zOut[j++] = c; -+ } -+ } -+ } -+ zOut[j] = 0; -+ sqlite3_result_text(pCtx, zOut, j, sqlite3_free); -+ } -+ break; -+ } -+ case JSON_ARRAY: -+ case JSON_OBJECT: { -+ jsonReturnJson(pNode, pCtx, aReplace); -+ break; -+ } -+ } -+} -+ -+/* Forward reference */ -+static int jsonParseAddNode(JsonParse*,u32,u32,const char*); -+ -+/* -+** A macro to hint to the compiler that a function should not be -+** inlined. -+*/ -+#if defined(__GNUC__) -+# define JSON_NOINLINE __attribute__((noinline)) -+#elif defined(_MSC_VER) && _MSC_VER>=1310 -+# define JSON_NOINLINE __declspec(noinline) -+#else -+# define JSON_NOINLINE -+#endif -+ -+ -+static JSON_NOINLINE int jsonParseAddNodeExpand( -+ JsonParse *pParse, /* Append the node to this object */ -+ u32 eType, /* Node type */ -+ u32 n, /* Content size or sub-node count */ -+ const char *zContent /* Content */ -+){ -+ u32 nNew; -+ JsonNode *pNew; -+ assert( pParse->nNode>=pParse->nAlloc ); -+ if( pParse->oom ) return -1; -+ nNew = pParse->nAlloc*2 + 10; -+ pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew); -+ if( pNew==0 ){ -+ pParse->oom = 1; -+ return -1; -+ } -+ pParse->nAlloc = nNew; -+ pParse->aNode = pNew; -+ assert( pParse->nNode<pParse->nAlloc ); -+ return jsonParseAddNode(pParse, eType, n, zContent); -+} -+ -+/* -+** Create a new JsonNode instance based on the arguments and append that -+** instance to the JsonParse. Return the index in pParse->aNode[] of the -+** new node, or -1 if a memory allocation fails. -+*/ -+static int jsonParseAddNode( -+ JsonParse *pParse, /* Append the node to this object */ -+ u32 eType, /* Node type */ -+ u32 n, /* Content size or sub-node count */ -+ const char *zContent /* Content */ -+){ -+ JsonNode *p; -+ if( pParse->nNode>=pParse->nAlloc ){ -+ return jsonParseAddNodeExpand(pParse, eType, n, zContent); -+ } -+ p = &pParse->aNode[pParse->nNode]; -+ p->eType = (u8)eType; -+ p->jnFlags = 0; -+ p->n = n; -+ p->u.zJContent = zContent; -+ return pParse->nNode++; -+} -+ -+/* -+** Return true if z[] begins with 4 (or more) hexadecimal digits -+*/ -+static int jsonIs4Hex(const char *z){ -+ int i; -+ for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0; -+ return 1; -+} -+ -+/* -+** Parse a single JSON value which begins at pParse->zJson[i]. Return the -+** index of the first character past the end of the value parsed. -+** -+** Return negative for a syntax error. Special cases: return -2 if the -+** first non-whitespace character is '}' and return -3 if the first -+** non-whitespace character is ']'. -+*/ -+static int jsonParseValue(JsonParse *pParse, u32 i){ -+ char c; -+ u32 j; -+ int iThis; -+ int x; -+ JsonNode *pNode; -+ const char *z = pParse->zJson; -+ while( safe_isspace(z[i]) ){ i++; } -+ if( (c = z[i])=='{' ){ -+ /* Parse object */ -+ iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); -+ if( iThis<0 ) return -1; -+ for(j=i+1;;j++){ -+ while( safe_isspace(z[j]) ){ j++; } -+ if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; -+ x = jsonParseValue(pParse, j); -+ if( x<0 ){ -+ pParse->iDepth--; -+ if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1; -+ return -1; -+ } -+ if( pParse->oom ) return -1; -+ pNode = &pParse->aNode[pParse->nNode-1]; -+ if( pNode->eType!=JSON_STRING ) return -1; -+ pNode->jnFlags |= JNODE_LABEL; -+ j = x; -+ while( safe_isspace(z[j]) ){ j++; } -+ if( z[j]!=':' ) return -1; -+ j++; -+ x = jsonParseValue(pParse, j); -+ pParse->iDepth--; -+ if( x<0 ) return -1; -+ j = x; -+ while( safe_isspace(z[j]) ){ j++; } -+ c = z[j]; -+ if( c==',' ) continue; -+ if( c!='}' ) return -1; -+ break; -+ } -+ pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; -+ return j+1; -+ }else if( c=='[' ){ -+ /* Parse array */ -+ iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); -+ if( iThis<0 ) return -1; -+ for(j=i+1;;j++){ -+ while( safe_isspace(z[j]) ){ j++; } -+ if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; -+ x = jsonParseValue(pParse, j); -+ pParse->iDepth--; -+ if( x<0 ){ -+ if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1; -+ return -1; -+ } -+ j = x; -+ while( safe_isspace(z[j]) ){ j++; } -+ c = z[j]; -+ if( c==',' ) continue; -+ if( c!=']' ) return -1; -+ break; -+ } -+ pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; -+ return j+1; -+ }else if( c=='"' ){ -+ /* Parse string */ -+ u8 jnFlags = 0; -+ j = i+1; -+ for(;;){ -+ c = z[j]; -+ if( (c & ~0x1f)==0 ){ -+ /* Control characters are not allowed in strings */ -+ return -1; -+ } -+ if( c=='\\' ){ -+ c = z[++j]; -+ if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' -+ || c=='n' || c=='r' || c=='t' -+ || (c=='u' && jsonIs4Hex(z+j+1)) ){ -+ jnFlags = JNODE_ESCAPE; -+ }else{ -+ return -1; -+ } -+ }else if( c=='"' ){ -+ break; -+ } -+ j++; -+ } -+ jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]); -+ if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags; -+ return j+1; -+ }else if( c=='n' -+ && strncmp(z+i,"null",4)==0 -+ && !safe_isalnum(z[i+4]) ){ -+ jsonParseAddNode(pParse, JSON_NULL, 0, 0); -+ return i+4; -+ }else if( c=='t' -+ && strncmp(z+i,"true",4)==0 -+ && !safe_isalnum(z[i+4]) ){ -+ jsonParseAddNode(pParse, JSON_TRUE, 0, 0); -+ return i+4; -+ }else if( c=='f' -+ && strncmp(z+i,"false",5)==0 -+ && !safe_isalnum(z[i+5]) ){ -+ jsonParseAddNode(pParse, JSON_FALSE, 0, 0); -+ return i+5; -+ }else if( c=='-' || (c>='0' && c<='9') ){ -+ /* Parse number */ -+ u8 seenDP = 0; -+ u8 seenE = 0; -+ assert( '-' < '0' ); -+ if( c<='0' ){ -+ j = c=='-' ? i+1 : i; -+ if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1; -+ } -+ j = i+1; -+ for(;; j++){ -+ c = z[j]; -+ if( c>='0' && c<='9' ) continue; -+ if( c=='.' ){ -+ if( z[j-1]=='-' ) return -1; -+ if( seenDP ) return -1; -+ seenDP = 1; -+ continue; -+ } -+ if( c=='e' || c=='E' ){ -+ if( z[j-1]<'0' ) return -1; -+ if( seenE ) return -1; -+ seenDP = seenE = 1; -+ c = z[j+1]; -+ if( c=='+' || c=='-' ){ -+ j++; -+ c = z[j+1]; -+ } -+ if( c<'0' || c>'9' ) return -1; -+ continue; -+ } -+ break; -+ } -+ if( z[j-1]<'0' ) return -1; -+ jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT, -+ j - i, &z[i]); -+ return j; -+ }else if( c=='}' ){ -+ return -2; /* End of {...} */ -+ }else if( c==']' ){ -+ return -3; /* End of [...] */ -+ }else if( c==0 ){ -+ return 0; /* End of file */ -+ }else{ -+ return -1; /* Syntax error */ -+ } -+} -+ -+/* -+** Parse a complete JSON string. Return 0 on success or non-zero if there -+** are any errors. If an error occurs, free all memory associated with -+** pParse. -+** -+** pParse is uninitialized when this routine is called. -+*/ -+static int jsonParse( -+ JsonParse *pParse, /* Initialize and fill this JsonParse object */ -+ sqlite3_context *pCtx, /* Report errors here */ -+ const char *zJson /* Input JSON text to be parsed */ -+){ -+ int i; -+ memset(pParse, 0, sizeof(*pParse)); -+ if( zJson==0 ) return 1; -+ pParse->zJson = zJson; -+ i = jsonParseValue(pParse, 0); -+ if( pParse->oom ) i = -1; -+ if( i>0 ){ -+ assert( pParse->iDepth==0 ); -+ while( safe_isspace(zJson[i]) ) i++; -+ if( zJson[i] ) i = -1; -+ } -+ if( i<=0 ){ -+ if( pCtx!=0 ){ -+ if( pParse->oom ){ -+ sqlite3_result_error_nomem(pCtx); -+ }else{ -+ sqlite3_result_error(pCtx, "malformed JSON", -1); -+ } -+ } -+ jsonParseReset(pParse); -+ return 1; -+ } -+ return 0; -+} -+ -+/* Mark node i of pParse as being a child of iParent. Call recursively -+** to fill in all the descendants of node i. -+*/ -+static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){ -+ JsonNode *pNode = &pParse->aNode[i]; -+ u32 j; -+ pParse->aUp[i] = iParent; -+ switch( pNode->eType ){ -+ case JSON_ARRAY: { -+ for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){ -+ jsonParseFillInParentage(pParse, i+j, i); -+ } -+ break; -+ } -+ case JSON_OBJECT: { -+ for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){ -+ pParse->aUp[i+j] = i; -+ jsonParseFillInParentage(pParse, i+j+1, i); -+ } -+ break; -+ } -+ default: { -+ break; -+ } -+ } -+} -+ -+/* -+** Compute the parentage of all nodes in a completed parse. -+*/ -+static int jsonParseFindParents(JsonParse *pParse){ -+ u32 *aUp; -+ assert( pParse->aUp==0 ); -+ aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode ); -+ if( aUp==0 ){ -+ pParse->oom = 1; -+ return SQLITE_NOMEM; -+ } -+ jsonParseFillInParentage(pParse, 0, 0); -+ return SQLITE_OK; -+} -+ -+/* -+** Magic number used for the JSON parse cache in sqlite3_get_auxdata() -+*/ -+#define JSON_CACHE_ID (-429938) /* First cache entry */ -+#define JSON_CACHE_SZ 4 /* Max number of cache entries */ -+ -+/* -+** Obtain a complete parse of the JSON found in the first argument -+** of the argv array. Use the sqlite3_get_auxdata() cache for this -+** parse if it is available. If the cache is not available or if it -+** is no longer valid, parse the JSON again and return the new parse, -+** and also register the new parse so that it will be available for -+** future sqlite3_get_auxdata() calls. -+*/ -+static JsonParse *jsonParseCached( -+ sqlite3_context *pCtx, -+ sqlite3_value **argv, -+ sqlite3_context *pErrCtx -+){ -+ const char *zJson = (const char*)sqlite3_value_text(argv[0]); -+ int nJson = sqlite3_value_bytes(argv[0]); -+ JsonParse *p; -+ JsonParse *pMatch = 0; -+ int iKey; -+ int iMinKey = 0; -+ u32 iMinHold = 0xffffffff; -+ u32 iMaxHold = 0; -+ if( zJson==0 ) return 0; -+ for(iKey=0; iKey<JSON_CACHE_SZ; iKey++){ -+ p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iKey); -+ if( p==0 ){ -+ iMinKey = iKey; -+ break; -+ } -+ if( pMatch==0 -+ && p->nJson==nJson -+ && memcmp(p->zJson,zJson,nJson)==0 -+ ){ -+ p->nErr = 0; -+ pMatch = p; -+ }else if( p->iHold<iMinHold ){ -+ iMinHold = p->iHold; -+ iMinKey = iKey; -+ } -+ if( p->iHold>iMaxHold ){ -+ iMaxHold = p->iHold; -+ } -+ } -+ if( pMatch ){ -+ pMatch->nErr = 0; -+ pMatch->iHold = iMaxHold+1; -+ return pMatch; -+ } -+ p = sqlite3_malloc( sizeof(*p) + nJson + 1 ); -+ if( p==0 ){ -+ sqlite3_result_error_nomem(pCtx); -+ return 0; -+ } -+ memset(p, 0, sizeof(*p)); -+ p->zJson = (char*)&p[1]; -+ memcpy((char*)p->zJson, zJson, nJson+1); -+ if( jsonParse(p, pErrCtx, p->zJson) ){ -+ sqlite3_free(p); -+ return 0; -+ } -+ p->nJson = nJson; -+ p->iHold = iMaxHold+1; -+ sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p, -+ (void(*)(void*))jsonParseFree); -+ return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey); -+} -+ -+/* -+** Compare the OBJECT label at pNode against zKey,nKey. Return true on -+** a match. -+*/ -+static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){ -+ if( pNode->jnFlags & JNODE_RAW ){ -+ if( pNode->n!=nKey ) return 0; -+ return strncmp(pNode->u.zJContent, zKey, nKey)==0; -+ }else{ -+ if( pNode->n!=nKey+2 ) return 0; -+ return strncmp(pNode->u.zJContent+1, zKey, nKey)==0; -+ } -+} -+ -+/* forward declaration */ -+static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**); -+ -+/* -+** Search along zPath to find the node specified. Return a pointer -+** to that node, or NULL if zPath is malformed or if there is no such -+** node. -+** -+** If pApnd!=0, then try to append new nodes to complete zPath if it is -+** possible to do so and if no existing node corresponds to zPath. If -+** new nodes are appended *pApnd is set to 1. -+*/ -+static JsonNode *jsonLookupStep( -+ JsonParse *pParse, /* The JSON to search */ -+ u32 iRoot, /* Begin the search at this node */ -+ const char *zPath, /* The path to search */ -+ int *pApnd, /* Append nodes to complete path if not NULL */ -+ const char **pzErr /* Make *pzErr point to any syntax error in zPath */ -+){ -+ u32 i, j, nKey; -+ const char *zKey; -+ JsonNode *pRoot = &pParse->aNode[iRoot]; -+ if( zPath[0]==0 ) return pRoot; -+ if( zPath[0]=='.' ){ -+ if( pRoot->eType!=JSON_OBJECT ) return 0; -+ zPath++; -+ if( zPath[0]=='"' ){ -+ zKey = zPath + 1; -+ for(i=1; zPath[i] && zPath[i]!='"'; i++){} -+ nKey = i-1; -+ if( zPath[i] ){ -+ i++; -+ }else{ -+ *pzErr = zPath; -+ return 0; -+ } -+ }else{ -+ zKey = zPath; -+ for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} -+ nKey = i; -+ } -+ if( nKey==0 ){ -+ *pzErr = zPath; -+ return 0; -+ } -+ j = 1; -+ for(;;){ -+ while( j<=pRoot->n ){ -+ if( jsonLabelCompare(pRoot+j, zKey, nKey) ){ -+ return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr); -+ } -+ j++; -+ j += jsonNodeSize(&pRoot[j]); -+ } -+ if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; -+ iRoot += pRoot->u.iAppend; -+ pRoot = &pParse->aNode[iRoot]; -+ j = 1; -+ } -+ if( pApnd ){ -+ u32 iStart, iLabel; -+ JsonNode *pNode; -+ iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); -+ iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath); -+ zPath += i; -+ pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); -+ if( pParse->oom ) return 0; -+ if( pNode ){ -+ pRoot = &pParse->aNode[iRoot]; -+ pRoot->u.iAppend = iStart - iRoot; -+ pRoot->jnFlags |= JNODE_APPEND; -+ pParse->aNode[iLabel].jnFlags |= JNODE_RAW; -+ } -+ return pNode; -+ } -+ }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){ -+ if( pRoot->eType!=JSON_ARRAY ) return 0; -+ i = 0; -+ j = 1; -+ while( safe_isdigit(zPath[j]) ){ -+ i = i*10 + zPath[j] - '0'; -+ j++; -+ } -+ if( zPath[j]!=']' ){ -+ *pzErr = zPath; -+ return 0; -+ } -+ zPath += j + 1; -+ j = 1; -+ for(;;){ -+ while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){ -+ if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--; -+ j += jsonNodeSize(&pRoot[j]); -+ } -+ if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; -+ iRoot += pRoot->u.iAppend; -+ pRoot = &pParse->aNode[iRoot]; -+ j = 1; -+ } -+ if( j<=pRoot->n ){ -+ return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr); -+ } -+ if( i==0 && pApnd ){ -+ u32 iStart; -+ JsonNode *pNode; -+ iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0); -+ pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); -+ if( pParse->oom ) return 0; -+ if( pNode ){ -+ pRoot = &pParse->aNode[iRoot]; -+ pRoot->u.iAppend = iStart - iRoot; -+ pRoot->jnFlags |= JNODE_APPEND; -+ } -+ return pNode; -+ } -+ }else{ -+ *pzErr = zPath; -+ } -+ return 0; -+} -+ -+/* -+** Append content to pParse that will complete zPath. Return a pointer -+** to the inserted node, or return NULL if the append fails. -+*/ -+static JsonNode *jsonLookupAppend( -+ JsonParse *pParse, /* Append content to the JSON parse */ -+ const char *zPath, /* Description of content to append */ -+ int *pApnd, /* Set this flag to 1 */ -+ const char **pzErr /* Make this point to any syntax error */ -+){ -+ *pApnd = 1; -+ if( zPath[0]==0 ){ -+ jsonParseAddNode(pParse, JSON_NULL, 0, 0); -+ return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1]; -+ } -+ if( zPath[0]=='.' ){ -+ jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); -+ }else if( strncmp(zPath,"[0]",3)==0 ){ -+ jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); -+ }else{ -+ return 0; -+ } -+ if( pParse->oom ) return 0; -+ return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr); -+} -+ -+/* -+** Return the text of a syntax error message on a JSON path. Space is -+** obtained from sqlite3_malloc(). -+*/ -+static char *jsonPathSyntaxError(const char *zErr){ -+ return sqlite3_mprintf("JSON path error near '%q'", zErr); -+} -+ -+/* -+** Do a node lookup using zPath. Return a pointer to the node on success. -+** Return NULL if not found or if there is an error. -+** -+** On an error, write an error message into pCtx and increment the -+** pParse->nErr counter. -+** -+** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if -+** nodes are appended. -+*/ -+static JsonNode *jsonLookup( -+ JsonParse *pParse, /* The JSON to search */ -+ const char *zPath, /* The path to search */ -+ int *pApnd, /* Append nodes to complete path if not NULL */ -+ sqlite3_context *pCtx /* Report errors here, if not NULL */ -+){ -+ const char *zErr = 0; -+ JsonNode *pNode = 0; -+ char *zMsg; -+ -+ if( zPath==0 ) return 0; -+ if( zPath[0]!='$' ){ -+ zErr = zPath; -+ goto lookup_err; -+ } -+ zPath++; -+ pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr); -+ if( zErr==0 ) return pNode; -+ -+lookup_err: -+ pParse->nErr++; -+ assert( zErr!=0 && pCtx!=0 ); -+ zMsg = jsonPathSyntaxError(zErr); -+ if( zMsg ){ -+ sqlite3_result_error(pCtx, zMsg, -1); -+ sqlite3_free(zMsg); -+ }else{ -+ sqlite3_result_error_nomem(pCtx); -+ } -+ return 0; -+} -+ -+ -+/* -+** Report the wrong number of arguments for json_insert(), json_replace() -+** or json_set(). -+*/ -+static void jsonWrongNumArgs( -+ sqlite3_context *pCtx, -+ const char *zFuncName -+){ -+ char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", -+ zFuncName); -+ sqlite3_result_error(pCtx, zMsg, -1); -+ sqlite3_free(zMsg); -+} -+ -+/* -+** Mark all NULL entries in the Object passed in as JNODE_REMOVE. -+*/ -+static void jsonRemoveAllNulls(JsonNode *pNode){ -+ int i, n; -+ assert( pNode->eType==JSON_OBJECT ); -+ n = pNode->n; -+ for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){ -+ switch( pNode[i].eType ){ -+ case JSON_NULL: -+ pNode[i].jnFlags |= JNODE_REMOVE; -+ break; -+ case JSON_OBJECT: -+ jsonRemoveAllNulls(&pNode[i]); -+ break; -+ } -+ } -+} -+ -+ -+/**************************************************************************** -+** SQL functions used for testing and debugging -+****************************************************************************/ -+ -+#ifdef SQLITE_DEBUG -+/* -+** The json_parse(JSON) function returns a string which describes -+** a parse of the JSON provided. Or it returns NULL if JSON is not -+** well-formed. -+*/ -+static void jsonParseFunc( -+ sqlite3_context *ctx, -+ int argc, -+ sqlite3_value **argv -+){ -+ JsonString s; /* Output string - not real JSON */ -+ JsonParse x; /* The parse */ -+ u32 i; -+ -+ assert( argc==1 ); -+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; -+ jsonParseFindParents(&x); -+ jsonInit(&s, ctx); -+ for(i=0; i<x.nNode; i++){ -+ const char *zType; -+ if( x.aNode[i].jnFlags & JNODE_LABEL ){ -+ assert( x.aNode[i].eType==JSON_STRING ); -+ zType = "label"; -+ }else{ -+ zType = jsonType[x.aNode[i].eType]; -+ } -+ jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d", -+ i, zType, x.aNode[i].n, x.aUp[i]); -+ if( x.aNode[i].u.zJContent!=0 ){ -+ jsonAppendRaw(&s, " ", 1); -+ jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n); -+ } -+ jsonAppendRaw(&s, "\n", 1); -+ } -+ jsonParseReset(&x); -+ jsonResult(&s); -+} -+ -+/* -+** The json_test1(JSON) function return true (1) if the input is JSON -+** text generated by another json function. It returns (0) if the input -+** is not known to be JSON. -+*/ -+static void jsonTest1Func( -+ sqlite3_context *ctx, -+ int argc, -+ sqlite3_value **argv -+){ -+ UNUSED_PARAM(argc); -+ sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE); -+} -+#endif /* SQLITE_DEBUG */ -+ -+/**************************************************************************** -+** Scalar SQL function implementations -+****************************************************************************/ -+ -+/* -+** Implementation of the json_QUOTE(VALUE) function. Return a JSON value -+** corresponding to the SQL value input. Mostly this means putting -+** double-quotes around strings and returning the unquoted string "null" -+** when given a NULL input. -+*/ -+static void jsonQuoteFunc( -+ sqlite3_context *ctx, -+ int argc, -+ sqlite3_value **argv -+){ -+ JsonString jx; -+ UNUSED_PARAM(argc); -+ -+ jsonInit(&jx, ctx); -+ jsonAppendValue(&jx, argv[0]); -+ jsonResult(&jx); -+ sqlite3_result_subtype(ctx, JSON_SUBTYPE); -+} -+ -+/* -+** Implementation of the json_array(VALUE,...) function. Return a JSON -+** array that contains all values given in arguments. Or if any argument -+** is a BLOB, throw an error. -+*/ -+static void jsonArrayFunc( -+ sqlite3_context *ctx, -+ int argc, -+ sqlite3_value **argv -+){ -+ int i; -+ JsonString jx; -+ -+ jsonInit(&jx, ctx); -+ jsonAppendChar(&jx, '['); -+ for(i=0; i<argc; i++){ -+ jsonAppendSeparator(&jx); -+ jsonAppendValue(&jx, argv[i]); -+ } -+ jsonAppendChar(&jx, ']'); -+ jsonResult(&jx); -+ sqlite3_result_subtype(ctx, JSON_SUBTYPE); -+} -+ -+ -+/* -+** json_array_length(JSON) -+** json_array_length(JSON, PATH) -+** -+** Return the number of elements in the top-level JSON array. -+** Return 0 if the input is not a well-formed JSON array. -+*/ -+static void jsonArrayLengthFunc( -+ sqlite3_context *ctx, -+ int argc, -+ sqlite3_value **argv -+){ -+ JsonParse *p; /* The parse */ -+ sqlite3_int64 n = 0; -+ u32 i; -+ JsonNode *pNode; -+ -+ p = jsonParseCached(ctx, argv, ctx); -+ if( p==0 ) return; -+ assert( p->nNode ); -+ if( argc==2 ){ -+ const char *zPath = (const char*)sqlite3_value_text(argv[1]); -+ pNode = jsonLookup(p, zPath, 0, ctx); -+ }else{ -+ pNode = p->aNode; -+ } -+ if( pNode==0 ){ -+ return; -+ } -+ if( pNode->eType==JSON_ARRAY ){ -+ assert( (pNode->jnFlags & JNODE_APPEND)==0 ); -+ for(i=1; i<=pNode->n; n++){ -+ i += jsonNodeSize(&pNode[i]); -+ } -+ } -+ sqlite3_result_int64(ctx, n); -+} -+ -+/* -+** json_extract(JSON, PATH, ...) -+** -+** Return the element described by PATH. Return NULL if there is no -+** PATH element. If there are multiple PATHs, then return a JSON array -+** with the result from each path. Throw an error if the JSON or any PATH -+** is malformed. -+*/ -+static void jsonExtractFunc( -+ sqlite3_context *ctx, -+ int argc, -+ sqlite3_value **argv -+){ -+ JsonParse *p; /* The parse */ -+ JsonNode *pNode; -+ const char *zPath; -+ JsonString jx; -+ int i; -+ -+ if( argc<2 ) return; -+ p = jsonParseCached(ctx, argv, ctx); -+ if( p==0 ) return; -+ jsonInit(&jx, ctx); -+ jsonAppendChar(&jx, '['); -+ for(i=1; i<argc; i++){ -+ zPath = (const char*)sqlite3_value_text(argv[i]); -+ pNode = jsonLookup(p, zPath, 0, ctx); -+ if( p->nErr ) break; -+ if( argc>2 ){ -+ jsonAppendSeparator(&jx); -+ if( pNode ){ -+ jsonRenderNode(pNode, &jx, 0); -+ }else{ -+ jsonAppendRaw(&jx, "null", 4); -+ } -+ }else if( pNode ){ -+ jsonReturn(pNode, ctx, 0); -+ } -+ } -+ if( argc>2 && i==argc ){ -+ jsonAppendChar(&jx, ']'); -+ jsonResult(&jx); -+ sqlite3_result_subtype(ctx, JSON_SUBTYPE); -+ } -+ jsonReset(&jx); -+} -+ -+/* This is the RFC 7396 MergePatch algorithm. -+*/ -+static JsonNode *jsonMergePatch( -+ JsonParse *pParse, /* The JSON parser that contains the TARGET */ -+ u32 iTarget, /* Node of the TARGET in pParse */ -+ JsonNode *pPatch /* The PATCH */ -+){ -+ u32 i, j; -+ u32 iRoot; -+ JsonNode *pTarget; -+ if( pPatch->eType!=JSON_OBJECT ){ -+ return pPatch; -+ } -+ assert( iTarget>=0 && iTarget<pParse->nNode ); -+ pTarget = &pParse->aNode[iTarget]; -+ assert( (pPatch->jnFlags & JNODE_APPEND)==0 ); -+ if( pTarget->eType!=JSON_OBJECT ){ -+ jsonRemoveAllNulls(pPatch); -+ return pPatch; -+ } -+ iRoot = iTarget; -+ for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){ -+ u32 nKey; -+ const char *zKey; -+ assert( pPatch[i].eType==JSON_STRING ); -+ assert( pPatch[i].jnFlags & JNODE_LABEL ); -+ nKey = pPatch[i].n; -+ zKey = pPatch[i].u.zJContent; -+ assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); -+ for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){ -+ assert( pTarget[j].eType==JSON_STRING ); -+ assert( pTarget[j].jnFlags & JNODE_LABEL ); -+ assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); -+ if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){ -+ if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break; -+ if( pPatch[i+1].eType==JSON_NULL ){ -+ pTarget[j+1].jnFlags |= JNODE_REMOVE; -+ }else{ -+ JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]); -+ if( pNew==0 ) return 0; -+ pTarget = &pParse->aNode[iTarget]; -+ if( pNew!=&pTarget[j+1] ){ -+ pTarget[j+1].u.pPatch = pNew; -+ pTarget[j+1].jnFlags |= JNODE_PATCH; -+ } -+ } -+ break; -+ } -+ } -+ if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){ -+ int iStart, iPatch; -+ iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); -+ jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); -+ iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0); -+ if( pParse->oom ) return 0; -+ jsonRemoveAllNulls(pPatch); -+ pTarget = &pParse->aNode[iTarget]; -+ pParse->aNode[iRoot].jnFlags |= JNODE_APPEND; -+ pParse->aNode[iRoot].u.iAppend = iStart - iRoot; -+ iRoot = iStart; -+ pParse->aNode[iPatch].jnFlags |= JNODE_PATCH; -+ pParse->aNode[iPatch].u.pPatch = &pPatch[i+1]; -+ } -+ } -+ return pTarget; -+} -+ -+/* -+** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON -+** object that is the result of running the RFC 7396 MergePatch() algorithm -+** on the two arguments. -+*/ -+static void jsonPatchFunc( -+ sqlite3_context *ctx, -+ int argc, -+ sqlite3_value **argv -+){ -+ JsonParse x; /* The JSON that is being patched */ -+ JsonParse y; /* The patch */ -+ JsonNode *pResult; /* The result of the merge */ -+ -+ UNUSED_PARAM(argc); -+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; -+ if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){ -+ jsonParseReset(&x); -+ return; -+ } -+ pResult = jsonMergePatch(&x, 0, y.aNode); -+ assert( pResult!=0 || x.oom ); -+ if( pResult ){ -+ jsonReturnJson(pResult, ctx, 0); -+ }else{ -+ sqlite3_result_error_nomem(ctx); -+ } -+ jsonParseReset(&x); -+ jsonParseReset(&y); -+} -+ -+ -+/* -+** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON -+** object that contains all name/value given in arguments. Or if any name -+** is not a string or if any value is a BLOB, throw an error. -+*/ -+static void jsonObjectFunc( -+ sqlite3_context *ctx, -+ int argc, -+ sqlite3_value **argv -+){ -+ int i; -+ JsonString jx; -+ const char *z; -+ u32 n; -+ -+ if( argc&1 ){ -+ sqlite3_result_error(ctx, "json_object() requires an even number " -+ "of arguments", -1); -+ return; -+ } -+ jsonInit(&jx, ctx); -+ jsonAppendChar(&jx, '{'); -+ for(i=0; i<argc; i+=2){ -+ if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){ -+ sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1); -+ jsonReset(&jx); -+ return; -+ } -+ jsonAppendSeparator(&jx); -+ z = (const char*)sqlite3_value_text(argv[i]); -+ n = (u32)sqlite3_value_bytes(argv[i]); -+ jsonAppendString(&jx, z, n); -+ jsonAppendChar(&jx, ':'); -+ jsonAppendValue(&jx, argv[i+1]); -+ } -+ jsonAppendChar(&jx, '}'); -+ jsonResult(&jx); -+ sqlite3_result_subtype(ctx, JSON_SUBTYPE); -+} -+ -+ -+/* -+** json_remove(JSON, PATH, ...) -+** -+** Remove the named elements from JSON and return the result. malformed -+** JSON or PATH arguments result in an error. -+*/ -+static void jsonRemoveFunc( -+ sqlite3_context *ctx, -+ int argc, -+ sqlite3_value **argv -+){ -+ JsonParse x; /* The parse */ -+ JsonNode *pNode; -+ const char *zPath; -+ u32 i; -+ -+ if( argc<1 ) return; -+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; -+ assert( x.nNode ); -+ for(i=1; i<(u32)argc; i++){ -+ zPath = (const char*)sqlite3_value_text(argv[i]); -+ if( zPath==0 ) goto remove_done; -+ pNode = jsonLookup(&x, zPath, 0, ctx); -+ if( x.nErr ) goto remove_done; -+ if( pNode ) pNode->jnFlags |= JNODE_REMOVE; -+ } -+ if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){ -+ jsonReturnJson(x.aNode, ctx, 0); -+ } -+remove_done: -+ jsonParseReset(&x); -+} -+ -+/* -+** json_replace(JSON, PATH, VALUE, ...) -+** -+** Replace the value at PATH with VALUE. If PATH does not already exist, -+** this routine is a no-op. If JSON or PATH is malformed, throw an error. -+*/ -+static void jsonReplaceFunc( -+ sqlite3_context *ctx, -+ int argc, -+ sqlite3_value **argv -+){ -+ JsonParse x; /* The parse */ -+ JsonNode *pNode; -+ const char *zPath; -+ u32 i; -+ -+ if( argc<1 ) return; -+ if( (argc&1)==0 ) { -+ jsonWrongNumArgs(ctx, "replace"); -+ return; -+ } -+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; -+ assert( x.nNode ); -+ for(i=1; i<(u32)argc; i+=2){ -+ zPath = (const char*)sqlite3_value_text(argv[i]); -+ pNode = jsonLookup(&x, zPath, 0, ctx); -+ if( x.nErr ) goto replace_err; -+ if( pNode ){ -+ pNode->jnFlags |= (u8)JNODE_REPLACE; -+ pNode->u.iReplace = i + 1; -+ } -+ } -+ if( x.aNode[0].jnFlags & JNODE_REPLACE ){ -+ sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); -+ }else{ -+ jsonReturnJson(x.aNode, ctx, argv); -+ } -+replace_err: -+ jsonParseReset(&x); -+} -+ -+/* -+** json_set(JSON, PATH, VALUE, ...) -+** -+** Set the value at PATH to VALUE. Create the PATH if it does not already -+** exist. Overwrite existing values that do exist. -+** If JSON or PATH is malformed, throw an error. -+** -+** json_insert(JSON, PATH, VALUE, ...) -+** -+** Create PATH and initialize it to VALUE. If PATH already exists, this -+** routine is a no-op. If JSON or PATH is malformed, throw an error. -+*/ -+static void jsonSetFunc( -+ sqlite3_context *ctx, -+ int argc, -+ sqlite3_value **argv -+){ -+ JsonParse x; /* The parse */ -+ JsonNode *pNode; -+ const char *zPath; -+ u32 i; -+ int bApnd; -+ int bIsSet = *(int*)sqlite3_user_data(ctx); -+ -+ if( argc<1 ) return; -+ if( (argc&1)==0 ) { -+ jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); -+ return; -+ } -+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; -+ assert( x.nNode ); -+ for(i=1; i<(u32)argc; i+=2){ -+ zPath = (const char*)sqlite3_value_text(argv[i]); -+ bApnd = 0; -+ pNode = jsonLookup(&x, zPath, &bApnd, ctx); -+ if( x.oom ){ -+ sqlite3_result_error_nomem(ctx); -+ goto jsonSetDone; -+ }else if( x.nErr ){ -+ goto jsonSetDone; -+ }else if( pNode && (bApnd || bIsSet) ){ -+ pNode->jnFlags |= (u8)JNODE_REPLACE; -+ pNode->u.iReplace = i + 1; -+ } -+ } -+ if( x.aNode[0].jnFlags & JNODE_REPLACE ){ -+ sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); -+ }else{ -+ jsonReturnJson(x.aNode, ctx, argv); -+ } -+jsonSetDone: -+ jsonParseReset(&x); -+} -+ -+/* -+** json_type(JSON) -+** json_type(JSON, PATH) -+** -+** Return the top-level "type" of a JSON string. Throw an error if -+** either the JSON or PATH inputs are not well-formed. -+*/ -+static void jsonTypeFunc( -+ sqlite3_context *ctx, -+ int argc, -+ sqlite3_value **argv -+){ -+ JsonParse *p; /* The parse */ -+ const char *zPath; -+ JsonNode *pNode; -+ -+ p = jsonParseCached(ctx, argv, ctx); -+ if( p==0 ) return; -+ if( argc==2 ){ -+ zPath = (const char*)sqlite3_value_text(argv[1]); -+ pNode = jsonLookup(p, zPath, 0, ctx); -+ }else{ -+ pNode = p->aNode; -+ } -+ if( pNode ){ -+ sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC); -+ } -+} -+ -+/* -+** json_valid(JSON) -+** -+** Return 1 if JSON is a well-formed JSON string according to RFC-7159. -+** Return 0 otherwise. -+*/ -+static void jsonValidFunc( -+ sqlite3_context *ctx, -+ int argc, -+ sqlite3_value **argv -+){ -+ JsonParse *p; /* The parse */ -+ UNUSED_PARAM(argc); -+ p = jsonParseCached(ctx, argv, 0); -+ sqlite3_result_int(ctx, p!=0); -+} -+ -+ -+/**************************************************************************** -+** Aggregate SQL function implementations -+****************************************************************************/ -+/* -+** json_group_array(VALUE) -+** -+** Return a JSON array composed of all values in the aggregate. -+*/ -+static void jsonArrayStep( -+ sqlite3_context *ctx, -+ int argc, -+ sqlite3_value **argv -+){ -+ JsonString *pStr; -+ UNUSED_PARAM(argc); -+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); -+ if( pStr ){ -+ if( pStr->zBuf==0 ){ -+ jsonInit(pStr, ctx); -+ jsonAppendChar(pStr, '['); -+ }else{ -+ jsonAppendChar(pStr, ','); -+ pStr->pCtx = ctx; -+ } -+ jsonAppendValue(pStr, argv[0]); -+ } -+} -+static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ -+ JsonString *pStr; -+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); -+ if( pStr ){ -+ pStr->pCtx = ctx; -+ jsonAppendChar(pStr, ']'); -+ if( pStr->bErr ){ -+ if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); -+ assert( pStr->bStatic ); -+ }else if( isFinal ){ -+ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, -+ pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); -+ pStr->bStatic = 1; -+ }else{ -+ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); -+ pStr->nUsed--; -+ } -+ }else{ -+ sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); -+ } -+ sqlite3_result_subtype(ctx, JSON_SUBTYPE); -+} -+static void jsonArrayValue(sqlite3_context *ctx){ -+ jsonArrayCompute(ctx, 0); -+} -+static void jsonArrayFinal(sqlite3_context *ctx){ -+ jsonArrayCompute(ctx, 1); -+} -+ -+#ifndef SQLITE_OMIT_WINDOWFUNC -+/* -+** This method works for both json_group_array() and json_group_object(). -+** It works by removing the first element of the group by searching forward -+** to the first comma (",") that is not within a string and deleting all -+** text through that comma. -+*/ -+static void jsonGroupInverse( -+ sqlite3_context *ctx, -+ int argc, -+ sqlite3_value **argv -+){ -+ int i; -+ int inStr = 0; -+ char *z; -+ JsonString *pStr; -+ UNUSED_PARAM(argc); -+ UNUSED_PARAM(argv); -+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); -+#ifdef NEVER -+ /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will -+ ** always have been called to initalize it */ -+ if( NEVER(!pStr) ) return; -+#endif -+ z = pStr->zBuf; -+ for(i=1; z[i]!=',' || inStr; i++){ -+ assert( i<pStr->nUsed ); -+ if( z[i]=='"' ){ -+ inStr = !inStr; -+ }else if( z[i]=='\\' ){ -+ i++; -+ } -+ } -+ pStr->nUsed -= i; -+ memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1); -+} -+#else -+# define jsonGroupInverse 0 -+#endif -+ -+ -+/* -+** json_group_obj(NAME,VALUE) -+** -+** Return a JSON object composed of all names and values in the aggregate. -+*/ -+static void jsonObjectStep( -+ sqlite3_context *ctx, -+ int argc, -+ sqlite3_value **argv -+){ -+ JsonString *pStr; -+ const char *z; -+ u32 n; -+ UNUSED_PARAM(argc); -+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); -+ if( pStr ){ -+ if( pStr->zBuf==0 ){ -+ jsonInit(pStr, ctx); -+ jsonAppendChar(pStr, '{'); -+ }else{ -+ jsonAppendChar(pStr, ','); -+ pStr->pCtx = ctx; -+ } -+ z = (const char*)sqlite3_value_text(argv[0]); -+ n = (u32)sqlite3_value_bytes(argv[0]); -+ jsonAppendString(pStr, z, n); -+ jsonAppendChar(pStr, ':'); -+ jsonAppendValue(pStr, argv[1]); -+ } -+} -+static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ -+ JsonString *pStr; -+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); -+ if( pStr ){ -+ jsonAppendChar(pStr, '}'); -+ if( pStr->bErr ){ -+ if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); -+ assert( pStr->bStatic ); -+ }else if( isFinal ){ -+ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, -+ pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); -+ pStr->bStatic = 1; -+ }else{ -+ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); -+ pStr->nUsed--; -+ } -+ }else{ -+ sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); -+ } -+ sqlite3_result_subtype(ctx, JSON_SUBTYPE); -+} -+static void jsonObjectValue(sqlite3_context *ctx){ -+ jsonObjectCompute(ctx, 0); -+} -+static void jsonObjectFinal(sqlite3_context *ctx){ -+ jsonObjectCompute(ctx, 1); -+} -+ -+ -+ -+#ifndef SQLITE_OMIT_VIRTUALTABLE -+/**************************************************************************** -+** The json_each virtual table -+****************************************************************************/ -+typedef struct JsonEachCursor JsonEachCursor; -+struct JsonEachCursor { -+ sqlite3_vtab_cursor base; /* Base class - must be first */ -+ u32 iRowid; /* The rowid */ -+ u32 iBegin; /* The first node of the scan */ -+ u32 i; /* Index in sParse.aNode[] of current row */ -+ u32 iEnd; /* EOF when i equals or exceeds this value */ -+ u8 eType; /* Type of top-level element */ -+ u8 bRecursive; /* True for json_tree(). False for json_each() */ -+ char *zJson; /* Input JSON */ -+ char *zRoot; /* Path by which to filter zJson */ -+ JsonParse sParse; /* Parse of the input JSON */ -+}; -+ -+/* Constructor for the json_each virtual table */ -+static int jsonEachConnect( -+ sqlite3 *db, -+ void *pAux, -+ int argc, const char *const*argv, -+ sqlite3_vtab **ppVtab, -+ char **pzErr -+){ -+ sqlite3_vtab *pNew; -+ int rc; -+ -+/* Column numbers */ -+#define JEACH_KEY 0 -+#define JEACH_VALUE 1 -+#define JEACH_TYPE 2 -+#define JEACH_ATOM 3 -+#define JEACH_ID 4 -+#define JEACH_PARENT 5 -+#define JEACH_FULLKEY 6 -+#define JEACH_PATH 7 -+/* The xBestIndex method assumes that the JSON and ROOT columns are -+** the last two columns in the table. Should this ever changes, be -+** sure to update the xBestIndex method. */ -+#define JEACH_JSON 8 -+#define JEACH_ROOT 9 -+ -+ UNUSED_PARAM(pzErr); -+ UNUSED_PARAM(argv); -+ UNUSED_PARAM(argc); -+ UNUSED_PARAM(pAux); -+ rc = sqlite3_declare_vtab(db, -+ "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," -+ "json HIDDEN,root HIDDEN)"); -+ if( rc==SQLITE_OK ){ -+ pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); -+ if( pNew==0 ) return SQLITE_NOMEM; -+ memset(pNew, 0, sizeof(*pNew)); -+ } -+ return rc; -+} -+ -+/* destructor for json_each virtual table */ -+static int jsonEachDisconnect(sqlite3_vtab *pVtab){ -+ sqlite3_free(pVtab); -+ return SQLITE_OK; -+} -+ -+/* constructor for a JsonEachCursor object for json_each(). */ -+static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ -+ JsonEachCursor *pCur; -+ -+ UNUSED_PARAM(p); -+ pCur = sqlite3_malloc( sizeof(*pCur) ); -+ if( pCur==0 ) return SQLITE_NOMEM; -+ memset(pCur, 0, sizeof(*pCur)); -+ *ppCursor = &pCur->base; -+ return SQLITE_OK; -+} -+ -+/* constructor for a JsonEachCursor object for json_tree(). */ -+static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ -+ int rc = jsonEachOpenEach(p, ppCursor); -+ if( rc==SQLITE_OK ){ -+ JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor; -+ pCur->bRecursive = 1; -+ } -+ return rc; -+} -+ -+/* Reset a JsonEachCursor back to its original state. Free any memory -+** held. */ -+static void jsonEachCursorReset(JsonEachCursor *p){ -+ sqlite3_free(p->zJson); -+ sqlite3_free(p->zRoot); -+ jsonParseReset(&p->sParse); -+ p->iRowid = 0; -+ p->i = 0; -+ p->iEnd = 0; -+ p->eType = 0; -+ p->zJson = 0; -+ p->zRoot = 0; -+} -+ -+/* Destructor for a jsonEachCursor object */ -+static int jsonEachClose(sqlite3_vtab_cursor *cur){ -+ JsonEachCursor *p = (JsonEachCursor*)cur; -+ jsonEachCursorReset(p); -+ sqlite3_free(cur); -+ return SQLITE_OK; -+} -+ -+/* Return TRUE if the jsonEachCursor object has been advanced off the end -+** of the JSON object */ -+static int jsonEachEof(sqlite3_vtab_cursor *cur){ -+ JsonEachCursor *p = (JsonEachCursor*)cur; -+ return p->i >= p->iEnd; -+} -+ -+/* Advance the cursor to the next element for json_tree() */ -+static int jsonEachNext(sqlite3_vtab_cursor *cur){ -+ JsonEachCursor *p = (JsonEachCursor*)cur; -+ if( p->bRecursive ){ -+ if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++; -+ p->i++; -+ p->iRowid++; -+ if( p->i<p->iEnd ){ -+ u32 iUp = p->sParse.aUp[p->i]; -+ JsonNode *pUp = &p->sParse.aNode[iUp]; -+ p->eType = pUp->eType; -+ if( pUp->eType==JSON_ARRAY ){ -+ if( iUp==p->i-1 ){ -+ pUp->u.iKey = 0; -+ }else{ -+ pUp->u.iKey++; -+ } -+ } -+ } -+ }else{ -+ switch( p->eType ){ -+ case JSON_ARRAY: { -+ p->i += jsonNodeSize(&p->sParse.aNode[p->i]); -+ p->iRowid++; -+ break; -+ } -+ case JSON_OBJECT: { -+ p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]); -+ p->iRowid++; -+ break; -+ } -+ default: { -+ p->i = p->iEnd; -+ break; -+ } -+ } -+ } -+ return SQLITE_OK; -+} -+ -+/* Append the name of the path for element i to pStr -+*/ -+static void jsonEachComputePath( -+ JsonEachCursor *p, /* The cursor */ -+ JsonString *pStr, /* Write the path here */ -+ u32 i /* Path to this element */ -+){ -+ JsonNode *pNode, *pUp; -+ u32 iUp; -+ if( i==0 ){ -+ jsonAppendChar(pStr, '$'); -+ return; -+ } -+ iUp = p->sParse.aUp[i]; -+ jsonEachComputePath(p, pStr, iUp); -+ pNode = &p->sParse.aNode[i]; -+ pUp = &p->sParse.aNode[iUp]; -+ if( pUp->eType==JSON_ARRAY ){ -+ jsonPrintf(30, pStr, "[%d]", pUp->u.iKey); -+ }else{ -+ assert( pUp->eType==JSON_OBJECT ); -+ if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--; -+ assert( pNode->eType==JSON_STRING ); -+ assert( pNode->jnFlags & JNODE_LABEL ); -+ jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1); -+ } -+} -+ -+/* Return the value of a column */ -+static int jsonEachColumn( -+ sqlite3_vtab_cursor *cur, /* The cursor */ -+ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ -+ int i /* Which column to return */ -+){ -+ JsonEachCursor *p = (JsonEachCursor*)cur; -+ JsonNode *pThis = &p->sParse.aNode[p->i]; -+ switch( i ){ -+ case JEACH_KEY: { -+ if( p->i==0 ) break; -+ if( p->eType==JSON_OBJECT ){ -+ jsonReturn(pThis, ctx, 0); -+ }else if( p->eType==JSON_ARRAY ){ -+ u32 iKey; -+ if( p->bRecursive ){ -+ if( p->iRowid==0 ) break; -+ iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey; -+ }else{ -+ iKey = p->iRowid; -+ } -+ sqlite3_result_int64(ctx, (sqlite3_int64)iKey); -+ } -+ break; -+ } -+ case JEACH_VALUE: { -+ if( pThis->jnFlags & JNODE_LABEL ) pThis++; -+ jsonReturn(pThis, ctx, 0); -+ break; -+ } -+ case JEACH_TYPE: { -+ if( pThis->jnFlags & JNODE_LABEL ) pThis++; -+ sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC); -+ break; -+ } -+ case JEACH_ATOM: { -+ if( pThis->jnFlags & JNODE_LABEL ) pThis++; -+ if( pThis->eType>=JSON_ARRAY ) break; -+ jsonReturn(pThis, ctx, 0); -+ break; -+ } -+ case JEACH_ID: { -+ sqlite3_result_int64(ctx, -+ (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0)); -+ break; -+ } -+ case JEACH_PARENT: { -+ if( p->i>p->iBegin && p->bRecursive ){ -+ sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]); -+ } -+ break; -+ } -+ case JEACH_FULLKEY: { -+ JsonString x; -+ jsonInit(&x, ctx); -+ if( p->bRecursive ){ -+ jsonEachComputePath(p, &x, p->i); -+ }else{ -+ if( p->zRoot ){ -+ jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot)); -+ }else{ -+ jsonAppendChar(&x, '$'); -+ } -+ if( p->eType==JSON_ARRAY ){ -+ jsonPrintf(30, &x, "[%d]", p->iRowid); -+ }else if( p->eType==JSON_OBJECT ){ -+ jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1); -+ } -+ } -+ jsonResult(&x); -+ break; -+ } -+ case JEACH_PATH: { -+ if( p->bRecursive ){ -+ JsonString x; -+ jsonInit(&x, ctx); -+ jsonEachComputePath(p, &x, p->sParse.aUp[p->i]); -+ jsonResult(&x); -+ break; -+ } -+ /* For json_each() path and root are the same so fall through -+ ** into the root case */ -+ } -+ default: { -+ const char *zRoot = p->zRoot; -+ if( zRoot==0 ) zRoot = "$"; -+ sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC); -+ break; -+ } -+ case JEACH_JSON: { -+ assert( i==JEACH_JSON ); -+ sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC); -+ break; -+ } -+ } -+ return SQLITE_OK; -+} -+ -+/* Return the current rowid value */ -+static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ -+ JsonEachCursor *p = (JsonEachCursor*)cur; -+ *pRowid = p->iRowid; -+ return SQLITE_OK; -+} -+ -+/* The query strategy is to look for an equality constraint on the json -+** column. Without such a constraint, the table cannot operate. idxNum is -+** 1 if the constraint is found, 3 if the constraint and zRoot are found, -+** and 0 otherwise. -+*/ -+static int jsonEachBestIndex( -+ sqlite3_vtab *tab, -+ sqlite3_index_info *pIdxInfo -+){ -+ int i; /* Loop counter or computed array index */ -+ int aIdx[2]; /* Index of constraints for JSON and ROOT */ -+ int unusableMask = 0; /* Mask of unusable JSON and ROOT constraints */ -+ int idxMask = 0; /* Mask of usable == constraints JSON and ROOT */ -+ const struct sqlite3_index_constraint *pConstraint; -+ -+ /* This implementation assumes that JSON and ROOT are the last two -+ ** columns in the table */ -+ assert( JEACH_ROOT == JEACH_JSON+1 ); -+ UNUSED_PARAM(tab); -+ aIdx[0] = aIdx[1] = -1; -+ pConstraint = pIdxInfo->aConstraint; -+ for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ -+ int iCol; -+ int iMask; -+ if( pConstraint->iColumn < JEACH_JSON ) continue; -+ iCol = pConstraint->iColumn - JEACH_JSON; -+ assert( iCol==0 || iCol==1 ); -+ iMask = 1 << iCol; -+ if( pConstraint->usable==0 ){ -+ unusableMask |= iMask; -+ }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){ -+ aIdx[iCol] = i; -+ idxMask |= iMask; -+ } -+ } -+ if( (unusableMask & ~idxMask)!=0 ){ -+ /* If there are any unusable constraints on JSON or ROOT, then reject -+ ** this entire plan */ -+ return SQLITE_CONSTRAINT; -+ } -+ if( aIdx[0]<0 ){ -+ /* No JSON input. Leave estimatedCost at the huge value that it was -+ ** initialized to to discourage the query planner from selecting this -+ ** plan. */ -+ pIdxInfo->idxNum = 0; -+ }else{ -+ pIdxInfo->estimatedCost = 1.0; -+ i = aIdx[0]; -+ pIdxInfo->aConstraintUsage[i].argvIndex = 1; -+ pIdxInfo->aConstraintUsage[i].omit = 1; -+ if( aIdx[1]<0 ){ -+ pIdxInfo->idxNum = 1; /* Only JSON supplied. Plan 1 */ -+ }else{ -+ i = aIdx[1]; -+ pIdxInfo->aConstraintUsage[i].argvIndex = 2; -+ pIdxInfo->aConstraintUsage[i].omit = 1; -+ pIdxInfo->idxNum = 3; /* Both JSON and ROOT are supplied. Plan 3 */ -+ } -+ } -+ return SQLITE_OK; -+} -+ -+/* Start a search on a new JSON string */ -+static int jsonEachFilter( -+ sqlite3_vtab_cursor *cur, -+ int idxNum, const char *idxStr, -+ int argc, sqlite3_value **argv -+){ -+ JsonEachCursor *p = (JsonEachCursor*)cur; -+ const char *z; -+ const char *zRoot = 0; -+ sqlite3_int64 n; -+ -+ UNUSED_PARAM(idxStr); -+ UNUSED_PARAM(argc); -+ jsonEachCursorReset(p); -+ if( idxNum==0 ) return SQLITE_OK; -+ z = (const char*)sqlite3_value_text(argv[0]); -+ if( z==0 ) return SQLITE_OK; -+ n = sqlite3_value_bytes(argv[0]); -+ p->zJson = sqlite3_malloc64( n+1 ); -+ if( p->zJson==0 ) return SQLITE_NOMEM; -+ memcpy(p->zJson, z, (size_t)n+1); -+ if( jsonParse(&p->sParse, 0, p->zJson) ){ -+ int rc = SQLITE_NOMEM; -+ if( p->sParse.oom==0 ){ -+ sqlite3_free(cur->pVtab->zErrMsg); -+ cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); -+ if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR; -+ } -+ jsonEachCursorReset(p); -+ return rc; -+ }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){ -+ jsonEachCursorReset(p); -+ return SQLITE_NOMEM; -+ }else{ -+ JsonNode *pNode = 0; -+ if( idxNum==3 ){ -+ const char *zErr = 0; -+ zRoot = (const char*)sqlite3_value_text(argv[1]); -+ if( zRoot==0 ) return SQLITE_OK; -+ n = sqlite3_value_bytes(argv[1]); -+ p->zRoot = sqlite3_malloc64( n+1 ); -+ if( p->zRoot==0 ) return SQLITE_NOMEM; -+ memcpy(p->zRoot, zRoot, (size_t)n+1); -+ if( zRoot[0]!='$' ){ -+ zErr = zRoot; -+ }else{ -+ pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr); -+ } -+ if( zErr ){ -+ sqlite3_free(cur->pVtab->zErrMsg); -+ cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr); -+ jsonEachCursorReset(p); -+ return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; -+ }else if( pNode==0 ){ -+ return SQLITE_OK; -+ } -+ }else{ -+ pNode = p->sParse.aNode; -+ } -+ p->iBegin = p->i = (int)(pNode - p->sParse.aNode); -+ p->eType = pNode->eType; -+ if( p->eType>=JSON_ARRAY ){ -+ pNode->u.iKey = 0; -+ p->iEnd = p->i + pNode->n + 1; -+ if( p->bRecursive ){ -+ p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType; -+ if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){ -+ p->i--; -+ } -+ }else{ -+ p->i++; -+ } -+ }else{ -+ p->iEnd = p->i+1; -+ } -+ } -+ return SQLITE_OK; -+} -+ -+/* The methods of the json_each virtual table */ -+static sqlite3_module jsonEachModule = { -+ 0, /* iVersion */ -+ 0, /* xCreate */ -+ jsonEachConnect, /* xConnect */ -+ jsonEachBestIndex, /* xBestIndex */ -+ jsonEachDisconnect, /* xDisconnect */ -+ 0, /* xDestroy */ -+ jsonEachOpenEach, /* xOpen - open a cursor */ -+ jsonEachClose, /* xClose - close a cursor */ -+ jsonEachFilter, /* xFilter - configure scan constraints */ -+ jsonEachNext, /* xNext - advance a cursor */ -+ jsonEachEof, /* xEof - check for end of scan */ -+ jsonEachColumn, /* xColumn - read data */ -+ jsonEachRowid, /* xRowid - read data */ -+ 0, /* xUpdate */ -+ 0, /* xBegin */ -+ 0, /* xSync */ -+ 0, /* xCommit */ -+ 0, /* xRollback */ -+ 0, /* xFindMethod */ -+ 0, /* xRename */ -+ 0, /* xSavepoint */ -+ 0, /* xRelease */ -+ 0, /* xRollbackTo */ -+ 0 /* xShadowName */ -+}; -+ -+/* The methods of the json_tree virtual table. */ -+static sqlite3_module jsonTreeModule = { -+ 0, /* iVersion */ -+ 0, /* xCreate */ -+ jsonEachConnect, /* xConnect */ -+ jsonEachBestIndex, /* xBestIndex */ -+ jsonEachDisconnect, /* xDisconnect */ -+ 0, /* xDestroy */ -+ jsonEachOpenTree, /* xOpen - open a cursor */ -+ jsonEachClose, /* xClose - close a cursor */ -+ jsonEachFilter, /* xFilter - configure scan constraints */ -+ jsonEachNext, /* xNext - advance a cursor */ -+ jsonEachEof, /* xEof - check for end of scan */ -+ jsonEachColumn, /* xColumn - read data */ -+ jsonEachRowid, /* xRowid - read data */ -+ 0, /* xUpdate */ -+ 0, /* xBegin */ -+ 0, /* xSync */ -+ 0, /* xCommit */ -+ 0, /* xRollback */ -+ 0, /* xFindMethod */ -+ 0, /* xRename */ -+ 0, /* xSavepoint */ -+ 0, /* xRelease */ -+ 0, /* xRollbackTo */ -+ 0 /* xShadowName */ -+}; -+#endif /* SQLITE_OMIT_VIRTUALTABLE */ -+ -+/**************************************************************************** -+** The following routines are the only publically visible identifiers in this -+** file. Call the following routines in order to register the various SQL -+** functions and the virtual table implemented by this file. -+****************************************************************************/ -+ -+SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){ -+ int rc = SQLITE_OK; -+ unsigned int i; -+ static const struct { -+ const char *zName; -+ int nArg; -+ int flag; -+ void (*xFunc)(sqlite3_context*,int,sqlite3_value**); -+ } aFunc[] = { -+ { "json", 1, 0, jsonRemoveFunc }, -+ { "json_array", -1, 0, jsonArrayFunc }, -+ { "json_array_length", 1, 0, jsonArrayLengthFunc }, -+ { "json_array_length", 2, 0, jsonArrayLengthFunc }, -+ { "json_extract", -1, 0, jsonExtractFunc }, -+ { "json_insert", -1, 0, jsonSetFunc }, -+ { "json_object", -1, 0, jsonObjectFunc }, -+ { "json_patch", 2, 0, jsonPatchFunc }, -+ { "json_quote", 1, 0, jsonQuoteFunc }, -+ { "json_remove", -1, 0, jsonRemoveFunc }, -+ { "json_replace", -1, 0, jsonReplaceFunc }, -+ { "json_set", -1, 1, jsonSetFunc }, -+ { "json_type", 1, 0, jsonTypeFunc }, -+ { "json_type", 2, 0, jsonTypeFunc }, -+ { "json_valid", 1, 0, jsonValidFunc }, -+ -+#if SQLITE_DEBUG -+ /* DEBUG and TESTING functions */ -+ { "json_parse", 1, 0, jsonParseFunc }, -+ { "json_test1", 1, 0, jsonTest1Func }, -+#endif -+ }; -+ static const struct { -+ const char *zName; -+ int nArg; -+ void (*xStep)(sqlite3_context*,int,sqlite3_value**); -+ void (*xFinal)(sqlite3_context*); -+ void (*xValue)(sqlite3_context*); -+ } aAgg[] = { -+ { "json_group_array", 1, -+ jsonArrayStep, jsonArrayFinal, jsonArrayValue }, -+ { "json_group_object", 2, -+ jsonObjectStep, jsonObjectFinal, jsonObjectValue }, -+ }; -+#ifndef SQLITE_OMIT_VIRTUALTABLE -+ static const struct { -+ const char *zName; -+ sqlite3_module *pModule; -+ } aMod[] = { -+ { "json_each", &jsonEachModule }, -+ { "json_tree", &jsonTreeModule }, -+ }; -+#endif -+ for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){ -+ rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg, -+ SQLITE_UTF8 | SQLITE_DETERMINISTIC, -+ (void*)&aFunc[i].flag, -+ aFunc[i].xFunc, 0, 0); -+ } -+#ifndef SQLITE_OMIT_WINDOWFUNC -+ for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){ -+ rc = sqlite3_create_window_function(db, aAgg[i].zName, aAgg[i].nArg, -+ SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, -+ aAgg[i].xStep, aAgg[i].xFinal, -+ aAgg[i].xValue, jsonGroupInverse, 0); -+ } -+#endif -+#ifndef SQLITE_OMIT_VIRTUALTABLE -+ for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){ -+ rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0); -+ } -+#endif -+ return rc; -+} -+ -+ -+#ifndef SQLITE_CORE -+#ifdef _WIN32 -+__declspec(dllexport) -+#endif -+SQLITE_API int sqlite3_json_init( -+ sqlite3 *db, -+ char **pzErrMsg, -+ const sqlite3_api_routines *pApi -+){ -+ SQLITE_EXTENSION_INIT2(pApi); -+ (void)pzErrMsg; /* Unused parameter */ -+ return sqlite3Json1Init(db); -+} -+#endif -+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) */ -+ -+/************** End of json1.c ***********************************************/ - /************** Begin file rtree.c *******************************************/ - /* - ** 2001 September 15 -@@ -165280,7 +179149,7 @@ - ** - ** CREATE TABLE %_node(nodeno INTEGER PRIMARY KEY, data BLOB) - ** CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER) --** CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER) -+** CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER, ...) - ** - ** The data for each node of the r-tree structure is stored in the %_node - ** table. For each node that is not the root node of the r-tree, there is -@@ -165287,7 +179156,8 @@ - ** an entry in the %_parent table associating the node with its parent. - ** And for each row of data in the table, there is an entry in the %_rowid - ** table that maps from the entries rowid to the id of the node that it --** is stored on. -+** is stored on. If the r-tree contains auxiliary columns, those are stored -+** on the end of the %_rowid table. - ** - ** The root node of an r-tree always exists, even if the r-tree table is - ** empty. The nodeno of the root node is always 1. All other nodes in the -@@ -165308,7 +179178,8 @@ - ** child page. - */ - --#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE) -+#if !defined(SQLITE_CORE) \ -+ || (defined(SQLITE_ENABLE_RTREE) && !defined(SQLITE_OMIT_VIRTUALTABLE)) - - #ifndef SQLITE_CORE - /* #include "sqlite3ext.h" */ -@@ -165349,6 +179220,9 @@ - /* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */ - #define RTREE_MAX_DIMENSIONS 5 - -+/* Maximum number of auxiliary columns */ -+#define RTREE_MAX_AUX_COLUMN 100 -+ - /* Size of hash table Rtree.aHash. This hash table is not expected to - ** ever contain very many entries, so a fixed number of buckets is - ** used. -@@ -165377,6 +179251,8 @@ - u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */ - u8 nBytesPerCell; /* Bytes consumed per cell */ - u8 inWrTrans; /* True if inside write transaction */ -+ u8 nAux; /* # of auxiliary columns in %_rowid */ -+ u8 nAuxNotNull; /* Number of initial not-null aux columns */ - int iDepth; /* Current depth of the r-tree structure */ - char *zDb; /* Name of database containing r-tree table */ - char *zName; /* Name of r-tree table */ -@@ -165383,6 +179259,8 @@ - u32 nBusy; /* Current number of users of this structure */ - i64 nRowEst; /* Estimated number of rows in this table */ - u32 nCursor; /* Number of open cursors */ -+ u32 nNodeRef; /* Number RtreeNodes with positive nRef */ -+ char *zReadAuxSql; /* SQL for statement to read aux data */ - - /* List of nodes removed during a CondenseTree operation. List is - ** linked together via the pointer normally used for hash chains - -@@ -165409,6 +179287,9 @@ - sqlite3_stmt *pWriteParent; - sqlite3_stmt *pDeleteParent; - -+ /* Statement for writing to the "aux:" fields, if there are any */ -+ sqlite3_stmt *pWriteAux; -+ - RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ - }; - -@@ -165465,7 +179346,7 @@ - ** The smallest possible node-size is (512-64)==448 bytes. And the largest - ** supported cell size is 48 bytes (8 byte rowid + ten 4 byte coordinates). - ** Therefore all non-root nodes must contain at least 3 entries. Since --** 2^40 is greater than 2^64, an r-tree structure always has a depth of -+** 3^40 is greater than 2^64, an r-tree structure always has a depth of - ** 40 or less. - */ - #define RTREE_MAX_DEPTH 40 -@@ -165485,6 +179366,7 @@ - sqlite3_vtab_cursor base; /* Base class. Must be first */ - u8 atEOF; /* True if at end of search */ - u8 bPoint; /* True if sPoint is valid */ -+ u8 bAuxValid; /* True if pReadAux is valid */ - int iStrategy; /* Copy of idxNum search parameter */ - int nConstraint; /* Number of entries in aConstraint */ - RtreeConstraint *aConstraint; /* Search constraints. */ -@@ -165492,6 +179374,7 @@ - int nPoint; /* Number of slots used in aPoint[] */ - int mxLevel; /* iLevel value for root of the tree */ - RtreeSearchPoint *aPoint; /* Priority queue for search points */ -+ sqlite3_stmt *pReadAux; /* Statement to read aux-data */ - RtreeSearchPoint sPoint; /* Cached next search point */ - RtreeNode *aNode[RTREE_CACHE_SZ]; /* Rtree node cache */ - u32 anQueue[RTREE_MAX_DEPTH+1]; /* Number of queued entries by iLevel */ -@@ -165778,6 +179661,7 @@ - */ - static void nodeReference(RtreeNode *p){ - if( p ){ -+ assert( p->nRef>0 ); - p->nRef++; - } - } -@@ -165845,6 +179729,7 @@ - memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize); - pNode->zData = (u8 *)&pNode[1]; - pNode->nRef = 1; -+ pRtree->nNodeRef++; - pNode->pParent = pParent; - pNode->isDirty = 1; - nodeReference(pParent); -@@ -165878,10 +179763,10 @@ - /* Check if the requested node is already in the hash table. If so, - ** increase its reference count and return it. - */ -- if( (pNode = nodeHashLookup(pRtree, iNode)) ){ -+ if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){ - assert( !pParent || !pNode->pParent || pNode->pParent==pParent ); - if( pParent && !pNode->pParent ){ -- nodeReference(pParent); -+ pParent->nRef++; - pNode->pParent = pParent; - } - pNode->nRef++; -@@ -165920,6 +179805,7 @@ - pNode->pParent = pParent; - pNode->zData = (u8 *)&pNode[1]; - pNode->nRef = 1; -+ pRtree->nNodeRef++; - pNode->iNode = iNode; - pNode->isDirty = 0; - pNode->pNext = 0; -@@ -165960,7 +179846,10 @@ - } - *ppNode = pNode; - }else{ -- sqlite3_free(pNode); -+ if( pNode ){ -+ pRtree->nNodeRef--; -+ sqlite3_free(pNode); -+ } - *ppNode = 0; - } - -@@ -166040,6 +179929,7 @@ - sqlite3_step(p); - pNode->isDirty = 0; - rc = sqlite3_reset(p); -+ sqlite3_bind_null(p, 2); - if( pNode->iNode==0 && rc==SQLITE_OK ){ - pNode->iNode = sqlite3_last_insert_rowid(pRtree->db); - nodeHashInsert(pRtree, pNode); -@@ -166056,8 +179946,10 @@ - int rc = SQLITE_OK; - if( pNode ){ - assert( pNode->nRef>0 ); -+ assert( pRtree->nNodeRef>0 ); - pNode->nRef--; - if( pNode->nRef==0 ){ -+ pRtree->nNodeRef--; - if( pNode->iNode==1 ){ - pRtree->iDepth = -1; - } -@@ -166174,8 +180066,9 @@ - pRtree->nBusy--; - if( pRtree->nBusy==0 ){ - pRtree->inWrTrans = 0; -- pRtree->nCursor = 0; -+ assert( pRtree->nCursor==0 ); - nodeBlobReset(pRtree); -+ assert( pRtree->nNodeRef==0 ); - sqlite3_finalize(pRtree->pWriteNode); - sqlite3_finalize(pRtree->pDeleteNode); - sqlite3_finalize(pRtree->pReadRowid); -@@ -166184,6 +180077,8 @@ - sqlite3_finalize(pRtree->pReadParent); - sqlite3_finalize(pRtree->pWriteParent); - sqlite3_finalize(pRtree->pDeleteParent); -+ sqlite3_finalize(pRtree->pWriteAux); -+ sqlite3_free(pRtree->zReadAuxSql); - sqlite3_free(pRtree); - } - } -@@ -166272,6 +180167,7 @@ - RtreeCursor *pCsr = (RtreeCursor *)cur; - assert( pRtree->nCursor>0 ); - freeCursorConstraints(pCsr); -+ sqlite3_finalize(pCsr->pReadAux); - sqlite3_free(pCsr->aPoint); - for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]); - sqlite3_free(pCsr); -@@ -166643,7 +180539,7 @@ - if( ii<RTREE_CACHE_SZ ){ - assert( pCur->aNode[ii]==0 ); - pCur->aNode[ii] = pCur->aNode[0]; -- }else{ -+ }else{ - nodeRelease(RTREE_OF_CURSOR(pCur), pCur->aNode[0]); - } - pCur->aNode[0] = 0; -@@ -166814,6 +180710,10 @@ - - /* Move to the next entry that matches the configured constraints. */ - RTREE_QUEUE_TRACE(pCsr, "POP-Nx:"); -+ if( pCsr->bAuxValid ){ -+ pCsr->bAuxValid = 0; -+ sqlite3_reset(pCsr->pReadAux); -+ } - rtreeSearchPointPop(pCsr); - rc = rtreeStepToLeaf(pCsr); - return rc; -@@ -166848,7 +180748,7 @@ - if( p==0 ) return SQLITE_OK; - if( i==0 ){ - sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell)); -- }else{ -+ }else if( i<=pRtree->nDim2 ){ - nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c); - #ifndef SQLITE_RTREE_INT_ONLY - if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ -@@ -166859,7 +180759,27 @@ - assert( pRtree->eCoordType==RTREE_COORD_INT32 ); - sqlite3_result_int(ctx, c.i); - } -- } -+ }else{ -+ if( !pCsr->bAuxValid ){ -+ if( pCsr->pReadAux==0 ){ -+ rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0, -+ &pCsr->pReadAux, 0); -+ if( rc ) return rc; -+ } -+ sqlite3_bind_int64(pCsr->pReadAux, 1, -+ nodeGetRowid(pRtree, pNode, p->iCell)); -+ rc = sqlite3_step(pCsr->pReadAux); -+ if( rc==SQLITE_ROW ){ -+ pCsr->bAuxValid = 1; -+ }else{ -+ sqlite3_reset(pCsr->pReadAux); -+ if( rc==SQLITE_DONE ) rc = SQLITE_OK; -+ return rc; -+ } -+ } -+ sqlite3_result_value(ctx, -+ sqlite3_column_value(pCsr->pReadAux, i - pRtree->nDim2 + 1)); -+ } - return SQLITE_OK; - } - -@@ -166937,6 +180857,7 @@ - int ii; - int rc = SQLITE_OK; - int iCell = 0; -+ sqlite3_stmt *pStmt; - - rtreeReference(pRtree); - -@@ -166943,8 +180864,10 @@ - /* 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; - - pCsr->iStrategy = idxNum; - if( idxNum==1 ){ -@@ -167107,10 +181030,14 @@ - */ - pIdxInfo->estimatedCost = 30.0; - pIdxInfo->estimatedRows = 1; -+ pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE; - return SQLITE_OK; - } - -- if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){ -+ if( p->usable -+ && ((p->iColumn>0 && p->iColumn<=pRtree->nDim2) -+ || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) -+ ){ - u8 op; - switch( p->op ){ - case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break; -@@ -167277,7 +181204,7 @@ - ){ - int rc; - int ii; -- RtreeNode *pNode; -+ RtreeNode *pNode = 0; - rc = nodeAcquire(pRtree, 1, 0, &pNode); - - for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){ -@@ -167683,7 +181610,7 @@ - }else{ - pLeft = pNode; - pRight = nodeNew(pRtree, pLeft->pParent); -- nodeReference(pLeft); -+ pLeft->nRef++; - } - - if( !pLeft || !pRight ){ -@@ -168092,7 +182019,7 @@ - /* - ** Select a currently unused rowid for a new r-tree record. - */ --static int newRowid(Rtree *pRtree, i64 *piRowid){ -+static int rtreeNewRowid(Rtree *pRtree, i64 *piRowid){ - int rc; - sqlite3_bind_null(pRtree->pWriteRowid, 1); - sqlite3_bind_null(pRtree->pWriteRowid, 2); -@@ -168109,7 +182036,7 @@ - int rc; /* Return code */ - RtreeNode *pLeaf = 0; /* Leaf node containing record iDelete */ - int iCell; /* Index of iDelete cell in pLeaf */ -- RtreeNode *pRoot; /* Root node of rtree structure */ -+ RtreeNode *pRoot = 0; /* Root node of rtree structure */ - - - /* Obtain a reference to the root node to initialize Rtree.iDepth */ -@@ -168152,7 +182079,7 @@ - */ - if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){ - int rc2; -- RtreeNode *pChild; -+ RtreeNode *pChild = 0; - i64 iChild = nodeGetRowid(pRtree, pRoot, 0); - rc = nodeAcquire(pRtree, iChild, pRoot, &pChild); - if( rc==SQLITE_OK ){ -@@ -168173,6 +182100,7 @@ - rc = reinsertNodeContent(pRtree, pLeaf); - } - pRtree->pDeleted = pLeaf->pNext; -+ pRtree->nNodeRef--; - sqlite3_free(pLeaf); - } - -@@ -168269,7 +182197,7 @@ - static int rtreeUpdate( - sqlite3_vtab *pVtab, - int nData, -- sqlite3_value **azData, -+ sqlite3_value **aData, - sqlite_int64 *pRowid - ){ - Rtree *pRtree = (Rtree *)pVtab; -@@ -168277,6 +182205,12 @@ - RtreeCell cell; /* New cell to insert if nData>1 */ - int bHaveRowid = 0; /* Set to 1 after new rowid is determined */ - -+ if( pRtree->nNodeRef ){ -+ /* Unable to write to the btree while another cursor is reading from it, -+ ** since the write might do a rebalance which would disrupt the read -+ ** cursor. */ -+ return SQLITE_LOCKED_VTAB; -+ } - rtreeReference(pRtree); - assert(nData>=1); - -@@ -168295,8 +182229,10 @@ - */ - if( nData>1 ){ - int ii; -+ int nn = nData - 4; - -- /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. -+ if( nn > pRtree->nDim2 ) nn = pRtree->nDim2; -+ /* Populate the cell.aCoord[] array. The first coordinate is aData[3]. - ** - ** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared - ** with "column" that are interpreted as table constraints. -@@ -168304,13 +182240,12 @@ - ** This problem was discovered after years of use, so we silently ignore - ** these kinds of misdeclared tables to avoid breaking any legacy. - */ -- assert( nData<=(pRtree->nDim2 + 3) ); - - #ifndef SQLITE_RTREE_INT_ONLY - if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ -- for(ii=0; ii<nData-4; ii+=2){ -- cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]); -- cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]); -+ for(ii=0; ii<nn; ii+=2){ -+ cell.aCoord[ii].f = rtreeValueDown(aData[ii+3]); -+ cell.aCoord[ii+1].f = rtreeValueUp(aData[ii+4]); - if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){ - rc = rtreeConstraintError(pRtree, ii+1); - goto constraint; -@@ -168319,9 +182254,9 @@ - }else - #endif - { -- for(ii=0; ii<nData-4; ii+=2){ -- cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]); -- cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]); -+ for(ii=0; ii<nn; ii+=2){ -+ cell.aCoord[ii].i = sqlite3_value_int(aData[ii+3]); -+ cell.aCoord[ii+1].i = sqlite3_value_int(aData[ii+4]); - if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){ - rc = rtreeConstraintError(pRtree, ii+1); - goto constraint; -@@ -168331,10 +182266,10 @@ - - /* If a rowid value was supplied, check if it is already present in - ** the table. If so, the constraint has failed. */ -- if( sqlite3_value_type(azData[2])!=SQLITE_NULL ){ -- cell.iRowid = sqlite3_value_int64(azData[2]); -- if( sqlite3_value_type(azData[0])==SQLITE_NULL -- || sqlite3_value_int64(azData[0])!=cell.iRowid -+ if( sqlite3_value_type(aData[2])!=SQLITE_NULL ){ -+ cell.iRowid = sqlite3_value_int64(aData[2]); -+ if( sqlite3_value_type(aData[0])==SQLITE_NULL -+ || sqlite3_value_int64(aData[0])!=cell.iRowid - ){ - int steprc; - sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); -@@ -168353,16 +182288,16 @@ - } - } - -- /* If azData[0] is not an SQL NULL value, it is the rowid of a -+ /* If aData[0] is not an SQL NULL value, it is the rowid of a - ** record to delete from the r-tree table. The following block does - ** just that. - */ -- if( sqlite3_value_type(azData[0])!=SQLITE_NULL ){ -- rc = rtreeDeleteRowid(pRtree, sqlite3_value_int64(azData[0])); -+ if( sqlite3_value_type(aData[0])!=SQLITE_NULL ){ -+ rc = rtreeDeleteRowid(pRtree, sqlite3_value_int64(aData[0])); - } - -- /* If the azData[] array contains more than one element, elements -- ** (azData[2]..azData[argc-1]) contain a new record to insert into -+ /* If the aData[] array contains more than one element, elements -+ ** (aData[2]..aData[argc-1]) contain a new record to insert into - ** the r-tree structure. - */ - if( rc==SQLITE_OK && nData>1 ){ -@@ -168371,7 +182306,7 @@ - - /* Figure out the rowid of the new row. */ - if( bHaveRowid==0 ){ -- rc = newRowid(pRtree, &cell.iRowid); -+ rc = rtreeNewRowid(pRtree, &cell.iRowid); - } - *pRowid = cell.iRowid; - -@@ -168387,6 +182322,16 @@ - rc = rc2; - } - } -+ if( pRtree->nAux ){ -+ sqlite3_stmt *pUp = pRtree->pWriteAux; -+ int jj; -+ sqlite3_bind_int64(pUp, 1, *pRowid); -+ for(jj=0; jj<pRtree->nAux; jj++){ -+ sqlite3_bind_value(pUp, jj+2, aData[pRtree->nDim2+3+jj]); -+ } -+ sqlite3_step(pUp); -+ rc = sqlite3_reset(pUp); -+ } - } - - constraint: -@@ -168453,7 +182398,7 @@ - */ - static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){ - Rtree *pRtree = (Rtree *)pVtab; -- int iwt = pRtree->inWrTrans; -+ u8 iwt = pRtree->inWrTrans; - UNUSED_PARAMETER(iSavepoint); - pRtree->inWrTrans = 0; - nodeBlobReset(pRtree); -@@ -168505,8 +182450,24 @@ - return rc; - } - -+ -+/* -+** Return true if zName is the extension on one of the shadow tables used -+** by this module. -+*/ -+static int rtreeShadowName(const char *zName){ -+ static const char *azName[] = { -+ "node", "parent", "rowid" -+ }; -+ unsigned int i; -+ for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){ -+ if( sqlite3_stricmp(zName, azName[i])==0 ) return 1; -+ } -+ return 0; -+} -+ - static sqlite3_module rtreeModule = { -- 2, /* iVersion */ -+ 3, /* iVersion */ - rtreeCreate, /* xCreate - create a table */ - rtreeConnect, /* xConnect - connect to an existing table */ - rtreeBestIndex, /* xBestIndex - Determine search strategy */ -@@ -168529,6 +182490,7 @@ - rtreeSavepoint, /* xSavepoint */ - 0, /* xRelease */ - 0, /* xRollbackTo */ -+ rtreeShadowName /* xShadowName */ - }; - - static int rtreeSqlInit( -@@ -168543,18 +182505,18 @@ - #define N_STATEMENT 8 - static const char *azSql[N_STATEMENT] = { - /* Write the xxx_node table */ -- "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(:1, :2)", -- "DELETE FROM '%q'.'%q_node' WHERE nodeno = :1", -+ "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(?1, ?2)", -+ "DELETE FROM '%q'.'%q_node' WHERE nodeno = ?1", - - /* Read and write the xxx_rowid table */ -- "SELECT nodeno FROM '%q'.'%q_rowid' WHERE rowid = :1", -- "INSERT OR REPLACE INTO '%q'.'%q_rowid' VALUES(:1, :2)", -- "DELETE FROM '%q'.'%q_rowid' WHERE rowid = :1", -+ "SELECT nodeno FROM '%q'.'%q_rowid' WHERE rowid = ?1", -+ "INSERT OR REPLACE INTO '%q'.'%q_rowid' VALUES(?1, ?2)", -+ "DELETE FROM '%q'.'%q_rowid' WHERE rowid = ?1", - - /* Read and write the xxx_parent table */ -- "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = :1", -- "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(:1, :2)", -- "DELETE FROM '%q'.'%q_parent' WHERE nodeno = :1" -+ "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = ?1", -+ "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(?1, ?2)", -+ "DELETE FROM '%q'.'%q_parent' WHERE nodeno = ?1" - }; - sqlite3_stmt **appStmt[N_STATEMENT]; - int i; -@@ -168562,14 +182524,25 @@ - pRtree->db = db; - - if( isCreate ){ -- char *zCreate = sqlite3_mprintf( --"CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY, data BLOB);" --"CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY, nodeno INTEGER);" --"CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY," -- " parentnode INTEGER);" --"INSERT INTO '%q'.'%q_node' VALUES(1, zeroblob(%d))", -- zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, pRtree->iNodeSize -- ); -+ char *zCreate; -+ sqlite3_str *p = sqlite3_str_new(db); -+ int ii; -+ sqlite3_str_appendf(p, -+ "CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY,nodeno", -+ zDb, zPrefix); -+ for(ii=0; ii<pRtree->nAux; ii++){ -+ sqlite3_str_appendf(p,",a%d",ii); -+ } -+ sqlite3_str_appendf(p, -+ ");CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY,data);", -+ zDb, zPrefix); -+ sqlite3_str_appendf(p, -+ "CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY,parentnode);", -+ zDb, zPrefix); -+ sqlite3_str_appendf(p, -+ "INSERT INTO \"%w\".\"%w_node\"VALUES(1,zeroblob(%d))", -+ zDb, zPrefix, pRtree->iNodeSize); -+ zCreate = sqlite3_str_finish(p); - if( !zCreate ){ - return SQLITE_NOMEM; - } -@@ -168591,7 +182564,17 @@ - - rc = rtreeQueryStat1(db, pRtree); - for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){ -- char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix); -+ char *zSql; -+ const char *zFormat; -+ if( i!=3 || pRtree->nAux==0 ){ -+ zFormat = azSql[i]; -+ }else { -+ /* An UPSERT is very slightly slower than REPLACE, but it is needed -+ ** if there are auxiliary columns */ -+ zFormat = "INSERT INTO\"%w\".\"%w_rowid\"(rowid,nodeno)VALUES(?1,?2)" -+ "ON CONFLICT(rowid)DO UPDATE SET nodeno=excluded.nodeno"; -+ } -+ zSql = sqlite3_mprintf(zFormat, zDb, zPrefix); - if( zSql ){ - rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT, - appStmt[i], 0); -@@ -168600,6 +182583,36 @@ - } - sqlite3_free(zSql); - } -+ if( pRtree->nAux ){ -+ pRtree->zReadAuxSql = sqlite3_mprintf( -+ "SELECT * FROM \"%w\".\"%w_rowid\" WHERE rowid=?1", -+ zDb, zPrefix); -+ if( pRtree->zReadAuxSql==0 ){ -+ rc = SQLITE_NOMEM; -+ }else{ -+ sqlite3_str *p = sqlite3_str_new(db); -+ int ii; -+ char *zSql; -+ sqlite3_str_appendf(p, "UPDATE \"%w\".\"%w_rowid\"SET ", zDb, zPrefix); -+ for(ii=0; ii<pRtree->nAux; ii++){ -+ if( ii ) sqlite3_str_append(p, ",", 1); -+ if( ii<pRtree->nAuxNotNull ){ -+ sqlite3_str_appendf(p,"a%d=coalesce(?%d,a%d)",ii,ii+2,ii); -+ }else{ -+ sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2); -+ } -+ } -+ sqlite3_str_appendf(p, " WHERE rowid=?1"); -+ zSql = sqlite3_str_finish(p); -+ if( zSql==0 ){ -+ rc = SQLITE_NOMEM; -+ }else{ -+ rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT, -+ &pRtree->pWriteAux, 0); -+ sqlite3_free(zSql); -+ } -+ } -+ } - - return rc; - } -@@ -168670,7 +182683,7 @@ - if( rc!=SQLITE_OK ){ - *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); - }else if( pRtree->iNodeSize<(512-64) ){ -- rc = SQLITE_CORRUPT; -+ rc = SQLITE_CORRUPT_VTAB; - *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"", - pRtree->zName); - } -@@ -168702,17 +182715,22 @@ - int nDb; /* Length of string argv[1] */ - int nName; /* Length of string argv[2] */ - int eCoordType = (pAux ? RTREE_COORD_INT32 : RTREE_COORD_REAL32); -+ sqlite3_str *pSql; -+ char *zSql; -+ int ii = 4; -+ int iErr; - - const char *aErrMsg[] = { - 0, /* 0 */ - "Wrong number of columns for an rtree table", /* 1 */ - "Too few columns for an rtree table", /* 2 */ -- "Too many columns for an rtree table" /* 3 */ -+ "Too many columns for an rtree table", /* 3 */ -+ "Auxiliary rtree columns must be last" /* 4 */ - }; - -- int iErr = (argc<6) ? 2 : argc>(RTREE_MAX_DIMENSIONS*2+4) ? 3 : argc%2; -- if( aErrMsg[iErr] ){ -- *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]); -+ 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]); - return SQLITE_ERROR; - } - -@@ -168730,53 +182748,73 @@ - pRtree->base.pModule = &rtreeModule; - pRtree->zDb = (char *)&pRtree[1]; - pRtree->zName = &pRtree->zDb[nDb+1]; -- pRtree->nDim = (u8)((argc-4)/2); -- pRtree->nDim2 = pRtree->nDim*2; -- pRtree->nBytesPerCell = 8 + pRtree->nDim2*4; - pRtree->eCoordType = (u8)eCoordType; - memcpy(pRtree->zDb, argv[1], nDb); - memcpy(pRtree->zName, argv[2], nName); - -- /* Figure out the node size to use. */ -- rc = getNodeSize(db, pRtree, isCreate, pzErr); - - /* Create/Connect to the underlying relational database schema. If - ** that is successful, call sqlite3_declare_vtab() to configure - ** the r-tree table schema. - */ -- if( rc==SQLITE_OK ){ -- if( (rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate)) ){ -- *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); -+ pSql = sqlite3_str_new(db); -+ sqlite3_str_appendf(pSql, "CREATE TABLE x(%s", argv[3]); -+ for(ii=4; ii<argc; ii++){ -+ if( argv[ii][0]=='+' ){ -+ pRtree->nAux++; -+ sqlite3_str_appendf(pSql, ",%s", argv[ii]+1); -+ }else if( pRtree->nAux>0 ){ -+ break; - }else{ -- char *zSql = sqlite3_mprintf("CREATE TABLE x(%s", argv[3]); -- char *zTmp; -- int ii; -- for(ii=4; zSql && ii<argc; ii++){ -- zTmp = zSql; -- zSql = sqlite3_mprintf("%s, %s", zTmp, argv[ii]); -- sqlite3_free(zTmp); -- } -- if( zSql ){ -- zTmp = zSql; -- zSql = sqlite3_mprintf("%s);", zTmp); -- sqlite3_free(zTmp); -- } -- if( !zSql ){ -- rc = SQLITE_NOMEM; -- }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){ -- *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); -- } -- sqlite3_free(zSql); -+ pRtree->nDim2++; -+ sqlite3_str_appendf(pSql, ",%s", argv[ii]); - } - } -- -- if( rc==SQLITE_OK ){ -- *ppVtab = (sqlite3_vtab *)pRtree; -+ sqlite3_str_appendf(pSql, ");"); -+ zSql = sqlite3_str_finish(pSql); -+ if( !zSql ){ -+ rc = SQLITE_NOMEM; -+ }else if( ii<argc ){ -+ *pzErr = sqlite3_mprintf("%s", aErrMsg[4]); -+ rc = SQLITE_ERROR; -+ }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){ -+ *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); -+ } -+ sqlite3_free(zSql); -+ if( rc ) goto rtreeInit_fail; -+ pRtree->nDim = pRtree->nDim2/2; -+ if( pRtree->nDim<1 ){ -+ iErr = 2; -+ }else if( pRtree->nDim2>RTREE_MAX_DIMENSIONS*2 ){ -+ iErr = 3; -+ }else if( pRtree->nDim2 % 2 ){ -+ iErr = 1; - }else{ -- assert( *ppVtab==0 ); -- assert( pRtree->nBusy==1 ); -- rtreeRelease(pRtree); -+ iErr = 0; - } -+ if( iErr ){ -+ *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]); -+ goto rtreeInit_fail; -+ } -+ pRtree->nBytesPerCell = 8 + pRtree->nDim2*4; -+ -+ /* Figure out the node size to use. */ -+ rc = getNodeSize(db, pRtree, isCreate, pzErr); -+ if( rc ) goto rtreeInit_fail; -+ rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate); -+ if( rc ){ -+ *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); -+ goto rtreeInit_fail; -+ } -+ -+ *ppVtab = (sqlite3_vtab *)pRtree; -+ return SQLITE_OK; -+ -+rtreeInit_fail: -+ if( rc==SQLITE_OK ) rc = SQLITE_ERROR; -+ assert( *ppVtab==0 ); -+ assert( pRtree->nBusy==1 ); -+ rtreeRelease(pRtree); - return rc; - } - -@@ -168865,6 +182903,2279 @@ - } - - /* -+** Context object passed between the various routines that make up the -+** implementation of integrity-check function rtreecheck(). -+*/ -+typedef struct RtreeCheck RtreeCheck; -+struct RtreeCheck { -+ sqlite3 *db; /* Database handle */ -+ const char *zDb; /* Database containing rtree table */ -+ const char *zTab; /* Name of rtree table */ -+ int bInt; /* True for rtree_i32 table */ -+ int nDim; /* Number of dimensions for this rtree tbl */ -+ sqlite3_stmt *pGetNode; /* Statement used to retrieve nodes */ -+ sqlite3_stmt *aCheckMapping[2]; /* Statements to query %_parent/%_rowid */ -+ int nLeaf; /* Number of leaf cells in table */ -+ int nNonLeaf; /* Number of non-leaf cells in table */ -+ int rc; /* Return code */ -+ char *zReport; /* Message to report */ -+ int nErr; /* Number of lines in zReport */ -+}; -+ -+#define RTREE_CHECK_MAX_ERROR 100 -+ -+/* -+** Reset SQL statement pStmt. If the sqlite3_reset() call returns an error, -+** and RtreeCheck.rc==SQLITE_OK, set RtreeCheck.rc to the error code. -+*/ -+static void rtreeCheckReset(RtreeCheck *pCheck, sqlite3_stmt *pStmt){ -+ int rc = sqlite3_reset(pStmt); -+ if( pCheck->rc==SQLITE_OK ) pCheck->rc = rc; -+} -+ -+/* -+** The second and subsequent arguments to this function are a format string -+** and printf style arguments. This function formats the string and attempts -+** to compile it as an SQL statement. -+** -+** If successful, a pointer to the new SQL statement is returned. Otherwise, -+** NULL is returned and an error code left in RtreeCheck.rc. -+*/ -+static sqlite3_stmt *rtreeCheckPrepare( -+ RtreeCheck *pCheck, /* RtreeCheck object */ -+ const char *zFmt, ... /* Format string and trailing args */ -+){ -+ va_list ap; -+ char *z; -+ sqlite3_stmt *pRet = 0; -+ -+ va_start(ap, zFmt); -+ z = sqlite3_vmprintf(zFmt, ap); -+ -+ if( pCheck->rc==SQLITE_OK ){ -+ if( z==0 ){ -+ pCheck->rc = SQLITE_NOMEM; -+ }else{ -+ pCheck->rc = sqlite3_prepare_v2(pCheck->db, z, -1, &pRet, 0); -+ } -+ } -+ -+ sqlite3_free(z); -+ va_end(ap); -+ return pRet; -+} -+ -+/* -+** The second and subsequent arguments to this function are a printf() -+** style format string and arguments. This function formats the string and -+** appends it to the report being accumuated in pCheck. -+*/ -+static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){ -+ va_list ap; -+ va_start(ap, zFmt); -+ if( pCheck->rc==SQLITE_OK && pCheck->nErr<RTREE_CHECK_MAX_ERROR ){ -+ char *z = sqlite3_vmprintf(zFmt, ap); -+ if( z==0 ){ -+ pCheck->rc = SQLITE_NOMEM; -+ }else{ -+ pCheck->zReport = sqlite3_mprintf("%z%s%z", -+ pCheck->zReport, (pCheck->zReport ? "\n" : ""), z -+ ); -+ if( pCheck->zReport==0 ){ -+ pCheck->rc = SQLITE_NOMEM; -+ } -+ } -+ pCheck->nErr++; -+ } -+ va_end(ap); -+} -+ -+/* -+** This function is a no-op if there is already an error code stored -+** in the RtreeCheck object indicated by the first argument. NULL is -+** returned in this case. -+** -+** Otherwise, the contents of rtree table node iNode are loaded from -+** the database and copied into a buffer obtained from sqlite3_malloc(). -+** If no error occurs, a pointer to the buffer is returned and (*pnNode) -+** is set to the size of the buffer in bytes. -+** -+** Or, if an error does occur, NULL is returned and an error code left -+** in the RtreeCheck object. The final value of *pnNode is undefined in -+** this case. -+*/ -+static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){ -+ u8 *pRet = 0; /* Return value */ -+ -+ assert( pCheck->rc==SQLITE_OK ); -+ if( pCheck->pGetNode==0 ){ -+ pCheck->pGetNode = rtreeCheckPrepare(pCheck, -+ "SELECT data FROM %Q.'%q_node' WHERE nodeno=?", -+ pCheck->zDb, pCheck->zTab -+ ); -+ } -+ -+ if( pCheck->rc==SQLITE_OK ){ -+ sqlite3_bind_int64(pCheck->pGetNode, 1, iNode); -+ if( sqlite3_step(pCheck->pGetNode)==SQLITE_ROW ){ -+ int nNode = sqlite3_column_bytes(pCheck->pGetNode, 0); -+ const u8 *pNode = (const u8*)sqlite3_column_blob(pCheck->pGetNode, 0); -+ pRet = sqlite3_malloc(nNode); -+ if( pRet==0 ){ -+ pCheck->rc = SQLITE_NOMEM; -+ }else{ -+ memcpy(pRet, pNode, nNode); -+ *pnNode = nNode; -+ } -+ } -+ rtreeCheckReset(pCheck, pCheck->pGetNode); -+ if( pCheck->rc==SQLITE_OK && pRet==0 ){ -+ rtreeCheckAppendMsg(pCheck, "Node %lld missing from database", iNode); -+ } -+ } -+ -+ return pRet; -+} -+ -+/* -+** This function is used to check that the %_parent (if bLeaf==0) or %_rowid -+** (if bLeaf==1) table contains a specified entry. The schemas of the -+** two tables are: -+** -+** CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER) -+** CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER, ...) -+** -+** In both cases, this function checks that there exists an entry with -+** IPK value iKey and the second column set to iVal. -+** -+*/ -+static void rtreeCheckMapping( -+ RtreeCheck *pCheck, /* RtreeCheck object */ -+ int bLeaf, /* True for a leaf cell, false for interior */ -+ i64 iKey, /* Key for mapping */ -+ i64 iVal /* Expected value for mapping */ -+){ -+ int rc; -+ sqlite3_stmt *pStmt; -+ const char *azSql[2] = { -+ "SELECT parentnode FROM %Q.'%q_parent' WHERE nodeno=?1", -+ "SELECT nodeno FROM %Q.'%q_rowid' WHERE rowid=?1" -+ }; -+ -+ assert( bLeaf==0 || bLeaf==1 ); -+ if( pCheck->aCheckMapping[bLeaf]==0 ){ -+ pCheck->aCheckMapping[bLeaf] = rtreeCheckPrepare(pCheck, -+ azSql[bLeaf], pCheck->zDb, pCheck->zTab -+ ); -+ } -+ if( pCheck->rc!=SQLITE_OK ) return; -+ -+ pStmt = pCheck->aCheckMapping[bLeaf]; -+ sqlite3_bind_int64(pStmt, 1, iKey); -+ rc = sqlite3_step(pStmt); -+ if( rc==SQLITE_DONE ){ -+ rtreeCheckAppendMsg(pCheck, "Mapping (%lld -> %lld) missing from %s table", -+ iKey, iVal, (bLeaf ? "%_rowid" : "%_parent") -+ ); -+ }else if( rc==SQLITE_ROW ){ -+ i64 ii = sqlite3_column_int64(pStmt, 0); -+ if( ii!=iVal ){ -+ rtreeCheckAppendMsg(pCheck, -+ "Found (%lld -> %lld) in %s table, expected (%lld -> %lld)", -+ iKey, ii, (bLeaf ? "%_rowid" : "%_parent"), iKey, iVal -+ ); -+ } -+ } -+ rtreeCheckReset(pCheck, pStmt); -+} -+ -+/* -+** Argument pCell points to an array of coordinates stored on an rtree page. -+** This function checks that the coordinates are internally consistent (no -+** x1>x2 conditions) and adds an error message to the RtreeCheck object -+** if they are not. -+** -+** Additionally, if pParent is not NULL, then it is assumed to point to -+** the array of coordinates on the parent page that bound the page -+** containing pCell. In this case it is also verified that the two -+** sets of coordinates are mutually consistent and an error message added -+** to the RtreeCheck object if they are not. -+*/ -+static void rtreeCheckCellCoord( -+ RtreeCheck *pCheck, -+ i64 iNode, /* Node id to use in error messages */ -+ int iCell, /* Cell number to use in error messages */ -+ u8 *pCell, /* Pointer to cell coordinates */ -+ u8 *pParent /* Pointer to parent coordinates */ -+){ -+ RtreeCoord c1, c2; -+ RtreeCoord p1, p2; -+ int i; -+ -+ for(i=0; i<pCheck->nDim; i++){ -+ readCoord(&pCell[4*2*i], &c1); -+ readCoord(&pCell[4*(2*i + 1)], &c2); -+ -+ /* printf("%e, %e\n", c1.u.f, c2.u.f); */ -+ if( pCheck->bInt ? c1.i>c2.i : c1.f>c2.f ){ -+ rtreeCheckAppendMsg(pCheck, -+ "Dimension %d of cell %d on node %lld is corrupt", i, iCell, iNode -+ ); -+ } -+ -+ if( pParent ){ -+ readCoord(&pParent[4*2*i], &p1); -+ readCoord(&pParent[4*(2*i + 1)], &p2); -+ -+ if( (pCheck->bInt ? c1.i<p1.i : c1.f<p1.f) -+ || (pCheck->bInt ? c2.i>p2.i : c2.f>p2.f) -+ ){ -+ rtreeCheckAppendMsg(pCheck, -+ "Dimension %d of cell %d on node %lld is corrupt relative to parent" -+ , i, iCell, iNode -+ ); -+ } -+ } -+ } -+} -+ -+/* -+** Run rtreecheck() checks on node iNode, which is at depth iDepth within -+** the r-tree structure. Argument aParent points to the array of coordinates -+** that bound node iNode on the parent node. -+** -+** If any problems are discovered, an error message is appended to the -+** report accumulated in the RtreeCheck object. -+*/ -+static void rtreeCheckNode( -+ RtreeCheck *pCheck, -+ int iDepth, /* Depth of iNode (0==leaf) */ -+ u8 *aParent, /* Buffer containing parent coords */ -+ i64 iNode /* Node to check */ -+){ -+ u8 *aNode = 0; -+ int nNode = 0; -+ -+ assert( iNode==1 || aParent!=0 ); -+ assert( pCheck->nDim>0 ); -+ -+ aNode = rtreeCheckGetNode(pCheck, iNode, &nNode); -+ if( aNode ){ -+ if( nNode<4 ){ -+ rtreeCheckAppendMsg(pCheck, -+ "Node %lld is too small (%d bytes)", iNode, nNode -+ ); -+ }else{ -+ int nCell; /* Number of cells on page */ -+ int i; /* Used to iterate through cells */ -+ if( aParent==0 ){ -+ iDepth = readInt16(aNode); -+ if( iDepth>RTREE_MAX_DEPTH ){ -+ rtreeCheckAppendMsg(pCheck, "Rtree depth out of range (%d)", iDepth); -+ sqlite3_free(aNode); -+ return; -+ } -+ } -+ nCell = readInt16(&aNode[2]); -+ if( (4 + nCell*(8 + pCheck->nDim*2*4))>nNode ){ -+ rtreeCheckAppendMsg(pCheck, -+ "Node %lld is too small for cell count of %d (%d bytes)", -+ iNode, nCell, nNode -+ ); -+ }else{ -+ for(i=0; i<nCell; i++){ -+ u8 *pCell = &aNode[4 + i*(8 + pCheck->nDim*2*4)]; -+ i64 iVal = readInt64(pCell); -+ rtreeCheckCellCoord(pCheck, iNode, i, &pCell[8], aParent); -+ -+ if( iDepth>0 ){ -+ rtreeCheckMapping(pCheck, 0, iVal, iNode); -+ rtreeCheckNode(pCheck, iDepth-1, &pCell[8], iVal); -+ pCheck->nNonLeaf++; -+ }else{ -+ rtreeCheckMapping(pCheck, 1, iVal, iNode); -+ pCheck->nLeaf++; -+ } -+ } -+ } -+ } -+ sqlite3_free(aNode); -+ } -+} -+ -+/* -+** The second argument to this function must be either "_rowid" or -+** "_parent". This function checks that the number of entries in the -+** %_rowid or %_parent table is exactly nExpect. If not, it adds -+** an error message to the report in the RtreeCheck object indicated -+** by the first argument. -+*/ -+static void rtreeCheckCount(RtreeCheck *pCheck, const char *zTbl, i64 nExpect){ -+ if( pCheck->rc==SQLITE_OK ){ -+ sqlite3_stmt *pCount; -+ pCount = rtreeCheckPrepare(pCheck, "SELECT count(*) FROM %Q.'%q%s'", -+ pCheck->zDb, pCheck->zTab, zTbl -+ ); -+ if( pCount ){ -+ if( sqlite3_step(pCount)==SQLITE_ROW ){ -+ i64 nActual = sqlite3_column_int64(pCount, 0); -+ if( nActual!=nExpect ){ -+ rtreeCheckAppendMsg(pCheck, "Wrong number of entries in %%%s table" -+ " - expected %lld, actual %lld" , zTbl, nExpect, nActual -+ ); -+ } -+ } -+ pCheck->rc = sqlite3_finalize(pCount); -+ } -+ } -+} -+ -+/* -+** This function does the bulk of the work for the rtree integrity-check. -+** It is called by rtreecheck(), which is the SQL function implementation. -+*/ -+static int rtreeCheckTable( -+ sqlite3 *db, /* Database handle to access db through */ -+ const char *zDb, /* Name of db ("main", "temp" etc.) */ -+ const char *zTab, /* Name of rtree table to check */ -+ char **pzReport /* OUT: sqlite3_malloc'd report text */ -+){ -+ RtreeCheck check; /* Common context for various routines */ -+ sqlite3_stmt *pStmt = 0; /* Used to find column count of rtree table */ -+ int bEnd = 0; /* True if transaction should be closed */ -+ int nAux = 0; /* Number of extra columns. */ -+ -+ /* Initialize the context object */ -+ memset(&check, 0, sizeof(check)); -+ check.db = db; -+ check.zDb = zDb; -+ check.zTab = zTab; -+ -+ /* If there is not already an open transaction, open one now. This is -+ ** to ensure that the queries run as part of this integrity-check operate -+ ** on a consistent snapshot. */ -+ if( sqlite3_get_autocommit(db) ){ -+ check.rc = sqlite3_exec(db, "BEGIN", 0, 0, 0); -+ bEnd = 1; -+ } -+ -+ /* Find the number of auxiliary columns */ -+ if( check.rc==SQLITE_OK ){ -+ pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab); -+ if( pStmt ){ -+ nAux = sqlite3_column_count(pStmt) - 2; -+ sqlite3_finalize(pStmt); -+ } -+ check.rc = SQLITE_OK; -+ } -+ -+ /* Find number of dimensions in the rtree table. */ -+ pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.%Q", zDb, zTab); -+ if( pStmt ){ -+ int rc; -+ check.nDim = (sqlite3_column_count(pStmt) - 1 - nAux) / 2; -+ if( check.nDim<1 ){ -+ rtreeCheckAppendMsg(&check, "Schema corrupt or not an rtree"); -+ }else if( SQLITE_ROW==sqlite3_step(pStmt) ){ -+ check.bInt = (sqlite3_column_type(pStmt, 1)==SQLITE_INTEGER); -+ } -+ rc = sqlite3_finalize(pStmt); -+ if( rc!=SQLITE_CORRUPT ) check.rc = rc; -+ } -+ -+ /* Do the actual integrity-check */ -+ if( check.nDim>=1 ){ -+ if( check.rc==SQLITE_OK ){ -+ rtreeCheckNode(&check, 0, 0, 1); -+ } -+ rtreeCheckCount(&check, "_rowid", check.nLeaf); -+ rtreeCheckCount(&check, "_parent", check.nNonLeaf); -+ } -+ -+ /* Finalize SQL statements used by the integrity-check */ -+ sqlite3_finalize(check.pGetNode); -+ sqlite3_finalize(check.aCheckMapping[0]); -+ sqlite3_finalize(check.aCheckMapping[1]); -+ -+ /* If one was opened, close the transaction */ -+ if( bEnd ){ -+ int rc = sqlite3_exec(db, "END", 0, 0, 0); -+ if( check.rc==SQLITE_OK ) check.rc = rc; -+ } -+ *pzReport = check.zReport; -+ return check.rc; -+} -+ -+/* -+** Usage: -+** -+** rtreecheck(<rtree-table>); -+** rtreecheck(<database>, <rtree-table>); -+** -+** Invoking this SQL function runs an integrity-check on the named rtree -+** table. The integrity-check verifies the following: -+** -+** 1. For each cell in the r-tree structure (%_node table), that: -+** -+** a) for each dimension, (coord1 <= coord2). -+** -+** b) unless the cell is on the root node, that the cell is bounded -+** by the parent cell on the parent node. -+** -+** c) for leaf nodes, that there is an entry in the %_rowid -+** table corresponding to the cell's rowid value that -+** points to the correct node. -+** -+** d) for cells on non-leaf nodes, that there is an entry in the -+** %_parent table mapping from the cell's child node to the -+** node that it resides on. -+** -+** 2. That there are the same number of entries in the %_rowid table -+** as there are leaf cells in the r-tree structure, and that there -+** is a leaf cell that corresponds to each entry in the %_rowid table. -+** -+** 3. That there are the same number of entries in the %_parent table -+** as there are non-leaf cells in the r-tree structure, and that -+** there is a non-leaf cell that corresponds to each entry in the -+** %_parent table. -+*/ -+static void rtreecheck( -+ sqlite3_context *ctx, -+ int nArg, -+ sqlite3_value **apArg -+){ -+ if( nArg!=1 && nArg!=2 ){ -+ sqlite3_result_error(ctx, -+ "wrong number of arguments to function rtreecheck()", -1 -+ ); -+ }else{ -+ int rc; -+ char *zReport = 0; -+ const char *zDb = (const char*)sqlite3_value_text(apArg[0]); -+ const char *zTab; -+ if( nArg==1 ){ -+ zTab = zDb; -+ zDb = "main"; -+ }else{ -+ zTab = (const char*)sqlite3_value_text(apArg[1]); -+ } -+ rc = rtreeCheckTable(sqlite3_context_db_handle(ctx), zDb, zTab, &zReport); -+ if( rc==SQLITE_OK ){ -+ sqlite3_result_text(ctx, zReport ? zReport : "ok", -1, SQLITE_TRANSIENT); -+ }else{ -+ sqlite3_result_error_code(ctx, rc); -+ } -+ sqlite3_free(zReport); -+ } -+} -+ -+/* Conditionally include the geopoly code */ -+#ifdef SQLITE_ENABLE_GEOPOLY -+/************** Include geopoly.c in the middle of rtree.c *******************/ -+/************** Begin file geopoly.c *****************************************/ -+/* -+** 2018-05-25 -+** -+** 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 an alternative R-Tree virtual table that -+** uses polygons to express the boundaries of 2-dimensional objects. -+** -+** This file is #include-ed onto the end of "rtree.c" so that it has -+** access to all of the R-Tree internals. -+*/ -+/* #include <stdlib.h> */ -+ -+/* Enable -DGEOPOLY_ENABLE_DEBUG for debugging facilities */ -+#ifdef GEOPOLY_ENABLE_DEBUG -+ static int geo_debug = 0; -+# define GEODEBUG(X) if(geo_debug)printf X -+#else -+# define GEODEBUG(X) -+#endif -+ -+#ifndef JSON_NULL /* The following stuff repeats things found in json1 */ -+/* -+** Versions of isspace(), isalnum() and isdigit() to which it is safe -+** to pass signed char values. -+*/ -+#ifdef sqlite3Isdigit -+ /* Use the SQLite core versions if this routine is part of the -+ ** SQLite amalgamation */ -+# define safe_isdigit(x) sqlite3Isdigit(x) -+# define safe_isalnum(x) sqlite3Isalnum(x) -+# define safe_isxdigit(x) sqlite3Isxdigit(x) -+#else -+ /* Use the standard library for separate compilation */ -+#include <ctype.h> /* amalgamator: keep */ -+# define safe_isdigit(x) isdigit((unsigned char)(x)) -+# define safe_isalnum(x) isalnum((unsigned char)(x)) -+# define safe_isxdigit(x) isxdigit((unsigned char)(x)) -+#endif -+ -+/* -+** Growing our own isspace() routine this way is twice as fast as -+** the library isspace() function. -+*/ -+static const char geopolyIsSpace[] = { -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+}; -+#define safe_isspace(x) (geopolyIsSpace[(unsigned char)x]) -+#endif /* JSON NULL - back to original code */ -+ -+/* Compiler and version */ -+#ifndef GCC_VERSION -+#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC) -+# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__) -+#else -+# define GCC_VERSION 0 -+#endif -+#endif -+#ifndef MSVC_VERSION -+#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC) -+# define MSVC_VERSION _MSC_VER -+#else -+# define MSVC_VERSION 0 -+#endif -+#endif -+ -+/* Datatype for coordinates -+*/ -+typedef float GeoCoord; -+ -+/* -+** Internal representation of a polygon. -+** -+** The polygon consists of a sequence of vertexes. There is a line -+** segment between each pair of vertexes, and one final segment from -+** the last vertex back to the first. (This differs from the GeoJSON -+** standard in which the final vertex is a repeat of the first.) -+** -+** The polygon follows the right-hand rule. The area to the right of -+** each segment is "outside" and the area to the left is "inside". -+** -+** The on-disk representation consists of a 4-byte header followed by -+** the values. The 4-byte header is: -+** -+** encoding (1 byte) 0=big-endian, 1=little-endian -+** nvertex (3 bytes) Number of vertexes as a big-endian integer -+** -+** Enough space is allocated for 4 coordinates, to work around over-zealous -+** warnings coming from some compiler (notably, clang). In reality, the size -+** of each GeoPoly memory allocate is adjusted as necessary so that the -+** GeoPoly.a[] array at the end is the appropriate size. -+*/ -+typedef struct GeoPoly GeoPoly; -+struct GeoPoly { -+ int nVertex; /* Number of vertexes */ -+ unsigned char hdr[4]; /* Header for on-disk representation */ -+ GeoCoord a[8]; /* 2*nVertex values. X (longitude) first, then Y */ -+}; -+ -+/* The size of a memory allocation needed for a GeoPoly object sufficient -+** to hold N coordinate pairs. -+*/ -+#define GEOPOLY_SZ(N) (sizeof(GeoPoly) + sizeof(GeoCoord)*2*((N)-4)) -+ -+/* -+** State of a parse of a GeoJSON input. -+*/ -+typedef struct GeoParse GeoParse; -+struct GeoParse { -+ const unsigned char *z; /* Unparsed input */ -+ int nVertex; /* Number of vertexes in a[] */ -+ int nAlloc; /* Space allocated to a[] */ -+ int nErr; /* Number of errors encountered */ -+ GeoCoord *a; /* Array of vertexes. From sqlite3_malloc64() */ -+}; -+ -+/* Do a 4-byte byte swap */ -+static void geopolySwab32(unsigned char *a){ -+ unsigned char t = a[0]; -+ a[0] = a[3]; -+ a[3] = t; -+ t = a[1]; -+ a[1] = a[2]; -+ a[2] = t; -+} -+ -+/* Skip whitespace. Return the next non-whitespace character. */ -+static char geopolySkipSpace(GeoParse *p){ -+ while( safe_isspace(p->z[0]) ) p->z++; -+ return p->z[0]; -+} -+ -+/* Parse out a number. Write the value into *pVal if pVal!=0. -+** return non-zero on success and zero if the next token is not a number. -+*/ -+static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){ -+ char c = geopolySkipSpace(p); -+ const unsigned char *z = p->z; -+ int j = 0; -+ int seenDP = 0; -+ int seenE = 0; -+ if( c=='-' ){ -+ j = 1; -+ c = z[j]; -+ } -+ if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0; -+ for(;; j++){ -+ c = z[j]; -+ if( safe_isdigit(c) ) continue; -+ if( c=='.' ){ -+ if( z[j-1]=='-' ) return 0; -+ if( seenDP ) return 0; -+ seenDP = 1; -+ continue; -+ } -+ if( c=='e' || c=='E' ){ -+ if( z[j-1]<'0' ) return 0; -+ if( seenE ) return -1; -+ seenDP = seenE = 1; -+ c = z[j+1]; -+ if( c=='+' || c=='-' ){ -+ j++; -+ c = z[j+1]; -+ } -+ if( c<'0' || c>'9' ) return 0; -+ continue; -+ } -+ break; -+ } -+ if( z[j-1]<'0' ) return 0; -+ if( pVal ){ -+#ifdef SQLITE_AMALGAMATION -+ /* The sqlite3AtoF() routine is much much faster than atof(), if it -+ ** is available */ -+ double r; -+ (void)sqlite3AtoF((const char*)p->z, &r, j, SQLITE_UTF8); -+ *pVal = r; -+#else -+ *pVal = (GeoCoord)atof((const char*)p->z); -+#endif -+ } -+ p->z += j; -+ return 1; -+} -+ -+/* -+** If the input is a well-formed JSON array of coordinates with at least -+** four coordinates and where each coordinate is itself a two-value array, -+** then convert the JSON into a GeoPoly object and return a pointer to -+** that object. -+** -+** If any error occurs, return NULL. -+*/ -+static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){ -+ GeoParse s; -+ int rc = SQLITE_OK; -+ memset(&s, 0, sizeof(s)); -+ s.z = z; -+ if( geopolySkipSpace(&s)=='[' ){ -+ s.z++; -+ while( geopolySkipSpace(&s)=='[' ){ -+ int ii = 0; -+ char c; -+ s.z++; -+ if( s.nVertex>=s.nAlloc ){ -+ GeoCoord *aNew; -+ s.nAlloc = s.nAlloc*2 + 16; -+ aNew = sqlite3_realloc64(s.a, s.nAlloc*sizeof(GeoCoord)*2 ); -+ if( aNew==0 ){ -+ rc = SQLITE_NOMEM; -+ s.nErr++; -+ break; -+ } -+ s.a = aNew; -+ } -+ while( geopolyParseNumber(&s, ii<=1 ? &s.a[s.nVertex*2+ii] : 0) ){ -+ ii++; -+ if( ii==2 ) s.nVertex++; -+ c = geopolySkipSpace(&s); -+ s.z++; -+ if( c==',' ) continue; -+ if( c==']' && ii>=2 ) break; -+ s.nErr++; -+ rc = SQLITE_ERROR; -+ goto parse_json_err; -+ } -+ if( geopolySkipSpace(&s)==',' ){ -+ s.z++; -+ continue; -+ } -+ break; -+ } -+ if( geopolySkipSpace(&s)==']' -+ && s.nVertex>=4 -+ && s.a[0]==s.a[s.nVertex*2-2] -+ && s.a[1]==s.a[s.nVertex*2-1] -+ && (s.z++, geopolySkipSpace(&s)==0) -+ ){ -+ GeoPoly *pOut; -+ int x = 1; -+ s.nVertex--; /* Remove the redundant vertex at the end */ -+ pOut = sqlite3_malloc64( GEOPOLY_SZ(s.nVertex) ); -+ x = 1; -+ if( pOut==0 ) goto parse_json_err; -+ pOut->nVertex = s.nVertex; -+ memcpy(pOut->a, s.a, s.nVertex*2*sizeof(GeoCoord)); -+ pOut->hdr[0] = *(unsigned char*)&x; -+ pOut->hdr[1] = (s.nVertex>>16)&0xff; -+ pOut->hdr[2] = (s.nVertex>>8)&0xff; -+ pOut->hdr[3] = s.nVertex&0xff; -+ sqlite3_free(s.a); -+ if( pRc ) *pRc = SQLITE_OK; -+ return pOut; -+ }else{ -+ s.nErr++; -+ rc = SQLITE_ERROR; -+ } -+ } -+parse_json_err: -+ if( pRc ) *pRc = rc; -+ sqlite3_free(s.a); -+ return 0; -+} -+ -+/* -+** Given a function parameter, try to interpret it as a polygon, either -+** in the binary format or JSON text. Compute a GeoPoly object and -+** return a pointer to that object. Or if the input is not a well-formed -+** polygon, put an error message in sqlite3_context and return NULL. -+*/ -+static GeoPoly *geopolyFuncParam( -+ sqlite3_context *pCtx, /* Context for error messages */ -+ sqlite3_value *pVal, /* The value to decode */ -+ int *pRc /* Write error here */ -+){ -+ GeoPoly *p = 0; -+ int nByte; -+ if( sqlite3_value_type(pVal)==SQLITE_BLOB -+ && (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord)) -+ ){ -+ const unsigned char *a = sqlite3_value_blob(pVal); -+ int nVertex; -+ nVertex = (a[1]<<16) + (a[2]<<8) + a[3]; -+ if( (a[0]==0 || a[0]==1) -+ && (nVertex*2*sizeof(GeoCoord) + 4)==(unsigned int)nByte -+ ){ -+ p = sqlite3_malloc64( sizeof(*p) + (nVertex-1)*2*sizeof(GeoCoord) ); -+ if( p==0 ){ -+ if( pRc ) *pRc = SQLITE_NOMEM; -+ if( pCtx ) sqlite3_result_error_nomem(pCtx); -+ }else{ -+ int x = 1; -+ p->nVertex = nVertex; -+ memcpy(p->hdr, a, nByte); -+ if( a[0] != *(unsigned char*)&x ){ -+ int ii; -+ for(ii=0; ii<nVertex*2; ii++){ -+ geopolySwab32((unsigned char*)&p->a[ii]); -+ } -+ p->hdr[0] ^= 1; -+ } -+ } -+ } -+ if( pRc ) *pRc = SQLITE_OK; -+ return p; -+ }else if( sqlite3_value_type(pVal)==SQLITE_TEXT ){ -+ const unsigned char *zJson = sqlite3_value_text(pVal); -+ if( zJson==0 ){ -+ if( pRc ) *pRc = SQLITE_NOMEM; -+ return 0; -+ } -+ return geopolyParseJson(zJson, pRc); -+ }else{ -+ if( pRc ) *pRc = SQLITE_ERROR; -+ return 0; -+ } -+} -+ -+/* -+** Implementation of the geopoly_blob(X) function. -+** -+** If the input is a well-formed Geopoly BLOB or JSON string -+** then return the BLOB representation of the polygon. Otherwise -+** return NULL. -+*/ -+static void geopolyBlobFunc( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); -+ if( p ){ -+ sqlite3_result_blob(context, p->hdr, -+ 4+8*p->nVertex, SQLITE_TRANSIENT); -+ sqlite3_free(p); -+ } -+} -+ -+/* -+** SQL function: geopoly_json(X) -+** -+** Interpret X as a polygon and render it as a JSON array -+** of coordinates. Or, if X is not a valid polygon, return NULL. -+*/ -+static void geopolyJsonFunc( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); -+ if( p ){ -+ sqlite3 *db = sqlite3_context_db_handle(context); -+ sqlite3_str *x = sqlite3_str_new(db); -+ int i; -+ sqlite3_str_append(x, "[", 1); -+ for(i=0; i<p->nVertex; i++){ -+ sqlite3_str_appendf(x, "[%!g,%!g],", p->a[i*2], p->a[i*2+1]); -+ } -+ sqlite3_str_appendf(x, "[%!g,%!g]]", p->a[0], p->a[1]); -+ sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free); -+ sqlite3_free(p); -+ } -+} -+ -+/* -+** SQL function: geopoly_svg(X, ....) -+** -+** Interpret X as a polygon and render it as a SVG <polyline>. -+** Additional arguments are added as attributes to the <polyline>. -+*/ -+static void geopolySvgFunc( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); -+ if( p ){ -+ sqlite3 *db = sqlite3_context_db_handle(context); -+ sqlite3_str *x = sqlite3_str_new(db); -+ int i; -+ char cSep = '\''; -+ sqlite3_str_appendf(x, "<polyline points="); -+ for(i=0; i<p->nVertex; i++){ -+ sqlite3_str_appendf(x, "%c%g,%g", cSep, p->a[i*2], p->a[i*2+1]); -+ cSep = ' '; -+ } -+ sqlite3_str_appendf(x, " %g,%g'", p->a[0], p->a[1]); -+ for(i=1; i<argc; i++){ -+ const char *z = (const char*)sqlite3_value_text(argv[i]); -+ if( z && z[0] ){ -+ sqlite3_str_appendf(x, " %s", z); -+ } -+ } -+ sqlite3_str_appendf(x, "></polyline>"); -+ sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free); -+ sqlite3_free(p); -+ } -+} -+ -+/* -+** SQL Function: geopoly_xform(poly, A, B, C, D, E, F) -+** -+** Transform and/or translate a polygon as follows: -+** -+** x1 = A*x0 + B*y0 + E -+** y1 = C*x0 + D*y0 + F -+** -+** For a translation: -+** -+** geopoly_xform(poly, 1, 0, 0, 1, x-offset, y-offset) -+** -+** Rotate by R around the point (0,0): -+** -+** geopoly_xform(poly, cos(R), sin(R), -sin(R), cos(R), 0, 0) -+*/ -+static void geopolyXformFunc( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); -+ double A = sqlite3_value_double(argv[1]); -+ double B = sqlite3_value_double(argv[2]); -+ double C = sqlite3_value_double(argv[3]); -+ double D = sqlite3_value_double(argv[4]); -+ double E = sqlite3_value_double(argv[5]); -+ double F = sqlite3_value_double(argv[6]); -+ GeoCoord x1, y1, x0, y0; -+ int ii; -+ if( p ){ -+ for(ii=0; ii<p->nVertex; ii++){ -+ x0 = p->a[ii*2]; -+ y0 = p->a[ii*2+1]; -+ x1 = (GeoCoord)(A*x0 + B*y0 + E); -+ y1 = (GeoCoord)(C*x0 + D*y0 + F); -+ p->a[ii*2] = x1; -+ p->a[ii*2+1] = y1; -+ } -+ sqlite3_result_blob(context, p->hdr, -+ 4+8*p->nVertex, SQLITE_TRANSIENT); -+ sqlite3_free(p); -+ } -+} -+ -+/* -+** Compute the area enclosed by the polygon. -+** -+** This routine can also be used to detect polygons that rotate in -+** the wrong direction. Polygons are suppose to be counter-clockwise (CCW). -+** This routine returns a negative value for clockwise (CW) polygons. -+*/ -+static double geopolyArea(GeoPoly *p){ -+ double rArea = 0.0; -+ int ii; -+ for(ii=0; ii<p->nVertex-1; ii++){ -+ rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */ -+ * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */ -+ * 0.5; -+ } -+ rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */ -+ * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */ -+ * 0.5; -+ return rArea; -+} -+ -+/* -+** Implementation of the geopoly_area(X) function. -+** -+** If the input is a well-formed Geopoly BLOB then return the area -+** enclosed by the polygon. If the polygon circulates clockwise instead -+** of counterclockwise (as it should) then return the negative of the -+** enclosed area. Otherwise return NULL. -+*/ -+static void geopolyAreaFunc( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); -+ if( p ){ -+ sqlite3_result_double(context, geopolyArea(p)); -+ sqlite3_free(p); -+ } -+} -+ -+/* -+** Implementation of the geopoly_ccw(X) function. -+** -+** If the rotation of polygon X is clockwise (incorrect) instead of -+** counter-clockwise (the correct winding order according to RFC7946) -+** then reverse the order of the vertexes in polygon X. -+** -+** In other words, this routine returns a CCW polygon regardless of the -+** winding order of its input. -+** -+** Use this routine to sanitize historical inputs that that sometimes -+** contain polygons that wind in the wrong direction. -+*/ -+static void geopolyCcwFunc( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); -+ if( p ){ -+ if( geopolyArea(p)<0.0 ){ -+ int ii, jj; -+ for(ii=2, jj=p->nVertex*2 - 2; ii<jj; ii+=2, jj-=2){ -+ GeoCoord t = p->a[ii]; -+ p->a[ii] = p->a[jj]; -+ p->a[jj] = t; -+ t = p->a[ii+1]; -+ p->a[ii+1] = p->a[jj+1]; -+ p->a[jj+1] = t; -+ } -+ } -+ sqlite3_result_blob(context, p->hdr, -+ 4+8*p->nVertex, SQLITE_TRANSIENT); -+ sqlite3_free(p); -+ } -+} -+ -+#define GEOPOLY_PI 3.1415926535897932385 -+ -+/* Fast approximation for sine(X) for X between -0.5*pi and 2*pi -+*/ -+static double geopolySine(double r){ -+ assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI ); -+ if( r>=1.5*GEOPOLY_PI ){ -+ r -= 2.0*GEOPOLY_PI; -+ } -+ if( r>=0.5*GEOPOLY_PI ){ -+ return -geopolySine(r-GEOPOLY_PI); -+ }else{ -+ double r2 = r*r; -+ double r3 = r2*r; -+ double r5 = r3*r2; -+ return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5; -+ } -+} -+ -+/* -+** Function: geopoly_regular(X,Y,R,N) -+** -+** Construct a simple, convex, regular polygon centered at X, Y -+** with circumradius R and with N sides. -+*/ -+static void geopolyRegularFunc( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ double x = sqlite3_value_double(argv[0]); -+ double y = sqlite3_value_double(argv[1]); -+ double r = sqlite3_value_double(argv[2]); -+ int n = sqlite3_value_int(argv[3]); -+ int i; -+ GeoPoly *p; -+ -+ if( n<3 || r<=0.0 ) return; -+ if( n>1000 ) n = 1000; -+ p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) ); -+ if( p==0 ){ -+ sqlite3_result_error_nomem(context); -+ return; -+ } -+ i = 1; -+ p->hdr[0] = *(unsigned char*)&i; -+ p->hdr[1] = 0; -+ p->hdr[2] = (n>>8)&0xff; -+ p->hdr[3] = n&0xff; -+ for(i=0; i<n; i++){ -+ double rAngle = 2.0*GEOPOLY_PI*i/n; -+ p->a[i*2] = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI); -+ p->a[i*2+1] = y + r*geopolySine(rAngle); -+ } -+ sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT); -+ sqlite3_free(p); -+} -+ -+/* -+** If pPoly is a polygon, compute its bounding box. Then: -+** -+** (1) if aCoord!=0 store the bounding box in aCoord, returning NULL -+** (2) otherwise, compute a GeoPoly for the bounding box and return the -+** new GeoPoly -+** -+** If pPoly is NULL but aCoord is not NULL, then compute a new GeoPoly from -+** the bounding box in aCoord and return a pointer to that GeoPoly. -+*/ -+static GeoPoly *geopolyBBox( -+ sqlite3_context *context, /* For recording the error */ -+ sqlite3_value *pPoly, /* The polygon */ -+ RtreeCoord *aCoord, /* Results here */ -+ int *pRc /* Error code here */ -+){ -+ GeoPoly *pOut = 0; -+ GeoPoly *p; -+ float mnX, mxX, mnY, mxY; -+ if( pPoly==0 && aCoord!=0 ){ -+ p = 0; -+ mnX = aCoord[0].f; -+ mxX = aCoord[1].f; -+ mnY = aCoord[2].f; -+ mxY = aCoord[3].f; -+ goto geopolyBboxFill; -+ }else{ -+ p = geopolyFuncParam(context, pPoly, pRc); -+ } -+ if( p ){ -+ int ii; -+ mnX = mxX = p->a[0]; -+ mnY = mxY = p->a[1]; -+ for(ii=1; ii<p->nVertex; ii++){ -+ double r = p->a[ii*2]; -+ if( r<mnX ) mnX = (float)r; -+ else if( r>mxX ) mxX = (float)r; -+ r = p->a[ii*2+1]; -+ if( r<mnY ) mnY = (float)r; -+ else if( r>mxY ) mxY = (float)r; -+ } -+ if( pRc ) *pRc = SQLITE_OK; -+ if( aCoord==0 ){ -+ geopolyBboxFill: -+ pOut = sqlite3_realloc(p, GEOPOLY_SZ(4)); -+ if( pOut==0 ){ -+ sqlite3_free(p); -+ if( context ) sqlite3_result_error_nomem(context); -+ if( pRc ) *pRc = SQLITE_NOMEM; -+ return 0; -+ } -+ pOut->nVertex = 4; -+ ii = 1; -+ pOut->hdr[0] = *(unsigned char*)ⅈ -+ pOut->hdr[1] = 0; -+ pOut->hdr[2] = 0; -+ pOut->hdr[3] = 4; -+ pOut->a[0] = mnX; -+ pOut->a[1] = mnY; -+ pOut->a[2] = mxX; -+ pOut->a[3] = mnY; -+ pOut->a[4] = mxX; -+ pOut->a[5] = mxY; -+ pOut->a[6] = mnX; -+ pOut->a[7] = mxY; -+ }else{ -+ sqlite3_free(p); -+ aCoord[0].f = mnX; -+ aCoord[1].f = mxX; -+ aCoord[2].f = mnY; -+ aCoord[3].f = mxY; -+ } -+ } -+ return pOut; -+} -+ -+/* -+** Implementation of the geopoly_bbox(X) SQL function. -+*/ -+static void geopolyBBoxFunc( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ GeoPoly *p = geopolyBBox(context, argv[0], 0, 0); -+ if( p ){ -+ sqlite3_result_blob(context, p->hdr, -+ 4+8*p->nVertex, SQLITE_TRANSIENT); -+ sqlite3_free(p); -+ } -+} -+ -+/* -+** State vector for the geopoly_group_bbox() aggregate function. -+*/ -+typedef struct GeoBBox GeoBBox; -+struct GeoBBox { -+ int isInit; -+ RtreeCoord a[4]; -+}; -+ -+ -+/* -+** Implementation of the geopoly_group_bbox(X) aggregate SQL function. -+*/ -+static void geopolyBBoxStep( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ RtreeCoord a[4]; -+ int rc = SQLITE_OK; -+ (void)geopolyBBox(context, argv[0], a, &rc); -+ if( rc==SQLITE_OK ){ -+ GeoBBox *pBBox; -+ pBBox = (GeoBBox*)sqlite3_aggregate_context(context, sizeof(*pBBox)); -+ if( pBBox==0 ) return; -+ if( pBBox->isInit==0 ){ -+ pBBox->isInit = 1; -+ memcpy(pBBox->a, a, sizeof(RtreeCoord)*4); -+ }else{ -+ if( a[0].f < pBBox->a[0].f ) pBBox->a[0] = a[0]; -+ if( a[1].f > pBBox->a[1].f ) pBBox->a[1] = a[1]; -+ if( a[2].f < pBBox->a[2].f ) pBBox->a[2] = a[2]; -+ if( a[3].f > pBBox->a[3].f ) pBBox->a[3] = a[3]; -+ } -+ } -+} -+static void geopolyBBoxFinal( -+ sqlite3_context *context -+){ -+ GeoPoly *p; -+ GeoBBox *pBBox; -+ pBBox = (GeoBBox*)sqlite3_aggregate_context(context, 0); -+ if( pBBox==0 ) return; -+ p = geopolyBBox(context, 0, pBBox->a, 0); -+ if( p ){ -+ sqlite3_result_blob(context, p->hdr, -+ 4+8*p->nVertex, SQLITE_TRANSIENT); -+ sqlite3_free(p); -+ } -+} -+ -+ -+/* -+** Determine if point (x0,y0) is beneath line segment (x1,y1)->(x2,y2). -+** Returns: -+** -+** +2 x0,y0 is on the line segement -+** -+** +1 x0,y0 is beneath line segment -+** -+** 0 x0,y0 is not on or beneath the line segment or the line segment -+** is vertical and x0,y0 is not on the line segment -+** -+** The left-most coordinate min(x1,x2) is not considered to be part of -+** the line segment for the purposes of this analysis. -+*/ -+static int pointBeneathLine( -+ double x0, double y0, -+ double x1, double y1, -+ double x2, double y2 -+){ -+ double y; -+ if( x0==x1 && y0==y1 ) return 2; -+ if( x1<x2 ){ -+ if( x0<=x1 || x0>x2 ) return 0; -+ }else if( x1>x2 ){ -+ if( x0<=x2 || x0>x1 ) return 0; -+ }else{ -+ /* Vertical line segment */ -+ if( x0!=x1 ) return 0; -+ if( y0<y1 && y0<y2 ) return 0; -+ if( y0>y1 && y0>y2 ) return 0; -+ return 2; -+ } -+ y = y1 + (y2-y1)*(x0-x1)/(x2-x1); -+ if( y0==y ) return 2; -+ if( y0<y ) return 1; -+ return 0; -+} -+ -+/* -+** SQL function: geopoly_contains_point(P,X,Y) -+** -+** Return +2 if point X,Y is within polygon P. -+** Return +1 if point X,Y is on the polygon boundary. -+** Return 0 if point X,Y is outside the polygon -+*/ -+static void geopolyContainsPointFunc( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); -+ double x0 = sqlite3_value_double(argv[1]); -+ double y0 = sqlite3_value_double(argv[2]); -+ int v = 0; -+ int cnt = 0; -+ int ii; -+ if( p1==0 ) return; -+ for(ii=0; ii<p1->nVertex-1; ii++){ -+ v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1], -+ p1->a[ii*2+2],p1->a[ii*2+3]); -+ if( v==2 ) break; -+ cnt += v; -+ } -+ if( v!=2 ){ -+ v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1], -+ p1->a[0],p1->a[1]); -+ } -+ if( v==2 ){ -+ sqlite3_result_int(context, 1); -+ }else if( ((v+cnt)&1)==0 ){ -+ sqlite3_result_int(context, 0); -+ }else{ -+ sqlite3_result_int(context, 2); -+ } -+ sqlite3_free(p1); -+} -+ -+/* Forward declaration */ -+static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2); -+ -+/* -+** SQL function: geopoly_within(P1,P2) -+** -+** Return +2 if P1 and P2 are the same polygon -+** Return +1 if P2 is contained within P1 -+** Return 0 if any part of P2 is on the outside of P1 -+** -+*/ -+static void geopolyWithinFunc( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); -+ GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); -+ if( p1 && p2 ){ -+ int x = geopolyOverlap(p1, p2); -+ if( x<0 ){ -+ sqlite3_result_error_nomem(context); -+ }else{ -+ sqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0); -+ } -+ } -+ sqlite3_free(p1); -+ sqlite3_free(p2); -+} -+ -+/* Objects used by the overlap algorihm. */ -+typedef struct GeoEvent GeoEvent; -+typedef struct GeoSegment GeoSegment; -+typedef struct GeoOverlap GeoOverlap; -+struct GeoEvent { -+ double x; /* X coordinate at which event occurs */ -+ int eType; /* 0 for ADD, 1 for REMOVE */ -+ GeoSegment *pSeg; /* The segment to be added or removed */ -+ GeoEvent *pNext; /* Next event in the sorted list */ -+}; -+struct GeoSegment { -+ double C, B; /* y = C*x + B */ -+ double y; /* Current y value */ -+ float y0; /* Initial y value */ -+ unsigned char side; /* 1 for p1, 2 for p2 */ -+ unsigned int idx; /* Which segment within the side */ -+ GeoSegment *pNext; /* Next segment in a list sorted by y */ -+}; -+struct GeoOverlap { -+ GeoEvent *aEvent; /* Array of all events */ -+ GeoSegment *aSegment; /* Array of all segments */ -+ int nEvent; /* Number of events */ -+ int nSegment; /* Number of segments */ -+}; -+ -+/* -+** Add a single segment and its associated events. -+*/ -+static void geopolyAddOneSegment( -+ GeoOverlap *p, -+ GeoCoord x0, -+ GeoCoord y0, -+ GeoCoord x1, -+ GeoCoord y1, -+ unsigned char side, -+ unsigned int idx -+){ -+ GeoSegment *pSeg; -+ GeoEvent *pEvent; -+ if( x0==x1 ) return; /* Ignore vertical segments */ -+ if( x0>x1 ){ -+ GeoCoord t = x0; -+ x0 = x1; -+ x1 = t; -+ t = y0; -+ y0 = y1; -+ y1 = t; -+ } -+ pSeg = p->aSegment + p->nSegment; -+ p->nSegment++; -+ pSeg->C = (y1-y0)/(x1-x0); -+ pSeg->B = y1 - x1*pSeg->C; -+ pSeg->y0 = y0; -+ pSeg->side = side; -+ pSeg->idx = idx; -+ pEvent = p->aEvent + p->nEvent; -+ p->nEvent++; -+ pEvent->x = x0; -+ pEvent->eType = 0; -+ pEvent->pSeg = pSeg; -+ pEvent = p->aEvent + p->nEvent; -+ p->nEvent++; -+ pEvent->x = x1; -+ pEvent->eType = 1; -+ pEvent->pSeg = pSeg; -+} -+ -+ -+ -+/* -+** Insert all segments and events for polygon pPoly. -+*/ -+static void geopolyAddSegments( -+ GeoOverlap *p, /* Add segments to this Overlap object */ -+ GeoPoly *pPoly, /* Take all segments from this polygon */ -+ unsigned char side /* The side of pPoly */ -+){ -+ unsigned int i; -+ GeoCoord *x; -+ for(i=0; i<(unsigned)pPoly->nVertex-1; i++){ -+ x = pPoly->a + (i*2); -+ geopolyAddOneSegment(p, x[0], x[1], x[2], x[3], side, i); -+ } -+ x = pPoly->a + (i*2); -+ geopolyAddOneSegment(p, x[0], x[1], pPoly->a[0], pPoly->a[1], side, i); -+} -+ -+/* -+** Merge two lists of sorted events by X coordinate -+*/ -+static GeoEvent *geopolyEventMerge(GeoEvent *pLeft, GeoEvent *pRight){ -+ GeoEvent head, *pLast; -+ head.pNext = 0; -+ pLast = &head; -+ while( pRight && pLeft ){ -+ if( pRight->x <= pLeft->x ){ -+ pLast->pNext = pRight; -+ pLast = pRight; -+ pRight = pRight->pNext; -+ }else{ -+ pLast->pNext = pLeft; -+ pLast = pLeft; -+ pLeft = pLeft->pNext; -+ } -+ } -+ pLast->pNext = pRight ? pRight : pLeft; -+ return head.pNext; -+} -+ -+/* -+** Sort an array of nEvent event objects into a list. -+*/ -+static GeoEvent *geopolySortEventsByX(GeoEvent *aEvent, int nEvent){ -+ int mx = 0; -+ int i, j; -+ GeoEvent *p; -+ GeoEvent *a[50]; -+ for(i=0; i<nEvent; i++){ -+ p = &aEvent[i]; -+ p->pNext = 0; -+ for(j=0; j<mx && a[j]; j++){ -+ p = geopolyEventMerge(a[j], p); -+ a[j] = 0; -+ } -+ a[j] = p; -+ if( j>=mx ) mx = j+1; -+ } -+ p = 0; -+ for(i=0; i<mx; i++){ -+ p = geopolyEventMerge(a[i], p); -+ } -+ return p; -+} -+ -+/* -+** Merge two lists of sorted segments by Y, and then by C. -+*/ -+static GeoSegment *geopolySegmentMerge(GeoSegment *pLeft, GeoSegment *pRight){ -+ GeoSegment head, *pLast; -+ head.pNext = 0; -+ pLast = &head; -+ while( pRight && pLeft ){ -+ double r = pRight->y - pLeft->y; -+ if( r==0.0 ) r = pRight->C - pLeft->C; -+ if( r<0.0 ){ -+ pLast->pNext = pRight; -+ pLast = pRight; -+ pRight = pRight->pNext; -+ }else{ -+ pLast->pNext = pLeft; -+ pLast = pLeft; -+ pLeft = pLeft->pNext; -+ } -+ } -+ pLast->pNext = pRight ? pRight : pLeft; -+ return head.pNext; -+} -+ -+/* -+** Sort a list of GeoSegments in order of increasing Y and in the event of -+** a tie, increasing C (slope). -+*/ -+static GeoSegment *geopolySortSegmentsByYAndC(GeoSegment *pList){ -+ int mx = 0; -+ int i; -+ GeoSegment *p; -+ GeoSegment *a[50]; -+ while( pList ){ -+ p = pList; -+ pList = pList->pNext; -+ p->pNext = 0; -+ for(i=0; i<mx && a[i]; i++){ -+ p = geopolySegmentMerge(a[i], p); -+ a[i] = 0; -+ } -+ a[i] = p; -+ if( i>=mx ) mx = i+1; -+ } -+ p = 0; -+ for(i=0; i<mx; i++){ -+ p = geopolySegmentMerge(a[i], p); -+ } -+ return p; -+} -+ -+/* -+** Determine the overlap between two polygons -+*/ -+static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){ -+ int nVertex = p1->nVertex + p2->nVertex + 2; -+ GeoOverlap *p; -+ int nByte; -+ GeoEvent *pThisEvent; -+ double rX; -+ int rc = 0; -+ int needSort = 0; -+ GeoSegment *pActive = 0; -+ GeoSegment *pSeg; -+ unsigned char aOverlap[4]; -+ -+ nByte = sizeof(GeoEvent)*nVertex*2 -+ + sizeof(GeoSegment)*nVertex -+ + sizeof(GeoOverlap); -+ p = sqlite3_malloc( nByte ); -+ if( p==0 ) return -1; -+ p->aEvent = (GeoEvent*)&p[1]; -+ p->aSegment = (GeoSegment*)&p->aEvent[nVertex*2]; -+ p->nEvent = p->nSegment = 0; -+ geopolyAddSegments(p, p1, 1); -+ geopolyAddSegments(p, p2, 2); -+ pThisEvent = geopolySortEventsByX(p->aEvent, p->nEvent); -+ rX = pThisEvent->x==0.0 ? -1.0 : 0.0; -+ memset(aOverlap, 0, sizeof(aOverlap)); -+ while( pThisEvent ){ -+ if( pThisEvent->x!=rX ){ -+ GeoSegment *pPrev = 0; -+ int iMask = 0; -+ GEODEBUG(("Distinct X: %g\n", pThisEvent->x)); -+ rX = pThisEvent->x; -+ if( needSort ){ -+ GEODEBUG(("SORT\n")); -+ pActive = geopolySortSegmentsByYAndC(pActive); -+ needSort = 0; -+ } -+ for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ -+ if( pPrev ){ -+ if( pPrev->y!=pSeg->y ){ -+ GEODEBUG(("MASK: %d\n", iMask)); -+ aOverlap[iMask] = 1; -+ } -+ } -+ iMask ^= pSeg->side; -+ pPrev = pSeg; -+ } -+ pPrev = 0; -+ for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ -+ double y = pSeg->C*rX + pSeg->B; -+ GEODEBUG(("Segment %d.%d %g->%g\n", pSeg->side, pSeg->idx, pSeg->y, y)); -+ pSeg->y = y; -+ if( pPrev ){ -+ if( pPrev->y>pSeg->y && pPrev->side!=pSeg->side ){ -+ rc = 1; -+ GEODEBUG(("Crossing: %d.%d and %d.%d\n", -+ pPrev->side, pPrev->idx, -+ pSeg->side, pSeg->idx)); -+ goto geopolyOverlapDone; -+ }else if( pPrev->y!=pSeg->y ){ -+ GEODEBUG(("MASK: %d\n", iMask)); -+ aOverlap[iMask] = 1; -+ } -+ } -+ iMask ^= pSeg->side; -+ pPrev = pSeg; -+ } -+ } -+ GEODEBUG(("%s %d.%d C=%g B=%g\n", -+ pThisEvent->eType ? "RM " : "ADD", -+ pThisEvent->pSeg->side, pThisEvent->pSeg->idx, -+ pThisEvent->pSeg->C, -+ pThisEvent->pSeg->B)); -+ if( pThisEvent->eType==0 ){ -+ /* Add a segment */ -+ pSeg = pThisEvent->pSeg; -+ pSeg->y = pSeg->y0; -+ pSeg->pNext = pActive; -+ pActive = pSeg; -+ needSort = 1; -+ }else{ -+ /* Remove a segment */ -+ if( pActive==pThisEvent->pSeg ){ -+ pActive = pActive->pNext; -+ }else{ -+ for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ -+ if( pSeg->pNext==pThisEvent->pSeg ){ -+ pSeg->pNext = pSeg->pNext->pNext; -+ break; -+ } -+ } -+ } -+ } -+ pThisEvent = pThisEvent->pNext; -+ } -+ if( aOverlap[3]==0 ){ -+ rc = 0; -+ }else if( aOverlap[1]!=0 && aOverlap[2]==0 ){ -+ rc = 3; -+ }else if( aOverlap[1]==0 && aOverlap[2]!=0 ){ -+ rc = 2; -+ }else if( aOverlap[1]==0 && aOverlap[2]==0 ){ -+ rc = 4; -+ }else{ -+ rc = 1; -+ } -+ -+geopolyOverlapDone: -+ sqlite3_free(p); -+ return rc; -+} -+ -+/* -+** SQL function: geopoly_overlap(P1,P2) -+** -+** Determine whether or not P1 and P2 overlap. Return value: -+** -+** 0 The two polygons are disjoint -+** 1 They overlap -+** 2 P1 is completely contained within P2 -+** 3 P2 is completely contained within P1 -+** 4 P1 and P2 are the same polygon -+** NULL Either P1 or P2 or both are not valid polygons -+*/ -+static void geopolyOverlapFunc( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+ GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); -+ GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); -+ if( p1 && p2 ){ -+ int x = geopolyOverlap(p1, p2); -+ if( x<0 ){ -+ sqlite3_result_error_nomem(context); -+ }else{ -+ sqlite3_result_int(context, x); -+ } -+ } -+ sqlite3_free(p1); -+ sqlite3_free(p2); -+} -+ -+/* -+** Enable or disable debugging output -+*/ -+static void geopolyDebugFunc( -+ sqlite3_context *context, -+ int argc, -+ sqlite3_value **argv -+){ -+#ifdef GEOPOLY_ENABLE_DEBUG -+ geo_debug = sqlite3_value_int(argv[0]); -+#endif -+} -+ -+/* -+** This function is the implementation of both the xConnect and xCreate -+** methods of the geopoly virtual table. -+** -+** argv[0] -> module name -+** argv[1] -> database name -+** argv[2] -> table name -+** argv[...] -> column names... -+*/ -+static int geopolyInit( -+ sqlite3 *db, /* Database connection */ -+ void *pAux, /* One of the RTREE_COORD_* constants */ -+ int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */ -+ sqlite3_vtab **ppVtab, /* OUT: New virtual table */ -+ char **pzErr, /* OUT: Error message, if any */ -+ int isCreate /* True for xCreate, false for xConnect */ -+){ -+ int rc = SQLITE_OK; -+ Rtree *pRtree; -+ int nDb; /* Length of string argv[1] */ -+ int nName; /* Length of string argv[2] */ -+ sqlite3_str *pSql; -+ char *zSql; -+ int ii; -+ -+ sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); -+ -+ /* Allocate the sqlite3_vtab structure */ -+ nDb = (int)strlen(argv[1]); -+ nName = (int)strlen(argv[2]); -+ pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2); -+ if( !pRtree ){ -+ return SQLITE_NOMEM; -+ } -+ memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2); -+ pRtree->nBusy = 1; -+ pRtree->base.pModule = &rtreeModule; -+ pRtree->zDb = (char *)&pRtree[1]; -+ pRtree->zName = &pRtree->zDb[nDb+1]; -+ pRtree->eCoordType = RTREE_COORD_REAL32; -+ pRtree->nDim = 2; -+ pRtree->nDim2 = 4; -+ memcpy(pRtree->zDb, argv[1], nDb); -+ memcpy(pRtree->zName, argv[2], nName); -+ -+ -+ /* Create/Connect to the underlying relational database schema. If -+ ** that is successful, call sqlite3_declare_vtab() to configure -+ ** the r-tree table schema. -+ */ -+ pSql = sqlite3_str_new(db); -+ sqlite3_str_appendf(pSql, "CREATE TABLE x(_shape"); -+ pRtree->nAux = 1; /* Add one for _shape */ -+ pRtree->nAuxNotNull = 1; /* The _shape column is always not-null */ -+ for(ii=3; ii<argc; ii++){ -+ pRtree->nAux++; -+ sqlite3_str_appendf(pSql, ",%s", argv[ii]); -+ } -+ sqlite3_str_appendf(pSql, ");"); -+ zSql = sqlite3_str_finish(pSql); -+ if( !zSql ){ -+ rc = SQLITE_NOMEM; -+ }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){ -+ *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); -+ } -+ sqlite3_free(zSql); -+ if( rc ) goto geopolyInit_fail; -+ pRtree->nBytesPerCell = 8 + pRtree->nDim2*4; -+ -+ /* Figure out the node size to use. */ -+ rc = getNodeSize(db, pRtree, isCreate, pzErr); -+ if( rc ) goto geopolyInit_fail; -+ rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate); -+ if( rc ){ -+ *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); -+ goto geopolyInit_fail; -+ } -+ -+ *ppVtab = (sqlite3_vtab *)pRtree; -+ return SQLITE_OK; -+ -+geopolyInit_fail: -+ if( rc==SQLITE_OK ) rc = SQLITE_ERROR; -+ assert( *ppVtab==0 ); -+ assert( pRtree->nBusy==1 ); -+ rtreeRelease(pRtree); -+ return rc; -+} -+ -+ -+/* -+** GEOPOLY virtual table module xCreate method. -+*/ -+static int geopolyCreate( -+ sqlite3 *db, -+ void *pAux, -+ int argc, const char *const*argv, -+ sqlite3_vtab **ppVtab, -+ char **pzErr -+){ -+ return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 1); -+} -+ -+/* -+** GEOPOLY virtual table module xConnect method. -+*/ -+static int geopolyConnect( -+ sqlite3 *db, -+ void *pAux, -+ int argc, const char *const*argv, -+ sqlite3_vtab **ppVtab, -+ char **pzErr -+){ -+ return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 0); -+} -+ -+ -+/* -+** GEOPOLY virtual table module xFilter method. -+** -+** Query plans: -+** -+** 1 rowid lookup -+** 2 search for objects overlapping the same bounding box -+** that contains polygon argv[0] -+** 3 search for objects overlapping the same bounding box -+** that contains polygon argv[0] -+** 4 full table scan -+*/ -+static int geopolyFilter( -+ sqlite3_vtab_cursor *pVtabCursor, /* The cursor to initialize */ -+ int idxNum, /* Query plan */ -+ const char *idxStr, /* Not Used */ -+ int argc, sqlite3_value **argv /* Parameters to the query plan */ -+){ -+ Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; -+ RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; -+ 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; -+ -+ pCsr->iStrategy = idxNum; -+ if( idxNum==1 ){ -+ /* Special case - lookup by rowid. */ -+ RtreeNode *pLeaf; /* Leaf on which the required cell resides */ -+ RtreeSearchPoint *p; /* Search point for the leaf */ -+ i64 iRowid = sqlite3_value_int64(argv[0]); -+ i64 iNode = 0; -+ rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); -+ if( rc==SQLITE_OK && pLeaf!=0 ){ -+ p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0); -+ assert( p!=0 ); /* Always returns pCsr->sPoint */ -+ pCsr->aNode[0] = pLeaf; -+ p->id = iNode; -+ p->eWithin = PARTLY_WITHIN; -+ rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); -+ p->iCell = (u8)iCell; -+ RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:"); -+ }else{ -+ pCsr->atEOF = 1; -+ } -+ }else{ -+ /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array -+ ** with the configured constraints. -+ */ -+ rc = nodeAcquire(pRtree, 1, 0, &pRoot); -+ if( rc==SQLITE_OK && idxNum<=3 ){ -+ RtreeCoord bbox[4]; -+ RtreeConstraint *p; -+ assert( argc==1 ); -+ geopolyBBox(0, argv[0], bbox, &rc); -+ if( rc ){ -+ goto geopoly_filter_end; -+ } -+ pCsr->aConstraint = p = sqlite3_malloc(sizeof(RtreeConstraint)*4); -+ pCsr->nConstraint = 4; -+ if( p==0 ){ -+ rc = SQLITE_NOMEM; -+ }else{ -+ memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*4); -+ memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1)); -+ if( idxNum==2 ){ -+ /* Overlap query */ -+ p->op = 'B'; -+ p->iCoord = 0; -+ p->u.rValue = bbox[1].f; -+ p++; -+ p->op = 'D'; -+ p->iCoord = 1; -+ p->u.rValue = bbox[0].f; -+ p++; -+ p->op = 'B'; -+ p->iCoord = 2; -+ p->u.rValue = bbox[3].f; -+ p++; -+ p->op = 'D'; -+ p->iCoord = 3; -+ p->u.rValue = bbox[2].f; -+ }else{ -+ /* Within query */ -+ p->op = 'D'; -+ p->iCoord = 0; -+ p->u.rValue = bbox[0].f; -+ p++; -+ p->op = 'B'; -+ p->iCoord = 1; -+ p->u.rValue = bbox[1].f; -+ p++; -+ p->op = 'D'; -+ p->iCoord = 2; -+ p->u.rValue = bbox[2].f; -+ p++; -+ p->op = 'B'; -+ p->iCoord = 3; -+ p->u.rValue = bbox[3].f; -+ } -+ } -+ } -+ if( rc==SQLITE_OK ){ -+ RtreeSearchPoint *pNew; -+ pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1)); -+ if( pNew==0 ){ -+ rc = SQLITE_NOMEM; -+ goto geopoly_filter_end; -+ } -+ pNew->id = 1; -+ pNew->iCell = 0; -+ pNew->eWithin = PARTLY_WITHIN; -+ assert( pCsr->bPoint==1 ); -+ pCsr->aNode[0] = pRoot; -+ pRoot = 0; -+ RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:"); -+ rc = rtreeStepToLeaf(pCsr); -+ } -+ } -+ -+geopoly_filter_end: -+ nodeRelease(pRtree, pRoot); -+ rtreeRelease(pRtree); -+ return rc; -+} -+ -+/* -+** Rtree virtual table module xBestIndex method. There are three -+** table scan strategies to choose from (in order from most to -+** least desirable): -+** -+** idxNum idxStr Strategy -+** ------------------------------------------------ -+** 1 "rowid" Direct lookup by rowid. -+** 2 "rtree" R-tree overlap query using geopoly_overlap() -+** 3 "rtree" R-tree within query using geopoly_within() -+** 4 "fullscan" full-table scan. -+** ------------------------------------------------ -+*/ -+static int geopolyBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ -+ int ii; -+ int iRowidTerm = -1; -+ int iFuncTerm = -1; -+ int idxNum = 0; -+ -+ for(ii=0; ii<pIdxInfo->nConstraint; ii++){ -+ struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; -+ if( !p->usable ) continue; -+ if( p->iColumn<0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ -+ iRowidTerm = ii; -+ break; -+ } -+ if( p->iColumn==0 && p->op>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){ -+ /* p->op==SQLITE_INDEX_CONSTRAINT_FUNCTION for geopoly_overlap() -+ ** p->op==(SQLITE_INDEX_CONTRAINT_FUNCTION+1) for geopoly_within(). -+ ** See geopolyFindFunction() */ -+ iFuncTerm = ii; -+ idxNum = p->op - SQLITE_INDEX_CONSTRAINT_FUNCTION + 2; -+ } -+ } -+ -+ if( iRowidTerm>=0 ){ -+ pIdxInfo->idxNum = 1; -+ pIdxInfo->idxStr = "rowid"; -+ pIdxInfo->aConstraintUsage[iRowidTerm].argvIndex = 1; -+ pIdxInfo->aConstraintUsage[iRowidTerm].omit = 1; -+ pIdxInfo->estimatedCost = 30.0; -+ pIdxInfo->estimatedRows = 1; -+ pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE; -+ return SQLITE_OK; -+ } -+ if( iFuncTerm>=0 ){ -+ pIdxInfo->idxNum = idxNum; -+ pIdxInfo->idxStr = "rtree"; -+ pIdxInfo->aConstraintUsage[iFuncTerm].argvIndex = 1; -+ pIdxInfo->aConstraintUsage[iFuncTerm].omit = 0; -+ pIdxInfo->estimatedCost = 300.0; -+ pIdxInfo->estimatedRows = 10; -+ return SQLITE_OK; -+ } -+ pIdxInfo->idxNum = 4; -+ pIdxInfo->idxStr = "fullscan"; -+ pIdxInfo->estimatedCost = 3000000.0; -+ pIdxInfo->estimatedRows = 100000; -+ return SQLITE_OK; -+} -+ -+ -+/* -+** GEOPOLY virtual table module xColumn method. -+*/ -+static int geopolyColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ -+ Rtree *pRtree = (Rtree *)cur->pVtab; -+ RtreeCursor *pCsr = (RtreeCursor *)cur; -+ RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); -+ int rc = SQLITE_OK; -+ RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); -+ -+ if( rc ) return rc; -+ if( p==0 ) return SQLITE_OK; -+ if( i==0 && sqlite3_vtab_nochange(ctx) ) return SQLITE_OK; -+ if( i<=pRtree->nAux ){ -+ if( !pCsr->bAuxValid ){ -+ if( pCsr->pReadAux==0 ){ -+ rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0, -+ &pCsr->pReadAux, 0); -+ if( rc ) return rc; -+ } -+ sqlite3_bind_int64(pCsr->pReadAux, 1, -+ nodeGetRowid(pRtree, pNode, p->iCell)); -+ rc = sqlite3_step(pCsr->pReadAux); -+ if( rc==SQLITE_ROW ){ -+ pCsr->bAuxValid = 1; -+ }else{ -+ sqlite3_reset(pCsr->pReadAux); -+ if( rc==SQLITE_DONE ) rc = SQLITE_OK; -+ return rc; -+ } -+ } -+ sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pReadAux, i+2)); -+ } -+ return SQLITE_OK; -+} -+ -+ -+/* -+** The xUpdate method for GEOPOLY module virtual tables. -+** -+** For DELETE: -+** -+** argv[0] = the rowid to be deleted -+** -+** For INSERT: -+** -+** argv[0] = SQL NULL -+** argv[1] = rowid to insert, or an SQL NULL to select automatically -+** argv[2] = _shape column -+** argv[3] = first application-defined column.... -+** -+** For UPDATE: -+** -+** argv[0] = rowid to modify. Never NULL -+** argv[1] = rowid after the change. Never NULL -+** argv[2] = new value for _shape -+** argv[3] = new value for first application-defined column.... -+*/ -+static int geopolyUpdate( -+ sqlite3_vtab *pVtab, -+ int nData, -+ sqlite3_value **aData, -+ sqlite_int64 *pRowid -+){ -+ Rtree *pRtree = (Rtree *)pVtab; -+ int rc = SQLITE_OK; -+ RtreeCell cell; /* New cell to insert if nData>1 */ -+ i64 oldRowid; /* The old rowid */ -+ int oldRowidValid; /* True if oldRowid is valid */ -+ i64 newRowid; /* The new rowid */ -+ int newRowidValid; /* True if newRowid is valid */ -+ int coordChange = 0; /* Change in coordinates */ -+ -+ if( pRtree->nNodeRef ){ -+ /* Unable to write to the btree while another cursor is reading from it, -+ ** since the write might do a rebalance which would disrupt the read -+ ** cursor. */ -+ return SQLITE_LOCKED_VTAB; -+ } -+ rtreeReference(pRtree); -+ assert(nData>=1); -+ -+ oldRowidValid = sqlite3_value_type(aData[0])!=SQLITE_NULL;; -+ oldRowid = oldRowidValid ? sqlite3_value_int64(aData[0]) : 0; -+ newRowidValid = nData>1 && sqlite3_value_type(aData[1])!=SQLITE_NULL; -+ newRowid = newRowidValid ? sqlite3_value_int64(aData[1]) : 0; -+ cell.iRowid = newRowid; -+ -+ if( nData>1 /* not a DELETE */ -+ && (!oldRowidValid /* INSERT */ -+ || !sqlite3_value_nochange(aData[2]) /* UPDATE _shape */ -+ || oldRowid!=newRowid) /* Rowid change */ -+ ){ -+ geopolyBBox(0, aData[2], cell.aCoord, &rc); -+ if( rc ){ -+ if( rc==SQLITE_ERROR ){ -+ pVtab->zErrMsg = -+ sqlite3_mprintf("_shape does not contain a valid polygon"); -+ } -+ goto geopoly_update_end; -+ } -+ coordChange = 1; -+ -+ /* If a rowid value was supplied, check if it is already present in -+ ** the table. If so, the constraint has failed. */ -+ if( newRowidValid && (!oldRowidValid || oldRowid!=newRowid) ){ -+ int steprc; -+ sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); -+ steprc = sqlite3_step(pRtree->pReadRowid); -+ rc = sqlite3_reset(pRtree->pReadRowid); -+ if( SQLITE_ROW==steprc ){ -+ if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){ -+ rc = rtreeDeleteRowid(pRtree, cell.iRowid); -+ }else{ -+ rc = rtreeConstraintError(pRtree, 0); -+ } -+ } -+ } -+ } -+ -+ /* If aData[0] is not an SQL NULL value, it is the rowid of a -+ ** record to delete from the r-tree table. The following block does -+ ** just that. -+ */ -+ if( rc==SQLITE_OK && (nData==1 || (coordChange && oldRowidValid)) ){ -+ rc = rtreeDeleteRowid(pRtree, oldRowid); -+ } -+ -+ /* If the aData[] array contains more than one element, elements -+ ** (aData[2]..aData[argc-1]) contain a new record to insert into -+ ** the r-tree structure. -+ */ -+ if( rc==SQLITE_OK && nData>1 && coordChange ){ -+ /* Insert the new record into the r-tree */ -+ RtreeNode *pLeaf = 0; -+ if( !newRowidValid ){ -+ rc = rtreeNewRowid(pRtree, &cell.iRowid); -+ } -+ *pRowid = cell.iRowid; -+ if( rc==SQLITE_OK ){ -+ rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf); -+ } -+ if( rc==SQLITE_OK ){ -+ int rc2; -+ pRtree->iReinsertHeight = -1; -+ rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); -+ rc2 = nodeRelease(pRtree, pLeaf); -+ if( rc==SQLITE_OK ){ -+ rc = rc2; -+ } -+ } -+ } -+ -+ /* Change the data */ -+ if( rc==SQLITE_OK && nData>1 ){ -+ sqlite3_stmt *pUp = pRtree->pWriteAux; -+ int jj; -+ int nChange = 0; -+ sqlite3_bind_int64(pUp, 1, cell.iRowid); -+ assert( pRtree->nAux>=1 ); -+ if( sqlite3_value_nochange(aData[2]) ){ -+ sqlite3_bind_null(pUp, 2); -+ }else{ -+ GeoPoly *p = 0; -+ if( sqlite3_value_type(aData[2])==SQLITE_TEXT -+ && (p = geopolyFuncParam(0, aData[2], &rc))!=0 -+ && rc==SQLITE_OK -+ ){ -+ sqlite3_bind_blob(pUp, 2, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); -+ }else{ -+ sqlite3_bind_value(pUp, 2, aData[2]); -+ } -+ sqlite3_free(p); -+ nChange = 1; -+ } -+ for(jj=1; jj<pRtree->nAux; jj++){ -+ nChange++; -+ sqlite3_bind_value(pUp, jj+2, aData[jj+2]); -+ } -+ if( nChange ){ -+ sqlite3_step(pUp); -+ rc = sqlite3_reset(pUp); -+ } -+ } -+ -+geopoly_update_end: -+ rtreeRelease(pRtree); -+ return rc; -+} -+ -+/* -+** Report that geopoly_overlap() is an overloaded function suitable -+** for use in xBestIndex. -+*/ -+static int geopolyFindFunction( -+ sqlite3_vtab *pVtab, -+ int nArg, -+ const char *zName, -+ void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), -+ void **ppArg -+){ -+ if( sqlite3_stricmp(zName, "geopoly_overlap")==0 ){ -+ *pxFunc = geopolyOverlapFunc; -+ *ppArg = 0; -+ return SQLITE_INDEX_CONSTRAINT_FUNCTION; -+ } -+ if( sqlite3_stricmp(zName, "geopoly_within")==0 ){ -+ *pxFunc = geopolyWithinFunc; -+ *ppArg = 0; -+ return SQLITE_INDEX_CONSTRAINT_FUNCTION+1; -+ } -+ return 0; -+} -+ -+ -+static sqlite3_module geopolyModule = { -+ 3, /* iVersion */ -+ geopolyCreate, /* xCreate - create a table */ -+ geopolyConnect, /* xConnect - connect to an existing table */ -+ geopolyBestIndex, /* xBestIndex - Determine search strategy */ -+ rtreeDisconnect, /* xDisconnect - Disconnect from a table */ -+ rtreeDestroy, /* xDestroy - Drop a table */ -+ rtreeOpen, /* xOpen - open a cursor */ -+ rtreeClose, /* xClose - close a cursor */ -+ geopolyFilter, /* xFilter - configure scan constraints */ -+ rtreeNext, /* xNext - advance a cursor */ -+ rtreeEof, /* xEof */ -+ geopolyColumn, /* xColumn - read data */ -+ rtreeRowid, /* xRowid - read data */ -+ geopolyUpdate, /* xUpdate - write data */ -+ rtreeBeginTransaction, /* xBegin - begin transaction */ -+ rtreeEndTransaction, /* xSync - sync transaction */ -+ rtreeEndTransaction, /* xCommit - commit transaction */ -+ rtreeEndTransaction, /* xRollback - rollback transaction */ -+ geopolyFindFunction, /* xFindFunction - function overloading */ -+ rtreeRename, /* xRename - rename the table */ -+ rtreeSavepoint, /* xSavepoint */ -+ 0, /* xRelease */ -+ 0, /* xRollbackTo */ -+ rtreeShadowName /* xShadowName */ -+}; -+ -+static int sqlite3_geopoly_init(sqlite3 *db){ -+ int rc = SQLITE_OK; -+ static const struct { -+ void (*xFunc)(sqlite3_context*,int,sqlite3_value**); -+ signed char nArg; -+ unsigned char bPure; -+ const char *zName; -+ } aFunc[] = { -+ { geopolyAreaFunc, 1, 1, "geopoly_area" }, -+ { geopolyBlobFunc, 1, 1, "geopoly_blob" }, -+ { geopolyJsonFunc, 1, 1, "geopoly_json" }, -+ { geopolySvgFunc, -1, 1, "geopoly_svg" }, -+ { geopolyWithinFunc, 2, 1, "geopoly_within" }, -+ { geopolyContainsPointFunc, 3, 1, "geopoly_contains_point" }, -+ { geopolyOverlapFunc, 2, 1, "geopoly_overlap" }, -+ { geopolyDebugFunc, 1, 0, "geopoly_debug" }, -+ { geopolyBBoxFunc, 1, 1, "geopoly_bbox" }, -+ { geopolyXformFunc, 7, 1, "geopoly_xform" }, -+ { geopolyRegularFunc, 4, 1, "geopoly_regular" }, -+ { geopolyCcwFunc, 1, 1, "geopoly_ccw" }, -+ }; -+ static const struct { -+ void (*xStep)(sqlite3_context*,int,sqlite3_value**); -+ void (*xFinal)(sqlite3_context*); -+ const char *zName; -+ } aAgg[] = { -+ { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" }, -+ }; -+ int i; -+ for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){ -+ int enc = aFunc[i].bPure ? SQLITE_UTF8|SQLITE_DETERMINISTIC : SQLITE_UTF8; -+ rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg, -+ enc, 0, -+ aFunc[i].xFunc, 0, 0); -+ } -+ for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){ -+ rc = sqlite3_create_function(db, aAgg[i].zName, 1, SQLITE_UTF8, 0, -+ 0, aAgg[i].xStep, aAgg[i].xFinal); -+ } -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3_create_module_v2(db, "geopoly", &geopolyModule, 0, 0); -+ } -+ return rc; -+} -+ -+/************** End of geopoly.c *********************************************/ -+/************** Continuing where we left off in rtree.c **********************/ -+#endif -+ -+/* - ** Register the r-tree module with database handle db. This creates the - ** virtual table module "rtree" and the debugging/analysis scalar - ** function "rtreenode". -@@ -168878,6 +185189,9 @@ - rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0); - } - if( rc==SQLITE_OK ){ -+ rc = sqlite3_create_function(db, "rtreecheck", -1, utf8, 0,rtreecheck, 0,0); -+ } -+ if( rc==SQLITE_OK ){ - #ifdef SQLITE_RTREE_INT_ONLY - void *c = (void *)RTREE_COORD_INT32; - #else -@@ -168889,6 +185203,11 @@ - void *c = (void *)RTREE_COORD_INT32; - rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0); - } -+#ifdef SQLITE_ENABLE_GEOPOLY -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3_geopoly_init(db); -+ } -+#endif - - return rc; - } -@@ -169063,7 +185382,9 @@ - ** provide case-independent matching. - */ - --#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) -+#if !defined(SQLITE_CORE) \ -+ || defined(SQLITE_ENABLE_ICU) \ -+ || defined(SQLITE_ENABLE_ICU_COLLATIONS) - - /* Include ICU headers */ - #include <unicode/utypes.h> -@@ -169081,6 +185402,26 @@ - #endif - - /* -+** This function is called when an ICU function called from within -+** the implementation of an SQL scalar function returns an error. -+** -+** The scalar function context passed as the first argument is -+** loaded with an error message based on the following two args. -+*/ -+static void icuFunctionError( -+ sqlite3_context *pCtx, /* SQLite scalar function context */ -+ const char *zName, /* Name of ICU function that failed */ -+ UErrorCode e /* Error code returned by ICU function */ -+){ -+ char zBuf[128]; -+ sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e)); -+ zBuf[127] = '\0'; -+ sqlite3_result_error(pCtx, zBuf, -1); -+} -+ -+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) -+ -+/* - ** Maximum length (in bytes) of the pattern in a LIKE or GLOB - ** operator. - */ -@@ -169137,8 +185478,8 @@ - const uint8_t *zString, /* The UTF-8 string to compare against */ - const UChar32 uEsc /* The escape character */ - ){ -- static const int MATCH_ONE = (UChar32)'_'; -- static const int MATCH_ALL = (UChar32)'%'; -+ static const uint32_t MATCH_ONE = (uint32_t)'_'; -+ static const uint32_t MATCH_ALL = (uint32_t)'%'; - - int prevEscape = 0; /* True if the previous character was uEsc */ - -@@ -169145,7 +185486,7 @@ - while( 1 ){ - - /* Read (and consume) the next character from the input pattern. */ -- UChar32 uPattern; -+ uint32_t uPattern; - SQLITE_ICU_READ_UTF8(zPattern, uPattern); - if( uPattern==0 ) break; - -@@ -169187,16 +185528,16 @@ - if( *zString==0 ) return 0; - SQLITE_ICU_SKIP_UTF8(zString); - -- }else if( !prevEscape && uPattern==uEsc){ -+ }else if( !prevEscape && uPattern==(uint32_t)uEsc){ - /* Case 3. */ - prevEscape = 1; - - }else{ - /* Case 4. */ -- UChar32 uString; -+ uint32_t uString; - SQLITE_ICU_READ_UTF8(zString, uString); -- uString = u_foldCase(uString, U_FOLD_CASE_DEFAULT); -- uPattern = u_foldCase(uPattern, U_FOLD_CASE_DEFAULT); -+ uString = (uint32_t)u_foldCase((UChar32)uString, U_FOLD_CASE_DEFAULT); -+ uPattern = (uint32_t)u_foldCase((UChar32)uPattern, U_FOLD_CASE_DEFAULT); - if( uString!=uPattern ){ - return 0; - } -@@ -169260,24 +185601,6 @@ - } - - /* --** This function is called when an ICU function called from within --** the implementation of an SQL scalar function returns an error. --** --** The scalar function context passed as the first argument is --** loaded with an error message based on the following two args. --*/ --static void icuFunctionError( -- sqlite3_context *pCtx, /* SQLite scalar function context */ -- const char *zName, /* Name of ICU function that failed */ -- UErrorCode e /* Error code returned by ICU function */ --){ -- char zBuf[128]; -- sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e)); -- zBuf[127] = '\0'; -- sqlite3_result_error(pCtx, zBuf, -1); --} -- --/* - ** Function to delete compiled regexp objects. Registered as - ** a destructor function with sqlite3_set_auxdata(). - */ -@@ -169442,6 +185765,8 @@ - assert( 0 ); /* Unreachable */ - } - -+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */ -+ - /* - ** Collation sequence destructor function. The pCtx argument points to - ** a UCollator structure previously allocated using ucol_open(). -@@ -169536,6 +185861,7 @@ - void (*xFunc)(sqlite3_context*,int,sqlite3_value**); - } scalars[] = { - {"icu_load_collation", 2, SQLITE_UTF8, 1, icuLoadCollation}, -+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) - {"regexp", 2, SQLITE_ANY|SQLITE_DETERMINISTIC, 0, icuRegexpFunc}, - {"lower", 1, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, - {"lower", 2, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, -@@ -169547,10 +185873,10 @@ - {"upper", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 1, icuCaseFunc16}, - {"like", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc}, - {"like", 3, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc}, -+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */ - }; - int rc = SQLITE_OK; - int i; -- - - for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){ - const struct IcuScalar *p = &scalars[i]; -@@ -170293,6 +186619,28 @@ - ); - - /* -+** Configure a limit for the amount of temp space that may be used by -+** the RBU handle passed as the first argument. The new limit is specified -+** in bytes by the second parameter. If it is positive, the limit is updated. -+** If the second parameter to this function is passed zero, then the limit -+** is removed entirely. If the second parameter is negative, the limit is -+** not modified (this is useful for querying the current limit). -+** -+** In all cases the returned value is the current limit in bytes (zero -+** indicates unlimited). -+** -+** If the temp space limit is exceeded during operation, an SQLITE_FULL -+** error is returned. -+*/ -+SQLITE_API sqlite3_int64 sqlite3rbu_temp_size_limit(sqlite3rbu*, sqlite3_int64); -+ -+/* -+** Return the current amount of temp file space, in bytes, currently used by -+** the RBU handle passed as the only argument. -+*/ -+SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu*); -+ -+/* - ** Internally, each RBU connection uses a separate SQLite database - ** connection to access the target and rbu update databases. This - ** API allows the application direct access to these database handles. -@@ -170418,7 +186766,7 @@ - ** table exists but is not correctly populated, the value of the *pnOne - ** output variable during stage 1 is undefined. - */ --SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int *pnTwo); -+SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int*pnTwo); - - /* - ** Obtain an indication as to the current stage of an RBU update or vacuum. -@@ -170528,6 +186876,13 @@ - /* Maximum number of prepared UPDATE statements held by this module */ - #define SQLITE_RBU_UPDATE_CACHESIZE 16 - -+/* Delta checksums disabled by default. Compile with -DRBU_ENABLE_DELTA_CKSUM -+** to enable checksum verification. -+*/ -+#ifndef RBU_ENABLE_DELTA_CKSUM -+# define RBU_ENABLE_DELTA_CKSUM 0 -+#endif -+ - /* - ** Swap two objects of type TYPE. - */ -@@ -170578,6 +186933,10 @@ - ** - ** RBU_STATE_OALSZ: - ** Valid if STAGE==1. The size in bytes of the *-oal file. -+** -+** RBU_STATE_DATATBL: -+** Only valid if STAGE==1. The RBU database name of the table -+** currently being read. - */ - #define RBU_STATE_STAGE 1 - #define RBU_STATE_TBL 2 -@@ -170588,6 +186947,7 @@ - #define RBU_STATE_COOKIE 7 - #define RBU_STATE_OALSZ 8 - #define RBU_STATE_PHASEONESTEP 9 -+#define RBU_STATE_DATATBL 10 - - #define RBU_STAGE_OAL 1 - #define RBU_STAGE_MOVE 2 -@@ -170630,6 +186990,7 @@ - struct RbuState { - int eStage; - char *zTbl; -+ char *zDataTbl; - char *zIdx; - i64 iWalCksum; - int nRow; -@@ -170803,6 +187164,8 @@ - int pgsz; - u8 *aBuf; - i64 iWalCksum; -+ i64 szTemp; /* Current size of all temp files in use */ -+ i64 szTempLimit; /* Total size limit for temp files */ - - /* Used in RBU vacuum mode only */ - int nRbu; /* Number of RBU VFS in the stack */ -@@ -170811,17 +187174,27 @@ - - /* - ** An rbu VFS is implemented using an instance of this structure. -+** -+** Variable pRbu is only non-NULL for automatically created RBU VFS objects. -+** It is NULL for RBU VFS objects created explicitly using -+** sqlite3rbu_create_vfs(). It is used to track the total amount of temp -+** space used by the RBU handle. - */ - struct rbu_vfs { - sqlite3_vfs base; /* rbu VFS shim methods */ - sqlite3_vfs *pRealVfs; /* Underlying VFS */ - sqlite3_mutex *mutex; /* Mutex to protect pMain */ -- rbu_file *pMain; /* Linked list of main db files */ -+ sqlite3rbu *pRbu; /* Owner RBU object */ -+ rbu_file *pMain; /* List of main db files */ -+ rbu_file *pMainRbu; /* List of main db files with pRbu!=0 */ - }; - - /* - ** Each file opened by an rbu VFS is represented by an instance of - ** the following structure. -+** -+** If this is a temporary file (pRbu!=0 && flags&DELETE_ON_CLOSE), variable -+** "sz" is set to the current size of the database file. - */ - struct rbu_file { - sqlite3_file base; /* sqlite3_file methods */ -@@ -170828,6 +187201,7 @@ - sqlite3_file *pReal; /* Underlying file handle */ - rbu_vfs *pRbuVfs; /* Pointer to the rbu_vfs object */ - sqlite3rbu *pRbu; /* Pointer to rbu object (rbu target only) */ -+ i64 sz; /* Size of file in bytes (temp only) */ - - int openFlags; /* Flags this file was opened with */ - u32 iCookie; /* Cookie value for main db files */ -@@ -170841,6 +187215,7 @@ - const char *zWal; /* Wal filename for this main db file */ - rbu_file *pWalFd; /* Wal file descriptor for this main db */ - rbu_file *pMainNext; /* Next MAIN_DB file */ -+ rbu_file *pMainRbuNext; /* Next MAIN_DB file with pRbu!=0 */ - }; - - /* -@@ -170890,6 +187265,7 @@ - return v; - } - -+#if RBU_ENABLE_DELTA_CKSUM - /* - ** Compute a 32-bit checksum on the N-byte buffer. Return the result. - */ -@@ -170924,6 +187300,7 @@ - } - return sum3; - } -+#endif - - /* - ** Apply a delta. -@@ -170954,7 +187331,7 @@ - ){ - unsigned int limit; - unsigned int total = 0; --#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST -+#if RBU_ENABLE_DELTA_CKSUM - char *zOrigOut = zOut; - #endif - -@@ -171009,7 +187386,7 @@ - case ';': { - zDelta++; lenDelta--; - zOut[0] = 0; --#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST -+#if RBU_ENABLE_DELTA_CKSUM - if( cnt!=rbuDeltaChecksum(zOrigOut, total) ){ - /* ERROR: bad checksum */ - return -1; -@@ -172217,7 +188594,7 @@ - int iCid = sqlite3_column_int(pXInfo, 1); - int bDesc = sqlite3_column_int(pXInfo, 3); - const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); -- zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %s", zCols, zComma, -+ zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %Q", zCols, zComma, - iCid, pIter->azTblType[iCid], zCollate - ); - zPk = rbuMPrintf(p, "%z%sc%d%s", zPk, zComma, iCid, bDesc?" DESC":""); -@@ -172278,7 +188655,7 @@ - ** "PRIMARY KEY" to the imposter table column declaration. */ - zPk = "PRIMARY KEY "; - } -- zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %s%s", -+ zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %Q%s", - zSql, zComma, zCol, pIter->azTblType[iCol], zPk, zColl, - (pIter->abNotNull[iCol] ? " NOT NULL" : "") - ); -@@ -172679,6 +189056,7 @@ - static void rbuFreeState(RbuState *p){ - if( p ){ - sqlite3_free(p->zTbl); -+ sqlite3_free(p->zDataTbl); - sqlite3_free(p->zIdx); - sqlite3_free(p); - } -@@ -172749,6 +189127,10 @@ - pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1); - break; - -+ case RBU_STATE_DATATBL: -+ pRet->zDataTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); -+ break; -+ - default: - rc = SQLITE_CORRUPT; - break; -@@ -173523,7 +189905,8 @@ - "(%d, %lld), " - "(%d, %lld), " - "(%d, %lld), " -- "(%d, %lld) ", -+ "(%d, %lld), " -+ "(%d, %Q) ", - p->zStateDb, - RBU_STATE_STAGE, eStage, - RBU_STATE_TBL, p->objiter.zTbl, -@@ -173533,7 +189916,8 @@ - RBU_STATE_CKPT, p->iWalCksum, - RBU_STATE_COOKIE, (i64)pFd->iCookie, - RBU_STATE_OALSZ, p->iOalSz, -- RBU_STATE_PHASEONESTEP, p->nPhaseOneStep -+ RBU_STATE_PHASEONESTEP, p->nPhaseOneStep, -+ RBU_STATE_DATATBL, p->objiter.zDataTbl - ) - ); - assert( pInsert==0 || rc==SQLITE_OK ); -@@ -173789,7 +190173,8 @@ - - while( rc==SQLITE_OK && pIter->zTbl && (pIter->bCleanup - || rbuStrCompare(pIter->zIdx, pState->zIdx) -- || rbuStrCompare(pIter->zTbl, pState->zTbl) -+ || (pState->zDataTbl==0 && rbuStrCompare(pIter->zTbl, pState->zTbl)) -+ || (pState->zDataTbl && rbuStrCompare(pIter->zDataTbl, pState->zDataTbl)) - )){ - rc = rbuObjIterNext(p, pIter); - } -@@ -173841,6 +190226,7 @@ - sqlite3_vfs *pVfs = sqlite3_vfs_find(zRnd); - assert( pVfs ); - p->zVfsName = pVfs->zName; -+ ((rbu_vfs*)pVfs)->pRbu = p; - } - } - -@@ -174213,6 +190599,7 @@ - /* Close the open database handle and VFS object. */ - sqlite3_close(p->dbRbu); - sqlite3_close(p->dbMain); -+ assert( p->szTemp==0 ); - rbuDeleteVfs(p); - sqlite3_free(p->aBuf); - sqlite3_free(p->aFrame); -@@ -174400,6 +190787,7 @@ - */ - - static void rbuUnlockShm(rbu_file *p){ -+ assert( p->openFlags & SQLITE_OPEN_MAIN_DB ); - if( p->pRbu ){ - int (*xShmLock)(sqlite3_file*,int,int,int) = p->pReal->pMethods->xShmLock; - int i; -@@ -174413,6 +190801,81 @@ - } - - /* -+*/ -+static int rbuUpdateTempSize(rbu_file *pFd, sqlite3_int64 nNew){ -+ sqlite3rbu *pRbu = pFd->pRbu; -+ i64 nDiff = nNew - pFd->sz; -+ pRbu->szTemp += nDiff; -+ pFd->sz = nNew; -+ assert( pRbu->szTemp>=0 ); -+ if( pRbu->szTempLimit && pRbu->szTemp>pRbu->szTempLimit ) return SQLITE_FULL; -+ return SQLITE_OK; -+} -+ -+/* -+** Add an item to the main-db lists, if it is not already present. -+** -+** There are two main-db lists. One for all file descriptors, and one -+** for all file descriptors with rbu_file.pDb!=0. If the argument has -+** rbu_file.pDb!=0, then it is assumed to already be present on the -+** main list and is only added to the pDb!=0 list. -+*/ -+static void rbuMainlistAdd(rbu_file *p){ -+ rbu_vfs *pRbuVfs = p->pRbuVfs; -+ rbu_file *pIter; -+ assert( (p->openFlags & SQLITE_OPEN_MAIN_DB) ); -+ sqlite3_mutex_enter(pRbuVfs->mutex); -+ if( p->pRbu==0 ){ -+ for(pIter=pRbuVfs->pMain; pIter; pIter=pIter->pMainNext); -+ p->pMainNext = pRbuVfs->pMain; -+ pRbuVfs->pMain = p; -+ }else{ -+ for(pIter=pRbuVfs->pMainRbu; pIter && pIter!=p; pIter=pIter->pMainRbuNext){} -+ if( pIter==0 ){ -+ p->pMainRbuNext = pRbuVfs->pMainRbu; -+ pRbuVfs->pMainRbu = p; -+ } -+ } -+ sqlite3_mutex_leave(pRbuVfs->mutex); -+} -+ -+/* -+** Remove an item from the main-db lists. -+*/ -+static void rbuMainlistRemove(rbu_file *p){ -+ rbu_file **pp; -+ sqlite3_mutex_enter(p->pRbuVfs->mutex); -+ for(pp=&p->pRbuVfs->pMain; *pp && *pp!=p; pp=&((*pp)->pMainNext)){} -+ if( *pp ) *pp = p->pMainNext; -+ p->pMainNext = 0; -+ for(pp=&p->pRbuVfs->pMainRbu; *pp && *pp!=p; pp=&((*pp)->pMainRbuNext)){} -+ if( *pp ) *pp = p->pMainRbuNext; -+ p->pMainRbuNext = 0; -+ sqlite3_mutex_leave(p->pRbuVfs->mutex); -+} -+ -+/* -+** Given that zWal points to a buffer containing a wal file name passed to -+** either the xOpen() or xAccess() VFS method, search the main-db list for -+** a file-handle opened by the same database connection on the corresponding -+** database file. -+** -+** If parameter bRbu is true, only search for file-descriptors with -+** rbu_file.pDb!=0. -+*/ -+static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal, int bRbu){ -+ rbu_file *pDb; -+ sqlite3_mutex_enter(pRbuVfs->mutex); -+ if( bRbu ){ -+ for(pDb=pRbuVfs->pMainRbu; pDb && pDb->zWal!=zWal; pDb=pDb->pMainRbuNext){} -+ }else{ -+ for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){} -+ } -+ sqlite3_mutex_leave(pRbuVfs->mutex); -+ return pDb; -+} -+ -+/* - ** Close an rbu file. - */ - static int rbuVfsClose(sqlite3_file *pFile){ -@@ -174429,14 +190892,14 @@ - sqlite3_free(p->zDel); - - if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ -- rbu_file **pp; -- sqlite3_mutex_enter(p->pRbuVfs->mutex); -- for(pp=&p->pRbuVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext)); -- *pp = p->pMainNext; -- sqlite3_mutex_leave(p->pRbuVfs->mutex); -+ rbuMainlistRemove(p); - rbuUnlockShm(p); - p->pReal->pMethods->xShmUnmap(p->pReal, 0); - } -+ else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){ -+ rbuUpdateTempSize(p, 0); -+ } -+ assert( p->pMainNext==0 && p->pRbuVfs->pMain!=p ); - - /* Close the underlying file handle */ - rc = p->pReal->pMethods->xClose(p->pReal); -@@ -174554,11 +191017,19 @@ - assert( p->openFlags & SQLITE_OPEN_MAIN_DB ); - rc = rbuCaptureDbWrite(p->pRbu, iOfst); - }else{ -- if( pRbu && pRbu->eStage==RBU_STAGE_OAL -- && (p->openFlags & SQLITE_OPEN_WAL) -- && iOfst>=pRbu->iOalSz -- ){ -- pRbu->iOalSz = iAmt + iOfst; -+ if( pRbu ){ -+ if( pRbu->eStage==RBU_STAGE_OAL -+ && (p->openFlags & SQLITE_OPEN_WAL) -+ && iOfst>=pRbu->iOalSz -+ ){ -+ pRbu->iOalSz = iAmt + iOfst; -+ }else if( p->openFlags & SQLITE_OPEN_DELETEONCLOSE ){ -+ i64 szNew = iAmt+iOfst; -+ if( szNew>p->sz ){ -+ rc = rbuUpdateTempSize(p, szNew); -+ if( rc!=SQLITE_OK ) return rc; -+ } -+ } - } - rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst); - if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){ -@@ -174577,6 +191048,10 @@ - */ - static int rbuVfsTruncate(sqlite3_file *pFile, sqlite_int64 size){ - rbu_file *p = (rbu_file*)pFile; -+ if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){ -+ int rc = rbuUpdateTempSize(p, size); -+ if( rc!=SQLITE_OK ) return rc; -+ } - return p->pReal->pMethods->xTruncate(p->pReal, size); - } - -@@ -174683,6 +191158,9 @@ - }else if( rc==SQLITE_NOTFOUND ){ - pRbu->pTargetFd = p; - p->pRbu = pRbu; -+ if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ -+ rbuMainlistAdd(p); -+ } - if( p->pWalFd ) p->pWalFd->pRbu = pRbu; - rc = SQLITE_OK; - } -@@ -174844,20 +191322,6 @@ - return rc; - } - --/* --** Given that zWal points to a buffer containing a wal file name passed to --** either the xOpen() or xAccess() VFS method, return a pointer to the --** file-handle opened by the same database connection on the corresponding --** database file. --*/ --static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){ -- rbu_file *pDb; -- sqlite3_mutex_enter(pRbuVfs->mutex); -- for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){} -- sqlite3_mutex_leave(pRbuVfs->mutex); -- return pDb; --} -- - /* - ** A main database named zName has just been opened. The following - ** function returns a pointer to a buffer owned by SQLite that contains -@@ -174936,7 +191400,7 @@ - pFd->zWal = rbuMainToWal(zName, flags); - } - else if( flags & SQLITE_OPEN_WAL ){ -- rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName); -+ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0); - if( pDb ){ - if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){ - /* This call is to open a *-wal file. Intead, open the *-oal. This -@@ -174966,6 +191430,8 @@ - pDb->pWalFd = pFd; - } - } -+ }else{ -+ pFd->pRbu = pRbuVfs->pRbu; - } - - if( oflags & SQLITE_OPEN_MAIN_DB -@@ -174986,10 +191452,7 @@ - ** mutex protected linked list of all such files. */ - pFile->pMethods = &rbuvfs_io_methods; - if( flags & SQLITE_OPEN_MAIN_DB ){ -- sqlite3_mutex_enter(pRbuVfs->mutex); -- pFd->pMainNext = pRbuVfs->pMain; -- pRbuVfs->pMain = pFd; -- sqlite3_mutex_leave(pRbuVfs->mutex); -+ rbuMainlistAdd(pFd); - } - }else{ - sqlite3_free(pFd->zDel); -@@ -175037,12 +191500,14 @@ - ** file opened instead. - */ - if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){ -- rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath); -+ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1); - if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){ - if( *pResOut ){ - rc = SQLITE_CANTOPEN; - }else{ -- *pResOut = 1; -+ sqlite3_int64 sz = 0; -+ rc = rbuVfsFileSize(&pDb->base, &sz); -+ *pResOut = (sz>0); - } - } - } -@@ -175231,7 +191696,21 @@ - return rc; - } - -+/* -+** Configure the aggregate temp file size limit for this RBU handle. -+*/ -+SQLITE_API sqlite3_int64 sqlite3rbu_temp_size_limit(sqlite3rbu *pRbu, sqlite3_int64 n){ -+ if( n>=0 ){ -+ pRbu->szTempLimit = n; -+ } -+ return pRbu->szTempLimit; -+} - -+SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu *pRbu){ -+ return pRbu->szTemp; -+} -+ -+ - /**************************************************************************/ - - #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */ -@@ -175434,8 +191913,6 @@ - static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ - int i; - -- pIdxInfo->estimatedCost = 1.0e6; /* Initial cost estimate */ -- - /* 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 - ** lower the cost estimate to encourage the constrained version to be -@@ -175442,9 +191919,9 @@ - ** used. - */ - for(i=0; i<pIdxInfo->nConstraint; i++){ -- if( pIdxInfo->aConstraint[i].usable==0 ) continue; -+ 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; -- if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue; - pIdxInfo->idxNum = 1; - pIdxInfo->estimatedCost = 1.0; - pIdxInfo->aConstraintUsage[i].argvIndex = 1; -@@ -175494,7 +191971,7 @@ - return SQLITE_OK; - } - --static void statClearPage(StatPage *p){ -+static void statClearCells(StatPage *p){ - int i; - if( p->aCell ){ - for(i=0; i<p->nCell; i++){ -@@ -175502,6 +191979,12 @@ - } - sqlite3_free(p->aCell); - } -+ p->nCell = 0; -+ p->aCell = 0; -+} -+ -+static void statClearPage(StatPage *p){ -+ statClearCells(p); - sqlite3PagerUnref(p->pPg); - sqlite3_free(p->zPath); - memset(p, 0, sizeof(StatPage)); -@@ -175564,22 +192047,33 @@ - u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0]; - - p->flags = aHdr[0]; -+ if( p->flags==0x0A || p->flags==0x0D ){ -+ isLeaf = 1; -+ nHdr = 8; -+ }else if( p->flags==0x05 || p->flags==0x02 ){ -+ isLeaf = 0; -+ nHdr = 12; -+ }else{ -+ goto statPageIsCorrupt; -+ } -+ if( p->iPgno==1 ) nHdr += 100; - p->nCell = get2byte(&aHdr[3]); - p->nMxPayload = 0; -+ szPage = sqlite3BtreeGetPageSize(pBt); - -- isLeaf = (p->flags==0x0A || p->flags==0x0D); -- nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100; -- - nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell; - nUnused += (int)aHdr[7]; - iOff = get2byte(&aHdr[1]); - while( iOff ){ -+ int iNext; -+ if( iOff>=szPage ) goto statPageIsCorrupt; - nUnused += get2byte(&aData[iOff+2]); -- iOff = get2byte(&aData[iOff]); -+ iNext = get2byte(&aData[iOff]); -+ if( iNext<iOff+4 && iNext>0 ) goto statPageIsCorrupt; -+ iOff = iNext; - } - p->nUnused = nUnused; - p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]); -- szPage = sqlite3BtreeGetPageSize(pBt); - - if( p->nCell ){ - int i; /* Used to iterate through cells */ -@@ -175596,6 +192090,7 @@ - StatCell *pCell = &p->aCell[i]; - - iOff = get2byte(&aData[nHdr+i*2]); -+ if( iOff<nHdr || iOff>=szPage ) goto statPageIsCorrupt; - if( !isLeaf ){ - pCell->iChildPg = sqlite3Get4byte(&aData[iOff]); - iOff += 4; -@@ -175612,13 +192107,14 @@ - } - if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload; - getLocalPayload(nUsable, p->flags, nPayload, &nLocal); -+ if( nLocal<0 ) goto statPageIsCorrupt; - pCell->nLocal = nLocal; -- assert( nLocal>=0 ); - assert( nPayload>=(u32)nLocal ); - assert( nLocal<=(nUsable-35) ); - if( nPayload>(u32)nLocal ){ - int j; - int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4); -+ if( iOff+nLocal>nUsable ) goto statPageIsCorrupt; - pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4); - pCell->nOvfl = nOvfl; - pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl); -@@ -175642,6 +192138,11 @@ - } - - return SQLITE_OK; -+ -+statPageIsCorrupt: -+ p->flags = 0; -+ statClearCells(p); -+ return SQLITE_OK; - } - - /* -@@ -175664,7 +192165,7 @@ - */ - fd = sqlite3PagerFile(pPager); - x[0] = pCsr->iPageno; -- if( fd->pMethods!=0 && sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){ -+ if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){ - pCsr->iOffset = x[0]; - pCsr->szPage = (int)x[1]; - } -@@ -175937,6 +192438,7 @@ - 0, /* xSavepoint */ - 0, /* xRelease */ - 0, /* xRollbackTo */ -+ 0 /* xShadowName */ - }; - return sqlite3_create_module(db, "dbstat", &dbstat_module, 0); - } -@@ -175945,6 +192447,424 @@ - #endif /* SQLITE_ENABLE_DBSTAT_VTAB */ - - /************** End of dbstat.c **********************************************/ -+/************** Begin file dbpage.c ******************************************/ -+/* -+** 2017-10-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 file contains an implementation of the "sqlite_dbpage" virtual table. -+** -+** The sqlite_dbpage virtual table is used to read or write whole raw -+** pages of the database file. The pager interface is used so that -+** uncommitted changes and changes recorded in the WAL file are correctly -+** retrieved. -+** -+** Usage example: -+** -+** SELECT data FROM sqlite_dbpage('aux1') WHERE pgno=123; -+** -+** This is an eponymous virtual table so it does not need to be created before -+** use. The optional argument to the sqlite_dbpage() table name is the -+** schema for the database file that is to be read. The default schema is -+** "main". -+** -+** The data field of sqlite_dbpage table can be updated. The new -+** value must be a BLOB which is the correct page size, otherwise the -+** update fails. Rows may not be deleted or inserted. -+*/ -+ -+/* #include "sqliteInt.h" ** Requires access to internal data structures ** */ -+#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \ -+ && !defined(SQLITE_OMIT_VIRTUALTABLE) -+ -+typedef struct DbpageTable DbpageTable; -+typedef struct DbpageCursor DbpageCursor; -+ -+struct DbpageCursor { -+ sqlite3_vtab_cursor base; /* Base class. Must be first */ -+ int pgno; /* Current page number */ -+ int mxPgno; /* Last page to visit on this scan */ -+ Pager *pPager; /* Pager being read/written */ -+ DbPage *pPage1; /* Page 1 of the database */ -+ int iDb; /* Index of database to analyze */ -+ int szPage; /* Size of each page in bytes */ -+}; -+ -+struct DbpageTable { -+ sqlite3_vtab base; /* Base class. Must be first */ -+ sqlite3 *db; /* The database */ -+}; -+ -+/* Columns */ -+#define DBPAGE_COLUMN_PGNO 0 -+#define DBPAGE_COLUMN_DATA 1 -+#define DBPAGE_COLUMN_SCHEMA 2 -+ -+ -+ -+/* -+** Connect to or create a dbpagevfs virtual table. -+*/ -+static int dbpageConnect( -+ sqlite3 *db, -+ void *pAux, -+ int argc, const char *const*argv, -+ sqlite3_vtab **ppVtab, -+ char **pzErr -+){ -+ DbpageTable *pTab = 0; -+ int rc = SQLITE_OK; -+ -+ rc = sqlite3_declare_vtab(db, -+ "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)"); -+ if( rc==SQLITE_OK ){ -+ pTab = (DbpageTable *)sqlite3_malloc64(sizeof(DbpageTable)); -+ if( pTab==0 ) rc = SQLITE_NOMEM_BKPT; -+ } -+ -+ assert( rc==SQLITE_OK || pTab==0 ); -+ if( rc==SQLITE_OK ){ -+ memset(pTab, 0, sizeof(DbpageTable)); -+ pTab->db = db; -+ } -+ -+ *ppVtab = (sqlite3_vtab*)pTab; -+ return rc; -+} -+ -+/* -+** Disconnect from or destroy a dbpagevfs virtual table. -+*/ -+static int dbpageDisconnect(sqlite3_vtab *pVtab){ -+ sqlite3_free(pVtab); -+ return SQLITE_OK; -+} -+ -+/* -+** idxNum: -+** -+** 0 schema=main, full table scan -+** 1 schema=main, pgno=?1 -+** 2 schema=?1, full table scan -+** 3 schema=?1, pgno=?2 -+*/ -+static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ -+ int i; -+ int iPlan = 0; -+ -+ /* If there is a schema= constraint, it must be honored. Report a -+ ** ridiculously large estimated cost if the schema= constraint is -+ ** unavailable -+ */ -+ for(i=0; i<pIdxInfo->nConstraint; i++){ -+ struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i]; -+ if( p->iColumn!=DBPAGE_COLUMN_SCHEMA ) continue; -+ if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; -+ if( !p->usable ){ -+ /* No solution. */ -+ return SQLITE_CONSTRAINT; -+ } -+ iPlan = 2; -+ pIdxInfo->aConstraintUsage[i].argvIndex = 1; -+ pIdxInfo->aConstraintUsage[i].omit = 1; -+ break; -+ } -+ -+ /* If we reach this point, it means that either there is no schema= -+ ** constraint (in which case we use the "main" schema) or else the -+ ** schema constraint was accepted. Lower the estimated cost accordingly -+ */ -+ pIdxInfo->estimatedCost = 1.0e6; -+ -+ /* Check for constraints against pgno */ -+ for(i=0; i<pIdxInfo->nConstraint; i++){ -+ struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i]; -+ if( p->usable && p->iColumn<=0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ -+ pIdxInfo->estimatedRows = 1; -+ pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE; -+ pIdxInfo->estimatedCost = 1.0; -+ pIdxInfo->aConstraintUsage[i].argvIndex = iPlan ? 2 : 1; -+ pIdxInfo->aConstraintUsage[i].omit = 1; -+ iPlan |= 1; -+ break; -+ } -+ } -+ pIdxInfo->idxNum = iPlan; -+ -+ if( pIdxInfo->nOrderBy>=1 -+ && pIdxInfo->aOrderBy[0].iColumn<=0 -+ && pIdxInfo->aOrderBy[0].desc==0 -+ ){ -+ pIdxInfo->orderByConsumed = 1; -+ } -+ return SQLITE_OK; -+} -+ -+/* -+** Open a new dbpagevfs cursor. -+*/ -+static int dbpageOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ -+ DbpageCursor *pCsr; -+ -+ pCsr = (DbpageCursor *)sqlite3_malloc64(sizeof(DbpageCursor)); -+ if( pCsr==0 ){ -+ return SQLITE_NOMEM_BKPT; -+ }else{ -+ memset(pCsr, 0, sizeof(DbpageCursor)); -+ pCsr->base.pVtab = pVTab; -+ pCsr->pgno = -1; -+ } -+ -+ *ppCursor = (sqlite3_vtab_cursor *)pCsr; -+ return SQLITE_OK; -+} -+ -+/* -+** Close a dbpagevfs cursor. -+*/ -+static int dbpageClose(sqlite3_vtab_cursor *pCursor){ -+ DbpageCursor *pCsr = (DbpageCursor *)pCursor; -+ if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1); -+ sqlite3_free(pCsr); -+ return SQLITE_OK; -+} -+ -+/* -+** Move a dbpagevfs cursor to the next entry in the file. -+*/ -+static int dbpageNext(sqlite3_vtab_cursor *pCursor){ -+ int rc = SQLITE_OK; -+ DbpageCursor *pCsr = (DbpageCursor *)pCursor; -+ pCsr->pgno++; -+ return rc; -+} -+ -+static int dbpageEof(sqlite3_vtab_cursor *pCursor){ -+ DbpageCursor *pCsr = (DbpageCursor *)pCursor; -+ return pCsr->pgno > pCsr->mxPgno; -+} -+ -+/* -+** idxNum: -+** -+** 0 schema=main, full table scan -+** 1 schema=main, pgno=?1 -+** 2 schema=?1, full table scan -+** 3 schema=?1, pgno=?2 -+** -+** idxStr is not used -+*/ -+static int dbpageFilter( -+ sqlite3_vtab_cursor *pCursor, -+ int idxNum, const char *idxStr, -+ int argc, sqlite3_value **argv -+){ -+ DbpageCursor *pCsr = (DbpageCursor *)pCursor; -+ DbpageTable *pTab = (DbpageTable *)pCursor->pVtab; -+ int rc; -+ sqlite3 *db = pTab->db; -+ Btree *pBt; -+ -+ /* Default setting is no rows of result */ -+ pCsr->pgno = 1; -+ pCsr->mxPgno = 0; -+ -+ if( idxNum & 2 ){ -+ const char *zSchema; -+ assert( argc>=1 ); -+ zSchema = (const char*)sqlite3_value_text(argv[0]); -+ pCsr->iDb = sqlite3FindDbName(db, zSchema); -+ if( pCsr->iDb<0 ) return SQLITE_OK; -+ }else{ -+ pCsr->iDb = 0; -+ } -+ pBt = db->aDb[pCsr->iDb].pBt; -+ if( pBt==0 ) return SQLITE_OK; -+ pCsr->pPager = sqlite3BtreePager(pBt); -+ pCsr->szPage = sqlite3BtreeGetPageSize(pBt); -+ pCsr->mxPgno = sqlite3BtreeLastPage(pBt); -+ if( idxNum & 1 ){ -+ assert( argc>(idxNum>>1) ); -+ pCsr->pgno = sqlite3_value_int(argv[idxNum>>1]); -+ if( pCsr->pgno<1 || pCsr->pgno>pCsr->mxPgno ){ -+ pCsr->pgno = 1; -+ pCsr->mxPgno = 0; -+ }else{ -+ pCsr->mxPgno = pCsr->pgno; -+ } -+ }else{ -+ assert( pCsr->pgno==1 ); -+ } -+ if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1); -+ rc = sqlite3PagerGet(pCsr->pPager, 1, &pCsr->pPage1, 0); -+ return rc; -+} -+ -+static int dbpageColumn( -+ sqlite3_vtab_cursor *pCursor, -+ sqlite3_context *ctx, -+ int i -+){ -+ DbpageCursor *pCsr = (DbpageCursor *)pCursor; -+ int rc = SQLITE_OK; -+ switch( i ){ -+ case 0: { /* pgno */ -+ sqlite3_result_int(ctx, pCsr->pgno); -+ break; -+ } -+ case 1: { /* data */ -+ DbPage *pDbPage = 0; -+ rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0); -+ if( rc==SQLITE_OK ){ -+ sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pCsr->szPage, -+ SQLITE_TRANSIENT); -+ } -+ sqlite3PagerUnref(pDbPage); -+ break; -+ } -+ default: { /* schema */ -+ sqlite3 *db = sqlite3_context_db_handle(ctx); -+ sqlite3_result_text(ctx, db->aDb[pCsr->iDb].zDbSName, -1, SQLITE_STATIC); -+ break; -+ } -+ } -+ return SQLITE_OK; -+} -+ -+static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ -+ DbpageCursor *pCsr = (DbpageCursor *)pCursor; -+ *pRowid = pCsr->pgno; -+ return SQLITE_OK; -+} -+ -+static int dbpageUpdate( -+ sqlite3_vtab *pVtab, -+ int argc, -+ sqlite3_value **argv, -+ sqlite_int64 *pRowid -+){ -+ DbpageTable *pTab = (DbpageTable *)pVtab; -+ Pgno pgno; -+ DbPage *pDbPage = 0; -+ int rc = SQLITE_OK; -+ char *zErr = 0; -+ const char *zSchema; -+ int iDb; -+ Btree *pBt; -+ Pager *pPager; -+ int szPage; -+ -+ if( pTab->db->flags & SQLITE_Defensive ){ -+ zErr = "read-only"; -+ goto update_fail; -+ } -+ if( argc==1 ){ -+ zErr = "cannot delete"; -+ goto update_fail; -+ } -+ pgno = sqlite3_value_int(argv[0]); -+ if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){ -+ zErr = "cannot insert"; -+ goto update_fail; -+ } -+ zSchema = (const char*)sqlite3_value_text(argv[4]); -+ iDb = zSchema ? sqlite3FindDbName(pTab->db, zSchema) : -1; -+ if( iDb<0 ){ -+ zErr = "no such schema"; -+ goto update_fail; -+ } -+ pBt = pTab->db->aDb[iDb].pBt; -+ if( pgno<1 || pBt==0 || pgno>(int)sqlite3BtreeLastPage(pBt) ){ -+ zErr = "bad page number"; -+ goto update_fail; -+ } -+ szPage = sqlite3BtreeGetPageSize(pBt); -+ if( sqlite3_value_type(argv[3])!=SQLITE_BLOB -+ || sqlite3_value_bytes(argv[3])!=szPage -+ ){ -+ zErr = "bad page value"; -+ goto update_fail; -+ } -+ pPager = sqlite3BtreePager(pBt); -+ rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3PagerWrite(pDbPage); -+ if( rc==SQLITE_OK ){ -+ memcpy(sqlite3PagerGetData(pDbPage), -+ sqlite3_value_blob(argv[3]), -+ szPage); -+ } -+ } -+ sqlite3PagerUnref(pDbPage); -+ return rc; -+ -+update_fail: -+ sqlite3_free(pVtab->zErrMsg); -+ pVtab->zErrMsg = sqlite3_mprintf("%s", zErr); -+ return SQLITE_ERROR; -+} -+ -+/* Since we do not know in advance which database files will be -+** written by the sqlite_dbpage virtual table, start a write transaction -+** on them all. -+*/ -+static int dbpageBegin(sqlite3_vtab *pVtab){ -+ DbpageTable *pTab = (DbpageTable *)pVtab; -+ sqlite3 *db = pTab->db; -+ int i; -+ for(i=0; i<db->nDb; i++){ -+ Btree *pBt = db->aDb[i].pBt; -+ if( pBt ) sqlite3BtreeBeginTrans(pBt, 1, 0); -+ } -+ return SQLITE_OK; -+} -+ -+ -+/* -+** Invoke this routine to register the "dbpage" virtual table module -+*/ -+SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ -+ static sqlite3_module dbpage_module = { -+ 0, /* iVersion */ -+ dbpageConnect, /* xCreate */ -+ dbpageConnect, /* xConnect */ -+ dbpageBestIndex, /* xBestIndex */ -+ dbpageDisconnect, /* xDisconnect */ -+ dbpageDisconnect, /* xDestroy */ -+ dbpageOpen, /* xOpen - open a cursor */ -+ dbpageClose, /* xClose - close a cursor */ -+ dbpageFilter, /* xFilter - configure scan constraints */ -+ dbpageNext, /* xNext - advance a cursor */ -+ dbpageEof, /* xEof - check for end of scan */ -+ dbpageColumn, /* xColumn - read data */ -+ dbpageRowid, /* xRowid - read data */ -+ dbpageUpdate, /* xUpdate */ -+ dbpageBegin, /* xBegin */ -+ 0, /* xSync */ -+ 0, /* xCommit */ -+ 0, /* xRollback */ -+ 0, /* xFindMethod */ -+ 0, /* xRename */ -+ 0, /* xSavepoint */ -+ 0, /* xRelease */ -+ 0, /* xRollbackTo */ -+ 0 /* xShadowName */ -+ }; -+ return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0); -+} -+#elif defined(SQLITE_ENABLE_DBPAGE_VTAB) -+SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; } -+#endif /* SQLITE_ENABLE_DBSTAT_VTAB */ -+ -+/************** End of dbpage.c **********************************************/ - /************** Begin file sqlite3session.c **********************************/ - - #if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK) -@@ -175973,6 +192893,8 @@ - # endif - #endif - -+static int sessions_strm_chunk_size = SESSIONS_STRM_CHUNK_SIZE; -+ - typedef struct SessionHook SessionHook; - struct SessionHook { - void *pCtx; -@@ -175994,6 +192916,7 @@ - int rc; /* Non-zero if an error has occurred */ - void *pFilterCtx; /* First argument to pass to xTableFilter */ - int (*xTableFilter)(void *pCtx, const char *zTab); -+ sqlite3_value *pZeroBlob; /* Value containing X'' */ - sqlite3_session *pNext; /* Next session object on same db. */ - SessionTable *pTable; /* List of attached tables */ - SessionHook hook; /* APIs to grab new and old data with */ -@@ -176015,7 +192938,7 @@ - ** sqlite3changeset_start_strm()). - */ - struct SessionInput { -- int bNoDiscard; /* If true, discard no data */ -+ int bNoDiscard; /* If true, do not discard in InputBuffer() */ - int iCurrent; /* Offset in aData[] of current change */ - int iNext; /* Offset in aData[] of next change */ - u8 *aData; /* Pointer to buffer containing changeset */ -@@ -176034,6 +192957,7 @@ - SessionInput in; /* Input buffer or stream */ - SessionBuffer tblhdr; /* Buffer to hold apValue/zTab/abPK/ */ - int bPatchset; /* True if this is a patchset */ -+ int bInvert; /* True to invert changeset */ - int rc; /* Iterator error code */ - sqlite3_stmt *pConflict; /* Points to conflicting row, if any */ - char *zTab; /* Current table */ -@@ -176061,6 +192985,7 @@ - SessionTable *pNext; - char *zName; /* Local name of table */ - int nCol; /* Number of columns in table zName */ -+ int bStat1; /* True if this is sqlite_stat1 */ - const char **azCol; /* Column names */ - u8 *abPK; /* Array of primary key flags */ - int nEntry; /* Total number of entries in hash table */ -@@ -176178,8 +193103,8 @@ - ** statement. - ** - ** For a DELETE change, all fields within the record except those associated --** with PRIMARY KEY columns are set to "undefined". The PRIMARY KEY fields --** contain the values identifying the row to delete. -+** with PRIMARY KEY columns are omitted. The PRIMARY KEY fields contain the -+** values identifying the row to delete. - ** - ** For an UPDATE change, all fields except those associated with PRIMARY KEY - ** columns and columns that are modified by the UPDATE are set to "undefined". -@@ -176189,6 +193114,42 @@ - ** The records associated with INSERT changes are in the same format as for - ** changesets. It is not possible for a record associated with an INSERT - ** change to contain a field set to "undefined". -+** -+** REBASE BLOB FORMAT: -+** -+** A rebase blob may be output by sqlite3changeset_apply_v2() and its -+** streaming equivalent for use with the sqlite3_rebaser APIs to rebase -+** existing changesets. A rebase blob contains one entry for each conflict -+** resolved using either the OMIT or REPLACE strategies within the apply_v2() -+** call. -+** -+** The format used for a rebase blob is very similar to that used for -+** changesets. All entries related to a single table are grouped together. -+** -+** Each group of entries begins with a table header in changeset format: -+** -+** 1 byte: Constant 0x54 (capital 'T') -+** Varint: Number of columns in the table. -+** nCol bytes: 0x01 for PK columns, 0x00 otherwise. -+** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated. -+** -+** Followed by one or more entries associated with the table. -+** -+** 1 byte: Either SQLITE_INSERT (0x12), DELETE (0x09). -+** 1 byte: Flag. 0x01 for REPLACE, 0x00 for OMIT. -+** record: (in the record format defined above). -+** -+** In a rebase blob, the first field is set to SQLITE_INSERT if the change -+** that caused the conflict was an INSERT or UPDATE, or to SQLITE_DELETE if -+** it was a DELETE. The second field is set to 0x01 if the conflict -+** resolution strategy was REPLACE, or 0x00 if it was OMIT. -+** -+** If the change that caused the conflict was a DELETE, then the single -+** record is a copy of the old.* record from the original changeset. If it -+** was an INSERT, then the single record is a copy of the new.* record. If -+** the conflicting change was an UPDATE, then the single record is a copy -+** of the new.* record with the PK fields filled in based on the original -+** old.* record. - */ - - /* -@@ -176444,6 +193405,7 @@ - h = sessionHashAppendBlob(h, n, z); - }else{ - assert( eType==SQLITE_NULL ); -+ assert( pTab->bStat1==0 || i!=1 ); - *pbNullPK = 1; - } - } -@@ -176461,7 +193423,7 @@ - static int sessionSerialLen(u8 *a){ - int e = *a; - int n; -- if( e==0 ) return 1; -+ if( e==0 || e==0xFF ) return 1; - if( e==SQLITE_NULL ) return 1; - if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9; - return sessionVarintGet(&a[1], &n) + 1 + n; -@@ -176541,7 +193503,7 @@ - int n1 = sessionSerialLen(a1); - int n2 = sessionSerialLen(a2); - -- if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){ -+ if( n1!=n2 || memcmp(a1, a2, n1) ){ - return 0; - } - a1 += n1; -@@ -176784,9 +193746,8 @@ - }else{ - z = sqlite3_value_blob(pVal); - } -- if( memcmp(a, z, n) ) return 0; -+ if( n>0 && memcmp(a, z, n) ) return 0; - a += n; -- break; - } - } - } -@@ -176842,9 +193803,7 @@ - - /* - ** This function queries the database for the names of the columns of table --** zThis, in schema zDb. It is expected that the table has nCol columns. If --** not, SQLITE_SCHEMA is returned and none of the output variables are --** populated. -+** zThis, in schema zDb. - ** - ** Otherwise, if they are not NULL, variable *pnCol is set to the number - ** of columns in the database table and variable *pzTab is set to point to a -@@ -176865,9 +193824,7 @@ - ** *pabPK = {1, 0, 0, 1} - ** - ** All returned buffers are part of the same single allocation, which must --** be freed using sqlite3_free() by the caller. If pazCol was not NULL, then --** pointer *pazCol should be freed to release all memory. Otherwise, pointer --** *pabPK. It is illegal for both pazCol and pabPK to be NULL. -+** be freed using sqlite3_free() by the caller - */ - static int sessionTableInfo( - sqlite3 *db, /* Database connection */ -@@ -176892,7 +193849,23 @@ - assert( pazCol && pabPK ); - - nThis = sqlite3Strlen30(zThis); -- zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis); -+ if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){ -+ rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0); -+ if( rc==SQLITE_OK ){ -+ /* For sqlite_stat1, pretend that (tbl,idx) is the PRIMARY KEY. */ -+ zPragma = sqlite3_mprintf( -+ "SELECT 0, 'tbl', '', 0, '', 1 UNION ALL " -+ "SELECT 1, 'idx', '', 0, '', 2 UNION ALL " -+ "SELECT 2, 'stat', '', 0, '', 0" -+ ); -+ }else if( rc==SQLITE_ERROR ){ -+ zPragma = sqlite3_mprintf(""); -+ }else{ -+ return rc; -+ } -+ }else{ -+ zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis); -+ } - if( !zPragma ) return SQLITE_NOMEM; - - rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0); -@@ -176984,6 +193957,9 @@ - break; - } - } -+ if( 0==sqlite3_stricmp("sqlite_stat1", pTab->zName) ){ -+ pTab->bStat1 = 1; -+ } - } - } - return (pSession->rc || pTab->abPK==0); -@@ -176990,6 +193966,47 @@ - } - - /* -+** Versions of the four methods in object SessionHook for use with the -+** sqlite_stat1 table. The purpose of this is to substitute a zero-length -+** blob each time a NULL value is read from the "idx" column of the -+** sqlite_stat1 table. -+*/ -+typedef struct SessionStat1Ctx SessionStat1Ctx; -+struct SessionStat1Ctx { -+ SessionHook hook; -+ sqlite3_session *pSession; -+}; -+static int sessionStat1Old(void *pCtx, int iCol, sqlite3_value **ppVal){ -+ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx; -+ sqlite3_value *pVal = 0; -+ int rc = p->hook.xOld(p->hook.pCtx, iCol, &pVal); -+ if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){ -+ pVal = p->pSession->pZeroBlob; -+ } -+ *ppVal = pVal; -+ return rc; -+} -+static int sessionStat1New(void *pCtx, int iCol, sqlite3_value **ppVal){ -+ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx; -+ sqlite3_value *pVal = 0; -+ int rc = p->hook.xNew(p->hook.pCtx, iCol, &pVal); -+ if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){ -+ pVal = p->pSession->pZeroBlob; -+ } -+ *ppVal = pVal; -+ return rc; -+} -+static int sessionStat1Count(void *pCtx){ -+ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx; -+ return p->hook.xCount(p->hook.pCtx); -+} -+static int sessionStat1Depth(void *pCtx){ -+ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx; -+ return p->hook.xDepth(p->hook.pCtx); -+} -+ -+ -+/* - ** This function is only called from with a pre-update-hook reporting a - ** change on table pTab (attached to session pSession). The type of change - ** (UPDATE, INSERT, DELETE) is specified by the first argument. -@@ -177005,6 +194022,7 @@ - int iHash; - int bNull = 0; - int rc = SQLITE_OK; -+ SessionStat1Ctx stat1 = {0}; - - if( pSession->rc ) return; - -@@ -177024,6 +194042,25 @@ - return; - } - -+ if( pTab->bStat1 ){ -+ stat1.hook = pSession->hook; -+ stat1.pSession = pSession; -+ pSession->hook.pCtx = (void*)&stat1; -+ pSession->hook.xNew = sessionStat1New; -+ pSession->hook.xOld = sessionStat1Old; -+ pSession->hook.xCount = sessionStat1Count; -+ pSession->hook.xDepth = sessionStat1Depth; -+ if( pSession->pZeroBlob==0 ){ -+ sqlite3_value *p = sqlite3ValueNew(0); -+ if( p==0 ){ -+ rc = SQLITE_NOMEM; -+ goto error_out; -+ } -+ sqlite3ValueSetStr(p, 0, "", 0, SQLITE_STATIC); -+ pSession->pZeroBlob = p; -+ } -+ } -+ - /* Calculate the hash-key for this change. If the primary key of the row - ** includes a NULL value, exit early. Such changes are ignored by the - ** session module. */ -@@ -177113,6 +194150,9 @@ - - /* If an error has occurred, mark the session object as failed. */ - error_out: -+ if( pTab->bStat1 ){ -+ pSession->hook = stat1.hook; -+ } - if( rc!=SQLITE_OK ){ - pSession->rc = rc; - } -@@ -177449,7 +194489,6 @@ - if( abPK[i] ) bHasPk = 1; - } - } -- - } - sqlite3_free((char*)azCol); - if( bMismatch ){ -@@ -177575,6 +194614,7 @@ - } - } - sqlite3_mutex_leave(sqlite3_db_mutex(db)); -+ sqlite3ValueFree(pSession->pZeroBlob); - - /* Delete all attached table objects. And the contents of their - ** associated hash-tables. */ -@@ -177660,12 +194700,12 @@ - static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){ - if( *pRc==SQLITE_OK && p->nAlloc-p->nBuf<nByte ){ - u8 *aNew; -- int nNew = p->nAlloc ? p->nAlloc : 128; -+ i64 nNew = p->nAlloc ? p->nAlloc : 128; - do { - nNew = nNew*2; -- }while( nNew<(p->nBuf+nByte) ); -+ }while( (nNew-p->nBuf)<nByte ); - -- aNew = (u8 *)sqlite3_realloc(p->aBuf, nNew); -+ aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew); - if( 0==aNew ){ - *pRc = SQLITE_NOMEM; - }else{ -@@ -178042,28 +195082,42 @@ - sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */ - ){ - int rc = SQLITE_OK; -- int i; -- const char *zSep = ""; -- SessionBuffer buf = {0, 0, 0}; -+ char *zSql = 0; -+ int nSql = -1; - -- sessionAppendStr(&buf, "SELECT * FROM ", &rc); -- sessionAppendIdent(&buf, zDb, &rc); -- sessionAppendStr(&buf, ".", &rc); -- sessionAppendIdent(&buf, zTab, &rc); -- sessionAppendStr(&buf, " WHERE ", &rc); -- for(i=0; i<nCol; i++){ -- if( abPK[i] ){ -- sessionAppendStr(&buf, zSep, &rc); -- sessionAppendIdent(&buf, azCol[i], &rc); -- sessionAppendStr(&buf, " = ?", &rc); -- sessionAppendInteger(&buf, i+1, &rc); -- zSep = " AND "; -+ if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){ -+ zSql = sqlite3_mprintf( -+ "SELECT tbl, ?2, stat FROM %Q.sqlite_stat1 WHERE tbl IS ?1 AND " -+ "idx IS (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", zDb -+ ); -+ if( zSql==0 ) rc = SQLITE_NOMEM; -+ }else{ -+ int i; -+ const char *zSep = ""; -+ SessionBuffer buf = {0, 0, 0}; -+ -+ sessionAppendStr(&buf, "SELECT * FROM ", &rc); -+ sessionAppendIdent(&buf, zDb, &rc); -+ sessionAppendStr(&buf, ".", &rc); -+ sessionAppendIdent(&buf, zTab, &rc); -+ sessionAppendStr(&buf, " WHERE ", &rc); -+ for(i=0; i<nCol; i++){ -+ if( abPK[i] ){ -+ sessionAppendStr(&buf, zSep, &rc); -+ sessionAppendIdent(&buf, azCol[i], &rc); -+ sessionAppendStr(&buf, " IS ?", &rc); -+ sessionAppendInteger(&buf, i+1, &rc); -+ zSep = " AND "; -+ } - } -+ zSql = (char*)buf.aBuf; -+ nSql = buf.nBuf; - } -+ - if( rc==SQLITE_OK ){ -- rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, ppStmt, 0); -+ rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0); - } -- sqlite3_free(buf.aBuf); -+ sqlite3_free(zSql); - return rc; - } - -@@ -178249,12 +195303,12 @@ - rc = sqlite3_reset(pSel); - } - -- /* If the buffer is now larger than SESSIONS_STRM_CHUNK_SIZE, pass -+ /* If the buffer is now larger than sessions_strm_chunk_size, pass - ** its contents to the xOutput() callback. */ - if( xOutput - && rc==SQLITE_OK - && buf.nBuf>nNoop -- && buf.nBuf>SESSIONS_STRM_CHUNK_SIZE -+ && buf.nBuf>sessions_strm_chunk_size - ){ - rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf); - nNoop = -1; -@@ -178393,7 +195447,8 @@ - int (*xInput)(void *pIn, void *pData, int *pnData), - void *pIn, - int nChangeset, /* Size of buffer pChangeset in bytes */ -- void *pChangeset /* Pointer to buffer containing changeset */ -+ void *pChangeset, /* Pointer to buffer containing changeset */ -+ int bInvert /* True to invert changeset */ - ){ - sqlite3_changeset_iter *pRet; /* Iterator to return */ - int nByte; /* Number of bytes to allocate for iterator */ -@@ -178413,6 +195468,7 @@ - pRet->in.xInput = xInput; - pRet->in.pIn = pIn; - pRet->in.bEof = (xInput ? 0 : 1); -+ pRet->bInvert = bInvert; - - /* Populate the output variable and return success. */ - *pp = pRet; -@@ -178427,8 +195483,17 @@ - int nChangeset, /* Size of buffer pChangeset in bytes */ - void *pChangeset /* Pointer to buffer containing changeset */ - ){ -- return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset); -+ return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0); - } -+SQLITE_API int sqlite3changeset_start_v2( -+ sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ -+ int nChangeset, /* Size of buffer pChangeset in bytes */ -+ void *pChangeset, /* Pointer to buffer containing changeset */ -+ int flags -+){ -+ int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT); -+ return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert); -+} - - /* - ** Streaming version of sqlite3changeset_start(). -@@ -178438,8 +195503,17 @@ - int (*xInput)(void *pIn, void *pData, int *pnData), - void *pIn - ){ -- return sessionChangesetStart(pp, xInput, pIn, 0, 0); -+ return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0); - } -+SQLITE_API int sqlite3changeset_start_v2_strm( -+ sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ -+ int (*xInput)(void *pIn, void *pData, int *pnData), -+ void *pIn, -+ int flags -+){ -+ int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT); -+ return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert); -+} - - /* - ** If the SessionInput object passed as the only argument is a streaming -@@ -178446,7 +195520,7 @@ - ** object and the buffer is full, discard some data to free up space. - */ - static void sessionDiscardData(SessionInput *pIn){ -- if( pIn->bEof && pIn->xInput && pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){ -+ if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){ - int nMove = pIn->buf.nBuf - pIn->iNext; - assert( nMove>=0 ); - if( nMove>0 ){ -@@ -178469,7 +195543,7 @@ - int rc = SQLITE_OK; - if( pIn->xInput ){ - while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){ -- int nNew = SESSIONS_STRM_CHUNK_SIZE; -+ int nNew = sessions_strm_chunk_size; - - if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn); - if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){ -@@ -178574,15 +195648,18 @@ - if( abPK && abPK[i]==0 ) continue; - rc = sessionInputBuffer(pIn, 9); - if( rc==SQLITE_OK ){ -- eType = pIn->aData[pIn->iNext++]; -+ if( pIn->iNext>=pIn->nData ){ -+ rc = SQLITE_CORRUPT_BKPT; -+ }else{ -+ eType = pIn->aData[pIn->iNext++]; -+ assert( apOut[i]==0 ); -+ if( eType ){ -+ apOut[i] = sqlite3ValueNew(0); -+ if( !apOut[i] ) rc = SQLITE_NOMEM; -+ } -+ } - } - -- assert( apOut[i]==0 ); -- if( eType ){ -- apOut[i] = sqlite3ValueNew(0); -- if( !apOut[i] ) rc = SQLITE_NOMEM; -- } -- - if( rc==SQLITE_OK ){ - u8 *aVal = &pIn->aData[pIn->iNext]; - if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ -@@ -178590,10 +195667,14 @@ - pIn->iNext += sessionVarintGet(aVal, &nByte); - rc = sessionInputBuffer(pIn, nByte); - if( rc==SQLITE_OK ){ -- u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0); -- rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc); -+ if( nByte<0 || nByte>pIn->nData-pIn->iNext ){ -+ rc = SQLITE_CORRUPT_BKPT; -+ }else{ -+ u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0); -+ rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc); -+ pIn->iNext += nByte; -+ } - } -- pIn->iNext += nByte; - } - if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ - sqlite3_int64 v = sessionGetI64(aVal); -@@ -178633,8 +195714,19 @@ - rc = sessionInputBuffer(pIn, 9); - if( rc==SQLITE_OK ){ - nRead += sessionVarintGet(&pIn->aData[pIn->iNext + nRead], &nCol); -- rc = sessionInputBuffer(pIn, nRead+nCol+100); -- nRead += nCol; -+ /* The hard upper limit for the number of columns in an SQLite -+ ** database table is, according to sqliteLimit.h, 32676. So -+ ** consider any table-header that purports to have more than 65536 -+ ** columns to be corrupt. This is convenient because otherwise, -+ ** if the (nCol>65536) condition below were omitted, a sufficiently -+ ** large value for nCol may cause nRead to wrap around and become -+ ** negative. Leading to a crash. */ -+ if( nCol<0 || nCol>65536 ){ -+ rc = SQLITE_CORRUPT_BKPT; -+ }else{ -+ rc = sessionInputBuffer(pIn, nRead+nCol+100); -+ nRead += nCol; -+ } - } - - while( rc==SQLITE_OK ){ -@@ -178711,11 +195803,15 @@ - int nByte; - int nVarint; - nVarint = sessionVarintGet(&p->in.aData[p->in.iNext], &p->nCol); -- nCopy -= nVarint; -- p->in.iNext += nVarint; -- nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy; -- p->tblhdr.nBuf = 0; -- sessionBufferGrow(&p->tblhdr, nByte, &rc); -+ if( p->nCol>0 ){ -+ nCopy -= nVarint; -+ p->in.iNext += nVarint; -+ nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy; -+ p->tblhdr.nBuf = 0; -+ sessionBufferGrow(&p->tblhdr, nByte, &rc); -+ }else{ -+ rc = SQLITE_CORRUPT_BKPT; -+ } - } - - if( rc==SQLITE_OK ){ -@@ -178750,7 +195846,8 @@ - static int sessionChangesetNext( - sqlite3_changeset_iter *p, /* Changeset iterator */ - u8 **paRec, /* If non-NULL, store record pointer here */ -- int *pnRec /* If non-NULL, store size of record here */ -+ int *pnRec, /* If non-NULL, store size of record here */ -+ int *pbNew /* If non-NULL, true if new table */ - ){ - int i; - u8 op; -@@ -178785,6 +195882,7 @@ - - op = p->in.aData[p->in.iNext++]; - while( op=='T' || op=='P' ){ -+ if( pbNew ) *pbNew = 1; - p->bPatchset = (op=='P'); - if( sessionChangesetReadTblhdr(p) ) return p->rc; - if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc; -@@ -178793,6 +195891,13 @@ - op = p->in.aData[p->in.iNext++]; - } - -+ if( p->zTab==0 || (p->bPatchset && p->bInvert) ){ -+ /* The first record in the changeset is not a table header. Must be a -+ ** corrupt changeset. */ -+ assert( p->in.iNext==1 || p->zTab ); -+ return (p->rc = SQLITE_CORRUPT_BKPT); -+ } -+ - p->op = op; - p->bIndirect = p->in.aData[p->in.iNext++]; - if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){ -@@ -178814,33 +195919,39 @@ - *paRec = &p->in.aData[p->in.iNext]; - p->in.iNext += *pnRec; - }else{ -+ sqlite3_value **apOld = (p->bInvert ? &p->apValue[p->nCol] : p->apValue); -+ sqlite3_value **apNew = (p->bInvert ? p->apValue : &p->apValue[p->nCol]); - - /* If this is an UPDATE or DELETE, read the old.* record. */ - if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){ - u8 *abPK = p->bPatchset ? p->abPK : 0; -- p->rc = sessionReadRecord(&p->in, p->nCol, abPK, p->apValue); -+ p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld); - if( p->rc!=SQLITE_OK ) return p->rc; - } - - /* If this is an INSERT or UPDATE, read the new.* record. */ - if( p->op!=SQLITE_DELETE ){ -- p->rc = sessionReadRecord(&p->in, p->nCol, 0, &p->apValue[p->nCol]); -+ p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew); - if( p->rc!=SQLITE_OK ) return p->rc; - } - -- if( p->bPatchset && p->op==SQLITE_UPDATE ){ -+ if( (p->bPatchset || p->bInvert) && p->op==SQLITE_UPDATE ){ - /* If this is an UPDATE that is part of a patchset, then all PK and - ** modified fields are present in the new.* record. The old.* record - ** is currently completely empty. This block shifts the PK fields from - ** new.* to old.*, to accommodate the code that reads these arrays. */ - for(i=0; i<p->nCol; i++){ -- assert( p->apValue[i]==0 ); -- assert( p->abPK[i]==0 || p->apValue[i+p->nCol] ); -+ assert( p->bPatchset==0 || p->apValue[i]==0 ); - if( p->abPK[i] ){ -+ assert( p->apValue[i]==0 ); - p->apValue[i] = p->apValue[i+p->nCol]; -+ if( p->apValue[i]==0 ) return (p->rc = SQLITE_CORRUPT_BKPT); - p->apValue[i+p->nCol] = 0; - } - } -+ }else if( p->bInvert ){ -+ if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE; -+ else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT; - } - } - -@@ -178856,7 +195967,7 @@ - ** callback by changeset_apply(). - */ - SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *p){ -- return sessionChangesetNext(p, 0, 0); -+ return sessionChangesetNext(p, 0, 0, 0); - } - - /* -@@ -179157,7 +196268,7 @@ - } - - assert( rc==SQLITE_OK ); -- if( xOutput && sOut.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){ -+ if( xOutput && sOut.nBuf>=sessions_strm_chunk_size ){ - rc = xOutput(pOut, sOut.aBuf, sOut.nBuf); - sOut.nBuf = 0; - if( rc!=SQLITE_OK ) goto finished_invert; -@@ -179232,9 +196343,12 @@ - int nCol; /* Size of azCol[] and abPK[] arrays */ - const char **azCol; /* Array of column names */ - u8 *abPK; /* Boolean array - true if column is in PK */ -- -+ int bStat1; /* True if table is sqlite_stat1 */ - int bDeferConstraints; /* True to defer constraints */ - SessionBuffer constraints; /* Deferred constraints are stored here */ -+ SessionBuffer rebase; /* Rebase information (if any) here */ -+ u8 bRebaseStarted; /* If table header is already in rebase */ -+ u8 bRebase; /* True to collect rebase information */ - }; - - /* -@@ -179402,6 +196516,7 @@ - return rc; - } - -+ - /* - ** Formulate and prepare an SQL statement to query table zTab by primary - ** key. Assuming the following table structure: -@@ -179463,7 +196578,47 @@ - return rc; - } - -+static int sessionPrepare(sqlite3 *db, sqlite3_stmt **pp, const char *zSql){ -+ return sqlite3_prepare_v2(db, zSql, -1, pp, 0); -+} -+ - /* -+** Prepare statements for applying changes to the sqlite_stat1 table. -+** These are similar to those created by sessionSelectRow(), -+** sessionInsertRow(), sessionUpdateRow() and sessionDeleteRow() for -+** other tables. -+*/ -+static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){ -+ int rc = sessionSelectRow(db, "sqlite_stat1", p); -+ if( rc==SQLITE_OK ){ -+ rc = sessionPrepare(db, &p->pInsert, -+ "INSERT INTO main.sqlite_stat1 VALUES(?1, " -+ "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END, " -+ "?3)" -+ ); -+ } -+ if( rc==SQLITE_OK ){ -+ rc = sessionPrepare(db, &p->pUpdate, -+ "UPDATE main.sqlite_stat1 SET " -+ "tbl = CASE WHEN ?2 THEN ?3 ELSE tbl END, " -+ "idx = CASE WHEN ?5 THEN ?6 ELSE idx END, " -+ "stat = CASE WHEN ?8 THEN ?9 ELSE stat END " -+ "WHERE tbl=?1 AND idx IS " -+ "CASE WHEN length(?4)=0 AND typeof(?4)='blob' THEN NULL ELSE ?4 END " -+ "AND (?10 OR ?8=0 OR stat IS ?7)" -+ ); -+ } -+ if( rc==SQLITE_OK ){ -+ rc = sessionPrepare(db, &p->pDelete, -+ "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS " -+ "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END " -+ "AND (?4 OR stat IS ?3)" -+ ); -+ } -+ return rc; -+} -+ -+/* - ** A wrapper around sqlite3_bind_value() that detects an extra problem. - ** See comments in the body of this function for details. - */ -@@ -179520,7 +196675,13 @@ - if( !abPK || abPK[i] ){ - sqlite3_value *pVal; - (void)xValue(pIter, i, &pVal); -- rc = sessionBindValue(pStmt, i+1, pVal); -+ if( pVal==0 ){ -+ /* The value in the changeset was "undefined". This indicates a -+ ** corrupt changeset blob. */ -+ rc = SQLITE_CORRUPT_BKPT; -+ }else{ -+ rc = sessionBindValue(pStmt, i+1, pVal); -+ } - } - } - return rc; -@@ -179569,6 +196730,55 @@ - } - - /* -+** This function is called from within sqlite3changset_apply_v2() when -+** a conflict is encountered and resolved using conflict resolution -+** mode eType (either SQLITE_CHANGESET_OMIT or SQLITE_CHANGESET_REPLACE).. -+** It adds a conflict resolution record to the buffer in -+** SessionApplyCtx.rebase, which will eventually be returned to the caller -+** of apply_v2() as the "rebase" buffer. -+** -+** Return SQLITE_OK if successful, or an SQLite error code otherwise. -+*/ -+static int sessionRebaseAdd( -+ SessionApplyCtx *p, /* Apply context */ -+ int eType, /* Conflict resolution (OMIT or REPLACE) */ -+ sqlite3_changeset_iter *pIter /* Iterator pointing at current change */ -+){ -+ int rc = SQLITE_OK; -+ if( p->bRebase ){ -+ int i; -+ int eOp = pIter->op; -+ if( p->bRebaseStarted==0 ){ -+ /* Append a table-header to the rebase buffer */ -+ const char *zTab = pIter->zTab; -+ sessionAppendByte(&p->rebase, 'T', &rc); -+ sessionAppendVarint(&p->rebase, p->nCol, &rc); -+ sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc); -+ sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc); -+ p->bRebaseStarted = 1; -+ } -+ -+ assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT ); -+ assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE ); -+ -+ sessionAppendByte(&p->rebase, -+ (eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc -+ ); -+ sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc); -+ for(i=0; i<p->nCol; i++){ -+ sqlite3_value *pVal = 0; -+ if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){ -+ sqlite3changeset_old(pIter, i, &pVal); -+ }else{ -+ sqlite3changeset_new(pIter, i, &pVal); -+ } -+ sessionAppendValue(&p->rebase, pVal, &rc); -+ } -+ } -+ return rc; -+} -+ -+/* - ** Invoke the conflict handler for the change that the changeset iterator - ** currently points to. - ** -@@ -179643,7 +196853,7 @@ - u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent]; - int nBlob = pIter->in.iNext - pIter->in.iCurrent; - sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc); -- res = SQLITE_CHANGESET_OMIT; -+ return SQLITE_OK; - }else{ - /* No other row with the new.* primary key. */ - res = xConflict(pCtx, eType+1, pIter); -@@ -179669,6 +196879,9 @@ - rc = SQLITE_MISUSE; - break; - } -+ if( rc==SQLITE_OK ){ -+ rc = sessionRebaseAdd(p, res, pIter); -+ } - } - - return rc; -@@ -179793,11 +197006,25 @@ - - }else{ - assert( op==SQLITE_INSERT ); -- rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert); -- if( rc!=SQLITE_OK ) return rc; -+ if( p->bStat1 ){ -+ /* Check if there is a conflicting row. For sqlite_stat1, this needs -+ ** to be done using a SELECT, as there is no PRIMARY KEY in the -+ ** database schema to throw an exception if a duplicate is inserted. */ -+ rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect); -+ if( rc==SQLITE_ROW ){ -+ rc = SQLITE_CONSTRAINT; -+ sqlite3_reset(p->pSelect); -+ } -+ } - -- sqlite3_step(p->pInsert); -- rc = sqlite3_reset(p->pInsert); -+ if( rc==SQLITE_OK ){ -+ rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert); -+ if( rc!=SQLITE_OK ) return rc; -+ -+ sqlite3_step(p->pInsert); -+ rc = sqlite3_reset(p->pInsert); -+ } -+ - if( (rc&0xff)==SQLITE_CONSTRAINT ){ - rc = sessionConflictHandler( - SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace -@@ -179830,42 +197057,42 @@ - int rc; - - rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, &bReplace, &bRetry); -- assert( rc==SQLITE_OK || (bRetry==0 && bReplace==0) ); -- -- /* If the bRetry flag is set, the change has not been applied due to an -- ** SQLITE_CHANGESET_DATA problem (i.e. this is an UPDATE or DELETE and -- ** a row with the correct PK is present in the db, but one or more other -- ** fields do not contain the expected values) and the conflict handler -- ** returned SQLITE_CHANGESET_REPLACE. In this case retry the operation, -- ** but pass NULL as the final argument so that sessionApplyOneOp() ignores -- ** the SQLITE_CHANGESET_DATA problem. */ -- if( bRetry ){ -- assert( pIter->op==SQLITE_UPDATE || pIter->op==SQLITE_DELETE ); -- rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0); -- } -- -- /* If the bReplace flag is set, the change is an INSERT that has not -- ** been performed because the database already contains a row with the -- ** specified primary key and the conflict handler returned -- ** SQLITE_CHANGESET_REPLACE. In this case remove the conflicting row -- ** before reattempting the INSERT. */ -- else if( bReplace ){ -- assert( pIter->op==SQLITE_INSERT ); -- rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0); -- if( rc==SQLITE_OK ){ -- rc = sessionBindRow(pIter, -- sqlite3changeset_new, pApply->nCol, pApply->abPK, pApply->pDelete); -- sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1); -- } -- if( rc==SQLITE_OK ){ -- sqlite3_step(pApply->pDelete); -- rc = sqlite3_reset(pApply->pDelete); -- } -- if( rc==SQLITE_OK ){ -+ if( rc==SQLITE_OK ){ -+ /* If the bRetry flag is set, the change has not been applied due to an -+ ** SQLITE_CHANGESET_DATA problem (i.e. this is an UPDATE or DELETE and -+ ** a row with the correct PK is present in the db, but one or more other -+ ** fields do not contain the expected values) and the conflict handler -+ ** returned SQLITE_CHANGESET_REPLACE. In this case retry the operation, -+ ** but pass NULL as the final argument so that sessionApplyOneOp() ignores -+ ** the SQLITE_CHANGESET_DATA problem. */ -+ if( bRetry ){ -+ assert( pIter->op==SQLITE_UPDATE || pIter->op==SQLITE_DELETE ); - rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0); - } -- if( rc==SQLITE_OK ){ -- rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0); -+ -+ /* If the bReplace flag is set, the change is an INSERT that has not -+ ** been performed because the database already contains a row with the -+ ** specified primary key and the conflict handler returned -+ ** SQLITE_CHANGESET_REPLACE. In this case remove the conflicting row -+ ** before reattempting the INSERT. */ -+ else if( bReplace ){ -+ assert( pIter->op==SQLITE_INSERT ); -+ rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0); -+ if( rc==SQLITE_OK ){ -+ rc = sessionBindRow(pIter, -+ sqlite3changeset_new, pApply->nCol, pApply->abPK, pApply->pDelete); -+ sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1); -+ } -+ if( rc==SQLITE_OK ){ -+ sqlite3_step(pApply->pDelete); -+ rc = sqlite3_reset(pApply->pDelete); -+ } -+ if( rc==SQLITE_OK ){ -+ rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0); -+ } -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0); -+ } - } - } - -@@ -179890,7 +197117,7 @@ - SessionBuffer cons = pApply->constraints; - memset(&pApply->constraints, 0, sizeof(SessionBuffer)); - -- rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf); -+ rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf, 0); - if( rc==SQLITE_OK ){ - int nByte = 2*pApply->nCol*sizeof(sqlite3_value*); - int rc2; -@@ -179941,10 +197168,12 @@ - int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ - sqlite3_changeset_iter *p /* Handle describing change and conflict */ - ), -- void *pCtx /* First argument passed to xConflict */ -+ void *pCtx, /* First argument passed to xConflict */ -+ void **ppRebase, int *pnRebase, /* OUT: Rebase information */ -+ int flags /* SESSION_APPLY_XXX flags */ - ){ - int schemaMismatch = 0; -- int rc; /* Return code */ -+ int rc = SQLITE_OK; /* Return code */ - const char *zTab = 0; /* Name of current table */ - int nTab = 0; /* Result of sqlite3Strlen30(zTab) */ - SessionApplyCtx sApply; /* changeset_apply() context object */ -@@ -179954,8 +197183,11 @@ - - pIter->in.bNoDiscard = 1; - memset(&sApply, 0, sizeof(sApply)); -+ sApply.bRebase = (ppRebase && pnRebase); - sqlite3_mutex_enter(sqlite3_db_mutex(db)); -- rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); -+ if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ -+ rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); -+ } - if( rc==SQLITE_OK ){ - rc = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 1", 0, 0, 0); - } -@@ -179979,9 +197211,18 @@ - sqlite3_finalize(sApply.pUpdate); - sqlite3_finalize(sApply.pInsert); - sqlite3_finalize(sApply.pSelect); -- memset(&sApply, 0, sizeof(sApply)); - sApply.db = db; -+ sApply.pDelete = 0; -+ sApply.pUpdate = 0; -+ sApply.pInsert = 0; -+ sApply.pSelect = 0; -+ sApply.nCol = 0; -+ sApply.azCol = 0; -+ sApply.abPK = 0; -+ sApply.bStat1 = 0; - sApply.bDeferConstraints = 1; -+ sApply.bRebaseStarted = 0; -+ memset(&sApply.constraints, 0, sizeof(SessionBuffer)); - - /* If an xFilter() callback was specified, invoke it now. If the - ** xFilter callback returns zero, skip this table. If it returns -@@ -180030,12 +197271,20 @@ - } - else{ - sApply.nCol = nCol; -- if((rc = sessionSelectRow(db, zTab, &sApply)) -- || (rc = sessionUpdateRow(db, zTab, &sApply)) -- || (rc = sessionDeleteRow(db, zTab, &sApply)) -- || (rc = sessionInsertRow(db, zTab, &sApply)) -- ){ -- break; -+ if( 0==sqlite3_stricmp(zTab, "sqlite_stat1") ){ -+ if( (rc = sessionStat1Sql(db, &sApply) ) ){ -+ break; -+ } -+ sApply.bStat1 = 1; -+ }else{ -+ if((rc = sessionSelectRow(db, zTab, &sApply)) -+ || (rc = sessionUpdateRow(db, zTab, &sApply)) -+ || (rc = sessionDeleteRow(db, zTab, &sApply)) -+ || (rc = sessionInsertRow(db, zTab, &sApply)) -+ ){ -+ break; -+ } -+ sApply.bStat1 = 0; - } - } - nTab = sqlite3Strlen30(zTab); -@@ -180076,13 +197325,21 @@ - } - sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0); - -- if( rc==SQLITE_OK ){ -- rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); -- }else{ -- sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0); -- sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); -+ if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ -+ if( rc==SQLITE_OK ){ -+ rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); -+ }else{ -+ sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0); -+ sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); -+ } - } - -+ assert( sApply.bRebase || sApply.rebase.nBuf==0 ); -+ if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){ -+ *ppRebase = (void*)sApply.rebase.aBuf; -+ *pnRebase = sApply.rebase.nBuf; -+ sApply.rebase.aBuf = 0; -+ } - sqlite3_finalize(sApply.pInsert); - sqlite3_finalize(sApply.pDelete); - sqlite3_finalize(sApply.pUpdate); -@@ -180089,11 +197346,44 @@ - sqlite3_finalize(sApply.pSelect); - sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ - sqlite3_free((char*)sApply.constraints.aBuf); -+ sqlite3_free((char*)sApply.rebase.aBuf); - sqlite3_mutex_leave(sqlite3_db_mutex(db)); - return rc; - } - - /* -+** Apply the changeset passed via pChangeset/nChangeset to the main -+** database attached to handle "db". -+*/ -+SQLITE_API int sqlite3changeset_apply_v2( -+ sqlite3 *db, /* Apply change to "main" db of this handle */ -+ int nChangeset, /* Size of changeset in bytes */ -+ void *pChangeset, /* Changeset blob */ -+ int(*xFilter)( -+ void *pCtx, /* Copy of sixth arg to _apply() */ -+ const char *zTab /* Table name */ -+ ), -+ int(*xConflict)( -+ void *pCtx, /* Copy of sixth arg to _apply() */ -+ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ -+ sqlite3_changeset_iter *p /* Handle describing change and conflict */ -+ ), -+ void *pCtx, /* First argument passed to xConflict */ -+ void **ppRebase, int *pnRebase, -+ int flags -+){ -+ sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ -+ int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); -+ int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset,bInverse); -+ if( rc==SQLITE_OK ){ -+ rc = sessionChangesetApply( -+ db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags -+ ); -+ } -+ return rc; -+} -+ -+/* - ** Apply the changeset passed via pChangeset/nChangeset to the main database - ** attached to handle "db". Invoke the supplied conflict handler callback - ** to resolve any conflicts encountered while applying the change. -@@ -180113,12 +197403,9 @@ - ), - void *pCtx /* First argument passed to xConflict */ - ){ -- sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ -- int rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset); -- if( rc==SQLITE_OK ){ -- rc = sessionChangesetApply(db, pIter, xFilter, xConflict, pCtx); -- } -- return rc; -+ return sqlite3changeset_apply_v2( -+ db, nChangeset, pChangeset, xFilter, xConflict, pCtx, 0, 0, 0 -+ ); - } - - /* -@@ -180126,7 +197413,7 @@ - ** attached to handle "db". Invoke the supplied conflict handler callback - ** to resolve any conflicts encountered while applying the change. - */ --SQLITE_API int sqlite3changeset_apply_strm( -+SQLITE_API int sqlite3changeset_apply_v2_strm( - sqlite3 *db, /* Apply change to "main" db of this handle */ - int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ - void *pIn, /* First arg for xInput */ -@@ -180139,15 +197426,39 @@ - int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ - sqlite3_changeset_iter *p /* Handle describing change and conflict */ - ), -- void *pCtx /* First argument passed to xConflict */ -+ void *pCtx, /* First argument passed to xConflict */ -+ void **ppRebase, int *pnRebase, -+ int flags - ){ - sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ -- int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn); -+ int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); -+ int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse); - if( rc==SQLITE_OK ){ -- rc = sessionChangesetApply(db, pIter, xFilter, xConflict, pCtx); -+ rc = sessionChangesetApply( -+ db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags -+ ); - } - return rc; - } -+SQLITE_API int sqlite3changeset_apply_strm( -+ sqlite3 *db, /* Apply change to "main" db of this handle */ -+ int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ -+ void *pIn, /* First arg for xInput */ -+ int(*xFilter)( -+ void *pCtx, /* Copy of sixth arg to _apply() */ -+ const char *zTab /* Table name */ -+ ), -+ int(*xConflict)( -+ void *pCtx, /* Copy of sixth arg to _apply() */ -+ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ -+ sqlite3_changeset_iter *p /* Handle describing change and conflict */ -+ ), -+ void *pCtx /* First argument passed to xConflict */ -+){ -+ return sqlite3changeset_apply_v2_strm( -+ db, xInput, pIn, xFilter, xConflict, pCtx, 0, 0, 0 -+ ); -+} - - /* - ** sqlite3_changegroup handle. -@@ -180165,6 +197476,7 @@ - */ - static int sessionChangeMerge( - SessionTable *pTab, /* Table structure */ -+ int bRebase, /* True for a rebase hash-table */ - int bPatchset, /* True for patchsets */ - SessionChange *pExist, /* Existing change */ - int op2, /* Second change operation */ -@@ -180174,6 +197486,7 @@ - SessionChange **ppNew /* OUT: Merged change */ - ){ - SessionChange *pNew = 0; -+ int rc = SQLITE_OK; - - if( !pExist ){ - pNew = (SessionChange *)sqlite3_malloc(sizeof(SessionChange) + nRec); -@@ -180183,9 +197496,66 @@ - memset(pNew, 0, sizeof(SessionChange)); - pNew->op = op2; - pNew->bIndirect = bIndirect; -- pNew->nRecord = nRec; - pNew->aRecord = (u8*)&pNew[1]; -- memcpy(pNew->aRecord, aRec, nRec); -+ if( bIndirect==0 || bRebase==0 ){ -+ pNew->nRecord = nRec; -+ memcpy(pNew->aRecord, aRec, nRec); -+ }else{ -+ int i; -+ u8 *pIn = aRec; -+ u8 *pOut = pNew->aRecord; -+ for(i=0; i<pTab->nCol; i++){ -+ int nIn = sessionSerialLen(pIn); -+ if( *pIn==0 ){ -+ *pOut++ = 0; -+ }else if( pTab->abPK[i]==0 ){ -+ *pOut++ = 0xFF; -+ }else{ -+ memcpy(pOut, pIn, nIn); -+ pOut += nIn; -+ } -+ pIn += nIn; -+ } -+ pNew->nRecord = pOut - pNew->aRecord; -+ } -+ }else if( bRebase ){ -+ if( pExist->op==SQLITE_DELETE && pExist->bIndirect ){ -+ *ppNew = pExist; -+ }else{ -+ int nByte = nRec + pExist->nRecord + sizeof(SessionChange); -+ pNew = (SessionChange*)sqlite3_malloc(nByte); -+ if( pNew==0 ){ -+ rc = SQLITE_NOMEM; -+ }else{ -+ int i; -+ u8 *a1 = pExist->aRecord; -+ u8 *a2 = aRec; -+ u8 *pOut; -+ -+ memset(pNew, 0, nByte); -+ pNew->bIndirect = bIndirect || pExist->bIndirect; -+ pNew->op = op2; -+ pOut = pNew->aRecord = (u8*)&pNew[1]; -+ -+ for(i=0; i<pTab->nCol; i++){ -+ int n1 = sessionSerialLen(a1); -+ int n2 = sessionSerialLen(a2); -+ if( *a1==0xFF || (pTab->abPK[i]==0 && bIndirect) ){ -+ *pOut++ = 0xFF; -+ }else if( *a2==0 ){ -+ memcpy(pOut, a1, n1); -+ pOut += n1; -+ }else{ -+ memcpy(pOut, a2, n2); -+ pOut += n2; -+ } -+ a1 += n1; -+ a2 += n2; -+ } -+ pNew->nRecord = pOut - pNew->aRecord; -+ } -+ sqlite3_free(pExist); -+ } - }else{ - int op1 = pExist->op; - -@@ -180279,7 +197649,7 @@ - } - - *ppNew = pNew; -- return SQLITE_OK; -+ return rc; - } - - /* -@@ -180288,7 +197658,8 @@ - */ - static int sessionChangesetToHash( - sqlite3_changeset_iter *pIter, /* Iterator to read from */ -- sqlite3_changegroup *pGrp /* Changegroup object to add changeset to */ -+ sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */ -+ int bRebase /* True if hash table is for rebasing */ - ){ - u8 *aRec; - int nRec; -@@ -180295,8 +197666,7 @@ - int rc = SQLITE_OK; - SessionTable *pTab = 0; - -- -- while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec) ){ -+ while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, 0) ){ - const char *zNew; - int nCol; - int op; -@@ -180376,7 +197746,7 @@ - } - } - -- rc = sessionChangeMerge(pTab, -+ rc = sessionChangeMerge(pTab, bRebase, - pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange - ); - if( rc ) break; -@@ -180435,13 +197805,12 @@ - sessionAppendByte(&buf, p->op, &rc); - sessionAppendByte(&buf, p->bIndirect, &rc); - sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); -+ if( rc==SQLITE_OK && xOutput && buf.nBuf>=sessions_strm_chunk_size ){ -+ rc = xOutput(pOut, buf.aBuf, buf.nBuf); -+ buf.nBuf = 0; -+ } - } - } -- -- if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){ -- rc = xOutput(pOut, buf.aBuf, buf.nBuf); -- buf.nBuf = 0; -- } - } - - if( rc==SQLITE_OK ){ -@@ -180484,7 +197853,7 @@ - - rc = sqlite3changeset_start(&pIter, nData, pData); - if( rc==SQLITE_OK ){ -- rc = sessionChangesetToHash(pIter, pGrp); -+ rc = sessionChangesetToHash(pIter, pGrp, 0); - } - sqlite3changeset_finalize(pIter); - return rc; -@@ -180515,7 +197884,7 @@ - - rc = sqlite3changeset_start_strm(&pIter, xInput, pIn); - if( rc==SQLITE_OK ){ -- rc = sessionChangesetToHash(pIter, pGrp); -+ rc = sessionChangesetToHash(pIter, pGrp, 0); - } - sqlite3changeset_finalize(pIter); - return rc; -@@ -180600,2439 +197969,373 @@ - return rc; - } - --#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */ -- --/************** End of sqlite3session.c **************************************/ --/************** Begin file json1.c *******************************************/ - /* --** 2015-08-12 --** --** 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 JSON functions. The interface is --** modeled after MySQL JSON functions: --** --** https://dev.mysql.com/doc/refman/5.7/en/json.html --** --** For the time being, all JSON is stored as pure text. (We might add --** a JSONB type in the future which stores a binary encoding of JSON in --** a BLOB, but there is no support for JSONB in the current implementation. --** This implementation parses JSON text at 250 MB/s, so it is hard to see --** how JSONB might improve on that.) -+** Changeset rebaser handle. - */ --#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) --#if !defined(SQLITEINT_H) --/* #include "sqlite3ext.h" */ --#endif --SQLITE_EXTENSION_INIT1 --/* #include <assert.h> */ --/* #include <string.h> */ --/* #include <stdlib.h> */ --/* #include <stdarg.h> */ -- --/* Mark a function parameter as unused, to suppress nuisance compiler --** warnings. */ --#ifndef UNUSED_PARAM --# define UNUSED_PARAM(X) (void)(X) --#endif -- --#ifndef LARGEST_INT64 --# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) --# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) --#endif -- --/* --** Versions of isspace(), isalnum() and isdigit() to which it is safe --** to pass signed char values. --*/ --#ifdef sqlite3Isdigit -- /* Use the SQLite core versions if this routine is part of the -- ** SQLite amalgamation */ --# define safe_isdigit(x) sqlite3Isdigit(x) --# define safe_isalnum(x) sqlite3Isalnum(x) --# define safe_isxdigit(x) sqlite3Isxdigit(x) --#else -- /* Use the standard library for separate compilation */ --#include <ctype.h> /* amalgamator: keep */ --# define safe_isdigit(x) isdigit((unsigned char)(x)) --# define safe_isalnum(x) isalnum((unsigned char)(x)) --# define safe_isxdigit(x) isxdigit((unsigned char)(x)) --#endif -- --/* --** Growing our own isspace() routine this way is twice as fast as --** the library isspace() function, resulting in a 7% overall performance --** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). --*/ --static const char jsonIsSpace[] = { -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+struct sqlite3_rebaser { -+ sqlite3_changegroup grp; /* Hash table */ - }; --#define safe_isspace(x) (jsonIsSpace[(unsigned char)x]) - --#ifndef SQLITE_AMALGAMATION -- /* Unsigned integer types. These are already defined in the sqliteInt.h, -- ** but the definitions need to be repeated for separate compilation. */ -- typedef sqlite3_uint64 u64; -- typedef unsigned int u32; -- typedef unsigned short int u16; -- typedef unsigned char u8; --#endif -- --/* Objects */ --typedef struct JsonString JsonString; --typedef struct JsonNode JsonNode; --typedef struct JsonParse JsonParse; -- --/* An instance of this object represents a JSON string --** under construction. Really, this is a generic string accumulator --** that can be and is used to create strings other than JSON. --*/ --struct JsonString { -- sqlite3_context *pCtx; /* Function context - put error messages here */ -- char *zBuf; /* Append JSON content here */ -- u64 nAlloc; /* Bytes of storage available in zBuf[] */ -- u64 nUsed; /* Bytes of zBuf[] currently used */ -- u8 bStatic; /* True if zBuf is static space */ -- u8 bErr; /* True if an error has been encountered */ -- char zSpace[100]; /* Initial static space */ --}; -- --/* JSON type values --*/ --#define JSON_NULL 0 --#define JSON_TRUE 1 --#define JSON_FALSE 2 --#define JSON_INT 3 --#define JSON_REAL 4 --#define JSON_STRING 5 --#define JSON_ARRAY 6 --#define JSON_OBJECT 7 -- --/* The "subtype" set for JSON values */ --#define JSON_SUBTYPE 74 /* Ascii for "J" */ -- - /* --** Names of the various JSON types: -+** Buffers a1 and a2 must both contain a sessions module record nCol -+** fields in size. This function appends an nCol sessions module -+** record to buffer pBuf that is a copy of a1, except that for -+** each field that is undefined in a1[], swap in the field from a2[]. - */ --static const char * const jsonType[] = { -- "null", "true", "false", "integer", "real", "text", "array", "object" --}; -- --/* Bit values for the JsonNode.jnFlag field --*/ --#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */ --#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */ --#define JNODE_REMOVE 0x04 /* Do not output */ --#define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */ --#define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */ --#define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */ --#define JNODE_LABEL 0x40 /* Is a label of an object */ -- -- --/* A single node of parsed JSON --*/ --struct JsonNode { -- u8 eType; /* One of the JSON_ type values */ -- u8 jnFlags; /* JNODE flags */ -- u32 n; /* Bytes of content, or number of sub-nodes */ -- union { -- const char *zJContent; /* Content for INT, REAL, and STRING */ -- u32 iAppend; /* More terms for ARRAY and OBJECT */ -- u32 iKey; /* Key for ARRAY objects in json_tree() */ -- u32 iReplace; /* Replacement content for JNODE_REPLACE */ -- JsonNode *pPatch; /* Node chain of patch for JNODE_PATCH */ -- } u; --}; -- --/* A completely parsed JSON string --*/ --struct JsonParse { -- u32 nNode; /* Number of slots of aNode[] used */ -- u32 nAlloc; /* Number of slots of aNode[] allocated */ -- JsonNode *aNode; /* Array of nodes containing the parse */ -- const char *zJson; /* Original JSON string */ -- u32 *aUp; /* Index of parent of each node */ -- u8 oom; /* Set to true if out of memory */ -- u8 nErr; /* Number of errors seen */ -- u16 iDepth; /* Nesting depth */ -- int nJson; /* Length of the zJson string in bytes */ --}; -- --/* --** Maximum nesting depth of JSON for this implementation. --** --** This limit is needed to avoid a stack overflow in the recursive --** descent parser. A depth of 2000 is far deeper than any sane JSON --** should go. --*/ --#define JSON_MAX_DEPTH 2000 -- --/************************************************************************** --** Utility routines for dealing with JsonString objects --**************************************************************************/ -- --/* Set the JsonString object to an empty string --*/ --static void jsonZero(JsonString *p){ -- p->zBuf = p->zSpace; -- p->nAlloc = sizeof(p->zSpace); -- p->nUsed = 0; -- p->bStatic = 1; --} -- --/* Initialize the JsonString object --*/ --static void jsonInit(JsonString *p, sqlite3_context *pCtx){ -- p->pCtx = pCtx; -- p->bErr = 0; -- jsonZero(p); --} -- -- --/* Free all allocated memory and reset the JsonString object back to its --** initial state. --*/ --static void jsonReset(JsonString *p){ -- if( !p->bStatic ) sqlite3_free(p->zBuf); -- jsonZero(p); --} -- -- --/* Report an out-of-memory (OOM) condition --*/ --static void jsonOom(JsonString *p){ -- p->bErr = 1; -- sqlite3_result_error_nomem(p->pCtx); -- jsonReset(p); --} -- --/* Enlarge pJson->zBuf so that it can hold at least N more bytes. --** Return zero on success. Return non-zero on an OOM error --*/ --static int jsonGrow(JsonString *p, u32 N){ -- u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10; -- char *zNew; -- if( p->bStatic ){ -- if( p->bErr ) return 1; -- zNew = sqlite3_malloc64(nTotal); -- if( zNew==0 ){ -- jsonOom(p); -- return SQLITE_NOMEM; -- } -- memcpy(zNew, p->zBuf, (size_t)p->nUsed); -- p->zBuf = zNew; -- p->bStatic = 0; -- }else{ -- zNew = sqlite3_realloc64(p->zBuf, nTotal); -- if( zNew==0 ){ -- jsonOom(p); -- return SQLITE_NOMEM; -- } -- p->zBuf = zNew; -- } -- p->nAlloc = nTotal; -- return SQLITE_OK; --} -- --/* Append N bytes from zIn onto the end of the JsonString string. --*/ --static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ -- if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return; -- memcpy(p->zBuf+p->nUsed, zIn, N); -- p->nUsed += N; --} -- --/* Append formatted text (not to exceed N bytes) to the JsonString. --*/ --static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ -- va_list ap; -- if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return; -- va_start(ap, zFormat); -- sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap); -- va_end(ap); -- p->nUsed += (int)strlen(p->zBuf+p->nUsed); --} -- --/* Append a single character --*/ --static void jsonAppendChar(JsonString *p, char c){ -- if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return; -- p->zBuf[p->nUsed++] = c; --} -- --/* Append a comma separator to the output buffer, if the previous --** character is not '[' or '{'. --*/ --static void jsonAppendSeparator(JsonString *p){ -- char c; -- if( p->nUsed==0 ) return; -- c = p->zBuf[p->nUsed-1]; -- if( c!='[' && c!='{' ) jsonAppendChar(p, ','); --} -- --/* Append the N-byte string in zIn to the end of the JsonString string --** under construction. Enclose the string in "..." and escape --** any double-quotes or backslash characters contained within the --** string. --*/ --static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ -- u32 i; -- if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return; -- p->zBuf[p->nUsed++] = '"'; -- for(i=0; i<N; i++){ -- unsigned char c = ((unsigned const char*)zIn)[i]; -- if( c=='"' || c=='\\' ){ -- json_simple_escape: -- if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; -- p->zBuf[p->nUsed++] = '\\'; -- }else if( c<=0x1f ){ -- static const char aSpecial[] = { -- 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -- }; -- assert( sizeof(aSpecial)==32 ); -- assert( aSpecial['\b']=='b' ); -- assert( aSpecial['\f']=='f' ); -- assert( aSpecial['\n']=='n' ); -- assert( aSpecial['\r']=='r' ); -- assert( aSpecial['\t']=='t' ); -- if( aSpecial[c] ){ -- c = aSpecial[c]; -- goto json_simple_escape; -- } -- if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return; -- p->zBuf[p->nUsed++] = '\\'; -- p->zBuf[p->nUsed++] = 'u'; -- p->zBuf[p->nUsed++] = '0'; -- p->zBuf[p->nUsed++] = '0'; -- p->zBuf[p->nUsed++] = '0' + (c>>4); -- c = "0123456789abcdef"[c&0xf]; -- } -- p->zBuf[p->nUsed++] = c; -- } -- p->zBuf[p->nUsed++] = '"'; -- assert( p->nUsed<p->nAlloc ); --} -- --/* --** Append a function parameter value to the JSON string under --** construction. --*/ --static void jsonAppendValue( -- JsonString *p, /* Append to this JSON string */ -- sqlite3_value *pValue /* Value to append */ -+static void sessionAppendRecordMerge( -+ SessionBuffer *pBuf, /* Buffer to append to */ -+ int nCol, /* Number of columns in each record */ -+ u8 *a1, int n1, /* Record 1 */ -+ u8 *a2, int n2, /* Record 2 */ -+ int *pRc /* IN/OUT: error code */ - ){ -- switch( sqlite3_value_type(pValue) ){ -- case SQLITE_NULL: { -- jsonAppendRaw(p, "null", 4); -- break; -- } -- case SQLITE_INTEGER: -- case SQLITE_FLOAT: { -- const char *z = (const char*)sqlite3_value_text(pValue); -- u32 n = (u32)sqlite3_value_bytes(pValue); -- jsonAppendRaw(p, z, n); -- break; -- } -- case SQLITE_TEXT: { -- const char *z = (const char*)sqlite3_value_text(pValue); -- u32 n = (u32)sqlite3_value_bytes(pValue); -- if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){ -- jsonAppendRaw(p, z, n); -+ sessionBufferGrow(pBuf, n1+n2, pRc); -+ if( *pRc==SQLITE_OK ){ -+ int i; -+ u8 *pOut = &pBuf->aBuf[pBuf->nBuf]; -+ for(i=0; i<nCol; i++){ -+ int nn1 = sessionSerialLen(a1); -+ int nn2 = sessionSerialLen(a2); -+ if( *a1==0 || *a1==0xFF ){ -+ memcpy(pOut, a2, nn2); -+ pOut += nn2; - }else{ -- jsonAppendString(p, z, n); -+ memcpy(pOut, a1, nn1); -+ pOut += nn1; - } -- break; -+ a1 += nn1; -+ a2 += nn2; - } -- default: { -- if( p->bErr==0 ){ -- sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); -- p->bErr = 2; -- jsonReset(p); -- } -- break; -- } -- } --} - -- --/* Make the JSON in p the result of the SQL function. --*/ --static void jsonResult(JsonString *p){ -- if( p->bErr==0 ){ -- sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, -- p->bStatic ? SQLITE_TRANSIENT : sqlite3_free, -- SQLITE_UTF8); -- jsonZero(p); -+ pBuf->nBuf = pOut-pBuf->aBuf; -+ assert( pBuf->nBuf<=pBuf->nAlloc ); - } -- assert( p->bStatic ); - } - --/************************************************************************** --** Utility routines for dealing with JsonNode and JsonParse objects --**************************************************************************/ -- - /* --** Return the number of consecutive JsonNode slots need to represent --** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and --** OBJECT types, the number might be larger. -+** This function is called when rebasing a local UPDATE change against one -+** or more remote UPDATE changes. The aRec/nRec buffer contains the current -+** old.* and new.* records for the change. The rebase buffer (a single -+** record) is in aChange/nChange. The rebased change is appended to buffer -+** pBuf. - ** --** Appended elements are not counted. The value returned is the number --** by which the JsonNode counter should increment in order to go to the --** next peer value. -+** Rebasing the UPDATE involves: -+** -+** * Removing any changes to fields for which the corresponding field -+** in the rebase buffer is set to "replaced" (type 0xFF). If this -+** means the UPDATE change updates no fields, nothing is appended -+** to the output buffer. -+** -+** * For each field modified by the local change for which the -+** corresponding field in the rebase buffer is not "undefined" (0x00) -+** or "replaced" (0xFF), the old.* value is replaced by the value -+** in the rebase buffer. - */ --static u32 jsonNodeSize(JsonNode *pNode){ -- return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1; --} -- --/* --** Reclaim all memory allocated by a JsonParse object. But do not --** delete the JsonParse object itself. --*/ --static void jsonParseReset(JsonParse *pParse){ -- sqlite3_free(pParse->aNode); -- pParse->aNode = 0; -- pParse->nNode = 0; -- pParse->nAlloc = 0; -- sqlite3_free(pParse->aUp); -- pParse->aUp = 0; --} -- --/* --** Free a JsonParse object that was obtained from sqlite3_malloc(). --*/ --static void jsonParseFree(JsonParse *pParse){ -- jsonParseReset(pParse); -- sqlite3_free(pParse); --} -- --/* --** Convert the JsonNode pNode into a pure JSON string and --** append to pOut. Subsubstructure is also included. Return --** the number of JsonNode objects that are encoded. --*/ --static void jsonRenderNode( -- JsonNode *pNode, /* The node to render */ -- JsonString *pOut, /* Write JSON here */ -- sqlite3_value **aReplace /* Replacement values */ -+static void sessionAppendPartialUpdate( -+ SessionBuffer *pBuf, /* Append record here */ -+ sqlite3_changeset_iter *pIter, /* Iterator pointed at local change */ -+ u8 *aRec, int nRec, /* Local change */ -+ u8 *aChange, int nChange, /* Record to rebase against */ -+ int *pRc /* IN/OUT: Return Code */ - ){ -- if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){ -- if( pNode->jnFlags & JNODE_REPLACE ){ -- jsonAppendValue(pOut, aReplace[pNode->u.iReplace]); -- return; -- } -- pNode = pNode->u.pPatch; -- } -- switch( pNode->eType ){ -- default: { -- assert( pNode->eType==JSON_NULL ); -- jsonAppendRaw(pOut, "null", 4); -- break; -- } -- case JSON_TRUE: { -- jsonAppendRaw(pOut, "true", 4); -- break; -- } -- case JSON_FALSE: { -- jsonAppendRaw(pOut, "false", 5); -- break; -- } -- case JSON_STRING: { -- if( pNode->jnFlags & JNODE_RAW ){ -- jsonAppendString(pOut, pNode->u.zJContent, pNode->n); -- break; -- } -- /* Fall through into the next case */ -- } -- case JSON_REAL: -- case JSON_INT: { -- jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); -- break; -- } -- case JSON_ARRAY: { -- u32 j = 1; -- jsonAppendChar(pOut, '['); -- for(;;){ -- while( j<=pNode->n ){ -- if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){ -- jsonAppendSeparator(pOut); -- jsonRenderNode(&pNode[j], pOut, aReplace); -- } -- j += jsonNodeSize(&pNode[j]); -- } -- if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; -- pNode = &pNode[pNode->u.iAppend]; -- j = 1; -- } -- jsonAppendChar(pOut, ']'); -- break; -- } -- case JSON_OBJECT: { -- u32 j = 1; -- jsonAppendChar(pOut, '{'); -- for(;;){ -- while( j<=pNode->n ){ -- if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){ -- jsonAppendSeparator(pOut); -- jsonRenderNode(&pNode[j], pOut, aReplace); -- jsonAppendChar(pOut, ':'); -- jsonRenderNode(&pNode[j+1], pOut, aReplace); -- } -- j += 1 + jsonNodeSize(&pNode[j+1]); -- } -- if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; -- pNode = &pNode[pNode->u.iAppend]; -- j = 1; -- } -- jsonAppendChar(pOut, '}'); -- break; -- } -- } --} -+ sessionBufferGrow(pBuf, 2+nRec+nChange, pRc); -+ if( *pRc==SQLITE_OK ){ -+ int bData = 0; -+ u8 *pOut = &pBuf->aBuf[pBuf->nBuf]; -+ int i; -+ u8 *a1 = aRec; -+ u8 *a2 = aChange; - --/* --** Return a JsonNode and all its descendents as a JSON string. --*/ --static void jsonReturnJson( -- JsonNode *pNode, /* Node to return */ -- sqlite3_context *pCtx, /* Return value for this function */ -- sqlite3_value **aReplace /* Array of replacement values */ --){ -- JsonString s; -- jsonInit(&s, pCtx); -- jsonRenderNode(pNode, &s, aReplace); -- jsonResult(&s); -- sqlite3_result_subtype(pCtx, JSON_SUBTYPE); --} -- --/* --** Make the JsonNode the return value of the function. --*/ --static void jsonReturn( -- JsonNode *pNode, /* Node to return */ -- sqlite3_context *pCtx, /* Return value for this function */ -- sqlite3_value **aReplace /* Array of replacement values */ --){ -- switch( pNode->eType ){ -- default: { -- assert( pNode->eType==JSON_NULL ); -- sqlite3_result_null(pCtx); -- break; -- } -- case JSON_TRUE: { -- sqlite3_result_int(pCtx, 1); -- break; -- } -- case JSON_FALSE: { -- sqlite3_result_int(pCtx, 0); -- break; -- } -- case JSON_INT: { -- sqlite3_int64 i = 0; -- const char *z = pNode->u.zJContent; -- if( z[0]=='-' ){ z++; } -- while( z[0]>='0' && z[0]<='9' ){ -- unsigned v = *(z++) - '0'; -- if( i>=LARGEST_INT64/10 ){ -- if( i>LARGEST_INT64/10 ) goto int_as_real; -- if( z[0]>='0' && z[0]<='9' ) goto int_as_real; -- if( v==9 ) goto int_as_real; -- if( v==8 ){ -- if( pNode->u.zJContent[0]=='-' ){ -- sqlite3_result_int64(pCtx, SMALLEST_INT64); -- goto int_done; -- }else{ -- goto int_as_real; -- } -- } -- } -- i = i*10 + v; -+ *pOut++ = SQLITE_UPDATE; -+ *pOut++ = pIter->bIndirect; -+ for(i=0; i<pIter->nCol; i++){ -+ int n1 = sessionSerialLen(a1); -+ int n2 = sessionSerialLen(a2); -+ if( pIter->abPK[i] || a2[0]==0 ){ -+ if( !pIter->abPK[i] ) bData = 1; -+ memcpy(pOut, a1, n1); -+ pOut += n1; -+ }else if( a2[0]!=0xFF ){ -+ bData = 1; -+ memcpy(pOut, a2, n2); -+ pOut += n2; -+ }else{ -+ *pOut++ = '\0'; - } -- if( pNode->u.zJContent[0]=='-' ){ i = -i; } -- sqlite3_result_int64(pCtx, i); -- int_done: -- break; -- int_as_real: /* fall through to real */; -+ a1 += n1; -+ a2 += n2; - } -- case JSON_REAL: { -- double r; --#ifdef SQLITE_AMALGAMATION -- const char *z = pNode->u.zJContent; -- sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); --#else -- r = strtod(pNode->u.zJContent, 0); --#endif -- sqlite3_result_double(pCtx, r); -- break; -- } -- case JSON_STRING: { --#if 0 /* Never happens because JNODE_RAW is only set by json_set(), -- ** json_insert() and json_replace() and those routines do not -- ** call jsonReturn() */ -- if( pNode->jnFlags & JNODE_RAW ){ -- sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, -- SQLITE_TRANSIENT); -- }else --#endif -- assert( (pNode->jnFlags & JNODE_RAW)==0 ); -- if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){ -- /* JSON formatted without any backslash-escapes */ -- sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, -- SQLITE_TRANSIENT); -- }else{ -- /* Translate JSON formatted string into raw text */ -- u32 i; -- u32 n = pNode->n; -- const char *z = pNode->u.zJContent; -- char *zOut; -- u32 j; -- zOut = sqlite3_malloc( n+1 ); -- if( zOut==0 ){ -- sqlite3_result_error_nomem(pCtx); -- break; -+ if( bData ){ -+ a2 = aChange; -+ for(i=0; i<pIter->nCol; i++){ -+ int n1 = sessionSerialLen(a1); -+ int n2 = sessionSerialLen(a2); -+ if( pIter->abPK[i] || a2[0]!=0xFF ){ -+ memcpy(pOut, a1, n1); -+ pOut += n1; -+ }else{ -+ *pOut++ = '\0'; - } -- for(i=1, j=0; i<n-1; i++){ -- char c = z[i]; -- if( c!='\\' ){ -- zOut[j++] = c; -- }else{ -- c = z[++i]; -- if( c=='u' ){ -- u32 v = 0, k; -- for(k=0; k<4; i++, k++){ -- assert( i<n-2 ); -- c = z[i+1]; -- assert( safe_isxdigit(c) ); -- if( c<='9' ) v = v*16 + c - '0'; -- else if( c<='F' ) v = v*16 + c - 'A' + 10; -- else v = v*16 + c - 'a' + 10; -- } -- if( v==0 ) break; -- if( v<=0x7f ){ -- zOut[j++] = (char)v; -- }else if( v<=0x7ff ){ -- zOut[j++] = (char)(0xc0 | (v>>6)); -- zOut[j++] = 0x80 | (v&0x3f); -- }else{ -- zOut[j++] = (char)(0xe0 | (v>>12)); -- zOut[j++] = 0x80 | ((v>>6)&0x3f); -- zOut[j++] = 0x80 | (v&0x3f); -- } -- }else{ -- if( c=='b' ){ -- c = '\b'; -- }else if( c=='f' ){ -- c = '\f'; -- }else if( c=='n' ){ -- c = '\n'; -- }else if( c=='r' ){ -- c = '\r'; -- }else if( c=='t' ){ -- c = '\t'; -- } -- zOut[j++] = c; -- } -- } -- } -- zOut[j] = 0; -- sqlite3_result_text(pCtx, zOut, j, sqlite3_free); -+ a1 += n1; -+ a2 += n2; - } -- break; -+ pBuf->nBuf = (pOut - pBuf->aBuf); - } -- case JSON_ARRAY: -- case JSON_OBJECT: { -- jsonReturnJson(pNode, pCtx, aReplace); -- break; -- } - } - } - --/* Forward reference */ --static int jsonParseAddNode(JsonParse*,u32,u32,const char*); -- - /* --** A macro to hint to the compiler that a function should not be --** inlined. -+** pIter is configured to iterate through a changeset. This function rebases -+** that changeset according to the current configuration of the rebaser -+** object passed as the first argument. If no error occurs and argument xOutput -+** is not NULL, then the changeset is returned to the caller by invoking -+** xOutput zero or more times and SQLITE_OK returned. Or, if xOutput is NULL, -+** then (*ppOut) is set to point to a buffer containing the rebased changeset -+** before this function returns. In this case (*pnOut) is set to the size of -+** the buffer in bytes. It is the responsibility of the caller to eventually -+** free the (*ppOut) buffer using sqlite3_free(). -+** -+** If an error occurs, an SQLite error code is returned. If ppOut and -+** pnOut are not NULL, then the two output parameters are set to 0 before -+** returning. - */ --#if defined(__GNUC__) --# define JSON_NOINLINE __attribute__((noinline)) --#elif defined(_MSC_VER) && _MSC_VER>=1310 --# define JSON_NOINLINE __declspec(noinline) --#else --# define JSON_NOINLINE --#endif -- -- --static JSON_NOINLINE int jsonParseAddNodeExpand( -- JsonParse *pParse, /* Append the node to this object */ -- u32 eType, /* Node type */ -- u32 n, /* Content size or sub-node count */ -- const char *zContent /* Content */ -+static int sessionRebase( -+ sqlite3_rebaser *p, /* Rebaser hash table */ -+ sqlite3_changeset_iter *pIter, /* Input data */ -+ int (*xOutput)(void *pOut, const void *pData, int nData), -+ void *pOut, /* Context for xOutput callback */ -+ int *pnOut, /* OUT: Number of bytes in output changeset */ -+ void **ppOut /* OUT: Inverse of pChangeset */ - ){ -- u32 nNew; -- JsonNode *pNew; -- assert( pParse->nNode>=pParse->nAlloc ); -- if( pParse->oom ) return -1; -- nNew = pParse->nAlloc*2 + 10; -- pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew); -- if( pNew==0 ){ -- pParse->oom = 1; -- return -1; -- } -- pParse->nAlloc = nNew; -- pParse->aNode = pNew; -- assert( pParse->nNode<pParse->nAlloc ); -- return jsonParseAddNode(pParse, eType, n, zContent); --} -+ int rc = SQLITE_OK; -+ u8 *aRec = 0; -+ int nRec = 0; -+ int bNew = 0; -+ SessionTable *pTab = 0; -+ SessionBuffer sOut = {0,0,0}; - --/* --** Create a new JsonNode instance based on the arguments and append that --** instance to the JsonParse. Return the index in pParse->aNode[] of the --** new node, or -1 if a memory allocation fails. --*/ --static int jsonParseAddNode( -- JsonParse *pParse, /* Append the node to this object */ -- u32 eType, /* Node type */ -- u32 n, /* Content size or sub-node count */ -- const char *zContent /* Content */ --){ -- JsonNode *p; -- if( pParse->nNode>=pParse->nAlloc ){ -- return jsonParseAddNodeExpand(pParse, eType, n, zContent); -- } -- p = &pParse->aNode[pParse->nNode]; -- p->eType = (u8)eType; -- p->jnFlags = 0; -- p->n = n; -- p->u.zJContent = zContent; -- return pParse->nNode++; --} -+ while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, &bNew) ){ -+ SessionChange *pChange = 0; -+ int bDone = 0; - --/* --** Return true if z[] begins with 4 (or more) hexadecimal digits --*/ --static int jsonIs4Hex(const char *z){ -- int i; -- for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0; -- return 1; --} -- --/* --** Parse a single JSON value which begins at pParse->zJson[i]. Return the --** index of the first character past the end of the value parsed. --** --** Return negative for a syntax error. Special cases: return -2 if the --** first non-whitespace character is '}' and return -3 if the first --** non-whitespace character is ']'. --*/ --static int jsonParseValue(JsonParse *pParse, u32 i){ -- char c; -- u32 j; -- int iThis; -- int x; -- JsonNode *pNode; -- const char *z = pParse->zJson; -- while( safe_isspace(z[i]) ){ i++; } -- if( (c = z[i])=='{' ){ -- /* Parse object */ -- iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); -- if( iThis<0 ) return -1; -- for(j=i+1;;j++){ -- while( safe_isspace(z[j]) ){ j++; } -- if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; -- x = jsonParseValue(pParse, j); -- if( x<0 ){ -- pParse->iDepth--; -- if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1; -- return -1; -+ if( bNew ){ -+ const char *zTab = pIter->zTab; -+ for(pTab=p->grp.pList; pTab; pTab=pTab->pNext){ -+ if( 0==sqlite3_stricmp(pTab->zName, zTab) ) break; - } -- if( pParse->oom ) return -1; -- pNode = &pParse->aNode[pParse->nNode-1]; -- if( pNode->eType!=JSON_STRING ) return -1; -- pNode->jnFlags |= JNODE_LABEL; -- j = x; -- while( safe_isspace(z[j]) ){ j++; } -- if( z[j]!=':' ) return -1; -- j++; -- x = jsonParseValue(pParse, j); -- pParse->iDepth--; -- if( x<0 ) return -1; -- j = x; -- while( safe_isspace(z[j]) ){ j++; } -- c = z[j]; -- if( c==',' ) continue; -- if( c!='}' ) return -1; -- break; -- } -- pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; -- return j+1; -- }else if( c=='[' ){ -- /* Parse array */ -- iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); -- if( iThis<0 ) return -1; -- for(j=i+1;;j++){ -- while( safe_isspace(z[j]) ){ j++; } -- if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; -- x = jsonParseValue(pParse, j); -- pParse->iDepth--; -- if( x<0 ){ -- if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1; -- return -1; -- } -- j = x; -- while( safe_isspace(z[j]) ){ j++; } -- c = z[j]; -- if( c==',' ) continue; -- if( c!=']' ) return -1; -- break; -- } -- pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; -- return j+1; -- }else if( c=='"' ){ -- /* Parse string */ -- u8 jnFlags = 0; -- j = i+1; -- for(;;){ -- c = z[j]; -- if( (c & ~0x1f)==0 ){ -- /* Control characters are not allowed in strings */ -- return -1; -- } -- if( c=='\\' ){ -- c = z[++j]; -- if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' -- || c=='n' || c=='r' || c=='t' -- || (c=='u' && jsonIs4Hex(z+j+1)) ){ -- jnFlags = JNODE_ESCAPE; -- }else{ -- return -1; -- } -- }else if( c=='"' ){ -- break; -- } -- j++; -- } -- jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]); -- if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags; -- return j+1; -- }else if( c=='n' -- && strncmp(z+i,"null",4)==0 -- && !safe_isalnum(z[i+4]) ){ -- jsonParseAddNode(pParse, JSON_NULL, 0, 0); -- return i+4; -- }else if( c=='t' -- && strncmp(z+i,"true",4)==0 -- && !safe_isalnum(z[i+4]) ){ -- jsonParseAddNode(pParse, JSON_TRUE, 0, 0); -- return i+4; -- }else if( c=='f' -- && strncmp(z+i,"false",5)==0 -- && !safe_isalnum(z[i+5]) ){ -- jsonParseAddNode(pParse, JSON_FALSE, 0, 0); -- return i+5; -- }else if( c=='-' || (c>='0' && c<='9') ){ -- /* Parse number */ -- u8 seenDP = 0; -- u8 seenE = 0; -- assert( '-' < '0' ); -- if( c<='0' ){ -- j = c=='-' ? i+1 : i; -- if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1; -- } -- j = i+1; -- for(;; j++){ -- c = z[j]; -- if( c>='0' && c<='9' ) continue; -- if( c=='.' ){ -- if( z[j-1]=='-' ) return -1; -- if( seenDP ) return -1; -- seenDP = 1; -- continue; -- } -- if( c=='e' || c=='E' ){ -- if( z[j-1]<'0' ) return -1; -- if( seenE ) return -1; -- seenDP = seenE = 1; -- c = z[j+1]; -- if( c=='+' || c=='-' ){ -- j++; -- c = z[j+1]; -- } -- if( c<'0' || c>'9' ) return -1; -- continue; -- } -- break; -- } -- if( z[j-1]<'0' ) return -1; -- jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT, -- j - i, &z[i]); -- return j; -- }else if( c=='}' ){ -- return -2; /* End of {...} */ -- }else if( c==']' ){ -- return -3; /* End of [...] */ -- }else if( c==0 ){ -- return 0; /* End of file */ -- }else{ -- return -1; /* Syntax error */ -- } --} -+ bNew = 0; - --/* --** Parse a complete JSON string. Return 0 on success or non-zero if there --** are any errors. If an error occurs, free all memory associated with --** pParse. --** --** pParse is uninitialized when this routine is called. --*/ --static int jsonParse( -- JsonParse *pParse, /* Initialize and fill this JsonParse object */ -- sqlite3_context *pCtx, /* Report errors here */ -- const char *zJson /* Input JSON text to be parsed */ --){ -- int i; -- memset(pParse, 0, sizeof(*pParse)); -- if( zJson==0 ) return 1; -- pParse->zJson = zJson; -- i = jsonParseValue(pParse, 0); -- if( pParse->oom ) i = -1; -- if( i>0 ){ -- assert( pParse->iDepth==0 ); -- while( safe_isspace(zJson[i]) ) i++; -- if( zJson[i] ) i = -1; -- } -- if( i<=0 ){ -- if( pCtx!=0 ){ -- if( pParse->oom ){ -- sqlite3_result_error_nomem(pCtx); -- }else{ -- sqlite3_result_error(pCtx, "malformed JSON", -1); -+ /* A patchset may not be rebased */ -+ if( pIter->bPatchset ){ -+ rc = SQLITE_ERROR; - } -- } -- jsonParseReset(pParse); -- return 1; -- } -- return 0; --} - --/* Mark node i of pParse as being a child of iParent. Call recursively --** to fill in all the descendants of node i. --*/ --static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){ -- JsonNode *pNode = &pParse->aNode[i]; -- u32 j; -- pParse->aUp[i] = iParent; -- switch( pNode->eType ){ -- case JSON_ARRAY: { -- for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){ -- jsonParseFillInParentage(pParse, i+j, i); -- } -- break; -+ /* Append a table header to the output for this new table */ -+ sessionAppendByte(&sOut, pIter->bPatchset ? 'P' : 'T', &rc); -+ sessionAppendVarint(&sOut, pIter->nCol, &rc); -+ sessionAppendBlob(&sOut, pIter->abPK, pIter->nCol, &rc); -+ sessionAppendBlob(&sOut,(u8*)pIter->zTab,(int)strlen(pIter->zTab)+1,&rc); - } -- case JSON_OBJECT: { -- for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){ -- pParse->aUp[i+j] = i; -- jsonParseFillInParentage(pParse, i+j+1, i); -- } -- break; -- } -- default: { -- break; -- } -- } --} - --/* --** Compute the parentage of all nodes in a completed parse. --*/ --static int jsonParseFindParents(JsonParse *pParse){ -- u32 *aUp; -- assert( pParse->aUp==0 ); -- aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode ); -- if( aUp==0 ){ -- pParse->oom = 1; -- return SQLITE_NOMEM; -- } -- jsonParseFillInParentage(pParse, 0, 0); -- return SQLITE_OK; --} -+ if( pTab && rc==SQLITE_OK ){ -+ int iHash = sessionChangeHash(pTab, 0, aRec, pTab->nChange); - --/* --** Magic number used for the JSON parse cache in sqlite3_get_auxdata() --*/ --#define JSON_CACHE_ID (-429938) -- --/* --** Obtain a complete parse of the JSON found in the first argument --** of the argv array. Use the sqlite3_get_auxdata() cache for this --** parse if it is available. If the cache is not available or if it --** is no longer valid, parse the JSON again and return the new parse, --** and also register the new parse so that it will be available for --** future sqlite3_get_auxdata() calls. --*/ --static JsonParse *jsonParseCached( -- sqlite3_context *pCtx, -- sqlite3_value **argv --){ -- const char *zJson = (const char*)sqlite3_value_text(argv[0]); -- int nJson = sqlite3_value_bytes(argv[0]); -- JsonParse *p; -- if( zJson==0 ) return 0; -- p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID); -- if( p && p->nJson==nJson && memcmp(p->zJson,zJson,nJson)==0 ){ -- p->nErr = 0; -- return p; /* The cached entry matches, so return it */ -- } -- p = sqlite3_malloc( sizeof(*p) + nJson + 1 ); -- if( p==0 ){ -- sqlite3_result_error_nomem(pCtx); -- return 0; -- } -- memset(p, 0, sizeof(*p)); -- p->zJson = (char*)&p[1]; -- memcpy((char*)p->zJson, zJson, nJson+1); -- if( jsonParse(p, pCtx, p->zJson) ){ -- sqlite3_free(p); -- return 0; -- } -- p->nJson = nJson; -- sqlite3_set_auxdata(pCtx, JSON_CACHE_ID, p, (void(*)(void*))jsonParseFree); -- return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID); --} -- --/* --** Compare the OBJECT label at pNode against zKey,nKey. Return true on --** a match. --*/ --static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){ -- if( pNode->jnFlags & JNODE_RAW ){ -- if( pNode->n!=nKey ) return 0; -- return strncmp(pNode->u.zJContent, zKey, nKey)==0; -- }else{ -- if( pNode->n!=nKey+2 ) return 0; -- return strncmp(pNode->u.zJContent+1, zKey, nKey)==0; -- } --} -- --/* forward declaration */ --static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**); -- --/* --** Search along zPath to find the node specified. Return a pointer --** to that node, or NULL if zPath is malformed or if there is no such --** node. --** --** If pApnd!=0, then try to append new nodes to complete zPath if it is --** possible to do so and if no existing node corresponds to zPath. If --** new nodes are appended *pApnd is set to 1. --*/ --static JsonNode *jsonLookupStep( -- JsonParse *pParse, /* The JSON to search */ -- u32 iRoot, /* Begin the search at this node */ -- const char *zPath, /* The path to search */ -- int *pApnd, /* Append nodes to complete path if not NULL */ -- const char **pzErr /* Make *pzErr point to any syntax error in zPath */ --){ -- u32 i, j, nKey; -- const char *zKey; -- JsonNode *pRoot = &pParse->aNode[iRoot]; -- if( zPath[0]==0 ) return pRoot; -- if( zPath[0]=='.' ){ -- if( pRoot->eType!=JSON_OBJECT ) return 0; -- zPath++; -- if( zPath[0]=='"' ){ -- zKey = zPath + 1; -- for(i=1; zPath[i] && zPath[i]!='"'; i++){} -- nKey = i-1; -- if( zPath[i] ){ -- i++; -- }else{ -- *pzErr = zPath; -- return 0; -- } -- }else{ -- zKey = zPath; -- for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} -- nKey = i; -- } -- if( nKey==0 ){ -- *pzErr = zPath; -- return 0; -- } -- j = 1; -- for(;;){ -- while( j<=pRoot->n ){ -- if( jsonLabelCompare(pRoot+j, zKey, nKey) ){ -- return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr); -+ for(pChange=pTab->apChange[iHash]; pChange; pChange=pChange->pNext){ -+ if( sessionChangeEqual(pTab, 0, aRec, 0, pChange->aRecord) ){ -+ break; - } -- j++; -- j += jsonNodeSize(&pRoot[j]); - } -- if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; -- iRoot += pRoot->u.iAppend; -- pRoot = &pParse->aNode[iRoot]; -- j = 1; - } -- if( pApnd ){ -- u32 iStart, iLabel; -- JsonNode *pNode; -- iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); -- iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath); -- zPath += i; -- pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); -- if( pParse->oom ) return 0; -- if( pNode ){ -- pRoot = &pParse->aNode[iRoot]; -- pRoot->u.iAppend = iStart - iRoot; -- pRoot->jnFlags |= JNODE_APPEND; -- pParse->aNode[iLabel].jnFlags |= JNODE_RAW; -- } -- return pNode; -- } -- }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){ -- if( pRoot->eType!=JSON_ARRAY ) return 0; -- i = 0; -- j = 1; -- while( safe_isdigit(zPath[j]) ){ -- i = i*10 + zPath[j] - '0'; -- j++; -- } -- if( zPath[j]!=']' ){ -- *pzErr = zPath; -- return 0; -- } -- zPath += j + 1; -- j = 1; -- for(;;){ -- while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){ -- if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--; -- j += jsonNodeSize(&pRoot[j]); -- } -- if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; -- iRoot += pRoot->u.iAppend; -- pRoot = &pParse->aNode[iRoot]; -- j = 1; -- } -- if( j<=pRoot->n ){ -- return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr); -- } -- if( i==0 && pApnd ){ -- u32 iStart; -- JsonNode *pNode; -- iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0); -- pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); -- if( pParse->oom ) return 0; -- if( pNode ){ -- pRoot = &pParse->aNode[iRoot]; -- pRoot->u.iAppend = iStart - iRoot; -- pRoot->jnFlags |= JNODE_APPEND; -- } -- return pNode; -- } -- }else{ -- *pzErr = zPath; -- } -- return 0; --} - --/* --** Append content to pParse that will complete zPath. Return a pointer --** to the inserted node, or return NULL if the append fails. --*/ --static JsonNode *jsonLookupAppend( -- JsonParse *pParse, /* Append content to the JSON parse */ -- const char *zPath, /* Description of content to append */ -- int *pApnd, /* Set this flag to 1 */ -- const char **pzErr /* Make this point to any syntax error */ --){ -- *pApnd = 1; -- if( zPath[0]==0 ){ -- jsonParseAddNode(pParse, JSON_NULL, 0, 0); -- return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1]; -- } -- if( zPath[0]=='.' ){ -- jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); -- }else if( strncmp(zPath,"[0]",3)==0 ){ -- jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); -- }else{ -- return 0; -- } -- if( pParse->oom ) return 0; -- return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr); --} -+ if( pChange ){ -+ assert( pChange->op==SQLITE_DELETE || pChange->op==SQLITE_INSERT ); -+ switch( pIter->op ){ -+ case SQLITE_INSERT: -+ if( pChange->op==SQLITE_INSERT ){ -+ bDone = 1; -+ if( pChange->bIndirect==0 ){ -+ sessionAppendByte(&sOut, SQLITE_UPDATE, &rc); -+ sessionAppendByte(&sOut, pIter->bIndirect, &rc); -+ sessionAppendBlob(&sOut, pChange->aRecord, pChange->nRecord, &rc); -+ sessionAppendBlob(&sOut, aRec, nRec, &rc); -+ } -+ } -+ break; - --/* --** Return the text of a syntax error message on a JSON path. Space is --** obtained from sqlite3_malloc(). --*/ --static char *jsonPathSyntaxError(const char *zErr){ -- return sqlite3_mprintf("JSON path error near '%q'", zErr); --} -+ case SQLITE_UPDATE: -+ bDone = 1; -+ if( pChange->op==SQLITE_DELETE ){ -+ if( pChange->bIndirect==0 ){ -+ u8 *pCsr = aRec; -+ sessionSkipRecord(&pCsr, pIter->nCol); -+ sessionAppendByte(&sOut, SQLITE_INSERT, &rc); -+ sessionAppendByte(&sOut, pIter->bIndirect, &rc); -+ sessionAppendRecordMerge(&sOut, pIter->nCol, -+ pCsr, nRec-(pCsr-aRec), -+ pChange->aRecord, pChange->nRecord, &rc -+ ); -+ } -+ }else{ -+ sessionAppendPartialUpdate(&sOut, pIter, -+ aRec, nRec, pChange->aRecord, pChange->nRecord, &rc -+ ); -+ } -+ break; - --/* --** Do a node lookup using zPath. Return a pointer to the node on success. --** Return NULL if not found or if there is an error. --** --** On an error, write an error message into pCtx and increment the --** pParse->nErr counter. --** --** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if --** nodes are appended. --*/ --static JsonNode *jsonLookup( -- JsonParse *pParse, /* The JSON to search */ -- const char *zPath, /* The path to search */ -- int *pApnd, /* Append nodes to complete path if not NULL */ -- sqlite3_context *pCtx /* Report errors here, if not NULL */ --){ -- const char *zErr = 0; -- JsonNode *pNode = 0; -- char *zMsg; -- -- if( zPath==0 ) return 0; -- if( zPath[0]!='$' ){ -- zErr = zPath; -- goto lookup_err; -- } -- zPath++; -- pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr); -- if( zErr==0 ) return pNode; -- --lookup_err: -- pParse->nErr++; -- assert( zErr!=0 && pCtx!=0 ); -- zMsg = jsonPathSyntaxError(zErr); -- if( zMsg ){ -- sqlite3_result_error(pCtx, zMsg, -1); -- sqlite3_free(zMsg); -- }else{ -- sqlite3_result_error_nomem(pCtx); -- } -- return 0; --} -- -- --/* --** Report the wrong number of arguments for json_insert(), json_replace() --** or json_set(). --*/ --static void jsonWrongNumArgs( -- sqlite3_context *pCtx, -- const char *zFuncName --){ -- char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", -- zFuncName); -- sqlite3_result_error(pCtx, zMsg, -1); -- sqlite3_free(zMsg); --} -- --/* --** Mark all NULL entries in the Object passed in as JNODE_REMOVE. --*/ --static void jsonRemoveAllNulls(JsonNode *pNode){ -- int i, n; -- assert( pNode->eType==JSON_OBJECT ); -- n = pNode->n; -- for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){ -- switch( pNode[i].eType ){ -- case JSON_NULL: -- pNode[i].jnFlags |= JNODE_REMOVE; -- break; -- case JSON_OBJECT: -- jsonRemoveAllNulls(&pNode[i]); -- break; -+ default: -+ assert( pIter->op==SQLITE_DELETE ); -+ bDone = 1; -+ if( pChange->op==SQLITE_INSERT ){ -+ sessionAppendByte(&sOut, SQLITE_DELETE, &rc); -+ sessionAppendByte(&sOut, pIter->bIndirect, &rc); -+ sessionAppendRecordMerge(&sOut, pIter->nCol, -+ pChange->aRecord, pChange->nRecord, aRec, nRec, &rc -+ ); -+ } -+ break; -+ } - } -- } --} - -- --/**************************************************************************** --** SQL functions used for testing and debugging --****************************************************************************/ -- --#ifdef SQLITE_DEBUG --/* --** The json_parse(JSON) function returns a string which describes --** a parse of the JSON provided. Or it returns NULL if JSON is not --** well-formed. --*/ --static void jsonParseFunc( -- sqlite3_context *ctx, -- int argc, -- sqlite3_value **argv --){ -- JsonString s; /* Output string - not real JSON */ -- JsonParse x; /* The parse */ -- u32 i; -- -- assert( argc==1 ); -- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; -- jsonParseFindParents(&x); -- jsonInit(&s, ctx); -- for(i=0; i<x.nNode; i++){ -- const char *zType; -- if( x.aNode[i].jnFlags & JNODE_LABEL ){ -- assert( x.aNode[i].eType==JSON_STRING ); -- zType = "label"; -- }else{ -- zType = jsonType[x.aNode[i].eType]; -+ if( bDone==0 ){ -+ sessionAppendByte(&sOut, pIter->op, &rc); -+ sessionAppendByte(&sOut, pIter->bIndirect, &rc); -+ sessionAppendBlob(&sOut, aRec, nRec, &rc); - } -- jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d", -- i, zType, x.aNode[i].n, x.aUp[i]); -- if( x.aNode[i].u.zJContent!=0 ){ -- jsonAppendRaw(&s, " ", 1); -- jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n); -+ if( rc==SQLITE_OK && xOutput && sOut.nBuf>sessions_strm_chunk_size ){ -+ rc = xOutput(pOut, sOut.aBuf, sOut.nBuf); -+ sOut.nBuf = 0; - } -- jsonAppendRaw(&s, "\n", 1); -+ if( rc ) break; - } -- jsonParseReset(&x); -- jsonResult(&s); --} - --/* --** The json_test1(JSON) function return true (1) if the input is JSON --** text generated by another json function. It returns (0) if the input --** is not known to be JSON. --*/ --static void jsonTest1Func( -- sqlite3_context *ctx, -- int argc, -- sqlite3_value **argv --){ -- UNUSED_PARAM(argc); -- sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE); --} --#endif /* SQLITE_DEBUG */ -- --/**************************************************************************** --** Scalar SQL function implementations --****************************************************************************/ -- --/* --** Implementation of the json_QUOTE(VALUE) function. Return a JSON value --** corresponding to the SQL value input. Mostly this means putting --** double-quotes around strings and returning the unquoted string "null" --** when given a NULL input. --*/ --static void jsonQuoteFunc( -- sqlite3_context *ctx, -- int argc, -- sqlite3_value **argv --){ -- JsonString jx; -- UNUSED_PARAM(argc); -- -- jsonInit(&jx, ctx); -- jsonAppendValue(&jx, argv[0]); -- jsonResult(&jx); -- sqlite3_result_subtype(ctx, JSON_SUBTYPE); --} -- --/* --** Implementation of the json_array(VALUE,...) function. Return a JSON --** array that contains all values given in arguments. Or if any argument --** is a BLOB, throw an error. --*/ --static void jsonArrayFunc( -- sqlite3_context *ctx, -- int argc, -- sqlite3_value **argv --){ -- int i; -- JsonString jx; -- -- jsonInit(&jx, ctx); -- jsonAppendChar(&jx, '['); -- for(i=0; i<argc; i++){ -- jsonAppendSeparator(&jx); -- jsonAppendValue(&jx, argv[i]); -+ if( rc!=SQLITE_OK ){ -+ sqlite3_free(sOut.aBuf); -+ memset(&sOut, 0, sizeof(sOut)); - } -- jsonAppendChar(&jx, ']'); -- jsonResult(&jx); -- sqlite3_result_subtype(ctx, JSON_SUBTYPE); --} - -- --/* --** json_array_length(JSON) --** json_array_length(JSON, PATH) --** --** Return the number of elements in the top-level JSON array. --** Return 0 if the input is not a well-formed JSON array. --*/ --static void jsonArrayLengthFunc( -- sqlite3_context *ctx, -- int argc, -- sqlite3_value **argv --){ -- JsonParse *p; /* The parse */ -- sqlite3_int64 n = 0; -- u32 i; -- JsonNode *pNode; -- -- p = jsonParseCached(ctx, argv); -- if( p==0 ) return; -- assert( p->nNode ); -- if( argc==2 ){ -- const char *zPath = (const char*)sqlite3_value_text(argv[1]); -- pNode = jsonLookup(p, zPath, 0, ctx); -- }else{ -- pNode = p->aNode; -- } -- if( pNode==0 ){ -- return; -- } -- if( pNode->eType==JSON_ARRAY ){ -- assert( (pNode->jnFlags & JNODE_APPEND)==0 ); -- for(i=1; i<=pNode->n; n++){ -- i += jsonNodeSize(&pNode[i]); -- } -- } -- sqlite3_result_int64(ctx, n); --} -- --/* --** json_extract(JSON, PATH, ...) --** --** Return the element described by PATH. Return NULL if there is no --** PATH element. If there are multiple PATHs, then return a JSON array --** with the result from each path. Throw an error if the JSON or any PATH --** is malformed. --*/ --static void jsonExtractFunc( -- sqlite3_context *ctx, -- int argc, -- sqlite3_value **argv --){ -- JsonParse *p; /* The parse */ -- JsonNode *pNode; -- const char *zPath; -- JsonString jx; -- int i; -- -- if( argc<2 ) return; -- p = jsonParseCached(ctx, argv); -- if( p==0 ) return; -- jsonInit(&jx, ctx); -- jsonAppendChar(&jx, '['); -- for(i=1; i<argc; i++){ -- zPath = (const char*)sqlite3_value_text(argv[i]); -- pNode = jsonLookup(p, zPath, 0, ctx); -- if( p->nErr ) break; -- if( argc>2 ){ -- jsonAppendSeparator(&jx); -- if( pNode ){ -- jsonRenderNode(pNode, &jx, 0); -- }else{ -- jsonAppendRaw(&jx, "null", 4); -+ if( rc==SQLITE_OK ){ -+ if( xOutput ){ -+ if( sOut.nBuf>0 ){ -+ rc = xOutput(pOut, sOut.aBuf, sOut.nBuf); - } -- }else if( pNode ){ -- jsonReturn(pNode, ctx, 0); -+ }else{ -+ *ppOut = (void*)sOut.aBuf; -+ *pnOut = sOut.nBuf; -+ sOut.aBuf = 0; - } - } -- if( argc>2 && i==argc ){ -- jsonAppendChar(&jx, ']'); -- jsonResult(&jx); -- sqlite3_result_subtype(ctx, JSON_SUBTYPE); -- } -- jsonReset(&jx); -+ sqlite3_free(sOut.aBuf); -+ return rc; - } - --/* This is the RFC 7396 MergePatch algorithm. -+/* -+** Create a new rebaser object. - */ --static JsonNode *jsonMergePatch( -- JsonParse *pParse, /* The JSON parser that contains the TARGET */ -- u32 iTarget, /* Node of the TARGET in pParse */ -- JsonNode *pPatch /* The PATCH */ --){ -- u32 i, j; -- u32 iRoot; -- JsonNode *pTarget; -- if( pPatch->eType!=JSON_OBJECT ){ -- return pPatch; -- } -- assert( iTarget>=0 && iTarget<pParse->nNode ); -- pTarget = &pParse->aNode[iTarget]; -- assert( (pPatch->jnFlags & JNODE_APPEND)==0 ); -- if( pTarget->eType!=JSON_OBJECT ){ -- jsonRemoveAllNulls(pPatch); -- return pPatch; -- } -- iRoot = iTarget; -- for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){ -- u32 nKey; -- const char *zKey; -- assert( pPatch[i].eType==JSON_STRING ); -- assert( pPatch[i].jnFlags & JNODE_LABEL ); -- nKey = pPatch[i].n; -- zKey = pPatch[i].u.zJContent; -- assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); -- for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){ -- assert( pTarget[j].eType==JSON_STRING ); -- assert( pTarget[j].jnFlags & JNODE_LABEL ); -- assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); -- if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){ -- if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break; -- if( pPatch[i+1].eType==JSON_NULL ){ -- pTarget[j+1].jnFlags |= JNODE_REMOVE; -- }else{ -- JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]); -- if( pNew==0 ) return 0; -- pTarget = &pParse->aNode[iTarget]; -- if( pNew!=&pTarget[j+1] ){ -- pTarget[j+1].u.pPatch = pNew; -- pTarget[j+1].jnFlags |= JNODE_PATCH; -- } -- } -- break; -- } -- } -- if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){ -- int iStart, iPatch; -- iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); -- jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); -- iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0); -- if( pParse->oom ) return 0; -- jsonRemoveAllNulls(pPatch); -- pTarget = &pParse->aNode[iTarget]; -- pParse->aNode[iRoot].jnFlags |= JNODE_APPEND; -- pParse->aNode[iRoot].u.iAppend = iStart - iRoot; -- iRoot = iStart; -- pParse->aNode[iPatch].jnFlags |= JNODE_PATCH; -- pParse->aNode[iPatch].u.pPatch = &pPatch[i+1]; -- } -- } -- return pTarget; --} -+SQLITE_API int sqlite3rebaser_create(sqlite3_rebaser **ppNew){ -+ int rc = SQLITE_OK; -+ sqlite3_rebaser *pNew; - --/* --** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON --** object that is the result of running the RFC 7396 MergePatch() algorithm --** on the two arguments. --*/ --static void jsonPatchFunc( -- sqlite3_context *ctx, -- int argc, -- sqlite3_value **argv --){ -- JsonParse x; /* The JSON that is being patched */ -- JsonParse y; /* The patch */ -- JsonNode *pResult; /* The result of the merge */ -- -- UNUSED_PARAM(argc); -- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; -- if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){ -- jsonParseReset(&x); -- return; -- } -- pResult = jsonMergePatch(&x, 0, y.aNode); -- assert( pResult!=0 || x.oom ); -- if( pResult ){ -- jsonReturnJson(pResult, ctx, 0); -+ pNew = sqlite3_malloc(sizeof(sqlite3_rebaser)); -+ if( pNew==0 ){ -+ rc = SQLITE_NOMEM; - }else{ -- sqlite3_result_error_nomem(ctx); -+ memset(pNew, 0, sizeof(sqlite3_rebaser)); - } -- jsonParseReset(&x); -- jsonParseReset(&y); -+ *ppNew = pNew; -+ return rc; - } - -- --/* --** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON --** object that contains all name/value given in arguments. Or if any name --** is not a string or if any value is a BLOB, throw an error. -+/* -+** Call this one or more times to configure a rebaser. - */ --static void jsonObjectFunc( -- sqlite3_context *ctx, -- int argc, -- sqlite3_value **argv -+SQLITE_API int sqlite3rebaser_configure( -+ sqlite3_rebaser *p, -+ int nRebase, const void *pRebase - ){ -- int i; -- JsonString jx; -- const char *z; -- u32 n; -- -- if( argc&1 ){ -- sqlite3_result_error(ctx, "json_object() requires an even number " -- "of arguments", -1); -- return; -+ sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */ -+ int rc; /* Return code */ -+ rc = sqlite3changeset_start(&pIter, nRebase, (void*)pRebase); -+ if( rc==SQLITE_OK ){ -+ rc = sessionChangesetToHash(pIter, &p->grp, 1); - } -- jsonInit(&jx, ctx); -- jsonAppendChar(&jx, '{'); -- for(i=0; i<argc; i+=2){ -- if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){ -- sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1); -- jsonReset(&jx); -- return; -- } -- jsonAppendSeparator(&jx); -- z = (const char*)sqlite3_value_text(argv[i]); -- n = (u32)sqlite3_value_bytes(argv[i]); -- jsonAppendString(&jx, z, n); -- jsonAppendChar(&jx, ':'); -- jsonAppendValue(&jx, argv[i+1]); -- } -- jsonAppendChar(&jx, '}'); -- jsonResult(&jx); -- sqlite3_result_subtype(ctx, JSON_SUBTYPE); -+ sqlite3changeset_finalize(pIter); -+ return rc; - } - -- --/* --** json_remove(JSON, PATH, ...) --** --** Remove the named elements from JSON and return the result. malformed --** JSON or PATH arguments result in an error. -+/* -+** Rebase a changeset according to current rebaser configuration - */ --static void jsonRemoveFunc( -- sqlite3_context *ctx, -- int argc, -- sqlite3_value **argv -+SQLITE_API int sqlite3rebaser_rebase( -+ sqlite3_rebaser *p, -+ int nIn, const void *pIn, -+ int *pnOut, void **ppOut - ){ -- JsonParse x; /* The parse */ -- JsonNode *pNode; -- const char *zPath; -- u32 i; -+ sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */ -+ int rc = sqlite3changeset_start(&pIter, nIn, (void*)pIn); - -- if( argc<1 ) return; -- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; -- assert( x.nNode ); -- for(i=1; i<(u32)argc; i++){ -- zPath = (const char*)sqlite3_value_text(argv[i]); -- if( zPath==0 ) goto remove_done; -- pNode = jsonLookup(&x, zPath, 0, ctx); -- if( x.nErr ) goto remove_done; -- if( pNode ) pNode->jnFlags |= JNODE_REMOVE; -+ if( rc==SQLITE_OK ){ -+ rc = sessionRebase(p, pIter, 0, 0, pnOut, ppOut); -+ sqlite3changeset_finalize(pIter); - } -- if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){ -- jsonReturnJson(x.aNode, ctx, 0); -- } --remove_done: -- jsonParseReset(&x); --} - --/* --** json_replace(JSON, PATH, VALUE, ...) --** --** Replace the value at PATH with VALUE. If PATH does not already exist, --** this routine is a no-op. If JSON or PATH is malformed, throw an error. --*/ --static void jsonReplaceFunc( -- sqlite3_context *ctx, -- int argc, -- sqlite3_value **argv --){ -- JsonParse x; /* The parse */ -- JsonNode *pNode; -- const char *zPath; -- u32 i; -- -- if( argc<1 ) return; -- if( (argc&1)==0 ) { -- jsonWrongNumArgs(ctx, "replace"); -- return; -- } -- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; -- assert( x.nNode ); -- for(i=1; i<(u32)argc; i+=2){ -- zPath = (const char*)sqlite3_value_text(argv[i]); -- pNode = jsonLookup(&x, zPath, 0, ctx); -- if( x.nErr ) goto replace_err; -- if( pNode ){ -- pNode->jnFlags |= (u8)JNODE_REPLACE; -- pNode->u.iReplace = i + 1; -- } -- } -- if( x.aNode[0].jnFlags & JNODE_REPLACE ){ -- sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); -- }else{ -- jsonReturnJson(x.aNode, ctx, argv); -- } --replace_err: -- jsonParseReset(&x); -+ return rc; - } - --/* --** json_set(JSON, PATH, VALUE, ...) --** --** Set the value at PATH to VALUE. Create the PATH if it does not already --** exist. Overwrite existing values that do exist. --** If JSON or PATH is malformed, throw an error. --** --** json_insert(JSON, PATH, VALUE, ...) --** --** Create PATH and initialize it to VALUE. If PATH already exists, this --** routine is a no-op. If JSON or PATH is malformed, throw an error. -+/* -+** Rebase a changeset according to current rebaser configuration - */ --static void jsonSetFunc( -- sqlite3_context *ctx, -- int argc, -- sqlite3_value **argv -+SQLITE_API int sqlite3rebaser_rebase_strm( -+ sqlite3_rebaser *p, -+ int (*xInput)(void *pIn, void *pData, int *pnData), -+ void *pIn, -+ int (*xOutput)(void *pOut, const void *pData, int nData), -+ void *pOut - ){ -- JsonParse x; /* The parse */ -- JsonNode *pNode; -- const char *zPath; -- u32 i; -- int bApnd; -- int bIsSet = *(int*)sqlite3_user_data(ctx); -+ sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */ -+ int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn); - -- if( argc<1 ) return; -- if( (argc&1)==0 ) { -- jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); -- return; -- } -- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; -- assert( x.nNode ); -- for(i=1; i<(u32)argc; i+=2){ -- zPath = (const char*)sqlite3_value_text(argv[i]); -- bApnd = 0; -- pNode = jsonLookup(&x, zPath, &bApnd, ctx); -- if( x.oom ){ -- sqlite3_result_error_nomem(ctx); -- goto jsonSetDone; -- }else if( x.nErr ){ -- goto jsonSetDone; -- }else if( pNode && (bApnd || bIsSet) ){ -- pNode->jnFlags |= (u8)JNODE_REPLACE; -- pNode->u.iReplace = i + 1; -- } -- } -- if( x.aNode[0].jnFlags & JNODE_REPLACE ){ -- sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); -- }else{ -- jsonReturnJson(x.aNode, ctx, argv); -- } --jsonSetDone: -- jsonParseReset(&x); --} -- --/* --** json_type(JSON) --** json_type(JSON, PATH) --** --** Return the top-level "type" of a JSON string. Throw an error if --** either the JSON or PATH inputs are not well-formed. --*/ --static void jsonTypeFunc( -- sqlite3_context *ctx, -- int argc, -- sqlite3_value **argv --){ -- JsonParse x; /* The parse */ -- const char *zPath; -- JsonNode *pNode; -- -- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; -- assert( x.nNode ); -- if( argc==2 ){ -- zPath = (const char*)sqlite3_value_text(argv[1]); -- pNode = jsonLookup(&x, zPath, 0, ctx); -- }else{ -- pNode = x.aNode; -- } -- if( pNode ){ -- sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC); -- } -- jsonParseReset(&x); --} -- --/* --** json_valid(JSON) --** --** Return 1 if JSON is a well-formed JSON string according to RFC-7159. --** Return 0 otherwise. --*/ --static void jsonValidFunc( -- sqlite3_context *ctx, -- int argc, -- sqlite3_value **argv --){ -- JsonParse x; /* The parse */ -- int rc = 0; -- -- UNUSED_PARAM(argc); -- if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0 ){ -- rc = 1; -- } -- jsonParseReset(&x); -- sqlite3_result_int(ctx, rc); --} -- -- --/**************************************************************************** --** Aggregate SQL function implementations --****************************************************************************/ --/* --** json_group_array(VALUE) --** --** Return a JSON array composed of all values in the aggregate. --*/ --static void jsonArrayStep( -- sqlite3_context *ctx, -- int argc, -- sqlite3_value **argv --){ -- JsonString *pStr; -- UNUSED_PARAM(argc); -- pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); -- if( pStr ){ -- if( pStr->zBuf==0 ){ -- jsonInit(pStr, ctx); -- jsonAppendChar(pStr, '['); -- }else{ -- jsonAppendChar(pStr, ','); -- pStr->pCtx = ctx; -- } -- jsonAppendValue(pStr, argv[0]); -- } --} --static void jsonArrayFinal(sqlite3_context *ctx){ -- JsonString *pStr; -- pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); -- if( pStr ){ -- pStr->pCtx = ctx; -- jsonAppendChar(pStr, ']'); -- if( pStr->bErr ){ -- if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); -- assert( pStr->bStatic ); -- }else{ -- sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, -- pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); -- pStr->bStatic = 1; -- } -- }else{ -- sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); -- } -- sqlite3_result_subtype(ctx, JSON_SUBTYPE); --} -- --/* --** json_group_obj(NAME,VALUE) --** --** Return a JSON object composed of all names and values in the aggregate. --*/ --static void jsonObjectStep( -- sqlite3_context *ctx, -- int argc, -- sqlite3_value **argv --){ -- JsonString *pStr; -- const char *z; -- u32 n; -- UNUSED_PARAM(argc); -- pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); -- if( pStr ){ -- if( pStr->zBuf==0 ){ -- jsonInit(pStr, ctx); -- jsonAppendChar(pStr, '{'); -- }else{ -- jsonAppendChar(pStr, ','); -- pStr->pCtx = ctx; -- } -- z = (const char*)sqlite3_value_text(argv[0]); -- n = (u32)sqlite3_value_bytes(argv[0]); -- jsonAppendString(pStr, z, n); -- jsonAppendChar(pStr, ':'); -- jsonAppendValue(pStr, argv[1]); -- } --} --static void jsonObjectFinal(sqlite3_context *ctx){ -- JsonString *pStr; -- pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); -- if( pStr ){ -- jsonAppendChar(pStr, '}'); -- if( pStr->bErr ){ -- if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); -- assert( pStr->bStatic ); -- }else{ -- sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, -- pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); -- pStr->bStatic = 1; -- } -- }else{ -- sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); -- } -- sqlite3_result_subtype(ctx, JSON_SUBTYPE); --} -- -- --#ifndef SQLITE_OMIT_VIRTUALTABLE --/**************************************************************************** --** The json_each virtual table --****************************************************************************/ --typedef struct JsonEachCursor JsonEachCursor; --struct JsonEachCursor { -- sqlite3_vtab_cursor base; /* Base class - must be first */ -- u32 iRowid; /* The rowid */ -- u32 iBegin; /* The first node of the scan */ -- u32 i; /* Index in sParse.aNode[] of current row */ -- u32 iEnd; /* EOF when i equals or exceeds this value */ -- u8 eType; /* Type of top-level element */ -- u8 bRecursive; /* True for json_tree(). False for json_each() */ -- char *zJson; /* Input JSON */ -- char *zRoot; /* Path by which to filter zJson */ -- JsonParse sParse; /* Parse of the input JSON */ --}; -- --/* Constructor for the json_each virtual table */ --static int jsonEachConnect( -- sqlite3 *db, -- void *pAux, -- int argc, const char *const*argv, -- sqlite3_vtab **ppVtab, -- char **pzErr --){ -- sqlite3_vtab *pNew; -- int rc; -- --/* Column numbers */ --#define JEACH_KEY 0 --#define JEACH_VALUE 1 --#define JEACH_TYPE 2 --#define JEACH_ATOM 3 --#define JEACH_ID 4 --#define JEACH_PARENT 5 --#define JEACH_FULLKEY 6 --#define JEACH_PATH 7 --#define JEACH_JSON 8 --#define JEACH_ROOT 9 -- -- UNUSED_PARAM(pzErr); -- UNUSED_PARAM(argv); -- UNUSED_PARAM(argc); -- UNUSED_PARAM(pAux); -- rc = sqlite3_declare_vtab(db, -- "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," -- "json HIDDEN,root HIDDEN)"); - if( rc==SQLITE_OK ){ -- pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); -- if( pNew==0 ) return SQLITE_NOMEM; -- memset(pNew, 0, sizeof(*pNew)); -+ rc = sessionRebase(p, pIter, xOutput, pOut, 0, 0); -+ sqlite3changeset_finalize(pIter); - } -- return rc; --} - --/* destructor for json_each virtual table */ --static int jsonEachDisconnect(sqlite3_vtab *pVtab){ -- sqlite3_free(pVtab); -- return SQLITE_OK; --} -- --/* constructor for a JsonEachCursor object for json_each(). */ --static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ -- JsonEachCursor *pCur; -- -- UNUSED_PARAM(p); -- pCur = sqlite3_malloc( sizeof(*pCur) ); -- if( pCur==0 ) return SQLITE_NOMEM; -- memset(pCur, 0, sizeof(*pCur)); -- *ppCursor = &pCur->base; -- return SQLITE_OK; --} -- --/* constructor for a JsonEachCursor object for json_tree(). */ --static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ -- int rc = jsonEachOpenEach(p, ppCursor); -- if( rc==SQLITE_OK ){ -- JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor; -- pCur->bRecursive = 1; -- } - return rc; - } - --/* Reset a JsonEachCursor back to its original state. Free any memory --** held. */ --static void jsonEachCursorReset(JsonEachCursor *p){ -- sqlite3_free(p->zJson); -- sqlite3_free(p->zRoot); -- jsonParseReset(&p->sParse); -- p->iRowid = 0; -- p->i = 0; -- p->iEnd = 0; -- p->eType = 0; -- p->zJson = 0; -- p->zRoot = 0; --} -- --/* Destructor for a jsonEachCursor object */ --static int jsonEachClose(sqlite3_vtab_cursor *cur){ -- JsonEachCursor *p = (JsonEachCursor*)cur; -- jsonEachCursorReset(p); -- sqlite3_free(cur); -- return SQLITE_OK; --} -- --/* Return TRUE if the jsonEachCursor object has been advanced off the end --** of the JSON object */ --static int jsonEachEof(sqlite3_vtab_cursor *cur){ -- JsonEachCursor *p = (JsonEachCursor*)cur; -- return p->i >= p->iEnd; --} -- --/* Advance the cursor to the next element for json_tree() */ --static int jsonEachNext(sqlite3_vtab_cursor *cur){ -- JsonEachCursor *p = (JsonEachCursor*)cur; -- if( p->bRecursive ){ -- if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++; -- p->i++; -- p->iRowid++; -- if( p->i<p->iEnd ){ -- u32 iUp = p->sParse.aUp[p->i]; -- JsonNode *pUp = &p->sParse.aNode[iUp]; -- p->eType = pUp->eType; -- if( pUp->eType==JSON_ARRAY ){ -- if( iUp==p->i-1 ){ -- pUp->u.iKey = 0; -- }else{ -- pUp->u.iKey++; -- } -- } -- } -- }else{ -- switch( p->eType ){ -- case JSON_ARRAY: { -- p->i += jsonNodeSize(&p->sParse.aNode[p->i]); -- p->iRowid++; -- break; -- } -- case JSON_OBJECT: { -- p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]); -- p->iRowid++; -- break; -- } -- default: { -- p->i = p->iEnd; -- break; -- } -- } -+/* -+** Destroy a rebaser object -+*/ -+SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p){ -+ if( p ){ -+ sessionDeleteTable(p->grp.pList); -+ sqlite3_free(p); - } -- return SQLITE_OK; - } - --/* Append the name of the path for element i to pStr -+/* -+** Global configuration - */ --static void jsonEachComputePath( -- JsonEachCursor *p, /* The cursor */ -- JsonString *pStr, /* Write the path here */ -- u32 i /* Path to this element */ --){ -- JsonNode *pNode, *pUp; -- u32 iUp; -- if( i==0 ){ -- jsonAppendChar(pStr, '$'); -- return; -- } -- iUp = p->sParse.aUp[i]; -- jsonEachComputePath(p, pStr, iUp); -- pNode = &p->sParse.aNode[i]; -- pUp = &p->sParse.aNode[iUp]; -- if( pUp->eType==JSON_ARRAY ){ -- jsonPrintf(30, pStr, "[%d]", pUp->u.iKey); -- }else{ -- assert( pUp->eType==JSON_OBJECT ); -- if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--; -- assert( pNode->eType==JSON_STRING ); -- assert( pNode->jnFlags & JNODE_LABEL ); -- jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1); -- } --} -- --/* Return the value of a column */ --static int jsonEachColumn( -- sqlite3_vtab_cursor *cur, /* The cursor */ -- sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ -- int i /* Which column to return */ --){ -- JsonEachCursor *p = (JsonEachCursor*)cur; -- JsonNode *pThis = &p->sParse.aNode[p->i]; -- switch( i ){ -- case JEACH_KEY: { -- if( p->i==0 ) break; -- if( p->eType==JSON_OBJECT ){ -- jsonReturn(pThis, ctx, 0); -- }else if( p->eType==JSON_ARRAY ){ -- u32 iKey; -- if( p->bRecursive ){ -- if( p->iRowid==0 ) break; -- iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey; -- }else{ -- iKey = p->iRowid; -- } -- sqlite3_result_int64(ctx, (sqlite3_int64)iKey); -+SQLITE_API int sqlite3session_config(int op, void *pArg){ -+ int rc = SQLITE_OK; -+ switch( op ){ -+ case SQLITE_SESSION_CONFIG_STRMSIZE: { -+ int *pInt = (int*)pArg; -+ if( *pInt>0 ){ -+ sessions_strm_chunk_size = *pInt; - } -+ *pInt = sessions_strm_chunk_size; - break; - } -- case JEACH_VALUE: { -- if( pThis->jnFlags & JNODE_LABEL ) pThis++; -- jsonReturn(pThis, ctx, 0); -+ default: -+ rc = SQLITE_MISUSE; - break; -- } -- case JEACH_TYPE: { -- if( pThis->jnFlags & JNODE_LABEL ) pThis++; -- sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC); -- break; -- } -- case JEACH_ATOM: { -- if( pThis->jnFlags & JNODE_LABEL ) pThis++; -- if( pThis->eType>=JSON_ARRAY ) break; -- jsonReturn(pThis, ctx, 0); -- break; -- } -- case JEACH_ID: { -- sqlite3_result_int64(ctx, -- (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0)); -- break; -- } -- case JEACH_PARENT: { -- if( p->i>p->iBegin && p->bRecursive ){ -- sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]); -- } -- break; -- } -- case JEACH_FULLKEY: { -- JsonString x; -- jsonInit(&x, ctx); -- if( p->bRecursive ){ -- jsonEachComputePath(p, &x, p->i); -- }else{ -- if( p->zRoot ){ -- jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot)); -- }else{ -- jsonAppendChar(&x, '$'); -- } -- if( p->eType==JSON_ARRAY ){ -- jsonPrintf(30, &x, "[%d]", p->iRowid); -- }else{ -- jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1); -- } -- } -- jsonResult(&x); -- break; -- } -- case JEACH_PATH: { -- if( p->bRecursive ){ -- JsonString x; -- jsonInit(&x, ctx); -- jsonEachComputePath(p, &x, p->sParse.aUp[p->i]); -- jsonResult(&x); -- break; -- } -- /* For json_each() path and root are the same so fall through -- ** into the root case */ -- } -- default: { -- const char *zRoot = p->zRoot; -- if( zRoot==0 ) zRoot = "$"; -- sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC); -- break; -- } -- case JEACH_JSON: { -- assert( i==JEACH_JSON ); -- sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC); -- break; -- } - } -- return SQLITE_OK; --} -- --/* Return the current rowid value */ --static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ -- JsonEachCursor *p = (JsonEachCursor*)cur; -- *pRowid = p->iRowid; -- return SQLITE_OK; --} -- --/* The query strategy is to look for an equality constraint on the json --** column. Without such a constraint, the table cannot operate. idxNum is --** 1 if the constraint is found, 3 if the constraint and zRoot are found, --** and 0 otherwise. --*/ --static int jsonEachBestIndex( -- sqlite3_vtab *tab, -- sqlite3_index_info *pIdxInfo --){ -- int i; -- int jsonIdx = -1; -- int rootIdx = -1; -- const struct sqlite3_index_constraint *pConstraint; -- -- UNUSED_PARAM(tab); -- pConstraint = pIdxInfo->aConstraint; -- for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ -- if( pConstraint->usable==0 ) continue; -- if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; -- switch( pConstraint->iColumn ){ -- case JEACH_JSON: jsonIdx = i; break; -- case JEACH_ROOT: rootIdx = i; break; -- default: /* no-op */ break; -- } -- } -- if( jsonIdx<0 ){ -- pIdxInfo->idxNum = 0; -- pIdxInfo->estimatedCost = 1e99; -- }else{ -- pIdxInfo->estimatedCost = 1.0; -- pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1; -- pIdxInfo->aConstraintUsage[jsonIdx].omit = 1; -- if( rootIdx<0 ){ -- pIdxInfo->idxNum = 1; -- }else{ -- pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2; -- pIdxInfo->aConstraintUsage[rootIdx].omit = 1; -- pIdxInfo->idxNum = 3; -- } -- } -- return SQLITE_OK; --} -- --/* Start a search on a new JSON string */ --static int jsonEachFilter( -- sqlite3_vtab_cursor *cur, -- int idxNum, const char *idxStr, -- int argc, sqlite3_value **argv --){ -- JsonEachCursor *p = (JsonEachCursor*)cur; -- const char *z; -- const char *zRoot = 0; -- sqlite3_int64 n; -- -- UNUSED_PARAM(idxStr); -- UNUSED_PARAM(argc); -- jsonEachCursorReset(p); -- if( idxNum==0 ) return SQLITE_OK; -- z = (const char*)sqlite3_value_text(argv[0]); -- if( z==0 ) return SQLITE_OK; -- n = sqlite3_value_bytes(argv[0]); -- p->zJson = sqlite3_malloc64( n+1 ); -- if( p->zJson==0 ) return SQLITE_NOMEM; -- memcpy(p->zJson, z, (size_t)n+1); -- if( jsonParse(&p->sParse, 0, p->zJson) ){ -- int rc = SQLITE_NOMEM; -- if( p->sParse.oom==0 ){ -- sqlite3_free(cur->pVtab->zErrMsg); -- cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); -- if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR; -- } -- jsonEachCursorReset(p); -- return rc; -- }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){ -- jsonEachCursorReset(p); -- return SQLITE_NOMEM; -- }else{ -- JsonNode *pNode = 0; -- if( idxNum==3 ){ -- const char *zErr = 0; -- zRoot = (const char*)sqlite3_value_text(argv[1]); -- if( zRoot==0 ) return SQLITE_OK; -- n = sqlite3_value_bytes(argv[1]); -- p->zRoot = sqlite3_malloc64( n+1 ); -- if( p->zRoot==0 ) return SQLITE_NOMEM; -- memcpy(p->zRoot, zRoot, (size_t)n+1); -- if( zRoot[0]!='$' ){ -- zErr = zRoot; -- }else{ -- pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr); -- } -- if( zErr ){ -- sqlite3_free(cur->pVtab->zErrMsg); -- cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr); -- jsonEachCursorReset(p); -- return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; -- }else if( pNode==0 ){ -- return SQLITE_OK; -- } -- }else{ -- pNode = p->sParse.aNode; -- } -- p->iBegin = p->i = (int)(pNode - p->sParse.aNode); -- p->eType = pNode->eType; -- if( p->eType>=JSON_ARRAY ){ -- pNode->u.iKey = 0; -- p->iEnd = p->i + pNode->n + 1; -- if( p->bRecursive ){ -- p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType; -- if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){ -- p->i--; -- } -- }else{ -- p->i++; -- } -- }else{ -- p->iEnd = p->i+1; -- } -- } -- return SQLITE_OK; --} -- --/* The methods of the json_each virtual table */ --static sqlite3_module jsonEachModule = { -- 0, /* iVersion */ -- 0, /* xCreate */ -- jsonEachConnect, /* xConnect */ -- jsonEachBestIndex, /* xBestIndex */ -- jsonEachDisconnect, /* xDisconnect */ -- 0, /* xDestroy */ -- jsonEachOpenEach, /* xOpen - open a cursor */ -- jsonEachClose, /* xClose - close a cursor */ -- jsonEachFilter, /* xFilter - configure scan constraints */ -- jsonEachNext, /* xNext - advance a cursor */ -- jsonEachEof, /* xEof - check for end of scan */ -- jsonEachColumn, /* xColumn - read data */ -- jsonEachRowid, /* xRowid - read data */ -- 0, /* xUpdate */ -- 0, /* xBegin */ -- 0, /* xSync */ -- 0, /* xCommit */ -- 0, /* xRollback */ -- 0, /* xFindMethod */ -- 0, /* xRename */ -- 0, /* xSavepoint */ -- 0, /* xRelease */ -- 0 /* xRollbackTo */ --}; -- --/* The methods of the json_tree virtual table. */ --static sqlite3_module jsonTreeModule = { -- 0, /* iVersion */ -- 0, /* xCreate */ -- jsonEachConnect, /* xConnect */ -- jsonEachBestIndex, /* xBestIndex */ -- jsonEachDisconnect, /* xDisconnect */ -- 0, /* xDestroy */ -- jsonEachOpenTree, /* xOpen - open a cursor */ -- jsonEachClose, /* xClose - close a cursor */ -- jsonEachFilter, /* xFilter - configure scan constraints */ -- jsonEachNext, /* xNext - advance a cursor */ -- jsonEachEof, /* xEof - check for end of scan */ -- jsonEachColumn, /* xColumn - read data */ -- jsonEachRowid, /* xRowid - read data */ -- 0, /* xUpdate */ -- 0, /* xBegin */ -- 0, /* xSync */ -- 0, /* xCommit */ -- 0, /* xRollback */ -- 0, /* xFindMethod */ -- 0, /* xRename */ -- 0, /* xSavepoint */ -- 0, /* xRelease */ -- 0 /* xRollbackTo */ --}; --#endif /* SQLITE_OMIT_VIRTUALTABLE */ -- --/**************************************************************************** --** The following routines are the only publically visible identifiers in this --** file. Call the following routines in order to register the various SQL --** functions and the virtual table implemented by this file. --****************************************************************************/ -- --SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){ -- int rc = SQLITE_OK; -- unsigned int i; -- static const struct { -- const char *zName; -- int nArg; -- int flag; -- void (*xFunc)(sqlite3_context*,int,sqlite3_value**); -- } aFunc[] = { -- { "json", 1, 0, jsonRemoveFunc }, -- { "json_array", -1, 0, jsonArrayFunc }, -- { "json_array_length", 1, 0, jsonArrayLengthFunc }, -- { "json_array_length", 2, 0, jsonArrayLengthFunc }, -- { "json_extract", -1, 0, jsonExtractFunc }, -- { "json_insert", -1, 0, jsonSetFunc }, -- { "json_object", -1, 0, jsonObjectFunc }, -- { "json_patch", 2, 0, jsonPatchFunc }, -- { "json_quote", 1, 0, jsonQuoteFunc }, -- { "json_remove", -1, 0, jsonRemoveFunc }, -- { "json_replace", -1, 0, jsonReplaceFunc }, -- { "json_set", -1, 1, jsonSetFunc }, -- { "json_type", 1, 0, jsonTypeFunc }, -- { "json_type", 2, 0, jsonTypeFunc }, -- { "json_valid", 1, 0, jsonValidFunc }, -- --#if SQLITE_DEBUG -- /* DEBUG and TESTING functions */ -- { "json_parse", 1, 0, jsonParseFunc }, -- { "json_test1", 1, 0, jsonTest1Func }, --#endif -- }; -- static const struct { -- const char *zName; -- int nArg; -- void (*xStep)(sqlite3_context*,int,sqlite3_value**); -- void (*xFinal)(sqlite3_context*); -- } aAgg[] = { -- { "json_group_array", 1, jsonArrayStep, jsonArrayFinal }, -- { "json_group_object", 2, jsonObjectStep, jsonObjectFinal }, -- }; --#ifndef SQLITE_OMIT_VIRTUALTABLE -- static const struct { -- const char *zName; -- sqlite3_module *pModule; -- } aMod[] = { -- { "json_each", &jsonEachModule }, -- { "json_tree", &jsonTreeModule }, -- }; --#endif -- for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){ -- rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg, -- SQLITE_UTF8 | SQLITE_DETERMINISTIC, -- (void*)&aFunc[i].flag, -- aFunc[i].xFunc, 0, 0); -- } -- for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){ -- rc = sqlite3_create_function(db, aAgg[i].zName, aAgg[i].nArg, -- SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, -- 0, aAgg[i].xStep, aAgg[i].xFinal); -- } --#ifndef SQLITE_OMIT_VIRTUALTABLE -- for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){ -- rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0); -- } --#endif - return rc; - } - -+#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */ - --#ifndef SQLITE_CORE --#ifdef _WIN32 --__declspec(dllexport) --#endif --SQLITE_API int sqlite3_json_init( -- sqlite3 *db, -- char **pzErrMsg, -- const sqlite3_api_routines *pApi --){ -- SQLITE_EXTENSION_INIT2(pApi); -- (void)pzErrMsg; /* Unused parameter */ -- return sqlite3Json1Init(db); --} --#endif --#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) */ -- --/************** End of json1.c ***********************************************/ -+/************** End of sqlite3session.c **************************************/ - /************** Begin file fts5.c ********************************************/ - - -@@ -183491,7 +198794,7 @@ - ** This way, even if the tokenizer does not provide synonyms - ** when tokenizing query text (it should not - to do would be - ** inefficient), it doesn't matter if the user queries for --** 'first + place' or '1st + place', as there are entires in the -+** 'first + place' or '1st + place', as there are entries in the - ** FTS index corresponding to both forms of the first token. - ** </ol> - ** -@@ -183519,7 +198822,7 @@ - ** extra data to the FTS index or require FTS5 to query for multiple terms, - ** so it is efficient in terms of disk space and query speed. However, it - ** does not support prefix queries very well. If, as suggested above, the --** token "first" is subsituted for "1st" by the tokenizer, then the query: -+** token "first" is substituted for "1st" by the tokenizer, then the query: - ** - ** <codeblock> - ** ... MATCH '1s*'</codeblock> -@@ -184349,6 +199652,8 @@ - int bPrefix - ); - -+static void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase*); -+ - static Fts5ExprNearset *sqlite3Fts5ParseNearset( - Fts5Parse*, - Fts5ExprNearset*, -@@ -184409,9 +199714,12 @@ - /************************************************************************** - ** Interface to automatically generated code in fts5_unicode2.c. - */ --static int sqlite3Fts5UnicodeIsalnum(int c); - static int sqlite3Fts5UnicodeIsdiacritic(int c); - static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic); -+ -+static int sqlite3Fts5UnicodeCatParse(const char*, u8*); -+static int sqlite3Fts5UnicodeCategory(int iCode); -+static void sqlite3Fts5UnicodeAscii(u8*, u8*); - /* - ** End of interface to code in fts5_unicode2.c. - **************************************************************************/ -@@ -184429,9 +199737,10 @@ - #define FTS5_STRING 9 - #define FTS5_LP 10 - #define FTS5_RP 11 --#define FTS5_COMMA 12 --#define FTS5_PLUS 13 --#define FTS5_STAR 14 -+#define FTS5_CARET 12 -+#define FTS5_COMMA 13 -+#define FTS5_PLUS 14 -+#define FTS5_STAR 15 - - /* - ** 2000-05-29 -@@ -184458,6 +199767,7 @@ - ** input grammar file: - */ - /* #include <stdio.h> */ -+/* #include <assert.h> */ - /************ Begin %include sections from the grammar ************************/ - - /* #include "fts5Int.h" */ -@@ -184526,19 +199836,23 @@ - ** zero the stack is dynamically sized using realloc() - ** sqlite3Fts5ParserARG_SDECL A static variable declaration for the %extra_argument - ** sqlite3Fts5ParserARG_PDECL A parameter declaration for the %extra_argument -+** sqlite3Fts5ParserARG_PARAM Code to pass %extra_argument as a subroutine parameter - ** sqlite3Fts5ParserARG_STORE Code to store %extra_argument into fts5yypParser - ** sqlite3Fts5ParserARG_FETCH Code to extract %extra_argument from fts5yypParser -+** sqlite3Fts5ParserCTX_* As sqlite3Fts5ParserARG_ except for %extra_context - ** fts5YYERRORSYMBOL is the code number of the error symbol. If not - ** defined, then do no error processing. - ** fts5YYNSTATE the combined number of states. - ** fts5YYNRULE the number of rules in the grammar -+** fts5YYNFTS5TOKEN Number of terminal symbols - ** fts5YY_MAX_SHIFT Maximum value for shift actions - ** fts5YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions - ** fts5YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions --** fts5YY_MIN_REDUCE Maximum value for reduce actions - ** fts5YY_ERROR_ACTION The fts5yy_action[] code for syntax error - ** fts5YY_ACCEPT_ACTION The fts5yy_action[] code for accept - ** fts5YY_NO_ACTION The fts5yy_action[] code for no-op -+** fts5YY_MIN_REDUCE Minimum value for reduce actions -+** fts5YY_MAX_REDUCE Maximum value for reduce actions - */ - #ifndef INTERFACE - # define INTERFACE 1 -@@ -184545,7 +199859,7 @@ - #endif - /************* Begin control #defines *****************************************/ - #define fts5YYCODETYPE unsigned char --#define fts5YYNOCODE 28 -+#define fts5YYNOCODE 27 - #define fts5YYACTIONTYPE unsigned char - #define sqlite3Fts5ParserFTS5TOKENTYPE Fts5Token - typedef union { -@@ -184562,19 +199876,27 @@ - #endif - #define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse; - #define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse --#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse = fts5yypParser->pParse --#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse = pParse --#define fts5YYNSTATE 33 --#define fts5YYNRULE 27 --#define fts5YY_MAX_SHIFT 32 --#define fts5YY_MIN_SHIFTREDUCE 50 --#define fts5YY_MAX_SHIFTREDUCE 76 --#define fts5YY_MIN_REDUCE 77 --#define fts5YY_MAX_REDUCE 103 --#define fts5YY_ERROR_ACTION 104 --#define fts5YY_ACCEPT_ACTION 105 --#define fts5YY_NO_ACTION 106 -+#define sqlite3Fts5ParserARG_PARAM ,pParse -+#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse; -+#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse; -+#define sqlite3Fts5ParserCTX_SDECL -+#define sqlite3Fts5ParserCTX_PDECL -+#define sqlite3Fts5ParserCTX_PARAM -+#define sqlite3Fts5ParserCTX_FETCH -+#define sqlite3Fts5ParserCTX_STORE -+#define fts5YYNSTATE 35 -+#define fts5YYNRULE 28 -+#define fts5YYNFTS5TOKEN 16 -+#define fts5YY_MAX_SHIFT 34 -+#define fts5YY_MIN_SHIFTREDUCE 52 -+#define fts5YY_MAX_SHIFTREDUCE 79 -+#define fts5YY_ERROR_ACTION 80 -+#define fts5YY_ACCEPT_ACTION 81 -+#define fts5YY_NO_ACTION 82 -+#define fts5YY_MIN_REDUCE 83 -+#define fts5YY_MAX_REDUCE 110 - /************* End control #defines *******************************************/ -+#define fts5YY_NLOOKAHEAD ((int)(sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0]))) - - /* Define the fts5yytestcase() macro to be a no-op if is not already defined - ** otherwise. -@@ -184603,9 +199925,6 @@ - ** N between fts5YY_MIN_SHIFTREDUCE Shift to an arbitrary state then - ** and fts5YY_MAX_SHIFTREDUCE reduce by rule N-fts5YY_MIN_SHIFTREDUCE. - ** --** N between fts5YY_MIN_REDUCE Reduce by rule N-fts5YY_MIN_REDUCE --** and fts5YY_MAX_REDUCE --** - ** N == fts5YY_ERROR_ACTION A syntax error has occurred. - ** - ** N == fts5YY_ACCEPT_ACTION The parser accepts its input. -@@ -184613,6 +199932,9 @@ - ** N == fts5YY_NO_ACTION No such action. Denotes unused - ** slots in the fts5yy_action[] table. - ** -+** N between fts5YY_MIN_REDUCE Reduce by rule N-fts5YY_MIN_REDUCE -+** and fts5YY_MAX_REDUCE -+** - ** The action table is constructed as a single large table named fts5yy_action[]. - ** Given state S and lookahead X, the action is computed as either: - ** -@@ -184619,19 +199941,13 @@ - ** (A) N = fts5yy_action[ fts5yy_shift_ofst[S] + X ] - ** (B) N = fts5yy_default[S] - ** --** The (A) formula is preferred. The B formula is used instead if: --** (1) The fts5yy_shift_ofst[S]+X value is out of range, or --** (2) fts5yy_lookahead[fts5yy_shift_ofst[S]+X] is not equal to X, or --** (3) fts5yy_shift_ofst[S] equal fts5YY_SHIFT_USE_DFLT. --** (Implementation note: fts5YY_SHIFT_USE_DFLT is chosen so that --** fts5YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X. --** Hence only tests (1) and (2) need to be evaluated.) -+** The (A) formula is preferred. The B formula is used instead if -+** fts5yy_lookahead[fts5yy_shift_ofst[S]+X] is not equal to X. - ** - ** The formulas above are for computing the action when the lookahead is - ** a terminal symbol. If the lookahead is a non-terminal (as occurs after - ** a reduce action) then the fts5yy_reduce_ofst[] array is used in place of --** the fts5yy_shift_ofst[] array and fts5YY_REDUCE_USE_DFLT is used in place of --** fts5YY_SHIFT_USE_DFLT. -+** the fts5yy_shift_ofst[] array. - ** - ** The following are the tables generated in this section: - ** -@@ -184645,54 +199961,56 @@ - ** fts5yy_default[] Default action for each state. - ** - *********** Begin parsing tables **********************************************/ --#define fts5YY_ACTTAB_COUNT (98) -+#define fts5YY_ACTTAB_COUNT (105) - static const fts5YYACTIONTYPE fts5yy_action[] = { -- /* 0 */ 105, 19, 90, 6, 26, 93, 92, 24, 24, 17, -- /* 10 */ 90, 6, 26, 16, 92, 54, 24, 18, 90, 6, -- /* 20 */ 26, 10, 92, 12, 24, 75, 86, 90, 6, 26, -- /* 30 */ 13, 92, 75, 24, 20, 90, 6, 26, 101, 92, -- /* 40 */ 56, 24, 27, 90, 6, 26, 100, 92, 21, 24, -- /* 50 */ 23, 15, 30, 11, 1, 91, 22, 25, 9, 92, -- /* 60 */ 7, 24, 3, 4, 5, 3, 4, 5, 3, 77, -- /* 70 */ 4, 5, 3, 61, 23, 15, 60, 11, 80, 12, -- /* 80 */ 2, 13, 68, 10, 29, 52, 55, 75, 31, 32, -- /* 90 */ 8, 28, 5, 3, 51, 55, 72, 14, -+ /* 0 */ 81, 20, 96, 6, 28, 99, 98, 26, 26, 18, -+ /* 10 */ 96, 6, 28, 17, 98, 56, 26, 19, 96, 6, -+ /* 20 */ 28, 14, 98, 14, 26, 31, 92, 96, 6, 28, -+ /* 30 */ 108, 98, 25, 26, 21, 96, 6, 28, 78, 98, -+ /* 40 */ 58, 26, 29, 96, 6, 28, 107, 98, 22, 26, -+ /* 50 */ 24, 16, 12, 11, 1, 13, 13, 24, 16, 23, -+ /* 60 */ 11, 33, 34, 13, 97, 8, 27, 32, 98, 7, -+ /* 70 */ 26, 3, 4, 5, 3, 4, 5, 3, 83, 4, -+ /* 80 */ 5, 3, 63, 5, 3, 62, 12, 2, 86, 13, -+ /* 90 */ 9, 30, 10, 10, 54, 57, 75, 78, 78, 53, -+ /* 100 */ 57, 15, 82, 82, 71, - }; - static const fts5YYCODETYPE fts5yy_lookahead[] = { - /* 0 */ 16, 17, 18, 19, 20, 22, 22, 24, 24, 17, - /* 10 */ 18, 19, 20, 7, 22, 9, 24, 17, 18, 19, -- /* 20 */ 20, 10, 22, 9, 24, 14, 17, 18, 19, 20, -- /* 30 */ 9, 22, 14, 24, 17, 18, 19, 20, 26, 22, -+ /* 20 */ 20, 9, 22, 9, 24, 13, 17, 18, 19, 20, -+ /* 30 */ 26, 22, 24, 24, 17, 18, 19, 20, 15, 22, - /* 40 */ 9, 24, 17, 18, 19, 20, 26, 22, 21, 24, -- /* 50 */ 6, 7, 13, 9, 10, 18, 21, 20, 5, 22, -- /* 60 */ 5, 24, 3, 1, 2, 3, 1, 2, 3, 0, -- /* 70 */ 1, 2, 3, 11, 6, 7, 11, 9, 5, 9, -- /* 80 */ 10, 9, 11, 10, 12, 8, 9, 14, 24, 25, -- /* 90 */ 23, 24, 2, 3, 8, 9, 9, 9, -+ /* 50 */ 6, 7, 9, 9, 10, 12, 12, 6, 7, 21, -+ /* 60 */ 9, 24, 25, 12, 18, 5, 20, 14, 22, 5, -+ /* 70 */ 24, 3, 1, 2, 3, 1, 2, 3, 0, 1, -+ /* 80 */ 2, 3, 11, 2, 3, 11, 9, 10, 5, 12, -+ /* 90 */ 23, 24, 10, 10, 8, 9, 9, 15, 15, 8, -+ /* 100 */ 9, 9, 27, 27, 11, 27, 27, 27, 27, 27, -+ /* 110 */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -+ /* 120 */ 27, - }; --#define fts5YY_SHIFT_USE_DFLT (98) --#define fts5YY_SHIFT_COUNT (32) -+#define fts5YY_SHIFT_COUNT (34) - #define fts5YY_SHIFT_MIN (0) --#define fts5YY_SHIFT_MAX (90) -+#define fts5YY_SHIFT_MAX (93) - static const unsigned char fts5yy_shift_ofst[] = { -- /* 0 */ 44, 44, 44, 44, 44, 44, 68, 70, 72, 14, -- /* 10 */ 21, 73, 11, 18, 18, 31, 31, 62, 65, 69, -- /* 20 */ 90, 77, 86, 6, 39, 53, 55, 59, 39, 87, -- /* 30 */ 88, 39, 71, -+ /* 0 */ 44, 44, 44, 44, 44, 44, 51, 77, 43, 12, -+ /* 10 */ 14, 83, 82, 14, 23, 23, 31, 31, 71, 74, -+ /* 20 */ 78, 81, 86, 91, 6, 53, 53, 60, 64, 68, -+ /* 30 */ 53, 87, 92, 53, 93, - }; --#define fts5YY_REDUCE_USE_DFLT (-18) --#define fts5YY_REDUCE_COUNT (16) -+#define fts5YY_REDUCE_COUNT (17) - #define fts5YY_REDUCE_MIN (-17) - #define fts5YY_REDUCE_MAX (67) - static const signed char fts5yy_reduce_ofst[] = { -- /* 0 */ -16, -8, 0, 9, 17, 25, 37, -17, 64, -17, -- /* 10 */ 67, 12, 12, 12, 20, 27, 35, -+ /* 0 */ -16, -8, 0, 9, 17, 25, 46, -17, -17, 37, -+ /* 10 */ 67, 4, 4, 8, 4, 20, 27, 38, - }; - static const fts5YYACTIONTYPE fts5yy_default[] = { -- /* 0 */ 104, 104, 104, 104, 104, 104, 89, 104, 98, 104, -- /* 10 */ 104, 103, 103, 103, 103, 104, 104, 104, 104, 104, -- /* 20 */ 85, 104, 104, 104, 94, 104, 104, 84, 96, 104, -- /* 30 */ 104, 97, 104, -+ /* 0 */ 80, 80, 80, 80, 80, 80, 95, 80, 80, 105, -+ /* 10 */ 80, 110, 110, 80, 110, 110, 80, 80, 80, 80, -+ /* 20 */ 80, 91, 80, 80, 80, 101, 100, 80, 80, 90, -+ /* 30 */ 103, 80, 80, 104, 80, - }; - /********** End of lemon-generated parsing tables *****************************/ - -@@ -184751,6 +200069,7 @@ - int fts5yyerrcnt; /* Shifts left before out of the error */ - #endif - sqlite3Fts5ParserARG_SDECL /* A place to hold %extra_argument */ -+ sqlite3Fts5ParserCTX_SDECL /* A place to hold %extra_context */ - #if fts5YYSTACKDEPTH<=0 - int fts5yystksz; /* Current side of the stack */ - fts5yyStackEntry *fts5yystack; /* The parser's stack */ -@@ -184794,19 +200113,39 @@ - } - #endif /* NDEBUG */ - --#ifndef NDEBUG -+#if defined(fts5YYCOVERAGE) || !defined(NDEBUG) - /* For tracing shifts, the names of all terminals and nonterminals - ** are required. The following table supplies these names */ - static const char *const fts5yyTokenName[] = { -- "$", "OR", "AND", "NOT", -- "TERM", "COLON", "MINUS", "LCP", -- "RCP", "STRING", "LP", "RP", -- "COMMA", "PLUS", "STAR", "error", -- "input", "expr", "cnearset", "exprlist", -- "colset", "colsetlist", "nearset", "nearphrases", -- "phrase", "neardist_opt", "star_opt", -+ /* 0 */ "$", -+ /* 1 */ "OR", -+ /* 2 */ "AND", -+ /* 3 */ "NOT", -+ /* 4 */ "TERM", -+ /* 5 */ "COLON", -+ /* 6 */ "MINUS", -+ /* 7 */ "LCP", -+ /* 8 */ "RCP", -+ /* 9 */ "STRING", -+ /* 10 */ "LP", -+ /* 11 */ "RP", -+ /* 12 */ "CARET", -+ /* 13 */ "COMMA", -+ /* 14 */ "PLUS", -+ /* 15 */ "STAR", -+ /* 16 */ "input", -+ /* 17 */ "expr", -+ /* 18 */ "cnearset", -+ /* 19 */ "exprlist", -+ /* 20 */ "colset", -+ /* 21 */ "colsetlist", -+ /* 22 */ "nearset", -+ /* 23 */ "nearphrases", -+ /* 24 */ "phrase", -+ /* 25 */ "neardist_opt", -+ /* 26 */ "star_opt", - }; --#endif /* NDEBUG */ -+#endif /* defined(fts5YYCOVERAGE) || !defined(NDEBUG) */ - - #ifndef NDEBUG - /* For tracing reduce actions, the names of all rules are required. -@@ -184830,15 +200169,16 @@ - /* 15 */ "cnearset ::= nearset", - /* 16 */ "cnearset ::= colset COLON nearset", - /* 17 */ "nearset ::= phrase", -- /* 18 */ "nearset ::= STRING LP nearphrases neardist_opt RP", -- /* 19 */ "nearphrases ::= phrase", -- /* 20 */ "nearphrases ::= nearphrases phrase", -- /* 21 */ "neardist_opt ::=", -- /* 22 */ "neardist_opt ::= COMMA STRING", -- /* 23 */ "phrase ::= phrase PLUS STRING star_opt", -- /* 24 */ "phrase ::= STRING star_opt", -- /* 25 */ "star_opt ::= STAR", -- /* 26 */ "star_opt ::=", -+ /* 18 */ "nearset ::= CARET phrase", -+ /* 19 */ "nearset ::= STRING LP nearphrases neardist_opt RP", -+ /* 20 */ "nearphrases ::= phrase", -+ /* 21 */ "nearphrases ::= nearphrases phrase", -+ /* 22 */ "neardist_opt ::=", -+ /* 23 */ "neardist_opt ::= COMMA STRING", -+ /* 24 */ "phrase ::= phrase PLUS STRING star_opt", -+ /* 25 */ "phrase ::= STRING star_opt", -+ /* 26 */ "star_opt ::= STAR", -+ /* 27 */ "star_opt ::=", - }; - #endif /* NDEBUG */ - -@@ -184887,28 +200227,29 @@ - - /* Initialize a new parser that has already been allocated. - */ --static void sqlite3Fts5ParserInit(void *fts5yypParser){ -- fts5yyParser *pParser = (fts5yyParser*)fts5yypParser; -+static void sqlite3Fts5ParserInit(void *fts5yypRawParser sqlite3Fts5ParserCTX_PDECL){ -+ fts5yyParser *fts5yypParser = (fts5yyParser*)fts5yypRawParser; -+ sqlite3Fts5ParserCTX_STORE - #ifdef fts5YYTRACKMAXSTACKDEPTH -- pParser->fts5yyhwm = 0; -+ fts5yypParser->fts5yyhwm = 0; - #endif - #if fts5YYSTACKDEPTH<=0 -- pParser->fts5yytos = NULL; -- pParser->fts5yystack = NULL; -- pParser->fts5yystksz = 0; -- if( fts5yyGrowStack(pParser) ){ -- pParser->fts5yystack = &pParser->fts5yystk0; -- pParser->fts5yystksz = 1; -+ fts5yypParser->fts5yytos = NULL; -+ fts5yypParser->fts5yystack = NULL; -+ fts5yypParser->fts5yystksz = 0; -+ if( fts5yyGrowStack(fts5yypParser) ){ -+ fts5yypParser->fts5yystack = &fts5yypParser->fts5yystk0; -+ fts5yypParser->fts5yystksz = 1; - } - #endif - #ifndef fts5YYNOERRORRECOVERY -- pParser->fts5yyerrcnt = -1; -+ fts5yypParser->fts5yyerrcnt = -1; - #endif -- pParser->fts5yytos = pParser->fts5yystack; -- pParser->fts5yystack[0].stateno = 0; -- pParser->fts5yystack[0].major = 0; -+ fts5yypParser->fts5yytos = fts5yypParser->fts5yystack; -+ fts5yypParser->fts5yystack[0].stateno = 0; -+ fts5yypParser->fts5yystack[0].major = 0; - #if fts5YYSTACKDEPTH>0 -- pParser->fts5yystackEnd = &pParser->fts5yystack[fts5YYSTACKDEPTH-1]; -+ fts5yypParser->fts5yystackEnd = &fts5yypParser->fts5yystack[fts5YYSTACKDEPTH-1]; - #endif - } - -@@ -184925,11 +200266,14 @@ - ** A pointer to a parser. This pointer is used in subsequent calls - ** to sqlite3Fts5Parser and sqlite3Fts5ParserFree. - */ --static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(fts5YYMALLOCARGTYPE)){ -- fts5yyParser *pParser; -- pParser = (fts5yyParser*)(*mallocProc)( (fts5YYMALLOCARGTYPE)sizeof(fts5yyParser) ); -- if( pParser ) sqlite3Fts5ParserInit(pParser); -- return pParser; -+static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(fts5YYMALLOCARGTYPE) sqlite3Fts5ParserCTX_PDECL){ -+ fts5yyParser *fts5yypParser; -+ fts5yypParser = (fts5yyParser*)(*mallocProc)( (fts5YYMALLOCARGTYPE)sizeof(fts5yyParser) ); -+ if( fts5yypParser ){ -+ sqlite3Fts5ParserCTX_STORE -+ sqlite3Fts5ParserInit(fts5yypParser sqlite3Fts5ParserCTX_PARAM); -+ } -+ return (void*)fts5yypParser; - } - #endif /* sqlite3Fts5Parser_ENGINEALWAYSONSTACK */ - -@@ -184946,7 +200290,8 @@ - fts5YYCODETYPE fts5yymajor, /* Type code for object to destroy */ - fts5YYMINORTYPE *fts5yypminor /* The object to be destroyed */ - ){ -- sqlite3Fts5ParserARG_FETCH; -+ sqlite3Fts5ParserARG_FETCH -+ sqlite3Fts5ParserCTX_FETCH - switch( fts5yymajor ){ - /* Here is inserted the actions which take place when a - ** terminal or non-terminal is destroyed. This can happen -@@ -185056,24 +200401,66 @@ - } - #endif - -+/* This array of booleans keeps track of the parser statement -+** coverage. The element fts5yycoverage[X][Y] is set when the parser -+** is in state X and has a lookahead token Y. In a well-tested -+** systems, every element of this matrix should end up being set. -+*/ -+#if defined(fts5YYCOVERAGE) -+static unsigned char fts5yycoverage[fts5YYNSTATE][fts5YYNFTS5TOKEN]; -+#endif -+ - /* -+** Write into out a description of every state/lookahead combination that -+** -+** (1) has not been used by the parser, and -+** (2) is not a syntax error. -+** -+** Return the number of missed state/lookahead combinations. -+*/ -+#if defined(fts5YYCOVERAGE) -+static int sqlite3Fts5ParserCoverage(FILE *out){ -+ int stateno, iLookAhead, i; -+ int nMissed = 0; -+ for(stateno=0; stateno<fts5YYNSTATE; stateno++){ -+ i = fts5yy_shift_ofst[stateno]; -+ for(iLookAhead=0; iLookAhead<fts5YYNFTS5TOKEN; iLookAhead++){ -+ if( fts5yy_lookahead[i+iLookAhead]!=iLookAhead ) continue; -+ if( fts5yycoverage[stateno][iLookAhead]==0 ) nMissed++; -+ if( out ){ -+ fprintf(out,"State %d lookahead %s %s\n", stateno, -+ fts5yyTokenName[iLookAhead], -+ fts5yycoverage[stateno][iLookAhead] ? "ok" : "missed"); -+ } -+ } -+ } -+ return nMissed; -+} -+#endif -+ -+/* - ** Find the appropriate action for a parser given the terminal - ** look-ahead token iLookAhead. - */ --static unsigned int fts5yy_find_shift_action( -- fts5yyParser *pParser, /* The parser */ -- fts5YYCODETYPE iLookAhead /* The look-ahead token */ -+static fts5YYACTIONTYPE fts5yy_find_shift_action( -+ fts5YYCODETYPE iLookAhead, /* The look-ahead token */ -+ fts5YYACTIONTYPE stateno /* Current state number */ - ){ - int i; -- int stateno = pParser->fts5yytos->stateno; -- -- if( stateno>=fts5YY_MIN_REDUCE ) return stateno; -+ -+ if( stateno>fts5YY_MAX_SHIFT ) return stateno; - assert( stateno <= fts5YY_SHIFT_COUNT ); -+#if defined(fts5YYCOVERAGE) -+ fts5yycoverage[stateno][iLookAhead] = 1; -+#endif - do{ - i = fts5yy_shift_ofst[stateno]; -+ assert( i>=0 ); -+ /* assert( i+fts5YYNFTS5TOKEN<=(int)fts5YY_NLOOKAHEAD ); */ - assert( iLookAhead!=fts5YYNOCODE ); -+ assert( iLookAhead < fts5YYNFTS5TOKEN ); - i += iLookAhead; -- if( i<0 || i>=fts5YY_ACTTAB_COUNT || fts5yy_lookahead[i]!=iLookAhead ){ -+ if( i>=fts5YY_NLOOKAHEAD || fts5yy_lookahead[i]!=iLookAhead ){ - #ifdef fts5YYFALLBACK - fts5YYCODETYPE iFallback; /* Fallback token */ - if( iLookAhead<sizeof(fts5yyFallback)/sizeof(fts5yyFallback[0]) -@@ -185099,6 +200486,7 @@ - #if fts5YY_SHIFT_MAX+fts5YYWILDCARD>=fts5YY_ACTTAB_COUNT - j<fts5YY_ACTTAB_COUNT && - #endif -+ j<(int)(sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0])) && - fts5yy_lookahead[j]==fts5YYWILDCARD && iLookAhead>0 - ){ - #ifndef NDEBUG -@@ -185123,8 +200511,8 @@ - ** Find the appropriate action for a parser given the non-terminal - ** look-ahead token iLookAhead. - */ --static int fts5yy_find_reduce_action( -- int stateno, /* Current state number */ -+static fts5YYACTIONTYPE fts5yy_find_reduce_action( -+ fts5YYACTIONTYPE stateno, /* Current state number */ - fts5YYCODETYPE iLookAhead /* The look-ahead token */ - ){ - int i; -@@ -185136,7 +200524,6 @@ - assert( stateno<=fts5YY_REDUCE_COUNT ); - #endif - i = fts5yy_reduce_ofst[stateno]; -- assert( i!=fts5YY_REDUCE_USE_DFLT ); - assert( iLookAhead!=fts5YYNOCODE ); - i += iLookAhead; - #ifdef fts5YYERRORSYMBOL -@@ -185154,7 +200541,8 @@ - ** The following routine is called if the stack overflows. - */ - static void fts5yyStackOverflow(fts5yyParser *fts5yypParser){ -- sqlite3Fts5ParserARG_FETCH; -+ sqlite3Fts5ParserARG_FETCH -+ sqlite3Fts5ParserCTX_FETCH - #ifndef NDEBUG - if( fts5yyTraceFILE ){ - fprintf(fts5yyTraceFILE,"%sStack Overflow!\n",fts5yyTracePrompt); -@@ -185167,7 +200555,8 @@ - - sqlite3Fts5ParseError(pParse, "fts5: parser stack overflow"); - /******** End %stack_overflow code ********************************************/ -- sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument var */ -+ sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument var */ -+ sqlite3Fts5ParserCTX_STORE - } - - /* -@@ -185174,20 +200563,21 @@ - ** Print tracing information for a SHIFT action - */ - #ifndef NDEBUG --static void fts5yyTraceShift(fts5yyParser *fts5yypParser, int fts5yyNewState){ -+static void fts5yyTraceShift(fts5yyParser *fts5yypParser, int fts5yyNewState, const char *zTag){ - if( fts5yyTraceFILE ){ - if( fts5yyNewState<fts5YYNSTATE ){ -- fprintf(fts5yyTraceFILE,"%sShift '%s', go to state %d\n", -- fts5yyTracePrompt,fts5yyTokenName[fts5yypParser->fts5yytos->major], -+ fprintf(fts5yyTraceFILE,"%s%s '%s', go to state %d\n", -+ fts5yyTracePrompt, zTag, fts5yyTokenName[fts5yypParser->fts5yytos->major], - fts5yyNewState); - }else{ -- fprintf(fts5yyTraceFILE,"%sShift '%s'\n", -- fts5yyTracePrompt,fts5yyTokenName[fts5yypParser->fts5yytos->major]); -+ fprintf(fts5yyTraceFILE,"%s%s '%s', pending reduce %d\n", -+ fts5yyTracePrompt, zTag, fts5yyTokenName[fts5yypParser->fts5yytos->major], -+ fts5yyNewState - fts5YY_MIN_REDUCE); - } - } - } - #else --# define fts5yyTraceShift(X,Y) -+# define fts5yyTraceShift(X,Y,Z) - #endif - - /* -@@ -185195,8 +200585,8 @@ - */ - static void fts5yy_shift( - fts5yyParser *fts5yypParser, /* The parser to be shifted */ -- int fts5yyNewState, /* The new state to shift in */ -- int fts5yyMajor, /* The major token to shift in */ -+ fts5YYACTIONTYPE fts5yyNewState, /* The new state to shift in */ -+ fts5YYCODETYPE fts5yyMajor, /* The major token to shift in */ - sqlite3Fts5ParserFTS5TOKENTYPE fts5yyMinor /* The minor token to shift in */ - ){ - fts5yyStackEntry *fts5yytos; -@@ -185226,10 +200616,10 @@ - fts5yyNewState += fts5YY_MIN_REDUCE - fts5YY_MIN_SHIFTREDUCE; - } - fts5yytos = fts5yypParser->fts5yytos; -- fts5yytos->stateno = (fts5YYACTIONTYPE)fts5yyNewState; -- fts5yytos->major = (fts5YYCODETYPE)fts5yyMajor; -+ fts5yytos->stateno = fts5yyNewState; -+ fts5yytos->major = fts5yyMajor; - fts5yytos->minor.fts5yy0 = fts5yyMinor; -- fts5yyTraceShift(fts5yypParser, fts5yyNewState); -+ fts5yyTraceShift(fts5yypParser, fts5yyNewState, "Shift"); - } - - /* The following table contains information about every rule that -@@ -185239,33 +200629,34 @@ - fts5YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ - signed char nrhs; /* Negative of the number of RHS symbols in the rule */ - } fts5yyRuleInfo[] = { -- { 16, -1 }, -- { 20, -4 }, -- { 20, -3 }, -- { 20, -1 }, -- { 20, -2 }, -- { 21, -2 }, -- { 21, -1 }, -- { 17, -3 }, -- { 17, -3 }, -- { 17, -3 }, -- { 17, -5 }, -- { 17, -3 }, -- { 17, -1 }, -- { 19, -1 }, -- { 19, -2 }, -- { 18, -1 }, -- { 18, -3 }, -- { 22, -1 }, -- { 22, -5 }, -- { 23, -1 }, -- { 23, -2 }, -- { 25, 0 }, -- { 25, -2 }, -- { 24, -4 }, -- { 24, -2 }, -- { 26, -1 }, -- { 26, 0 }, -+ { 16, -1 }, /* (0) input ::= expr */ -+ { 20, -4 }, /* (1) colset ::= MINUS LCP colsetlist RCP */ -+ { 20, -3 }, /* (2) colset ::= LCP colsetlist RCP */ -+ { 20, -1 }, /* (3) colset ::= STRING */ -+ { 20, -2 }, /* (4) colset ::= MINUS STRING */ -+ { 21, -2 }, /* (5) colsetlist ::= colsetlist STRING */ -+ { 21, -1 }, /* (6) colsetlist ::= STRING */ -+ { 17, -3 }, /* (7) expr ::= expr AND expr */ -+ { 17, -3 }, /* (8) expr ::= expr OR expr */ -+ { 17, -3 }, /* (9) expr ::= expr NOT expr */ -+ { 17, -5 }, /* (10) expr ::= colset COLON LP expr RP */ -+ { 17, -3 }, /* (11) expr ::= LP expr RP */ -+ { 17, -1 }, /* (12) expr ::= exprlist */ -+ { 19, -1 }, /* (13) exprlist ::= cnearset */ -+ { 19, -2 }, /* (14) exprlist ::= exprlist cnearset */ -+ { 18, -1 }, /* (15) cnearset ::= nearset */ -+ { 18, -3 }, /* (16) cnearset ::= colset COLON nearset */ -+ { 22, -1 }, /* (17) nearset ::= phrase */ -+ { 22, -2 }, /* (18) nearset ::= CARET phrase */ -+ { 22, -5 }, /* (19) nearset ::= STRING LP nearphrases neardist_opt RP */ -+ { 23, -1 }, /* (20) nearphrases ::= phrase */ -+ { 23, -2 }, /* (21) nearphrases ::= nearphrases phrase */ -+ { 25, 0 }, /* (22) neardist_opt ::= */ -+ { 25, -2 }, /* (23) neardist_opt ::= COMMA STRING */ -+ { 24, -4 }, /* (24) phrase ::= phrase PLUS STRING star_opt */ -+ { 24, -2 }, /* (25) phrase ::= STRING star_opt */ -+ { 26, -1 }, /* (26) star_opt ::= STAR */ -+ { 26, 0 }, /* (27) star_opt ::= */ - }; - - static void fts5yy_accept(fts5yyParser*); /* Forward Declaration */ -@@ -185273,22 +200664,39 @@ - /* - ** Perform a reduce action and the shift that must immediately - ** follow the reduce. -+** -+** The fts5yyLookahead and fts5yyLookaheadToken parameters provide reduce actions -+** access to the lookahead token (if any). The fts5yyLookahead will be fts5YYNOCODE -+** if the lookahead token has already been consumed. As this procedure is -+** only called from one place, optimizing compilers will in-line it, which -+** means that the extra parameters have no performance impact. - */ --static void fts5yy_reduce( -+static fts5YYACTIONTYPE fts5yy_reduce( - fts5yyParser *fts5yypParser, /* The parser */ -- unsigned int fts5yyruleno /* Number of the rule by which to reduce */ -+ unsigned int fts5yyruleno, /* Number of the rule by which to reduce */ -+ int fts5yyLookahead, /* Lookahead token, or fts5YYNOCODE if none */ -+ sqlite3Fts5ParserFTS5TOKENTYPE fts5yyLookaheadToken /* Value of the lookahead token */ -+ sqlite3Fts5ParserCTX_PDECL /* %extra_context */ - ){ - int fts5yygoto; /* The next state */ -- int fts5yyact; /* The next action */ -+ fts5YYACTIONTYPE fts5yyact; /* The next action */ - fts5yyStackEntry *fts5yymsp; /* The top of the parser's stack */ - int fts5yysize; /* Amount to pop the stack */ -- sqlite3Fts5ParserARG_FETCH; -+ sqlite3Fts5ParserARG_FETCH -+ (void)fts5yyLookahead; -+ (void)fts5yyLookaheadToken; - fts5yymsp = fts5yypParser->fts5yytos; - #ifndef NDEBUG - if( fts5yyTraceFILE && fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ){ - fts5yysize = fts5yyRuleInfo[fts5yyruleno].nrhs; -- fprintf(fts5yyTraceFILE, "%sReduce [%s], go to state %d.\n", fts5yyTracePrompt, -- fts5yyRuleName[fts5yyruleno], fts5yymsp[fts5yysize].stateno); -+ if( fts5yysize ){ -+ fprintf(fts5yyTraceFILE, "%sReduce %d [%s], go to state %d.\n", -+ fts5yyTracePrompt, -+ fts5yyruleno, fts5yyRuleName[fts5yyruleno], fts5yymsp[fts5yysize].stateno); -+ }else{ -+ fprintf(fts5yyTraceFILE, "%sReduce %d [%s].\n", -+ fts5yyTracePrompt, fts5yyruleno, fts5yyRuleName[fts5yyruleno]); -+ } - } - #endif /* NDEBUG */ - -@@ -185305,13 +200713,19 @@ - #if fts5YYSTACKDEPTH>0 - if( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystackEnd ){ - fts5yyStackOverflow(fts5yypParser); -- return; -+ /* The call to fts5yyStackOverflow() above pops the stack until it is -+ ** empty, causing the main parser loop to exit. So the return value -+ ** is never used and does not matter. */ -+ return 0; - } - #else - if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz-1] ){ - if( fts5yyGrowStack(fts5yypParser) ){ - fts5yyStackOverflow(fts5yypParser); -- return; -+ /* The call to fts5yyStackOverflow() above pops the stack until it is -+ ** empty, causing the main parser loop to exit. So the return value -+ ** is never used and does not matter. */ -+ return 0; - } - fts5yymsp = fts5yypParser->fts5yytos; - } -@@ -185419,7 +200833,13 @@ - { fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); } - fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46; - break; -- case 18: /* nearset ::= STRING LP nearphrases neardist_opt RP */ -+ case 18: /* nearset ::= CARET phrase */ -+{ -+ sqlite3Fts5ParseSetCaret(fts5yymsp[0].minor.fts5yy53); -+ fts5yymsp[-1].minor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); -+} -+ break; -+ case 19: /* nearset ::= STRING LP nearphrases neardist_opt RP */ - { - sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0); - sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0); -@@ -185427,40 +200847,40 @@ - } - fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46; - break; -- case 19: /* nearphrases ::= phrase */ -+ case 20: /* nearphrases ::= phrase */ - { - fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); - } - fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46; - break; -- case 20: /* nearphrases ::= nearphrases phrase */ -+ case 21: /* nearphrases ::= nearphrases phrase */ - { - fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53); - } - fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46; - break; -- case 21: /* neardist_opt ::= */ -+ case 22: /* neardist_opt ::= */ - { fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; } - break; -- case 22: /* neardist_opt ::= COMMA STRING */ -+ case 23: /* neardist_opt ::= COMMA STRING */ - { fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; } - break; -- case 23: /* phrase ::= phrase PLUS STRING star_opt */ -+ case 24: /* phrase ::= phrase PLUS STRING star_opt */ - { - fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4); - } - fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53; - break; -- case 24: /* phrase ::= STRING star_opt */ -+ case 25: /* phrase ::= STRING star_opt */ - { - fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4); - } - fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53; - break; -- case 25: /* star_opt ::= STAR */ -+ case 26: /* star_opt ::= STAR */ - { fts5yymsp[0].minor.fts5yy4 = 1; } - break; -- case 26: /* star_opt ::= */ -+ case 27: /* star_opt ::= */ - { fts5yymsp[1].minor.fts5yy4 = 0; } - break; - default: -@@ -185479,16 +200899,12 @@ - /* It is not possible for a REDUCE to be followed by an error */ - assert( fts5yyact!=fts5YY_ERROR_ACTION ); - -- if( fts5yyact==fts5YY_ACCEPT_ACTION ){ -- fts5yypParser->fts5yytos += fts5yysize; -- fts5yy_accept(fts5yypParser); -- }else{ -- fts5yymsp += fts5yysize+1; -- fts5yypParser->fts5yytos = fts5yymsp; -- fts5yymsp->stateno = (fts5YYACTIONTYPE)fts5yyact; -- fts5yymsp->major = (fts5YYCODETYPE)fts5yygoto; -- fts5yyTraceShift(fts5yypParser, fts5yyact); -- } -+ fts5yymsp += fts5yysize+1; -+ fts5yypParser->fts5yytos = fts5yymsp; -+ fts5yymsp->stateno = (fts5YYACTIONTYPE)fts5yyact; -+ fts5yymsp->major = (fts5YYCODETYPE)fts5yygoto; -+ fts5yyTraceShift(fts5yypParser, fts5yyact, "... then shift"); -+ return fts5yyact; - } - - /* -@@ -185498,7 +200914,8 @@ - static void fts5yy_parse_failed( - fts5yyParser *fts5yypParser /* The parser */ - ){ -- sqlite3Fts5ParserARG_FETCH; -+ sqlite3Fts5ParserARG_FETCH -+ sqlite3Fts5ParserCTX_FETCH - #ifndef NDEBUG - if( fts5yyTraceFILE ){ - fprintf(fts5yyTraceFILE,"%sFail!\n",fts5yyTracePrompt); -@@ -185509,7 +200926,8 @@ - ** parser fails */ - /************ Begin %parse_failure code ***************************************/ - /************ End %parse_failure code *****************************************/ -- sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ -+ sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ -+ sqlite3Fts5ParserCTX_STORE - } - #endif /* fts5YYNOERRORRECOVERY */ - -@@ -185521,7 +200939,8 @@ - int fts5yymajor, /* The major type of the error token */ - sqlite3Fts5ParserFTS5TOKENTYPE fts5yyminor /* The minor type of the error token */ - ){ -- sqlite3Fts5ParserARG_FETCH; -+ sqlite3Fts5ParserARG_FETCH -+ sqlite3Fts5ParserCTX_FETCH - #define FTS5TOKEN fts5yyminor - /************ Begin %syntax_error code ****************************************/ - -@@ -185530,7 +200949,8 @@ - pParse, "fts5: syntax error near \"%.*s\"",FTS5TOKEN.n,FTS5TOKEN.p - ); - /************ End %syntax_error code ******************************************/ -- sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ -+ sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ -+ sqlite3Fts5ParserCTX_STORE - } - - /* -@@ -185539,7 +200959,8 @@ - static void fts5yy_accept( - fts5yyParser *fts5yypParser /* The parser */ - ){ -- sqlite3Fts5ParserARG_FETCH; -+ sqlite3Fts5ParserARG_FETCH -+ sqlite3Fts5ParserCTX_FETCH - #ifndef NDEBUG - if( fts5yyTraceFILE ){ - fprintf(fts5yyTraceFILE,"%sAccept!\n",fts5yyTracePrompt); -@@ -185553,7 +200974,8 @@ - ** parser accepts */ - /*********** Begin %parse_accept code *****************************************/ - /*********** End %parse_accept code *******************************************/ -- sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ -+ sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ -+ sqlite3Fts5ParserCTX_STORE - } - - /* The main parser program. -@@ -185582,7 +201004,7 @@ - sqlite3Fts5ParserARG_PDECL /* Optional %extra_argument parameter */ - ){ - fts5YYMINORTYPE fts5yyminorunion; -- unsigned int fts5yyact; /* The parser action. */ -+ fts5YYACTIONTYPE fts5yyact; /* The parser action. */ - #if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY) - int fts5yyendofinput; /* True if we are at the end of input */ - #endif -@@ -185589,31 +201011,44 @@ - #ifdef fts5YYERRORSYMBOL - int fts5yyerrorhit = 0; /* True if fts5yymajor has invoked an error */ - #endif -- fts5yyParser *fts5yypParser; /* The parser */ -+ fts5yyParser *fts5yypParser = (fts5yyParser*)fts5yyp; /* The parser */ -+ sqlite3Fts5ParserCTX_FETCH -+ sqlite3Fts5ParserARG_STORE - -- fts5yypParser = (fts5yyParser*)fts5yyp; - assert( fts5yypParser->fts5yytos!=0 ); - #if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY) - fts5yyendofinput = (fts5yymajor==0); - #endif -- sqlite3Fts5ParserARG_STORE; - -+ fts5yyact = fts5yypParser->fts5yytos->stateno; - #ifndef NDEBUG - if( fts5yyTraceFILE ){ -- fprintf(fts5yyTraceFILE,"%sInput '%s'\n",fts5yyTracePrompt,fts5yyTokenName[fts5yymajor]); -+ if( fts5yyact < fts5YY_MIN_REDUCE ){ -+ fprintf(fts5yyTraceFILE,"%sInput '%s' in state %d\n", -+ fts5yyTracePrompt,fts5yyTokenName[fts5yymajor],fts5yyact); -+ }else{ -+ fprintf(fts5yyTraceFILE,"%sInput '%s' with pending reduce %d\n", -+ fts5yyTracePrompt,fts5yyTokenName[fts5yymajor],fts5yyact-fts5YY_MIN_REDUCE); -+ } - } - #endif - - do{ -- fts5yyact = fts5yy_find_shift_action(fts5yypParser,(fts5YYCODETYPE)fts5yymajor); -- if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){ -- fts5yy_shift(fts5yypParser,fts5yyact,fts5yymajor,fts5yyminor); -+ assert( fts5yyact==fts5yypParser->fts5yytos->stateno ); -+ fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact); -+ if( fts5yyact >= fts5YY_MIN_REDUCE ){ -+ fts5yyact = fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE,fts5yymajor, -+ fts5yyminor sqlite3Fts5ParserCTX_PARAM); -+ }else if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){ -+ fts5yy_shift(fts5yypParser,fts5yyact,(fts5YYCODETYPE)fts5yymajor,fts5yyminor); - #ifndef fts5YYNOERRORRECOVERY - fts5yypParser->fts5yyerrcnt--; - #endif -- fts5yymajor = fts5YYNOCODE; -- }else if( fts5yyact <= fts5YY_MAX_REDUCE ){ -- fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE); -+ break; -+ }else if( fts5yyact==fts5YY_ACCEPT_ACTION ){ -+ fts5yypParser->fts5yytos--; -+ fts5yy_accept(fts5yypParser); -+ return; - }else{ - assert( fts5yyact == fts5YY_ERROR_ACTION ); - fts5yyminorunion.fts5yy0 = fts5yyminor; -@@ -185660,10 +201095,9 @@ - fts5yymajor = fts5YYNOCODE; - }else{ - while( fts5yypParser->fts5yytos >= fts5yypParser->fts5yystack -- && fts5yymx != fts5YYERRORSYMBOL - && (fts5yyact = fts5yy_find_reduce_action( - fts5yypParser->fts5yytos->stateno, -- fts5YYERRORSYMBOL)) >= fts5YY_MIN_REDUCE -+ fts5YYERRORSYMBOL)) > fts5YY_MAX_SHIFTREDUCE - ){ - fts5yy_pop_parser_stack(fts5yypParser); - } -@@ -185680,6 +201114,8 @@ - } - fts5yypParser->fts5yyerrcnt = 3; - fts5yyerrorhit = 1; -+ if( fts5yymajor==fts5YYNOCODE ) break; -+ fts5yyact = fts5yypParser->fts5yytos->stateno; - #elif defined(fts5YYNOERRORRECOVERY) - /* If the fts5YYNOERRORRECOVERY macro is defined, then do not attempt to - ** do any kind of error recovery. Instead, simply invoke the syntax -@@ -185690,8 +201126,7 @@ - */ - fts5yy_syntax_error(fts5yypParser,fts5yymajor, fts5yyminor); - fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion); -- fts5yymajor = fts5YYNOCODE; -- -+ break; - #else /* fts5YYERRORSYMBOL is not defined */ - /* This is what we do if the grammar does not define ERROR: - ** -@@ -185713,10 +201148,10 @@ - fts5yypParser->fts5yyerrcnt = -1; - #endif - } -- fts5yymajor = fts5YYNOCODE; -+ break; - #endif - } -- }while( fts5yymajor!=fts5YYNOCODE && fts5yypParser->fts5yytos>fts5yypParser->fts5yystack ); -+ }while( fts5yypParser->fts5yytos>fts5yypParser->fts5yystack ); - #ifndef NDEBUG - if( fts5yyTraceFILE ){ - fts5yyStackEntry *i; -@@ -185733,6 +201168,21 @@ - } - - /* -+** Return the fallback token corresponding to canonical token iToken, or -+** 0 if iToken has no fallback. -+*/ -+static int sqlite3Fts5ParserFallback(int iToken){ -+#ifdef fts5YYFALLBACK -+ if( iToken<(int)(sizeof(fts5yyFallback)/sizeof(fts5yyFallback[0])) ){ -+ return fts5yyFallback[iToken]; -+ } -+#else -+ (void)iToken; -+#endif -+ return 0; -+} -+ -+/* - ** 2014 May 31 - ** - ** The author disclaims copyright to this source code. In place of -@@ -186093,6 +201543,16 @@ - } - - /* -+** Return the value in pVal interpreted as utf-8 text. Except, if pVal -+** contains a NULL value, return a pointer to a static string zero -+** bytes in length instead of a NULL pointer. -+*/ -+static const char *fts5ValueToText(sqlite3_value *pVal){ -+ const char *zRet = (const char*)sqlite3_value_text(pVal); -+ return zRet ? zRet : ""; -+} -+ -+/* - ** Implementation of snippet() function. - */ - static void fts5SnippetFunction( -@@ -186127,9 +201587,9 @@ - nCol = pApi->xColumnCount(pFts); - memset(&ctx, 0, sizeof(HighlightContext)); - iCol = sqlite3_value_int(apVal[0]); -- ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]); -- ctx.zClose = (const char*)sqlite3_value_text(apVal[2]); -- zEllips = (const char*)sqlite3_value_text(apVal[3]); -+ ctx.zOpen = fts5ValueToText(apVal[1]); -+ ctx.zClose = fts5ValueToText(apVal[2]); -+ zEllips = fts5ValueToText(apVal[3]); - nToken = sqlite3_value_int(apVal[4]); - - iBestCol = (iCol>=0 ? iCol : 0); -@@ -187832,6 +203292,7 @@ - /* #include <stdio.h> */ - static void sqlite3Fts5ParserTrace(FILE*, char*); - #endif -+static int sqlite3Fts5ParserFallback(int); - - - struct Fts5Expr { -@@ -187883,7 +203344,8 @@ - ** or term prefix. - */ - struct Fts5ExprTerm { -- int bPrefix; /* True for a prefix term */ -+ u8 bPrefix; /* True for a prefix term */ -+ u8 bFirst; /* True if token must be first in column */ - char *zTerm; /* nul-terminated term */ - Fts5IndexIter *pIter; /* Iterator for this term */ - Fts5ExprTerm *pSynonym; /* Pointer to first in list of synonyms */ -@@ -187964,6 +203426,7 @@ - case '+': tok = FTS5_PLUS; break; - case '*': tok = FTS5_STAR; break; - case '-': tok = FTS5_MINUS; break; -+ case '^': tok = FTS5_CARET; break; - case '\0': tok = FTS5_EOF; break; - - case '"': { -@@ -188223,6 +203686,7 @@ - Fts5PoslistReader *aIter = aStatic; - int i; - int rc = SQLITE_OK; -+ int bFirst = pPhrase->aTerm[0].bFirst; - - fts5BufferZero(&pPhrase->poslist); - -@@ -188277,8 +203741,10 @@ - }while( bMatch==0 ); - - /* Append position iPos to the output */ -- rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos); -- if( rc!=SQLITE_OK ) goto ismatch_out; -+ if( bFirst==0 || FTS5_POS2OFFSET(iPos)==0 ){ -+ rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos); -+ if( rc!=SQLITE_OK ) goto ismatch_out; -+ } - - for(i=0; i<pPhrase->nTerm; i++){ - if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out; -@@ -188532,7 +203998,9 @@ - ** phrase is not a match, break out of the loop early. */ - for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){ - Fts5ExprPhrase *pPhrase = pNear->apPhrase[i]; -- if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym || pNear->pColset ){ -+ if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym -+ || pNear->pColset || pPhrase->aTerm[0].bFirst -+ ){ - int bMatch = 0; - rc = fts5ExprPhraseIsMatch(pNode, pPhrase, &bMatch); - if( bMatch==0 ) break; -@@ -188713,6 +204181,7 @@ - assert( pNear->nPhrase>1 - || pNear->apPhrase[0]->nTerm>1 - || pNear->apPhrase[0]->aTerm[0].pSynonym -+ || pNear->apPhrase[0]->aTerm[0].bFirst - ); - - /* Initialize iLast, the "lastest" rowid any iterator points to. If the -@@ -189238,6 +204707,16 @@ - } - - /* -+** Set the "bFirst" flag on the first token of the phrase passed as the -+** only argument. -+*/ -+static void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase *pPhrase){ -+ if( pPhrase && pPhrase->nTerm ){ -+ pPhrase->aTerm[0].bFirst = 1; -+ } -+} -+ -+/* - ** If argument pNear is NULL, then a new Fts5ExprNearset object is allocated - ** and populated with pPhrase. Or, if pNear is not NULL, phrase pPhrase is - ** appended to it and the results returned. -@@ -189454,7 +204933,7 @@ - ** no token characters at all. (e.g ... MATCH '""'). */ - sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase)); - }else if( sCtx.pPhrase->nTerm ){ -- sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = bPrefix; -+ sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix; - } - pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase; - } -@@ -189515,6 +204994,7 @@ - } - if( rc==SQLITE_OK ){ - sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix; -+ sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst; - } - } - }else{ -@@ -189533,7 +205013,10 @@ - pNew->pRoot->pNear->nPhrase = 1; - sCtx.pPhrase->pNode = pNew->pRoot; - -- if( pOrig->nTerm==1 && pOrig->aTerm[0].pSynonym==0 ){ -+ if( pOrig->nTerm==1 -+ && pOrig->aTerm[0].pSynonym==0 -+ && pOrig->aTerm[0].bFirst==0 -+ ){ - pNew->pRoot->eType = FTS5_TERM; - pNew->pRoot->xNext = fts5ExprNodeNext_TERM; - }else{ -@@ -189807,6 +205290,7 @@ - Fts5ExprNearset *pNear = pNode->pNear; - if( pNear->nPhrase==1 && pNear->apPhrase[0]->nTerm==1 - && pNear->apPhrase[0]->aTerm[0].pSynonym==0 -+ && pNear->apPhrase[0]->aTerm[0].bFirst==0 - ){ - pNode->eType = FTS5_TERM; - pNode->xNext = fts5ExprNodeNext_TERM; -@@ -189893,20 +205377,23 @@ - } - } - -- if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL -- && (pNear->nPhrase!=1 || pNear->apPhrase[0]->nTerm>1) -- ){ -- assert( pParse->rc==SQLITE_OK ); -- pParse->rc = SQLITE_ERROR; -- assert( pParse->zErr==0 ); -- pParse->zErr = sqlite3_mprintf( -- "fts5: %s queries are not supported (detail!=full)", -- pNear->nPhrase==1 ? "phrase": "NEAR" -- ); -- sqlite3_free(pRet); -- pRet = 0; -+ if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){ -+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[0]; -+ if( pNear->nPhrase!=1 -+ || pPhrase->nTerm>1 -+ || (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst) -+ ){ -+ assert( pParse->rc==SQLITE_OK ); -+ pParse->rc = SQLITE_ERROR; -+ assert( pParse->zErr==0 ); -+ pParse->zErr = sqlite3_mprintf( -+ "fts5: %s queries are not supported (detail!=full)", -+ pNear->nPhrase==1 ? "phrase": "NEAR" -+ ); -+ sqlite3_free(pRet); -+ pRet = 0; -+ } - } -- - }else{ - fts5ExprAddChildren(pRet, pLeft); - fts5ExprAddChildren(pRet, pRight); -@@ -190310,6 +205797,7 @@ - sqlite3_value **apVal /* Function arguments */ - ){ - int iCode; -+ u8 aArr[32]; - if( nArg!=1 ){ - sqlite3_result_error(pCtx, - "wrong number of arguments to function fts5_isalnum", -1 -@@ -190316,8 +205804,12 @@ - ); - return; - } -+ memset(aArr, 0, sizeof(aArr)); -+ sqlite3Fts5UnicodeCatParse("L*", aArr); -+ sqlite3Fts5UnicodeCatParse("N*", aArr); -+ sqlite3Fts5UnicodeCatParse("Co", aArr); - iCode = sqlite3_value_int(apVal[0]); -- sqlite3_result_int(pCtx, sqlite3Fts5UnicodeIsalnum(iCode)); -+ sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory(iCode)]); - } - - static void fts5ExprFold( -@@ -190361,10 +205853,12 @@ - rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0); - } - -- /* Avoid a warning indicating that sqlite3Fts5ParserTrace() is unused */ -+ /* Avoid warnings indicating that sqlite3Fts5ParserTrace() and -+ ** sqlite3Fts5ParserFallback() are unused */ - #ifndef NDEBUG - (void)sqlite3Fts5ParserTrace; - #endif -+ (void)sqlite3Fts5ParserFallback; - - return rc; - } -@@ -191909,6 +207403,7 @@ - sqlite3_bind_blob(p->pWriter, 2, pData, nData, SQLITE_STATIC); - sqlite3_step(p->pWriter); - p->rc = sqlite3_reset(p->pWriter); -+ sqlite3_bind_null(p->pWriter, 2); - } - - /* -@@ -193537,6 +209032,7 @@ - bDlidx = (val & 0x0001); - } - p->rc = sqlite3_reset(pIdxSelect); -+ sqlite3_bind_null(pIdxSelect, 2); - - if( iPg<pSeg->pgnoFirst ){ - iPg = pSeg->pgnoFirst; -@@ -194749,6 +210245,7 @@ - sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC); - assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW ); - p->rc = sqlite3_reset(pIdxSelect); -+ sqlite3_bind_null(pIdxSelect, 2); - } - } - #endif -@@ -194875,6 +210372,7 @@ - sqlite3_bind_int64(p->pIdxWriter, 3, bFlag + ((i64)pWriter->iBtPage<<1)); - sqlite3_step(p->pIdxWriter); - p->rc = sqlite3_reset(p->pIdxWriter); -+ sqlite3_bind_null(p->pIdxWriter, 2); - } - pWriter->iBtPage = 0; - } -@@ -196060,7 +211558,13 @@ - Fts5Buffer out = {0, 0, 0}; - Fts5Buffer tmp = {0, 0, 0}; - -- if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n) ) return; -+ /* The maximum size of the output is equal to the sum of the two -+ ** input sizes + 1 varint (9 bytes). The extra varint is because if the -+ ** first rowid in one input is a large negative number, and the first in -+ ** the other a non-negative number, the delta for the non-negative -+ ** number will be larger on disk than the literal integer value -+ ** was. */ -+ if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9) ) return; - fts5DoclistIterInit(p1, &i1); - fts5DoclistIterInit(p2, &i2); - -@@ -196154,6 +211658,7 @@ - fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); - fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist); - } -+ assert( out.n<=(p1->n+p2->n+9) ); - - fts5BufferSet(&p->rc, p1, out.n, out.p); - fts5BufferFree(&tmp); -@@ -196401,7 +211906,10 @@ - for(i=0; i<nChar; i++){ - if( n>=nByte ) return 0; /* Input contains fewer than nChar chars */ - if( (unsigned char)p[n++]>=0xc0 ){ -- while( (p[n] & 0xc0)==0x80 ) n++; -+ while( (p[n] & 0xc0)==0x80 ){ -+ n++; -+ if( n>=nByte ) break; -+ } - } - } - return n; -@@ -196539,7 +212047,7 @@ - fts5CloseReader(p); - } - -- *ppIter = &pRet->base; -+ *ppIter = (Fts5IndexIter*)pRet; - sqlite3Fts5BufferFree(&buf); - } - return fts5IndexReturn(p); -@@ -197926,7 +213434,7 @@ - case FTS5_SAVEPOINT: - assert( p->ts.eState==1 ); - assert( iSavepoint>=0 ); -- assert( iSavepoint>p->ts.iSavepoint ); -+ assert( iSavepoint>=p->ts.iSavepoint ); - p->ts.iSavepoint = iSavepoint; - break; - -@@ -198181,6 +213689,12 @@ - aColMap[1] = nCol; - aColMap[2] = nCol+1; - -+ assert( SQLITE_INDEX_CONSTRAINT_EQ<SQLITE_INDEX_CONSTRAINT_MATCH ); -+ assert( SQLITE_INDEX_CONSTRAINT_GT<SQLITE_INDEX_CONSTRAINT_MATCH ); -+ assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH ); -+ assert( SQLITE_INDEX_CONSTRAINT_GE<SQLITE_INDEX_CONSTRAINT_MATCH ); -+ assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH ); -+ - /* Set idxFlags flags for all WHERE clause terms that will be used. */ - for(i=0; i<pInfo->nConstraint; i++){ - struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; -@@ -198199,11 +213713,11 @@ - pInfo->estimatedCost = 1e50; - return SQLITE_OK; - } -- }else{ -+ }else if( p->op<=SQLITE_INDEX_CONSTRAINT_MATCH ){ - int j; - for(j=1; j<ArraySize(aConstraint); j++){ - struct Constraint *pC = &aConstraint[j]; -- if( iCol==aColMap[pC->iCol] && p->op & pC->op && p->usable ){ -+ if( iCol==aColMap[pC->iCol] && (p->op & pC->op) && p->usable ){ - pC->iConsIndex = i; - idxFlags |= pC->fts5op; - } -@@ -198845,6 +214359,13 @@ - assert( nVal==0 && pMatch==0 && bOrderByRank==0 && bDesc==0 ); - assert( pCsr->iLastRowid==LARGEST_INT64 ); - assert( pCsr->iFirstRowid==SMALLEST_INT64 ); -+ if( pTab->pSortCsr->bDesc ){ -+ pCsr->iLastRowid = pTab->pSortCsr->iFirstRowid; -+ pCsr->iFirstRowid = pTab->pSortCsr->iLastRowid; -+ }else{ -+ pCsr->iLastRowid = pTab->pSortCsr->iLastRowid; -+ pCsr->iFirstRowid = pTab->pSortCsr->iFirstRowid; -+ } - pCsr->ePlan = FTS5_PLAN_SOURCE; - pCsr->pExpr = pTab->pSortCsr->pExpr; - rc = fts5CursorFirst(pTab, pCsr, bDesc); -@@ -200275,12 +215796,27 @@ - ){ - assert( nArg==0 ); - UNUSED_PARAM2(nArg, apUnused); -- sqlite3_result_text(pCtx, "fts5: 2017-08-01 13:24:15 9501e22dfeebdcefa783575e47c60b514d7c2e0cad73b2a496c0bc4b680900a8", -1, SQLITE_TRANSIENT); -+ sqlite3_result_text(pCtx, "fts5: 2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9", -1, SQLITE_TRANSIENT); - } - -+/* -+** Return true if zName is the extension on one of the shadow tables used -+** by this module. -+*/ -+static int fts5ShadowName(const char *zName){ -+ static const char *azName[] = { -+ "config", "content", "data", "docsize", "idx" -+ }; -+ unsigned int i; -+ for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){ -+ if( sqlite3_stricmp(zName, azName[i])==0 ) return 1; -+ } -+ return 0; -+} -+ - static int fts5Init(sqlite3 *db){ - static const sqlite3_module fts5Mod = { -- /* iVersion */ 2, -+ /* iVersion */ 3, - /* xCreate */ fts5CreateMethod, - /* xConnect */ fts5ConnectMethod, - /* xBestIndex */ fts5BestIndexMethod, -@@ -200303,6 +215839,7 @@ - /* xSavepoint */ fts5SavepointMethod, - /* xRelease */ fts5ReleaseMethod, - /* xRollbackTo */ fts5RollbackToMethod, -+ /* xShadowName */ fts5ShadowName - }; - - int rc; -@@ -200851,6 +216388,7 @@ - sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); - sqlite3_step(pReplace); - rc = sqlite3_reset(pReplace); -+ sqlite3_bind_null(pReplace, 2); - } - } - return rc; -@@ -201511,6 +217049,7 @@ - } - sqlite3_step(pReplace); - rc = sqlite3_reset(pReplace); -+ sqlite3_bind_null(pReplace, 1); - } - if( rc==SQLITE_OK && pVal ){ - int iNew = p->pConfig->iCookie + 1; -@@ -201761,6 +217300,8 @@ - int bRemoveDiacritic; /* True if remove_diacritics=1 is set */ - int nException; - int *aiException; -+ -+ unsigned char aCategory[32]; /* True for token char categories */ - }; - - static int fts5UnicodeAddExceptions( -@@ -201785,7 +217326,7 @@ - if( iCode<128 ){ - p->aTokenChar[iCode] = (unsigned char)bTokenChars; - }else{ -- bToken = sqlite3Fts5UnicodeIsalnum(iCode); -+ bToken = p->aCategory[sqlite3Fts5UnicodeCategory(iCode)]; - assert( (bToken==0 || bToken==1) ); - assert( (bTokenChars==0 || bTokenChars==1) ); - if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){ -@@ -201846,6 +217387,21 @@ - return; - } - -+static int unicodeSetCategories(Unicode61Tokenizer *p, const char *zCat){ -+ const char *z = zCat; -+ -+ while( *z ){ -+ while( *z==' ' || *z=='\t' ) z++; -+ if( *z && sqlite3Fts5UnicodeCatParse(z, p->aCategory) ){ -+ return SQLITE_ERROR; -+ } -+ while( *z!=' ' && *z!='\t' && *z!='\0' ) z++; -+ } -+ -+ sqlite3Fts5UnicodeAscii(p->aCategory, p->aTokenChar); -+ return SQLITE_OK; -+} -+ - /* - ** Create a "unicode61" tokenizer. - */ -@@ -201864,9 +217420,10 @@ - }else{ - p = (Unicode61Tokenizer*)sqlite3_malloc(sizeof(Unicode61Tokenizer)); - if( p ){ -+ const char *zCat = "L* N* Co"; - int i; - memset(p, 0, sizeof(Unicode61Tokenizer)); -- memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar)); -+ - p->bRemoveDiacritic = 1; - p->nFold = 64; - p->aFold = sqlite3_malloc(p->nFold * sizeof(char)); -@@ -201873,7 +217430,19 @@ - if( p->aFold==0 ){ - rc = SQLITE_NOMEM; - } -+ -+ /* Search for a "categories" argument */ - for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ -+ if( 0==sqlite3_stricmp(azArg[i], "categories") ){ -+ zCat = azArg[i+1]; -+ } -+ } -+ -+ if( rc==SQLITE_OK ){ -+ rc = unicodeSetCategories(p, zCat); -+ } -+ -+ for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ - const char *zArg = azArg[i+1]; - if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ - if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){ -@@ -201886,10 +217455,14 @@ - }else - if( 0==sqlite3_stricmp(azArg[i], "separators") ){ - rc = fts5UnicodeAddExceptions(p, zArg, 0); -+ }else -+ if( 0==sqlite3_stricmp(azArg[i], "categories") ){ -+ /* no-op */ - }else{ - rc = SQLITE_ERROR; - } - } -+ - }else{ - rc = SQLITE_NOMEM; - } -@@ -201908,8 +217481,10 @@ - ** character (not a separator). - */ - static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){ -- assert( (sqlite3Fts5UnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 ); -- return sqlite3Fts5UnicodeIsalnum(iCode) ^ fts5UnicodeIsException(p, iCode); -+ return ( -+ p->aCategory[sqlite3Fts5UnicodeCategory(iCode)] -+ ^ fts5UnicodeIsException(p, iCode) -+ ); - } - - static int fts5UnicodeTokenize( -@@ -202785,137 +218360,8 @@ - - /* #include <assert.h> */ - --/* --** Return true if the argument corresponds to a unicode codepoint --** classified as either a letter or a number. Otherwise false. --** --** The results are undefined if the value passed to this function --** is less than zero. --*/ --static int sqlite3Fts5UnicodeIsalnum(int c){ -- /* Each unsigned integer in the following array corresponds to a contiguous -- ** range of unicode codepoints that are not either letters or numbers (i.e. -- ** codepoints for which this function should return 0). -- ** -- ** The most significant 22 bits in each 32-bit value contain the first -- ** codepoint in the range. The least significant 10 bits are used to store -- ** the size of the range (always at least 1). In other words, the value -- ** ((C<<22) + N) represents a range of N codepoints starting with codepoint -- ** C. It is not possible to represent a range larger than 1023 codepoints -- ** using this format. -- */ -- static const unsigned int aEntry[] = { -- 0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07, -- 0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01, -- 0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401, -- 0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01, -- 0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01, -- 0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802, -- 0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F, -- 0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401, -- 0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804, -- 0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, -- 0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812, -- 0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001, -- 0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802, -- 0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805, -- 0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401, -- 0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03, -- 0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807, -- 0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001, -- 0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01, -- 0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804, -- 0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001, -- 0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802, -- 0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01, -- 0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06, -- 0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007, -- 0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006, -- 0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417, -- 0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14, -- 0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07, -- 0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01, -- 0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001, -- 0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802, -- 0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F, -- 0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002, -- 0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802, -- 0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006, -- 0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D, -- 0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802, -- 0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027, -- 0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403, -- 0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805, -- 0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04, -- 0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401, -- 0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005, -- 0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B, -- 0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A, -- 0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001, -- 0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59, -- 0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807, -- 0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01, -- 0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E, -- 0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100, -- 0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10, -- 0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402, -- 0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804, -- 0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012, -- 0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004, -- 0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002, -- 0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803, -- 0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07, -- 0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02, -- 0x037FFC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802, -- 0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023, 0x03F95013, -- 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06, -- 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003, -- 0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E, 0x040E7C01, -- 0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01, 0x04280403, -- 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009, -- 0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016, 0x04420003, -- 0x0442C012, 0x04440003, 0x04449C0E, 0x04450004, 0x04460003, -- 0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004, 0x05BD442E, -- 0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5, 0x07480046, -- 0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01, 0x075C5401, -- 0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401, 0x075EA401, -- 0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064, 0x07C2800F, -- 0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F, 0x07C4C03C, -- 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009, 0x07C94002, -- 0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014, 0x07CE8025, -- 0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001, 0x07D108B6, -- 0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, 0x07D7EC46, -- 0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, 0x38008060, -- 0x380400F0, -- }; -- static const unsigned int aAscii[4] = { -- 0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001, -- }; - -- if( (unsigned int)c<128 ){ -- return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 ); -- }else if( (unsigned int)c<(1<<22) ){ -- unsigned int key = (((unsigned int)c)<<10) | 0x000003FF; -- int iRes = 0; -- int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1; -- int iLo = 0; -- while( iHi>=iLo ){ -- int iTest = (iHi + iLo) / 2; -- if( key >= aEntry[iTest] ){ -- iRes = iTest; -- iLo = iTest+1; -- }else{ -- iHi = iTest-1; -- } -- } -- assert( aEntry[0]<key ); -- assert( key>=aEntry[iRes] ); -- return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF))); -- } -- return 1; --} - -- - /* - ** If the argument is a codepoint corresponding to a lowercase letter - ** in the ASCII range with a diacritic added, return the codepoint -@@ -203126,6 +218572,539 @@ - return ret; - } - -+ -+#if 0 -+static int sqlite3Fts5UnicodeNCat(void) { -+ return 32; -+} -+#endif -+ -+static int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ -+ aArray[0] = 1; -+ switch( zCat[0] ){ -+ case 'C': -+ switch( zCat[1] ){ -+ case 'c': aArray[1] = 1; break; -+ case 'f': aArray[2] = 1; break; -+ case 'n': aArray[3] = 1; break; -+ case 's': aArray[4] = 1; break; -+ case 'o': aArray[31] = 1; break; -+ case '*': -+ aArray[1] = 1; -+ aArray[2] = 1; -+ aArray[3] = 1; -+ aArray[4] = 1; -+ aArray[31] = 1; -+ break; -+ default: return 1; } -+ break; -+ -+ case 'L': -+ switch( zCat[1] ){ -+ case 'l': aArray[5] = 1; break; -+ case 'm': aArray[6] = 1; break; -+ case 'o': aArray[7] = 1; break; -+ case 't': aArray[8] = 1; break; -+ case 'u': aArray[9] = 1; break; -+ case 'C': aArray[30] = 1; break; -+ case '*': -+ aArray[5] = 1; -+ aArray[6] = 1; -+ aArray[7] = 1; -+ aArray[8] = 1; -+ aArray[9] = 1; -+ aArray[30] = 1; -+ break; -+ default: return 1; } -+ break; -+ -+ case 'M': -+ switch( zCat[1] ){ -+ case 'c': aArray[10] = 1; break; -+ case 'e': aArray[11] = 1; break; -+ case 'n': aArray[12] = 1; break; -+ case '*': -+ aArray[10] = 1; -+ aArray[11] = 1; -+ aArray[12] = 1; -+ break; -+ default: return 1; } -+ break; -+ -+ case 'N': -+ switch( zCat[1] ){ -+ case 'd': aArray[13] = 1; break; -+ case 'l': aArray[14] = 1; break; -+ case 'o': aArray[15] = 1; break; -+ case '*': -+ aArray[13] = 1; -+ aArray[14] = 1; -+ aArray[15] = 1; -+ break; -+ default: return 1; } -+ break; -+ -+ case 'P': -+ switch( zCat[1] ){ -+ case 'c': aArray[16] = 1; break; -+ case 'd': aArray[17] = 1; break; -+ case 'e': aArray[18] = 1; break; -+ case 'f': aArray[19] = 1; break; -+ case 'i': aArray[20] = 1; break; -+ case 'o': aArray[21] = 1; break; -+ case 's': aArray[22] = 1; break; -+ case '*': -+ aArray[16] = 1; -+ aArray[17] = 1; -+ aArray[18] = 1; -+ aArray[19] = 1; -+ aArray[20] = 1; -+ aArray[21] = 1; -+ aArray[22] = 1; -+ break; -+ default: return 1; } -+ break; -+ -+ case 'S': -+ switch( zCat[1] ){ -+ case 'c': aArray[23] = 1; break; -+ case 'k': aArray[24] = 1; break; -+ case 'm': aArray[25] = 1; break; -+ case 'o': aArray[26] = 1; break; -+ case '*': -+ aArray[23] = 1; -+ aArray[24] = 1; -+ aArray[25] = 1; -+ aArray[26] = 1; -+ break; -+ default: return 1; } -+ break; -+ -+ case 'Z': -+ switch( zCat[1] ){ -+ case 'l': aArray[27] = 1; break; -+ case 'p': aArray[28] = 1; break; -+ case 's': aArray[29] = 1; break; -+ case '*': -+ aArray[27] = 1; -+ aArray[28] = 1; -+ aArray[29] = 1; -+ break; -+ default: return 1; } -+ break; -+ -+ } -+ return 0; -+} -+ -+static u16 aFts5UnicodeBlock[] = { -+ 0, 1471, 1753, 1760, 1760, 1760, 1760, 1760, 1760, 1760, -+ 1760, 1760, 1760, 1760, 1760, 1763, 1765, -+ }; -+static u16 aFts5UnicodeMap[] = { -+ 0, 32, 33, 36, 37, 40, 41, 42, 43, 44, -+ 45, 46, 48, 58, 60, 63, 65, 91, 92, 93, -+ 94, 95, 96, 97, 123, 124, 125, 126, 127, 160, -+ 161, 162, 166, 167, 168, 169, 170, 171, 172, 173, -+ 174, 175, 176, 177, 178, 180, 181, 182, 184, 185, -+ 186, 187, 188, 191, 192, 215, 216, 223, 247, 248, -+ 256, 312, 313, 329, 330, 377, 383, 385, 387, 388, -+ 391, 394, 396, 398, 402, 403, 405, 406, 409, 412, -+ 414, 415, 417, 418, 423, 427, 428, 431, 434, 436, -+ 437, 440, 442, 443, 444, 446, 448, 452, 453, 454, -+ 455, 456, 457, 458, 459, 460, 461, 477, 478, 496, -+ 497, 498, 499, 500, 503, 505, 506, 564, 570, 572, -+ 573, 575, 577, 580, 583, 584, 592, 660, 661, 688, -+ 706, 710, 722, 736, 741, 748, 749, 750, 751, 768, -+ 880, 884, 885, 886, 890, 891, 894, 900, 902, 903, -+ 904, 908, 910, 912, 913, 931, 940, 975, 977, 978, -+ 981, 984, 1008, 1012, 1014, 1015, 1018, 1020, 1021, 1072, -+ 1120, 1154, 1155, 1160, 1162, 1217, 1231, 1232, 1329, 1369, -+ 1370, 1377, 1417, 1418, 1423, 1425, 1470, 1471, 1472, 1473, -+ 1475, 1476, 1478, 1479, 1488, 1520, 1523, 1536, 1542, 1545, -+ 1547, 1548, 1550, 1552, 1563, 1566, 1568, 1600, 1601, 1611, -+ 1632, 1642, 1646, 1648, 1649, 1748, 1749, 1750, 1757, 1758, -+ 1759, 1765, 1767, 1769, 1770, 1774, 1776, 1786, 1789, 1791, -+ 1792, 1807, 1808, 1809, 1810, 1840, 1869, 1958, 1969, 1984, -+ 1994, 2027, 2036, 2038, 2039, 2042, 2048, 2070, 2074, 2075, -+ 2084, 2085, 2088, 2089, 2096, 2112, 2137, 2142, 2208, 2210, -+ 2276, 2304, 2307, 2308, 2362, 2363, 2364, 2365, 2366, 2369, -+ 2377, 2381, 2382, 2384, 2385, 2392, 2402, 2404, 2406, 2416, -+ 2417, 2418, 2425, 2433, 2434, 2437, 2447, 2451, 2474, 2482, -+ 2486, 2492, 2493, 2494, 2497, 2503, 2507, 2509, 2510, 2519, -+ 2524, 2527, 2530, 2534, 2544, 2546, 2548, 2554, 2555, 2561, -+ 2563, 2565, 2575, 2579, 2602, 2610, 2613, 2616, 2620, 2622, -+ 2625, 2631, 2635, 2641, 2649, 2654, 2662, 2672, 2674, 2677, -+ 2689, 2691, 2693, 2703, 2707, 2730, 2738, 2741, 2748, 2749, -+ 2750, 2753, 2759, 2761, 2763, 2765, 2768, 2784, 2786, 2790, -+ 2800, 2801, 2817, 2818, 2821, 2831, 2835, 2858, 2866, 2869, -+ 2876, 2877, 2878, 2879, 2880, 2881, 2887, 2891, 2893, 2902, -+ 2903, 2908, 2911, 2914, 2918, 2928, 2929, 2930, 2946, 2947, -+ 2949, 2958, 2962, 2969, 2972, 2974, 2979, 2984, 2990, 3006, -+ 3008, 3009, 3014, 3018, 3021, 3024, 3031, 3046, 3056, 3059, -+ 3065, 3066, 3073, 3077, 3086, 3090, 3114, 3125, 3133, 3134, -+ 3137, 3142, 3146, 3157, 3160, 3168, 3170, 3174, 3192, 3199, -+ 3202, 3205, 3214, 3218, 3242, 3253, 3260, 3261, 3262, 3263, -+ 3264, 3270, 3271, 3274, 3276, 3285, 3294, 3296, 3298, 3302, -+ 3313, 3330, 3333, 3342, 3346, 3389, 3390, 3393, 3398, 3402, -+ 3405, 3406, 3415, 3424, 3426, 3430, 3440, 3449, 3450, 3458, -+ 3461, 3482, 3507, 3517, 3520, 3530, 3535, 3538, 3542, 3544, -+ 3570, 3572, 3585, 3633, 3634, 3636, 3647, 3648, 3654, 3655, -+ 3663, 3664, 3674, 3713, 3716, 3719, 3722, 3725, 3732, 3737, -+ 3745, 3749, 3751, 3754, 3757, 3761, 3762, 3764, 3771, 3773, -+ 3776, 3782, 3784, 3792, 3804, 3840, 3841, 3844, 3859, 3860, -+ 3861, 3864, 3866, 3872, 3882, 3892, 3893, 3894, 3895, 3896, -+ 3897, 3898, 3899, 3900, 3901, 3902, 3904, 3913, 3953, 3967, -+ 3968, 3973, 3974, 3976, 3981, 3993, 4030, 4038, 4039, 4046, -+ 4048, 4053, 4057, 4096, 4139, 4141, 4145, 4146, 4152, 4153, -+ 4155, 4157, 4159, 4160, 4170, 4176, 4182, 4184, 4186, 4190, -+ 4193, 4194, 4197, 4199, 4206, 4209, 4213, 4226, 4227, 4229, -+ 4231, 4237, 4238, 4239, 4240, 4250, 4253, 4254, 4256, 4295, -+ 4301, 4304, 4347, 4348, 4349, 4682, 4688, 4696, 4698, 4704, -+ 4746, 4752, 4786, 4792, 4800, 4802, 4808, 4824, 4882, 4888, -+ 4957, 4960, 4969, 4992, 5008, 5024, 5120, 5121, 5741, 5743, -+ 5760, 5761, 5787, 5788, 5792, 5867, 5870, 5888, 5902, 5906, -+ 5920, 5938, 5941, 5952, 5970, 5984, 5998, 6002, 6016, 6068, -+ 6070, 6071, 6078, 6086, 6087, 6089, 6100, 6103, 6104, 6107, -+ 6108, 6109, 6112, 6128, 6144, 6150, 6151, 6155, 6158, 6160, -+ 6176, 6211, 6212, 6272, 6313, 6314, 6320, 6400, 6432, 6435, -+ 6439, 6441, 6448, 6450, 6451, 6457, 6464, 6468, 6470, 6480, -+ 6512, 6528, 6576, 6593, 6600, 6608, 6618, 6622, 6656, 6679, -+ 6681, 6686, 6688, 6741, 6742, 6743, 6744, 6752, 6753, 6754, -+ 6755, 6757, 6765, 6771, 6783, 6784, 6800, 6816, 6823, 6824, -+ 6912, 6916, 6917, 6964, 6965, 6966, 6971, 6972, 6973, 6978, -+ 6979, 6981, 6992, 7002, 7009, 7019, 7028, 7040, 7042, 7043, -+ 7073, 7074, 7078, 7080, 7082, 7083, 7084, 7086, 7088, 7098, -+ 7142, 7143, 7144, 7146, 7149, 7150, 7151, 7154, 7164, 7168, -+ 7204, 7212, 7220, 7222, 7227, 7232, 7245, 7248, 7258, 7288, -+ 7294, 7360, 7376, 7379, 7380, 7393, 7394, 7401, 7405, 7406, -+ 7410, 7412, 7413, 7424, 7468, 7531, 7544, 7545, 7579, 7616, -+ 7676, 7680, 7830, 7838, 7936, 7944, 7952, 7960, 7968, 7976, -+ 7984, 7992, 8000, 8008, 8016, 8025, 8027, 8029, 8031, 8033, -+ 8040, 8048, 8064, 8072, 8080, 8088, 8096, 8104, 8112, 8118, -+ 8120, 8124, 8125, 8126, 8127, 8130, 8134, 8136, 8140, 8141, -+ 8144, 8150, 8152, 8157, 8160, 8168, 8173, 8178, 8182, 8184, -+ 8188, 8189, 8192, 8203, 8208, 8214, 8216, 8217, 8218, 8219, -+ 8221, 8222, 8223, 8224, 8232, 8233, 8234, 8239, 8240, 8249, -+ 8250, 8251, 8255, 8257, 8260, 8261, 8262, 8263, 8274, 8275, -+ 8276, 8277, 8287, 8288, 8298, 8304, 8305, 8308, 8314, 8317, -+ 8318, 8319, 8320, 8330, 8333, 8334, 8336, 8352, 8400, 8413, -+ 8417, 8418, 8421, 8448, 8450, 8451, 8455, 8456, 8458, 8459, -+ 8462, 8464, 8467, 8468, 8469, 8470, 8472, 8473, 8478, 8484, -+ 8485, 8486, 8487, 8488, 8489, 8490, 8494, 8495, 8496, 8500, -+ 8501, 8505, 8506, 8508, 8510, 8512, 8517, 8519, 8522, 8523, -+ 8524, 8526, 8527, 8528, 8544, 8579, 8581, 8585, 8592, 8597, -+ 8602, 8604, 8608, 8609, 8611, 8612, 8614, 8615, 8622, 8623, -+ 8654, 8656, 8658, 8659, 8660, 8661, 8692, 8960, 8968, 8972, -+ 8992, 8994, 9001, 9002, 9003, 9084, 9085, 9115, 9140, 9180, -+ 9186, 9216, 9280, 9312, 9372, 9450, 9472, 9655, 9656, 9665, -+ 9666, 9720, 9728, 9839, 9840, 9985, 10088, 10089, 10090, 10091, -+ 10092, 10093, 10094, 10095, 10096, 10097, 10098, 10099, 10100, 10101, -+ 10102, 10132, 10176, 10181, 10182, 10183, 10214, 10215, 10216, 10217, -+ 10218, 10219, 10220, 10221, 10222, 10223, 10224, 10240, 10496, 10627, -+ 10628, 10629, 10630, 10631, 10632, 10633, 10634, 10635, 10636, 10637, -+ 10638, 10639, 10640, 10641, 10642, 10643, 10644, 10645, 10646, 10647, -+ 10648, 10649, 10712, 10713, 10714, 10715, 10716, 10748, 10749, 10750, -+ 11008, 11056, 11077, 11079, 11088, 11264, 11312, 11360, 11363, 11365, -+ 11367, 11374, 11377, 11378, 11380, 11381, 11383, 11388, 11390, 11393, -+ 11394, 11492, 11493, 11499, 11503, 11506, 11513, 11517, 11518, 11520, -+ 11559, 11565, 11568, 11631, 11632, 11647, 11648, 11680, 11688, 11696, -+ 11704, 11712, 11720, 11728, 11736, 11744, 11776, 11778, 11779, 11780, -+ 11781, 11782, 11785, 11786, 11787, 11788, 11789, 11790, 11799, 11800, -+ 11802, 11803, 11804, 11805, 11806, 11808, 11809, 11810, 11811, 11812, -+ 11813, 11814, 11815, 11816, 11817, 11818, 11823, 11824, 11834, 11904, -+ 11931, 12032, 12272, 12288, 12289, 12292, 12293, 12294, 12295, 12296, -+ 12297, 12298, 12299, 12300, 12301, 12302, 12303, 12304, 12305, 12306, -+ 12308, 12309, 12310, 12311, 12312, 12313, 12314, 12315, 12316, 12317, -+ 12318, 12320, 12321, 12330, 12334, 12336, 12337, 12342, 12344, 12347, -+ 12348, 12349, 12350, 12353, 12441, 12443, 12445, 12447, 12448, 12449, -+ 12539, 12540, 12543, 12549, 12593, 12688, 12690, 12694, 12704, 12736, -+ 12784, 12800, 12832, 12842, 12872, 12880, 12881, 12896, 12928, 12938, -+ 12977, 12992, 13056, 13312, 19893, 19904, 19968, 40908, 40960, 40981, -+ 40982, 42128, 42192, 42232, 42238, 42240, 42508, 42509, 42512, 42528, -+ 42538, 42560, 42606, 42607, 42608, 42611, 42612, 42622, 42623, 42624, -+ 42655, 42656, 42726, 42736, 42738, 42752, 42775, 42784, 42786, 42800, -+ 42802, 42864, 42865, 42873, 42878, 42888, 42889, 42891, 42896, 42912, -+ 43000, 43002, 43003, 43010, 43011, 43014, 43015, 43019, 43020, 43043, -+ 43045, 43047, 43048, 43056, 43062, 43064, 43065, 43072, 43124, 43136, -+ 43138, 43188, 43204, 43214, 43216, 43232, 43250, 43256, 43259, 43264, -+ 43274, 43302, 43310, 43312, 43335, 43346, 43359, 43360, 43392, 43395, -+ 43396, 43443, 43444, 43446, 43450, 43452, 43453, 43457, 43471, 43472, -+ 43486, 43520, 43561, 43567, 43569, 43571, 43573, 43584, 43587, 43588, -+ 43596, 43597, 43600, 43612, 43616, 43632, 43633, 43639, 43642, 43643, -+ 43648, 43696, 43697, 43698, 43701, 43703, 43705, 43710, 43712, 43713, -+ 43714, 43739, 43741, 43742, 43744, 43755, 43756, 43758, 43760, 43762, -+ 43763, 43765, 43766, 43777, 43785, 43793, 43808, 43816, 43968, 44003, -+ 44005, 44006, 44008, 44009, 44011, 44012, 44013, 44016, 44032, 55203, -+ 55216, 55243, 55296, 56191, 56319, 57343, 57344, 63743, 63744, 64112, -+ 64256, 64275, 64285, 64286, 64287, 64297, 64298, 64312, 64318, 64320, -+ 64323, 64326, 64434, 64467, 64830, 64831, 64848, 64914, 65008, 65020, -+ 65021, 65024, 65040, 65047, 65048, 65049, 65056, 65072, 65073, 65075, -+ 65077, 65078, 65079, 65080, 65081, 65082, 65083, 65084, 65085, 65086, -+ 65087, 65088, 65089, 65090, 65091, 65092, 65093, 65095, 65096, 65097, -+ 65101, 65104, 65108, 65112, 65113, 65114, 65115, 65116, 65117, 65118, -+ 65119, 65122, 65123, 65124, 65128, 65129, 65130, 65136, 65142, 65279, -+ 65281, 65284, 65285, 65288, 65289, 65290, 65291, 65292, 65293, 65294, -+ 65296, 65306, 65308, 65311, 65313, 65339, 65340, 65341, 65342, 65343, -+ 65344, 65345, 65371, 65372, 65373, 65374, 65375, 65376, 65377, 65378, -+ 65379, 65380, 65382, 65392, 65393, 65438, 65440, 65474, 65482, 65490, -+ 65498, 65504, 65506, 65507, 65508, 65509, 65512, 65513, 65517, 65529, -+ 65532, 0, 13, 40, 60, 63, 80, 128, 256, 263, -+ 311, 320, 373, 377, 394, 400, 464, 509, 640, 672, -+ 768, 800, 816, 833, 834, 842, 896, 927, 928, 968, -+ 976, 977, 1024, 1064, 1104, 1184, 2048, 2056, 2058, 2103, -+ 2108, 2111, 2135, 2136, 2304, 2326, 2335, 2336, 2367, 2432, -+ 2494, 2560, 2561, 2565, 2572, 2576, 2581, 2585, 2616, 2623, -+ 2624, 2640, 2656, 2685, 2687, 2816, 2873, 2880, 2904, 2912, -+ 2936, 3072, 3680, 4096, 4097, 4098, 4099, 4152, 4167, 4178, -+ 4198, 4224, 4226, 4227, 4272, 4275, 4279, 4281, 4283, 4285, -+ 4286, 4304, 4336, 4352, 4355, 4391, 4396, 4397, 4406, 4416, -+ 4480, 4482, 4483, 4531, 4534, 4543, 4545, 4549, 4560, 5760, -+ 5803, 5804, 5805, 5806, 5808, 5814, 5815, 5824, 8192, 9216, -+ 9328, 12288, 26624, 28416, 28496, 28497, 28559, 28563, 45056, 53248, -+ 53504, 53545, 53605, 53607, 53610, 53613, 53619, 53627, 53635, 53637, -+ 53644, 53674, 53678, 53760, 53826, 53829, 54016, 54112, 54272, 54298, -+ 54324, 54350, 54358, 54376, 54402, 54428, 54430, 54434, 54437, 54441, -+ 54446, 54454, 54459, 54461, 54469, 54480, 54506, 54532, 54535, 54541, -+ 54550, 54558, 54584, 54587, 54592, 54598, 54602, 54610, 54636, 54662, -+ 54688, 54714, 54740, 54766, 54792, 54818, 54844, 54870, 54896, 54922, -+ 54952, 54977, 54978, 55003, 55004, 55010, 55035, 55036, 55061, 55062, -+ 55068, 55093, 55094, 55119, 55120, 55126, 55151, 55152, 55177, 55178, -+ 55184, 55209, 55210, 55235, 55236, 55242, 55246, 60928, 60933, 60961, -+ 60964, 60967, 60969, 60980, 60985, 60987, 60994, 60999, 61001, 61003, -+ 61005, 61009, 61012, 61015, 61017, 61019, 61021, 61023, 61025, 61028, -+ 61031, 61036, 61044, 61049, 61054, 61056, 61067, 61089, 61093, 61099, -+ 61168, 61440, 61488, 61600, 61617, 61633, 61649, 61696, 61712, 61744, -+ 61808, 61926, 61968, 62016, 62032, 62208, 62256, 62263, 62336, 62368, -+ 62406, 62432, 62464, 62528, 62530, 62713, 62720, 62784, 62800, 62971, -+ 63045, 63104, 63232, 0, 42710, 42752, 46900, 46912, 47133, 63488, -+ 1, 32, 256, 0, 65533, -+ }; -+static u16 aFts5UnicodeData[] = { -+ 1025, 61, 117, 55, 117, 54, 50, 53, 57, 53, -+ 49, 85, 333, 85, 121, 85, 841, 54, 53, 50, -+ 56, 48, 56, 837, 54, 57, 50, 57, 1057, 61, -+ 53, 151, 58, 53, 56, 58, 39, 52, 57, 34, -+ 58, 56, 58, 57, 79, 56, 37, 85, 56, 47, -+ 39, 51, 111, 53, 745, 57, 233, 773, 57, 261, -+ 1822, 37, 542, 37, 1534, 222, 69, 73, 37, 126, -+ 126, 73, 69, 137, 37, 73, 37, 105, 101, 73, -+ 37, 73, 37, 190, 158, 37, 126, 126, 73, 37, -+ 126, 94, 37, 39, 94, 69, 135, 41, 40, 37, -+ 41, 40, 37, 41, 40, 37, 542, 37, 606, 37, -+ 41, 40, 37, 126, 73, 37, 1886, 197, 73, 37, -+ 73, 69, 126, 105, 37, 286, 2181, 39, 869, 582, -+ 152, 390, 472, 166, 248, 38, 56, 38, 568, 3596, -+ 158, 38, 56, 94, 38, 101, 53, 88, 41, 53, -+ 105, 41, 73, 37, 553, 297, 1125, 94, 37, 105, -+ 101, 798, 133, 94, 57, 126, 94, 37, 1641, 1541, -+ 1118, 58, 172, 75, 1790, 478, 37, 2846, 1225, 38, -+ 213, 1253, 53, 49, 55, 1452, 49, 44, 53, 76, -+ 53, 76, 53, 44, 871, 103, 85, 162, 121, 85, -+ 55, 85, 90, 364, 53, 85, 1031, 38, 327, 684, -+ 333, 149, 71, 44, 3175, 53, 39, 236, 34, 58, -+ 204, 70, 76, 58, 140, 71, 333, 103, 90, 39, -+ 469, 34, 39, 44, 967, 876, 2855, 364, 39, 333, -+ 1063, 300, 70, 58, 117, 38, 711, 140, 38, 300, -+ 38, 108, 38, 172, 501, 807, 108, 53, 39, 359, -+ 876, 108, 42, 1735, 44, 42, 44, 39, 106, 268, -+ 138, 44, 74, 39, 236, 327, 76, 85, 333, 53, -+ 38, 199, 231, 44, 74, 263, 71, 711, 231, 39, -+ 135, 44, 39, 106, 140, 74, 74, 44, 39, 42, -+ 71, 103, 76, 333, 71, 87, 207, 58, 55, 76, -+ 42, 199, 71, 711, 231, 71, 71, 71, 44, 106, -+ 76, 76, 108, 44, 135, 39, 333, 76, 103, 44, -+ 76, 42, 295, 103, 711, 231, 71, 167, 44, 39, -+ 106, 172, 76, 42, 74, 44, 39, 71, 76, 333, -+ 53, 55, 44, 74, 263, 71, 711, 231, 71, 167, -+ 44, 39, 42, 44, 42, 140, 74, 74, 44, 44, -+ 42, 71, 103, 76, 333, 58, 39, 207, 44, 39, -+ 199, 103, 135, 71, 39, 71, 71, 103, 391, 74, -+ 44, 74, 106, 106, 44, 39, 42, 333, 111, 218, -+ 55, 58, 106, 263, 103, 743, 327, 167, 39, 108, -+ 138, 108, 140, 76, 71, 71, 76, 333, 239, 58, -+ 74, 263, 103, 743, 327, 167, 44, 39, 42, 44, -+ 170, 44, 74, 74, 76, 74, 39, 71, 76, 333, -+ 71, 74, 263, 103, 1319, 39, 106, 140, 106, 106, -+ 44, 39, 42, 71, 76, 333, 207, 58, 199, 74, -+ 583, 775, 295, 39, 231, 44, 106, 108, 44, 266, -+ 74, 53, 1543, 44, 71, 236, 55, 199, 38, 268, -+ 53, 333, 85, 71, 39, 71, 39, 39, 135, 231, -+ 103, 39, 39, 71, 135, 44, 71, 204, 76, 39, -+ 167, 38, 204, 333, 135, 39, 122, 501, 58, 53, -+ 122, 76, 218, 333, 335, 58, 44, 58, 44, 58, -+ 44, 54, 50, 54, 50, 74, 263, 1159, 460, 42, -+ 172, 53, 76, 167, 364, 1164, 282, 44, 218, 90, -+ 181, 154, 85, 1383, 74, 140, 42, 204, 42, 76, -+ 74, 76, 39, 333, 213, 199, 74, 76, 135, 108, -+ 39, 106, 71, 234, 103, 140, 423, 44, 74, 76, -+ 202, 44, 39, 42, 333, 106, 44, 90, 1225, 41, -+ 41, 1383, 53, 38, 10631, 135, 231, 39, 135, 1319, -+ 135, 1063, 135, 231, 39, 135, 487, 1831, 135, 2151, -+ 108, 309, 655, 519, 346, 2727, 49, 19847, 85, 551, -+ 61, 839, 54, 50, 2407, 117, 110, 423, 135, 108, -+ 583, 108, 85, 583, 76, 423, 103, 76, 1671, 76, -+ 42, 236, 266, 44, 74, 364, 117, 38, 117, 55, -+ 39, 44, 333, 335, 213, 49, 149, 108, 61, 333, -+ 1127, 38, 1671, 1319, 44, 39, 2247, 935, 108, 138, -+ 76, 106, 74, 44, 202, 108, 58, 85, 333, 967, -+ 167, 1415, 554, 231, 74, 333, 47, 1114, 743, 76, -+ 106, 85, 1703, 42, 44, 42, 236, 44, 42, 44, -+ 74, 268, 202, 332, 44, 333, 333, 245, 38, 213, -+ 140, 42, 1511, 44, 42, 172, 42, 44, 170, 44, -+ 74, 231, 333, 245, 346, 300, 314, 76, 42, 967, -+ 42, 140, 74, 76, 42, 44, 74, 71, 333, 1415, -+ 44, 42, 76, 106, 44, 42, 108, 74, 149, 1159, -+ 266, 268, 74, 76, 181, 333, 103, 333, 967, 198, -+ 85, 277, 108, 53, 428, 42, 236, 135, 44, 135, -+ 74, 44, 71, 1413, 2022, 421, 38, 1093, 1190, 1260, -+ 140, 4830, 261, 3166, 261, 265, 197, 201, 261, 265, -+ 261, 265, 197, 201, 261, 41, 41, 41, 94, 229, -+ 265, 453, 261, 264, 261, 264, 261, 264, 165, 69, -+ 137, 40, 56, 37, 120, 101, 69, 137, 40, 120, -+ 133, 69, 137, 120, 261, 169, 120, 101, 69, 137, -+ 40, 88, 381, 162, 209, 85, 52, 51, 54, 84, -+ 51, 54, 52, 277, 59, 60, 162, 61, 309, 52, -+ 51, 149, 80, 117, 57, 54, 50, 373, 57, 53, -+ 48, 341, 61, 162, 194, 47, 38, 207, 121, 54, -+ 50, 38, 335, 121, 54, 50, 422, 855, 428, 139, -+ 44, 107, 396, 90, 41, 154, 41, 90, 37, 105, -+ 69, 105, 37, 58, 41, 90, 57, 169, 218, 41, -+ 58, 41, 58, 41, 58, 137, 58, 37, 137, 37, -+ 135, 37, 90, 69, 73, 185, 94, 101, 58, 57, -+ 90, 37, 58, 527, 1134, 94, 142, 47, 185, 186, -+ 89, 154, 57, 90, 57, 90, 57, 250, 57, 1018, -+ 89, 90, 57, 58, 57, 1018, 8601, 282, 153, 666, -+ 89, 250, 54, 50, 2618, 57, 986, 825, 1306, 217, -+ 602, 1274, 378, 1935, 2522, 719, 5882, 57, 314, 57, -+ 1754, 281, 3578, 57, 4634, 3322, 54, 50, 54, 50, -+ 54, 50, 54, 50, 54, 50, 54, 50, 54, 50, -+ 975, 1434, 185, 54, 50, 1017, 54, 50, 54, 50, -+ 54, 50, 54, 50, 54, 50, 537, 8218, 4217, 54, -+ 50, 54, 50, 54, 50, 54, 50, 54, 50, 54, -+ 50, 54, 50, 54, 50, 54, 50, 54, 50, 54, -+ 50, 2041, 54, 50, 54, 50, 1049, 54, 50, 8281, -+ 1562, 697, 90, 217, 346, 1513, 1509, 126, 73, 69, -+ 254, 105, 37, 94, 37, 94, 165, 70, 105, 37, -+ 3166, 37, 218, 158, 108, 94, 149, 47, 85, 1221, -+ 37, 37, 1799, 38, 53, 44, 743, 231, 231, 231, -+ 231, 231, 231, 231, 231, 1036, 85, 52, 51, 52, -+ 51, 117, 52, 51, 53, 52, 51, 309, 49, 85, -+ 49, 53, 52, 51, 85, 52, 51, 54, 50, 54, -+ 50, 54, 50, 54, 50, 181, 38, 341, 81, 858, -+ 2874, 6874, 410, 61, 117, 58, 38, 39, 46, 54, -+ 50, 54, 50, 54, 50, 54, 50, 54, 50, 90, -+ 54, 50, 54, 50, 54, 50, 54, 50, 49, 54, -+ 82, 58, 302, 140, 74, 49, 166, 90, 110, 38, -+ 39, 53, 90, 2759, 76, 88, 70, 39, 49, 2887, -+ 53, 102, 39, 1319, 3015, 90, 143, 346, 871, 1178, -+ 519, 1018, 335, 986, 271, 58, 495, 1050, 335, 1274, -+ 495, 2042, 8218, 39, 39, 2074, 39, 39, 679, 38, -+ 36583, 1786, 1287, 198, 85, 8583, 38, 117, 519, 333, -+ 71, 1502, 39, 44, 107, 53, 332, 53, 38, 798, -+ 44, 2247, 334, 76, 213, 760, 294, 88, 478, 69, -+ 2014, 38, 261, 190, 350, 38, 88, 158, 158, 382, -+ 70, 37, 231, 44, 103, 44, 135, 44, 743, 74, -+ 76, 42, 154, 207, 90, 55, 58, 1671, 149, 74, -+ 1607, 522, 44, 85, 333, 588, 199, 117, 39, 333, -+ 903, 268, 85, 743, 364, 74, 53, 935, 108, 42, -+ 1511, 44, 74, 140, 74, 44, 138, 437, 38, 333, -+ 85, 1319, 204, 74, 76, 74, 76, 103, 44, 263, -+ 44, 42, 333, 149, 519, 38, 199, 122, 39, 42, -+ 1543, 44, 39, 108, 71, 76, 167, 76, 39, 44, -+ 39, 71, 38, 85, 359, 42, 76, 74, 85, 39, -+ 70, 42, 44, 199, 199, 199, 231, 231, 1127, 74, -+ 44, 74, 44, 74, 53, 42, 44, 333, 39, 39, -+ 743, 1575, 36, 68, 68, 36, 63, 63, 11719, 3399, -+ 229, 165, 39, 44, 327, 57, 423, 167, 39, 71, -+ 71, 3463, 536, 11623, 54, 50, 2055, 1735, 391, 55, -+ 58, 524, 245, 54, 50, 53, 236, 53, 81, 80, -+ 54, 50, 54, 50, 54, 50, 54, 50, 54, 50, -+ 54, 50, 54, 50, 54, 50, 85, 54, 50, 149, -+ 112, 117, 149, 49, 54, 50, 54, 50, 54, 50, -+ 117, 57, 49, 121, 53, 55, 85, 167, 4327, 34, -+ 117, 55, 117, 54, 50, 53, 57, 53, 49, 85, -+ 333, 85, 121, 85, 841, 54, 53, 50, 56, 48, -+ 56, 837, 54, 57, 50, 57, 54, 50, 53, 54, -+ 50, 85, 327, 38, 1447, 70, 999, 199, 199, 199, -+ 103, 87, 57, 56, 58, 87, 58, 153, 90, 98, -+ 90, 391, 839, 615, 71, 487, 455, 3943, 117, 1455, -+ 314, 1710, 143, 570, 47, 410, 1466, 44, 935, 1575, -+ 999, 143, 551, 46, 263, 46, 967, 53, 1159, 263, -+ 53, 174, 1289, 1285, 2503, 333, 199, 39, 1415, 71, -+ 39, 743, 53, 271, 711, 207, 53, 839, 53, 1799, -+ 71, 39, 108, 76, 140, 135, 103, 871, 108, 44, -+ 271, 309, 935, 79, 53, 1735, 245, 711, 271, 615, -+ 271, 2343, 1007, 42, 44, 42, 1703, 492, 245, 655, -+ 333, 76, 42, 1447, 106, 140, 74, 76, 85, 34, -+ 149, 807, 333, 108, 1159, 172, 42, 268, 333, 149, -+ 76, 42, 1543, 106, 300, 74, 135, 149, 333, 1383, -+ 44, 42, 44, 74, 204, 42, 44, 333, 28135, 3182, -+ 149, 34279, 18215, 2215, 39, 1482, 140, 422, 71, 7898, -+ 1274, 1946, 74, 108, 122, 202, 258, 268, 90, 236, -+ 986, 140, 1562, 2138, 108, 58, 2810, 591, 841, 837, -+ 841, 229, 581, 841, 837, 41, 73, 41, 73, 137, -+ 265, 133, 37, 229, 357, 841, 837, 73, 137, 265, -+ 233, 837, 73, 137, 169, 41, 233, 837, 841, 837, -+ 841, 837, 841, 837, 841, 837, 841, 837, 841, 901, -+ 809, 57, 805, 57, 197, 809, 57, 805, 57, 197, -+ 809, 57, 805, 57, 197, 809, 57, 805, 57, 197, -+ 809, 57, 805, 57, 197, 94, 1613, 135, 871, 71, -+ 39, 39, 327, 135, 39, 39, 39, 39, 39, 39, -+ 103, 71, 39, 39, 39, 39, 39, 39, 71, 39, -+ 135, 231, 135, 135, 39, 327, 551, 103, 167, 551, -+ 89, 1434, 3226, 506, 474, 506, 506, 367, 1018, 1946, -+ 1402, 954, 1402, 314, 90, 1082, 218, 2266, 666, 1210, -+ 186, 570, 2042, 58, 5850, 154, 2010, 154, 794, 2266, -+ 378, 2266, 3738, 39, 39, 39, 39, 39, 39, 17351, -+ 34, 3074, 7692, 63, 63, -+ }; -+ -+static int sqlite3Fts5UnicodeCategory(int iCode) { -+ int iRes = -1; -+ int iHi; -+ int iLo; -+ int ret; -+ u16 iKey; -+ -+ if( iCode>=(1<<20) ){ -+ return 0; -+ } -+ iLo = aFts5UnicodeBlock[(iCode>>16)]; -+ iHi = aFts5UnicodeBlock[1+(iCode>>16)]; -+ iKey = (iCode & 0xFFFF); -+ while( iHi>iLo ){ -+ int iTest = (iHi + iLo) / 2; -+ assert( iTest>=iLo && iTest<iHi ); -+ if( iKey>=aFts5UnicodeMap[iTest] ){ -+ iRes = iTest; -+ iLo = iTest+1; -+ }else{ -+ iHi = iTest; -+ } -+ } -+ -+ if( iRes<0 ) return 0; -+ if( iKey>=(aFts5UnicodeMap[iRes]+(aFts5UnicodeData[iRes]>>5)) ) return 0; -+ ret = aFts5UnicodeData[iRes] & 0x1F; -+ if( ret!=30 ) return ret; -+ return ((iKey - aFts5UnicodeMap[iRes]) & 0x01) ? 5 : 9; -+} -+ -+static void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){ -+ int i = 0; -+ int iTbl = 0; -+ while( i<128 ){ -+ int bToken = aArray[ aFts5UnicodeData[iTbl] & 0x1F ]; -+ int n = (aFts5UnicodeData[iTbl] >> 5) + i; -+ for(; i<128 && i<n; i++){ -+ aAscii[i] = (u8)bToken; -+ } -+ iTbl++; -+ } -+} -+ -+ - /* - ** 2015 May 30 - ** -@@ -203503,6 +219482,11 @@ - ** the number of fts5 rows that contain at least one instance of term - ** $term. Field $cnt is set to the total number of instances of term - ** $term in the database. -+** -+** instance: -+** CREATE TABLE vocab(term, doc, col, offset, PRIMARY KEY(<all-fields>)); -+** -+** One row for each term instance in the database. - */ - - -@@ -203518,7 +219502,7 @@ - char *zFts5Db; /* Db containing fts5 table */ - sqlite3 *db; /* Database handle */ - Fts5Global *pGlobal; /* FTS5 global object for this database */ -- int eType; /* FTS5_VOCAB_COL or ROW */ -+ int eType; /* FTS5_VOCAB_COL, ROW or INSTANCE */ - }; - - struct Fts5VocabCursor { -@@ -203538,16 +219522,22 @@ - i64 *aCnt; - i64 *aDoc; - -- /* Output values used by 'row' and 'col' tables */ -+ /* Output values used by all tables. */ - i64 rowid; /* This table's current rowid value */ - Fts5Buffer term; /* Current value of 'term' column */ -+ -+ /* Output values Used by 'instance' tables only */ -+ i64 iInstPos; -+ int iInstOff; - }; - --#define FTS5_VOCAB_COL 0 --#define FTS5_VOCAB_ROW 1 -+#define FTS5_VOCAB_COL 0 -+#define FTS5_VOCAB_ROW 1 -+#define FTS5_VOCAB_INSTANCE 2 - - #define FTS5_VOCAB_COL_SCHEMA "term, col, doc, cnt" - #define FTS5_VOCAB_ROW_SCHEMA "term, doc, cnt" -+#define FTS5_VOCAB_INST_SCHEMA "term, doc, col, offset" - - /* - ** Bits for the mask used as the idxNum value by xBestIndex/xFilter. -@@ -203575,6 +219565,9 @@ - if( sqlite3_stricmp(zCopy, "row")==0 ){ - *peType = FTS5_VOCAB_ROW; - }else -+ if( sqlite3_stricmp(zCopy, "instance")==0 ){ -+ *peType = FTS5_VOCAB_INSTANCE; -+ }else - { - *pzErr = sqlite3_mprintf("fts5vocab: unknown table type: %Q", zCopy); - rc = SQLITE_ERROR; -@@ -203635,7 +219628,8 @@ - ){ - const char *azSchema[] = { - "CREATE TABlE vocab(" FTS5_VOCAB_COL_SCHEMA ")", -- "CREATE TABlE vocab(" FTS5_VOCAB_ROW_SCHEMA ")" -+ "CREATE TABlE vocab(" FTS5_VOCAB_ROW_SCHEMA ")", -+ "CREATE TABlE vocab(" FTS5_VOCAB_INST_SCHEMA ")" - }; - - Fts5VocabTable *pRet = 0; -@@ -203709,6 +219703,15 @@ - - /* - ** Implementation of the xBestIndex method. -+** -+** Only constraints of the form: -+** -+** term <= ? -+** term == ? -+** term >= ? -+** -+** are interpreted. Less-than and less-than-or-equal are treated -+** identically, as are greater-than and greater-than-or-equal. - */ - static int fts5VocabBestIndexMethod( - sqlite3_vtab *pUnused, -@@ -203852,7 +219855,57 @@ - return SQLITE_OK; - } - -+static int fts5VocabInstanceNewTerm(Fts5VocabCursor *pCsr){ -+ int rc = SQLITE_OK; -+ -+ if( sqlite3Fts5IterEof(pCsr->pIter) ){ -+ pCsr->bEof = 1; -+ }else{ -+ const char *zTerm; -+ int nTerm; -+ zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm); -+ if( pCsr->nLeTerm>=0 ){ -+ int nCmp = MIN(nTerm, pCsr->nLeTerm); -+ int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp); -+ if( bCmp<0 || (bCmp==0 && pCsr->nLeTerm<nTerm) ){ -+ pCsr->bEof = 1; -+ } -+ } - -+ sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm); -+ } -+ return rc; -+} -+ -+static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){ -+ int eDetail = pCsr->pConfig->eDetail; -+ int rc = SQLITE_OK; -+ Fts5IndexIter *pIter = pCsr->pIter; -+ i64 *pp = &pCsr->iInstPos; -+ int *po = &pCsr->iInstOff; -+ -+ assert( sqlite3Fts5IterEof(pIter)==0 ); -+ assert( pCsr->bEof==0 ); -+ while( eDetail==FTS5_DETAIL_NONE -+ || sqlite3Fts5PoslistNext64(pIter->pData, pIter->nData, po, pp) -+ ){ -+ pCsr->iInstPos = 0; -+ pCsr->iInstOff = 0; -+ -+ rc = sqlite3Fts5IterNextScan(pCsr->pIter); -+ if( rc==SQLITE_OK ){ -+ rc = fts5VocabInstanceNewTerm(pCsr); -+ if( pCsr->bEof || eDetail==FTS5_DETAIL_NONE ) break; -+ } -+ if( rc ){ -+ pCsr->bEof = 1; -+ break; -+ } -+ } -+ -+ return rc; -+} -+ - /* - ** Advance the cursor to the next row in the table. - */ -@@ -203864,6 +219917,10 @@ - - pCsr->rowid++; - -+ if( pTab->eType==FTS5_VOCAB_INSTANCE ){ -+ return fts5VocabInstanceNext(pCsr); -+ } -+ - if( pTab->eType==FTS5_VOCAB_COL ){ - for(pCsr->iCol++; pCsr->iCol<nCol; pCsr->iCol++){ - if( pCsr->aDoc[pCsr->iCol] ) break; -@@ -203870,7 +219927,7 @@ - } - } - -- if( pTab->eType==FTS5_VOCAB_ROW || pCsr->iCol>=nCol ){ -+ if( pTab->eType!=FTS5_VOCAB_COL || pCsr->iCol>=nCol ){ - if( sqlite3Fts5IterEof(pCsr->pIter) ){ - pCsr->bEof = 1; - }else{ -@@ -203894,6 +219951,7 @@ - - assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW ); - while( rc==SQLITE_OK ){ -+ int eDetail = pCsr->pConfig->eDetail; - const u8 *pPos; int nPos; /* Position list */ - i64 iPos = 0; /* 64-bit position read from poslist */ - int iOff = 0; /* Current offset within position list */ -@@ -203900,16 +219958,19 @@ - - pPos = pCsr->pIter->pData; - nPos = pCsr->pIter->nData; -- switch( pCsr->pConfig->eDetail ){ -- case FTS5_DETAIL_FULL: -- pPos = pCsr->pIter->pData; -- nPos = pCsr->pIter->nData; -- if( pTab->eType==FTS5_VOCAB_ROW ){ -+ -+ switch( pTab->eType ){ -+ case FTS5_VOCAB_ROW: -+ if( eDetail==FTS5_DETAIL_FULL ){ - while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ - pCsr->aCnt[0]++; - } -- pCsr->aDoc[0]++; -- }else{ -+ } -+ pCsr->aDoc[0]++; -+ break; -+ -+ case FTS5_VOCAB_COL: -+ if( eDetail==FTS5_DETAIL_FULL ){ - int iCol = -1; - while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ - int ii = FTS5_POS2COLUMN(iPos); -@@ -203923,13 +219984,7 @@ - iCol = ii; - } - } -- } -- break; -- -- case FTS5_DETAIL_COLUMNS: -- if( pTab->eType==FTS5_VOCAB_ROW ){ -- pCsr->aDoc[0]++; -- }else{ -+ }else if( eDetail==FTS5_DETAIL_COLUMNS ){ - while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){ - assert_nc( iPos>=0 && iPos<nCol ); - if( iPos>=nCol ){ -@@ -203938,12 +219993,14 @@ - } - pCsr->aDoc[iPos]++; - } -+ }else{ -+ assert( eDetail==FTS5_DETAIL_NONE ); -+ pCsr->aDoc[0]++; - } - break; - -- default: -- assert( pCsr->pConfig->eDetail==FTS5_DETAIL_NONE ); -- pCsr->aDoc[0]++; -+ default: -+ assert( pTab->eType==FTS5_VOCAB_INSTANCE ); - break; - } - -@@ -203950,6 +220007,7 @@ - if( rc==SQLITE_OK ){ - rc = sqlite3Fts5IterNextScan(pCsr->pIter); - } -+ if( pTab->eType==FTS5_VOCAB_INSTANCE ) break; - - if( rc==SQLITE_OK ){ - zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm); -@@ -203979,7 +220037,9 @@ - int nUnused, /* Number of elements in apVal */ - sqlite3_value **apVal /* Arguments for the indexing scheme */ - ){ -+ Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab; - Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; -+ int eType = pTab->eType; - int rc = SQLITE_OK; - - int iVal = 0; -@@ -204019,11 +220079,16 @@ - } - } - -- - if( rc==SQLITE_OK ){ - rc = sqlite3Fts5IndexQuery(pCsr->pIndex, zTerm, nTerm, f, 0, &pCsr->pIter); - } -- if( rc==SQLITE_OK ){ -+ if( rc==SQLITE_OK && eType==FTS5_VOCAB_INSTANCE ){ -+ rc = fts5VocabInstanceNewTerm(pCsr); -+ } -+ if( rc==SQLITE_OK -+ && !pCsr->bEof -+ && (eType!=FTS5_VOCAB_INSTANCE || pCsr->pConfig->eDetail!=FTS5_DETAIL_NONE) -+ ){ - rc = fts5VocabNextMethod(pCursor); - } - -@@ -204065,7 +220130,7 @@ - }else{ - iVal = pCsr->aCnt[pCsr->iCol]; - } -- }else{ -+ }else if( eType==FTS5_VOCAB_ROW ){ - assert( iCol==1 || iCol==2 ); - if( iCol==1 ){ - iVal = pCsr->aDoc[0]; -@@ -204072,6 +220137,34 @@ - }else{ - iVal = pCsr->aCnt[0]; - } -+ }else{ -+ assert( eType==FTS5_VOCAB_INSTANCE ); -+ switch( iCol ){ -+ case 1: -+ sqlite3_result_int64(pCtx, pCsr->pIter->iRowid); -+ break; -+ case 2: { -+ int ii = -1; -+ if( eDetail==FTS5_DETAIL_FULL ){ -+ ii = FTS5_POS2COLUMN(pCsr->iInstPos); -+ }else if( eDetail==FTS5_DETAIL_COLUMNS ){ -+ ii = (int)pCsr->iInstPos; -+ } -+ if( ii>=0 && ii<pCsr->pConfig->nCol ){ -+ const char *z = pCsr->pConfig->azCol[ii]; -+ sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC); -+ } -+ break; -+ } -+ default: { -+ assert( iCol==3 ); -+ if( eDetail==FTS5_DETAIL_FULL ){ -+ int ii = FTS5_POS2OFFSET(pCsr->iInstPos); -+ sqlite3_result_int(pCtx, ii); -+ } -+ break; -+ } -+ } - } - - if( iVal>0 ) sqlite3_result_int64(pCtx, iVal); -@@ -204117,6 +220210,7 @@ - /* xSavepoint */ 0, - /* xRelease */ 0, - /* xRollbackTo */ 0, -+ /* xShadowName */ 0 - }; - void *p = (void*)pGlobal; - -@@ -204124,8 +220218,6 @@ - } - - -- -- - - #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */ - -@@ -204399,6 +220491,7 @@ - 0, /* xSavepoint */ - 0, /* xRelease */ - 0, /* xRollbackTo */ -+ 0, /* xShadowName */ - }; - - #endif /* SQLITE_OMIT_VIRTUALTABLE */ -@@ -204431,3 +220524,10 @@ - #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ - - /************** End of stmt.c ************************************************/ -+#if __LINE__!=220527 -+#undef SQLITE_SOURCE_ID -+#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238alt2" -+#endif -+/* Return the source-id for this library */ -+SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } -+/************************** End of sqlite3.c ******************************/ ---- contrib/sqlite3/sqlite3.h.orig -+++ contrib/sqlite3/sqlite3.h -@@ -115,15 +115,17 @@ - ** a string which identifies a particular check-in of SQLite - ** within its configuration management system. ^The SQLITE_SOURCE_ID - ** string contains the date and time of the check-in (UTC) and a SHA1 --** or SHA3-256 hash of the entire source tree. -+** or SHA3-256 hash of the entire source tree. If the source code has -+** been edited in any way since it was last checked in, then the last -+** four hexadecimal digits of the hash may be modified. - ** - ** See also: [sqlite3_libversion()], - ** [sqlite3_libversion_number()], [sqlite3_sourceid()], - ** [sqlite_version()] and [sqlite_source_id()]. - */ --#define SQLITE_VERSION "3.20.0" --#define SQLITE_VERSION_NUMBER 3020000 --#define SQLITE_SOURCE_ID "2017-08-01 13:24:15 9501e22dfeebdcefa783575e47c60b514d7c2e0cad73b2a496c0bc4b680900a8" -+#define SQLITE_VERSION "3.26.0" -+#define SQLITE_VERSION_NUMBER 3026000 -+#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9" - - /* - ** CAPI3REF: Run-Time Library Version Numbers -@@ -139,7 +141,7 @@ - ** - ** <blockquote><pre> - ** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER ); --** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 ); -+** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 ); - ** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 ); - ** </pre></blockquote>)^ - ** -@@ -149,9 +151,11 @@ - ** function is provided for use in DLLs since DLL users usually do not have - ** direct access to string constants within the DLL. ^The - ** sqlite3_libversion_number() function returns an integer equal to --** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns -+** [SQLITE_VERSION_NUMBER]. ^(The sqlite3_sourceid() function returns - ** a pointer to a string constant whose value is the same as the --** [SQLITE_SOURCE_ID] C preprocessor macro. -+** [SQLITE_SOURCE_ID] C preprocessor macro. Except if SQLite is built -+** using an edited copy of [the amalgamation], then the last four characters -+** of the hash might be different from [SQLITE_SOURCE_ID].)^ - ** - ** See also: [sqlite_version()] and [sqlite_source_id()]. - */ -@@ -432,7 +436,7 @@ - #define SQLITE_FULL 13 /* Insertion failed because database is full */ - #define SQLITE_CANTOPEN 14 /* Unable to open the database file */ - #define SQLITE_PROTOCOL 15 /* Database lock protocol error */ --#define SQLITE_EMPTY 16 /* Not used */ -+#define SQLITE_EMPTY 16 /* Internal use only */ - #define SQLITE_SCHEMA 17 /* The database schema changed */ - #define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ - #define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ -@@ -466,6 +470,9 @@ - ** the most recent error can be obtained using - ** [sqlite3_extended_errcode()]. - */ -+#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8)) -+#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8)) -+#define SQLITE_ERROR_SNAPSHOT (SQLITE_ERROR | (3<<8)) - #define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) - #define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) - #define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) -@@ -494,7 +501,11 @@ - #define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) - #define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8)) - #define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8)) -+#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8)) -+#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) -+#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) - #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) -+#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) - #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) - #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) - #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) -@@ -501,11 +512,15 @@ - #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) - #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_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) -+#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8)) - #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) - #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) - #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) - #define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8)) -+#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8)) -+#define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8)) - #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) - #define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8)) - #define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8)) -@@ -580,6 +595,11 @@ - ** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on - ** read-only media and cannot be changed even by processes with - ** elevated privileges. -+** -+** The SQLITE_IOCAP_BATCH_ATOMIC property means that the underlying -+** filesystem supports doing multiple write operations atomically when those -+** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and -+** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. - */ - #define SQLITE_IOCAP_ATOMIC 0x00000001 - #define SQLITE_IOCAP_ATOMIC512 0x00000002 -@@ -595,6 +615,7 @@ - #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 - #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 - #define SQLITE_IOCAP_IMMUTABLE 0x00002000 -+#define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 - - /* - ** CAPI3REF: File Locking Levels -@@ -729,6 +750,7 @@ - ** <li> [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN] - ** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE] - ** <li> [SQLITE_IOCAP_IMMUTABLE] -+** <li> [SQLITE_IOCAP_BATCH_ATOMIC] - ** </ul> - ** - ** The SQLITE_IOCAP_ATOMIC property means that all writes of -@@ -866,7 +888,8 @@ - ** <li>[[SQLITE_FCNTL_PERSIST_WAL]] - ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the - ** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary --** write ahead log and shared memory files used for transaction control -+** write ahead log ([WAL file]) and shared memory -+** files used for transaction control - ** are automatically deleted when the latest connection to the database - ** closes. Setting persistent WAL mode causes those files to persist after - ** close. Persisting the files is useful when other processes that do not -@@ -1012,6 +1035,66 @@ - ** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by - ** the RBU extension only. All other VFS should return SQLITE_NOTFOUND for - ** this opcode. -+** -+** <li>[[SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]] -+** If the [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] opcode returns SQLITE_OK, then -+** the file descriptor is placed in "batch write mode", which -+** means all subsequent write operations will be deferred and done -+** atomically at the next [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. Systems -+** that do not support batch atomic writes will return SQLITE_NOTFOUND. -+** ^Following a successful SQLITE_FCNTL_BEGIN_ATOMIC_WRITE and prior to -+** the closing [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] or -+** [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE], SQLite will make -+** no VFS interface calls on the same [sqlite3_file] file descriptor -+** except for calls to the xWrite method and the xFileControl method -+** with [SQLITE_FCNTL_SIZE_HINT]. -+** -+** <li>[[SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]] -+** The [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] opcode causes all write -+** operations since the previous successful call to -+** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be performed atomically. -+** This file control returns [SQLITE_OK] if and only if the writes were -+** all performed successfully and have been committed to persistent storage. -+** ^Regardless of whether or not it is successful, this file control takes -+** the file descriptor out of batch write mode so that all subsequent -+** write operations are independent. -+** ^SQLite will never invoke SQLITE_FCNTL_COMMIT_ATOMIC_WRITE without -+** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]. -+** -+** <li>[[SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE]] -+** The [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE] opcode causes all write -+** operations since the previous successful call to -+** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be rolled back. -+** ^This file control takes the file descriptor out of batch write mode -+** so that all subsequent write operations are independent. -+** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without -+** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]. -+** -+** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]] -+** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain -+** a file lock using the xLock or xShmLock methods of the VFS to wait -+** for up to M milliseconds before failing, where M is the single -+** unsigned integer parameter. -+** -+** <li>[[SQLITE_FCNTL_DATA_VERSION]] -+** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to -+** a database file. The argument is a pointer to a 32-bit unsigned integer. -+** The "data version" for the pager is written into the pointer. The -+** "data version" changes whenever any change occurs to the corresponding -+** database file, either through SQL statements on the same database -+** connection or through transactions committed by separate database -+** connections possibly in other processes. The [sqlite3_total_changes()] -+** interface can be used to find if any database on the connection has changed, -+** but that interface responds to changes on TEMP as well as MAIN and does -+** 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 -+** 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. - ** </ul> - */ - #define SQLITE_FCNTL_LOCKSTATE 1 -@@ -1043,6 +1126,11 @@ - #define SQLITE_FCNTL_JOURNAL_POINTER 28 - #define SQLITE_FCNTL_WIN32_GET_HANDLE 29 - #define SQLITE_FCNTL_PDB 30 -+#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31 -+#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32 -+#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33 -+#define SQLITE_FCNTL_LOCK_TIMEOUT 34 -+#define SQLITE_FCNTL_DATA_VERSION 35 - - /* deprecated names */ - #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE -@@ -1080,12 +1168,18 @@ - ** in the name of the object stands for "virtual file system". See - ** the [VFS | VFS documentation] for further information. - ** --** The value of the iVersion field is initially 1 but may be larger in --** future versions of SQLite. Additional fields may be appended to this --** object when the iVersion value is increased. Note that the structure --** of the sqlite3_vfs object changes in the transaction between --** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not --** modified. -+** The VFS interface is sometimes extended by adding new methods onto -+** the end. Each time such an extension occurs, the iVersion field -+** is incremented. The iVersion value started out as 1 in -+** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2 -+** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased -+** 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 -+** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0] -+** and yet the iVersion field was not modified. - ** - ** The szOsFile field is the size of the subclassed [sqlite3_file] - ** structure used by this VFS. mxPathname is the maximum length of -@@ -1613,6 +1707,16 @@ - ** routines with a wrapper that simulations memory allocation failure or - ** tracks memory usage, for example. </dd> - ** -+** [[SQLITE_CONFIG_SMALL_MALLOC]] <dt>SQLITE_CONFIG_SMALL_MALLOC</dt> -+** <dd> ^The SQLITE_CONFIG_SMALL_MALLOC option takes single argument of -+** type int, interpreted as a boolean, which if true provides a hint to -+** SQLite that it should avoid large memory allocations if possible. -+** SQLite will run faster if it is free to make large memory allocations, -+** but some application might prefer to run slower in exchange for -+** guarantees about memory fragmentation that are possible if large -+** allocations are avoided. This hint is normally off. -+** </dd> -+** - ** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt> - ** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int, - ** interpreted as a boolean, which enables or disables the collection of -@@ -1630,25 +1734,7 @@ - ** </dd> - ** - ** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt> --** <dd> ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer --** that SQLite can use for scratch memory. ^(There are three arguments --** to SQLITE_CONFIG_SCRATCH: A pointer an 8-byte --** aligned memory buffer from which the scratch allocations will be --** drawn, the size of each scratch allocation (sz), --** and the maximum number of scratch allocations (N).)^ --** The first argument must be a pointer to an 8-byte aligned buffer --** of at least sz*N bytes of memory. --** ^SQLite will not use more than one scratch buffers per thread. --** ^SQLite will never request a scratch buffer that is more than 6 --** times the database page size. --** ^If SQLite needs needs additional --** scratch memory beyond what is provided by this configuration option, then --** [sqlite3_malloc()] will be used to obtain the memory needed.<p> --** ^When the application provides any amount of scratch memory using --** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large --** [sqlite3_malloc|heap allocations]. --** This can help [Robson proof|prevent memory allocation failures] due to heap --** fragmentation in low-memory embedded systems. -+** <dd> The SQLITE_CONFIG_SCRATCH option is no longer used. - ** </dd> - ** - ** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt> -@@ -1684,8 +1770,7 @@ - ** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt> - ** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer - ** that SQLite will use for all of its dynamic memory allocation needs --** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and --** [SQLITE_CONFIG_PAGECACHE]. -+** beyond those provided for by [SQLITE_CONFIG_PAGECACHE]. - ** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled - ** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns - ** [SQLITE_ERROR] if invoked otherwise. -@@ -1871,6 +1956,22 @@ - ** I/O required to support statement rollback. - ** The default value for this setting is controlled by the - ** [SQLITE_STMTJRNL_SPILL] compile-time option. -+** -+** [[SQLITE_CONFIG_SORTERREF_SIZE]] -+** <dt>SQLITE_CONFIG_SORTERREF_SIZE -+** <dd>The SQLITE_CONFIG_SORTERREF_SIZE option accepts a single parameter -+** of type (int) - the new value of the sorter-reference size threshold. -+** Usually, when SQLite uses an external sort to order records according -+** to an ORDER BY clause, all fields required by the caller are present in the -+** sorted records. However, if SQLite determines based on the declared type -+** of a table column that its values are likely to be very large - larger -+** than the configured sorter-reference size threshold - then a reference -+** is stored in each sorted record and the required column values loaded -+** from the database as records are returned in sorted order. The default -+** value for this option is to never use this optimization. Specifying a -+** negative value for this option restores the default behaviour. -+** This option is only available if SQLite is compiled with the -+** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option. - ** </dl> - */ - #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ -@@ -1878,7 +1979,7 @@ - #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ - #define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ - #define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ --#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */ -+#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */ - #define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ - #define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ - #define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ -@@ -1899,6 +2000,8 @@ - #define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */ - #define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ - #define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */ -+#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */ -+#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */ - - /* - ** CAPI3REF: Database Connection Configuration Options -@@ -1914,6 +2017,7 @@ - ** is invoked. - ** - ** <dl> -+** [[SQLITE_DBCONFIG_LOOKASIDE]] - ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt> - ** <dd> ^This option takes three additional arguments that determine the - ** [lookaside memory allocator] configuration for the [database connection]. -@@ -1936,6 +2040,7 @@ - ** memory is in use leaves the configuration unchanged and returns - ** [SQLITE_BUSY].)^</dd> - ** -+** [[SQLITE_DBCONFIG_ENABLE_FKEY]] - ** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt> - ** <dd> ^This option is used to enable or disable the enforcement of - ** [foreign key constraints]. There should be two additional arguments. -@@ -1946,6 +2051,7 @@ - ** following this call. The second parameter may be a NULL pointer, in - ** which case the FK enforcement setting is not reported back. </dd> - ** -+** [[SQLITE_DBCONFIG_ENABLE_TRIGGER]] - ** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt> - ** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers]. - ** There should be two additional arguments. -@@ -1956,6 +2062,7 @@ - ** following this call. The second parameter may be a NULL pointer, in - ** which case the trigger setting is not reported back. </dd> - ** -+** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] - ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> - ** <dd> ^This option is used to enable or disable the two-argument - ** version of the [fts3_tokenizer()] function which is part of the -@@ -1969,6 +2076,7 @@ - ** following this call. The second parameter may be a NULL pointer, in - ** which case the new setting is not reported back. </dd> - ** -+** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]] - ** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt> - ** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()] - ** interface independently of the [load_extension()] SQL function. -@@ -1986,7 +2094,7 @@ - ** be a NULL pointer, in which case the new setting is not reported back. - ** </dd> - ** --** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt> -+** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt> - ** <dd> ^This option is used to change the name of the "main" database - ** schema. ^The sole argument is a pointer to a constant UTF8 string - ** which will become the new schema name in place of "main". ^SQLite -@@ -1995,6 +2103,7 @@ - ** until after the database connection closes. - ** </dd> - ** -+** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]] - ** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt> - ** <dd> Usually, when a database in wal mode is closed or detached from a - ** database handle, SQLite checks if this will mean that there are now no -@@ -2001,13 +2110,14 @@ - ** connections at all to the database. If so, it performs a checkpoint - ** operation before closing the connection. This option may be used to - ** override this behaviour. The first parameter passed to this operation --** is an integer - non-zero to disable checkpoints-on-close, or zero (the --** default) to enable them. The second parameter is a pointer to an integer -+** is an integer - positive to disable checkpoints-on-close, or zero (the -+** default) to enable them, and negative to leave the setting unchanged. -+** The second parameter is a pointer to an integer - ** into which is written 0 or 1 to indicate whether checkpoints-on-close - ** have been disabled - 0 if they are not disabled, 1 if they are. - ** </dd> - ** --** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt> -+** [[SQLITE_DBCONFIG_ENABLE_QPSG]] <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt> - ** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates - ** the [query planner stability guarantee] (QPSG). When the QPSG is active, - ** a single SQL query statement will always use the same algorithm regardless -@@ -2016,8 +2126,57 @@ - ** slower. But the QPSG has the advantage of more predictable behavior. With - ** the QPSG active, SQLite will always use the same query plan in the field as - ** was used during testing in the lab. -+** The first argument to this setting is an integer which is 0 to disable -+** the QPSG, positive to enable QPSG, or negative to leave the setting -+** unchanged. The second parameter is a pointer to an integer into which -+** is written 0 or 1 to indicate whether the QPSG is disabled or enabled -+** following this call. - ** </dd> - ** -+** [[SQLITE_DBCONFIG_TRIGGER_EQP]] <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt> -+** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not -+** include output for any operations performed by trigger programs. This -+** option is used to set or clear (the default) a flag that governs this -+** behavior. The first parameter passed to this operation is an integer - -+** positive to enable output for trigger programs, or zero to disable it, -+** or negative to leave the setting unchanged. -+** The second parameter is a pointer to an integer into which is written -+** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if -+** it is not disabled, 1 if it is. -+** </dd> -+** -+** [[SQLITE_DBCONFIG_RESET_DATABASE]] <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt> -+** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run -+** [VACUUM] in order to reset a database back to an empty database -+** with no schema and no content. The following process works even for -+** a badly corrupted database file: -+** <ol> -+** <li> If the database connection is newly opened, make sure it has read the -+** database schema by preparing then discarding some query against the -+** database, or calling sqlite3_table_column_metadata(), ignoring any -+** errors. This step is only necessary if the application desires to keep -+** the database in WAL mode after the reset if it was in WAL mode before -+** the reset. -+** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); -+** <li> [sqlite3_exec](db, "[VACUUM]", 0, 0, 0); -+** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); -+** </ol> -+** Because resetting a database is destructive and irreversible, the -+** process requires the use of this obscure API and multiple steps to help -+** ensure that it does not happen by accident. -+** -+** [[SQLITE_DBCONFIG_DEFENSIVE]] <dt>SQLITE_DBCONFIG_DEFENSIVE</dt> -+** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the -+** "defensive" flag for a database connection. When the defensive -+** flag is enabled, language features that allow ordinary SQL to -+** deliberately corrupt the database file are disabled. The disabled -+** features include but are not limited to the following: -+** <ul> -+** <li> The [PRAGMA writable_schema=ON] statement. -+** <li> Writes to the [sqlite_dbpage] virtual table. -+** <li> Direct writes to [shadow tables]. -+** </ul> -+** </dd> - ** </dl> - */ - #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ -@@ -2028,8 +2187,11 @@ - #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */ - #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */ - #define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */ -+#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */ -+#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */ -+#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */ -+#define SQLITE_DBCONFIG_MAX 1010 /* Largest DBCONFIG */ - -- - /* - ** CAPI3REF: Enable Or Disable Extended Result Codes - ** METHOD: sqlite3 -@@ -2156,12 +2318,17 @@ - ** program, the value returned reflects the number of rows modified by the - ** previous INSERT, UPDATE or DELETE statement within the same trigger. - ** --** See also the [sqlite3_total_changes()] interface, the --** [count_changes pragma], and the [changes() SQL function]. --** - ** If a separate thread makes changes on the same database connection - ** while [sqlite3_changes()] is running then the value returned - ** is unpredictable and not meaningful. -+** -+** See also: -+** <ul> -+** <li> the [sqlite3_total_changes()] interface -+** <li> the [count_changes pragma] -+** <li> the [changes() SQL function] -+** <li> the [data_version pragma] -+** </ul> - */ - SQLITE_API int sqlite3_changes(sqlite3*); - -@@ -2179,13 +2346,26 @@ - ** count, but those made as part of REPLACE constraint resolution are - ** not. ^Changes to a view that are intercepted by INSTEAD OF triggers - ** are not counted. -+** -+** This the [sqlite3_total_changes(D)] interface only reports the number -+** of rows that changed due to SQL statement run against database -+** connection D. Any changes by other database connections are ignored. -+** To detect changes against a database file from other database -+** connections use the [PRAGMA data_version] command or the -+** [SQLITE_FCNTL_DATA_VERSION] [file control]. - ** --** See also the [sqlite3_changes()] interface, the --** [count_changes pragma], and the [total_changes() SQL function]. --** - ** If a separate thread makes changes on the same database connection - ** while [sqlite3_total_changes()] is running then the value - ** returned is unpredictable and not meaningful. -+** -+** See also: -+** <ul> -+** <li> the [sqlite3_changes()] interface -+** <li> the [count_changes pragma] -+** <li> the [changes() SQL function] -+** <li> the [data_version pragma] -+** <li> the [SQLITE_FCNTL_DATA_VERSION] [file control] -+** </ul> - */ - SQLITE_API int sqlite3_total_changes(sqlite3*); - -@@ -2434,16 +2614,16 @@ - ** - ** These routines are work-alikes of the "printf()" family of functions - ** from the standard C library. --** These routines understand most of the common K&R formatting options, --** plus some additional non-standard formats, detailed below. --** Note that some of the more obscure formatting options from recent --** C-library standards are omitted from this implementation. -+** These routines understand most of the common formatting options from -+** the standard library printf() -+** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]). -+** See the [built-in printf()] documentation for details. - ** - ** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their --** results into memory obtained from [sqlite3_malloc()]. -+** results into memory obtained from [sqlite3_malloc64()]. - ** The strings returned by these two routines should be - ** released by [sqlite3_free()]. ^Both routines return a --** NULL pointer if [sqlite3_malloc()] is unable to allocate enough -+** NULL pointer if [sqlite3_malloc64()] is unable to allocate enough - ** memory to hold the resulting string. - ** - ** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from -@@ -2467,71 +2647,7 @@ - ** - ** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf(). - ** --** These routines all implement some additional formatting --** options that are useful for constructing SQL statements. --** All of the usual printf() formatting options apply. In addition, there --** is are "%q", "%Q", "%w" and "%z" options. --** --** ^(The %q option works like %s in that it substitutes a nul-terminated --** string from the argument list. But %q also doubles every '\'' character. --** %q is designed for use inside a string literal.)^ By doubling each '\'' --** character it escapes that character and allows it to be inserted into --** the string. --** --** For example, assume the string variable zText contains text as follows: --** --** <blockquote><pre> --** char *zText = "It's a happy day!"; --** </pre></blockquote> --** --** One can use this text in an SQL statement as follows: --** --** <blockquote><pre> --** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText); --** sqlite3_exec(db, zSQL, 0, 0, 0); --** sqlite3_free(zSQL); --** </pre></blockquote> --** --** Because the %q format string is used, the '\'' character in zText --** is escaped and the SQL generated is as follows: --** --** <blockquote><pre> --** INSERT INTO table1 VALUES('It''s a happy day!') --** </pre></blockquote> --** --** This is correct. Had we used %s instead of %q, the generated SQL --** would have looked like this: --** --** <blockquote><pre> --** INSERT INTO table1 VALUES('It's a happy day!'); --** </pre></blockquote> --** --** This second example is an SQL syntax error. As a general rule you should --** always use %q instead of %s when inserting text into a string literal. --** --** ^(The %Q option works like %q except it also adds single quotes around --** the outside of the total string. Additionally, if the parameter in the --** argument list is a NULL pointer, %Q substitutes the text "NULL" (without --** single quotes).)^ So, for example, one could say: --** --** <blockquote><pre> --** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText); --** sqlite3_exec(db, zSQL, 0, 0, 0); --** sqlite3_free(zSQL); --** </pre></blockquote> --** --** The code above will render a correct SQL statement in the zSQL --** variable even if the zText variable is a NULL pointer. --** --** ^(The "%w" formatting option is like "%q" except that it expects to --** be contained within double-quotes instead of single quotes, and it --** escapes the double-quote character instead of the single-quote --** character.)^ The "%w" formatting option is intended for safely inserting --** table and column names into a constructed SQL statement. --** --** ^(The "%z" formatting option works like "%s" but with the --** addition that after the string has been read and copied into --** the result, [sqlite3_free()] is called on the input string.)^ -+** See also: [built-in printf()], [printf() SQL function] - */ - SQLITE_API char *sqlite3_mprintf(const char*,...); - SQLITE_API char *sqlite3_vmprintf(const char*, va_list); -@@ -2889,8 +3005,8 @@ - ** KEYWORDS: SQLITE_TRACE - ** - ** These constants identify classes of events that can be monitored --** using the [sqlite3_trace_v2()] tracing logic. The third argument --** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of -+** using the [sqlite3_trace_v2()] tracing logic. The M argument -+** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of - ** the following constants. ^The first argument to the trace callback - ** is one of the following constants. - ** -@@ -3099,10 +3215,10 @@ - ** ^If [URI filename] interpretation is enabled, and the filename argument - ** begins with "file:", then the filename is interpreted as a URI. ^URI - ** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is --** set in the fourth argument to sqlite3_open_v2(), or if it has -+** set in the third argument to sqlite3_open_v2(), or if it has - ** been enabled globally using the [SQLITE_CONFIG_URI] option with the - ** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. --** As of SQLite version 3.7.7, URI filename interpretation is turned off -+** URI filename interpretation is turned off - ** by default, but future releases of SQLite might enable URI filename - ** interpretation by default. See "[URI filenames]" for additional - ** information. -@@ -3305,13 +3421,24 @@ - ** [database connection] D failed, then the sqlite3_errcode(D) interface - ** returns the numeric [result code] or [extended result code] for that - ** API call. --** If the most recent API call was successful, --** then the return value from sqlite3_errcode() is undefined. - ** ^The sqlite3_extended_errcode() - ** interface is the same except that it always returns the - ** [extended result code] even when extended result codes are - ** disabled. - ** -+** The values returned by sqlite3_errcode() and/or -+** sqlite3_extended_errcode() might change with each API call. -+** Except, there are some interfaces that are guaranteed to never -+** change the value of the error code. The error-code preserving -+** interfaces are: -+** -+** <ul> -+** <li> sqlite3_errcode() -+** <li> sqlite3_extended_errcode() -+** <li> sqlite3_errmsg() -+** <li> sqlite3_errmsg16() -+** </ul> -+** - ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language - ** text that describes the error, as either UTF-8 or UTF-16 respectively. - ** ^(Memory to hold the error message string is managed internally. -@@ -3501,9 +3628,19 @@ - ** on this hint by avoiding the use of [lookaside memory] so as not to - ** deplete the limited store of lookaside memory. Future versions of - ** SQLite may act on this hint differently. -+** -+** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt> -+** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized -+** representation of the SQL statement should be calculated and then -+** associated with the prepared statement, which can be obtained via -+** the [sqlite3_normalized_sql()] interface.)^ The semantics used to -+** normalize a SQL statement are unspecified and subject to change. -+** At a minimum, literal values will be replaced with suitable -+** placeholders. - ** </dl> - */ - #define SQLITE_PREPARE_PERSISTENT 0x01 -+#define SQLITE_PREPARE_NORMALIZE 0x02 - - /* - ** CAPI3REF: Compiling An SQL Statement -@@ -3597,6 +3734,7 @@ - ** or [GLOB] operator or if the parameter is compared to an indexed column - ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. - ** </li> -+** </ol> - ** - ** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having - ** the extra prepFlags parameter, which is a bit array consisting of zero or -@@ -3603,7 +3741,6 @@ - ** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags. ^The - ** sqlite3_prepare_v2() interface works exactly the same as - ** sqlite3_prepare_v3() with a zero prepFlags parameter. --** </ol> - */ - SQLITE_API int sqlite3_prepare( - sqlite3 *db, /* Database handle */ -@@ -3661,6 +3798,11 @@ - ** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8 - ** string containing the SQL text of prepared statement P with - ** [bound parameters] expanded. -+** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8 -+** string containing the normalized SQL text of prepared statement P. The -+** semantics used to normalize a SQL statement are unspecified and subject -+** to change. At a minimum, literal values will be replaced with suitable -+** placeholders. - ** - ** ^(For example, if a prepared statement is created using the SQL - ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345 -@@ -3676,8 +3818,9 @@ - ** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time - ** option causes sqlite3_expanded_sql() to always return NULL. - ** --** ^The string returned by sqlite3_sql(P) is managed by SQLite and is --** automatically freed when the prepared statement is finalized. -+** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P) -+** are managed by SQLite and are automatically freed when the prepared -+** statement is finalized. - ** ^The string returned by sqlite3_expanded_sql(P), on the other hand, - ** is obtained from [sqlite3_malloc()] and must be free by the application - ** by passing it to [sqlite3_free()]. -@@ -3684,6 +3827,7 @@ - */ - SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); - SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt); -+SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); - - /* - ** CAPI3REF: Determine If An SQL Statement Writes The Database -@@ -3776,8 +3920,9 @@ - ** implementation of [application-defined SQL functions] are protected. - ** ^The sqlite3_value object returned by - ** [sqlite3_column_value()] is unprotected. --** Unprotected sqlite3_value objects may only be used with --** [sqlite3_result_value()] and [sqlite3_bind_value()]. -+** Unprotected sqlite3_value objects may only be used as arguments -+** to [sqlite3_result_value()], [sqlite3_bind_value()], and -+** [sqlite3_value_dup()]. - ** The [sqlite3_value_blob | sqlite3_value_type()] family of - ** interfaces require protected sqlite3_value objects. - */ -@@ -4199,7 +4344,7 @@ - ** other than [SQLITE_ROW] before any subsequent invocation of - ** sqlite3_step(). Failure to reset the prepared statement using - ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from --** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1]), -+** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1], - ** sqlite3_step() began - ** calling [sqlite3_reset()] automatically in this circumstance rather - ** than returning [SQLITE_MISUSE]. This is not considered a compatibility -@@ -4464,11 +4609,25 @@ - ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into - ** [sqlite3_free()]. - ** --** ^(If a memory allocation error occurs during the evaluation of any --** of these routines, a default value is returned. The default value --** is either the integer 0, the floating point number 0.0, or a NULL --** pointer. Subsequent calls to [sqlite3_errcode()] will return --** [SQLITE_NOMEM].)^ -+** As long as the input parameters are correct, these routines will only -+** fail if an out-of-memory error occurs during a format conversion. -+** Only the following subset of interfaces are subject to out-of-memory -+** errors: -+** -+** <ul> -+** <li> sqlite3_column_blob() -+** <li> sqlite3_column_text() -+** <li> sqlite3_column_text16() -+** <li> sqlite3_column_bytes() -+** <li> sqlite3_column_bytes16() -+** </ul> -+** -+** If an out-of-memory error occurs, then the return value from these -+** routines is the same as if the column had contained an SQL NULL value. -+** Valid SQL NULL returns can be distinguished from out-of-memory errors -+** by invoking the [sqlite3_errcode()] immediately after the suspect -+** return value is obtained and before any -+** other SQLite interface is called on the same [database connection]. - */ - SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); - SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); -@@ -4545,11 +4704,13 @@ - ** - ** ^These functions (collectively known as "function creation routines") - ** are used to add SQL functions or aggregates or to redefine the behavior --** of existing SQL functions or aggregates. The only differences between --** these routines are the text encoding expected for --** the second parameter (the name of the function being created) --** and the presence or absence of a destructor callback for --** the application data pointer. -+** of existing SQL functions or aggregates. The only differences between -+** the three "sqlite3_create_function*" routines are the text encoding -+** expected for the second parameter (the name of the function being -+** created) and the presence or absence of a destructor callback for -+** the application data pointer. Function sqlite3_create_window_function() -+** is similar, but allows the user to supply the extra callback functions -+** needed by [aggregate window functions]. - ** - ** ^The first parameter is the [database connection] to which the SQL - ** function is to be added. ^If an application uses more than one database -@@ -4595,7 +4756,8 @@ - ** ^(The fifth parameter is an arbitrary pointer. The implementation of the - ** function can gain access to this pointer using [sqlite3_user_data()].)^ - ** --** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are -+** ^The sixth, seventh and eighth parameters passed to the three -+** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are - ** pointers to C-language functions that implement the SQL function or - ** aggregate. ^A scalar SQL function requires an implementation of the xFunc - ** callback only; NULL pointers must be passed as the xStep and xFinal -@@ -4604,16 +4766,25 @@ - ** SQL function or aggregate, pass NULL pointers for all three function - ** callbacks. - ** --** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL, --** then it is destructor for the application data pointer. --** The destructor is invoked when the function is deleted, either by being --** overloaded or when the database connection closes.)^ --** ^The destructor is also invoked if the call to --** sqlite3_create_function_v2() fails. --** ^When the destructor callback of the tenth parameter is invoked, it --** is passed a single argument which is a copy of the application data --** pointer which was the fifth parameter to sqlite3_create_function_v2(). -+** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue -+** and xInverse) passed to sqlite3_create_window_function are pointers to -+** C-language callbacks that implement the new function. xStep and xFinal -+** must both be non-NULL. xValue and xInverse may either both be NULL, in -+** which case a regular aggregate function is created, or must both be -+** non-NULL, in which case the new function may be used as either an aggregate -+** or aggregate window function. More details regarding the implementation -+** of aggregate window functions are -+** [user-defined window functions|available here]. - ** -+** ^(If the final parameter to sqlite3_create_function_v2() or -+** sqlite3_create_window_function() is not NULL, then it is destructor for -+** the application data pointer. The destructor is invoked when the function -+** is deleted, either by being overloaded or when the database connection -+** closes.)^ ^The destructor is also invoked if the call to -+** sqlite3_create_function_v2() fails. ^When the destructor callback is -+** invoked, it is passed a single argument which is a copy of the application -+** data pointer which was the fifth parameter to sqlite3_create_function_v2(). -+** - ** ^It is permitted to register multiple implementations of the same - ** functions with the same name but with either differing numbers of - ** arguments or differing preferred text encodings. ^SQLite will use -@@ -4665,6 +4836,18 @@ - void (*xFinal)(sqlite3_context*), - void(*xDestroy)(void*) - ); -+SQLITE_API int sqlite3_create_window_function( -+ sqlite3 *db, -+ const char *zFunctionName, -+ int nArg, -+ int eTextRep, -+ void *pApp, -+ void (*xStep)(sqlite3_context*,int,sqlite3_value**), -+ void (*xFinal)(sqlite3_context*), -+ void (*xValue)(sqlite3_context*), -+ void (*xInverse)(sqlite3_context*,int,sqlite3_value**), -+ void(*xDestroy)(void*) -+); - - /* - ** CAPI3REF: Text Encodings -@@ -4735,6 +4918,9 @@ - ** datatype of the value - ** <tr><td><b>sqlite3_value_numeric_type </b> - ** <td>→ <td>Best numeric datatype of the value -+** <tr><td><b>sqlite3_value_nochange </b> -+** <td>→ <td>True if the column is unchanged in an UPDATE -+** against a virtual table. - ** </table></blockquote> - ** - ** <b>Details:</b> -@@ -4783,6 +4969,19 @@ - ** then the conversion is performed. Otherwise no conversion occurs. - ** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ - ** -+** ^Within the [xUpdate] method of a [virtual table], the -+** sqlite3_value_nochange(X) interface returns true if and only if -+** the column corresponding to X is unchanged by the UPDATE operation -+** that the xUpdate method call was invoked to implement and if -+** and the prior [xColumn] method call that was invoked to extracted -+** the value for that column returned without setting a result (probably -+** because it queried [sqlite3_vtab_nochange()] and found that the column -+** was unchanging). ^Within an [xUpdate] method, any value for which -+** sqlite3_value_nochange(X) is true will in all other respects appear -+** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other -+** than within an [xUpdate] method call for an UPDATE statement, then -+** the return value is arbitrary and meaningless. -+** - ** Please pay particular attention to the fact that the pointer returned - ** from [sqlite3_value_blob()], [sqlite3_value_text()], or - ** [sqlite3_value_text16()] can be invalidated by a subsequent call to -@@ -4791,6 +4990,28 @@ - ** - ** These routines must be called from the same thread as - ** the SQL function that supplied the [sqlite3_value*] parameters. -+** -+** As long as the input parameter is correct, these routines can only -+** fail if an out-of-memory error occurs during a format conversion. -+** Only the following subset of interfaces are subject to out-of-memory -+** errors: -+** -+** <ul> -+** <li> sqlite3_value_blob() -+** <li> sqlite3_value_text() -+** <li> sqlite3_value_text16() -+** <li> sqlite3_value_text16le() -+** <li> sqlite3_value_text16be() -+** <li> sqlite3_value_bytes() -+** <li> sqlite3_value_bytes16() -+** </ul> -+** -+** If an out-of-memory error occurs, then the return value from these -+** routines is the same as if the column had contained an SQL NULL value. -+** Valid SQL NULL returns can be distinguished from out-of-memory errors -+** by invoking the [sqlite3_errcode()] immediately after the suspect -+** return value is obtained and before any -+** other SQLite interface is called on the same [database connection]. - */ - SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); - SQLITE_API double sqlite3_value_double(sqlite3_value*); -@@ -4805,6 +5026,7 @@ - SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); - SQLITE_API int sqlite3_value_type(sqlite3_value*); - SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); -+SQLITE_API int sqlite3_value_nochange(sqlite3_value*); - - /* - ** CAPI3REF: Finding The Subtype Of SQL Values -@@ -5461,6 +5683,41 @@ - SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory; - - /* -+** CAPI3REF: Win32 Specific Interface -+** -+** These interfaces are available only on Windows. The -+** [sqlite3_win32_set_directory] interface is used to set the value associated -+** with the [sqlite3_temp_directory] or [sqlite3_data_directory] variable, to -+** zValue, depending on the value of the type parameter. The zValue parameter -+** should be NULL to cause the previous value to be freed via [sqlite3_free]; -+** a non-NULL value will be copied into memory obtained from [sqlite3_malloc] -+** prior to being used. The [sqlite3_win32_set_directory] interface returns -+** [SQLITE_OK] to indicate success, [SQLITE_ERROR] if the type is unsupported, -+** or [SQLITE_NOMEM] if memory could not be allocated. The value of the -+** [sqlite3_data_directory] variable is intended to act as a replacement for -+** the current directory on the sub-platforms of Win32 where that concept is -+** not present, e.g. WinRT and UWP. The [sqlite3_win32_set_directory8] and -+** [sqlite3_win32_set_directory16] interfaces behave exactly the same as the -+** sqlite3_win32_set_directory interface except the string parameter must be -+** UTF-8 or UTF-16, respectively. -+*/ -+SQLITE_API int sqlite3_win32_set_directory( -+ unsigned long type, /* Identifier for directory being set or reset */ -+ void *zValue /* New value for directory being set or reset */ -+); -+SQLITE_API int sqlite3_win32_set_directory8(unsigned long type, const char *zValue); -+SQLITE_API int sqlite3_win32_set_directory16(unsigned long type, const void *zValue); -+ -+/* -+** CAPI3REF: Win32 Directory Types -+** -+** These macros are only available on Windows. They define the allowed values -+** for the type argument to the [sqlite3_win32_set_directory] interface. -+*/ -+#define SQLITE_WIN32_DATA_DIRECTORY_TYPE 1 -+#define SQLITE_WIN32_TEMP_DIRECTORY_TYPE 2 -+ -+/* - ** CAPI3REF: Test For Auto-Commit Mode - ** KEYWORDS: {autocommit mode} - ** METHOD: sqlite3 -@@ -6060,6 +6317,9 @@ - int (*xSavepoint)(sqlite3_vtab *pVTab, int); - int (*xRelease)(sqlite3_vtab *pVTab, int); - int (*xRollbackTo)(sqlite3_vtab *pVTab, int); -+ /* The methods above are in versions 1 and 2 of the sqlite_module object. -+ ** Those below are for version 3 and greater. */ -+ int (*xShadowName)(const char*); - }; - - /* -@@ -6192,6 +6452,10 @@ - - /* - ** CAPI3REF: Virtual Table Scan Flags -+** -+** Virtual table implementations are allowed to set the -+** [sqlite3_index_info].idxFlags field to some combination of -+** these bits. - */ - #define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */ - -@@ -6203,15 +6467,21 @@ - ** an operator that is part of a constraint term in the wHERE clause of - ** a query that uses a [virtual table]. - */ --#define SQLITE_INDEX_CONSTRAINT_EQ 2 --#define SQLITE_INDEX_CONSTRAINT_GT 4 --#define SQLITE_INDEX_CONSTRAINT_LE 8 --#define SQLITE_INDEX_CONSTRAINT_LT 16 --#define SQLITE_INDEX_CONSTRAINT_GE 32 --#define SQLITE_INDEX_CONSTRAINT_MATCH 64 --#define SQLITE_INDEX_CONSTRAINT_LIKE 65 --#define SQLITE_INDEX_CONSTRAINT_GLOB 66 --#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 -+#define SQLITE_INDEX_CONSTRAINT_EQ 2 -+#define SQLITE_INDEX_CONSTRAINT_GT 4 -+#define SQLITE_INDEX_CONSTRAINT_LE 8 -+#define SQLITE_INDEX_CONSTRAINT_LT 16 -+#define SQLITE_INDEX_CONSTRAINT_GE 32 -+#define SQLITE_INDEX_CONSTRAINT_MATCH 64 -+#define SQLITE_INDEX_CONSTRAINT_LIKE 65 -+#define SQLITE_INDEX_CONSTRAINT_GLOB 66 -+#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 -+#define SQLITE_INDEX_CONSTRAINT_NE 68 -+#define SQLITE_INDEX_CONSTRAINT_ISNOT 69 -+#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 -+#define SQLITE_INDEX_CONSTRAINT_ISNULL 71 -+#define SQLITE_INDEX_CONSTRAINT_IS 72 -+#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 - - /* - ** CAPI3REF: Register A Virtual Table Implementation -@@ -6888,6 +7158,7 @@ - /* - ** CAPI3REF: Low-Level Control Of Database Files - ** METHOD: sqlite3 -+** KEYWORDS: {file control} - ** - ** ^The [sqlite3_file_control()] interface makes a direct call to the - ** xFileControl method for the [sqlite3_io_methods] object associated -@@ -6902,11 +7173,18 @@ - ** the xFileControl method. ^The return value of the xFileControl - ** method becomes the return value of this routine. - ** --** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes -+** A few opcodes for [sqlite3_file_control()] are handled directly -+** by the SQLite core and never invoke the -+** sqlite3_io_methods.xFileControl method. -+** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes - ** a pointer to the underlying [sqlite3_file] object to be written into --** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER --** case is a short-circuit path which does not actually invoke the --** underlying sqlite3_io_methods.xFileControl method. -+** the space pointed to by the 4th parameter. The -+** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns -+** the [sqlite3_file] object associated with the journal file instead of -+** the main database. The [SQLITE_FCNTL_VFS_POINTER] opcode returns -+** a pointer to the underlying [sqlite3_vfs] object for the file. -+** The [SQLITE_FCNTL_DATA_VERSION] returns the data version counter -+** from the pager. - ** - ** ^If the second parameter (zDbName) does not match the name of any - ** open database file, then SQLITE_ERROR is returned. ^This error -@@ -6916,7 +7194,7 @@ - ** an incorrect zDbName and an SQLITE_ERROR return from the underlying - ** xFileControl method. - ** --** See also: [SQLITE_FCNTL_LOCKSTATE] -+** See also: [file control opcodes] - */ - SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); - -@@ -6962,8 +7240,9 @@ - #define SQLITE_TESTCTRL_ALWAYS 13 - #define SQLITE_TESTCTRL_RESERVE 14 - #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 --#define SQLITE_TESTCTRL_ISKEYWORD 16 --#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 -+#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ -+#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ -+#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 - #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 - #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ - #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19 -@@ -6973,9 +7252,193 @@ - #define SQLITE_TESTCTRL_ISINIT 23 - #define SQLITE_TESTCTRL_SORTER_MMAP 24 - #define SQLITE_TESTCTRL_IMPOSTER 25 --#define SQLITE_TESTCTRL_LAST 25 -+#define SQLITE_TESTCTRL_PARSER_COVERAGE 26 -+#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */ - - /* -+** CAPI3REF: SQL Keyword Checking -+** -+** These routines provide access to the set of SQL language keywords -+** recognized by SQLite. Applications can uses these routines to determine -+** whether or not a specific identifier needs to be escaped (for example, -+** by enclosing in double-quotes) so as not to confuse the parser. -+** -+** The sqlite3_keyword_count() interface returns the number of distinct -+** keywords understood by SQLite. -+** -+** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and -+** makes *Z point to that keyword expressed as UTF8 and writes the number -+** of bytes in the keyword into *L. The string that *Z points to is not -+** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns -+** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z -+** or L are NULL or invalid pointers then calls to -+** sqlite3_keyword_name(N,Z,L) result in undefined behavior. -+** -+** The sqlite3_keyword_check(Z,L) interface checks to see whether or not -+** the L-byte UTF8 identifier that Z points to is a keyword, returning non-zero -+** if it is and zero if not. -+** -+** The parser used by SQLite is forgiving. It is often possible to use -+** a keyword as an identifier as long as such use does not result in a -+** parsing ambiguity. For example, the statement -+** "CREATE TABLE BEGIN(REPLACE,PRAGMA,END);" is accepted by SQLite, and -+** creates a new table named "BEGIN" with three columns named -+** "REPLACE", "PRAGMA", and "END". Nevertheless, best practice is to avoid -+** using keywords as identifiers. Common techniques used to avoid keyword -+** name collisions include: -+** <ul> -+** <li> Put all identifier names inside double-quotes. This is the official -+** SQL way to escape identifier names. -+** <li> Put identifier names inside [...]. This is not standard SQL, -+** but it is what SQL Server does and so lots of programmers use this -+** technique. -+** <li> Begin every identifier with the letter "Z" as no SQL keywords start -+** with "Z". -+** <li> Include a digit somewhere in every identifier name. -+** </ul> -+** -+** Note that the number of keywords understood by SQLite can depend on -+** compile-time options. For example, "VACUUM" is not a keyword if -+** SQLite is compiled with the [-DSQLITE_OMIT_VACUUM] option. Also, -+** new keywords may be added to future releases of SQLite. -+*/ -+SQLITE_API int sqlite3_keyword_count(void); -+SQLITE_API int sqlite3_keyword_name(int,const char**,int*); -+SQLITE_API int sqlite3_keyword_check(const char*,int); -+ -+/* -+** CAPI3REF: Dynamic String Object -+** KEYWORDS: {dynamic string} -+** -+** An instance of the sqlite3_str object contains a dynamically-sized -+** string under construction. -+** -+** The lifecycle of an sqlite3_str object is as follows: -+** <ol> -+** <li> ^The sqlite3_str object is created using [sqlite3_str_new()]. -+** <li> ^Text is appended to the sqlite3_str object using various -+** methods, such as [sqlite3_str_appendf()]. -+** <li> ^The sqlite3_str object is destroyed and the string it created -+** is returned using the [sqlite3_str_finish()] interface. -+** </ol> -+*/ -+typedef struct sqlite3_str sqlite3_str; -+ -+/* -+** CAPI3REF: Create A New Dynamic String Object -+** CONSTRUCTOR: sqlite3_str -+** -+** ^The [sqlite3_str_new(D)] interface allocates and initializes -+** a new [sqlite3_str] object. To avoid memory leaks, the object returned by -+** [sqlite3_str_new()] must be freed by a subsequent call to -+** [sqlite3_str_finish(X)]. -+** -+** ^The [sqlite3_str_new(D)] interface always returns a pointer to a -+** valid [sqlite3_str] object, though in the event of an out-of-memory -+** error the returned object might be a special singleton that will -+** silently reject new text, always return SQLITE_NOMEM from -+** [sqlite3_str_errcode()], always return 0 for -+** [sqlite3_str_length()], and always return NULL from -+** [sqlite3_str_finish(X)]. It is always safe to use the value -+** returned by [sqlite3_str_new(D)] as the sqlite3_str parameter -+** to any of the other [sqlite3_str] methods. -+** -+** The D parameter to [sqlite3_str_new(D)] may be NULL. If the -+** D parameter in [sqlite3_str_new(D)] is not NULL, then the maximum -+** length of the string contained in the [sqlite3_str] object will be -+** the value set for [sqlite3_limit](D,[SQLITE_LIMIT_LENGTH]) instead -+** of [SQLITE_MAX_LENGTH]. -+*/ -+SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*); -+ -+/* -+** CAPI3REF: Finalize A Dynamic String -+** DESTRUCTOR: sqlite3_str -+** -+** ^The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X -+** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()] -+** that contains the constructed string. The calling application should -+** pass the returned value to [sqlite3_free()] to avoid a memory leak. -+** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any -+** errors were encountered during construction of the string. ^The -+** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the -+** string in [sqlite3_str] object X is zero bytes long. -+*/ -+SQLITE_API char *sqlite3_str_finish(sqlite3_str*); -+ -+/* -+** CAPI3REF: Add Content To A Dynamic String -+** METHOD: sqlite3_str -+** -+** These interfaces add content to an sqlite3_str object previously obtained -+** from [sqlite3_str_new()]. -+** -+** ^The [sqlite3_str_appendf(X,F,...)] and -+** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf] -+** functionality of SQLite to append formatted text onto the end of -+** [sqlite3_str] object X. -+** -+** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S -+** onto the end of the [sqlite3_str] object X. N must be non-negative. -+** S must contain at least N non-zero bytes of content. To append a -+** zero-terminated string in its entirety, use the [sqlite3_str_appendall()] -+** method instead. -+** -+** ^The [sqlite3_str_appendall(X,S)] method appends the complete content of -+** zero-terminated string S onto the end of [sqlite3_str] object X. -+** -+** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the -+** single-byte character C onto the end of [sqlite3_str] object X. -+** ^This method can be used, for example, to add whitespace indentation. -+** -+** ^The [sqlite3_str_reset(X)] method resets the string under construction -+** inside [sqlite3_str] object X back to zero bytes in length. -+** -+** These methods do not return a result code. ^If an error occurs, that fact -+** is recorded in the [sqlite3_str] object and can be recovered by a -+** subsequent call to [sqlite3_str_errcode(X)]. -+*/ -+SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...); -+SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list); -+SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N); -+SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn); -+SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C); -+SQLITE_API void sqlite3_str_reset(sqlite3_str*); -+ -+/* -+** CAPI3REF: Status Of A Dynamic String -+** METHOD: sqlite3_str -+** -+** These interfaces return the current status of an [sqlite3_str] object. -+** -+** ^If any prior errors have occurred while constructing the dynamic string -+** in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return -+** an appropriate error code. ^The [sqlite3_str_errcode(X)] method returns -+** [SQLITE_NOMEM] following any out-of-memory error, or -+** [SQLITE_TOOBIG] if the size of the dynamic string exceeds -+** [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors. -+** -+** ^The [sqlite3_str_length(X)] method returns the current length, in bytes, -+** of the dynamic string under construction in [sqlite3_str] object X. -+** ^The length returned by [sqlite3_str_length(X)] does not include the -+** zero-termination byte. -+** -+** ^The [sqlite3_str_value(X)] method returns a pointer to the current -+** content of the dynamic string under construction in X. The value -+** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X -+** and might be freed or altered by any subsequent method on the same -+** [sqlite3_str] object. Applications must not used the pointer returned -+** [sqlite3_str_value(X)] after any subsequent method call on the same -+** object. ^Applications may change the content of the string returned -+** by [sqlite3_str_value(X)] as long as they do not write into any bytes -+** outside the range of 0 to [sqlite3_str_length(X)] and do not read or -+** write any byte after any subsequent sqlite3_str method call. -+*/ -+SQLITE_API int sqlite3_str_errcode(sqlite3_str*); -+SQLITE_API int sqlite3_str_length(sqlite3_str*); -+SQLITE_API char *sqlite3_str_value(sqlite3_str*); -+ -+/* - ** CAPI3REF: SQLite Runtime Status - ** - ** ^These interfaces are used to retrieve runtime status information -@@ -7022,8 +7485,7 @@ - ** <dd>This parameter is the current amount of memory checked out - ** using [sqlite3_malloc()], either directly or indirectly. The - ** figure includes calls made to [sqlite3_malloc()] by the application --** and internal memory usage by the SQLite library. Scratch memory --** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache -+** and internal memory usage by the SQLite library. Auxiliary page-cache - ** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in - ** this parameter. The amount returned is the sum of the allocation - ** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>)^ -@@ -7061,29 +7523,14 @@ - ** *pHighwater parameter to [sqlite3_status()] is of interest. - ** The value written into the *pCurrent parameter is undefined.</dd>)^ - ** --** [[SQLITE_STATUS_SCRATCH_USED]] ^(<dt>SQLITE_STATUS_SCRATCH_USED</dt> --** <dd>This parameter returns the number of allocations used out of the --** [scratch memory allocator] configured using --** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not --** in bytes. Since a single thread may only have one scratch allocation --** outstanding at time, this parameter also reports the number of threads --** using scratch memory at the same time.</dd>)^ -+** [[SQLITE_STATUS_SCRATCH_USED]] <dt>SQLITE_STATUS_SCRATCH_USED</dt> -+** <dd>No longer used.</dd> - ** - ** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt> --** <dd>This parameter returns the number of bytes of scratch memory --** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH] --** buffer and where forced to overflow to [sqlite3_malloc()]. The values --** returned include overflows because the requested allocation was too --** larger (that is, because the requested allocation was larger than the --** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer --** slots were available. --** </dd>)^ -+** <dd>No longer used.</dd> - ** --** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt> --** <dd>This parameter records the largest memory allocation request --** handed to [scratch 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.</dd>)^ -+** [[SQLITE_STATUS_SCRATCH_SIZE]] <dt>SQLITE_STATUS_SCRATCH_SIZE</dt> -+** <dd>No longer used.</dd> - ** - ** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt> - ** <dd>The *pHighwater parameter records the deepest parser stack. -@@ -7096,12 +7543,12 @@ - #define SQLITE_STATUS_MEMORY_USED 0 - #define SQLITE_STATUS_PAGECACHE_USED 1 - #define SQLITE_STATUS_PAGECACHE_OVERFLOW 2 --#define SQLITE_STATUS_SCRATCH_USED 3 --#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 -+#define SQLITE_STATUS_SCRATCH_USED 3 /* NOT USED */ -+#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 /* NOT USED */ - #define SQLITE_STATUS_MALLOC_SIZE 5 - #define SQLITE_STATUS_PARSER_STACK 6 - #define SQLITE_STATUS_PAGECACHE_SIZE 7 --#define SQLITE_STATUS_SCRATCH_SIZE 8 -+#define SQLITE_STATUS_SCRATCH_SIZE 8 /* NOT USED */ - #define SQLITE_STATUS_MALLOC_COUNT 9 - - /* -@@ -7224,6 +7671,15 @@ - ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. - ** </dd> - ** -+** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt> -+** <dd>This parameter returns the number of dirty cache entries that have -+** been written to disk in the middle of a transaction due to the page -+** 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. -+** </dd> -+** - ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt> - ** <dd>This parameter returns zero for the current value if and only if - ** all foreign key constraints (deferred or immediate) have been -@@ -7243,7 +7699,8 @@ - #define SQLITE_DBSTATUS_CACHE_WRITE 9 - #define SQLITE_DBSTATUS_DEFERRED_FKS 10 - #define SQLITE_DBSTATUS_CACHE_USED_SHARED 11 --#define SQLITE_DBSTATUS_MAX 11 /* Largest defined DBSTATUS */ -+#define SQLITE_DBSTATUS_CACHE_SPILL 12 -+#define SQLITE_DBSTATUS_MAX 12 /* Largest defined DBSTATUS */ - - - /* -@@ -8198,6 +8655,7 @@ - ** can use to customize and optimize their behavior. - ** - ** <dl> -+** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]] - ** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT - ** <dd>Calls of the form - ** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, -@@ -8244,6 +8702,40 @@ - SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); - - /* -+** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE -+** -+** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn] -+** method of a [virtual table], then it returns true if and only if the -+** column is being fetched as part of an UPDATE operation during which the -+** column value will not change. Applications might use this to substitute -+** a return value that is less expensive to compute and that the corresponding -+** [xUpdate] method understands as a "no-change" value. -+** -+** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that -+** the column is not changed by the UPDATE statement, then the xColumn -+** method can optionally return without setting a result, without calling -+** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces]. -+** In that case, [sqlite3_value_nochange(X)] will return true for the -+** same column in the [xUpdate] method. -+*/ -+SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*); -+ -+/* -+** CAPI3REF: Determine The Collation For a Virtual Table Constraint -+** -+** This function may only be called from within a call to the [xBestIndex] -+** method of a [virtual table]. -+** -+** The first argument must be the sqlite3_index_info object that is the -+** first parameter to the xBestIndex() method. The second argument must be -+** an index into the aConstraint[] array belonging to the sqlite3_index_info -+** structure passed to xBestIndex. This function returns a pointer to a buffer -+** containing the name of the collation sequence for the corresponding -+** constraint. -+*/ -+SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); -+ -+/* - ** CAPI3REF: Conflict resolution modes - ** KEYWORDS: {conflict resolution mode} - ** -@@ -8513,7 +9005,6 @@ - /* - ** CAPI3REF: Database Snapshot - ** KEYWORDS: {snapshot} {sqlite3_snapshot} --** EXPERIMENTAL - ** - ** An instance of the snapshot object records the state of a [WAL mode] - ** database for some specific point in history. -@@ -8530,11 +9021,6 @@ - ** version of the database file so that it is possible to later open a new read - ** transaction that sees that historical version of the database rather than - ** the most recent version. --** --** The constructor for this object is [sqlite3_snapshot_get()]. The --** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer --** to an historical snapshot (if possible). The destructor for --** sqlite3_snapshot objects is [sqlite3_snapshot_free()]. - */ - typedef struct sqlite3_snapshot { - unsigned char hidden[48]; -@@ -8542,7 +9028,7 @@ - - /* - ** CAPI3REF: Record A Database Snapshot --** EXPERIMENTAL -+** CONSTRUCTOR: sqlite3_snapshot - ** - ** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a - ** new [sqlite3_snapshot] object that records the current state of -@@ -8558,7 +9044,7 @@ - ** in this case. - ** - ** <ul> --** <li> The database handle must be in [autocommit mode]. -+** <li> The database handle must not be in [autocommit mode]. - ** - ** <li> Schema S of [database connection] D must be a [WAL mode] database. - ** -@@ -8581,7 +9067,7 @@ - ** to avoid a memory leak. - ** - ** The [sqlite3_snapshot_get()] interface is only available when the --** SQLITE_ENABLE_SNAPSHOT compile-time option is used. -+** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. - */ - SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( - sqlite3 *db, -@@ -8591,24 +9077,35 @@ - - /* - ** CAPI3REF: Start a read transaction on an historical snapshot --** EXPERIMENTAL -+** METHOD: sqlite3_snapshot - ** --** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a --** read transaction for schema S of --** [database connection] D such that the read transaction --** refers to historical [snapshot] P, rather than the most --** recent change to the database. --** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success --** or an appropriate [error code] if it fails. -+** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read -+** transaction or upgrades an existing one for schema S of -+** [database connection] D such that the read transaction refers to -+** historical [snapshot] P, rather than the most recent change to the -+** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK -+** on success or an appropriate [error code] if it fails. - ** --** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be --** the first operation following the [BEGIN] that takes the schema S --** out of [autocommit mode]. --** ^In other words, schema S must not currently be in --** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the --** database connection D must be out of [autocommit mode]. --** ^A [snapshot] will fail to open if it has been overwritten by a --** [checkpoint]. -+** ^In order to succeed, the database connection must not be in -+** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there -+** is already a read transaction open on schema S, then the database handle -+** must have no active statements (SELECT statements that have been passed -+** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). -+** SQLITE_ERROR is returned if either of these conditions is violated, or -+** if schema S does not exist, or if the snapshot object is invalid. -+** -+** ^A call to sqlite3_snapshot_open() will fail to open if the specified -+** snapshot has been overwritten by a [checkpoint]. In this case -+** SQLITE_ERROR_SNAPSHOT is returned. -+** -+** If there is already a read transaction open when this function is -+** invoked, then the same read transaction remains open (on the same -+** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT -+** is returned. If another error code - for example SQLITE_PROTOCOL or an -+** SQLITE_IOERR error code - is returned, then the final state of the -+** read transaction is undefined. If SQLITE_OK is returned, then the -+** read transaction is now open on database snapshot P. -+** - ** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the - ** database connection D does not know that the database file for - ** schema S is in [WAL mode]. A database connection might not know -@@ -8619,7 +9116,7 @@ - ** database connection in order to make it ready to use snapshots.) - ** - ** The [sqlite3_snapshot_open()] interface is only available when the --** SQLITE_ENABLE_SNAPSHOT compile-time option is used. -+** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. - */ - SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open( - sqlite3 *db, -@@ -8629,7 +9126,7 @@ - - /* - ** CAPI3REF: Destroy a snapshot --** EXPERIMENTAL -+** DESTRUCTOR: sqlite3_snapshot - ** - ** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P. - ** The application must eventually free every [sqlite3_snapshot] object -@@ -8636,13 +9133,13 @@ - ** using this routine to avoid a memory leak. - ** - ** The [sqlite3_snapshot_free()] interface is only available when the --** SQLITE_ENABLE_SNAPSHOT compile-time option is used. -+** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. - */ - SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); - - /* - ** CAPI3REF: Compare the ages of two snapshot handles. --** EXPERIMENTAL -+** METHOD: sqlite3_snapshot - ** - ** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages - ** of two valid snapshot handles. -@@ -8661,6 +9158,9 @@ - ** Otherwise, this API returns a negative value if P1 refers to an older - ** snapshot than P2, zero if the two handles refer to the same database - ** snapshot, and a positive value if P1 is a newer snapshot than P2. -+** -+** This interface is only available if SQLite is compiled with the -+** [SQLITE_ENABLE_SNAPSHOT] option. - */ - SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( - sqlite3_snapshot *p1, -@@ -8669,27 +9169,152 @@ - - /* - ** CAPI3REF: Recover snapshots from a wal file --** EXPERIMENTAL -+** METHOD: sqlite3_snapshot - ** --** If all connections disconnect from a database file but do not perform --** a checkpoint, the existing wal file is opened along with the database --** file the next time the database is opened. At this point it is only --** possible to successfully call sqlite3_snapshot_open() to open the most --** recent snapshot of the database (the one at the head of the wal file), --** even though the wal file may contain other valid snapshots for which --** clients have sqlite3_snapshot handles. -+** If a [WAL file] remains on disk after all database connections close -+** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control] -+** or because the last process to have the database opened exited without -+** calling [sqlite3_close()]) and a new connection is subsequently opened -+** on that database and [WAL file], the [sqlite3_snapshot_open()] interface -+** will only be able to open the last transaction added to the WAL file -+** even though the WAL file contains other valid transactions. - ** --** This function attempts to scan the wal file associated with database zDb -+** This function attempts to scan the WAL file associated with database zDb - ** of database handle db and make all valid snapshots available to - ** sqlite3_snapshot_open(). It is an error if there is already a read --** transaction open on the database, or if the database is not a wal mode -+** transaction open on the database, or if the database is not a WAL mode - ** database. - ** - ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. -+** -+** This interface is only available if SQLite is compiled with the -+** [SQLITE_ENABLE_SNAPSHOT] option. - */ - SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); - - /* -+** CAPI3REF: Serialize a database -+** -+** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory -+** that is a serialization of the S database on [database connection] D. -+** If P is not a NULL pointer, then the size of the database in bytes -+** is written into *P. -+** -+** For an ordinary on-disk database file, the serialization is just a -+** copy of the disk file. For an in-memory database or a "TEMP" database, -+** the serialization is the same sequence of bytes which would be written -+** to disk if that database where backed up to disk. -+** -+** The usual case is that sqlite3_serialize() copies the serialization of -+** the database into memory obtained from [sqlite3_malloc64()] and returns -+** a pointer to that memory. The caller is responsible for freeing the -+** returned value to avoid a memory leak. However, if the F argument -+** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations -+** are made, and the sqlite3_serialize() function will return a pointer -+** to the contiguous memory representation of the database that SQLite -+** is currently using for that database, or NULL if the no such contiguous -+** memory representation of the database exists. A contiguous memory -+** representation of the database will usually only exist if there has -+** been a prior call to [sqlite3_deserialize(D,S,...)] with the same -+** values of D and S. -+** The size of the database is written into *P even if the -+** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy -+** of the database exists. -+** -+** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the -+** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory -+** allocation error occurs. -+** -+** This interface is only available if SQLite is compiled with the -+** [SQLITE_ENABLE_DESERIALIZE] option. -+*/ -+SQLITE_API unsigned char *sqlite3_serialize( -+ sqlite3 *db, /* The database connection */ -+ const char *zSchema, /* Which DB to serialize. ex: "main", "temp", ... */ -+ sqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */ -+ unsigned int mFlags /* Zero or more SQLITE_SERIALIZE_* flags */ -+); -+ -+/* -+** CAPI3REF: Flags for sqlite3_serialize -+** -+** Zero or more of the following constants can be OR-ed together for -+** the F argument to [sqlite3_serialize(D,S,P,F)]. -+** -+** SQLITE_SERIALIZE_NOCOPY means that [sqlite3_serialize()] will return -+** a pointer to contiguous in-memory database that it is currently using, -+** without making a copy of the database. If SQLite is not currently using -+** a contiguous in-memory database, then this option causes -+** [sqlite3_serialize()] to return a NULL pointer. SQLite will only be -+** using a contiguous in-memory database if it has been initialized by a -+** prior call to [sqlite3_deserialize()]. -+*/ -+#define SQLITE_SERIALIZE_NOCOPY 0x001 /* Do no memory allocations */ -+ -+/* -+** CAPI3REF: Deserialize a database -+** -+** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the -+** [database connection] D to disconnect from database S and then -+** reopen S as an in-memory database based on the serialization contained -+** in P. The serialized database P is N bytes in size. M is the size of -+** the buffer P, which might be larger than N. If M is larger than N, and -+** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is -+** permitted to add content to the in-memory database as long as the total -+** size does not exceed M bytes. -+** -+** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will -+** invoke sqlite3_free() on the serialization buffer when the database -+** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then -+** SQLite will try to increase the buffer size using sqlite3_realloc64() -+** if writes on the database cause it to grow larger than M bytes. -+** -+** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the -+** database is currently in a read transaction or is involved in a backup -+** operation. -+** -+** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the -+** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then -+** [sqlite3_free()] is invoked on argument P prior to returning. -+** -+** This interface is only available if SQLite is compiled with the -+** [SQLITE_ENABLE_DESERIALIZE] option. -+*/ -+SQLITE_API int sqlite3_deserialize( -+ sqlite3 *db, /* The database connection */ -+ const char *zSchema, /* Which DB to reopen with the deserialization */ -+ unsigned char *pData, /* The serialized database content */ -+ sqlite3_int64 szDb, /* Number bytes in the deserialization */ -+ sqlite3_int64 szBuf, /* Total size of buffer pData[] */ -+ unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */ -+); -+ -+/* -+** CAPI3REF: Flags for sqlite3_deserialize() -+** -+** The following are allowed values for 6th argument (the F argument) to -+** the [sqlite3_deserialize(D,S,P,N,M,F)] interface. -+** -+** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization -+** in the P argument is held in memory obtained from [sqlite3_malloc64()] -+** and that SQLite should take ownership of this memory and automatically -+** free it when it has finished using it. Without this flag, the caller -+** is responsible for freeing any dynamically allocated memory. -+** -+** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to -+** grow the size of the database using calls to [sqlite3_realloc64()]. This -+** flag should only be used if SQLITE_DESERIALIZE_FREEONCLOSE is also used. -+** Without this flag, the deserialized database cannot increase in size beyond -+** the number of bytes specified by the M parameter. -+** -+** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database -+** should be treated as read-only. -+*/ -+#define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */ -+#define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */ -+#define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */ -+ -+/* - ** Undo the hack that converts floating point types to integer for - ** builds on processors without floating point support. - */ -@@ -8800,7 +9425,7 @@ - sqlite3_int64 iRowid; /* Rowid for current entry */ - sqlite3_rtree_dbl rParentScore; /* Score of parent node */ - int eParentWithin; /* Visibility of parent node */ -- int eWithin; /* OUT: Visiblity */ -+ int eWithin; /* OUT: Visibility */ - sqlite3_rtree_dbl rScore; /* OUT: Write the score here */ - /* The following fields are only available in 3.8.11 and later */ - sqlite3_value **apSqlParam; /* Original SQL values of parameters */ -@@ -8836,16 +9461,23 @@ - - /* - ** CAPI3REF: Session Object Handle -+** -+** An instance of this object is a [session] that can be used to -+** record changes to a database. - */ - typedef struct sqlite3_session sqlite3_session; - - /* - ** CAPI3REF: Changeset Iterator Handle -+** -+** An instance of this object acts as a cursor for iterating -+** over the elements of a [changeset] or [patchset]. - */ - typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; - - /* - ** CAPI3REF: Create A New Session Object -+** CONSTRUCTOR: sqlite3_session - ** - ** Create a new session object attached to database handle db. If successful, - ** a pointer to the new object is written to *ppSession and SQLITE_OK is -@@ -8882,6 +9514,7 @@ - - /* - ** CAPI3REF: Delete A Session Object -+** DESTRUCTOR: sqlite3_session - ** - ** Delete a session object previously allocated using - ** [sqlite3session_create()]. Once a session object has been deleted, the -@@ -8897,6 +9530,7 @@ - - /* - ** CAPI3REF: Enable Or Disable A Session Object -+** METHOD: sqlite3_session - ** - ** Enable or disable the recording of changes by a session object. When - ** enabled, a session object records changes made to the database. When -@@ -8916,6 +9550,7 @@ - - /* - ** CAPI3REF: Set Or Clear the Indirect Change Flag -+** METHOD: sqlite3_session - ** - ** Each change recorded by a session object is marked as either direct or - ** indirect. A change is marked as indirect if either: -@@ -8945,6 +9580,7 @@ - - /* - ** CAPI3REF: Attach A Table To A Session Object -+** METHOD: sqlite3_session - ** - ** If argument zTab is not NULL, then it is the name of a table to attach - ** to the session object passed as the first argument. All subsequent changes -@@ -8970,6 +9606,35 @@ - ** - ** SQLITE_OK is returned if the call completes without error. Or, if an error - ** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned. -+** -+** <h3>Special sqlite_stat1 Handling</h3> -+** -+** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to -+** some of the rules above. In SQLite, the schema of sqlite_stat1 is: -+** <pre> -+** CREATE TABLE sqlite_stat1(tbl,idx,stat) -+** </pre> -+** -+** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are -+** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes -+** are recorded for rows for which (idx IS NULL) is true. However, for such -+** rows a zero-length blob (SQL value X'') is stored in the changeset or -+** patchset instead of a NULL value. This allows such changesets to be -+** manipulated by legacy implementations of sqlite3changeset_invert(), -+** concat() and similar. -+** -+** The sqlite3changeset_apply() function automatically converts the -+** zero-length blob back to a NULL value when updating the sqlite_stat1 -+** table. However, if the application calls sqlite3changeset_new(), -+** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset -+** iterator directly (including on a changeset iterator passed to a -+** conflict-handler callback) then the X'' value is returned. The application -+** must translate X'' to NULL itself if required. -+** -+** Legacy (older than 3.22.0) versions of the sessions module cannot capture -+** changes made to the sqlite_stat1 table. Legacy versions of the -+** sqlite3changeset_apply() function silently ignore any modifications to the -+** sqlite_stat1 table that are part of a changeset or patchset. - */ - SQLITE_API int sqlite3session_attach( - sqlite3_session *pSession, /* Session object */ -@@ -8978,6 +9643,7 @@ - - /* - ** CAPI3REF: Set a table filter on a Session Object. -+** METHOD: sqlite3_session - ** - ** 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 -@@ -8996,6 +9662,7 @@ - - /* - ** CAPI3REF: Generate A Changeset From A Session Object -+** METHOD: sqlite3_session - ** - ** Obtain a changeset containing changes to the tables attached to the - ** session object passed as the first argument. If successful, -@@ -9105,7 +9772,8 @@ - ); - - /* --** CAPI3REF: Load The Difference Between Tables Into A Session -+** CAPI3REF: Load The Difference Between Tables Into A Session -+** METHOD: sqlite3_session - ** - ** If it is not already attached to the session object passed as the first - ** argument, this function attaches table zTbl in the same manner as the -@@ -9170,6 +9838,7 @@ - - /* - ** CAPI3REF: Generate A Patchset From A Session Object -+** METHOD: sqlite3_session - ** - ** The differences between a patchset and a changeset are that: - ** -@@ -9198,8 +9867,8 @@ - */ - SQLITE_API int sqlite3session_patchset( - sqlite3_session *pSession, /* Session object */ -- int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */ -- void **ppPatchset /* OUT: Buffer containing changeset */ -+ int *pnPatchset, /* OUT: Size of buffer at *ppPatchset */ -+ void **ppPatchset /* OUT: Buffer containing patchset */ - ); - - /* -@@ -9221,6 +9890,7 @@ - - /* - ** CAPI3REF: Create An Iterator To Traverse A Changeset -+** CONSTRUCTOR: sqlite3_changeset_iter - ** - ** Create an iterator used to iterate through the contents of a changeset. - ** If successful, *pp is set to point to the iterator handle and SQLITE_OK -@@ -9251,6 +9921,13 @@ - ** consecutively. There is no chance that the iterator will visit a change - ** the applies to table X, then one for table Y, and then later on visit - ** another change for table X. -+** -+** The behavior of sqlite3changeset_start_v2() and its streaming equivalent -+** may be modified by passing a combination of -+** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter. -+** -+** Note that the sqlite3changeset_start_v2() API is still <b>experimental</b> -+** and therefore subject to change. - */ - SQLITE_API int sqlite3changeset_start( - sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ -@@ -9257,10 +9934,30 @@ - int nChangeset, /* Size of changeset blob in bytes */ - void *pChangeset /* Pointer to blob containing changeset */ - ); -+SQLITE_API int sqlite3changeset_start_v2( -+ sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ -+ int nChangeset, /* Size of changeset blob in bytes */ -+ void *pChangeset, /* Pointer to blob containing changeset */ -+ int flags /* SESSION_CHANGESETSTART_* flags */ -+); - -+/* -+** CAPI3REF: Flags for sqlite3changeset_start_v2 -+** -+** The following flags may passed via the 4th parameter to -+** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]: -+** -+** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd> -+** Invert the changeset while iterating through it. This is equivalent to -+** inverting a changeset using sqlite3changeset_invert() before applying it. -+** It is an error to specify this flag with a patchset. -+*/ -+#define SQLITE_CHANGESETSTART_INVERT 0x0002 - -+ - /* - ** CAPI3REF: Advance A Changeset Iterator -+** METHOD: sqlite3_changeset_iter - ** - ** This function may only be used with iterators created by function - ** [sqlite3changeset_start()]. If it is called on an iterator passed to -@@ -9285,6 +9982,7 @@ - - /* - ** CAPI3REF: Obtain The Current Operation From A Changeset Iterator -+** METHOD: sqlite3_changeset_iter - ** - ** The pIter argument passed to this function may either be an iterator - ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator -@@ -9319,6 +10017,7 @@ - - /* - ** CAPI3REF: Obtain The Primary Key Definition Of A Table -+** METHOD: sqlite3_changeset_iter - ** - ** For each modified table, a changeset includes the following: - ** -@@ -9350,6 +10049,7 @@ - - /* - ** CAPI3REF: Obtain old.* Values From A Changeset Iterator -+** METHOD: sqlite3_changeset_iter - ** - ** The pIter argument passed to this function may either be an iterator - ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator -@@ -9380,6 +10080,7 @@ - - /* - ** CAPI3REF: Obtain new.* Values From A Changeset Iterator -+** METHOD: sqlite3_changeset_iter - ** - ** The pIter argument passed to this function may either be an iterator - ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator -@@ -9413,6 +10114,7 @@ - - /* - ** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator -+** METHOD: sqlite3_changeset_iter - ** - ** This function should only be used with iterator objects passed to a - ** conflict-handler callback by [sqlite3changeset_apply()] with either -@@ -9440,6 +10142,7 @@ - - /* - ** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations -+** METHOD: sqlite3_changeset_iter - ** - ** This function may only be called with an iterator passed to an - ** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case -@@ -9456,6 +10159,7 @@ - - /* - ** CAPI3REF: Finalize A Changeset Iterator -+** METHOD: sqlite3_changeset_iter - ** - ** This function is used to finalize an iterator allocated with - ** [sqlite3changeset_start()]. -@@ -9472,6 +10176,7 @@ - ** to that error is returned by this function. Otherwise, SQLITE_OK is - ** returned. This is to allow the following pattern (pseudo-code): - ** -+** <pre> - ** sqlite3changeset_start(); - ** while( SQLITE_ROW==sqlite3changeset_next() ){ - ** // Do something with change. -@@ -9480,6 +10185,7 @@ - ** if( rc!=SQLITE_OK ){ - ** // An error has occurred - ** } -+** </pre> - */ - SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); - -@@ -9527,6 +10233,7 @@ - ** sqlite3_changegroup object. Calling it produces similar results as the - ** following code fragment: - ** -+** <pre> - ** sqlite3_changegroup *pGrp; - ** rc = sqlite3_changegroup_new(&pGrp); - ** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA); -@@ -9537,6 +10244,7 @@ - ** *ppOut = 0; - ** *pnOut = 0; - ** } -+** </pre> - ** - ** Refer to the sqlite3_changegroup documentation below for details. - */ -@@ -9552,11 +10260,15 @@ - - /* - ** CAPI3REF: Changegroup Handle -+** -+** A changegroup is an object used to combine two or more -+** [changesets] or [patchsets] - */ - typedef struct sqlite3_changegroup sqlite3_changegroup; - - /* - ** CAPI3REF: Create A New Changegroup Object -+** CONSTRUCTOR: sqlite3_changegroup - ** - ** An sqlite3_changegroup object is used to combine two or more changesets - ** (or patchsets) into a single changeset (or patchset). A single changegroup -@@ -9594,6 +10306,7 @@ - - /* - ** CAPI3REF: Add A Changeset To A Changegroup -+** METHOD: sqlite3_changegroup - ** - ** Add all changes within the changeset (or patchset) in buffer pData (size - ** nData bytes) to the changegroup. -@@ -9671,6 +10384,7 @@ - - /* - ** CAPI3REF: Obtain A Composite Changeset From A Changegroup -+** METHOD: sqlite3_changegroup - ** - ** Obtain a buffer containing a changeset (or patchset) representing the - ** current contents of the changegroup. If the inputs to the changegroup -@@ -9701,6 +10415,7 @@ - - /* - ** CAPI3REF: Delete A Changegroup Object -+** DESTRUCTOR: sqlite3_changegroup - */ - SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*); - -@@ -9707,19 +10422,18 @@ - /* - ** CAPI3REF: Apply A Changeset To A Database - ** --** Apply a changeset to a database. This function attempts to update the --** "main" database attached to handle db with the changes found in the --** changeset passed via the second and third arguments. -+** Apply a changeset or patchset to a database. These functions attempt to -+** update the "main" database attached to handle db with the changes found in -+** the changeset passed via the second and third arguments. - ** --** The fourth argument (xFilter) passed to this function is the "filter -+** The fourth argument (xFilter) passed to these functions is the "filter - ** callback". If it is not NULL, then for each table affected by at least one - ** change in the changeset, the filter callback is invoked with - ** the table name as the second argument, and a copy of the context pointer --** passed as the sixth argument to this function as the first. If the "filter --** callback" returns zero, then no attempt is made to apply any changes to --** the table. Otherwise, if the return value is non-zero or the xFilter --** argument to this function is NULL, all changes related to the table are --** attempted. -+** passed as the sixth argument as the first. If the "filter callback" -+** returns zero, then no attempt is made to apply any changes to the table. -+** Otherwise, if the return value is non-zero or the xFilter argument to -+** is NULL, all changes related to the table are attempted. - ** - ** For each table that is not excluded by the filter callback, this function - ** tests that the target database contains a compatible table. A table is -@@ -9764,7 +10478,7 @@ - ** - ** <dl> - ** <dt>DELETE Changes<dd> --** For each DELETE change, this function checks if the target database -+** For each DELETE change, the function checks if the target database - ** contains a row with the same primary key value (or values) as the - ** original row values stored in the changeset. If it does, and the values - ** stored in all non-primary key columns also match the values stored in -@@ -9809,7 +10523,7 @@ - ** [SQLITE_CHANGESET_REPLACE]. - ** - ** <dt>UPDATE Changes<dd> --** For each UPDATE change, this function checks if the target database -+** For each UPDATE change, the function checks if the target database - ** contains a row with the same primary key value (or values) as the - ** original row values stored in the changeset. If it does, and the values - ** stored in all modified non-primary key columns also match the values -@@ -9840,11 +10554,28 @@ - ** This can be used to further customize the applications conflict - ** resolution strategy. - ** --** All changes made by this function are enclosed in a savepoint transaction. -+** All changes made by these functions are enclosed in a savepoint transaction. - ** If any other error (aside from a constraint failure when attempting to - ** write to the target database) occurs, then the savepoint transaction is - ** rolled back, restoring the target database to its original state, and an - ** SQLite error code returned. -+** -+** If the output parameters (ppRebase) and (pnRebase) are non-NULL and -+** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2() -+** may set (*ppRebase) to point to a "rebase" that may be used with the -+** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase) -+** is set to the size of the buffer in bytes. It is the responsibility of the -+** caller to eventually free any such buffer using sqlite3_free(). The buffer -+** is only allocated and populated if one or more conflicts were encountered -+** while applying the patchset. See comments surrounding the sqlite3_rebaser -+** APIs for further details. -+** -+** The behavior of sqlite3changeset_apply_v2() and its streaming equivalent -+** may be modified by passing a combination of -+** [SQLITE_CHANGESETAPPLY_NOSAVEPOINT | supported flags] as the 9th parameter. -+** -+** Note that the sqlite3changeset_apply_v2() API is still <b>experimental</b> -+** and therefore subject to change. - */ - SQLITE_API int sqlite3changeset_apply( - sqlite3 *db, /* Apply change to "main" db of this handle */ -@@ -9861,7 +10592,48 @@ - ), - void *pCtx /* First argument passed to xConflict */ - ); -+SQLITE_API int sqlite3changeset_apply_v2( -+ sqlite3 *db, /* Apply change to "main" db of this handle */ -+ int nChangeset, /* Size of changeset in bytes */ -+ void *pChangeset, /* Changeset blob */ -+ int(*xFilter)( -+ void *pCtx, /* Copy of sixth arg to _apply() */ -+ const char *zTab /* Table name */ -+ ), -+ int(*xConflict)( -+ void *pCtx, /* Copy of sixth arg to _apply() */ -+ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ -+ sqlite3_changeset_iter *p /* Handle describing change and conflict */ -+ ), -+ void *pCtx, /* First argument passed to xConflict */ -+ void **ppRebase, int *pnRebase, /* OUT: Rebase data */ -+ int flags /* SESSION_CHANGESETAPPLY_* flags */ -+); - -+/* -+** CAPI3REF: Flags for sqlite3changeset_apply_v2 -+** -+** The following flags may passed via the 9th parameter to -+** [sqlite3changeset_apply_v2] and [sqlite3changeset_apply_v2_strm]: -+** -+** <dl> -+** <dt>SQLITE_CHANGESETAPPLY_NOSAVEPOINT <dd> -+** Usually, the sessions module encloses all operations performed by -+** a single call to apply_v2() or apply_v2_strm() in a [SAVEPOINT]. The -+** SAVEPOINT is committed if the changeset or patchset is successfully -+** applied, or rolled back if an error occurs. Specifying this flag -+** causes the sessions module to omit this savepoint. In this case, if the -+** caller has an open transaction or savepoint when apply_v2() is called, -+** it may revert the partially applied changeset by rolling it back. -+** -+** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd> -+** Invert the changeset before applying it. This is equivalent to inverting -+** a changeset using sqlite3changeset_invert() before applying it. It is -+** an error to specify this flag with a patchset. -+*/ -+#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 -+#define SQLITE_CHANGESETAPPLY_INVERT 0x0002 -+ - /* - ** CAPI3REF: Constants Passed To The Conflict Handler - ** -@@ -9958,7 +10730,162 @@ - #define SQLITE_CHANGESET_REPLACE 1 - #define SQLITE_CHANGESET_ABORT 2 - -+/* -+** CAPI3REF: Rebasing changesets -+** EXPERIMENTAL -+** -+** Suppose there is a site hosting a database in state S0. And that -+** modifications are made that move that database to state S1 and a -+** changeset recorded (the "local" changeset). Then, a changeset based -+** on S0 is received from another site (the "remote" changeset) and -+** applied to the database. The database is then in state -+** (S1+"remote"), where the exact state depends on any conflict -+** resolution decisions (OMIT or REPLACE) made while applying "remote". -+** Rebasing a changeset is to update it to take those conflict -+** resolution decisions into account, so that the same conflicts -+** do not have to be resolved elsewhere in the network. -+** -+** For example, if both the local and remote changesets contain an -+** INSERT of the same key on "CREATE TABLE t1(a PRIMARY KEY, b)": -+** -+** local: INSERT INTO t1 VALUES(1, 'v1'); -+** remote: INSERT INTO t1 VALUES(1, 'v2'); -+** -+** and the conflict resolution is REPLACE, then the INSERT change is -+** removed from the local changeset (it was overridden). Or, if the -+** conflict resolution was "OMIT", then the local changeset is modified -+** to instead contain: -+** -+** UPDATE t1 SET b = 'v2' WHERE a=1; -+** -+** Changes within the local changeset are rebased as follows: -+** -+** <dl> -+** <dt>Local INSERT<dd> -+** This may only conflict with a remote INSERT. If the conflict -+** resolution was OMIT, then add an UPDATE change to the rebased -+** changeset. Or, if the conflict resolution was REPLACE, add -+** nothing to the rebased changeset. -+** -+** <dt>Local DELETE<dd> -+** This may conflict with a remote UPDATE or DELETE. In both cases the -+** only possible resolution is OMIT. If the remote operation was a -+** DELETE, then add no change to the rebased changeset. If the remote -+** operation was an UPDATE, then the old.* fields of change are updated -+** to reflect the new.* values in the UPDATE. -+** -+** <dt>Local UPDATE<dd> -+** This may conflict with a remote UPDATE or DELETE. If it conflicts -+** with a DELETE, and the conflict resolution was OMIT, then the update -+** is changed into an INSERT. Any undefined values in the new.* record -+** from the update change are filled in using the old.* values from -+** the conflicting DELETE. Or, if the conflict resolution was REPLACE, -+** the UPDATE change is simply omitted from the rebased changeset. -+** -+** If conflict is with a remote UPDATE and the resolution is OMIT, then -+** the old.* values are rebased using the new.* values in the remote -+** change. Or, if the resolution is REPLACE, then the change is copied -+** into the rebased changeset with updates to columns also updated by -+** the conflicting remote UPDATE removed. If this means no columns would -+** be updated, the change is omitted. -+** </dl> -+** -+** A local change may be rebased against multiple remote changes -+** simultaneously. If a single key is modified by multiple remote -+** changesets, they are combined as follows before the local changeset -+** is rebased: -+** -+** <ul> -+** <li> If there has been one or more REPLACE resolutions on a -+** key, it is rebased according to a REPLACE. -+** -+** <li> If there have been no REPLACE resolutions on a key, then -+** the local changeset is rebased according to the most recent -+** of the OMIT resolutions. -+** </ul> -+** -+** Note that conflict resolutions from multiple remote changesets are -+** combined on a per-field basis, not per-row. This means that in the -+** case of multiple remote UPDATE operations, some fields of a single -+** local change may be rebased for REPLACE while others are rebased for -+** OMIT. -+** -+** In order to rebase a local changeset, the remote changeset must first -+** be applied to the local database using sqlite3changeset_apply_v2() and -+** the buffer of rebase information captured. Then: -+** -+** <ol> -+** <li> An sqlite3_rebaser object is created by calling -+** sqlite3rebaser_create(). -+** <li> The new object is configured with the rebase buffer obtained from -+** sqlite3changeset_apply_v2() by calling sqlite3rebaser_configure(). -+** If the local changeset is to be rebased against multiple remote -+** changesets, then sqlite3rebaser_configure() should be called -+** multiple times, in the same order that the multiple -+** sqlite3changeset_apply_v2() calls were made. -+** <li> Each local changeset is rebased by calling sqlite3rebaser_rebase(). -+** <li> The sqlite3_rebaser object is deleted by calling -+** sqlite3rebaser_delete(). -+** </ol> -+*/ -+typedef struct sqlite3_rebaser sqlite3_rebaser; -+ - /* -+** CAPI3REF: Create a changeset rebaser object. -+** EXPERIMENTAL -+** -+** Allocate a new changeset rebaser object. If successful, set (*ppNew) to -+** point to the new object and return SQLITE_OK. Otherwise, if an error -+** occurs, return an SQLite error code (e.g. SQLITE_NOMEM) and set (*ppNew) -+** to NULL. -+*/ -+SQLITE_API int sqlite3rebaser_create(sqlite3_rebaser **ppNew); -+ -+/* -+** CAPI3REF: Configure a changeset rebaser object. -+** EXPERIMENTAL -+** -+** Configure the changeset rebaser object to rebase changesets according -+** to the conflict resolutions described by buffer pRebase (size nRebase -+** bytes), which must have been obtained from a previous call to -+** sqlite3changeset_apply_v2(). -+*/ -+SQLITE_API int sqlite3rebaser_configure( -+ sqlite3_rebaser*, -+ int nRebase, const void *pRebase -+); -+ -+/* -+** CAPI3REF: Rebase a changeset -+** EXPERIMENTAL -+** -+** 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 -+** rebaser object passed as the first argument. If successful, (*ppOut) -+** is set to point to the new buffer containing the rebased changset and -+** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the -+** responsibility of the caller to eventually free the new buffer using -+** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut) -+** are set to zero and an SQLite error code returned. -+*/ -+SQLITE_API int sqlite3rebaser_rebase( -+ sqlite3_rebaser*, -+ int nIn, const void *pIn, -+ int *pnOut, void **ppOut -+); -+ -+/* -+** CAPI3REF: Delete a changeset rebaser object. -+** EXPERIMENTAL -+** -+** Delete the changeset rebaser object and all associated resources. There -+** should be one call to this function for each successful invocation -+** of sqlite3rebaser_create(). -+*/ -+SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p); -+ -+/* - ** CAPI3REF: Streaming Versions of API functions. - ** - ** The six streaming API xxx_strm() functions serve similar purposes to the -@@ -9966,12 +10893,13 @@ - ** - ** <table border=1 style="margin-left:8ex;margin-right:8ex"> - ** <tr><th>Streaming function<th>Non-streaming equivalent</th> --** <tr><td>sqlite3changeset_apply_str<td>[sqlite3changeset_apply] --** <tr><td>sqlite3changeset_concat_str<td>[sqlite3changeset_concat] --** <tr><td>sqlite3changeset_invert_str<td>[sqlite3changeset_invert] --** <tr><td>sqlite3changeset_start_str<td>[sqlite3changeset_start] --** <tr><td>sqlite3session_changeset_str<td>[sqlite3session_changeset] --** <tr><td>sqlite3session_patchset_str<td>[sqlite3session_patchset] -+** <tr><td>sqlite3changeset_apply_strm<td>[sqlite3changeset_apply] -+** <tr><td>sqlite3changeset_apply_strm_v2<td>[sqlite3changeset_apply_v2] -+** <tr><td>sqlite3changeset_concat_strm<td>[sqlite3changeset_concat] -+** <tr><td>sqlite3changeset_invert_strm<td>[sqlite3changeset_invert] -+** <tr><td>sqlite3changeset_start_strm<td>[sqlite3changeset_start] -+** <tr><td>sqlite3session_changeset_strm<td>[sqlite3session_changeset] -+** <tr><td>sqlite3session_patchset_strm<td>[sqlite3session_patchset] - ** </table> - ** - ** Non-streaming functions that accept changesets (or patchsets) as input -@@ -10062,6 +10990,23 @@ - ), - void *pCtx /* First argument passed to xConflict */ - ); -+SQLITE_API int sqlite3changeset_apply_v2_strm( -+ sqlite3 *db, /* Apply change to "main" db of this handle */ -+ int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ -+ void *pIn, /* First arg for xInput */ -+ int(*xFilter)( -+ void *pCtx, /* Copy of sixth arg to _apply() */ -+ const char *zTab /* Table name */ -+ ), -+ int(*xConflict)( -+ void *pCtx, /* Copy of sixth arg to _apply() */ -+ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ -+ sqlite3_changeset_iter *p /* Handle describing change and conflict */ -+ ), -+ void *pCtx, /* First argument passed to xConflict */ -+ void **ppRebase, int *pnRebase, -+ int flags -+); - SQLITE_API int sqlite3changeset_concat_strm( - int (*xInputA)(void *pIn, void *pData, int *pnData), - void *pInA, -@@ -10081,6 +11026,12 @@ - int (*xInput)(void *pIn, void *pData, int *pnData), - void *pIn - ); -+SQLITE_API int sqlite3changeset_start_v2_strm( -+ sqlite3_changeset_iter **pp, -+ int (*xInput)(void *pIn, void *pData, int *pnData), -+ void *pIn, -+ int flags -+); - SQLITE_API int sqlite3session_changeset_strm( - sqlite3_session *pSession, - int (*xOutput)(void *pOut, const void *pData, int nData), -@@ -10099,9 +11050,55 @@ - int (*xOutput)(void *pOut, const void *pData, int nData), - void *pOut - ); -+SQLITE_API int sqlite3rebaser_rebase_strm( -+ sqlite3_rebaser *pRebaser, -+ int (*xInput)(void *pIn, void *pData, int *pnData), -+ void *pIn, -+ int (*xOutput)(void *pOut, const void *pData, int nData), -+ void *pOut -+); - -+/* -+** CAPI3REF: Configure global parameters -+** -+** The sqlite3session_config() interface is used to make global configuration -+** changes to the sessions module in order to tune it to the specific needs -+** of the application. -+** -+** The sqlite3session_config() interface is not threadsafe. If it is invoked -+** while any other thread is inside any other sessions method then the -+** results are undefined. Furthermore, if it is invoked after any sessions -+** related objects have been created, the results are also undefined. -+** -+** The first argument to the sqlite3session_config() function must be one -+** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The -+** interpretation of the (void*) value passed as the second parameter and -+** the effect of calling this function depends on the value of the first -+** parameter. -+** -+** <dl> -+** <dt>SQLITE_SESSION_CONFIG_STRMSIZE<dd> -+** By default, the sessions module streaming interfaces attempt to input -+** and output data in approximately 1 KiB chunks. This operand may be used -+** to set and query the value of this configuration setting. The pointer -+** passed as the second argument must point to a value of type (int). -+** If this value is greater than 0, it is used as the new streaming data -+** chunk size for both input and output. Before returning, the (int) value -+** pointed to by pArg is set to the final value of the streaming interface -+** chunk size. -+** </dl> -+** -+** This function returns SQLITE_OK if successful, or an SQLite error code -+** otherwise. -+*/ -+SQLITE_API int sqlite3session_config(int op, void *pArg); - - /* -+** CAPI3REF: Values for sqlite3session_config(). -+*/ -+#define SQLITE_SESSION_CONFIG_STRMSIZE 1 -+ -+/* - ** Make sure we can call this stuff from C++. - */ - #ifdef __cplusplus -@@ -10557,7 +11554,7 @@ - ** This way, even if the tokenizer does not provide synonyms - ** when tokenizing query text (it should not - to do would be - ** inefficient), it doesn't matter if the user queries for --** 'first + place' or '1st + place', as there are entires in the -+** 'first + place' or '1st + place', as there are entries in the - ** FTS index corresponding to both forms of the first token. - ** </ol> - ** -@@ -10585,7 +11582,7 @@ - ** extra data to the FTS index or require FTS5 to query for multiple terms, - ** so it is efficient in terms of disk space and query speed. However, it - ** does not support prefix queries very well. If, as suggested above, the --** token "first" is subsituted for "1st" by the tokenizer, then the query: -+** token "first" is substituted for "1st" by the tokenizer, then the query: - ** - ** <codeblock> - ** ... MATCH '1s*'</codeblock> ---- contrib/sqlite3/sqlite3ext.h.orig -+++ contrib/sqlite3/sqlite3ext.h -@@ -134,7 +134,7 @@ - int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*, - const char*,const char*),void*); - void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); -- char * (*snprintf)(int,char*,const char*,...); -+ char * (*xsnprintf)(int,char*,const char*,...); - int (*step)(sqlite3_stmt*); - int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*, - char const**,char const**,int*,int*,int*); -@@ -246,7 +246,7 @@ - int (*uri_boolean)(const char*,const char*,int); - sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64); - const char *(*uri_parameter)(const char*,const char*); -- char *(*vsnprintf)(int,char*,const char*,va_list); -+ char *(*xvsnprintf)(int,char*,const char*,va_list); - int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*); - /* Version 3.8.7 and later */ - int (*auto_extension)(void(*)(void)); -@@ -292,6 +292,33 @@ - int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*)); - void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*)); - void *(*value_pointer)(sqlite3_value*,const char*); -+ int (*vtab_nochange)(sqlite3_context*); -+ int (*value_nochange)(sqlite3_value*); -+ const char *(*vtab_collation)(sqlite3_index_info*,int); -+ /* Version 3.24.0 and later */ -+ int (*keyword_count)(void); -+ int (*keyword_name)(int,const char**,int*); -+ int (*keyword_check)(const char*,int); -+ sqlite3_str *(*str_new)(sqlite3*); -+ char *(*str_finish)(sqlite3_str*); -+ void (*str_appendf)(sqlite3_str*, const char *zFormat, ...); -+ void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list); -+ void (*str_append)(sqlite3_str*, const char *zIn, int N); -+ void (*str_appendall)(sqlite3_str*, const char *zIn); -+ void (*str_appendchar)(sqlite3_str*, int N, char C); -+ void (*str_reset)(sqlite3_str*); -+ int (*str_errcode)(sqlite3_str*); -+ int (*str_length)(sqlite3_str*); -+ char *(*str_value)(sqlite3_str*); -+ /* Version 3.25.0 and later */ -+ int (*create_window_function)(sqlite3*,const char*,int,int,void*, -+ void (*xStep)(sqlite3_context*,int,sqlite3_value**), -+ void (*xFinal)(sqlite3_context*), -+ void (*xValue)(sqlite3_context*), -+ void (*xInv)(sqlite3_context*,int,sqlite3_value**), -+ void(*xDestroy)(void*)); -+ /* Version 3.26.0 and later */ -+ const char *(*normalized_sql)(sqlite3_stmt*); - }; - - /* -@@ -418,7 +445,7 @@ - #define sqlite3_rollback_hook sqlite3_api->rollback_hook - #define sqlite3_set_authorizer sqlite3_api->set_authorizer - #define sqlite3_set_auxdata sqlite3_api->set_auxdata --#define sqlite3_snprintf sqlite3_api->snprintf -+#define sqlite3_snprintf sqlite3_api->xsnprintf - #define sqlite3_step sqlite3_api->step - #define sqlite3_table_column_metadata sqlite3_api->table_column_metadata - #define sqlite3_thread_cleanup sqlite3_api->thread_cleanup -@@ -442,7 +469,7 @@ - #define sqlite3_value_text16le sqlite3_api->value_text16le - #define sqlite3_value_type sqlite3_api->value_type - #define sqlite3_vmprintf sqlite3_api->vmprintf --#define sqlite3_vsnprintf sqlite3_api->vsnprintf -+#define sqlite3_vsnprintf sqlite3_api->xvsnprintf - #define sqlite3_overload_function sqlite3_api->overload_function - #define sqlite3_prepare_v2 sqlite3_api->prepare_v2 - #define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 -@@ -518,7 +545,7 @@ - #define sqlite3_uri_boolean sqlite3_api->uri_boolean - #define sqlite3_uri_int64 sqlite3_api->uri_int64 - #define sqlite3_uri_parameter sqlite3_api->uri_parameter --#define sqlite3_uri_vsnprintf sqlite3_api->vsnprintf -+#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf - #define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2 - /* Version 3.8.7 and later */ - #define sqlite3_auto_extension sqlite3_api->auto_extension -@@ -558,6 +585,29 @@ - #define sqlite3_bind_pointer sqlite3_api->bind_pointer - #define sqlite3_result_pointer sqlite3_api->result_pointer - #define sqlite3_value_pointer sqlite3_api->value_pointer -+/* Version 3.22.0 and later */ -+#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange -+#define sqlite3_value_nochange sqlite3_api->value_nochange -+#define sqlite3_vtab_collation sqlite3_api->vtab_collation -+/* Version 3.24.0 and later */ -+#define sqlite3_keyword_count sqlite3_api->keyword_count -+#define sqlite3_keyword_name sqlite3_api->keyword_name -+#define sqlite3_keyword_check sqlite3_api->keyword_check -+#define sqlite3_str_new sqlite3_api->str_new -+#define sqlite3_str_finish sqlite3_api->str_finish -+#define sqlite3_str_appendf sqlite3_api->str_appendf -+#define sqlite3_str_vappendf sqlite3_api->str_vappendf -+#define sqlite3_str_append sqlite3_api->str_append -+#define sqlite3_str_appendall sqlite3_api->str_appendall -+#define sqlite3_str_appendchar sqlite3_api->str_appendchar -+#define sqlite3_str_reset sqlite3_api->str_reset -+#define sqlite3_str_errcode sqlite3_api->str_errcode -+#define sqlite3_str_length sqlite3_api->str_length -+#define sqlite3_str_value sqlite3_api->str_value -+/* Version 3.25.0 and later */ -+#define sqlite3_create_window_function sqlite3_api->create_window_function -+/* Version 3.26.0 and later */ -+#define sqlite3_normalized_sql sqlite3_api->normalized_sql - #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ - - #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) ---- contrib/sqlite3/tea/configure.orig -+++ contrib/sqlite3/tea/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.20.0. -+# Generated by GNU Autoconf 2.69 for sqlite 3.26.0. - # - # - # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. -@@ -577,8 +577,8 @@ - # Identity of this package. - PACKAGE_NAME='sqlite' - PACKAGE_TARNAME='sqlite' --PACKAGE_VERSION='3.20.0' --PACKAGE_STRING='sqlite 3.20.0' -+PACKAGE_VERSION='3.26.0' -+PACKAGE_STRING='sqlite 3.26.0' - PACKAGE_BUGREPORT='' - PACKAGE_URL='' - -@@ -1292,7 +1292,7 @@ - # 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.20.0 to adapt to many kinds of systems. -+\`configure' configures sqlite 3.26.0 to adapt to many kinds of systems. - - Usage: $0 [OPTION]... [VAR=VALUE]... - -@@ -1353,7 +1353,7 @@ - - if test -n "$ac_init_help"; then - case $ac_init_help in -- short | recursive ) echo "Configuration of sqlite 3.20.0:";; -+ short | recursive ) echo "Configuration of sqlite 3.26.0:";; - esac - cat <<\_ACEOF - -@@ -1455,7 +1455,7 @@ - test -n "$ac_init_help" && exit $ac_status - if $ac_init_version; then - cat <<\_ACEOF --sqlite configure 3.20.0 -+sqlite configure 3.26.0 - generated by GNU Autoconf 2.69 - - Copyright (C) 2012 Free Software Foundation, Inc. -@@ -1866,7 +1866,7 @@ - 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.20.0, which was -+It was created by sqlite $as_me 3.26.0, which was - generated by GNU Autoconf 2.69. Invocation command line was - - $ $0 $@ -@@ -9361,7 +9361,7 @@ - # 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.20.0, which was -+This file was extended by sqlite $as_me 3.26.0, which was - generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES -@@ -9414,7 +9414,7 @@ - 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.20.0 -+sqlite config.status 3.26.0 - configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" - ---- contrib/sqlite3/tea/configure.ac.orig -+++ contrib/sqlite3/tea/configure.ac -@@ -19,7 +19,7 @@ - # so you can encode the package version directly into the source files. - #----------------------------------------------------------------------- - --AC_INIT([sqlite], [3.20.0]) -+AC_INIT([sqlite], [3.26.0]) - - #-------------------------------------------------------------------- - # Call TEA_INIT as the first TEA_ macro to set up initial vars. ---- contrib/sqlite3/tea/generic/tclsqlite3.c.orig -+++ contrib/sqlite3/tea/generic/tclsqlite3.c -@@ -19,17 +19,19 @@ - ** - ** Compile-time options: - ** --** -DTCLSH=1 Add a "main()" routine that works as a tclsh. -+** -DTCLSH Add a "main()" routine that works as a tclsh. - ** --** -DSQLITE_TCLMD5 When used in conjuction with -DTCLSH=1, add --** four new commands to the TCL interpreter for --** generating MD5 checksums: md5, md5file, --** md5-10x8, and md5file-10x8. -+** -DTCLSH_INIT_PROC=name - ** --** -DSQLITE_TEST When used in conjuction with -DTCLSH=1, add --** hundreds of new commands used for testing --** SQLite. This option implies -DSQLITE_TCLMD5. -+** Invoke name(interp) to initialize the Tcl interpreter. -+** If name(interp) returns a non-NULL string, then run -+** that string as a Tcl script to launch the application. -+** If name(interp) returns NULL, then run the regular -+** tclsh-emulator code. - */ -+#ifdef TCLSH_INIT_PROC -+# define TCLSH 1 -+#endif - - /* - ** If requested, include the SQLite compiler options file for MSVC. -@@ -63,13 +65,18 @@ - - /* Used to get the current process ID */ - #if !defined(_WIN32) -+# include <signal.h> - # include <unistd.h> - # define GETPID getpid - #elif !defined(_WIN32_WCE) - # ifndef SQLITE_AMALGAMATION --# define WIN32_LEAN_AND_MEAN -+# ifndef WIN32_LEAN_AND_MEAN -+# define WIN32_LEAN_AND_MEAN -+# endif - # include <windows.h> - # endif -+# include <io.h> -+# define isatty(h) _isatty(h) - # define GETPID (int)GetCurrentProcessId - #endif - -@@ -649,7 +656,7 @@ - } - case SQLITE_TRACE_PROFILE: { - sqlite3_stmt *pStmt = (sqlite3_stmt *)pd; -- sqlite3_int64 ns = (sqlite3_int64)xd; -+ sqlite3_int64 ns = *(sqlite3_int64*)xd; - - pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1); - Tcl_IncrRefCount(pCmd); -@@ -1849,35 +1856,35 @@ - int choice; - int rc = TCL_OK; - static const char *DB_strs[] = { -- "authorizer", "backup", "busy", -- "cache", "changes", "close", -- "collate", "collation_needed", "commit_hook", -- "complete", "copy", "enable_load_extension", -- "errorcode", "eval", "exists", -- "function", "incrblob", "interrupt", -- "last_insert_rowid", "nullvalue", "onecolumn", -- "preupdate", "profile", "progress", -- "rekey", "restore", "rollback_hook", -- "status", "timeout", "total_changes", -- "trace", "trace_v2", "transaction", -- "unlock_notify", "update_hook", "version", -- "wal_hook", -- 0 -+ "authorizer", "backup", "busy", -+ "cache", "changes", "close", -+ "collate", "collation_needed", "commit_hook", -+ "complete", "copy", "deserialize", -+ "enable_load_extension", "errorcode", "eval", -+ "exists", "function", "incrblob", -+ "interrupt", "last_insert_rowid", "nullvalue", -+ "onecolumn", "preupdate", "profile", -+ "progress", "rekey", "restore", -+ "rollback_hook", "serialize", "status", -+ "timeout", "total_changes", "trace", -+ "trace_v2", "transaction", "unlock_notify", -+ "update_hook", "version", "wal_hook", -+ 0 - }; - enum DB_enum { -- DB_AUTHORIZER, DB_BACKUP, DB_BUSY, -- DB_CACHE, DB_CHANGES, DB_CLOSE, -- DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK, -- DB_COMPLETE, DB_COPY, DB_ENABLE_LOAD_EXTENSION, -- DB_ERRORCODE, DB_EVAL, DB_EXISTS, -- DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT, -- DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN, -- DB_PREUPDATE, DB_PROFILE, DB_PROGRESS, -- DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK, -- DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES, -- DB_TRACE, DB_TRACE_V2, DB_TRANSACTION, -- DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION, -- DB_WAL_HOOK, -+ DB_AUTHORIZER, DB_BACKUP, DB_BUSY, -+ DB_CACHE, DB_CHANGES, DB_CLOSE, -+ DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK, -+ DB_COMPLETE, DB_COPY, DB_DESERIALIZE, -+ DB_ENABLE_LOAD_EXTENSION, DB_ERRORCODE, DB_EVAL, -+ DB_EXISTS, DB_FUNCTION, DB_INCRBLOB, -+ DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE, -+ DB_ONECOLUMN, DB_PREUPDATE, DB_PROFILE, -+ DB_PROGRESS, DB_REKEY, DB_RESTORE, -+ DB_ROLLBACK_HOOK, DB_SERIALIZE, DB_STATUS, -+ DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE, -+ DB_TRACE_V2, DB_TRANSACTION, DB_UNLOCK_NOTIFY, -+ DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK - }; - /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ - -@@ -2416,6 +2423,53 @@ - } - - /* -+ ** $db deserialize ?DATABASE? VALUE -+ ** -+ ** Reopen DATABASE (default "main") using the content in $VALUE -+ */ -+ case DB_DESERIALIZE: { -+#ifndef SQLITE_ENABLE_DESERIALIZE -+ Tcl_AppendResult(interp, "MEMDB not available in this build", -+ (char*)0); -+ rc = TCL_ERROR; -+#else -+ const char *zSchema; -+ Tcl_Obj *pValue; -+ unsigned char *pBA; -+ unsigned char *pData; -+ int len, xrc; -+ -+ if( objc==3 ){ -+ zSchema = 0; -+ pValue = objv[2]; -+ }else if( objc==4 ){ -+ zSchema = Tcl_GetString(objv[2]); -+ pValue = objv[3]; -+ }else{ -+ Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? VALUE"); -+ rc = TCL_ERROR; -+ break; -+ } -+ pBA = Tcl_GetByteArrayFromObj(pValue, &len); -+ pData = sqlite3_malloc64( len ); -+ if( pData==0 && len>0 ){ -+ Tcl_AppendResult(interp, "out of memory", (char*)0); -+ rc = TCL_ERROR; -+ }else{ -+ if( len>0 ) memcpy(pData, pBA, len); -+ xrc = sqlite3_deserialize(pDb->db, zSchema, pData, len, len, -+ SQLITE_DESERIALIZE_FREEONCLOSE | -+ SQLITE_DESERIALIZE_RESIZEABLE); -+ if( xrc ){ -+ Tcl_AppendResult(interp, "unable to set MEMDB content", (char*)0); -+ rc = TCL_ERROR; -+ } -+ } -+#endif -+ break; -+ } -+ -+ /* - ** $db enable_load_extension BOOLEAN - ** - ** Turn the extension loading feature on or off. It if off by -@@ -2891,6 +2945,39 @@ - } - - /* -+ ** $db serialize ?DATABASE? -+ ** -+ ** Return a serialization of a database. -+ */ -+ case DB_SERIALIZE: { -+#ifndef SQLITE_ENABLE_DESERIALIZE -+ Tcl_AppendResult(interp, "MEMDB not available in this build", -+ (char*)0); -+ rc = TCL_ERROR; -+#else -+ const char *zSchema = objc>=3 ? Tcl_GetString(objv[2]) : "main"; -+ sqlite3_int64 sz = 0; -+ unsigned char *pData; -+ if( objc!=2 && objc!=3 ){ -+ Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE?"); -+ rc = TCL_ERROR; -+ }else{ -+ int needFree; -+ pData = sqlite3_serialize(pDb->db, zSchema, &sz, SQLITE_SERIALIZE_NOCOPY); -+ if( pData ){ -+ needFree = 0; -+ }else{ -+ pData = sqlite3_serialize(pDb->db, zSchema, &sz, 0); -+ needFree = 1; -+ } -+ Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pData,sz)); -+ if( needFree ) sqlite3_free(pData); -+ } -+#endif -+ break; -+ } -+ -+ /* - ** $db status (step|sort|autoindex|vmstep) - ** - ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or -@@ -3291,7 +3378,42 @@ - ** Return the version string for this database. - */ - case DB_VERSION: { -- Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC); -+ int i; -+ for(i=2; i<objc; i++){ -+ const char *zArg = Tcl_GetString(objv[i]); -+ /* Optional arguments to $db version are used for testing purpose */ -+#ifdef SQLITE_TEST -+ /* $db version -use-legacy-prepare BOOLEAN -+ ** -+ ** Turn the use of legacy sqlite3_prepare() on or off. -+ */ -+ if( strcmp(zArg, "-use-legacy-prepare")==0 && i+1<objc ){ -+ i++; -+ if( Tcl_GetBooleanFromObj(interp, objv[i], &pDb->bLegacyPrepare) ){ -+ return TCL_ERROR; -+ } -+ }else -+ -+ /* $db version -last-stmt-ptr -+ ** -+ ** Return a string which is a hex encoding of the pointer to the -+ ** most recent sqlite3_stmt in the statement cache. -+ */ -+ if( strcmp(zArg, "-last-stmt-ptr")==0 ){ -+ char zBuf[100]; -+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%p", -+ pDb->stmtList ? pDb->stmtList->pStmt: 0); -+ Tcl_SetResult(interp, zBuf, TCL_VOLATILE); -+ }else -+#endif /* SQLITE_TEST */ -+ { -+ Tcl_AppendResult(interp, "unknown argument: ", zArg, (char*)0); -+ return TCL_ERROR; -+ } -+ } -+ if( i==2 ){ -+ Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC); -+ } - break; - } - -@@ -3316,6 +3438,24 @@ - #endif /* SQLITE_TCL_NRE */ - - /* -+** Issue the usage message when the "sqlite3" command arguments are -+** incorrect. -+*/ -+static int sqliteCmdUsage( -+ Tcl_Interp *interp, -+ Tcl_Obj *const*objv -+){ -+ Tcl_WrongNumArgs(interp, 1, objv, -+ "HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?" -+ " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" -+#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) -+ " ?-key CODECKEY?" -+#endif -+ ); -+ return TCL_ERROR; -+} -+ -+/* - ** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN? - ** ?-create BOOLEAN? ?-nomutex BOOLEAN? - ** -@@ -3340,7 +3480,7 @@ - const char *zArg; - char *zErrMsg; - int i; -- const char *zFile; -+ const char *zFile = 0; - const char *zVfs = 0; - int flags; - Tcl_DString translatedFilename; -@@ -3351,7 +3491,7 @@ - int rc; - - /* In normal use, each TCL interpreter runs in a single thread. So -- ** by default, we can turn of mutexing on SQLite database connections. -+ ** by default, we can turn off mutexing on SQLite database connections. - ** However, for testing purposes it is useful to have mutexes turned - ** on. So, by default, mutexes default off. But if compiled with - ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on. -@@ -3362,6 +3502,7 @@ - flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX; - #endif - -+ if( objc==1 ) return sqliteCmdUsage(interp, objv); - if( objc==2 ){ - zArg = Tcl_GetStringFromObj(objv[1], 0); - if( strcmp(zArg,"-version")==0 ){ -@@ -3380,18 +3521,26 @@ - #endif - return TCL_OK; - } -+ if( zArg[0]=='-' ) return sqliteCmdUsage(interp, objv); - } -- for(i=3; i+1<objc; i+=2){ -+ for(i=2; i<objc; i++){ - zArg = Tcl_GetString(objv[i]); -+ if( zArg[0]!='-' ){ -+ if( zFile!=0 ) return sqliteCmdUsage(interp, objv); -+ zFile = zArg; -+ continue; -+ } -+ if( i==objc-1 ) return sqliteCmdUsage(interp, objv); -+ i++; - if( strcmp(zArg,"-key")==0 ){ - #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) -- pKey = Tcl_GetByteArrayFromObj(objv[i+1], &nKey); -+ pKey = Tcl_GetByteArrayFromObj(objv[i], &nKey); - #endif - }else if( strcmp(zArg, "-vfs")==0 ){ -- zVfs = Tcl_GetString(objv[i+1]); -+ zVfs = Tcl_GetString(objv[i]); - }else if( strcmp(zArg, "-readonly")==0 ){ - int b; -- if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; -+ if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; - if( b ){ - flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); - flags |= SQLITE_OPEN_READONLY; -@@ -3401,7 +3550,7 @@ - } - }else if( strcmp(zArg, "-create")==0 ){ - int b; -- if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; -+ if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; - if( b && (flags & SQLITE_OPEN_READONLY)==0 ){ - flags |= SQLITE_OPEN_CREATE; - }else{ -@@ -3409,7 +3558,7 @@ - } - }else if( strcmp(zArg, "-nomutex")==0 ){ - int b; -- if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; -+ if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; - if( b ){ - flags |= SQLITE_OPEN_NOMUTEX; - flags &= ~SQLITE_OPEN_FULLMUTEX; -@@ -3418,7 +3567,7 @@ - } - }else if( strcmp(zArg, "-fullmutex")==0 ){ - int b; -- if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; -+ if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; - if( b ){ - flags |= SQLITE_OPEN_FULLMUTEX; - flags &= ~SQLITE_OPEN_NOMUTEX; -@@ -3427,7 +3576,7 @@ - } - }else if( strcmp(zArg, "-uri")==0 ){ - int b; -- if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; -+ if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; - if( b ){ - flags |= SQLITE_OPEN_URI; - }else{ -@@ -3438,20 +3587,10 @@ - return TCL_ERROR; - } - } -- if( objc<3 || (objc&1)!=1 ){ -- Tcl_WrongNumArgs(interp, 1, objv, -- "HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?" -- " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" --#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) -- " ?-key CODECKEY?" --#endif -- ); -- return TCL_ERROR; -- } - zErrMsg = 0; - p = (SqliteDb*)Tcl_Alloc( sizeof(*p) ); - memset(p, 0, sizeof(*p)); -- zFile = Tcl_GetStringFromObj(objv[2], 0); -+ if( zFile==0 ) zFile = ""; - zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename); - rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs); - Tcl_DStringFree(&translatedFilename); -@@ -3551,731 +3690,74 @@ - int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } - #endif - --#ifdef TCLSH --/***************************************************************************** --** All of the code that follows is used to build standalone TCL interpreters --** that are statically linked with SQLite. Enable these by compiling --** with -DTCLSH=n where n can be 1 or 2. An n of 1 generates a standard --** tclsh but with SQLite built in. An n of 2 generates the SQLite space --** analysis program. --*/ -- --#if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5) - /* -- * This code implements the MD5 message-digest algorithm. -- * The algorithm is due to Ron Rivest. This code was -- * written by Colin Plumb in 1993, no copyright is claimed. -- * This code is in the public domain; do with it what you wish. -- * -- * Equivalent code is available from RSA Data Security, Inc. -- * This code has been tested against that, and is equivalent, -- * except that you don't need to include two pages of legalese -- * with every copy. -- * -- * To compute the message digest of a chunk of bytes, declare an -- * MD5Context structure, pass it to MD5Init, call MD5Update as -- * needed on buffers full of bytes, and then call MD5Final, which -- * will fill a supplied 16-byte array with the digest. -- */ -- --/* -- * If compiled on a machine that doesn't have a 32-bit integer, -- * you just set "uint32" to the appropriate datatype for an -- * unsigned 32-bit integer. For example: -- * -- * cc -Duint32='unsigned long' md5.c -- * -- */ --#ifndef uint32 --# define uint32 unsigned int --#endif -- --struct MD5Context { -- int isInit; -- uint32 buf[4]; -- uint32 bits[2]; -- unsigned char in[64]; --}; --typedef struct MD5Context MD5Context; -- --/* -- * Note: this code is harmless on little-endian machines. -- */ --static void byteReverse (unsigned char *buf, unsigned longs){ -- uint32 t; -- do { -- t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 | -- ((unsigned)buf[1]<<8 | buf[0]); -- *(uint32 *)buf = t; -- buf += 4; -- } while (--longs); --} --/* The four core functions - F1 is optimized somewhat */ -- --/* #define F1(x, y, z) (x & y | ~x & z) */ --#define F1(x, y, z) (z ^ (x & (y ^ z))) --#define F2(x, y, z) F1(z, x, y) --#define F3(x, y, z) (x ^ y ^ z) --#define F4(x, y, z) (y ^ (x | ~z)) -- --/* This is the central step in the MD5 algorithm. */ --#define MD5STEP(f, w, x, y, z, data, s) \ -- ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) -- --/* -- * The core of the MD5 algorithm, this alters an existing MD5 hash to -- * reflect the addition of 16 longwords of new data. MD5Update blocks -- * the data and converts bytes into longwords for this routine. -- */ --static void MD5Transform(uint32 buf[4], const uint32 in[16]){ -- register uint32 a, b, c, d; -- -- a = buf[0]; -- b = buf[1]; -- c = buf[2]; -- d = buf[3]; -- -- MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7); -- MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12); -- MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17); -- MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22); -- MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7); -- MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12); -- MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17); -- MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22); -- MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7); -- MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12); -- MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17); -- MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22); -- MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7); -- MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12); -- MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17); -- MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22); -- -- MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5); -- MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9); -- MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14); -- MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20); -- MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5); -- MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9); -- MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14); -- MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20); -- MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5); -- MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9); -- MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14); -- MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20); -- MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5); -- MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9); -- MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14); -- MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20); -- -- MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4); -- MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11); -- MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16); -- MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23); -- MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4); -- MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11); -- MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16); -- MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23); -- MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4); -- MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11); -- MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16); -- MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23); -- MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4); -- MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11); -- MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16); -- MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23); -- -- MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6); -- MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10); -- MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15); -- MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21); -- MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6); -- MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10); -- MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15); -- MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21); -- MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6); -- MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10); -- MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15); -- MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21); -- MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6); -- MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10); -- MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15); -- MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21); -- -- buf[0] += a; -- buf[1] += b; -- buf[2] += c; -- buf[3] += d; --} -- --/* -- * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious -- * initialization constants. -- */ --static void MD5Init(MD5Context *ctx){ -- ctx->isInit = 1; -- ctx->buf[0] = 0x67452301; -- ctx->buf[1] = 0xefcdab89; -- ctx->buf[2] = 0x98badcfe; -- ctx->buf[3] = 0x10325476; -- ctx->bits[0] = 0; -- ctx->bits[1] = 0; --} -- --/* -- * Update context to reflect the concatenation of another buffer full -- * of bytes. -- */ --static --void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){ -- uint32 t; -- -- /* Update bitcount */ -- -- t = ctx->bits[0]; -- if ((ctx->bits[0] = t + ((uint32)len << 3)) < t) -- ctx->bits[1]++; /* Carry from low to high */ -- ctx->bits[1] += len >> 29; -- -- t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ -- -- /* Handle any leading odd-sized chunks */ -- -- if ( t ) { -- unsigned char *p = (unsigned char *)ctx->in + t; -- -- t = 64-t; -- if (len < t) { -- memcpy(p, buf, len); -- return; -- } -- memcpy(p, buf, t); -- byteReverse(ctx->in, 16); -- MD5Transform(ctx->buf, (uint32 *)ctx->in); -- buf += t; -- len -= t; -- } -- -- /* Process data in 64-byte chunks */ -- -- while (len >= 64) { -- memcpy(ctx->in, buf, 64); -- byteReverse(ctx->in, 16); -- MD5Transform(ctx->buf, (uint32 *)ctx->in); -- buf += 64; -- len -= 64; -- } -- -- /* Handle any remaining bytes of data. */ -- -- memcpy(ctx->in, buf, len); --} -- --/* -- * Final wrapup - pad to 64-byte boundary with the bit pattern -- * 1 0* (64-bit count of bits processed, MSB-first) -- */ --static void MD5Final(unsigned char digest[16], MD5Context *ctx){ -- unsigned count; -- unsigned char *p; -- -- /* Compute number of bytes mod 64 */ -- count = (ctx->bits[0] >> 3) & 0x3F; -- -- /* Set the first char of padding to 0x80. This is safe since there is -- always at least one byte free */ -- p = ctx->in + count; -- *p++ = 0x80; -- -- /* Bytes of padding needed to make 64 bytes */ -- count = 64 - 1 - count; -- -- /* Pad out to 56 mod 64 */ -- if (count < 8) { -- /* Two lots of padding: Pad the first block to 64 bytes */ -- memset(p, 0, count); -- byteReverse(ctx->in, 16); -- MD5Transform(ctx->buf, (uint32 *)ctx->in); -- -- /* Now fill the next block with 56 bytes */ -- memset(ctx->in, 0, 56); -- } else { -- /* Pad block to 56 bytes */ -- memset(p, 0, count-8); -- } -- byteReverse(ctx->in, 14); -- -- /* Append length in bits and transform */ -- memcpy(ctx->in + 14*4, ctx->bits, 8); -- -- MD5Transform(ctx->buf, (uint32 *)ctx->in); -- byteReverse((unsigned char *)ctx->buf, 4); -- memcpy(digest, ctx->buf, 16); --} -- --/* --** Convert a 128-bit MD5 digest into a 32-digit base-16 number. -+** If the TCLSH macro is defined, add code to make a stand-alone program. - */ --static void MD5DigestToBase16(unsigned char *digest, char *zBuf){ -- static char const zEncode[] = "0123456789abcdef"; -- int i, j; -+#if defined(TCLSH) - -- for(j=i=0; i<16; i++){ -- int a = digest[i]; -- zBuf[j++] = zEncode[(a>>4)&0xf]; -- zBuf[j++] = zEncode[a & 0xf]; -- } -- zBuf[j] = 0; --} -- -- --/* --** Convert a 128-bit MD5 digest into sequency of eight 5-digit integers --** each representing 16 bits of the digest and separated from each --** other by a "-" character. -+/* This is the main routine for an ordinary TCL shell. If there are -+** are arguments, run the first argument as a script. Otherwise, -+** read TCL commands from standard input - */ --static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){ -- int i, j; -- unsigned int x; -- for(i=j=0; i<16; i+=2){ -- x = digest[i]*256 + digest[i+1]; -- if( i>0 ) zDigest[j++] = '-'; -- sqlite3_snprintf(50-j, &zDigest[j], "%05u", x); -- j += 5; -- } -- zDigest[j] = 0; --} -- --/* --** A TCL command for md5. The argument is the text to be hashed. The --** Result is the hash in base64. --*/ --static int SQLITE_TCLAPI md5_cmd( -- void*cd, -- Tcl_Interp *interp, -- int argc, -- const char **argv --){ -- MD5Context ctx; -- unsigned char digest[16]; -- char zBuf[50]; -- void (*converter)(unsigned char*, char*); -- -- if( argc!=2 ){ -- Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], -- " TEXT\"", (char*)0); -- return TCL_ERROR; -- } -- MD5Init(&ctx); -- MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1])); -- MD5Final(digest, &ctx); -- converter = (void(*)(unsigned char*,char*))cd; -- converter(digest, zBuf); -- Tcl_AppendResult(interp, zBuf, (char*)0); -- return TCL_OK; --} -- --/* --** A TCL command to take the md5 hash of a file. The argument is the --** name of the file. --*/ --static int SQLITE_TCLAPI md5file_cmd( -- void*cd, -- Tcl_Interp *interp, -- int argc, -- const char **argv --){ -- FILE *in; -- MD5Context ctx; -- void (*converter)(unsigned char*, char*); -- unsigned char digest[16]; -- char zBuf[10240]; -- -- if( argc!=2 ){ -- Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], -- " FILENAME\"", (char*)0); -- return TCL_ERROR; -- } -- in = fopen(argv[1],"rb"); -- if( in==0 ){ -- Tcl_AppendResult(interp,"unable to open file \"", argv[1], -- "\" for reading", (char*)0); -- return TCL_ERROR; -- } -- MD5Init(&ctx); -- for(;;){ -- int n; -- n = (int)fread(zBuf, 1, sizeof(zBuf), in); -- if( n<=0 ) break; -- MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n); -- } -- fclose(in); -- MD5Final(digest, &ctx); -- converter = (void(*)(unsigned char*,char*))cd; -- converter(digest, zBuf); -- Tcl_AppendResult(interp, zBuf, (char*)0); -- return TCL_OK; --} -- --/* --** Register the four new TCL commands for generating MD5 checksums --** with the TCL interpreter. --*/ --int Md5_Init(Tcl_Interp *interp){ -- Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd, -- MD5DigestToBase16, 0); -- Tcl_CreateCommand(interp, "md5-10x8", (Tcl_CmdProc*)md5_cmd, -- MD5DigestToBase10x8, 0); -- Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd, -- MD5DigestToBase16, 0); -- Tcl_CreateCommand(interp, "md5file-10x8", (Tcl_CmdProc*)md5file_cmd, -- MD5DigestToBase10x8, 0); -- return TCL_OK; --} --#endif /* defined(SQLITE_TEST) || defined(SQLITE_TCLMD5) */ -- --#if defined(SQLITE_TEST) --/* --** During testing, the special md5sum() aggregate function is available. --** inside SQLite. The following routines implement that function. --*/ --static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){ -- MD5Context *p; -- int i; -- if( argc<1 ) return; -- p = sqlite3_aggregate_context(context, sizeof(*p)); -- if( p==0 ) return; -- if( !p->isInit ){ -- MD5Init(p); -- } -- for(i=0; i<argc; i++){ -- const char *zData = (char*)sqlite3_value_text(argv[i]); -- if( zData ){ -- MD5Update(p, (unsigned char*)zData, (int)strlen(zData)); -- } -- } --} --static void md5finalize(sqlite3_context *context){ -- MD5Context *p; -- unsigned char digest[16]; -- char zBuf[33]; -- p = sqlite3_aggregate_context(context, sizeof(*p)); -- MD5Final(digest,p); -- MD5DigestToBase16(digest, zBuf); -- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); --} --int Md5_Register( -- sqlite3 *db, -- char **pzErrMsg, -- const sqlite3_api_routines *pThunk --){ -- int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0, -- md5step, md5finalize); -- sqlite3_overload_function(db, "md5sum", -1); /* To exercise this API */ -- return rc; --} --#endif /* defined(SQLITE_TEST) */ -- -- --/* --** If the macro TCLSH is one, then put in code this for the --** "main" routine that will initialize Tcl and take input from --** standard input, or if a file is named on the command line --** the TCL interpreter reads and evaluates that file. --*/ --#if TCLSH==1 - static const char *tclsh_main_loop(void){ - static const char zMainloop[] = -- "set line {}\n" -- "while {![eof stdin]} {\n" -- "if {$line!=\"\"} {\n" -- "puts -nonewline \"> \"\n" -- "} else {\n" -- "puts -nonewline \"% \"\n" -- "}\n" -- "flush stdout\n" -- "append line [gets stdin]\n" -- "if {[info complete $line]} {\n" -- "if {[catch {uplevel #0 $line} result]} {\n" -- "puts stderr \"Error: $result\"\n" -- "} elseif {$result!=\"\"} {\n" -- "puts $result\n" -+ "if {[llength $argv]>=1} {\n" -+ "set argv0 [lindex $argv 0]\n" -+ "set argv [lrange $argv 1 end]\n" -+ "source $argv0\n" -+ "} else {\n" -+ "set line {}\n" -+ "while {![eof stdin]} {\n" -+ "if {$line!=\"\"} {\n" -+ "puts -nonewline \"> \"\n" -+ "} else {\n" -+ "puts -nonewline \"% \"\n" - "}\n" -- "set line {}\n" -- "} else {\n" -- "append line \\n\n" -+ "flush stdout\n" -+ "append line [gets stdin]\n" -+ "if {[info complete $line]} {\n" -+ "if {[catch {uplevel #0 $line} result]} {\n" -+ "puts stderr \"Error: $result\"\n" -+ "} elseif {$result!=\"\"} {\n" -+ "puts $result\n" -+ "}\n" -+ "set line {}\n" -+ "} else {\n" -+ "append line \\n\n" -+ "}\n" - "}\n" - "}\n" - ; - return zMainloop; - } --#endif --#if TCLSH==2 --static const char *tclsh_main_loop(void); --#endif - --#ifdef SQLITE_TEST --static void init_all(Tcl_Interp *); --static int SQLITE_TCLAPI init_all_cmd( -- ClientData cd, -- Tcl_Interp *interp, -- int objc, -- Tcl_Obj *CONST objv[] --){ -- -- Tcl_Interp *slave; -- if( objc!=2 ){ -- Tcl_WrongNumArgs(interp, 1, objv, "SLAVE"); -- return TCL_ERROR; -- } -- -- slave = Tcl_GetSlave(interp, Tcl_GetString(objv[1])); -- if( !slave ){ -- return TCL_ERROR; -- } -- -- init_all(slave); -- return TCL_OK; --} -- --/* --** Tclcmd: db_use_legacy_prepare DB BOOLEAN --** --** The first argument to this command must be a database command created by --** [sqlite3]. If the second argument is true, then the handle is configured --** to use the sqlite3_prepare_v2() function to prepare statements. If it --** is false, sqlite3_prepare(). --*/ --static int SQLITE_TCLAPI db_use_legacy_prepare_cmd( -- ClientData cd, -- Tcl_Interp *interp, -- int objc, -- Tcl_Obj *CONST objv[] --){ -- Tcl_CmdInfo cmdInfo; -- SqliteDb *pDb; -- int bPrepare; -- -- if( objc!=3 ){ -- Tcl_WrongNumArgs(interp, 1, objv, "DB BOOLEAN"); -- return TCL_ERROR; -- } -- -- if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){ -- Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0); -- return TCL_ERROR; -- } -- pDb = (SqliteDb*)cmdInfo.objClientData; -- if( Tcl_GetBooleanFromObj(interp, objv[2], &bPrepare) ){ -- return TCL_ERROR; -- } -- -- pDb->bLegacyPrepare = bPrepare; -- -- Tcl_ResetResult(interp); -- return TCL_OK; --} -- --/* --** Tclcmd: db_last_stmt_ptr DB --** --** If the statement cache associated with database DB is not empty, --** return the text representation of the most recently used statement --** handle. --*/ --static int SQLITE_TCLAPI db_last_stmt_ptr( -- ClientData cd, -- Tcl_Interp *interp, -- int objc, -- Tcl_Obj *CONST objv[] --){ -- extern int sqlite3TestMakePointerStr(Tcl_Interp*, char*, void*); -- Tcl_CmdInfo cmdInfo; -- SqliteDb *pDb; -- sqlite3_stmt *pStmt = 0; -- char zBuf[100]; -- -- if( objc!=2 ){ -- Tcl_WrongNumArgs(interp, 1, objv, "DB"); -- return TCL_ERROR; -- } -- -- if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){ -- Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0); -- return TCL_ERROR; -- } -- pDb = (SqliteDb*)cmdInfo.objClientData; -- -- if( pDb->stmtList ) pStmt = pDb->stmtList->pStmt; -- if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ){ -- return TCL_ERROR; -- } -- Tcl_SetResult(interp, zBuf, TCL_VOLATILE); -- -- return TCL_OK; --} --#endif /* SQLITE_TEST */ -- --/* --** Configure the interpreter passed as the first argument to have access --** to the commands and linked variables that make up: --** --** * the [sqlite3] extension itself, --** --** * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and --** --** * If SQLITE_TEST is set, the various test interfaces used by the Tcl --** test suite. --*/ --static void init_all(Tcl_Interp *interp){ -- Sqlite3_Init(interp); -- --#if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5) -- Md5_Init(interp); --#endif -- --#ifdef SQLITE_TEST -- { -- extern int Sqliteconfig_Init(Tcl_Interp*); -- extern int Sqlitetest1_Init(Tcl_Interp*); -- extern int Sqlitetest2_Init(Tcl_Interp*); -- extern int Sqlitetest3_Init(Tcl_Interp*); -- extern int Sqlitetest4_Init(Tcl_Interp*); -- extern int Sqlitetest5_Init(Tcl_Interp*); -- extern int Sqlitetest6_Init(Tcl_Interp*); -- extern int Sqlitetest7_Init(Tcl_Interp*); -- extern int Sqlitetest8_Init(Tcl_Interp*); -- extern int Sqlitetest9_Init(Tcl_Interp*); -- extern int Sqlitetestasync_Init(Tcl_Interp*); -- extern int Sqlitetest_autoext_Init(Tcl_Interp*); -- extern int Sqlitetest_blob_Init(Tcl_Interp*); -- extern int Sqlitetest_demovfs_Init(Tcl_Interp *); -- extern int Sqlitetest_func_Init(Tcl_Interp*); -- extern int Sqlitetest_hexio_Init(Tcl_Interp*); -- extern int Sqlitetest_init_Init(Tcl_Interp*); -- extern int Sqlitetest_malloc_Init(Tcl_Interp*); -- extern int Sqlitetest_mutex_Init(Tcl_Interp*); -- extern int Sqlitetestschema_Init(Tcl_Interp*); -- extern int Sqlitetestsse_Init(Tcl_Interp*); -- extern int Sqlitetesttclvar_Init(Tcl_Interp*); -- extern int Sqlitetestfs_Init(Tcl_Interp*); -- extern int SqlitetestThread_Init(Tcl_Interp*); -- extern int SqlitetestOnefile_Init(); -- extern int SqlitetestOsinst_Init(Tcl_Interp*); -- extern int Sqlitetestbackup_Init(Tcl_Interp*); -- extern int Sqlitetestintarray_Init(Tcl_Interp*); -- extern int Sqlitetestvfs_Init(Tcl_Interp *); -- extern int Sqlitetestrtree_Init(Tcl_Interp*); -- extern int Sqlitequota_Init(Tcl_Interp*); -- extern int Sqlitemultiplex_Init(Tcl_Interp*); -- extern int SqliteSuperlock_Init(Tcl_Interp*); -- extern int SqlitetestSyscall_Init(Tcl_Interp*); --#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK) -- extern int TestSession_Init(Tcl_Interp*); --#endif -- extern int Fts5tcl_Init(Tcl_Interp *); -- extern int SqliteRbu_Init(Tcl_Interp*); -- extern int Sqlitetesttcl_Init(Tcl_Interp*); --#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) -- extern int Sqlitetestfts3_Init(Tcl_Interp *interp); --#endif -- --#ifdef SQLITE_ENABLE_ZIPVFS -- extern int Zipvfs_Init(Tcl_Interp*); -- Zipvfs_Init(interp); --#endif -- -- Sqliteconfig_Init(interp); -- Sqlitetest1_Init(interp); -- Sqlitetest2_Init(interp); -- Sqlitetest3_Init(interp); -- Sqlitetest4_Init(interp); -- Sqlitetest5_Init(interp); -- Sqlitetest6_Init(interp); -- Sqlitetest7_Init(interp); -- Sqlitetest8_Init(interp); -- Sqlitetest9_Init(interp); -- Sqlitetestasync_Init(interp); -- Sqlitetest_autoext_Init(interp); -- Sqlitetest_blob_Init(interp); -- Sqlitetest_demovfs_Init(interp); -- Sqlitetest_func_Init(interp); -- Sqlitetest_hexio_Init(interp); -- Sqlitetest_init_Init(interp); -- Sqlitetest_malloc_Init(interp); -- Sqlitetest_mutex_Init(interp); -- Sqlitetestschema_Init(interp); -- Sqlitetesttclvar_Init(interp); -- Sqlitetestfs_Init(interp); -- SqlitetestThread_Init(interp); -- SqlitetestOnefile_Init(); -- SqlitetestOsinst_Init(interp); -- Sqlitetestbackup_Init(interp); -- Sqlitetestintarray_Init(interp); -- Sqlitetestvfs_Init(interp); -- Sqlitetestrtree_Init(interp); -- Sqlitequota_Init(interp); -- Sqlitemultiplex_Init(interp); -- SqliteSuperlock_Init(interp); -- SqlitetestSyscall_Init(interp); --#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK) -- TestSession_Init(interp); --#endif -- Fts5tcl_Init(interp); -- SqliteRbu_Init(interp); -- Sqlitetesttcl_Init(interp); -- --#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) -- Sqlitetestfts3_Init(interp); --#endif -- -- Tcl_CreateObjCommand( -- interp, "load_testfixture_extensions", init_all_cmd, 0, 0 -- ); -- Tcl_CreateObjCommand( -- interp, "db_use_legacy_prepare", db_use_legacy_prepare_cmd, 0, 0 -- ); -- Tcl_CreateObjCommand( -- interp, "db_last_stmt_ptr", db_last_stmt_ptr, 0, 0 -- ); -- --#ifdef SQLITE_SSE -- Sqlitetestsse_Init(interp); --#endif -- } --#endif --} -- --/* Needed for the setrlimit() system call on unix */ --#if defined(unix) --#include <sys/resource.h> --#endif -- - #define TCLSH_MAIN main /* Needed to fake out mktclapp */ - int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){ - Tcl_Interp *interp; -+ int i; -+ const char *zScript = 0; -+ char zArgc[32]; -+#if defined(TCLSH_INIT_PROC) -+ extern const char *TCLSH_INIT_PROC(Tcl_Interp*); -+#endif - - #if !defined(_WIN32_WCE) -- if( getenv("BREAK") ){ -- fprintf(stderr, -- "attach debugger to process %d and press any key to continue.\n", -- GETPID()); -- fgetc(stdin); -+ if( getenv("SQLITE_DEBUG_BREAK") ){ -+ if( isatty(0) && isatty(2) ){ -+ fprintf(stderr, -+ "attach debugger to process %d and press any key to continue.\n", -+ GETPID()); -+ fgetc(stdin); -+ }else{ -+#if defined(_WIN32) || defined(WIN32) -+ DebugBreak(); -+#elif defined(SIGTRAP) -+ raise(SIGTRAP); -+#endif -+ } - } - #endif - -- /* Since the primary use case for this binary is testing of SQLite, -- ** be sure to generate core files if we crash */ --#if defined(SQLITE_TEST) && defined(unix) -- { struct rlimit x; -- getrlimit(RLIMIT_CORE, &x); -- x.rlim_cur = x.rlim_max; -- setrlimit(RLIMIT_CORE, &x); -- } --#endif /* SQLITE_TEST && unix */ -- -- - /* Call sqlite3_shutdown() once before doing anything else. This is to - ** test that sqlite3_shutdown() can be safely called by a process before - ** sqlite3_initialize() is. */ -@@ -4284,32 +3766,27 @@ - Tcl_FindExecutable(argv[0]); - Tcl_SetSystemEncoding(NULL, "utf-8"); - interp = Tcl_CreateInterp(); -+ Sqlite3_Init(interp); - --#if TCLSH==2 -- sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); -+ sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-1); -+ Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY); -+ Tcl_SetVar(interp,"argv0",argv[0],TCL_GLOBAL_ONLY); -+ Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY); -+ for(i=1; i<argc; i++){ -+ Tcl_SetVar(interp, "argv", argv[i], -+ TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE); -+ } -+#if defined(TCLSH_INIT_PROC) -+ zScript = TCLSH_INIT_PROC(interp); - #endif -- -- init_all(interp); -- if( argc>=2 ){ -- int i; -- char zArgc[32]; -- sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-(3-TCLSH)); -- Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY); -- Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY); -- Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY); -- for(i=3-TCLSH; i<argc; i++){ -- Tcl_SetVar(interp, "argv", argv[i], -- TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE); -- } -- if( TCLSH==1 && Tcl_EvalFile(interp, argv[1])!=TCL_OK ){ -- const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); -- if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp); -- fprintf(stderr,"%s: %s\n", *argv, zInfo); -- return 1; -- } -+ if( zScript==0 ){ -+ zScript = tclsh_main_loop(); - } -- if( TCLSH==2 || argc<=1 ){ -- Tcl_GlobalEval(interp, tclsh_main_loop()); -+ if( Tcl_GlobalEval(interp, zScript)!=TCL_OK ){ -+ const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); -+ if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp); -+ fprintf(stderr,"%s: %s\n", *argv, zInfo); -+ return 1; - } - return 0; - } |