Compare commits

..

16 Commits

Author SHA1 Message Date
drh 653b4f6078 Version 3.25.2
FossilOrigin-Name: fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7
2018-09-25 19:08:10 +00:00
dan b67fd17b5f Fix a problem in releasetest.tcl causing configuration "Fast-One" to fail.
FossilOrigin-Name: 32ac0014266706baa4e98de808eb5a6d0ffdb39dc37b4e37668f339e9e238183
2018-09-25 13:52:54 +00:00
drh e4b1eb90b7 Bump the version number to 3.25.2.
FossilOrigin-Name: 996d74f501a45ae12ddc16fe66f849993142e47ccb8b068c412d2ea9bd301ec2
2018-09-25 01:38:00 +00:00
drh 5bc4851d00 Fix a compilation issue in the "userauth" extension. Also fix a few test
script errors that occur with SQLITE_USER_AUTHENTICATION=1 builds.

FossilOrigin-Name: e7db5f59ee62bb8bf61e17a75ecf89f7472fccf68d6d02b892e349142db1f47e
2018-09-25 01:35:17 +00:00
drh 77f136a4a4 Fix a problem building on Android with SQLITE_ENABLE_BATCH_ATOMIC_WRITE set.
FossilOrigin-Name: b9ffa77c92cbc47618da16f412df7745cbf92a7098d3f015724f9b66dca8a2e1
2018-09-25 01:17:50 +00:00
drh 4195437504 Avoid incrementing the SQLITE_LOOKASIDE_MISS_SIZE stat before sqlite3_open()
returns. Fix test script problem in lookaside.test.

FossilOrigin-Name: 3bd94e431783085a22733102218c0fe24a26376033cf9fe4380f6890aba8c79a
2018-09-24 21:07:35 +00:00
drh 75d1119500 Fix missing space in 'configure.ac' reported on the mailing list.
FossilOrigin-Name: 4407e15ac953cca0e33d76bd1e6500d70ae9cb239ea2d776a19a13f59532b3f6
2018-09-24 20:50:14 +00:00
drh ca446b3ccd Add the "PRAGMA legacy_alter_table=ON" command to enable the pre-3.25.0
behavior of ALTER TABLE that does not modify the bodies of triggers or
views or the WHERE clause of a partial index.  Enable the legacy behavior
by default when running the xRename method of virtual tables.

FossilOrigin-Name: 31dc8b191c3b7921f1e9ac1a07854d2bd9e39bc4a20cf2a70a28c41cdb0d0e95
2018-09-24 20:48:20 +00:00
drh d4c1fdafd3 Allow a writable virtual table to have a schema with an INTEGER PRIMARY KEY
and WITHOUT ROWID.  This fixes ticket
[f25d5ceebe1d710ff61a571e395356869d8272ef].  Test case in TH3.

FossilOrigin-Name: 3139af9910e484682d37eeac9dca188a73859b3241017bde31bc6cb597b40d3c
2018-09-24 19:41:12 +00:00
drh 30b281b5dc Fix a faulty assert() in the validation logic for the LEFT JOIN strength
reduction optimization.  Problem found by OSSFuzz.

FossilOrigin-Name: 8694c3d565f6f8209e24230765efa476e10048abb69a300b9df5cbaa45824ab8
2018-09-24 19:32:16 +00:00
drh 579e80cd2f Fix the "sqlite3" command in the TCL interface so that it correctly returns
an error if invoked with no arguments.

FossilOrigin-Name: 8a82fcf05fa84def1433489f71dc28b47c1e082d044512b8756ec1bb4b913fab
2018-09-24 19:21:46 +00:00
drh 8f25fe573b Fix a problem with views that use window functions as part of complex expressions.
FossilOrigin-Name: 1c0ecbbdf1f309feaca747230d8925e61ddc6049a46c1dbbac7344bb933ab5e3
2018-09-24 18:29:21 +00:00
drh aaec593fbc Version 3.25.1
FossilOrigin-Name: 2ac9003de44da7dafa3fbb1915ac5725a9275c86bf2f3b7aa19321bf1460b386
2018-09-18 20:20:44 +00:00
drh ccc6551307 Disable the ORDER BY LIMIT optimization in queries using window functions.
This fixes a problem that was introduced by check-in [206720129ed2fa8875a286]
which attempted to fix ticket [9936b2fa443fec03ff25f9].  This changes is
a fix for the follow-in tocket [510cde277783b5fb5de628].

FossilOrigin-Name: 36c75fd5b7cddb48be74f4f86fafe588b3e597a80d226eeb43b77cbd3817572e
2018-09-17 15:25:21 +00:00
drh 25f801305a Fix a false-positive in the post-ALTER-TABLE schema verification logic that
prevents ALTER TABLE from working if the table being altered has a trigger
that references any column of a virtual table. Ticket [b41031ea2b537237].

FossilOrigin-Name: 5ce568c0e73c8cd258c8fe21e6c5088cfbe3ac017460a014a4b832daecc0cdf7
2018-09-17 14:18:41 +00:00
drh 01191f66f5 Increase the version number to 3.25.1.
FossilOrigin-Name: f3c8cfdb35c6f0786bb21cafcc8c7e751e48a465f3e5a01292399f40e068e1d6
2018-09-17 11:36:20 +00:00
116 changed files with 1034 additions and 6247 deletions
+19 -45
View File
@@ -22,7 +22,7 @@ TOP = @abs_srcdir@
#
BCC = @BUILD_CC@ @BUILD_CFLAGS@
# TCC is the C Compile and options for use in building executables that
# TCC is the C Compile and options for use in building executables that
# will run on the target platform. (BCC and TCC are usually the
# same unless your are cross-compiling.) Separate CC and CFLAGS macros
# are provide so that these aspects of the build process can be changed
@@ -35,7 +35,7 @@ TCC += -I${TOP}/ext/fts3 -I${TOP}/ext/async -I${TOP}/ext/session
# Define this for the autoconf-based build, so that the code knows it can
# include the generated config.h
#
#
TCC += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite
# Define -DNDEBUG to compile without debugging (i.e., for production usage)
@@ -66,7 +66,7 @@ LIBREADLINE = @TARGET_READLINE_LIBS@
TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@
# Any target libraries which libsqlite must be linked against
#
#
TLIBS = @LIBS@ $(LIBS)
# Flags controlling use of the in memory btree implementation
@@ -78,8 +78,8 @@ TLIBS = @LIBS@ $(LIBS)
TEMP_STORE = -DSQLITE_TEMP_STORE=@TEMP_STORE@
# Enable/disable loadable extensions, and other optional features
# based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*).
# The same set of OMIT and ENABLE flags should be passed to the
# based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*).
# The same set of OMIT and ENABLE flags should be passed to the
# LEMON parser generator and the mkkeywordhash tool as well.
OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@
@@ -126,8 +126,8 @@ SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
# If gcov support was enabled by the configure script, add the appropriate
# flags here. It's not always as easy as just having the user add the right
# CFLAGS / LDFLAGS, because libtool wants to use CFLAGS when linking, which
# causes build errors with -fprofile-arcs -ftest-coverage with some GCCs.
# Supposedly GCC does the right thing if you use --coverage, but in
# causes build errors with -fprofile-arcs -ftest-coverage with some GCCs.
# Supposedly GCC does the right thing if you use --coverage, but in
# practice it still fails. See:
#
# http://www.mail-archive.com/debian-gcc@lists.debian.org/msg26197.html
@@ -425,7 +425,7 @@ TESTSRC = \
$(TOP)/ext/fts3/fts3_term.c \
$(TOP)/ext/fts3/fts3_test.c \
$(TOP)/ext/session/test_session.c \
$(TOP)/ext/rbu/test_rbu.c
$(TOP)/ext/rbu/test_rbu.c
# Statically linked extensions
#
@@ -437,7 +437,6 @@ TESTSRC += \
$(TOP)/ext/misc/closure.c \
$(TOP)/ext/misc/csv.c \
$(TOP)/ext/misc/eval.c \
$(TOP)/ext/misc/explain.c \
$(TOP)/ext/misc/fileio.c \
$(TOP)/ext/misc/fuzzer.c \
$(TOP)/ext/fts5/fts5_tcl.c \
@@ -507,7 +506,7 @@ TESTSRC2 = \
$(TOP)/ext/fts3/fts3_write.c \
$(TOP)/ext/async/sqlite3async.c \
$(TOP)/ext/session/sqlite3session.c \
$(TOP)/ext/misc/stmt.c
$(TOP)/ext/misc/stmt.c
# Header files used by all library source files.
#
@@ -579,8 +578,7 @@ FUZZDATA = \
$(TOP)/test/fuzzdata3.db \
$(TOP)/test/fuzzdata4.db \
$(TOP)/test/fuzzdata5.db \
$(TOP)/test/fuzzdata6.db \
$(TOP)/test/fuzzdata7.db
$(TOP)/test/fuzzdata6.db
# Standard options to testfixture
#
@@ -597,14 +595,13 @@ SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_ENABLE_DESERIALIZE
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
DBFUZZ_OPT =
DBFUZZ_OPT =
# This is the default Makefile target. The objects listed here
# are what get build when you type just "make" with no arguments.
@@ -666,22 +663,6 @@ sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h
dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h
$(LTLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS)
DBFUZZ2_OPTS = \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_ENABLE_DESERIALIZE \
-DSQLITE_DEBUG \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_RTREE \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_EANBLE_FTS5
dbfuzz2: $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h
clang-6.0 -I. -g -O0 -fsanitize=fuzzer,undefined -o dbfuzz2 \
$(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c
mkdir -p dbfuzz2-dir
cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir
mptester$(TEXE): sqlite3.lo $(TOP)/mptest/mptest.c
$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \
$(TLIBS) -rpath "$(libdir)"
@@ -1145,7 +1126,7 @@ FTS5_SRC = \
$(TOP)/ext/fts5/fts5_varint.c \
$(TOP)/ext/fts5/fts5_vocab.c \
fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon
fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon
cp $(TOP)/ext/fts5/fts5parse.y .
rm -f fts5parse.h
./lemon$(BEXE) $(OPTS) fts5parse.y
@@ -1172,7 +1153,7 @@ sqlite3rbu.lo: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR)
#
TESTFIXTURE_FLAGS = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit
TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
TESTFIXTURE_FLAGS += -DBUILD_sqlite
TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
@@ -1188,10 +1169,6 @@ testfixture$(TEXE): $(TESTFIXTURE_SRC)
$(LTLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \
-o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS)
coretestprogs: $(TESTPROGS)
testprogs: coretestprogs srcck1$(BEXE) fuzzcheck$(TEXE) sessionfuzz$(TEXE)
# A very detailed test running most or all test cases
fulltest: $(TESTPROGS) fuzztest
./testfixture$(TEXE) $(TOP)/test/all.test $(TESTOPTS)
@@ -1251,7 +1228,7 @@ 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)
sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in
sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in
$(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c
sqltclsh$(TEXE): sqltclsh.c
@@ -1298,9 +1275,6 @@ showshm$(TEXE): $(TOP)/tool/showshm.c
changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.lo
$(LTLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(TLIBS)
changesetfuzz$(TEXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.lo
$(LTLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.lo $(TLIBS)
rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo
$(LTLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(TLIBS)
@@ -1321,7 +1295,7 @@ 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)
rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo
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)
loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la
@@ -1349,7 +1323,7 @@ snapshot-tarball: sqlite3.c
# The next two rules are used to support the "threadtest" target. Building
# threadtest runs a few thread-safety tests that are implemented in C. This
# target is invoked by the releasetest.tcl script.
#
#
THREADTEST3_SRC = $(TOP)/test/threadtest3.c \
$(TOP)/test/tt3_checkpoint.c \
$(TOP)/test/tt3_index.c \
@@ -1363,7 +1337,7 @@ threadtest3$(TEXE): sqlite3.lo $(THREADTEST3_SRC)
threadtest: threadtest3$(TEXE)
./threadtest3$(TEXE)
releasetest:
releasetest:
$(TCLSH_CMD) $(TOP)/test/releasetest.tcl
# Standard install and cleanup targets
@@ -1371,7 +1345,7 @@ releasetest:
lib_install: libsqlite3.la
$(INSTALL) -d $(DESTDIR)$(libdir)
$(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir)
install: sqlite3$(TEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_install}
$(INSTALL) -d $(DESTDIR)$(bindir)
$(LTINSTALL) sqlite3$(TEXE) $(DESTDIR)$(bindir)
@@ -1389,7 +1363,7 @@ tcl_install: lib_install libtclsqlite3.la pkgIndex.tcl
rm -f $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.a
$(INSTALL) -m 0644 pkgIndex.tcl $(DESTDIR)$(TCLLIBDIR)
clean:
clean:
rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la
rm -f sqlite3.h opcodes.*
rm -rf .libs .deps
+1 -13
View File
@@ -1515,7 +1515,6 @@ TESTEXT = \
$(TOP)\ext\misc\closure.c \
$(TOP)\ext\misc\csv.c \
$(TOP)\ext\misc\eval.c \
$(TOP)\ext\misc\explain.c \
$(TOP)\ext\misc\fileio.c \
$(TOP)\ext\misc\fuzzer.c \
$(TOP)\ext\fts5\fts5_tcl.c \
@@ -1623,8 +1622,7 @@ FUZZDATA = \
$(TOP)\test\fuzzdata3.db \
$(TOP)\test\fuzzdata4.db \
$(TOP)\test\fuzzdata5.db \
$(TOP)\test\fuzzdata6.db \
$(TOP)\test\fuzzdata7.db
$(TOP)\test\fuzzdata6.db
# <</mark>>
# Additional compiler options for the shell. These are only effective
@@ -1634,7 +1632,6 @@ FUZZDATA = \
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
# <<mark>>
@@ -2337,10 +2334,6 @@ extensiontest: testfixture.exe testloadext.dll
@set PATH=$(LIBTCLPATH);$(PATH)
.\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS)
coretestprogs: $(TESTPROGS)
testprogs: coretestprogs srcck1.exe fuzzcheck.exe sessionfuzz.exe
fulltest: $(TESTPROGS) fuzztest
@set PATH=$(LIBTCLPATH);$(PATH)
.\testfixture.exe $(TOP)\test\all.test $(TESTOPTS)
@@ -2448,11 +2441,6 @@ changeset.exe: $(TOP)\ext\session\changeset.c $(SQLITE3C) $(SQLITE3H)
-DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 \
$(TOP)\ext\session\changeset.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
changesetfuzz.exe: $(TOP)\ext\session\changesetfuzz.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 \
$(TOP)\ext\session\changesetfuzz.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
fts3view.exe: $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
+1 -1
View File
@@ -1 +1 @@
3.26.0
3.25.2
Vendored
+9 -9
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for sqlite 3.26.0.
# Generated by GNU Autoconf 2.69 for sqlite 3.25.2.
#
#
# 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.26.0'
PACKAGE_STRING='sqlite 3.26.0'
PACKAGE_VERSION='3.25.2'
PACKAGE_STRING='sqlite 3.25.2'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1466,7 +1466,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.26.0 to adapt to many kinds of systems.
\`configure' configures sqlite 3.25.2 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1531,7 +1531,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.26.0:";;
short | recursive ) echo "Configuration of sqlite 3.25.2:";;
esac
cat <<\_ACEOF
@@ -1657,7 +1657,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.26.0
sqlite configure 3.25.2
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2076,7 +2076,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.26.0, which was
It was created by sqlite $as_me 3.25.2, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -12232,7 +12232,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.26.0, which was
This file was extended by sqlite $as_me 3.25.2, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -12298,7 +12298,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.26.0
sqlite config.status 3.25.2
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
+5 -5
View File
@@ -1821,7 +1821,7 @@ static int fts3ScanInteriorNode(
const char *zCsr = zNode; /* Cursor to iterate through node */
const char *zEnd = &zCsr[nNode];/* End of interior node buffer */
char *zBuffer = 0; /* Buffer to load terms into */
i64 nAlloc = 0; /* Size of allocated buffer */
int nAlloc = 0; /* Size of allocated buffer */
int isFirstTerm = 1; /* True when processing first term on page */
sqlite3_int64 iChild; /* Block id of child node to descend to */
@@ -1859,14 +1859,14 @@ static int fts3ScanInteriorNode(
zCsr += fts3GetVarint32(zCsr, &nSuffix);
assert( nPrefix>=0 && nSuffix>=0 );
if( nPrefix>zCsr-zNode || nSuffix>zEnd-zCsr ){
if( &zCsr[nSuffix]>zEnd ){
rc = FTS_CORRUPT_VTAB;
goto finish_scan;
}
if( (i64)nPrefix+nSuffix>nAlloc ){
if( nPrefix+nSuffix>nAlloc ){
char *zNew;
nAlloc = ((i64)nPrefix+nSuffix) * 2;
zNew = (char *)sqlite3_realloc64(zBuffer, nAlloc);
nAlloc = (nPrefix+nSuffix) * 2;
zNew = (char *)sqlite3_realloc(zBuffer, nAlloc);
if( !zNew ){
rc = SQLITE_NOMEM;
goto finish_scan;
+7 -16
View File
@@ -1374,19 +1374,15 @@ static int fts3SegReaderNext(
** safe (no risk of overread) even if the node data is corrupted. */
pNext += fts3GetVarint32(pNext, &nPrefix);
pNext += fts3GetVarint32(pNext, &nSuffix);
if( nSuffix<=0
|| (&pReader->aNode[pReader->nNode] - pNext)<nSuffix
|| nPrefix>pReader->nTermAlloc
if( nPrefix<0 || nSuffix<=0
|| &pNext[nSuffix]>&pReader->aNode[pReader->nNode]
){
return FTS_CORRUPT_VTAB;
}
/* Both nPrefix and nSuffix were read by fts3GetVarint32() and so are
** between 0 and 0x7FFFFFFF. But the sum of the two may cause integer
** overflow - hence the (i64) casts. */
if( (i64)nPrefix+nSuffix>(i64)pReader->nTermAlloc ){
i64 nNew = ((i64)nPrefix+nSuffix)*2;
char *zNew = sqlite3_realloc64(pReader->zTerm, nNew);
if( nPrefix+nSuffix>pReader->nTermAlloc ){
int nNew = (nPrefix+nSuffix)*2;
char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
if( !zNew ){
return SQLITE_NOMEM;
}
@@ -1408,7 +1404,7 @@ static int fts3SegReaderNext(
** b-tree node. And that the final byte of the doclist is 0x00. If either
** of these statements is untrue, then the data structure is corrupt.
*/
if( (&pReader->aNode[pReader->nNode] - pReader->aDoclist)<pReader->nDoclist
if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode]
|| (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
){
return FTS_CORRUPT_VTAB;
@@ -3734,9 +3730,6 @@ static int nodeReaderNext(NodeReader *p){
}
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){
return SQLITE_CORRUPT_VTAB;
}
blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
if( rc==SQLITE_OK ){
memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
@@ -3744,9 +3737,6 @@ static int nodeReaderNext(NodeReader *p){
p->iOff += nSuffix;
if( p->iChild==0 ){
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
if( (p->nNode-p->iOff)<p->nDoclist ){
return SQLITE_CORRUPT_VTAB;
}
p->aDoclist = &p->aNode[p->iOff];
p->iOff += p->nDoclist;
}
@@ -3754,6 +3744,7 @@ static int nodeReaderNext(NodeReader *p){
}
assert( p->iOff<=p->nNode );
return rc;
}
-309
View File
@@ -1,309 +0,0 @@
/*
** 2018-09-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 demonstrates an eponymous virtual table that returns the
** EXPLAIN output from an SQL statement.
**
** Usage example:
**
** .load ./explain
** SELECT p2 FROM explain('SELECT * FROM sqlite_master')
** WHERE opcode='OpenRead';
*/
#if !defined(SQLITEINT_H)
#include "sqlite3ext.h"
#endif
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* explain_vtab is a subclass of sqlite3_vtab which will
** serve as the underlying representation of a explain virtual table
*/
typedef struct explain_vtab explain_vtab;
struct explain_vtab {
sqlite3_vtab base; /* Base class - must be first */
sqlite3 *db; /* Database connection for this explain vtab */
};
/* explain_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 from an EXPLAIN operation.
*/
typedef struct explain_cursor explain_cursor;
struct explain_cursor {
sqlite3_vtab_cursor base; /* Base class - must be first */
sqlite3 *db; /* Database connection for this cursor */
char *zSql; /* Value for the EXPLN_COLUMN_SQL column */
sqlite3_stmt *pExplain; /* Statement being explained */
int rc; /* Result of last sqlite3_step() on pExplain */
};
/*
** The explainConnect() method is invoked to create a new
** explain_vtab that describes the explain virtual table.
**
** Think of this routine as the constructor for explain_vtab objects.
**
** All this routine needs to do is:
**
** (1) Allocate the explain_vtab object and initialize all fields.
**
** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
** result set of queries against explain will look like.
*/
static int explainConnect(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
explain_vtab *pNew;
int rc;
/* Column numbers */
#define EXPLN_COLUMN_ADDR 0 /* Instruction address */
#define EXPLN_COLUMN_OPCODE 1 /* Opcode */
#define EXPLN_COLUMN_P1 2 /* Operand 1 */
#define EXPLN_COLUMN_P2 3 /* Operand 2 */
#define EXPLN_COLUMN_P3 4 /* Operand 3 */
#define EXPLN_COLUMN_P4 5 /* Operand 4 */
#define EXPLN_COLUMN_P5 6 /* Operand 5 */
#define EXPLN_COLUMN_COMMENT 7 /* Comment */
#define EXPLN_COLUMN_SQL 8 /* SQL that is being explained */
rc = sqlite3_declare_vtab(db,
"CREATE TABLE x(addr,opcode,p1,p2,p3,p4,p5,comment,sql HIDDEN)");
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 explain_cursor objects.
*/
static int explainDisconnect(sqlite3_vtab *pVtab){
sqlite3_free(pVtab);
return SQLITE_OK;
}
/*
** Constructor for a new explain_cursor object.
*/
static int explainOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
explain_cursor *pCur;
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
pCur->db = ((explain_vtab*)p)->db;
*ppCursor = &pCur->base;
return SQLITE_OK;
}
/*
** Destructor for a explain_cursor.
*/
static int explainClose(sqlite3_vtab_cursor *cur){
explain_cursor *pCur = (explain_cursor*)cur;
sqlite3_finalize(pCur->pExplain);
sqlite3_free(pCur->zSql);
sqlite3_free(pCur);
return SQLITE_OK;
}
/*
** Advance a explain_cursor to its next row of output.
*/
static int explainNext(sqlite3_vtab_cursor *cur){
explain_cursor *pCur = (explain_cursor*)cur;
pCur->rc = sqlite3_step(pCur->pExplain);
if( pCur->rc!=SQLITE_DONE && pCur->rc!=SQLITE_ROW ) return pCur->rc;
return SQLITE_OK;
}
/*
** Return values of columns for the row at which the explain_cursor
** is currently pointing.
*/
static int explainColumn(
sqlite3_vtab_cursor *cur, /* The cursor */
sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
int i /* Which column to return */
){
explain_cursor *pCur = (explain_cursor*)cur;
if( i==EXPLN_COLUMN_SQL ){
sqlite3_result_text(ctx, pCur->zSql, -1, SQLITE_TRANSIENT);
}else{
sqlite3_result_value(ctx, sqlite3_column_value(pCur->pExplain, i));
}
return SQLITE_OK;
}
/*
** Return the rowid for the current row. In this implementation, the
** rowid is the same as the output value.
*/
static int explainRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
explain_cursor *pCur = (explain_cursor*)cur;
*pRowid = sqlite3_column_int64(pCur->pExplain, 0);
return SQLITE_OK;
}
/*
** Return TRUE if the cursor has been moved off of the last
** row of output.
*/
static int explainEof(sqlite3_vtab_cursor *cur){
explain_cursor *pCur = (explain_cursor*)cur;
return pCur->rc!=SQLITE_ROW;
}
/*
** This method is called to "rewind" the explain_cursor object back
** to the first row of output. This method is always called at least
** once prior to any call to explainColumn() or explainRowid() or
** explainEof().
**
** The argv[0] is the SQL statement that is to be explained.
*/
static int explainFilter(
sqlite3_vtab_cursor *pVtabCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
explain_cursor *pCur = (explain_cursor *)pVtabCursor;
char *zSql = 0;
int rc;
sqlite3_finalize(pCur->pExplain);
pCur->pExplain = 0;
if( sqlite3_value_type(argv[0])!=SQLITE_TEXT ){
pCur->rc = SQLITE_DONE;
return SQLITE_OK;
}
sqlite3_free(pCur->zSql);
pCur->zSql = sqlite3_mprintf("%s", sqlite3_value_text(argv[0]));
if( pCur->zSql ){
zSql = sqlite3_mprintf("EXPLAIN %s", pCur->zSql);
}
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pExplain, 0);
sqlite3_free(zSql);
}
if( rc ){
sqlite3_finalize(pCur->pExplain);
pCur->pExplain = 0;
sqlite3_free(pCur->zSql);
pCur->zSql = 0;
}else{
pCur->rc = sqlite3_step(pCur->pExplain);
rc = (pCur->rc==SQLITE_DONE || pCur->rc==SQLITE_ROW) ? SQLITE_OK : pCur->rc;
}
return rc;
}
/*
** SQLite will invoke this method one or more times while planning a query
** that uses the explain virtual table. This routine needs to create
** a query plan for each invocation and compute an estimated cost for that
** plan.
*/
static int explainBestIndex(
sqlite3_vtab *tab,
sqlite3_index_info *pIdxInfo
){
int i;
pIdxInfo->estimatedCost = (double)1000000;
pIdxInfo->estimatedRows = 500;
for(i=0; i<pIdxInfo->nConstraint; i++){
struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
if( p->usable
&& p->iColumn==EXPLN_COLUMN_SQL
&& p->op==SQLITE_INDEX_CONSTRAINT_EQ
){
pIdxInfo->estimatedCost = 10.0;
pIdxInfo->idxNum = 1;
pIdxInfo->aConstraintUsage[i].argvIndex = 1;
pIdxInfo->aConstraintUsage[i].omit = 1;
break;
}
}
return SQLITE_OK;
}
/*
** This following structure defines all the methods for the
** explain virtual table.
*/
static sqlite3_module explainModule = {
0, /* iVersion */
0, /* xCreate */
explainConnect, /* xConnect */
explainBestIndex, /* xBestIndex */
explainDisconnect, /* xDisconnect */
0, /* xDestroy */
explainOpen, /* xOpen - open a cursor */
explainClose, /* xClose - close a cursor */
explainFilter, /* xFilter - configure scan constraints */
explainNext, /* xNext - advance a cursor */
explainEof, /* xEof - check for end of scan */
explainColumn, /* xColumn - read data */
explainRowid, /* xRowid - read data */
0, /* xUpdate */
0, /* xBegin */
0, /* xSync */
0, /* xCommit */
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
};
#endif /* SQLITE_OMIT_VIRTUALTABLE */
int sqlite3ExplainVtabInit(sqlite3 *db){
int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_VIRTUALTABLE
rc = sqlite3_create_module(db, "explain", &explainModule, 0);
#endif
return rc;
}
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_explain_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
#ifndef SQLITE_OMIT_VIRTUALTABLE
rc = sqlite3ExplainVtabInit(db);
#endif
return rc;
}
-427
View File
@@ -1,427 +0,0 @@
/*
** 2018-09-27
**
** 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
** from sqlite3_status64() and sqlite3_db_status().
**
** Usage example:
**
** .load ./memstat
** .mode quote
** .header on
** SELECT * FROM memstat;
*/
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_MEMSTATVTAB)
#if !defined(SQLITEINT_H)
#include "sqlite3ext.h"
#endif
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* memstat_vtab is a subclass of sqlite3_vtab which will
** serve as the underlying representation of a memstat virtual table
*/
typedef struct memstat_vtab memstat_vtab;
struct memstat_vtab {
sqlite3_vtab base; /* Base class - must be first */
sqlite3 *db; /* Database connection for this memstat vtab */
};
/* memstat_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 memstat_cursor memstat_cursor;
struct memstat_cursor {
sqlite3_vtab_cursor base; /* Base class - must be first */
sqlite3 *db; /* Database connection for this cursor */
int iRowid; /* Current row in aMemstatColumn[] */
int iDb; /* Which schema we are looking at */
int nDb; /* Number of schemas */
char **azDb; /* Names of all schemas */
sqlite3_int64 aVal[2]; /* Result values */
};
/*
** The memstatConnect() method is invoked to create a new
** memstat_vtab that describes the memstat virtual table.
**
** Think of this routine as the constructor for memstat_vtab objects.
**
** All this routine needs to do is:
**
** (1) Allocate the memstat_vtab object and initialize all fields.
**
** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
** result set of queries against memstat will look like.
*/
static int memstatConnect(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
memstat_vtab *pNew;
int rc;
/* Column numbers */
#define MSV_COLUMN_NAME 0 /* Name of quantity being measured */
#define MSV_COLUMN_SCHEMA 1 /* schema name */
#define MSV_COLUMN_VALUE 2 /* Current value */
#define MSV_COLUMN_HIWTR 3 /* Highwater mark */
rc = sqlite3_declare_vtab(db,"CREATE TABLE x(name,schema,value,hiwtr)");
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 memstat_cursor objects.
*/
static int memstatDisconnect(sqlite3_vtab *pVtab){
sqlite3_free(pVtab);
return SQLITE_OK;
}
/*
** Constructor for a new memstat_cursor object.
*/
static int memstatOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
memstat_cursor *pCur;
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
pCur->db = ((memstat_vtab*)p)->db;
*ppCursor = &pCur->base;
return SQLITE_OK;
}
/*
** Clear all the schema names from a cursor
*/
static void memstatClearSchema(memstat_cursor *pCur){
int i;
if( pCur->azDb==0 ) return;
for(i=0; i<pCur->nDb; i++){
sqlite3_free(pCur->azDb[i]);
}
sqlite3_free(pCur->azDb);
pCur->azDb = 0;
pCur->nDb = 0;
}
/*
** Fill in the azDb[] array for the cursor.
*/
static int memstatFindSchemas(memstat_cursor *pCur){
sqlite3_stmt *pStmt = 0;
int rc;
if( pCur->nDb ) return SQLITE_OK;
rc = sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pStmt, 0);
if( rc ){
sqlite3_finalize(pStmt);
return rc;
}
while( sqlite3_step(pStmt)==SQLITE_ROW ){
char **az, *z;
az = sqlite3_realloc(pCur->azDb, sizeof(char*)*(pCur->nDb+1));
if( az==0 ){
memstatClearSchema(pCur);
return SQLITE_NOMEM;
}
pCur->azDb = az;
z = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
if( z==0 ){
memstatClearSchema(pCur);
return SQLITE_NOMEM;
}
pCur->azDb[pCur->nDb] = z;
pCur->nDb++;
}
sqlite3_finalize(pStmt);
return SQLITE_OK;
}
/*
** Destructor for a memstat_cursor.
*/
static int memstatClose(sqlite3_vtab_cursor *cur){
memstat_cursor *pCur = (memstat_cursor*)cur;
memstatClearSchema(pCur);
sqlite3_free(cur);
return SQLITE_OK;
}
/*
** Allowed values for aMemstatColumn[].eType
*/
#define MSV_GSTAT 0 /* sqlite3_status64() information */
#define MSV_DB 1 /* sqlite3_db_status() information */
#define MSV_ZIPVFS 2 /* ZIPVFS file-control with 64-bit return */
/*
** An array of quantities that can be measured and reported by
** this virtual table
*/
static const struct MemstatColumns {
const char *zName; /* Symbolic name */
unsigned char eType; /* Type of interface */
unsigned char mNull; /* Bitmask of which columns are NULL */
/* 2: dbname, 4: current, 8: hiwtr */
int eOp; /* Opcode */
} aMemstatColumn[] = {
{"MEMORY_USED", MSV_GSTAT, 2, SQLITE_STATUS_MEMORY_USED },
{"MALLOC_SIZE", MSV_GSTAT, 6, SQLITE_STATUS_MALLOC_SIZE },
{"MALLOC_COUNT", MSV_GSTAT, 2, SQLITE_STATUS_MALLOC_COUNT },
{"PAGECACHE_USED", MSV_GSTAT, 2, SQLITE_STATUS_PAGECACHE_USED },
{"PAGECACHE_OVERFLOW", MSV_GSTAT, 2, SQLITE_STATUS_PAGECACHE_OVERFLOW },
{"PAGECACHE_SIZE", MSV_GSTAT, 6, SQLITE_STATUS_PAGECACHE_SIZE },
{"PARSER_STACK", MSV_GSTAT, 6, SQLITE_STATUS_PARSER_STACK },
{"DB_LOOKASIDE_USED", MSV_DB, 2, SQLITE_DBSTATUS_LOOKASIDE_USED },
{"DB_LOOKASIDE_HIT", MSV_DB, 6, SQLITE_DBSTATUS_LOOKASIDE_HIT },
{"DB_LOOKASIDE_MISS_SIZE", MSV_DB, 6, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE},
{"DB_LOOKASIDE_MISS_FULL", MSV_DB, 6, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL},
{"DB_CACHE_USED", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_USED },
#if SQLITE_VERSION_NUMBER >= 3140000
{"DB_CACHE_USED_SHARED", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_USED_SHARED },
#endif
{"DB_SCHEMA_USED", MSV_DB, 10, SQLITE_DBSTATUS_SCHEMA_USED },
{"DB_STMT_USED", MSV_DB, 10, SQLITE_DBSTATUS_STMT_USED },
{"DB_CACHE_HIT", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_HIT },
{"DB_CACHE_MISS", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_MISS },
{"DB_CACHE_WRITE", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_WRITE },
#if SQLITE_VERSION_NUMBER >= 3230000
{"DB_CACHE_SPILL", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_SPILL },
#endif
{"DB_DEFERRED_FKS", MSV_DB, 10, SQLITE_DBSTATUS_DEFERRED_FKS },
#ifdef SQLITE_ENABLE_ZIPVFS
{"ZIPVFS_CACHE_USED", MSV_ZIPVFS, 8, 231454 },
{"ZIPVFS_CACHE_HIT", MSV_ZIPVFS, 8, 231455 },
{"ZIPVFS_CACHE_MISS", MSV_ZIPVFS, 8, 231456 },
{"ZIPVFS_CACHE_WRITE", MSV_ZIPVFS, 8, 231457 },
{"ZIPVFS_DIRECT_READ", MSV_ZIPVFS, 8, 231458 },
{"ZIPVFS_DIRECT_BYTES", MSV_ZIPVFS, 8, 231459 },
#endif /* SQLITE_ENABLE_ZIPVFS */
};
#define MSV_NROW (sizeof(aMemstatColumn)/sizeof(aMemstatColumn[0]))
/*
** Advance a memstat_cursor to its next row of output.
*/
static int memstatNext(sqlite3_vtab_cursor *cur){
memstat_cursor *pCur = (memstat_cursor*)cur;
int i;
assert( pCur->iRowid<=MSV_NROW );
while(1){
i = (int)pCur->iRowid - 1;
if( i<0 || (aMemstatColumn[i].mNull & 2)!=0 || (++pCur->iDb)>=pCur->nDb ){
pCur->iRowid++;
if( pCur->iRowid>MSV_NROW ) return SQLITE_OK; /* End of the table */
pCur->iDb = 0;
i++;
}
pCur->aVal[0] = 0;
pCur->aVal[1] = 0;
switch( aMemstatColumn[i].eType ){
case MSV_GSTAT: {
if( sqlite3_libversion_number()>=3010000 ){
sqlite3_status64(aMemstatColumn[i].eOp,
&pCur->aVal[0], &pCur->aVal[1],0);
}else{
int xCur, xHiwtr;
sqlite3_status(aMemstatColumn[i].eOp, &xCur, &xHiwtr, 0);
pCur->aVal[0] = xCur;
pCur->aVal[1] = xHiwtr;
}
break;
}
case MSV_DB: {
int xCur, xHiwtr;
sqlite3_db_status(pCur->db, aMemstatColumn[i].eOp, &xCur, &xHiwtr, 0);
pCur->aVal[0] = xCur;
pCur->aVal[1] = xHiwtr;
break;
}
case MSV_ZIPVFS: {
int rc;
rc = sqlite3_file_control(pCur->db, pCur->azDb[pCur->iDb],
aMemstatColumn[i].eOp, (void*)&pCur->aVal[0]);
if( rc!=SQLITE_OK ) continue;
break;
}
}
break;
}
return SQLITE_OK;
}
/*
** Return values of columns for the row at which the memstat_cursor
** is currently pointing.
*/
static int memstatColumn(
sqlite3_vtab_cursor *cur, /* The cursor */
sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
int iCol /* Which column to return */
){
memstat_cursor *pCur = (memstat_cursor*)cur;
int i;
assert( pCur->iRowid>0 && pCur->iRowid<=MSV_NROW );
i = (int)pCur->iRowid - 1;
if( (aMemstatColumn[i].mNull & (1<<iCol))!=0 ){
return SQLITE_OK;
}
switch( iCol ){
case MSV_COLUMN_NAME: {
sqlite3_result_text(ctx, aMemstatColumn[i].zName, -1, SQLITE_STATIC);
break;
}
case MSV_COLUMN_SCHEMA: {
sqlite3_result_text(ctx, pCur->azDb[pCur->iDb], -1, 0);
break;
}
case MSV_COLUMN_VALUE: {
sqlite3_result_int64(ctx, pCur->aVal[0]);
break;
}
case MSV_COLUMN_HIWTR: {
sqlite3_result_int64(ctx, pCur->aVal[1]);
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 memstatRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
memstat_cursor *pCur = (memstat_cursor*)cur;
*pRowid = pCur->iRowid*1000 + pCur->iDb;
return SQLITE_OK;
}
/*
** Return TRUE if the cursor has been moved off of the last
** row of output.
*/
static int memstatEof(sqlite3_vtab_cursor *cur){
memstat_cursor *pCur = (memstat_cursor*)cur;
return pCur->iRowid>MSV_NROW;
}
/*
** This method is called to "rewind" the memstat_cursor object back
** to the first row of output. This method is always called at least
** once prior to any call to memstatColumn() or memstatRowid() or
** memstatEof().
*/
static int memstatFilter(
sqlite3_vtab_cursor *pVtabCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
memstat_cursor *pCur = (memstat_cursor *)pVtabCursor;
int rc = memstatFindSchemas(pCur);
if( rc ) return rc;
pCur->iRowid = 0;
pCur->iDb = 0;
return memstatNext(pVtabCursor);
}
/*
** SQLite will invoke this method one or more times while planning a query
** that uses the memstat virtual table. This routine needs to create
** a query plan for each invocation and compute an estimated cost for that
** plan.
*/
static int memstatBestIndex(
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
** memstat virtual table.
*/
static sqlite3_module memstatModule = {
0, /* iVersion */
0, /* xCreate */
memstatConnect, /* xConnect */
memstatBestIndex, /* xBestIndex */
memstatDisconnect, /* xDisconnect */
0, /* xDestroy */
memstatOpen, /* xOpen - open a cursor */
memstatClose, /* xClose - close a cursor */
memstatFilter, /* xFilter - configure scan constraints */
memstatNext, /* xNext - advance a cursor */
memstatEof, /* xEof - check for end of scan */
memstatColumn, /* xColumn - read data */
memstatRowid, /* xRowid - read data */
0, /* xUpdate */
0, /* xBegin */
0, /* xSync */
0, /* xCommit */
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
};
#endif /* SQLITE_OMIT_VIRTUALTABLE */
int sqlite3MemstatVtabInit(sqlite3 *db){
int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_VIRTUALTABLE
rc = sqlite3_create_module(db, "sqlite_memstat", &memstatModule, 0);
#endif
return rc;
}
#ifndef SQLITE_CORE
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_memstat_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
#ifndef SQLITE_OMIT_VIRTUALTABLE
rc = sqlite3MemstatVtabInit(db);
#endif
return rc;
}
#endif /* SQLITE_CORE */
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_MEMSTATVTAB) */
+1 -1
View File
@@ -10,7 +10,7 @@
**
******************************************************************************
**
** This SQLite extension implements functions that compute SHA1 hashes.
** This SQLite extension implements a functions that compute SHA1 hashes.
** Two SQL functions are implemented:
**
** sha1(X)
+1 -1
View File
@@ -10,7 +10,7 @@
**
******************************************************************************
**
** This SQLite extension implements functions that compute SHA3 hashes.
** This SQLite extension implements a functions that compute SHA1 hashes.
** Two SQL functions are implemented:
**
** sha3(X,SIZE)
-12
View File
@@ -1295,9 +1295,6 @@ typedef struct Transliteration Transliteration;
struct Transliteration {
unsigned short int cFrom;
unsigned char cTo0, cTo1, cTo2, cTo3;
#ifdef SQLITE_SPELLFIX_5BYTE_MAPPINGS
unsigned char cTo4;
#endif
};
/*
@@ -1711,11 +1708,7 @@ static const Transliteration *spellfixFindTranslit(int c, int *pxTop){
** should be freed by the caller.
*/
static unsigned char *transliterate(const unsigned char *zIn, int nIn){
#ifdef SQLITE_SPELLFIX_5BYTE_MAPPINGS
unsigned char *zOut = sqlite3_malloc64( nIn*5 + 1 );
#else
unsigned char *zOut = sqlite3_malloc64( nIn*4 + 1 );
#endif
int c, sz, nOut;
if( zOut==0 ) return 0;
nOut = 0;
@@ -1739,11 +1732,6 @@ static unsigned char *transliterate(const unsigned char *zIn, int nIn){
zOut[nOut++] = tbl[x].cTo2;
if( tbl[x].cTo3 ){
zOut[nOut++] = tbl[x].cTo3;
#ifdef SQLITE_SPELLFIX_5BYTE_MAPPINGS
if( tbl[x].cTo4 ){
zOut[nOut++] = tbl[x].cTo4;
}
#endif /* SQLITE_SPELLFIX_5BYTE_MAPPINGS */
}
}
}
+26 -74
View File
@@ -405,8 +405,7 @@ struct rbu_vfs {
sqlite3_vfs *pRealVfs; /* Underlying VFS */
sqlite3_mutex *mutex; /* Mutex to protect pMain */
sqlite3rbu *pRbu; /* Owner RBU object */
rbu_file *pMain; /* List of main db files */
rbu_file *pMainRbu; /* List of main db files with pRbu!=0 */
rbu_file *pMain; /* Linked list of main db files */
};
/*
@@ -435,7 +434,6 @@ struct rbu_file {
const char *zWal; /* Wal filename for this main db file */
rbu_file *pWalFd; /* Wal file descriptor for this main db */
rbu_file *pMainNext; /* Next MAIN_DB file */
rbu_file *pMainRbuNext; /* Next MAIN_DB file with pRbu!=0 */
};
/*
@@ -4032,69 +4030,6 @@ static int rbuUpdateTempSize(rbu_file *pFd, sqlite3_int64 nNew){
return SQLITE_OK;
}
/*
** Add an item to the main-db lists, if it is not already present.
**
** There are two main-db lists. One for all file descriptors, and one
** for all file descriptors with rbu_file.pDb!=0. If the argument has
** rbu_file.pDb!=0, then it is assumed to already be present on the
** main list and is only added to the pDb!=0 list.
*/
static void rbuMainlistAdd(rbu_file *p){
rbu_vfs *pRbuVfs = p->pRbuVfs;
rbu_file *pIter;
assert( (p->openFlags & SQLITE_OPEN_MAIN_DB) );
sqlite3_mutex_enter(pRbuVfs->mutex);
if( p->pRbu==0 ){
for(pIter=pRbuVfs->pMain; pIter; pIter=pIter->pMainNext);
p->pMainNext = pRbuVfs->pMain;
pRbuVfs->pMain = p;
}else{
for(pIter=pRbuVfs->pMainRbu; pIter && pIter!=p; pIter=pIter->pMainRbuNext){}
if( pIter==0 ){
p->pMainRbuNext = pRbuVfs->pMainRbu;
pRbuVfs->pMainRbu = p;
}
}
sqlite3_mutex_leave(pRbuVfs->mutex);
}
/*
** Remove an item from the main-db lists.
*/
static void rbuMainlistRemove(rbu_file *p){
rbu_file **pp;
sqlite3_mutex_enter(p->pRbuVfs->mutex);
for(pp=&p->pRbuVfs->pMain; *pp && *pp!=p; pp=&((*pp)->pMainNext)){}
if( *pp ) *pp = p->pMainNext;
p->pMainNext = 0;
for(pp=&p->pRbuVfs->pMainRbu; *pp && *pp!=p; pp=&((*pp)->pMainRbuNext)){}
if( *pp ) *pp = p->pMainRbuNext;
p->pMainRbuNext = 0;
sqlite3_mutex_leave(p->pRbuVfs->mutex);
}
/*
** Given that zWal points to a buffer containing a wal file name passed to
** either the xOpen() or xAccess() VFS method, search the main-db list for
** a file-handle opened by the same database connection on the corresponding
** database file.
**
** If parameter bRbu is true, only search for file-descriptors with
** rbu_file.pDb!=0.
*/
static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal, int bRbu){
rbu_file *pDb;
sqlite3_mutex_enter(pRbuVfs->mutex);
if( bRbu ){
for(pDb=pRbuVfs->pMainRbu; pDb && pDb->zWal!=zWal; pDb=pDb->pMainRbuNext){}
}else{
for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
}
sqlite3_mutex_leave(pRbuVfs->mutex);
return pDb;
}
/*
** Close an rbu file.
*/
@@ -4112,14 +4047,17 @@ static int rbuVfsClose(sqlite3_file *pFile){
sqlite3_free(p->zDel);
if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
rbuMainlistRemove(p);
rbu_file **pp;
sqlite3_mutex_enter(p->pRbuVfs->mutex);
for(pp=&p->pRbuVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext));
*pp = p->pMainNext;
sqlite3_mutex_leave(p->pRbuVfs->mutex);
rbuUnlockShm(p);
p->pReal->pMethods->xShmUnmap(p->pReal, 0);
}
else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){
rbuUpdateTempSize(p, 0);
}
assert( p->pMainNext==0 && p->pRbuVfs->pMain!=p );
/* Close the underlying file handle */
rc = p->pReal->pMethods->xClose(p->pReal);
@@ -4378,9 +4316,6 @@ static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){
}else if( rc==SQLITE_NOTFOUND ){
pRbu->pTargetFd = p;
p->pRbu = pRbu;
if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
rbuMainlistAdd(p);
}
if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
rc = SQLITE_OK;
}
@@ -4542,6 +4477,20 @@ static int rbuVfsShmUnmap(sqlite3_file *pFile, int delFlag){
return rc;
}
/*
** Given that zWal points to a buffer containing a wal file name passed to
** either the xOpen() or xAccess() VFS method, return a pointer to the
** file-handle opened by the same database connection on the corresponding
** database file.
*/
static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){
rbu_file *pDb;
sqlite3_mutex_enter(pRbuVfs->mutex);
for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
sqlite3_mutex_leave(pRbuVfs->mutex);
return pDb;
}
/*
** A main database named zName has just been opened. The following
** function returns a pointer to a buffer owned by SQLite that contains
@@ -4620,7 +4569,7 @@ static int rbuVfsOpen(
pFd->zWal = rbuMainToWal(zName, flags);
}
else if( flags & SQLITE_OPEN_WAL ){
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0);
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName);
if( pDb ){
if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
/* This call is to open a *-wal file. Intead, open the *-oal. This
@@ -4672,7 +4621,10 @@ static int rbuVfsOpen(
** mutex protected linked list of all such files. */
pFile->pMethods = &rbuvfs_io_methods;
if( flags & SQLITE_OPEN_MAIN_DB ){
rbuMainlistAdd(pFd);
sqlite3_mutex_enter(pRbuVfs->mutex);
pFd->pMainNext = pRbuVfs->pMain;
pRbuVfs->pMain = pFd;
sqlite3_mutex_leave(pRbuVfs->mutex);
}
}else{
sqlite3_free(pFd->zDel);
@@ -4720,7 +4672,7 @@ static int rbuVfsAccess(
** file opened instead.
*/
if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1);
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath);
if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
if( *pResOut ){
rc = SQLITE_CANTOPEN;
+31 -168
View File
@@ -106,24 +106,14 @@ typedef float GeoCoord;
**
** encoding (1 byte) 0=big-endian, 1=little-endian
** nvertex (3 bytes) Number of vertexes as a big-endian integer
**
** Enough space is allocated for 4 coordinates, to work around over-zealous
** warnings coming from some compiler (notably, clang). In reality, the size
** of each GeoPoly memory allocate is adjusted as necessary so that the
** GeoPoly.a[] array at the end is the appropriate size.
*/
typedef struct GeoPoly GeoPoly;
struct GeoPoly {
int nVertex; /* Number of vertexes */
unsigned char hdr[4]; /* Header for on-disk representation */
GeoCoord a[8]; /* 2*nVertex values. X (longitude) first, then Y */
GeoCoord a[2]; /* 2*nVertex values. X (longitude) first, then Y */
};
/* The size of a memory allocation needed for a GeoPoly object sufficient
** to hold N coordinate pairs.
*/
#define GEOPOLY_SZ(N) (sizeof(GeoPoly) + sizeof(GeoCoord)*2*((N)-4))
/*
** State of a parse of a GeoJSON input.
*/
@@ -148,7 +138,7 @@ static void geopolySwab32(unsigned char *a){
/* Skip whitespace. Return the next non-whitespace character. */
static char geopolySkipSpace(GeoParse *p){
while( safe_isspace(p->z[0]) ) p->z++;
while( p->z[0] && safe_isspace(p->z[0]) ) p->z++;
return p->z[0];
}
@@ -168,7 +158,7 @@ static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){
if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0;
for(;; j++){
c = z[j];
if( safe_isdigit(c) ) continue;
if( c>='0' && c<='9' ) continue;
if( c=='.' ){
if( z[j-1]=='-' ) return 0;
if( seenDP ) return 0;
@@ -190,17 +180,7 @@ static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){
break;
}
if( z[j-1]<'0' ) return 0;
if( pVal ){
#ifdef SQLITE_AMALGAMATION
/* The sqlite3AtoF() routine is much much faster than atof(), if it
** is available */
double r;
(void)sqlite3AtoF((const char*)p->z, &r, j, SQLITE_UTF8);
*pVal = r;
#else
*pVal = (GeoCoord)atof((const char*)p->z);
#endif
}
if( pVal ) *pVal = (GeoCoord)atof((const char*)p->z);
p->z += j;
return 1;
}
@@ -258,10 +238,12 @@ static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){
&& s.a[1]==s.a[s.nVertex*2-1]
&& (s.z++, geopolySkipSpace(&s)==0)
){
int nByte;
GeoPoly *pOut;
int x = 1;
s.nVertex--; /* Remove the redundant vertex at the end */
pOut = sqlite3_malloc64( GEOPOLY_SZ(s.nVertex) );
nByte = sizeof(GeoPoly) * s.nVertex*2*sizeof(GeoCoord);
pOut = sqlite3_malloc64( nByte );
x = 1;
if( pOut==0 ) goto parse_json_err;
pOut->nVertex = s.nVertex;
@@ -464,27 +446,6 @@ static void geopolyXformFunc(
}
}
/*
** Compute the area enclosed by the polygon.
**
** This routine can also be used to detect polygons that rotate in
** the wrong direction. Polygons are suppose to be counter-clockwise (CCW).
** This routine returns a negative value for clockwise (CW) polygons.
*/
static double geopolyArea(GeoPoly *p){
double rArea = 0.0;
int ii;
for(ii=0; ii<p->nVertex-1; ii++){
rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */
* (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */
* 0.5;
}
rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */
* (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */
* 0.5;
return rArea;
}
/*
** Implementation of the geopoly_area(X) function.
**
@@ -500,106 +461,21 @@ static void geopolyAreaFunc(
){
GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
if( p ){
sqlite3_result_double(context, geopolyArea(p));
sqlite3_free(p);
}
}
/*
** Implementation of the geopoly_ccw(X) function.
**
** If the rotation of polygon X is clockwise (incorrect) instead of
** counter-clockwise (the correct winding order according to RFC7946)
** then reverse the order of the vertexes in polygon X.
**
** In other words, this routine returns a CCW polygon regardless of the
** winding order of its input.
**
** Use this routine to sanitize historical inputs that that sometimes
** contain polygons that wind in the wrong direction.
*/
static void geopolyCcwFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
if( p ){
if( geopolyArea(p)<0.0 ){
int ii, jj;
for(ii=2, jj=p->nVertex*2 - 4; ii<jj; ii+=2, jj-=2){
GeoCoord t = p->a[ii];
p->a[ii] = p->a[jj];
p->a[jj] = t;
t = p->a[ii+1];
p->a[ii+1] = p->a[jj+1];
p->a[jj+1] = t;
}
double rArea = 0.0;
int ii;
for(ii=0; ii<p->nVertex-1; ii++){
rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */
* (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */
* 0.5;
}
sqlite3_result_blob(context, p->hdr,
4+8*p->nVertex, SQLITE_TRANSIENT);
rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */
* (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */
* 0.5;
sqlite3_result_double(context, rArea);
sqlite3_free(p);
}
}
#define GEOPOLY_PI 3.1415926535897932385
/* Fast approximation for cosine(X) for X between -0.5*pi and 2*pi
*/
static double geopolyCosine(double r){
assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI );
if( r>=1.5*GEOPOLY_PI ){
r -= 2.0*GEOPOLY_PI;
}
if( r>=0.5*GEOPOLY_PI ){
return -geopolyCosine(r-GEOPOLY_PI);
}else{
double r2 = r*r;
double r3 = r2*r;
double r5 = r3*r2;
return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5;
}
}
/*
** Function: geopoly_regular(X,Y,R,N)
**
** Construct a simple, convex, regular polygon centered at X, Y
** with circumradius R and with N sides.
*/
static void geopolyRegularFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
double x = sqlite3_value_double(argv[0]);
double y = sqlite3_value_double(argv[1]);
double r = sqlite3_value_double(argv[2]);
int n = sqlite3_value_int(argv[3]);
int i;
GeoPoly *p;
if( n<3 || r<=0.0 ) return;
if( n>1000 ) n = 1000;
p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) );
if( p==0 ){
sqlite3_result_error_nomem(context);
return;
}
i = 1;
p->hdr[0] = *(unsigned char*)&i;
p->hdr[1] = 0;
p->hdr[2] = (n>>8)&0xff;
p->hdr[3] = n&0xff;
for(i=0; i<n; i++){
double rAngle = 2.0*GEOPOLY_PI*i/n;
p->a[i*2] = x - r*geopolyCosine(rAngle-0.5*GEOPOLY_PI);
p->a[i*2+1] = y + r*geopolyCosine(rAngle);
}
sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT);
sqlite3_free(p);
}
/*
** If pPoly is a polygon, compute its bounding box. Then:
**
@@ -644,7 +520,7 @@ static GeoPoly *geopolyBBox(
if( pRc ) *pRc = SQLITE_OK;
if( aCoord==0 ){
geopolyBboxFill:
pOut = sqlite3_realloc(p, GEOPOLY_SZ(4));
pOut = sqlite3_realloc(p, sizeof(GeoPoly)+sizeof(GeoCoord)*6);
if( pOut==0 ){
sqlite3_free(p);
if( context ) sqlite3_result_error_nomem(context);
@@ -1672,16 +1548,7 @@ static int geopolyUpdate(
if( sqlite3_value_nochange(aData[2]) ){
sqlite3_bind_null(pUp, 2);
}else{
GeoPoly *p = 0;
if( sqlite3_value_type(aData[2])==SQLITE_TEXT
&& (p = geopolyFuncParam(0, aData[2], &rc))!=0
&& rc==SQLITE_OK
){
sqlite3_bind_blob(pUp, 2, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT);
}else{
sqlite3_bind_value(pUp, 2, aData[2]);
}
sqlite3_free(p);
sqlite3_bind_value(pUp, 2, aData[2]);
nChange = 1;
}
for(jj=1; jj<pRtree->nAux; jj++){
@@ -1754,22 +1621,19 @@ static int sqlite3_geopoly_init(sqlite3 *db){
int rc = SQLITE_OK;
static const struct {
void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
signed char nArg;
unsigned char bPure;
int nArg;
const char *zName;
} aFunc[] = {
{ geopolyAreaFunc, 1, 1, "geopoly_area" },
{ geopolyBlobFunc, 1, 1, "geopoly_blob" },
{ geopolyJsonFunc, 1, 1, "geopoly_json" },
{ geopolySvgFunc, -1, 1, "geopoly_svg" },
{ geopolyWithinFunc, 2, 1, "geopoly_within" },
{ geopolyContainsPointFunc, 3, 1, "geopoly_contains_point" },
{ geopolyOverlapFunc, 2, 1, "geopoly_overlap" },
{ geopolyDebugFunc, 1, 0, "geopoly_debug" },
{ geopolyBBoxFunc, 1, 1, "geopoly_bbox" },
{ geopolyXformFunc, 7, 1, "geopoly_xform" },
{ geopolyRegularFunc, 4, 1, "geopoly_regular" },
{ geopolyCcwFunc, 1, 1, "geopoly_ccw" },
{ geopolyAreaFunc, 1, "geopoly_area" },
{ geopolyBlobFunc, 1, "geopoly_blob" },
{ geopolyJsonFunc, 1, "geopoly_json" },
{ geopolySvgFunc, -1, "geopoly_svg" },
{ geopolyWithinFunc, 2, "geopoly_within" },
{ geopolyContainsPointFunc, 3, "geopoly_contains_point" },
{ geopolyOverlapFunc, 2, "geopoly_overlap" },
{ geopolyDebugFunc, 1, "geopoly_debug" },
{ geopolyBBoxFunc, 1, "geopoly_bbox" },
{ geopolyXformFunc, 7, "geopoly_xform" },
};
static const struct {
void (*xStep)(sqlite3_context*,int,sqlite3_value**);
@@ -1780,9 +1644,8 @@ static int sqlite3_geopoly_init(sqlite3 *db){
};
int i;
for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
int enc = aFunc[i].bPure ? SQLITE_UTF8|SQLITE_DETERMINISTIC : SQLITE_UTF8;
rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
enc, 0,
SQLITE_UTF8, 0,
aFunc[i].xFunc, 0, 0);
}
for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
-13
View File
@@ -586,17 +586,4 @@ SELECT geopoly_svg(poly,'style="fill:none;stroke:black;stroke-width:2"')
ROLLBACK;
.print '</svg>'
.print '<h1>Regular Polygons</h1>'
.print '<svg width="1000" height="200" style="border:1px solid black">'
SELECT geopoly_svg(geopoly_regular(100,100,40,3),'style="fill:none;stroke:red;stroke-width:1"');
SELECT geopoly_svg(geopoly_regular(200,100,40,4),'style="fill:none;stroke:orange;stroke-width:1"');
SELECT geopoly_svg(geopoly_regular(300,100,40,5),'style="fill:none;stroke:green;stroke-width:1"');
SELECT geopoly_svg(geopoly_regular(400,100,40,6),'style="fill:none;stroke:blue;stroke-width:1"');
SELECT geopoly_svg(geopoly_regular(500,100,40,7),'style="fill:none;stroke:purple;stroke-width:1"');
SELECT geopoly_svg(geopoly_regular(600,100,40,8),'style="fill:none;stroke:red;stroke-width:1"');
SELECT geopoly_svg(geopoly_regular(700,100,40,10),'style="fill:none;stroke:orange;stroke-width:1"');
SELECT geopoly_svg(geopoly_regular(800,100,40,20),'style="fill:none;stroke:green;stroke-width:1"');
SELECT geopoly_svg(geopoly_regular(900,100,40,30),'style="fill:none;stroke:blue;stroke-width:1"');
.print '</svg>'
.print '</html>'
File diff suppressed because it is too large Load Diff
-84
View File
@@ -1,84 +0,0 @@
# 2018 November 08
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
if {![info exists testdir]} {
set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl
ifcapable !session {finish_test; return}
set testprefix changesetfuzz1
set CF [test_find_binary changesetfuzz]
if {$CF==""} {
finish_test
return
}
proc writefile {zFile data} {
set fd [open $zFile w]
fconfigure $fd -translation binary -encoding binary
puts -nonewline $fd $data
close $fd
}
do_execsql_test 1.0 {
CREATE TABLE t1(a, b, c, d, PRIMARY KEY(c, d));
CREATE TABLE t2(a INTEGER PRIMARY KEY, b, c);
INSERT INTO t1 VALUES ('one', 'two', 'three', 'four'),
('five', 'six', 'seven', 'eight'),
('nine', 'ten', 'eleven', 'twelve');
INSERT INTO t2 VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9);
}
set C [changeset_from_sql {
INSERT INTO t2 VALUES(10, 11, 12);
DELETE FROM t2 WHERE a=1;
UPDATE t1 SET b='forty-five' WHERE a='one';
UPDATE t1 SET a='twenty-nine', b='seventy' WHERE a='five';
}]
writefile c1.changeset $C
do_test 1.1 {
for {set j 0} {$j < 200} {incr j} {
forcecopy c1.changeset input.changeset
for {set i 0} {$i < 6} {incr i} {
exec $CF input.changeset $i 1
exec $CF input.changeset-0
forcecopy input.changeset-0 input.changeset
}
}
} {}
set P [patchset_from_sql {
INSERT INTO t2 VALUES(13, 14, 15);
DELETE FROM t2 WHERE a=4;
UPDATE t1 SET b='thirteen' WHERE a='one';
UPDATE t1 SET a='ninety-seven', b='twenty' WHERE a='five';
}]
writefile p1.patchset $P
do_test 1.2 {
for {set j 0} {$j < 200} {incr j} {
forcecopy p1.patchset input.patchset
for {set i 0} {$i < 6} {incr i} {
exec $CF input.patchset $i 1
exec $CF input.patchset-0
forcecopy input.patchset-0 input.patchset
}
}
} {}
finish_test
-7
View File
@@ -655,13 +655,6 @@ do_test $tn.13.3 {
} {1 one 2 two 3 iii}
execsql ROLLBACK
do_test $tn.14.1 { sqlite3session_config strm_size -1 } 64
do_test $tn.14.2 { sqlite3session_config strm_size 65536 } 65536
do_test $tn.14.3 { sqlite3session_config strm_size 64 } 64
do_test $tn.14.4 {
list [catch {sqlite3session_config invalid 123} msg] $msg
} {1 SQLITE_MISUSE}
}]
}
-17
View File
@@ -95,23 +95,6 @@ proc changeset_from_sql {sql {dbname main}} {
return $changeset
}
proc patchset_from_sql {sql {dbname main}} {
set rc [catch {
sqlite3session S db $dbname
db eval "SELECT name FROM $dbname.sqlite_master WHERE type = 'table'" {
S attach $name
}
db eval $sql
S patchset
} patchset]
catch { S delete }
if {$rc} {
error $patchset
}
return $patchset
}
proc do_then_apply_sql {sql {dbname main}} {
proc xConflict args { return "OMIT" }
set rc [catch {
-159
View File
@@ -1,159 +0,0 @@
# 2018 October 18
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
if {![info exists testdir]} {
set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl
ifcapable !session {finish_test; return}
set testprefix sessioninvert
proc iter_invert {C} {
set x [list]
sqlite3session_foreach -invert c $C { lappend x $c }
set x
}
proc do_invert_test {tn sql {iter {}}} {
forcecopy test.db test.db2
sqlite3 db2 test.db2
set C [changeset_from_sql $sql]
forcecopy test.db test.db3
sqlite3 db3 test.db3
uplevel [list do_test $tn.1 [list compare_db db db3] {}]
set I [sqlite3changeset_invert $C]
sqlite3changeset_apply db $I {}
uplevel [list do_test $tn.2 [list compare_db db db2] {}]
sqlite3changeset_apply_v2 -invert db3 $C {}
uplevel [list do_test $tn.3 [list compare_db db db3] {}]
if {$iter!=""} {
uplevel [list do_test $tn.4 [list iter_invert $C] [list {*}$iter]]
}
catch { db2 close }
catch { db3 close }
}
do_execsql_test 1.0 {
CREATE TABLE t1(a PRIMARY KEY, b, c);
CREATE TABLE t2(d, e, f, PRIMARY KEY(e, f));
INSERT INTO t1 VALUES(1, 'one', 'i');
INSERT INTO t1 VALUES(2, 'two', 'ii');
INSERT INTO t1 VALUES(3, 'three', 'iii');
INSERT INTO t1 VALUES(4, 'four', 'iv');
INSERT INTO t1 VALUES(5, 'five', 'v');
INSERT INTO t1 VALUES(6, 'six', 'vi');
INSERT INTO t2 SELECT * FROM t1;
}
do_invert_test 1.1 {
INSERT INTO t1 VALUES(7, 'seven', 'vii');
} {
{DELETE t1 0 X.. {i 7 t seven t vii} {}}
}
do_invert_test 1.2 {
DELETE FROM t1 WHERE a<4;
} {
{INSERT t1 0 X.. {} {i 1 t one t i}}
{INSERT t1 0 X.. {} {i 2 t two t ii}}
{INSERT t1 0 X.. {} {i 3 t three t iii}}
}
do_invert_test 1.3 {
UPDATE t1 SET c=5;
} {
{UPDATE t1 0 X.. {i 1 {} {} i 5} {{} {} {} {} t i}}
{UPDATE t1 0 X.. {i 2 {} {} i 5} {{} {} {} {} t ii}}
{UPDATE t1 0 X.. {i 3 {} {} i 5} {{} {} {} {} t iii}}
{UPDATE t1 0 X.. {i 4 {} {} i 5} {{} {} {} {} t iv}}
{UPDATE t1 0 X.. {i 5 {} {} i 5} {{} {} {} {} t v}}
{UPDATE t1 0 X.. {i 6 {} {} i 5} {{} {} {} {} t vi}}
}
do_invert_test 1.4 {
UPDATE t1 SET b = a+1 WHERE a%2;
DELETE FROM t2;
INSERT INTO t1 VALUES(10, 'ten', NULL);
}
do_invert_test 1.5 {
UPDATE t2 SET d = d-1;
} {
{UPDATE t2 0 .XX {i 2 t three t iii} {i 3 {} {} {} {}}}
{UPDATE t2 0 .XX {i 1 t two t ii} {i 2 {} {} {} {}}}
{UPDATE t2 0 .XX {i 5 t six t vi} {i 6 {} {} {} {}}}
{UPDATE t2 0 .XX {i 3 t four t iv} {i 4 {} {} {} {}}}
{UPDATE t2 0 .XX {i 0 t one t i} {i 1 {} {} {} {}}}
{UPDATE t2 0 .XX {i 4 t five t v} {i 5 {} {} {} {}}}
}
do_execsql_test 2.0 {
ANALYZE;
PRAGMA writable_schema = 1;
DROP TABLE IF EXISTS sqlite_stat4;
SELECT * FROM sqlite_stat1;
} {
t2 sqlite_autoindex_t2_1 {6 1 1}
t1 sqlite_autoindex_t1_1 {6 1}
}
do_invert_test 2.1 {
INSERT INTO sqlite_stat1 VALUES('t3', 'idx2', '1 2 3');
} {
{DELETE sqlite_stat1 0 XX. {t t3 t idx2 t {1 2 3}} {}}
}
do_invert_test 2.2 {
DELETE FROM sqlite_stat1;
} {
{INSERT sqlite_stat1 0 XX. {} {t t1 t sqlite_autoindex_t1_1 t {6 1}}}
{INSERT sqlite_stat1 0 XX. {} {t t2 t sqlite_autoindex_t2_1 t {6 1 1}}}
}
do_invert_test 2.3 {
UPDATE sqlite_stat1 SET stat = 'hello world';
}
do_test 3.0 {
forcecopy test.db test.db2
sqlite3 db2 test.db2
set P [patchset_from_sql {
INSERT INTO t2 VALUES(1, 2, 3);
DELETE FROM t2 WHERE d = 3;
}]
list [catch { sqlite3changeset_apply_v2 -invert db2 $P {} } msg] $msg
} {1 SQLITE_CORRUPT}
do_test 3.1 {
list [catch { sqlite3session_foreach -invert db2 $P {} } msg] $msg
} {1 SQLITE_CORRUPT}
do_test 3.2 {
sqlite3changeset_apply_v2 db2 $P {}
compare_db db db2
} {}
finish_test
+56 -147
View File
@@ -25,8 +25,6 @@ typedef struct SessionInput SessionInput;
# endif
#endif
static int sessions_strm_chunk_size = SESSIONS_STRM_CHUNK_SIZE;
typedef struct SessionHook SessionHook;
struct SessionHook {
void *pCtx;
@@ -89,7 +87,6 @@ struct sqlite3_changeset_iter {
SessionInput in; /* Input buffer or stream */
SessionBuffer tblhdr; /* Buffer to hold apValue/zTab/abPK/ */
int bPatchset; /* True if this is a patchset */
int bInvert; /* True to invert changeset */
int rc; /* Iterator error code */
sqlite3_stmt *pConflict; /* Points to conflicting row, if any */
char *zTab; /* Current table */
@@ -246,42 +243,6 @@ struct SessionTable {
** The records associated with INSERT changes are in the same format as for
** changesets. It is not possible for a record associated with an INSERT
** change to contain a field set to "undefined".
**
** REBASE BLOB FORMAT:
**
** A rebase blob may be output by sqlite3changeset_apply_v2() and its
** streaming equivalent for use with the sqlite3_rebaser APIs to rebase
** existing changesets. A rebase blob contains one entry for each conflict
** resolved using either the OMIT or REPLACE strategies within the apply_v2()
** call.
**
** The format used for a rebase blob is very similar to that used for
** changesets. All entries related to a single table are grouped together.
**
** Each group of entries begins with a table header in changeset format:
**
** 1 byte: Constant 0x54 (capital 'T')
** Varint: Number of columns in the table.
** nCol bytes: 0x01 for PK columns, 0x00 otherwise.
** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
**
** Followed by one or more entries associated with the table.
**
** 1 byte: Either SQLITE_INSERT (0x12), DELETE (0x09).
** 1 byte: Flag. 0x01 for REPLACE, 0x00 for OMIT.
** record: (in the record format defined above).
**
** In a rebase blob, the first field is set to SQLITE_INSERT if the change
** that caused the conflict was an INSERT or UPDATE, or to SQLITE_DELETE if
** it was a DELETE. The second field is set to 0x01 if the conflict
** resolution strategy was REPLACE, or 0x00 if it was OMIT.
**
** If the change that caused the conflict was a DELETE, then the single
** record is a copy of the old.* record from the original changeset. If it
** was an INSERT, then the single record is a copy of the new.* record. If
** the conflicting change was an UPDATE, then the single record is a copy
** of the new.* record with the PK fields filled in based on the original
** old.* record.
*/
/*
@@ -1832,12 +1793,12 @@ int sqlite3session_attach(
static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
if( *pRc==SQLITE_OK && p->nAlloc-p->nBuf<nByte ){
u8 *aNew;
i64 nNew = p->nAlloc ? p->nAlloc : 128;
int nNew = p->nAlloc ? p->nAlloc : 128;
do {
nNew = nNew*2;
}while( (nNew-p->nBuf)<nByte );
}while( nNew<(p->nBuf+nByte) );
aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew);
aNew = (u8 *)sqlite3_realloc(p->aBuf, nNew);
if( 0==aNew ){
*pRc = SQLITE_NOMEM;
}else{
@@ -2435,12 +2396,12 @@ static int sessionGenerateChangeset(
rc = sqlite3_reset(pSel);
}
/* If the buffer is now larger than sessions_strm_chunk_size, pass
/* If the buffer is now larger than SESSIONS_STRM_CHUNK_SIZE, pass
** its contents to the xOutput() callback. */
if( xOutput
&& rc==SQLITE_OK
&& buf.nBuf>nNoop
&& buf.nBuf>sessions_strm_chunk_size
&& buf.nBuf>SESSIONS_STRM_CHUNK_SIZE
){
rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
nNoop = -1;
@@ -2579,8 +2540,7 @@ static int sessionChangesetStart(
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn,
int nChangeset, /* Size of buffer pChangeset in bytes */
void *pChangeset, /* Pointer to buffer containing changeset */
int bInvert /* True to invert changeset */
void *pChangeset /* Pointer to buffer containing changeset */
){
sqlite3_changeset_iter *pRet; /* Iterator to return */
int nByte; /* Number of bytes to allocate for iterator */
@@ -2600,7 +2560,6 @@ static int sessionChangesetStart(
pRet->in.xInput = xInput;
pRet->in.pIn = pIn;
pRet->in.bEof = (xInput ? 0 : 1);
pRet->bInvert = bInvert;
/* Populate the output variable and return success. */
*pp = pRet;
@@ -2615,16 +2574,7 @@ int sqlite3changeset_start(
int nChangeset, /* Size of buffer pChangeset in bytes */
void *pChangeset /* Pointer to buffer containing changeset */
){
return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0);
}
int sqlite3changeset_start_v2(
sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
int nChangeset, /* Size of buffer pChangeset in bytes */
void *pChangeset, /* Pointer to buffer containing changeset */
int flags
){
int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert);
return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset);
}
/*
@@ -2635,16 +2585,7 @@ int sqlite3changeset_start_strm(
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn
){
return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0);
}
int sqlite3changeset_start_v2_strm(
sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn,
int flags
){
int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert);
return sessionChangesetStart(pp, xInput, pIn, 0, 0);
}
/*
@@ -2652,7 +2593,7 @@ int sqlite3changeset_start_v2_strm(
** object and the buffer is full, discard some data to free up space.
*/
static void sessionDiscardData(SessionInput *pIn){
if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){
if( pIn->xInput && pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){
int nMove = pIn->buf.nBuf - pIn->iNext;
assert( nMove>=0 );
if( nMove>0 ){
@@ -2675,7 +2616,7 @@ static int sessionInputBuffer(SessionInput *pIn, int nByte){
int rc = SQLITE_OK;
if( pIn->xInput ){
while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){
int nNew = sessions_strm_chunk_size;
int nNew = SESSIONS_STRM_CHUNK_SIZE;
if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn);
if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){
@@ -3023,10 +2964,10 @@ static int sessionChangesetNext(
op = p->in.aData[p->in.iNext++];
}
if( p->zTab==0 || (p->bPatchset && p->bInvert) ){
if( p->zTab==0 ){
/* The first record in the changeset is not a table header. Must be a
** corrupt changeset. */
assert( p->in.iNext==1 || p->zTab );
assert( p->in.iNext==1 );
return (p->rc = SQLITE_CORRUPT_BKPT);
}
@@ -3051,39 +2992,33 @@ static int sessionChangesetNext(
*paRec = &p->in.aData[p->in.iNext];
p->in.iNext += *pnRec;
}else{
sqlite3_value **apOld = (p->bInvert ? &p->apValue[p->nCol] : p->apValue);
sqlite3_value **apNew = (p->bInvert ? p->apValue : &p->apValue[p->nCol]);
/* If this is an UPDATE or DELETE, read the old.* record. */
if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){
u8 *abPK = p->bPatchset ? p->abPK : 0;
p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld);
p->rc = sessionReadRecord(&p->in, p->nCol, abPK, p->apValue);
if( p->rc!=SQLITE_OK ) return p->rc;
}
/* If this is an INSERT or UPDATE, read the new.* record. */
if( p->op!=SQLITE_DELETE ){
p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew);
p->rc = sessionReadRecord(&p->in, p->nCol, 0, &p->apValue[p->nCol]);
if( p->rc!=SQLITE_OK ) return p->rc;
}
if( (p->bPatchset || p->bInvert) && p->op==SQLITE_UPDATE ){
if( p->bPatchset && p->op==SQLITE_UPDATE ){
/* If this is an UPDATE that is part of a patchset, then all PK and
** modified fields are present in the new.* record. The old.* record
** is currently completely empty. This block shifts the PK fields from
** new.* to old.*, to accommodate the code that reads these arrays. */
for(i=0; i<p->nCol; i++){
assert( p->bPatchset==0 || p->apValue[i]==0 );
assert( p->apValue[i]==0 );
if( p->abPK[i] ){
assert( p->apValue[i]==0 );
p->apValue[i] = p->apValue[i+p->nCol];
if( p->apValue[i]==0 ) return (p->rc = SQLITE_CORRUPT_BKPT);
p->apValue[i+p->nCol] = 0;
}
}
}else if( p->bInvert ){
if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE;
else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT;
}
}
@@ -3400,7 +3335,7 @@ static int sessionChangesetInvert(
}
assert( rc==SQLITE_OK );
if( xOutput && sOut.nBuf>=sessions_strm_chunk_size ){
if( xOutput && sOut.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
sOut.nBuf = 0;
if( rc!=SQLITE_OK ) goto finished_invert;
@@ -3479,8 +3414,7 @@ struct SessionApplyCtx {
int bDeferConstraints; /* True to defer constraints */
SessionBuffer constraints; /* Deferred constraints are stored here */
SessionBuffer rebase; /* Rebase information (if any) here */
u8 bRebaseStarted; /* If table header is already in rebase */
u8 bRebase; /* True to collect rebase information */
int bRebaseStarted; /* If table header is already in rebase */
};
/*
@@ -3877,36 +3811,35 @@ static int sessionRebaseAdd(
sqlite3_changeset_iter *pIter /* Iterator pointing at current change */
){
int rc = SQLITE_OK;
if( p->bRebase ){
int i;
int eOp = pIter->op;
if( p->bRebaseStarted==0 ){
/* Append a table-header to the rebase buffer */
const char *zTab = pIter->zTab;
sessionAppendByte(&p->rebase, 'T', &rc);
sessionAppendVarint(&p->rebase, p->nCol, &rc);
sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc);
sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc);
p->bRebaseStarted = 1;
}
assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT );
assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE );
sessionAppendByte(&p->rebase,
(eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc
);
sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc);
for(i=0; i<p->nCol; i++){
sqlite3_value *pVal = 0;
if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){
sqlite3changeset_old(pIter, i, &pVal);
}else{
sqlite3changeset_new(pIter, i, &pVal);
}
sessionAppendValue(&p->rebase, pVal, &rc);
}
int i;
int eOp = pIter->op;
if( p->bRebaseStarted==0 ){
/* Append a table-header to the rebase buffer */
const char *zTab = pIter->zTab;
sessionAppendByte(&p->rebase, 'T', &rc);
sessionAppendVarint(&p->rebase, p->nCol, &rc);
sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc);
sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc);
p->bRebaseStarted = 1;
}
assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT );
assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE );
sessionAppendByte(&p->rebase,
(eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc
);
sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc);
for(i=0; i<p->nCol; i++){
sqlite3_value *pVal = 0;
if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){
sqlite3changeset_old(pIter, i, &pVal);
}else{
sqlite3changeset_new(pIter, i, &pVal);
}
sessionAppendValue(&p->rebase, pVal, &rc);
}
return rc;
}
@@ -4249,7 +4182,7 @@ static int sessionRetryConstraints(
SessionBuffer cons = pApply->constraints;
memset(&pApply->constraints, 0, sizeof(SessionBuffer));
rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf, 0);
rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf);
if( rc==SQLITE_OK ){
int nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
int rc2;
@@ -4315,7 +4248,6 @@ static int sessionChangesetApply(
pIter->in.bNoDiscard = 1;
memset(&sApply, 0, sizeof(sApply));
sApply.bRebase = (ppRebase && pnRebase);
sqlite3_mutex_enter(sqlite3_db_mutex(db));
if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
@@ -4466,8 +4398,7 @@ static int sessionChangesetApply(
}
}
assert( sApply.bRebase || sApply.rebase.nBuf==0 );
if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
if( rc==SQLITE_OK && bPatchset==0 && ppRebase && pnRebase ){
*ppRebase = (void*)sApply.rebase.aBuf;
*pnRebase = sApply.rebase.nBuf;
sApply.rebase.aBuf = 0;
@@ -4505,8 +4436,7 @@ int sqlite3changeset_apply_v2(
int flags
){
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset,bInverse);
int rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset);
if( rc==SQLITE_OK ){
rc = sessionChangesetApply(
db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
@@ -4563,8 +4493,7 @@ int sqlite3changeset_apply_v2_strm(
int flags
){
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse);
int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
if( rc==SQLITE_OK ){
rc = sessionChangesetApply(
db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
@@ -4937,12 +4866,13 @@ static int sessionChangegroupOutput(
sessionAppendByte(&buf, p->op, &rc);
sessionAppendByte(&buf, p->bIndirect, &rc);
sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc);
if( rc==SQLITE_OK && xOutput && buf.nBuf>=sessions_strm_chunk_size ){
rc = xOutput(pOut, buf.aBuf, buf.nBuf);
buf.nBuf = 0;
}
}
}
if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
rc = xOutput(pOut, buf.aBuf, buf.nBuf);
buf.nBuf = 0;
}
}
if( rc==SQLITE_OK ){
@@ -5333,7 +5263,7 @@ static int sessionRebase(
sessionAppendByte(&sOut, pIter->bIndirect, &rc);
sessionAppendBlob(&sOut, aRec, nRec, &rc);
}
if( rc==SQLITE_OK && xOutput && sOut.nBuf>sessions_strm_chunk_size ){
if( rc==SQLITE_OK && xOutput && sOut.nBuf>SESSIONS_STRM_CHUNK_SIZE ){
rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
sOut.nBuf = 0;
}
@@ -5444,25 +5374,4 @@ void sqlite3rebaser_delete(sqlite3_rebaser *p){
}
}
/*
** Global configuration
*/
int sqlite3session_config(int op, void *pArg){
int rc = SQLITE_OK;
switch( op ){
case SQLITE_SESSION_CONFIG_STRMSIZE: {
int *pInt = (int*)pArg;
if( *pInt>0 ){
sessions_strm_chunk_size = *pInt;
}
*pInt = sessions_strm_chunk_size;
break;
}
default:
rc = SQLITE_MISUSE;
break;
}
return rc;
}
#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
+1 -78
View File
@@ -473,38 +473,12 @@ int sqlite3session_isempty(sqlite3_session *pSession);
** consecutively. There is no chance that the iterator will visit a change
** the applies to table X, then one for table Y, and then later on visit
** another change for table X.
**
** The behavior of sqlite3changeset_start_v2() and its streaming equivalent
** may be modified by passing a combination of
** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter.
**
** Note that the sqlite3changeset_start_v2() API is still <b>experimental</b>
** and therefore subject to change.
*/
int sqlite3changeset_start(
sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
int nChangeset, /* Size of changeset blob in bytes */
void *pChangeset /* Pointer to blob containing changeset */
);
int sqlite3changeset_start_v2(
sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
int nChangeset, /* Size of changeset blob in bytes */
void *pChangeset, /* Pointer to blob containing changeset */
int flags /* SESSION_CHANGESETSTART_* flags */
);
/*
** CAPI3REF: Flags for sqlite3changeset_start_v2
**
** The following flags may passed via the 4th parameter to
** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]:
**
** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
** Invert the changeset while iterating through it. This is equivalent to
** inverting a changeset using sqlite3changeset_invert() before applying it.
** It is an error to specify this flag with a patchset.
*/
#define SQLITE_CHANGESETSTART_INVERT 0x0002
/*
@@ -1159,7 +1133,7 @@ int sqlite3changeset_apply_v2(
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
int flags /* SESSION_CHANGESETAPPLY_* flags */
int flags /* Combination of SESSION_APPLY_* flags */
);
/*
@@ -1177,14 +1151,8 @@ int sqlite3changeset_apply_v2(
** causes the sessions module to omit this savepoint. In this case, if the
** caller has an open transaction or savepoint when apply_v2() is called,
** it may revert the partially applied changeset by rolling it back.
**
** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
** Invert the changeset before applying it. This is equivalent to inverting
** a changeset using sqlite3changeset_invert() before applying it. It is
** an error to specify this flag with a patchset.
*/
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
#define SQLITE_CHANGESETAPPLY_INVERT 0x0002
/*
** CAPI3REF: Constants Passed To The Conflict Handler
@@ -1578,12 +1546,6 @@ int sqlite3changeset_start_strm(
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn
);
int sqlite3changeset_start_v2_strm(
sqlite3_changeset_iter **pp,
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn,
int flags
);
int sqlite3session_changeset_strm(
sqlite3_session *pSession,
int (*xOutput)(void *pOut, const void *pData, int nData),
@@ -1610,45 +1572,6 @@ int sqlite3rebaser_rebase_strm(
void *pOut
);
/*
** CAPI3REF: Configure global parameters
**
** The sqlite3session_config() interface is used to make global configuration
** changes to the sessions module in order to tune it to the specific needs
** of the application.
**
** The sqlite3session_config() interface is not threadsafe. If it is invoked
** while any other thread is inside any other sessions method then the
** results are undefined. Furthermore, if it is invoked after any sessions
** related objects have been created, the results are also undefined.
**
** The first argument to the sqlite3session_config() function must be one
** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The
** interpretation of the (void*) value passed as the second parameter and
** the effect of calling this function depends on the value of the first
** parameter.
**
** <dl>
** <dt>SQLITE_SESSION_CONFIG_STRMSIZE<dd>
** By default, the sessions module streaming interfaces attempt to input
** and output data in approximately 1 KiB chunks. This operand may be used
** to set and query the value of this configuration setting. The pointer
** passed as the second argument must point to a value of type (int).
** If this value is greater than 0, it is used as the new streaming data
** chunk size for both input and output. Before returning, the (int) value
** pointed to by pArg is set to the final value of the streaming interface
** chunk size.
** </dl>
**
** This function returns SQLITE_OK if successful, or an SQLite error code
** otherwise.
*/
int sqlite3session_config(int op, void *pArg);
/*
** CAPI3REF: Values for sqlite3session_config().
*/
#define SQLITE_SESSION_CONFIG_STRMSIZE 1
/*
** Make sure we can call this stuff from C++.
+20 -97
View File
@@ -737,32 +737,20 @@ static int SQLITE_TCLAPI testSqlite3changesetApply(
sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR);
/* Check for the -nosavepoint flag */
if( bV2 ){
if( objc>1 ){
const char *z1 = Tcl_GetString(objv[1]);
int n = strlen(z1);
if( n>1 && n<=12 && 0==sqlite3_strnicmp("-nosavepoint", z1, n) ){
flags |= SQLITE_CHANGESETAPPLY_NOSAVEPOINT;
objc--;
objv++;
}
}
if( objc>1 ){
const char *z1 = Tcl_GetString(objv[1]);
int n = strlen(z1);
if( n>1 && n<=7 && 0==sqlite3_strnicmp("-invert", z1, n) ){
flags |= SQLITE_CHANGESETAPPLY_INVERT;
objc--;
objv++;
}
if( bV2 && objc>1 ){
const char *z1 = Tcl_GetString(objv[1]);
int n = strlen(z1);
if( n>1 && n<=12 && 0==sqlite3_strnicmp("-nosavepoint", z1, n) ){
flags = SQLITE_CHANGESETAPPLY_NOSAVEPOINT;
objc--;
objv++;
}
}
if( objc!=4 && objc!=5 ){
const char *zMsg;
if( bV2 ){
zMsg = "?-nosavepoint? ?-inverse? "
"DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?";
zMsg = "?-nosavepoint? DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?";
}else{
zMsg = "DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?";
}
@@ -981,56 +969,31 @@ static int SQLITE_TCLAPI test_sqlite3session_foreach(
Tcl_Obj *pCS;
Tcl_Obj *pScript;
int isCheckNext = 0;
int isInvert = 0;
TestStreamInput sStr;
memset(&sStr, 0, sizeof(sStr));
while( objc>1 ){
if( objc>1 ){
char *zOpt = Tcl_GetString(objv[1]);
int nOpt = strlen(zOpt);
if( zOpt[0]!='-' ) break;
if( nOpt<=7 && 0==sqlite3_strnicmp(zOpt, "-invert", nOpt) ){
isInvert = 1;
}else
if( nOpt<=5 && 0==sqlite3_strnicmp(zOpt, "-next", nOpt) ){
isCheckNext = 1;
}else{
break;
}
objv++;
objc--;
isCheckNext = (strcmp(zOpt, "-next")==0);
}
if( objc!=4 ){
Tcl_WrongNumArgs(
interp, 1, objv, "?-next? ?-invert? VARNAME CHANGESET SCRIPT");
if( objc!=4+isCheckNext ){
Tcl_WrongNumArgs(interp, 1, objv, "?-next? VARNAME CHANGESET SCRIPT");
return TCL_ERROR;
}
pVarname = objv[1];
pCS = objv[2];
pScript = objv[3];
pVarname = objv[1+isCheckNext];
pCS = objv[2+isCheckNext];
pScript = objv[3+isCheckNext];
pChangeset = (void *)Tcl_GetByteArrayFromObj(pCS, &nChangeset);
sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR);
if( isInvert ){
int f = SQLITE_CHANGESETSTART_INVERT;
if( sStr.nStream==0 ){
rc = sqlite3changeset_start_v2(&pIter, nChangeset, pChangeset, f);
}else{
void *pCtx = (void*)&sStr;
sStr.aData = (unsigned char*)pChangeset;
sStr.nData = nChangeset;
rc = sqlite3changeset_start_v2_strm(&pIter, testStreamInput, pCtx, f);
}
if( sStr.nStream==0 ){
rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset);
}else{
if( sStr.nStream==0 ){
rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset);
}else{
sStr.aData = (unsigned char*)pChangeset;
sStr.nData = nChangeset;
rc = sqlite3changeset_start_strm(&pIter, testStreamInput, (void*)&sStr);
}
sStr.aData = (unsigned char*)pChangeset;
sStr.nData = nChangeset;
rc = sqlite3changeset_start_strm(&pIter, testStreamInput, (void*)&sStr);
}
if( rc!=SQLITE_OK ){
return test_session_error(interp, rc, 0);
@@ -1239,45 +1202,6 @@ static int SQLITE_TCLAPI test_sqlite3rebaser_create(
return TCL_OK;
}
/*
** tclcmd: sqlite3rebaser_configure OP VALUE
*/
static int SQLITE_TCLAPI test_sqlite3session_config(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
struct ConfigOpt {
const char *zSub;
int op;
} aSub[] = {
{ "strm_size", SQLITE_SESSION_CONFIG_STRMSIZE },
{ "invalid", 0 },
{ 0 }
};
int rc;
int iSub;
int iVal;
if( objc!=3 ){
Tcl_WrongNumArgs(interp, 1, objv, "OP VALUE");
return SQLITE_ERROR;
}
rc = Tcl_GetIndexFromObjStruct(interp,
objv[1], aSub, sizeof(aSub[0]), "sub-command", 0, &iSub
);
if( rc!=TCL_OK ) return rc;
if( Tcl_GetIntFromObj(interp, objv[2], &iVal) ) return TCL_ERROR;
rc = sqlite3session_config(aSub[iSub].op, (void*)&iVal);
if( rc!=SQLITE_OK ){
return test_session_error(interp, rc, 0);
}
Tcl_SetObjResult(interp, Tcl_NewIntObj(iVal));
return TCL_OK;
}
int TestSession_Init(Tcl_Interp *interp){
struct Cmd {
const char *zCmd;
@@ -1293,7 +1217,6 @@ int TestSession_Init(Tcl_Interp *interp){
test_sqlite3changeset_apply_replace_all },
{ "sql_exec_changeset", test_sql_exec_changeset },
{ "sqlite3rebaser_create", test_sqlite3rebaser_create },
{ "sqlite3session_config", test_sqlite3session_config },
};
int i;
+16 -26
View File
@@ -19,7 +19,7 @@
# EXE The suffix to add to executable files. ".exe" for windows
# and "" for Unix.
#
# TCC C Compiler and options for use in building executables that
# TCC C Compiler and options for use in building executables that
# will run on the target platform. This is usually the same
# as BCC, unless you are cross-compiling.
#
@@ -43,7 +43,7 @@
# This is how we compile
#
TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP)
TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP)
TCCX += -I$(TOP)/ext/rtree -I$(TOP)/ext/icu -I$(TOP)/ext/fts3
TCCX += -I$(TOP)/ext/async -I$(TOP)/ext/userauth
TCCX += -I$(TOP)/ext/session
@@ -236,7 +236,7 @@ SRC += \
$(TOP)/ext/session/sqlite3session.h
SRC += \
$(TOP)/ext/userauth/userauth.c \
$(TOP)/ext/userauth/sqlite3userauth.h
$(TOP)/ext/userauth/sqlite3userauth.h
SRC += \
$(TOP)/ext/rbu/sqlite3rbu.c \
$(TOP)/ext/rbu/sqlite3rbu.h
@@ -251,7 +251,7 @@ FTS5_HDR = \
$(TOP)/ext/fts5/fts5.h \
$(TOP)/ext/fts5/fts5Int.h \
fts5parse.h
FTS5_SRC = \
$(TOP)/ext/fts5/fts5_aux.c \
$(TOP)/ext/fts5/fts5_buffer.c \
@@ -361,7 +361,6 @@ TESTSRC += \
$(TOP)/ext/misc/closure.c \
$(TOP)/ext/misc/csv.c \
$(TOP)/ext/misc/eval.c \
$(TOP)/ext/misc/explain.c \
$(TOP)/ext/misc/fileio.c \
$(TOP)/ext/misc/fuzzer.c \
$(TOP)/ext/misc/ieee754.c \
@@ -431,7 +430,7 @@ TESTSRC2 = \
$(TOP)/ext/async/sqlite3async.c \
$(TOP)/ext/misc/stmt.c \
$(TOP)/ext/session/sqlite3session.c \
$(TOP)/ext/session/test_session.c
$(TOP)/ext/session/test_session.c
# Header files used by all library source files.
#
@@ -484,7 +483,7 @@ EXTHDR += \
EXTHDR += \
$(TOP)/ext/fts5/fts5Int.h \
fts5parse.h \
$(TOP)/ext/fts5/fts5.h
$(TOP)/ext/fts5/fts5.h
EXTHDR += \
$(TOP)/ext/userauth/sqlite3userauth.h
@@ -507,8 +506,7 @@ FUZZDATA = \
$(TOP)/test/fuzzdata3.db \
$(TOP)/test/fuzzdata4.db \
$(TOP)/test/fuzzdata5.db \
$(TOP)/test/fuzzdata6.db \
$(TOP)/test/fuzzdata7.db
$(TOP)/test/fuzzdata6.db
# Standard options to testfixture
#
@@ -801,7 +799,7 @@ rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon
fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon
cp $(TOP)/ext/fts5/fts5parse.y .
rm -f fts5parse.h
./lemon $(OPTS) fts5parse.y
@@ -835,13 +833,13 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $
tclsh $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c
sqlite3_analyzer$(EXE): sqlite3_analyzer.c
$(TCCX) $(TCL_FLAGS) sqlite3_analyzer.c -o $@ $(LIBTCL) $(THREADLIB)
$(TCCX) $(TCL_FLAGS) sqlite3_analyzer.c -o $@ $(LIBTCL) $(THREADLIB)
sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl
tclsh $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c
sqltclsh$(EXE): sqltclsh.c
$(TCCX) $(TCL_FLAGS) sqltclsh.c -o $@ $(LIBTCL) $(THREADLIB)
$(TCCX) $(TCL_FLAGS) sqltclsh.c -o $@ $(LIBTCL) $(THREADLIB)
sqlite3_expert$(EXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c
$(TCCX) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert$(EXE) $(THREADLIB)
@@ -894,10 +892,6 @@ fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c \
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
coretestprogs: $(TESTPROGS)
testprogs: coretestprogs srcck1$(EXE) fuzzcheck$(EXE) sessionfuzz$(EXE)
fulltest: $(TESTPROGS) fuzztest
./testfixture$(EXE) $(TOP)/test/all.test $(TESTOPTS)
@@ -954,7 +948,7 @@ smoketest: $(TESTPROGS) fuzzcheck$(EXE)
# The next two rules are used to support the "threadtest" target. Building
# threadtest runs a few thread-safety tests that are implemented in C. This
# target is invoked by the releasetest.tcl script.
#
#
THREADTEST3_SRC = $(TOP)/test/threadtest3.c \
$(TOP)/test/tt3_checkpoint.c \
$(TOP)/test/tt3_index.c \
@@ -998,10 +992,6 @@ changeset$(EXE): $(TOP)/ext/session/changeset.c sqlite3.o
$(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o changeset$(EXE) \
$(TOP)/ext/session/changeset.c sqlite3.o $(THREADLIB)
changesetfuzz$(EXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.o
$(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o changesetfuzz$(EXE) \
$(TOP)/ext/session/changesetfuzz.c sqlite3.o $(THREADLIB)
fts3view$(EXE): $(TOP)/ext/fts3/tool/fts3view.c sqlite3.o
$(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o fts3view$(EXE) \
$(TOP)/ext/fts3/tool/fts3view.c sqlite3.o $(THREADLIB)
@@ -1022,12 +1012,12 @@ wordcount$(EXE): $(TOP)/test/wordcount.c sqlite3.c
$(TOP)/test/wordcount.c sqlite3.c
speedtest1$(EXE): $(TOP)/test/speedtest1.c sqlite3.c
$(TCCX) -I. $(ST_OPT) -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.c $(THREADLIB)
$(TCCX) -I. $(ST_OPT) -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.c $(THREADLIB)
kvtest$(EXE): $(TOP)/test/kvtest.c sqlite3.c
$(TCCX) -I. $(KV_OPT) -o kvtest$(EXE) $(TOP)/test/kvtest.c sqlite3.c $(THREADLIB)
$(TCCX) -I. $(KV_OPT) -o kvtest$(EXE) $(TOP)/test/kvtest.c sqlite3.c $(THREADLIB)
rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o
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)
@@ -1059,7 +1049,7 @@ install: sqlite3 libsqlite3.a sqlite3.h
mv libsqlite3.a /usr/lib
mv sqlite3.h /usr/include
clean:
clean:
rm -f *.o sqlite3 sqlite3.exe libsqlite3.a sqlite3.h opcodes.*
rm -f lemon lemon.exe lempar.c parse.* sqlite*.tar.gz
rm -f mkkeywordhash mkkeywordhash.exe keywordhash.h
@@ -1087,7 +1077,7 @@ clean:
rm -f sqlite3rc.h
rm -f shell.c sqlite3ext.h
rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
rm -f sqlite3_expert sqlite3_expert.exe
rm -f sqlite3_expert sqlite3_expert.exe
rm -f sqlite-*-output.vsix
rm -f mptester mptester.exe
rm -f fuzzershell fuzzershell.exe
+112 -120
View File
@@ -1,12 +1,12 @@
C Merge\slatest\strunk\schanges.
D 2018-11-10T17:36:55.425
C Version\s3.25.2
D 2018-09-25T19:08:10.988
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in d298b31769d4c737887102462cd45684786b09f2a626a80b3e413790fb436219
F Makefile.in 6b650013511fd9d8b094203ac268af9220d292cc7d4e1bc9fbca15aacd8c7995
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 071853dfc2148aadaeb7a153b9986cc9d71b7f256874f79b119f97a4c89453f5
F Makefile.msc a889c6981a222d639f8a548adcfb3183ac07871e27452ace4d810735750f216a
F README.md 377233394b905d3b2e2b33741289e093bc93f2e7adbe00923b2c5958c9a9edee
F VERSION 654da1d4053fb09ffc33a3910e6d427182a7dcdc67e934fa83de2849ac83fccb
F VERSION 8d89a0e3dbf2fe06a028ad03f03d38e30295290cf2ef425a877547b193acaa58
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
@@ -33,7 +33,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure 5811ffcd4866902d1706dcf8e0527f89165ec52859659942c9649bb1d3e4cc7b x
F configure 6876c95d54c96d8675f0e39838b6b557eb5fc7ce619ba014e31e0e261dff1f25 x
F configure.ac 3552d3aecade98a9d4b64bceb48ffb7726cbc85902efde956812942f060fbd0a
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
@@ -80,7 +80,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 012384f01df28345a8d0d0c7fe465ab211598a91d78a7331b3664533756ed9fa
F ext/fts3/fts3.c 53020b61dac31c167668f098ec83c0387ecd65b9e89ba3659f2f8d3e76efdf1e
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h 3378157f383540857a466420b8279626204434c3eb0dc948ad9bcd3991fc41f5
F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1
@@ -98,7 +98,7 @@ 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 a85bc4885fde7f1b44c9de013b62f7cd3332dc59e208053d878729b1d04745bc
F ext/fts3/fts3_write.c b583dede85eb0c3c3026f8d7ccb781ea4e845ae583754fecb2ca425b5907d87d
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
@@ -281,12 +281,10 @@ F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f0
F ext/misc/csv.c 65297bcce8d5acd5aadef42acbe739aef5a2ef5e74c7b73361ca19f3e21de657
F ext/misc/dbdump.c 12389a10c410fadf1e68eeb382def92d5a7fa9ce7cce4fb86a736fa2bac1000a
F ext/misc/eval.c 6ea9b22a5fa0dd973b67ca4e53555be177bc0b7b263aadf1024429457c82c0e3
F ext/misc/explain.c 5851a1a4a1bba6e078da4103fcafc84aa54adfd8edbba419f5cf1eba9f000d50
F ext/misc/fileio.c 7317d825fab6a3c48f6e3822a00a6a22e08e55af31700ac96f16a523f83069fd
F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
F ext/misc/json1.c 276f87dc8365b34b0fffb7ef32481dd07fac6fdb3224e2822396a48377ac8363
F ext/misc/memstat.c 7542ff1dd1d926e63dab904070e689cd5b47e4dd19498ad31947c42b207f5363
F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567
F ext/misc/mmapwarm.c 70b618f2d0bde43fae288ad0b7498a629f2b6f61b50a27e06fae3cd23c83af29
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
@@ -297,10 +295,10 @@ F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6
F ext/misc/rot13.c 540a169cb0d74f15522a8930b0cccdcb37a4fd071d219a5a083a319fc6e8db77
F ext/misc/scrub.c db9fff56fed322ca587d73727c6021b11ae79ce3f31b389e1d82891d144f22ad
F ext/misc/series.c c7197db304f7009b08d6459a9de02e7f51ad0e1a3fdacbc1ebf5252a9a346959
F ext/misc/sha1.c df0a667211baa2c0612d8486acbf6331b9f8633fd4d605c17c7cccd26d59c6bd
F ext/misc/shathree.c 22ba7ca84a433d6466a7d05dcc876910b435a715da8cc462517db9351412b8c8
F ext/misc/sha1.c 0b9e9b855354910d3ca467bf39099d570e73db56
F ext/misc/shathree.c 9e960ba50483214c6a7a4b1517f8d8cef799e9db381195178c3fd3ad207e10c0
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
F ext/misc/spellfix.c f88ecb2c0294453ce8b7704b211f5350c41b085b38c8e056852e3a08b0f5e484
F ext/misc/spellfix.c 54d650f44f3a69a851814791bd4d304575cdbbf78d96d4f0801b44a8f31a58c5
F ext/misc/sqlar.c 57d5bc45cd5492208e451f697404be88f8612527d64c9d42f96b325b64983d74
F ext/misc/stmt.c 6f16443abb3551e3f5813bb13ba19a30e7032830015b0f92fe0c0453045c0a11
F ext/misc/templatevtab.c 8251b31011dd00fc38e739c78c234c930be42b3b274bbe0493b79cd40db02a9e
@@ -348,7 +346,7 @@ F ext/rbu/rbusplit.test 69271c790732b28bd465551d80b0a9a3f074e189896ee8490ce56d22
F ext/rbu/rbutemplimit.test cd553a9288d515d0b5f87d277e76fd18c4aa740b761e7880fab11ce986ea18d1
F ext/rbu/rbuvacuum.test ff357e9b556ca7ad4673da0ff7f244def919ff858e0f9f350d3e30fdd83a62a8
F ext/rbu/rbuvacuum2.test 2074ab14fe66e1c7e7210c62562650dcd215bbaa
F ext/rbu/sqlite3rbu.c 71f8c09948d09ec9c5a8dbe7127e8ef61ef0853e698b2650be2485ac7b9c75c8
F ext/rbu/sqlite3rbu.c f438fea899d15d13ff3e3133242b9e378c37b5a3d76add8c342c68bdd65c6819
F ext/rbu/sqlite3rbu.h b42bcd4d8357268c6c39ab2a60b29c091e89328fa8cc49c8fac5ab8d007e79b2
F ext/rbu/test_rbu.c baa23eb28457580673d2175e5f0c29ced0cd320ee819b13ad362398c53b96e90
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
@@ -361,7 +359,7 @@ F ext/repair/test/checkfreelist01.test 3e8aa6aeb4007680c94a8d07b41c339aa635cc782
F ext/repair/test/checkindex01.test 6945d0ffc0c1dc993b2ce88036b26e0f5d6fcc65da70fc9df27c2647bb358b0f
F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/geopoly.c 2464b3325fcc2878ed08458efeb995f830f4eef28bbf3da9757c4bd95e6f9549
F ext/rtree/geopoly.c 415a8ca5dfab54eea779e0bf31a859afb0b869a5147a726df4aec4b57c1bad57
F ext/rtree/rtree.c 6cc2e673cf1e9ea1619f13ab990f12389dfb951b131acbc2fbe164cee8992a20
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
F ext/rtree/rtree1.test 309afc04d4287542b2cd74f933296832cc681c7b014d9405cb329b62053a5349
@@ -389,11 +387,9 @@ F ext/rtree/sqlite3rtree.h 9c5777af3d2921c7b4ae4954e8e5697502289d28
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
F ext/rtree/util/randomshape.tcl 54ee03d0d4a1c621806f7f44d5b78d2db8fac26e0e8687c36c4bd0203b27dbff
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
F ext/rtree/visual01.txt e9c2564083bcd30ec51b07f881bffbf0e12b50a3f6fced0c222c5c1d2f94ac66
F ext/rtree/visual01.txt 17c3afefc208c375607aa82242e97fa79c316e539bcd0b7b3e59344c69445d05
F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a
F ext/session/changesetfuzz.c 255826ee367781ec4c29a36c7c63e9ee6387dc03a8346cf240feb8d597958b0e
F ext/session/changesetfuzz1.test 2e1b90d888fbf0eea5e1bd2f1e527a48cc85f8e0ff75df1ec4e320b21f580b3a
F ext/session/session1.test 0b2f88995832ea040ae8e83a1ad4afa99c00b85c779d213da73a95ea4113233e
F ext/session/session1.test 4532116484f525110eb4cfff7030c59354c0cde9def4d109466b0df2b35ad5cc
F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0
F ext/session/session3.test ce9ce3dfa489473987f899e9f6a0f2db9bde3479
F ext/session/session4.test 6778997065b44d99c51ff9cece047ff9244a32856b328735ae27ddef68979c40
@@ -409,26 +405,25 @@ F ext/session/sessionE.test 0a616c4ad8fd2c05f23217ebb6212ef80b7fef30f5f086a6633a
F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce
F ext/session/sessionG.test 3edde849c4071078d92bd682c836186f6e4e5a3fb6bcf3fc1de1a7caa5e4427d
F ext/session/sessionH.test 332b60e4c2e0a680105e11936201cabe378216f307e2747803cea56fa7d9ebae
F ext/session/session_common.tcl 29ec9910aca1e996ca1c8531b8cecabf96eb576aa53de65a8ff03d848b9a2a8b
F ext/session/session_common.tcl ee925e0d233677e45e395fb1f559b84068ce7baa8aa1034441739d3e87ee249c
F ext/session/session_speed_test.c edc1f96fd5e0e4b16eb03e2a73041013d59e8723
F ext/session/sessionat.test efe88965e74ff1bc2af9c310b28358c02d420c1fb2705cc7a28f0c1cc142c3ec
F ext/session/sessiondiff.test ad13dd65664bae26744e1f18eb3cbd5588349b7e9118851d8f9364248d67bcec
F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7
F ext/session/sessionfault2.test 555a8504de03d59b369ef20209585da5aeb2671dedabc4584e9ffe6269689185
F ext/session/sessioninvert.test ae1a003a9ab1f8d64227dbb5c3a4c97e65b561b01e7b2953cf48683fb2724169
F ext/session/sessionrebase.test 4e1bcfd26fd8ed8ac571746f56cceeb45184f4d65490ea0d405227cfc8a9cba8
F ext/session/sessionstat1.test 41cd97c2e48619a41cdf8ae749e1b25f34719de638689221aa43971be693bf4e
F ext/session/sessionwor.test 2f3744236dc8b170a695b7d8ddc8c743c7e79fdc
F ext/session/sqlite3session.c dbd6f7a89c1236d8e7b58f4e217391670ce91b9e6f85c16ba02832674ef0cf3c
F ext/session/sqlite3session.h 05351d2f50a1203fdffbeb590fdbbc796c9a6bfcd0c9b26cf6db3854e3eb4294
F ext/session/test_session.c 98797aba475a799376c9a42214f2d1debf2d0c3cb657d9c8bbf4f70bf3fb4aec
F ext/session/sqlite3session.c 2d29bbd888599b94b2c8b31ff433675e008273a4d225b336508b18e6187fec1d
F ext/session/sqlite3session.h c01820d5b6e73e86d88008f4d1c1c7dfb83422963018292b864028a0400ceccf
F ext/session/test_session.c dba36c6c0153b22501112d3e8882b5c946cf617c955153b6712bd2f8ba1428c0
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
F ext/userauth/userauth.c f81aa5a3ecacf406f170c62a144405858f6f6de51dbdc0920134e629edbe2648
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk ddb6616776c53dfc06bb3f8396df8721c8b699294271fd0c3d110dd278d9c723
F main.mk 1db6df4bff24ed6684917e3fe311ce28f5924d6417c698fe4326f7cadf02df31
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@@ -440,37 +435,37 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 61c1ace40a9e39c45a975cb6c57a1a283a262ea21bbe3fb5b473708b790a8d43
F src/alter.c 70dd115eb1f949f69f61773733dc89d6494915ec6a736f259c7a7de4aeb51726
F src/analyze.c 3dc6b98cf007b005af89df165c966baaa48e8124f38c87b4d2b276fe7f0b9eb9
F src/attach.c 4bd5b92633671d3e8ce431153ebb1893b50335818423b5373f3f27969f79769a
F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df
F src/auth.c 32a5bbe3b755169ab6c66311c5225a3cd4f75a46c041f7fb117e0cbb68055114
F src/backup.c 78d3cecfbe28230a3a9a1793e2ead609f469be43e8f486ca996006be551857ab
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
F src/btree.c 3ef104ecae8b1b5f0458be1f5fa7c1ecf25fdc322a9d63bb8151f89eb32d381e
F src/btree.c 3f5e1a03db871e627bf5da21092bf7434ecfc5c5980bbd7d45eba13341340173
F src/btree.h febb2e817be499570b7a2e32a9bbb4b607a9234f6b84bb9ae84916d4806e96f2
F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
F src/build.c a614b226b9af1e49ec6d0ffbf3aa0d38a73123336a7f78930005db939d038253
F src/callback.c 789bd33d188146f66c0dd8306472a72d1c05f71924b24a91caf6bd45cf9aba73
F src/build.c 0b3d422770877d74ee6d54f4c122d82c48f7d04ee3bfb91702e402de7f5c45ac
F src/callback.c 36caff1e7eb7deb58572d59c41cee8f064a11d00297616995c5050ea0cfc1288
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b
F src/ctime.c b157b01081f92442f8b0218ddb93ddce8ebddad36dbddeecfdd771561dd4f387
F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
F src/dbpage.c ada9bc6964bb68e4c128df70cb0938faaa214e1a0e1d730ea6b13c5e1fde9a45
F src/dbstat.c e042b0e7833fdacf2d5ea92c6b536962fea6aeed8b7287ca87ddfa3412bd9564
F src/delete.c e1ac11c062a4a2ed29a9e9a63f4cbc7f0330291ae276d768b26fb2c5152cc3b4
F src/expr.c 9aacc0b72348ba90010b672dcbbbe2fa56e1182043bc917a3a147b2bc57a5497
F src/dbpage.c 4aa7f26198934dbd002e69418220eae3dbc71b010bbac32bd78faf86b52ce6c3
F src/dbstat.c edabb82611143727511a45ca0859b8cd037851ebe756ae3db289859dd18b6f91
F src/delete.c 107e28d3ef8bd72fd11953374ca9107cd74e8b09c3ded076a6048742d26ce7d2
F src/expr.c d8da79a5cb19bbded56181337a221ead5f4ad3cbf0fbcb5da2156abefab566cd
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 972a4ba14296bef2303a0abbad1e3d82bc3c61f9e6ce4e8e9528bdee68748812
F src/fkey.c f59253c0be4b1e9dfcb073b6d6d6ab83090ae50c08b5c113b76013c4b157cd6a
F src/func.c 7c288b4ce309b5a8b8473514b88e1f8e69a80134509a8c0db8e39c858e367e7f
F src/global.c 9bf034fd560bdd514715170ed8460bb7f823cec113f0569ef3f18a20c7ccd128
F src/hash.c 931ec82d7e070654a8facb42549bbb3a25720171d73ba94c3d3160580d01ef1f
F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c 6b81aae27b196925d8ff78824f4bbd435d6a40cd38dc324685e21735bb402109
F src/insert.c c723716f0de7aa0a679300f7d3541c89645f4a9882161cecdb3093fc07f8cc4b
F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
F src/loadext.c 448eab53ecdb566a1259ee2d45ebff9c0bc4a2cf393774488775c33e4fbe89bf
F src/main.c 03204aa22720654f0bc128b6d25626a89f9faca17e10ffdf738036d5453b13b3
F src/loadext.c 30b140d0e5031924c56f802760506c0a235ced0dff9f3d95119aa86df12856e2
F src/main.c 6275ece0699a957c4709a7ebe29476f132adbe459d18a6b497e234e4669abf91
F src/malloc.c 07295435093ce354c6d9063ac05a2eeae28bd251d2e63c48b3d67c12c76f7e18
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
@@ -490,33 +485,33 @@ F src/os.c 8aeb0b0f40f8f5b0da03fe49706695adaf42d2f516ab95abc72e86c245e119de
F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
F src/os_unix.c f6e91b8fd82af7afbfd073c4974ad6cdb8e62d9f65ceddb45167835a0567fdc0
F src/os_unix.c 7cfd67db0e2f926243f646db7ec1caa33ca9bee45799b0160ddfcd6ccfc175d2
F src/os_win.c 070cdbb400097c6cda54aa005356095afdc2f3ee691d17192c54724ef146a971
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c f803ffcd8440b5249549ea103158a1c659bf060961b2389f9fede66a3a352d0b
F src/pager.c a0d8f686ef64549ad5b356fd30429bd9ee7a06dd42b4d6faa096352ff26b1c5b
F src/pager.h ecc554a55bc55d1c4ba5e17137b72e238e00bd81e72ff2662d8b9c8c10ae3963
F src/parse.y 6840fe7c0b5eb4dd25ee5d075213bc8255ed4c0678d71bfb6744d0520d91c179
F src/pcache.c 4196eb6ed3bbf00b80596c8e0b4f50e57eb7d890c19fb27a7354306abb7f983d
F src/parse.y 4118dbf9c37c410e5c4775c033b1aaf67ac8ff7965df7a4bb429dd5db2dbe374
F src/pcache.c 135ef0bc6fb2e3b7178d49ab5c9176254c8a691832c1bceb1156b2fbdd0869bd
F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170
F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880
F src/pragma.c 0bb05b1788d7af5fdc7f40f5655a79a140dece8fd2523402eb2103925e4739c2
F src/pragma.h fdd03d78a7497f74a3f652909f945328480089189526841ae829ce7313d98d13
F src/prepare.c f81f8d707e583192c28fea0b2e19385415b7d188123b23f49b038076408d7a69
F src/pragma.c 79abc65c08d2754048efee3ba99fe91863dfeab0ba699a4439fa5053ec87cf36
F src/pragma.h fb46b1e663128f6827979ad8ebddb55be2a0276ea923c47adeac02144207a682
F src/prepare.c f8e260d940a0e08494c0f30744521b2f832d7263eca9d02b050cea0ba144b097
F src/printf.c 0f1177cf1dd4d7827bf64d840768514ec76409abecaca9e8b577dbd065150381
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c bc8c79e56439b111e7d9415e44940951f7087e9466c3a9d664558ef0faf31073
F src/resolve.c 352c6af1a99441206ff62a6f7429dbf537827f42c428639695220b9c8639e33b
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
F src/select.c 61e867a906f140b73baf4ce7a201ad6dcba30820969f5618ee40e9a0d32c6f5f
F src/shell.c.in 060ccc327959bdc85c895015eb382017fd0cd000ebd47b7e8dda42f8aab0b66f
F src/sqlite.h.in 1383b2fbce61bd3634caeafb2513205326a297e988ea749d4f6dec7da7a281c9
F src/select.c 8afcc2b56a6ef76717bb59b6109cd3de0f6fae2803894d6f806640c0aa24dfac
F src/shell.c.in 6e0aad854be738a5d0368940459399be211e9ac43aebe92bb9ed46cfe38d0e1f
F src/sqlite.h.in 4b4c2f2daeeed4412ba9d81bc78092c69831fe6eda4f0ae5bf951da51a8dccec
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683
F src/sqliteInt.h cad10b3a482bd5b11f586df9877ff5f637ce14534291a438430d1f1a2b882296
F src/sqlite3ext.h 305adca1b5da4a33ce2db5bd236935768e951d5651bfe5560ed55cfcdbce6a63
F src/sqliteInt.h 10d7835f2a1ae736a468c38a413b754933051fc97255aa2f4ac2df2ad349e863
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
F src/tclsqlite.c e72862a271348d779672b45a730c33fd0c535e630ff927e8ce4a0c908d1d28c6
F src/test1.c b95363b0bc9e1ecc61964ca5a22c137422af4808a54a7bbb1a4f7d6d6257f704
F src/test1.c 31c491ccb536bd9916a084e732ffe783b3c8973f2586d5a56aed0e3a9701dfff
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6
@@ -531,7 +526,7 @@ F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0
F src/test_bestindex.c 78809f11026f18a93fcfd798d9479cba37e1201c830260bf1edc674b2fa9b857
F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31ce
F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274
F src/test_config.c 5ebafbcd5c75ac1c16bb0c8fe926dc325cc03e780943a88ca50e0d9a4fc4d2f5
F src/test_config.c 6c3f341ece48020c4ddbce055643a91c653283b3a6853c46ea18d22e5c72847d
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e
F src/test_devsym.c 1960abbb234b97e9b920f07e99503fc04b443f62bbc3c6ff2c2cea2133e3b8a2
@@ -539,8 +534,8 @@ F src/test_fs.c 35a2f7dd8a915900873386331386d9ba1ae1b5026d74fd20c2807bc76221f291
F src/test_func.c d12d805953bcb3bb19f71d29cdc93383b7b7a3369504d2b7e398a1bd77376294
F src/test_hexio.c 1d4469ca61ab202a1fcec6543f584d2407205e8d
F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664
F src/test_intarray.c 39b4181662a0f33a427748d87218e7578d913e683dc27eab7098bb41617cac71
F src/test_intarray.h d57ae92f420cda25e22790dac474d60961bd0c500cbaa3338a05152d4a669ef7
F src/test_intarray.c 988fc61cb0ff539f4172c0d95f15287c92516f64
F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c
F src/test_journal.c 619f2aa10e0d7a5f87c0f06825bc61dfce1c6b9c7f3ad990fb13de6c3b8874a3
F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
F src/test_malloc.c dec0aa821b230773aeb3dd11d652c1193f7cedb18a20b25659bc672288115242
@@ -548,7 +543,7 @@ F src/test_md5.c 7268e1e8c399d4a5e181b64ac20e1e6f3bc4dd9fc87abac02db145a3d951fa8
F src/test_multiplex.c e054459f7633f3ff8ce1245da724f9a8be189e4e
F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635
F src/test_mutex.c 7f4337ba23ee6b1d2ec81c189653608cb069926a
F src/test_onefile.c f31e52e891c5fef6709b9fcef54ce660648a34172423a9cbdf4cbce3ba0049f4
F src/test_onefile.c 416f87a28d6d673352d33fc4b1c7d39db878e50f
F src/test_osinst.c 98ef31ff03d55497829ca0f6c74a9f4e1aa48690
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
F src/test_quota.c 6cb9297115b551f433a9ad1741817a9831abed99
@@ -569,33 +564,33 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9
F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c 9e781e1ca80eefe7b5d6a9e2cd5c678c847da55fd6f093781fad7950934d4c83
F src/treeview.c 7b12ac059de54c939b6eb0dbffc9410c29c80d2470cee5cbe07d5ff9ea2d9253
F src/tokenize.c 9f55961518f77793edd56eee860ecf035d4370ebbb0726ad2f6cada6637fd16b
F src/treeview.c e7a7f90552bb418533cdd0309b5eb71d4effa50165b880fc8c2001e613577e5f
F src/trigger.c d3d78568f37fb2e6cdcc2d1e7b60156f15b0b600adec55b83c5d42f6cad250bd
F src/update.c 1816d56c1bca1ba4e0ef98cac2f49be62858e9df1dc08844c7067eb41cc44274
F src/update.c 345ce35eb1332eb4829857aa8b1f65a614b07dae91d0346c0dc2baacafbcc51b
F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
F src/vacuum.c 36e7d21a20c0bf6ef4ef7c399d192b5239410b7c4d3c1070fba4e30810d0b855
F src/vdbe.c 005e691ea4c7d51e6c1a69d9389aeb34700884c85f51681817ddea3fdc2fc39b
F src/vdbe.c 7433ac76608b80b745f57b8544416dc0178db52ce2cc806a10353309e5f781fb
F src/vdbe.h 5081dcc497777efe5e9ebe7330d283a044a005e4bdda2e2e984f03bf89a0d907
F src/vdbeInt.h 8a52b8db3d20f9755a965d864b8653052c7ef1ccadceb2e057047cd421f6336e
F src/vdbeapi.c ecccfce6f614c33a95952efeec969d163e8349eac314ee2b7b163eda921b5eb0
F src/vdbeaux.c f547901b1aa9e2d81c63f06893f633648e434180666a827aacb547d7d6c8a601
F src/vdbeInt.h f1f35f70460698d8f5a2bdef1001114babf318e2983a067804e2ae077d8e9827
F src/vdbeapi.c 2ba821c5929a2769e4b217dd85843479c718b8989d414723ec8af0616a83d611
F src/vdbeaux.c c3c397274380f13db702baa3506ba87379446a4d71135a1177b624f73dd3c830
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
F src/vdbemem.c 7b3305bc4a5139f4536ac9b5f61da0f915e49d2e3fdfa87dfdfa9d7aba8bc1e9
F src/vdbemem.c 81329ab760e4ec0162119d9cd10193e0303c45c5935bb20c7ae9139d44dd6641
F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7f
F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
F src/vtab.c 70188a745dc4e57d26e942681ff4b2912b7c8249ad5de3f60f0677b4337bcfaa
F src/vtab.c 8665561f244c137a2d17b5c3e5910d7303054fe841c5d510e53f23beb0089594
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 3f4f653daf234fe713edbcbca3fec2350417d159d28801feabc702a22c4e213f
F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
F src/walker.c fb94aadc9099ff9c6506d0a8b88d51266005bcaa265403f3d7caf732a562eb66
F src/where.c f5da1079f084c569aa70fd4ada6b7e45b356e19708f1e5307493cc65857ec9e4
F src/whereInt.h f125f29fca80890768e0b2caa14f95db74b2dacd3a122a168f97aa7b64d6968f
F src/wherecode.c c45f03aefc2266b990df0fc4d7acc4e27f56f881f4fc0fc355b7cbc4d7189da5
F src/whereexpr.c 491f0894ad9903750cdecb7894437a0cabdffdd88f574d2b1c9ac85d14fe4b9c
F src/window.c 6550e2850ebced51100ef83d49b00a1cf03f81a482dafedafb0320df647ed8fc
F src/walker.c ba7225773931760cf60bf22f34d0cce2588df7ce5ce0f215a52eb88234b55ac4
F src/where.c 2019126801437944c38cc62a99491e98591460b7cc07ab57eb66165f710a289b
F src/whereInt.h b90ef9b9707ef750eab2a7a080c48fb4900315033274689def32d0cf5a81ebe4
F src/wherecode.c 4f88f5b39ad4aeb5bdd47a546d74149bb902ef49ca9f02a45b2a5bd2dd70b6bd
F src/whereexpr.c eb462ebe085f6cbb6bdda797a041fbd7e3724586203344043d1088a2117d8e44
F src/window.c 4b503da928dace3e845b891381a4d98eeb8c5744313ae3643df8d8d21fdcca65
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -608,13 +603,12 @@ F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060
F test/alter3.test 4d79934d812eaeacc6f22781a080f8cfe012fdc3
F test/alter4.test 7e93a21fe131e1dfeb317e90056856f96b10381fc7fe3a05e765569a23400433
F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959
F test/alterauth2.test c0a1ddf5b93d93cb0d15ba7acaf0c5c6fb515bbe861ede75b2d3fabad33b6499
F test/altercol.test 53fb5e218c9296afc160f2c4fcbeaf42bd0604815d9b3896a7d2eec583ad8704
F test/alterlegacy.test e7c07d605c2a85e7d1696c89e6bf64dfc932fc6d9320fe8708c8f5fc0b524d41
F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b
F test/altertab.test fb8a9a2ab6deb5f860d27675f6213d14ab79b705e0d6350eead4ef3a3f73bf3e
F test/altertab2.test 7b3f4a6ca0dd833b75b889477a3e291e2799b4af25db908fe6930e39a353b1eb
F test/altertab.test 3b830144c18ae00abd2a27e3d2851c8bb1ee8fe655fa16d8a5971066dc71b58a
F test/altertab2.test 159fd5f7b23ddc841fe678f579f9b1b8e69f44296f3ff75d1b4c155d37a59832
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
F test/analyze.test b3a9c67d00e1df7588a5b7be9a0292899f94fe8cac1f94a017277474ca2e59df
F test/analyze3.test ff62d9029e6deb2c914490c6b00caf7fae47cc85cdc046e4a0d0a4d4b87c71d8
@@ -640,11 +634,11 @@ F test/atof1.test ff0b0156fd705b67c506e1f2bfe9e26102bea9bd
F test/atomic.test 065a453dde33c77ff586d91ccaa6ed419829d492dbb1a5694b8a09f3f9d7d061
F test/atomic2.test b6863b4aa552543874f80b42fb3063f1c8c2e3d8e56b6562f00a3cc347b5c1da
F test/atrc.c ec92d56d8fbed9eb3e11aaf1ab98cf7dd59e69dae31f128013f1d97e54e7dfed
F test/attach.test dff436fd94d4c7ffd7f0a8831d50193595f3b94a9428b3ddd41d24b897bae729
F test/attach.test f4b8918ba2f3e88e6883b8452340545f10a1388af808343c37fc5c577be8281c
F test/attach2.test 256bd240da1835fb8408dd59fb7ef71f8358c7a756c46662434d11d07ba3a0ce
F test/attach3.test c59d92791070c59272e00183b7353eeb94915976
F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c
F test/attachmalloc.test 12c4f028e570acf9e0a4b0b7fe6f536e21f3d5ebddcece423603d0569beaf438
F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0
F test/auth.test 3310d9c08e928beca42d3eadaaf53cef619d9d275f598565a3758a21ce63138e
F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1
F test/auth3.test db21405b95257c24d29273b6b31d0efc59e1d337e3d5804ba2d1fd4897b1ae49
@@ -654,7 +648,7 @@ F test/autoindex1.test a09958fa756129af10b6582bcbf3cbdf11e305e027b393f393caef801
F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df
F test/autoindex3.test 2dd997d6590438b53e4f715f9278aa91c9299cf3f81246a0915269c35beb790e
F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf
F test/autoindex5.test 4a0eb6c7c7ae456d97a2061d4c8d6380946272c5c91d91507c1feb1af3dc7cce
F test/autoindex5.test 5f0135dc3b266277b8c1904624439097d8e8020dd7197eda13fda23c35c21a05
F test/autovacuum.test 0831cd34e14695d297187f7f6519265e3121c5b0a1720e548e86829e796129e9
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
F test/avtrans.test b7dc25459ecbd86c6fa9c606ee3068f59d81e225118617dcf2bbb6ded2ade89e
@@ -671,7 +665,7 @@ F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c
F test/bestindex1.test 852170bddbb21daa121fabcc274640ff83d7d8705912e8b5fe7ed2c5a9a9224a
F test/bestindex2.test 9a0ccd320b6525eec3a706aae6cdab7e1b7b5abca75027e39f39f755e76e5928
F test/bestindex3.test 001788a114ad96d81d5154fe77c7f1e26e84b3a2b5635ca29e4f96f6decc534e
F test/bestindex4.test 210eac9323ef88881212d6ae90c84dad86ec14d82c6f4fc9a9ee24c76a8f2014
F test/bestindex4.test 4cb5ff7dbaebadb87d366f51969271778423b455
F test/bestindex5.test 412b42f8036b28d8b2f3534d89389ad946a4b1a65a12263f51936f7424296f1b
F test/bestindex6.test d856a9bb63d927493575823eed44053bc36251e241aa364e54d0f2a2d302e1d4
F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c
@@ -700,9 +694,9 @@ F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61
F test/cachespill.test 895997f84a25b323b166aecb69baab2d6380ea98f9e0bcc688c4493c535cfab9
F test/capi2.test 34a1a9a96d543a2ec2c209696b11b164444f57253b1f2cba1c2e53fadede6c7b
F test/capi3.test b299c89d80891c6c9b7f0e4b199df002b8b9f11c19f07d4a6eb7b325f1244de0
F test/capi3.test 36f5c859c91a9bb0075d6ddcfcf2476cad629b09f7bfd135776fb94b06c04706
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
F test/capi3c.test e853c6c1f9a596e0bc58153be08706813bf5795d479d6f81581e3bda3f9d0909
F test/capi3c.test 7ebed1d8fa2f3190149d556fe8cff5a006be62af437c5c4640db614470126098
F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
F test/cast.test 5ceb920718d280b61163500a7d29e0e0a86458b1cbd92d96f962c9d970aa3857
@@ -756,7 +750,7 @@ F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651
F test/crash3.test 8f5de9d32ab9ab95475a9efe7f47a940aa889418
F test/crash4.test fe2821baf37168dc59dd733dcf7dba2a401487bc
F test/crash5.test f14ff37eddc41991be4eb63568f86caa306fd9962a0ae3750db8836777bb7aae
F test/crash5.test 05dd3aa9dbb751a22d5cdaf22a9c49b6667aa219
F test/crash6.test 4c56f1e40d0291e1110790a99807aa875b1647ba
F test/crash7.test 1a194c4900a255258cf94b7fcbfd29536db572df
F test/crash8.test 64366e459c28dd62edfb7ad87253a409c7533b92d16fcc479a6a8131bdcc3100
@@ -772,10 +766,8 @@ F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68
F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee
F test/dbfuzz2.c 652f85bac1770e927da139db513234a3eba308f72ac2f8b32f0093d7d19def70
F test/dbpage.test dbf50a4d361f9e45a979432c727506065113124478a7d2db12074fa655e65d6c
F test/dbstatus.test cd83aa623b8aab477269bc94cf8aa90c1e195a144561dd04a1620770aaa8524e
F test/dbstatus.test c15fa97f743dac7ce996814c84b56317e138895ee15ce27f15b608aa6924c90a
F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
F test/delete.test 31832b0c45ecb51a54348c68db173be462985901e6ed7f403d6d7a8f70ab4ef0
@@ -907,7 +899,6 @@ F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f
F test/fts3corrupt.test 2710b77983cc7789295ddbffea52c1d3b7506dbb
F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba
F test/fts3corrupt3.test 56e0ee83e90b57f5f3644cb7d1b36a067b7b8b19cdf0dedce45e5e13cf752f65
F test/fts3corrupt4.test 98022cbacbd6ddc4708f210768f5684f041f50ce330c461f2631752492611d96
F test/fts3cov.test 9c3681325b9a850bca8dd75cc29dde73e9a87972bb75204e97d826f13c7181f9
F test/fts3d.test d3e9c8fb75135ada06bf3bab4f9666224965d708
F test/fts3defer.test 0be4440b73a2e651fc1e472066686d6ada4b9963
@@ -969,7 +960,7 @@ F test/fuzz.test 96083052bf5765e4518c1ba686ce2bab785670d1
F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1
F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c31
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
F test/fuzz_malloc.test 5b257a7652d8ee90b22e9cf80d9dbea31a4f3e6fed1d33de57b24b1bdb211d79
F test/fuzzcheck.c 8074a35ed4ec3735a5e144b7e0e9123d9821a92281756c1a40d43e302dd79243
F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
@@ -977,7 +968,6 @@ F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e42ed2
F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5
F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7
F test/fuzzdata7.db 829cbab68b8fa5223405f4bf0d4775b05391a8ff670790d09154a56dd22a8d1e
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
@@ -1001,14 +991,14 @@ F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822
F test/incrblob2.test a494c9e848560039a23974b9119cfc2cf3ad3bd15cc2694ee6367ae537ef8f1f
F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4
F test/incrblob4.test 21a52a6843a56cdcce968c6a86b72a7066d0e6ba
F test/incrblob_err.test 89372a28f1d98254f03fed705f9efcd34ef61a674df16d2dbb4726944a2de5e9
F test/incrblob_err.test 69f9247fed50278d48ea710d1a8f9cdb09e4c0b8
F test/incrblobfault.test 74dd8ac108304cea0b4a0df6df63a1567e558758
F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a
F test/incrvacuum.test b729aab1d4983037da57e66c20dfd7458561a85626dcf824f60175e35f4ce152
F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d
F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a
F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635
F test/index.test 5131c0106a6d0c892c5f438f0630e1b4361370c393ba8a000dd0dcaa2b3bf1de
F test/index.test fe3c7a1aad82af92623747e9c3f3aa94ccd51238
F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407
F test/index3.test 81bc47890b8abfb181bc35f8d10b56c069803386
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
@@ -1019,7 +1009,7 @@ F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721
F test/indexedby.test a52c8c6abfae4fbfb51d99440de4ca1840dbacc606b05e29328a2a8ba7cd914e
F test/indexexpr1.test 635261197bcdc19b9b2c59bbfa7227d525c00e9587faddb2d293c44d287ce60e
F test/indexexpr2.test d8f56b6cf4e5663486129bc18c6bde4cef9f8876942b001bfdd692a2b1a42668
F test/indexexpr2.test 08551aa8956a91582979e17b6d369f321a5cb6ed6d3e952925a3e54e9e7de216
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
F test/insert.test 5604b1ff5675cc84c34a5b315792b958f48c32edccc0dafcc81d3b776270b70a
@@ -1029,7 +1019,7 @@ F test/insert4.test 46bead5f39e181850ee56adcf49d3a3157c460c52249211714612ac89fe3
F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
F test/instr.test 9a8802f28437d8ade53fedfc47b2ca599b4e48ba
F test/instrfault.test 0f870b218ea17cd477bb19ed330eecdb460dd53a
F test/intarray.test 8319986182af37c8eb4879c6bfe9cf0074e9d43b193a4c728a0efa3417c53fb7
F test/intarray.test 46d95b457916638c5d8b1af21fb174804b3acf8b
F test/interrupt.test 16ea879ec728cb76414c148c5f24afd5d1f91054
F test/interrupt2.test e4408ca770a6feafbadb0801e54a0dcd1a8d108d
F test/intpkey.test ac71107a49a06492b69b82aafaf225400598d3c8
@@ -1063,7 +1053,7 @@ F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
F test/like.test 11cfd7d4ef8625389df9efc46735ff0b0b41d5e62047ef0f3bc24c380d28a7a6
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
F test/like3.test 430691e6057e11a59e934be74c06b85605b80061d45af5714d52886a811efeb7
F test/like3.test cf0ff2d06c9d8456283aeff405b911642298441206306aeaeaa93973233b1195
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
F test/limit2.test 9409b033284642a859fafc95f29a5a6a557bd57c1f0d7c3f554bd64ed69df77e
F test/loadext.test d077450695ddb5c1ea3ad7d48e5f5850fe732ad9
@@ -1102,7 +1092,6 @@ F test/mallocK.test 1f4b5efbf61715ab79b20b38739ff4b3d110ceb53f54e5db6da1f01c0837
F test/mallocL.test fb311ff80afddf3b1a75e52289081f4754d901dc
F test/mallocM.test 78bbe9d3da84a5c679123cdb40d7b2010b18fc46e13897e4f253c6ba6fbff134
F test/malloc_common.tcl aac62499b76be719fac31e7a3e54a7fd53272e7f
F test/malloctraceviewer.tcl b7a54595270c1d201abf1c3f3d461f27eaf24cdef623ad08a0fe5e411264c8a9
F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7
@@ -1139,7 +1128,7 @@ F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660
F test/nan.test 437d40e6d0778b050d7750726c0cbd2c9936b81962926e8f8c48ca698f00f4d1
F test/nockpt.test 8c43b25af63b0bd620cf1b003529e37b6f1dc53bd22690e96a1bd73f78dde53a
F test/nolock.test f196cf8b8fbea4e2ca345140a2b3f3b0da45c76e
F test/normalize.test 6a80564d2000702b5919ed2c1069fef0f95762142bc96a71b4c124a845165713
F test/normalize.test 1dedf653ca33b0b55fd0c7967d2861a51f1801a7aa899a02d4c0d7adfcd5acdc
F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf
F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161
F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
@@ -1178,15 +1167,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 cf0b4e498db1d0143c19641d4420df7cc27fab2c95ed0abd2c7c5753beab25b8
F test/permutations.test fdcb2d733fc21396e0300206023795463ba0d0ee5eda2042863b044933391da3
F test/pg_common.tcl 301ac19c1a52fd55166d26db929b3b89165c634d52b5f8ad76ea8cb06960db30
F test/pragma.test 7c8cfc328a1717a95663cf8edb06c52ddfeaf97bb0aee69ae7457132e8d39e7d
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
F test/pragma3.test 8300aa9c63cff1027006ca34bf413a148abbd6dcd471fa9a1ded322fe18c0df9
F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed
F test/pragma4.test 3046501bee2f652dc2a4f9c87781e2741361d6864439c8381aba6c3b774b335c
F test/pragma5.test 824ce6ced5d6b7ec71abe37fc6005ff836fe39d638273dc5192b39864b9ee983
F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8
F test/printf.test a3e559bc9d922e7fe44e9d05c6965fee34fe3bc28300a4248c6a063425246ffd
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
F test/printf2.test 30b5dd0b4b992dc5626496846ecce17ff592cacbcb11c3e589f3ac4d7e129dae
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
@@ -1213,7 +1202,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a
F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d
F test/rowvalue.test b8680f07d19c8c5223b808bba998faffcec6d505f5689ff6070280119173bb51
F test/rowvalue.test ef851a80f7e6de93b51caca9e4b6b7d2dcd540bbcca7d51860e80435b8b4c0de
F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b
F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256
F test/rowvalue4.test 2b20468da3775aba971caf3158e9696a4d99c69a7623fb495f332a596daebbee
@@ -1262,7 +1251,7 @@ F test/server1.test c2b00864514a68a0e6fd518659dc95d0050307a357a08969872bef027d78
F test/session.test 78fa2365e93d3663a6e933f86e7afc395adf18be
F test/sessionfuzz-data1.db 1f8d5def831f19b1c74571037f0d53a588ea49a6c4ca2a028fc0c27ef896dbcb
F test/sessionfuzz.c b0fcdcf757451957e17396a3af5171f1fdf9b2babc81da9fa35675df46c4729a
F test/shared.test 1826673eb5eb745fb91a3bdac99a7737057742ae38dcb0fe076a384d6727578b
F test/shared.test 1da9dbad400cee0d93f252ccf76e1ae007a63746
F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879
F test/shared3.test ab693f9b6e156b8bfb2a0ad94f29fe69602a5d38
F test/shared4.test c75f476804e76e26bf6fa0e7b421fb0ca7d07558
@@ -1274,7 +1263,7 @@ F test/sharedA.test 49d87ec54ab640fbbc3786ee3c01de94aaa482a3a9f834ad3fe92770eb69
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
F test/shell1.test d2bf5daeb6f449f0169c9ef3094db17a16a02199c5dcf1a635a3e79b07eb0edd
F test/shell1.test 707c03fbd07ac506cfb6fa09da4ee22e2b50453c3db2f404694116eb990168f3
F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
F test/shell3.test ac8c2b744014c3e9a0e26bfd829ab65f00923dc1a91ffd044863e9423cc91494
F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d
@@ -1342,9 +1331,9 @@ F test/sync.test 89539f4973c010eda5638407e71ca7fddbcd8e0594f4c9980229f804d433309
F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef2039
F test/syscall.test a39d9a36f852ae6e4800f861bc2f2e83f68bbc2112d9399931ecfadeabd2d69d
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
F test/tabfunc01.test 54300134f76db817685194d2f0e63e3fbf7380b45e0d426e00a9aee752497cfb
F test/tabfunc01.test c47171c36b3d411df2bd49719dcaa5d034f8d277477fd41d253940723b969a51
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
F test/tclsqlite.test dca8aa30d84175e7d8c8fc43d3ffa11fa56e23fbdac2679d03833a0f326edf34
F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08
@@ -1354,7 +1343,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptable2.test d2940417496e2b9548e01d09990763fbe88c316504033256d51493e1f1a5ce6a
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
F test/tester.tcl fa5656391e3b477508abe12b3b81f019b2e71397399ab38a2f32d8d7f3bf8e56
F test/tester.tcl d5138d226cc2aaacb6934cdd79acaa5edd17cad862482895b833bbf62c49aca0
F test/thread001.test b61a29dd87cf669f5f6ac96124a7c97d71b0c80d9012746072055877055cf9ef
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@@ -1527,7 +1516,7 @@ F test/trigger6.test 0e411654f122552da6590f0b4e6f781048a4a9b9
F test/trigger7.test 93cfa9b48ab9104b2b3d87bc544ac8021405643e36f23ee84635fbfaf9b8fef5
F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4
F test/trigger9.test 2226ec795a33b0460ab5cf8891e9054cc7edef41
F test/triggerA.test 837be862d8721f903dba3f3ceff05b32e0bee5214cf6ea3da5fadf12d3650e9d
F test/triggerA.test fe5597f47ee21bacb4936dc827994ed94161e332
F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe
F test/triggerC.test 302d8995f5ffe63bbc15053abb3ef7a39cf5a092
F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650
@@ -1587,7 +1576,7 @@ F test/vtabH.test 3cf9aa1c1c4381b3b3ac33f933376f06fbb99d2294a83c79b7562d3ed87be4
F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f
F test/vtabJ.test d7b73675708cf63cfcb9d443bb451fc01a028347275b7311e51f9fdf3ca6757f
F test/vtab_alter.test 736e66fb5ec7b4fee58229aa3ada2f27ec58bc58c00edae4836890c3784c6783
F test/vtab_err.test 1c476cac24c9c730f83cd7c8bf66482a30151be08d36a2283f87fc38a2dacbb1
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad
F test/wal.test 613efec03e517e1775d86b993a54877d2e29a477
F test/wal2.test 155b9efa999bdb38ce1cd729b9a4fcdbffd6b88be27f039bad1d2929d287d918
@@ -1595,7 +1584,7 @@ F test/wal3.test 2a93004bc0fb2b5c29888964024695bade278ab2
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
F test/wal5.test 9c11da7aeccd83a46d79a556ad11a18d3cb15aa9
F test/wal6.test b602704e4b066199bc89d91ca9000f335dcf4572
F test/wal64k.test 2a525c0f45d709bae3765c71045ccec5df7d100ccbd3a7860fdba46c9addb965
F test/wal64k.test 163655ecd2cb8afef4737cac2a40fdd2eeaf20b8
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
F test/wal8.test d9df3fba4caad5854ed69ed673c68482514203c8
F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750
@@ -1622,7 +1611,7 @@ F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cf
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
F test/where.test 8215d220633f08da331781cf9ede7fb7aed50eb113473c10acd39a643fd258ba
F test/where.test 480cfc1758ac9df3f70c6a2541ff586f6a4833354d5ecb548f643e30e31fddc8
F test/where2.test 478d2170637b9211f593120648858593bf2445a1
F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c
F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8
@@ -1642,7 +1631,7 @@ F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
F test/whereI.test b7769ee8dbefd987fb266715fee887f05f9ff180016b06fca7fa402df739193b
F test/whereJ.test 88287550f6ee604422403b053455b1ad894eeaa5c35d348532dfa1439286cb9a
F test/whereK.test f8e3cf26a8513ecc7f514f54df9f0572c046c42b
F test/whereL.test 0a19fc44cd1122040f56c934f1b14d0ca85bde28f270268a428dd9796ea0634c
F test/whereL.test 84de61afe4b8e5a3ff7d741c990d85cb44b3ce798cd8412d5603930f3f75014f
F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864
F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3
F test/wherelimit.test 592081800806d297dd7449b1030c863d2883d6d42901837ccd2e5a9bd962edb0
@@ -1652,7 +1641,7 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2
F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
F test/window1.test 02e481ac48c445b43bab7b3cf1e4115165b5127a1aa29e14f5372922c836f1a4
F test/window1.test 474bef1a6ac291755e51d1f9458dc11117c1870ac5e08b4d3938649b215f8334
F test/window2.tcl 9bfa842d8a62b0d36dc8c1b5972206393c43847433c6d75940b87fec93ce3143
F test/window2.test 8e6d2a1b9f54dfebee1cde961c8590cd87b4db45c50f44947a211e1b63c2a05e
F test/window3.tcl 577a3b1ff913208e5248c04dab9df17fd760ce159a752789e26d0cb4a5f91823
@@ -1660,9 +1649,9 @@ F test/window3.test e274b7f8952ca4ed25996e0e45c047192b066e0aaff2a822d4293c8c4f1d
F test/window4.tcl 511425f6b0abf9b953df54cc9c7295cc7c25d78f4ed6f7a74b094eec0120eccb
F test/window4.test c5d6bf3403e4ade2f19df2afe4c16f29fb817c392c6c1c8017edb7165c191a62
F test/window5.test 8187f46597c90b73e8f96659e893353cbda337479cc582f7a488eab351ba08d3
F test/window6.test 5eae4ae7a590ccf1e605880969ca0bad3955616ac91cad3031baea38748badb3
F test/window6.test 7574778c79cae89f1781df237bf9ff5063886deca91a36efc53934315f0e7612
F test/windowfault.test 23abad97b72c6f609002255ddd41ef5c8922408f918f9b98ad6005ab316e482f
F test/with1.test 2465d98ffce80d00553ac7135697c18b0369275b6ecc750daa2af320b8c812ca
F test/with1.test 58475190cd8caaeebea8cfeb2a264ec97a0c492b8ffe9ad20cefbb23df462f96
F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab
F test/with3.test 5e8ce2c585170bbbc0544e2a01a4941fa0be173ba5265e5c92eb588cd99a232d
F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
@@ -1711,7 +1700,7 @@ F tool/mkmsvcmin.tcl cad0c7b54d7dd92bc87d59f36d4cc4f070eb2e625f14159dc2f5c4204e6
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
F tool/mkpragmatab.tcl a1334e70a08fdf5de32cd0093613212bb11ac8f880487540987175c536ac335f
F tool/mkpragmatab.tcl 8b9b448b5eb7222d4e3f7afb3c678596784180d319eb4e01c842887ed8213b85
F tool/mkshellc.tcl 1f45770aea226ac093a9c72f718efbb88a2a2833409ec2e1c4cecae4202626f5
F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
@@ -1743,7 +1732,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
F tool/split-sqlite3c.tcl 3efcd4240b738f6bb2b5af0aea7e1e0ef9bc1c61654f645076cec883030b710c
F tool/sqldiff.c 7b9b7238284f02131dbb8f21a4e862409bff728045c5473139d28c67ac87580e
F tool/sqldiff.c 579d7e4e42c30a963781654c87d2868823120b55d59e16ca77b0edbab0218713
F tool/sqlite3_analyzer.c.in 7eeaae8b0d7577662acaabbb11107af0659d1b41bc1dfdd4d91422de27127968
F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898
F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848
@@ -1778,7 +1767,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 09b90db56c2d5e3aceae59c6bf1eb07f9db9ef38da29d2162046b88d39e47b86 a8d65214a567eb1afd703ee4d09d398247e060a610b46097a726364db2861001
R 3aab479e5526baa65c5716bd2f30b798
U dan
Z abcba01d465aa5012c21006dab111180
P 32ac0014266706baa4e98de808eb5a6d0ffdb39dc37b4e37668f339e9e238183
R ddde28c6e30330f60d15473895b4b263
T +bgcolor * #d0c0ff
T +sym-release *
T +sym-version-3.25.2 *
U drh
Z 46b344691181d24f6c0596b245d11075
+1 -1
View File
@@ -1 +1 @@
b6d549c988e765789c4a81d586170451db9f5da1973dde8aa0329445f915fbb2
fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7
+5 -10
View File
@@ -803,7 +803,7 @@ static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){
renameTokenFind(pWalker->pParse, p, (void*)pExpr);
}else if( pExpr->op==TK_COLUMN
&& pExpr->iColumn==p->iCol
&& p->pTab==pExpr->y.pTab
&& p->pTab==pExpr->pTab
){
renameTokenFind(pWalker->pParse, p, (void*)pExpr);
}
@@ -1061,14 +1061,9 @@ static int renameResolveTrigger(Parse *pParse, const char *zDb){
db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName
);
pParse->eTriggerOp = pNew->op;
/* ALWAYS() because if the table of the trigger does not exist, the
** error would have been hit before this point */
if( ALWAYS(pParse->pTriggerTab) ){
rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab);
}
/* Resolve symbols in WHEN clause */
if( rc==SQLITE_OK && pNew->pWhen ){
if( pNew->pWhen ){
rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen);
}
@@ -1346,8 +1341,8 @@ renameColumnFunc_done:
*/
static int renameTableExprCb(Walker *pWalker, Expr *pExpr){
RenameCtx *p = pWalker->u.pRename;
if( pExpr->op==TK_COLUMN && p->pTab==pExpr->y.pTab ){
renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab);
if( pExpr->op==TK_COLUMN && p->pTab==pExpr->pTab ){
renameTokenFind(pWalker->pParse, p, (void*)&pExpr->pTab);
}
return WRC_Continue;
}
@@ -1444,7 +1439,7 @@ static void renameTableFunc(
}else{
/* Modify any FK definitions to point to the new table. */
#ifndef SQLITE_OMIT_FOREIGN_KEY
if( isLegacy==0 || (db->flags & SQLITE_ForeignKeys) ){
if( db->flags & SQLITE_ForeignKeys ){
FKey *pFKey;
for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
-2
View File
@@ -151,7 +151,6 @@ void sqlite3AuthRead(
int iCol; /* Index of column in table */
assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
assert( !IN_RENAME_OBJECT || db->xAuth==0 );
if( db->xAuth==0 ) return;
iDb = sqlite3SchemaToIndex(pParse->db, pSchema);
if( iDb<0 ){
@@ -208,7 +207,6 @@ int sqlite3AuthCheck(
/* Don't do any authorization checks if the database is initialising
** or if the parser is being invoked from within sqlite3_declare_vtab.
*/
assert( !IN_RENAME_OBJECT || db->xAuth==0 );
if( db->init.busy || IN_SPECIAL_PARSE ){
return SQLITE_OK;
}
+1 -2
View File
@@ -3112,7 +3112,7 @@ static int lockBtree(BtShared *pBt){
pageSize-usableSize);
return rc;
}
if( sqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){
if( (pBt->db->flags & SQLITE_WriteSchema)==0 && nPage>nPageFile ){
rc = SQLITE_CORRUPT_BKPT;
goto page1_init_failed;
}
@@ -3586,7 +3586,6 @@ static int relocatePage(
eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE );
assert( sqlite3_mutex_held(pBt->mutex) );
assert( pDbPage->pBt==pBt );
if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT;
/* Move page iDbPage from its current location to page number iFreePage */
TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n",
+13 -31
View File
@@ -356,15 +356,17 @@ Table *sqlite3LocateTable(
if( p==0 ){
const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* If zName is the not the name of a table in the schema created using
** CREATE, then check to see if it is the name of an virtual table that
** can be an eponymous virtual table. */
Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
pMod = sqlite3PragmaVtabRegister(db, zName);
}
if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
return pMod->pEpoTab;
if( sqlite3FindDbName(db, zDbase)<1 ){
/* If zName is the not the name of a table in the schema created using
** CREATE, then check to see if it is the name of an virtual table that
** can be an eponymous virtual table. */
Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
pMod = sqlite3PragmaVtabRegister(db, zName);
}
if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
return pMod->pEpoTab;
}
}
#endif
if( (flags & LOCATE_NOERR)==0 ){
@@ -631,12 +633,6 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
/* Delete the Table structure itself.
*/
#ifdef SQLITE_ENABLE_NORMALIZE
if( pTable->pColHash ){
sqlite3HashClear(pTable->pColHash);
sqlite3_free(pTable->pColHash);
}
#endif
sqlite3DeleteColumnNames(db, pTable);
sqlite3DbFree(db, pTable->zName);
sqlite3DbFree(db, pTable->zColAff);
@@ -795,20 +791,6 @@ int sqlite3TwoPartName(
return iDb;
}
/*
** True if PRAGMA writable_schema is ON
*/
int sqlite3WritableSchema(sqlite3 *db){
testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==0 );
testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
SQLITE_WriteSchema );
testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
SQLITE_Defensive );
testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
(SQLITE_WriteSchema|SQLITE_Defensive) );
return (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==SQLITE_WriteSchema;
}
/*
** This routine is used to check if the UTF-8 string zName is a legal
** unqualified name for a new schema object (table, index, view or
@@ -818,7 +800,7 @@ int sqlite3WritableSchema(sqlite3 *db){
*/
int sqlite3CheckObjectName(Parse *pParse, const char *zName){
if( !pParse->db->init.busy && pParse->nested==0
&& sqlite3WritableSchema(pParse->db)==0
&& (pParse->db->flags & SQLITE_WriteSchema)==0
&& 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
return SQLITE_ERROR;
@@ -2440,7 +2422,7 @@ void sqlite3RootPageMoved(sqlite3 *db, int iDb, int iFrom, int iTo){
static void destroyRootPage(Parse *pParse, int iTable, int iDb){
Vdbe *v = sqlite3GetVdbe(pParse);
int r1 = sqlite3GetTempReg(pParse);
if( iTable<2 ) sqlite3ErrorMsg(pParse, "corrupt schema");
assert( iTable>1 );
sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
sqlite3MayAbort(pParse);
#ifndef SQLITE_OMIT_AUTOVACUUM
+2 -17
View File
@@ -295,21 +295,6 @@ static FuncDef *functionSearch(
}
return 0;
}
#ifdef SQLITE_ENABLE_NORMALIZE
FuncDef *sqlite3FunctionSearchN(
int h, /* Hash of the name */
const char *zFunc, /* Name of function */
int nFunc /* Length of the name */
){
FuncDef *p;
for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 ){
return p;
}
}
return 0;
}
#endif /* SQLITE_ENABLE_NORMALIZE */
/*
** Insert a new FuncDef into a FuncDefHash hash table.
@@ -323,7 +308,7 @@ void sqlite3InsertBuiltinFuncs(
FuncDef *pOther;
const char *zName = aDef[i].zName;
int nName = sqlite3Strlen30(zName);
int h = SQLITE_FUNC_HASH(zName[0], nName);
int h = (zName[0] + nName) % SQLITE_FUNC_HASH_SZ;
assert( zName[0]>='a' && zName[0]<='z' );
pOther = functionSearch(h, zName);
if( pOther ){
@@ -402,7 +387,7 @@ FuncDef *sqlite3FindFunction(
*/
if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){
bestScore = 0;
h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName);
h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
p = functionSearch(h, zName);
while( p ){
int score = matchQuality(p, nArg, enc);
-6
View File
@@ -235,9 +235,6 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_ENABLE_FTS5
"ENABLE_FTS5",
#endif
#if SQLITE_ENABLE_GEOPOLY
"ENABLE_GEOPOLY",
#endif
#if SQLITE_ENABLE_HIDDEN_COLUMNS
"ENABLE_HIDDEN_COLUMNS",
#endif
@@ -268,9 +265,6 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_ENABLE_MULTIPLEX
"ENABLE_MULTIPLEX",
#endif
#if SQLITE_ENABLE_NORMALIZE
"ENABLE_NORMALIZE",
#endif
#if SQLITE_ENABLE_NULL_TRIM
"ENABLE_NULL_TRIM",
#endif
-4
View File
@@ -313,10 +313,6 @@ static int dbpageUpdate(
Pager *pPager;
int szPage;
if( pTab->db->flags & SQLITE_Defensive ){
zErr = "read-only";
goto update_fail;
}
if( argc==1 ){
zErr = "cannot delete";
goto update_fail;
+7 -30
View File
@@ -254,7 +254,7 @@ static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
return SQLITE_OK;
}
static void statClearCells(StatPage *p){
static void statClearPage(StatPage *p){
int i;
if( p->aCell ){
for(i=0; i<p->nCell; i++){
@@ -262,12 +262,6 @@ static void statClearCells(StatPage *p){
}
sqlite3_free(p->aCell);
}
p->nCell = 0;
p->aCell = 0;
}
static void statClearPage(StatPage *p){
statClearCells(p);
sqlite3PagerUnref(p->pPg);
sqlite3_free(p->zPath);
memset(p, 0, sizeof(StatPage));
@@ -330,33 +324,22 @@ static int statDecodePage(Btree *pBt, StatPage *p){
u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0];
p->flags = aHdr[0];
if( p->flags==0x0A || p->flags==0x0D ){
isLeaf = 1;
nHdr = 8;
}else if( p->flags==0x05 || p->flags==0x02 ){
isLeaf = 0;
nHdr = 12;
}else{
goto statPageIsCorrupt;
}
if( p->iPgno==1 ) nHdr += 100;
p->nCell = get2byte(&aHdr[3]);
p->nMxPayload = 0;
szPage = sqlite3BtreeGetPageSize(pBt);
isLeaf = (p->flags==0x0A || p->flags==0x0D);
nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100;
nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell;
nUnused += (int)aHdr[7];
iOff = get2byte(&aHdr[1]);
while( iOff ){
int iNext;
if( iOff>=szPage ) goto statPageIsCorrupt;
nUnused += get2byte(&aData[iOff+2]);
iNext = get2byte(&aData[iOff]);
if( iNext<iOff+4 && iNext>0 ) goto statPageIsCorrupt;
iOff = iNext;
iOff = get2byte(&aData[iOff]);
}
p->nUnused = nUnused;
p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]);
szPage = sqlite3BtreeGetPageSize(pBt);
if( p->nCell ){
int i; /* Used to iterate through cells */
@@ -373,7 +356,6 @@ static int statDecodePage(Btree *pBt, StatPage *p){
StatCell *pCell = &p->aCell[i];
iOff = get2byte(&aData[nHdr+i*2]);
if( iOff<nHdr || iOff>=szPage ) goto statPageIsCorrupt;
if( !isLeaf ){
pCell->iChildPg = sqlite3Get4byte(&aData[iOff]);
iOff += 4;
@@ -390,8 +372,8 @@ static int statDecodePage(Btree *pBt, StatPage *p){
}
if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload;
getLocalPayload(nUsable, p->flags, nPayload, &nLocal);
if( nLocal<0 ) goto statPageIsCorrupt;
pCell->nLocal = nLocal;
assert( nLocal>=0 );
assert( nPayload>=(u32)nLocal );
assert( nLocal<=(nUsable-35) );
if( nPayload>(u32)nLocal ){
@@ -420,11 +402,6 @@ static int statDecodePage(Btree *pBt, StatPage *p){
}
return SQLITE_OK;
statPageIsCorrupt:
p->flags = 0;
statClearCells(p);
return SQLITE_OK;
}
/*
+2 -2
View File
@@ -63,8 +63,8 @@ int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
if( ( IsVirtual(pTab)
&& sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 )
|| ( (pTab->tabFlags & TF_Readonly)!=0
&& sqlite3WritableSchema(pParse->db)==0
&& pParse->nested==0)
&& (pParse->db->flags & SQLITE_WriteSchema)==0
&& pParse->nested==0 )
){
sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
return 1;
+45 -56
View File
@@ -58,8 +58,8 @@ char sqlite3ExprAffinity(Expr *pExpr){
return sqlite3AffinityType(pExpr->u.zToken, 0);
}
#endif
if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->y.pTab ){
return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){
return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
}
if( op==TK_SELECT_COLUMN ){
assert( pExpr->pLeft->flags&EP_xIsSelect );
@@ -143,13 +143,13 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
if( p->flags & EP_Generic ) break;
if( (op==TK_AGG_COLUMN || op==TK_COLUMN
|| op==TK_REGISTER || op==TK_TRIGGER)
&& p->y.pTab!=0
&& p->pTab!=0
){
/* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
/* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
** a TK_COLUMN but was previously evaluated and cached in a register */
int j = p->iColumn;
if( j>=0 ){
const char *zColl = p->y.pTab->aCol[j].zColl;
const char *zColl = p->pTab->aCol[j].zColl;
pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
}
break;
@@ -1052,10 +1052,6 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
assert( p!=0 );
/* Sanity check: Assert that the IntValue is non-negative if it exists */
assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
assert( !ExprHasProperty(p, EP_WinFunc) || p->y.pWin!=0 || db->mallocFailed );
assert( p->op!=TK_FUNCTION || ExprHasProperty(p, EP_TokenOnly|EP_Reduced)
|| p->y.pWin==0 || ExprHasProperty(p, EP_WinFunc) );
#ifdef SQLITE_DEBUG
if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
assert( p->pLeft==0 );
@@ -1074,9 +1070,8 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
}else{
sqlite3ExprListDelete(db, p->x.pList);
}
if( ExprHasProperty(p, EP_WinFunc) ){
assert( p->op==TK_FUNCTION );
sqlite3WindowDelete(db, p->y.pWin);
if( !ExprHasProperty(p, EP_Reduced) ){
sqlite3WindowDelete(db, p->pWin);
}
}
if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
@@ -1140,7 +1135,7 @@ static int dupedExprStructSize(Expr *p, int flags){
assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
if( 0==flags || p->op==TK_SELECT_COLUMN
#ifndef SQLITE_OMIT_WINDOWFUNC
|| ExprHasProperty(p, EP_WinFunc)
|| p->pWin
#endif
){
nSize = EXPR_FULLSIZE;
@@ -1167,7 +1162,7 @@ static int dupedExprStructSize(Expr *p, int flags){
static int dupedExprNodeSize(Expr *p, int flags){
int nByte = dupedExprStructSize(p, flags) & 0xfff;
if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
nByte += sqlite3Strlen30NN(p->u.zToken)+1;
nByte += sqlite3Strlen30(p->u.zToken)+1;
}
return ROUND8(nByte);
}
@@ -1270,24 +1265,22 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
}
/* Fill in pNew->pLeft and pNew->pRight. */
if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly|EP_WinFunc) ){
zAlloc += dupedExprNodeSize(p, dupFlags);
zAlloc += dupedExprNodeSize(p, dupFlags);
if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
pNew->pLeft = p->pLeft ?
exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
pNew->pRight = p->pRight ?
exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
}
}else{
#ifndef SQLITE_OMIT_WINDOWFUNC
if( ExprHasProperty(p, EP_WinFunc) ){
pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin);
assert( ExprHasProperty(pNew, EP_WinFunc) );
if( ExprHasProperty(p, EP_Reduced|EP_TokenOnly) ){
pNew->pWin = 0;
}else{
pNew->pWin = sqlite3WindowDup(db, pNew, p->pWin);
}
#endif /* SQLITE_OMIT_WINDOWFUNC */
if( pzBuffer ){
*pzBuffer = zAlloc;
}
}else{
if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
if( pNew->op==TK_SELECT_COLUMN ){
pNew->pLeft = p->pLeft;
@@ -1299,6 +1292,9 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
}
}
if( pzBuffer ){
*pzBuffer = zAlloc;
}
}
return pNew;
}
@@ -2093,8 +2089,8 @@ int sqlite3ExprCanBeNull(const Expr *p){
return 0;
case TK_COLUMN:
return ExprHasProperty(p, EP_CanBeNull) ||
p->y.pTab==0 || /* Reference to column of index on expression */
(p->iColumn>=0 && p->y.pTab->aCol[p->iColumn].notNull==0);
p->pTab==0 || /* Reference to column of index on expression */
(p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
default:
return 1;
}
@@ -2149,14 +2145,6 @@ int sqlite3IsRowid(const char *z){
if( sqlite3StrICmp(z, "OID")==0 ) return 1;
return 0;
}
#ifdef SQLITE_ENABLE_NORMALIZE
int sqlite3IsRowidN(const char *z, int n){
if( sqlite3StrNICmp(z, "_ROWID_", n)==0 ) return 1;
if( sqlite3StrNICmp(z, "ROWID", n)==0 ) return 1;
if( sqlite3StrNICmp(z, "OID", n)==0 ) return 1;
return 0;
}
#endif
/*
** pX is the RHS of an IN operator. If pX is a SELECT statement
@@ -3390,7 +3378,7 @@ expr_code_doover:
** constant.
*/
int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
int aff = sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
if( aff!=SQLITE_AFF_BLOB ){
static const char zAff[] = "B\000C\000D\000E";
assert( SQLITE_AFF_BLOB=='A' );
@@ -3414,7 +3402,7 @@ expr_code_doover:
iTab = pParse->iSelfTab - 1;
}
}
return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
pExpr->iColumn, iTab, target,
pExpr->op2);
}
@@ -3628,8 +3616,8 @@ expr_code_doover:
CollSeq *pColl = 0; /* A collating sequence */
#ifndef SQLITE_OMIT_WINDOWFUNC
if( ExprHasProperty(pExpr, EP_WinFunc) ){
return pExpr->y.pWin->regResult;
if( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) && pExpr->pWin ){
return pExpr->pWin->regResult;
}
#endif
@@ -3872,7 +3860,7 @@ expr_code_doover:
** p1==1 -> old.a p1==4 -> new.a
** p1==2 -> old.b p1==5 -> new.b
*/
Table *pTab = pExpr->y.pTab;
Table *pTab = pExpr->pTab;
int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;
assert( pExpr->iTable==0 || pExpr->iTable==1 );
@@ -3883,7 +3871,7 @@ expr_code_doover:
sqlite3VdbeAddOp2(v, OP_Param, p1, target);
VdbeComment((v, "r[%d]=%s.%s", target,
(pExpr->iTable ? "new" : "old"),
(pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[pExpr->iColumn].zName)
(pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName)
));
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -4734,20 +4722,6 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){
if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
if( pA->op==TK_FUNCTION ){
if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
#ifndef SQLITE_OMIT_WINDOWFUNC
/* Justification for the assert():
** window functions have p->op==TK_FUNCTION but aggregate functions
** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate
** function and a window function should have failed before reaching
** this point. And, it is not possible to have a window function and
** a scalar function with the same name and number of arguments. So
** if we reach this point, either A and B both window functions or
** neither are a window functions. */
assert( ExprHasProperty(pA,EP_WinFunc)==ExprHasProperty(pB,EP_WinFunc) );
if( ExprHasProperty(pA,EP_WinFunc) ){
if( sqlite3WindowCompare(pParse,pA->y.pWin,pB->y.pWin)!=0 ) return 2;
}
#endif
}else if( pA->op==TK_COLLATE ){
if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
}else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
@@ -4767,6 +4741,21 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){
if( pA->iTable!=pB->iTable
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
}
#ifndef SQLITE_OMIT_WINDOWFUNC
/* Justification for the assert():
** window functions have p->op==TK_FUNCTION but aggregate functions
** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate
** function and a window function should have failed before reaching
** this point. And, it is not possible to have a window function and
** a scalar function with the same name and number of arguments. So
** if we reach this point, either A and B both window functions or
** neither are a window functions. */
assert( (pA->pWin==0)==(pB->pWin==0) );
if( pA->pWin!=0 ){
if( sqlite3WindowCompare(pParse,pA->pWin,pB->pWin)!=0 ) return 2;
}
#endif
}
return 0;
}
@@ -4907,8 +4896,8 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
testcase( pExpr->op==TK_LE );
testcase( pExpr->op==TK_GT );
testcase( pExpr->op==TK_GE );
if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab))
|| (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab))
if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->pTab))
|| (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->pTab))
){
return WRC_Prune;
}
@@ -5139,7 +5128,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
&& (k = addAggInfoColumn(pParse->db, pAggInfo))>=0
){
pCol = &pAggInfo->aCol[k];
pCol->pTab = pExpr->y.pTab;
pCol->pTab = pExpr->pTab;
pCol->iTable = pExpr->iTable;
pCol->iColumn = pExpr->iColumn;
pCol->iMem = ++pParse->nMem;
+1 -1
View File
@@ -502,7 +502,7 @@ static Expr *exprTableColumn(
){
Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
if( pExpr ){
pExpr->y.pTab = pTab;
pExpr->pTab = pTab;
pExpr->iTable = iCursor;
pExpr->iColumn = iCol;
}
-56
View File
@@ -64,20 +64,6 @@ static unsigned int strHash(const char *z){
}
return h;
}
#ifdef SQLITE_ENABLE_NORMALIZE
static unsigned int strHashN(const char *z, int n){
unsigned int h = 0;
int i;
for(i=0; i<n; i++){
/* Knuth multiplicative hashing. (Sorting & Searching, p. 510).
** 0x9e3779b1 is 2654435761 which is the closest prime number to
** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */
h += sqlite3UpperToLower[z[i]];
h *= 0x9e3779b1;
}
return h;
}
#endif /* SQLITE_ENABLE_NORMALIZE */
/* Link pNew element into the hash table pH. If pEntry!=0 then also
@@ -189,40 +175,6 @@ static HashElem *findElementWithHash(
}
return &nullElement;
}
#ifdef SQLITE_ENABLE_NORMALIZE
static HashElem *findElementWithHashN(
const Hash *pH, /* The pH to be searched */
const char *pKey, /* The key we are searching for */
int nKey, /* Number of key bytes to use */
unsigned int *pHash /* Write the hash value here */
){
HashElem *elem; /* Used to loop thru the element list */
int count; /* Number of elements left to test */
unsigned int h; /* The computed hash */
static HashElem nullElement = { 0, 0, 0, 0 };
if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/
struct _ht *pEntry;
h = strHashN(pKey, nKey) % pH->htsize;
pEntry = &pH->ht[h];
elem = pEntry->chain;
count = pEntry->count;
}else{
h = 0;
elem = pH->first;
count = pH->count;
}
if( pHash ) *pHash = h;
while( count-- ){
assert( elem!=0 );
if( sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){
return elem;
}
elem = elem->next;
}
return &nullElement;
}
#endif /* SQLITE_ENABLE_NORMALIZE */
/* Remove a single entry from the hash table given a pointer to that
** element and a hash on the element's key.
@@ -267,14 +219,6 @@ void *sqlite3HashFind(const Hash *pH, const char *pKey){
assert( pKey!=0 );
return findElementWithHash(pH, pKey, 0)->data;
}
#ifdef SQLITE_ENABLE_NORMALIZE
void *sqlite3HashFindN(const Hash *pH, const char *pKey, int nKey){
assert( pH!=0 );
assert( pKey!=0 );
assert( nKey>=0 );
return findElementWithHashN(pH, pKey, nKey, 0)->data;
}
#endif /* SQLITE_ENABLE_NORMALIZE */
/* Insert an element into the hash table pH. The key is pKey
** and the data is "data".
+10 -27
View File
@@ -146,8 +146,7 @@ void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
}while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB );
pTab->zColAff = zColAff;
}
assert( zColAff!=0 );
i = sqlite3Strlen30NN(zColAff);
i = sqlite3Strlen30(zColAff);
if( i ){
if( iReg ){
sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i);
@@ -1127,15 +1126,14 @@ insert_cleanup:
#endif
/*
** Meanings of bits in of pWalker->eCode for
** sqlite3ExprReferencesUpdatedColumn()
** Meanings of bits in of pWalker->eCode for checkConstraintUnchanged()
*/
#define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */
#define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */
/* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn().
* Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this
** expression node references any of the
/* This is the Walker callback from checkConstraintUnchanged(). Set
** bit 0x01 of pWalker->eCode if
** pWalker->eCode to 0 if this expression node references any of the
** columns that are being modifed by an UPDATE statement.
*/
static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
@@ -1157,21 +1155,12 @@ static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
** only columns that are modified by the UPDATE are those for which
** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true.
**
** Return true if CHECK constraint pExpr uses any of the
** Return true if CHECK constraint pExpr does not use any of the
** changing columns (or the rowid if it is changing). In other words,
** return true if this CHECK constraint must be validated for
** return true if this CHECK constraint can be skipped when validating
** the new row in the UPDATE statement.
**
** 2018-09-15: pExpr might also be an expression for an index-on-expressions.
** The operation of this routine is the same - return true if an only if
** the expression uses one or more of columns identified by the second and
** third arguments.
*/
int sqlite3ExprReferencesUpdatedColumn(
Expr *pExpr, /* The expression to be checked */
int *aiChng, /* aiChng[x]>=0 if column x changed by the UPDATE */
int chngRowid /* True if UPDATE changes the rowid */
){
static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){
Walker w;
memset(&w, 0, sizeof(w));
w.eCode = 0;
@@ -1186,7 +1175,7 @@ int sqlite3ExprReferencesUpdatedColumn(
testcase( w.eCode==CKCNSTRNT_COLUMN );
testcase( w.eCode==CKCNSTRNT_ROWID );
testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
return w.eCode!=0;
return !w.eCode;
}
/*
@@ -1392,13 +1381,7 @@ void sqlite3GenerateConstraintChecks(
for(i=0; i<pCheck->nExpr; i++){
int allOk;
Expr *pExpr = pCheck->a[i].pExpr;
if( aiChng
&& !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng)
){
/* The check constraints do not reference any of the columns being
** updated so there is no point it verifying the check constraint */
continue;
}
if( aiChng && checkConstraintUnchanged(pExpr, aiChng, pkChng) ) continue;
allOk = sqlite3VdbeMakeLabel(v);
sqlite3VdbeVerifyAbortable(v, onError);
sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
+1 -7
View File
@@ -451,13 +451,7 @@ static const sqlite3_api_routines sqlite3Apis = {
sqlite3_str_length,
sqlite3_str_value,
/* Version 3.25.0 and later */
sqlite3_create_window_function,
/* Version 3.26.0 and later */
#ifdef SQLITE_ENABLE_NORMALIZE
sqlite3_normalized_sql
#else
0
#endif
sqlite3_create_window_function
};
/*
-1
View File
@@ -835,7 +835,6 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
{ SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG },
{ SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP },
{ SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase },
{ SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive },
};
unsigned int i;
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
+59 -66
View File
@@ -136,10 +136,12 @@
#define SQLITE_FSFLAGS_IS_MSDOS 0x1
/*
** If we are to be thread-safe, include the pthreads header.
** If we are to be thread-safe, include the pthreads header and define
** the SQLITE_UNIX_THREADS macro.
*/
#if SQLITE_THREADSAFE
# include <pthread.h>
# define SQLITE_UNIX_THREADS 1
#endif
/*
@@ -1117,7 +1119,8 @@ struct unixFileId {
/*
** An instance of the following structure is allocated for each open
** inode.
** inode. Or, on LinuxThreads, there is one of these structures for
** each inode opened by each thread.
**
** A single inode can have multiple file descriptors, so each unixFile
** structure contains a pointer to an instance of this object and this
@@ -1163,16 +1166,13 @@ struct unixInodeInfo {
/*
** A lists of all unixInodeInfo objects.
**
** Must hold unixBigLock in order to read or write this variable.
*/
static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */
#ifdef SQLITE_DEBUG
/*
** True if the inode mutex (on the unixFile.pFileMutex field) is held, or not.
** This routine is used only within assert() to help verify correct mutex
** usage.
** True if the inode mutex is held, or not. Used only within assert()
** to help verify correct mutex usage.
*/
int unixFileMutexHeld(unixFile *pFile){
assert( pFile->pInode );
@@ -1300,8 +1300,8 @@ static void closePendingFds(unixFile *pFile){
/*
** Release a unixInodeInfo structure previously allocated by findInodeInfo().
**
** The global mutex must be held when this routine is called, but the mutex
** on the inode being deleted must NOT be held.
** The mutex entered using the unixEnterMutex() function must be held
** when this function is called.
*/
static void releaseInodeInfo(unixFile *pFile){
unixInodeInfo *pInode = pFile->pInode;
@@ -1336,7 +1336,8 @@ static void releaseInodeInfo(unixFile *pFile){
** describes that file descriptor. Create a new one if necessary. The
** return value might be uninitialized if an error occurs.
**
** The global mutex must held when calling this routine.
** The mutex entered using the unixEnterMutex() function must be held
** when this function is called.
**
** Return an appropriate error code.
*/
@@ -1397,7 +1398,6 @@ static int findInodeInfo(
#else
fileId.ino = (u64)statbuf.st_ino;
#endif
assert( unixMutexHeld() );
pInode = inodeList;
while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
pInode = pInode->pNext;
@@ -1417,7 +1417,6 @@ static int findInodeInfo(
}
}
pInode->nRef = 1;
assert( unixMutexHeld() );
pInode->pNext = inodeList;
pInode->pPrev = 0;
if( inodeList ) inodeList->pPrev = pInode;
@@ -4215,18 +4214,18 @@ static int unixGetpagesize(void){
**
** The following fields are read-only after the object is created:
**
** hShm
** fid
** zFilename
**
** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and
** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and
** unixMutexHeld() is true when reading or writing any other field
** in this structure.
*/
struct unixShmNode {
unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */
sqlite3_mutex *pShmMutex; /* Mutex to access this object */
sqlite3_mutex *mutex; /* Mutex to access this object */
char *zFilename; /* Name of the mmapped file */
int hShm; /* Open file descriptor */
int h; /* Open file descriptor */
int szRegion; /* Size of shared-memory regions */
u16 nRegion; /* Size of array apRegion */
u8 isReadonly; /* True if read-only */
@@ -4248,16 +4247,16 @@ struct unixShmNode {
** The following fields are initialized when this object is created and
** are read-only thereafter:
**
** unixShm.pShmNode
** unixShm.pFile
** unixShm.id
**
** All other fields are read/write. The unixShm.pShmNode->pShmMutex must
** be held while accessing any read/write fields.
** All other fields are read/write. The unixShm.pFile->mutex must be held
** while accessing any read/write fields.
*/
struct unixShm {
unixShmNode *pShmNode; /* The underlying unixShmNode object */
unixShm *pNext; /* Next unixShm with the same unixShmNode */
u8 hasMutex; /* True if holding the unixShmNode->pShmMutex */
u8 hasMutex; /* True if holding the unixShmNode mutex */
u8 id; /* Id of this connection within its unixShmNode */
u16 sharedMask; /* Mask of shared locks held */
u16 exclMask; /* Mask of exclusive locks held */
@@ -4287,8 +4286,7 @@ static int unixShmSystemLock(
/* Access to the unixShmNode object is serialized by the caller */
pShmNode = pFile->pInode->pShmNode;
assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) );
assert( pShmNode->nRef>0 || unixMutexHeld() );
assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->mutex) );
/* Shared locks never span more than one byte */
assert( n==1 || lockType!=F_RDLCK );
@@ -4296,13 +4294,13 @@ static int unixShmSystemLock(
/* Locks are within range */
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
if( pShmNode->hShm>=0 ){
if( pShmNode->h>=0 ){
/* Initialize the locking parameters */
f.l_type = lockType;
f.l_whence = SEEK_SET;
f.l_start = ofst;
f.l_len = n;
rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
rc = osSetPosixAdvisoryLock(pShmNode->h, &f, pFile);
rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
}
@@ -4374,18 +4372,18 @@ static void unixShmPurge(unixFile *pFd){
int nShmPerMap = unixShmRegionPerMap();
int i;
assert( p->pInode==pFd->pInode );
sqlite3_mutex_free(p->pShmMutex);
sqlite3_mutex_free(p->mutex);
for(i=0; i<p->nRegion; i+=nShmPerMap){
if( p->hShm>=0 ){
if( p->h>=0 ){
osMunmap(p->apRegion[i], p->szRegion);
}else{
sqlite3_free(p->apRegion[i]);
}
}
sqlite3_free(p->apRegion);
if( p->hShm>=0 ){
robust_close(pFd, p->hShm, __LINE__);
p->hShm = -1;
if( p->h>=0 ){
robust_close(pFd, p->h, __LINE__);
p->h = -1;
}
p->pInode->pShmNode = 0;
sqlite3_free(p);
@@ -4427,7 +4425,7 @@ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){
lock.l_start = UNIX_SHM_DMS;
lock.l_len = 1;
lock.l_type = F_WRLCK;
if( osFcntl(pShmNode->hShm, F_GETLK, &lock)!=0 ) {
if( osFcntl(pShmNode->h, F_GETLK, &lock)!=0 ) {
rc = SQLITE_IOERR_LOCK;
}else if( lock.l_type==F_UNLCK ){
if( pShmNode->isReadonly ){
@@ -4435,12 +4433,7 @@ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){
rc = SQLITE_READONLY_CANTINIT;
}else{
rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
/* The first connection to attach must truncate the -shm file. We
** truncate to 3 bytes (an arbitrary small number, less than the
** -shm header size) rather than 0 as a system debugging aid, to
** help detect if a -shm file truncation is legitimate or is the work
** or a rogue process. */
if( rc==SQLITE_OK && robust_ftruncate(pShmNode->hShm, 3) ){
if( rc==SQLITE_OK && robust_ftruncate(pShmNode->h, 0) ){
rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename);
}
}
@@ -4546,12 +4539,12 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath);
sqlite3FileSuffix3(pDbFd->zPath, zShm);
#endif
pShmNode->hShm = -1;
pShmNode->h = -1;
pDbFd->pInode->pShmNode = pShmNode;
pShmNode->pInode = pDbFd->pInode;
if( sqlite3GlobalConfig.bCoreMutex ){
pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
if( pShmNode->pShmMutex==0 ){
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
if( pShmNode->mutex==0 ){
rc = SQLITE_NOMEM_BKPT;
goto shm_open_err;
}
@@ -4559,11 +4552,11 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
if( pInode->bProcessLock==0 ){
if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777));
pShmNode->h = robust_open(zShm, O_RDWR|O_CREAT, (sStat.st_mode&0777));
}
if( pShmNode->hShm<0 ){
pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
if( pShmNode->hShm<0 ){
if( pShmNode->h<0 ){
pShmNode->h = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
if( pShmNode->h<0 ){
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
goto shm_open_err;
}
@@ -4574,7 +4567,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
** is owned by the same user that owns the original database. Otherwise,
** the original owner will not be able to connect.
*/
robustFchown(pShmNode->hShm, sStat.st_uid, sStat.st_gid);
robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
rc = unixLockSharedMemory(pDbFd, pShmNode);
if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
@@ -4594,13 +4587,13 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
** the cover of the unixEnterMutex() mutex and the pointer from the
** new (struct unixShm) object to the pShmNode has been set. All that is
** left to do is to link the new object into the linked list starting
** at pShmNode->pFirst. This must be done while holding the
** pShmNode->pShmMutex.
** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
** mutex.
*/
sqlite3_mutex_enter(pShmNode->pShmMutex);
sqlite3_mutex_enter(pShmNode->mutex);
p->pNext = pShmNode->pFirst;
pShmNode->pFirst = p;
sqlite3_mutex_leave(pShmNode->pShmMutex);
sqlite3_mutex_leave(pShmNode->mutex);
return rc;
/* Jump here on any error */
@@ -4652,7 +4645,7 @@ static int unixShmMap(
p = pDbFd->pShm;
pShmNode = p->pShmNode;
sqlite3_mutex_enter(pShmNode->pShmMutex);
sqlite3_mutex_enter(pShmNode->mutex);
if( pShmNode->isUnlocked ){
rc = unixLockSharedMemory(pDbFd, pShmNode);
if( rc!=SQLITE_OK ) goto shmpage_out;
@@ -4660,8 +4653,8 @@ static int unixShmMap(
}
assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
assert( pShmNode->pInode==pDbFd->pInode );
assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
/* Minimum number of regions required to be mapped. */
nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap;
@@ -4673,12 +4666,12 @@ static int unixShmMap(
pShmNode->szRegion = szRegion;
if( pShmNode->hShm>=0 ){
if( pShmNode->h>=0 ){
/* The requested region is not mapped into this processes address space.
** Check to see if it has been allocated (i.e. if the wal-index file is
** large enough to contain the requested region).
*/
if( osFstat(pShmNode->hShm, &sStat) ){
if( osFstat(pShmNode->h, &sStat) ){
rc = SQLITE_IOERR_SHMSIZE;
goto shmpage_out;
}
@@ -4706,7 +4699,7 @@ static int unixShmMap(
assert( (nByte % pgsz)==0 );
for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){
int x = 0;
if( seekAndWriteFd(pShmNode->hShm, iPg*pgsz + pgsz-1,"",1,&x)!=1 ){
if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){
const char *zFile = pShmNode->zFilename;
rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
goto shmpage_out;
@@ -4729,22 +4722,22 @@ static int unixShmMap(
int nMap = szRegion*nShmPerMap;
int i;
void *pMem;
if( pShmNode->hShm>=0 ){
if( pShmNode->h>=0 ){
pMem = osMmap(0, nMap,
pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE,
MAP_SHARED, pShmNode->hShm, szRegion*(i64)pShmNode->nRegion
MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
);
if( pMem==MAP_FAILED ){
rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
goto shmpage_out;
}
}else{
pMem = sqlite3_malloc64(nMap);
pMem = sqlite3_malloc64(szRegion);
if( pMem==0 ){
rc = SQLITE_NOMEM_BKPT;
goto shmpage_out;
}
memset(pMem, 0, nMap);
memset(pMem, 0, szRegion);
}
for(i=0; i<nShmPerMap; i++){
@@ -4761,7 +4754,7 @@ shmpage_out:
*pp = 0;
}
if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
sqlite3_mutex_leave(pShmNode->pShmMutex);
sqlite3_mutex_leave(pShmNode->mutex);
return rc;
}
@@ -4795,12 +4788,12 @@ static int unixShmLock(
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
mask = (1<<(ofst+n)) - (1<<ofst);
assert( n>1 || mask==(1<<ofst) );
sqlite3_mutex_enter(pShmNode->pShmMutex);
sqlite3_mutex_enter(pShmNode->mutex);
if( flags & SQLITE_SHM_UNLOCK ){
u16 allMask = 0; /* Mask of locks held by siblings */
@@ -4873,7 +4866,7 @@ static int unixShmLock(
}
}
}
sqlite3_mutex_leave(pShmNode->pShmMutex);
sqlite3_mutex_leave(pShmNode->mutex);
OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
p->id, osGetpid(0), p->sharedMask, p->exclMask));
return rc;
@@ -4923,14 +4916,14 @@ static int unixShmUnmap(
/* Remove connection p from the set of connections associated
** with pShmNode */
sqlite3_mutex_enter(pShmNode->pShmMutex);
sqlite3_mutex_enter(pShmNode->mutex);
for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
*pp = p->pNext;
/* Free the connection p */
sqlite3_free(p);
pDbFd->pShm = 0;
sqlite3_mutex_leave(pShmNode->pShmMutex);
sqlite3_mutex_leave(pShmNode->mutex);
/* If pShmNode->nRef has reached 0, then close the underlying
** shared-memory file, too */
@@ -4939,7 +4932,7 @@ static int unixShmUnmap(
assert( pShmNode->nRef>0 );
pShmNode->nRef--;
if( pShmNode->nRef==0 ){
if( deleteFlag && pShmNode->hShm>=0 ){
if( deleteFlag && pShmNode->h>=0 ){
osUnlink(pShmNode->zFilename);
}
unixShmPurge(pDbFd);
-1
View File
@@ -7021,7 +7021,6 @@ void sqlite3PagerSetCodec(
void (*xCodecFree)(void*),
void *pCodec
){
pager_reset(pPager);
if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
pPager->xCodec = pPager->memDb ? 0 : xCodec;
pPager->xCodecSizeChng = xCodecSizeChng;
+4 -1
View File
@@ -941,10 +941,13 @@ idlist(A) ::= nm(Y).
p->pLeft = p->pRight = 0;
p->x.pList = 0;
p->pAggInfo = 0;
p->y.pTab = 0;
p->pTab = 0;
p->op2 = 0;
p->iTable = 0;
p->iColumn = 0;
#ifndef SQLITE_OMIT_WINDOWFUNC
p->pWin = 0;
#endif
p->u.zToken = (char*)&p[1];
memcpy(p->u.zToken, t.z, t.n);
p->u.zToken[t.n] = 0;
+1 -1
View File
@@ -32,7 +32,7 @@
** The PCache.pSynced variable is used to optimize searching for a dirty
** page to eject from the cache mid-transaction. It is better to eject
** a page that does not require a journal sync than one that does.
** Therefore, pSynced is maintained so that it *almost* always points
** Therefore, pSynced is maintained to that it *almost* always points
** to either the oldest page in the pDirty/pDirtyTail list that has a
** clear PGHDR_NEED_SYNC flag or to a page that is older than this one
** (so that the right page to eject can be found by following pDirtyPrev
+11 -25
View File
@@ -1037,7 +1037,7 @@ void sqlite3Pragma(
setPragmaResultColumnNames(v, pPragma);
returnSingleInt(v, (db->flags & pPragma->iArg)!=0 );
}else{
u64 mask = pPragma->iArg; /* Mask of bits to set or clear. */
int mask = pPragma->iArg; /* Mask of bits to set or clear. */
if( db->autoCommit==0 ){
/* Foreign key support may not be enabled or disabled while not
** in auto-commit mode. */
@@ -1090,12 +1090,11 @@ void sqlite3Pragma(
int nHidden = 0;
Column *pCol;
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
pParse->nMem = 7;
pParse->nMem = 6;
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3ViewGetColumnNames(pParse, pTab);
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
int isHidden = IsHiddenColumn(pCol);
if( isHidden && pPragma->iArg==0 ){
if( IsHiddenColumn(pCol) ){
nHidden++;
continue;
}
@@ -1107,14 +1106,13 @@ void sqlite3Pragma(
for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
}
assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi",
sqlite3VdbeMultiLoad(v, 1, "issisi",
i-nHidden,
pCol->zName,
sqlite3ColumnType(pCol,""),
pCol->notNull ? 1 : 0,
pCol->pDflt ? pCol->pDflt->u.zToken : 0,
k,
isHidden);
k);
}
}
}
@@ -2118,24 +2116,12 @@ void sqlite3Pragma(
#endif
#ifdef SQLITE_HAS_CODEC
/* Pragma iArg
** ---------- ------
** key 0
** rekey 1
** hexkey 2
** hexrekey 3
** textkey 4
** textrekey 5
*/
case PragTyp_KEY: {
if( zRight ){
int n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1;
if( (pPragma->iArg & 1)==0 ){
sqlite3_key_v2(db, zDb, zRight, n);
}else{
sqlite3_rekey_v2(db, zDb, zRight, n);
}
}
if( zRight ) sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
break;
}
case PragTyp_REKEY: {
if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
break;
}
case PragTyp_HEXKEY: {
@@ -2147,7 +2133,7 @@ void sqlite3Pragma(
iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
if( (i&1)!=0 ) zKey[i/2] = iByte;
}
if( (pPragma->iArg & 1)==0 ){
if( (zLeft[3] & 0xf)==0xb ){
sqlite3_key_v2(db, zDb, zKey, i/2);
}else{
sqlite3_rekey_v2(db, zDb, zKey, i/2);
+71 -86
View File
@@ -48,9 +48,10 @@
#define PragTyp_ACTIVATE_EXTENSIONS 40
#define PragTyp_HEXKEY 41
#define PragTyp_KEY 42
#define PragTyp_LOCK_STATUS 43
#define PragTyp_PARSER_TRACE 44
#define PragTyp_STATS 45
#define PragTyp_REKEY 43
#define PragTyp_LOCK_STATUS 44
#define PragTyp_PARSER_TRACE 45
#define PragTyp_STATS 46
/* Property flags associated with various pragma. */
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
@@ -67,57 +68,58 @@
** result column is different from the name of the pragma
*/
static const char *const pragCName[] = {
/* 0 */ "id", /* Used by: foreign_key_list */
/* 1 */ "seq",
/* 2 */ "table",
/* 3 */ "from",
/* 4 */ "to",
/* 5 */ "on_update",
/* 6 */ "on_delete",
/* 7 */ "match",
/* 8 */ "cid", /* Used by: table_xinfo */
/* 9 */ "name",
/* 10 */ "type",
/* 11 */ "notnull",
/* 12 */ "dflt_value",
/* 13 */ "pk",
/* 14 */ "hidden",
/* table_info reuses 8 */
/* 0 */ "cache_size", /* Used by: default_cache_size */
/* 1 */ "cid", /* Used by: table_info */
/* 2 */ "name",
/* 3 */ "type",
/* 4 */ "notnull",
/* 5 */ "dflt_value",
/* 6 */ "pk",
/* 7 */ "tbl", /* Used by: stats */
/* 8 */ "idx",
/* 9 */ "wdth",
/* 10 */ "hght",
/* 11 */ "flgs",
/* 12 */ "seqno", /* Used by: index_info */
/* 13 */ "cid",
/* 14 */ "name",
/* 15 */ "seqno", /* Used by: index_xinfo */
/* 16 */ "cid",
/* 17 */ "name",
/* 18 */ "desc",
/* 19 */ "coll",
/* 20 */ "key",
/* 21 */ "tbl", /* Used by: stats */
/* 22 */ "idx",
/* 23 */ "wdth",
/* 24 */ "hght",
/* 25 */ "flgs",
/* 26 */ "seq", /* Used by: index_list */
/* 21 */ "seq", /* Used by: index_list */
/* 22 */ "name",
/* 23 */ "unique",
/* 24 */ "origin",
/* 25 */ "partial",
/* 26 */ "seq", /* Used by: database_list */
/* 27 */ "name",
/* 28 */ "unique",
/* 29 */ "origin",
/* 30 */ "partial",
/* 31 */ "table", /* Used by: foreign_key_check */
/* 32 */ "rowid",
/* 33 */ "parent",
/* 34 */ "fkid",
/* index_info reuses 15 */
/* 35 */ "seq", /* Used by: database_list */
/* 36 */ "name",
/* 37 */ "file",
/* 38 */ "busy", /* Used by: wal_checkpoint */
/* 39 */ "log",
/* 40 */ "checkpointed",
/* 41 */ "name", /* Used by: function_list */
/* 42 */ "builtin",
/* collation_list reuses 26 */
/* 43 */ "database", /* Used by: lock_status */
/* 44 */ "status",
/* 45 */ "cache_size", /* Used by: default_cache_size */
/* module_list pragma_list reuses 9 */
/* 46 */ "timeout", /* Used by: busy_timeout */
/* 28 */ "file",
/* 29 */ "name", /* Used by: function_list */
/* 30 */ "builtin",
/* 31 */ "name", /* Used by: module_list pragma_list */
/* 32 */ "seq", /* Used by: collation_list */
/* 33 */ "name",
/* 34 */ "id", /* Used by: foreign_key_list */
/* 35 */ "seq",
/* 36 */ "table",
/* 37 */ "from",
/* 38 */ "to",
/* 39 */ "on_update",
/* 40 */ "on_delete",
/* 41 */ "match",
/* 42 */ "table", /* Used by: foreign_key_check */
/* 43 */ "rowid",
/* 44 */ "parent",
/* 45 */ "fkid",
/* 46 */ "busy", /* Used by: wal_checkpoint */
/* 47 */ "log",
/* 48 */ "checkpointed",
/* 49 */ "timeout", /* Used by: busy_timeout */
/* 50 */ "database", /* Used by: lock_status */
/* 51 */ "status",
};
/* Definitions of all built-in pragmas */
@@ -127,7 +129,7 @@ typedef struct PragmaName {
u8 mPragFlg; /* Zero or more PragFlg_XXX values */
u8 iPragCName; /* Start of column names in pragCName[] */
u8 nPragCName; /* Num of col names. 0 means use pragma name */
u64 iArg; /* Extra argument */
u32 iArg; /* Extra argument */
} PragmaName;
static const PragmaName aPragmaName[] = {
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
@@ -163,7 +165,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "busy_timeout",
/* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 46, 1,
/* ColNames: */ 49, 1,
/* iArg: */ 0 },
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "cache_size",
@@ -200,7 +202,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "collation_list",
/* ePragTyp: */ PragTyp_COLLATION_LIST,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 26, 2,
/* ColNames: */ 32, 2,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
@@ -235,14 +237,14 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "database_list",
/* ePragTyp: */ PragTyp_DATABASE_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
/* ColNames: */ 35, 3,
/* ColNames: */ 26, 3,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
{/* zName: */ "default_cache_size",
/* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
/* ColNames: */ 45, 1,
/* ColNames: */ 0, 1,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
@@ -272,14 +274,14 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "foreign_key_check",
/* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
/* ColNames: */ 31, 4,
/* ColNames: */ 42, 4,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
{/* zName: */ "foreign_key_list",
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
/* ColNames: */ 0, 8,
/* ColNames: */ 34, 8,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
@@ -315,7 +317,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "function_list",
/* ePragTyp: */ PragTyp_FUNCTION_LIST,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 41, 2,
/* ColNames: */ 29, 2,
/* iArg: */ 0 },
#endif
#endif
@@ -324,12 +326,12 @@ static const PragmaName aPragmaName[] = {
/* ePragTyp: */ PragTyp_HEXKEY,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
/* iArg: */ 2 },
/* iArg: */ 0 },
{/* zName: */ "hexrekey",
/* ePragTyp: */ PragTyp_HEXKEY,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
/* iArg: */ 3 },
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_CHECK)
@@ -351,12 +353,12 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "index_info",
/* ePragTyp: */ PragTyp_INDEX_INFO,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
/* ColNames: */ 15, 3,
/* ColNames: */ 12, 3,
/* iArg: */ 0 },
{/* zName: */ "index_list",
/* ePragTyp: */ PragTyp_INDEX_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
/* ColNames: */ 26, 5,
/* ColNames: */ 21, 5,
/* iArg: */ 0 },
{/* zName: */ "index_xinfo",
/* ePragTyp: */ PragTyp_INDEX_INFO,
@@ -413,7 +415,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "lock_status",
/* ePragTyp: */ PragTyp_LOCK_STATUS,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 43, 2,
/* ColNames: */ 50, 2,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
@@ -439,7 +441,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "module_list",
/* ePragTyp: */ PragTyp_MODULE_LIST,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 9, 1,
/* ColNames: */ 31, 1,
/* iArg: */ 0 },
#endif
#endif
@@ -472,7 +474,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "pragma_list",
/* ePragTyp: */ PragTyp_PRAGMA_LIST,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 9, 1,
/* ColNames: */ 31, 1,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
@@ -503,10 +505,10 @@ static const PragmaName aPragmaName[] = {
#endif
#if defined(SQLITE_HAS_CODEC)
{/* zName: */ "rekey",
/* ePragTyp: */ PragTyp_KEY,
/* ePragTyp: */ PragTyp_REKEY,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
/* iArg: */ 1 },
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{/* zName: */ "reverse_unordered_selects",
@@ -559,7 +561,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "stats",
/* ePragTyp: */ PragTyp_STATS,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
/* ColNames: */ 21, 5,
/* ColNames: */ 7, 5,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
@@ -573,13 +575,8 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "table_info",
/* ePragTyp: */ PragTyp_TABLE_INFO,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
/* ColNames: */ 8, 6,
/* ColNames: */ 1, 6,
/* iArg: */ 0 },
{/* zName: */ "table_xinfo",
/* ePragTyp: */ PragTyp_TABLE_INFO,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
/* ColNames: */ 8, 7,
/* iArg: */ 1 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "temp_store",
@@ -592,18 +589,6 @@ static const PragmaName aPragmaName[] = {
/* ePragFlg: */ PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
#if defined(SQLITE_HAS_CODEC)
{/* zName: */ "textkey",
/* ePragTyp: */ PragTyp_KEY,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
/* iArg: */ 4 },
{/* zName: */ "textrekey",
/* ePragTyp: */ PragTyp_KEY,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
/* iArg: */ 5 },
#endif
{/* zName: */ "threads",
/* ePragTyp: */ PragTyp_THREADS,
@@ -655,7 +640,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "wal_checkpoint",
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
/* ePragFlg: */ PragFlg_NeedSchema,
/* ColNames: */ 38, 3,
/* ColNames: */ 46, 3,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
@@ -663,7 +648,7 @@ static const PragmaName aPragmaName[] = {
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
/* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
/* iArg: */ SQLITE_WriteSchema },
#endif
};
/* Number of pragmas: 62 on by default, 81 total. */
/* Number of pragmas: 61 on by default, 78 total. */
+2 -290
View File
@@ -327,8 +327,8 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
rc = SQLITE_NOMEM_BKPT;
sqlite3ResetAllSchemasOfConnection(db);
}
if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){
/* Black magic: If the SQLITE_NoSchemaError flag is set, then consider
if( rc==SQLITE_OK || (db->flags&SQLITE_WriteSchema)){
/* Black magic: If the SQLITE_WriteSchema flag is set, then consider
** the schema loaded, even if errors occurred. In this situation the
** current sqlite3_prepare() operation will fail, but the following one
** will attempt to compile the supplied statement against whatever subset
@@ -709,294 +709,6 @@ static int sqlite3LockAndPrepare(
return rc;
}
#ifdef SQLITE_ENABLE_NORMALIZE
/*
** Checks if the specified token is a table, column, or function name,
** based on the databases associated with the statement being prepared.
** If the function fails, zero is returned and pRc is filled with the
** error code.
*/
static int shouldTreatAsIdentifier(
sqlite3 *db, /* Database handle. */
const char *zToken, /* Pointer to start of token to be checked */
int nToken, /* Length of token to be checked */
int *pRc /* Pointer to error code upon failure */
){
int bFound = 0; /* Non-zero if token is an identifier name. */
int i, j; /* Database and column loop indexes. */
Schema *pSchema; /* Schema for current database. */
Hash *pHash; /* Hash table of tables for current database. */
HashElem *e; /* Hash element for hash table iteration. */
Table *pTab; /* Database table for columns being checked. */
if( sqlite3IsRowidN(zToken, nToken) ){
return 1;
}
if( nToken>0 ){
int hash = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zToken[0]], nToken);
if( sqlite3FunctionSearchN(hash, zToken, nToken) ) return 1;
}
assert( db!=0 );
sqlite3_mutex_enter(db->mutex);
sqlite3BtreeEnterAll(db);
for(i=0; i<db->nDb; i++){
pHash = &db->aFunc;
if( sqlite3HashFindN(pHash, zToken, nToken) ){
bFound = 1;
break;
}
pSchema = db->aDb[i].pSchema;
if( pSchema==0 ) continue;
pHash = &pSchema->tblHash;
if( sqlite3HashFindN(pHash, zToken, nToken) ){
bFound = 1;
break;
}
for(e=sqliteHashFirst(pHash); e; e=sqliteHashNext(e)){
pTab = sqliteHashData(e);
if( pTab==0 ) continue;
pHash = pTab->pColHash;
if( pHash==0 ){
pTab->pColHash = pHash = sqlite3_malloc(sizeof(Hash));
if( pHash ){
sqlite3HashInit(pHash);
for(j=0; j<pTab->nCol; j++){
Column *pCol = &pTab->aCol[j];
sqlite3HashInsert(pHash, pCol->zName, pCol);
}
}else{
*pRc = SQLITE_NOMEM_BKPT;
bFound = 0;
goto done;
}
}
if( pHash && sqlite3HashFindN(pHash, zToken, nToken) ){
bFound = 1;
goto done;
}
}
}
done:
sqlite3BtreeLeaveAll(db);
sqlite3_mutex_leave(db->mutex);
return bFound;
}
/*
** Attempt to estimate the final output buffer size needed for the fully
** normalized version of the specified SQL string. This should take into
** account any potential expansion that could occur (e.g. via IN clauses
** being expanded, etc). This size returned is the total number of bytes
** including the NUL terminator.
*/
static int estimateNormalizedSize(
const char *zSql, /* The original SQL string */
int nSql, /* Length of original SQL string */
u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */
){
int nOut = nSql + 4;
const char *z = zSql;
while( nOut<nSql*5 ){
while( z[0]!=0 && z[0]!='I' && z[0]!='i' ){ z++; }
if( z[0]==0 ) break;
z++;
if( z[0]!='N' && z[0]!='n' ) break;
z++;
while( sqlite3Isspace(z[0]) ){ z++; }
if( z[0]!='(' ) break;
z++;
nOut += 5; /* ?,?,? */
}
return nOut;
}
/*
** Copy the current token into the output buffer while dealing with quoted
** identifiers. By default, all letters will be converted into lowercase.
** If the bUpper flag is set, uppercase will be used. The piOut argument
** will be used to update the target index into the output string.
*/
static void copyNormalizedToken(
const char *zSql, /* The original SQL string */
int iIn, /* Current index into the original SQL string */
int nToken, /* Number of bytes in the current token */
int tokenFlags, /* Flags returned by the tokenizer */
char *zOut, /* The output string */
int *piOut /* Pointer to target index into the output string */
){
int bQuoted = tokenFlags & SQLITE_TOKEN_QUOTED;
int bKeyword = tokenFlags & SQLITE_TOKEN_KEYWORD;
int j = *piOut, k = 0;
for(; k<nToken; k++){
if( bQuoted ){
if( k==0 && iIn>0 ){
zOut[j++] = '"';
continue;
}else if( k==nToken-1 ){
zOut[j++] = '"';
continue;
}
}
if( bKeyword ){
zOut[j++] = sqlite3Toupper(zSql[iIn+k]);
}else{
zOut[j++] = sqlite3Tolower(zSql[iIn+k]);
}
}
*piOut = j;
}
/*
** Perform normalization of the SQL contained in the prepared statement and
** store the result in the zNormSql field. The schema for the associated
** databases are consulted while performing the normalization in order to
** determine if a token appears to be an identifier. All identifiers are
** left intact in the normalized SQL and all literals are replaced with a
** single '?'.
*/
void sqlite3Normalize(
Vdbe *pVdbe, /* VM being reprepared */
const char *zSql, /* The original SQL string */
int nSql, /* Size of the input string in bytes */
u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */
){
sqlite3 *db; /* Database handle. */
char *z; /* The output string */
int nZ; /* Size of the output string in bytes */
int i; /* Next character to read from zSql[] */
int j; /* Next character to fill in on z[] */
int tokenType = 0; /* Type of the next token */
int prevTokenType = 0; /* Type of the previous token, except spaces */
int n; /* Size of the next token */
int nParen = 0; /* Nesting level of parenthesis */
Hash inHash; /* Table of parenthesis levels to output index. */
db = sqlite3VdbeDb(pVdbe);
assert( db!=0 );
assert( pVdbe->zNormSql==0 );
if( zSql==0 ) return;
nZ = estimateNormalizedSize(zSql, nSql, prepFlags);
z = sqlite3DbMallocRawNN(db, nZ);
if( z==0 ) return;
sqlite3HashInit(&inHash);
for(i=j=0; i<nSql && zSql[i]; i+=n){
int flags = 0;
if( tokenType!=TK_SPACE ) prevTokenType = tokenType;
n = sqlite3GetTokenNormalized((unsigned char*)zSql+i, &tokenType, &flags);
switch( tokenType ){
case TK_SPACE: {
break;
}
case TK_ILLEGAL: {
sqlite3DbFree(db, z);
sqlite3HashClear(&inHash);
return;
}
case TK_STRING:
case TK_INTEGER:
case TK_FLOAT:
case TK_VARIABLE:
case TK_BLOB: {
z[j++] = '?';
break;
}
case TK_LP:
case TK_RP: {
if( tokenType==TK_LP ){
nParen++;
if( prevTokenType==TK_IN ){
assert( nParen<nSql );
sqlite3HashInsert(&inHash, zSql+nParen, SQLITE_INT_TO_PTR(j));
}
}else{
int jj;
assert( nParen<nSql );
jj = SQLITE_PTR_TO_INT(sqlite3HashFind(&inHash, zSql+nParen));
if( jj>0 ){
sqlite3HashInsert(&inHash, zSql+nParen, 0);
assert( jj+6<nZ );
memcpy(z+jj+1, "?,?,?", 5);
j = jj+6;
assert( nZ-1-j>=0 );
assert( nZ-1-j<nZ );
memset(z+j, 0, nZ-1-j);
}
nParen--;
}
assert( nParen>=0 );
/* Fall through */
}
case TK_MINUS:
case TK_SEMI:
case TK_PLUS:
case TK_STAR:
case TK_SLASH:
case TK_REM:
case TK_EQ:
case TK_LE:
case TK_NE:
case TK_LSHIFT:
case TK_LT:
case TK_RSHIFT:
case TK_GT:
case TK_GE:
case TK_BITOR:
case TK_CONCAT:
case TK_COMMA:
case TK_BITAND:
case TK_BITNOT:
case TK_DOT:
case TK_IN:
case TK_IS:
case TK_NOT:
case TK_NULL:
case TK_ID: {
if( tokenType==TK_NULL ){
if( prevTokenType==TK_IS || prevTokenType==TK_NOT ){
/* NULL is a keyword in this case, not a literal value */
}else{
/* Here the NULL is a literal value */
z[j++] = '?';
break;
}
}
if( j>0 && sqlite3IsIdChar(z[j-1]) && sqlite3IsIdChar(zSql[i]) ){
z[j++] = ' ';
}
if( tokenType==TK_ID ){
int i2 = i, n2 = n, rc = SQLITE_OK;
if( nParen>0 ){
assert( nParen<nSql );
sqlite3HashInsert(&inHash, zSql+nParen, 0);
}
if( flags&SQLITE_TOKEN_QUOTED ){ i2++; n2-=2; }
if( shouldTreatAsIdentifier(db, zSql+i2, n2, &rc)==0 ){
if( rc!=SQLITE_OK ){
sqlite3DbFree(db, z);
sqlite3HashClear(&inHash);
return;
}
if( sqlite3_keyword_check(zSql+i2, n2)==0 ){
z[j++] = '?';
break;
}
}
}
copyNormalizedToken(zSql, i, n, flags, z, &j);
break;
}
}
}
assert( j<nZ && "one" );
while( j>0 && z[j-1]==' ' ){ j--; }
if( j>0 && z[j-1]!=';' ){ z[j++] = ';'; }
z[j] = 0;
assert( j<nZ && "two" );
pVdbe->zNormSql = z;
sqlite3HashClear(&inHash);
}
#endif /* SQLITE_ENABLE_NORMALIZE */
/*
** Rerun the compilation of a statement after a schema change.
**
+29 -26
View File
@@ -159,7 +159,7 @@ int sqlite3MatchSpanName(
** (even if X is implied).
** pExpr->iTable Set to the cursor number for the table obtained
** from pSrcList.
** pExpr->y.pTab Points to the Table structure of X.Y (even if
** pExpr->pTab Points to the Table structure of X.Y (even if
** X and/or Y are implied.)
** pExpr->iColumn Set to the column number within the table.
** pExpr->op Set to TK_COLUMN.
@@ -203,6 +203,7 @@ static int lookupName(
/* Initialize the node to no-match */
pExpr->iTable = -1;
pExpr->pTab = 0;
ExprSetVVAProperty(pExpr, EP_NoReduce);
/* Translate the schema name in zDb into a pointer to the corresponding
@@ -264,7 +265,7 @@ static int lookupName(
continue;
}
if( IN_RENAME_OBJECT && pItem->zAlias ){
sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->pTab);
}
}
if( 0==(cntTab++) ){
@@ -290,13 +291,13 @@ static int lookupName(
}
if( pMatch ){
pExpr->iTable = pMatch->iCursor;
pExpr->y.pTab = pMatch->pTab;
pExpr->pTab = pMatch->pTab;
/* RIGHT JOIN not (yet) supported */
assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
ExprSetProperty(pExpr, EP_CanBeNull);
}
pSchema = pExpr->y.pTab->pSchema;
pSchema = pExpr->pTab->pSchema;
}
} /* if( pSrcList ) */
@@ -353,7 +354,7 @@ static int lookupName(
testcase( iCol==(-1) );
if( IN_RENAME_OBJECT ){
pExpr->iColumn = iCol;
pExpr->y.pTab = pTab;
pExpr->pTab = pTab;
eNewExprOp = TK_COLUMN;
}else{
pExpr->iTable = pNC->uNC.pUpsert->regData + iCol;
@@ -375,7 +376,7 @@ static int lookupName(
testcase( iCol==32 );
pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
}
pExpr->y.pTab = pTab;
pExpr->pTab = pTab;
pExpr->iColumn = (i16)iCol;
eNewExprOp = TK_TRIGGER;
#endif /* SQLITE_OMIT_TRIGGER */
@@ -475,7 +476,7 @@ static int lookupName(
assert( pExpr->op==TK_ID );
if( ExprHasProperty(pExpr,EP_DblQuoted) ){
pExpr->op = TK_STRING;
pExpr->y.pTab = 0;
pExpr->pTab = 0;
return WRC_Prune;
}
if( sqlite3ExprIdToTrueFalse(pExpr) ){
@@ -553,9 +554,9 @@ Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){
Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
if( p ){
struct SrcList_item *pItem = &pSrc->a[iSrc];
p->y.pTab = pItem->pTab;
p->pTab = pItem->pTab;
p->iTable = pItem->iCursor;
if( p->y.pTab->iPKey==iCol ){
if( p->pTab->iPKey==iCol ){
p->iColumn = -1;
}else{
p->iColumn = (ynVar)iCol;
@@ -645,7 +646,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
pItem = pSrcList->a;
assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 );
pExpr->op = TK_COLUMN;
pExpr->y.pTab = pItem->pTab;
pExpr->pTab = pItem->pTab;
pExpr->iTable = pItem->iCursor;
pExpr->iColumn = -1;
pExpr->affinity = SQLITE_AFF_INTEGER;
@@ -689,7 +690,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
zColumn = pRight->u.zToken;
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft);
}
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenRemap(pParse, (void*)&pExpr->pTab, (void*)pLeft);
}
}
return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
@@ -779,18 +782,18 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|| (pDef->xValue==0 && pDef->xInverse==0)
|| (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
);
if( pDef && pDef->xValue==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
if( pDef && pDef->xValue==0 && pExpr->pWin ){
sqlite3ErrorMsg(pParse,
"%.*s() may not be used as a window function", nId, zId
);
pNC->nErr++;
}else if(
(is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
|| (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pExpr->y.pWin)
|| (is_agg && pExpr->y.pWin && (pNC->ncFlags & NC_AllowWin)==0)
|| (is_agg && (pDef->funcFlags & SQLITE_FUNC_WINDOW) && !pExpr->pWin)
|| (is_agg && pExpr->pWin && (pNC->ncFlags & NC_AllowWin)==0)
){
const char *zType;
if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->y.pWin ){
if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->pWin ){
zType = "window";
}else{
zType = "aggregate";
@@ -820,7 +823,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
}
if( is_agg ){
#ifndef SQLITE_OMIT_WINDOWFUNC
pNC->ncFlags &= ~(pExpr->y.pWin ? NC_AllowWin : NC_AllowAgg);
pNC->ncFlags &= ~(pExpr->pWin ? NC_AllowWin : NC_AllowAgg);
#else
pNC->ncFlags &= ~NC_AllowAgg;
#endif
@@ -829,17 +832,17 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
sqlite3WalkExprList(pWalker, pList);
if( is_agg ){
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pExpr->y.pWin ){
if( pExpr->pWin ){
Select *pSel = pNC->pWinSelect;
sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
sqlite3WalkExprList(pWalker, pExpr->pWin->pPartition);
sqlite3WalkExprList(pWalker, pExpr->pWin->pOrderBy);
sqlite3WalkExpr(pWalker, pExpr->pWin->pFilter);
sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->pWin, pDef);
if( 0==pSel->pWin
|| 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin)
|| 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->pWin)
){
pExpr->y.pWin->pNextWin = pSel->pWin;
pSel->pWin = pExpr->y.pWin;
pExpr->pWin->pNextWin = pSel->pWin;
pSel->pWin = pExpr->pWin;
}
pNC->ncFlags |= NC_AllowWin;
}else
@@ -1262,13 +1265,13 @@ static int resolveOrderGroupBy(
for(j=0; j<pSelect->pEList->nExpr; j++){
if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
#ifndef SQLITE_OMIT_WINDOWFUNC
if( ExprHasProperty(pE, EP_WinFunc) ){
if( pE->pWin ){
/* Since this window function is being changed into a reference
** to the same window function the result set, remove the instance
** of this window function from the Select.pWin list. */
Window **pp;
for(pp=&pSelect->pWin; *pp; pp=&(*pp)->pNextWin){
if( *pp==pE->y.pWin ){
if( *pp==pE->pWin ){
*pp = (*pp)->pNextWin;
}
}
+12 -34
View File
@@ -803,7 +803,7 @@ static void selectExprDefer(
struct ExprList_item *pItem = &pEList->a[i];
if( pItem->u.x.iOrderByCol==0 ){
Expr *pExpr = pItem->pExpr;
Table *pTab = pExpr->y.pTab;
Table *pTab = pExpr->pTab;
if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab)
&& (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)
){
@@ -826,12 +826,12 @@ static void selectExprDefer(
Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0);
if( pNew ){
pNew->iTable = pExpr->iTable;
pNew->y.pTab = pExpr->y.pTab;
pNew->pTab = pExpr->pTab;
pNew->iColumn = pPk ? pPk->aiColumn[k] : -1;
pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew);
}
}
pSort->aDefer[nDefer].pTab = pExpr->y.pTab;
pSort->aDefer[nDefer].pTab = pExpr->pTab;
pSort->aDefer[nDefer].iCsr = pExpr->iTable;
pSort->aDefer[nDefer].nKey = nKey;
nDefer++;
@@ -1680,7 +1680,7 @@ static const char *columnTypeImpl(
break;
}
assert( pTab && pExpr->y.pTab==pTab );
assert( pTab && pExpr->pTab==pTab );
if( pS ){
/* The "table" is actually a sub-select or a view in the FROM clause
** of the SELECT statement. Return the declaration type and origin
@@ -1865,7 +1865,7 @@ static void generateColumnNames(
assert( p!=0 );
assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */
assert( p->op!=TK_COLUMN || p->y.pTab!=0 ); /* Covering idx not yet coded */
assert( p->op!=TK_COLUMN || p->pTab!=0 ); /* Covering idx not yet coded */
if( pEList->a[i].zName ){
/* An AS clause always takes first priority */
char *zName = pEList->a[i].zName;
@@ -1873,7 +1873,7 @@ static void generateColumnNames(
}else if( srcName && p->op==TK_COLUMN ){
char *zCol;
int iCol = p->iColumn;
pTab = p->y.pTab;
pTab = p->pTab;
assert( pTab!=0 );
if( iCol<0 ) iCol = pTab->iPKey;
assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
@@ -1964,7 +1964,7 @@ int sqlite3ColumnsFromExprList(
if( pColExpr->op==TK_COLUMN ){
/* For columns use the column name name */
int iCol = pColExpr->iColumn;
Table *pTab = pColExpr->y.pTab;
Table *pTab = pColExpr->pTab;
assert( pTab!=0 );
if( iCol<0 ) iCol = pTab->iPKey;
zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
@@ -2318,13 +2318,6 @@ static void generateWithRecursiveQuery(
Expr *pLimit; /* Saved LIMIT and OFFSET */
int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */
#ifndef SQLITE_OMIT_WINDOWFUNC
if( p->pWin ){
sqlite3ErrorMsg(pParse, "cannot use window functions in recursive queries");
return;
}
#endif
/* Obtain authorization to do a recursive query */
if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return;
@@ -4074,7 +4067,7 @@ static int flattenSubquery(
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
/*
** A structure to keep track of all of the column values that are fixed to
** A structure to keep track of all of the column values that fixed to
** a known value due to WHERE clause constraints of the form COLUMN=VALUE.
*/
typedef struct WhereConst WhereConst;
@@ -4086,28 +4079,13 @@ struct WhereConst {
};
/*
** Add a new entry to the pConst object. Except, do not add duplicate
** pColumn entires.
** Add a new entry to the pConst object
*/
static void constInsert(
WhereConst *pConst, /* The WhereConst into which we are inserting */
Expr *pColumn, /* The COLUMN part of the constraint */
Expr *pValue /* The VALUE part of the constraint */
WhereConst *pConst,
Expr *pColumn,
Expr *pValue
){
int i;
assert( pColumn->op==TK_COLUMN );
/* 2018-10-25 ticket [cf5ed20f]
** Make sure the same pColumn is not inserted more than once */
for(i=0; i<pConst->nConst; i++){
const Expr *pExpr = pConst->apExpr[i*2];
assert( pExpr->op==TK_COLUMN );
if( pExpr->iTable==pColumn->iTable
&& pExpr->iColumn==pColumn->iColumn
){
return; /* Already present. Return without doing anything. */
}
}
pConst->nConst++;
pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr,
+147 -272
View File
@@ -1059,12 +1059,11 @@ struct ShellState {
/* Allowed values for ShellState.openMode
*/
#define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */
#define SHELL_OPEN_NORMAL 1 /* Normal database file */
#define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */
#define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */
#define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */
#define SHELL_OPEN_DESERIALIZE 5 /* Open using sqlite3_deserialize() */
#define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */
#define SHELL_OPEN_NORMAL 1 /* Normal database file */
#define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */
#define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */
#define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */
/*
** These are the allowed shellFlgs values
@@ -1274,7 +1273,7 @@ static void editFunc(
if( bBin ){
sqlite3_result_blob64(context, p, sz, sqlite3_free);
}else{
sqlite3_int64 i, j;
int i, j;
if( hasCRNL ){
/* If the original contains \r\n then do no conversions back to \n */
j = sz;
@@ -3336,238 +3335,137 @@ static int run_schema_dump_query(
}
/*
** Text of help messages.
**
** The help text for each individual command begins with a line that starts
** with ".". Subsequent lines are supplimental information.
**
** There must be two or more spaces between the end of the command and the
** start of the description of what that command does.
** Text of a help message
*/
static const char *(azHelp[]) = {
static char zHelp[] =
#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
".archive ... Manage SQL archives",
" Each command must have exactly one of the following options:",
" -c, --create Create a new archive",
" -u, --update Update or add files to an existing archive",
" -t, --list List contents of archive",
" -x, --extract Extract files from archive",
" Optional arguments:",
" -v, --verbose Print each filename as it is processed",
" -f FILE, --file FILE Operate on archive FILE (default is current db)",
" -a FILE, --append FILE Operate on FILE opened using the apndvfs VFS",
" -C DIR, --directory DIR Change to directory DIR to read/extract files",
" -n, --dryrun Show the SQL that would have occurred",
" Examples:",
" .ar -cf archive.sar foo bar # Create archive.sar from files foo and bar",
" .ar -tf archive.sar # List members of archive.sar",
" .ar -xvf archive.sar # Verbosely extract files from archive.sar",
" See also:",
" http://sqlite.org/cli.html#sqlar_archive_support",
".archive ... Manage SQL archives: \".archive --help\" for details\n"
#endif
#ifndef SQLITE_OMIT_AUTHORIZATION
".auth ON|OFF Show authorizer callbacks",
".auth ON|OFF Show authorizer callbacks\n"
#endif
".backup ?DB? FILE Backup DB (default \"main\") to FILE",
" --append Use the appendvfs",
".bail on|off Stop after hitting an error. Default OFF",
".binary on|off Turn binary output on or off. Default OFF",
".cd DIRECTORY Change the working directory to DIRECTORY",
".changes on|off Show number of rows changed by SQL",
".check GLOB Fail if output since .testcase does not match",
".clone NEWDB Clone data into NEWDB from the existing database",
".databases List names and files of attached databases",
".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
".dbinfo ?DB? Show status information about the database",
".dump ?TABLE? ... Render all database content as SQL",
" Options:",
" --preserve-rowids Include ROWID values in the output",
" --newlines Allow unescaped newline characters in output",
" TABLE is LIKE pattern for the tables to dump",
".echo on|off Turn command echo on or off",
".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN",
".excel Display the output of next command in a spreadsheet",
".exit ?CODE? Exit this program with return-code CODE",
".expert EXPERIMENTAL. Suggest indexes for specified queries",
".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
" Add \"--append\" to open using appendvfs.\n"
".bail on|off Stop after hitting an error. Default OFF\n"
".binary on|off Turn binary output on or off. Default OFF\n"
".cd DIRECTORY Change the working directory to DIRECTORY\n"
".changes on|off Show number of rows changed by SQL\n"
".check GLOB Fail if output since .testcase does not match\n"
".clone NEWDB Clone data into NEWDB from the existing database\n"
".databases List names and files of attached databases\n"
".dbconfig ?op? ?val? List or change sqlite3_db_config() options\n"
".dbinfo ?DB? Show status information about the database\n"
".dump ?TABLE? ... Dump the database in an SQL text format\n"
" If TABLE specified, only dump tables matching\n"
" LIKE pattern TABLE.\n"
".echo on|off Turn command echo on or off\n"
".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n"
".excel Display the output of next command in a spreadsheet\n"
".exit Exit this program\n"
".expert EXPERIMENTAL. Suggest indexes for specified queries\n"
/* Because explain mode comes on automatically now, the ".explain" mode
** is removed from the help screen. It is still supported for legacy, however */
/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic",*/
".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
".headers on|off Turn display of headers on or off",
".help ?-all? ?PATTERN? Show help text for PATTERN",
".import FILE TABLE Import data from FILE into TABLE",
/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"*/
".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n"
".headers on|off Turn display of headers on or off\n"
".help Show this message\n"
".import FILE TABLE Import data from FILE into TABLE\n"
#ifndef SQLITE_OMIT_TEST_CONTROL
".imposter INDEX TABLE Create imposter table TABLE on index INDEX",
".imposter INDEX TABLE Create imposter table TABLE on index INDEX\n"
#endif
".indexes ?TABLE? Show names of indexes",
" If TABLE is specified, only show indexes for",
" tables matching TABLE using the LIKE operator.",
".indexes ?TABLE? Show names of all indexes\n"
" If TABLE specified, only show indexes for tables\n"
" matching LIKE pattern TABLE.\n"
#ifdef SQLITE_ENABLE_IOTRACE
".iotrace FILE Enable I/O diagnostic logging to FILE",
".iotrace FILE Enable I/O diagnostic logging to FILE\n"
#endif
".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT",
".lint OPTIONS Report potential schema issues.",
" Options:",
" fkey-indexes Find missing foreign key indexes",
".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
".lint OPTIONS Report potential schema issues. Options:\n"
" fkey-indexes Find missing foreign key indexes\n"
#ifndef SQLITE_OMIT_LOAD_EXTENSION
".load FILE ?ENTRY? Load an extension library",
".load FILE ?ENTRY? Load an extension library\n"
#endif
".log FILE|off Turn logging on or off. FILE can be stderr/stdout",
".mode MODE ?TABLE? Set output mode",
" MODE is one of:",
" ascii Columns/rows delimited by 0x1F and 0x1E",
" csv Comma-separated values",
" column Left-aligned columns. (See .width)",
" html HTML <table> code",
" insert SQL insert statements for TABLE",
" line One value per line",
" list Values delimited by \"|\"",
" quote Escape answers as for SQL",
" tabs Tab-separated values",
" tcl TCL list elements",
".nullvalue STRING Use STRING in place of NULL values",
".once (-e|-x|FILE) Output for the next SQL command only to FILE",
" If FILE begins with '|' then open as a pipe",
" Other options:",
" -e Invoke system text editor",
" -x Open in a spreadsheet",
".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
" Options:",
" --append Use appendvfs to append database to the end of FILE",
#ifdef SQLITE_ENABLE_DESERIALIZE
" --deserialize Load into memory useing sqlite3_deserialize()",
#endif
" --new Initialize FILE to an empty database",
" --readonly Open FILE readonly",
" --zip FILE is a ZIP archive",
".output ?FILE? Send output to FILE or stdout if FILE is omitted",
" If FILE begins with '|' then open it as a pipe.",
".print STRING... Print literal STRING",
".prompt MAIN CONTINUE Replace the standard prompts",
".quit Exit this program",
".read FILE Read input from FILE",
".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
".save FILE Write in-memory database into FILE",
".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
".schema ?PATTERN? Show the CREATE statements matching PATTERN",
" Options:",
" --indent Try to pretty-print the schema",
".selftest ?OPTIONS? Run tests defined in the SELFTEST table",
" Options:",
" --init Create a new SELFTEST table",
" -v Verbose output",
".separator COL ?ROW? Change the column and row separators",
".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
" ascii Columns/rows delimited by 0x1F and 0x1E\n"
" csv Comma-separated values\n"
" column Left-aligned columns. (See .width)\n"
" html HTML <table> code\n"
" insert SQL insert statements for TABLE\n"
" line One value per line\n"
" list Values delimited by \"|\"\n"
" quote Escape answers as for SQL\n"
" tabs Tab-separated values\n"
" tcl TCL list elements\n"
".nullvalue STRING Use STRING in place of NULL values\n"
".once (-e|-x|FILE) Output for the next SQL command only to FILE\n"
" or invoke system text editor (-e) or spreadsheet (-x)\n"
" on the output.\n"
".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n"
" The --new option starts with an empty file\n"
" Other options: --readonly --append --zip\n"
".output ?FILE? Send output to FILE or stdout\n"
".print STRING... Print literal STRING\n"
".prompt MAIN CONTINUE Replace the standard prompts\n"
".quit Exit this program\n"
".read FILENAME Execute SQL in FILENAME\n"
".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
".save FILE Write in-memory database into FILE\n"
".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
".schema ?PATTERN? Show the CREATE statements matching PATTERN\n"
" Add --indent for pretty-printing\n"
".selftest ?--init? Run tests defined in the SELFTEST table\n"
".separator COL ?ROW? Change the column separator and optionally the row\n"
" separator for both the output mode and .import\n"
#if defined(SQLITE_ENABLE_SESSION)
".session ?NAME? CMD ... Create or control sessions",
" Subcommands:",
" attach TABLE Attach TABLE",
" changeset FILE Write a changeset into FILE",
" close Close one session",
" enable ?BOOLEAN? Set or query the enable bit",
" filter GLOB... Reject tables matching GLOBs",
" indirect ?BOOLEAN? Mark or query the indirect status",
" isempty Query whether the session is empty",
" list List currently open session names",
" open DB NAME Open a new session on DB",
" patchset FILE Write a patchset into FILE",
" If ?NAME? is omitted, the first defined session is used.",
".session CMD ... Create or control sessions\n"
#endif
".sha3sum ... Compute a SHA3 hash of database content",
" Options:",
" --schema Also hash the sqlite_master table",
" --sha3-224 Use the sha3-224 algorithm",
" --sha3-256 Use the sha3-256 algorithm. This is the default.",
" --sha3-384 Use the sha3-384 algorithm",
" --sha3-512 Use the sha3-512 algorithm",
" Any other argument is a LIKE pattern for tables to hash",
".sha3sum ?OPTIONS...? Compute a SHA3 hash of database content\n"
#ifndef SQLITE_NOHAVE_SYSTEM
".shell CMD ARGS... Run CMD ARGS... in a system shell",
".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
#endif
".show Show the current values for various settings",
".stats ?on|off? Show stats or turn stats on or off",
".show Show the current values for various settings\n"
".stats ?on|off? Show stats or turn stats on or off\n"
#ifndef SQLITE_NOHAVE_SYSTEM
".system CMD ARGS... Run CMD ARGS... in a system shell",
".system CMD ARGS... Run CMD ARGS... in a system shell\n"
#endif
".tables ?TABLE? List names of tables matching LIKE pattern TABLE",
".testcase NAME Begin redirecting output to 'testcase-out.txt'",
".timeout MS Try opening locked tables for MS milliseconds",
".timer on|off Turn SQL timer on or off",
".trace FILE|off Output each SQL statement as it is run",
".vfsinfo ?AUX? Information about the top-level VFS",
".vfslist List all available VFSes",
".vfsname ?AUX? Print the name of the VFS stack",
".width NUM1 NUM2 ... Set column widths for \"column\" mode",
" Negative values right-justify",
};
".tables ?TABLE? List names of tables\n"
" If TABLE specified, only list tables matching\n"
" LIKE pattern TABLE.\n"
".testcase NAME Begin redirecting output to 'testcase-out.txt'\n"
".timeout MS Try opening locked tables for MS milliseconds\n"
".timer on|off Turn SQL timer on or off\n"
".trace FILE|off Output each SQL statement as it is run\n"
".vfsinfo ?AUX? Information about the top-level VFS\n"
".vfslist List all available VFSes\n"
".vfsname ?AUX? Print the name of the VFS stack\n"
".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
" Negative values right-justify\n"
;
#if defined(SQLITE_ENABLE_SESSION)
/*
** Output help text.
**
** zPattern describes the set of commands for which help text is provided.
** If zPattern is NULL, then show all commands, but only give a one-line
** description of each.
**
** Return the number of matches.
** Print help information for the ".sessions" command
*/
static int showHelp(FILE *out, const char *zPattern){
int i = 0;
int j = 0;
int n = 0;
char *zPat;
if( zPattern==0
|| zPattern[0]=='0'
|| strcmp(zPattern,"-a")==0
|| strcmp(zPattern,"-all")==0
){
/* Show all commands, but only one line per command */
if( zPattern==0 ) zPattern = "";
for(i=0; i<ArraySize(azHelp); i++){
if( azHelp[i][0]=='.' || zPattern[0] ){
utf8_printf(out, "%s\n", azHelp[i]);
n++;
}
}
}else{
/* Look for commands that for which zPattern is an exact prefix */
zPat = sqlite3_mprintf(".%s*", zPattern);
for(i=0; i<ArraySize(azHelp); i++){
if( sqlite3_strglob(zPat, azHelp[i])==0 ){
utf8_printf(out, "%s\n", azHelp[i]);
j = i+1;
n++;
}
}
sqlite3_free(zPat);
if( n ){
if( n==1 ){
/* when zPattern is a prefix of exactly one command, then include the
** details of that command, which should begin at offset j */
while( j<ArraySize(azHelp)-1 && azHelp[j][0]!='.' ){
utf8_printf(out, "%s\n", azHelp[j]);
j++;
}
}
return n;
}
/* Look for commands that contain zPattern anywhere. Show the complete
** text of all commands that match. */
zPat = sqlite3_mprintf("%%%s%%", zPattern);
for(i=0; i<ArraySize(azHelp); i++){
if( azHelp[i][0]=='.' ) j = i;
if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
utf8_printf(out, "%s\n", azHelp[j]);
while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]!='.' ){
j++;
utf8_printf(out, "%s\n", azHelp[j]);
}
i = j;
n++;
}
}
sqlite3_free(zPat);
}
return n;
void session_help(ShellState *p){
raw_printf(p->out,
".session ?NAME? SUBCOMMAND ?ARGS...?\n"
"If ?NAME? is omitted, the first defined session is used.\n"
"Subcommands:\n"
" attach TABLE Attach TABLE\n"
" changeset FILE Write a changeset into FILE\n"
" close Close one session\n"
" enable ?BOOLEAN? Set or query the enable bit\n"
" filter GLOB... Reject tables matching GLOBs\n"
" indirect ?BOOLEAN? Mark or query the indirect status\n"
" isempty Query whether the session is empty\n"
" list List currently open session names\n"
" open DB NAME Open a new session on DB\n"
" patchset FILE Write a patchset into FILE\n"
);
}
#endif
/* Forward reference */
static int process_input(ShellState *p, FILE *in);
@@ -3597,7 +3495,7 @@ static char *readFile(const char *zName, int *pnByte){
nIn = ftell(in);
rewind(in);
pBuf = sqlite3_malloc64( nIn+1 );
if( pBuf==0 ){ fclose(in); return 0; }
if( pBuf==0 ) return 0;
nRead = fread(pBuf, nIn, 1, in);
fclose(in);
if( nRead!=1 ){
@@ -3677,11 +3575,6 @@ int deduceDatabaseType(const char *zName, int dfltZip){
return SHELL_OPEN_NORMAL;
}
}
n = fread(zBuf, 16, 1, f);
if( n==1 && memcmp(zBuf, "SQLite format 3", 16)==0 ){
fclose(f);
return SHELL_OPEN_NORMAL;
}
fseek(f, -25, SEEK_END);
n = fread(zBuf, 25, 1, f);
if( n==1 && memcmp(zBuf, "Start-Of-SQLite3-", 17)==0 ){
@@ -3733,10 +3626,6 @@ static void open_db(ShellState *p, int openFlags){
SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs");
break;
}
case SHELL_OPEN_DESERIALIZE: {
sqlite3_open(0, &p->db);
break;
}
case SHELL_OPEN_ZIPFILE: {
sqlite3_open(":memory:", &p->db);
break;
@@ -3786,18 +3675,6 @@ static void open_db(ShellState *p, int openFlags){
sqlite3_exec(p->db, zSql, 0, 0, 0);
sqlite3_free(zSql);
}
#ifdef SQLITE_ENABLE_DESERIALIZE
else if( p->openMode==SHELL_OPEN_DESERIALIZE ){
int nData = 0;
unsigned char *aData = (unsigned char*)readFile(p->zDbFilename, &nData);
int rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
SQLITE_DESERIALIZE_RESIZEABLE |
SQLITE_DESERIALIZE_FREEONCLOSE);
if( rc ){
utf8_printf(stderr, "Error: sqlite3_deserialize() returns %d\n", rc);
}
}
#endif
}
}
@@ -5002,7 +4879,6 @@ static void shellPreparePrintf(
char *z;
va_start(ap, zFmt);
z = sqlite3_vmprintf(zFmt, ap);
va_end(ap);
if( z==0 ){
*pRc = SQLITE_NOMEM;
}else{
@@ -5065,7 +4941,32 @@ struct ArCommand {
** Print a usage message for the .ar command to stderr and return SQLITE_ERROR.
*/
static int arUsage(FILE *f){
showHelp(f,"archive");
raw_printf(f,
"\n"
"Usage: .ar [OPTION...] [FILE...]\n"
"The .ar command manages sqlar archives.\n"
"\n"
"Examples:\n"
" .ar -cf archive.sar foo bar # Create archive.sar from files foo and bar\n"
" .ar -tf archive.sar # List members of archive.sar\n"
" .ar -xvf archive.sar # Verbosely extract files from archive.sar\n"
"\n"
"Each command line must feature exactly one command option:\n"
" -c, --create Create a new archive\n"
" -u, --update Update or add files to an existing archive\n"
" -t, --list List contents of archive\n"
" -x, --extract Extract files from archive\n"
"\n"
"And zero or more optional options:\n"
" -v, --verbose Print each filename as it is processed\n"
" -f FILE, --file FILE Operate on archive FILE (default is current db)\n"
" -a FILE, --append FILE Operate on FILE opened using the apndvfs VFS\n"
" -C DIR, --directory DIR Change to directory DIR to read/extract files\n"
" -n, --dryrun Show the SQL that would have occurred\n"
"\n"
"See also: http://sqlite.org/cli.html#sqlar_archive_support\n"
"\n"
);
return SQLITE_ERROR;
}
@@ -5172,7 +5073,6 @@ static int arParseCommand(
struct ArSwitch *pEnd = &aSwitch[nSwitch];
if( nArg<=1 ){
utf8_printf(stderr, "Wrong number of arguments. Usage:\n");
return arUsage(stderr);
}else{
char *z = azArg[1];
@@ -5944,10 +5844,7 @@ static int do_meta_command(char *zLine, ShellState *p){
}else
if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){
static const struct DbConfigChoices {
const char *zName;
int op;
} aDbConfig[] = {
static const struct DbConfigChoices {const char *zName; int op;} aDbConfig[] = {
{ "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
{ "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
{ "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
@@ -5956,7 +5853,6 @@ static int do_meta_command(char *zLine, ShellState *p){
{ "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG },
{ "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP },
{ "reset_database", SQLITE_DBCONFIG_RESET_DATABASE },
{ "defensive", SQLITE_DBCONFIG_DEFENSIVE },
};
int ii, v;
open_db(p, 0);
@@ -6195,14 +6091,7 @@ static int do_meta_command(char *zLine, ShellState *p){
}else
if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
if( nArg>=2 ){
n = showHelp(p->out, azArg[1]);
if( n==0 ){
utf8_printf(p->out, "Nothing matches '%s'\n", azArg[1]);
}
}else{
showHelp(p->out, 0);
}
utf8_printf(p->out, "%s", zHelp);
}else
if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
@@ -6679,10 +6568,6 @@ static int do_meta_command(char *zLine, ShellState *p){
p->openMode = SHELL_OPEN_APPENDVFS;
}else if( optionMatch(z, "readonly") ){
p->openMode = SHELL_OPEN_READONLY;
#ifdef SQLITE_ENABLE_DESERIALIZE
}else if( optionMatch(z, "deserialize") ){
p->openMode = SHELL_OPEN_DESERIALIZE;
#endif
}else if( z[0]=='-' ){
utf8_printf(stderr, "unknown option: %s\n", z);
rc = 1;
@@ -7210,7 +7095,7 @@ static int do_meta_command(char *zLine, ShellState *p){
}else
/* If no command name matches, show a syntax error */
session_syntax_error:
showHelp(p->out, "session");
session_help(p);
}else
#endif
@@ -8651,10 +8536,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
#endif
}else if( strcmp(z,"-append")==0 ){
data.openMode = SHELL_OPEN_APPENDVFS;
#ifdef SQLITE_ENABLE_DESERIALIZE
}else if( strcmp(z,"-deserialize")==0 ){
data.openMode = SHELL_OPEN_DESERIALIZE;
#endif
}else if( strcmp(z,"-readonly")==0 ){
data.openMode = SHELL_OPEN_READONLY;
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
@@ -8750,10 +8631,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
#endif
}else if( strcmp(z,"-append")==0 ){
data.openMode = SHELL_OPEN_APPENDVFS;
#ifdef SQLITE_ENABLE_DESERIALIZE
}else if( strcmp(z,"-deserialize")==0 ){
data.openMode = SHELL_OPEN_DESERIALIZE;
#endif
}else if( strcmp(z,"-readonly")==0 ){
data.openMode = SHELL_OPEN_READONLY;
}else if( strcmp(z,"-ascii")==0 ){
@@ -8898,7 +8775,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
*/
if( stdin_is_interactive ){
char *zHome;
char *zHistory;
char *zHistory = 0;
int nHistory;
printf(
"SQLite version %s %.19s\n" /*extra-version-info*/
@@ -8911,10 +8788,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
printf(".\nUse \".open FILENAME\" to reopen on a "
"persistent database.\n");
}
zHistory = getenv("SQLITE_HISTORY");
if( zHistory ){
zHistory = strdup(zHistory);
}else if( (zHome = find_home_dir(0))!=0 ){
zHome = find_home_dir(0);
if( zHome ){
nHistory = strlen30(zHome) + 20;
if( (zHistory = malloc(nHistory))!=0 ){
sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
+3 -44
View File
@@ -2158,29 +2158,6 @@ struct sqlite3_mem_methods {
** Because resetting a database is destructive and irreversible, the
** process requires the use of this obscure API and multiple steps to help
** ensure that it does not happen by accident.
**
** <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
** <dd>The SQLITE_DBCONFIG_DEFENSIVE option actives or deactivates the
** "defensive" flag for a database connection. When the defensive
** flag is enabled, some obscure features of SQLite are disabled in order
** to reduce the attack surface. Applications that run untrusted SQL
** can activate this flag to reduce the risk of zero-day exploits.
** <p>
** Features disabled by the defensive flag include:
** <ul>
** <li>The [PRAGMA writable_schema=ON] statement.
** <li>Writes to the [sqlite_dbpage] virtual table.
** </ul>
** New restrictions may be added in future releases.
** <p>
** To be clear: It should never be possible for hostile SQL to cause
** arbitrary memory reads, memory leaks, buffer overflows, assertion
** faults, arbitrary code execution, crashes, or other mischief, regardless
** of the value of the defensive flag. Any occurrance of these problems
** is considered a serious bug and will be fixed promptly. It is not
** necessary to enable the defensive flag in order to make SQLite secure
** against attack. The defensive flag merely provides an additional layer
** of defense against unknown vulnerabilities.
** </dd>
** </dl>
*/
@@ -2194,8 +2171,7 @@ struct sqlite3_mem_methods {
#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */
#define SQLITE_DBCONFIG_MAX 1010 /* Largest DBCONFIG */
#define SQLITE_DBCONFIG_MAX 1009 /* Largest DBCONFIG */
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
@@ -3633,19 +3609,9 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
** on this hint by avoiding the use of [lookaside memory] so as not to
** deplete the limited store of lookaside memory. Future versions of
** SQLite may act on this hint differently.
**
** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt>
** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
** representation of the SQL statement should be calculated and then
** associated with the prepared statement, which can be obtained via
** the [sqlite3_normalized_sql()] interface. The semantics used to
** normalize a SQL statement are unspecified and subject to change.
** At a minimum, literal values will be replaced with suitable
** placeholders.
** </dl>
*/
#define SQLITE_PREPARE_PERSISTENT 0x01
#define SQLITE_PREPARE_NORMALIZE 0x02
/*
** CAPI3REF: Compiling An SQL Statement
@@ -3803,11 +3769,6 @@ int sqlite3_prepare16_v3(
** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
** string containing the SQL text of prepared statement P with
** [bound parameters] expanded.
** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8
** string containing the normalized SQL text of prepared statement P. The
** semantics used to normalize a SQL statement are unspecified and subject
** to change. At a minimum, literal values will be replaced with suitable
** placeholders.
**
** ^(For example, if a prepared statement is created using the SQL
** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
@@ -3823,16 +3784,14 @@ int sqlite3_prepare16_v3(
** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time
** option causes sqlite3_expanded_sql() to always return NULL.
**
** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P)
** are managed by SQLite and are automatically freed when the prepared
** statement is finalized.
** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
** automatically freed when the prepared statement is finalized.
** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
** is obtained from [sqlite3_malloc()] and must be free by the application
** by passing it to [sqlite3_free()].
*/
const char *sqlite3_sql(sqlite3_stmt *pStmt);
char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Determine If An SQL Statement Writes The Database
-5
View File
@@ -310,15 +310,12 @@ struct sqlite3_api_routines {
int (*str_errcode)(sqlite3_str*);
int (*str_length)(sqlite3_str*);
char *(*str_value)(sqlite3_str*);
/* Version 3.25.0 and later */
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
void (*xValue)(sqlite3_context*),
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
void(*xDestroy)(void*));
/* Version 3.26.0 and later */
const char *(*normalized_sql)(sqlite3_stmt*);
};
/*
@@ -606,8 +603,6 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_str_value sqlite3_api->str_value
/* Version 3.25.0 and later */
#define sqlite3_create_window_function sqlite3_api->create_window_function
/* Version 3.26.0 and later */
#define sqlite3_normalized_sql sqlite3_api->normalized_sql
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+12 -44
View File
@@ -1305,14 +1305,12 @@ struct LookasideSlot {
** functions use a regular table table from hash.h.)
**
** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
** Collisions are on the FuncDef.u.pHash chain. Use the SQLITE_FUNC_HASH()
** macro to compute a hash on the function name.
** Collisions are on the FuncDef.u.pHash chain.
*/
#define SQLITE_FUNC_HASH_SZ 23
struct FuncDefHash {
FuncDef *a[SQLITE_FUNC_HASH_SZ]; /* Hash table for functions */
};
#define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ)
#ifdef SQLITE_USER_AUTHENTICATION
/*
@@ -1373,7 +1371,7 @@ struct sqlite3 {
Db *aDb; /* All backends */
int nDb; /* Number of backends currently in use */
u32 mDbFlags; /* flags recording internal state */
u64 flags; /* flags settable by pragmas. See below */
u32 flags; /* flags settable by pragmas. See below */
i64 lastRowid; /* ROWID of most recent insert (see above) */
i64 szMmap; /* Default mmap_size setting */
u32 nSchemaLock; /* Do not reset the schema when non-zero */
@@ -1539,17 +1537,14 @@ struct sqlite3 {
#define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */
#define SQLITE_ResetDatabase 0x02000000 /* Reset the database */
#define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */
#define SQLITE_NoSchemaError 0x08000000 /* Do not report schema parse errors*/
#define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */
/* Flags used only if debugging */
#define HI(X) ((u64)(X)<<32)
#ifdef SQLITE_DEBUG
#define SQLITE_SqlTrace HI(0x0001) /* Debug print SQL as it executes */
#define SQLITE_VdbeListing HI(0x0002) /* Debug listings of VDBE progs */
#define SQLITE_VdbeTrace HI(0x0004) /* True to trace VDBE execution */
#define SQLITE_VdbeAddopTrace HI(0x0008) /* Trace sqlite3VdbeAddOp() calls */
#define SQLITE_VdbeEQP HI(0x0010) /* Debug EXPLAIN QUERY PLAN */
#define SQLITE_SqlTrace 0x08000000 /* Debug print SQL as it executes */
#define SQLITE_VdbeListing 0x10000000 /* Debug listings of VDBE programs */
#define SQLITE_VdbeTrace 0x20000000 /* True to trace VDBE execution */
#define SQLITE_VdbeAddopTrace 0x40000000 /* Trace sqlite3VdbeAddOp() calls */
#define SQLITE_VdbeEQP 0x80000000 /* Debug EXPLAIN QUERY PLAN */
#endif
/*
@@ -1948,9 +1943,6 @@ struct VTable {
struct Table {
char *zName; /* Name of the table or view */
Column *aCol; /* Information about each column */
#ifdef SQLITE_ENABLE_NORMALIZE
Hash *pColHash; /* All columns indexed by name */
#endif
Index *pIndex; /* List of SQL indexes on this table. */
Select *pSelect; /* NULL for tables. Points to definition if a view. */
FKey *pFKey; /* Linked list of all foreign keys in this table */
@@ -2287,12 +2279,6 @@ struct IndexSample {
tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */
};
/*
** Possible values to use within the flags argument to sqlite3GetToken().
*/
#define SQLITE_TOKEN_QUOTED 0x1 /* Token is a quoted identifier. */
#define SQLITE_TOKEN_KEYWORD 0x2 /* Token is a keyword. */
/*
** Each token coming out of the lexer is an instance of
** this structure. Tokens are also used as part of an expression.
@@ -2474,11 +2460,11 @@ struct Expr {
** TK_COLUMN: the value of p5 for OP_Column
** TK_AGG_FUNCTION: nesting depth */
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
union {
Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
** for a column of an index on an expression */
Window *pWin; /* TK_FUNCTION: Window definition for the func */
} y;
Table *pTab; /* Table for TK_COLUMN expressions. Can be NULL
** for a column of an index on an expression */
#ifndef SQLITE_OMIT_WINDOWFUNC
Window *pWin; /* Window definition for window functions */
#endif
};
/*
@@ -2508,7 +2494,6 @@ struct Expr {
#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
#define EP_Alias 0x400000 /* Is an alias for a result set column */
#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
/*
** The EP_Propagate mask is a set of properties that automatically propagate
@@ -3194,7 +3179,6 @@ struct AuthContext {
*/
#define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */
/* Also used in P2 (not P5) of OP_Delete */
#define OPFLAG_NOCHNG 0x01 /* OP_VColumn nochange for UPDATE */
#define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */
#define OPFLAG_LASTROWID 0x20 /* Set to update db->lastRowid */
#define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
@@ -3666,7 +3650,6 @@ int sqlite3IsIdChar(u8);
*/
int sqlite3StrICmp(const char*,const char*);
int sqlite3Strlen30(const char*);
#define sqlite3Strlen30NN(C) (strlen(C)&0x3fffffff)
char *sqlite3ColumnType(Column*,char*);
#define sqlite3StrNICmp sqlite3_strnicmp
@@ -3783,7 +3766,6 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*);
void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
void sqlite3TreeViewSrcList(TreeView*, const SrcList*);
void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
void sqlite3TreeViewWith(TreeView*, const With*, u8);
#ifndef SQLITE_OMIT_WINDOWFUNC
@@ -4016,15 +3998,11 @@ int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3ExprCanBeNull(const Expr*);
int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
int sqlite3IsRowid(const char*);
#ifdef SQLITE_ENABLE_NORMALIZE
int sqlite3IsRowidN(const char*, int);
#endif
void sqlite3GenerateRowDelete(
Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
void sqlite3ResolvePartIdxLabel(Parse*,int);
int sqlite3ExprReferencesUpdatedColumn(Expr*,int*,int);
void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
u8,u8,int,int*,int*,Upsert*);
#ifdef SQLITE_ENABLE_NULL_TRIM
@@ -4045,9 +4023,6 @@ ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
IdList *sqlite3IdListDup(sqlite3*,IdList*);
Select *sqlite3SelectDup(sqlite3*,Select*,int);
#ifdef SQLITE_ENABLE_NORMALIZE
FuncDef *sqlite3FunctionSearchN(int,const char*,int);
#endif
void sqlite3InsertBuiltinFuncs(FuncDef*,int);
FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
void sqlite3RegisterBuiltinFunctions(void);
@@ -4205,7 +4180,6 @@ Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
Expr *sqlite3ExprSkipCollate(Expr*);
int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3WritableSchema(sqlite3*);
int sqlite3CheckObjectName(Parse *, const char *);
void sqlite3VdbeSetChanges(sqlite3 *, int);
int sqlite3AddInt64(i64*,i64);
@@ -4252,9 +4226,6 @@ void sqlite3AlterFunctions(void);
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
#ifdef SQLITE_ENABLE_NORMALIZE
int sqlite3GetTokenNormalized(const unsigned char *, int *, int *);
#endif
void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*, int);
int sqlite3CodeSubselect(Parse*, Expr *, int, int);
@@ -4412,9 +4383,6 @@ sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
void sqlite3ParserReset(Parse*);
#ifdef SQLITE_ENABLE_NORMALIZE
void sqlite3Normalize(Vdbe*, const char*, int, u8);
#endif
int sqlite3Reprepare(Vdbe*);
void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
+1 -102
View File
@@ -4218,7 +4218,6 @@ static int SQLITE_TCLAPI test_prepare_v2(
char *zCopy = 0; /* malloc() copy of zSql */
int bytes;
const char *zTail = 0;
const char **pzTail;
sqlite3_stmt *pStmt = 0;
char zBuf[50];
int rc;
@@ -4243,8 +4242,7 @@ static int SQLITE_TCLAPI test_prepare_v2(
zCopy = malloc(n);
memcpy(zCopy, zSql, n);
}
pzTail = objc>=5 ? &zTail : 0;
rc = sqlite3_prepare_v2(db, zCopy, bytes, &pStmt, pzTail);
rc = sqlite3_prepare_v2(db, zCopy, bytes, &pStmt, objc>=5 ? &zTail : 0);
free(zCopy);
zTail = &zSql[(zTail - zCopy)];
@@ -4271,79 +4269,6 @@ static int SQLITE_TCLAPI test_prepare_v2(
return TCL_OK;
}
/*
** Usage: sqlite3_prepare_v3 DB sql bytes flags ?tailvar?
**
** Compile up to <bytes> bytes of the supplied SQL string <sql> using
** database handle <DB> and flags <flags>. The parameter <tailval> is
** the name of a global variable that is set to the unused portion of
** <sql> (if any). A STMT handle is returned.
*/
static int SQLITE_TCLAPI test_prepare_v3(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3 *db;
const char *zSql;
char *zCopy = 0; /* malloc() copy of zSql */
int bytes, flags;
const char *zTail = 0;
const char **pzTail;
sqlite3_stmt *pStmt = 0;
char zBuf[50];
int rc;
if( objc!=6 && objc!=5 ){
Tcl_AppendResult(interp, "wrong # args: should be \"",
Tcl_GetString(objv[0]), " DB sql bytes flags tailvar", 0);
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
zSql = Tcl_GetString(objv[2]);
if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
if( Tcl_GetIntFromObj(interp, objv[4], &flags) ) return TCL_ERROR;
/* Instead of using zSql directly, make a copy into a buffer obtained
** directly from malloc(). The idea is to make it easier for valgrind
** to spot buffer overreads. */
if( bytes>=0 ){
zCopy = malloc(bytes);
memcpy(zCopy, zSql, bytes);
}else{
int n = (int)strlen(zSql) + 1;
zCopy = malloc(n);
memcpy(zCopy, zSql, n);
}
pzTail = objc>=6 ? &zTail : 0;
rc = sqlite3_prepare_v3(db, zCopy, bytes, (unsigned int)flags,&pStmt,pzTail);
free(zCopy);
zTail = &zSql[(zTail - zCopy)];
assert(rc==SQLITE_OK || pStmt==0);
Tcl_ResetResult(interp);
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
if( rc==SQLITE_OK && zTail && objc>=6 ){
if( bytes>=0 ){
bytes = bytes - (int)(zTail-zSql);
}
Tcl_ObjSetVar2(interp, objv[5], 0, Tcl_NewStringObj(zTail, bytes), 0);
}
if( rc!=SQLITE_OK ){
assert( pStmt==0 );
sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc);
Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
return TCL_ERROR;
}
if( pStmt ){
if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
Tcl_AppendResult(interp, zBuf, 0);
}
return TCL_OK;
}
/*
** Usage: sqlite3_prepare_tkt3134 DB
**
@@ -4751,25 +4676,6 @@ static int SQLITE_TCLAPI test_ex_sql(
sqlite3_free(z);
return TCL_OK;
}
#ifdef SQLITE_ENABLE_NORMALIZE
static int SQLITE_TCLAPI test_norm_sql(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3_stmt *pStmt;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "STMT");
return TCL_ERROR;
}
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
Tcl_SetResult(interp, (char *)sqlite3_normalized_sql(pStmt), TCL_VOLATILE);
return TCL_OK;
}
#endif /* SQLITE_ENABLE_NORMALIZE */
/*
** Usage: sqlite3_column_count STMT
@@ -7132,7 +7038,6 @@ static int SQLITE_TCLAPI tclLoadStaticExtensionCmd(
extern int sqlite3_closure_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_csv_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_eval_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_explain_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_fileio_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_fuzzer_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_ieee_init(sqlite3*,char**,const sqlite3_api_routines*);
@@ -7157,7 +7062,6 @@ static int SQLITE_TCLAPI tclLoadStaticExtensionCmd(
{ "closure", sqlite3_closure_init },
{ "csv", sqlite3_csv_init },
{ "eval", sqlite3_eval_init },
{ "explain", sqlite3_explain_init },
{ "fileio", sqlite3_fileio_init },
{ "fuzzer", sqlite3_fuzzer_init },
{ "ieee754", sqlite3_ieee_init },
@@ -7556,7 +7460,6 @@ static int SQLITE_TCLAPI test_sqlite3_db_config(
{ "QPSG", SQLITE_DBCONFIG_ENABLE_QPSG },
{ "TRIGGER_EQP", SQLITE_DBCONFIG_TRIGGER_EQP },
{ "RESET_DB", SQLITE_DBCONFIG_RESET_DATABASE },
{ "DEFENSIVE", SQLITE_DBCONFIG_DEFENSIVE },
};
int i;
int v;
@@ -7741,7 +7644,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_prepare", test_prepare ,0 },
{ "sqlite3_prepare16", test_prepare16 ,0 },
{ "sqlite3_prepare_v2", test_prepare_v2 ,0 },
{ "sqlite3_prepare_v3", test_prepare_v3 ,0 },
{ "sqlite3_prepare_tkt3134", test_prepare_tkt3134, 0},
{ "sqlite3_prepare16_v2", test_prepare16_v2 ,0 },
{ "sqlite3_finalize", test_finalize ,0 },
@@ -7753,9 +7655,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_step", test_step ,0 },
{ "sqlite3_sql", test_sql ,0 },
{ "sqlite3_expanded_sql", test_ex_sql ,0 },
#ifdef SQLITE_ENABLE_NORMALIZE
{ "sqlite3_normalized_sql", test_norm_sql ,0 },
#endif
{ "sqlite3_next_stmt", test_next_stmt ,0 },
{ "sqlite3_stmt_readonly", test_stmt_readonly ,0 },
{ "sqlite3_stmt_busy", test_stmt_busy ,0 },
+1 -7
View File
@@ -124,7 +124,7 @@ static void set_options(Tcl_Interp *interp){
STRINGVALUE(SQLITE_MAX_WORKER_THREADS), TCL_GLOBAL_ONLY
);
#ifdef SQLITE_MEMDEBUG
#if 1 /* def SQLITE_MEMDEBUG */
Tcl_SetVar2(interp, "sqlite_options", "memdebug", "1", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "memdebug", "0", TCL_GLOBAL_ONLY);
@@ -762,12 +762,6 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
Tcl_SetVar2(interp, "sqlite_options", "uri_00_error", "0", TCL_GLOBAL_ONLY);
#endif
#if defined(SQLITE_ENABLE_NORMALIZE)
Tcl_SetVar2(interp, "sqlite_options", "normalize", "1", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "normalize", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_OMIT_WINDOWFUNC
Tcl_SetVar2(interp, "sqlite_options", "windowfunc", "0", TCL_GLOBAL_ONLY);
#else
+1 -4
View File
@@ -13,10 +13,6 @@
** This file implements a read-only VIRTUAL TABLE that contains the
** content of a C-language array of integer values. See the corresponding
** header file for full details.
**
** This virtual table is used for internal testing of SQLite only. It is
** not recommended for use in production. For a similar virtual table that
** is production-ready, see the "carray" virtual table over in ext/misc.
*/
#include "test_intarray.h"
#include <string.h>
@@ -319,6 +315,7 @@ static int SQLITE_TCLAPI test_intarray_create(
rc = sqlite3_intarray_create(db, zName, &pArray);
#endif
if( rc!=SQLITE_OK ){
assert( pArray==0 );
Tcl_AppendResult(interp, sqlite3ErrName(rc), (char*)0);
return TCL_ERROR;
}
+1 -8
View File
@@ -13,10 +13,6 @@
** This is the C-language interface definition for the "intarray" or
** integer array virtual table for SQLite.
**
** This virtual table is used for internal testing of SQLite only. It is
** not recommended for use in production. For a similar virtual table that
** is production-ready, see the "carray" virtual table over in ext/misc.
**
** The intarray virtual table is designed to facilitate using an
** array of integers as the right-hand side of an IN operator. So
** instead of doing a prepared statement like this:
@@ -76,10 +72,7 @@
** virtual table is dropped. Since the virtual tables are created in the
** TEMP database, they are automatically dropped when the database connection
** closes so the application does not normally need to take any special
** action to free the intarray objects. Because of the way virtual tables
** work and the (somewhat goofy) way that the intarray virtual table is
** implemented, it is not allowed to invoke sqlite3_intarray_create(D,N,P)
** more than once with the same D and N values.
** action to free the intarray objects.
*/
#include "sqlite3.h"
#ifndef SQLITE_INTARRAY_H
-1
View File
@@ -560,7 +560,6 @@ static int fsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
** File control method. For custom operations on an fs-file.
*/
static int fsFileControl(sqlite3_file *pFile, int op, void *pArg){
if( op==SQLITE_FCNTL_PRAGMA ) return SQLITE_NOTFOUND;
return SQLITE_OK;
}
-67
View File
@@ -545,73 +545,6 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
return i;
}
#ifdef SQLITE_ENABLE_NORMALIZE
/*
** Return the length (in bytes) of the token that begins at z[0].
** Store the token type in *tokenType before returning. If flags has
** SQLITE_TOKEN_NORMALIZE flag enabled, use the identifier token type
** for keywords. Add SQLITE_TOKEN_QUOTED to flags if the token was
** actually a quoted identifier. Add SQLITE_TOKEN_KEYWORD to flags
** if the token was recognized as a keyword; this is useful when the
** SQLITE_TOKEN_NORMALIZE flag is used, because it enables the caller
** to differentiate between a keyword being treated as an identifier
** (for normalization purposes) and an actual identifier.
*/
int sqlite3GetTokenNormalized(
const unsigned char *z,
int *tokenType,
int *flags
){
int n;
unsigned char iClass = aiClass[*z];
if( iClass==CC_KYWD ){
int i;
for(i=1; aiClass[z[i]]<=CC_KYWD; i++){}
if( IdChar(z[i]) ){
/* This token started out using characters that can appear in keywords,
** but z[i] is a character not allowed within keywords, so this must
** be an identifier instead */
i++;
while( IdChar(z[i]) ){ i++; }
*tokenType = TK_ID;
return i;
}
*tokenType = TK_ID;
n = keywordCode((char*)z, i, tokenType);
/* If the token is no longer considered to be an identifier, then it is a
** keyword of some kind. Make the token back into an identifier and then
** set the SQLITE_TOKEN_KEYWORD flag. Several non-identifier tokens are
** used verbatim, including IN, IS, NOT, and NULL. */
switch( *tokenType ){
case TK_ID: {
/* do nothing, handled by caller */
break;
}
case TK_IN:
case TK_IS:
case TK_NOT:
case TK_NULL: {
*flags |= SQLITE_TOKEN_KEYWORD;
break;
}
default: {
*tokenType = TK_ID;
*flags |= SQLITE_TOKEN_KEYWORD;
break;
}
}
}else{
n = sqlite3GetToken(z, tokenType);
/* If the token is considered to be an identifier and the character class
** of the first character is a quote, set the SQLITE_TOKEN_QUOTED flag. */
if( *tokenType==TK_ID && (iClass==CC_QUOTE || iClass==CC_QUOTE2) ){
*flags |= SQLITE_TOKEN_QUOTED;
}
}
return n;
}
#endif /* SQLITE_ENABLE_NORMALIZE */
/*
** Run the parser on the given SQL string. The parser structure is
** passed in. An SQLITE_ status code is returned. If an error occurs
+32 -38
View File
@@ -121,42 +121,6 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){
}
}
/*
** Generate a human-readable description of a SrcList object.
*/
void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
int i;
for(i=0; i<pSrc->nSrc; i++){
const struct SrcList_item *pItem = &pSrc->a[i];
StrAccum x;
char zLine[100];
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
if( pItem->zDatabase ){
sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
}else if( pItem->zName ){
sqlite3_str_appendf(&x, " %s", pItem->zName);
}
if( pItem->pTab ){
sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
}
if( pItem->zAlias ){
sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
}
if( pItem->fg.jointype & JT_LEFT ){
sqlite3_str_appendf(&x, " LEFT-JOIN");
}
sqlite3StrAccumFinish(&x);
sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
if( pItem->pSelect ){
sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
}
if( pItem->fg.isTabFunc ){
sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
}
sqlite3TreeViewPop(pView);
}
}
/*
** Generate a human-readable description of a Select object.
@@ -211,9 +175,39 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
}
#endif
if( p->pSrc && p->pSrc->nSrc ){
int i;
pView = sqlite3TreeViewPush(pView, (n--)>0);
sqlite3TreeViewLine(pView, "FROM");
sqlite3TreeViewSrcList(pView, p->pSrc);
for(i=0; i<p->pSrc->nSrc; i++){
struct SrcList_item *pItem = &p->pSrc->a[i];
StrAccum x;
char zLine[100];
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
if( pItem->zDatabase ){
sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
}else if( pItem->zName ){
sqlite3_str_appendf(&x, " %s", pItem->zName);
}
if( pItem->pTab ){
sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
}
if( pItem->zAlias ){
sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
}
if( pItem->fg.jointype & JT_LEFT ){
sqlite3_str_appendf(&x, " LEFT-JOIN");
}
sqlite3StrAccumFinish(&x);
sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1);
if( pItem->pSelect ){
sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
}
if( pItem->fg.isTabFunc ){
sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
}
sqlite3TreeViewPop(pView);
}
sqlite3TreeViewPop(pView);
}
if( p->pWhere ){
@@ -503,7 +497,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
}else{
pFarg = pExpr->x.pList;
#ifndef SQLITE_OMIT_WINDOWFUNC
pWin = pExpr->y.pWin;
pWin = pExpr->pWin;
#else
pWin = 0;
#endif
+6 -56
View File
@@ -79,57 +79,6 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
#endif
}
/*
** Check to see if column iCol of index pIdx references any of the
** columns defined by aXRef and chngRowid. Return true if it does
** and false if not. This is an optimization. False-positives are a
** performance degradation, but false-negatives can result in a corrupt
** index and incorrect answers.
**
** aXRef[j] will be non-negative if column j of the original table is
** being updated. chngRowid will be true if the rowid of the table is
** being updated.
*/
static int indexColumnIsBeingUpdated(
Index *pIdx, /* The index to check */
int iCol, /* Which column of the index to check */
int *aXRef, /* aXRef[j]>=0 if column j is being updated */
int chngRowid /* true if the rowid is being updated */
){
i16 iIdxCol = pIdx->aiColumn[iCol];
assert( iIdxCol!=XN_ROWID ); /* Cannot index rowid */
if( iIdxCol>=0 ){
return aXRef[iIdxCol]>=0;
}
assert( iIdxCol==XN_EXPR );
assert( pIdx->aColExpr!=0 );
assert( pIdx->aColExpr->a[iCol].pExpr!=0 );
return sqlite3ExprReferencesUpdatedColumn(pIdx->aColExpr->a[iCol].pExpr,
aXRef,chngRowid);
}
/*
** Check to see if index pIdx is a partial index whose conditional
** expression might change values due to an UPDATE. Return true if
** the index is subject to change and false if the index is guaranteed
** to be unchanged. This is an optimization. False-positives are a
** performance degradation, but false-negatives can result in a corrupt
** index and incorrect answers.
**
** aXRef[j] will be non-negative if column j of the original table is
** being updated. chngRowid will be true if the rowid of the table is
** being updated.
*/
static int indexWhereClauseMightChange(
Index *pIdx, /* The index to check */
int *aXRef, /* aXRef[j]>=0 if column j is being updated */
int chngRowid /* true if the rowid is being updated */
){
if( pIdx->pPartIdxWhere==0 ) return 0;
return sqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere,
aXRef, chngRowid);
}
/*
** Process an UPDATE statement.
**
@@ -353,18 +302,19 @@ void sqlite3Update(
/* There is one entry in the aRegIdx[] array for each index on the table
** being updated. Fill in aRegIdx[] with a register number that will hold
** the key for accessing each index.
**
** FIXME: Be smarter about omitting indexes that use expressions.
*/
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int reg;
if( chngKey || hasFK>1 || pIdx==pPk
|| indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
){
if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){
reg = ++pParse->nMem;
pParse->nMem += pIdx->nColumn;
}else{
reg = 0;
for(i=0; i<pIdx->nKeyCol; i++){
if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){
i16 iIdxCol = pIdx->aiColumn[i];
if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){
reg = ++pParse->nMem;
pParse->nMem += pIdx->nColumn;
if( (onError==OE_Replace)
@@ -913,7 +863,7 @@ static void updateVirtualTable(
sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
}else{
sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG);/* Enable sqlite3_vtab_nochange() */
sqlite3VdbeChangeP5(v, 1); /* Enable sqlite3_vtab_nochange() */
}
}
if( HasRowid(pTab) ){
+11 -21
View File
@@ -2894,25 +2894,17 @@ case OP_MakeRecord: {
if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
}
nByte = nHdr+nData;
if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
/* Make sure the output register has a buffer large enough to store
** the new record. The output register (pOp->p3) is not allowed to
** be one of the input registers (because the following call to
** sqlite3VdbeMemClearAndResize() could clobber the value before it is used).
*/
if( nByte+nZero<=pOut->szMalloc ){
/* The output register is already large enough to hold the record.
** No error checks or buffer enlargement is required */
pOut->z = pOut->zMalloc;
}else{
/* Need to make sure that the output is not too big and then enlarge
** the output register to hold the full result */
if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
goto no_mem;
}
if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
goto no_mem;
}
zNewRecord = (u8 *)pOut->z;
@@ -5768,7 +5760,7 @@ case OP_ParseSchema: {
{
zMaster = MASTER_NAME;
initData.db = db;
initData.iDb = iDb;
initData.iDb = pOp->p1;
initData.pzErrMsg = &p->zErrMsg;
initData.mInitFlags = 0;
zSql = sqlite3MPrintf(db,
@@ -6965,11 +6957,10 @@ case OP_VFilter: { /* jump */
**
** If the VColumn opcode is being used to fetch the value of
** an unchanging column during an UPDATE operation, then the P5
** value is OPFLAG_NOCHNG. This will cause the sqlite3_vtab_nochange()
** function to return true inside the xColumn method of the virtual
** table implementation. The P5 column might also contain other
** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are
** unused by OP_VColumn.
** value is 1. Otherwise, P5 is 0. The P5 value is returned
** by sqlite3_vtab_nochange() routine and can be used
** by virtual table implementations to return special "no-change"
** marks which can be more efficient, depending on the virtual table.
*/
case OP_VColumn: {
sqlite3_vtab *pVtab;
@@ -6991,8 +6982,7 @@ case OP_VColumn: {
assert( pModule->xColumn );
memset(&sContext, 0, sizeof(sContext));
sContext.pOut = pDest;
testcase( (pOp->p5 & OPFLAG_NOCHNG)==0 && pOp->p5!=0 );
if( pOp->p5 & OPFLAG_NOCHNG ){
if( pOp->p5 ){
sqlite3VdbeMemSetNull(pDest);
pDest->flags = MEM_Null|MEM_Zero;
pDest->u.nZero = 0;
-3
View File
@@ -406,9 +406,6 @@ struct Vdbe {
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */
char *zSql; /* Text of the SQL statement that generated this */
#ifdef SQLITE_ENABLE_NORMALIZE
char *zNormSql; /* Normalization of the associated SQL statement */
#endif
void *pFree; /* Free this when deleting the vdbe */
VdbeFrame *pFrame; /* Parent frame */
VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
-10
View File
@@ -1702,16 +1702,6 @@ char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){
#endif
}
#ifdef SQLITE_ENABLE_NORMALIZE
/*
** Return the normalized SQL associated with a prepared statement.
*/
const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe *)pStmt;
return p ? p->zNormSql : 0;
}
#endif /* SQLITE_ENABLE_NORMALIZE */
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
/*
** Allocate and populate an UnpackedRecord structure based on the serialized
+1 -18
View File
@@ -64,13 +64,6 @@ void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlags){
}
assert( p->zSql==0 );
p->zSql = sqlite3DbStrNDup(p->db, z, n);
#ifdef SQLITE_ENABLE_NORMALIZE
assert( p->zNormSql==0 );
if( p->zSql && (prepFlags & SQLITE_PREPARE_NORMALIZE)!=0 ){
sqlite3Normalize(p, p->zSql, n, prepFlags);
assert( p->zNormSql!=0 || p->db->mallocFailed );
}
#endif
}
/*
@@ -92,11 +85,6 @@ void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
zTmp = pA->zSql;
pA->zSql = pB->zSql;
pB->zSql = zTmp;
#ifdef SQLITE_ENABLE_NORMALIZE
zTmp = pA->zNormSql;
pA->zNormSql = pB->zNormSql;
pB->zNormSql = zTmp;
#endif
pB->expmask = pA->expmask;
pB->prepFlags = pA->prepFlags;
memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter));
@@ -3168,9 +3156,6 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
vdbeFreeOpArray(db, p->aOp, p->nOp);
sqlite3DbFree(db, p->aColName);
sqlite3DbFree(db, p->zSql);
#ifdef SQLITE_ENABLE_NORMALIZE
sqlite3DbFree(db, p->zNormSql);
#endif
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
{
int i;
@@ -4572,9 +4557,7 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
(void)getVarint32((u8*)m.z, szHdr);
testcase( szHdr==3 );
testcase( szHdr==m.n );
testcase( szHdr>0x7fffffff );
assert( m.n>=0 );
if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){
if( unlikely(szHdr<3 || (int)szHdr>m.n) ){
goto idx_rowid_corruption;
}
+1 -2
View File
@@ -377,8 +377,7 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
assert( fg & MEM_Real );
sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
}
assert( pMem->z!=0 );
pMem->n = sqlite3Strlen30NN(pMem->z);
pMem->n = sqlite3Strlen30(pMem->z);
pMem->enc = SQLITE_UTF8;
pMem->flags |= MEM_Str|MEM_Term;
if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
+4 -3
View File
@@ -328,6 +328,7 @@ void sqlite3VtabBeginParse(
Token *pModuleName, /* Name of the module for the virtual table */
int ifNotExists /* No error if the table already exists */
){
int iDb; /* The database the table is being created in */
Table *pTable; /* The new virtual table */
sqlite3 *db; /* Database connection */
@@ -337,6 +338,8 @@ void sqlite3VtabBeginParse(
assert( 0==pTable->pIndex );
db = pParse->db;
iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
assert( iDb>=0 );
assert( pTable->nModuleArg==0 );
addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
@@ -356,8 +359,6 @@ void sqlite3VtabBeginParse(
** The second call, to obtain permission to create the table, is made now.
*/
if( pTable->azModuleArg ){
int iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
assert( iDb>=0 ); /* The database the table is being created in */
sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName,
pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName);
}
@@ -1052,7 +1053,7 @@ FuncDef *sqlite3VtabOverloadFunction(
/* Check to see the left operand is a column in a virtual table */
if( NEVER(pExpr==0) ) return pDef;
if( pExpr->op!=TK_COLUMN ) return pDef;
pTab = pExpr->y.pTab;
pTab = pExpr->pTab;
if( pTab==0 ) return pDef;
if( !IsVirtual(pTab) ) return pDef;
pVtab = sqlite3GetVTable(db, pTab)->pVtab;
+2 -2
View File
@@ -55,8 +55,8 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
}
#ifndef SQLITE_OMIT_WINDOWFUNC
if( ExprHasProperty(pExpr, EP_WinFunc) ){
Window *pWin = pExpr->y.pWin;
if( !ExprHasProperty(pExpr, EP_Reduced) && pExpr->pWin ){
Window *pWin = pExpr->pWin;
if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
+2 -19
View File
@@ -854,6 +854,7 @@ static void constructAutomaticIndex(
translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
pTabItem->regResult, 1);
sqlite3VdbeGoto(v, addrTop);
pTabItem->fg.viaCoroutine = 0;
}else{
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
}
@@ -2125,14 +2126,6 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
sqlite3 *db = pWInfo->pParse->db;
int rc;
/* Stop the search once we hit the query planner search limit */
if( pBuilder->iPlanLimit==0 ){
WHERETRACE(0xffffffff,("=== query planner search limit reached ===\n"));
if( pBuilder->pOrSet ) pBuilder->pOrSet->n = 0;
return SQLITE_DONE;
}
pBuilder->iPlanLimit--;
/* If pBuilder->pOrSet is defined, then only keep track of the costs
** and prereqs.
*/
@@ -3539,11 +3532,9 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
/* Loop over the tables in the join, from left to right */
pNew = pBuilder->pNew;
whereLoopInit(pNew);
pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT;
for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
Bitmask mUnusable = 0;
pNew->iTab = iTab;
pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR;
pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
/* This condition is true when pItem is the FROM clause term on the
@@ -3569,15 +3560,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable);
}
mPrior |= pNew->maskSelf;
if( rc || db->mallocFailed ){
if( rc==SQLITE_DONE ){
/* We hit the query planner search limit set by iPlanLimit */
sqlite3_log(SQLITE_WARNING, "abbreviated query algorithm search");
rc = SQLITE_OK;
}else{
break;
}
}
if( rc || db->mallocFailed ) break;
}
whereLoopClear(db, pNew);
-21
View File
@@ -402,33 +402,12 @@ struct WhereLoopBuilder {
int nRecValid; /* Number of valid fields currently in pRec */
#endif
unsigned int bldFlags; /* SQLITE_BLDF_* flags */
unsigned int iPlanLimit; /* Search limiter */
};
/* Allowed values for WhereLoopBuider.bldFlags */
#define SQLITE_BLDF_INDEXED 0x0001 /* An index is used */
#define SQLITE_BLDF_UNIQUE 0x0002 /* All keys of a UNIQUE index used */
/* The WhereLoopBuilder.iPlanLimit is used to limit the number of
** index+constraint combinations the query planner will consider for a
** particular query. If this parameter is unlimited, then certain
** pathological queries can spend excess time in the sqlite3WhereBegin()
** routine. The limit is high enough that is should not impact real-world
** queries.
**
** SQLITE_QUERY_PLANNER_LIMIT is the baseline limit. The limit is
** increased by SQLITE_QUERY_PLANNER_LIMIT_INCR before each term of the FROM
** clause is processed, so that every table in a join is guaranteed to be
** able to propose a some index+constraint combinations even if the initial
** baseline limit was exhausted by prior tables of the join.
*/
#ifndef SQLITE_QUERY_PLANNER_LIMIT
# define SQLITE_QUERY_PLANNER_LIMIT 20000
#endif
#ifndef SQLITE_QUERY_PLANNER_LIMIT_INCR
# define SQLITE_QUERY_PLANNER_LIMIT_INCR 1000
#endif
/*
** The WHERE clause processing routine has two halves. The
** first part does the start of the WHERE loop and the second
+2 -2
View File
@@ -425,7 +425,7 @@ static Expr *removeUnindexableInClauseTerms(
for(i=iEq; i<pLoop->nLTerm; i++){
if( pLoop->aLTerm[i]->pExpr==pX ){
int iField = pLoop->aLTerm[i]->iField - 1;
if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
assert( pOrigRhs->a[iField].pExpr!=0 );
pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
pOrigRhs->a[iField].pExpr = 0;
assert( pOrigLhs->a[iField].pExpr!=0 );
@@ -1117,7 +1117,7 @@ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
pExpr->op = TK_COLUMN;
pExpr->iTable = pX->iIdxCur;
pExpr->iColumn = pX->iIdxCol;
pExpr->y.pTab = 0;
pExpr->pTab = 0;
return WRC_Prune;
}else{
return WRC_Continue;
+9 -12
View File
@@ -281,7 +281,7 @@ static int isLikeOrGlob(
){
if( pLeft->op!=TK_COLUMN
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
|| IsVirtual(pLeft->y.pTab) /* Value might be numeric */
|| IsVirtual(pLeft->pTab) /* Value might be numeric */
){
sqlite3ExprDelete(db, pPrefix);
sqlite3ValueFree(pVal);
@@ -382,7 +382,7 @@ static int isAuxiliaryVtabOperator(
** MATCH(expression,vtab_column)
*/
pCol = pList->a[1].pExpr;
if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
for(i=0; i<ArraySize(aOp); i++){
if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
*peOp2 = aOp[i].eOp2;
@@ -404,12 +404,12 @@ static int isAuxiliaryVtabOperator(
** with function names in an arbitrary case.
*/
pCol = pList->a[0].pExpr;
if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
sqlite3_vtab *pVtab;
sqlite3_module *pMod;
void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
void *pNotUsed;
pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
pVtab = sqlite3GetVTable(db, pCol->pTab)->pVtab;
assert( pVtab!=0 );
assert( pVtab->pModule!=0 );
pMod = (sqlite3_module *)pVtab->pModule;
@@ -427,10 +427,10 @@ static int isAuxiliaryVtabOperator(
int res = 0;
Expr *pLeft = pExpr->pLeft;
Expr *pRight = pExpr->pRight;
if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){
if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->pTab) ){
res++;
}
if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){
if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->pTab) ){
res++;
SWAP(Expr*, pLeft, pRight);
}
@@ -1382,7 +1382,6 @@ static void exprAnalyze(
if( pExpr->op==TK_NOTNULL
&& pExpr->pLeft->op==TK_COLUMN
&& pExpr->pLeft->iColumn>=0
&& !ExprHasProperty(pExpr, EP_FromJoin)
&& OptimizationEnabled(db, SQLITE_Stat34)
){
Expr *pNewExpr;
@@ -1574,7 +1573,6 @@ void sqlite3WhereTabFuncArgs(
pArgs = pItem->u1.pFuncArg;
if( pArgs==0 ) return;
for(j=k=0; j<pArgs->nExpr; j++){
Expr *pRhs;
while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;}
if( k>=pTab->nCol ){
sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
@@ -1585,10 +1583,9 @@ void sqlite3WhereTabFuncArgs(
if( pColRef==0 ) return;
pColRef->iTable = pItem->iCursor;
pColRef->iColumn = k++;
pColRef->y.pTab = pTab;
pRhs = sqlite3PExpr(pParse, TK_UPLUS,
sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
pColRef->pTab = pTab;
pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0));
whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
}
}
+5 -7
View File
@@ -624,12 +624,12 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
switch( pExpr->op ){
case TK_FUNCTION:
if( !ExprHasProperty(pExpr, EP_WinFunc) ){
if( pExpr->pWin==0 ){
break;
}else{
Window *pWin;
for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
if( pExpr->y.pWin==pWin ){
if( pExpr->pWin==pWin ){
assert( pWin->pOwner==pExpr );
return WRC_Prune;
}
@@ -746,7 +746,7 @@ static ExprList *exprListAppendList(
*/
int sqlite3WindowRewrite(Parse *pParse, Select *p){
int rc = SQLITE_OK;
if( p->pWin && p->pPrior==0 ){
if( p->pWin ){
Vdbe *v = sqlite3GetVdbe(pParse);
sqlite3 *db = pParse->db;
Select *pSub = 0; /* The subquery */
@@ -959,13 +959,11 @@ windowAllocErr:
*/
void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
if( p ){
assert( p->op==TK_FUNCTION );
/* This routine is only called for the parser. If pWin was not
** allocated due to an OOM, then the parser would fail before ever
** invoking this routine */
if( ALWAYS(pWin) ){
p->y.pWin = pWin;
ExprSetProperty(p, EP_WinFunc);
p->pWin = pWin;
pWin->pOwner = p;
if( p->flags & EP_Distinct ){
sqlite3ErrorMsg(pParse,
@@ -2128,7 +2126,7 @@ static void windowCodeDefaultStep(
*/
Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
Window *pNew = 0;
if( ALWAYS(p) ){
if( p ){
pNew = sqlite3DbMallocZero(db, sizeof(Window));
if( pNew ){
pNew->zName = sqlite3DbStrDup(db, p->zName);
-98
View File
@@ -1,98 +0,0 @@
# 2018 October 6
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
finish_test
return
}
set testprefix alterauth2
set ::auth [list]
proc xAuth {type args} {
lappend ::auth [concat $type [lrange $args 0 3]]
if {$type=="SQLITE_READ" && [lindex $args 0] == "t2"} breakpoint
return SQLITE_OK
}
db auth xAuth
proc do_auth_test {tn sql authcode} {
set script "
set ::auth \[list\]
execsql {$sql}
lsort -unique \[set ::auth\]
"
set normal [list {*}$authcode]
uplevel [list do_test $tn $script $normal]
}
do_execsql_test 1.0 {
CREATE TABLE t1(a, b, c);
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
DELETE FROM t1 WHERE a<new.a;
END;
CREATE TEMP TRIGGER tr2 AFTER UPDATE OF a, b ON t1 BEGIN
UPDATE t1 SET a=a+1 WHERE new.b<b;
END;
}
do_auth_test 1.1 {
ALTER TABLE t1 RENAME TO t2;
} {
{SQLITE_ALTER_TABLE main t1 {} {}}
{SQLITE_FUNCTION {} like {} {}}
{SQLITE_FUNCTION {} sqlite_rename_table {} {}}
{SQLITE_FUNCTION {} sqlite_rename_test {} {}}
{SQLITE_FUNCTION {} substr {} {}}
{SQLITE_READ sqlite_master name main {}}
{SQLITE_READ sqlite_master sql main {}}
{SQLITE_READ sqlite_master tbl_name main {}}
{SQLITE_READ sqlite_master type main {}}
{SQLITE_READ sqlite_temp_master name temp {}}
{SQLITE_READ sqlite_temp_master sql temp {}}
{SQLITE_READ sqlite_temp_master tbl_name temp {}}
{SQLITE_READ sqlite_temp_master type temp {}}
{SQLITE_SELECT {} {} {} {}}
{SQLITE_UPDATE sqlite_master name main {}}
{SQLITE_UPDATE sqlite_master sql main {}}
{SQLITE_UPDATE sqlite_master tbl_name main {}}
{SQLITE_UPDATE sqlite_temp_master sql temp {}}
{SQLITE_UPDATE sqlite_temp_master tbl_name temp {}}
}
do_auth_test 1.2 {
ALTER TABLE t2 RENAME a TO aaa;
} {
{SQLITE_ALTER_TABLE main t2 {} {}}
{SQLITE_FUNCTION {} like {} {}}
{SQLITE_FUNCTION {} sqlite_rename_column {} {}}
{SQLITE_FUNCTION {} sqlite_rename_test {} {}}
{SQLITE_READ sqlite_master name main {}}
{SQLITE_READ sqlite_master sql main {}}
{SQLITE_READ sqlite_master tbl_name main {}}
{SQLITE_READ sqlite_master type main {}}
{SQLITE_READ sqlite_temp_master name temp {}}
{SQLITE_READ sqlite_temp_master sql temp {}}
{SQLITE_READ sqlite_temp_master type temp {}}
{SQLITE_SELECT {} {} {} {}}
{SQLITE_UPDATE sqlite_master sql main {}}
{SQLITE_UPDATE sqlite_temp_master sql temp {}}
}
finish_test
+1 -1
View File
@@ -19,7 +19,7 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
ifcapable !altertable||!memdebug {
finish_test
return
}
-43
View File
@@ -459,49 +459,6 @@ do_execsql_test 14.6 {
ALTER TABLE t1 RENAME TO tt1;
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 15.0 {
CREATE TABLE t1(a integer NOT NULL PRIMARY KEY);
CREATE VIEW v1 AS SELECT a FROM t1;
CREATE TRIGGER tr1 INSTEAD OF INSERT ON v1 BEGIN
UPDATE t1 SET a = NEW.a;
END;
CREATE TRIGGER tr2 INSTEAD OF INSERT ON v1 BEGIN
SELECT new.a;
END;
CREATE TABLE t2 (b);
}
do_execsql_test 15.1 {
INSERT INTO v1 VALUES(1);
ALTER TABLE t2 RENAME TO t3;
}
do_execsql_test 15.2 {
CREATE TABLE x(f1 integer NOT NULL);
CREATE VIEW y AS SELECT f1 AS f1 FROM x;
CREATE TRIGGER t INSTEAD OF UPDATE OF f1 ON y BEGIN
UPDATE x SET f1 = NEW.f1;
END;
CREATE TABLE z (f1 integer NOT NULL PRIMARY KEY);
ALTER TABLE z RENAME TO z2;
}
do_execsql_test 15.3 {
INSERT INTO x VALUES(1), (2), (3);
ALTER TABLE x RENAME f1 TO f2;
SELECT * FROM x;
} {1 2 3}
do_execsql_test 15.4 {
UPDATE y SET f1 = 'x' WHERE f1 = 1;
SELECT * FROM x;
} {x x x}
do_execsql_test 15.5 {
SELECT sql FROM sqlite_master WHERE name = 'y';
} {{CREATE VIEW y AS SELECT f2 AS f1 FROM x}}
finish_test
-44
View File
@@ -41,50 +41,6 @@ ifcapable fts5 {
} {hello world in tcl}
}
#-------------------------------------------------------------------------
# Check that table names that appear in REFERENCES clauses are updated
# when a table is renamed unless:
#
# a) "PRAGMA legacy_alter_table" is true, and
# b) "PRAGMA foreign_keys" is false.
#
do_execsql_test 2.0 {
CREATE TABLE p1(a PRIMARY KEY, b);
CREATE TABLE c1(x REFERENCES p1);
CREATE TABLE c2(x, FOREIGN KEY (x) REFERENCES p1);
CREATE TABLE c3(x, FOREIGN KEY (x) REFERENCES p1(a));
}
do_execsql_test 2.1 {
ALTER TABLE p1 RENAME TO p2;
SELECT sql FROM sqlite_master WHERE name LIKE 'c%';
} {
{CREATE TABLE c1(x REFERENCES "p2")}
{CREATE TABLE c2(x, FOREIGN KEY (x) REFERENCES "p2")}
{CREATE TABLE c3(x, FOREIGN KEY (x) REFERENCES "p2"(a))}
}
do_execsql_test 2.2 {
PRAGMA legacy_alter_table = 1;
ALTER TABLE p2 RENAME TO p3;
SELECT sql FROM sqlite_master WHERE name LIKE 'c%';
} {
{CREATE TABLE c1(x REFERENCES "p2")}
{CREATE TABLE c2(x, FOREIGN KEY (x) REFERENCES "p2")}
{CREATE TABLE c3(x, FOREIGN KEY (x) REFERENCES "p2"(a))}
}
do_execsql_test 2.3 {
ALTER TABLE p3 RENAME TO p2;
PRAGMA foreign_keys = 1;
ALTER TABLE p2 RENAME TO p3;
SELECT sql FROM sqlite_master WHERE name LIKE 'c%';
} {
{CREATE TABLE c1(x REFERENCES "p3")}
{CREATE TABLE c2(x, FOREIGN KEY (x) REFERENCES "p3")}
{CREATE TABLE c3(x, FOREIGN KEY (x) REFERENCES "p3"(a))}
}
finish_test
-25
View File
@@ -726,31 +726,6 @@ ifcapable subquery {
} db2
} {1 {trigger r5 cannot reference objects in database temp}}
} ;# endif subquery
ifcapable json1 {
do_test attach-5.10 {
db close
forcedelete test.db
sqlite3 db test.db
db eval {
CREATE TABLE t1(x);
CREATE TABLE t2(a,b);
CREATE TRIGGER x1 AFTER INSERT ON t1 BEGIN
INSERT INTO t2(a,b) SELECT key, value FROM json_each(NEW.x);
END;
INSERT INTO t1(x) VALUES('{"a":1}');
SELECT * FROM t2;
}
} {a 1}
do_test attach-5.11 {
sqlite3 db2 :memory:
db2 eval {
CREATE TABLE t3(y);
ATTACH 'test.db' AS aux;
INSERT INTO aux.t1(x) VALUES('{"b":2}');
SELECT * FROM aux.t2;
}
} {a 1 b 2}
} ;# endif json1
} ;# endif trigger
# Check to make sure we get a sensible error if unable to open
+1 -1
View File
@@ -18,7 +18,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !attach {
ifcapable !memdebug||!attach {
finish_test
return
}
-85
View File
@@ -123,91 +123,6 @@ do_execsql_test 2.1 {
SELECT sum(z) FROM vvv WHERE x='aaa'
) FROM one;
} {8.0}
# Ticket https://www.sqlite.org/src/info/787fa716be3a7f65
# Segfault due to multiple uses of the same subquery where the
# subquery is implemented via coroutine.
#
sqlite3 db :memory:
do_execsql_test 3.0 {
-- This is the original test case reported on the mailing list
CREATE TABLE artists (
id integer NOT NULL PRIMARY KEY AUTOINCREMENT,
name varchar(255)
);
CREATE TABLE albums (
id integer NOT NULL PRIMARY KEY AUTOINCREMENT,
name varchar(255),
artist_id integer REFERENCES artists
);
INSERT INTO artists (name) VALUES ('Ar');
INSERT INTO albums (name, artist_id) VALUES ('Al', 1);
SELECT artists.*
FROM artists
INNER JOIN artists AS 'b' ON (b.id = artists.id)
WHERE (artists.id IN (
SELECT albums.artist_id
FROM albums
WHERE ((name = 'Al')
AND (albums.artist_id IS NOT NULL)
AND (albums.id IN (
SELECT id
FROM (
SELECT albums.id,
row_number() OVER (
PARTITION BY albums.artist_id
ORDER BY name
) AS 'x'
FROM albums
WHERE (name = 'Al')
) AS 't1'
WHERE (x = 1)
))
AND (albums.id IN (1, 2)))
));
} {1 Ar}
# The remaining test cases were discovered (by Dan) during trouble-shooting
sqlite3 db :memory:
do_execsql_test 3.1 {
CREATE TABLE t1 (a); INSERT INTO t1 (a) VALUES (104);
CREATE TABLE t2 (b); INSERT INTO t2 (b) VALUES (104);
CREATE TABLE t3 (c); INSERT INTO t3 (c) VALUES (104);
CREATE TABLE t4 (d); INSERT INTO t4 (d) VALUES (104);
SELECT *
FROM t1 CROSS JOIN t2 ON (t1.a = t2.b) WHERE t2.b IN (
SELECT t3.c
FROM t3
WHERE t3.c IN (
SELECT d FROM (SELECT DISTINCT d FROM t4) AS x WHERE x.d=104
)
);
} {104 104}
sqlite3 db :memory:
do_execsql_test 3.2 {
CREATE TABLE t5(a, b, c, d);
CREATE INDEX t5a ON t5(a);
CREATE INDEX t5b ON t5(b);
CREATE TABLE t6(e);
INSERT INTO t6 VALUES(1);
INSERT INTO t5 VALUES(1,1,1,1), (2,2,2,2);
SELECT * FROM t5 WHERE (a=1 OR b=2) AND c IN (
SELECT e FROM (SELECT DISTINCT e FROM t6) WHERE e=1
);
} {1 1 1 1}
sqlite3 db :memory:
do_execsql_test 3.3 {
CREATE TABLE t1(a1, a2, a3);
CREATE INDEX t1a2 ON t1(a2, a1);
CREATE INDEX t1a3 ON t1(a3, a1);
CREATE TABLE t2(d);
INSERT INTO t1 VALUES(3, 1, 1), (3, 2, 2);
INSERT INTO t2 VALUES(3);
SELECT *, 'x' FROM t1 WHERE (a2=1 OR a3=2) AND a1 = (
SELECT d FROM (SELECT DISTINCT d FROM t2) WHERE d=3
);
} {3 1 1 x 3 2 2 x}
finish_test
-53
View File
@@ -117,57 +117,4 @@ for {set param1 0} {$param1<16} {incr param1} {
}
}
#-------------------------------------------------------------------------
# Test that a parameter passed to a table-valued function cannot be
# used to drive an index. i.e. that in the following:
#
# SELECT * FROM tbl, vtab(tbl.x);
#
# The implicit constraint "tbl.x = vtab.hidden" is not optimized using
# an index on tbl.x.
#
reset_db
register_tcl_module db
proc vtab_command {method args} {
switch -- $method {
xConnect {
return "CREATE TABLE t1(a, b, c, d HIDDEN)"
}
xBestIndex {
set clist [lindex $args 0]
if {[llength $clist]!=1} { error "unexpected constraint list" }
catch { array unset C }
array set C [lindex $clist 0]
if {$C(usable)} {
return [list omit 0 idxnum 555 rows 10 cost 100]
}
return [list cost 100000000]
}
}
return {}
}
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE x1 USING tcl(vtab_command);
CREATE TABLE t1 (x INT PRIMARY KEY);
} {}
do_execsql_test 2.1 {
EXPLAIN QUERY PLAN SELECT * FROM t1, x1 WHERE x1.d=t1.x;
} {
3 0 0 {SCAN TABLE x1 VIRTUAL TABLE INDEX 0:}
7 0 0 {SEARCH TABLE t1 USING COVERING INDEX sqlite_autoindex_t1_1 (x=?)}
}
do_execsql_test 2.2 {
EXPLAIN QUERY PLAN SELECT * FROM t1, x1(t1.x)
} {
3 0 0 {SCAN TABLE t1}
5 0 0 {SCAN TABLE x1 VIRTUAL TABLE INDEX 555:}
}
finish_test
+2
View File
@@ -811,6 +811,7 @@ foreach {code english} $code2english {
# Test the error message when a "real" out of memory occurs.
if { [permutation] != "nofaultsim" } {
ifcapable memdebug {
do_test capi3-10-1 {
sqlite3 db test.db
set DB [sqlite3_connection_pointer db]
@@ -848,6 +849,7 @@ if { [permutation] != "nofaultsim" } {
db close
sqlite3_memdebug_fail -1
}
}
# The following tests - capi3-11.* - test that a COMMIT or ROLLBACK
# statement issued while there are still outstanding VMs that are part of
+2
View File
@@ -757,6 +757,7 @@ foreach {code english} $code2english {
# Test the error message when a "real" out of memory occurs.
if { [permutation] != "nofaultsim" } {
ifcapable memdebug {
do_test capi3c-10-1 {
sqlite3 db test.db
set DB [sqlite3_connection_pointer db]
@@ -776,6 +777,7 @@ if { [permutation] != "nofaultsim" } {
db close
sqlite3_memdebug_fail -1
}
}
# The following tests - capi3c-11.* - test that a COMMIT or ROLLBACK
# statement issued while there are still outstanding VMs that are part of
+1 -1
View File
@@ -20,7 +20,7 @@ source $testdir/tester.tcl
# Only run these tests if memory debugging is turned on.
#
ifcapable !crashtest||!memorymanage {
ifcapable !memdebug||!crashtest||!memorymanage {
puts "Skipping crash5 tests: not compiled with -DSQLITE_MEMDEBUG..."
finish_test
return
Binary file not shown.
-138
View File
@@ -1,138 +0,0 @@
/*
** 2018-10-26
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This program is designed for fuzz-testing SQLite database files using
** the -fsanitize=fuzzer option of clang.
**
** The -fsanitize=fuzzer option causes a main() to be inserted automatically.
** That main() invokes LLVMFuzzerTestOneInput(D,S) to be invoked repeatedly.
** Each D is a fuzzed database file. The code in this file runs various
** SQL statements against that database, trying to provoke a failure.
**
** For best results the seed database files should have these tables:
**
** Table "t1" with columns "a" and "b"
** Tables "t2" and "t3 with the same number of compatible columns
** "t3" should have a column names "x"
** Table "t4" with a column "x" that is compatible with t3.x.
**
** Any of these tables can be virtual tables, for example FTS or RTree tables.
**
** To run this test:
**
** mkdir dir
** cp dbfuzz2-seed*.db dir
** clang-6.0 -I. -g -O1 -fsanitize=fuzzer \
** -DTHREADSAFE=0 -DSQLITE_ENABLE_DESERIALIZE \
** -DSQLITE_ENABLE_DBSTAT_VTAB dbfuzz2.c sqlite3.c -ldl
** ./a.out dir
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#include <stdint.h>
#include "sqlite3.h"
/*
** This is the is the SQL that is run against the database.
*/
static const char *azSql[] = {
"PRAGMA integrity_check;",
"SELECT * FROM sqlite_master;",
"SELECT sum(length(name)) FROM dbstat;",
"UPDATE t1 SET b=a, a=b WHERE a<b;",
"ALTER TABLE t1 RENAME TO alkjalkjdfiiiwuer987lkjwer82mx97sf98788s9789s;",
"INSERT INTO t3 SELECT * FROM t2;",
"DELETE FROM t3 WHERE x IN (SELECT x FROM t4);",
"REINDEX;",
"DROP TABLE t3;",
"VACUUM;",
};
/* Output verbosity level. 0 means complete silence */
int eVerbosity = 0;
/* libFuzzer invokes this routine with fuzzed database files (in aData).
** This routine run SQLite against the malformed database to see if it
** can provoke a failure or malfunction.
*/
int LLVMFuzzerTestOneInput(const uint8_t *aData, size_t nByte){
unsigned char *a;
sqlite3 *db;
int rc;
int i;
if( eVerbosity>=1 ){
printf("************** nByte=%d ***************\n", (int)nByte);
fflush(stdout);
}
rc = sqlite3_open(0, &db);
if( rc ) return 1;
a = sqlite3_malloc64(nByte+1);
if( a==0 ) return 1;
memcpy(a, aData, nByte);
sqlite3_deserialize(db, "main", a, nByte, nByte,
SQLITE_DESERIALIZE_RESIZEABLE |
SQLITE_DESERIALIZE_FREEONCLOSE);
for(i=0; i<sizeof(azSql)/sizeof(azSql[0]); i++){
if( eVerbosity>=1 ){
printf("%s\n", azSql[i]);
fflush(stdout);
}
sqlite3_exec(db, azSql[i], 0, 0, 0);
}
rc = sqlite3_close(db);
if( rc!=SQLITE_OK ){
fprintf(stdout, "sqlite3_close() returns %d\n", rc);
}
if( sqlite3_memory_used()!=0 ){
int nAlloc = 0;
int nNotUsed = 0;
sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &nAlloc, &nNotUsed, 0);
fprintf(stderr,"Memory leak: %lld bytes in %d allocations\n",
sqlite3_memory_used(), nAlloc);
exit(1);
}
return 0;
}
/* libFuzzer invokes this routine once when the executable starts, to
** process the command-line arguments.
*/
int LLVMFuzzerInitialize(int *pArgc, char ***pArgv){
int i, j;
int argc = *pArgc;
char **newArgv;
char **argv = *pArgv;
newArgv = malloc( sizeof(char*)*(argc+1) );
if( newArgv==0 ) return 0;
newArgv[0] = argv[0];
for(i=j=1; i<argc; i++){
char *z = argv[i];
if( z[0]=='-' ){
z++;
if( z[0]=='-' ) z++;
if( strcmp(z,"v")==0 ){
eVerbosity++;
continue;
}
}
newArgv[j++] = argv[i];
}
newArgv[j] = 0;
*pArgv = newArgv;
*pArgc = j;
return 0;
}
+2 -2
View File
@@ -379,9 +379,9 @@ foreach ::lookaside_buffer_size {0 64 120} {
# The following tests focus on DBSTATUS_CACHE_USED_SHARED
#
ifcapable shared_cache {
if {([permutation]=="memsys3"
if {[permutation]=="memsys3"
|| [permutation]=="memsys5"
|| $::tcl_platform(os)=="Linux") && ![sqlite3 -has-codec]} {
|| $::tcl_platform(os)=="Linux"} {
proc do_cacheused_test {tn db res} {
set cu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED 0]
set pcu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED_SHARED 0]
-147
View File
@@ -1,147 +0,0 @@
# 2006 September 9
#
# 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 FTS3 module.
#
# $Id: fts3aa.test,v 1.1 2007/08/20 17:38:42 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix fts3corrupt4
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
finish_test
return
}
do_execsql_test 1.0 {
BEGIN;
CREATE VIRTUAL TABLE ft USING fts3;
INSERT INTO ft VALUES('aback');
INSERT INTO ft VALUES('abaft');
INSERT INTO ft VALUES('abandon');
COMMIT;
}
proc blob {a} { binary decode hex $a }
db func blob blob
do_execsql_test 1.1 {
SELECT quote(root) FROM ft_segdir;
} {X'0005616261636B03010200030266740302020003046E646F6E03030200'}
do_execsql_test 1.2 {
UPDATE ft_segdir SET root = blob(
'0005616261636B03010200 FFFFFFFF0702 66740302020003046E646F6E03030200'
);
}
do_catchsql_test 1.3 {
SELECT * FROM ft WHERE ft MATCH 'abandon';
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0.0 {
CREATE VIRTUAL TABLE ft USING fts3;
INSERT INTO ft(ft) VALUES('nodesize=32');
}
do_test 2.0.1 {
for {set i 0} {$i < 12} {incr i} {
execsql {
BEGIN;
INSERT INTO ft VALUES('abc' || $i);
INSERT INTO ft VALUES('abc' || $i || 'x' );
INSERT INTO ft VALUES('abc' || $i || 'xx' );
COMMIT
}
}
execsql {
SELECT count(*) FROM ft_segdir;
SELECT count(*) FROM ft_segments;
}
} {12 0}
do_execsql_test 2.1 {
INSERT INTO ft(ft) VALUES('merge=1,4');
SELECT count(*) FROM ft_segdir;
SELECT count(*) FROM ft_segments;
} {12 3}
do_execsql_test 2.2 {
SELECT quote(block) FROM ft_segments WHERE blockid=2
} {X'00056162633130031F0200'}
db func blob blob
do_execsql_test 2.3.1 {
UPDATE ft_segments SET block =
blob('00056162633130031F0200 FFFFFFFF07FF55 66740302020003046E646F6E03030200')
WHERE blockid=2;
} {}
do_catchsql_test 2.3.2 {
INSERT INTO ft(ft) VALUES('merge=1,4');
} {1 {database disk image is malformed}}
do_execsql_test 2.4.1 {
UPDATE ft_segments SET block =
blob('00056162633130031F0200 02FFFFFFFF07 66740302020003046E646F6E03030200')
WHERE blockid=2;
} {}
do_catchsql_test 2.4.2 {
INSERT INTO ft(ft) VALUES('merge=1,4');
} {1 {database disk image is malformed}}
do_execsql_test 2.5.1 {
UPDATE ft_segments SET block =
blob('00056162633130031F0200 0202 6674 FFFFFF070302020003046E646F6E030200')
WHERE blockid=2;
} {}
do_catchsql_test 2.5.2 {
INSERT INTO ft(ft) VALUES('merge=1,4');
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 3.0.0 {
CREATE VIRTUAL TABLE ft USING fts3;
INSERT INTO ft(ft) VALUES('nodesize=32');
}
do_test 3.0.1 {
execsql BEGIN
for {set i 0} {$i < 20} {incr i} {
execsql { INSERT INTO ft VALUES('abc' || $i) }
}
execsql {
COMMIT;
SELECT count(*) FROM ft_segdir;
SELECT count(*) FROM ft_segments;
}
} {1 5}
do_execsql_test 3.1 {
SELECT quote(root) FROM ft_segdir
} {X'0101056162633132040136030132030136'}
db func blob blob
do_execsql_test 3.2 {
UPDATE ft_segdir
SET root = blob('0101056162633132FFFFFFFF070236030132030136');
}
do_catchsql_test 3.1 {
SELECT * FROM ft WHERE ft MATCH 'abc20'
} {1 {database disk image is malformed}}
finish_test
+5
View File
@@ -17,6 +17,11 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !memdebug {
finish_test
return
}
source $testdir/malloc_common.tcl
source $testdir/fuzz_common.tcl
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -16,7 +16,7 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix incrblob_err
ifcapable {!incrblob || !tclvar} {
ifcapable {!incrblob || !memdebug || !tclvar} {
finish_test
return
}
-7
View File
@@ -625,13 +625,6 @@ do_test index-18.1 {
CREATE TABLE sqlite_t1(a, b, c);
}
} {1 {object name reserved for internal use: sqlite_t1}}
do_test index-18.1.2 {
sqlite3_db_config db DEFENSIVE 1
catchsql {
CREATE TABLE sqlite_t1(a, b, c);
}
} {1 {object name reserved for internal use: sqlite_t1}}
sqlite3_db_config db DEFENSIVE 0
do_test index-18.2 {
catchsql {
CREATE INDEX sqlite_i1 ON t7(c);
-70
View File
@@ -159,75 +159,5 @@ do_execsql_test 3.4.6 {
SELECT * FROM t4 ORDER BY Substr(a,-2) COLLATE binary;
} {.ABC1 1 .ABC3 3 .abc2 2 .abc4 4}
# 2014-09-15: Verify that UPDATEs of columns not referenced by a
# index on expression do not modify the index.
#
unset -nocomplain cnt
set cnt 0
proc refcnt {x} {
global cnt
incr cnt
return $x
}
db close
sqlite3 db :memory:
db function refcnt -deterministic refcnt
do_test 4.100 {
db eval {
CREATE TABLE t1(a,b,c,d,e,f);
CREATE INDEX t1abc ON t1(refcnt(a+b+c));
}
set ::cnt
} {0}
do_test 4.110 {
db eval {INSERT INTO t1 VALUES(1,2,3,4,5,6);}
set ::cnt
# The refcnt() function is invoked once to compute the index value
} {1}
do_test 4.120 {
set ::cnt 0
db eval {UPDATE t1 SET b=b+1;}
set ::cnt
# The refcnt() function is invoked twice, once to remove the old index
# entry and a second time to insert the new one.
} {2}
do_test 4.130 {
set ::cnt 0
db eval {UPDATE t1 SET d=d+1;}
set ::cnt
# Refcnt() should not be invoked because that index does not change.
} {0}
# Additional test cases to show that UPDATE does not modify indexes that
# do not involve unchanged columns.
#
load_static_extension db explain
do_execsql_test 4.200 {
CREATE TABLE t2(a,b,c,d,e,f);
INSERT INTO t2 VALUES(2,3,4,5,6,7);
CREATE INDEX t2abc ON t2(a+b+c);
CREATE INDEX t2cd ON t2(c*d);
CREATE INDEX t2def ON t2(d,e+25*f);
SELECT sqlite_master.name
FROM sqlite_master, explain('UPDATE t2 SET b=b+1')
WHERE explain.opcode LIKE 'Open%'
AND sqlite_master.rootpage=explain.p2
ORDER BY 1;
} {t2 t2abc}
do_execsql_test 4.210 {
SELECT sqlite_master.name
FROM sqlite_master, explain('UPDATE t2 SET c=c+1')
WHERE explain.opcode LIKE 'Open%'
AND sqlite_master.rootpage=explain.p2
ORDER BY 1;
} {t2 t2abc t2cd}
do_execsql_test 4.220 {
SELECT sqlite_master.name
FROM sqlite_master, explain('UPDATE t2 SET c=c+1, f=NULL')
WHERE explain.opcode LIKE 'Open%'
AND sqlite_master.rootpage=explain.p2
ORDER BY 1;
} {t2 t2abc t2cd t2def}
finish_test
-7
View File
@@ -47,13 +47,6 @@ do_test intarray-1.1 {
}
} {table ia1 table ia2 table ia3 table ia4}
# Verify the inability to DROP and recreate an intarray virtual table.
do_test intarray-1.1b {
db eval {DROP TABLE ia1}
set rc [catch {sqlite3_intarray_create db ia1} msg]
lappend rc $msg
} {1 SQLITE_MISUSE}
do_test intarray-1.2 {
db eval {
SELECT b FROM t1 WHERE a IN ia3 ORDER BY a
-2
View File
@@ -130,14 +130,12 @@ do_eqp_test like3-5.101 {
do_execsql_test like3-5.110 {
SELECT x FROM t5a WHERE x LIKE '/a%';
} {/abc}
ifcapable !icu {
do_eqp_test like3-5.111 {
SELECT x FROM t5a WHERE x LIKE '/a%';
} {
QUERY PLAN
`--SEARCH TABLE t5a USING COVERING INDEX sqlite_autoindex_t5a_1 (x>? AND x<?)
}
}
do_execsql_test like3-5.120 {
SELECT x FROM t5a WHERE x LIKE '^12%' ESCAPE '^';
} {123}
-253
View File
@@ -1,253 +0,0 @@
package require sqlite3
package require Tk
#############################################################################
# Code to set up scrollbars for widgets. This is generic, boring stuff.
#
namespace eval autoscroll {
proc scrollable {widget path args} {
::ttk::frame $path
set w [$widget ${path}.widget {*}$args]
set vs [::ttk::scrollbar ${path}.vs]
set hs [::ttk::scrollbar ${path}.hs -orient horizontal]
grid $w -row 0 -column 0 -sticky nsew
grid rowconfigure $path 0 -weight 1
grid columnconfigure $path 0 -weight 1
set grid [list grid $vs -row 0 -column 1 -sticky nsew]
$w configure -yscrollcommand [list ::autoscroll::scrollcommand $grid $vs]
$vs configure -command [list $w yview]
set grid [list grid $hs -row 1 -column 0 -sticky nsew]
$w configure -xscrollcommand [list ::autoscroll::scrollcommand $grid $hs]
$hs configure -command [list $w xview]
return $w
}
proc scrollcommand {grid sb args} {
$sb set {*}$args
set isRequired [expr {[lindex $args 0] != 0.0 || [lindex $args 1] != 1.0}]
if {$isRequired && ![winfo ismapped $sb]} {
{*}$grid
}
if {!$isRequired && [winfo ismapped $sb]} {
grid forget $sb
}
}
namespace export scrollable
}
namespace import ::autoscroll::*
#############################################################################
proc populate_text_widget {db} {
$::O(text) configure -state normal
set id [lindex [$::O(tree) selection] 0]
set frame [lindex $id end]
set line [$db one {SELECT line FROM frame WHERE frame = $frame}]
if {$line ne ""} {
foreach {file line} [split $line :] {}
set content [$db one "SELECT content FROM file WHERE name = '$file'"]
$::O(text) delete 0.0 end
set iLine 1
foreach L [split $content "\n"] {
if {$iLine == $line} {
$::O(text) insert end "$L\n" highlight
} else {
$::O(text) insert end "$L\n"
}
incr iLine
}
$::O(text) yview -pickplace ${line}.0
}
$::O(text) configure -state disabled
}
proc populate_index {db} {
$::O(text) configure -state normal
$::O(text) delete 0.0 end
$::O(text) insert end "\n\n"
set L [format " % -40s%12s%12s\n" "Test Case" "Allocations" "Bytes"]
$::O(text) insert end $L
$::O(text) insert end " [string repeat - 64]\n"
$db eval {
SELECT 'TOTAL' AS ztest, sum(ncall) AS calls, sum(nbyte) AS bytes
FROM malloc
UNION ALL
SELECT ztest AS ztest, sum(ncall) AS calls, sum(nbyte) AS bytes
FROM malloc
GROUP BY ztest
ORDER BY 3 DESC
} {
set tags [list $ztest]
if {$ztest eq $::O(current)} {
lappend tags highlight
}
set L [format " % -40s%12s%12s\n" $ztest $calls $bytes]
$::O(text) insert end $L $tags
$::O(text) tag bind $ztest <1> [list populate_tree_widget $db $ztest]
$::O(text) tag bind $ztest <Enter> [list $::O(text) configure -cursor hand2]
$::O(text) tag bind $ztest <Leave> [list $::O(text) configure -cursor ""]
}
$::O(text) configure -state disabled
}
proc sort_tree_compare {iLeft iRight} {
global O
switch -- [expr (int($O(tree_sort)/2))] {
0 {
set left [$O(tree) item $iLeft -text]
set right [$O(tree) item $iRight -text]
set res [string compare $left $right]
}
1 {
set left [lindex [$O(tree) item $iLeft -values] 0]
set right [lindex [$O(tree) item $iRight -values] 0]
set res [expr $left - $right]
}
2 {
set left [lindex [$O(tree) item $iLeft -values] 1]
set right [lindex [$O(tree) item $iRight -values] 1]
set res [expr $left - $right]
}
}
if {$O(tree_sort)&0x01} {
set res [expr -1 * $res]
}
return $res
}
proc sort_tree {iMode} {
global O
if {$O(tree_sort) == $iMode} {
incr O(tree_sort)
} else {
set O(tree_sort) $iMode
}
set T $O(tree)
set items [$T children {}]
set items [lsort -command sort_tree_compare $items]
for {set ii 0} {$ii < [llength $items]} {incr ii} {
$T move [lindex $items $ii] {} $ii
}
}
proc trim_frames {stack} {
while {[info exists ::O(ignore.[lindex $stack 0])]} {
set stack [lrange $stack 1 end]
}
return $stack
}
proc populate_tree_widget {db zTest} {
$::O(tree) delete [$::O(tree) children {}]
for {set ii 0} {$ii < 15} {incr ii} {
$db eval {
SELECT
sum(ncall) AS calls,
sum(nbyte) AS bytes,
trim_frames(lrange(lstack, 0, $ii)) AS stack
FROM malloc
WHERE (zTest = $zTest OR $zTest = 'TOTAL') AND llength(lstack)>$ii
GROUP BY stack
HAVING stack != ''
} {
set parent_id [lrange $stack 0 end-1]
set frame [lindex $stack end]
set line [$db one {SELECT line FROM frame WHERE frame = $frame}]
set line [lindex [split $line /] end]
set v [list $calls $bytes]
catch {
$::O(tree) insert $parent_id end -id $stack -text $line -values $v
}
}
}
set ::O(current) $zTest
populate_index $db
}
set O(tree_sort) 0
::ttk::panedwindow .pan -orient horizontal
set O(tree) [scrollable ::ttk::treeview .pan.tree]
frame .pan.right
set O(text) [scrollable text .pan.right.text]
button .pan.right.index -command {populate_index mddb} -text "Show Index"
pack .pan.right.index -side top -fill x
pack .pan.right.text -fill both -expand true
$O(text) tag configure highlight -background wheat
$O(text) configure -wrap none -height 35
.pan add .pan.tree
.pan add .pan.right
$O(tree) configure -columns {calls bytes}
$O(tree) heading #0 -text Line -anchor w -command {sort_tree 0}
$O(tree) heading calls -text Calls -anchor w -command {sort_tree 2}
$O(tree) heading bytes -text Bytes -anchor w -command {sort_tree 4}
$O(tree) column #0 -width 150
$O(tree) column calls -width 100
$O(tree) column bytes -width 100
pack .pan -fill both -expand 1
#--------------------------------------------------------------------
# Open the database containing the malloc data. The user specifies the
# database to use by passing the file-name on the command line.
#
proc open_database {} {
if {[info exists ::BUILTIN]} {
sqlite3 mddb :memory:
mddb eval $::BUILTIN
wm title . $::argv0
} else {
set zFilename [lindex $::argv 0]
if {$zFilename eq ""} {
set zFilename mallocs.sql
}
set fd [open $zFilename]
set zHdr [read $fd 15]
if {$zHdr eq "SQLite format 3"} {
close $fd
sqlite3 mddb $zFilename
} else {
seek $fd 0
sqlite3 mddb :memory:
mddb eval [read $fd]
close $fd
}
wm title . $zFilename
}
mddb function lrange -argcount 3 lrange
mddb function llength -argcount 1 llength
mddb function trim_frames -argcount 1 trim_frames
mddb eval {
SELECT frame FROM frame
WHERE line LIKE '%malloc.c:%' OR line LIKE '%mem2.c:%'
} {
set ::O(ignore.$frame) 1
}
}
open_database
bind $O(tree) <<TreeviewSelect>> [list populate_text_widget mddb]
populate_tree_widget mddb [mddb one {SELECT zTest FROM malloc LIMIT 1}]
-289
View File
@@ -72,293 +72,4 @@ foreach {tnum sql norm} {
do_test $tnum [list sqlite3_normalize $sql] $norm
}
ifcapable normalize {
do_test 200 {
execsql {
CREATE TABLE t1(a,b);
}
} {}
do_test 201 {
set STMT [sqlite3_prepare_v3 $DB \
"SELECT a, b FROM t1 WHERE b = ? ORDER BY a;" -1 0 TAIL]
sqlite3_bind_null $STMT 1
} {}
do_test 202 {
sqlite3_normalized_sql $STMT
} {}
do_test 203 {
sqlite3_finalize $STMT
} {SQLITE_OK}
do_test 210 {
set STMT [sqlite3_prepare_v3 $DB \
"SELECT a, b FROM t1 WHERE b = ? ORDER BY a;" -1 2 TAIL]
sqlite3_bind_null $STMT 1
} {}
do_test 211 {
sqlite3_normalized_sql $STMT
} {SELECT a,b FROM t1 WHERE b=?ORDER BY a;}
do_test 212 {
sqlite3_finalize $STMT
} {SQLITE_OK}
do_test 220 {
set STMT [sqlite3_prepare_v3 $DB \
"SELECT a, b FROM t1 WHERE b = 'a' ORDER BY a;" -1 2 TAIL]
} {/^[0-9A-Fa-f]+$/}
do_test 221 {
sqlite3_normalized_sql $STMT
} {SELECT a,b FROM t1 WHERE b=?ORDER BY a;}
do_test 222 {
sqlite3_finalize $STMT
} {SQLITE_OK}
do_test 297 {
execsql {
DROP TABLE t1;
}
} {}
do_test 298 {
execsql {
CREATE TABLE t1(a,b,c,d,e,"col f",w,x,y,z);
CREATE TABLE t2(x,"col y");
}
} {}
do_test 299 {
sqlite3_create_function db
} {SQLITE_OK}
foreach {tnum sql flags norm} {
300
{SELECT * FROM t1 WHERE a IN (1) AND b=51.42}
0x2
{0 {SELECT*FROM t1 WHERE a IN(?,?,?)AND b=?;}}
310
{SELECT a, b+15, c FROM t1 WHERE d NOT IN (SELECT x FROM t2);}
0x2
{0 {SELECT a,b+?,c FROM t1 WHERE d NOT IN(SELECT x FROM t2);}}
320
{ SELECT NULL, b FROM t1 -- comment text
WHERE d IN (WITH t(a) AS (VALUES(5)) /* CTE */
SELECT a FROM t)
OR e='hello';
}
0x2
{0 {SELECT?,b FROM t1 WHERE d IN(WITH t(a)AS(VALUES(?))SELECT a FROM t)OR e=?;}}
321
{/*Initial comment*/
-- another comment line
SELECT NULL /* comment */ , b FROM t1 -- comment text
WHERE d IN (WITH t(a) AS (VALUES(5)) /* CTE */
SELECT a FROM t)
OR e='hello';
}
0x2
{0 {SELECT?,b FROM t1 WHERE d IN(WITH t(a)AS(VALUES(?))SELECT a FROM t)OR e=?;}}
330
{/* Query containing parameters */
SELECT x,$::abc(15),y,@abc,z,?99,w FROM t1 /* Trailing comment */}
0x2
{0 {SELECT x,?,y,?,z,?,w FROM t1;}}
340
{/* Long list on the RHS of IN */
SELECT 15 IN (1,2,3,(SELECT * FROM t1),'xyz',x'abcd',22*(x+5),null);}
0x2
{1 {(1) no such column: x}}
350
{SELECT x'abc'; -- illegal token}
0x2
{1 {(1) unrecognized token: "x'abc'"}}
360
{SELECT a,NULL,b FROM t1 WHERE c IS NOT NULL or D is null or e=5}
0x2
{0 {SELECT a,?,b FROM t1 WHERE c IS NOT NULL OR d IS NULL OR e=?;}}
370
{/* IN list exactly 5 bytes long */
SELECT * FROM t1 WHERE x IN (1,2,3);}
0x2
{0 {SELECT*FROM t1 WHERE x IN(?,?,?);}}
400
{SELECT a FROM t1 WHERE x IN (1,2,3) AND sqlite_version();}
0x2
{0 {SELECT a FROM t1 WHERE x IN(?,?,?)AND sqlite_version();}}
410
{SELECT a FROM t1 WHERE x IN (1,2,3) AND hex8();}
0x2
{1 {(1) wrong number of arguments to function hex8()}}
420
{SELECT a FROM t1 WHERE x IN (1,2,3) AND hex8('abc');}
0x2
{0 {SELECT a FROM t1 WHERE x IN(?,?,?)AND hex8(?);}}
430
{SELECT "a" FROM t1 WHERE "x" IN ("1","2",'3');}
0x2
{0 {SELECT"a"FROM t1 WHERE"x"IN(?,?,?);}}
440
{SELECT 'a' FROM t1 WHERE 'x';}
0x2
{0 {SELECT?FROM t1 WHERE?;}}
450
{SELECT [a] FROM t1 WHERE [x];}
0x2
{0 {SELECT"a"FROM t1 WHERE"x";}}
460
{SELECT * FROM t1 WHERE x IN (x);}
0x2
{0 {SELECT*FROM t1 WHERE x IN(x);}}
470
{SELECT * FROM t1 WHERE x IN (x,a);}
0x2
{0 {SELECT*FROM t1 WHERE x IN(x,a);}}
480
{SELECT * FROM t1 WHERE x IN ([x],"a");}
0x2
{0 {SELECT*FROM t1 WHERE x IN("x","a");}}
500
{SELECT * FROM t1 WHERE x IN ([x],"a",'b',sqlite_version());}
0x2
{0 {SELECT*FROM t1 WHERE x IN("x","a",?,sqlite_version());}}
520
{SELECT * FROM t1 WHERE x IN (SELECT x FROM t1);}
0x2
{0 {SELECT*FROM t1 WHERE x IN(SELECT x FROM t1);}}
540
{SELECT * FROM t1 WHERE x IN ((SELECT x FROM t1));}
0x2
{0 {SELECT*FROM t1 WHERE x IN(?,?,?);}}
550
{SELECT a, a+1, a||'b', a+"b" FROM t1;}
0x2
{0 {SELECT a,a+?,a||?,a+"b"FROM t1;}}
570
{SELECT * FROM t1 WHERE x IN (1);}
0x2
{0 {SELECT*FROM t1 WHERE x IN(?,?,?);}}
580
{SELECT * FROM t1 WHERE x IN (1,2);}
0x2
{0 {SELECT*FROM t1 WHERE x IN(?,?,?);}}
590
{SELECT * FROM t1 WHERE x IN (1,2,3);}
0x2
{0 {SELECT*FROM t1 WHERE x IN(?,?,?);}}
600
{SELECT * FROM t1 WHERE x IN (1,2,3,4);}
0x2
{0 {SELECT*FROM t1 WHERE x IN(?,?,?);}}
610
{SELECT * FROM t1 WHERE x IN (SELECT x FROM t1);}
0x2
{0 {SELECT*FROM t1 WHERE x IN(SELECT x FROM t1);}}
620
{SELECT * FROM t1 WHERE x IN (SELECT x FROM t1 WHERE x IN (1,2,3));}
0x2
{0 {SELECT*FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(?,?,?));}}
630
{SELECT * FROM t1 WHERE x IN (SELECT x FROM t1 WHERE x IN (x));}
0x2
{0 {SELECT*FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(x));}}
640
{SELECT x FROM t1 WHERE x IN (SELECT x FROM t1 WHERE x IN (
SELECT x FROM t1 WHERE x IN (SELECT x FROM t1 WHERE x IN (
SELECT x FROM t1 WHERE x IN (x)))));}
0x2
{0 {SELECT x FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(x)))));}}
650
{SELECT x FROM t1 WHERE x IN (SELECT x FROM t1 WHERE x IN (
SELECT x FROM t1 WHERE x IN (SELECT x FROM t1 WHERE x IN (
SELECT x FROM t1 WHERE x IN (1)))));}
0x2
{0 {SELECT x FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(SELECT x FROM t1 WHERE x IN(?,?,?)))));}}
660
{SELECT x FROM t1 WHERE x IN (1) UNION ALL SELECT x FROM t1 WHERE x IN (1);}
0x2
{0 {SELECT x FROM t1 WHERE x IN(?,?,?)UNION ALL SELECT x FROM t1 WHERE x IN(?,?,?);}}
670
{SELECT "col f", [col f] FROM t1;}
0x2
{0 {SELECT"col f","col f"FROM t1;}}
680
{SELECT a, "col f" FROM t1 LEFT OUTER JOIN t2 ON [t1].[col f] == [t2].[col y];}
0x2
{0 {SELECT a,"col f"FROM t1 LEFT OUTER JOIN t2 ON"t1"."col f"=="t2"."col y";}}
690
{SELECT * FROM ( WITH x AS ( SELECT * FROM t1 WHERE x IN ( 1)) SELECT 10);}
0x2
{0 {SELECT*FROM(WITH x AS(SELECT*FROM t1 WHERE x IN(?,?,?))SELECT?);}}
700
{SELECT rowid, oid, _rowid_ FROM t1;}
0x2
{0 {SELECT rowid,oid,_rowid_ FROM t1;}}
710
{SELECT x FROM t1 WHERE x IS NULL;}
0x2
{0 {SELECT x FROM t1 WHERE x IS NULL;}}
740
{SELECT x FROM t1 WHERE x IS NOT NULL;}
0x2
{0 {SELECT x FROM t1 WHERE x IS NOT NULL;}}
750
{SELECT x FROM t1 WHERE x = NULL;}
0x2
{0 {SELECT x FROM t1 WHERE x=?;}}
760
{SELECT x FROM t1 WHERE x IN ([x] IS NOT NULL, NULL, 1, 'a', "b", x'00');}
0x2
{0 {SELECT x FROM t1 WHERE x IN("x"IS NOT NULL,?,?,?,"b",?);}}
} {
do_test $tnum {
set code [catch {
set STMT [sqlite3_prepare_v3 $DB $sql -1 $flags TAIL]
sqlite3_normalized_sql $STMT
} res]
if {[info exists STMT]} {
sqlite3_finalize $STMT; unset STMT
}
list $code $res
} $norm
}
}
finish_test
+63 -64
View File
@@ -255,7 +255,6 @@ test_suite "fts3" -prefix "" -description {
fts3am.test fts3an.test fts3ao.test fts3atoken.test
fts3auto.test fts3aux1.test fts3aux2.test fts3b.test
fts3comp1.test fts3conf.test fts3corrupt2.test fts3corrupt.test
fts3corrupt4.test
fts3cov.test fts3c.test fts3defer2.test fts3defer3.test
fts3defer.test fts3drop.test fts3d.test fts3e.test
fts3expr2.test fts3expr3.test fts3expr4.test fts3expr5.test
@@ -290,6 +289,12 @@ test_suite "window" -prefix "" -description {
test_set [glob -nocomplain $::testdir/window*.test]
]
test_suite "alter" -prefix "" -description {
All ALTER function related tests .
} -files [
test_set [glob -nocomplain $::testdir/alter*.test]
]
test_suite "lsm1" -prefix "" -description {
All LSM1 tests.
} -files [glob -nocomplain $::testdir/../ext/lsm1/test/*.test]
@@ -555,12 +560,21 @@ test_suite "singlethread" -description {
test_suite "nomutex" -description {
Tests run with the SQLITE_OPEN_MULTITHREADED flag passed to sqlite3_open().
} -initialize {
set ::G(perm:sqlite3_args) [list -fullmutex 0 -nomutex 1]
rename sqlite3 sqlite3_nomutex
proc sqlite3 {args} {
if {[string range [lindex $args 0] 0 0] ne "-"} {
lappend args -fullmutex 0 -nomutex 1
}
uplevel [concat sqlite3_nomutex $args]
}
} -files {
delete.test delete2.test insert.test rollback.test select1.test
select2.test trans.test update.test vacuum.test types.test
types2.test types3.test
}
} -shutdown {
rename sqlite3 {}
rename sqlite3_nomutex sqlite3
}
# Run some tests in SQLITE_CONFIG_MULTITHREAD mode.
#
@@ -589,11 +603,20 @@ test_suite "multithread" -description {
test_suite "fullmutex" -description {
Tests run in SQLITE_OPEN_FULLMUTEX mode
} -initialize {
set ::G(perm:sqlite3_args) [list -nomutex 0 -fullmutex 1]
rename sqlite3 sqlite3_fullmutex
proc sqlite3 {args} {
if {[string range [lindex $args 0] 0 0] ne "-"} {
lappend args -nomutex 0 -fullmutex 1
}
uplevel [concat sqlite3_fullmutex $args]
}
} -files {
delete.test delete2.test insert.test rollback.test select1.test
select2.test trans.test update.test vacuum.test types.test
types2.test types3.test
} -shutdown {
rename sqlite3 {}
rename sqlite3_fullmutex sqlite3
}
# Run some tests using the "onefile" demo.
@@ -601,10 +624,19 @@ test_suite "fullmutex" -description {
test_suite "onefile" -description {
Run some tests using the "test_onefile.c" demo
} -initialize {
set ::G(perm:sqlite3_args) [list -vfs fs]
rename sqlite3 sqlite3_onefile
proc sqlite3 {args} {
if {[string range [lindex $args 0] 0 0] ne "-"} {
lappend args -vfs fs
}
uplevel [concat sqlite3_onefile $args]
}
} -files {
conflict.test insert.test insert2.test insert3.test
rollback.test select1.test select2.test select3.test
} -shutdown {
rename sqlite3 {}
rename sqlite3_onefile sqlite3
}
# Run some tests using UTF-16 databases.
@@ -906,8 +938,17 @@ ifcapable threadsafe {
test_suite "safe_append" -description {
Run some tests on a SAFE_APPEND file-system.
} -initialize {
set ::G(perm:sqlite3_args) [list -vfs devsym]
rename sqlite3 sqlite3_safeappend
proc sqlite3 {args} {
if {[string range [lindex $args 0] 0 0] ne "-"} {
lappend args -vfs devsym
}
uplevel [concat sqlite3_safeappend $args]
}
sqlite3_simulate_device -char safe_append
} -shutdown {
rename sqlite3 {}
rename sqlite3_shutdown sqlite3
} -files [
test_set $::allquicktests shared_err.test -exclude async3.test
]
@@ -1074,38 +1115,30 @@ test_suite "sorterref" -prefix "" -description {
# -description TITLE
# -initialize SCRIPT
# -shutdown SCRIPT
# -presql SQL
# -files LIST-OF-FILES
# -prefix NAME
# -dbconfig SCRIPT
#
proc run_tests {name args} {
set options(-initialize) ""
set options(-shutdown) ""
set options(-prefix) ""
set options(-dbconfig) ""
set options(-presql) ""
array set options $args
set ::G(perm:name) $name
set ::G(perm:prefix) $options(-prefix)
set ::G(perm:presql) $options(-presql)
set ::G(isquick) 1
set ::G(perm:dbconfig) $options(-dbconfig)
set ::G(perm:presql) $options(-presql)
foreach file [lsort $options(-files)] {
uplevel $options(-initialize)
if {[file tail $file] == $file} { set file [file join $::testdir $file] }
slave_test_file $file
uplevel $options(-shutdown)
unset -nocomplain ::G(perm:sqlite3_args)
}
unset ::G(perm:name)
unset ::G(perm:prefix)
unset ::G(perm:dbconfig)
unset ::G(perm:presql)
unset ::G(perm:dbconfig)
}
proc run_test_suite {name} {
@@ -1119,29 +1152,19 @@ proc help {} {
puts "Usage: $::argv0 TESTSUITE ?TESTFILE?"
puts ""
puts "Available test-suites are:"
set iPos 0
foreach k $::testsuitelist {
if {[info exists ::testspec($k)]} {
switch $iPos {
0 {
puts ""
puts -nonewline " [format %-30s $k]"
}
1 {
puts -nonewline [format %-30s $k]
}
2 {
puts -nonewline $k
}
}
set iPos [expr (($iPos+1) % 3)]
if {[info exists ::testspec($k)]==0} {
puts " ----------------------------------------"
puts ""
} else {
array set o $::testspec($k)
puts "Test suite: \"$k\""
set d [string trim $o(-description)]
set d [regsub {\n *} $d "\n "]
puts " $d"
puts ""
}
}
puts ""
exit -1
}
@@ -1150,35 +1173,11 @@ if {[file tail $argv0] == "permutations.test"} {
if {[llength $argv]==0} {
help
} else {
# See if the first argument is a named test-suite.
#
set suite [file tail [lindex $argv 0]]
if {[info exists ::testspec($suite)]} {
set S $::testspec($suite)
set i 1
} else {
set S [list]
set i 0
}
if {[info exists ::testspec($suite)]==0} help
set extra ""
if {$i < [llength $argv] && [string range [lindex $argv $i] 0 0]!="-" } {
set files [list]
for {} {$i < [llength $argv]} {incr i} {
set pattern [string map {% *} [lindex $argv $i]]
if {[string range $pattern 0 0]=="-"} break
foreach f $::alltests {
set tail [file tail $f]
if {[lsearch $files $f]<0 && [string match $pattern $tail]} {
lappend files $f
}
}
}
set extra [list -files $files]
}
eval run_tests $suite $S $extra
if {[llength $argv]>1} { set extra [list -files [lrange $argv 1 end]] }
eval run_tests $suite $::testspec($suite) $extra
}
}
main $argv
+1 -5
View File
@@ -15,11 +15,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
if {[sqlite3 -has-codec]} {
finish_test
return
}
do_not_use_codec
do_execsql_test pragma3-100 {
PRAGMA data_version;
+19 -17
View File
@@ -3757,23 +3757,25 @@ do_test printf-15.3 {
# Now test malloc() failure within a sqlite3_mprintf():
#
foreach var {a b c d} {
set $var [string repeat $var 400]
}
set str1 "[string repeat A 360]%d%d%s"
set str2 [string repeat B 5000]
set zSuccess "[string repeat A 360]11[string repeat B 5000]"
foreach ::iRepeat {0 1} {
set nTestNum 1
while {1} {
sqlite3_memdebug_fail $nTestNum -repeat $::iRepeat
set z [sqlite3_mprintf_str $str1 1 1 $str2]
set nFail [sqlite3_memdebug_fail -1 -benign nBenign]
do_test printf-malloc-$::iRepeat.$nTestNum {
expr {($nFail>0 && $z eq "") || ($nFail==$nBenign && $z eq $zSuccess)}
} {1}
if {$nFail == 0} break
incr nTestNum
ifcapable memdebug {
foreach var {a b c d} {
set $var [string repeat $var 400]
}
set str1 "[string repeat A 360]%d%d%s"
set str2 [string repeat B 5000]
set zSuccess "[string repeat A 360]11[string repeat B 5000]"
foreach ::iRepeat {0 1} {
set nTestNum 1
while {1} {
sqlite3_memdebug_fail $nTestNum -repeat $::iRepeat
set z [sqlite3_mprintf_str $str1 1 1 $str2]
set nFail [sqlite3_memdebug_fail -1 -benign nBenign]
do_test printf-malloc-$::iRepeat.$nTestNum {
expr {($nFail>0 && $z eq "") || ($nFail==$nBenign && $z eq $zSuccess)}
} {1}
if {$nFail == 0} break
incr nTestNum
}
}
}

Some files were not shown because too many files have changed in this diff Show More