Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 336636f61b |
+6
-7
@@ -566,7 +566,6 @@ SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
|
||||
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
||||
FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
|
||||
DBFUZZ_OPT =
|
||||
|
||||
@@ -621,8 +620,7 @@ fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS)
|
||||
|
||||
ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \
|
||||
$(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS)
|
||||
$(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c sqlite3.c sqlite3.h $(TLIBS)
|
||||
|
||||
dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS)
|
||||
@@ -1155,10 +1153,6 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
|
||||
sqlite3_analyzer$(TEXE): sqlite3_analyzer.c
|
||||
$(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS)
|
||||
|
||||
dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo
|
||||
$(LTLINK) -DDBDUMP_STANDALONE -o $@ \
|
||||
$(TOP)/ext/misc/dbdump.c sqlite3.lo $(TLIBS)
|
||||
|
||||
showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.lo
|
||||
$(LTLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(TLIBS)
|
||||
|
||||
@@ -1191,6 +1185,11 @@ KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ
|
||||
kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c
|
||||
$(LTLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(TLIBS)
|
||||
|
||||
DBSELFTEST_OPT += -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS4
|
||||
|
||||
dbselftest$(TEXE): $(TOP)/test/dbselftest.c sqlite3.c
|
||||
$(LTLINK) $(DBSELFTEST_OPT) -o $@ $(TOP)/test/dbselftest.c sqlite3.c $(TLIBS)
|
||||
|
||||
rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo
|
||||
$(LTLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.lo $(TLIBS)
|
||||
|
||||
|
||||
+5
-12
@@ -21,7 +21,7 @@ USE_AMALGAMATION = 1
|
||||
# Set this non-0 to enable full warnings (-W4, etc) when compiling.
|
||||
#
|
||||
!IFNDEF USE_FULLWARN
|
||||
USE_FULLWARN = 1
|
||||
USE_FULLWARN = 0
|
||||
!ENDIF
|
||||
|
||||
# Set this non-0 to enable treating warnings as errors (-WX, etc) when
|
||||
@@ -745,11 +745,8 @@ RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
|
||||
|
||||
!IF $(DEBUG)>2
|
||||
TCC = $(TCC) -DSQLITE_DEBUG=1
|
||||
RCC = $(RCC) -DSQLITE_DEBUG=1
|
||||
!IF $(DYNAMIC_SHELL)==0
|
||||
TCC = $(TCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE
|
||||
RCC = $(RCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE
|
||||
!ENDIF
|
||||
RCC = $(RCC) -DSQLITE_DEBUG=1
|
||||
!ENDIF
|
||||
|
||||
!IF $(DEBUG)>4 || $(OSTRACE)!=0
|
||||
@@ -1513,7 +1510,7 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_
|
||||
#
|
||||
MPTESTER_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS5
|
||||
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000
|
||||
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
|
||||
FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c
|
||||
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
|
||||
DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
|
||||
@@ -1562,7 +1559,7 @@ $(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
|
||||
sqlite3.def: libsqlite3.lib
|
||||
echo EXPORTS > sqlite3.def
|
||||
dumpbin /all libsqlite3.lib \
|
||||
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset|changegroup)?_[^@]*)(?:@\d+)?$$" \1 \
|
||||
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset)?_[^@]*)(?:@\d+)?$$" \1 \
|
||||
| sort >> sqlite3.def
|
||||
# <</block2>>
|
||||
|
||||
@@ -2181,10 +2178,6 @@ sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS)
|
||||
$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \
|
||||
/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||
|
||||
dbdump.exe: $(TOP)\ext\misc\dbdump.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DDBDUMP_STANDALONE $(TOP)\ext\misc\dbdump.c $(SQLITE3C) \
|
||||
/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS)
|
||||
|
||||
testloadext.lo: $(TOP)\src\test_loadext.c
|
||||
$(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c
|
||||
|
||||
@@ -2263,7 +2256,7 @@ clean:
|
||||
del /Q tclsqlite3.exe $(SQLITETCLH) $(SQLITETCLDECLSH) 2>NUL
|
||||
del /Q testloadext.dll 2>NUL
|
||||
del /Q testfixture.exe test.db 2>NUL
|
||||
del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe dbdump.exe 2>NUL
|
||||
del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe 2>NUL
|
||||
del /Q changeset.exe 2>NUL
|
||||
del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL
|
||||
del /Q mptester.exe wordcount.exe rbu.exe srcck1.exe 2>NUL
|
||||
|
||||
@@ -8,48 +8,6 @@ If you are reading this on a Git mirror someplace, you are doing it wrong.
|
||||
The [official repository](https://www.sqlite.org/src/) is better. Go there
|
||||
now.
|
||||
|
||||
## Obtaining The Code
|
||||
|
||||
SQLite sources are managed using the
|
||||
[Fossil](https://www.fossil-scm.org/), a distributed version control system
|
||||
that was specifically designed to support SQLite development.
|
||||
If you do not want to use Fossil, you can download tarballs or ZIP
|
||||
archives as follows:
|
||||
|
||||
* Lastest trunk check-in:
|
||||
<https://www.sqlite.org/src/tarball/sqlite.tar.gz> or
|
||||
<https://www.sqlite.org/src/zip/sqlite.zip>.
|
||||
|
||||
* Latest release:
|
||||
<https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release> or
|
||||
<https://www.sqlite.org/src/zip/sqlite.zip?r=release>.
|
||||
|
||||
* For other check-ins, substitute an appropriate branch name or
|
||||
tag or hash prefix for "release" in the URLs of the previous
|
||||
bullet. Or browse the [timeline](https://www.sqlite.org/src/timeline)
|
||||
to locate the check-in desired, click on its information page link,
|
||||
then click on the "Tarball" or "ZIP Archive" links on the information
|
||||
page.
|
||||
|
||||
If you do want to use Fossil to check out the source tree,
|
||||
first install Fossil version 2.0 or later.
|
||||
(Source tarballs and precompiled binaries available
|
||||
[here](https://www.fossil-scm.org/fossil/uv/download.html).)
|
||||
Then run commands like this:
|
||||
|
||||
mkdir ~/sqlite
|
||||
cd ~/sqlite
|
||||
fossil clone https://www.sqlite.org/src sqlite.fossil
|
||||
fossil open sqlite.fossil
|
||||
|
||||
After setting up a repository using the steps above, you can always
|
||||
update to the lastest version using:
|
||||
|
||||
fossil update trunk ;# latest trunk check-in
|
||||
fossil update release ;# latest official release
|
||||
|
||||
Or type "fossil ui" to get a web-based user interface.
|
||||
|
||||
## Compiling
|
||||
|
||||
First create a directory in which to place
|
||||
@@ -60,13 +18,13 @@ script found at the root of the source tree. Then run "make".
|
||||
|
||||
For example:
|
||||
|
||||
tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite"
|
||||
mkdir bld ;# Build will occur in a sibling directory
|
||||
cd bld ;# Change to the build directory
|
||||
../sqlite/configure ;# Run the configure script
|
||||
make ;# Run the makefile.
|
||||
make sqlite3.c ;# Build the "amalgamation" source file
|
||||
make test ;# Run some tests (requires Tcl)
|
||||
tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite"
|
||||
mkdir bld ;# Build will occur in a sibling directory
|
||||
cd bld ;# Change to the build directory
|
||||
../sqlite/configure ;# Run the configure script
|
||||
make ;# Run the makefile.
|
||||
make sqlite3.c ;# Build the "amalgamation" source file
|
||||
make test ;# Run some tests (requires Tcl)
|
||||
|
||||
See the makefile for additional targets.
|
||||
|
||||
@@ -85,13 +43,13 @@ with the provided "Makefile.msc" to build one of the supported targets.
|
||||
|
||||
For example:
|
||||
|
||||
mkdir bld
|
||||
cd bld
|
||||
nmake /f Makefile.msc TOP=..\sqlite
|
||||
nmake /f Makefile.msc sqlite3.c TOP=..\sqlite
|
||||
nmake /f Makefile.msc sqlite3.dll TOP=..\sqlite
|
||||
nmake /f Makefile.msc sqlite3.exe TOP=..\sqlite
|
||||
nmake /f Makefile.msc test TOP=..\sqlite
|
||||
mkdir bld
|
||||
cd bld
|
||||
nmake /f Makefile.msc TOP=..\sqlite
|
||||
nmake /f Makefile.msc sqlite3.c TOP=..\sqlite
|
||||
nmake /f Makefile.msc sqlite3.dll TOP=..\sqlite
|
||||
nmake /f Makefile.msc sqlite3.exe TOP=..\sqlite
|
||||
nmake /f Makefile.msc test TOP=..\sqlite
|
||||
|
||||
There are several build options that can be set via the NMAKE command
|
||||
line. For example, to build for WinRT, simply add "FOR_WINRT=1" argument
|
||||
|
||||
@@ -21,7 +21,7 @@ TOP = .
|
||||
# Set this non-0 to enable full warnings (-W4, etc) when compiling.
|
||||
#
|
||||
!IFNDEF USE_FULLWARN
|
||||
USE_FULLWARN = 1
|
||||
USE_FULLWARN = 0
|
||||
!ENDIF
|
||||
|
||||
# Set this non-0 to enable treating warnings as errors (-WX, etc) when
|
||||
@@ -645,10 +645,6 @@ RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
|
||||
!IF $(DEBUG)>2
|
||||
TCC = $(TCC) -DSQLITE_DEBUG=1
|
||||
RCC = $(RCC) -DSQLITE_DEBUG=1
|
||||
!IF $(DYNAMIC_SHELL)==0
|
||||
TCC = $(TCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE
|
||||
RCC = $(RCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
!IF $(DEBUG)>4 || $(OSTRACE)!=0
|
||||
@@ -954,7 +950,7 @@ Replace.exe:
|
||||
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)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
|
||||
| sort >> sqlite3.def
|
||||
|
||||
$(SQLITE3EXE): $(TOP)\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
|
||||
|
||||
@@ -55,9 +55,9 @@ AS_IF([ test x"$enable_editline" != xno ],[
|
||||
LIBS=""
|
||||
AC_SEARCH_LIBS([readline],[edit],[
|
||||
AC_DEFINE([HAVE_EDITLINE],1,Define to use BSD editline)
|
||||
READLINE_LIBS="$LIBS -ltinfo"
|
||||
READLINE_LIBS=$LIBS
|
||||
enable_readline=no
|
||||
],[],[-ltinfo])
|
||||
])
|
||||
AS_UNSET(ac_cv_search_readline)
|
||||
LIBS=$sLIBS
|
||||
])
|
||||
|
||||
@@ -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.18.0.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
@@ -726,8 +726,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='sqlite'
|
||||
PACKAGE_TARNAME='sqlite'
|
||||
PACKAGE_VERSION='3.20.0'
|
||||
PACKAGE_STRING='sqlite 3.20.0'
|
||||
PACKAGE_VERSION='3.18.0'
|
||||
PACKAGE_STRING='sqlite 3.18.0'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -1463,7 +1463,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures sqlite 3.20.0 to adapt to many kinds of systems.
|
||||
\`configure' configures sqlite 3.18.0 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1528,7 +1528,7 @@ fi
|
||||
|
||||
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.18.0:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1652,7 +1652,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlite configure 3.20.0
|
||||
sqlite configure 3.18.0
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2071,7 +2071,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by sqlite $as_me 3.20.0, which was
|
||||
It was created by sqlite $as_me 3.18.0, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -11252,7 +11252,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${use_debug}" = "yes" ; then
|
||||
TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0"
|
||||
TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE"
|
||||
else
|
||||
TARGET_DEBUG="-DNDEBUG"
|
||||
fi
|
||||
@@ -11356,7 +11356,7 @@ fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS5" >&5
|
||||
$as_echo_n "checking whether to support MEMSYS5... " >&6; }
|
||||
if test "${enable_memsys5}" = "yes"; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS5"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS5"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
@@ -11373,7 +11373,7 @@ fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS3" >&5
|
||||
$as_echo_n "checking whether to support MEMSYS3... " >&6; }
|
||||
if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS3"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
@@ -11391,7 +11391,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_fts3}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS3"
|
||||
fi
|
||||
# Check whether --enable-fts4 was given.
|
||||
if test "${enable_fts4+set}" = set; then :
|
||||
@@ -11401,7 +11401,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_fts4}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS4"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5
|
||||
$as_echo_n "checking for library containing log... " >&6; }
|
||||
if ${ac_cv_search_log+:} false; then :
|
||||
@@ -11467,7 +11467,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_fts5}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS5"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5
|
||||
$as_echo_n "checking for library containing log... " >&6; }
|
||||
if ${ac_cv_search_log+:} false; then :
|
||||
@@ -11536,7 +11536,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_json1}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_JSON1"
|
||||
fi
|
||||
|
||||
#########
|
||||
@@ -11549,7 +11549,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_rtree}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_RTREE"
|
||||
fi
|
||||
|
||||
#########
|
||||
@@ -11562,12 +11562,12 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_session}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_SESSION"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_PREUPDATE_HOOK"
|
||||
fi
|
||||
|
||||
#########
|
||||
# attempt to duplicate any OMITS and ENABLES into the ${OPT_FEATURE_FLAGS} parameter
|
||||
# attempt to duplicate any OMITS and ENABLES into the $(OPT_FEATURE_FLAGS) parameter
|
||||
for option in $CFLAGS $CPPFLAGS
|
||||
do
|
||||
case $option in
|
||||
@@ -12151,7 +12151,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by sqlite $as_me 3.20.0, which was
|
||||
This file was extended by sqlite $as_me 3.18.0, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -12217,7 +12217,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
sqlite config.status 3.20.0
|
||||
sqlite config.status 3.18.0
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
+11
-11
@@ -560,7 +560,7 @@ AC_SEARCH_LIBS(fdatasync, [rt])
|
||||
AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],[enable debugging & verbose explain]),
|
||||
[use_debug=$enableval],[use_debug=no])
|
||||
if test "${use_debug}" = "yes" ; then
|
||||
TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0"
|
||||
TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE"
|
||||
else
|
||||
TARGET_DEBUG="-DNDEBUG"
|
||||
fi
|
||||
@@ -596,7 +596,7 @@ AC_ARG_ENABLE(memsys5,
|
||||
[enable_memsys5=yes],[enable_memsys5=no])
|
||||
AC_MSG_CHECKING([whether to support MEMSYS5])
|
||||
if test "${enable_memsys5}" = "yes"; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS5"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS5"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
@@ -606,7 +606,7 @@ AC_ARG_ENABLE(memsys3,
|
||||
[enable_memsys3=yes],[enable_memsys3=no])
|
||||
AC_MSG_CHECKING([whether to support MEMSYS3])
|
||||
if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS3"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
@@ -618,20 +618,20 @@ AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3],
|
||||
[Enable the FTS3 extension]),
|
||||
[enable_fts3=yes],[enable_fts3=no])
|
||||
if test "${enable_fts3}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS3"
|
||||
fi
|
||||
AC_ARG_ENABLE(fts4, AC_HELP_STRING([--enable-fts4],
|
||||
[Enable the FTS4 extension]),
|
||||
[enable_fts4=yes],[enable_fts4=no])
|
||||
if test "${enable_fts4}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS4"
|
||||
AC_SEARCH_LIBS([log],[m])
|
||||
fi
|
||||
AC_ARG_ENABLE(fts5, AC_HELP_STRING([--enable-fts5],
|
||||
[Enable the FTS5 extension]),
|
||||
[enable_fts5=yes],[enable_fts5=no])
|
||||
if test "${enable_fts5}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS5"
|
||||
AC_SEARCH_LIBS([log],[m])
|
||||
fi
|
||||
|
||||
@@ -641,7 +641,7 @@ AC_ARG_ENABLE(json1, AC_HELP_STRING([--enable-json1],
|
||||
[Enable the JSON1 extension]),
|
||||
[enable_json1=yes],[enable_json1=no])
|
||||
if test "${enable_json1}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_JSON1"
|
||||
fi
|
||||
|
||||
#########
|
||||
@@ -650,7 +650,7 @@ AC_ARG_ENABLE(rtree, AC_HELP_STRING([--enable-rtree],
|
||||
[Enable the RTREE extension]),
|
||||
[enable_rtree=yes],[enable_rtree=no])
|
||||
if test "${enable_rtree}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_RTREE"
|
||||
fi
|
||||
|
||||
#########
|
||||
@@ -659,12 +659,12 @@ AC_ARG_ENABLE(session, AC_HELP_STRING([--enable-session],
|
||||
[Enable the SESSION extension]),
|
||||
[enable_session=yes],[enable_session=no])
|
||||
if test "${enable_session}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_SESSION"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_PREUPDATE_HOOK"
|
||||
fi
|
||||
|
||||
#########
|
||||
# attempt to duplicate any OMITS and ENABLES into the ${OPT_FEATURE_FLAGS} parameter
|
||||
# attempt to duplicate any OMITS and ENABLES into the $(OPT_FEATURE_FLAGS) parameter
|
||||
for option in $CFLAGS $CPPFLAGS
|
||||
do
|
||||
case $option in
|
||||
|
||||
@@ -23,26 +23,6 @@ or embedded controllers.</p>
|
||||
<p>This document is an introduction to the Lemon
|
||||
parser generator.</p>
|
||||
|
||||
<h2>Security Note</h2>
|
||||
|
||||
<p>The language parser code created by Lemon is very robust and
|
||||
is well-suited for use in internet-facing applications that need to
|
||||
safely process maliciously crafted inputs.
|
||||
|
||||
<p>The "lemon.exe" command-line tool itself works great when given a valid
|
||||
input grammar file and almost always gives helpful
|
||||
error messages for malformed inputs. However, it is possible for
|
||||
a malicious user to craft a grammar file that will cause
|
||||
lemon.exe to crash.
|
||||
We do not see this as a problem, as lemon.exe is not intended to be used
|
||||
with hostile inputs.
|
||||
To summarize:</p>
|
||||
|
||||
<ul>
|
||||
<li>Parser code generated by lemon → Robust and secure
|
||||
<li>The "lemon.exe" command line tool itself → Not so much
|
||||
</ul>
|
||||
|
||||
<h2>Theory of Operation</h2>
|
||||
|
||||
<p>The main goal of Lemon is to translate a context free grammar (CFG)
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
## Loadable Extensions
|
||||
|
||||
Various [loadable extensions](https://www.sqlite.org/loadext.html) for
|
||||
SQLite are found in subfolders.
|
||||
|
||||
Most subfolders are dedicated to a single loadable extension (for
|
||||
example FTS5, or RTREE). But the misc/ subfolder contains a collection
|
||||
of smaller single-file extensions.
|
||||
@@ -0,0 +1,2 @@
|
||||
Version loadable extensions to SQLite are found in subfolders
|
||||
of this folder.
|
||||
+138
-138
@@ -349,9 +349,8 @@ int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){
|
||||
** Return the number of bytes read, or 0 on error.
|
||||
** The value is stored in *v.
|
||||
*/
|
||||
int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){
|
||||
const unsigned char *p = (const unsigned char*)pBuf;
|
||||
const unsigned char *pStart = p;
|
||||
int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){
|
||||
const char *pStart = p;
|
||||
u32 a;
|
||||
u64 b;
|
||||
int shift;
|
||||
@@ -372,8 +371,8 @@ int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){
|
||||
}
|
||||
|
||||
/*
|
||||
** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to
|
||||
** a non-negative 32-bit integer before it is returned.
|
||||
** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to a
|
||||
** 32-bit integer before it is returned.
|
||||
*/
|
||||
int sqlite3Fts3GetVarint32(const char *p, int *pi){
|
||||
u32 a;
|
||||
@@ -389,9 +388,7 @@ int sqlite3Fts3GetVarint32(const char *p, int *pi){
|
||||
GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *pi, 3);
|
||||
GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *pi, 4);
|
||||
a = (a & 0x0FFFFFFF );
|
||||
*pi = (int)(a | ((u32)(*p & 0x07) << 28));
|
||||
assert( 0==(a & 0x80000000) );
|
||||
assert( *pi>=0 );
|
||||
*pi = (int)(a | ((u32)(*p & 0x0F) << 28));
|
||||
return 5;
|
||||
}
|
||||
|
||||
@@ -1221,66 +1218,65 @@ static int fts3InitVtab(
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch( iOpt ){
|
||||
case 0: /* MATCHINFO */
|
||||
if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
bNoDocsize = 1;
|
||||
break;
|
||||
if( iOpt==SizeofArray(aFts4Opt) ){
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
switch( iOpt ){
|
||||
case 0: /* MATCHINFO */
|
||||
if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
bNoDocsize = 1;
|
||||
break;
|
||||
|
||||
case 1: /* PREFIX */
|
||||
sqlite3_free(zPrefix);
|
||||
zPrefix = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
case 1: /* PREFIX */
|
||||
sqlite3_free(zPrefix);
|
||||
zPrefix = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
|
||||
case 2: /* COMPRESS */
|
||||
sqlite3_free(zCompress);
|
||||
zCompress = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
case 2: /* COMPRESS */
|
||||
sqlite3_free(zCompress);
|
||||
zCompress = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
|
||||
case 3: /* UNCOMPRESS */
|
||||
sqlite3_free(zUncompress);
|
||||
zUncompress = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
case 3: /* UNCOMPRESS */
|
||||
sqlite3_free(zUncompress);
|
||||
zUncompress = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
|
||||
case 4: /* ORDER */
|
||||
if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
|
||||
&& (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
|
||||
){
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
|
||||
break;
|
||||
case 4: /* ORDER */
|
||||
if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
|
||||
&& (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
|
||||
){
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
|
||||
break;
|
||||
|
||||
case 5: /* CONTENT */
|
||||
sqlite3_free(zContent);
|
||||
zContent = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
case 5: /* CONTENT */
|
||||
sqlite3_free(zContent);
|
||||
zContent = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
|
||||
case 6: /* LANGUAGEID */
|
||||
assert( iOpt==6 );
|
||||
sqlite3_free(zLanguageid);
|
||||
zLanguageid = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
case 6: /* LANGUAGEID */
|
||||
assert( iOpt==6 );
|
||||
sqlite3_free(zLanguageid);
|
||||
zLanguageid = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
|
||||
case 7: /* NOTINDEXED */
|
||||
azNotindexed[nNotindexed++] = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( iOpt==SizeofArray(aFts4Opt) );
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
|
||||
rc = SQLITE_ERROR;
|
||||
break;
|
||||
case 7: /* NOTINDEXED */
|
||||
azNotindexed[nNotindexed++] = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sqlite3_free(zVal);
|
||||
}
|
||||
@@ -1401,9 +1397,7 @@ static int fts3InitVtab(
|
||||
char *z;
|
||||
int n = 0;
|
||||
z = (char *)sqlite3Fts3NextToken(aCol[iCol], &n);
|
||||
if( n>0 ){
|
||||
memcpy(zCsr, z, n);
|
||||
}
|
||||
memcpy(zCsr, z, n);
|
||||
zCsr[n] = '\0';
|
||||
sqlite3Fts3Dequote(zCsr);
|
||||
p->azColumn[iCol] = zCsr;
|
||||
@@ -1849,8 +1843,7 @@ static int fts3ScanInteriorNode(
|
||||
isFirstTerm = 0;
|
||||
zCsr += fts3GetVarint32(zCsr, &nSuffix);
|
||||
|
||||
assert( nPrefix>=0 && nSuffix>=0 );
|
||||
if( &zCsr[nSuffix]>zEnd ){
|
||||
if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){
|
||||
rc = FTS_CORRUPT_VTAB;
|
||||
goto finish_scan;
|
||||
}
|
||||
@@ -2660,7 +2653,7 @@ int sqlite3Fts3FirstFilter(
|
||||
fts3ColumnlistCopy(0, &p);
|
||||
}
|
||||
|
||||
while( p<pEnd ){
|
||||
while( p<pEnd && *p==0x01 ){
|
||||
sqlite3_int64 iCol;
|
||||
p++;
|
||||
p += sqlite3Fts3GetVarint(p, &iCol);
|
||||
@@ -3340,38 +3333,33 @@ static int fts3ColumnMethod(
|
||||
/* The column value supplied by SQLite must be in range. */
|
||||
assert( iCol>=0 && iCol<=p->nColumn+2 );
|
||||
|
||||
switch( iCol-p->nColumn ){
|
||||
case 0:
|
||||
/* The special 'table-name' column */
|
||||
sqlite3_result_blob(pCtx, &pCsr, sizeof(Fts3Cursor*), SQLITE_TRANSIENT);
|
||||
sqlite3_result_subtype(pCtx, SQLITE_BLOB);
|
||||
break;
|
||||
if( iCol==p->nColumn+1 ){
|
||||
/* This call is a request for the "docid" column. Since "docid" is an
|
||||
** alias for "rowid", use the xRowid() method to obtain the value.
|
||||
*/
|
||||
sqlite3_result_int64(pCtx, pCsr->iPrevId);
|
||||
}else if( iCol==p->nColumn ){
|
||||
/* The extra column whose name is the same as the table.
|
||||
** Return a blob which is a pointer to the cursor. */
|
||||
sqlite3_result_blob(pCtx, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT);
|
||||
}else if( iCol==p->nColumn+2 && pCsr->pExpr ){
|
||||
sqlite3_result_int64(pCtx, pCsr->iLangid);
|
||||
}else{
|
||||
/* The requested column is either a user column (one that contains
|
||||
** indexed data), or the language-id column. */
|
||||
rc = fts3CursorSeek(0, pCsr);
|
||||
|
||||
case 1:
|
||||
/* The docid column */
|
||||
sqlite3_result_int64(pCtx, pCsr->iPrevId);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if( pCsr->pExpr ){
|
||||
sqlite3_result_int64(pCtx, pCsr->iLangid);
|
||||
break;
|
||||
}else if( p->zLanguageid==0 ){
|
||||
sqlite3_result_int(pCtx, 0);
|
||||
break;
|
||||
}else{
|
||||
iCol = p->nColumn;
|
||||
/* fall-through */
|
||||
}
|
||||
|
||||
default:
|
||||
/* A user column. Or, if this is a full-table scan, possibly the
|
||||
** language-id column. Seek the cursor. */
|
||||
rc = fts3CursorSeek(0, pCsr);
|
||||
if( rc==SQLITE_OK && sqlite3_data_count(pCsr->pStmt)-1>iCol ){
|
||||
if( rc==SQLITE_OK ){
|
||||
if( iCol==p->nColumn+2 ){
|
||||
int iLangid = 0;
|
||||
if( p->zLanguageid ){
|
||||
iLangid = sqlite3_column_int(pCsr->pStmt, p->nColumn+1);
|
||||
}
|
||||
sqlite3_result_int(pCtx, iLangid);
|
||||
}else if( sqlite3_data_count(pCsr->pStmt)>(iCol+1) ){
|
||||
sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
|
||||
@@ -3451,11 +3439,17 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
|
||||
static int fts3SetHasStat(Fts3Table *p){
|
||||
int rc = SQLITE_OK;
|
||||
if( p->bHasStat==2 ){
|
||||
char *zTbl = sqlite3_mprintf("%s_stat", p->zName);
|
||||
if( zTbl ){
|
||||
int res = sqlite3_table_column_metadata(p->db, p->zDb, zTbl, 0,0,0,0,0,0);
|
||||
sqlite3_free(zTbl);
|
||||
p->bHasStat = (res==SQLITE_OK);
|
||||
const char *zFmt ="SELECT 1 FROM %Q.sqlite_master WHERE tbl_name='%q_stat'";
|
||||
char *zSql = sqlite3_mprintf(zFmt, p->zDb, p->zName);
|
||||
if( zSql ){
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
int bHasStat = (sqlite3_step(pStmt)==SQLITE_ROW);
|
||||
rc = sqlite3_finalize(pStmt);
|
||||
if( rc==SQLITE_OK ) p->bHasStat = (u8)bHasStat;
|
||||
}
|
||||
sqlite3_free(zSql);
|
||||
}else{
|
||||
rc = SQLITE_NOMEM;
|
||||
}
|
||||
@@ -3562,16 +3556,18 @@ static int fts3FunctionArg(
|
||||
sqlite3_value *pVal, /* argv[0] passed to function */
|
||||
Fts3Cursor **ppCsr /* OUT: Store cursor handle here */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
if( sqlite3_value_subtype(pVal)==SQLITE_BLOB ){
|
||||
*ppCsr = *(Fts3Cursor**)sqlite3_value_blob(pVal);
|
||||
}else{
|
||||
Fts3Cursor *pRet;
|
||||
if( sqlite3_value_type(pVal)!=SQLITE_BLOB
|
||||
|| sqlite3_value_bytes(pVal)!=sizeof(Fts3Cursor *)
|
||||
){
|
||||
char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc);
|
||||
sqlite3_result_error(pContext, zErr, -1);
|
||||
sqlite3_free(zErr);
|
||||
rc = SQLITE_ERROR;
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
return rc;
|
||||
memcpy(&pRet, sqlite3_value_blob(pVal), sizeof(Fts3Cursor *));
|
||||
*ppCsr = pRet;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3958,7 +3954,7 @@ int sqlite3Fts3Init(sqlite3 *db){
|
||||
#endif
|
||||
|
||||
/* Create the virtual table wrapper around the hash-table and overload
|
||||
** the four scalar functions. If this is successful, register the
|
||||
** the two scalar functions. If this is successful, register the
|
||||
** module with sqlite.
|
||||
*/
|
||||
if( SQLITE_OK==rc
|
||||
@@ -4541,7 +4537,7 @@ static int fts3EvalIncrPhraseNext(
|
||||
** one incremental token. In which case the bIncr flag is set. */
|
||||
assert( p->bIncr==1 );
|
||||
|
||||
if( p->nToken==1 ){
|
||||
if( p->nToken==1 && p->bIncr ){
|
||||
rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr,
|
||||
&pDL->iDocid, &pDL->pList, &pDL->nList
|
||||
);
|
||||
@@ -4774,7 +4770,6 @@ static void fts3EvalTokenCosts(
|
||||
** the number of overflow pages consumed by a record B bytes in size.
|
||||
*/
|
||||
static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){
|
||||
int rc = SQLITE_OK;
|
||||
if( pCsr->nRowAvg==0 ){
|
||||
/* The average document size, which is required to calculate the cost
|
||||
** of each doclist, has not yet been determined. Read the required
|
||||
@@ -4787,6 +4782,7 @@ static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){
|
||||
** data stored in all rows of each column of the table, from left
|
||||
** to right.
|
||||
*/
|
||||
int rc;
|
||||
Fts3Table *p = (Fts3Table*)pCsr->base.pVtab;
|
||||
sqlite3_stmt *pStmt;
|
||||
sqlite3_int64 nDoc = 0;
|
||||
@@ -4813,10 +4809,11 @@ static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){
|
||||
pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz);
|
||||
assert( pCsr->nRowAvg>0 );
|
||||
rc = sqlite3_reset(pStmt);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
|
||||
*pnPage = pCsr->nRowAvg;
|
||||
return rc;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5166,8 +5163,7 @@ static void fts3EvalNextRow(
|
||||
pExpr->iDocid = pLeft->iDocid;
|
||||
pExpr->bEof = (pLeft->bEof || pRight->bEof);
|
||||
if( pExpr->eType==FTSQUERY_NEAR && pExpr->bEof ){
|
||||
assert( pRight->eType==FTSQUERY_PHRASE );
|
||||
if( pRight->pPhrase->doclist.aAll ){
|
||||
if( pRight->pPhrase && pRight->pPhrase->doclist.aAll ){
|
||||
Fts3Doclist *pDl = &pRight->pPhrase->doclist;
|
||||
while( *pRc==SQLITE_OK && pRight->bEof==0 ){
|
||||
memset(pDl->pList, 0, pDl->nList);
|
||||
@@ -5196,7 +5192,7 @@ static void fts3EvalNextRow(
|
||||
|
||||
if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){
|
||||
fts3EvalNextRow(pCsr, pLeft, pRc);
|
||||
}else if( pLeft->bEof || iCmp>0 ){
|
||||
}else if( pLeft->bEof || (pRight->bEof==0 && iCmp>0) ){
|
||||
fts3EvalNextRow(pCsr, pRight, pRc);
|
||||
}else{
|
||||
fts3EvalNextRow(pCsr, pLeft, pRc);
|
||||
@@ -5288,6 +5284,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
|
||||
*/
|
||||
if( *pRc==SQLITE_OK
|
||||
&& pExpr->eType==FTSQUERY_NEAR
|
||||
&& pExpr->bEof==0
|
||||
&& (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR)
|
||||
){
|
||||
Fts3Expr *p;
|
||||
@@ -5296,39 +5293,42 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
|
||||
|
||||
/* Allocate temporary working space. */
|
||||
for(p=pExpr; p->pLeft; p=p->pLeft){
|
||||
assert( p->pRight->pPhrase->doclist.nList>0 );
|
||||
nTmp += p->pRight->pPhrase->doclist.nList;
|
||||
}
|
||||
nTmp += p->pPhrase->doclist.nList;
|
||||
aTmp = sqlite3_malloc(nTmp*2);
|
||||
if( !aTmp ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
if( nTmp==0 ){
|
||||
res = 0;
|
||||
}else{
|
||||
char *aPoslist = p->pPhrase->doclist.pList;
|
||||
int nToken = p->pPhrase->nToken;
|
||||
aTmp = sqlite3_malloc(nTmp*2);
|
||||
if( !aTmp ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
res = 0;
|
||||
}else{
|
||||
char *aPoslist = p->pPhrase->doclist.pList;
|
||||
int nToken = p->pPhrase->nToken;
|
||||
|
||||
for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
|
||||
Fts3Phrase *pPhrase = p->pRight->pPhrase;
|
||||
int nNear = p->nNear;
|
||||
res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
|
||||
for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
|
||||
Fts3Phrase *pPhrase = p->pRight->pPhrase;
|
||||
int nNear = p->nNear;
|
||||
res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
|
||||
}
|
||||
|
||||
aPoslist = pExpr->pRight->pPhrase->doclist.pList;
|
||||
nToken = pExpr->pRight->pPhrase->nToken;
|
||||
for(p=pExpr->pLeft; p && res; p=p->pLeft){
|
||||
int nNear;
|
||||
Fts3Phrase *pPhrase;
|
||||
assert( p->pParent && p->pParent->pLeft==p );
|
||||
nNear = p->pParent->nNear;
|
||||
pPhrase = (
|
||||
p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
|
||||
);
|
||||
res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
|
||||
}
|
||||
}
|
||||
|
||||
aPoslist = pExpr->pRight->pPhrase->doclist.pList;
|
||||
nToken = pExpr->pRight->pPhrase->nToken;
|
||||
for(p=pExpr->pLeft; p && res; p=p->pLeft){
|
||||
int nNear;
|
||||
Fts3Phrase *pPhrase;
|
||||
assert( p->pParent && p->pParent->pLeft==p );
|
||||
nNear = p->pParent->nNear;
|
||||
pPhrase = (
|
||||
p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
|
||||
);
|
||||
res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
|
||||
}
|
||||
sqlite3_free(aTmp);
|
||||
}
|
||||
|
||||
sqlite3_free(aTmp);
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
+13
-13
@@ -136,16 +136,16 @@ static int unicodeAddExceptions(
|
||||
){
|
||||
const unsigned char *z = (const unsigned char *)zIn;
|
||||
const unsigned char *zTerm = &z[nIn];
|
||||
unsigned int iCode;
|
||||
int iCode;
|
||||
int nEntry = 0;
|
||||
|
||||
assert( bAlnum==0 || bAlnum==1 );
|
||||
|
||||
while( z<zTerm ){
|
||||
READ_UTF8(z, zTerm, iCode);
|
||||
assert( (sqlite3FtsUnicodeIsalnum((int)iCode) & 0xFFFFFFFE)==0 );
|
||||
if( sqlite3FtsUnicodeIsalnum((int)iCode)!=bAlnum
|
||||
&& sqlite3FtsUnicodeIsdiacritic((int)iCode)==0
|
||||
assert( (sqlite3FtsUnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
|
||||
if( sqlite3FtsUnicodeIsalnum(iCode)!=bAlnum
|
||||
&& sqlite3FtsUnicodeIsdiacritic(iCode)==0
|
||||
){
|
||||
nEntry++;
|
||||
}
|
||||
@@ -162,13 +162,13 @@ static int unicodeAddExceptions(
|
||||
z = (const unsigned char *)zIn;
|
||||
while( z<zTerm ){
|
||||
READ_UTF8(z, zTerm, iCode);
|
||||
if( sqlite3FtsUnicodeIsalnum((int)iCode)!=bAlnum
|
||||
&& sqlite3FtsUnicodeIsdiacritic((int)iCode)==0
|
||||
if( sqlite3FtsUnicodeIsalnum(iCode)!=bAlnum
|
||||
&& sqlite3FtsUnicodeIsdiacritic(iCode)==0
|
||||
){
|
||||
int i, j;
|
||||
for(i=0; i<nNew && aNew[i]<(int)iCode; i++);
|
||||
for(i=0; i<nNew && aNew[i]<iCode; i++);
|
||||
for(j=nNew; j>i; j--) aNew[j] = aNew[j-1];
|
||||
aNew[i] = (int)iCode;
|
||||
aNew[i] = iCode;
|
||||
nNew++;
|
||||
}
|
||||
}
|
||||
@@ -318,7 +318,7 @@ static int unicodeNext(
|
||||
){
|
||||
unicode_cursor *pCsr = (unicode_cursor *)pC;
|
||||
unicode_tokenizer *p = ((unicode_tokenizer *)pCsr->base.pTokenizer);
|
||||
unsigned int iCode = 0;
|
||||
int iCode = 0;
|
||||
char *zOut;
|
||||
const unsigned char *z = &pCsr->aInput[pCsr->iOff];
|
||||
const unsigned char *zStart = z;
|
||||
@@ -330,7 +330,7 @@ static int unicodeNext(
|
||||
** the input. */
|
||||
while( z<zTerm ){
|
||||
READ_UTF8(z, zTerm, iCode);
|
||||
if( unicodeIsAlnum(p, (int)iCode) ) break;
|
||||
if( unicodeIsAlnum(p, iCode) ) break;
|
||||
zStart = z;
|
||||
}
|
||||
if( zStart>=zTerm ) return SQLITE_DONE;
|
||||
@@ -350,7 +350,7 @@ static int unicodeNext(
|
||||
|
||||
/* Write the folded case of the last character read to the output */
|
||||
zEnd = z;
|
||||
iOut = sqlite3FtsUnicodeFold((int)iCode, p->bRemoveDiacritic);
|
||||
iOut = sqlite3FtsUnicodeFold(iCode, p->bRemoveDiacritic);
|
||||
if( iOut ){
|
||||
WRITE_UTF8(zOut, iOut);
|
||||
}
|
||||
@@ -358,8 +358,8 @@ static int unicodeNext(
|
||||
/* If the cursor is not at EOF, read the next character */
|
||||
if( z>=zTerm ) break;
|
||||
READ_UTF8(z, zTerm, iCode);
|
||||
}while( unicodeIsAlnum(p, (int)iCode)
|
||||
|| sqlite3FtsUnicodeIsdiacritic((int)iCode)
|
||||
}while( unicodeIsAlnum(p, iCode)
|
||||
|| sqlite3FtsUnicodeIsdiacritic(iCode)
|
||||
);
|
||||
|
||||
/* Set the output variables and return. */
|
||||
|
||||
+11
-10
@@ -127,9 +127,9 @@ int sqlite3FtsUnicodeIsalnum(int c){
|
||||
0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
|
||||
};
|
||||
|
||||
if( (unsigned int)c<128 ){
|
||||
return ( (aAscii[c >> 5] & ((unsigned int)1 << (c & 0x001F)))==0 );
|
||||
}else if( (unsigned int)c<(1<<22) ){
|
||||
if( c<128 ){
|
||||
return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
|
||||
}else if( c<(1<<22) ){
|
||||
unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
|
||||
int iRes = 0;
|
||||
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
|
||||
@@ -322,17 +322,16 @@ int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
|
||||
|
||||
int ret = c;
|
||||
|
||||
assert( c>=0 );
|
||||
assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 );
|
||||
|
||||
if( c<128 ){
|
||||
if( c>='A' && c<='Z' ) ret = c + ('a' - 'A');
|
||||
}else if( c<65536 ){
|
||||
const struct TableEntry *p;
|
||||
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
|
||||
int iLo = 0;
|
||||
int iRes = -1;
|
||||
|
||||
assert( c>aEntry[0].iCode );
|
||||
while( iHi>=iLo ){
|
||||
int iTest = (iHi + iLo) / 2;
|
||||
int cmp = (c - aEntry[iTest].iCode);
|
||||
@@ -343,12 +342,14 @@ int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
|
||||
iHi = iTest-1;
|
||||
}
|
||||
}
|
||||
assert( iRes<0 || c>=aEntry[iRes].iCode );
|
||||
|
||||
assert( iRes>=0 && c>=aEntry[iRes].iCode );
|
||||
p = &aEntry[iRes];
|
||||
if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
|
||||
ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
|
||||
assert( ret>0 );
|
||||
if( iRes>=0 ){
|
||||
const struct TableEntry *p = &aEntry[iRes];
|
||||
if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
|
||||
ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
|
||||
assert( ret>0 );
|
||||
}
|
||||
}
|
||||
|
||||
if( bRemoveDiacritic ) ret = remove_diacritic(ret);
|
||||
|
||||
@@ -4956,14 +4956,11 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
|
||||
** Convert the text beginning at *pz into an integer and return
|
||||
** its value. Advance *pz to point to the first character past
|
||||
** the integer.
|
||||
**
|
||||
** This function used for parameters to merge= and incrmerge=
|
||||
** commands.
|
||||
*/
|
||||
static int fts3Getint(const char **pz){
|
||||
const char *z = *pz;
|
||||
int i = 0;
|
||||
while( (*z)>='0' && (*z)<='9' && i<214748363 ) i = 10*i + *(z++) - '0';
|
||||
while( (*z)>='0' && (*z)<='9' ) i = 10*i + *(z++) - '0';
|
||||
*pz = z;
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
srcdir=`dirname $(dirname $(dirname $(dirname $0)))`
|
||||
./testfixture $srcdir/test/fts3.test --output=fts3cov-out.txt
|
||||
|
||||
echo ""
|
||||
|
||||
for f in `ls $srcdir/ext/fts3/*.c`
|
||||
do
|
||||
f=`basename $f`
|
||||
echo -ne "$f: "
|
||||
gcov -b $f | grep Taken | sed 's/Taken at least once://'
|
||||
done
|
||||
|
||||
@@ -227,7 +227,7 @@ proc print_isalnum {zFunc lRange} {
|
||||
an_print_ascii_bitmap $lRange
|
||||
puts {
|
||||
if( (unsigned int)c<128 ){
|
||||
return ( (aAscii[c >> 5] & ((unsigned int)1 << (c & 0x001F)))==0 );
|
||||
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;
|
||||
|
||||
+4
-5
@@ -446,9 +446,9 @@ int sqlite3Fts5IndexBeginWrite(
|
||||
|
||||
/*
|
||||
** Flush any data stored in the in-memory hash tables to the database.
|
||||
** Also close any open blob handles.
|
||||
** If the bCommit flag is true, also close any open blob handles.
|
||||
*/
|
||||
int sqlite3Fts5IndexSync(Fts5Index *p);
|
||||
int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit);
|
||||
|
||||
/*
|
||||
** Discard any data stored in the in-memory hash tables. Do not write it
|
||||
@@ -618,7 +618,7 @@ int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol);
|
||||
int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnAvg);
|
||||
int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow);
|
||||
|
||||
int sqlite3Fts5StorageSync(Fts5Storage *p);
|
||||
int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit);
|
||||
int sqlite3Fts5StorageRollback(Fts5Storage *p);
|
||||
|
||||
int sqlite3Fts5StorageConfigValue(
|
||||
@@ -654,7 +654,6 @@ struct Fts5Token {
|
||||
/* Parse a MATCH expression. */
|
||||
int sqlite3Fts5ExprNew(
|
||||
Fts5Config *pConfig,
|
||||
int iCol, /* Column on LHS of MATCH operator */
|
||||
const char *zExpr,
|
||||
Fts5Expr **ppNew,
|
||||
char **pzErr
|
||||
@@ -739,7 +738,7 @@ void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset*);
|
||||
void sqlite3Fts5ParseNodeFree(Fts5ExprNode*);
|
||||
|
||||
void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*);
|
||||
void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNode*, Fts5Colset*);
|
||||
void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5Colset*);
|
||||
Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse*, Fts5Colset*);
|
||||
void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p);
|
||||
void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*);
|
||||
|
||||
@@ -67,11 +67,9 @@ void sqlite3Fts5BufferAppendBlob(
|
||||
const u8 *pData
|
||||
){
|
||||
assert_nc( *pRc || nData>=0 );
|
||||
if( nData ){
|
||||
if( fts5BufferGrow(pRc, pBuf, nData) ) return;
|
||||
memcpy(&pBuf->p[pBuf->n], pData, nData);
|
||||
pBuf->n += nData;
|
||||
}
|
||||
if( fts5BufferGrow(pRc, pBuf, nData) ) return;
|
||||
memcpy(&pBuf->p[pBuf->n], pData, nData);
|
||||
pBuf->n += nData;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -248,8 +246,8 @@ void *sqlite3Fts5MallocZero(int *pRc, int nByte){
|
||||
void *pRet = 0;
|
||||
if( *pRc==SQLITE_OK ){
|
||||
pRet = sqlite3_malloc(nByte);
|
||||
if( pRet==0 ){
|
||||
if( nByte>0 ) *pRc = SQLITE_NOMEM;
|
||||
if( pRet==0 && nByte>0 ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
}else{
|
||||
memset(pRet, 0, nByte);
|
||||
}
|
||||
|
||||
+10
-108
@@ -213,7 +213,6 @@ static void fts5ParseFree(void *p){ sqlite3_free(p); }
|
||||
|
||||
int sqlite3Fts5ExprNew(
|
||||
Fts5Config *pConfig, /* FTS5 Configuration */
|
||||
int iCol,
|
||||
const char *zExpr, /* Expression text */
|
||||
Fts5Expr **ppNew,
|
||||
char **pzErr
|
||||
@@ -238,18 +237,6 @@ int sqlite3Fts5ExprNew(
|
||||
}while( sParse.rc==SQLITE_OK && t!=FTS5_EOF );
|
||||
sqlite3Fts5ParserFree(pEngine, fts5ParseFree);
|
||||
|
||||
/* If the LHS of the MATCH expression was a user column, apply the
|
||||
** implicit column-filter. */
|
||||
if( iCol<pConfig->nCol && sParse.pExpr && sParse.rc==SQLITE_OK ){
|
||||
int n = sizeof(Fts5Colset);
|
||||
Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n);
|
||||
if( pColset ){
|
||||
pColset->nCol = 1;
|
||||
pColset->aiCol[0] = iCol;
|
||||
sqlite3Fts5ParseSetColset(&sParse, sParse.pExpr, pColset);
|
||||
}
|
||||
}
|
||||
|
||||
assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 );
|
||||
if( sParse.rc==SQLITE_OK ){
|
||||
*ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr));
|
||||
@@ -1899,110 +1886,25 @@ Fts5Colset *sqlite3Fts5ParseColset(
|
||||
return pRet;
|
||||
}
|
||||
|
||||
/*
|
||||
** If argument pOrig is NULL, or if (*pRc) is set to anything other than
|
||||
** SQLITE_OK when this function is called, NULL is returned.
|
||||
**
|
||||
** Otherwise, a copy of (*pOrig) is made into memory obtained from
|
||||
** sqlite3Fts5MallocZero() and a pointer to it returned. If the allocation
|
||||
** fails, (*pRc) is set to SQLITE_NOMEM and NULL is returned.
|
||||
*/
|
||||
static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){
|
||||
Fts5Colset *pRet;
|
||||
if( pOrig ){
|
||||
int nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
|
||||
pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte);
|
||||
if( pRet ){
|
||||
memcpy(pRet, pOrig, nByte);
|
||||
}
|
||||
}else{
|
||||
pRet = 0;
|
||||
}
|
||||
return pRet;
|
||||
}
|
||||
|
||||
/*
|
||||
** Remove from colset pColset any columns that are not also in colset pMerge.
|
||||
*/
|
||||
static void fts5MergeColset(Fts5Colset *pColset, Fts5Colset *pMerge){
|
||||
int iIn = 0; /* Next input in pColset */
|
||||
int iMerge = 0; /* Next input in pMerge */
|
||||
int iOut = 0; /* Next output slot in pColset */
|
||||
|
||||
while( iIn<pColset->nCol && iMerge<pMerge->nCol ){
|
||||
int iDiff = pColset->aiCol[iIn] - pMerge->aiCol[iMerge];
|
||||
if( iDiff==0 ){
|
||||
pColset->aiCol[iOut++] = pMerge->aiCol[iMerge];
|
||||
iMerge++;
|
||||
iIn++;
|
||||
}else if( iDiff>0 ){
|
||||
iMerge++;
|
||||
}else{
|
||||
iIn++;
|
||||
}
|
||||
}
|
||||
pColset->nCol = iOut;
|
||||
}
|
||||
|
||||
/*
|
||||
** Recursively apply colset pColset to expression node pNode and all of
|
||||
** its decendents. If (*ppFree) is not NULL, it contains a spare copy
|
||||
** of pColset. This function may use the spare copy and set (*ppFree) to
|
||||
** zero, or it may create copies of pColset using fts5CloneColset().
|
||||
*/
|
||||
static void fts5ParseSetColset(
|
||||
Fts5Parse *pParse,
|
||||
Fts5ExprNode *pNode,
|
||||
Fts5Colset *pColset,
|
||||
Fts5Colset **ppFree
|
||||
){
|
||||
if( pParse->rc==SQLITE_OK ){
|
||||
assert( pNode->eType==FTS5_TERM || pNode->eType==FTS5_STRING
|
||||
|| pNode->eType==FTS5_AND || pNode->eType==FTS5_OR
|
||||
|| pNode->eType==FTS5_NOT || pNode->eType==FTS5_EOF
|
||||
);
|
||||
if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){
|
||||
Fts5ExprNearset *pNear = pNode->pNear;
|
||||
if( pNear->pColset ){
|
||||
fts5MergeColset(pNear->pColset, pColset);
|
||||
if( pNear->pColset->nCol==0 ){
|
||||
pNode->eType = FTS5_EOF;
|
||||
pNode->xNext = 0;
|
||||
}
|
||||
}else if( *ppFree ){
|
||||
pNear->pColset = pColset;
|
||||
*ppFree = 0;
|
||||
}else{
|
||||
pNear->pColset = fts5CloneColset(&pParse->rc, pColset);
|
||||
}
|
||||
}else{
|
||||
int i;
|
||||
assert( pNode->eType!=FTS5_EOF || pNode->nChild==0 );
|
||||
for(i=0; i<pNode->nChild; i++){
|
||||
fts5ParseSetColset(pParse, pNode->apChild[i], pColset, ppFree);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Apply colset pColset to expression node pExpr and all of its descendents.
|
||||
*/
|
||||
void sqlite3Fts5ParseSetColset(
|
||||
Fts5Parse *pParse,
|
||||
Fts5ExprNode *pExpr,
|
||||
Fts5ExprNearset *pNear,
|
||||
Fts5Colset *pColset
|
||||
){
|
||||
Fts5Colset *pFree = pColset;
|
||||
if( pParse->pConfig->eDetail==FTS5_DETAIL_NONE ){
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
pParse->zErr = sqlite3_mprintf(
|
||||
"fts5: column queries are not supported (detail=none)"
|
||||
);
|
||||
}else{
|
||||
fts5ParseSetColset(pParse, pExpr, pColset, &pFree);
|
||||
sqlite3_free(pColset);
|
||||
return;
|
||||
}
|
||||
|
||||
if( pNear ){
|
||||
pNear->pColset = pColset;
|
||||
}else{
|
||||
sqlite3_free(pColset);
|
||||
}
|
||||
sqlite3_free(pFree);
|
||||
}
|
||||
|
||||
static void fts5ExprAssignXNext(Fts5ExprNode *pNode){
|
||||
@@ -2456,7 +2358,7 @@ static void fts5ExprFunction(
|
||||
|
||||
rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5ExprNew(pConfig, pConfig->nCol, zExpr, &pExpr, &zErr);
|
||||
rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pExpr, &zErr);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
char *zText;
|
||||
|
||||
+29
-39
@@ -36,10 +36,9 @@ struct Fts5Hash {
|
||||
|
||||
/*
|
||||
** Each entry in the hash table is represented by an object of the
|
||||
** following type. Each object, its key (a nul-terminated string) and
|
||||
** its current data are stored in a single memory allocation. The
|
||||
** key immediately follows the object in memory. The position list
|
||||
** data immediately follows the key data in memory.
|
||||
** following type. Each object, its key (zKey[]) and its current data
|
||||
** are stored in a single memory allocation. The position list data
|
||||
** immediately follows the key data in memory.
|
||||
**
|
||||
** The data that follows the key is in a similar, but not identical format
|
||||
** to the doclist data stored in the database. It is:
|
||||
@@ -63,20 +62,20 @@ struct Fts5HashEntry {
|
||||
int nAlloc; /* Total size of allocation */
|
||||
int iSzPoslist; /* Offset of space for 4-byte poslist size */
|
||||
int nData; /* Total bytes of data (incl. structure) */
|
||||
int nKey; /* Length of key in bytes */
|
||||
int nKey; /* Length of zKey[] in bytes */
|
||||
u8 bDel; /* Set delete-flag @ iSzPoslist */
|
||||
u8 bContent; /* Set content-flag (detail=none mode) */
|
||||
i16 iCol; /* Column of last value written */
|
||||
int iPos; /* Position of last value written */
|
||||
i64 iRowid; /* Rowid of last value written */
|
||||
char zKey[8]; /* Nul-terminated entry key */
|
||||
};
|
||||
|
||||
/*
|
||||
** Eqivalent to:
|
||||
**
|
||||
** char *fts5EntryKey(Fts5HashEntry *pEntry){ return zKey; }
|
||||
** Size of Fts5HashEntry without the zKey[] array.
|
||||
*/
|
||||
#define fts5EntryKey(p) ( ((char *)(&(p)[1])) )
|
||||
#define FTS5_HASHENTRYSIZE (sizeof(Fts5HashEntry)-8)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@@ -171,11 +170,10 @@ static int fts5HashResize(Fts5Hash *pHash){
|
||||
|
||||
for(i=0; i<pHash->nSlot; i++){
|
||||
while( apOld[i] ){
|
||||
unsigned int iHash;
|
||||
int iHash;
|
||||
Fts5HashEntry *p = apOld[i];
|
||||
apOld[i] = p->pHashNext;
|
||||
iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p),
|
||||
(int)strlen(fts5EntryKey(p)));
|
||||
iHash = fts5HashKey(nNew, (u8*)p->zKey, (int)strlen(p->zKey));
|
||||
p->pHashNext = apNew[iHash];
|
||||
apNew[iHash] = p;
|
||||
}
|
||||
@@ -246,10 +244,9 @@ int sqlite3Fts5HashWrite(
|
||||
/* Attempt to locate an existing hash entry */
|
||||
iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
|
||||
for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
|
||||
char *zKey = fts5EntryKey(p);
|
||||
if( zKey[0]==bByte
|
||||
if( p->zKey[0]==bByte
|
||||
&& p->nKey==nToken
|
||||
&& memcmp(&zKey[1], pToken, nToken)==0
|
||||
&& memcmp(&p->zKey[1], pToken, nToken)==0
|
||||
){
|
||||
break;
|
||||
}
|
||||
@@ -258,8 +255,7 @@ int sqlite3Fts5HashWrite(
|
||||
/* If an existing hash entry cannot be found, create a new one. */
|
||||
if( p==0 ){
|
||||
/* Figure out how much space to allocate */
|
||||
char *zKey;
|
||||
int nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64;
|
||||
int nByte = FTS5_HASHENTRYSIZE + (nToken+1) + 1 + 64;
|
||||
if( nByte<128 ) nByte = 128;
|
||||
|
||||
/* Grow the Fts5Hash.aSlot[] array if necessary. */
|
||||
@@ -272,15 +268,14 @@ int sqlite3Fts5HashWrite(
|
||||
/* Allocate new Fts5HashEntry and add it to the hash table. */
|
||||
p = (Fts5HashEntry*)sqlite3_malloc(nByte);
|
||||
if( !p ) return SQLITE_NOMEM;
|
||||
memset(p, 0, sizeof(Fts5HashEntry));
|
||||
memset(p, 0, FTS5_HASHENTRYSIZE);
|
||||
p->nAlloc = nByte;
|
||||
zKey = fts5EntryKey(p);
|
||||
zKey[0] = bByte;
|
||||
memcpy(&zKey[1], pToken, nToken);
|
||||
assert( iHash==fts5HashKey(pHash->nSlot, (u8*)zKey, nToken+1) );
|
||||
p->zKey[0] = bByte;
|
||||
memcpy(&p->zKey[1], pToken, nToken);
|
||||
assert( iHash==fts5HashKey(pHash->nSlot, (u8*)p->zKey, nToken+1) );
|
||||
p->nKey = nToken;
|
||||
zKey[nToken+1] = '\0';
|
||||
p->nData = nToken+1 + 1 + sizeof(Fts5HashEntry);
|
||||
p->zKey[nToken+1] = '\0';
|
||||
p->nData = nToken+1 + 1 + FTS5_HASHENTRYSIZE;
|
||||
p->pHashNext = pHash->aSlot[iHash];
|
||||
pHash->aSlot[iHash] = p;
|
||||
pHash->nEntry++;
|
||||
@@ -398,11 +393,9 @@ static Fts5HashEntry *fts5HashEntryMerge(
|
||||
p1 = 0;
|
||||
}else{
|
||||
int i = 0;
|
||||
char *zKey1 = fts5EntryKey(p1);
|
||||
char *zKey2 = fts5EntryKey(p2);
|
||||
while( zKey1[i]==zKey2[i] ) i++;
|
||||
while( p1->zKey[i]==p2->zKey[i] ) i++;
|
||||
|
||||
if( ((u8)zKey1[i])>((u8)zKey2[i]) ){
|
||||
if( ((u8)p1->zKey[i])>((u8)p2->zKey[i]) ){
|
||||
/* p2 is smaller */
|
||||
*ppOut = p2;
|
||||
ppOut = &p2->pScanNext;
|
||||
@@ -445,7 +438,7 @@ static int fts5HashEntrySort(
|
||||
for(iSlot=0; iSlot<pHash->nSlot; iSlot++){
|
||||
Fts5HashEntry *pIter;
|
||||
for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){
|
||||
if( pTerm==0 || 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm) ){
|
||||
if( pTerm==0 || 0==memcmp(pIter->zKey, pTerm, nTerm) ){
|
||||
Fts5HashEntry *pEntry = pIter;
|
||||
pEntry->pScanNext = 0;
|
||||
for(i=0; ap[i]; i++){
|
||||
@@ -478,18 +471,16 @@ int sqlite3Fts5HashQuery(
|
||||
int *pnDoclist /* OUT: Size of doclist in bytes */
|
||||
){
|
||||
unsigned int iHash = fts5HashKey(pHash->nSlot, (const u8*)pTerm, nTerm);
|
||||
char *zKey = 0;
|
||||
Fts5HashEntry *p;
|
||||
|
||||
for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
|
||||
zKey = fts5EntryKey(p);
|
||||
if( memcmp(zKey, pTerm, nTerm)==0 && zKey[nTerm]==0 ) break;
|
||||
if( memcmp(p->zKey, pTerm, nTerm)==0 && p->zKey[nTerm]==0 ) break;
|
||||
}
|
||||
|
||||
if( p ){
|
||||
fts5HashAddPoslistSize(pHash, p);
|
||||
*ppDoclist = (const u8*)&zKey[nTerm+1];
|
||||
*pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
|
||||
*ppDoclist = (const u8*)&p->zKey[nTerm+1];
|
||||
*pnDoclist = p->nData - (FTS5_HASHENTRYSIZE + nTerm + 1);
|
||||
}else{
|
||||
*ppDoclist = 0;
|
||||
*pnDoclist = 0;
|
||||
@@ -522,12 +513,11 @@ void sqlite3Fts5HashScanEntry(
|
||||
){
|
||||
Fts5HashEntry *p;
|
||||
if( (p = pHash->pScan) ){
|
||||
char *zKey = fts5EntryKey(p);
|
||||
int nTerm = (int)strlen(zKey);
|
||||
int nTerm = (int)strlen(p->zKey);
|
||||
fts5HashAddPoslistSize(pHash, p);
|
||||
*pzTerm = zKey;
|
||||
*ppDoclist = (const u8*)&zKey[nTerm+1];
|
||||
*pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
|
||||
*pzTerm = p->zKey;
|
||||
*ppDoclist = (const u8*)&p->zKey[nTerm+1];
|
||||
*pnDoclist = p->nData - (FTS5_HASHENTRYSIZE + nTerm + 1);
|
||||
}else{
|
||||
*pzTerm = 0;
|
||||
*ppDoclist = 0;
|
||||
|
||||
+28
-29
@@ -628,6 +628,7 @@ static void fts5CloseReader(Fts5Index *p){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Retrieve a record from the %_data table.
|
||||
**
|
||||
@@ -2878,8 +2879,7 @@ static void fts5MultiIterNext2(
|
||||
){
|
||||
assert( pIter->bSkipEmpty );
|
||||
if( p->rc==SQLITE_OK ){
|
||||
*pbNewTerm = 0;
|
||||
do{
|
||||
do {
|
||||
int iFirst = pIter->aFirst[1].iFirst;
|
||||
Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
|
||||
int bNewTerm = 0;
|
||||
@@ -2892,6 +2892,8 @@ static void fts5MultiIterNext2(
|
||||
fts5MultiIterAdvanced(p, pIter, iFirst, 1);
|
||||
fts5MultiIterSetEof(pIter);
|
||||
*pbNewTerm = 1;
|
||||
}else{
|
||||
*pbNewTerm = 0;
|
||||
}
|
||||
fts5AssertMultiIterSetup(p, pIter);
|
||||
|
||||
@@ -3157,23 +3159,23 @@ static int fts5IndexExtractCol(
|
||||
return p - (*pa);
|
||||
}
|
||||
|
||||
static void fts5IndexExtractColset(
|
||||
int *pRc,
|
||||
static int fts5IndexExtractColset (
|
||||
Fts5Colset *pColset, /* Colset to filter on */
|
||||
const u8 *pPos, int nPos, /* Position list */
|
||||
Fts5Buffer *pBuf /* Output buffer */
|
||||
){
|
||||
if( *pRc==SQLITE_OK ){
|
||||
int i;
|
||||
fts5BufferZero(pBuf);
|
||||
for(i=0; i<pColset->nCol; i++){
|
||||
const u8 *pSub = pPos;
|
||||
int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
|
||||
if( nSub ){
|
||||
fts5BufferAppendBlob(pRc, pBuf, nSub, pSub);
|
||||
}
|
||||
int rc = SQLITE_OK;
|
||||
int i;
|
||||
|
||||
fts5BufferZero(pBuf);
|
||||
for(i=0; i<pColset->nCol; i++){
|
||||
const u8 *pSub = pPos;
|
||||
int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
|
||||
if( nSub ){
|
||||
fts5BufferAppendBlob(&rc, pBuf, nSub, pSub);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3297,9 +3299,8 @@ static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){
|
||||
pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]);
|
||||
pIter->base.pData = a;
|
||||
}else{
|
||||
int *pRc = &pIter->pIndex->rc;
|
||||
fts5BufferZero(&pIter->poslist);
|
||||
fts5IndexExtractColset(pRc, pColset, a, pSeg->nPos, &pIter->poslist);
|
||||
fts5IndexExtractColset(pColset, a, pSeg->nPos, &pIter->poslist);
|
||||
pIter->base.pData = pIter->poslist.p;
|
||||
pIter->base.nData = pIter->poslist.n;
|
||||
}
|
||||
@@ -3844,6 +3845,9 @@ static void fts5WriteFlushLeaf(Fts5Index *p, Fts5SegWriter *pWriter){
|
||||
Fts5PageWriter *pPage = &pWriter->writer;
|
||||
i64 iRowid;
|
||||
|
||||
static int nCall = 0;
|
||||
nCall++;
|
||||
|
||||
assert( (pPage->pgidx.n==0)==(pWriter->bFirstTermInPage) );
|
||||
|
||||
/* Set the szLeaf header field. */
|
||||
@@ -4192,7 +4196,6 @@ static void fts5IndexMergeLevel(
|
||||
int bOldest; /* True if the output segment is the oldest */
|
||||
int eDetail = p->pConfig->eDetail;
|
||||
const int flags = FTS5INDEX_QUERY_NOOUTPUT;
|
||||
int bTermWritten = 0; /* True if current term already output */
|
||||
|
||||
assert( iLvl<pStruct->nLevel );
|
||||
assert( pLvl->nMerge<=pLvl->nSeg );
|
||||
@@ -4246,22 +4249,18 @@ static void fts5IndexMergeLevel(
|
||||
int nTerm;
|
||||
const u8 *pTerm;
|
||||
|
||||
/* Check for key annihilation. */
|
||||
if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue;
|
||||
|
||||
pTerm = fts5MultiIterTerm(pIter, &nTerm);
|
||||
if( nTerm!=term.n || memcmp(pTerm, term.p, nTerm) ){
|
||||
if( pnRem && writer.nLeafWritten>nRem ){
|
||||
break;
|
||||
}
|
||||
fts5BufferSet(&p->rc, &term, nTerm, pTerm);
|
||||
bTermWritten =0;
|
||||
}
|
||||
|
||||
/* Check for key annihilation. */
|
||||
if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue;
|
||||
|
||||
if( p->rc==SQLITE_OK && bTermWritten==0 ){
|
||||
/* This is a new term. Append a term to the output segment. */
|
||||
fts5WriteAppendTerm(p, &writer, nTerm, pTerm);
|
||||
bTermWritten = 1;
|
||||
fts5BufferSet(&p->rc, &term, nTerm, pTerm);
|
||||
}
|
||||
|
||||
/* Append the rowid to the output */
|
||||
@@ -5093,7 +5092,7 @@ static void fts5SetupPrefixIter(
|
||||
if( pData ){
|
||||
pData->p = (u8*)&pData[1];
|
||||
pData->nn = pData->szLeaf = doclist.n;
|
||||
if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n);
|
||||
memcpy(pData->p, doclist.p, doclist.n);
|
||||
fts5MultiIterNew2(p, pData, bDesc, ppIter);
|
||||
}
|
||||
fts5BufferFree(&doclist);
|
||||
@@ -5132,10 +5131,10 @@ int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){
|
||||
/*
|
||||
** Commit data to disk.
|
||||
*/
|
||||
int sqlite3Fts5IndexSync(Fts5Index *p){
|
||||
int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit){
|
||||
assert( p->rc==SQLITE_OK );
|
||||
fts5IndexFlush(p);
|
||||
fts5CloseReader(p);
|
||||
if( bCommit ) fts5CloseReader(p);
|
||||
return fts5IndexReturn(p);
|
||||
}
|
||||
|
||||
@@ -5332,7 +5331,7 @@ int sqlite3Fts5IndexQuery(
|
||||
|
||||
if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
|
||||
int iIdx = 0; /* Index to search */
|
||||
if( nToken ) memcpy(&buf.p[1], pToken, nToken);
|
||||
memcpy(&buf.p[1], pToken, nToken);
|
||||
|
||||
/* Figure out which index to search and set iIdx accordingly. If this
|
||||
** is a prefix query for which there is no prefix index, set iIdx to
|
||||
@@ -5381,7 +5380,7 @@ int sqlite3Fts5IndexQuery(
|
||||
}
|
||||
|
||||
if( p->rc ){
|
||||
sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
|
||||
sqlite3Fts5IterClose(&pRet->base);
|
||||
pRet = 0;
|
||||
fts5CloseReader(p);
|
||||
}
|
||||
|
||||
+16
-30
@@ -506,7 +506,6 @@ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
|
||||
static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
|
||||
Fts5Table *pTab = (Fts5Table*)pVTab;
|
||||
Fts5Config *pConfig = pTab->pConfig;
|
||||
const int nCol = pConfig->nCol;
|
||||
int idxFlags = 0; /* Parameter passed through to xFilter() */
|
||||
int bHasMatch;
|
||||
int iNext;
|
||||
@@ -532,34 +531,24 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
|
||||
|
||||
int aColMap[3];
|
||||
aColMap[0] = -1;
|
||||
aColMap[1] = nCol;
|
||||
aColMap[2] = nCol+1;
|
||||
aColMap[1] = pConfig->nCol;
|
||||
aColMap[2] = pConfig->nCol+1;
|
||||
|
||||
/* 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];
|
||||
int iCol = p->iColumn;
|
||||
|
||||
if( (p->op==SQLITE_INDEX_CONSTRAINT_MATCH && iCol>=0 && iCol<=nCol)
|
||||
|| (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol==nCol)
|
||||
){
|
||||
/* A MATCH operator or equivalent */
|
||||
if( p->usable ){
|
||||
idxFlags = (idxFlags & 0xFFFF) | FTS5_BI_MATCH | (iCol << 16);
|
||||
aConstraint[0].iConsIndex = i;
|
||||
}else{
|
||||
/* As there exists an unusable MATCH constraint this is an
|
||||
** unusable plan. Set a prohibitively high cost. */
|
||||
pInfo->estimatedCost = 1e50;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}else{
|
||||
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 ){
|
||||
int j;
|
||||
for(j=0; j<ArraySize(aConstraint); j++){
|
||||
struct Constraint *pC = &aConstraint[j];
|
||||
if( p->iColumn==aColMap[pC->iCol] && p->op & pC->op ){
|
||||
if( p->usable ){
|
||||
pC->iConsIndex = i;
|
||||
idxFlags |= pC->fts5op;
|
||||
}else if( j==0 ){
|
||||
/* As there exists an unusable MATCH constraint this is an
|
||||
** unusable plan. Set a prohibitively high cost. */
|
||||
pInfo->estimatedCost = 1e50;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1134,7 +1123,6 @@ static int fts5FilterMethod(
|
||||
sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */
|
||||
sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */
|
||||
sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
|
||||
int iCol; /* Column on LHS of MATCH operator */
|
||||
char **pzErrmsg = pConfig->pzErrmsg;
|
||||
|
||||
UNUSED_PARAM(zUnused);
|
||||
@@ -1165,8 +1153,6 @@ static int fts5FilterMethod(
|
||||
if( BitFlagTest(idxNum, FTS5_BI_ROWID_EQ) ) pRowidEq = apVal[iVal++];
|
||||
if( BitFlagTest(idxNum, FTS5_BI_ROWID_LE) ) pRowidLe = apVal[iVal++];
|
||||
if( BitFlagTest(idxNum, FTS5_BI_ROWID_GE) ) pRowidGe = apVal[iVal++];
|
||||
iCol = (idxNum>>16);
|
||||
assert( iCol>=0 && iCol<=pConfig->nCol );
|
||||
assert( iVal==nVal );
|
||||
bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0);
|
||||
pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0);
|
||||
@@ -1213,7 +1199,7 @@ static int fts5FilterMethod(
|
||||
rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]);
|
||||
}else{
|
||||
char **pzErr = &pTab->base.zErrMsg;
|
||||
rc = sqlite3Fts5ExprNew(pConfig, iCol, zExpr, &pCsr->pExpr, pzErr);
|
||||
rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pCsr->pExpr, pzErr);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( bOrderByRank ){
|
||||
pCsr->ePlan = FTS5_PLAN_SORTED_MATCH;
|
||||
@@ -1593,7 +1579,7 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){
|
||||
fts5CheckTransactionState(pTab, FTS5_SYNC, 0);
|
||||
pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg;
|
||||
fts5TripCursors(pTab);
|
||||
rc = sqlite3Fts5StorageSync(pTab->pStorage);
|
||||
rc = sqlite3Fts5StorageSync(pTab->pStorage, 1);
|
||||
pTab->pConfig->pzErrmsg = 0;
|
||||
return rc;
|
||||
}
|
||||
@@ -2404,7 +2390,7 @@ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
|
||||
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
|
||||
fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint);
|
||||
fts5TripCursors(pTab);
|
||||
return sqlite3Fts5StorageSync(pTab->pStorage);
|
||||
return sqlite3Fts5StorageSync(pTab->pStorage, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2417,7 +2403,7 @@ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
|
||||
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
|
||||
fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint);
|
||||
fts5TripCursors(pTab);
|
||||
return sqlite3Fts5StorageSync(pTab->pStorage);
|
||||
return sqlite3Fts5StorageSync(pTab->pStorage, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -218,7 +218,7 @@ static void fts5StorageRenameOne(
|
||||
|
||||
int sqlite3Fts5StorageRename(Fts5Storage *pStorage, const char *zName){
|
||||
Fts5Config *pConfig = pStorage->pConfig;
|
||||
int rc = sqlite3Fts5StorageSync(pStorage);
|
||||
int rc = sqlite3Fts5StorageSync(pStorage, 1);
|
||||
|
||||
fts5StorageRenameOne(pConfig, &rc, "data", zName);
|
||||
fts5StorageRenameOne(pConfig, &rc, "idx", zName);
|
||||
@@ -1081,15 +1081,15 @@ int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){
|
||||
/*
|
||||
** Flush any data currently held in-memory to disk.
|
||||
*/
|
||||
int sqlite3Fts5StorageSync(Fts5Storage *p){
|
||||
int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit){
|
||||
int rc = SQLITE_OK;
|
||||
i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db);
|
||||
if( p->bTotalsValid ){
|
||||
rc = fts5StorageSaveTotals(p);
|
||||
p->bTotalsValid = 0;
|
||||
if( bCommit ) p->bTotalsValid = 0;
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5IndexSync(p->pIndex);
|
||||
rc = sqlite3Fts5IndexSync(p->pIndex, bCommit);
|
||||
}
|
||||
sqlite3_set_last_insert_rowid(p->pConfig->db, iLastRowid);
|
||||
return rc;
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
*/
|
||||
#if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_FTS5)
|
||||
|
||||
#include "fts5.h"
|
||||
#include <fts5.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
@@ -182,7 +182,7 @@ static int fts5tokConnectMethod(
|
||||
Fts5tokTable *pTab = 0;
|
||||
int rc;
|
||||
char **azDequote = 0;
|
||||
int nDequote = 0;
|
||||
int nDequote;
|
||||
|
||||
rc = sqlite3_declare_vtab(db,
|
||||
"CREATE TABLE x(input HIDDEN, token, start, end, position)"
|
||||
|
||||
+26
-31
@@ -89,6 +89,32 @@ input ::= expr(X). { sqlite3Fts5ParseFinished(pParse, X); }
|
||||
%destructor expr { sqlite3Fts5ParseNodeFree($$); }
|
||||
%destructor exprlist { sqlite3Fts5ParseNodeFree($$); }
|
||||
|
||||
expr(A) ::= expr(X) AND expr(Y). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_AND, X, Y, 0);
|
||||
}
|
||||
expr(A) ::= expr(X) OR expr(Y). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_OR, X, Y, 0);
|
||||
}
|
||||
expr(A) ::= expr(X) NOT expr(Y). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_NOT, X, Y, 0);
|
||||
}
|
||||
|
||||
expr(A) ::= LP expr(X) RP. {A = X;}
|
||||
expr(A) ::= exprlist(X). {A = X;}
|
||||
|
||||
exprlist(A) ::= cnearset(X). {A = X;}
|
||||
exprlist(A) ::= exprlist(X) cnearset(Y). {
|
||||
A = sqlite3Fts5ParseImplicitAnd(pParse, X, Y);
|
||||
}
|
||||
|
||||
cnearset(A) ::= nearset(X). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, X);
|
||||
}
|
||||
cnearset(A) ::= colset(X) COLON nearset(Y). {
|
||||
sqlite3Fts5ParseSetColset(pParse, Y, X);
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, Y);
|
||||
}
|
||||
|
||||
%type colset {Fts5Colset*}
|
||||
%destructor colset { sqlite3_free($$); }
|
||||
%type colsetlist {Fts5Colset*}
|
||||
@@ -112,37 +138,6 @@ colsetlist(A) ::= STRING(X). {
|
||||
A = sqlite3Fts5ParseColset(pParse, 0, &X);
|
||||
}
|
||||
|
||||
expr(A) ::= expr(X) AND expr(Y). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_AND, X, Y, 0);
|
||||
}
|
||||
expr(A) ::= expr(X) OR expr(Y). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_OR, X, Y, 0);
|
||||
}
|
||||
expr(A) ::= expr(X) NOT expr(Y). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_NOT, X, Y, 0);
|
||||
}
|
||||
|
||||
expr(A) ::= colset(X) COLON LP expr(Y) RP. {
|
||||
sqlite3Fts5ParseSetColset(pParse, Y, X);
|
||||
A = Y;
|
||||
}
|
||||
expr(A) ::= LP expr(X) RP. {A = X;}
|
||||
expr(A) ::= exprlist(X). {A = X;}
|
||||
|
||||
exprlist(A) ::= cnearset(X). {A = X;}
|
||||
exprlist(A) ::= exprlist(X) cnearset(Y). {
|
||||
A = sqlite3Fts5ParseImplicitAnd(pParse, X, Y);
|
||||
}
|
||||
|
||||
cnearset(A) ::= nearset(X). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, X);
|
||||
}
|
||||
cnearset(A) ::= colset(X) COLON nearset(Y). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, Y);
|
||||
sqlite3Fts5ParseSetColset(pParse, A, X);
|
||||
}
|
||||
|
||||
|
||||
%type nearset {Fts5ExprNearset*}
|
||||
%type nearphrases {Fts5ExprNearset*}
|
||||
%destructor nearset { sqlite3Fts5ParseNearsetFree($$); }
|
||||
|
||||
@@ -561,36 +561,6 @@ do_test 20.1 {
|
||||
execsql { SELECT rowid FROM tmp WHERE tmp MATCH 'y' }
|
||||
} $::ids
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Test that a DROP TABLE may be executed within a transaction that
|
||||
# writes to an FTS5 table.
|
||||
#
|
||||
do_execsql_test 21.0 {
|
||||
CREATE TEMP TABLE t8(a, b);
|
||||
CREATE VIRTUAL TABLE ft USING fts5(x, detail=%DETAIL%);
|
||||
}
|
||||
|
||||
do_execsql_test 21.1 {
|
||||
BEGIN;
|
||||
INSERT INTO ft VALUES('a b c');
|
||||
DROP TABLE t8;
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
do_execsql_test 22.0 {
|
||||
CREATE VIRTUAL TABLE t9 USING fts5(x, detail=%DETAIL%);
|
||||
INSERT INTO t9(rowid, x) VALUES(2, 'bbb');
|
||||
BEGIN;
|
||||
INSERT INTO t9(rowid, x) VALUES(1, 'aaa');
|
||||
DELETE FROM t9 WHERE rowid = 2;
|
||||
INSERT INTO t9(rowid, x) VALUES(3, 'bbb');
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
do_execsql_test 22.1 {
|
||||
SELECT rowid FROM t9('a*')
|
||||
} {1}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -44,42 +44,13 @@ foreach_detail_mode $::testprefix {
|
||||
9 "-c : a" {1 2 4}
|
||||
10 "-\"c\" : a" {1 2 4}
|
||||
} {
|
||||
breakpoint
|
||||
do_execsql_test 1.$tn {
|
||||
SELECT rowid FROM t1($q)
|
||||
} $res
|
||||
}
|
||||
|
||||
foreach {tn q res} {
|
||||
0 {{a} : (a AND ":")} {}
|
||||
1 "{a b c} : (a AND d)" {2 3}
|
||||
2 "{a b c} : (a AND b:d)" {3}
|
||||
3 "{a b c} : (a AND d:d)" {}
|
||||
4 "{b} : ( {b a} : ( {c b a} : ( {d b c a} : ( d OR c ) ) ) )" {3 4}
|
||||
5 "{a} : ( {b a} : ( {c b a} : ( {d b c a} : ( d OR c ) ) ) )" {2 3}
|
||||
6 "{a} : ( {b a} : ( {c b} : ( {d b c a} : ( d OR c ) ) ) )" {}
|
||||
7 "{a b c} : (b:a AND c:b)" {2}
|
||||
} {
|
||||
do_execsql_test 2.$tn {
|
||||
SELECT rowid FROM t1($q)
|
||||
} $res
|
||||
}
|
||||
|
||||
foreach {tn w res} {
|
||||
0 "a MATCH 'a'" {1}
|
||||
1 "b MATCH 'a'" {2}
|
||||
2 "b MATCH '{a b c} : a'" {2}
|
||||
3 "b MATCH 'a OR b'" {1 2}
|
||||
4 "b MATCH 'a OR a:b'" {2}
|
||||
5 "b MATCH 'a OR b:b'" {1 2}
|
||||
} {
|
||||
do_execsql_test 3.$tn "
|
||||
SELECT rowid FROM t1 WHERE $w
|
||||
" $res
|
||||
}
|
||||
|
||||
do_catchsql_test 4.1 {
|
||||
SELECT * FROM t1 WHERE rowid MATCH 'a'
|
||||
} {1 {unable to use function MATCH in the requested context}}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
# 2017 May 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 implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the FTS5 module.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5delete
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
fts5_aux_test_functions db
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x);
|
||||
WITH s(i) AS (
|
||||
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<5000
|
||||
)
|
||||
INSERT INTO t1(rowid, x) SELECT i, (i/2)*2 FROM s;
|
||||
}
|
||||
|
||||
do_test 1.1 {
|
||||
execsql BEGIN
|
||||
for {set i 1} {$i<=5000} {incr i} {
|
||||
if {$i % 2} {
|
||||
execsql { INSERT INTO t1 VALUES($i) }
|
||||
} else {
|
||||
execsql { DELETE FROM t1 WHERE rowid = $i }
|
||||
}
|
||||
}
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_test 1.2 {
|
||||
execsql { INSERT INTO t1(t1, rank) VALUES('usermerge', 2); }
|
||||
for {set i 0} {$i < 5} {incr i} {
|
||||
execsql { INSERT INTO t1(t1, rank) VALUES('merge', 1) }
|
||||
execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
|
||||
}
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -107,29 +107,5 @@ do_faultsim_test 3.3 -faults oom* -body {
|
||||
faultsim_test_result {0 {2 3}}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test OOM injection with nested colsets.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 4.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(a, b, c, d);
|
||||
INSERT INTO t1 VALUES('a', 'b', 'c', 'd'); -- 1
|
||||
INSERT INTO t1 VALUES('d', 'a', 'b', 'c'); -- 2
|
||||
INSERT INTO t1 VALUES('c', 'd', 'a', 'b'); -- 3
|
||||
INSERT INTO t1 VALUES('b', 'c', 'd', 'a'); -- 4
|
||||
}
|
||||
do_faultsim_test 4.1 -faults oom* -body {
|
||||
execsql { SELECT rowid FROM t1('{a b c} : (b:a AND c:b)'); }
|
||||
} -test {
|
||||
faultsim_test_result {0 2}
|
||||
}
|
||||
|
||||
do_faultsim_test 4.2 -faults oom* -body {
|
||||
execsql { SELECT rowid FROM t1('{a b c} : (a AND d)') }
|
||||
} -test {
|
||||
faultsim_test_result {0 {2 3}}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ do_eqp_test 1.1 {
|
||||
SELECT * FROM t1, f1 WHERE f1 MATCH t1.x
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 1 1 {SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:}
|
||||
0 1 1 {SCAN TABLE f1 VIRTUAL TABLE INDEX 1:}
|
||||
}
|
||||
|
||||
do_eqp_test 1.2 {
|
||||
@@ -43,7 +43,7 @@ do_eqp_test 1.2 {
|
||||
do_eqp_test 1.3 {
|
||||
SELECT * FROM f1 WHERE f1 MATCH ? ORDER BY ff
|
||||
} {
|
||||
0 0 0 {SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:}
|
||||
0 0 0 {SCAN TABLE f1 VIRTUAL TABLE INDEX 1:}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,6 @@ do_test 2.7 {
|
||||
execsql { SELECT rowid FROM tt('a') ORDER BY rank; } db
|
||||
} {1 3 2}
|
||||
|
||||
db2 close
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# At one point there was a problem with queries such as:
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
## Miscellaneous Extensions
|
||||
|
||||
This folder contains a collection of smaller loadable extensions.
|
||||
See <https://www.sqlite.org/loadext.html> for instructions on how
|
||||
to compile and use loadable extensions.
|
||||
Each extension in this folder is implemented in a single file of C code.
|
||||
|
||||
Each source file contains a description in its header comment. See the
|
||||
header comments for details about each extension. Additional notes are
|
||||
as follows:
|
||||
|
||||
* **carray.c** — This module implements the
|
||||
[carray](https://www.sqlite.org/carray.html) table-valued function.
|
||||
It is a good example of how to go about implementing a custom
|
||||
[table-valued function](https://www.sqlite.org/vtab.html#tabfunc2).
|
||||
|
||||
* **dbdump.c** — This is not actually a loadable extension, but
|
||||
rather a library that implements an approximate equivalent to the
|
||||
".dump" command of the
|
||||
[command-line shell](https://www.sqlite.org/cli.html).
|
||||
|
||||
* **memvfs.c** — This file implements a custom
|
||||
[VFS](https://www.sqlite.org/vfs.html) that stores an entire database
|
||||
file in a single block of RAM. It serves as a good example of how
|
||||
to implement a simple custom VFS.
|
||||
|
||||
* **rot13.c** — This file implements the very simple rot13()
|
||||
substitution function. This file makes a good template for implementing
|
||||
new custom SQL functions for SQLite.
|
||||
|
||||
* **series.c** — This is an implementation of the
|
||||
"generate_series" [virtual table](https://www.sqlite.org/vtab.html).
|
||||
It can make a good template for new custom virtual table implementations.
|
||||
|
||||
* **shathree.c** — An implementation of the sha3() and
|
||||
sha3_query() SQL functions. The file is named "shathree.c" instead
|
||||
of "sha3.c" because the default entry point names in SQLite are based
|
||||
on the source filename with digits removed, so if we used the name
|
||||
"sha3.c" then the entry point would conflict with the prior "sha1.c"
|
||||
extension.
|
||||
@@ -1001,6 +1001,7 @@ static void amatchWriteCost(amatch_word *pWord){
|
||||
/* Circumvent compiler warnings about the use of strcpy() by supplying
|
||||
** our own implementation.
|
||||
*/
|
||||
#if defined(__OpenBSD__)
|
||||
static void amatchStrcpy(char *dest, const char *src){
|
||||
while( (*(dest++) = *(src++))!=0 ){}
|
||||
}
|
||||
@@ -1008,6 +1009,11 @@ static void amatchStrcat(char *dest, const char *src){
|
||||
while( *dest ) dest++;
|
||||
amatchStrcpy(dest, src);
|
||||
}
|
||||
#else
|
||||
# define amatchStrcpy strcpy
|
||||
# define amatchStrcat strcat
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** Add a new amatch_word object to the queue.
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
** 2017-04-16
|
||||
**
|
||||
** 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 run-time loadable extension to SQLite that
|
||||
** registers a sqlite3_collation_needed() callback to register a fake
|
||||
** collating function for any unknown collating sequence. The fake
|
||||
** collating function works like BINARY.
|
||||
**
|
||||
** This extension can be used to load schemas that contain one or more
|
||||
** unknown collating sequences.
|
||||
*/
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
#include <string.h>
|
||||
|
||||
static int anyCollFunc(
|
||||
void *NotUsed,
|
||||
int nKey1, const void *pKey1,
|
||||
int nKey2, const void *pKey2
|
||||
){
|
||||
int rc, n;
|
||||
n = nKey1<nKey2 ? nKey1 : nKey2;
|
||||
rc = memcmp(pKey1, pKey2, n);
|
||||
if( rc==0 ) rc = nKey1 - nKey2;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void anyCollNeeded(
|
||||
void *NotUsed,
|
||||
sqlite3 *db,
|
||||
int eTextRep,
|
||||
const char *zCollName
|
||||
){
|
||||
sqlite3_create_collation(db, zCollName, eTextRep, 0, anyCollFunc);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_anycollseq_init(
|
||||
sqlite3 *db,
|
||||
char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
SQLITE_EXTENSION_INIT2(pApi);
|
||||
rc = sqlite3_collation_needed(db, 0, anyCollNeeded);
|
||||
return rc;
|
||||
}
|
||||
@@ -1,750 +0,0 @@
|
||||
/*
|
||||
** 2016-03-13
|
||||
**
|
||||
** 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 C-language subroutine that converts the content
|
||||
** of an SQLite database into UTF-8 text SQL statements that can be used
|
||||
** to exactly recreate the original database. ROWID values are preserved.
|
||||
**
|
||||
** A prototype of the implemented subroutine is this:
|
||||
**
|
||||
** int sqlite3_db_dump(
|
||||
** sqlite3 *db,
|
||||
** const char *zSchema,
|
||||
** const char *zTable,
|
||||
** void (*xCallback)(void*, const char*),
|
||||
** void *pArg
|
||||
** );
|
||||
**
|
||||
** The db parameter is the database connection. zSchema is the schema within
|
||||
** that database which is to be dumped. Usually the zSchema is "main" but
|
||||
** can also be "temp" or any ATTACH-ed database. If zTable is not NULL, then
|
||||
** only the content of that one table is dumped. If zTable is NULL, then all
|
||||
** tables are dumped.
|
||||
**
|
||||
** The generate text is passed to xCallback() in multiple calls. The second
|
||||
** argument to xCallback() is a copy of the pArg parameter. The first
|
||||
** argument is some of the output text that this routine generates. The
|
||||
** signature to xCallback() is designed to make it compatible with fputs().
|
||||
**
|
||||
** The sqlite3_db_dump() subroutine returns SQLITE_OK on success or some error
|
||||
** code if it encounters a problem.
|
||||
**
|
||||
** If this file is compiled with -DDBDUMP_STANDALONE then a "main()" routine
|
||||
** is included so that this routine becomes a command-line utility. The
|
||||
** command-line utility takes two or three arguments which are the name
|
||||
** of the database file, the schema, and optionally the table, forming the
|
||||
** first three arguments of a single call to the library routine.
|
||||
*/
|
||||
#include "sqlite3.h"
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
** The state of the dump process.
|
||||
*/
|
||||
typedef struct DState DState;
|
||||
struct DState {
|
||||
sqlite3 *db; /* The database connection */
|
||||
int nErr; /* Number of errors seen so far */
|
||||
int rc; /* Error code */
|
||||
int writableSchema; /* True if in writable_schema mode */
|
||||
int (*xCallback)(const char*,void*); /* Send output here */
|
||||
void *pArg; /* Argument to xCallback() */
|
||||
};
|
||||
|
||||
/*
|
||||
** A variable length string to which one can append text.
|
||||
*/
|
||||
typedef struct DText DText;
|
||||
struct DText {
|
||||
char *z; /* The text */
|
||||
int n; /* Number of bytes of content in z[] */
|
||||
int nAlloc; /* Number of bytes allocated to z[] */
|
||||
};
|
||||
|
||||
/*
|
||||
** Initialize and destroy a DText object
|
||||
*/
|
||||
static void initText(DText *p){
|
||||
memset(p, 0, sizeof(*p));
|
||||
}
|
||||
static void freeText(DText *p){
|
||||
sqlite3_free(p->z);
|
||||
initText(p);
|
||||
}
|
||||
|
||||
/* zIn is either a pointer to a NULL-terminated string in memory obtained
|
||||
** from malloc(), or a NULL pointer. The string pointed to by zAppend is
|
||||
** added to zIn, and the result returned in memory obtained from malloc().
|
||||
** zIn, if it was not NULL, is freed.
|
||||
**
|
||||
** If the third argument, quote, is not '\0', then it is used as a
|
||||
** quote character for zAppend.
|
||||
*/
|
||||
static void appendText(DText *p, char const *zAppend, char quote){
|
||||
int len;
|
||||
int i;
|
||||
int nAppend = (int)(strlen(zAppend) & 0x3fffffff);
|
||||
|
||||
len = nAppend+p->n+1;
|
||||
if( quote ){
|
||||
len += 2;
|
||||
for(i=0; i<nAppend; i++){
|
||||
if( zAppend[i]==quote ) len++;
|
||||
}
|
||||
}
|
||||
|
||||
if( p->n+len>=p->nAlloc ){
|
||||
char *zNew;
|
||||
p->nAlloc = p->nAlloc*2 + len + 20;
|
||||
zNew = sqlite3_realloc(p->z, p->nAlloc);
|
||||
if( zNew==0 ){
|
||||
freeText(p);
|
||||
return;
|
||||
}
|
||||
p->z = zNew;
|
||||
}
|
||||
|
||||
if( quote ){
|
||||
char *zCsr = p->z+p->n;
|
||||
*zCsr++ = quote;
|
||||
for(i=0; i<nAppend; i++){
|
||||
*zCsr++ = zAppend[i];
|
||||
if( zAppend[i]==quote ) *zCsr++ = quote;
|
||||
}
|
||||
*zCsr++ = quote;
|
||||
p->n = (int)(zCsr - p->z);
|
||||
*zCsr = '\0';
|
||||
}else{
|
||||
memcpy(p->z+p->n, zAppend, nAppend);
|
||||
p->n += nAppend;
|
||||
p->z[p->n] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Attempt to determine if identifier zName needs to be quoted, either
|
||||
** because it contains non-alphanumeric characters, or because it is an
|
||||
** SQLite keyword. Be conservative in this estimate: When in doubt assume
|
||||
** that quoting is required.
|
||||
**
|
||||
** 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;
|
||||
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 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Release memory previously allocated by tableColumnList().
|
||||
*/
|
||||
static void freeColumnList(char **azCol){
|
||||
int i;
|
||||
for(i=1; azCol[i]; i++){
|
||||
sqlite3_free(azCol[i]);
|
||||
}
|
||||
/* azCol[0] is a static string */
|
||||
sqlite3_free(azCol);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a list of pointers to strings which are the names of all
|
||||
** columns in table zTab. The memory to hold the names is dynamically
|
||||
** allocated and must be released by the caller using a subsequent call
|
||||
** to freeColumnList().
|
||||
**
|
||||
** The azCol[0] entry is usually NULL. However, if zTab contains a rowid
|
||||
** value that needs to be preserved, then azCol[0] is filled in with the
|
||||
** name of the rowid column.
|
||||
**
|
||||
** The first regular column in the table is azCol[1]. The list is terminated
|
||||
** by an entry with azCol[i]==0.
|
||||
*/
|
||||
static char **tableColumnList(DState *p, const char *zTab){
|
||||
char **azCol = 0;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
char *zSql;
|
||||
int nCol = 0;
|
||||
int nAlloc = 0;
|
||||
int nPK = 0; /* Number of PRIMARY KEY columns seen */
|
||||
int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */
|
||||
int preserveRowid = 1;
|
||||
int rc;
|
||||
|
||||
zSql = sqlite3_mprintf("PRAGMA table_info=%Q", zTab);
|
||||
if( zSql==0 ) return 0;
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
||||
sqlite3_free(zSql);
|
||||
if( rc ) return 0;
|
||||
while( sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
if( nCol>=nAlloc-2 ){
|
||||
char **azNew;
|
||||
nAlloc = nAlloc*2 + nCol + 10;
|
||||
azNew = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0]));
|
||||
if( azNew==0 ) goto col_oom;
|
||||
azCol = azNew;
|
||||
azCol[0] = 0;
|
||||
}
|
||||
azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
|
||||
if( azCol[nCol]==0 ) goto col_oom;
|
||||
if( sqlite3_column_int(pStmt, 5) ){
|
||||
nPK++;
|
||||
if( nPK==1
|
||||
&& sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,2),
|
||||
"INTEGER")==0
|
||||
){
|
||||
isIPK = 1;
|
||||
}else{
|
||||
isIPK = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
pStmt = 0;
|
||||
azCol[nCol+1] = 0;
|
||||
|
||||
/* The decision of whether or not a rowid really needs to be preserved
|
||||
** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table
|
||||
** or a table with an INTEGER PRIMARY KEY. We are unable to preserve
|
||||
** rowids on tables where the rowid is inaccessible because there are other
|
||||
** columns in the table named "rowid", "_rowid_", and "oid".
|
||||
*/
|
||||
if( isIPK ){
|
||||
/* If a single PRIMARY KEY column with type INTEGER was seen, then it
|
||||
** might be an alise for the ROWID. But it might also be a WITHOUT ROWID
|
||||
** table or a INTEGER PRIMARY KEY DESC column, neither of which are
|
||||
** ROWID aliases. To distinguish these cases, check to see if
|
||||
** there is a "pk" entry in "PRAGMA index_list". There will be
|
||||
** no "pk" index if the PRIMARY KEY really is an alias for the ROWID.
|
||||
*/
|
||||
zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)"
|
||||
" WHERE origin='pk'", zTab);
|
||||
if( zSql==0 ) goto col_oom;
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
||||
sqlite3_free(zSql);
|
||||
if( rc ){
|
||||
freeColumnList(azCol);
|
||||
return 0;
|
||||
}
|
||||
rc = sqlite3_step(pStmt);
|
||||
sqlite3_finalize(pStmt);
|
||||
pStmt = 0;
|
||||
preserveRowid = rc==SQLITE_ROW;
|
||||
}
|
||||
if( preserveRowid ){
|
||||
/* Only preserve the rowid if we can find a name to use for the
|
||||
** rowid */
|
||||
static char *azRowid[] = { "rowid", "_rowid_", "oid" };
|
||||
int i, j;
|
||||
for(j=0; j<3; j++){
|
||||
for(i=1; i<=nCol; i++){
|
||||
if( sqlite3_stricmp(azRowid[j],azCol[i])==0 ) break;
|
||||
}
|
||||
if( i>nCol ){
|
||||
/* At this point, we know that azRowid[j] is not the name of any
|
||||
** ordinary column in the table. Verify that azRowid[j] is a valid
|
||||
** name for the rowid before adding it to azCol[0]. WITHOUT ROWID
|
||||
** tables will fail this last check */
|
||||
int rc;
|
||||
rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0);
|
||||
if( rc==SQLITE_OK ) azCol[0] = azRowid[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return azCol;
|
||||
|
||||
col_oom:
|
||||
sqlite3_finalize(pStmt);
|
||||
freeColumnList(azCol);
|
||||
p->nErr++;
|
||||
p->rc = SQLITE_NOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Send mprintf-formatted content to the output callback.
|
||||
*/
|
||||
static void output_formatted(DState *p, const char *zFormat, ...){
|
||||
va_list ap;
|
||||
char *z;
|
||||
va_start(ap, zFormat);
|
||||
z = sqlite3_vmprintf(zFormat, ap);
|
||||
va_end(ap);
|
||||
p->xCallback(z, p->pArg);
|
||||
sqlite3_free(z);
|
||||
}
|
||||
|
||||
/*
|
||||
** Find a string that is not found anywhere in z[]. Return a pointer
|
||||
** to that string.
|
||||
**
|
||||
** Try to use zA and zB first. If both of those are already found in z[]
|
||||
** then make up some string and store it in the buffer zBuf.
|
||||
*/
|
||||
static const char *unused_string(
|
||||
const char *z, /* Result must not appear anywhere in z */
|
||||
const char *zA, const char *zB, /* Try these first */
|
||||
char *zBuf /* Space to store a generated string */
|
||||
){
|
||||
unsigned i = 0;
|
||||
if( strstr(z, zA)==0 ) return zA;
|
||||
if( strstr(z, zB)==0 ) return zB;
|
||||
do{
|
||||
sqlite3_snprintf(20,zBuf,"(%s%u)", zA, i++);
|
||||
}while( strstr(z,zBuf)!=0 );
|
||||
return zBuf;
|
||||
}
|
||||
|
||||
/*
|
||||
** Output the given string as a quoted string using SQL quoting conventions.
|
||||
** Additionallly , escape the "\n" and "\r" characters so that they do not
|
||||
** get corrupted by end-of-line translation facilities in some operating
|
||||
** systems.
|
||||
*/
|
||||
static void output_quoted_escaped_string(DState *p, const char *z){
|
||||
int i;
|
||||
char c;
|
||||
for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){}
|
||||
if( c==0 ){
|
||||
output_formatted(p,"'%s'",z);
|
||||
}else{
|
||||
const char *zNL = 0;
|
||||
const char *zCR = 0;
|
||||
int nNL = 0;
|
||||
int nCR = 0;
|
||||
char zBuf1[20], zBuf2[20];
|
||||
for(i=0; z[i]; i++){
|
||||
if( z[i]=='\n' ) nNL++;
|
||||
if( z[i]=='\r' ) nCR++;
|
||||
}
|
||||
if( nNL ){
|
||||
p->xCallback("replace(", p->pArg);
|
||||
zNL = unused_string(z, "\\n", "\\012", zBuf1);
|
||||
}
|
||||
if( nCR ){
|
||||
p->xCallback("replace(", p->pArg);
|
||||
zCR = unused_string(z, "\\r", "\\015", zBuf2);
|
||||
}
|
||||
p->xCallback("'", p->pArg);
|
||||
while( *z ){
|
||||
for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){}
|
||||
if( c=='\'' ) i++;
|
||||
if( i ){
|
||||
output_formatted(p, "%.*s", i, z);
|
||||
z += i;
|
||||
}
|
||||
if( c=='\'' ){
|
||||
p->xCallback("'", p->pArg);
|
||||
continue;
|
||||
}
|
||||
if( c==0 ){
|
||||
break;
|
||||
}
|
||||
z++;
|
||||
if( c=='\n' ){
|
||||
p->xCallback(zNL, p->pArg);
|
||||
continue;
|
||||
}
|
||||
p->xCallback(zCR, p->pArg);
|
||||
}
|
||||
p->xCallback("'", p->pArg);
|
||||
if( nCR ){
|
||||
output_formatted(p, ",'%s',char(13))", zCR);
|
||||
}
|
||||
if( nNL ){
|
||||
output_formatted(p, ",'%s',char(10))", zNL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** This is an sqlite3_exec callback routine used for dumping the database.
|
||||
** Each row received by this callback consists of a table name,
|
||||
** the table type ("index" or "table") and SQL to create the table.
|
||||
** This routine should print text sufficient to recreate the table.
|
||||
*/
|
||||
static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
|
||||
int rc;
|
||||
const char *zTable;
|
||||
const char *zType;
|
||||
const char *zSql;
|
||||
DState *p = (DState*)pArg;
|
||||
sqlite3_stmt *pStmt;
|
||||
|
||||
(void)azCol;
|
||||
if( nArg!=3 ) return 1;
|
||||
zTable = azArg[0];
|
||||
zType = azArg[1];
|
||||
zSql = azArg[2];
|
||||
|
||||
if( strcmp(zTable, "sqlite_sequence")==0 ){
|
||||
p->xCallback("DELETE FROM sqlite_sequence;\n", p->pArg);
|
||||
}else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
|
||||
p->xCallback("ANALYZE sqlite_master;\n", p->pArg);
|
||||
}else if( strncmp(zTable, "sqlite_", 7)==0 ){
|
||||
return 0;
|
||||
}else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
|
||||
if( !p->writableSchema ){
|
||||
p->xCallback("PRAGMA writable_schema=ON;\n", p->pArg);
|
||||
p->writableSchema = 1;
|
||||
}
|
||||
output_formatted(p,
|
||||
"INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
|
||||
"VALUES('table','%q','%q',0,'%q');",
|
||||
zTable, zTable, zSql);
|
||||
return 0;
|
||||
}else{
|
||||
if( sqlite3_strglob("CREATE TABLE ['\"]*", zSql)==0 ){
|
||||
p->xCallback("CREATE TABLE IF NOT EXISTS ", p->pArg);
|
||||
p->xCallback(zSql+13, p->pArg);
|
||||
}else{
|
||||
p->xCallback(zSql, p->pArg);
|
||||
}
|
||||
p->xCallback(";\n", p->pArg);
|
||||
}
|
||||
|
||||
if( strcmp(zType, "table")==0 ){
|
||||
DText sSelect;
|
||||
DText sTable;
|
||||
char **azCol;
|
||||
int i;
|
||||
int nCol;
|
||||
|
||||
azCol = tableColumnList(p, zTable);
|
||||
if( azCol==0 ) return 0;
|
||||
|
||||
initText(&sTable);
|
||||
appendText(&sTable, "INSERT INTO ", 0);
|
||||
|
||||
/* Always quote the table name, even if it appears to be pure ascii,
|
||||
** in case it is a keyword. Ex: INSERT INTO "table" ... */
|
||||
appendText(&sTable, zTable, quoteChar(zTable));
|
||||
|
||||
/* If preserving the rowid, add a column list after the table name.
|
||||
** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)"
|
||||
** instead of the usual "INSERT INTO tab VALUES(...)".
|
||||
*/
|
||||
if( azCol[0] ){
|
||||
appendText(&sTable, "(", 0);
|
||||
appendText(&sTable, azCol[0], 0);
|
||||
for(i=1; azCol[i]; i++){
|
||||
appendText(&sTable, ",", 0);
|
||||
appendText(&sTable, azCol[i], quoteChar(azCol[i]));
|
||||
}
|
||||
appendText(&sTable, ")", 0);
|
||||
}
|
||||
appendText(&sTable, " VALUES(", 0);
|
||||
|
||||
/* Build an appropriate SELECT statement */
|
||||
initText(&sSelect);
|
||||
appendText(&sSelect, "SELECT ", 0);
|
||||
if( azCol[0] ){
|
||||
appendText(&sSelect, azCol[0], 0);
|
||||
appendText(&sSelect, ",", 0);
|
||||
}
|
||||
for(i=1; azCol[i]; i++){
|
||||
appendText(&sSelect, azCol[i], quoteChar(azCol[i]));
|
||||
if( azCol[i+1] ){
|
||||
appendText(&sSelect, ",", 0);
|
||||
}
|
||||
}
|
||||
nCol = i;
|
||||
if( azCol[0]==0 ) nCol--;
|
||||
freeColumnList(azCol);
|
||||
appendText(&sSelect, " FROM ", 0);
|
||||
appendText(&sSelect, zTable, quoteChar(zTable));
|
||||
|
||||
rc = sqlite3_prepare_v2(p->db, sSelect.z, -1, &pStmt, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
p->nErr++;
|
||||
if( p->rc==SQLITE_OK ) p->rc = rc;
|
||||
}else{
|
||||
while( SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||
p->xCallback(sTable.z, p->pArg);
|
||||
for(i=0; i<nCol; i++){
|
||||
if( i ) p->xCallback(",", p->pArg);
|
||||
switch( sqlite3_column_type(pStmt,i) ){
|
||||
case SQLITE_INTEGER: {
|
||||
output_formatted(p, "%lld", sqlite3_column_int64(pStmt,i));
|
||||
break;
|
||||
}
|
||||
case SQLITE_FLOAT: {
|
||||
double r = sqlite3_column_double(pStmt,i);
|
||||
output_formatted(p, "%!.20g", r);
|
||||
break;
|
||||
}
|
||||
case SQLITE_NULL: {
|
||||
p->xCallback("NULL", p->pArg);
|
||||
break;
|
||||
}
|
||||
case SQLITE_TEXT: {
|
||||
output_quoted_escaped_string(p,
|
||||
(const char*)sqlite3_column_text(pStmt,i));
|
||||
break;
|
||||
}
|
||||
case SQLITE_BLOB: {
|
||||
int nByte = sqlite3_column_bytes(pStmt,i);
|
||||
unsigned char *a = (unsigned char*)sqlite3_column_blob(pStmt,i);
|
||||
int j;
|
||||
p->xCallback("x'", p->pArg);
|
||||
for(j=0; j<nByte; j++){
|
||||
char zWord[3];
|
||||
zWord[0] = "0123456789abcdef"[(a[j]>>4)&15];
|
||||
zWord[1] = "0123456789abcdef"[a[j]&15];
|
||||
zWord[2] = 0;
|
||||
p->xCallback(zWord, p->pArg);
|
||||
}
|
||||
p->xCallback("'", p->pArg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
p->xCallback(");\n", p->pArg);
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
freeText(&sTable);
|
||||
freeText(&sSelect);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Execute a query statement that will generate SQL output. Print
|
||||
** the result columns, comma-separated, on a line and then add a
|
||||
** semicolon terminator to the end of that line.
|
||||
**
|
||||
** If the number of columns is 1 and that column contains text "--"
|
||||
** then write the semicolon on a separate line. That way, if a
|
||||
** "--" comment occurs at the end of the statement, the comment
|
||||
** won't consume the semicolon terminator.
|
||||
*/
|
||||
static void output_sql_from_query(
|
||||
DState *p, /* Query context */
|
||||
const char *zSelect, /* SELECT statement to extract content */
|
||||
...
|
||||
){
|
||||
sqlite3_stmt *pSelect;
|
||||
int rc;
|
||||
int nResult;
|
||||
int i;
|
||||
const char *z;
|
||||
char *zSql;
|
||||
va_list ap;
|
||||
va_start(ap, zSelect);
|
||||
zSql = sqlite3_vmprintf(zSelect, ap);
|
||||
va_end(ap);
|
||||
if( zSql==0 ){
|
||||
p->rc = SQLITE_NOMEM;
|
||||
p->nErr++;
|
||||
return;
|
||||
}
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pSelect, 0);
|
||||
sqlite3_free(zSql);
|
||||
if( rc!=SQLITE_OK || !pSelect ){
|
||||
output_formatted(p, "/**** ERROR: (%d) %s *****/\n", rc,
|
||||
sqlite3_errmsg(p->db));
|
||||
p->nErr++;
|
||||
return;
|
||||
}
|
||||
rc = sqlite3_step(pSelect);
|
||||
nResult = sqlite3_column_count(pSelect);
|
||||
while( rc==SQLITE_ROW ){
|
||||
z = (const char*)sqlite3_column_text(pSelect, 0);
|
||||
p->xCallback(z, p->pArg);
|
||||
for(i=1; i<nResult; i++){
|
||||
p->xCallback(",", p->pArg);
|
||||
p->xCallback((const char*)sqlite3_column_text(pSelect,i), p->pArg);
|
||||
}
|
||||
if( z==0 ) z = "";
|
||||
while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
|
||||
if( z[0] ){
|
||||
p->xCallback("\n;\n", p->pArg);
|
||||
}else{
|
||||
p->xCallback(";\n", p->pArg);
|
||||
}
|
||||
rc = sqlite3_step(pSelect);
|
||||
}
|
||||
rc = sqlite3_finalize(pSelect);
|
||||
if( rc!=SQLITE_OK ){
|
||||
output_formatted(p, "/**** ERROR: (%d) %s *****/\n", rc,
|
||||
sqlite3_errmsg(p->db));
|
||||
if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Run zQuery. Use dump_callback() as the callback routine so that
|
||||
** the contents of the query are output as SQL statements.
|
||||
**
|
||||
** If we get a SQLITE_CORRUPT error, rerun the query after appending
|
||||
** "ORDER BY rowid DESC" to the end.
|
||||
*/
|
||||
static void run_schema_dump_query(
|
||||
DState *p,
|
||||
const char *zQuery,
|
||||
...
|
||||
){
|
||||
char *zErr = 0;
|
||||
char *z;
|
||||
va_list ap;
|
||||
va_start(ap, zQuery);
|
||||
z = sqlite3_vmprintf(zQuery, ap);
|
||||
va_end(ap);
|
||||
sqlite3_exec(p->db, z, dump_callback, p, &zErr);
|
||||
sqlite3_free(z);
|
||||
if( zErr ){
|
||||
output_formatted(p, "/****** %s ******/\n", zErr);
|
||||
sqlite3_free(zErr);
|
||||
p->nErr++;
|
||||
zErr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Convert an SQLite database into SQL statements that will recreate that
|
||||
** database.
|
||||
*/
|
||||
int sqlite3_db_dump(
|
||||
sqlite3 *db, /* The database connection */
|
||||
const char *zSchema, /* Which schema to dump. Usually "main". */
|
||||
const char *zTable, /* Which table to dump. NULL means everything. */
|
||||
int (*xCallback)(const char*,void*), /* Output sent to this callback */
|
||||
void *pArg /* Second argument of the callback */
|
||||
){
|
||||
DState x;
|
||||
memset(&x, 0, sizeof(x));
|
||||
x.rc = sqlite3_exec(db, "BEGIN", 0, 0, 0);
|
||||
if( x.rc ) return x.rc;
|
||||
x.db = db;
|
||||
x.xCallback = xCallback;
|
||||
x.pArg = pArg;
|
||||
xCallback("PRAGMA foreign_keys=OFF;\nBEGIN TRANSACTION;\n", pArg);
|
||||
if( zTable==0 ){
|
||||
run_schema_dump_query(&x,
|
||||
"SELECT name, type, sql FROM \"%w\".sqlite_master "
|
||||
"WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'",
|
||||
zSchema
|
||||
);
|
||||
run_schema_dump_query(&x,
|
||||
"SELECT name, type, sql FROM \"%w\".sqlite_master "
|
||||
"WHERE name=='sqlite_sequence'", zSchema
|
||||
);
|
||||
output_sql_from_query(&x,
|
||||
"SELECT sql FROM sqlite_master "
|
||||
"WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
|
||||
);
|
||||
}else{
|
||||
run_schema_dump_query(&x,
|
||||
"SELECT name, type, sql FROM \"%w\".sqlite_master "
|
||||
"WHERE tbl_name=%Q COLLATE nocase AND type=='table'"
|
||||
" AND sql NOT NULL",
|
||||
zSchema, zTable
|
||||
);
|
||||
output_sql_from_query(&x,
|
||||
"SELECT sql FROM \"%w\".sqlite_master "
|
||||
"WHERE sql NOT NULL"
|
||||
" AND type IN ('index','trigger','view')"
|
||||
" AND tbl_name=%Q COLLATE nocase",
|
||||
zSchema, zTable
|
||||
);
|
||||
}
|
||||
if( x.writableSchema ){
|
||||
xCallback("PRAGMA writable_schema=OFF;\n", pArg);
|
||||
}
|
||||
xCallback(x.nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n", pArg);
|
||||
sqlite3_exec(db, "COMMIT", 0, 0, 0);
|
||||
return x.rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The generic subroutine is above. The code the follows implements
|
||||
** the command-line interface.
|
||||
*/
|
||||
#ifdef DBDUMP_STANDALONE
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
** Command-line interface
|
||||
*/
|
||||
int main(int argc, char **argv){
|
||||
sqlite3 *db;
|
||||
const char *zDb;
|
||||
const char *zSchema;
|
||||
const char *zTable = 0;
|
||||
int rc;
|
||||
|
||||
if( argc<2 || argc>4 ){
|
||||
fprintf(stderr, "Usage: %s DATABASE ?SCHEMA? ?TABLE?\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
zDb = argv[1];
|
||||
zSchema = argc>=3 ? argv[2] : "main";
|
||||
zTable = argc==4 ? argv[3] : 0;
|
||||
|
||||
rc = sqlite3_open(zDb, &db);
|
||||
if( rc ){
|
||||
fprintf(stderr, "Cannot open \"%s\": %s\n", zDb, sqlite3_errmsg(db));
|
||||
sqlite3_close(db);
|
||||
return 1;
|
||||
}
|
||||
rc = sqlite3_db_dump(db, zSchema, zTable,
|
||||
(int(*)(const char*,void*))fputs, (void*)stdout);
|
||||
if( rc ){
|
||||
fprintf(stderr, "Error: sqlite3_db_dump() returns %d\n", rc);
|
||||
}
|
||||
sqlite3_close(db);
|
||||
return rc!=SQLITE_OK;
|
||||
}
|
||||
#endif /* DBDUMP_STANDALONE */
|
||||
+61
-258
@@ -90,7 +90,6 @@ static const char jsonIsSpace[] = {
|
||||
** 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
|
||||
|
||||
@@ -139,10 +138,9 @@ static const char * const jsonType[] = {
|
||||
#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 */
|
||||
#define JNODE_REPLACE 0x08 /* Replace with JsonNode.iVal */
|
||||
#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */
|
||||
#define JNODE_LABEL 0x20 /* Is a label of an object */
|
||||
|
||||
|
||||
/* A single node of parsed JSON
|
||||
@@ -150,13 +148,12 @@ static const char * const jsonType[] = {
|
||||
struct JsonNode {
|
||||
u8 eType; /* One of the JSON_ type values */
|
||||
u8 jnFlags; /* JNODE flags */
|
||||
u8 iVal; /* Replacement value when JNODE_REPLACE */
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -170,19 +167,8 @@ struct JsonParse {
|
||||
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
|
||||
**************************************************************************/
|
||||
@@ -414,14 +400,6 @@ static void jsonParseReset(JsonParse *pParse){
|
||||
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
|
||||
@@ -432,13 +410,6 @@ static void jsonRenderNode(
|
||||
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 );
|
||||
@@ -470,7 +441,12 @@ static void jsonRenderNode(
|
||||
jsonAppendChar(pOut, '[');
|
||||
for(;;){
|
||||
while( j<=pNode->n ){
|
||||
if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){
|
||||
if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
|
||||
if( pNode[j].jnFlags & JNODE_REPLACE ){
|
||||
jsonAppendSeparator(pOut);
|
||||
jsonAppendValue(pOut, aReplace[pNode[j].iVal]);
|
||||
}
|
||||
}else{
|
||||
jsonAppendSeparator(pOut);
|
||||
jsonRenderNode(&pNode[j], pOut, aReplace);
|
||||
}
|
||||
@@ -492,7 +468,11 @@ static void jsonRenderNode(
|
||||
jsonAppendSeparator(pOut);
|
||||
jsonRenderNode(&pNode[j], pOut, aReplace);
|
||||
jsonAppendChar(pOut, ':');
|
||||
jsonRenderNode(&pNode[j+1], pOut, aReplace);
|
||||
if( pNode[j+1].jnFlags & JNODE_REPLACE ){
|
||||
jsonAppendValue(pOut, aReplace[pNode[j+1].iVal]);
|
||||
}else{
|
||||
jsonRenderNode(&pNode[j+1], pOut, aReplace);
|
||||
}
|
||||
}
|
||||
j += 1 + jsonNodeSize(&pNode[j+1]);
|
||||
}
|
||||
@@ -719,6 +699,7 @@ static int jsonParseAddNode(
|
||||
p = &pParse->aNode[pParse->nNode];
|
||||
p->eType = (u8)eType;
|
||||
p->jnFlags = 0;
|
||||
p->iVal = 0;
|
||||
p->n = n;
|
||||
p->u.zJContent = zContent;
|
||||
return pParse->nNode++;
|
||||
@@ -747,18 +728,15 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
|
||||
int iThis;
|
||||
int x;
|
||||
JsonNode *pNode;
|
||||
const char *z = pParse->zJson;
|
||||
while( safe_isspace(z[i]) ){ i++; }
|
||||
if( (c = z[i])=='{' ){
|
||||
while( safe_isspace(pParse->zJson[i]) ){ i++; }
|
||||
if( (c = pParse->zJson[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;
|
||||
while( safe_isspace(pParse->zJson[j]) ){ j++; }
|
||||
x = jsonParseValue(pParse, j);
|
||||
if( x<0 ){
|
||||
pParse->iDepth--;
|
||||
if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
|
||||
return -1;
|
||||
}
|
||||
@@ -767,15 +745,14 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
|
||||
if( pNode->eType!=JSON_STRING ) return -1;
|
||||
pNode->jnFlags |= JNODE_LABEL;
|
||||
j = x;
|
||||
while( safe_isspace(z[j]) ){ j++; }
|
||||
if( z[j]!=':' ) return -1;
|
||||
while( safe_isspace(pParse->zJson[j]) ){ j++; }
|
||||
if( pParse->zJson[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];
|
||||
while( safe_isspace(pParse->zJson[j]) ){ j++; }
|
||||
c = pParse->zJson[j];
|
||||
if( c==',' ) continue;
|
||||
if( c!='}' ) return -1;
|
||||
break;
|
||||
@@ -787,17 +764,15 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
|
||||
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;
|
||||
while( safe_isspace(pParse->zJson[j]) ){ j++; }
|
||||
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];
|
||||
while( safe_isspace(pParse->zJson[j]) ){ j++; }
|
||||
c = pParse->zJson[j];
|
||||
if( c==',' ) continue;
|
||||
if( c!=']' ) return -1;
|
||||
break;
|
||||
@@ -809,16 +784,13 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
|
||||
u8 jnFlags = 0;
|
||||
j = i+1;
|
||||
for(;;){
|
||||
c = z[j];
|
||||
if( (c & ~0x1f)==0 ){
|
||||
/* Control characters are not allowed in strings */
|
||||
return -1;
|
||||
}
|
||||
c = pParse->zJson[j];
|
||||
if( c==0 ) return -1;
|
||||
if( c=='\\' ){
|
||||
c = z[++j];
|
||||
c = pParse->zJson[++j];
|
||||
if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
|
||||
|| c=='n' || c=='r' || c=='t'
|
||||
|| (c=='u' && jsonIs4Hex(z+j+1)) ){
|
||||
|| (c=='u' && jsonIs4Hex(pParse->zJson+j+1)) ){
|
||||
jnFlags = JNODE_ESCAPE;
|
||||
}else{
|
||||
return -1;
|
||||
@@ -828,60 +800,55 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
|
||||
}
|
||||
j++;
|
||||
}
|
||||
jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]);
|
||||
jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[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]) ){
|
||||
&& strncmp(pParse->zJson+i,"null",4)==0
|
||||
&& !safe_isalnum(pParse->zJson[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]) ){
|
||||
&& strncmp(pParse->zJson+i,"true",4)==0
|
||||
&& !safe_isalnum(pParse->zJson[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]) ){
|
||||
&& strncmp(pParse->zJson+i,"false",5)==0
|
||||
&& !safe_isalnum(pParse->zJson[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];
|
||||
c = pParse->zJson[j];
|
||||
if( c>='0' && c<='9' ) continue;
|
||||
if( c=='.' ){
|
||||
if( z[j-1]=='-' ) return -1;
|
||||
if( pParse->zJson[j-1]=='-' ) return -1;
|
||||
if( seenDP ) return -1;
|
||||
seenDP = 1;
|
||||
continue;
|
||||
}
|
||||
if( c=='e' || c=='E' ){
|
||||
if( z[j-1]<'0' ) return -1;
|
||||
if( pParse->zJson[j-1]<'0' ) return -1;
|
||||
if( seenE ) return -1;
|
||||
seenDP = seenE = 1;
|
||||
c = z[j+1];
|
||||
c = pParse->zJson[j+1];
|
||||
if( c=='+' || c=='-' ){
|
||||
j++;
|
||||
c = z[j+1];
|
||||
c = pParse->zJson[j+1];
|
||||
}
|
||||
if( c<'0' || c>'9' ) return -1;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if( z[j-1]<'0' ) return -1;
|
||||
if( pParse->zJson[j-1]<'0' ) return -1;
|
||||
jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
|
||||
j - i, &z[i]);
|
||||
j - i, &pParse->zJson[i]);
|
||||
return j;
|
||||
}else if( c=='}' ){
|
||||
return -2; /* End of {...} */
|
||||
@@ -913,7 +880,6 @@ static int jsonParse(
|
||||
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;
|
||||
}
|
||||
@@ -973,49 +939,6 @@ static int jsonParseFindParents(JsonParse *pParse){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** 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.
|
||||
@@ -1242,25 +1165,6 @@ static void jsonWrongNumArgs(
|
||||
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
|
||||
@@ -1381,30 +1285,29 @@ static void jsonArrayLengthFunc(
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
JsonParse *p; /* The parse */
|
||||
JsonParse x; /* The parse */
|
||||
sqlite3_int64 n = 0;
|
||||
u32 i;
|
||||
JsonNode *pNode;
|
||||
|
||||
p = jsonParseCached(ctx, argv);
|
||||
if( p==0 ) return;
|
||||
assert( p->nNode );
|
||||
if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
|
||||
assert( x.nNode );
|
||||
if( argc==2 ){
|
||||
const char *zPath = (const char*)sqlite3_value_text(argv[1]);
|
||||
pNode = jsonLookup(p, zPath, 0, ctx);
|
||||
pNode = jsonLookup(&x, zPath, 0, ctx);
|
||||
}else{
|
||||
pNode = p->aNode;
|
||||
pNode = x.aNode;
|
||||
}
|
||||
if( pNode==0 ){
|
||||
return;
|
||||
}
|
||||
if( pNode->eType==JSON_ARRAY ){
|
||||
x.nErr = 1;
|
||||
}else 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);
|
||||
if( x.nErr==0 ) sqlite3_result_int64(ctx, n);
|
||||
jsonParseReset(&x);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1420,21 +1323,20 @@ static void jsonExtractFunc(
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
JsonParse *p; /* The parse */
|
||||
JsonParse x; /* The parse */
|
||||
JsonNode *pNode;
|
||||
const char *zPath;
|
||||
JsonString jx;
|
||||
int i;
|
||||
|
||||
if( argc<2 ) return;
|
||||
p = jsonParseCached(ctx, argv);
|
||||
if( p==0 ) return;
|
||||
if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[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;
|
||||
pNode = jsonLookup(&x, zPath, 0, ctx);
|
||||
if( x.nErr ) break;
|
||||
if( argc>2 ){
|
||||
jsonAppendSeparator(&jx);
|
||||
if( pNode ){
|
||||
@@ -1452,107 +1354,9 @@ static void jsonExtractFunc(
|
||||
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
|
||||
@@ -1656,11 +1460,11 @@ static void jsonReplaceFunc(
|
||||
if( x.nErr ) goto replace_err;
|
||||
if( pNode ){
|
||||
pNode->jnFlags |= (u8)JNODE_REPLACE;
|
||||
pNode->u.iReplace = i + 1;
|
||||
pNode->iVal = (u8)(i+1);
|
||||
}
|
||||
}
|
||||
if( x.aNode[0].jnFlags & JNODE_REPLACE ){
|
||||
sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
|
||||
sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
|
||||
}else{
|
||||
jsonReturnJson(x.aNode, ctx, argv);
|
||||
}
|
||||
@@ -1710,11 +1514,11 @@ static void jsonSetFunc(
|
||||
goto jsonSetDone;
|
||||
}else if( pNode && (bApnd || bIsSet) ){
|
||||
pNode->jnFlags |= (u8)JNODE_REPLACE;
|
||||
pNode->u.iReplace = i + 1;
|
||||
pNode->iVal = (u8)(i+1);
|
||||
}
|
||||
}
|
||||
if( x.aNode[0].jnFlags & JNODE_REPLACE ){
|
||||
sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
|
||||
sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
|
||||
}else{
|
||||
jsonReturnJson(x.aNode, ctx, argv);
|
||||
}
|
||||
@@ -2357,7 +2161,6 @@ int sqlite3Json1Init(sqlite3 *db){
|
||||
{ "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 },
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@
|
||||
** The generate_series "function" is really a virtual table with the
|
||||
** following schema:
|
||||
**
|
||||
** CREATE TABLE generate_series(
|
||||
** CREATE FUNCTION generate_series(
|
||||
** value,
|
||||
** start HIDDEN,
|
||||
** stop HIDDEN,
|
||||
|
||||
@@ -21,10 +21,6 @@
|
||||
**
|
||||
** The sha3_query(Y) function evalutes all queries in the SQL statements of Y
|
||||
** and returns a hash of their results.
|
||||
**
|
||||
** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm
|
||||
** is used. If SIZE is included it must be one of the integers 224, 256,
|
||||
** 384, or 512, to determine SHA3 hash variant that is computed.
|
||||
*/
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
|
||||
@@ -1,299 +0,0 @@
|
||||
/*
|
||||
** 2017-05-31
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
**
|
||||
** This file demonstrates an eponymous virtual table that returns information
|
||||
** about all prepared statements for the database connection.
|
||||
**
|
||||
** Usage example:
|
||||
**
|
||||
** .load ./stmts
|
||||
** .mode line
|
||||
** .header on
|
||||
** SELECT * FROM stmts;
|
||||
*/
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
|
||||
/*
|
||||
** The following macros are used to cast pointers to integers.
|
||||
** The way you do this varies from one compiler
|
||||
** to the next, so we have developed the following set of #if statements
|
||||
** to generate appropriate macros for a wide range of compilers.
|
||||
*/
|
||||
#if defined(__PTRDIFF_TYPE__) /* This case should work for GCC */
|
||||
# define SQLITE_PTR_TO_INT64(X) ((sqlite3_int64)(__PTRDIFF_TYPE__)(X))
|
||||
#elif !defined(__GNUC__) /* Works for compilers other than LLVM */
|
||||
# define SQLITE_PTR_TO_INT64(X) ((sqlite3_int64)(((char*)X)-(char*)0))
|
||||
#elif defined(HAVE_STDINT_H) /* Use this case if we have ANSI headers */
|
||||
# define SQLITE_PTR_TO_INT64(X) ((sqlite3_int64)(intptr_t)(X))
|
||||
#else /* Generates a warning - but it always works */
|
||||
# define SQLITE_PTR_TO_INT64(X) ((sqlite3_int64)(X))
|
||||
#endif
|
||||
|
||||
|
||||
/* stmts_vtab is a subclass of sqlite3_vtab which will
|
||||
** serve as the underlying representation of a stmts virtual table
|
||||
*/
|
||||
typedef struct stmts_vtab stmts_vtab;
|
||||
struct stmts_vtab {
|
||||
sqlite3_vtab base; /* Base class - must be first */
|
||||
sqlite3 *db; /* Database connection for this stmts vtab */
|
||||
};
|
||||
|
||||
/* stmts_cursor is a subclass of sqlite3_vtab_cursor which will
|
||||
** serve as the underlying representation of a cursor that scans
|
||||
** over rows of the result
|
||||
*/
|
||||
typedef struct stmts_cursor stmts_cursor;
|
||||
struct stmts_cursor {
|
||||
sqlite3_vtab_cursor base; /* Base class - must be first */
|
||||
sqlite3 *db; /* Database connection for this cursor */
|
||||
sqlite3_stmt *pStmt; /* Statement cursor is currently pointing at */
|
||||
sqlite3_int64 iRowid; /* The rowid */
|
||||
};
|
||||
|
||||
/*
|
||||
** The stmtsConnect() method is invoked to create a new
|
||||
** stmts_vtab that describes the generate_stmts virtual table.
|
||||
**
|
||||
** Think of this routine as the constructor for stmts_vtab objects.
|
||||
**
|
||||
** All this routine needs to do is:
|
||||
**
|
||||
** (1) Allocate the stmts_vtab object and initialize all fields.
|
||||
**
|
||||
** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
|
||||
** result set of queries against generate_stmts will look like.
|
||||
*/
|
||||
static int stmtsConnect(
|
||||
sqlite3 *db,
|
||||
void *pAux,
|
||||
int argc, const char *const*argv,
|
||||
sqlite3_vtab **ppVtab,
|
||||
char **pzErr
|
||||
){
|
||||
stmts_vtab *pNew;
|
||||
int rc;
|
||||
|
||||
/* Column numbers */
|
||||
#define STMTS_COLUMN_PTR 0 /* Numeric value of the statement pointer */
|
||||
#define STMTS_COLUMN_SQL 1 /* SQL for the statement */
|
||||
#define STMTS_COLUMN_NCOL 2 /* Number of result columns */
|
||||
#define STMTS_COLUMN_RO 3 /* True if read-only */
|
||||
#define STMTS_COLUMN_BUSY 4 /* True if currently busy */
|
||||
#define STMTS_COLUMN_NSCAN 5 /* SQLITE_STMTSTATUS_FULLSCAN_STEP */
|
||||
#define STMTS_COLUMN_NSORT 6 /* SQLITE_STMTSTATUS_SORT */
|
||||
#define STMTS_COLUMN_NAIDX 7 /* SQLITE_STMTSTATUS_AUTOINDEX */
|
||||
#define STMTS_COLUMN_NSTEP 8 /* SQLITE_STMTSTATUS_VM_STEP */
|
||||
#define STMTS_COLUMN_MEM 9 /* SQLITE_STMTSTATUS_MEMUSED */
|
||||
|
||||
|
||||
rc = sqlite3_declare_vtab(db,
|
||||
"CREATE TABLE x(ptr,sql,ncol,ro,busy,nscan,nsort,naidx,nstep,mem)");
|
||||
if( rc==SQLITE_OK ){
|
||||
pNew = sqlite3_malloc( sizeof(*pNew) );
|
||||
*ppVtab = (sqlite3_vtab*)pNew;
|
||||
if( pNew==0 ) return SQLITE_NOMEM;
|
||||
memset(pNew, 0, sizeof(*pNew));
|
||||
pNew->db = db;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** This method is the destructor for stmts_cursor objects.
|
||||
*/
|
||||
static int stmtsDisconnect(sqlite3_vtab *pVtab){
|
||||
sqlite3_free(pVtab);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Constructor for a new stmts_cursor object.
|
||||
*/
|
||||
static int stmtsOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
|
||||
stmts_cursor *pCur;
|
||||
pCur = sqlite3_malloc( sizeof(*pCur) );
|
||||
if( pCur==0 ) return SQLITE_NOMEM;
|
||||
memset(pCur, 0, sizeof(*pCur));
|
||||
pCur->db = ((stmts_vtab*)p)->db;
|
||||
*ppCursor = &pCur->base;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Destructor for a stmts_cursor.
|
||||
*/
|
||||
static int stmtsClose(sqlite3_vtab_cursor *cur){
|
||||
sqlite3_free(cur);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Advance a stmts_cursor to its next row of output.
|
||||
*/
|
||||
static int stmtsNext(sqlite3_vtab_cursor *cur){
|
||||
stmts_cursor *pCur = (stmts_cursor*)cur;
|
||||
pCur->iRowid++;
|
||||
pCur->pStmt = sqlite3_next_stmt(pCur->db, pCur->pStmt);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return values of columns for the row at which the stmts_cursor
|
||||
** is currently pointing.
|
||||
*/
|
||||
static int stmtsColumn(
|
||||
sqlite3_vtab_cursor *cur, /* The cursor */
|
||||
sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
|
||||
int i /* Which column to return */
|
||||
){
|
||||
stmts_cursor *pCur = (stmts_cursor*)cur;
|
||||
switch( i ){
|
||||
case STMTS_COLUMN_PTR: {
|
||||
sqlite3_result_int64(ctx, SQLITE_PTR_TO_INT64(pCur->pStmt));
|
||||
break;
|
||||
}
|
||||
case STMTS_COLUMN_SQL: {
|
||||
sqlite3_result_text(ctx, sqlite3_sql(pCur->pStmt), -1, SQLITE_TRANSIENT);
|
||||
break;
|
||||
}
|
||||
case STMTS_COLUMN_NCOL: {
|
||||
sqlite3_result_int(ctx, sqlite3_column_count(pCur->pStmt));
|
||||
break;
|
||||
}
|
||||
case STMTS_COLUMN_RO: {
|
||||
sqlite3_result_int(ctx, sqlite3_stmt_readonly(pCur->pStmt));
|
||||
break;
|
||||
}
|
||||
case STMTS_COLUMN_BUSY: {
|
||||
sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt));
|
||||
break;
|
||||
}
|
||||
case STMTS_COLUMN_NSCAN:
|
||||
case STMTS_COLUMN_NSORT:
|
||||
case STMTS_COLUMN_NAIDX:
|
||||
case STMTS_COLUMN_NSTEP:
|
||||
case STMTS_COLUMN_MEM: {
|
||||
sqlite3_result_int(ctx, sqlite3_stmt_status(pCur->pStmt,
|
||||
i-STMTS_COLUMN_NSCAN+SQLITE_STMTSTATUS_FULLSCAN_STEP, 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the rowid for the current row. In this implementation, the
|
||||
** rowid is the same as the output value.
|
||||
*/
|
||||
static int stmtsRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
|
||||
stmts_cursor *pCur = (stmts_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 stmtsEof(sqlite3_vtab_cursor *cur){
|
||||
stmts_cursor *pCur = (stmts_cursor*)cur;
|
||||
return pCur->pStmt==0;
|
||||
}
|
||||
|
||||
/*
|
||||
** This method is called to "rewind" the stmts_cursor object back
|
||||
** to the first row of output. This method is always called at least
|
||||
** once prior to any call to stmtsColumn() or stmtsRowid() or
|
||||
** stmtsEof().
|
||||
*/
|
||||
static int stmtsFilter(
|
||||
sqlite3_vtab_cursor *pVtabCursor,
|
||||
int idxNum, const char *idxStr,
|
||||
int argc, sqlite3_value **argv
|
||||
){
|
||||
stmts_cursor *pCur = (stmts_cursor *)pVtabCursor;
|
||||
pCur->pStmt = 0;
|
||||
pCur->iRowid = 0;
|
||||
return stmtsNext(pVtabCursor);
|
||||
}
|
||||
|
||||
/*
|
||||
** SQLite will invoke this method one or more times while planning a query
|
||||
** that uses the generate_stmts virtual table. This routine needs to create
|
||||
** a query plan for each invocation and compute an estimated cost for that
|
||||
** plan.
|
||||
*/
|
||||
static int stmtsBestIndex(
|
||||
sqlite3_vtab *tab,
|
||||
sqlite3_index_info *pIdxInfo
|
||||
){
|
||||
pIdxInfo->estimatedCost = (double)500;
|
||||
pIdxInfo->estimatedRows = 500;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** This following structure defines all the methods for the
|
||||
** generate_stmts virtual table.
|
||||
*/
|
||||
static sqlite3_module stmtsModule = {
|
||||
0, /* iVersion */
|
||||
0, /* xCreate */
|
||||
stmtsConnect, /* xConnect */
|
||||
stmtsBestIndex, /* xBestIndex */
|
||||
stmtsDisconnect, /* xDisconnect */
|
||||
0, /* xDestroy */
|
||||
stmtsOpen, /* xOpen - open a cursor */
|
||||
stmtsClose, /* xClose - close a cursor */
|
||||
stmtsFilter, /* xFilter - configure scan constraints */
|
||||
stmtsNext, /* xNext - advance a cursor */
|
||||
stmtsEof, /* xEof - check for end of scan */
|
||||
stmtsColumn, /* xColumn - read data */
|
||||
stmtsRowid, /* xRowid - read data */
|
||||
0, /* xUpdate */
|
||||
0, /* xBegin */
|
||||
0, /* xSync */
|
||||
0, /* xCommit */
|
||||
0, /* xRollback */
|
||||
0, /* xFindMethod */
|
||||
0, /* xRename */
|
||||
};
|
||||
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_stmts_init(
|
||||
sqlite3 *db,
|
||||
char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
SQLITE_EXTENSION_INIT2(pApi);
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( sqlite3_libversion_number()<3008012 ){
|
||||
*pzErrMsg = sqlite3_mprintf(
|
||||
"generate_stmts() requires SQLite 3.8.12 or later");
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
rc = sqlite3_create_module(db, "stmts", &stmtsModule, 0);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
+2
-2
@@ -82,10 +82,10 @@ int main(int argc, char **argv){
|
||||
int bVacuum = 0;
|
||||
int rc;
|
||||
sqlite3_int64 nProgress = 0;
|
||||
int nArgc = argc-2;
|
||||
int nArg = argc-2;
|
||||
|
||||
if( argc<3 ) usage(argv[0]);
|
||||
for(i=1; i<nArgc; i++){
|
||||
for(i=1; i<nArg; i++){
|
||||
const char *zArg = argv[i];
|
||||
int nArg = strlen(zArg);
|
||||
if( nArg>1 && nArg<=8 && 0==memcmp(zArg, "-vacuum", nArg) ){
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
##########################################################################
|
||||
# 2016 Mar 8
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
proc process_cmdline {} {
|
||||
cmdline::process ::A $::argv {
|
||||
{make "try to build missing tools"}
|
||||
{verbose "make more noise"}
|
||||
database
|
||||
database2
|
||||
} {
|
||||
This script uses/tests the following tools:
|
||||
|
||||
dbselftest
|
||||
rbu
|
||||
sqldiff
|
||||
sqlite3
|
||||
|
||||
The user passes the names of two database files - a.db and b.db below - as
|
||||
arguments. This program:
|
||||
|
||||
1. Runs [dbselftest --init] against both databases.
|
||||
2. Runs [sqldiff --rbu --vtab a.db b.db | sqlite3 <tmpname>.db] to create an
|
||||
RBU database.
|
||||
3. Runs [rbu b.db <tmpname>.db] to patch b.db to a.db.
|
||||
4. Runs [sqldiff --table selftest a.db b.db] to check that the selftest
|
||||
tables are now identical.
|
||||
5. Runs [dbselftest] against both databases.
|
||||
}
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
###########################################################################
|
||||
# Command line options processor. This is generic code that can be copied
|
||||
# between scripts.
|
||||
#
|
||||
namespace eval cmdline {
|
||||
proc cmdline_error {O E {msg ""}} {
|
||||
if {$msg != ""} {
|
||||
puts stderr "Error: $msg"
|
||||
puts stderr ""
|
||||
}
|
||||
|
||||
set L [list]
|
||||
foreach o $O {
|
||||
if {[llength $o]==1} {
|
||||
lappend L [string toupper $o]
|
||||
}
|
||||
}
|
||||
|
||||
puts stderr "Usage: $::argv0 ?SWITCHES? $L"
|
||||
puts stderr ""
|
||||
puts stderr "Switches are:"
|
||||
foreach o $O {
|
||||
if {[llength $o]==3} {
|
||||
foreach {a b c} $o {}
|
||||
puts stderr [format " -%-15s %s (default \"%s\")" "$a VAL" $c $b]
|
||||
} elseif {[llength $o]==2} {
|
||||
foreach {a b} $o {}
|
||||
puts stderr [format " -%-15s %s" $a $b]
|
||||
}
|
||||
}
|
||||
puts stderr ""
|
||||
puts stderr $E
|
||||
exit -1
|
||||
}
|
||||
|
||||
proc process {avar lArgs O E} {
|
||||
upvar $avar A
|
||||
set zTrailing "" ;# True if ... is present in $O
|
||||
set lPosargs [list]
|
||||
|
||||
# Populate A() with default values. Also, for each switch in the command
|
||||
# line spec, set an entry in the idx() array as follows:
|
||||
#
|
||||
# {tblname t1 "table name to use"}
|
||||
# -> [set idx(-tblname) {tblname t1 "table name to use"}
|
||||
#
|
||||
# For each position parameter, append its name to $lPosargs. If the ...
|
||||
# specifier is present, set $zTrailing to the name of the prefix.
|
||||
#
|
||||
foreach o $O {
|
||||
set nm [lindex $o 0]
|
||||
set nArg [llength $o]
|
||||
switch -- $nArg {
|
||||
1 {
|
||||
if {[string range $nm end-2 end]=="..."} {
|
||||
set zTrailing [string range $nm 0 end-3]
|
||||
} else {
|
||||
lappend lPosargs $nm
|
||||
}
|
||||
}
|
||||
2 {
|
||||
set A($nm) 0
|
||||
set idx(-$nm) $o
|
||||
}
|
||||
3 {
|
||||
set A($nm) [lindex $o 1]
|
||||
set idx(-$nm) $o
|
||||
}
|
||||
default {
|
||||
error "Error in command line specification"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Set explicitly specified option values
|
||||
#
|
||||
set nArg [llength $lArgs]
|
||||
for {set i 0} {$i < $nArg} {incr i} {
|
||||
set opt [lindex $lArgs $i]
|
||||
if {[string range $opt 0 0]!="-" || $opt=="--"} break
|
||||
set c [array names idx "${opt}*"]
|
||||
if {[llength $c]==0} { cmdline_error $O $E "Unrecognized option: $opt"}
|
||||
if {[llength $c]>1} { cmdline_error $O $E "Ambiguous option: $opt"}
|
||||
|
||||
if {[llength $idx($c)]==3} {
|
||||
if {$i==[llength $lArgs]-1} {
|
||||
cmdline_error $O $E "Option requires argument: $c"
|
||||
}
|
||||
incr i
|
||||
set A([lindex $idx($c) 0]) [lindex $lArgs $i]
|
||||
} else {
|
||||
set A([lindex $idx($c) 0]) 1
|
||||
}
|
||||
}
|
||||
|
||||
# Deal with position arguments.
|
||||
#
|
||||
set nPosarg [llength $lPosargs]
|
||||
set nRem [expr $nArg - $i]
|
||||
if {$nRem < $nPosarg || ($zTrailing=="" && $nRem > $nPosarg)} {
|
||||
cmdline_error $O $E
|
||||
}
|
||||
for {set j 0} {$j < $nPosarg} {incr j} {
|
||||
set A([lindex $lPosargs $j]) [lindex $lArgs [expr $j+$i]]
|
||||
}
|
||||
if {$zTrailing!=""} {
|
||||
set A($zTrailing) [lrange $lArgs [expr $j+$i] end]
|
||||
}
|
||||
}
|
||||
} ;# namespace eval cmdline
|
||||
# End of command line options processor.
|
||||
###########################################################################
|
||||
###########################################################################
|
||||
|
||||
process_cmdline
|
||||
|
||||
# Check that the specified tool is present.
|
||||
#
|
||||
proc check_for_tool {tool} {
|
||||
if {[file exists $tool]==0 || [file executable $tool]==0} {
|
||||
puts stderr "Missing $tool... exiting. (run \[make $tool\])"
|
||||
exit -1
|
||||
}
|
||||
}
|
||||
|
||||
if {$A(make)} {
|
||||
if {$A(verbose)} { puts "building tools..." }
|
||||
exec make dbselftest rbu sqlite3 sqldiff
|
||||
}
|
||||
|
||||
check_for_tool dbselftest
|
||||
check_for_tool rbu
|
||||
check_for_tool sqlite3
|
||||
check_for_tool sqldiff
|
||||
|
||||
exec ./sqlite3 $A(database) "DROP TABLE selftest;"
|
||||
exec ./sqlite3 $A(database2) "DROP TABLE selftest;"
|
||||
|
||||
# Run [dbselftest --init] on both databases
|
||||
if {$A(verbose)} { puts "Running \[dbselftest --init\]" }
|
||||
exec ./dbselftest --init $A(database)
|
||||
exec ./dbselftest --init $A(database2)
|
||||
|
||||
# Create an RBU patch.
|
||||
set tmpname "./rrt-[format %x [expr int(rand()*0x7FFFFFFF)]].db"
|
||||
if {$A(verbose)} { puts "rbu database is $tmpname" }
|
||||
exec ./sqldiff --rbu --vtab $A(database2) $A(database) | ./sqlite3 $tmpname
|
||||
|
||||
# Run the [rbu] patch.
|
||||
if {$A(verbose)} { puts "Running \[rbu]" }
|
||||
exec ./rbu $A(database2) $tmpname
|
||||
|
||||
set selftest_diff [exec ./sqldiff --table selftest $A(database) $A(database2)]
|
||||
if {$selftest_diff != ""} {
|
||||
puts stderr "patching table \"selftest\" failed: $selftest_diff"
|
||||
exit -1
|
||||
}
|
||||
|
||||
# Run [dbselftest] on both databases
|
||||
if {$A(verbose)} { puts "Running \[dbselftest]" }
|
||||
exec ./dbselftest $A(database)
|
||||
exec ./dbselftest $A(database2)
|
||||
|
||||
# Remove the RBU database
|
||||
file delete $tmpname
|
||||
puts "round trip test successful."
|
||||
|
||||
@@ -298,14 +298,6 @@ do_test 2.1.2 {
|
||||
list [catch { rbu close } msg] $msg
|
||||
} {1 {SQLITE_ERROR - cannot vacuum wal mode database}}
|
||||
|
||||
do_test 2.1.3 {
|
||||
sqlite3rbu_vacuum rbu test.db state.db
|
||||
rbu step
|
||||
} {SQLITE_ERROR}
|
||||
do_test 2.1.4 {
|
||||
list [catch { rbu close_no_error } msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 2.2.0 {
|
||||
CREATE TABLE tx(a PRIMARY KEY, b BLOB);
|
||||
|
||||
@@ -3787,11 +3787,7 @@ int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
|
||||
|
||||
rbuEditErrmsg(p);
|
||||
rc = p->rc;
|
||||
if( pzErrmsg ){
|
||||
*pzErrmsg = p->zErrmsg;
|
||||
}else{
|
||||
sqlite3_free(p->zErrmsg);
|
||||
}
|
||||
*pzErrmsg = p->zErrmsg;
|
||||
sqlite3_free(p->zState);
|
||||
sqlite3_free(p);
|
||||
}else{
|
||||
|
||||
@@ -420,10 +420,10 @@ int sqlite3rbu_savestate(sqlite3rbu *pRbu);
|
||||
**
|
||||
** If an error has already occurred as part of an sqlite3rbu_step()
|
||||
** or sqlite3rbu_open() call, or if one occurs within this function, an
|
||||
** SQLite error code is returned. Additionally, if pzErrmsg is not NULL,
|
||||
** *pzErrmsg may be set to point to a buffer containing a utf-8 formatted
|
||||
** English language error message. It is the responsibility of the caller to
|
||||
** eventually free any such buffer using sqlite3_free().
|
||||
** SQLite error code is returned. Additionally, *pzErrmsg may be set to
|
||||
** point to a buffer containing a utf-8 formatted English language error
|
||||
** message. It is the responsibility of the caller to eventually free any
|
||||
** such buffer using sqlite3_free().
|
||||
**
|
||||
** Otherwise, if no error occurs, this function returns SQLITE_OK if the
|
||||
** update has been partially applied, or SQLITE_DONE if it has been
|
||||
|
||||
+1
-7
@@ -78,7 +78,6 @@ static int SQLITE_TCLAPI test_sqlite3rbu_cmd(
|
||||
{"db", 3, "RBU"}, /* 6 */
|
||||
{"state", 2, ""}, /* 7 */
|
||||
{"progress", 2, ""}, /* 8 */
|
||||
{"close_no_error", 2, ""}, /* 9 */
|
||||
{0,0,0}
|
||||
};
|
||||
int iCmd;
|
||||
@@ -103,16 +102,11 @@ static int SQLITE_TCLAPI test_sqlite3rbu_cmd(
|
||||
break;
|
||||
}
|
||||
|
||||
case 9: /* close_no_error */
|
||||
case 1: /* close */ {
|
||||
char *zErrmsg = 0;
|
||||
int rc;
|
||||
Tcl_DeleteCommand(interp, Tcl_GetString(objv[0]));
|
||||
if( iCmd==1 ){
|
||||
rc = sqlite3rbu_close(pRbu, &zErrmsg);
|
||||
}else{
|
||||
rc = sqlite3rbu_close(pRbu, 0);
|
||||
}
|
||||
rc = sqlite3rbu_close(pRbu, &zErrmsg);
|
||||
if( rc==SQLITE_OK || rc==SQLITE_DONE ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
|
||||
assert( zErrmsg==0 );
|
||||
|
||||
+11
-35
@@ -458,15 +458,15 @@ static i64 readInt64(u8 *p){
|
||||
memcpy(&x, p, 8);
|
||||
return x;
|
||||
#else
|
||||
return (i64)(
|
||||
(((u64)p[0]) << 56) +
|
||||
(((u64)p[1]) << 48) +
|
||||
(((u64)p[2]) << 40) +
|
||||
(((u64)p[3]) << 32) +
|
||||
(((u64)p[4]) << 24) +
|
||||
(((u64)p[5]) << 16) +
|
||||
(((u64)p[6]) << 8) +
|
||||
(((u64)p[7]) << 0)
|
||||
return (
|
||||
(((i64)p[0]) << 56) +
|
||||
(((i64)p[1]) << 48) +
|
||||
(((i64)p[2]) << 40) +
|
||||
(((i64)p[3]) << 32) +
|
||||
(((i64)p[4]) << 24) +
|
||||
(((i64)p[5]) << 16) +
|
||||
(((i64)p[6]) << 8) +
|
||||
(((i64)p[7]) << 0)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
@@ -3198,36 +3198,12 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
|
||||
, pRtree->zDb, pRtree->zName, zNewName
|
||||
);
|
||||
if( zSql ){
|
||||
nodeBlobReset(pRtree);
|
||||
rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** The xSavepoint method.
|
||||
**
|
||||
** This module does not need to do anything to support savepoints. However,
|
||||
** it uses this hook to close any open blob handle. This is done because a
|
||||
** DROP TABLE command - which fortunately always opens a savepoint - cannot
|
||||
** succeed if there are any open blob handles. i.e. if the blob handle were
|
||||
** not closed here, the following would fail:
|
||||
**
|
||||
** BEGIN;
|
||||
** INSERT INTO rtree...
|
||||
** DROP TABLE <tablename>; -- Would fail with SQLITE_LOCKED
|
||||
** COMMIT;
|
||||
*/
|
||||
static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){
|
||||
Rtree *pRtree = (Rtree *)pVtab;
|
||||
int iwt = pRtree->inWrTrans;
|
||||
UNUSED_PARAMETER(iSavepoint);
|
||||
pRtree->inWrTrans = 0;
|
||||
nodeBlobReset(pRtree);
|
||||
pRtree->inWrTrans = iwt;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function populates the pRtree->nRowEst variable with an estimate
|
||||
@@ -3274,7 +3250,7 @@ static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
|
||||
}
|
||||
|
||||
static sqlite3_module rtreeModule = {
|
||||
2, /* iVersion */
|
||||
0, /* iVersion */
|
||||
rtreeCreate, /* xCreate - create a table */
|
||||
rtreeConnect, /* xConnect - connect to an existing table */
|
||||
rtreeBestIndex, /* xBestIndex - Determine search strategy */
|
||||
@@ -3294,7 +3270,7 @@ static sqlite3_module rtreeModule = {
|
||||
rtreeEndTransaction, /* xRollback - rollback transaction */
|
||||
0, /* xFindFunction - function overloading */
|
||||
rtreeRename, /* xRename - rename the table */
|
||||
rtreeSavepoint, /* xSavepoint */
|
||||
0, /* xSavepoint */
|
||||
0, /* xRelease */
|
||||
0, /* xRollbackTo */
|
||||
};
|
||||
|
||||
@@ -39,8 +39,6 @@ set testprefix rtree1
|
||||
# inserted. Also that if a non-numeric is inserted into one
|
||||
# of the min/max dimension columns, it is converted to the
|
||||
# required type before being inserted.
|
||||
# rtree-15.*: Check that DROP TABLE works within a transaction that
|
||||
# writes to an r-tree table.
|
||||
#
|
||||
|
||||
ifcapable !rtree {
|
||||
@@ -594,20 +592,4 @@ do_execsql_test 14.5 {
|
||||
3 42 49
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
do_execsql_test 15.0 {
|
||||
CREATE VIRTUAL TABLE rt USING rtree(id, x1,x2, y1,y2);
|
||||
CREATE TEMP TABLE t13(a, b, c);
|
||||
}
|
||||
do_execsql_test 15.1 {
|
||||
BEGIN;
|
||||
INSERT INTO rt VALUES(1,2,3,4,5);
|
||||
}
|
||||
breakpoint
|
||||
do_execsql_test 15.2 {
|
||||
DROP TABLE t13;
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -209,35 +209,6 @@ eval [string map [list %WR% $trailing] {
|
||||
list [catch { sqlite3changeset_concat $c1 $c2} msg] $msg
|
||||
} {1 SQLITE_SCHEMA}
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
db2 close
|
||||
sqlite3 db2 test.db
|
||||
do_execsql_test $tn.6.0 {
|
||||
CREATE TABLE t7(a INTEGER PRIMARY KEY, b) %WR%;
|
||||
INSERT INTO t7 VALUES(1, 1);
|
||||
INSERT INTO t7 VALUES(2, 2);
|
||||
INSERT INTO t7 VALUES(3, 3);
|
||||
}
|
||||
|
||||
do_test $tn.6.1 {
|
||||
set c1 [sql_exec_changeset db {
|
||||
INSERT INTO t7 VALUES(4, 4);
|
||||
DELETE FROM t7 WHERE a=1;
|
||||
UPDATE t7 SET b=222 WHERE a=2;
|
||||
}]
|
||||
set cinv [sqlite3changeset_invert $c1]
|
||||
execsql { SELECT * FROM t7 }
|
||||
} {2 222 3 3 4 4}
|
||||
|
||||
do_execsql_test -db db2 $tn.6.2 {
|
||||
ALTER TABLE t7 ADD COLUMN c DEFAULT 'ccc'
|
||||
}
|
||||
|
||||
proc xConfict {args} { return "OMIT" }
|
||||
do_test $tn.6.3 {
|
||||
sqlite3changeset_apply db $cinv xConflict
|
||||
execsql { SELECT * FROM t7 }
|
||||
} {1 1 ccc 2 2 ccc 3 3 ccc}
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
# 2015-07-31
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Tests for the [sqldiff --changeset] command.
|
||||
#
|
||||
#
|
||||
if {![info exists testdir]} {
|
||||
set testdir [file join [file dirname [info script]] .. .. test]
|
||||
}
|
||||
source $testdir/tester.tcl
|
||||
ifcapable !session {finish_test; return}
|
||||
set testprefix sessiondiff
|
||||
|
||||
set PROG [test_find_sqldiff]
|
||||
db close
|
||||
|
||||
proc sqlesc {id} {
|
||||
set ret "'[string map {' ''} $id]'"
|
||||
set ret
|
||||
}
|
||||
|
||||
proc database_cksum {db1} {
|
||||
set txt ""
|
||||
|
||||
sqlite3 dbtmp $db1
|
||||
foreach tbl [dbtmp eval {SELECT name FROM sqlite_master WHERE type='table'}] {
|
||||
set cols [list]
|
||||
dbtmp eval "PRAGMA table_info = [sqlesc $tbl]" {
|
||||
lappend cols "quote( $name )"
|
||||
}
|
||||
append txt [dbtmp eval \
|
||||
"SELECT [join $cols {||'.'||}] FROM [sqlesc $tbl] ORDER BY 1"
|
||||
]
|
||||
}
|
||||
dbtmp close
|
||||
|
||||
md5 $txt
|
||||
}
|
||||
|
||||
proc readfile {filename} {
|
||||
set fd [open $filename]
|
||||
fconfigure $fd -translation binary -encoding binary
|
||||
set data [read $fd]
|
||||
close $fd
|
||||
set data
|
||||
}
|
||||
|
||||
proc get_changeset {db1 db2} {
|
||||
exec $::PROG --changeset changeset.bin $db1 $db2
|
||||
set bin [readfile changeset.bin]
|
||||
return $bin
|
||||
}
|
||||
|
||||
proc xConflict {args} {
|
||||
return ""
|
||||
}
|
||||
|
||||
proc do_changeset_test {tn sql1 sql2} {
|
||||
forcedelete test.db123 test.db124
|
||||
|
||||
sqlite3 db test.db123
|
||||
db eval $sql1
|
||||
db close
|
||||
|
||||
sqlite3 db test.db124
|
||||
db eval $sql2
|
||||
|
||||
set cs [get_changeset test.db124 test.db123]
|
||||
sqlite3changeset_apply db $cs xConflict
|
||||
db close
|
||||
|
||||
set database_cksum1 [database_cksum test.db123]
|
||||
set database_cksum2 [database_cksum test.db124]
|
||||
|
||||
uplevel [list \
|
||||
do_test $tn [list string compare $database_cksum1 $database_cksum2] 0
|
||||
]
|
||||
}
|
||||
|
||||
do_changeset_test 1.0 {
|
||||
CREATE TABLE t1(x PRIMARY KEY);
|
||||
} {
|
||||
CREATE TABLE t1(x PRIMARY KEY);
|
||||
}
|
||||
|
||||
do_changeset_test 1.1 {
|
||||
CREATE TABLE t1(x PRIMARY KEY);
|
||||
CREATE TABLE t2(x PRIMARY KEY, y);
|
||||
INSERT INTO t2 VALUES(1, 2);
|
||||
} {
|
||||
CREATE TABLE t1(x PRIMARY KEY);
|
||||
CREATE TABLE t2(x PRIMARY KEY, y);
|
||||
INSERT INTO t2 VALUES(3, 4);
|
||||
}
|
||||
|
||||
do_changeset_test 1.2 {
|
||||
CREATE TABLE t2(a, b, c, PRIMARY KEY(b, c));
|
||||
INSERT INTO t2 VALUES(1, 2, 3);
|
||||
INSERT INTO t2 VALUES(4, 5, 6);
|
||||
} {
|
||||
CREATE TABLE t2(a, b, c, PRIMARY KEY(b, c));
|
||||
INSERT INTO t2 VALUES(1, 2, 11);
|
||||
INSERT INTO t2 VALUES(7, 8, 9);
|
||||
}
|
||||
|
||||
finish_test
|
||||
@@ -2836,12 +2836,11 @@ static int sessionChangesetNext(
|
||||
p->in.iCurrent = p->in.iNext;
|
||||
|
||||
op = p->in.aData[p->in.iNext++];
|
||||
while( op=='T' || op=='P' ){
|
||||
if( op=='T' || op=='P' ){
|
||||
p->bPatchset = (op=='P');
|
||||
if( sessionChangesetReadTblhdr(p) ) return p->rc;
|
||||
if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc;
|
||||
p->in.iCurrent = p->in.iNext;
|
||||
if( p->in.iNext>=p->in.nData ) return SQLITE_DONE;
|
||||
op = p->in.aData[p->in.iNext++];
|
||||
}
|
||||
|
||||
|
||||
@@ -477,9 +477,10 @@ SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
|
||||
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
||||
DBFUZZ_OPT =
|
||||
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
|
||||
DBSELFTEST_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
|
||||
DBSELFTEST_OPT += -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
|
||||
ST_OPT = -DSQLITE_THREADSAFE=0
|
||||
|
||||
# This is the default Makefile target. The objects listed here
|
||||
@@ -761,10 +762,6 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
|
||||
sqlite3_analyzer$(EXE): sqlite3_analyzer.c
|
||||
$(TCCX) $(TCL_FLAGS) sqlite3_analyzer.c -o $@ $(LIBTCL) $(THREADLIB)
|
||||
|
||||
dbdump$(EXE): $(TOP)/ext/misc/dbdump.c sqlite3.o
|
||||
$(TCCX) -DDBDUMP_STANDALONE -o dbdump$(EXE) \
|
||||
$(TOP)/ext/misc/dbdump.c sqlite3.o $(THREADLIB)
|
||||
|
||||
# Rules to build the 'testfixture' application.
|
||||
#
|
||||
TESTFIXTURE_FLAGS = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
|
||||
@@ -905,6 +902,9 @@ speedtest1$(EXE): $(TOP)/test/speedtest1.c sqlite3.c
|
||||
kvtest$(EXE): $(TOP)/test/kvtest.c sqlite3.c
|
||||
$(TCCX) -I. $(KV_OPT) -o kvtest$(EXE) $(TOP)/test/kvtest.c sqlite3.c $(THREADLIB)
|
||||
|
||||
dbselftest$(EXE): $(TOP)/test/dbselftest.c sqlite3.c
|
||||
$(TCCX) -I. $(DBSELFTEST_OPT) -o dbselftest$(EXE) $(TOP)/test/dbselftest.c sqlite3.c $(THREADLIB)
|
||||
|
||||
rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o
|
||||
$(TCC) -I. -o rbu$(EXE) $(TOP)/ext/rbu/rbu.c sqlite3.o \
|
||||
$(THREADLIB)
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
C When\sgenerating\sindividual\sloops\sfor\seach\sORed\sterm\sof\san\sOR\sscan,\smove\sany\nconstant\sWHERE\sexpressions\soutside\sof\sthe\sloop,\sas\sis\sdone\sfor\stop-level\nloops.
|
||||
D 2017-06-22T16:51:16.239
|
||||
F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
|
||||
C Refactor\sthe\soutput\slogic\sin\sthe\sCLI.\s\sNot\ssure\swe\swant\sto\sgo\sthis\sway.\s\sJust\nsaving\sthe\swork\sfor\shistorical\sreference,\sor\sin\scase\sI\sdecide\sto\scome\sback\nto\sit.
|
||||
D 2017-03-08T23:29:19.825
|
||||
F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 8eeb80162074004e906b53d7340a12a14c471a83743aab975947e95ce061efcc
|
||||
F README.md 2b15fae33852f2f53996774c21fb41e1d94181c4401a0e43ac93e11f2cc901b9
|
||||
F VERSION 87f1498f27e398bce3da2fa8125c9879a38ed9d87e4b5fb922b351de1e25cadb
|
||||
F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2
|
||||
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
|
||||
F VERSION 3605fa447e4623f5ff4a6adc97b1fde9a257b8f2
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
||||
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
|
||||
F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4
|
||||
F autoconf/Makefile.msc 1014be616b420a5f48611d21b62ca2f50ec97ee795087ecb8a4d6bf6375ba11d
|
||||
F autoconf/Makefile.msc 3de603bcec5c07462801a20fd7dc1b871400af99
|
||||
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
|
||||
F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1
|
||||
F autoconf/configure.ac 2893b823ecc86cea13739f6c8109a41392254d1db08235c5615e0af5722c8578
|
||||
F autoconf/configure.ac cacf2616abf6e4a569bde2ef365c143caeec40bc
|
||||
F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd
|
||||
F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873
|
||||
F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43
|
||||
@@ -30,13 +30,13 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
|
||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||
F configure 1bcc61cdd063171d8945551c265e5701a770deeff77e0ad634f8d22e4e91c831 x
|
||||
F configure.ac 13f45f02e6c51dd0e347315b5401c3f047712b7f79b7f35619115c23755afcff
|
||||
F configure b15d030a8ae2e672d76c97b6667dacb98934a467 x
|
||||
F configure.ac 605173e829ab64514ed89f9b53d0da1739d7b0a0
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/lemon.html 1f8b8d4c9f5cfe40e679fee279cc9eb2da8e6eb74ad406028538d7864cc4b6cb
|
||||
F doc/lemon.html b5a3c07d33ecb8e019ce8f7660fe2dbbad9d7977
|
||||
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
|
||||
F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a
|
||||
F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd
|
||||
F ext/README.txt 913a7bd3f4837ab14d7e063304181787658b14e1
|
||||
F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91
|
||||
F ext/async/sqlite3async.c 0f3070cc3f5ede78f2b9361fb3b629ce200d7d74
|
||||
F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef
|
||||
@@ -70,7 +70,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
|
||||
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
|
||||
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
|
||||
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
||||
F ext/fts3/fts3.c 88ea5c444fdf262b4eb7b5872b9a3192b8b8d0df8cc9735c5aed159ec5dae02a
|
||||
F ext/fts3/fts3.c 95c7041ea75d82d2d9a4cd058904ba889751f5b8
|
||||
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
|
||||
F ext/fts3/fts3Int.h eb2502000148e80913b965db3e59f29251266d0a
|
||||
F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1
|
||||
@@ -86,39 +86,38 @@ F ext/fts3/fts3_tokenize_vtab.c a27593ab19657166f6fa5ec073b678cc29a75860
|
||||
F ext/fts3/fts3_tokenizer.c a22bf311a71f3efa9d7012d8cc48fc9b0f3dace7
|
||||
F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
|
||||
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
|
||||
F ext/fts3/fts3_unicode.c 525a3bd9a7564603c5c061b7de55403a565307758a94600e8a2f6b00d1c40d9d
|
||||
F ext/fts3/fts3_unicode2.c cc04fc672bfd42b1e650398cb0bf71f64f9aae032cfe75bbcfe75b9cf966029c
|
||||
F ext/fts3/fts3_write.c a51d48d646974ee2fb4b17fcd5da0416a5759a32dcacc2cce2ba00d5a767848e
|
||||
F ext/fts3/fts3_unicode.c a93f5edc0aff44ef8b06d7cb55b52026541ca145
|
||||
F ext/fts3/fts3_unicode2.c c3d01968d497bd7001e7dc774ba75b372738c057
|
||||
F ext/fts3/fts3_write.c c3863f23b6b4623c8b9d5cf31c12ce4469f78ca9
|
||||
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
|
||||
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
|
||||
F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
|
||||
F ext/fts3/tool/fts3view.c 202801a2056995b763864d60c2dee744d46f1677
|
||||
F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c
|
||||
F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
|
||||
F ext/fts3/unicode/mkunicode.tcl ab0543a3b2399092ea2dd75df1bef333405b0d7f6b8c4951a0fbb60e780cb69f
|
||||
F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8
|
||||
F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95
|
||||
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
|
||||
F ext/fts5/fts5.h 62f3e33ceeb9a428db139f9c012186b371da1cc7
|
||||
F ext/fts5/fts5Int.h 15e7514b46a845937d7c62e5c69e935091f0dbb72eb61aa4c8bcfbd39fdea158
|
||||
F ext/fts5/fts5Int.h c629b24d2b92b99596f3b8e82289fddca06df6e1
|
||||
F ext/fts5/fts5_aux.c 67acf8d51723cf28ffc3828210ba662df4b8d267
|
||||
F ext/fts5/fts5_buffer.c 1dd1ec0446b3acfc2d7d407eb894762a461613e2695273f48e449bfd13e973ff
|
||||
F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd
|
||||
F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857
|
||||
F ext/fts5/fts5_expr.c f2825f714d91bbe62ab5820aee9ad12e0c94205b2a01725eaa9072415ae9ff1c
|
||||
F ext/fts5/fts5_hash.c 32be400cf761868c9db33efe81a06eb19a17c5402ad477ee9efb51301546dd55
|
||||
F ext/fts5/fts5_index.c cdceac47287c66500214ee946ca871ac48027a82a0ca82177c1c6af19f181ca0
|
||||
F ext/fts5/fts5_main.c 1ba0e7806886c1bc16e20d0dde1c2b535d1aeb98cbbb937c4c3e064af5ac6f03
|
||||
F ext/fts5/fts5_storage.c 7750986004f3f0c94619a85ecb5dd6cbef53e5e3853488e8a906c269d4d11db6
|
||||
F ext/fts5/fts5_expr.c c6ecc2280162a3714d15dce2a8f2299f748b627c
|
||||
F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2
|
||||
F ext/fts5/fts5_index.c f67032a9a529ba52a545e6e3ab970764199c05d4
|
||||
F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2
|
||||
F ext/fts5/fts5_storage.c 8f0e65cb33bde8f449e1c9b4be4600d18b4da6e9
|
||||
F ext/fts5/fts5_tcl.c 4a901f00c8553740dba63511603f5527d741c26a
|
||||
F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc
|
||||
F ext/fts5/fts5_test_tok.c ffd657dd67e7fcdb31bf63fb60b6d867299a581d0f46e97086abacd66c2a9b26
|
||||
F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be
|
||||
F ext/fts5/fts5_tokenize.c 2ce7b44183538ec46b7907726262ee43ffdd39a8
|
||||
F ext/fts5/fts5_unicode2.c b450b209b157d598f7b9df9f837afb75a14c24bf
|
||||
F ext/fts5/fts5_varint.c a5aceacda04dafcbae725413d7a16818ecd65738
|
||||
F ext/fts5/fts5_vocab.c e44fefa7f0c1db252998af071daf06a7147e17e7
|
||||
F ext/fts5/fts5parse.y a070b538e08ae9e2177d15c337ed2a3464408f0f886e746307098f746efd94ca
|
||||
F ext/fts5/fts5parse.y e51b375403421b8b37428a89b095d00597129aae
|
||||
F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
|
||||
F ext/fts5/test/fts5_common.tcl b01c584144b5064f30e6c648145a2dd6bc440841
|
||||
F ext/fts5/test/fts5aa.test 6dd1bfa4426a8d77e8c8d447aad02515c85118b082f24053ac89802300077ff1
|
||||
F ext/fts5/test/fts5aa.test bd2d88182b9f7f30d300044048ad14683306b745
|
||||
F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b
|
||||
F ext/fts5/test/fts5ac.test 55cad4275a1f5acabfe14d8442a8046b47e49e5f
|
||||
F ext/fts5/test/fts5ad.test 36995f0586f30f5602074e012b9224c71ec5171c
|
||||
@@ -136,7 +135,7 @@ F ext/fts5/test/fts5aux.test 5dd158a1e7869e27e9762a2a452b189c728d1be3
|
||||
F ext/fts5/test/fts5auxdata.test 141a7cbffcceb1bd2799b4b29c183ff8780d586e
|
||||
F ext/fts5/test/fts5bigpl.test 04ee0d7eebbebf17c31f5a0b5c5f9494eac3a0cb
|
||||
F ext/fts5/test/fts5bigtok.test 017a9397b14e7598883a6328ead4a6539b42d59a
|
||||
F ext/fts5/test/fts5colset.test 97084e7fd3183a3c148ade1d4ad980b7e764cb2711ac77c3176680c3e75ea2b9
|
||||
F ext/fts5/test/fts5colset.test 1cdf56e079316005aabda790059aee86f2222ee4
|
||||
F ext/fts5/test/fts5columnsize.test a8cfef21ffa1c264b9f670a7d94eeaccb5341c07
|
||||
F ext/fts5/test/fts5config.test 7788b9c058074d640dfcdd81d97b6a9480000368
|
||||
F ext/fts5/test/fts5conflict.test 26f4e46c4d31e16221794832a990dc4e30e18de5
|
||||
@@ -144,7 +143,6 @@ F ext/fts5/test/fts5content.test 9a952c95518a14182dc3b59e3c8fa71cda82a4e1
|
||||
F ext/fts5/test/fts5corrupt.test c2ad090192708150d50d961278df10ae7a4b8b62
|
||||
F ext/fts5/test/fts5corrupt2.test 128eb6e2d26b09f4da339e581f424b3321e0fdaa
|
||||
F ext/fts5/test/fts5corrupt3.test f77f65e386231daf62902466b40ff998b2c8ce4f
|
||||
F ext/fts5/test/fts5delete.test 0585395660889090a6a04b0cac0e70b16801da44ee321534d6169da49af8167f
|
||||
F ext/fts5/test/fts5detail.test ef5c690535a797413acaf5ad9b8ab5d49972df69
|
||||
F ext/fts5/test/fts5determin.test 10648edb75ef1e196b10978fd21a9be0c31e09c3
|
||||
F ext/fts5/test/fts5dlidx.test 007e9390c94638760797dbec2990c97c3fa08dfe
|
||||
@@ -161,7 +159,7 @@ F ext/fts5/test/fts5fault7.test cb14ea3c1f42394f06f2284abc58eecee6ff8080
|
||||
F ext/fts5/test/fts5fault8.test 6785af34bd1760de74e2824ea9c161965af78f85
|
||||
F ext/fts5/test/fts5fault9.test e10e395428a9ea0596ebe752ff7123d16ab78e08
|
||||
F ext/fts5/test/fts5faultA.test fa5d59c0ff62b7125cd14eee38ded1c46e15a7ea
|
||||
F ext/fts5/test/fts5faultB.test 8a7e4c89c663e599e88fa1b9f2b8dcf4b85a338bd250e1a94341773b1e9ebfcc
|
||||
F ext/fts5/test/fts5faultB.test 7f3bba790fa172073ac314f9b8ed197390b61eca
|
||||
F ext/fts5/test/fts5faultD.test cc5d1225556e356615e719c612e845d41bff7d5a
|
||||
F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741
|
||||
F ext/fts5/test/fts5fuzz1.test bece4695fc169b61ab236ada7931c6e4942cbef9
|
||||
@@ -176,12 +174,12 @@ F ext/fts5/test/fts5near.test b214cddb1c1f1bddf45c75af768f20145f7e71cc
|
||||
F ext/fts5/test/fts5onepass.test 7ed9608e258132cb8d55e7c479b08676ad68810c
|
||||
F ext/fts5/test/fts5optimize.test 9d3ac53bb9cae58cb070d795db86bcb2f9fec105
|
||||
F ext/fts5/test/fts5phrase.test f6d1d464da5beb25dc56277aa4f1d6102f0d9a2f
|
||||
F ext/fts5/test/fts5plan.test fb0ee60c9a092b17bb958dd742f01e3731b520d50b5d61b288c49c7acdc286cb
|
||||
F ext/fts5/test/fts5plan.test 6a55ecbac9890765b0e16f8c421c7e0888cfe436
|
||||
F ext/fts5/test/fts5porter.test 7cdc07bef301d70eebbfa75dcaf45c3680e1d0e1
|
||||
F ext/fts5/test/fts5porter2.test 2e65633d58a1c525d5af0f6c01e5a59155bb3487
|
||||
F ext/fts5/test/fts5prefix.test 6ef7e875738412907b17687d25db39a25cbdaba4
|
||||
F ext/fts5/test/fts5query.test f5ec25f5f2fbb70033424113cdffc101b1985a40
|
||||
F ext/fts5/test/fts5rank.test 485e1d7ab8b0f939172a88e279acd0894b1f64458f92d7cd5826a31335c6a093
|
||||
F ext/fts5/test/fts5rank.test 2bdc0c5f22ccc1f9dbe9f4d0b82a491dce6f8a32
|
||||
F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b
|
||||
F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17
|
||||
F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6
|
||||
@@ -208,19 +206,16 @@ F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
|
||||
F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43
|
||||
F ext/icu/icu.c 84900472a088a3a172c6c079f58a1d3a1952c332
|
||||
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
|
||||
F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2
|
||||
F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87
|
||||
F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb
|
||||
F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234
|
||||
F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d
|
||||
F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704
|
||||
F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83
|
||||
F ext/misc/csv.c 531a46cbad789fca0aa9db69a0e6c8ac9e68767d
|
||||
F ext/misc/dbdump.c 3509fa6b8932d04e932d6b6b827b6a82ca362781b8e8f3c77336f416793e215e
|
||||
F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
|
||||
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
|
||||
F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
|
||||
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
|
||||
F ext/misc/json1.c dbe086615b9546c156bf32b9378fc09383b58bd17513b866cfd24c1e15281984
|
||||
F ext/misc/json1.c 552a7d730863419e05dc947265b28bd411680e2e
|
||||
F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33
|
||||
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
|
||||
F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e
|
||||
@@ -228,18 +223,17 @@ F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4
|
||||
F ext/misc/remember.c 8440f8d0b452c5cdefb62b57135ccd1267aa729d
|
||||
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
|
||||
F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb
|
||||
F ext/misc/series.c b0f5f346aca9b7ff7caaf0da2efb4ad462441abd4dcd92a460cb573b3ea2370b
|
||||
F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35
|
||||
F ext/misc/sha1.c 0b9e9b855354910d3ca467bf39099d570e73db56
|
||||
F ext/misc/shathree.c fa185d7aee0ad0aca5e091b4a2db7baff11796170e5793b5de99e511a13af448
|
||||
F ext/misc/shathree.c 38aa4c3c3d3c3fc34b8ea367bed299d8d8a224b2
|
||||
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
|
||||
F ext/misc/spellfix.c a4723b6aff748a417b5091b68a46443265c40f0d
|
||||
F ext/misc/stmts.c 4aa554f671f6a55a52060437a0215a93d2e9f10f2fa66b0f7f65aa0576fc90bb
|
||||
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
|
||||
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
|
||||
F ext/misc/vfsstat.c bf10ef0bc51e1ad6756629e1edb142f7a8db1178
|
||||
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
|
||||
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
||||
F ext/rbu/rbu.c ea7d1b7eb44c123a2a619332e19fe5313500705c4a58aaa1887905c0d83ffc2e
|
||||
F ext/rbu/rbu.c b2c0b5e6ae1a89affc0edfc127ebfa5f637a0ce4
|
||||
F ext/rbu/rbu1.test 43836fac8c7179a358eaf38a8a1ef3d6e6285842
|
||||
F ext/rbu/rbu10.test 046b0980041d30700464a800bbf6733ed2df515d
|
||||
F ext/rbu/rbu11.test 9bc68c2d3dbeb1720153626e3bd0466dcc017702
|
||||
@@ -256,6 +250,7 @@ F ext/rbu/rbuA.test c1a7b3e2d926b8f8448bb3b4ae787e314ee4b2b3
|
||||
F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2
|
||||
F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831
|
||||
F ext/rbu/rbu_common.tcl a38e8e2d4a50fd6aaf151633714c1b1d2fae3ead
|
||||
F ext/rbu/rbu_round_trip.tcl f3216836bbaeb10d76a2c70b89c13f59eabbd117
|
||||
F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695
|
||||
F ext/rbu/rbucrash2.test b2ecbdd7bb72c88bd217c65bd00dafa07f7f2d4d
|
||||
F ext/rbu/rbudiff.test 3e605cf624d00d04d0fb1316a3acec4fbe3b3ac5
|
||||
@@ -268,15 +263,15 @@ F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda
|
||||
F ext/rbu/rbuprogress.test 1849d4e0e50616edf5ce75ce7db86622e656b5cf
|
||||
F ext/rbu/rburesume.test 8acb77f4a422ff55acfcfc9cc15a5cb210b1de83
|
||||
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
|
||||
F ext/rbu/rbuvacuum.test ff357e9b556ca7ad4673da0ff7f244def919ff858e0f9f350d3e30fdd83a62a8
|
||||
F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0
|
||||
F ext/rbu/rbuvacuum2.test 2074ab14fe66e1c7e7210c62562650dcd215bbaa
|
||||
F ext/rbu/sqlite3rbu.c d1438580a451eebda3bfd42ef69b677512f00125285e0e4e789b6131a45f6dd8
|
||||
F ext/rbu/sqlite3rbu.h fc25e1fcd99b5c6d32b1b5b1c73122632e873ac89bd0be9bf646db362b7ce02c
|
||||
F ext/rbu/test_rbu.c ec18cfc69a104309df23c359e3c80306c9a6bdd1d2c53c8b70ae158e9832dcd6
|
||||
F ext/rbu/sqlite3rbu.c 2a89efba9eeba8e6c89a498dc195e8efbdde2694
|
||||
F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba
|
||||
F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c 8205d6e4466f766e57ce1b8aa38224ac9e1cec2d2bf4684cd1cc5a6ddf9b7014
|
||||
F ext/rtree/rtree.c 3f3a595dba485e340246fa2c8ba330a6b9768b00
|
||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||
F ext/rtree/rtree1.test d5f0ba215b3bd1d05269ada86e74073b8445852aa0d33a63e10ec63a09c39473
|
||||
F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec
|
||||
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
|
||||
F ext/rtree/rtree3.test 2cafe8265d1ff28f206fce88d114f208349df482
|
||||
F ext/rtree/rtree4.test c8fe384f60ebd49540a5fecc990041bf452eb6e0
|
||||
@@ -315,12 +310,11 @@ F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce
|
||||
F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60
|
||||
F ext/session/session_common.tcl 7776eda579773113b30c7abfd4545c445228cb73
|
||||
F ext/session/session_speed_test.c edc1f96fd5e0e4b16eb03e2a73041013d59e8723
|
||||
F ext/session/sessionat.test feb7d22b3124882064b9d9df69f5484a9bb8c123dc9ddc6ffcd357521848139f
|
||||
F ext/session/sessiondiff.test ad13dd65664bae26744e1f18eb3cbd5588349b7e9118851d8f9364248d67bcec
|
||||
F ext/session/sessionat.test b25d61d663ebc795506bf74079dc4ba0092fad25
|
||||
F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7
|
||||
F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0
|
||||
F ext/session/sessionwor.test 2f3744236dc8b170a695b7d8ddc8c743c7e79fdc
|
||||
F ext/session/sqlite3session.c cc127222a9ea6f4eaa31281aa9da924f5244f6099be0ee526c950684fb3513a6
|
||||
F ext/session/sqlite3session.c 13642d9c754cc18f17e141f82860d269e2adf920
|
||||
F ext/session/sqlite3session.h d4db650adfcc7a4360e9f12a09c2d117b1db6b53
|
||||
F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386
|
||||
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
||||
@@ -329,7 +323,7 @@ F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk 9abb506e717887d57f754bae139b85c1a06d6f2ac25b589f3e792e310567f278
|
||||
F main.mk 08e0b151abb46353c677ac4974b50c6077f85eee
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
@@ -342,38 +336,38 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121
|
||||
F src/analyze.c 0d0ccf7520a201d8747ea2f02c92c26e26f801bc161f714f27b9f7630dde0421
|
||||
F src/attach.c 3bd555e28382603e80d430dfebb2270f86e1e375b4c4be3e1ab1aec3a0c44943
|
||||
F src/auth.c 79f96c6f33bf0e5da8d1c282cee5ebb1852bb8a6ccca3e485d7c459b035d9c3c
|
||||
F src/analyze.c 6d8234916c29be943e6ea28b5bef67dff98d9905
|
||||
F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43
|
||||
F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792
|
||||
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
|
||||
F src/btree.c 430e34151e6ef37e42d3f956bb062907c80ff91e1380704b967b8c1a02a98f64
|
||||
F src/btree.h 3edc5329bc59534d2d15b4f069a9f54b779a7e51289e98fa481ae3c0e526a5ca
|
||||
F src/btreeInt.h a392d353104b4add58b4a59cb185f5d5693dde832c565b77d8d4c343ed98f610
|
||||
F src/build.c 88a8cdc11d1c081ed565aa3e795bdf9160f4556463b4c4555e9860b59dd80340
|
||||
F src/btree.c e2bae0a03f73d119910fb35c9550987564065137
|
||||
F src/btree.h bf64dfeeddeebdb775a5eba0098bbc00d073290d
|
||||
F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0
|
||||
F src/build.c 43f903c9082040ced2b421543cb0300c2973647d
|
||||
F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c ca1b2403003ef5d0e331ad2d73ee812ac33b8efc55f8e525ffa8ce5ac1f2c4ea
|
||||
F src/date.c cc42a41c7422389860d40419a5e3bce5eaf6e7835c3ba2677751dc653550a5c7
|
||||
F src/ctime.c a9984df73898c042a5cfc8f9d8e7723d02bc35c9
|
||||
F src/date.c ee676e7694dfadbdd2fde1a258a71be8360ba5ae
|
||||
F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d
|
||||
F src/delete.c 3213547e97b676c6fa79948b7a9ede4801ea04a01a2043241deafedf132ecf5d
|
||||
F src/expr.c 452c6f3aa656aabf3eefe96bb5f316b2c987fbc12c647964e4ed880f193ca31f
|
||||
F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c
|
||||
F src/expr.c 8a29e9b72d4b642189999c41782cd6c5bc43512f
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 5ff2c895fe087756d8085dc1a9bc229b5670e2a65c3929dd87c71e43649af333
|
||||
F src/func.c 9d52522cc8ae7f5cdadfe14594262f1618bc1f86083c4cd6da861b4cf5af6174
|
||||
F src/global.c 8a6ab6b4d91effb96ffa81b39f0d70c862abca157f8aaa194600a4a8b7923344
|
||||
F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae
|
||||
F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b
|
||||
F src/global.c 4a34512d82fc5aa13c802db06bcfff5e1d3de955
|
||||
F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd
|
||||
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
|
||||
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c 974499a3999d339a4c1ba8ef129a988d9f136b3789e423808b38cdc19d28adbe
|
||||
F src/insert.c 3ed64afc49c0a2221e397b9f65d231ffbef506fe
|
||||
F src/legacy.c e88ed13c2d531decde75d42c2e35623fb9ce3cb0
|
||||
F src/loadext.c a72909474dadce771d3669bf84bf689424f6f87d471fee898589c3ef9b2acfd9
|
||||
F src/main.c 18f2145d572069dae91161add89446aec680aab296492a92ae5afcc2fc7c6b5a
|
||||
F src/malloc.c e20bb2b48abec52d3faf01cce12e8b4f95973755fafec98d45162dfdab111978
|
||||
F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258
|
||||
F src/main.c 158326243c5ddc8b98a1e983fa488650cf76d760
|
||||
F src/malloc.c d0a1474236486165bcb349af82e2a6560178bf7b
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||
F src/mem1.c fd7cd6fe21d46fe0a4186367dd8dc26d87b787eb
|
||||
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
|
||||
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
|
||||
@@ -392,32 +386,32 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820
|
||||
F src/os_win.c 2a6c73eef01c51a048cc4ddccd57f981afbec18a
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c 14f6982c470c05b8e85575c69e9c1712010602e20400f8670d8699e21283e0e4
|
||||
F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b
|
||||
F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa
|
||||
F src/parse.y 0513387ce02fea97897d8caef82d45f347818593f24f1bdc48e0c530a8af122d
|
||||
F src/parse.y 48b03113704ee8bd78ee6996d81de7fbee22e105
|
||||
F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870
|
||||
F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11
|
||||
F src/pcache1.c 1195a21fe28e223e024f900b2011e80df53793f0356a24caace4188b098540dc
|
||||
F src/pragma.c 2362670a9d28b71708aecb2b9b10b3f7be71f4c950961c07e81dc400e3ce6371
|
||||
F src/pragma.h a8a949000214fefb6210330eed8ccbbb4f752619a9871f31b3dedd4a240277fd
|
||||
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
|
||||
F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953
|
||||
F src/pragma.c b7bf4f1dd9cdcdd3f72f0bdbce3502d69d0f48ba
|
||||
F src/pragma.h c9c763958fec92b04125571472c9500b351c5f7f
|
||||
F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a
|
||||
F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2
|
||||
F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c adf3ef9843135b1383321ad751f16f5a40c3f37925154555a3e61653d2a954e8
|
||||
F src/resolve.c 3e518b962d932a997fae373366880fc028c75706
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c 35ccfae64cecfa843d54a5898c4ab7d6595ce03d147267fa5eecdc8eab39cd6a
|
||||
F src/shell.c bcd3358ad6cb3f3dc7ec76ad3bd8191f123ed2425360c5c48fe431780eceb729
|
||||
F src/sqlite.h.in 67fa8bd29808e7988e0ce36c8d4c6043eb1727f94522fc612687aa5af51931e6
|
||||
F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f
|
||||
F src/shell.c 7708b95090b2d2b211628eeeafb142c4107296df
|
||||
F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28
|
||||
F src/sqliteInt.h 17e9bce594ea0c38c44ad0cbff4aa50cbff4b25f4bac9d38306caf9f1f028ac9
|
||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||
F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
|
||||
F src/sqliteInt.h df268ce1d04df042cf43b557d2309eb0b71e86c4
|
||||
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
|
||||
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
F src/tclsqlite.c 1ac29f18b1b3787a30b45dbbdf6fdc4aa4f1a2f8c7c8fe586beba1b177eba97d
|
||||
F src/test1.c c99f0442918a7a5d5b68a95d6024c211989e6c782c15ced5a558994baaf76a5e
|
||||
F src/tclsqlite.c 6c2151b6d8d98e183a04466d40df8889c0574d79
|
||||
F src/test1.c 8a98191a1da8e100f77cdb5cc716df67d405028d
|
||||
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
|
||||
F src/test3.c b8434949dfb8aff8dfa082c8b592109e77844c2135ed3c492113839b6956255b
|
||||
F src/test3.c d03f5b5da9a2410b7a91c64b0d3306ed28ab6fee
|
||||
F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6
|
||||
F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d
|
||||
F src/test6.c 004ad42f121f693b8cbe060d1a330678abc61620
|
||||
@@ -430,17 +424,17 @@ F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0
|
||||
F src/test_bestindex.c d23f80d334c59662af69191854c76b8d3d0c8c96
|
||||
F src/test_blob.c f65ac717da2618691cf9dad094e6da0219dcd208
|
||||
F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274
|
||||
F src/test_config.c edcba290248dc18736dd814c9b95863c6762e0b35753048d8cbe5bf65f7abfbb
|
||||
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
|
||||
F src/test_config.c 83179ea845479b5be9a651d014649e3f2722a1fe
|
||||
F src/test_delete.c af7eab5702f853fb1c62a5f7665e2234cf1ae17b
|
||||
F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e
|
||||
F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58
|
||||
F src/test_fs.c 35a2f7dd8a915900873386331386d9ba1ae1b5026d74fd20c2807bc76221f291
|
||||
F src/test_fs.c e16cbe68d3b107e00a907c20a9a02629870eb69b
|
||||
F src/test_func.c a4fdab3363b436c1b12660e9362ce3f3782b7b5e
|
||||
F src/test_hexio.c 1d4469ca61ab202a1fcec6543f584d2407205e8d
|
||||
F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664
|
||||
F src/test_intarray.c 988fc61cb0ff539f4172c0d95f15287c92516f64
|
||||
F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c
|
||||
F src/test_journal.c 619f2aa10e0d7a5f87c0f06825bc61dfce1c6b9c7f3ad990fb13de6c3b8874a3
|
||||
F src/test_journal.c d3b83f2bcb7792c709e57abddc456a2b1818643a
|
||||
F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
|
||||
F src/test_malloc.c c05f6c40bd6c8bfe5f1718212f81fd5687f91766
|
||||
F src/test_multiplex.c e054459f7633f3ff8ce1245da724f9a8be189e4e
|
||||
@@ -465,31 +459,31 @@ F src/test_windirent.c 17f91f5f2aa1bb7328abb49414c363b5d2a9d3ff
|
||||
F src/test_windirent.h 5d67483a55442e31e1bde0f4a230e6e932ad5906
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c 1003d6d90c6783206c711f0a9397656fa5b055209f4d092caa43bb3bf5215db5
|
||||
F src/treeview.c 6cf8d7fe9e63fae57dad1bb57f6615e14eac0c527e43d868e805042cae8ed1f7
|
||||
F src/trigger.c d1cae560bfacc8bfb3a072d73658245c1714c0389097da69b4cb23877a082d7e
|
||||
F src/update.c c443935c652af9365e033f756550b5032d02e1b06eb2cb890ed7511ae0c051dc
|
||||
F src/tokenize.c dc748c5afcb9e5beb3ef5651bc99a4622e30f6a1
|
||||
F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c
|
||||
F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182
|
||||
F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58
|
||||
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
||||
F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23
|
||||
F src/vacuum.c 874c0f2f15ab2908748297d587d22d485ea96d55aaec91d4775dddb2e24d2ecf
|
||||
F src/vdbe.c 6783778df820f3e0c68289fe5d12ddd34168b0eb1acf248668fec6e2ea1012d5
|
||||
F src/vdbe.h 70a409d171d4e51b962f0d53abf15c33c404c6aa4c9d62fb3a931b5a62ba9615
|
||||
F src/vdbeInt.h cdcdabad4f5d6bf7a3beb826a7f33ee6f8f1cb220042bedd5b7d4bf2ea1d179f
|
||||
F src/vdbeapi.c c961d8d9e0f52e2df60a6ddbbccd7d99dc4d00103db7e53f77fcef44fbd23178
|
||||
F src/vdbeaux.c bc9b3228f6d99bef0d0ecaf3a0e0e8358b3873242d0d2fe944226de3fdf9521e
|
||||
F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6
|
||||
F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569
|
||||
F src/vdbe.c f520378e510fd36bbf289921798dbc8f2b3dc30d
|
||||
F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c
|
||||
F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f
|
||||
F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860
|
||||
F src/vdbeaux.c 57361f2e761d92a254638bdbfc03fc68ae6aebc6
|
||||
F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9
|
||||
F src/vdbemem.c 94b17d851f31d4fd075d47d373d4b33ed3962a6ecb82cf385018025751091360
|
||||
F src/vdbesort.c f512c68d0bf7e0105316a5594c4329358c8ee9cae3b25138df041d97516c0372
|
||||
F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd
|
||||
F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face
|
||||
F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
|
||||
F src/vtab.c 35b9bdc2b41de32a417141d12097bcc4e29a77ed7cdb8f836d1d2305d946b61b
|
||||
F src/vtab.c 007513c2ef52472fcdea6a741683d50662e82790
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344
|
||||
F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71
|
||||
F src/walker.c d46044e7a5842560dfe7122d93ff5145dd4a96f4d0bf5ba5910a7731b8c01e79
|
||||
F src/where.c d4f329d9055dbdb475d697f205db1104af886aad4400168fb9b957f6251ea926
|
||||
F src/whereInt.h 2a4b634d63ce488b46d4b0da8f2eaa8f9aeab202bc25ef76f007de5e3fba1f20
|
||||
F src/wherecode.c 339ee802d9d311acf0cba8b5a9a092e167ef71c3a777d4b3e57de25d193251c7
|
||||
F src/whereexpr.c a2fe3811d45af45a5c6667caabc15e01054fe6228c64e86e1f7d2ba5ef5284f9
|
||||
F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791
|
||||
F src/where.c 1a3a8adb717a20f17c186f3baa22b0b5f3a5ab13
|
||||
F src/whereInt.h 2d50c2b74a33be44cb68fdecee30b4d93552f1f4
|
||||
F src/wherecode.c 677e95413c472c0b413023b6b69a47f40fce1b04
|
||||
F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
|
||||
@@ -529,17 +523,17 @@ F test/attach2.test 0ec5defa340363de6cd50fd595046465e9aaba2d
|
||||
F test/attach3.test c59d92791070c59272e00183b7353eeb94915976
|
||||
F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c
|
||||
F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0
|
||||
F test/auth.test 3d6cd8f3978ba55b1202574e6ecd79c6e00914ca44b9bfd6c1fe6fb873fcac88
|
||||
F test/auth.test c6ede04bee65637ff354b43fc1235aa560c0863e
|
||||
F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1
|
||||
F test/auth3.test db21405b95257c24d29273b6b31d0efc59e1d337e3d5804ba2d1fd4897b1ae49
|
||||
F test/autoanalyze1.test b9cc3f32a990fa56669b668d237c6d53e983554ae80c0604992e18869a0b2dec
|
||||
F test/auth3.test 0d48b901cf111c14b4b1b5205c7d28f1a278190f
|
||||
F test/autoanalyze1.test 1ba80d5e1412d46503566b70741a5eea060da929
|
||||
F test/autoinc.test 6ae8fb69c9f656962464ae4e6667045d0dfc3b46
|
||||
F test/autoindex1.test 14b63a9f1e405fe6d5bfc8c8d00249c2ebaf13ea
|
||||
F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df
|
||||
F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972
|
||||
F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf
|
||||
F test/autoindex5.test 96f084a5e6024ea07cace5888df3223f3ea86990
|
||||
F test/autovacuum.test 0831cd34e14695d297187f7f6519265e3121c5b0a1720e548e86829e796129e9
|
||||
F test/autovacuum.test 92c24eedbdb68e49f3fb71f26f9ce6d8988cac15
|
||||
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
|
||||
F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
|
||||
F test/backcompat.test 3e64cedda754c778ef6bbe417b6e7a295e662a4d
|
||||
@@ -579,7 +573,6 @@ F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3
|
||||
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
|
||||
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
|
||||
F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61
|
||||
F test/cachespill.test 895997f84a25b323b166aecb69baab2d6380ea98f9e0bcc688c4493c535cfab9
|
||||
F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738
|
||||
F test/capi3.test f0c66919e43d42e1572a69be039e4527a931b00f
|
||||
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
|
||||
@@ -588,7 +581,7 @@ F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82
|
||||
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
|
||||
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
|
||||
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
|
||||
F test/check.test 33a698e8c63613449d85d624a38ef669bf20331daabebe3891c9405dd6df463a
|
||||
F test/check.test 92b23a91fb7be12fba7ee9ce518217e2919a21da
|
||||
F test/close.test 83947daf3b700631f90f4850ddaab455be4af73d
|
||||
F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4
|
||||
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
|
||||
@@ -602,12 +595,12 @@ F test/collate7.test 8ec29d98f3ee4ccebce6e16ce3863fb6b8c7b868
|
||||
F test/collate8.test cd9b3d3f999b8520ffaa7cc1647061fc5bab1334
|
||||
F test/collate9.test 3adcc799229545940df2f25308dd1ad65869145a
|
||||
F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6
|
||||
F test/collateB.test 1e68906951b846570f29f20102ed91d29e634854ee47454d725f2151ecac0b95
|
||||
F test/collateB.test 8ec2accd2d7166c1eff0d2a39bc90262c6f89632
|
||||
F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1
|
||||
F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b
|
||||
F test/conflict.test 029faa2d81a0d1cafb5f88614beb663d972c01db
|
||||
F test/conflict2.test bb0b94cf7196c64a3cbd815c66d3ee98c2fecd9c
|
||||
F test/conflict3.test a83db76a6c3503b2fa057c7bfb08c318d8a422202d8bc5b86226e078e5b49ff9
|
||||
F test/conflict3.test dec0634c0f31dec9a4b01c63063e939f0cd21b6b
|
||||
F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4
|
||||
F test/corrupt.test 141c39ea650c1365e85a49e402fa05cb9617fb97
|
||||
F test/corrupt2.test e4964cee73dda57a90958e0087a6b388b1d9cb58
|
||||
@@ -645,11 +638,12 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
|
||||
F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8
|
||||
F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
|
||||
F test/csv01.test e0ba3caaa57e4c667a0b45977689fb8082f14348
|
||||
F test/ctime.test 78749e6c9a5f0010d67985be80788f841e3cd2da18114e2ed6010399a7d807f3
|
||||
F test/ctime.test ff6c38e822459d6ca743c34901caf57740b08b54
|
||||
F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856
|
||||
F test/cursorhint2.test 8457e93d97f665f23f97cdbc8477d16e3480331b
|
||||
F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
|
||||
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
|
||||
F test/dbselftest.c b2e6cfac59066dbcb7334b66304bb15a5508dd42
|
||||
F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5
|
||||
F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab
|
||||
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
|
||||
@@ -663,7 +657,6 @@ F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
|
||||
F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
|
||||
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
|
||||
F test/distinct.test a1783b960ad8c15a77cd9f207be072898db1026c
|
||||
F test/distinct2.test faef8a3f27424e2cfbe19b2a40752294de3b5d957e049e3336be53ec0476cb58
|
||||
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
|
||||
F test/e_blobbytes.test 439a945953b35cb6948a552edaec4dc31fd70a05
|
||||
F test/e_blobclose.test 4b3c8c60c2171164d472059c73e9f3c1844bb66d
|
||||
@@ -695,7 +688,7 @@ F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
|
||||
F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473
|
||||
F test/enc3.test 6807f7a7740a00361ca8d0ccd66bc60c8dc5f2b6
|
||||
F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
|
||||
F test/eqp.test 3f9ba0b2594837c7beaa3ba824e2137cfe857308f020ec5a0c7a62b444e837b0
|
||||
F test/eqp.test 3fe051af50921284189d1970eb653f9fcf5117d2
|
||||
F test/errmsg.test f31592a594b44ee121371d25ddd5d63497bb3401
|
||||
F test/eval.test a64c9105d6ff163df7cf09d6ac29cdad5922078c
|
||||
F test/exclusive.test 9a57bd66e39144b888ca75c309914fcdefb4e3f9
|
||||
@@ -712,7 +705,7 @@ F test/fkey1.test ba64806ff9a04eecab2679caad377ae99a5e94e4
|
||||
F test/fkey2.test 155809016fad6b2a1491facf2ac53a551bc57c2c
|
||||
F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
|
||||
F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
|
||||
F test/fkey5.test 24dd28eb3d9f1b5a174f47e9899ace5facb08373a4223593c8c631e6cf9f7d5a
|
||||
F test/fkey5.test 5a373303f201ac03c22ba1ef17a733d3f56e611a
|
||||
F test/fkey6.test d078a1e323a740062bed38df32b8a736fd320dc0
|
||||
F test/fkey7.test 72e915890ee4a005daaf3002cb208e8fe973ac13
|
||||
F test/fkey8.test e5372e32cdb4481f121ec3550703eeb7b4e0762c
|
||||
@@ -756,7 +749,7 @@ F test/fts2r.test b154c30b63061d8725e320fba1a39e2201cadd5e
|
||||
F test/fts2token.test d8070b241a15ff13592a9ae4a8b7c171af6f445a
|
||||
F test/fts3.test 672a040ea57036fb4b6fdc09027c18d7d24ab654
|
||||
F test/fts3_common.tcl 99cf6659b87c0f74f55963c2aea03b3a7d66ceb0
|
||||
F test/fts3aa.test 39b65c11913d277c91d7426c62cfc1d147d1b4e9a48fecd9e38f60d0b5a5f505
|
||||
F test/fts3aa.test 6c263a6f8845205ee02550981a94c2e8dc1e7058
|
||||
F test/fts3ab.test 7f6cf260ae80dda064023df8e8e503e9a412b91f
|
||||
F test/fts3ac.test 636ed7486043055d4f126a0e385f2d5a82ebbf63
|
||||
F test/fts3ad.test e40570cb6f74f059129ad48bcef3d7cbc20dda49
|
||||
@@ -781,7 +774,6 @@ F test/fts3comp1.test a0f5b16a2df44dd0b15751787130af2183167c0c
|
||||
F test/fts3conf.test 60317efd562080e198b5bdc9fcd222ce32cf01d7
|
||||
F test/fts3corrupt.test 2710b77983cc7789295ddbffea52c1d3b7506dbb
|
||||
F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba
|
||||
F test/fts3corrupt3.test 56e0ee83e90b57f5f3644cb7d1b36a067b7b8b19cdf0dedce45e5e13cf752f65
|
||||
F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7
|
||||
F test/fts3d.test d3e9c8fb75135ada06bf3bab4f9666224965d708
|
||||
F test/fts3defer.test 0be4440b73a2e651fc1e472066686d6ada4b9963
|
||||
@@ -794,13 +786,12 @@ F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a
|
||||
F test/fts3expr3.test c4d4a7d6327418428c96e0a3a1137c251b8dfbf8
|
||||
F test/fts3expr4.test c39a15d676b14fc439d9bf845aa7bddcf4a74dc3
|
||||
F test/fts3expr5.test f9abfffbf5e53d48a33e12a1e8f8ba2c551c9b49
|
||||
F test/fts3fault.test 3764ecffb3d341c5b05b3abe64153f385880035e67706ca2fc719e5d3352aedb
|
||||
F test/fts3fault2.test 536bbe01fe2946ec24b063a5eee813e8fd90354a6ca0b8f941d299c405edd17e
|
||||
F test/fts3fault.test da49627b280b210ebc6657f76344c7851f10ce66
|
||||
F test/fts3fault2.test f953bb3cf903988172270a9a0aafd5a890b0f98f
|
||||
F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641
|
||||
F test/fts3join.test 34750f3ce1e29b2749eaf0f1be2fa6301c5d50da
|
||||
F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6
|
||||
F test/fts3matchinfo.test ce864e0bd92429df8008f31cf557269ba172482a
|
||||
F test/fts3misc.test 66e7b59576ce2c795f0baff6d47f7f6f57e6f41101cf85fad05989e43bb060dd
|
||||
F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905
|
||||
F test/fts3offsets.test b85fd382abdc78ebce721d8117bd552dfb75094c
|
||||
F test/fts3prefix.test fa794eaab0bdae466494947b0b153d7844478ab2
|
||||
@@ -820,7 +811,7 @@ F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01
|
||||
F test/fts4growth.test e5390da74619cacc389711bac9349640b32c4f9a
|
||||
F test/fts4growth2.test 13ad4e76451af6e6906c95cdc725d01b00044269
|
||||
F test/fts4incr.test 4e353a0bd886ea984e56fce9e77724fc923b8d0d
|
||||
F test/fts4langid.test 89a107d36710dc3f44dab0861a784ffab967bd1f32c8d700b031748b9d2703c6
|
||||
F test/fts4langid.test 65a7332c9bc257919e259a304aa8a38c41655b9d
|
||||
F test/fts4lastrowid.test fa5e157955a3121615ef3e16ff5196e96c9e1e64
|
||||
F test/fts4merge.test d2b39f6b1bd4a9738a13540e2d044cba11c43d47
|
||||
F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891
|
||||
@@ -829,7 +820,7 @@ F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b
|
||||
F test/fts4noti.test 5553d7bb2e20bf4a06b23e849352efc022ce6309
|
||||
F test/fts4onepass.test 7319d61a2ed1325fc54afd0c060a0513b462303a
|
||||
F test/fts4opt.test fd6a11684b965e1999564ae763797b7fb9e34c96
|
||||
F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95
|
||||
F test/fts4unicode.test 27378af76394542cf490cf001d8d1505fe55f6a9
|
||||
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
|
||||
F test/func.test ae97561957aba6ca9e3a7b8a13aac41830d701ef
|
||||
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
|
||||
@@ -842,7 +833,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1
|
||||
F test/fuzz3.test b47377143f0c80f91ed29d722861077ff34415d5
|
||||
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
|
||||
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
|
||||
F test/fuzzcheck.c 2152602232c96d9c790eff3013e1369ce59de3203fa0b75bc613531448454e61
|
||||
F test/fuzzcheck.c a87e6067a8d19844bade916841cb76150ecf24a2
|
||||
F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664
|
||||
F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973
|
||||
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||
@@ -853,7 +844,6 @@ F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
|
||||
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
|
||||
F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c
|
||||
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
|
||||
F test/having.test 30a02b8a9a47cba7bdb5281999c5cbff407c2ac296511ee64dd0b418fe38eb0f
|
||||
F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751
|
||||
F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711
|
||||
F test/hook.test dbc0b87756e1e20e7497b56889c9e9cd2f8cc2b5
|
||||
@@ -865,7 +855,7 @@ F test/in.test 20c5529986998949908f889c8208b2cd894b2cc9
|
||||
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
|
||||
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
|
||||
F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068
|
||||
F test/in5.test 7ae37fcd4a5e198291c6ab5f31a5bb3d15397efe8b75a6736d7a95a7b8dd9e08
|
||||
F test/in5.test 6c006e0bcd7351b69350ef566e65f244023489e9
|
||||
F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822
|
||||
F test/incrblob2.test a5ce5ed1d0b01e2ed347245a21170372528af0a5
|
||||
F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4
|
||||
@@ -887,13 +877,12 @@ F test/index7.test 7feababe16f2091b229c22aff2bcc1d4d6b9d2bb
|
||||
F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
|
||||
F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985
|
||||
F test/indexexpr1.test 038b3befa74e5a75126b6e9dd2ae5df61c1c7cf7
|
||||
F test/indexexpr2.test 68ee9dbe83fcf85e50f4d0bd1f742a082496f2ee5153f4be2a1861db84462bf7
|
||||
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
|
||||
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371
|
||||
F test/insert2.test 4d14b8f1b810a41995f6286b64a6943215d52208
|
||||
F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
|
||||
F test/insert4.test 46bead5f39e181850ee56adcf49d3a3157c460c52249211714612ac89fe34835
|
||||
F test/insert4.test a20432f1c0fbbcff8f11d0e6ab4acb8c9db58023
|
||||
F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
|
||||
F test/instr.test 9a8802f28437d8ade53fedfc47b2ca599b4e48ba
|
||||
F test/instrfault.test 0f870b218ea17cd477bb19ed330eecdb460dd53a
|
||||
@@ -908,7 +897,7 @@ F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
|
||||
F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
|
||||
F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
|
||||
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
|
||||
F test/join.test 442c462eea85cf065d70a663c626b780a95af6e11585d909bb63b87598afe678
|
||||
F test/join.test f9d4a28dec81c6e9dc21b73518e024d73b5ebf57
|
||||
F test/join2.test a48f723c5692e2cbb23a9297ac2720cb77d51a70
|
||||
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
|
||||
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
|
||||
@@ -920,12 +909,11 @@ F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
|
||||
F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
|
||||
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
|
||||
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
||||
F test/json101.test 2bd3703a8566e39f8efee8b83bb60aac363fa312e69c94b4024114e0fe77e380
|
||||
F test/json102.test eeb54efa221e50b74a2d6fb9259963b48d7414dca3ce2fdfdeed45cb28487bc1
|
||||
F test/json101.test c0897616f32d95431f37fd291cb78742181980ac
|
||||
F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a
|
||||
F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0
|
||||
F test/json104.test 877d5845f6303899b7889ea5dd1bea99076e3100574d5c536082245c5805dcaa
|
||||
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
||||
F test/kvtest.c d2b8cfc91047ebf6cac4f3a04f19c3a864e4ecfd683bbb65c395df450b8dc79c
|
||||
F test/kvtest.c b9a9822dda05a1aa481215a52e2fc93cd8b22ee5
|
||||
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
||||
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
|
||||
F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302
|
||||
@@ -949,7 +937,7 @@ F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
|
||||
F test/malloc.test 21c213365f2cca95ab2d7dc078dc8525f96065f8
|
||||
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
|
||||
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
|
||||
F test/malloc5.test a591be066ebc6ad34adaa4b38939a037a59ebd80ad681e79dedac7b4a9e7bc09
|
||||
F test/malloc5.test 192d0b5ee1d023a07d5164c34cf47d010da73da1
|
||||
F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
|
||||
F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a
|
||||
F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d
|
||||
@@ -967,7 +955,6 @@ F test/mallocI.test 6c23a71df077fa5d387be90e7e669c5b368ca38a
|
||||
F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e
|
||||
F test/mallocK.test 27cb5566a6e5f2d76f9d4aa2eca45524401fd61e
|
||||
F test/mallocL.test fb311ff80afddf3b1a75e52289081f4754d901dc
|
||||
F test/mallocM.test 78bbe9d3da84a5c679123cdb40d7b2010b18fc46e13897e4f253c6ba6fbff134
|
||||
F test/malloc_common.tcl aac62499b76be719fac31e7a3e54a7fd53272e7f
|
||||
F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
|
||||
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
|
||||
@@ -1021,8 +1008,8 @@ F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
|
||||
F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
|
||||
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
|
||||
F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f
|
||||
F test/ossfuzz.c f5abed3177f719df3c3109901fcdd26b9fb7f581c8da50fc26f3a81ddfb2c2ae
|
||||
F test/ossshell.c 296ab63067841bd1b1e97b46a0b2af48ee7f69d50d1a723008bee12dd7122622
|
||||
F test/ossfuzz.c e469138f4be3e92df6173b79b3b216ab6e17b407
|
||||
F test/ossshell.c d9f1a6f43e7bab45d6be857a5800f5d4a1861db3
|
||||
F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
|
||||
F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d
|
||||
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
|
||||
@@ -1037,17 +1024,15 @@ F test/parser1.test 391b9bf9a229547a129c61ac345ed1a6f5eb1854
|
||||
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
F test/permutations.test 8aaa22a0f428a7e6b8446b97bc7691a273eaeff5dc290fb9129bf79fa9813a6e
|
||||
F test/permutations.test 46ad98770d3c04ce2418cab2cc527647bfe961a7
|
||||
F test/pragma.test 1e94755164a3a3264cd39836de4bebcb7809e5f8
|
||||
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
|
||||
F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed
|
||||
F test/pragma4.test 6e85b6eab8e61ffc9c7db59d842276674e8e3264
|
||||
F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8
|
||||
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
|
||||
F test/printf2.test 9e6db85f81c63f2367c34a9d7db384088bd374ad
|
||||
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
|
||||
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
|
||||
F test/pushdown.test a5d2e5e66cc94cfb0989a5dd23e77427dd6c4313019155ba9051f52dfc5326aa
|
||||
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
|
||||
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
|
||||
F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26
|
||||
@@ -1061,7 +1046,7 @@ F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
|
||||
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
|
||||
F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c
|
||||
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
|
||||
F test/releasetest.tcl 7bb585433ce7fb2a2c255ae4b5e24f1bc27fe177ec1120f886cc4852f48f5ee9 x
|
||||
F test/releasetest.tcl cb06c4df0de4872e65b178316f8a87ccf7624d59 x
|
||||
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
|
||||
F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea
|
||||
F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5
|
||||
@@ -1126,12 +1111,12 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
|
||||
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
|
||||
F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test 50226a3a66bbd42a902e9f7698f768927eb33a56e9cfc55b7c157c38eb3e80ac
|
||||
F test/shell1.test bc1ca4161e1f459c9cd412d3f21f4ee635cf2322
|
||||
F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
|
||||
F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1
|
||||
F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d
|
||||
F test/shell5.test 50a732c1c2158b1cd62cf53975ce1ea7ce6b9dc9
|
||||
F test/shell6.test ab1592ebe881371f651f18ee6a0df21cbfb5310f88cb832ab642d4038f679772
|
||||
F test/shell6.test cff624fadf71bdb5e3a9b0f86eaf59a43c0622b1
|
||||
F test/shell7.test 07751911b294698e0c5df67bcbd29e7d2f0f2907
|
||||
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
||||
F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
|
||||
@@ -1171,7 +1156,6 @@ F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a
|
||||
F test/stat.test f8f1279ffffabe6df825723af18cc6e0ae70a893
|
||||
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
|
||||
F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f
|
||||
F test/subjournal.test 2121a93ef3d3e83d52bf236c8a02aef4009fbf52884754104b2b6cad9a041095
|
||||
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
|
||||
F test/subquery2.test 438f8a7da1457277b22e4176510f7659b286995f
|
||||
F test/subselect.test 0966aa8e720224dbd6a5e769a3ec2a723e332303
|
||||
@@ -1180,7 +1164,6 @@ F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8
|
||||
F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12
|
||||
F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849
|
||||
F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529
|
||||
F test/sync2.test 6be8ed007fa063b147773c1982b5bdba97a32badc536bdc6077eff5cf8710ece
|
||||
F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c
|
||||
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
|
||||
F test/tabfunc01.test 699251cb99651415218a891384510a685c7ab012
|
||||
@@ -1373,7 +1356,6 @@ F test/triggerC.test 302d8995f5ffe63bbc15053abb3ef7a39cf5a092
|
||||
F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650
|
||||
F test/triggerE.test 15fa63f1097db1f83dd62d121616006978063d1f
|
||||
F test/triggerF.test 55b1eb13433997faac3a4948c1d8252f6c8c636b
|
||||
F test/triggerG.test 175cafdc6399d85231a09e82e051b0e45a2fd1f23dd08ae715bc359716149ab6
|
||||
F test/tt3_checkpoint.c 9e75cf7c1c364f52e1c47fd0f14c4340a9db0fe1
|
||||
F test/tt3_index.c 39eec10a35f57672225be4d182862152896dee4a
|
||||
F test/tt3_lookaside1.c 0377e202c3c2a50d688cb65ba203afeda6fafeb9
|
||||
@@ -1416,7 +1398,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292
|
||||
F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96
|
||||
F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe
|
||||
F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b
|
||||
F test/vtabH.test 26d54e8b5407f797638b787a55f9c88323850a58dd142de02d06b9a1159bd283
|
||||
F test/vtabH.test 5f9253eb9e41ba9fe94f4aa3e9230191893d7764
|
||||
F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f
|
||||
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
|
||||
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
|
||||
@@ -1465,7 +1447,7 @@ F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
|
||||
F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6
|
||||
F test/whereD.test 711d4df58d6d4fb9b3f5ce040b818564198be002
|
||||
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
|
||||
F test/whereF.test 97a86ecdfa4c21684fdff501dbd2cb7397689be8676d0dbad1f5a0892c6b56a3
|
||||
F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7
|
||||
F test/whereG.test dde4c52a97385a55be6a7cd46be8373f0cf35501
|
||||
F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
|
||||
F test/whereI.test eab5b226bbc344ac70d7dc09b963a064860ae6d7
|
||||
@@ -1478,7 +1460,7 @@ F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c
|
||||
F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
|
||||
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
|
||||
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
|
||||
F test/with1.test 732e3ef398dcecb609839cd5ef0cb63beb2a9eff31420f3b745fc55b9e85b61e
|
||||
F test/with1.test cef099a491eac9874f2c28bd2dc86394fb3e47b3
|
||||
F test/with2.test 2b40da883658eb74ad8ad06afabe11a408e7fb87
|
||||
F test/with3.test e71604a0e53cba82bc04c703987cb1d6751ec0b6
|
||||
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
|
||||
@@ -1494,7 +1476,7 @@ F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e
|
||||
F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
|
||||
F tool/GetTclKit.bat 6afa640edc7810725aec61c3076ac617c4aaf0b7
|
||||
F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
|
||||
F tool/addopcodes.tcl edbd53806bf20e25af2373ad0c091be4385081c1aa1813b916bf093f94ed8380
|
||||
F tool/addopcodes.tcl 10c889c4a65ec6c5604e4a47306fa77ff57ae189
|
||||
F tool/build-all-msvc.bat c12328d06c45fec8baada5949e3d5af54bf8c887 x
|
||||
F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
|
||||
F tool/cg_anno.tcl f95b0006c52cf7f0496b506343415b6ee3cdcdd3 x
|
||||
@@ -1503,46 +1485,45 @@ F tool/dbhash.c a06228aa21ebc4e6ea8daa486601d938499238a5
|
||||
F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2
|
||||
F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1
|
||||
F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
|
||||
F tool/fuzzershell.c e1d90a03ca790d7c331c2aae08ca46ff435f1ae1faa6cb9cc48f4687c18fdc6e
|
||||
F tool/fuzzershell.c dbf6c26eef936ec78cb0707570de3a4308b2507e
|
||||
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
|
||||
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
|
||||
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
||||
F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f
|
||||
F tool/lemon.c f4f1045743e12f86b132253a3192ef92c94bfceb7f41ac41b8e3b373aa78474e
|
||||
F tool/lemon.c 5ccba178a8e8a4b21e1c9232944d23973da38ad7
|
||||
F tool/lempar.c db1bdb4821f2d8fbd76e577cf3ab18642c8d08d1
|
||||
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
|
||||
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
||||
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
|
||||
F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
|
||||
F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7
|
||||
F tool/mkctimec.tcl dd183b73ae1c28249669741c250525f0407e579a70482371668fd5f130d9feb3
|
||||
F tool/mkkeywordhash.c f7f3b342211ac6a14258b9726d5b97cf4f548f22
|
||||
F tool/mkmsvcmin.tcl cbd93f1cfa3a0a9ae56fc958510aa3fc3ac65e29cb111716199e3d0e66eefaa4
|
||||
F tool/mkmsvcmin.tcl 95b37e202cbed873aa8ffdbb493b9db45927be2b
|
||||
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
|
||||
F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3
|
||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||
F tool/mkpragmatab.tcl bdd4c76449e9e0874ae7f0846868c42583e63b47a081b177a97f94e2b702b3e7
|
||||
F tool/mkpragmatab.tcl 2ffe6d5fdc2d3381621d6c77978ba054466e757f
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb
|
||||
F tool/mksqlite3c.tcl 226da6d794d7d43a31e159a6fa89db867bf1f5eafe4b37d031222287ef8dbadc
|
||||
F tool/mksqlite3h.tcl 51bd5e7e840a920388a5966c9f2ccc618f434c57bd68c1bab4085b2553e1e237
|
||||
F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e
|
||||
F tool/mksqlite3h.tcl b9836752c3d08f9fab2dfc0017ca9fd5d90ac863
|
||||
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
|
||||
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
|
||||
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
|
||||
F tool/omittest.tcl dfc8b18a23e9e5289104145b712cdb887c2d840c2d70dc09ce5dbeba8ed8d47c
|
||||
F tool/omittest.tcl 34d7ac01fe4fd18e3637f64abe12c40eca0f6b97
|
||||
F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a
|
||||
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
|
||||
F tool/replace.tcl 60f91e8dd06ab81f74d213ecbd9c9945f32ac048
|
||||
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
|
||||
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
|
||||
F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076
|
||||
F tool/showdb.c e6bc9dba233bf1b57ca0a525a2bba762db4e223de84990739db3f09c46151b1e
|
||||
F tool/showdb.c c695a5d5c8110640e0d9fadf5e254da90c79c36e
|
||||
F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818
|
||||
F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68
|
||||
F tool/showstat4.c b14159aa062f661b394ba37b6b7b94bfb8012ab9
|
||||
F tool/showwal.c ad9d768f96ca6199ad3a8c9562d679680bd032dd01204ea3e5ea6fb931d81847
|
||||
F tool/showwal.c ec79959834f7b21f1e0a2aa52bb7c056d2203977
|
||||
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
|
||||
F tool/spaceanal.tcl f40dc82b4d5e39d040a02a3ec38268e324068815e4292a15ffa30ee93208bbfd
|
||||
F tool/spaceanal.tcl ab7d9bf68062907282a64b3e12ccbfad47193c5a
|
||||
F tool/speed-check.sh 9630ba0468b609c52f48309243d4eb6e9c34deda
|
||||
F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
|
||||
F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e
|
||||
@@ -1550,7 +1531,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
|
||||
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
|
||||
F tool/sqldiff.c 30879bbc8de686df4624e86adce2d8981f500904c1cfb55b5d1eea2ffd9341eb
|
||||
F tool/sqldiff.c 3fb48a6c6669d2d2c59a7f072a410dd2583579b4
|
||||
F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f
|
||||
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
|
||||
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
|
||||
@@ -1560,7 +1541,7 @@ F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003
|
||||
F tool/vdbe-compress.tcl 5926c71f9c12d2ab73ef35c29376e756eb68361c
|
||||
F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 8a4acea31e0f9c562949a2d767329533c0930d699ea19c6704c0ca0aa9154068
|
||||
F tool/warnings.sh d9ded5274b3cb947e98e70d587f71d6263f803b5
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
F vsixtest/App.xaml b76d3b48860e7454775c47ea38ffea9c4abe3e85
|
||||
F vsixtest/App.xaml.cpp c465147f50871165c60ca16955219f6c5812d6d8
|
||||
@@ -1583,10 +1564,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 118f7bb33a6f78951bbffa957f48015d1bce5aaf9246a99262a90bc8ad52e5a3
|
||||
R b4aae75660dcec44ff13144cfab52224
|
||||
T *branch * or-optimization
|
||||
T *sym-or-optimization *
|
||||
P 2ea300fb8f7c497f3f092dc91f4305d8431c27d9
|
||||
R c02034589707ebfaa15c308979e3e64d
|
||||
T *branch * shell-print-refactor
|
||||
T *sym-shell-print-refactor *
|
||||
T -sym-trunk *
|
||||
U dan
|
||||
Z 7d390f8e00d309abb459da345f7f0ca9
|
||||
U drh
|
||||
Z e3e35f6a310eb359a3cc12fa796fab47
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
e4a022be4b069b08cfdfda5295461676b99d28e17bbbedfbcb362dec69de59bd
|
||||
aacac906633fbc5a887a58cd589e63356554dbbe
|
||||
+1
-1
@@ -1204,7 +1204,7 @@ static void analyzeOneTable(
|
||||
regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
|
||||
for(j=0; j<pPk->nKeyCol; j++){
|
||||
k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
|
||||
assert( k>=0 && k<pIdx->nColumn );
|
||||
assert( k>=0 && k<pTab->nCol );
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
|
||||
VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
|
||||
}
|
||||
|
||||
+15
-16
@@ -69,8 +69,7 @@ static void attachFunc(
|
||||
char *zPath = 0;
|
||||
char *zErr = 0;
|
||||
unsigned int flags;
|
||||
Db *aNew; /* New array of Db pointers */
|
||||
Db *pNew; /* Db object for the newly attached database */
|
||||
Db *aNew;
|
||||
char *zErrDyn = 0;
|
||||
sqlite3_vfs *pVfs;
|
||||
|
||||
@@ -118,8 +117,8 @@ static void attachFunc(
|
||||
if( aNew==0 ) return;
|
||||
}
|
||||
db->aDb = aNew;
|
||||
pNew = &db->aDb[db->nDb];
|
||||
memset(pNew, 0, sizeof(*pNew));
|
||||
aNew = &db->aDb[db->nDb];
|
||||
memset(aNew, 0, sizeof(*aNew));
|
||||
|
||||
/* Open the database file. If the btree is successfully opened, use
|
||||
** it to obtain the database schema. At this point the schema may
|
||||
@@ -135,7 +134,7 @@ static void attachFunc(
|
||||
}
|
||||
assert( pVfs );
|
||||
flags |= SQLITE_OPEN_MAIN_DB;
|
||||
rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
|
||||
rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, 0, flags);
|
||||
sqlite3_free( zPath );
|
||||
db->nDb++;
|
||||
db->skipBtreeMutex = 0;
|
||||
@@ -144,28 +143,28 @@ static void attachFunc(
|
||||
zErrDyn = sqlite3MPrintf(db, "database is already attached");
|
||||
}else if( rc==SQLITE_OK ){
|
||||
Pager *pPager;
|
||||
pNew->pSchema = sqlite3SchemaGet(db, pNew->pBt);
|
||||
if( !pNew->pSchema ){
|
||||
aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt);
|
||||
if( !aNew->pSchema ){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
}else if( pNew->pSchema->file_format && pNew->pSchema->enc!=ENC(db) ){
|
||||
}else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
|
||||
zErrDyn = sqlite3MPrintf(db,
|
||||
"attached databases must use the same text encoding as main database");
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
sqlite3BtreeEnter(pNew->pBt);
|
||||
pPager = sqlite3BtreePager(pNew->pBt);
|
||||
sqlite3BtreeEnter(aNew->pBt);
|
||||
pPager = sqlite3BtreePager(aNew->pBt);
|
||||
sqlite3PagerLockingMode(pPager, db->dfltLockMode);
|
||||
sqlite3BtreeSecureDelete(pNew->pBt,
|
||||
sqlite3BtreeSecureDelete(aNew->pBt,
|
||||
sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) );
|
||||
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||
sqlite3BtreeSetPagerFlags(pNew->pBt,
|
||||
sqlite3BtreeSetPagerFlags(aNew->pBt,
|
||||
PAGER_SYNCHRONOUS_FULL | (db->flags & PAGER_FLAGS_MASK));
|
||||
#endif
|
||||
sqlite3BtreeLeave(pNew->pBt);
|
||||
sqlite3BtreeLeave(aNew->pBt);
|
||||
}
|
||||
pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
|
||||
pNew->zDbSName = sqlite3DbStrDup(db, zName);
|
||||
if( rc==SQLITE_OK && pNew->zDbSName==0 ){
|
||||
aNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
|
||||
aNew->zDbSName = sqlite3DbStrDup(db, zName);
|
||||
if( rc==SQLITE_OK && aNew->zDbSName==0 ){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
|
||||
|
||||
-12
@@ -216,18 +216,6 @@ int sqlite3AuthCheck(
|
||||
if( db->xAuth==0 ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/* EVIDENCE-OF: R-43249-19882 The third through sixth parameters to the
|
||||
** callback are either NULL pointers or zero-terminated strings that
|
||||
** contain additional details about the action to be authorized.
|
||||
**
|
||||
** The following testcase() macros show that any of the 3rd through 6th
|
||||
** parameters can be either NULL or a string. */
|
||||
testcase( zArg1==0 );
|
||||
testcase( zArg2==0 );
|
||||
testcase( zArg3==0 );
|
||||
testcase( pParse->zAuthContext==0 );
|
||||
|
||||
rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext
|
||||
#ifdef SQLITE_USER_AUTHENTICATION
|
||||
,db->auth.zAuthUser
|
||||
|
||||
+263
-283
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -276,7 +276,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 */
|
||||
sqlite3_value *aMem; /* First of nMem value in the unpacked pKey */
|
||||
struct Mem *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. */
|
||||
int nZero; /* Extra zero data appended after pData,nData */
|
||||
@@ -286,9 +286,9 @@ int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
|
||||
int flags, int seekResult);
|
||||
int sqlite3BtreeFirst(BtCursor*, int *pRes);
|
||||
int sqlite3BtreeLast(BtCursor*, int *pRes);
|
||||
int sqlite3BtreeNext(BtCursor*, int flags);
|
||||
int sqlite3BtreeNext(BtCursor*, int *pRes);
|
||||
int sqlite3BtreeEof(BtCursor*);
|
||||
int sqlite3BtreePrevious(BtCursor*, int flags);
|
||||
int sqlite3BtreePrevious(BtCursor*, int *pRes);
|
||||
i64 sqlite3BtreeIntegerKey(BtCursor*);
|
||||
int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
|
||||
const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
|
||||
|
||||
+4
-4
@@ -517,10 +517,10 @@ struct BtCursor {
|
||||
** 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 */
|
||||
struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
|
||||
void *padding1; /* Make object size a multiple of 16 */
|
||||
u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */
|
||||
MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+2
-6
@@ -939,11 +939,7 @@ void sqlite3StartTable(
|
||||
pTable->iPKey = -1;
|
||||
pTable->pSchema = db->aDb[iDb].pSchema;
|
||||
pTable->nTabRef = 1;
|
||||
#ifdef SQLITE_DEFAULT_ROWEST
|
||||
pTable->nRowLogEst = sqlite3LogEst(SQLITE_DEFAULT_ROWEST);
|
||||
#else
|
||||
pTable->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
|
||||
#endif
|
||||
assert( pParse->pNewTable==0 );
|
||||
pParse->pNewTable = pTable;
|
||||
|
||||
@@ -3627,7 +3623,7 @@ void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
|
||||
sqlite3DbFree(db, pList->a[i].zName);
|
||||
}
|
||||
sqlite3DbFree(db, pList->a);
|
||||
sqlite3DbFreeNN(db, pList);
|
||||
sqlite3DbFree(db, pList);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3817,7 +3813,7 @@ void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
|
||||
sqlite3ExprDelete(db, pItem->pOn);
|
||||
sqlite3IdListDelete(db, pItem->pUsing);
|
||||
}
|
||||
sqlite3DbFreeNN(db, pList);
|
||||
sqlite3DbFree(db, pList);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+61
-339
@@ -16,11 +16,7 @@
|
||||
|
||||
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
|
||||
|
||||
|
||||
/* These macros are provided to "stringify" the value of the define
|
||||
** for those options in which the value is meaningful. */
|
||||
#define CTIMEOPT_VAL_(opt) #opt
|
||||
#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
|
||||
#include "sqliteInt.h"
|
||||
|
||||
/*
|
||||
** An array of names of all compile-time options. This array should
|
||||
@@ -30,32 +26,19 @@
|
||||
** only a handful of compile-time options, so most times this array is usually
|
||||
** rather short and uses little memory space.
|
||||
*/
|
||||
static const char * const sqlite3azCompileOpt[] = {
|
||||
static const char * const azCompileOpt[] = {
|
||||
|
||||
/* These macros are provided to "stringify" the value of the define
|
||||
** for those options in which the value is meaningful. */
|
||||
#define CTIMEOPT_VAL_(opt) #opt
|
||||
#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
|
||||
|
||||
/*
|
||||
** BEGIN CODE GENERATED BY tool/mkctime.tcl
|
||||
*/
|
||||
#if SQLITE_32BIT_ROWID
|
||||
"32BIT_ROWID",
|
||||
#endif
|
||||
#if SQLITE_4_BYTE_ALIGNED_MALLOC
|
||||
"4_BYTE_ALIGNED_MALLOC",
|
||||
#endif
|
||||
#if SQLITE_64BIT_STATS
|
||||
"64BIT_STATS",
|
||||
#endif
|
||||
#if SQLITE_ALLOW_COVERING_INDEX_SCAN
|
||||
"ALLOW_COVERING_INDEX_SCAN",
|
||||
#endif
|
||||
#if SQLITE_ALLOW_URI_AUTHORITY
|
||||
"ALLOW_URI_AUTHORITY",
|
||||
#endif
|
||||
#ifdef SQLITE_BITMASK_TYPE
|
||||
"BITMASK_TYPE=" CTIMEOPT_VAL(SQLITE_BITMASK_TYPE),
|
||||
#endif
|
||||
#if SQLITE_BUG_COMPATIBLE_20160819
|
||||
"BUG_COMPATIBLE_20160819",
|
||||
#endif
|
||||
#if SQLITE_CASE_SENSITIVE_LIKE
|
||||
"CASE_SENSITIVE_LIKE",
|
||||
#endif
|
||||
@@ -74,100 +57,25 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_COVERAGE_TEST
|
||||
"COVERAGE_TEST",
|
||||
#endif
|
||||
#if SQLITE_DEBUG
|
||||
#ifdef SQLITE_DEBUG
|
||||
"DEBUG",
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_AUTOMATIC_INDEX
|
||||
"DEFAULT_AUTOMATIC_INDEX",
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_AUTOVACUUM
|
||||
"DEFAULT_AUTOVACUUM",
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_CACHE_SIZE
|
||||
"DEFAULT_CACHE_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_CACHE_SIZE),
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_CKPTFULLFSYNC
|
||||
"DEFAULT_CKPTFULLFSYNC",
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_FILE_FORMAT
|
||||
"DEFAULT_FILE_FORMAT=" CTIMEOPT_VAL(SQLITE_DEFAULT_FILE_FORMAT),
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_FILE_PERMISSIONS
|
||||
"DEFAULT_FILE_PERMISSIONS=" CTIMEOPT_VAL(SQLITE_DEFAULT_FILE_PERMISSIONS),
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_FOREIGN_KEYS
|
||||
"DEFAULT_FOREIGN_KEYS",
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT
|
||||
"DEFAULT_JOURNAL_SIZE_LIMIT=" CTIMEOPT_VAL(SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT),
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_LOCKING_MODE
|
||||
#if SQLITE_DEFAULT_LOCKING_MODE
|
||||
"DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_LOOKASIDE
|
||||
"DEFAULT_LOOKASIDE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOOKASIDE),
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_MEMSTATUS
|
||||
"DEFAULT_MEMSTATUS",
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_MMAP_SIZE
|
||||
#if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc)
|
||||
"DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_PAGE_SIZE
|
||||
"DEFAULT_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_PAGE_SIZE),
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_PCACHE_INITSZ
|
||||
"DEFAULT_PCACHE_INITSZ=" CTIMEOPT_VAL(SQLITE_DEFAULT_PCACHE_INITSZ),
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS
|
||||
"DEFAULT_PROXYDIR_PERMISSIONS=" CTIMEOPT_VAL(SQLITE_DEFAULT_PROXYDIR_PERMISSIONS),
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_RECURSIVE_TRIGGERS
|
||||
"DEFAULT_RECURSIVE_TRIGGERS",
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_ROWEST
|
||||
"DEFAULT_ROWEST=" CTIMEOPT_VAL(SQLITE_DEFAULT_ROWEST),
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_SECTOR_SIZE
|
||||
"DEFAULT_SECTOR_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_SECTOR_SIZE),
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_SYNCHRONOUS
|
||||
"DEFAULT_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_SYNCHRONOUS),
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT
|
||||
"DEFAULT_WAL_AUTOCHECKPOINT=" CTIMEOPT_VAL(SQLITE_DEFAULT_WAL_AUTOCHECKPOINT),
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_WAL_SYNCHRONOUS
|
||||
"DEFAULT_WAL_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_WAL_SYNCHRONOUS),
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_WORKER_THREADS
|
||||
"DEFAULT_WORKER_THREADS=" CTIMEOPT_VAL(SQLITE_DEFAULT_WORKER_THREADS),
|
||||
#endif
|
||||
#if SQLITE_DIRECT_OVERFLOW_READ
|
||||
"DIRECT_OVERFLOW_READ",
|
||||
#endif
|
||||
#if SQLITE_DISABLE_DIRSYNC
|
||||
"DISABLE_DIRSYNC",
|
||||
#endif
|
||||
#if SQLITE_DISABLE_FTS3_UNICODE
|
||||
"DISABLE_FTS3_UNICODE",
|
||||
#endif
|
||||
#if SQLITE_DISABLE_FTS4_DEFERRED
|
||||
"DISABLE_FTS4_DEFERRED",
|
||||
#endif
|
||||
#if SQLITE_DISABLE_INTRINSIC
|
||||
"DISABLE_INTRINSIC",
|
||||
#endif
|
||||
#if SQLITE_DISABLE_LFS
|
||||
"DISABLE_LFS",
|
||||
#endif
|
||||
#if SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
|
||||
"DISABLE_PAGECACHE_OVERFLOW_STATS",
|
||||
#endif
|
||||
#if SQLITE_DISABLE_SKIPAHEAD_DISTINCT
|
||||
"DISABLE_SKIPAHEAD_DISTINCT",
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_8_3_NAMES
|
||||
#if SQLITE_ENABLE_8_3_NAMES
|
||||
"ENABLE_8_3_NAMES=" CTIMEOPT_VAL(SQLITE_ENABLE_8_3_NAMES),
|
||||
#endif
|
||||
#if SQLITE_ENABLE_API_ARMOR
|
||||
@@ -182,15 +90,6 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_ENABLE_COLUMN_METADATA
|
||||
"ENABLE_COLUMN_METADATA",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_COLUMN_USED_MASK
|
||||
"ENABLE_COLUMN_USED_MASK",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_COSTMULT
|
||||
"ENABLE_COSTMULT",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_CURSOR_HINTS
|
||||
"ENABLE_CURSOR_HINTS",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_DBSTAT_VTAB
|
||||
"ENABLE_DBSTAT_VTAB",
|
||||
#endif
|
||||
@@ -209,18 +108,12 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_ENABLE_FTS3_PARENTHESIS
|
||||
"ENABLE_FTS3_PARENTHESIS",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_FTS3_TOKENIZER
|
||||
"ENABLE_FTS3_TOKENIZER",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_FTS4
|
||||
"ENABLE_FTS4",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_FTS5
|
||||
"ENABLE_FTS5",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_HIDDEN_COLUMNS
|
||||
"ENABLE_HIDDEN_COLUMNS",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_ICU
|
||||
"ENABLE_ICU",
|
||||
#endif
|
||||
@@ -233,7 +126,7 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_ENABLE_LOAD_EXTENSION
|
||||
"ENABLE_LOAD_EXTENSION",
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_LOCKING_STYLE
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||
"ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),
|
||||
#endif
|
||||
#if SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
@@ -245,86 +138,26 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_ENABLE_MEMSYS5
|
||||
"ENABLE_MEMSYS5",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_MULTIPLEX
|
||||
"ENABLE_MULTIPLEX",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_NULL_TRIM
|
||||
"ENABLE_NULL_TRIM",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
|
||||
"ENABLE_OVERSIZE_CELL_CHECK",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_PREUPDATE_HOOK
|
||||
"ENABLE_PREUPDATE_HOOK",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_RBU
|
||||
"ENABLE_RBU",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_RTREE
|
||||
"ENABLE_RTREE",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_SELECTTRACE
|
||||
"ENABLE_SELECTTRACE",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_SESSION
|
||||
"ENABLE_SESSION",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_SNAPSHOT
|
||||
"ENABLE_SNAPSHOT",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_SQLLOG
|
||||
"ENABLE_SQLLOG",
|
||||
#endif
|
||||
#if defined(SQLITE_ENABLE_STAT4)
|
||||
"ENABLE_STAT4",
|
||||
#elif defined(SQLITE_ENABLE_STAT3)
|
||||
"ENABLE_STAT3",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
"ENABLE_STMT_SCANSTATUS",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
"ENABLE_UNKNOWN_SQL_FUNCTION",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_UNLOCK_NOTIFY
|
||||
"ENABLE_UNLOCK_NOTIFY",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_UPDATE_DELETE_LIMIT
|
||||
"ENABLE_UPDATE_DELETE_LIMIT",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_URI_00_ERROR
|
||||
#if defined(SQLITE_ENABLE_URI_00_ERROR)
|
||||
"ENABLE_URI_00_ERROR",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_VFSTRACE
|
||||
"ENABLE_VFSTRACE",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_WHERETRACE
|
||||
"ENABLE_WHERETRACE",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_ZIPVFS
|
||||
"ENABLE_ZIPVFS",
|
||||
#endif
|
||||
#if SQLITE_EXPLAIN_ESTIMATED_ROWS
|
||||
"EXPLAIN_ESTIMATED_ROWS",
|
||||
#endif
|
||||
#if SQLITE_EXTRA_IFNULLROW
|
||||
"EXTRA_IFNULLROW",
|
||||
#endif
|
||||
#ifdef SQLITE_EXTRA_INIT
|
||||
"EXTRA_INIT=" CTIMEOPT_VAL(SQLITE_EXTRA_INIT),
|
||||
#endif
|
||||
#ifdef SQLITE_EXTRA_SHUTDOWN
|
||||
"EXTRA_SHUTDOWN=" CTIMEOPT_VAL(SQLITE_EXTRA_SHUTDOWN),
|
||||
#endif
|
||||
#ifdef SQLITE_FTS3_MAX_EXPR_DEPTH
|
||||
"FTS3_MAX_EXPR_DEPTH=" CTIMEOPT_VAL(SQLITE_FTS3_MAX_EXPR_DEPTH),
|
||||
#endif
|
||||
#if SQLITE_FTS5_ENABLE_TEST_MI
|
||||
"FTS5_ENABLE_TEST_MI",
|
||||
#endif
|
||||
#if SQLITE_FTS5_NO_WITHOUT_ROWID
|
||||
"FTS5_NO_WITHOUT_ROWID",
|
||||
#endif
|
||||
#if SQLITE_HAS_CODEC
|
||||
"HAS_CODEC",
|
||||
#endif
|
||||
@@ -340,114 +173,27 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_IGNORE_FLOCK_LOCK_ERRORS
|
||||
"IGNORE_FLOCK_LOCK_ERRORS",
|
||||
#endif
|
||||
#if SQLITE_INLINE_MEMCPY
|
||||
"INLINE_MEMCPY",
|
||||
#endif
|
||||
#if SQLITE_INT64_TYPE
|
||||
#ifdef SQLITE_INT64_TYPE
|
||||
"INT64_TYPE",
|
||||
#endif
|
||||
#ifdef SQLITE_INTEGRITY_CHECK_ERROR_MAX
|
||||
"INTEGRITY_CHECK_ERROR_MAX=" CTIMEOPT_VAL(SQLITE_INTEGRITY_CHECK_ERROR_MAX),
|
||||
#endif
|
||||
#if SQLITE_LIKE_DOESNT_MATCH_BLOBS
|
||||
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
|
||||
"LIKE_DOESNT_MATCH_BLOBS",
|
||||
#endif
|
||||
#if SQLITE_LOCK_TRACE
|
||||
"LOCK_TRACE",
|
||||
#endif
|
||||
#if SQLITE_LOG_CACHE_SPILL
|
||||
"LOG_CACHE_SPILL",
|
||||
#endif
|
||||
#ifdef SQLITE_MALLOC_SOFT_LIMIT
|
||||
"MALLOC_SOFT_LIMIT=" CTIMEOPT_VAL(SQLITE_MALLOC_SOFT_LIMIT),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_ATTACHED
|
||||
"MAX_ATTACHED=" CTIMEOPT_VAL(SQLITE_MAX_ATTACHED),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_COLUMN
|
||||
"MAX_COLUMN=" CTIMEOPT_VAL(SQLITE_MAX_COLUMN),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_COMPOUND_SELECT
|
||||
"MAX_COMPOUND_SELECT=" CTIMEOPT_VAL(SQLITE_MAX_COMPOUND_SELECT),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_DEFAULT_PAGE_SIZE
|
||||
"MAX_DEFAULT_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_DEFAULT_PAGE_SIZE),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_EXPR_DEPTH
|
||||
"MAX_EXPR_DEPTH=" CTIMEOPT_VAL(SQLITE_MAX_EXPR_DEPTH),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_FUNCTION_ARG
|
||||
"MAX_FUNCTION_ARG=" CTIMEOPT_VAL(SQLITE_MAX_FUNCTION_ARG),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_LENGTH
|
||||
"MAX_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_LENGTH),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_LIKE_PATTERN_LENGTH
|
||||
"MAX_LIKE_PATTERN_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_LIKE_PATTERN_LENGTH),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_MEMORY
|
||||
"MAX_MEMORY=" CTIMEOPT_VAL(SQLITE_MAX_MEMORY),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_MMAP_SIZE
|
||||
#if defined(SQLITE_MAX_MMAP_SIZE) && !defined(SQLITE_MAX_MMAP_SIZE_xc)
|
||||
"MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_MMAP_SIZE_
|
||||
"MAX_MMAP_SIZE_=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE_),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_PAGE_COUNT
|
||||
"MAX_PAGE_COUNT=" CTIMEOPT_VAL(SQLITE_MAX_PAGE_COUNT),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_PAGE_SIZE
|
||||
"MAX_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_PAGE_SIZE),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_SCHEMA_RETRY
|
||||
"MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_SQL_LENGTH
|
||||
"MAX_SQL_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_SQL_LENGTH),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_TRIGGER_DEPTH
|
||||
"MAX_TRIGGER_DEPTH=" CTIMEOPT_VAL(SQLITE_MAX_TRIGGER_DEPTH),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_VARIABLE_NUMBER
|
||||
"MAX_VARIABLE_NUMBER=" CTIMEOPT_VAL(SQLITE_MAX_VARIABLE_NUMBER),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_VDBE_OP
|
||||
"MAX_VDBE_OP=" CTIMEOPT_VAL(SQLITE_MAX_VDBE_OP),
|
||||
#endif
|
||||
#ifdef SQLITE_MAX_WORKER_THREADS
|
||||
"MAX_WORKER_THREADS=" CTIMEOPT_VAL(SQLITE_MAX_WORKER_THREADS),
|
||||
#endif
|
||||
#if SQLITE_MEMDEBUG
|
||||
"MEMDEBUG",
|
||||
#endif
|
||||
#if SQLITE_MIXED_ENDIAN_64BIT_FLOAT
|
||||
"MIXED_ENDIAN_64BIT_FLOAT",
|
||||
#endif
|
||||
#if SQLITE_MMAP_READWRITE
|
||||
"MMAP_READWRITE",
|
||||
#endif
|
||||
#if SQLITE_MUTEX_NOOP
|
||||
"MUTEX_NOOP",
|
||||
#endif
|
||||
#if SQLITE_MUTEX_NREF
|
||||
"MUTEX_NREF",
|
||||
#endif
|
||||
#if SQLITE_MUTEX_OMIT
|
||||
"MUTEX_OMIT",
|
||||
#endif
|
||||
#if SQLITE_MUTEX_PTHREADS
|
||||
"MUTEX_PTHREADS",
|
||||
#endif
|
||||
#if SQLITE_MUTEX_W32
|
||||
"MUTEX_W32",
|
||||
#endif
|
||||
#if SQLITE_NEED_ERR_NAME
|
||||
"NEED_ERR_NAME",
|
||||
#endif
|
||||
#if SQLITE_NOINLINE
|
||||
"NOINLINE",
|
||||
#endif
|
||||
#if SQLITE_NO_SYNC
|
||||
"NO_SYNC",
|
||||
#endif
|
||||
@@ -499,9 +245,6 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_OMIT_COMPOUND_SELECT
|
||||
"OMIT_COMPOUND_SELECT",
|
||||
#endif
|
||||
#if SQLITE_OMIT_CONFLICT_CLAUSE
|
||||
"OMIT_CONFLICT_CLAUSE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_CTE
|
||||
"OMIT_CTE",
|
||||
#endif
|
||||
@@ -532,9 +275,6 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_OMIT_GET_TABLE
|
||||
"OMIT_GET_TABLE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_HEX_INTEGER
|
||||
"OMIT_HEX_INTEGER",
|
||||
#endif
|
||||
#if SQLITE_OMIT_INCRBLOB
|
||||
"OMIT_INCRBLOB",
|
||||
#endif
|
||||
@@ -562,12 +302,6 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_OMIT_PAGER_PRAGMAS
|
||||
"OMIT_PAGER_PRAGMAS",
|
||||
#endif
|
||||
#if SQLITE_OMIT_PARSER_TRACE
|
||||
"OMIT_PARSER_TRACE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_POPEN
|
||||
"OMIT_POPEN",
|
||||
#endif
|
||||
#if SQLITE_OMIT_PRAGMA
|
||||
"OMIT_PRAGMA",
|
||||
#endif
|
||||
@@ -589,9 +323,6 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_OMIT_SHARED_CACHE
|
||||
"OMIT_SHARED_CACHE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_SHUTDOWN_DIRECTORIES
|
||||
"OMIT_SHUTDOWN_DIRECTORIES",
|
||||
#endif
|
||||
#if SQLITE_OMIT_SUBQUERY
|
||||
"OMIT_SUBQUERY",
|
||||
#endif
|
||||
@@ -601,9 +332,6 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_OMIT_TEMPDB
|
||||
"OMIT_TEMPDB",
|
||||
#endif
|
||||
#if SQLITE_OMIT_TEST_CONTROL
|
||||
"OMIT_TEST_CONTROL",
|
||||
#endif
|
||||
#if SQLITE_OMIT_TRACE
|
||||
"OMIT_TRACE",
|
||||
#endif
|
||||
@@ -634,24 +362,12 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_OMIT_XFER_OPT
|
||||
"OMIT_XFER_OPT",
|
||||
#endif
|
||||
#if SQLITE_PCACHE_SEPARATE_HEADER
|
||||
"PCACHE_SEPARATE_HEADER",
|
||||
#endif
|
||||
#if SQLITE_PERFORMANCE_TRACE
|
||||
"PERFORMANCE_TRACE",
|
||||
#endif
|
||||
#if SQLITE_POWERSAFE_OVERWRITE
|
||||
"POWERSAFE_OVERWRITE",
|
||||
#endif
|
||||
#if SQLITE_PREFER_PROXY_LOCKING
|
||||
"PREFER_PROXY_LOCKING",
|
||||
#endif
|
||||
#if SQLITE_PROXY_DEBUG
|
||||
"PROXY_DEBUG",
|
||||
#endif
|
||||
#if SQLITE_REVERSE_UNORDERED_SELECTS
|
||||
"REVERSE_UNORDERED_SELECTS",
|
||||
#endif
|
||||
#if SQLITE_RTREE_INT_ONLY
|
||||
"RTREE_INT_ONLY",
|
||||
#endif
|
||||
@@ -661,28 +377,16 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_SMALL_STACK
|
||||
"SMALL_STACK",
|
||||
#endif
|
||||
#ifdef SQLITE_SORTER_PMASZ
|
||||
"SORTER_PMASZ=" CTIMEOPT_VAL(SQLITE_SORTER_PMASZ),
|
||||
#endif
|
||||
#if SQLITE_SOUNDEX
|
||||
"SOUNDEX",
|
||||
#endif
|
||||
#ifdef SQLITE_STAT4_SAMPLES
|
||||
"STAT4_SAMPLES=" CTIMEOPT_VAL(SQLITE_STAT4_SAMPLES),
|
||||
#endif
|
||||
#ifdef SQLITE_STMTJRNL_SPILL
|
||||
"STMTJRNL_SPILL=" CTIMEOPT_VAL(SQLITE_STMTJRNL_SPILL),
|
||||
#endif
|
||||
#if SQLITE_SUBSTR_COMPATIBILITY
|
||||
"SUBSTR_COMPATIBILITY",
|
||||
#endif
|
||||
#if SQLITE_SYSTEM_MALLOC
|
||||
"SYSTEM_MALLOC",
|
||||
#endif
|
||||
#if SQLITE_TCL
|
||||
"TCL",
|
||||
#endif
|
||||
#ifdef SQLITE_TEMP_STORE
|
||||
#if defined(SQLITE_TEMP_STORE) && !defined(SQLITE_TEMP_STORE_xc)
|
||||
"TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE),
|
||||
#endif
|
||||
#if SQLITE_TEST
|
||||
@@ -690,46 +394,64 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#endif
|
||||
#if defined(SQLITE_THREADSAFE)
|
||||
"THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
|
||||
#elif defined(THREADSAFE)
|
||||
"THREADSAFE=" CTIMEOPT_VAL(THREADSAFE),
|
||||
#else
|
||||
"THREADSAFE=1",
|
||||
#endif
|
||||
#if SQLITE_UNLINK_AFTER_CLOSE
|
||||
"UNLINK_AFTER_CLOSE",
|
||||
#endif
|
||||
#if SQLITE_UNTESTABLE
|
||||
"UNTESTABLE",
|
||||
#endif
|
||||
#if SQLITE_USER_AUTHENTICATION
|
||||
"USER_AUTHENTICATION",
|
||||
"UNTESTABLE"
|
||||
#endif
|
||||
#if SQLITE_USE_ALLOCA
|
||||
"USE_ALLOCA",
|
||||
#endif
|
||||
#if SQLITE_USE_FCNTL_TRACE
|
||||
"USE_FCNTL_TRACE",
|
||||
#endif
|
||||
#if SQLITE_USE_URI
|
||||
"USE_URI",
|
||||
#endif
|
||||
#if SQLITE_VDBE_COVERAGE
|
||||
"VDBE_COVERAGE",
|
||||
#if SQLITE_USER_AUTHENTICATION
|
||||
"USER_AUTHENTICATION",
|
||||
#endif
|
||||
#if SQLITE_WIN32_MALLOC
|
||||
"WIN32_MALLOC",
|
||||
#endif
|
||||
#if SQLITE_ZERO_MALLOC
|
||||
"ZERO_MALLOC",
|
||||
"ZERO_MALLOC"
|
||||
#endif
|
||||
/*
|
||||
** END CODE GENERATED BY tool/mkctime.tcl
|
||||
*/
|
||||
};
|
||||
|
||||
const char **sqlite3CompileOptions(int *pnOpt){
|
||||
*pnOpt = sizeof(sqlite3azCompileOpt) / sizeof(sqlite3azCompileOpt[0]);
|
||||
return (const char**)sqlite3azCompileOpt;
|
||||
/*
|
||||
** Given the name of a compile-time option, return true if that option
|
||||
** was used and false if not.
|
||||
**
|
||||
** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
|
||||
** is not required for a match.
|
||||
*/
|
||||
int sqlite3_compileoption_used(const char *zOptName){
|
||||
int i, n;
|
||||
|
||||
#if SQLITE_ENABLE_API_ARMOR
|
||||
if( zOptName==0 ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
|
||||
n = sqlite3Strlen30(zOptName);
|
||||
|
||||
/* Since ArraySize(azCompileOpt) is normally in single digits, a
|
||||
** linear search is adequate. No need for a binary search. */
|
||||
for(i=0; i<ArraySize(azCompileOpt); i++){
|
||||
if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
|
||||
&& sqlite3IsIdChar((unsigned char)azCompileOpt[i][n])==0
|
||||
){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the N-th compile-time option string. If N is out of range,
|
||||
** return a NULL pointer.
|
||||
*/
|
||||
const char *sqlite3_compileoption_get(int N){
|
||||
if( N>=0 && N<ArraySize(azCompileOpt) ){
|
||||
return azCompileOpt[N];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
|
||||
|
||||
+1
-3
@@ -423,10 +423,8 @@ static void computeYMD(DateTime *p){
|
||||
p->Y = 2000;
|
||||
p->M = 1;
|
||||
p->D = 1;
|
||||
}else if( !validJulianDay(p->iJD) ){
|
||||
datetimeError(p);
|
||||
return;
|
||||
}else{
|
||||
assert( validJulianDay(p->iJD) );
|
||||
Z = (int)((p->iJD + 43200000)/86400000);
|
||||
A = (int)((Z - 1867216.25)/36524.25);
|
||||
A = Z + 1 + A - (A/4);
|
||||
|
||||
+2
-9
@@ -350,14 +350,7 @@ void sqlite3DeleteFrom(
|
||||
/* Special case: A DELETE without a WHERE clause deletes everything.
|
||||
** It is easier just to erase the whole table. Prior to version 3.6.5,
|
||||
** this optimization caused the row change count (the value returned by
|
||||
** API function sqlite3_count_changes) to be set incorrectly.
|
||||
**
|
||||
** The "rcauth==SQLITE_OK" terms is the
|
||||
** IMPLEMENTATION-OF: R-17228-37124 If the action code is SQLITE_DELETE and
|
||||
** the callback returns SQLITE_IGNORE then the DELETE operation proceeds but
|
||||
** the truncate optimization is disabled and all rows are deleted
|
||||
** individually.
|
||||
*/
|
||||
** API function sqlite3_count_changes) to be set incorrectly. */
|
||||
if( rcauth==SQLITE_OK
|
||||
&& pWhere==0
|
||||
&& !bComplex
|
||||
@@ -459,7 +452,7 @@ void sqlite3DeleteFrom(
|
||||
sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEphCur, iKey, iPk, nPk);
|
||||
}else{
|
||||
/* Add the rowid of the row to be deleted to the RowSet */
|
||||
nKey = 1; /* OP_DeferredSeek always uses a single rowid */
|
||||
nKey = 1; /* OP_Seek always uses a single rowid */
|
||||
sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);
|
||||
}
|
||||
}
|
||||
|
||||
+58
-138
@@ -58,7 +58,7 @@ char sqlite3ExprAffinity(Expr *pExpr){
|
||||
return sqlite3AffinityType(pExpr->u.zToken, 0);
|
||||
}
|
||||
#endif
|
||||
if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){
|
||||
if( op==TK_AGG_COLUMN || op==TK_COLUMN ){
|
||||
return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
|
||||
}
|
||||
if( op==TK_SELECT_COLUMN ){
|
||||
@@ -352,6 +352,7 @@ int sqlite3ExprVectorSize(Expr *pExpr){
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_SUBQUERY
|
||||
/*
|
||||
** Return a pointer to a subexpression of pVector that is the i-th
|
||||
** column of the vector (numbered starting with 0). The caller must
|
||||
@@ -379,7 +380,9 @@ Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){
|
||||
}
|
||||
return pVector;
|
||||
}
|
||||
#endif /* !defined(SQLITE_OMIT_SUBQUERY) */
|
||||
|
||||
#ifndef SQLITE_OMIT_SUBQUERY
|
||||
/*
|
||||
** Compute and return a new Expr object which when passed to
|
||||
** sqlite3ExprCode() will generate all necessary code to compute
|
||||
@@ -437,6 +440,7 @@ Expr *sqlite3ExprForVectorField(
|
||||
}
|
||||
return pRet;
|
||||
}
|
||||
#endif /* !define(SQLITE_OMIT_SUBQUERY) */
|
||||
|
||||
/*
|
||||
** If expression pExpr is of type TK_SELECT, generate code to evaluate
|
||||
@@ -952,7 +956,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){
|
||||
z = pExpr->u.zToken;
|
||||
assert( z!=0 );
|
||||
assert( z[0]!=0 );
|
||||
assert( n==(u32)sqlite3Strlen30(z) );
|
||||
assert( n==sqlite3Strlen30(z) );
|
||||
if( z[1]==0 ){
|
||||
/* Wildcard of the form "?". Assign the next variable number */
|
||||
assert( z[0]=='?' );
|
||||
@@ -1034,7 +1038,7 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
|
||||
}
|
||||
if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
|
||||
if( !ExprHasProperty(p, EP_Static) ){
|
||||
sqlite3DbFreeNN(db, p);
|
||||
sqlite3DbFree(db, p);
|
||||
}
|
||||
}
|
||||
void sqlite3ExprDelete(sqlite3 *db, Expr *p){
|
||||
@@ -1301,11 +1305,15 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
|
||||
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, sizeof(*pNew) );
|
||||
if( pNew==0 ) return 0;
|
||||
pNew->nAlloc = pNew->nExpr = p->nExpr;
|
||||
pItem = pNew->a;
|
||||
pNew->nExpr = i = p->nExpr;
|
||||
if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; i<p->nExpr; i+=i){}
|
||||
pNew->a = pItem = sqlite3DbMallocRawNN(db, i*sizeof(p->a[0]) );
|
||||
if( pItem==0 ){
|
||||
sqlite3DbFree(db, pNew);
|
||||
return 0;
|
||||
}
|
||||
pOldItem = p->a;
|
||||
for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
|
||||
Expr *pOldExpr = pOldItem->pExpr;
|
||||
@@ -1396,7 +1404,7 @@ IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){
|
||||
pNew->nId = p->nId;
|
||||
pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) );
|
||||
if( pNew->a==0 ){
|
||||
sqlite3DbFreeNN(db, pNew);
|
||||
sqlite3DbFree(db, pNew);
|
||||
return 0;
|
||||
}
|
||||
/* Note that because the size of the allocation for p->a[] is not
|
||||
@@ -1467,7 +1475,6 @@ ExprList *sqlite3ExprListAppend(
|
||||
ExprList *pList, /* List to which to append. Might be NULL */
|
||||
Expr *pExpr /* Expression to be appended. Might be NULL */
|
||||
){
|
||||
struct ExprList_item *pItem;
|
||||
sqlite3 *db = pParse->db;
|
||||
assert( db!=0 );
|
||||
if( pList==0 ){
|
||||
@@ -1476,22 +1483,23 @@ ExprList *sqlite3ExprListAppend(
|
||||
goto no_mem;
|
||||
}
|
||||
pList->nExpr = 0;
|
||||
pList->nAlloc = 1;
|
||||
}else if( pList->nExpr==pList->nAlloc ){
|
||||
ExprList *pNew;
|
||||
pNew = sqlite3DbRealloc(db, pList,
|
||||
sizeof(*pList)+(2*pList->nAlloc - 1)*sizeof(pList->a[0]));
|
||||
if( pNew==0 ){
|
||||
pList->a = sqlite3DbMallocRawNN(db, sizeof(pList->a[0]));
|
||||
if( pList->a==0 ) goto no_mem;
|
||||
}else if( (pList->nExpr & (pList->nExpr-1))==0 ){
|
||||
struct ExprList_item *a;
|
||||
assert( pList->nExpr>0 );
|
||||
a = sqlite3DbRealloc(db, pList->a, pList->nExpr*2*sizeof(pList->a[0]));
|
||||
if( a==0 ){
|
||||
goto no_mem;
|
||||
}
|
||||
pList = pNew;
|
||||
pList->nAlloc *= 2;
|
||||
pList->a = a;
|
||||
}
|
||||
assert( pList->a!=0 );
|
||||
if( 1 ){
|
||||
struct ExprList_item *pItem = &pList->a[pList->nExpr++];
|
||||
memset(pItem, 0, sizeof(*pItem));
|
||||
pItem->pExpr = pExpr;
|
||||
}
|
||||
pItem = &pList->a[pList->nExpr++];
|
||||
assert( offsetof(struct ExprList_item,zName)==sizeof(pItem->pExpr) );
|
||||
assert( offsetof(struct ExprList_item,pExpr)==0 );
|
||||
memset(&pItem->zName,0,sizeof(*pItem)-offsetof(struct ExprList_item,zName));
|
||||
pItem->pExpr = pExpr;
|
||||
return pList;
|
||||
|
||||
no_mem:
|
||||
@@ -1548,19 +1556,20 @@ ExprList *sqlite3ExprListAppendVector(
|
||||
}
|
||||
}
|
||||
|
||||
if( !db->mallocFailed && pExpr->op==TK_SELECT && ALWAYS(pList!=0) ){
|
||||
Expr *pFirst = pList->a[iFirst].pExpr;
|
||||
assert( pFirst!=0 );
|
||||
assert( pFirst->op==TK_SELECT_COLUMN );
|
||||
if( pExpr->op==TK_SELECT ){
|
||||
if( pList && pList->a[iFirst].pExpr ){
|
||||
Expr *pFirst = pList->a[iFirst].pExpr;
|
||||
assert( pFirst->op==TK_SELECT_COLUMN );
|
||||
|
||||
/* Store the SELECT statement in pRight so it will be deleted when
|
||||
** sqlite3ExprListDelete() is called */
|
||||
pFirst->pRight = pExpr;
|
||||
pExpr = 0;
|
||||
/* Store the SELECT statement in pRight so it will be deleted when
|
||||
** sqlite3ExprListDelete() is called */
|
||||
pFirst->pRight = pExpr;
|
||||
pExpr = 0;
|
||||
|
||||
/* Remember the size of the LHS in iTable so that we can check that
|
||||
** the RHS and LHS sizes match during code generation. */
|
||||
pFirst->iTable = pColumns->nId;
|
||||
/* Remember the size of the LHS in iTable so that we can check that
|
||||
** the RHS and LHS sizes match during code generation. */
|
||||
pFirst->iTable = pColumns->nId;
|
||||
}
|
||||
}
|
||||
|
||||
vector_append_error:
|
||||
@@ -1654,16 +1663,16 @@ void sqlite3ExprListCheckLength(
|
||||
** Delete an entire expression list.
|
||||
*/
|
||||
static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){
|
||||
int i = pList->nExpr;
|
||||
struct ExprList_item *pItem = pList->a;
|
||||
assert( pList->nExpr>0 );
|
||||
do{
|
||||
int i;
|
||||
struct ExprList_item *pItem;
|
||||
assert( pList->a!=0 || pList->nExpr==0 );
|
||||
for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
|
||||
sqlite3ExprDelete(db, pItem->pExpr);
|
||||
sqlite3DbFree(db, pItem->zName);
|
||||
sqlite3DbFree(db, pItem->zSpan);
|
||||
pItem++;
|
||||
}while( --i>0 );
|
||||
sqlite3DbFreeNN(db, pList);
|
||||
}
|
||||
sqlite3DbFree(db, pList->a);
|
||||
sqlite3DbFree(db, pList);
|
||||
}
|
||||
void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
|
||||
if( pList ) exprListDeleteNN(db, pList);
|
||||
@@ -1742,12 +1751,10 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
|
||||
testcase( pExpr->op==TK_AGG_COLUMN );
|
||||
if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){
|
||||
return WRC_Continue;
|
||||
}else{
|
||||
pWalker->eCode = 0;
|
||||
return WRC_Abort;
|
||||
}
|
||||
/* Fall through */
|
||||
case TK_IF_NULL_ROW:
|
||||
testcase( pExpr->op==TK_IF_NULL_ROW );
|
||||
pWalker->eCode = 0;
|
||||
return WRC_Abort;
|
||||
case TK_VARIABLE:
|
||||
if( pWalker->eCode==5 ){
|
||||
/* Silently convert bound parameters that appear inside of CREATE
|
||||
@@ -1774,12 +1781,10 @@ static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){
|
||||
}
|
||||
static int exprIsConst(Expr *p, int initFlag, int iCur){
|
||||
Walker w;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.eCode = initFlag;
|
||||
w.xExprCallback = exprNodeIsConstant;
|
||||
w.xSelectCallback = selectNodeIsConstant;
|
||||
#ifdef SQLITE_DEBUG
|
||||
w.xSelectCallback2 = sqlite3SelectWalkAssert2;
|
||||
#endif
|
||||
w.u.iCur = iCur;
|
||||
sqlite3WalkExpr(&w, p);
|
||||
return w.eCode;
|
||||
@@ -1817,65 +1822,6 @@ int sqlite3ExprIsTableConstant(Expr *p, int iCur){
|
||||
return exprIsConst(p, 3, iCur);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy().
|
||||
*/
|
||||
static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){
|
||||
ExprList *pGroupBy = pWalker->u.pGroupBy;
|
||||
int i;
|
||||
|
||||
/* Check if pExpr is identical to any GROUP BY term. If so, consider
|
||||
** it constant. */
|
||||
for(i=0; i<pGroupBy->nExpr; i++){
|
||||
Expr *p = pGroupBy->a[i].pExpr;
|
||||
if( sqlite3ExprCompare(pExpr, p, -1)<2 ){
|
||||
CollSeq *pColl = sqlite3ExprCollSeq(pWalker->pParse, p);
|
||||
if( pColl==0 || sqlite3_stricmp("BINARY", pColl->zName)==0 ){
|
||||
return WRC_Prune;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if pExpr is a sub-select. If so, consider it variable. */
|
||||
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
|
||||
pWalker->eCode = 0;
|
||||
return WRC_Abort;
|
||||
}
|
||||
|
||||
return exprNodeIsConstant(pWalker, pExpr);
|
||||
}
|
||||
|
||||
/*
|
||||
** Walk the expression tree passed as the first argument. Return non-zero
|
||||
** if the expression consists entirely of constants or copies of terms
|
||||
** in pGroupBy that sort with the BINARY collation sequence.
|
||||
**
|
||||
** This routine is used to determine if a term of the HAVING clause can
|
||||
** be promoted into the WHERE clause. In order for such a promotion to work,
|
||||
** the value of the HAVING clause term must be the same for all members of
|
||||
** a "group". The requirement that the GROUP BY term must be BINARY
|
||||
** assumes that no other collating sequence will have a finer-grained
|
||||
** grouping than binary. In other words (A=B COLLATE binary) implies
|
||||
** A=B in every other collating sequence. The requirement that the
|
||||
** GROUP BY be BINARY is stricter than necessary. It would also work
|
||||
** to promote HAVING clauses that use the same alternative collating
|
||||
** sequence as the GROUP BY term, but that is much harder to check,
|
||||
** alternative collating sequences are uncommon, and this is only an
|
||||
** optimization, so we take the easy way out and simply require the
|
||||
** GROUP BY to use the BINARY collating sequence.
|
||||
*/
|
||||
int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){
|
||||
Walker w;
|
||||
w.eCode = 1;
|
||||
w.xExprCallback = exprNodeIsConstantOrGroupBy;
|
||||
w.xSelectCallback = 0;
|
||||
w.u.pGroupBy = pGroupBy;
|
||||
w.pParse = pParse;
|
||||
sqlite3WalkExpr(&w, p);
|
||||
return w.eCode;
|
||||
}
|
||||
|
||||
/*
|
||||
** Walk an expression tree. Return non-zero if the expression is constant
|
||||
** or a function call with constant arguments. Return and 0 if there
|
||||
@@ -1897,12 +1843,10 @@ int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
|
||||
*/
|
||||
int sqlite3ExprContainsSubquery(Expr *p){
|
||||
Walker w;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.eCode = 1;
|
||||
w.xExprCallback = sqlite3ExprWalkNoop;
|
||||
w.xSelectCallback = selectNodeIsConstant;
|
||||
#ifdef SQLITE_DEBUG
|
||||
w.xSelectCallback2 = sqlite3SelectWalkAssert2;
|
||||
#endif
|
||||
sqlite3WalkExpr(&w, p);
|
||||
return w.eCode==0;
|
||||
}
|
||||
@@ -1916,7 +1860,6 @@ int sqlite3ExprContainsSubquery(Expr *p){
|
||||
*/
|
||||
int sqlite3ExprIsInteger(Expr *p, int *pValue){
|
||||
int rc = 0;
|
||||
if( p==0 ) return 0; /* Can only happen following on OOM */
|
||||
|
||||
/* If an expression is an integer literal that fits in a signed 32-bit
|
||||
** integer, then the EP_IntValue flag will have already been set */
|
||||
@@ -2589,6 +2532,7 @@ int sqlite3CodeSubselect(
|
||||
int i;
|
||||
sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
|
||||
dest.zAffSdst = exprINAffinity(pParse, pExpr);
|
||||
assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
|
||||
pSelect->iLimit = 0;
|
||||
testcase( pSelect->selFlags & SF_Distinct );
|
||||
testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
|
||||
@@ -3255,10 +3199,6 @@ void sqlite3ExprCodeGetColumnOfTable(
|
||||
int iCol, /* Index of the column to extract */
|
||||
int regOut /* Extract the value into this register */
|
||||
){
|
||||
if( pTab==0 ){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
|
||||
return;
|
||||
}
|
||||
if( iCol<0 || iCol==pTab->iPKey ){
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
|
||||
}else{
|
||||
@@ -3415,11 +3355,7 @@ static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){
|
||||
}else{
|
||||
*piFreeable = 0;
|
||||
if( p->op==TK_SELECT ){
|
||||
#if SQLITE_OMIT_SUBQUERY
|
||||
iResult = 0;
|
||||
#else
|
||||
iResult = sqlite3CodeSubselect(pParse, p, 0, 0);
|
||||
#endif
|
||||
}else{
|
||||
int i;
|
||||
iResult = pParse->nMem+1;
|
||||
@@ -3956,17 +3892,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
** Form A:
|
||||
** CASE x WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END
|
||||
@@ -4907,8 +4832,8 @@ int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
|
||||
Walker w;
|
||||
struct SrcCount cnt;
|
||||
assert( pExpr->op==TK_AGG_FUNCTION );
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.xExprCallback = exprSrcCount;
|
||||
w.xSelectCallback = 0;
|
||||
w.u.pSrcCount = &cnt;
|
||||
cnt.pSrc = pSrcList;
|
||||
cnt.nThis = 0;
|
||||
@@ -5080,14 +5005,10 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
|
||||
return WRC_Continue;
|
||||
}
|
||||
static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
|
||||
UNUSED_PARAMETER(pWalker);
|
||||
UNUSED_PARAMETER(pSelect);
|
||||
pWalker->walkerDepth++;
|
||||
return WRC_Continue;
|
||||
}
|
||||
static void analyzeAggregatesInSelectEnd(Walker *pWalker, Select *pSelect){
|
||||
UNUSED_PARAMETER(pSelect);
|
||||
pWalker->walkerDepth--;
|
||||
}
|
||||
|
||||
/*
|
||||
** Analyze the pExpr expression looking for aggregate functions and
|
||||
@@ -5100,10 +5021,9 @@ static void analyzeAggregatesInSelectEnd(Walker *pWalker, Select *pSelect){
|
||||
*/
|
||||
void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
|
||||
Walker w;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.xExprCallback = analyzeAggregate;
|
||||
w.xSelectCallback = analyzeAggregatesInSelect;
|
||||
w.xSelectCallback2 = analyzeAggregatesInSelectEnd;
|
||||
w.walkerDepth = 0;
|
||||
w.u.pNC = pNC;
|
||||
assert( pNC->pSrcList!=0 );
|
||||
sqlite3WalkExpr(&w, pExpr);
|
||||
|
||||
+10
-27
@@ -633,12 +633,10 @@ static void fkScanChildren(
|
||||
/* Create VDBE to loop through the entries in pSrc that match the WHERE
|
||||
** clause. For each row found, increment either the deferred or immediate
|
||||
** foreign key constraint counter. */
|
||||
if( pParse->nErr==0 ){
|
||||
pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
|
||||
if( pWInfo ){
|
||||
sqlite3WhereEnd(pWInfo);
|
||||
}
|
||||
pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
|
||||
if( pWInfo ){
|
||||
sqlite3WhereEnd(pWInfo);
|
||||
}
|
||||
|
||||
/* Clean up the WHERE clause constructed above. */
|
||||
@@ -1089,16 +1087,8 @@ u32 sqlite3FkOldmask(
|
||||
** UPDATE statement modifies the rowid fields of the table.
|
||||
**
|
||||
** If any foreign key processing will be required, this function returns
|
||||
** non-zero. If there is no foreign key related processing, this function
|
||||
** returns zero.
|
||||
**
|
||||
** For an UPDATE, this function returns 2 if:
|
||||
**
|
||||
** * There are any FKs for which pTab is the child and the parent table, or
|
||||
** * the UPDATE modifies one or more parent keys for which the action is
|
||||
** not "NO ACTION" (i.e. is CASCADE, SET DEFAULT or SET NULL).
|
||||
**
|
||||
** Or, assuming some other foreign key processing is required, 1.
|
||||
** true. If there is no foreign key related processing, this function
|
||||
** returns false.
|
||||
*/
|
||||
int sqlite3FkRequired(
|
||||
Parse *pParse, /* Parse context */
|
||||
@@ -1106,13 +1096,12 @@ int sqlite3FkRequired(
|
||||
int *aChange, /* Non-NULL for UPDATE operations */
|
||||
int chngRowid /* True for UPDATE that affects rowid */
|
||||
){
|
||||
int eRet = 0;
|
||||
if( pParse->db->flags&SQLITE_ForeignKeys ){
|
||||
if( !aChange ){
|
||||
/* A DELETE operation. Foreign key processing is required if the
|
||||
** table in question is either the child or parent table for any
|
||||
** foreign key constraint. */
|
||||
eRet = (sqlite3FkReferences(pTab) || pTab->pFKey);
|
||||
return (sqlite3FkReferences(pTab) || pTab->pFKey);
|
||||
}else{
|
||||
/* This is an UPDATE. Foreign key processing is only required if the
|
||||
** operation modifies one or more child or parent key columns. */
|
||||
@@ -1120,22 +1109,16 @@ int sqlite3FkRequired(
|
||||
|
||||
/* Check if any child key columns are being modified. */
|
||||
for(p=pTab->pFKey; p; p=p->pNextFrom){
|
||||
if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) return 2;
|
||||
if( fkChildIsModified(pTab, p, aChange, chngRowid) ){
|
||||
eRet = 1;
|
||||
}
|
||||
if( fkChildIsModified(pTab, p, aChange, chngRowid) ) return 1;
|
||||
}
|
||||
|
||||
/* Check if any parent key columns are being modified. */
|
||||
for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
|
||||
if( fkParentIsModified(pTab, p, aChange, chngRowid) ){
|
||||
if( p->aAction[1]!=OE_None ) return 2;
|
||||
eRet = 1;
|
||||
}
|
||||
if( fkParentIsModified(pTab, p, aChange, chngRowid) ) return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return eRet;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+3
-1
@@ -204,13 +204,15 @@ static void instrFunc(
|
||||
if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){
|
||||
zHaystack = sqlite3_value_blob(argv[0]);
|
||||
zNeedle = sqlite3_value_blob(argv[1]);
|
||||
assert( zNeedle!=0 );
|
||||
assert( zHaystack!=0 || nHaystack==0 );
|
||||
isText = 0;
|
||||
}else{
|
||||
zHaystack = sqlite3_value_text(argv[0]);
|
||||
zNeedle = sqlite3_value_text(argv[1]);
|
||||
isText = 1;
|
||||
if( zHaystack==0 || zNeedle==0 ) return;
|
||||
}
|
||||
if( zNeedle==0 || (nHaystack && zHaystack==0) ) return;
|
||||
while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){
|
||||
N++;
|
||||
do{
|
||||
|
||||
+1
-8
@@ -137,16 +137,9 @@ const unsigned char sqlite3CtypeMap[256] = {
|
||||
** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
|
||||
** disabled. The default value may be changed by compiling with the
|
||||
** SQLITE_USE_URI symbol defined.
|
||||
**
|
||||
** URI filenames are enabled by default if SQLITE_HAS_CODEC is
|
||||
** enabled.
|
||||
*/
|
||||
#ifndef SQLITE_USE_URI
|
||||
# ifdef SQLITE_HAS_CODEC
|
||||
# define SQLITE_USE_URI 1
|
||||
# else
|
||||
# define SQLITE_USE_URI 0
|
||||
# endif
|
||||
# define SQLITE_USE_URI 0
|
||||
#endif
|
||||
|
||||
/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
|
||||
|
||||
+3
-1
@@ -521,10 +521,10 @@ void sqlite3Insert(
|
||||
#endif
|
||||
|
||||
db = pParse->db;
|
||||
memset(&dest, 0, sizeof(dest));
|
||||
if( pParse->nErr || db->mallocFailed ){
|
||||
goto insert_cleanup;
|
||||
}
|
||||
dest.iSDParm = 0; /* Suppress a harmless compiler warning */
|
||||
|
||||
/* If the Select object is really just a simple VALUES() list with a
|
||||
** single row (the common case) then keep that one row of values
|
||||
@@ -2227,6 +2227,8 @@ static int xferOptimization(
|
||||
** sorted order. */
|
||||
for(i=0; i<pSrcIdx->nColumn; i++){
|
||||
const char *zColl = pSrcIdx->azColl[i];
|
||||
assert( sqlite3_stricmp(sqlite3StrBINARY, zColl)!=0
|
||||
|| sqlite3StrBINARY==zColl );
|
||||
if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break;
|
||||
}
|
||||
if( i==pSrcIdx->nColumn ){
|
||||
|
||||
+1
-3
@@ -421,9 +421,7 @@ static const sqlite3_api_routines sqlite3Apis = {
|
||||
sqlite3_system_errno,
|
||||
/* Version 3.14.0 and later */
|
||||
sqlite3_trace_v2,
|
||||
sqlite3_expanded_sql,
|
||||
/* Version 3.18.0 and later */
|
||||
sqlite3_set_last_insert_rowid
|
||||
sqlite3_expanded_sql
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+7
-68
@@ -867,7 +867,6 @@ static int binCollFunc(
|
||||
/* EVIDENCE-OF: R-65033-28449 The built-in BINARY collation compares
|
||||
** strings byte by byte using the memcmp() function from the standard C
|
||||
** library. */
|
||||
assert( pKey1 && pKey2 );
|
||||
rc = memcmp(pKey1, pKey2, n);
|
||||
if( rc==0 ){
|
||||
if( padFlag
|
||||
@@ -3096,18 +3095,16 @@ opendb_out:
|
||||
#endif
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
if( rc==SQLITE_OK ){
|
||||
const char *zKey;
|
||||
if( (zKey = sqlite3_uri_parameter(zOpen, "hexkey"))!=0 && zKey[0] ){
|
||||
const char *zHexKey = sqlite3_uri_parameter(zOpen, "hexkey");
|
||||
if( zHexKey && zHexKey[0] ){
|
||||
u8 iByte;
|
||||
int i;
|
||||
char zDecoded[40];
|
||||
for(i=0, iByte=0; i<sizeof(zDecoded)*2 && sqlite3Isxdigit(zKey[i]); i++){
|
||||
iByte = (iByte<<4) + sqlite3HexToInt(zKey[i]);
|
||||
if( (i&1)!=0 ) zDecoded[i/2] = iByte;
|
||||
char zKey[40];
|
||||
for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zHexKey[i]); i++){
|
||||
iByte = (iByte<<4) + sqlite3HexToInt(zHexKey[i]);
|
||||
if( (i&1)!=0 ) zKey[i/2] = iByte;
|
||||
}
|
||||
sqlite3_key_v2(db, 0, zDecoded, i/2);
|
||||
}else if( (zKey = sqlite3_uri_parameter(zOpen, "key"))!=0 ){
|
||||
sqlite3_key_v2(db, 0, zKey, sqlite3Strlen30(zKey));
|
||||
sqlite3_key_v2(db, 0, zKey, i/2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -3338,12 +3335,6 @@ int sqlite3CantopenError(int lineno){
|
||||
return reportError(SQLITE_CANTOPEN, lineno, "cannot open file");
|
||||
}
|
||||
#ifdef SQLITE_DEBUG
|
||||
int sqlite3CorruptPgnoError(int lineno, Pgno pgno){
|
||||
char zMsg[100];
|
||||
sqlite3_snprintf(sizeof(zMsg), zMsg, "database corruption page %d", pgno);
|
||||
testcase( sqlite3GlobalConfig.xLog!=0 );
|
||||
return reportError(SQLITE_CORRUPT, lineno, zMsg);
|
||||
}
|
||||
int sqlite3NomemError(int lineno){
|
||||
testcase( sqlite3GlobalConfig.xLog!=0 );
|
||||
return reportError(SQLITE_NOMEM, lineno, "OOM");
|
||||
@@ -4102,55 +4093,3 @@ void sqlite3_snapshot_free(sqlite3_snapshot *pSnapshot){
|
||||
sqlite3_free(pSnapshot);
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_SNAPSHOT */
|
||||
|
||||
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
|
||||
/*
|
||||
** Given the name of a compile-time option, return true if that option
|
||||
** was used and false if not.
|
||||
**
|
||||
** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
|
||||
** is not required for a match.
|
||||
*/
|
||||
int sqlite3_compileoption_used(const char *zOptName){
|
||||
int i, n;
|
||||
int nOpt;
|
||||
const char **azCompileOpt;
|
||||
|
||||
#if SQLITE_ENABLE_API_ARMOR
|
||||
if( zOptName==0 ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
azCompileOpt = sqlite3CompileOptions(&nOpt);
|
||||
|
||||
if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
|
||||
n = sqlite3Strlen30(zOptName);
|
||||
|
||||
/* Since nOpt is normally in single digits, a linear search is
|
||||
** adequate. No need for a binary search. */
|
||||
for(i=0; i<nOpt; i++){
|
||||
if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
|
||||
&& sqlite3IsIdChar((unsigned char)azCompileOpt[i][n])==0
|
||||
){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the N-th compile-time option string. If N is out of range,
|
||||
** return a NULL pointer.
|
||||
*/
|
||||
const char *sqlite3_compileoption_get(int N){
|
||||
int nOpt;
|
||||
const char **azCompileOpt;
|
||||
azCompileOpt = sqlite3CompileOptions(&nOpt);
|
||||
if( N>=0 && N<nOpt ){
|
||||
return azCompileOpt[N];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
|
||||
|
||||
+3
-15
@@ -230,13 +230,6 @@ static void mallocWithAlarm(int n, void **pp){
|
||||
** following xRoundup() call. */
|
||||
nFull = sqlite3GlobalConfig.m.xRoundup(n);
|
||||
|
||||
#ifdef SQLITE_MAX_MEMORY
|
||||
if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nFull>SQLITE_MAX_MEMORY ){
|
||||
*pp = 0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
|
||||
if( mem0.alarmThreshold>0 ){
|
||||
sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
|
||||
@@ -474,12 +467,11 @@ static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){
|
||||
|
||||
/*
|
||||
** Free memory that might be associated with a particular database
|
||||
** connection. Calling sqlite3DbFree(D,X) for X==0 is a harmless no-op.
|
||||
** The sqlite3DbFreeNN(D,X) version requires that X be non-NULL.
|
||||
** connection.
|
||||
*/
|
||||
void sqlite3DbFreeNN(sqlite3 *db, void *p){
|
||||
void sqlite3DbFree(sqlite3 *db, void *p){
|
||||
assert( db==0 || sqlite3_mutex_held(db->mutex) );
|
||||
assert( p!=0 );
|
||||
if( p==0 ) return;
|
||||
if( db ){
|
||||
if( db->pnBytesFreed ){
|
||||
measureAllocationSize(db, p);
|
||||
@@ -503,10 +495,6 @@ void sqlite3DbFreeNN(sqlite3 *db, void *p){
|
||||
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
void sqlite3DbFree(sqlite3 *db, void *p){
|
||||
assert( db==0 || sqlite3_mutex_held(db->mutex) );
|
||||
if( p ) sqlite3DbFreeNN(db, p);
|
||||
}
|
||||
|
||||
/*
|
||||
** Change the size of an existing memory allocation
|
||||
|
||||
+12
-5
@@ -57,9 +57,7 @@
|
||||
*/
|
||||
#include <sys/sysctl.h>
|
||||
#include <malloc/malloc.h>
|
||||
#ifdef SQLITE_MIGHT_BE_SINGLE_CORE
|
||||
#include <libkern/OSAtomic.h>
|
||||
#endif /* SQLITE_MIGHT_BE_SINGLE_CORE */
|
||||
static malloc_zone_t* _sqliteZone_;
|
||||
#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x))
|
||||
#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x));
|
||||
@@ -252,10 +250,19 @@ static int sqlite3MemInit(void *NotUsed){
|
||||
}else{
|
||||
/* only 1 core, use our own zone to contention over global locks,
|
||||
** e.g. we have our own dedicated locks */
|
||||
_sqliteZone_ = malloc_create_zone(4096, 0);
|
||||
malloc_set_zone_name(_sqliteZone_, "Sqlite_Heap");
|
||||
bool success;
|
||||
malloc_zone_t* newzone = malloc_create_zone(4096, 0);
|
||||
malloc_set_zone_name(newzone, "Sqlite_Heap");
|
||||
do{
|
||||
success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone,
|
||||
(void * volatile *)&_sqliteZone_);
|
||||
}while(!_sqliteZone_);
|
||||
if( !success ){
|
||||
/* somebody registered a zone first */
|
||||
malloc_destroy_zone(newzone);
|
||||
}
|
||||
}
|
||||
#endif /* defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) */
|
||||
#endif
|
||||
UNUSED_PARAMETER(NotUsed);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
+30
-55
@@ -2258,11 +2258,6 @@ static int pager_playback_one_page(
|
||||
char *aData; /* Temporary storage for the page */
|
||||
sqlite3_file *jfd; /* The file descriptor for the journal file */
|
||||
int isSynced; /* True if journal page is synced */
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
/* The jrnlEnc flag is true if Journal pages should be passed through
|
||||
** the codec. It is false for pure in-memory journals. */
|
||||
const int jrnlEnc = (isMainJrnl || pPager->subjInMemory==0);
|
||||
#endif
|
||||
|
||||
assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */
|
||||
assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */
|
||||
@@ -2386,34 +2381,14 @@ static int pager_playback_one_page(
|
||||
i64 ofst = (pgno-1)*(i64)pPager->pageSize;
|
||||
testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 );
|
||||
assert( !pagerUseWal(pPager) );
|
||||
|
||||
/* Write the data read from the journal back into the database file.
|
||||
** This is usually safe even for an encrypted database - as the data
|
||||
** was encrypted before it was written to the journal file. The exception
|
||||
** is if the data was just read from an in-memory sub-journal. In that
|
||||
** case it must be encrypted here before it is copied into the database
|
||||
** file. */
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
if( !jrnlEnc ){
|
||||
CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData);
|
||||
rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
|
||||
CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
|
||||
}else
|
||||
#endif
|
||||
rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
|
||||
|
||||
if( pgno>pPager->dbFileSize ){
|
||||
pPager->dbFileSize = pgno;
|
||||
}
|
||||
if( pPager->pBackup ){
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
if( jrnlEnc ){
|
||||
CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
|
||||
sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
|
||||
CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT,aData);
|
||||
}else
|
||||
#endif
|
||||
CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
|
||||
sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
|
||||
CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData);
|
||||
}
|
||||
}else if( !isMainJrnl && pPg==0 ){
|
||||
/* If this is a rollback of a savepoint and data was not written to
|
||||
@@ -2465,9 +2440,7 @@ static int pager_playback_one_page(
|
||||
}
|
||||
|
||||
/* Decode the page just read from disk */
|
||||
#if SQLITE_HAS_CODEC
|
||||
if( jrnlEnc ){ CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT); }
|
||||
#endif
|
||||
CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT);
|
||||
sqlite3PcacheRelease(pPg);
|
||||
}
|
||||
return rc;
|
||||
@@ -3253,7 +3226,7 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){
|
||||
nPage = sqlite3WalDbsize(pPager->pWal);
|
||||
|
||||
/* If the number of pages in the database is not available from the
|
||||
** WAL sub-system, determine the page count based on the size of
|
||||
** WAL sub-system, determine the page counte based on the size of
|
||||
** the database file. If the size of the database file is not an
|
||||
** integer multiple of the page-size, round up the result.
|
||||
*/
|
||||
@@ -3304,21 +3277,23 @@ static int pagerOpenWalIfPresent(Pager *pPager){
|
||||
|
||||
if( !pPager->tempFile ){
|
||||
int isWal; /* True if WAL file exists */
|
||||
rc = sqlite3OsAccess(
|
||||
pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal
|
||||
);
|
||||
Pgno nPage; /* Size of the database file */
|
||||
|
||||
rc = pagerPagecount(pPager, &nPage);
|
||||
if( rc ) return rc;
|
||||
if( nPage==0 ){
|
||||
rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
|
||||
if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK;
|
||||
isWal = 0;
|
||||
}else{
|
||||
rc = sqlite3OsAccess(
|
||||
pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal
|
||||
);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
if( isWal ){
|
||||
Pgno nPage; /* Size of the database file */
|
||||
|
||||
rc = pagerPagecount(pPager, &nPage);
|
||||
if( rc ) return rc;
|
||||
if( nPage==0 ){
|
||||
rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
|
||||
}else{
|
||||
testcase( sqlite3PcachePagecount(pPager->pPCache)==0 );
|
||||
rc = sqlite3PagerOpenWal(pPager, 0);
|
||||
}
|
||||
testcase( sqlite3PcachePagecount(pPager->pPCache)==0 );
|
||||
rc = sqlite3PagerOpenWal(pPager, 0);
|
||||
}else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
|
||||
pPager->journalMode = PAGER_JOURNALMODE_DELETE;
|
||||
}
|
||||
@@ -4477,13 +4452,8 @@ static int subjournalPage(PgHdr *pPg){
|
||||
void *pData = pPg->pData;
|
||||
i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
|
||||
char *pData2;
|
||||
|
||||
#if SQLITE_HAS_CODEC
|
||||
if( !pPager->subjInMemory ){
|
||||
CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
|
||||
}else
|
||||
#endif
|
||||
pData2 = pData;
|
||||
|
||||
CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
|
||||
PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
|
||||
rc = write32bits(pPager->sjfd, offset, pPg->pgno);
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -5261,14 +5231,19 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
||||
** detected. The chance of an undetected change is so small that
|
||||
** it can be neglected.
|
||||
*/
|
||||
Pgno nPage = 0;
|
||||
char dbFileVers[sizeof(pPager->dbFileVers)];
|
||||
|
||||
IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
|
||||
rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( rc!=SQLITE_IOERR_SHORT_READ ){
|
||||
rc = pagerPagecount(pPager, &nPage);
|
||||
if( rc ) goto failed;
|
||||
|
||||
if( nPage>0 ){
|
||||
IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
|
||||
rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
|
||||
if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
|
||||
goto failed;
|
||||
}
|
||||
}else{
|
||||
memset(dbFileVers, 0, sizeof(dbFileVers));
|
||||
}
|
||||
|
||||
|
||||
+17
-17
@@ -193,23 +193,6 @@ columnlist ::= columnlist COMMA columnname carglist.
|
||||
columnlist ::= columnname carglist.
|
||||
columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);}
|
||||
|
||||
// The following directive causes tokens ABORT, AFTER, ASC, etc. to
|
||||
// fallback to ID if they will not parse as their original value.
|
||||
// This obviates the need for the "id" nonterminal.
|
||||
//
|
||||
%fallback ID
|
||||
ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW
|
||||
CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
|
||||
IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
|
||||
QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW
|
||||
ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
|
||||
%ifdef SQLITE_OMIT_COMPOUND_SELECT
|
||||
EXCEPT INTERSECT UNION
|
||||
%endif SQLITE_OMIT_COMPOUND_SELECT
|
||||
REINDEX RENAME CTIME_KW IF
|
||||
.
|
||||
%wildcard ANY.
|
||||
|
||||
// Define operator precedence early so that this is the first occurrence
|
||||
// of the operator tokens in the grammer. Keeping the operators together
|
||||
// causes them to be assigned integer values that are close together,
|
||||
@@ -239,6 +222,23 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);}
|
||||
//
|
||||
%token_class id ID|INDEXED.
|
||||
|
||||
// The following directive causes tokens ABORT, AFTER, ASC, etc. to
|
||||
// fallback to ID if they will not parse as their original value.
|
||||
// This obviates the need for the "id" nonterminal.
|
||||
//
|
||||
%fallback ID
|
||||
ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW
|
||||
CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
|
||||
IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
|
||||
QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW
|
||||
ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
|
||||
%ifdef SQLITE_OMIT_COMPOUND_SELECT
|
||||
EXCEPT INTERSECT UNION
|
||||
%endif SQLITE_OMIT_COMPOUND_SELECT
|
||||
REINDEX RENAME CTIME_KW IF
|
||||
.
|
||||
%wildcard ANY.
|
||||
|
||||
|
||||
// And "ids" is an identifer-or-string.
|
||||
//
|
||||
|
||||
+4
-4
@@ -26,7 +26,6 @@ struct PgHdr {
|
||||
sqlite3_pcache_page *pPage; /* Pcache object page handle */
|
||||
void *pData; /* Page data */
|
||||
void *pExtra; /* Extra content */
|
||||
PCache *pCache; /* PRIVATE: Cache that owns this page */
|
||||
PgHdr *pDirty; /* Transient list of dirty sorted by pgno */
|
||||
Pager *pPager; /* The pager this page is part of */
|
||||
Pgno pgno; /* Page number for this page */
|
||||
@@ -36,11 +35,12 @@ struct PgHdr {
|
||||
u16 flags; /* PGHDR flags defined below */
|
||||
|
||||
/**********************************************************************
|
||||
** Elements above, except pCache, are public. All that follow are
|
||||
** private to pcache.c and should not be accessed by other modules.
|
||||
** pCache is grouped with the public elements for efficiency.
|
||||
** Elements above are public. All that follows is private to pcache.c
|
||||
** and should not be accessed by other modules.
|
||||
*/
|
||||
i16 nRef; /* Number of users of this page */
|
||||
PCache *pCache; /* Cache that owns this page */
|
||||
|
||||
PgHdr *pDirtyNext; /* Next element in list of dirty pages */
|
||||
PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */
|
||||
};
|
||||
|
||||
+4
-3
@@ -285,7 +285,8 @@ static int pcache1InitBulk(PCache1 *pCache){
|
||||
sqlite3EndBenignMalloc();
|
||||
if( zBulk ){
|
||||
int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc;
|
||||
do{
|
||||
int i;
|
||||
for(i=0; i<nBulk; i++){
|
||||
PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage];
|
||||
pX->page.pBuf = zBulk;
|
||||
pX->page.pExtra = &pX[1];
|
||||
@@ -294,7 +295,7 @@ static int pcache1InitBulk(PCache1 *pCache){
|
||||
pX->pNext = pCache->pFree;
|
||||
pCache->pFree = pX;
|
||||
zBulk += pCache->szAlloc;
|
||||
}while( --nBulk );
|
||||
}
|
||||
}
|
||||
return pCache->pFree!=0;
|
||||
}
|
||||
@@ -1210,7 +1211,7 @@ int sqlite3PcacheReleaseMemory(int nReq){
|
||||
int nFree = 0;
|
||||
assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
|
||||
assert( sqlite3_mutex_notheld(pcache1.mutex) );
|
||||
if( sqlite3GlobalConfig.pPage==0 ){
|
||||
if( sqlite3GlobalConfig.nPage==0 ){
|
||||
PgHdr1 *p;
|
||||
pcache1EnterMutex(&pcache1.grp);
|
||||
while( (nReq<0 || nFree<nReq)
|
||||
|
||||
+43
-51
@@ -1015,7 +1015,7 @@ void sqlite3Pragma(
|
||||
if( !db->autoCommit ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"Safety level may not be changed inside a transaction");
|
||||
}else if( iDb!=1 ){
|
||||
}else{
|
||||
int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK;
|
||||
if( iLevel==0 ) iLevel = 1;
|
||||
pDb->safety_level = iLevel;
|
||||
@@ -1329,37 +1329,33 @@ void sqlite3Pragma(
|
||||
assert( x==0 );
|
||||
}
|
||||
addrOk = sqlite3VdbeMakeLabel(v);
|
||||
|
||||
/* Generate code to read the child key values into registers
|
||||
** regRow..regRow+n. If any of the child key values are NULL, this
|
||||
** row cannot cause an FK violation. Jump directly to addrOk in
|
||||
** this case. */
|
||||
for(j=0; j<pFK->nCol; j++){
|
||||
int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom;
|
||||
sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j);
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);
|
||||
}
|
||||
|
||||
/* Generate code to query the parent index for a matching parent
|
||||
** key. If a match is found, jump to addrOk. */
|
||||
if( pIdx ){
|
||||
sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
|
||||
sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
|
||||
sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
|
||||
VdbeCoverage(v);
|
||||
}else if( pParent ){
|
||||
int jmp = sqlite3VdbeCurrentAddr(v)+2;
|
||||
sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v);
|
||||
if( pParent && pIdx==0 ){
|
||||
int iKey = pFK->aCol[0].iFrom;
|
||||
assert( iKey>=0 && iKey<pTab->nCol );
|
||||
if( iKey!=pTab->iPKey ){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
|
||||
sqlite3ColumnDefault(v, pTab, iKey, regRow);
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v);
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
|
||||
}
|
||||
sqlite3VdbeAddOp3(v, OP_SeekRowid, i, 0, regRow); VdbeCoverage(v);
|
||||
sqlite3VdbeGoto(v, addrOk);
|
||||
assert( pFK->nCol==1 );
|
||||
}
|
||||
|
||||
/* Generate code to report an FK violation to the caller. */
|
||||
if( HasRowid(pTab) ){
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
|
||||
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, regResult+1);
|
||||
for(j=0; j<pFK->nCol; j++){
|
||||
sqlite3ExprCodeGetColumnOfTable(v, pTab, 0,
|
||||
aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j);
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);
|
||||
}
|
||||
if( pParent ){
|
||||
sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
|
||||
sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
|
||||
sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
|
||||
sqlite3VdbeMultiLoad(v, regResult+2, "si", pFK->zTo, i-1);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4);
|
||||
sqlite3VdbeResolveLabel(v, addrOk);
|
||||
@@ -1509,7 +1505,6 @@ void sqlite3Pragma(
|
||||
int iDataCur, iIdxCur;
|
||||
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)
|
||||
@@ -1545,28 +1540,25 @@ void sqlite3Pragma(
|
||||
}
|
||||
/* Verify CHECK constraints */
|
||||
if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
|
||||
ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0);
|
||||
if( db->mallocFailed==0 ){
|
||||
int addrCkFault = sqlite3VdbeMakeLabel(v);
|
||||
int addrCkOk = sqlite3VdbeMakeLabel(v);
|
||||
char *zErr;
|
||||
int k;
|
||||
pParse->iSelfTab = iDataCur;
|
||||
sqlite3ExprCachePush(pParse);
|
||||
for(k=pCheck->nExpr-1; k>0; k--){
|
||||
sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
|
||||
}
|
||||
sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk,
|
||||
SQLITE_JUMPIFNULL);
|
||||
sqlite3VdbeResolveLabel(v, addrCkFault);
|
||||
zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
|
||||
pTab->zName);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
||||
integrityCheckResultRow(v, 3);
|
||||
sqlite3VdbeResolveLabel(v, addrCkOk);
|
||||
sqlite3ExprCachePop(pParse);
|
||||
int addrCkFault = sqlite3VdbeMakeLabel(v);
|
||||
int addrCkOk = sqlite3VdbeMakeLabel(v);
|
||||
ExprList *pCheck = pTab->pCheck;
|
||||
char *zErr;
|
||||
int k;
|
||||
pParse->iSelfTab = iDataCur;
|
||||
sqlite3ExprCachePush(pParse);
|
||||
for(k=pCheck->nExpr-1; k>0; k--){
|
||||
sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
|
||||
}
|
||||
sqlite3ExprListDelete(db, pCheck);
|
||||
sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk,
|
||||
SQLITE_JUMPIFNULL);
|
||||
sqlite3VdbeResolveLabel(v, addrCkFault);
|
||||
zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
|
||||
pTab->zName);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
||||
integrityCheckResultRow(v, 3);
|
||||
sqlite3VdbeResolveLabel(v, addrCkOk);
|
||||
sqlite3ExprCachePop(pParse);
|
||||
}
|
||||
/* Validate index entries for the current row */
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; pIdx=pIdx->pNext, j++){
|
||||
|
||||
+4
-4
@@ -267,7 +267,7 @@ static const PragmaName aPragmaName[] = {
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
{/* zName: */ "foreign_key_check",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema,
|
||||
/* ColNames: */ 39, 4,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
@@ -354,7 +354,7 @@ static const PragmaName aPragmaName[] = {
|
||||
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
|
||||
{/* zName: */ "integrity_check",
|
||||
/* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
@@ -417,7 +417,7 @@ static const PragmaName aPragmaName[] = {
|
||||
#endif
|
||||
{/* zName: */ "optimize",
|
||||
/* ePragTyp: */ PragTyp_OPTIMIZE,
|
||||
/* ePragFlg: */ PragFlg_Result1|PragFlg_NeedSchema,
|
||||
/* ePragFlg: */ PragFlg_Result1,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
@@ -449,7 +449,7 @@ static const PragmaName aPragmaName[] = {
|
||||
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
|
||||
{/* zName: */ "quick_check",
|
||||
/* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
|
||||
+2
-3
@@ -400,13 +400,12 @@ void sqlite3VXPrintf(
|
||||
nOut = etBUFSIZE;
|
||||
zOut = buf;
|
||||
}else{
|
||||
u64 n = (u64)precision + 10 + precision/3;
|
||||
zOut = zExtra = sqlite3Malloc( n );
|
||||
nOut = precision + 10 + precision/3;
|
||||
zOut = zExtra = sqlite3Malloc( nOut );
|
||||
if( zOut==0 ){
|
||||
setStrAccumError(pAccum, STRACCUM_NOMEM);
|
||||
return;
|
||||
}
|
||||
nOut = (int)n;
|
||||
}
|
||||
bufpt = &zOut[nOut-1];
|
||||
if( xtype==etORDINAL ){
|
||||
|
||||
+18
-10
@@ -1430,29 +1430,37 @@ int sqlite3ResolveExprNames(
|
||||
u16 savedHasAgg;
|
||||
Walker w;
|
||||
|
||||
if( pExpr==0 ) return SQLITE_OK;
|
||||
if( pExpr==0 ) return 0;
|
||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||
{
|
||||
Parse *pParse = pNC->pParse;
|
||||
if( sqlite3ExprCheckHeight(pParse, pExpr->nHeight+pNC->pParse->nHeight) ){
|
||||
return 1;
|
||||
}
|
||||
pParse->nHeight += pExpr->nHeight;
|
||||
}
|
||||
#endif
|
||||
savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg);
|
||||
pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg);
|
||||
w.pParse = pNC->pParse;
|
||||
w.xExprCallback = resolveExprStep;
|
||||
w.xSelectCallback = resolveSelectStep;
|
||||
w.xSelectCallback2 = 0;
|
||||
w.walkerDepth = 0;
|
||||
w.eCode = 0;
|
||||
w.u.pNC = pNC;
|
||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||
w.pParse->nHeight += pExpr->nHeight;
|
||||
if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
#endif
|
||||
sqlite3WalkExpr(&w, pExpr);
|
||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||
w.pParse->nHeight -= pExpr->nHeight;
|
||||
pNC->pParse->nHeight -= pExpr->nHeight;
|
||||
#endif
|
||||
if( pNC->nErr>0 || w.pParse->nErr>0 ){
|
||||
ExprSetProperty(pExpr, EP_Error);
|
||||
}
|
||||
if( pNC->ncFlags & NC_HasAgg ){
|
||||
ExprSetProperty(pExpr, EP_Agg);
|
||||
}
|
||||
pNC->ncFlags |= savedHasAgg;
|
||||
return pNC->nErr>0 || w.pParse->nErr>0;
|
||||
return ExprHasProperty(pExpr, EP_Error);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1493,9 +1501,9 @@ void sqlite3ResolveSelectNames(
|
||||
Walker w;
|
||||
|
||||
assert( p!=0 );
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.xExprCallback = resolveExprStep;
|
||||
w.xSelectCallback = resolveSelectStep;
|
||||
w.xSelectCallback2 = 0;
|
||||
w.pParse = pParse;
|
||||
w.u.pNC = pOuterNC;
|
||||
sqlite3WalkSelect(&w, p);
|
||||
|
||||
+93
-308
@@ -76,7 +76,7 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){
|
||||
sqlite3ExprDelete(db, p->pLimit);
|
||||
sqlite3ExprDelete(db, p->pOffset);
|
||||
if( p->pWith ) sqlite3WithDelete(db, p->pWith);
|
||||
if( bFree ) sqlite3DbFreeNN(db, p);
|
||||
if( bFree ) sqlite3DbFree(db, p);
|
||||
p = pPrior;
|
||||
bFree = 1;
|
||||
}
|
||||
@@ -112,13 +112,14 @@ Select *sqlite3SelectNew(
|
||||
){
|
||||
Select *pNew;
|
||||
Select standin;
|
||||
pNew = sqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) );
|
||||
sqlite3 *db = pParse->db;
|
||||
pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
|
||||
if( pNew==0 ){
|
||||
assert( pParse->db->mallocFailed );
|
||||
assert( db->mallocFailed );
|
||||
pNew = &standin;
|
||||
}
|
||||
if( pEList==0 ){
|
||||
pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(pParse->db,TK_ASTERISK,0));
|
||||
pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ASTERISK,0));
|
||||
}
|
||||
pNew->pEList = pEList;
|
||||
pNew->op = TK_SELECT;
|
||||
@@ -131,7 +132,7 @@ Select *sqlite3SelectNew(
|
||||
pNew->addrOpenEphm[0] = -1;
|
||||
pNew->addrOpenEphm[1] = -1;
|
||||
pNew->nSelectRow = 0;
|
||||
if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*pSrc));
|
||||
if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc));
|
||||
pNew->pSrc = pSrc;
|
||||
pNew->pWhere = pWhere;
|
||||
pNew->pGroupBy = pGroupBy;
|
||||
@@ -142,9 +143,9 @@ Select *sqlite3SelectNew(
|
||||
pNew->pLimit = pLimit;
|
||||
pNew->pOffset = pOffset;
|
||||
pNew->pWith = 0;
|
||||
assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || pParse->db->mallocFailed!=0 );
|
||||
if( pParse->db->mallocFailed ) {
|
||||
clearSelect(pParse->db, pNew, pNew!=&standin);
|
||||
assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
|
||||
if( db->mallocFailed ) {
|
||||
clearSelect(db, pNew, pNew!=&standin);
|
||||
pNew = 0;
|
||||
}else{
|
||||
assert( pNew->pSrc!=0 || pParse->nErr>0 );
|
||||
@@ -1031,7 +1032,7 @@ static void selectInnerLoop(
|
||||
** X extra columns.
|
||||
*/
|
||||
KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
|
||||
int nExtra = (N+X)*(sizeof(CollSeq*)+1) - sizeof(CollSeq*);
|
||||
int nExtra = (N+X)*(sizeof(CollSeq*)+1);
|
||||
KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra);
|
||||
if( p ){
|
||||
p->aSortOrder = (u8*)&p->aColl[N+X];
|
||||
@@ -1054,7 +1055,7 @@ void sqlite3KeyInfoUnref(KeyInfo *p){
|
||||
if( p ){
|
||||
assert( p->nRef>0 );
|
||||
p->nRef--;
|
||||
if( p->nRef==0 ) sqlite3DbFreeNN(p->db, p);
|
||||
if( p->nRef==0 ) sqlite3DbFree(p->db, p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1529,7 +1530,6 @@ static void generateColumnTypes(
|
||||
NameContext sNC;
|
||||
sNC.pSrcList = pTabList;
|
||||
sNC.pParse = pParse;
|
||||
sNC.pNext = 0;
|
||||
for(i=0; i<pEList->nExpr; i++){
|
||||
Expr *p = pEList->a[i].pExpr;
|
||||
const char *zType;
|
||||
@@ -1554,19 +1554,6 @@ static void generateColumnTypes(
|
||||
#endif /* !defined(SQLITE_OMIT_DECLTYPE) */
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the Table objecct in the SrcList that has cursor iCursor.
|
||||
** Or return NULL if no such Table object exists in the SrcList.
|
||||
*/
|
||||
static Table *tableWithCursor(SrcList *pList, int iCursor){
|
||||
int j;
|
||||
for(j=0; j<pList->nSrc; j++){
|
||||
if( pList->a[j].iCursor==iCursor ) return pList->a[j].pTab;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Generate code that will tell the VDBE the names of columns
|
||||
** in the result set. This information is used to provide the
|
||||
@@ -1578,8 +1565,7 @@ static void generateColumnNames(
|
||||
ExprList *pEList /* Expressions defining the result set */
|
||||
){
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
int i;
|
||||
Table *pTab;
|
||||
int i, j;
|
||||
sqlite3 *db = pParse->db;
|
||||
int fullNames, shortNames;
|
||||
|
||||
@@ -1604,11 +1590,15 @@ static void generateColumnNames(
|
||||
if( pEList->a[i].zName ){
|
||||
char *zName = pEList->a[i].zName;
|
||||
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
|
||||
}else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN)
|
||||
&& (pTab = tableWithCursor(pTabList, p->iTable))!=0
|
||||
){
|
||||
}else if( p->op==TK_COLUMN || p->op==TK_AGG_COLUMN ){
|
||||
Table *pTab;
|
||||
char *zCol;
|
||||
int iCol = p->iColumn;
|
||||
for(j=0; ALWAYS(j<pTabList->nSrc); j++){
|
||||
if( pTabList->a[j].iCursor==p->iTable ) break;
|
||||
}
|
||||
assert( j<pTabList->nSrc );
|
||||
pTab = pTabList->a[j].pTab;
|
||||
if( iCol<0 ) iCol = pTab->iPKey;
|
||||
assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
|
||||
if( iCol<0 ){
|
||||
@@ -1690,7 +1680,7 @@ int sqlite3ColumnsFromExprList(
|
||||
pColExpr = pColExpr->pRight;
|
||||
assert( pColExpr!=0 );
|
||||
}
|
||||
if( pColExpr->op==TK_COLUMN && pColExpr->pTab!=0 ){
|
||||
if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
|
||||
/* For columns use the column name name */
|
||||
int iCol = pColExpr->iColumn;
|
||||
pTab = pColExpr->pTab;
|
||||
@@ -2910,7 +2900,7 @@ static int multiSelectOrderBy(
|
||||
if( pNew==0 ) return SQLITE_NOMEM_BKPT;
|
||||
pNew->flags |= EP_IntValue;
|
||||
pNew->u.iValue = i;
|
||||
p->pOrderBy = pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
|
||||
pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
|
||||
if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i;
|
||||
}
|
||||
}
|
||||
@@ -3144,24 +3134,9 @@ static int multiSelectOrderBy(
|
||||
#endif
|
||||
|
||||
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
|
||||
|
||||
/* An instance of the SubstContext object describes an substitution edit
|
||||
** to be performed on a parse tree.
|
||||
**
|
||||
** All references to columns in table iTable are to be replaced by corresponding
|
||||
** expressions in pEList.
|
||||
*/
|
||||
typedef struct SubstContext {
|
||||
Parse *pParse; /* The parsing context */
|
||||
int iTable; /* Replace references to this table */
|
||||
int iNewTable; /* New table number */
|
||||
int isLeftJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */
|
||||
ExprList *pEList; /* Replacement expressions */
|
||||
} SubstContext;
|
||||
|
||||
/* Forward Declarations */
|
||||
static void substExprList(SubstContext*, ExprList*);
|
||||
static void substSelect(SubstContext*, Select*, int);
|
||||
static void substExprList(Parse*, ExprList*, int, ExprList*);
|
||||
static void substSelect(Parse*, Select *, int, ExprList*, int);
|
||||
|
||||
/*
|
||||
** Scan through the expression pExpr. Replace every reference to
|
||||
@@ -3172,95 +3147,84 @@ static void substSelect(SubstContext*, Select*, int);
|
||||
** This routine is part of the flattening procedure. A subquery
|
||||
** whose result set is defined by pEList appears as entry in the
|
||||
** FROM clause of a SELECT such that the VDBE cursor assigned to that
|
||||
** FORM clause entry is iTable. This routine makes the necessary
|
||||
** FORM clause entry is iTable. This routine make the necessary
|
||||
** changes to pExpr so that it refers directly to the source table
|
||||
** of the subquery rather the result set of the subquery.
|
||||
*/
|
||||
static Expr *substExpr(
|
||||
SubstContext *pSubst, /* Description of the substitution */
|
||||
Expr *pExpr /* Expr in which substitution occurs */
|
||||
Parse *pParse, /* Report errors here */
|
||||
Expr *pExpr, /* Expr in which substitution occurs */
|
||||
int iTable, /* Table to be substituted */
|
||||
ExprList *pEList /* Substitute expressions */
|
||||
){
|
||||
sqlite3 *db = pParse->db;
|
||||
if( pExpr==0 ) return 0;
|
||||
if( ExprHasProperty(pExpr, EP_FromJoin) && pExpr->iRightJoinTable==pSubst->iTable ){
|
||||
pExpr->iRightJoinTable = pSubst->iNewTable;
|
||||
}
|
||||
if( pExpr->op==TK_COLUMN && pExpr->iTable==pSubst->iTable ){
|
||||
if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){
|
||||
if( pExpr->iColumn<0 ){
|
||||
pExpr->op = TK_NULL;
|
||||
}else{
|
||||
Expr *pNew;
|
||||
Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr;
|
||||
Expr ifNullRow;
|
||||
assert( pSubst->pEList!=0 && pExpr->iColumn<pSubst->pEList->nExpr );
|
||||
Expr *pCopy = pEList->a[pExpr->iColumn].pExpr;
|
||||
assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
|
||||
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
|
||||
if( sqlite3ExprIsVector(pCopy) ){
|
||||
sqlite3VectorErrorMsg(pSubst->pParse, pCopy);
|
||||
sqlite3VectorErrorMsg(pParse, pCopy);
|
||||
}else{
|
||||
sqlite3 *db = pSubst->pParse->db;
|
||||
if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){
|
||||
memset(&ifNullRow, 0, sizeof(ifNullRow));
|
||||
ifNullRow.op = TK_IF_NULL_ROW;
|
||||
ifNullRow.pLeft = pCopy;
|
||||
ifNullRow.iTable = pSubst->iNewTable;
|
||||
pCopy = &ifNullRow;
|
||||
}
|
||||
pNew = sqlite3ExprDup(db, pCopy, 0);
|
||||
if( pNew && pSubst->isLeftJoin ){
|
||||
ExprSetProperty(pNew, EP_CanBeNull);
|
||||
}
|
||||
if( pNew && ExprHasProperty(pExpr,EP_FromJoin) ){
|
||||
if( pNew && (pExpr->flags & EP_FromJoin) ){
|
||||
pNew->iRightJoinTable = pExpr->iRightJoinTable;
|
||||
ExprSetProperty(pNew, EP_FromJoin);
|
||||
pNew->flags |= EP_FromJoin;
|
||||
}
|
||||
sqlite3ExprDelete(db, pExpr);
|
||||
pExpr = pNew;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){
|
||||
pExpr->iTable = pSubst->iNewTable;
|
||||
}
|
||||
pExpr->pLeft = substExpr(pSubst, pExpr->pLeft);
|
||||
pExpr->pRight = substExpr(pSubst, pExpr->pRight);
|
||||
pExpr->pLeft = substExpr(pParse, pExpr->pLeft, iTable, pEList);
|
||||
pExpr->pRight = substExpr(pParse, pExpr->pRight, iTable, pEList);
|
||||
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
|
||||
substSelect(pSubst, pExpr->x.pSelect, 1);
|
||||
substSelect(pParse, pExpr->x.pSelect, iTable, pEList, 1);
|
||||
}else{
|
||||
substExprList(pSubst, pExpr->x.pList);
|
||||
substExprList(pParse, pExpr->x.pList, iTable, pEList);
|
||||
}
|
||||
}
|
||||
return pExpr;
|
||||
}
|
||||
static void substExprList(
|
||||
SubstContext *pSubst, /* Description of the substitution */
|
||||
ExprList *pList /* List to scan and in which to make substitutes */
|
||||
Parse *pParse, /* Report errors here */
|
||||
ExprList *pList, /* List to scan and in which to make substitutes */
|
||||
int iTable, /* Table to be substituted */
|
||||
ExprList *pEList /* Substitute values */
|
||||
){
|
||||
int i;
|
||||
if( pList==0 ) return;
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
pList->a[i].pExpr = substExpr(pSubst, pList->a[i].pExpr);
|
||||
pList->a[i].pExpr = substExpr(pParse, pList->a[i].pExpr, iTable, pEList);
|
||||
}
|
||||
}
|
||||
static void substSelect(
|
||||
SubstContext *pSubst, /* Description of the substitution */
|
||||
Select *p, /* SELECT statement in which to make substitutions */
|
||||
int doPrior /* Do substitutes on p->pPrior too */
|
||||
Parse *pParse, /* Report errors here */
|
||||
Select *p, /* SELECT statement in which to make substitutions */
|
||||
int iTable, /* Table to be replaced */
|
||||
ExprList *pEList, /* Substitute values */
|
||||
int doPrior /* Do substitutes on p->pPrior too */
|
||||
){
|
||||
SrcList *pSrc;
|
||||
struct SrcList_item *pItem;
|
||||
int i;
|
||||
if( !p ) return;
|
||||
do{
|
||||
substExprList(pSubst, p->pEList);
|
||||
substExprList(pSubst, p->pGroupBy);
|
||||
substExprList(pSubst, p->pOrderBy);
|
||||
p->pHaving = substExpr(pSubst, p->pHaving);
|
||||
p->pWhere = substExpr(pSubst, p->pWhere);
|
||||
substExprList(pParse, p->pEList, iTable, pEList);
|
||||
substExprList(pParse, p->pGroupBy, iTable, pEList);
|
||||
substExprList(pParse, p->pOrderBy, iTable, pEList);
|
||||
p->pHaving = substExpr(pParse, p->pHaving, iTable, pEList);
|
||||
p->pWhere = substExpr(pParse, p->pWhere, iTable, pEList);
|
||||
pSrc = p->pSrc;
|
||||
assert( pSrc!=0 );
|
||||
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
|
||||
substSelect(pSubst, pItem->pSelect, 1);
|
||||
substSelect(pParse, pItem->pSelect, iTable, pEList, 1);
|
||||
if( pItem->fg.isTabFunc ){
|
||||
substExprList(pSubst, pItem->u1.pFuncArg);
|
||||
substExprList(pParse, pItem->u1.pFuncArg, iTable, pEList);
|
||||
}
|
||||
}
|
||||
}while( doPrior && (p = p->pPrior)!=0 );
|
||||
@@ -3303,9 +3267,8 @@ static void substSelect(
|
||||
** FROM-clause subquery that is a candidate for flattening. (2b is
|
||||
** due to ticket [2f7170d73bf9abf80] from 2015-02-09.)
|
||||
**
|
||||
** (3) The subquery is not the right operand of a LEFT JOIN
|
||||
** or the subquery is not itself a join and the outer query is not
|
||||
** an aggregate.
|
||||
** (3) The subquery is not the right operand of a left outer join
|
||||
** (Originally ticket #306. Strengthened by ticket #3300)
|
||||
**
|
||||
** (4) The subquery is not DISTINCT.
|
||||
**
|
||||
@@ -3317,7 +3280,7 @@ static void substSelect(
|
||||
** DISTINCT.
|
||||
**
|
||||
** (7) The subquery has a FROM clause. TODO: For subqueries without
|
||||
** A FROM clause, consider adding a FROM clause with the special
|
||||
** A FROM clause, consider adding a FROM close with the special
|
||||
** table sqlite_once that consists of a single row containing a
|
||||
** single NULL.
|
||||
**
|
||||
@@ -3423,8 +3386,6 @@ static int flattenSubquery(
|
||||
SrcList *pSubSrc; /* The FROM clause of the subquery */
|
||||
ExprList *pList; /* The result set of the outer query */
|
||||
int iParent; /* VDBE cursor number of the pSub result set temp table */
|
||||
int iNewParent = -1;/* Replacement table for iParent */
|
||||
int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */
|
||||
int i; /* Loop counter */
|
||||
Expr *pWhere; /* The WHERE clause */
|
||||
struct SrcList_item *pSubitem; /* The subquery */
|
||||
@@ -3451,7 +3412,7 @@ static int flattenSubquery(
|
||||
return 0; /* Restriction (2b) */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pSubSrc = pSub->pSrc;
|
||||
assert( pSubSrc );
|
||||
/* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
|
||||
@@ -3489,9 +3450,10 @@ static int flattenSubquery(
|
||||
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:
|
||||
/* OBSOLETE COMMENT 1:
|
||||
** Restriction 3: If the subquery is a join, make sure the subquery is
|
||||
** not used as the right operand of an outer join. Examples of why this
|
||||
** is not allowed:
|
||||
**
|
||||
** t1 LEFT OUTER JOIN (t2 JOIN t3)
|
||||
**
|
||||
@@ -3501,27 +3463,28 @@ static int flattenSubquery(
|
||||
**
|
||||
** 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.
|
||||
** OBSOLETE COMMENT 2:
|
||||
** Restriction 12: If the subquery is the right operand of a left outer
|
||||
** join, make sure the subquery has no WHERE clause.
|
||||
** An examples of why this is not allowed:
|
||||
**
|
||||
** See also tickets #306, #350, and #3300.
|
||||
** t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0)
|
||||
**
|
||||
** If we flatten the above, we would get
|
||||
**
|
||||
** (t1 LEFT OUTER JOIN t2) WHERE t2.x>0
|
||||
**
|
||||
** But the t2.x>0 test will always fail on a NULL row of t2, which
|
||||
** effectively converts the OUTER JOIN into an INNER JOIN.
|
||||
**
|
||||
** THIS OVERRIDES OBSOLETE COMMENTS 1 AND 2 ABOVE:
|
||||
** Ticket #3300 shows that flattening the right term of a LEFT JOIN
|
||||
** is fraught with danger. Best to avoid the whole thing. If the
|
||||
** subquery is the right term of a LEFT JOIN, then do not flatten.
|
||||
*/
|
||||
if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
|
||||
isLeftJoin = 1;
|
||||
if( pSubSrc->nSrc>1 || isAgg ){
|
||||
return 0; /* Restriction (3) */
|
||||
}
|
||||
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. */
|
||||
isLeftJoin = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
@@ -3729,7 +3692,6 @@ static int flattenSubquery(
|
||||
sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing);
|
||||
assert( pSrc->a[i+iFrom].fg.isTabFunc==0 );
|
||||
pSrc->a[i+iFrom] = pSubSrc->a[i];
|
||||
iNewParent = pSubSrc->a[i].iCursor;
|
||||
memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
|
||||
}
|
||||
pSrc->a[iFrom].fg.jointype = jointype;
|
||||
@@ -3775,9 +3737,6 @@ static int flattenSubquery(
|
||||
pSub->pOrderBy = 0;
|
||||
}
|
||||
pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
|
||||
if( isLeftJoin>0 ){
|
||||
setJoinExpr(pWhere, iNewParent);
|
||||
}
|
||||
if( subqueryIsAgg ){
|
||||
assert( pParent->pHaving==0 );
|
||||
pParent->pHaving = pParent->pWhere;
|
||||
@@ -3790,15 +3749,7 @@ static int flattenSubquery(
|
||||
}else{
|
||||
pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
|
||||
}
|
||||
if( db->mallocFailed==0 ){
|
||||
SubstContext x;
|
||||
x.pParse = pParse;
|
||||
x.iTable = iParent;
|
||||
x.iNewTable = iNewParent;
|
||||
x.isLeftJoin = isLeftJoin;
|
||||
x.pEList = pSub->pEList;
|
||||
substSelect(&x, pParent, 0);
|
||||
}
|
||||
substSelect(pParse, pParent, iParent, pSub->pEList, 0);
|
||||
|
||||
/* The flattened query is distinct if either the inner or the
|
||||
** outer query is distinct.
|
||||
@@ -3900,14 +3851,8 @@ static int pushDownWhereTerms(
|
||||
if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
|
||||
nChng++;
|
||||
while( pSubq ){
|
||||
SubstContext x;
|
||||
pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
|
||||
x.pParse = pParse;
|
||||
x.iTable = iCursor;
|
||||
x.iNewTable = iCursor;
|
||||
x.isLeftJoin = 0;
|
||||
x.pEList = pSubq->pEList;
|
||||
pNew = substExpr(&x, pNew);
|
||||
pNew = substExpr(pParse, pNew, iCursor, pSubq->pEList);
|
||||
pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew);
|
||||
pSubq = pSubq->pPrior;
|
||||
}
|
||||
@@ -4613,25 +4558,6 @@ int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
|
||||
return WRC_Continue;
|
||||
}
|
||||
|
||||
/*
|
||||
** No-op routine for the parse-tree walker for SELECT statements.
|
||||
** subquery in the parser tree.
|
||||
*/
|
||||
int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){
|
||||
UNUSED_PARAMETER2(NotUsed, NotUsed2);
|
||||
return WRC_Continue;
|
||||
}
|
||||
|
||||
#if SQLITE_DEBUG
|
||||
/*
|
||||
** Always assert. This xSelectCallback2 implementation proves that the
|
||||
** xSelectCallback2 is never invoked.
|
||||
*/
|
||||
void sqlite3SelectWalkAssert2(Walker *NotUsed, Select *NotUsed2){
|
||||
UNUSED_PARAMETER2(NotUsed, NotUsed2);
|
||||
assert( 0 );
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
** This routine "expands" a SELECT statement and all of its subqueries.
|
||||
** For additional information on what it means to "expand" a SELECT
|
||||
@@ -4647,11 +4573,11 @@ void sqlite3SelectWalkAssert2(Walker *NotUsed, Select *NotUsed2){
|
||||
*/
|
||||
static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
|
||||
Walker w;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.xExprCallback = sqlite3ExprWalkNoop;
|
||||
w.pParse = pParse;
|
||||
if( pParse->hasCompound ){
|
||||
w.xSelectCallback = convertCompoundSelectToSubquery;
|
||||
w.xSelectCallback2 = 0;
|
||||
sqlite3WalkSelect(&w, pSelect);
|
||||
}
|
||||
w.xSelectCallback = selectExpander;
|
||||
@@ -4711,7 +4637,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
|
||||
static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){
|
||||
#ifndef SQLITE_OMIT_SUBQUERY
|
||||
Walker w;
|
||||
w.xSelectCallback = sqlite3SelectWalkNoop;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.xSelectCallback2 = selectAddSubqueryTypeInfo;
|
||||
w.xExprCallback = sqlite3ExprWalkNoop;
|
||||
w.pParse = pParse;
|
||||
@@ -4918,103 +4844,6 @@ static void explainSimpleCount(
|
||||
# define explainSimpleCount(a,b,c)
|
||||
#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
|
||||
** WRC_Continue to tell sqlite3WalkExpr() to iterate through child nodes.
|
||||
**
|
||||
** Otherwise, return WRC_Prune. In this case, also check if the
|
||||
** sub-expression matches the criteria for being moved to the WHERE
|
||||
** clause. If so, add it to the WHERE clause and replace the sub-expression
|
||||
** within the HAVING expression with a constant "1".
|
||||
*/
|
||||
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) ){
|
||||
sqlite3 *db = pWalker->pParse->db;
|
||||
Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0);
|
||||
if( pNew ){
|
||||
Expr *pWhere = *(p->ppWhere);
|
||||
SWAP(Expr, *pNew, *pExpr);
|
||||
pNew = sqlite3ExprAnd(db, pWhere, pNew);
|
||||
*(p->ppWhere) = pNew;
|
||||
}
|
||||
}
|
||||
return WRC_Prune;
|
||||
}
|
||||
return WRC_Continue;
|
||||
}
|
||||
|
||||
/*
|
||||
** Transfer eligible terms from the HAVING clause of a query, which is
|
||||
** processed after grouping, to the WHERE clause, which is processed before
|
||||
** grouping. For example, the query:
|
||||
**
|
||||
** SELECT * FROM <tables> WHERE a=? GROUP BY b HAVING b=? AND c=?
|
||||
**
|
||||
** can be rewritten as:
|
||||
**
|
||||
** SELECT * FROM <tables> WHERE a=? AND b=? GROUP BY b HAVING c=?
|
||||
**
|
||||
** A term of the HAVING expression is eligible for transfer if it consists
|
||||
** 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;
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
** Check to see if the pThis entry of pTabList is a self-join of a prior view.
|
||||
** If it is, then return the SrcList_item for the prior view. If it is not,
|
||||
** then return 0.
|
||||
*/
|
||||
static struct SrcList_item *isSelfJoinView(
|
||||
SrcList *pTabList, /* Search for self-joins in this FROM clause */
|
||||
struct SrcList_item *pThis /* Search for prior reference to this subquery */
|
||||
){
|
||||
struct SrcList_item *pItem;
|
||||
for(pItem = pTabList->a; pItem<pThis; pItem++){
|
||||
if( pItem->pSelect==0 ) continue;
|
||||
if( pItem->fg.viaCoroutine ) continue;
|
||||
if( pItem->zName==0 ) continue;
|
||||
if( sqlite3_stricmp(pItem->zDatabase, pThis->zDatabase)!=0 ) continue;
|
||||
if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
|
||||
if( sqlite3ExprCompare(pThis->pSelect->pWhere, pItem->pSelect->pWhere, -1) ){
|
||||
/* The view was modified by some other optimization such as
|
||||
** pushDownWhereTerms() */
|
||||
continue;
|
||||
}
|
||||
return pItem;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate code for the SELECT statement given in the p argument.
|
||||
**
|
||||
@@ -5154,38 +4983,13 @@ int sqlite3Select(
|
||||
}
|
||||
#endif
|
||||
|
||||
/* For each term in the FROM clause, do two things:
|
||||
** (1) Authorized unreferenced tables
|
||||
** (2) Generate code for all sub-queries
|
||||
/* Generate code for all sub-queries in the FROM clause
|
||||
*/
|
||||
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
|
||||
for(i=0; i<pTabList->nSrc; i++){
|
||||
struct SrcList_item *pItem = &pTabList->a[i];
|
||||
SelectDest dest;
|
||||
Select *pSub;
|
||||
|
||||
/* 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.""
|
||||
**
|
||||
** 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,
|
||||
** 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.
|
||||
*/
|
||||
if( pItem->colUsed==0 ){
|
||||
sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase);
|
||||
}
|
||||
|
||||
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
|
||||
/* Generate code for all sub-queries in the FROM clause
|
||||
*/
|
||||
pSub = pItem->pSelect;
|
||||
Select *pSub = pItem->pSelect;
|
||||
if( pSub==0 ) continue;
|
||||
|
||||
/* Sometimes the code for a subquery will be generated more than
|
||||
@@ -5196,10 +5000,6 @@ int sqlite3Select(
|
||||
** to be invoked again. */
|
||||
if( pItem->addrFillSub ){
|
||||
if( pItem->fg.viaCoroutine==0 ){
|
||||
/* The subroutine that manifests the view might be a one-time routine,
|
||||
** or it might need to be rerun on each iteration because it
|
||||
** encodes a correlated subquery. */
|
||||
testcase( sqlite3VdbeGetOp(v, pItem->addrFillSub)->opcode==OP_Once );
|
||||
sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
|
||||
}
|
||||
continue;
|
||||
@@ -5274,8 +5074,6 @@ int sqlite3Select(
|
||||
int topAddr;
|
||||
int onceAddr = 0;
|
||||
int retAddr;
|
||||
struct SrcList_item *pPrior;
|
||||
|
||||
assert( pItem->addrFillSub==0 );
|
||||
pItem->regReturn = ++pParse->nMem;
|
||||
topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
|
||||
@@ -5289,17 +5087,9 @@ int sqlite3Select(
|
||||
}else{
|
||||
VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName));
|
||||
}
|
||||
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);
|
||||
sqlite3Select(pParse, pSub, &dest);
|
||||
}
|
||||
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
|
||||
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
|
||||
sqlite3Select(pParse, pSub, &dest);
|
||||
pItem->pTab->nRowLogEst = pSub->nSelectRow;
|
||||
if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
|
||||
retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
|
||||
@@ -5309,8 +5099,8 @@ int sqlite3Select(
|
||||
}
|
||||
if( db->mallocFailed ) goto select_end;
|
||||
pParse->nHeight -= sqlite3SelectExprHeight(p);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Various elements of the SELECT copied into local variables for
|
||||
** convenience */
|
||||
@@ -5518,11 +5308,6 @@ int sqlite3Select(
|
||||
sqlite3ExprAnalyzeAggList(&sNC, pEList);
|
||||
sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy);
|
||||
if( pHaving ){
|
||||
if( pGroupBy ){
|
||||
assert( pWhere==p->pWhere );
|
||||
havingToWhere(pParse, pGroupBy, pHaving, &p->pWhere);
|
||||
pWhere = p->pWhere;
|
||||
}
|
||||
sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
|
||||
}
|
||||
sAggInfo.nAccumulator = sAggInfo.nColumn;
|
||||
|
||||
+767
-1244
File diff suppressed because it is too large
Load Diff
+17
-36
@@ -114,8 +114,8 @@ extern "C" {
|
||||
** system</a>. ^The SQLITE_SOURCE_ID macro evaluates to
|
||||
** 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.
|
||||
** string contains the date and time of the check-in (UTC) and an SHA1
|
||||
** hash of the entire source tree.
|
||||
**
|
||||
** See also: [sqlite3_libversion()],
|
||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
@@ -857,7 +857,7 @@ struct sqlite3_io_methods {
|
||||
** opcode allows these two values (10 retries and 25 milliseconds of delay)
|
||||
** to be adjusted. The values are changed for all database connections
|
||||
** within the same process. The argument is a pointer to an array of two
|
||||
** integers where the first integer is the new retry count and the second
|
||||
** integers where the first integer i the new retry count and the second
|
||||
** integer is the delay. If either integer is negative, then the setting
|
||||
** is not changed but instead the prior value of that setting is written
|
||||
** into the array entry, allowing the current retry settings to be
|
||||
@@ -2211,6 +2211,9 @@ int sqlite3_total_changes(sqlite3*);
|
||||
** ^A call to sqlite3_interrupt(D) that occurs when there are no running
|
||||
** SQL statements is a no-op and has no effect on SQL statements
|
||||
** that are started after the sqlite3_interrupt() call returns.
|
||||
**
|
||||
** If the database connection closes while [sqlite3_interrupt()]
|
||||
** is running then bad things will likely happen.
|
||||
*/
|
||||
void sqlite3_interrupt(sqlite3*);
|
||||
|
||||
@@ -2673,7 +2676,6 @@ void sqlite3_randomness(int N, void *P);
|
||||
/*
|
||||
** CAPI3REF: Compile-Time Authorization Callbacks
|
||||
** METHOD: sqlite3
|
||||
** KEYWORDS: {authorizer callback}
|
||||
**
|
||||
** ^This routine registers an authorizer callback with a particular
|
||||
** [database connection], supplied in the first argument.
|
||||
@@ -2701,10 +2703,8 @@ void sqlite3_randomness(int N, void *P);
|
||||
** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
|
||||
** to the callback is an integer [SQLITE_COPY | action code] that specifies
|
||||
** the particular action to be authorized. ^The third through sixth parameters
|
||||
** to the callback are either NULL pointers or zero-terminated strings
|
||||
** that contain additional details about the action to be authorized.
|
||||
** Applications must always be prepared to encounter a NULL pointer in any
|
||||
** of the third through the sixth parameters of the authorization callback.
|
||||
** to the callback are zero-terminated strings that contain additional
|
||||
** details about the action to be authorized.
|
||||
**
|
||||
** ^If the action code is [SQLITE_READ]
|
||||
** and the callback returns [SQLITE_IGNORE] then the
|
||||
@@ -2713,10 +2713,6 @@ void sqlite3_randomness(int N, void *P);
|
||||
** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE]
|
||||
** return can be used to deny an untrusted user access to individual
|
||||
** columns of a table.
|
||||
** ^When a table is referenced by a [SELECT] but no column values are
|
||||
** extracted from that table (for example in a query like
|
||||
** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback
|
||||
** is invoked once for that table with a column name that is an empty string.
|
||||
** ^If the action code is [SQLITE_DELETE] and the callback returns
|
||||
** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
|
||||
** [truncate optimization] is disabled and all rows are deleted individually.
|
||||
@@ -3428,9 +3424,9 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
|
||||
**
|
||||
** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
|
||||
** <dd>The maximum number of instructions in a virtual machine program
|
||||
** used to implement an SQL statement. If [sqlite3_prepare_v2()] or
|
||||
** the equivalent tries to allocate space for more than this many opcodes
|
||||
** in a single prepared statement, an SQLITE_NOMEM error is returned.</dd>)^
|
||||
** used to implement an SQL statement. This limit is not currently
|
||||
** enforced, though that might be added in some future release of
|
||||
** SQLite.</dd>)^
|
||||
**
|
||||
** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
|
||||
** <dd>The maximum number of arguments on a function.</dd>)^
|
||||
@@ -3468,7 +3464,6 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
|
||||
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
|
||||
#define SQLITE_LIMIT_WORKER_THREADS 11
|
||||
|
||||
|
||||
/*
|
||||
** CAPI3REF: Compiling An SQL Statement
|
||||
** KEYWORDS: {SQL statement compiler}
|
||||
@@ -3709,7 +3704,7 @@ int sqlite3_stmt_busy(sqlite3_stmt*);
|
||||
** The [sqlite3_value_blob | sqlite3_value_type()] family of
|
||||
** interfaces require protected sqlite3_value objects.
|
||||
*/
|
||||
typedef struct sqlite3_value sqlite3_value;
|
||||
typedef struct Mem sqlite3_value;
|
||||
|
||||
/*
|
||||
** CAPI3REF: SQL Function Context Object
|
||||
@@ -4763,11 +4758,10 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
|
||||
** the compiled regular expression can be reused on multiple
|
||||
** invocations of the same function.
|
||||
**
|
||||
** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata
|
||||
** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
|
||||
** value to the application-defined function. ^N is zero for the left-most
|
||||
** function argument. ^If there is no metadata
|
||||
** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
|
||||
** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
|
||||
** associated by the sqlite3_set_auxdata() function with the Nth argument
|
||||
** value to the application-defined function. ^If there is no metadata
|
||||
** associated with the function argument, this sqlite3_get_auxdata() interface
|
||||
** returns a NULL pointer.
|
||||
**
|
||||
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
|
||||
@@ -4798,10 +4792,6 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
|
||||
** function parameters that are compile-time constants, including literal
|
||||
** values and [parameters] and expressions composed from the same.)^
|
||||
**
|
||||
** The value of the N parameter to these interfaces should be non-negative.
|
||||
** Future enhancements may make use of negative N values to define new
|
||||
** kinds of function caching behavior.
|
||||
**
|
||||
** These routines must be called from the same thread in which
|
||||
** the SQL function is running.
|
||||
*/
|
||||
@@ -5620,9 +5610,7 @@ SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
|
||||
** ^If the column-name parameter to sqlite3_table_column_metadata() is a
|
||||
** NULL pointer, then this routine simply checks for the existence of the
|
||||
** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
|
||||
** does not. If the table name parameter T in a call to
|
||||
** sqlite3_table_column_metadata(X,D,T,C,...) is NULL then the result is
|
||||
** undefined behavior.
|
||||
** does not.
|
||||
**
|
||||
** ^The column is identified by the second, third and fourth parameters to
|
||||
** this function. ^(The second parameter is either the name of the database
|
||||
@@ -7135,12 +7123,6 @@ int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
|
||||
** used as a proxy for the total work done by the prepared statement.
|
||||
** If the number of virtual machine operations exceeds 2147483647
|
||||
** then the value returned by this statement status code is undefined.
|
||||
**
|
||||
** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
|
||||
** <dd>^This is the approximate number of bytes of heap memory
|
||||
** used to store the prepared statement. ^This value is not actually
|
||||
** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
|
||||
** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED.
|
||||
** </dd>
|
||||
** </dl>
|
||||
*/
|
||||
@@ -7148,7 +7130,6 @@ int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
|
||||
#define SQLITE_STMTSTATUS_SORT 2
|
||||
#define SQLITE_STMTSTATUS_AUTOINDEX 3
|
||||
#define SQLITE_STMTSTATUS_VM_STEP 4
|
||||
#define SQLITE_STMTSTATUS_MEMUSED 5
|
||||
|
||||
/*
|
||||
** CAPI3REF: Custom Page Cache Object
|
||||
|
||||
@@ -282,8 +282,6 @@ struct sqlite3_api_routines {
|
||||
/* Version 3.14.0 and later */
|
||||
int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
|
||||
char *(*expanded_sql)(sqlite3_stmt*);
|
||||
/* Version 3.18.0 and later */
|
||||
void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -542,8 +540,6 @@ typedef int (*sqlite3_loadext_entry)(
|
||||
/* Version 3.14.0 and later */
|
||||
#define sqlite3_trace_v2 sqlite3_api->trace_v2
|
||||
#define sqlite3_expanded_sql sqlite3_api->expanded_sql
|
||||
/* Version 3.18.0 and later */
|
||||
#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
||||
+15
-32
@@ -274,11 +274,6 @@
|
||||
**
|
||||
** Older versions of SQLite used an optional THREADSAFE macro.
|
||||
** We support that for legacy.
|
||||
**
|
||||
** To ensure that the correct value of "THREADSAFE" is reported when querying
|
||||
** for compile-time options at runtime (e.g. "PRAGMA compile_options"), this
|
||||
** logic is partially replicated in ctime.c. If it is updated here, it should
|
||||
** also be updated there.
|
||||
*/
|
||||
#if !defined(SQLITE_THREADSAFE)
|
||||
# if defined(THREADSAFE)
|
||||
@@ -594,6 +589,7 @@
|
||||
*/
|
||||
#ifndef SQLITE_TEMP_STORE
|
||||
# define SQLITE_TEMP_STORE 1
|
||||
# define SQLITE_TEMP_STORE_xc 1 /* Exclude from ctime.c */
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -894,6 +890,7 @@ typedef INT16_TYPE LogEst;
|
||||
# else
|
||||
# define SQLITE_MAX_MMAP_SIZE 0
|
||||
# endif
|
||||
# define SQLITE_MAX_MMAP_SIZE_xc 1 /* exclude from ctime.c */
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -903,6 +900,7 @@ typedef INT16_TYPE LogEst;
|
||||
*/
|
||||
#ifndef SQLITE_DEFAULT_MMAP_SIZE
|
||||
# define SQLITE_DEFAULT_MMAP_SIZE 0
|
||||
# define SQLITE_DEFAULT_MMAP_SIZE_xc 1 /* Exclude from ctime.c */
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE
|
||||
# undef SQLITE_DEFAULT_MMAP_SIZE
|
||||
@@ -1129,7 +1127,7 @@ typedef int VList;
|
||||
** and the one-based values are used internally.
|
||||
*/
|
||||
#ifndef SQLITE_DEFAULT_SYNCHRONOUS
|
||||
# define SQLITE_DEFAULT_SYNCHRONOUS 2
|
||||
# define SQLITE_DEFAULT_SYNCHRONOUS (PAGER_SYNCHRONOUS_FULL-1)
|
||||
#endif
|
||||
#ifndef SQLITE_DEFAULT_WAL_SYNCHRONOUS
|
||||
# define SQLITE_DEFAULT_WAL_SYNCHRONOUS SQLITE_DEFAULT_SYNCHRONOUS
|
||||
@@ -2366,7 +2364,7 @@ struct Expr {
|
||||
#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
|
||||
#define EP_Agg 0x000002 /* Contains one or more aggregate functions */
|
||||
#define EP_Resolved 0x000004 /* IDs have been resolved to COLUMNs */
|
||||
/* 0x000008 // available for use */
|
||||
#define EP_Error 0x000008 /* Expression contains one or more errors */
|
||||
#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 "..." */
|
||||
@@ -2445,7 +2443,6 @@ struct Expr {
|
||||
*/
|
||||
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 */
|
||||
@@ -2461,7 +2458,7 @@ struct ExprList {
|
||||
} x;
|
||||
int iConstExprReg; /* Register in which Expr value is cached */
|
||||
} u;
|
||||
} a[1]; /* One slot for each expression in the list */
|
||||
} *a; /* Alloc a power of two greater or equal to nExpr */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -2833,10 +2830,10 @@ struct Select {
|
||||
*/
|
||||
struct SelectDest {
|
||||
u8 eDest; /* How to dispose of the results. On of SRT_* above. */
|
||||
char *zAffSdst; /* Affinity used when eDest==SRT_Set */
|
||||
int iSDParm; /* A parameter used by the eDest disposal method */
|
||||
int iSdst; /* Base register where results are written */
|
||||
int nSdst; /* Number of registers allocated */
|
||||
char *zAffSdst; /* Affinity used when eDest==SRT_Set */
|
||||
ExprList *pOrderBy; /* Key columns for SRT_Queue and SRT_DistQueue */
|
||||
};
|
||||
|
||||
@@ -3318,17 +3315,14 @@ struct Walker {
|
||||
int walkerDepth; /* Number of subqueries */
|
||||
u8 eCode; /* A small processing code */
|
||||
union { /* Extra data for callback */
|
||||
NameContext *pNC; /* Naming context */
|
||||
int n; /* A counter */
|
||||
int iCur; /* A cursor number */
|
||||
SrcList *pSrcList; /* FROM clause */
|
||||
struct SrcCount *pSrcCount; /* Counting column references */
|
||||
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 */
|
||||
ExprList *pGroupBy; /* GROUP BY clause */
|
||||
struct HavingToWhereCtx *pHavingCtx; /* HAVING to WHERE clause ctx */
|
||||
NameContext *pNC; /* Naming context */
|
||||
int n; /* A counter */
|
||||
int iCur; /* A cursor number */
|
||||
SrcList *pSrcList; /* FROM clause */
|
||||
struct SrcCount *pSrcCount; /* Counting column references */
|
||||
struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
|
||||
int *aiCol; /* array of column indexes */
|
||||
struct IdxCover *pIdxCover; /* Check for index coverage */
|
||||
} u;
|
||||
};
|
||||
|
||||
@@ -3339,10 +3333,6 @@ int sqlite3WalkSelect(Walker*, Select*);
|
||||
int sqlite3WalkSelectExpr(Walker*, Select*);
|
||||
int sqlite3WalkSelectFrom(Walker*, Select*);
|
||||
int sqlite3ExprWalkNoop(Walker*, Expr*);
|
||||
int sqlite3SelectWalkNoop(Walker*, Select*);
|
||||
#ifdef SQLITE_DEBUG
|
||||
void sqlite3SelectWalkAssert2(Walker*, Select*);
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Return code from the parse-tree walking primitives and their
|
||||
@@ -3404,14 +3394,11 @@ int sqlite3CantopenError(int);
|
||||
#ifdef SQLITE_DEBUG
|
||||
int sqlite3NomemError(int);
|
||||
int sqlite3IoerrnomemError(int);
|
||||
int sqlite3CorruptPgnoError(int,Pgno);
|
||||
# define SQLITE_NOMEM_BKPT sqlite3NomemError(__LINE__)
|
||||
# define SQLITE_IOERR_NOMEM_BKPT sqlite3IoerrnomemError(__LINE__)
|
||||
# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptPgnoError(__LINE__,(P))
|
||||
#else
|
||||
# define SQLITE_NOMEM_BKPT SQLITE_NOMEM
|
||||
# define SQLITE_IOERR_NOMEM_BKPT SQLITE_IOERR_NOMEM
|
||||
# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptError(__LINE__)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -3489,7 +3476,6 @@ void *sqlite3Realloc(void*, u64);
|
||||
void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64);
|
||||
void *sqlite3DbRealloc(sqlite3 *, void *, u64);
|
||||
void sqlite3DbFree(sqlite3*, void*);
|
||||
void sqlite3DbFreeNN(sqlite3*, void*);
|
||||
int sqlite3MallocSize(void*);
|
||||
int sqlite3DbMallocSize(sqlite3*, void*);
|
||||
void *sqlite3ScratchMalloc(int);
|
||||
@@ -3805,7 +3791,6 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
|
||||
int sqlite3ExprIsConstant(Expr*);
|
||||
int sqlite3ExprIsConstantNotJoin(Expr*);
|
||||
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
|
||||
int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
|
||||
int sqlite3ExprIsTableConstant(Expr*,int);
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
int sqlite3ExprContainsSubquery(Expr*);
|
||||
@@ -4372,6 +4357,4 @@ Expr *sqlite3VectorFieldSubexpr(Expr*, int);
|
||||
Expr *sqlite3ExprForVectorField(Parse*,Expr*,int);
|
||||
void sqlite3VectorErrorMsg(Parse*, Expr*);
|
||||
|
||||
const char **sqlite3CompileOptions(int *pnOpt);
|
||||
|
||||
#endif /* SQLITEINT_H */
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@
|
||||
** Not currently enforced.
|
||||
*/
|
||||
#ifndef SQLITE_MAX_VDBE_OP
|
||||
# define SQLITE_MAX_VDBE_OP 250000000
|
||||
# define SQLITE_MAX_VDBE_OP 25000
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
+2
-13
@@ -161,7 +161,6 @@ struct SqliteDb {
|
||||
int nStmt; /* Number of statements in stmtList */
|
||||
IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
|
||||
int nStep, nSort, nIndex; /* Statistics for most recent operation */
|
||||
int nVMStep; /* Another statistic for most recent operation */
|
||||
int nTransaction; /* Number of nested [transaction] methods */
|
||||
int openFlags; /* Flags used to open. (SQLITE_OPEN_URI) */
|
||||
#ifdef SQLITE_TEST
|
||||
@@ -1034,16 +1033,9 @@ static int auth_callback(
|
||||
Tcl_DString str;
|
||||
int rc;
|
||||
const char *zReply;
|
||||
/* EVIDENCE-OF: R-38590-62769 The first parameter to the authorizer
|
||||
** callback is a copy of the third parameter to the
|
||||
** sqlite3_set_authorizer() interface.
|
||||
*/
|
||||
SqliteDb *pDb = (SqliteDb*)pArg;
|
||||
if( pDb->disableAuth ) return SQLITE_OK;
|
||||
|
||||
/* EVIDENCE-OF: R-56518-44310 The second parameter to the callback is an
|
||||
** integer action code that specifies the particular action to be
|
||||
** authorized. */
|
||||
switch( code ){
|
||||
case SQLITE_COPY : zCode="SQLITE_COPY"; break;
|
||||
case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break;
|
||||
@@ -1589,7 +1581,6 @@ static int dbEvalStep(DbEvalContext *p){
|
||||
pDb->nStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_FULLSCAN_STEP,1);
|
||||
pDb->nSort = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_SORT,1);
|
||||
pDb->nIndex = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_AUTOINDEX,1);
|
||||
pDb->nVMStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_VM_STEP,1);
|
||||
dbReleaseColumnNames(p);
|
||||
p->pPreStmt = 0;
|
||||
|
||||
@@ -2857,7 +2848,7 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
}
|
||||
|
||||
/*
|
||||
** $db status (step|sort|autoindex|vmstep)
|
||||
** $db status (step|sort|autoindex)
|
||||
**
|
||||
** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or
|
||||
** SQLITE_STMTSTATUS_SORT for the most recent eval.
|
||||
@@ -2876,11 +2867,9 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
v = pDb->nSort;
|
||||
}else if( strcmp(zOp, "autoindex")==0 ){
|
||||
v = pDb->nIndex;
|
||||
}else if( strcmp(zOp, "vmstep")==0 ){
|
||||
v = pDb->nVMStep;
|
||||
}else{
|
||||
Tcl_AppendResult(interp,
|
||||
"bad argument: should be autoindex, step, sort or vmstep",
|
||||
"bad argument: should be autoindex, step, or sort",
|
||||
(char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
+47
@@ -4949,6 +4949,52 @@ static int SQLITE_TCLAPI test_interrupt(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
static u8 *sqlite3_stack_baseline = 0;
|
||||
|
||||
/*
|
||||
** Fill the stack with a known bitpattern.
|
||||
*/
|
||||
static void prepStack(void){
|
||||
int i;
|
||||
u32 bigBuf[65536];
|
||||
for(i=0; i<sizeof(bigBuf)/sizeof(bigBuf[0]); i++) bigBuf[i] = 0xdeadbeef;
|
||||
sqlite3_stack_baseline = (u8*)&bigBuf[65536];
|
||||
}
|
||||
|
||||
/*
|
||||
** Get the current stack depth. Used for debugging only.
|
||||
*/
|
||||
u64 sqlite3StackDepth(void){
|
||||
u8 x;
|
||||
return (u64)(sqlite3_stack_baseline - &x);
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_stack_used DB SQL
|
||||
**
|
||||
** Try to measure the amount of stack space used by a call to sqlite3_exec
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_stack_used(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int argc,
|
||||
char **argv
|
||||
){
|
||||
sqlite3 *db;
|
||||
int i;
|
||||
if( argc!=3 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" DB SQL", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
|
||||
prepStack();
|
||||
(void)sqlite3_exec(db, argv[2], 0, 0, 0);
|
||||
for(i=65535; i>=0 && ((u32*)sqlite3_stack_baseline)[-i]==0xdeadbeef; i--){}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(i*4));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite_delete_function DB function-name
|
||||
**
|
||||
@@ -7427,6 +7473,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite_delete_function", (Tcl_CmdProc*)delete_function },
|
||||
{ "sqlite_delete_collation", (Tcl_CmdProc*)delete_collation },
|
||||
{ "sqlite3_get_autocommit", (Tcl_CmdProc*)get_autocommit },
|
||||
{ "sqlite3_stack_used", (Tcl_CmdProc*)test_stack_used },
|
||||
{ "sqlite3_busy_timeout", (Tcl_CmdProc*)test_busy_timeout },
|
||||
{ "printf", (Tcl_CmdProc*)test_printf },
|
||||
{ "sqlite3IoTrace", (Tcl_CmdProc*)test_io_trace },
|
||||
|
||||
+1
-5
@@ -306,11 +306,7 @@ static int SQLITE_TCLAPI btree_next(
|
||||
}
|
||||
pCur = sqlite3TestTextToPtr(argv[1]);
|
||||
sqlite3BtreeEnter(pCur->pBtree);
|
||||
rc = sqlite3BtreeNext(pCur, 0);
|
||||
if( rc==SQLITE_DONE ){
|
||||
res = 1;
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
rc = sqlite3BtreeNext(pCur, &res);
|
||||
sqlite3BtreeLeave(pCur->pBtree);
|
||||
if( rc ){
|
||||
Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
|
||||
|
||||
@@ -740,8 +740,6 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
|
||||
LINKVAR( DEFAULT_CACHE_SIZE );
|
||||
LINKVAR( DEFAULT_PAGE_SIZE );
|
||||
LINKVAR( DEFAULT_FILE_FORMAT );
|
||||
LINKVAR( DEFAULT_SYNCHRONOUS );
|
||||
LINKVAR( DEFAULT_WAL_SYNCHRONOUS );
|
||||
LINKVAR( MAX_ATTACHED );
|
||||
LINKVAR( MAX_DEFAULT_PAGE_SIZE );
|
||||
LINKVAR( MAX_WORKER_THREADS );
|
||||
|
||||
+18
-36
@@ -19,12 +19,14 @@
|
||||
** above.
|
||||
*/
|
||||
|
||||
#ifndef SQLITE_OS_WIN
|
||||
#if SQLITE_OS_WIN
|
||||
# include <io.h>
|
||||
# define F_OK 0
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include "sqlite3.h"
|
||||
|
||||
/* The following #defines are copied from test_multiplex.c */
|
||||
@@ -55,37 +57,23 @@ static void sqlite3Delete83Name(char *z){
|
||||
** set *pbExists to true and unlink it. Or, if the file does not exist,
|
||||
** set *pbExists to false before returning.
|
||||
**
|
||||
** If an error occurs, non-zero is returned. Or, if no error occurs, zero.
|
||||
** If an error occurs, the value of errno is returned. Or, if no error
|
||||
** occurs, zero is returned.
|
||||
*/
|
||||
static int sqlite3DeleteUnlinkIfExists(
|
||||
sqlite3_vfs *pVfs,
|
||||
const char *zFile,
|
||||
int *pbExists
|
||||
){
|
||||
int rc = SQLITE_ERROR;
|
||||
#if SQLITE_OS_WIN
|
||||
if( pVfs ){
|
||||
if( pbExists ) *pbExists = 1;
|
||||
rc = pVfs->xDelete(pVfs, zFile, 0);
|
||||
if( rc==SQLITE_IOERR_DELETE_NOENT ){
|
||||
if( pbExists ) *pbExists = 0;
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
}
|
||||
#else
|
||||
assert( pVfs==0 );
|
||||
static int sqlite3DeleteUnlinkIfExists(const char *zFile, int *pbExists){
|
||||
int rc;
|
||||
rc = access(zFile, F_OK);
|
||||
if( rc ){
|
||||
if( errno==ENOENT ){
|
||||
if( pbExists ) *pbExists = 0;
|
||||
rc = SQLITE_OK;
|
||||
return 0;
|
||||
}
|
||||
}else{
|
||||
if( pbExists ) *pbExists = 1;
|
||||
rc = unlink(zFile);
|
||||
return errno;
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
if( pbExists ) *pbExists = 1;
|
||||
rc = unlink(zFile);
|
||||
if( rc ) return errno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -115,12 +103,6 @@ SQLITE_API int sqlite3_delete_database(
|
||||
{ "%s-wal%03d", SQLITE_MULTIPLEX_WAL_8_3_OFFSET, 1 },
|
||||
};
|
||||
|
||||
#ifdef SQLITE_OS_WIN
|
||||
sqlite3_vfs *pVfs = sqlite3_vfs_find("win32");
|
||||
#else
|
||||
sqlite3_vfs *pVfs = 0;
|
||||
#endif
|
||||
|
||||
/* Allocate a buffer large enough for any of the files that need to be
|
||||
** deleted. */
|
||||
nBuf = (int)strlen(zFile) + 100;
|
||||
@@ -131,10 +113,10 @@ SQLITE_API int sqlite3_delete_database(
|
||||
** journal, wal and shm files. */
|
||||
for(i=0; rc==0 && i<sizeof(azFmt)/sizeof(azFmt[0]); i++){
|
||||
sqlite3_snprintf(nBuf, zBuf, azFmt[i], zFile);
|
||||
rc = sqlite3DeleteUnlinkIfExists(pVfs, zBuf, 0);
|
||||
rc = sqlite3DeleteUnlinkIfExists(zBuf, 0);
|
||||
if( rc==0 && i!=0 ){
|
||||
sqlite3Delete83Name(zBuf);
|
||||
rc = sqlite3DeleteUnlinkIfExists(pVfs, zBuf, 0);
|
||||
rc = sqlite3DeleteUnlinkIfExists(zBuf, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +128,7 @@ SQLITE_API int sqlite3_delete_database(
|
||||
int bExists;
|
||||
sqlite3_snprintf(nBuf, zBuf, p->zFmt, zFile, iChunk+p->iOffset);
|
||||
if( p->b83 ) sqlite3Delete83Name(zBuf);
|
||||
rc = sqlite3DeleteUnlinkIfExists(pVfs, zBuf, &bExists);
|
||||
rc = sqlite3DeleteUnlinkIfExists(zBuf, &bExists);
|
||||
if( bExists==0 || rc!=0 ) break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -545,7 +545,6 @@ static int fstreeFilter(
|
||||
zDir = zQuery;
|
||||
}
|
||||
}
|
||||
if( nDir==0 ) nDir = 1;
|
||||
|
||||
sqlite3_bind_text(pCsr->pStmt, 1, zDir, nDir, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(pCsr->pStmt, 2, zRoot, nRoot, SQLITE_TRANSIENT);
|
||||
|
||||
@@ -557,9 +557,6 @@ static int jtWrite(
|
||||
u32 pgno = (u32)(iOfst/p->nPagesize + 1);
|
||||
assert( (iAmt==1||iAmt==(int)p->nPagesize) &&
|
||||
((iOfst+iAmt)%p->nPagesize)==0 );
|
||||
/* The following assert() statements may fail if this layer is used
|
||||
** with a connection in "PRAGMA synchronous=off" mode. If they
|
||||
** fail with sync=normal or sync=full, this may indicate problem. */
|
||||
assert( pgno<=p->nPage || p->nSync>0 );
|
||||
assert( pgno>p->nPage || sqlite3BitvecTest(p->pWritable, pgno) );
|
||||
}
|
||||
|
||||
+3
-3
@@ -482,7 +482,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
sqlite3 *db = pParse->db; /* The database connection */
|
||||
int mxSqlLen; /* Max length of an SQL string */
|
||||
#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
|
||||
yyParser sEngine; /* Space to hold the Lemon-generated Parser object */
|
||||
unsigned char zSpace[sizeof(yyParser)]; /* Space for parser engine object */
|
||||
#endif
|
||||
|
||||
assert( zSql!=0 );
|
||||
@@ -495,7 +495,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
assert( pzErrMsg!=0 );
|
||||
/* sqlite3ParserTrace(stdout, "parser: "); */
|
||||
#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
|
||||
pEngine = &sEngine;
|
||||
pEngine = zSpace;
|
||||
sqlite3ParserInit(pEngine);
|
||||
#else
|
||||
pEngine = sqlite3ParserAlloc(sqlite3Malloc);
|
||||
@@ -604,7 +604,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
while( pParse->pAinc ){
|
||||
AutoincInfo *p = pParse->pAinc;
|
||||
pParse->pAinc = p->pNext;
|
||||
sqlite3DbFreeNN(db, p);
|
||||
sqlite3DbFree(db, p);
|
||||
}
|
||||
while( pParse->pZombieTab ){
|
||||
Table *p = pParse->pZombieTab;
|
||||
|
||||
+2
-16
@@ -126,10 +126,6 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){
|
||||
void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
|
||||
int n = 0;
|
||||
int cnt = 0;
|
||||
if( p==0 ){
|
||||
sqlite3TreeViewLine(pView, "nil-SELECT");
|
||||
return;
|
||||
}
|
||||
pView = sqlite3TreeViewPush(pView, moreToFollow);
|
||||
if( p->pWith ){
|
||||
sqlite3TreeViewWith(pView, p->pWith, 1);
|
||||
@@ -238,7 +234,7 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
|
||||
void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
const char *zBinOp = 0; /* Binary operator */
|
||||
const char *zUniOp = 0; /* Unary operator */
|
||||
char zFlgs[60];
|
||||
char zFlgs[30];
|
||||
pView = sqlite3TreeViewPush(pView, moreToFollow);
|
||||
if( pExpr==0 ){
|
||||
sqlite3TreeViewLine(pView, "nil");
|
||||
@@ -246,12 +242,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
return;
|
||||
}
|
||||
if( pExpr->flags ){
|
||||
if( ExprHasProperty(pExpr, EP_FromJoin) ){
|
||||
sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x iRJT=%d",
|
||||
pExpr->flags, pExpr->iRightJoinTable);
|
||||
}else{
|
||||
sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x",pExpr->flags);
|
||||
}
|
||||
sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x",pExpr->flags);
|
||||
}else{
|
||||
zFlgs[0] = 0;
|
||||
}
|
||||
@@ -470,11 +461,6 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0);
|
||||
break;
|
||||
}
|
||||
case TK_IF_NULL_ROW: {
|
||||
sqlite3TreeViewLine(pView, "IF-NULL-ROW %d", pExpr->iTable);
|
||||
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sqlite3TreeViewLine(pView, "op=%d", pExpr->op);
|
||||
break;
|
||||
|
||||
@@ -306,7 +306,6 @@ void sqlite3FinishTrigger(
|
||||
if( v==0 ) goto triggerfinish_cleanup;
|
||||
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
||||
z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
|
||||
testcase( z==0 );
|
||||
sqlite3NestedParse(pParse,
|
||||
"INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
|
||||
db->aDb[iDb].zDbSName, MASTER_NAME, zName,
|
||||
|
||||
+3
-3
@@ -285,7 +285,7 @@ void sqlite3Update(
|
||||
*/
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
int reg;
|
||||
if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){
|
||||
if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){
|
||||
reg = ++pParse->nMem;
|
||||
pParse->nMem += pIdx->nColumn;
|
||||
}else{
|
||||
@@ -640,7 +640,7 @@ void sqlite3Update(
|
||||
assert( regNew==regNewRowid+1 );
|
||||
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
|
||||
sqlite3VdbeAddOp3(v, OP_Delete, iDataCur,
|
||||
OPFLAG_ISUPDATE | ((hasFK>1 || chngKey) ? 0 : OPFLAG_ISNOOP),
|
||||
OPFLAG_ISUPDATE | ((hasFK || chngKey) ? 0 : OPFLAG_ISNOOP),
|
||||
regNewRowid
|
||||
);
|
||||
if( eOnePass==ONEPASS_MULTI ){
|
||||
@@ -651,7 +651,7 @@ void sqlite3Update(
|
||||
sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
|
||||
}
|
||||
#else
|
||||
if( hasFK>1 || chngKey ){
|
||||
if( hasFK || chngKey ){
|
||||
sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -713,7 +713,6 @@ int sqlite3GetInt32(const char *zNum, int *pValue){
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if( !sqlite3Isdigit(zNum[0]) ) return 0;
|
||||
while( zNum[0]=='0' ) zNum++;
|
||||
for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
|
||||
v = v*10 + c;
|
||||
|
||||
+1
-1
@@ -201,7 +201,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
|
||||
extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
|
||||
int nKey;
|
||||
char *zKey;
|
||||
sqlite3CodecGetKey(db, iDb, (void**)&zKey, &nKey);
|
||||
sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
|
||||
if( nKey ) db->nextPagesize = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user