Compare commits

..

5 Commits

Author SHA1 Message Date
drh 425ab50c8f Change more OP_OpenEphemeral operations to OP_OpenHash.
FossilOrigin-Name: 881164cf6e5c987ae0e40804267715d878135198
2014-02-06 14:59:47 +00:00
drh 5eba9b73da Use OpenHash instead of OpenEphemeral for the RHS of IN operators if the
result is not needed for sorting.

FossilOrigin-Name: 715fac7749a6b1523fe9f7de8263f0c4d1571d07
2014-02-06 03:31:41 +00:00
drh 34c5ed29e8 Separate out the code generators for the RHS of an IN operator and for
SELECT/EXISTS expressions.

FossilOrigin-Name: 61c34ba71b733b81312078d90c1e21a8cbad669a
2014-02-05 19:10:06 +00:00
drh e255f2d2ce Use a new opcode, OP_OpenHash, to indicate that ephemeral tables can be
unordered, rather than using the BTREE_UNORDERED bit in the P5 field.

FossilOrigin-Name: 2997e181575da7e37fe70d20bdddf934f064ae1d
2014-02-05 18:15:38 +00:00
drh c3caa4f091 Make the root page of an ephemeral index be page 1 instead of page 2.
FossilOrigin-Name: a332908b70afa4e77e60b30a3b96d8a8504363a2
2014-02-05 17:08:07 +00:00
133 changed files with 3375 additions and 9121 deletions
+1 -5
View File
@@ -177,7 +177,7 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
random.lo resolve.lo rowset.lo rtree.lo select.lo status.lo \
table.lo threads.lo tokenize.lo trigger.lo \
table.lo tokenize.lo trigger.lo \
update.lo util.lo vacuum.lo \
vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
vdbetrace.lo wal.lo walker.lo where.lo utf.lo vtab.lo
@@ -261,7 +261,6 @@ SRC = \
$(TOP)/src/sqliteInt.h \
$(TOP)/src/sqliteLimit.h \
$(TOP)/src/table.c \
$(TOP)/src/threads.c \
$(TOP)/src/tclsqlite.c \
$(TOP)/src/tokenize.c \
$(TOP)/src/trigger.c \
@@ -733,9 +732,6 @@ status.lo: $(TOP)/src/status.c $(HDR)
table.lo: $(TOP)/src/table.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/table.c
threads.lo: $(TOP)/src/threads.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/threads.c
tokenize.lo: $(TOP)/src/tokenize.c keywordhash.h $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/tokenize.c
+3 -18
View File
@@ -214,7 +214,7 @@ NLTLIBPATHS = "/LIBPATH:$(NCRTLIBPATH)" "/LIBPATH:$(NSDKLIBPATH)"
# will run on the target platform. (BCC and TCC are usually the
# same unless your are cross-compiling.)
#
TCC = $(CC) -W3 -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src -fp:precise
TCC = $(CC) -W3 -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src -fp:precise
RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src
# Check if assembly code listings should be generated for the source
@@ -564,7 +564,7 @@ LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
pager.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
random.lo resolve.lo rowset.lo rtree.lo select.lo status.lo \
table.lo threads.o tokenize.lo trigger.lo \
table.lo tokenize.lo trigger.lo \
update.lo util.lo vacuum.lo \
vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
vdbetrace.lo wal.lo walker.lo where.lo utf.lo vtab.lo
@@ -659,7 +659,6 @@ SRC = \
$(TOP)\src\sqliteInt.h \
$(TOP)\src\sqliteLimit.h \
$(TOP)\src\table.c \
$(TOP)\src\threads.c \
$(TOP)\src\tclsqlite.c \
$(TOP)\src\tokenize.c \
$(TOP)\src\trigger.c \
@@ -1140,9 +1139,6 @@ status.lo: $(TOP)\src\status.c $(HDR)
table.lo: $(TOP)\src\table.c $(HDR)
$(LTCOMPILE) -c $(TOP)\src\table.c
threads.lo: $(TOP)\src\threads.c $(HDR)
$(LTCOMPILE) -c $(TOP)\src\threads.c
tokenize.lo: $(TOP)\src\tokenize.c keywordhash.h $(HDR)
$(LTCOMPILE) -c $(TOP)\src\tokenize.c
@@ -1223,7 +1219,7 @@ parse.c: $(TOP)\src\parse.y lemon.exe $(TOP)\addopcodes.awk
$(NAWK) -f $(TOP)\addopcodes.awk parse.h.temp > parse.h
sqlite3.h: $(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION
$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > sqlite3.h
$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP) > sqlite3.h
mkkeywordhash.exe: $(TOP)\tool\mkkeywordhash.c
$(BCC) -Fe$@ $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)\tool\mkkeywordhash.c /link $(NLTLIBPATHS)
@@ -1323,9 +1319,6 @@ testfixture.exe: $(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR)
$(TESTFIXTURE_SRC) \
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
extensiontest: testfixture.exe testloadext.dll
.\testfixture.exe $(TOP)\test\loadext.test
fulltest: testfixture.exe sqlite3.exe
.\testfixture.exe $(TOP)\test\all.test
@@ -1352,12 +1345,6 @@ sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS)
$(LTLINK) -DBUILD_sqlite -DTCLSH=2 -I$(TCLINCDIR) sqlite3_analyzer.c \
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
testloadext.lo: $(TOP)\src\test_loadext.c
$(LTCOMPILE) -c $(TOP)\src\test_loadext.c
testloadext.dll: testloadext.lo
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo
showdb.exe: $(TOP)\tool\showdb.c $(SQLITE3C)
$(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\tool\showdb.c $(SQLITE3C)
@@ -1376,7 +1363,6 @@ clean:
del /Q sqlite3.h opcodes.c opcodes.h
del /Q lemon.exe lempar.c parse.*
del /Q mkkeywordhash.exe keywordhash.h
del /Q notasharedlib.*
-rmdir /Q/S .deps
-rmdir /Q/S .libs
-rmdir /Q/S quota2a
@@ -1385,7 +1371,6 @@ clean:
-rmdir /Q/S tsrc
del /Q .target_source
del /Q tclsqlite3.exe tclsqlite3.exp
del /Q testloadext.dll testloadext.exp
del /Q testfixture.exe testfixture.exp test.db
del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
del /Q sqlite3.c sqlite3-*.c
+39
View File
@@ -0,0 +1,39 @@
This directory contains source code to
SQLite: An Embeddable SQL Database Engine
To compile the project, first create a directory in which to place
the build products. It is recommended, but not required, that the
build directory be separate from the source directory. Cd into the
build directory and then from the build directory run the configure
script found at the root of the source tree. Then run "make".
For example:
tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite"
mkdir bld ;# Build will occur in a sibling directory
cd bld ;# Change to the build directory
../sqlite/configure ;# Run the configure script
make ;# Run the makefile.
make install ;# (Optional) Install the build products
The configure script uses autoconf 2.61 and libtool. If the configure
script does not work out for you, there is a generic makefile named
"Makefile.linux-gcc" in the top directory of the source tree that you
can copy and edit to suit your needs. Comments on the generic makefile
show what changes are needed.
The linux binaries on the website are created using the generic makefile,
not the configure script. The windows binaries on the website are created
using MinGW32 configured as a cross-compiler running under Linux. For
details, see the ./publish.sh script at the top-level of the source tree.
The developers do not use teh configure script.
SQLite does not require TCL to run, but a TCL installation is required
by the makefiles. SQLite contains a lot of generated code and TCL is
used to do much of that code generation. The makefile also requires
AWK.
Contacts:
http://www.sqlite.org/
-215
View File
@@ -1,215 +0,0 @@
<h1 align="center">SQLite Source Repository</h1>
This repository contains the complete source code for the SQLite database
engine. Some test scripts are also include. However, many other test scripts
and most of the documentation are managed separately.
## Compiling
First create a directory in which to place
the build products. It is recommended, but not required, that the
build directory be separate from the source directory. Cd into the
build directory and then from the build directory run the configure
script found at the root of the source tree. Then run "make".
For example:
tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite"
mkdir bld ;# Build will occur in a sibling directory
cd bld ;# Change to the build directory
../sqlite/configure ;# Run the configure script
make ;# Run the makefile.
make sqlite3.c ;# Build the "amalgamation" source file
make test ;# Run some tests (requires Tcl)
See the makefile for additional targets.
The configure script uses autoconf 2.61 and libtool. If the configure
script does not work out for you, there is a generic makefile named
"Makefile.linux-gcc" in the top directory of the source tree that you
can copy and edit to suit your needs. Comments on the generic makefile
show what changes are needed.
## Using MSVC
On Windows, all applicable build products can be compiled with MSVC.
First open the command prompt window associated with the desired compiler
version (e.g. "Developer Command Prompt for VS2013"). Next, use NMAKE
with the provided "Makefile.msc" to build one of the supported targets.
For example:
mkdir bld
cd bld
nmake /f Makefile.msc TOP=..\sqlite
nmake /f Makefile.msc sqlite3.c TOP=..\sqlite
nmake /f Makefile.msc sqlite3.dll TOP=..\sqlite
nmake /f Makefile.msc sqlite3.exe TOP=..\sqlite
nmake /f Makefile.msc test TOP=..\sqlite
There are several build options that can be set via the NMAKE command
line. For example, to build for WinRT, simply add "FOR_WINRT=1" argument
to the "sqlite3.dll" command line above. When debugging into the SQLite
code, adding the "DEBUG=1" argument to one of the above command lines is
recommended.
SQLite does not require Tcl to run, but a Tcl installation is required
by the makefiles (including those for MSVC). SQLite contains a lot of
generated code and Tcl is used to do much of that code generation. The
makefiles also require AWK.
## Source Code Tour
Most of the core source files are in the **src/** subdirectory. But
src/ also contains files used to build the "testfixture" test harness;
those file all begin with "test". And src/ contains the "shell.c" file
which is the main program for the "sqlite3.exe" command-line shell and
the "tclsqlite.c" file which implements the bindings to SQLite from the
Tcl programming language. (Historical note: SQLite began as a Tcl
extension and only later escaped to the wild as an independent library.)
Test scripts and programs are found in the **test/** subdirectory.
There are other test suites for SQLite (see
[How SQLite Is Tested](http://www.sqlite.org/testing.html))
but those other test suites are
in separate source repositories.
The **ext/** subdirectory contains code for extensions. The
Full-text search engine is in **ext/fts3**. The R-Tree engine is in
**ext/rtree**. The **ext/misc** subdirectory contains a number of
smaller, single-file extensions, such as a REGEXP operator.
The **tool/** subdirectory contains various scripts and programs used
for building generated source code files or for testing or for generating
accessory programs such as "sqlite3_analyzer(.exe)".
### Generated Source Code Files
Several of the C-language source files used by SQLite are generated from
other sources rather than being typed in manually by a programmer. This
section will summarize those automatically-generated files. To create all
of the automatically-generated files, simply run "make target&#95;source".
The "target&#95;source" make target will create a subdirectory "tsrc/" and
fill it with all the source files needed to build SQLite, both
manually-edited files and automatically-generated files.
The SQLite interface is defined by the **sqlite3.h** header file, which is
generated from src/sqlite.h.in, ./manifest.uuid, and ./VERSION. The
Tcl script at tool/mksqlite3h.tcl does the conversion. The manifest.uuid
file contains the SHA1 hash of the particular check-in and is used to generate
the SQLITE_SOURCE_ID macro. The VERSION file contains the current SQLite
version number. The sqlite3.h header is really just a copy of src/sqlite.h.in
with the source-id and version number inserted at just the right spots.
Note that comment text in the sqlite3.h file is used to generate much of
the SQLite API documentation. The Tcl scripts used to generate that
documentation are in a separate source repository.
The SQL language parser is **parse.c** which is generate from a grammar in
the src/parse.y file. The conversion of "parse.y" into "parse.c" is done
by the [lemon](./doc/lemon.html) LALR(1) parser generator. The source code
for lemon is at tool/lemon.c. Lemon uses a
template for generating its parser. A generic template is in tool/lempar.c,
but SQLite uses a slightly modified template found in src/lempar.c.
Lemon also generates the **parse.h** header file, at the same time it
generates parse.c. But the parse.h header file is
modified further (to add additional symbols) using the ./addopcodes.awk
AWK script.
The **opcodes.h** header file contains macros that define the numbers
corresponding to opcodes in the "VDBE" virtual machine. The opcodes.h
file is generated by the scanning the src/vdbe.c source file. The
AWK script at ./mkopcodeh.awk does this scan and generates opcodes.h.
A second AWK script, ./mkopcodec.awk, then scans opcodes.h to generate
the **opcodes.c** source file, which contains a reverse mapping from
opcode-number to opcode-name that is used for EXPLAIN output.
The **keywordhash.h** header file contains the definition of a hash table
that maps SQL language keywords (ex: "CREATE", "SELECT", "INDEX", etc.) into
the numeric codes used by the parse.c parser. The keywordhash.h file is
generated by a C-language program at tool mkkeywordhash.c.
### The Amalgamation
All of the individual C source code and header files (both manually-edited
and automatically-generated) can be combined into a single big source file
**sqlite3.c** called "the amalgamation". The amalgamation is the recommended
way of using SQLite in a larger application. Combining all individual
source code files into a single big source code file allows the C compiler
to perform more cross-procedure analysis and generate better code. SQLite
runs about 5% faster when compiled from the amalgamation versus when compiled
from individual source files.
The amalgamation is generated from the tool/mksqlite3c.tcl Tcl script.
First, all of the individual source files must be gathered into the tsrc/
subdirectory (using the equivalent of "make target_source") then the
tool/mksqlite3c.tcl script is run to copy them all together in just the
right order while resolving internal "#include" references.
The amalgamation source file is more than 100K lines long. Some symbolic
debuggers (most notably MSVC) are unable to deal with files longer than 64K
lines. To work around this, a separate Tcl script, tool/split-sqlite3c.tcl,
can be run on the amalgamation to break it up into a single small C file
called **sqlite3-all.c** that does #include on about five other files
named **sqlite3-1.c**, **sqlite3-2.c**, ..., **sqlite3-5.c**. In this way,
all of the source code is contained within a single translation unit so
that the compiler can do extra cross-procedure optimization, but no
individual source file exceeds 32K lines in length.
## How It All Fits Together
SQLite is modular in design.
See the [architectural description](http://www.sqlite.org/arch.html)
for details. Other documents that are useful in
(helping to understand how SQLite works include the
[file format](http://www.sqlite.org/fileformat2.html) description,
the [virtual machine](http://www.sqlite.org/vdbe.html) that runs
prepared statements, the description of
[how transactions work](http://www.sqlite.org/atomiccommit.html), and
the [overview of the query planner](http://www.sqlite.org/optoverview.html).
Unfortunately, years of effort have gone into optimizating SQLite, both
for small size and high performance. And optimizations tend to result in
complex code. So there is a lot of complexity in the SQLite implementation.
Key files:
* **sqlite3.h** - This file defines the public interface to the SQLite
library. Readers will need to be familiar with this interface before
trying to understand how the library works internally.
* **sqliteInt.h** - this header file defines many of the data objects
used internally by SQLite.
* **parse.y** - This file describes the LALR(1) grammer that SQLite uses
to parse SQL statements, and the actions that are taken at each stop
in the parsing process.
* **vdbe.c** - This file implements the virtual machine that runs
prepared statements. There are various helper files whose names
begin with "vdbe". The VDBE has access to the vdbeInt.h header file
which defines internal data objects. The rest of SQLite interacts
with the VDBE through an interface defined by vdbe.h.
* **where.c** - This file analyzes the WHERE clause and generates
virtual machine code to run queries efficiently. This file is
sometimes called the "query optimizer". It has its own private
header file, whereInt.h, that defines data objects used internally.
* **btree.c** - This file contains the implementation of the B-Tree
storage engine used by SQLite.
* **pager.c** - This file contains the "pager" implementation, the
module that implements transactions.
* **os_unix.c** and **os_win.c** - These two files implement the interface
between SQLite and the underlying operating system using the run-time
pluggable VFS interface.
## Contacts
The main SQLite webpage is [http://www.sqlite.org/](http://www.sqlite.org/)
with geographically distributed backup servers at
[http://www2.sqlite.org/](http://www2.sqlite.org) and
[http://www3.sqlite.org/](http://www3.sqlite.org).
+1 -1
View File
@@ -1 +1 @@
3.8.5
3.8.3
+91 -500
View File
@@ -1,528 +1,119 @@
#!/bin/sh
#
# install - install a program, script, or datafile
scriptversion=2011-04-20.01; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
# This comes from X11R5; it is not part of GNU.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
#
# This script is compatible with the BSD install script, but was written
# from scratch.
#
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
doit="${DOITPROG-}"
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
# put in absolute paths if you don't have them in your path; or use env. vars.
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
instcmd="$mvprog"
chmodcmd=""
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
stripcmd=
mvcmd="$mvprog"
src=""
dst=""
src=
dst=
dir_arg=
dst_arg=
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
copy_on_change=false
no_target_directory=
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
Options:
--help display this help and exit.
--version display version info and exit.
-s) stripcmd="$stripprog"
shift
continue;;
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-S $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-S) stripcmd="$stripprog $2"
shift;;
-t) dst_arg=$2
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
*) if [ x"$src" = x ]
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writeable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
src=$1
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
dst=$1
fi
trap '' 0;;
esac;;
shift
continue;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
-*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test -z "$d" && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
fi
# Make a temp file name in the proper directory.
dstdir=`dirname $dst`
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp
# and set any options; do chmod last to preserve setuid bits
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
# Now rename the file to the real destination.
$doit $rmcmd $dst
$doit $mvcmd $dsttmp $dst
exit 0
+145 -313
View File
@@ -8,6 +8,8 @@
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: tcl.m4,v 1.145 2010/08/17 00:33:40 hobbs Exp $
AC_PREREQ(2.57)
@@ -138,8 +140,6 @@ AC_DEFUN([TEA_PATH_TCLCONFIG], [
`ls -d /usr/contrib/lib 2>/dev/null` \
`ls -d /usr/lib 2>/dev/null` \
`ls -d /usr/lib64 2>/dev/null` \
`ls -d /usr/lib/tcl8.6 2>/dev/null` \
`ls -d /usr/lib/tcl8.5 2>/dev/null` \
; do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i; pwd)`"
@@ -170,7 +170,7 @@ AC_DEFUN([TEA_PATH_TCLCONFIG], [
if test x"${ac_cv_c_tclconfig}" = x ; then
TCL_BIN_DIR="# no Tcl configs found"
AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh])
AC_MSG_ERROR([Can't find Tcl configuration definitions])
else
no_tcl=
TCL_BIN_DIR="${ac_cv_c_tclconfig}"
@@ -323,7 +323,7 @@ AC_DEFUN([TEA_PATH_TKCONFIG], [
if test x"${ac_cv_c_tkconfig}" = x ; then
TK_BIN_DIR="# no Tk configs found"
AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh])
AC_MSG_ERROR([Can't find Tk configuration definitions])
else
no_tk=
TK_BIN_DIR="${ac_cv_c_tkconfig}"
@@ -344,10 +344,11 @@ AC_DEFUN([TEA_PATH_TKCONFIG], [
#
# Results:
#
# Substitutes the following vars:
# Subst the following vars:
# TCL_BIN_DIR
# TCL_SRC_DIR
# TCL_LIB_FILE
#
#------------------------------------------------------------------------
AC_DEFUN([TEA_LOAD_TCLCONFIG], [
@@ -416,26 +417,32 @@ AC_DEFUN([TEA_LOAD_TCLCONFIG], [
AC_SUBST(TCL_STUB_LIB_FLAG)
AC_SUBST(TCL_STUB_LIB_SPEC)
AC_MSG_CHECKING([platform])
hold_cc=$CC; CC="$TCL_CC"
AC_TRY_COMPILE(,[
#ifdef _WIN32
#error win32
#endif
], TEA_PLATFORM="unix",
TEA_PLATFORM="windows"
)
CC=$hold_cc
AC_MSG_RESULT($TEA_PLATFORM)
case "`uname -s`" in
*CYGWIN_*)
AC_MSG_CHECKING([for cygwin variant])
case ${TCL_EXTRA_CFLAGS} in
*-mwin32*|*-mno-cygwin*)
TEA_PLATFORM="windows"
CFLAGS="$CFLAGS -mwin32"
AC_MSG_RESULT([win32])
;;
*)
TEA_PLATFORM="unix"
AC_MSG_RESULT([unix])
;;
esac
EXEEXT=".exe"
;;
*)
;;
esac
# The BUILD_$pkg is to define the correct extern storage class
# handling when making this package
AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}, [],
[Building extension source?])
# Do this here as we have fully defined TEA_PLATFORM now
if test "${TEA_PLATFORM}" = "windows" ; then
EXEEXT=".exe"
CLEANFILES="$CLEANFILES *.lib *.dll *.pdb *.exp"
# The BUILD_$pkg is to define the correct extern storage class
# handling when making this package
AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME})
CLEANFILES="$CLEANFILES *.lib *.dll *.pdb"
fi
# TEA specific:
@@ -559,11 +566,11 @@ AC_DEFUN([TEA_LOAD_TKCONFIG], [
# only for running extension test cases. It should never be
# or generation of files (like pkgIndex.tcl) at build time.
#
# Arguments:
# Arguments
# none
#
# Results:
# Substitutes the following vars:
# Results
# Subst's the following values:
# TCLSH_PROG
#------------------------------------------------------------------------
@@ -609,11 +616,11 @@ AC_DEFUN([TEA_PROG_TCLSH], [
# only for running extension test cases. It should never be
# or generation of files (like pkgIndex.tcl) at build time.
#
# Arguments:
# Arguments
# none
#
# Results:
# Substitutes the following vars:
# Results
# Subst's the following values:
# WISH_PROG
#------------------------------------------------------------------------
@@ -724,6 +731,7 @@ AC_DEFUN([TEA_ENABLE_SHARED], [
# TCL_THREADS
# _REENTRANT
# _THREAD_SAFE
#
#------------------------------------------------------------------------
AC_DEFUN([TEA_ENABLE_THREADS], [
@@ -847,11 +855,12 @@ AC_DEFUN([TEA_ENABLE_THREADS], [
#
# Defines the following vars:
# CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true
# Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false
# Sets to $(CFLAGS_OPTIMIZE) if false
# LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true
# Sets to $(LDFLAGS_OPTIMIZE) if false
# DBGX Formerly used as debug library extension;
# always blank now.
#
#------------------------------------------------------------------------
AC_DEFUN([TEA_ENABLE_SYMBOLS], [
@@ -864,7 +873,7 @@ AC_DEFUN([TEA_ENABLE_SYMBOLS], [
[tcl_ok=$enableval], [tcl_ok=no])
DBGX=""
if test "$tcl_ok" = "no"; then
CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG"
CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}"
LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
AC_MSG_RESULT([no])
else
@@ -911,6 +920,7 @@ AC_DEFUN([TEA_ENABLE_SYMBOLS], [
#
# Defines the following vars:
# HAVE_LANGINFO Triggers use of nl_langinfo if defined.
#
#------------------------------------------------------------------------
AC_DEFUN([TEA_ENABLE_LANGINFO], [
@@ -951,6 +961,7 @@ AC_DEFUN([TEA_ENABLE_LANGINFO], [
# Defines the following var:
#
# system - System/platform/version identification code.
#
#--------------------------------------------------------------------
AC_DEFUN([TEA_CONFIG_SYSTEM], [
@@ -1019,20 +1030,21 @@ AC_DEFUN([TEA_CONFIG_SYSTEM], [
# extensions. An empty string means we don't know how
# to use shared libraries on this platform.
# LIB_SUFFIX - Specifies everything that comes after the "libfoo"
# in a static or shared library name, using the $PACKAGE_VERSION variable
# in a static or shared library name, using the $VERSION variable
# to put the version in the right place. This is used
# by platforms that need non-standard library names.
# Examples: ${PACKAGE_VERSION}.so.1.1 on NetBSD, since it needs
# to have a version after the .so, and ${PACKAGE_VERSION}.a
# Examples: ${VERSION}.so.1.1 on NetBSD, since it needs
# to have a version after the .so, and ${VERSION}.a
# on AIX, since a shared library needs to have
# a .a extension whereas shared objects for loadable
# extensions have a .so extension. Defaults to
# ${PACKAGE_VERSION}${SHLIB_SUFFIX}.
# ${VERSION}${SHLIB_SUFFIX}.
# CFLAGS_DEBUG -
# Flags used when running the compiler in debug mode
# CFLAGS_OPTIMIZE -
# Flags used when running the compiler in optimize mode
# CFLAGS - Additional CFLAGS added as necessary (usually 64-bit)
#
#--------------------------------------------------------------------
AC_DEFUN([TEA_CONFIG_CFLAGS], [
@@ -1074,7 +1086,6 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
AC_DEFINE(MODULE_SCOPE,
[extern __attribute__((__visibility__("hidden")))],
[Compiler support for module scope symbols])
AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
])
# Step 0.d: Disable -rpath support?
@@ -1123,14 +1134,15 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
TCL_LIB_VERSIONS_OK=ok
CFLAGS_DEBUG=-g
CFLAGS_OPTIMIZE=-O
AS_IF([test "$GCC" = yes], [
# TEA specific:
CFLAGS_OPTIMIZE=-O2
CFLAGS_WARNING="-Wall"
], [
CFLAGS_OPTIMIZE=-O
CFLAGS_WARNING=""
])
AC_CHECK_TOOL(AR, ar)
], [CFLAGS_WARNING=""])
dnl FIXME: Replace AC_CHECK_PROG with AC_CHECK_TOOL once cross compiling is fixed.
dnl AC_CHECK_TOOL(AR, ar)
AC_CHECK_PROG(AR, ar, ar)
STLIB_LD='${AR} cr'
LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION="1.0"])
@@ -1159,7 +1171,7 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
PATH64="${MSSDK}/Bin/Win64"
;;
esac
if test "$GCC" != "yes" -a ! -d "${PATH64}" ; then
if test ! -d "${PATH64}" ; then
AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
AC_MSG_WARN([Ensure latest Platform SDK is installed])
do64bit="no"
@@ -1276,7 +1288,7 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
else
RC="rc"
lflags="-nologo"
LINKBIN="link"
LINKBIN="link"
CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
fi
@@ -1284,43 +1296,13 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
if test "$GCC" = "yes"; then
# mingw gcc mode
AC_CHECK_TOOL(RC, windres)
RC="windres"
CFLAGS_DEBUG="-g"
CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
SHLIB_LD='${CC} -shared'
SHLIB_LD="$CC -shared"
UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
AC_CACHE_CHECK(for cross-compile version of gcc,
ac_cv_cross,
AC_TRY_COMPILE([
#ifdef _WIN32
#error cross-compiler
#endif
], [],
ac_cv_cross=yes,
ac_cv_cross=no)
)
if test "$ac_cv_cross" = "yes"; then
case "$do64bit" in
amd64|x64|yes)
CC="x86_64-w64-mingw32-gcc"
LD="x86_64-w64-mingw32-ld"
AR="x86_64-w64-mingw32-ar"
RANLIB="x86_64-w64-mingw32-ranlib"
RC="x86_64-w64-mingw32-windres"
;;
*)
CC="i686-w64-mingw32-gcc"
LD="i686-w64-mingw32-ld"
AR="i686-w64-mingw32-ar"
RANLIB="i686-w64-mingw32-ranlib"
RC="i686-w64-mingw32-windres"
;;
esac
fi
else
SHLIB_LD="${LINKBIN} -dll ${lflags}"
# link -lib only works when -lib is the first arg
@@ -1427,8 +1409,7 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
SHLIB_CFLAGS=""
SHLIB_LD='${CC} -shared'
SHLIB_SUFFIX=".dll"
EXEEXT=".exe"
do64bit_ok=yes
EXE_SUFFIX=".exe"
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
;;
@@ -1457,7 +1438,7 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
])
AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
AS_IF([test "$tcl_ok" = yes], [
LDFLAGS="$LDFLAGS -Wl,-E"
LDFLAGS="$LDFLAGS -E"
CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
LD_LIBRARY_PATH_VAR="SHLIB_PATH"
@@ -1539,7 +1520,7 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
])
])
;;
Linux*|GNU*|NetBSD-Debian)
Linux*)
SHLIB_CFLAGS="-fPIC"
SHLIB_SUFFIX=".so"
@@ -1572,6 +1553,17 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
# files in compat/*.c is being linked in.
AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
;;
GNU*)
SHLIB_CFLAGS="-fPIC"
SHLIB_SUFFIX=".so"
SHLIB_LD='${CC} -shared'
LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
;;
Lynx*)
SHLIB_CFLAGS="-fPIC"
@@ -1584,44 +1576,35 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
;;
OpenBSD-*)
arch=`arch -s`
case "$arch" in
vax)
SHLIB_SUFFIX=""
SHARED_LIB_SUFFIX=""
LDFLAGS=""
;;
*)
SHLIB_CFLAGS="-fPIC"
SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
SHLIB_SUFFIX=".so"
AS_IF([test $doRpath = yes], [
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
LDFLAGS="-Wl,-export-dynamic"
;;
esac
case "$arch" in
vax)
CFLAGS_OPTIMIZE="-O1"
;;
*)
CFLAGS_OPTIMIZE="-O2"
;;
esac
SHLIB_CFLAGS="-fPIC"
SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
SHLIB_SUFFIX=".so"
AS_IF([test $doRpath = yes], [
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
AC_EGREP_CPP(yes, [
#ifdef __ELF__
yes
#endif
], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
AS_IF([test $tcl_cv_ld_elf = yes], [
LDFLAGS=-Wl,-export-dynamic
], [LDFLAGS=""])
AS_IF([test "${TCL_THREADS}" = "1"], [
# On OpenBSD: Compile with -pthread
# Don't link with -lpthread
# OpenBSD builds and links with -pthread, never -lpthread.
LIBS=`echo $LIBS | sed s/-lpthread//`
CFLAGS="$CFLAGS -pthread"
SHLIB_CFLAGS="$SHLIB_CFLAGS -pthread"
])
# OpenBSD doesn't do version numbers with dots.
UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
TCL_LIB_VERSIONS_OK=nodots
;;
NetBSD-*)
# NetBSD has ELF and can use 'cc -shared' to build shared libs
NetBSD-*|FreeBSD-[[3-4]].*)
# FreeBSD 3.* and greater have ELF.
# NetBSD 2.* has ELF and can use 'cc -shared' to build shared libs
SHLIB_CFLAGS="-fPIC"
SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
SHLIB_SUFFIX=".so"
@@ -1635,24 +1618,32 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
CFLAGS="$CFLAGS -pthread"
LDFLAGS="$LDFLAGS -pthread"
])
case $system in
FreeBSD-3.*)
# FreeBSD-3 doesn't handle version numbers with dots.
UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
TCL_LIB_VERSIONS_OK=nodots
;;
esac
;;
FreeBSD-*)
# This configuration from FreeBSD Ports.
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared"
TCL_SHLIB_LD_EXTRAS="-Wl,-soname=\$[@]"
TCL_SHLIB_LD_EXTRAS="-soname \$[@]"
SHLIB_SUFFIX=".so"
LDFLAGS=""
AS_IF([test $doRpath = yes], [
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
AS_IF([test "${TCL_THREADS}" = "1"], [
# The -pthread needs to go in the LDFLAGS, not LIBS
LIBS=`echo $LIBS | sed s/-pthread//`
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
# Version numbers are dot-stripped by system policy.
TCL_TRIM_DOTS=`echo ${PACKAGE_VERSION} | tr -d .`
TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .`
UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1'
TCL_LIB_VERSIONS_OK=nodots
@@ -1714,7 +1705,7 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
AS_IF([test $tcl_cv_ld_single_module = yes], [
SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
])
# TEA specific: link shlib with current and compatibility version flags
# TEA specific: link shlib with current and compatiblity version flags
vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([[0-9]]\{1,5\}\)\(\(\.[[0-9]]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d`
SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}"
SHLIB_SUFFIX=".dylib"
@@ -1950,24 +1941,6 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
])
;;
UNIX_SV* | UnixWare-5*)
SHLIB_CFLAGS="-KPIC"
SHLIB_LD='${CC} -G'
SHLIB_LD_LIBS=""
SHLIB_SUFFIX=".so"
# Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
# that don't grok the -Bexport option. Test that it does.
AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
hold_ldflags=$LDFLAGS
LDFLAGS="$LDFLAGS -Wl,-Bexport"
AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
LDFLAGS=$hold_ldflags])
AS_IF([test $tcl_cv_ld_Bexport = yes], [
LDFLAGS="$LDFLAGS -Wl,-Bexport"
])
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
;;
esac
AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [
@@ -1992,7 +1965,7 @@ dnl # preprocessing tests use only CPPFLAGS.
case $system in
AIX-*) ;;
BSD/OS*) ;;
CYGWIN_*|MINGW32_*) ;;
CYGWIN_*) ;;
IRIX*) ;;
NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
Darwin-*) ;;
@@ -2004,109 +1977,15 @@ dnl # preprocessing tests use only CPPFLAGS.
AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
AC_DEFINE(MODULE_SCOPE, [extern],
[No Compiler support for module scope symbols])
AC_DEFINE(NO_VIZ)
])
AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
# TEA specific: use PACKAGE_VERSION instead of VERSION
SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'])
# TEA specific: use PACKAGE_VERSION instead of VERSION
SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'])
AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
# TEA specific: use PACKAGE_VERSION instead of VERSION
UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'])
if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
AC_CACHE_CHECK(for SEH support in compiler,
tcl_cv_seh,
AC_TRY_RUN([
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
int main(int argc, char** argv) {
int a, b = 0;
__try {
a = 666 / b;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return 0;
}
return 1;
}
],
tcl_cv_seh=yes,
tcl_cv_seh=no,
tcl_cv_seh=no)
)
if test "$tcl_cv_seh" = "no" ; then
AC_DEFINE(HAVE_NO_SEH, 1,
[Defined when mingw does not support SEH])
fi
#
# Check to see if the excpt.h include file provided contains the
# definition for EXCEPTION_DISPOSITION; if not, which is the case
# with Cygwin's version as of 2002-04-10, define it to be int,
# sufficient for getting the current code to work.
#
AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
tcl_cv_eh_disposition,
AC_TRY_COMPILE([
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# undef WIN32_LEAN_AND_MEAN
],[
EXCEPTION_DISPOSITION x;
],
tcl_cv_eh_disposition=yes,
tcl_cv_eh_disposition=no)
)
if test "$tcl_cv_eh_disposition" = "no" ; then
AC_DEFINE(EXCEPTION_DISPOSITION, int,
[Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
fi
# Check to see if winnt.h defines CHAR, SHORT, and LONG
# even if VOID has already been #defined. The win32api
# used by mingw and cygwin is known to do this.
AC_CACHE_CHECK(for winnt.h that ignores VOID define,
tcl_cv_winnt_ignore_void,
AC_TRY_COMPILE([
#define VOID void
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
], [
CHAR c;
SHORT s;
LONG l;
],
tcl_cv_winnt_ignore_void=yes,
tcl_cv_winnt_ignore_void=no)
)
if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
[Defined when cygwin/mingw ignores VOID define in winnt.h])
fi
fi
# See if the compiler supports casting to a union type.
# This is used to stop gcc from printing a compiler
# warning when initializing a union member.
AC_CACHE_CHECK(for cast to union support,
tcl_cv_cast_to_union,
AC_TRY_COMPILE([],
[
union foo { int i; double d; };
union foo f = (union foo) (int) 0;
],
tcl_cv_cast_to_union=yes,
tcl_cv_cast_to_union=no)
)
if test "$tcl_cv_cast_to_union" = "yes"; then
AC_DEFINE(HAVE_CAST_TO_UNION, 1,
[Defined when compiler supports casting to union type.])
fi
# TEA specific: use PACKAGE_VERSION instead of VERSION
UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'])
AC_SUBST(CFLAGS_DEBUG)
AC_SUBST(CFLAGS_OPTIMIZE)
@@ -2145,6 +2024,7 @@ dnl # preprocessing tests use only CPPFLAGS.
# USE_TERMIOS
# USE_TERMIO
# USE_SGTTY
#
#--------------------------------------------------------------------
AC_DEFUN([TEA_SERIAL_PORT], [
@@ -2356,6 +2236,7 @@ closedir(d);
# XINCLUDES
# XLIBSW
# PKG_LIBS (appends to)
#
#--------------------------------------------------------------------
AC_DEFUN([TEA_PATH_X], [
@@ -2369,9 +2250,9 @@ AC_DEFUN([TEA_PATH_UNIX_X], [
not_really_there=""
if test "$no_x" = ""; then
if test "$x_includes" = ""; then
AC_TRY_CPP([#include <X11/Xlib.h>], , not_really_there="yes")
AC_TRY_CPP([#include <X11/XIntrinsic.h>], , not_really_there="yes")
else
if test ! -r $x_includes/X11/Xlib.h; then
if test ! -r $x_includes/X11/Intrinsic.h; then
not_really_there="yes"
fi
fi
@@ -2379,11 +2260,11 @@ AC_DEFUN([TEA_PATH_UNIX_X], [
if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
AC_MSG_CHECKING([for X11 header files])
found_xincludes="no"
AC_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", found_xincludes="no")
AC_TRY_CPP([#include <X11/Intrinsic.h>], found_xincludes="yes", found_xincludes="no")
if test "$found_xincludes" = "no"; then
dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
for i in $dirs ; do
if test -r $i/X11/Xlib.h; then
if test -r $i/X11/Intrinsic.h; then
AC_MSG_RESULT([$i])
XINCLUDES=" -I$i"
found_xincludes="yes"
@@ -2451,6 +2332,7 @@ AC_DEFUN([TEA_PATH_UNIX_X], [
# HAVE_SYS_FILIO_H
# USE_FIONBIO
# O_NONBLOCK
#
#--------------------------------------------------------------------
AC_DEFUN([TEA_BLOCKING_STYLE], [
@@ -2485,6 +2367,7 @@ AC_DEFUN([TEA_BLOCKING_STYLE], [
# HAVE_TM_GMTOFF
# HAVE_TM_TZADJ
# HAVE_TIMEZONE_VAR
#
#--------------------------------------------------------------------
AC_DEFUN([TEA_TIME_HANDLER], [
@@ -2553,6 +2436,7 @@ AC_DEFUN([TEA_TIME_HANDLER], [
#
# Might defines some of the following vars:
# strtod (=fixstrtod)
#
#--------------------------------------------------------------------
AC_DEFUN([TEA_BUGGY_STRTOD], [
@@ -2603,7 +2487,7 @@ AC_DEFUN([TEA_BUGGY_STRTOD], [
#
# Results:
#
# Substitutes the following vars:
# Subst's the following var:
# TCL_LIBS
# MATH_LIBS
#
@@ -2612,6 +2496,7 @@ AC_DEFUN([TEA_BUGGY_STRTOD], [
#
# Might define the following vars:
# HAVE_NET_ERRNO_H
#
#--------------------------------------------------------------------
AC_DEFUN([TEA_TCL_LINK_LIBS], [
@@ -2689,6 +2574,7 @@ AC_DEFUN([TEA_TCL_LINK_LIBS], [
# _ISOC99_SOURCE
# _LARGEFILE64_SOURCE
# _LARGEFILE_SOURCE64
#
#--------------------------------------------------------------------
AC_DEFUN([TEA_TCL_EARLY_FLAG],[
@@ -2736,6 +2622,7 @@ AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
# HAVE_STRUCT_DIRENT64
# HAVE_STRUCT_STAT64
# HAVE_TYPE_OFF64_T
#
#--------------------------------------------------------------------
AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
@@ -2767,7 +2654,7 @@ AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
# Now check for auxiliary declarations
AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
AC_TRY_COMPILE([#include <sys/types.h>
#include <dirent.h>],[struct dirent64 p;],
#include <sys/dirent.h>],[struct dirent64 p;],
tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
@@ -2852,13 +2739,6 @@ TEA version not specified.])
else
AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
fi
# If the user did not set CFLAGS, set it now to keep macros
# like AC_PROG_CC and AC_TRY_COMPILE from adding "-g -O2".
if test "${CFLAGS+set}" != "set" ; then
CFLAGS=""
fi
case "`uname -s`" in
*win32*|*WIN32*|*MINGW32_*)
AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo)
@@ -2872,17 +2752,8 @@ TEA version not specified.])
;;
*)
CYGPATH=echo
# Maybe we are cross-compiling....
case ${host_alias} in
*mingw32*)
EXEEXT=".exe"
TEA_PLATFORM="windows"
;;
*)
EXEEXT=""
TEA_PLATFORM="unix"
;;
esac
EXEEXT=""
TEA_PLATFORM="unix"
;;
esac
@@ -2895,8 +2766,6 @@ TEA version not specified.])
exec_prefix=$prefix
fi
AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}])
AC_SUBST(EXEEXT)
AC_SUBST(CYGPATH)
@@ -3132,22 +3001,6 @@ AC_DEFUN([TEA_ADD_CFLAGS], [
AC_SUBST(PKG_CFLAGS)
])
#------------------------------------------------------------------------
# TEA_ADD_CLEANFILES --
#
# Specify one or more CLEANFILES.
#
# Arguments:
# one or more file names to clean target
#
# Results:
#
# Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG
#------------------------------------------------------------------------
AC_DEFUN([TEA_ADD_CLEANFILES], [
CLEANFILES="$CLEANFILES $@"
])
#------------------------------------------------------------------------
# TEA_PREFIX --
#
@@ -3202,17 +3055,16 @@ AC_DEFUN([TEA_SETUP_COMPILER_CC], [
# Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
# in this macro, they need to go into TEA_SETUP_COMPILER instead.
# If the user did not set CFLAGS, set it now to keep
# the AC_PROG_CC macro from adding "-g -O2".
if test "${CFLAGS+set}" != "set" ; then
CFLAGS=""
fi
AC_PROG_CC
AC_PROG_CPP
INSTALL="\$(SHELL) \$(srcdir)/tclconfig/install-sh -c"
AC_SUBST(INSTALL)
INSTALL_DATA="\${INSTALL} -m 644"
AC_SUBST(INSTALL_DATA)
INSTALL_PROGRAM="\${INSTALL}"
AC_SUBST(INSTALL_PROGRAM)
INSTALL_SCRIPT="\${INSTALL}"
AC_SUBST(INSTALL_SCRIPT)
AC_PROG_INSTALL
#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
@@ -3224,7 +3076,7 @@ AC_DEFUN([TEA_SETUP_COMPILER_CC], [
# Find ranlib
#--------------------------------------------------------------------
AC_CHECK_TOOL(RANLIB, ranlib)
AC_PROG_RANLIB
#--------------------------------------------------------------------
# Determines the correct binary file extension (.o, .obj, .exe etc.)
@@ -3303,26 +3155,13 @@ AC_DEFUN([TEA_SETUP_COMPILER], [
# MAKE_SHARED_LIB Makefile rule for building a shared library
# MAKE_STATIC_LIB Makefile rule for building a static library
# MAKE_STUB_LIB Makefile rule for building a stub library
# VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL
# VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE
#------------------------------------------------------------------------
AC_DEFUN([TEA_MAKE_LIB], [
if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
AC_EGREP_CPP([manifest needed], [
#if defined(_MSC_VER) && _MSC_VER >= 1400
print("manifest needed")
#endif
], [
# Could do a CHECK_PROG for mt, but should always be with MSVC8+
VC_MANIFEST_EMBED_DLL="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;2 ; fi"
VC_MANIFEST_EMBED_EXE="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;1 ; fi"
MAKE_SHARED_LIB="${MAKE_SHARED_LIB} ; ${VC_MANIFEST_EMBED_DLL}"
TEA_ADD_CLEANFILES([*.manifest])
])
MAKE_STUB_LIB="\${STLIB_LD} -nodefaultlib -out:\[$]@ \$(PKG_STUB_OBJECTS)"
MAKE_STUB_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_STUB_OBJECTS)"
else
MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)"
MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
@@ -3345,19 +3184,13 @@ print("manifest needed")
if test "${SHARED_BUILD}" = "1" ; then
# We force the unresolved linking of symbols that are really in
# the private libraries of Tcl and Tk.
SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
if test x"${TK_BIN_DIR}" != x ; then
SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
fi
SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
if test "$GCC" = "yes"; then
SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -static-libgcc"
fi
eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
else
eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
if test "$GCC" = "yes"; then
PKG_LIB_FILE=lib${PKG_LIB_FILE}
fi
fi
# Some packages build their own stubs libraries
eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
@@ -3395,8 +3228,6 @@ print("manifest needed")
AC_SUBST(MAKE_STATIC_LIB)
AC_SUBST(MAKE_STUB_LIB)
AC_SUBST(RANLIB_STUB)
AC_SUBST(VC_MANIFEST_EMBED_DLL)
AC_SUBST(VC_MANIFEST_EMBED_EXE)
])
#------------------------------------------------------------------------
@@ -3485,7 +3316,7 @@ AC_DEFUN([TEA_LIB_SPEC], [
#
# Results:
#
# Substitutes the following vars:
# Substs the following vars:
# TCL_TOP_DIR_NATIVE
# TCL_INCLUDES
#------------------------------------------------------------------------
@@ -3563,7 +3394,7 @@ AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
# Adds a --with-tclinclude switch to configure.
# Result is cached.
#
# Substitutes the following vars:
# Substs the following vars:
# TCL_INCLUDES
#------------------------------------------------------------------------
@@ -3653,7 +3484,7 @@ AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
#
# Results:
#
# Substitutes the following vars:
# Substs the following vars:
# TK_INCLUDES
#------------------------------------------------------------------------
@@ -3742,7 +3573,7 @@ AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
# Adds a --with-tkinclude switch to configure.
# Result is cached.
#
# Substitutes the following vars:
# Substs the following vars:
# TK_INCLUDES
#------------------------------------------------------------------------
@@ -3960,10 +3791,11 @@ AC_DEFUN([TEA_PATH_CONFIG], [
#
# Results:
#
# Substitutes the following vars:
# Subst the following vars:
# $1_SRC_DIR
# $1_LIB_FILE
# $1_LIB_SPEC
#
#------------------------------------------------------------------------
AC_DEFUN([TEA_LOAD_CONFIG], [
@@ -3990,8 +3822,6 @@ AC_DEFUN([TEA_LOAD_CONFIG], [
$1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
$1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
$1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
$1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC}
$1_LIBRARY_PATH=${$1_LIBRARY_PATH}
fi
AC_SUBST($1_VERSION)
@@ -4024,6 +3854,7 @@ AC_DEFUN([TEA_LOAD_CONFIG], [
#
# Results:
# Adds to LIBS the appropriate extension library
#
#------------------------------------------------------------------------
AC_DEFUN([TEA_LOAD_CONFIG_LIB], [
AC_MSG_CHECKING([For $1 library for LIBS])
@@ -4055,10 +3886,11 @@ AC_DEFUN([TEA_LOAD_CONFIG_LIB], [
# $1
#
# Results:
# Substitutes the following vars:
# Subst the following vars:
#
#------------------------------------------------------------------------
AC_DEFUN([TEA_EXPORT_CONFIG], [
AC_DEFUN(TEA_EXPORT_CONFIG, [
#--------------------------------------------------------------------
# These are for $1Config.sh
#--------------------------------------------------------------------
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.62 for sqlite 3.8.5.
# Generated by GNU Autoconf 2.62 for sqlite 3.8.3.
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
@@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.8.5'
PACKAGE_STRING='sqlite 3.8.5'
PACKAGE_VERSION='3.8.3'
PACKAGE_STRING='sqlite 3.8.3'
PACKAGE_BUGREPORT=''
# Factoring default headers for most tests.
@@ -1483,7 +1483,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.8.5 to adapt to many kinds of systems.
\`configure' configures sqlite 3.8.3 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1548,7 +1548,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.8.5:";;
short | recursive ) echo "Configuration of sqlite 3.8.3:";;
esac
cat <<\_ACEOF
@@ -1664,7 +1664,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.8.5
sqlite configure 3.8.3
generated by GNU Autoconf 2.62
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1678,7 +1678,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.8.5, which was
It was created by sqlite $as_me 3.8.3, which was
generated by GNU Autoconf 2.62. Invocation command line was
$ $0 $@
@@ -14021,7 +14021,7 @@ exec 6>&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.8.5, which was
This file was extended by sqlite $as_me 3.8.3, which was
generated by GNU Autoconf 2.62. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -14074,7 +14074,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
sqlite config.status 3.8.5
sqlite config.status 3.8.3
configured by $0, generated by GNU Autoconf 2.62,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+7 -37
View File
@@ -1410,7 +1410,10 @@ static int fts3InitVtab(
** addition of a %_stat table so that it can use incremental merge.
*/
if( !isFts4 && !isCreate ){
p->bHasStat = 2;
int rc2 = SQLITE_OK;
fts3DbExec(&rc2, db, "SELECT 1 FROM %Q.'%q_stat' WHERE id=2",
p->zDb, p->zName);
if( rc2==SQLITE_OK ) p->bHasStat = 1;
}
/* Figure out the page-size for the database. This is required in order to
@@ -3317,34 +3320,7 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
}
/*
** If it is currently unknown whether or not the FTS table has an %_stat
** table (if p->bHasStat==2), attempt to determine this (set p->bHasStat
** to 0 or 1). Return SQLITE_OK if successful, or an SQLite error code
** if an error occurs.
*/
static int fts3SetHasStat(Fts3Table *p){
int rc = SQLITE_OK;
if( p->bHasStat==2 ){
const char *zFmt ="SELECT 1 FROM %Q.sqlite_master WHERE tbl_name='%q_stat'";
char *zSql = sqlite3_mprintf(zFmt, p->zDb, p->zName);
if( zSql ){
sqlite3_stmt *pStmt = 0;
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
if( rc==SQLITE_OK ){
int bHasStat = (sqlite3_step(pStmt)==SQLITE_ROW);
rc = sqlite3_finalize(pStmt);
if( rc==SQLITE_OK ) p->bHasStat = bHasStat;
}
sqlite3_free(zSql);
}else{
rc = SQLITE_NOMEM;
}
}
return rc;
}
/*
** Implementation of xBegin() method.
** Implementation of xBegin() method. This is a no-op.
*/
static int fts3BeginMethod(sqlite3_vtab *pVtab){
Fts3Table *p = (Fts3Table*)pVtab;
@@ -3355,7 +3331,7 @@ static int fts3BeginMethod(sqlite3_vtab *pVtab){
TESTONLY( p->inTransaction = 1 );
TESTONLY( p->mxSavepoint = -1; );
p->nLeafAdd = 0;
return fts3SetHasStat(p);
return SQLITE_OK;
}
/*
@@ -3604,10 +3580,6 @@ static int fts3RenameMethod(
sqlite3 *db = p->db; /* Database connection */
int rc; /* Return Code */
/* At this point it must be known if the %_stat table exists or not.
** So bHasStat may not be 2. */
rc = fts3SetHasStat(p);
/* As it happens, the pending terms table is always empty here. This is
** because an "ALTER TABLE RENAME TABLE" statement inside a transaction
** always opens a savepoint transaction. And the xSavepoint() method
@@ -3615,9 +3587,7 @@ static int fts3RenameMethod(
** PendingTermsFlush() in in case that changes.
*/
assert( p->nPendingData==0 );
if( rc==SQLITE_OK ){
rc = sqlite3Fts3PendingTermsFlush(p);
}
rc = sqlite3Fts3PendingTermsFlush(p);
if( p->zContentTbl==0 ){
fts3DbExec(&rc, db,
+1 -1
View File
@@ -223,7 +223,7 @@ struct Fts3Table {
int nNodeSize; /* Soft limit for node size */
u8 bFts4; /* True for FTS4, false for FTS3 */
u8 bHasStat; /* True if %_stat table exists (2==unknown) */
u8 bHasStat; /* True if %_stat table exists */
u8 bHasDocsize; /* True if %_docsize table exists */
u8 bDescIdx; /* True if doclists are in reverse order */
u8 bIgnoreSavepoint; /* True to ignore xSavepoint invocations */
-4
View File
@@ -5271,10 +5271,6 @@ int sqlite3Fts3UpdateMethod(
int nChng = 0; /* Net change in number of documents */
int bInsertDone = 0;
/* At this point it must be known if the %_stat table exists or not.
** So bHasStat may not be 2. */
assert( p->bHasStat==0 || p->bHasStat==1 );
assert( p->pSegments==0 );
assert(
nArg==1 /* DELETE operations */
+5 -3
View File
@@ -26,8 +26,8 @@ SQLITE_EXTENSION_INIT1
# define NEVER(X) 0
typedef unsigned char u8;
typedef unsigned short u16;
# include <ctype.h>
#endif
#include <ctype.h>
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -1933,6 +1933,7 @@ static int spellfix1Init(
#define SPELLFIX_COL_COMMAND 11
}
if( rc==SQLITE_OK && isCreate ){
sqlite3_uint64 r;
spellfix1DbExec(&rc, db,
"CREATE TABLE IF NOT EXISTS \"%w\".\"%w_vocab\"(\n"
" id INTEGER PRIMARY KEY,\n"
@@ -1944,10 +1945,11 @@ static int spellfix1Init(
");\n",
zDbName, zTableName
);
sqlite3_randomness(sizeof(r), &r);
spellfix1DbExec(&rc, db,
"CREATE INDEX IF NOT EXISTS \"%w\".\"%w_vocab_index_langid_k2\" "
"CREATE INDEX IF NOT EXISTS \"%w\".\"%w_index_%llx\" "
"ON \"%w_vocab\"(langid,k2);",
zDbName, zModule, zTableName
zDbName, zModule, r, zTableName
);
}
for(i=3; rc==SQLITE_OK && i<argc; i++){
+14 -22
View File
@@ -2947,32 +2947,26 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST.
*/
static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
const char *zFmt = "SELECT stat FROM %Q.sqlite_stat1 WHERE tbl = '%q_rowid'";
char *zSql;
const char *zSql = "SELECT stat FROM sqlite_stat1 WHERE tbl= ? || '_rowid'";
sqlite3_stmt *p;
int rc;
i64 nRow = 0;
zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName);
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0);
if( rc==SQLITE_OK ){
if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0);
rc = sqlite3_finalize(p);
}else if( rc!=SQLITE_NOMEM ){
rc = SQLITE_OK;
}
rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0);
if( rc==SQLITE_OK ){
sqlite3_bind_text(p, 1, pRtree->zName, -1, SQLITE_STATIC);
if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0);
rc = sqlite3_finalize(p);
}else if( rc!=SQLITE_NOMEM ){
rc = SQLITE_OK;
}
if( rc==SQLITE_OK ){
if( nRow==0 ){
pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
}else{
pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST);
}
if( rc==SQLITE_OK ){
if( nRow==0 ){
pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
}else{
pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST);
}
sqlite3_free(zSql);
}
return rc;
@@ -3241,8 +3235,6 @@ static int rtreeInit(
if( rc==SQLITE_OK ){
*ppVtab = (sqlite3_vtab *)pRtree;
}else{
assert( *ppVtab==0 );
assert( pRtree->nBusy==1 );
rtreeRelease(pRtree);
}
return rc;
-112
View File
@@ -158,117 +158,5 @@ do_execsql_test 4.3 {
SELECT b, a FROM t2 LEFT JOIN t1 ON (+a = +b);
} {1 1 3 {}}
#--------------------------------------------------------------------
# Test that the sqlite_stat1 data is used correctly.
#
reset_db
do_execsql_test 5.1 {
CREATE TABLE t1(x PRIMARY KEY, y);
CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2);
INSERT INTO t1(x) VALUES(1);
INSERT INTO t1(x) SELECT x+1 FROM t1; -- 2
INSERT INTO t1(x) SELECT x+2 FROM t1; -- 4
INSERT INTO t1(x) SELECT x+4 FROM t1; -- 8
INSERT INTO t1(x) SELECT x+8 FROM t1; -- 16
INSERT INTO t1(x) SELECT x+16 FROM t1; -- 32
INSERT INTO t1(x) SELECT x+32 FROM t1; -- 64
INSERT INTO t1(x) SELECT x+64 FROM t1; -- 128
INSERT INTO t1(x) SELECT x+128 FROM t1; -- 256
INSERT INTO t1(x) SELECT x+256 FROM t1; -- 512
INSERT INTO t1(x) SELECT x+512 FROM t1; --1024
INSERT INTO rt SELECT x, x, x+1 FROM t1 WHERE x<=5;
}
# First test a query with no ANALYZE data at all. The outer loop is
# real table "t1".
#
do_eqp_test 5.2 {
SELECT * FROM t1, rt WHERE x==id;
} {
0 0 0 {SCAN TABLE t1}
0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:}
}
# Now create enough ANALYZE data to tell SQLite that virtual table "rt"
# contains very few rows. This causes it to move "rt" to the outer loop.
#
do_execsql_test 5.3 {
ANALYZE;
DELETE FROM sqlite_stat1 WHERE tbl='t1';
}
db close
sqlite3 db test.db
do_eqp_test 5.4 {
SELECT * FROM t1, rt WHERE x==id;
} {
0 0 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:}
0 1 0 {SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (x=?)}
}
# Delete the ANALYZE data. "t1" should be the outer loop again.
#
do_execsql_test 5.5 { DROP TABLE sqlite_stat1; }
db close
sqlite3 db test.db
do_eqp_test 5.6 {
SELECT * FROM t1, rt WHERE x==id;
} {
0 0 0 {SCAN TABLE t1}
0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:}
}
# This time create and attach a database that contains ANALYZE data for
# tables of the same names as those used internally by virtual table
# "rt". Check that the rtree module is not fooled into using this data.
# Table "t1" should remain the outer loop.
#
do_test 5.7 {
db backup test.db2
sqlite3 db2 test.db2
db2 eval {
ANALYZE;
DELETE FROM sqlite_stat1 WHERE tbl='t1';
}
db2 close
db close
sqlite3 db test.db
execsql { ATTACH 'test.db2' AS aux; }
} {}
do_eqp_test 5.8 {
SELECT * FROM t1, rt WHERE x==id;
} {
0 0 0 {SCAN TABLE t1}
0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:}
}
#--------------------------------------------------------------------
# Test that having a second connection drop the sqlite_stat1 table
# before it is required by rtreeConnect() does not cause problems.
#
ifcapable rtree {
reset_db
do_execsql_test 6.1 {
CREATE TABLE t1(x);
CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2);
INSERT INTO t1 VALUES(1);
INSERT INTO rt VALUES(1,2,3);
ANALYZE;
}
db close
sqlite3 db test.db
do_execsql_test 6.2 { SELECT * FROM t1 } {1}
do_test 6.3 {
sqlite3 db2 test.db
db2 eval { DROP TABLE sqlite_stat1 }
db2 close
execsql { SELECT * FROM rt }
} {1 2.0 3.0}
db close
}
finish_test
-57
View File
@@ -1,57 +0,0 @@
# 2014 March 11
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Miscellaneous tests for errors in the rtree constructor.
#
if {![info exists testdir]} {
set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] rtree_util.tcl]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
ifcapable !rtree {
finish_test
return
}
set testprefix rtreeD
#-------------------------------------------------------------------------
# Test that if an SQLITE_BUSY is encountered within the vtable
# constructor, a relevant error message is returned.
#
do_multiclient_test tn {
do_test 1.$tn.1 {
sql1 {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1,2);
CREATE VIRTUAL TABLE rt USING rtree(id, minx, maxx, miny, maxy);
INSERT INTO rt VALUES(1,2,3,4,5);
}
} {}
do_test 1.$tn.2 {
sql2 { SELECT * FROM t1; }
} {1 2}
do_test 1.$tn.3 {
sql1 { BEGIN EXCLUSIVE; INSERT INTO t1 VALUES(3, 4); }
} {}
do_test 1.$tn.4 {
list [catch { sql2 { SELECT * FROM rt } } msg] $msg
} {1 {database is locked}}
}
finish_test
+1 -2
View File
@@ -66,7 +66,7 @@ LIBOBJ+= vdbe.o parse.o \
notify.o opcodes.o os.o os_unix.o os_win.o \
pager.o pcache.o pcache1.o pragma.o prepare.o printf.o \
random.o resolve.o rowset.o rtree.o select.o status.o \
table.o threads.o tokenize.o trigger.o \
table.o tokenize.o trigger.o \
update.o util.o vacuum.o \
vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \
vdbetrace.o wal.o walker.o where.o utf.o vtab.o
@@ -144,7 +144,6 @@ SRC = \
$(TOP)/src/sqliteLimit.h \
$(TOP)/src/table.c \
$(TOP)/src/tclsqlite.c \
$(TOP)/src/threads.c \
$(TOP)/src/tokenize.c \
$(TOP)/src/trigger.c \
$(TOP)/src/utf.c \
+122 -133
View File
@@ -1,12 +1,12 @@
C Improve\sperformance\sin\ssingle-threaded\smode\sby\shaving\sthe\sfinal\smerge\spass\skeys\sdirectly\sto\sthe\sVDBE,\sinstead\sof\sgoing\svia\sa\sfinal\sPMA.
D 2014-04-14T18:41:21.894
C Change\smore\sOP_OpenEphemeral\soperations\sto\sOP_OpenHash.
D 2014-02-06T14:59:47.807
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in ad0921c4b2780d01868cf69b419a4f102308d125
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc 153eb9b9725bc7b8e4dbe963219298e0c4a644b0
F Makefile.msc 6ff3ff2eef45c7dd309a8626ff7947b20bd387e7
F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315
F README.md 64f270c43c38c46de749e419c22f0ae2f4499fe8
F VERSION 9f823c026c6a32fc5f84d212a8aae0a221dba45c
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
F VERSION 8ed548d87d0a27fd7d7620476f9e25f9fa742d73
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
@@ -30,15 +30,15 @@ F autoconf/tea/configure.in e0466b881b53f31f5a4a69e7a91ad130902fb359
F autoconf/tea/doc/sqlite3.n e1fe45d4f5286ee3d0ccc877aca2a0def488e9bb
F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523
F autoconf/tea/pkgIndex.tcl.in 3ef61715cf1c7bdcff56947ffadb26bc991ca39d
F autoconf/tea/tclconfig/install-sh bdd5e293591621ae60d9824d86a4b1c5f22c3d00
F autoconf/tea/tclconfig/tcl.m4 f035b86539a5ab30689e997a11ae9e7fd2e65570
F autoconf/tea/tclconfig/install-sh b087e5c4b92820c60bffb74acc1d9c2d40d80b8f
F autoconf/tea/tclconfig/tcl.m4 a68179d7cc45524fa59db428a36610e20bdba808
F autoconf/tea/win/makefile.vc f89d0184d0eee5f7e356ea407964dcd139939928
F autoconf/tea/win/nmakehlp.c 2070e086f39866b353a482d3a14dedaf26196506
F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure 5de98fac90452f876511fee8a35565a55dfb191f x
F configure 1673bc402f8fc95015f72c279adc5a9a668ee237 x
F configure.ac 4cf9f60785143fa141b10962ccc885d973792e9a
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
@@ -78,9 +78,9 @@ 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 41b1920b9a8657963f09cb93b208c2671c5568db
F ext/fts3/fts3.c 3fe91e36a0304ad4b35020f0e22ff37e95873166
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h bdeb9015405e8facffb8fc7e09174521a2a780f4
F ext/fts3/fts3Int.h eb5f8029589f3d8f1dc7fd50c773326a640388b1
F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365
F ext/fts3/fts3_expr.c 5165c365cb5a035f5be8bb296f7aa3211d43e4ac
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
@@ -96,7 +96,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
F ext/fts3/fts3_unicode.c 92391b4b4fb043564c6539ea9b8661e3bcba47b9
F ext/fts3/fts3_unicode2.c 0113d3acf13429e6dc38e0647d1bc71211c31a4d
F ext/fts3/fts3_write.c 74c00329006c3ed6325ba4e5ab7c9b5fc99c8934
F ext/fts3/fts3_write.c cdebe72171a217b1465032dec103f8d17f7dad4d
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/fts3/tool/fts3view.c 6cfc5b67a5f0e09c0d698f9fd012c784bfaa9197
@@ -114,13 +114,13 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
F ext/misc/spellfix.c 93f3961074cebe63c31fcefe62ca2a032ee8dfed
F ext/misc/spellfix.c adfc569fafef7a1eb8f21528e5277686b358c3ce
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/rtree.c 2d9f95da404d850474e628c720c5ce15d29b47de
F ext/rtree/rtree.c a4e18b2c150adad20aecbeb3408cd235a0a57441
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
@@ -133,8 +133,7 @@ F ext/rtree/rtree8.test db79c812f9e4a11f9b1f3f9934007884610a713a
F ext/rtree/rtree9.test d86ebf08ff6328895613ed577dd8a2a37c472c34
F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf
F ext/rtree/rtreeB.test 983e567b49b5dca165940f66b87e161aa30e82b2
F ext/rtree/rtreeC.test 16d7aa86ecb6a876d2a38cf590a1471a41b3a46d
F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca
F ext/rtree/rtreeC.test 03975565f40a0bee165f613143e4dec716dd5a59
F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195
F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
F ext/rtree/sqlite3rtree.h c34c1e41d1ab80bb8ad09aae402c9c956871a765
@@ -143,7 +142,10 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt f439556c5ce01ced70987e5ee86549a45165d9ff
F main.mk 4b30dd2a6cb441db688972496b45a6c3abef8b20
F main.mk 3ae543fa446525c1dec55f58de67f41b78651812
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
F mkextw.sh d2a981497b404d6498f5ff3e3b1f3816bdfcb338
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
@@ -157,42 +159,42 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 5d99edbac5bc416032772b723ee30182ee6e5de0
F src/analyze.c 663e0b291d27eb03c9fd6b421e2d61ba348a2389
F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083
F src/analyze.c 581d5c18ce89c6f45d4dca65914d0de5b4dad41f
F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 0d1be67448c45eccc40114556186397eb9da7f7d
F src/btree.h 232836cb51753f2e96aa8ce0f052c6df850f76ba
F src/btreeInt.h 0be66063468a520e4d66b80c7a1dc26d04ee6ea4
F src/build.c e120a3693ac78ab3e74048205f07a3a522d9b982
F src/btree.c ae408b77caf025df8c1baab52aad8a5a393bed35
F src/btree.h f1c65e0511d7a228fd1a7c7463ef842525364348
F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0
F src/build.c 7e6c275ab1731510d6f793d0f88373ab3e858e69
F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a
F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd
F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
F src/delete.c cdd57149543bb28304d8f717c243f2a86b1fc280
F src/expr.c da2b3cb41081af6b56e95e7c9e95949564ce2e21
F src/delete.c 3987ac3e32f6a447b1f3ca0268d67bdaf0a8b97f
F src/expr.c fa9cd9b4bdc8989efce99d49c7e46484e17f41f4
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 5269ef07b100763134f71b889327c333bd0989cf
F src/func.c 2945bb2c4cdc0ac43733046285a4434310be1811
F src/global.c deadd872189b92aca4ee2566332a86315839f811
F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5
F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5
F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486
F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c d8bb30535c8c0785876025a4a07f9074640a15d1
F src/insert.c c6b4ba486e62d0b600632fdfce4bca76213158cb
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303
F src/main.c fcceb01d74a79c2d7984f33545b35b06da3bb1e8
F src/main.c 07225af6a00be0b7f34ac52e60f99cf5cbb2a475
F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b
F src/mem2.c dce31758da87ec2cfa52ba4c5df1aed6e07d8e8f
F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534
F src/mem5.c 74670012946c4adc8a6ad84d03acc80959c3e529
F src/mem5.c 19d9271cb936742707b6118ed44d779657c7c511
F src/memjournal.c 0683aac6cab6ec2b5374c0db37c0deb2436a3785
F src/mutex.c d3b66a569368015e0fcb1ac15f81c119f504d3bc
F src/mutex.h 5bc526e19dccc412b7ff04642f6fdad3fdfdabea
@@ -203,35 +205,35 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace
F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_unix.c ae4b5240af4619d711301d7992396e182585269f
F src/os_win.c 8245fe9184300e641d02e29a8ca95cefe0cb0fd0
F src/pager.c ab62a24218d87dda1be641f6c5ad291bff78fd94
F src/os_unix.c f3ed0e406cbf9c820565b2118232d0796346130f
F src/os_win.c d4284f003445054a26689f1264b1b9bf7261bd1b
F src/pager.c efa923693e958696eee69b205a20bfbc402c8480
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0
F src/parse.y bd51bc17cbfe7549adb4ca3747b1c3d384645065
F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c
F src/pragma.c 10f169b9650f0930a7a6df67e1387a4c2c449f38
F src/pragma.c ed409ce4104cf4d9de6ead40ace70974f124853b
F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337
F src/printf.c e5a0005f8b3de21f85da6a709d2fbee76775bf4b
F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66
F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
F src/select.c 20055cf917222e660c4222fea306bd13a0623caa
F src/shell.c b44c3f17f0bf41b3431e9cc171706251156ae85f
F src/sqlite.h.in 81221c50addbf698c3247154d92efd1095bfd885
F src/select.c d1acf45637f70d71a76cb8312507550e3aee6caa
F src/shell.c 24722d24d4ea8ca93db35e44db7308de786767ca
F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h 533154bf9d8401ff3e6f8030f4373774c0a6ad41
F src/sqliteInt.h 29b97acb02309ad07de107a81c381512066fc2e4
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c e87c99e28a145943666b51b212dacae35fcea0bd
F src/test1.c 0cd73ae82fdf7add76ca603e3575380ae7539ae2
F src/tclsqlite.c 21ca0043d7c48cde5dabed5c1116eee1be692f62
F src/test1.c 2401eee14a4309a7cfe2aeb2f30ad517a1d9c299
F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1
F src/test5.c a6d1ac55ac054d0b2b8f37b5e655b6c92645a013
F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723
F src/test7.c 72b732baa5642f795655ba1126ea032af46ecfd2
F src/test8.c 54ccd7b1df5062f0ecbf50a8f7b618f8b1f13b20
@@ -240,18 +242,18 @@ F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8
F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e
F src/test_btree.c 5b89601dcb42a33ba8b820a6b763cc9cb48bac16
F src/test_config.c ebd0a42983b696f2b121515d577753cf2afdc9b0
F src/test_config.c 0336e0bdbe541b4af89d7e3dd0656e8e6b51e585
F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
F src/test_func.c d3013ce36f19ac72a99c73864930fd1fa41832f8
F src/test_func.c f8235719dff4bf9ffee04c55a190af8782ce9ab5
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32
F src/test_intarray.c 87847c71c3c36889c0bcc9c4baf9d31881665d61
F src/test_intarray.h 2ece66438cfd177b78d1bfda7a4180cd3a10844d
F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64
F src/test_loadext.c a5251f956ab6af21e138dc1f9c0399394a510cb4
F src/test_malloc.c 27047a841f5bff1cb638123806a2c30714771307
F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
F src/test_malloc.c 1ff5b1243d96124c9a180f3b89424820a1f337f3
F src/test_multiplex.c 9f304bf04170c91c0318238d512df2da039eb1c8
F src/test_multiplex.h 110a8c4d356e0aa464ca8730375608a9a0b61ae1
F src/test_mutex.c 293042d623ebba969160f471a82aa1551626454f
@@ -266,34 +268,33 @@ F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e
F src/test_stat.c 9898687a6c2beca733b0dd6fe19163d987826d31
F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b
F src/test_syscall.c 16dbe79fb320fadb5acd7a0a59f49e52ab2d2091
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb
F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9
F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c b8e7232f2b9c9d148d6886117160de394d172f85
F src/tokenize.c 6da2de6e12218ccb0aea5184b56727d011f4bee7
F src/trigger.c 66f3470b03b52b395e839155786966e3e037fddb
F src/update.c 5b3e74a03b3811e586b4f2b4cbd7c49f01c93115
F src/utf.c 6dc9ec9f1b3db43ae8ba0365377f11df1ee4c01c
F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf
F src/trigger.c 5c1c0b899ac0ce284763dcb8fdbaa38ecf15ef98
F src/update.c 3d2bdfe24d78303cf7fd3017aaa2d848d47a1020
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
F src/vdbe.c 9f3d1b35b5fe8c7f3a4f734bd524d0df844a2576
F src/vdbe.h 394464909ed682334aa3d5831aae0c2fe2abef94
F src/vdbeInt.h ba1069627d0ab75e9ddb8f9c10958b86cdbd333d
F src/vdbeapi.c 0ed6053f947edd0b30f64ce5aeb811872a3450a4
F src/vdbeaux.c d8dc38965507a34b0e150c0d7fc82b02f8cf25ea
F src/vdbeblob.c 15377abfb59251bccedd5a9c7d014a895f0c04aa
F src/vdbemem.c 6fc77594c60f6155404f3f8d71bf36d1fdeb4447
F src/vdbesort.c 15f59dc56c7c4509b4783ad20fb25479ac63d267
F src/vdbe.c 2e46c464e910cf0f11acf6690e8f72d7239a5f63
F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26
F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56
F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad
F src/vdbeaux.c a3327afa8cfcc5bb3d38f2b2a599bac5fb63c6be
F src/vdbeblob.c bc40f98f256f0b34116d6a44b114da4a81a15d33
F src/vdbemem.c 23cdc14ed43e0aafa57bd72b9bf3d5b1641afa91
F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147
F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767
F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
F src/where.c 70eb10da08cebbd6a576ced18edb7c8f79d41597
F src/whereInt.h 2564055b440e44ebec8b47f237bbccae6719b7af
F src/where.c 087307272e374c35c7eb1eb722f0ab7db09317f2
F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@@ -302,7 +303,7 @@ F test/all.test 6ff7b43c2b4b905c74dc4a813d201d0fa64c5783
F test/alter.test e88dfa77e020c2b48e52a8020c70171ab828e079
F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060
F test/alter3.test 49c9d9fba2b8fcdce2dedeca97bbf1f369cc548d
F test/alter4.test d6c011fa0d6227abba762498cafbb607c9609e93
F test/alter4.test 8e93bf7a7e6919b14b0c9a6c1e4908bcf21b0165
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
F test/analyze.test 1772936d66471c65221e437b6d1999c3a03166c4
@@ -312,7 +313,7 @@ F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
F test/analyze6.test d31defa011a561b938b4608d3538c1b4e0b5e92c
F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f
F test/analyze8.test 093d15c1c888eed5034304a98c992f7360130b88
F test/analyze9.test e072a5172d55afcba98d6ca6a219ce8878c2f5c9
F test/analyze9.test 339e87723cd4dc158dc5e9095acd8df9e87faf79
F test/analyzeA.test 1a5c40079894847976d983ca39c707aaa44b6944
F test/analyzeB.test 8bf35ee0a548aea831bf56762cb8e7fdb1db083d
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
@@ -363,11 +364,11 @@ F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738
F test/capi3.test 71bcf2fbd36a9732f617766dfd752552c8e491b5
F test/capi3.test 6cdd49656bd62a296924f4d2fcfd05cd2a298369
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
F test/capi3c.test a21869e4d50d5dbb7e566e328fc0bc7c2efa6a32
F test/capi3d.test 6d0fc0a86d73f42dd19a7d8b7761ab9bc02277d0
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
F test/capi3e.test ad90088b18b0367125ff2d4b5400153fd2f99aab
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763
F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815
@@ -404,9 +405,8 @@ F test/corruptC.test 02405cf7ed0c1e989060e1aab6d02ffbc3906fbb
F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040
F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
F test/corruptG.test 1ab3bf97ee7bdba70e0ff3ba2320657df55d1804
F test/corruptH.test 88ed71a086e13591c917aac6de32750e7c7281cb
F test/corruptI.test b3e4203d420490fc3d3062711597bc1dea06a789
F test/corruptG.test c150f156dace653c00a121ad0f5772a0568c41ba
F test/corruptH.test 9d8186f6f8751efdfd445d8546fd98f073499039
F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
@@ -432,7 +432,7 @@ F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240
F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
F test/distinct.test 086e70c765f172e8974e9f83b9ac5ca03c154e77
F test/distinct.test b9f34f3827a67baf5b5bcb1cdf5185963d629d49
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
F test/e_createtable.test ee95d48664503d40f6cc9ef4a7d03216188e2ada
F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a
@@ -524,7 +524,7 @@ F test/fts3ak.test bd14deafe9d1586e8e9bf032411026ac4f8c925d
F test/fts3al.test 07d64326e79bbdbab20ee87fc3328fbf01641c9f
F test/fts3am.test 218aa6ba0dfc50c7c16b2022aac5c6be593d08d8
F test/fts3an.test a49ccadc07a2f7d646ec1b81bc09da2d85a85b18
F test/fts3ao.test 3e4e3d5e75c076520341d0bdf4eb17c00e8cbde2
F test/fts3ao.test 71b0675e3df5c512a5a03daaa95ee1916de23dda
F test/fts3atoken.test fca30fd86db9241d571c637751e9a8a2f50f1451
F test/fts3auto.test b981fea19b132b4e6878f50d7c1f369b28f68eb9
F test/fts3aux1.test f8f287a4a73f381f8fa15b6a70f36245f903d221
@@ -536,7 +536,7 @@ F test/fts3conf.test ee8500c86dd58ec075e8831a1e216a79989436de
F test/fts3corrupt.test 2710b77983cc7789295ddbffea52c1d3b7506dbb
F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba
F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7
F test/fts3d.test 597b0b76e41f0d672e2731c4d7b631d628efd13f
F test/fts3d.test c8a193513a269ec4c205ca09645e26e0bc71b860
F test/fts3defer.test 0be4440b73a2e651fc1e472066686d6ada4b9963
F test/fts3defer2.test a3b6cbeabaf28c9398652a4d101ea224d9358479
F test/fts3defer3.test dd53fc13223c6d8264a98244e9b19abd35ed71cd
@@ -575,7 +575,7 @@ F test/fts4merge4.test c19c85ca1faa7b6d536832b49c12e1867235f584
F test/fts4noti.test aed33ba44808852dcb24bf70fa132e7bf530f057
F test/fts4unicode.test 01ec3fe2a7c3cfff3b4c0581b83caa11b33efa36
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
F test/func.test a21814945d32137412b553d98ad2107f9b2173a9
F test/func.test 00667bbeac044d007f6f021af1b9f6150f0c7ff8
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
F test/func3.test dbccee9133cfef1473c59ec07b5f0262b9d72f9a
F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f
@@ -593,9 +593,9 @@ F test/hook.test 162d7cef7a2d2b04839fe14402934e6a1b79442f
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
F test/in.test 047c4671328e9032ab95666a67021adbbd36e98e
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
F test/in4.test 41c1c031aa46b1eb4411df2687ed2ed498da23b5
F test/in5.test 99f9a40af01711b06d2d614ecfe96129f334fba3
F test/in3.test dbf41c0c073c10a8c0fee280cba3e9dddbd4a9c6
F test/in4.test 64f3cc1acde1b9161ccdd8e5bde3daefdb5b2617
F test/in5.test 9d8c15bfc9a06da5b354d4d4ecfea9f928769641
F test/incrblob.test e81846d214f3637622620fbde7cd526781cfe328
F test/incrblob2.test bf4d549aa4a466d7fbe3e3a3693d3861263d5600
F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4
@@ -616,10 +616,10 @@ F test/index7.test a3baf9a625bda7fd49471e99aeae04095fbfeecf
F test/indexedby.test b2f22f3e693a53813aa3f50b812eb609ba6df1ec
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
F test/insert.test acf909b067b838eb55338d619e800e148c17f1f5
F test/insert.test 489aa12a027c83d291f5034a83c8c32e6be1dca2
F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435
F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
F test/insert4.test 4791662c50518bdd37d394cae9a7a8014e845bb3
F test/insert4.test b00ddf82d6d4f0a6f3999f42bb6a3c813ea70707
F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2
F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4
@@ -632,7 +632,7 @@ F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
F test/join.test 559b81eb56ae350246f9c25986aa52c81c725c7e
F test/join.test 8d63cc4d230a7affafa4b6ab0b97c49b8ccb365c
F test/join2.test f2171c265e57ee298a27e57e7051d22962f9f324
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
@@ -649,8 +649,8 @@ F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
F test/like.test e191e536d0fcd722a6b965e7cd1ee0bfd12a5991
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
F test/limit.test 3d7df19c35ac672a11f7de406cd3205d592babbb
F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b
F test/limit.test cc0ab63385239b63c72452b0e93700bf5e8f0b99
F test/loadext.test 92e6dfefd1229c3ef4aaabd87419efd8fa57a7a5
F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7
F test/lock.test 87af515b0c4cf928576d0f89946d67d7c265dfb4
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
@@ -663,7 +663,7 @@ F test/lock_common.tcl 0c270b121d40959fa2f3add382200c27045b3d95
F test/lookaside.test 93f07bac140c5bb1d49f3892d2684decafdc7af2
F test/main.test 39c4bb8a157f57298ed1659d6df89d9f35aaf2c8
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
F test/malloc.test 26ae08a09cc15a98d147ee63925e3a66048e71c9
F test/malloc.test fd368e31fe98d4779ed80442f311ed9f03bcd1f7
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
F test/malloc5.test fafce0aa9157060445cd1a56ad50fc79d82f28c3
@@ -671,7 +671,7 @@ F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a
F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d
F test/malloc9.test 2307c6ee3703b0a21391f3ea92388b4b73f9105e
F test/mallocA.test c049224adeb0244b8f6eb770c1fa6ac40f9b3518
F test/mallocA.test 1ba0367fb5434e7bc2fa4afcb30b14174d91b160
F test/mallocAll.test 98f1be74bc9f49a858bc4f361fc58e26486798be
F test/mallocB.test bc475ab850cda896142ab935bbfbc74c24e51ed6
F test/mallocC.test 3dffe16532f109293ce1ccecd0c31dca55ef08c4
@@ -723,8 +723,7 @@ F test/orderby1.test 9b524aff9147288da43a6d7ddfdcff47fa2303c6
F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04
F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99
F test/orderby4.test 4d39bfbaaa3ae64d026ca2ff166353d2edca4ba4
F test/orderby5.test 2490183fef54417209d1df253633a605d46bd350
F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859
F test/orderby5.test 0eb82d5890c3f3d0563966560cfdc984ea69e30c
F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
@@ -738,8 +737,8 @@ F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54
F test/permutations.test a214a42b4767bbbc7cd0fd965ea6198044ab414d
F test/pragma.test adb21a90875bc54a880fa939c4d7c46598905aa0
F test/permutations.test 40add071ba71aefe1c04f5845308cf46f7de8d04
F test/pragma.test e882183ecd21d064cec5c7aaea174fbd36293429
F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
F test/printf2.test bed79b4c3e5da08ba88ad637c0bf62586843cfb1
@@ -781,18 +780,17 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
F test/select1.test fc2a61f226a649393664ad54bc5376631801517c
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
F test/select4.test 8c5a60d439e2df824aed56223566877a883c5c84
F test/select4.test 00179be44e531fe04c1c3f15df216439dff2519d
F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
F test/select6.test e76bd10a56988f15726c097a5d5a7966fe82d3b2
F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d
F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d
F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95
F test/selectA.test 77adaffe9704cb80e301ebaeff4b107b58d435c5
F test/selectA.test 99cf21df033b93033ea4f34aba14a500f48f04fe
F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25
F test/selectC.test 871fb55d884d3de5943c4057ebd22c2459e71977
F test/selectD.test b0f02a04ef7737decb24e08be2c39b9664b43394
F test/selectE.test fc02a1eb04c8eb537091482644b7d778ae8759b7
F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3
F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118
F test/shared.test 1da9dbad400cee0d93f252ccf76e1ae007a63746
F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879
@@ -805,21 +803,19 @@ F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21
F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
F test/shell1.test f2a1d471e5cd2b42f7a65b166dc1ace2b8d11583
F test/shell1.test e7c0b9ebda25d5e78f0a3ea0dc4e31bb6d8098c0
F test/shell2.test c57da3a381c099b02c813ba156298d5c2f5c93a3
F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29
F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9
F test/shell5.test bb755ea9144b8078a752fc56223582627070b5f1
F test/shell5.test cee83b4385f842fec1f2a0bec9ea811f35386edf
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
F test/skipscan1.test bed8cbe9d554c8c27afb6c88500f704c86a9196f
F test/skipscan1.test 8c777ffd9dad6ee6d2568160cb2158f0b5cd9dd2
F test/skipscan2.test 5a4db0799c338ddbacb154aaa5589c0254b36a8d
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24
F test/sort.test 79dc647c4e9b123a64e57b7080b7f9a2df43f87a
F test/sort2.test 04e99d0d028b469c6cfab2c647c6c28755504063
F test/sort3.test c3f88d233452a129de519de311d109a0ad0da0af
F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5
F test/speed1.test f2974a91d79f58507ada01864c0e323093065452
F test/speed1p.explain d841e650a04728b39e6740296b852dccdca9b2cb
F test/speed1p.test b180e98609c7677382cf618c0ec9b69f789033a8
@@ -828,7 +824,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/speedtest1.c 90446861e566a9965a8d005381a3c964ff333646
F test/speedtest1.c 7130d2cb6db45baa553a4ab2f715116c71c2d9f4
F test/spellfix.test 61309f5efbec53603b3f86457d34a504f80abafe
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de
@@ -839,7 +835,7 @@ F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c
F test/syscall.test a653783d985108c4912cc64d341ffbbb55ad2806
F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6
F test/table.test 580d23530187026d4502fae74a490f0408cf2cc7
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
@@ -848,7 +844,7 @@ F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
F test/tester.tcl bc0889a2f86d9c17307992ca1e70391794780265
F test/tester.tcl 9bd04481b8b0ef1f2049ad01f28e175ee9a14f7b
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@@ -873,9 +869,7 @@ F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7
F test/tkt-3a77c9714e.test b08bca26de1140bdf004a37716582a43d7bd8be8
F test/tkt-3fe897352e.test 27e26eb0f1811aeba4d65aba43a4c52e99da5e70
F test/tkt-4a03edc4c8.test 91c0e135888cdc3d4eea82406a44b05c8c1648d0
F test/tkt-4c86b126f2.test cbcc611becd0396890169ab23102dd70048bbc9a
F test/tkt-4dd95f6943.test 3d0ce415d2ee15d3d564121960016b9c7be79407
F test/tkt-4ef7e3cfca.test 3965ae11cc9cf6e334f9d7d3c1e20bf8d56254b1
F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894
F test/tkt-5d863f876e.test c9f36ca503fa154a3655f92a69d2c30da1747bfa
F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84
@@ -889,13 +883,11 @@ F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8
F test/tkt-80e031a00f.test 9a154173461a4dbe2de49cda73963e04842d52f7
F test/tkt-8454a207b9.test c583a9f814a82a2b5ba95207f55001c9f0cd816c
F test/tkt-868145d012.test a5f941107ece6a64410ca4755c6329b7eb57a356
F test/tkt-8c63ff0ec.test 258b7fc8d7e4e1cb5362c7d65c143528b9c4cbed
F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5
F test/tkt-94c04eaadb.test f738c57c7f68ab8be1c054415af7774617cb6223
F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67
F test/tkt-9f2eb3abac.test 85bc63e749f050e6a61c8f9207f1eee65c9d3395
F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4
F test/tkt-a8a0d2996a.test eb597379dbcefa24765763d7f682c00cb5924fa9
F test/tkt-b1d3a2e531.test 8f7576e41ca179289ee1a8fee28386fd8e4b0550
F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0
F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3
@@ -1023,10 +1015,10 @@ F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
F test/types2.test 3555aacf8ed8dc883356e59efc314707e6247a84
F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a
F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264
F test/unixexcl.test cd6c765f75e50e8e2c2ba763149e5d340ea19825
F test/unixexcl.test a9870e46cc6f8390a494513d4f2bf55b5a8b3e46
F test/unordered.test ef85ac8f2f3c93ed2b9e811b684de73175fc464c
F test/update.test 1b6c488a8f993d090b7ee9ad0e234faa161b3aeb
F test/uri.test 23662b7b61958b0f0e47082de7d06341ccf85d5b
F test/uri.test 63e03df051620a18f794b4f4adcdefb3c23b6751
F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae
F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d
F test/vacuum2.test af432e6e3bfc0ea20a80cb86a03c7d9876d38324
@@ -1034,7 +1026,7 @@ F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d
F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
F test/view.test f311691d696a5cc27e3c1b875cec1b0866b4ccd9
F test/view.test 4057630287bfa5955628fe90a13d4c225d1c7352
F test/vtab1.test b631d147b198cfd7903ab5fed028eb2a3d321dc6
F test/vtab2.test 7bcffc050da5c68f4f312e49e443063e2d391c0d
F test/vtab3.test baad99fd27217f5d6db10660522e0b7192446de1
@@ -1052,14 +1044,13 @@ F test/vtabE.test 7c4693638d7797ce2eda17af74292b97e705cc61
F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
F test/vtab_shared.test ea8778d5b0df200adef2ca7c00c3c37d4375f772
F test/wal.test 885f32b2b390b30b4aa3dbb0e568f8f78d40f5cc
F test/vtab_shared.test 6acafaae7126c9f49be72c2f57eb8bef3024f1cb
F test/wal.test 40073e54359d43354925b2b700b7eebd5e207285
F test/wal2.test a8e3963abf6b232cf0b852b09b53665ef34007af
F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
F test/wal5.test 8f888b50f66b78821e61ed0e233ded5de378224b
F test/wal6.test 527581f5527bf9c24394991e2be83000aace5f9e
F test/wal64k.test 163655ecd2cb8afef4737cac2a40fdd2eeaf20b8
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
F test/wal8.test 75c42e1bc4545c277fed212f8fc9b7723cd02216
F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750
@@ -1075,18 +1066,18 @@ F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c
F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496
F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6
F test/walro.test 34422d1d95aaff0388f0791ec20edb34e2a3ed57
F test/walro.test 6cc247a0cc9b36aeea2057dd28a922a1cdfbd630
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
F test/where.test 28b64e93428961b07b0d486778d63fd672948f6b
F test/where2.test 455a2eb2666e66c1e84e2cb5815173a85e6237db
F test/where.test 701a633ed16c661cd597b9d504b485197a0f49d7
F test/where2.test ed6baa9420a109d8be683dbef5d153d186f3690b
F test/where3.test d28c51f257e60be30f74308fa385ceeddfb54a6e
F test/where4.test d8420ceeb8323a41ceff1f1841fc528e824e1ecf
F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8
F test/where8.test 806f1dcec4088be2b826b33f757fe6e17c3236a1
F test/where8.test d2b4fd6d7b7c5d44f590182a05033d78a14c00a1
F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739
F test/where9.test 4f3eab951353a3ae164befc521c777dfa903e46c
F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b
@@ -1095,24 +1086,23 @@ F test/whereC.test d6f4ecd4fa2d9429681a5b22a25d2bda8e86ab8a
F test/whereD.test 6c2feb79ef1f68381b07f39017fe5f9b96da8d62
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7
F test/whereG.test 2533b72ed4a31fd1687230a499b557b911525344
F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
F test/whereG.test 2a3d5181decc801b36600fa1c40b0dad2ccc267f
F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c
F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
F test/with1.test 268081a6b14817a262ced4d0ee34d4d2a1dd2068
F test/with2.test ee227a663586aa09771cafd4fa269c5217eaf775
F test/with1.test ce15d69d34a2576b0e47d78c244d1ba2a31679d1
F test/with2.test 2fe78fcd8deef2a0f9cfc49bfc755911d0b3fd64
F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991
F test/without_rowid1.test e00a0a9dc9f0be651f011d61e8a32b7add5afb30
F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
F test/without_rowid5.test b4a639a367f04d382d20e8f44fc1be4f2d57d107
F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac
F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd
F tool/build-all-msvc.bat e0917e787df675b020d250d60a00de8abaa4e30a x
F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
@@ -1125,14 +1115,14 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
F tool/lemon.c 07aba6270d5a5016ba8107b09e431eea4ecdc123
F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc
F tool/logest.c 388c318c7ac8b52b7c08ca1e2de0f4ca9a8f7e81
F tool/logest.c 7ad625cac3d54012b27d468b7af6612f78b9ba75
F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383
F tool/mkkeywordhash.c c9e05e4a7bcab8fab9f583d5b321fb72f565ad97
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkpragmatab.tcl 78a77b2c554d534c6f2dc903130186ed15715460
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c-noext.tcl 752f1a9d3287f6c0ef5738b1c4add0b96fbe0854
F tool/mksqlite3c.tcl 8da823522f27608494997e1dba19cd426572ba80
F tool/mksqlite3c-noext.tcl 8bce31074e4cbe631bb7676526a048335f4c9f02
F tool/mksqlite3c.tcl e2ba20d3f690990079d17f3e5a7417dfb7ada543
F tool/mksqlite3h.tcl ba24038056f51fde07c0079c41885ab85e2cff12
F tool/mksqlite3internalh.tcl 3dca7bb5374cee003379b8cbac73714f610ef795
F tool/mkvsix.tcl 6477fb9dab838b7eea1eed50658ff1cda04850b5
@@ -1159,11 +1149,10 @@ F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891
F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P e400bbbf26cdfe88f6cb231e96cdcddb9a6bcc0f
R b74f7a073d8c77e32a2dce332520aa10
U dan
Z cd43207b847b4088208c6c3dd9c99bf8
P 715fac7749a6b1523fe9f7de8263f0c4d1571d07
R f507eae713e5b72113d4535fdf641347
U drh
Z 759564bb3627cf7a97644b4104ef33de
+1 -1
View File
@@ -1 +1 @@
02610cd9b77caa2c181210056088beb3ad6ce30f
881164cf6e5c987ae0e40804267715d878135198
+49
View File
@@ -0,0 +1,49 @@
#!/bin/sh
#
# This script is used to compile SQLite into a DLL.
#
# Two separate DLLs are generated. "sqlite3.dll" is the core
# library. "tclsqlite3.dll" contains the TCL bindings and is the
# library that is loaded into TCL in order to run SQLite.
#
make sqlite3.c
PATH=$PATH:/opt/mingw/bin
TCLDIR=/home/drh/tcltk/846/win/846win
TCLSTUBLIB=$TCLDIR/libtcl84stub.a
OPTS='-DUSE_TCL_STUBS=1 -DBUILD_sqlite=1 -DSQLITE_OS_WIN=1'
OPTS="$OPTS -DSQLITE_THREADSAFE=1"
OPTS="$OPTS -DSQLITE_ENABLE_FTS3=1"
OPTS="$OPTS -DSQLITE_ENABLE_RTREE=1"
OPTS="$OPTS -DSQLITE_ENABLE_COLUMN_METADATA=1"
CC="i386-mingw32msvc-gcc -Os $OPTS -Itsrc -I$TCLDIR"
NM="i386-mingw32msvc-nm"
CMD="$CC -c sqlite3.c"
echo $CMD
$CMD
CMD="$CC -c tclsqlite3.c"
echo $CMD
$CMD
echo 'EXPORTS' >tclsqlite3.def
$NM tclsqlite3.o | grep ' T ' >temp1
grep '_Init$' temp1 >temp2
grep '_SafeInit$' temp1 >>temp2
grep ' T _sqlite3_' temp1 >>temp2
echo 'EXPORTS' >tclsqlite3.def
sed 's/^.* T _//' temp2 | sort | uniq >>tclsqlite3.def
i386-mingw32msvc-dllwrap \
--def tclsqlite3.def -v --export-all \
--driver-name i386-mingw32msvc-gcc \
--dlltool-name i386-mingw32msvc-dlltool \
--as i386-mingw32msvc-as \
--target i386-mingw32 \
-dllname tclsqlite3.dll -lmsvcrt tclsqlite3.o $TCLSTUBLIB
$NM sqlite3.o | grep ' T ' >temp1
echo 'EXPORTS' >sqlite3.def
grep ' _sqlite3_' temp1 | sed 's/^.* _//' >>sqlite3.def
i386-mingw32msvc-dllwrap \
--def sqlite3.def -v --export-all \
--driver-name i386-mingw32msvc-gcc \
--dlltool-name i386-mingw32msvc-dlltool \
--as i386-mingw32msvc-as \
--target i386-mingw32 \
-dllname sqlite3.dll -lmsvcrt sqlite3.o
+13
View File
@@ -0,0 +1,13 @@
#!/bin/sh
#
# This script is used to compile SQLite into a shared library on Linux.
#
# Two separate shared libraries are generated. "sqlite3.so" is the core
# library. "tclsqlite3.so" contains the TCL bindings and is the
# library that is loaded into TCL in order to run SQLite.
#
CFLAGS=-O2 -Wall
make fts2amal.c
echo gcc $CFLAGS -shared fts2amal.c -o fts2.so
gcc $CFLAGS -shared fts2amal.c -o fts2.so
strip fts2.so
+22
View File
@@ -0,0 +1,22 @@
#!/bin/sh
#
# This script is used to compile SQLite extensions into DLLs.
#
make fts2amal.c
PATH=$PATH:/opt/mingw/bin
OPTS='-DTHREADSAFE=1 -DBUILD_sqlite=1 -DSQLITE_OS_WIN=1'
CC="i386-mingw32msvc-gcc -O2 $OPTS -Itsrc"
NM="i386-mingw32msvc-nm"
CMD="$CC -c fts2amal.c"
echo $CMD
$CMD
echo 'EXPORTS' >fts2.def
echo 'sqlite3_fts2_init' >>fts2.def
i386-mingw32msvc-dllwrap \
--def fts2.def -v --export-all \
--driver-name i386-mingw32msvc-gcc \
--dlltool-name i386-mingw32msvc-dlltool \
--as i386-mingw32msvc-as \
--target i386-mingw32 \
-dllname fts2.dll -lmsvcrt fts2amal.o
zip fts2dll.zip fts2.dll fts2.def
+6 -7
View File
@@ -77,8 +77,8 @@ static void renameTableFunc(
assert( len>0 );
} while( token!=TK_LP && token!=TK_USING );
zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql),
zSql, zTableName, tname.z+tname.n);
zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql,
zTableName, tname.z+tname.n);
sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
}
}
@@ -130,7 +130,7 @@ static void renameParentFunc(
sqlite3Dequote(zParent);
if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){
char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"",
(zOutput?zOutput:""), (int)(z-zInput), zInput, (const char *)zNew
(zOutput?zOutput:""), z-zInput, zInput, (const char *)zNew
);
sqlite3DbFree(db, zOutput);
zOutput = zOut;
@@ -216,8 +216,8 @@ static void renameTriggerFunc(
/* Variable tname now contains the token that is the old table-name
** in the CREATE TRIGGER statement.
*/
zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql),
zSql, zTableName, tname.z+tname.n);
zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql,
zTableName, tname.z+tname.n);
sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
}
}
@@ -469,7 +469,7 @@ void sqlite3AlterRenameTable(
}
#endif
/* Begin a transaction for database iDb.
/* Begin a transaction and code the VerifyCookie for database iDb.
** Then modify the schema cookie (since the ALTER TABLE modifies the
** schema). Open a statement transaction if the table is a virtual
** table.
@@ -605,7 +605,6 @@ void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
sqlite3VdbeUsesBtree(v, iDb);
sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2);
j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2);
sqlite3VdbeJumpHere(v, j1);
sqlite3ReleaseTempReg(pParse, r1);
+4 -11
View File
@@ -1077,7 +1077,6 @@ static void analyzeOneTable(
**
*/
addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
addrGotoChng0 = sqlite3VdbeAddOp0(v, OP_Goto);
@@ -1099,7 +1098,6 @@ static void analyzeOneTable(
aGotoChng[i] =
sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
VdbeCoverage(v);
}
sqlite3VdbeAddOp2(v, OP_Integer, nCol, regChng);
aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto);
@@ -1146,7 +1144,7 @@ static void analyzeOneTable(
sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp);
sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, 2+IsStat34);
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow);
/* Add the entry to the stat1 table. */
callStatGet(v, regStat4, STAT_GET_STAT1, regStat1);
@@ -1173,15 +1171,10 @@ static void analyzeOneTable(
addrNext = sqlite3VdbeCurrentAddr(v);
callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid);
addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
VdbeCoverage(v);
callStatGet(v, regStat4, STAT_GET_NEQ, regEq);
callStatGet(v, regStat4, STAT_GET_NLT, regLt);
callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
/* We know that the regSampleRowid row exists because it was read by
** the previous loop. Thus the not-found jump of seekOp will never
** be taken */
VdbeCoverageNeverTaken(v);
#ifdef SQLITE_ENABLE_STAT3
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
pIdx->aiColumn[0], regSample);
@@ -1192,10 +1185,10 @@ static void analyzeOneTable(
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);
#endif
sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regTemp, "bbbbbb", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
sqlite3VdbeJumpHere(v, addrIsNull);
}
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
@@ -1212,7 +1205,7 @@ static void analyzeOneTable(
if( pOnlyIdx==0 && needTableCnt ){
VdbeComment((v, "%s", pTab->zName));
sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1);
jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); VdbeCoverage(v);
jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1);
sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
+52 -66
View File
@@ -746,32 +746,20 @@ static int btreeRestoreCursorPosition(BtCursor *pCur){
** at is deleted out from under them.
**
** This routine returns an error code if something goes wrong. The
** integer *pHasMoved is set as follows:
**
** 0: The cursor is unchanged
** 1: The cursor is still pointing at the same row, but the pointers
** returned by sqlite3BtreeKeyFetch() or sqlite3BtreeDataFetch()
** might now be invalid because of a balance() or other change to the
** b-tree.
** 2: The cursor is no longer pointing to the row. The row might have
** been deleted out from under the cursor.
** integer *pHasMoved is set to one if the cursor has moved and 0 if not.
*/
int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){
int rc;
if( pCur->eState==CURSOR_VALID ){
*pHasMoved = 0;
return SQLITE_OK;
}
rc = restoreCursorPosition(pCur);
if( rc ){
*pHasMoved = 2;
*pHasMoved = 1;
return rc;
}
if( pCur->eState!=CURSOR_VALID || NEVER(pCur->skipNext!=0) ){
*pHasMoved = 2;
}else{
*pHasMoved = 1;
}else{
*pHasMoved = 0;
}
return SQLITE_OK;
}
@@ -1539,7 +1527,7 @@ static int btreeInitPage(MemPage *pPage){
** Set up a raw page so that it looks like a database page holding
** no entries.
*/
static void zeroPage(MemPage *pPage, int flags){
static void zeroPage(MemPage *pPage, u8 flags){
unsigned char *data = pPage->aData;
BtShared *pBt = pPage->pBt;
u8 hdr = pPage->hdrOffset;
@@ -1554,12 +1542,13 @@ static void zeroPage(MemPage *pPage, int flags){
memset(&data[hdr], 0, pBt->usableSize - hdr);
}
data[hdr] = (char)flags;
first = hdr + ((flags&PTF_LEAF)==0 ? 12 : 8);
first = hdr + 8 + 4*((flags&PTF_LEAF)==0 ?1:0);
memset(&data[hdr+1], 0, 4);
data[hdr+7] = 0;
put2byte(&data[hdr+5], pBt->usableSize);
pPage->nFree = (u16)(pBt->usableSize - first);
decodeFlags(pPage, flags);
pPage->hdrOffset = hdr;
pPage->cellOffset = first;
pPage->aDataEnd = &data[pBt->usableSize];
pPage->aCellIdx = &data[first];
@@ -2173,7 +2162,6 @@ int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
return SQLITE_OK;
}
#if SQLITE_MAX_MMAP_SIZE>0
/*
** Change the limit on the amount of the database file that may be
** memory mapped.
@@ -2186,7 +2174,6 @@ int sqlite3BtreeSetMmapLimit(Btree *p, sqlite3_int64 szMmap){
sqlite3BtreeLeave(p);
return SQLITE_OK;
}
#endif /* SQLITE_MAX_MMAP_SIZE>0 */
/*
** Change the way data is synced to disk in order to increase or decrease
@@ -2598,6 +2585,7 @@ static int newDatabase(BtShared *pBt){
MemPage *pP1;
unsigned char *data;
int rc;
u8 flags;
assert( sqlite3_mutex_held(pBt->mutex) );
if( pBt->nPage>0 ){
@@ -2620,7 +2608,9 @@ static int newDatabase(BtShared *pBt){
data[22] = 32;
data[23] = 32;
memset(&data[24], 0, 100-24);
zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA );
flags = (pBt->openFlags&BTREE_SINGLE_INDEX) ? PTF_ZERODATA|PTF_LEAF
: PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF;
zeroPage(pP1, flags);
pBt->btsFlags |= BTS_PAGESIZE_FIXED;
#ifndef SQLITE_OMIT_AUTOVACUUM
assert( pBt->autoVacuum==1 || pBt->autoVacuum==0 );
@@ -3645,6 +3635,7 @@ static int btreeCursor(
}
pBt->pCursor = pCur;
pCur->eState = CURSOR_INVALID;
pCur->cachedRowid = 0;
return SQLITE_OK;
}
int sqlite3BtreeCursor(
@@ -3685,6 +3676,36 @@ void sqlite3BtreeCursorZero(BtCursor *p){
memset(p, 0, offsetof(BtCursor, iPage));
}
/*
** Set the cached rowid value of every cursor in the same database file
** as pCur and having the same root page number as pCur. The value is
** set to iRowid.
**
** Only positive rowid values are considered valid for this cache.
** The cache is initialized to zero, indicating an invalid cache.
** A btree will work fine with zero or negative rowids. We just cannot
** cache zero or negative rowids, which means tables that use zero or
** negative rowids might run a little slower. But in practice, zero
** or negative rowids are very uncommon so this should not be a problem.
*/
void sqlite3BtreeSetCachedRowid(BtCursor *pCur, sqlite3_int64 iRowid){
BtCursor *p;
for(p=pCur->pBt->pCursor; p; p=p->pNext){
if( p->pgnoRoot==pCur->pgnoRoot ) p->cachedRowid = iRowid;
}
assert( pCur->cachedRowid==iRowid );
}
/*
** Return the cached rowid for the given cursor. A negative or zero
** return value indicates that the rowid cache is invalid and should be
** ignored. If the rowid cache has never before been set, then a
** zero is returned.
*/
sqlite3_int64 sqlite3BtreeGetCachedRowid(BtCursor *pCur){
return pCur->cachedRowid;
}
/*
** Close a cursor. The read lock on the database file is released
** when the last cursor is closed.
@@ -4200,13 +4221,10 @@ static const void *fetchPayload(
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
assert( cursorHoldsMutex(pCur) );
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
assert( pCur->info.nSize>0 );
#if 0
if( pCur->info.nSize==0 ){
btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage],
&pCur->info);
}
#endif
*pAmt = pCur->info.nLocal;
return (void*)(pCur->info.pCell + pCur->info.nHeader);
}
@@ -4564,7 +4582,6 @@ int sqlite3BtreeMovetoUnpacked(
int *pRes /* Write search results here */
){
int rc;
RecordCompare xRecordCompare;
assert( cursorHoldsMutex(pCur) );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
@@ -4586,17 +4603,6 @@ int sqlite3BtreeMovetoUnpacked(
}
}
if( pIdxKey ){
xRecordCompare = sqlite3VdbeFindCompare(pIdxKey);
pIdxKey->errCode = 0;
assert( pIdxKey->default_rc==1
|| pIdxKey->default_rc==0
|| pIdxKey->default_rc==-1
);
}else{
xRecordCompare = 0; /* All keys are integers */
}
rc = moveToRoot(pCur);
if( rc ){
return rc;
@@ -4629,7 +4635,7 @@ int sqlite3BtreeMovetoUnpacked(
assert( biasRight==0 || biasRight==1 );
idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */
pCur->aiIdx[pCur->iPage] = (u16)idx;
if( xRecordCompare==0 ){
if( pPage->intKey ){
for(;;){
i64 nCellKey;
pCell = findCell(pPage, idx) + pPage->childPtrSize;
@@ -4681,14 +4687,14 @@ int sqlite3BtreeMovetoUnpacked(
** single byte varint and the record fits entirely on the main
** b-tree page. */
testcase( pCell+nCell+1==pPage->aDataEnd );
c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey, 0);
c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[1], pIdxKey);
}else if( !(pCell[1] & 0x80)
&& (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal
){
/* The record-size field is a 2 byte varint and the record
** fits entirely on the main b-tree page. */
testcase( pCell+nCell+2==pPage->aDataEnd );
c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey, 0);
c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
}else{
/* The record flows over onto one or more overflow pages. In
** this case the whole cell needs to be parsed, a buffer allocated
@@ -4709,13 +4715,9 @@ int sqlite3BtreeMovetoUnpacked(
sqlite3_free(pCellKey);
goto moveto_finish;
}
c = xRecordCompare(nCell, pCellKey, pIdxKey, 0);
c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
sqlite3_free(pCellKey);
}
assert(
(pIdxKey->errCode!=SQLITE_CORRUPT || c==0)
&& (pIdxKey->errCode!=SQLITE_NOMEM || !pCur->pBtree->db->mallocFailed)
);
if( c<0 ){
lwr = idx+1;
}else if( c>0 ){
@@ -4725,7 +4727,6 @@ int sqlite3BtreeMovetoUnpacked(
*pRes = 0;
rc = SQLITE_OK;
pCur->aiIdx[pCur->iPage] = (u16)idx;
if( pIdxKey->errCode ) rc = SQLITE_CORRUPT;
goto moveto_finish;
}
if( lwr>upr ) break;
@@ -6111,7 +6112,7 @@ static int balance_nonroot(
u16 leafCorrection; /* 4 if pPage is a leaf. 0 if not */
int leafData; /* True if pPage is a leaf of a LEAFDATA tree */
int usableSpace; /* Bytes in pPage beyond the header */
int pageFlags; /* Value of pPage->aData[0] */
u8 pageFlags; /* Value of pPage->aData[0] */
int subtotal; /* Subtotal of bytes in cells on one page */
int iSpace1 = 0; /* First unused byte of aSpace1[] */
int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */
@@ -6988,17 +6989,11 @@ int sqlite3BtreeInsert(
rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
if( rc ) return rc;
/* If this is an insert into a table b-tree, invalidate any incrblob
** cursors open on the row being replaced (assuming this is a replace
** operation - if it is not, the following is a no-op). */
if( pCur->pKeyInfo==0 ){
/* If this is an insert into a table b-tree, invalidate any incrblob
** cursors open on the row being replaced */
invalidateIncrblobCursors(p, nKey, 0);
/* If the cursor is currently on the last row and we are appending a
** new row onto the end, set the "loc" to avoid an unnecessary btreeMoveto()
** call */
if( pCur->validNKey && nKey>0 && pCur->info.nKey==nKey-1 ){
loc = -1;
}
}
if( !loc ){
@@ -7068,8 +7063,8 @@ int sqlite3BtreeInsert(
** row without seeking the cursor. This can be a big performance boost.
*/
pCur->info.nSize = 0;
pCur->validNKey = 0;
if( rc==SQLITE_OK && pPage->nOverflow ){
pCur->validNKey = 0;
rc = balance(pCur);
/* Must make sure nOverflow is reset to zero even if the balance()
@@ -7218,7 +7213,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
MemPage *pRoot;
Pgno pgnoRoot;
int rc;
int ptfFlags; /* Page-type flage for the root page of new table */
u8 ptfFlags; /* Page-type flage for the root page of new table */
assert( sqlite3BtreeHoldsMutex(p) );
assert( pBt->inTransaction==TRANS_WRITE );
@@ -7446,15 +7441,6 @@ int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){
return rc;
}
/*
** Delete all information from the single table that pCur is open on.
**
** This routine only work for pCur on an ephemeral table.
*/
int sqlite3BtreeClearTableOfCursor(BtCursor *pCur){
return sqlite3BtreeClearTable(pCur->pBtree, pCur->pgnoRoot, 0);
}
/*
** Erase all information in a table and add the root of the table to
** the freelist. Except, the root of the principle table (the one on
+8 -8
View File
@@ -56,16 +56,15 @@ int sqlite3BtreeOpen(
** NOTE: These values must match the corresponding PAGER_ values in
** pager.h.
*/
#define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */
#define BTREE_MEMORY 2 /* This is an in-memory DB */
#define BTREE_SINGLE 4 /* The file contains at most 1 b-tree */
#define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */
#define BTREE_OMIT_JOURNAL 0x01 /* Do not create or use a rollback journal */
#define BTREE_MEMORY 0x02 /* This is an in-memory DB */
#define BTREE_SINGLE 0x04 /* The file contains at most 1 b-tree */
#define BTREE_UNORDERED 0x08 /* Use of a hash implementation is OK */
#define BTREE_SINGLE_INDEX 0x10 /* File contains one index btree */
int sqlite3BtreeClose(Btree*);
int sqlite3BtreeSetCacheSize(Btree*,int);
#if SQLITE_MAX_MMAP_SIZE>0
int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
#endif
int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
int sqlite3BtreeSetPagerFlags(Btree*,unsigned);
int sqlite3BtreeSyncDisabled(Btree*);
int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
@@ -115,7 +114,6 @@ int sqlite3BtreeIncrVacuum(Btree *);
int sqlite3BtreeDropTable(Btree*, int, int*);
int sqlite3BtreeClearTable(Btree*, int, int*);
int sqlite3BtreeClearTableOfCursor(BtCursor*);
void sqlite3BtreeTripAllCursors(Btree*, int);
void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
@@ -185,6 +183,8 @@ const void *sqlite3BtreeKeyFetch(BtCursor*, u32 *pAmt);
const void *sqlite3BtreeDataFetch(BtCursor*, u32 *pAmt);
int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
void sqlite3BtreeSetCachedRowid(BtCursor*, sqlite3_int64);
sqlite3_int64 sqlite3BtreeGetCachedRowid(BtCursor*);
char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
struct Pager *sqlite3BtreePager(Btree*);
+1
View File
@@ -500,6 +500,7 @@ struct BtCursor {
Pgno *aOverflow; /* Cache of overflow page locations */
#endif
Pgno pgnoRoot; /* The root page of this tree */
sqlite3_int64 cachedRowid; /* Next rowid cache. 0 means not valid */
CellInfo info; /* A parse of the cell we are pointing at */
i64 nKey; /* Size of pKey, or last integer key */
void *pKey; /* Saved key that was cursor's last known position */
+74 -41
View File
@@ -149,22 +149,20 @@ void sqlite3FinishCoding(Parse *pParse){
** transaction on each used database and to verify the schema cookie
** on each used database.
*/
if( db->mallocFailed==0 && (pParse->cookieMask || pParse->pConstExpr) ){
if( pParse->cookieGoto>0 ){
yDbMask mask;
int iDb, i;
assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
sqlite3VdbeJumpHere(v, 0);
int iDb, i, addr;
sqlite3VdbeJumpHere(v, pParse->cookieGoto-1);
for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){
if( (mask & pParse->cookieMask)==0 ) continue;
sqlite3VdbeUsesBtree(v, iDb);
sqlite3VdbeAddOp4Int(v,
OP_Transaction, /* Opcode */
iDb, /* P1 */
(mask & pParse->writeMask)!=0, /* P2 */
pParse->cookieValue[iDb], /* P3 */
db->aDb[iDb].pSchema->iGeneration /* P4 */
);
if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
if( db->init.busy==0 ){
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
sqlite3VdbeAddOp3(v, OP_VerifyCookie,
iDb, pParse->cookieValue[iDb],
db->aDb[iDb].pSchema->iGeneration);
}
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
for(i=0; i<pParse->nVtabLock; i++){
@@ -185,16 +183,17 @@ void sqlite3FinishCoding(Parse *pParse){
sqlite3AutoincrementBegin(pParse);
/* Code constant expressions that where factored out of inner loops */
addr = pParse->cookieGoto;
if( pParse->pConstExpr ){
ExprList *pEL = pParse->pConstExpr;
pParse->okConstFactor = 0;
pParse->cookieGoto = 0;
for(i=0; i<pEL->nExpr; i++){
sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg);
}
}
/* Finally, jump back to the beginning of the executable code. */
sqlite3VdbeAddOp2(v, OP_Goto, 0, 1);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
}
}
@@ -217,6 +216,7 @@ void sqlite3FinishCoding(Parse *pParse){
pParse->nSet = 0;
pParse->nVar = 0;
pParse->cookieMask = 0;
pParse->cookieGoto = 0;
}
/*
@@ -948,7 +948,7 @@ void sqlite3StartTable(
reg3 = ++pParse->nMem;
sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT);
sqlite3VdbeUsesBtree(v, iDb);
j1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v);
j1 = sqlite3VdbeAddOp1(v, OP_If, reg3);
fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
1 : SQLITE_MAX_FILE_FORMAT;
sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3);
@@ -2669,33 +2669,33 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
/* Open the sorter cursor if we are to use one. */
iSorter = pParse->nTab++;
sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, pIndex->nKeyCol, (char*)
sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)
sqlite3KeyInfoRef(pKey), P4_KEYINFO);
/* Open the table. Loop through all rows of the table, inserting index
** records into the sorter. */
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v);
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
regRecord = sqlite3GetTempReg(pParse);
sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0);
sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
sqlite3VdbeResolveLabel(v, iPartIdxLabel);
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
sqlite3VdbeJumpHere(v, addr1);
if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb,
(char *)pKey, P4_KEYINFO);
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v);
addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
assert( pKey!=0 || db->mallocFailed || pParse->nErr );
if( pIndex->onError!=OE_None && pKey!=0 ){
int j2 = sqlite3VdbeCurrentAddr(v) + 3;
sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
addr2 = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
pKey->nField - pIndex->nKeyCol); VdbeCoverage(v);
pKey->nField - pIndex->nKeyCol);
sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
}else{
addr2 = sqlite3VdbeCurrentAddr(v);
@@ -2704,7 +2704,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3ReleaseTempReg(pParse, regRecord);
sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp1(v, OP_Close, iTab);
@@ -3018,7 +3018,7 @@ Index *sqlite3CreateIndex(
pParse->checkSchema = 1;
goto exit_create_index;
}
assert( j<=0x7fff );
assert( pTab->nCol<=0x7fff && j<=0x7fff );
pIndex->aiColumn[i] = (i16)j;
if( pListItem->pExpr ){
int nColl;
@@ -3473,7 +3473,7 @@ SrcList *sqlite3SrcListEnlarge(
assert( iStart<=pSrc->nSrc );
/* Allocate additional space if needed */
if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){
if( pSrc->nSrc+nExtra>pSrc->nAlloc ){
SrcList *pNew;
int nAlloc = pSrc->nSrc+nExtra;
int nGot;
@@ -3485,7 +3485,7 @@ SrcList *sqlite3SrcListEnlarge(
}
pSrc = pNew;
nGot = (sqlite3DbMallocSize(db, pNew) - sizeof(*pSrc))/sizeof(pSrc->a[0])+1;
pSrc->nAlloc = nGot;
pSrc->nAlloc = (u8)nGot;
}
/* Move existing slots that come after the newly inserted slots
@@ -3493,7 +3493,7 @@ SrcList *sqlite3SrcListEnlarge(
for(i=pSrc->nSrc-1; i>=iStart; i--){
pSrc->a[i+nExtra] = pSrc->a[i];
}
pSrc->nSrc += nExtra;
pSrc->nSrc += (i8)nExtra;
/* Zero the newly allocated slots */
memset(&pSrc->a[iStart], 0, sizeof(pSrc->a[0])*nExtra);
@@ -3825,26 +3825,59 @@ int sqlite3OpenTempDatabase(Parse *pParse){
}
/*
** Record the fact that the schema cookie will need to be verified
** for database iDb. The code to actually verify the schema cookie
** will occur at the end of the top-level VDBE and will be generated
** later, by sqlite3FinishCoding().
** Generate VDBE code that will verify the schema cookie and start
** a read-transaction for all named database files.
**
** It is important that all schema cookies be verified and all
** read transactions be started before anything else happens in
** the VDBE program. But this routine can be called after much other
** code has been generated. So here is what we do:
**
** The first time this routine is called, we code an OP_Goto that
** will jump to a subroutine at the end of the program. Then we
** record every database that needs its schema verified in the
** pParse->cookieMask field. Later, after all other code has been
** generated, the subroutine that does the cookie verifications and
** starts the transactions will be coded and the OP_Goto P2 value
** will be made to point to that subroutine. The generation of the
** cookie verification subroutine code happens in sqlite3FinishCoding().
**
** If iDb<0 then code the OP_Goto only - don't set flag to verify the
** schema on any databases. This can be used to position the OP_Goto
** early in the code, before we know if any database tables will be used.
*/
void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
sqlite3 *db = pToplevel->db;
yDbMask mask;
assert( iDb>=0 && iDb<db->nDb );
assert( db->aDb[iDb].pBt!=0 || iDb==1 );
assert( iDb<SQLITE_MAX_ATTACHED+2 );
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
mask = ((yDbMask)1)<<iDb;
if( (pToplevel->cookieMask & mask)==0 ){
pToplevel->cookieMask |= mask;
pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
if( !OMIT_TEMPDB && iDb==1 ){
sqlite3OpenTempDatabase(pToplevel);
#ifndef SQLITE_OMIT_TRIGGER
if( pToplevel!=pParse ){
/* This branch is taken if a trigger is currently being coded. In this
** case, set cookieGoto to a non-zero value to show that this function
** has been called. This is used by the sqlite3ExprCodeConstants()
** function. */
pParse->cookieGoto = -1;
}
#endif
if( pToplevel->cookieGoto==0 ){
Vdbe *v = sqlite3GetVdbe(pToplevel);
if( v==0 ) return; /* This only happens if there was a prior error */
pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1;
}
if( iDb>=0 ){
sqlite3 *db = pToplevel->db;
yDbMask mask;
assert( iDb<db->nDb );
assert( db->aDb[iDb].pBt!=0 || iDb==1 );
assert( iDb<SQLITE_MAX_ATTACHED+2 );
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
mask = ((yDbMask)1)<<iDb;
if( (pToplevel->cookieMask & mask)==0 ){
pToplevel->cookieMask |= mask;
pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
if( !OMIT_TEMPDB && iDb==1 ){
sqlite3OpenTempDatabase(pToplevel);
}
}
}
}
-3
View File
@@ -215,9 +215,6 @@ static const char * const azCompileOpt[] = {
#ifdef SQLITE_OMIT_COMPOUND_SELECT
"OMIT_COMPOUND_SELECT",
#endif
#ifdef SQLITE_OMIT_CTE
"OMIT_CTE",
#endif
#ifdef SQLITE_OMIT_DATETIME_FUNCS
"OMIT_DATETIME_FUNCS",
#endif
+7 -13
View File
@@ -383,7 +383,9 @@ void sqlite3DeleteFrom(
sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet);
}else{
/* For a WITHOUT ROWID table, create an ephermeral table used to
** hold all primary keys for rows to be deleted. */
** hold all primary keys for rows to be deleted. Use OP_OpenEphemeral
** rather than OP_OpenHash since for efficiency reasons it is good to
** process the primary keys in order. */
pPk = sqlite3PrimaryKeyIndex(pTab);
assert( pPk!=0 );
nPk = pPk->nKeyCol;
@@ -443,7 +445,7 @@ void sqlite3DeleteFrom(
iKey = ++pParse->nMem;
nKey = 0; /* Zero tells OP_Found to use a composite key */
sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
sqlite3IndexAffinityStr(v, pPk), nPk);
sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey);
}else{
/* Get the rowid of the row to be deleted and remember it in the RowSet */
@@ -481,15 +483,13 @@ void sqlite3DeleteFrom(
if( aToOpen[iDataCur-iTabCur] ){
assert( pPk!=0 );
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
VdbeCoverage(v);
}
}else if( pPk ){
addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur);
sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey);
assert( nKey==0 ); /* OP_Found will use a composite key */
}else{
addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey);
VdbeCoverage(v);
assert( nKey==1 );
}
@@ -513,7 +513,7 @@ void sqlite3DeleteFrom(
if( okOnePass ){
sqlite3VdbeResolveLabel(v, addrBypass);
}else if( pPk ){
sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1);
sqlite3VdbeJumpHere(v, addrLoop);
}else{
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrLoop);
@@ -611,11 +611,7 @@ void sqlite3GenerateRowDelete(
** not attempt to delete it or fire any DELETE triggers. */
iLabel = sqlite3VdbeMakeLabel(v);
opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
if( !bNoSeek ){
sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
VdbeCoverageIf(v, opSeek==OP_NotExists);
VdbeCoverageIf(v, opSeek==OP_NotFound);
}
if( !bNoSeek ) sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
/* If there are any triggers to fire, allocate a range of registers to
** use for the old.* references in the triggers. */
@@ -657,8 +653,6 @@ void sqlite3GenerateRowDelete(
*/
if( addrStart<sqlite3VdbeCurrentAddr(v) ){
sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
VdbeCoverageIf(v, opSeek==OP_NotExists);
VdbeCoverageIf(v, opSeek==OP_NotFound);
}
/* Do FK processing. This call checks that any FK constraints that
+349 -316
View File
File diff suppressed because it is too large Load Diff
+9 -14
View File
@@ -340,11 +340,10 @@ static void fkLookupParent(
** search for a matching row in the parent table. */
if( nIncr<0 ){
sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk);
VdbeCoverage(v);
}
for(i=0; i<pFKey->nCol; i++){
int iReg = aiCol[i] + regData + 1;
sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk);
}
if( isIgnore==0 ){
@@ -361,19 +360,17 @@ static void fkLookupParent(
** will have INTEGER affinity applied to it, which may not be correct. */
sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp);
iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0);
VdbeCoverage(v);
/* If the parent table is the same as the child table, and we are about
** to increment the constraint-counter (i.e. this is an INSERT operation),
** then check if the row being inserted matches itself. If so, do not
** increment the constraint-counter. */
if( pTab==pFKey->pFrom && nIncr==1 ){
sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp);
}
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp);
sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
sqlite3VdbeJumpHere(v, iMustBeInt);
@@ -409,15 +406,15 @@ static void fkLookupParent(
/* The parent key is a composite key that includes the IPK column */
iParent = regData;
}
sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent);
sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
}
sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
}
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec,
sqlite3IndexAffinityStr(v,pIdx), nCol);
sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regTemp, nCol, regRec);
sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT);
sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0);
sqlite3ReleaseTempReg(pParse, regRec);
sqlite3ReleaseTempRange(pParse, regTemp, nCol);
@@ -555,7 +552,6 @@ static void fkScanChildren(
if( nIncr<0 ){
iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0);
VdbeCoverage(v);
}
/* Create an Expr object representing an SQL expression like:
@@ -718,7 +714,7 @@ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
}
if( !p ) return;
iSkip = sqlite3VdbeMakeLabel(v);
sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip);
}
pParse->disableTriggers = 1;
@@ -736,7 +732,6 @@ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
*/
if( (db->flags & SQLITE_DeferFKs)==0 ){
sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
VdbeCoverage(v);
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
OE_Abort, 0, P4_STATIC, P5_ConstraintFK);
}
@@ -896,7 +891,7 @@ void sqlite3FkCheck(
int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1;
for(i=0; i<pFKey->nCol; i++){
int iReg = pFKey->aCol[i].iFrom + regOld + 1;
sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump);
}
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1);
}
+1 -1
View File
@@ -1017,7 +1017,7 @@ static void charFunc(
){
unsigned char *z, *zOut;
int i;
zOut = z = sqlite3_malloc( argc*4+1 );
zOut = z = sqlite3_malloc( argc*4 );
if( z==0 ){
sqlite3_result_error_nomem(context);
return;
-1
View File
@@ -167,7 +167,6 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
0, /* nPage */
0, /* mxParserStack */
0, /* sharedCacheEnabled */
0, /* nWorker */
/* All the rest should always be initialized to zero */
0, /* isInit */
0, /* inProgress */
+249 -168
View File
@@ -98,16 +98,10 @@ const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
}
/*
** Compute the affinity string for table pTab, if it has not already been
** computed. As an optimization, omit trailing SQLITE_AFF_NONE affinities.
**
** If the affinity exists (if it is no entirely SQLITE_AFF_NONE values) and
** if iReg>0 then code an OP_Affinity opcode that will set the affinities
** for register iReg and following. Or if affinities exists and iReg==0,
** then just set the P4 operand of the previous opcode (which should be
** an OP_MakeRecord) to the affinity string.
**
** A column affinity string has one character per column:
** Set P4 of the most recently inserted opcode to a column affinity
** string for table pTab. A column affinity string has one character
** for each column indexed by the index, according to the affinity of the
** column:
**
** Character Column affinity
** ------------------------------
@@ -117,11 +111,19 @@ const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
** 'd' INTEGER
** 'e' REAL
*/
void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
int i;
char *zColAff = pTab->zColAff;
if( zColAff==0 ){
void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){
/* The first time a column affinity string for a particular table
** is required, it is allocated and populated here. It is then
** stored as a member of the Table structure for subsequent use.
**
** The column affinity string will eventually be deleted by
** sqlite3DeleteTable() when the Table structure itself is cleaned up.
*/
if( !pTab->zColAff ){
char *zColAff;
int i;
sqlite3 *db = sqlite3VdbeDb(v);
zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1);
if( !zColAff ){
db->mallocFailed = 1;
@@ -131,28 +133,22 @@ void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
for(i=0; i<pTab->nCol; i++){
zColAff[i] = pTab->aCol[i].affinity;
}
do{
zColAff[i--] = 0;
}while( i>=0 && zColAff[i]==SQLITE_AFF_NONE );
zColAff[pTab->nCol] = '\0';
pTab->zColAff = zColAff;
}
i = sqlite3Strlen30(zColAff);
if( i ){
if( iReg ){
sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i);
}else{
sqlite3VdbeChangeP4(v, -1, zColAff, i);
}
}
sqlite3VdbeChangeP4(v, -1, pTab->zColAff, P4_TRANSIENT);
}
/*
** Return non-zero if the table pTab in database iDb or any of its indices
** have been opened at any point in the VDBE program. This is used to see if
** have been opened at any point in the VDBE program beginning at location
** iStartAddr throught the end of the program. This is used to see if
** a statement of the form "INSERT INTO <iDb, pTab> SELECT ..." can
** run without using a temporary table for the results of the SELECT.
** run without using temporary table for the results of the SELECT.
*/
static int readsTable(Parse *p, int iDb, Table *pTab){
static int readsTable(Parse *p, int iStartAddr, int iDb, Table *pTab){
Vdbe *v = sqlite3GetVdbe(p);
int i;
int iEnd = sqlite3VdbeCurrentAddr(v);
@@ -160,7 +156,7 @@ static int readsTable(Parse *p, int iDb, Table *pTab){
VTable *pVTab = IsVirtual(pTab) ? sqlite3GetVTable(p->db, pTab) : 0;
#endif
for(i=1; i<iEnd; i++){
for(i=iStartAddr; i<iEnd; i++){
VdbeOp *pOp = sqlite3VdbeGetOp(v, i);
assert( pOp!=0 );
if( pOp->opcode==OP_OpenRead && pOp->p3==iDb ){
@@ -261,14 +257,14 @@ void sqlite3AutoincrementBegin(Parse *pParse){
sqlite3VdbeAddOp3(v, OP_Null, 0, memId, memId+1);
addr = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0);
sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9);
sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId);
sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId);
sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1);
sqlite3VdbeAddOp3(v, OP_Column, 0, 1, memId);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+9);
sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2);
sqlite3VdbeAddOp2(v, OP_Integer, 0, memId);
sqlite3VdbeAddOp0(v, OP_Close);
}
@@ -303,16 +299,25 @@ void sqlite3AutoincrementEnd(Parse *pParse){
assert( v );
for(p = pParse->pAinc; p; p = p->pNext){
Db *pDb = &db->aDb[p->iDb];
int j1;
int j1, j2, j3, j4, j5;
int iRec;
int memId = p->regCtr;
iRec = sqlite3GetTempReg(pParse);
assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); VdbeCoverage(v);
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1);
j2 = sqlite3VdbeAddOp0(v, OP_Rewind);
j3 = sqlite3VdbeAddOp3(v, OP_Column, 0, 0, iRec);
j4 = sqlite3VdbeAddOp3(v, OP_Eq, memId-1, 0, iRec);
sqlite3VdbeAddOp2(v, OP_Next, 0, j3);
sqlite3VdbeJumpHere(v, j2);
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1);
j5 = sqlite3VdbeAddOp0(v, OP_Goto);
sqlite3VdbeJumpHere(v, j4);
sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeJumpHere(v, j5);
sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec);
sqlite3VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
@@ -330,6 +335,97 @@ void sqlite3AutoincrementEnd(Parse *pParse){
#endif /* SQLITE_OMIT_AUTOINCREMENT */
/*
** Generate code for a co-routine that will evaluate a subquery one
** row at a time.
**
** The pSelect parameter is the subquery that the co-routine will evaluation.
** Information about the location of co-routine and the registers it will use
** is returned by filling in the pDest object.
**
** Registers are allocated as follows:
**
** pDest->iSDParm The register holding the next entry-point of the
** co-routine. Run the co-routine to its next breakpoint
** by calling "OP_Yield $X" where $X is pDest->iSDParm.
**
** pDest->iSDParm+1 The register holding the "completed" flag for the
** co-routine. This register is 0 if the previous Yield
** generated a new result row, or 1 if the subquery
** has completed. If the Yield is called again
** after this register becomes 1, then the VDBE will
** halt with an SQLITE_INTERNAL error.
**
** pDest->iSdst First result register.
**
** pDest->nSdst Number of result registers.
**
** This routine handles all of the register allocation and fills in the
** pDest structure appropriately.
**
** Here is a schematic of the generated code assuming that X is the
** co-routine entry-point register reg[pDest->iSDParm], that EOF is the
** completed flag reg[pDest->iSDParm+1], and R and S are the range of
** registers that hold the result set, reg[pDest->iSdst] through
** reg[pDest->iSdst+pDest->nSdst-1]:
**
** X <- A
** EOF <- 0
** goto B
** A: setup for the SELECT
** loop rows in the SELECT
** load results into registers R..S
** yield X
** end loop
** cleanup after the SELECT
** EOF <- 1
** yield X
** halt-error
** B:
**
** To use this subroutine, the caller generates code as follows:
**
** [ Co-routine generated by this subroutine, shown above ]
** S: yield X
** if EOF goto E
** if skip this row, goto C
** if terminate loop, goto E
** deal with this row
** C: goto S
** E:
*/
int sqlite3CodeCoroutine(Parse *pParse, Select *pSelect, SelectDest *pDest){
int regYield; /* Register holding co-routine entry-point */
int regEof; /* Register holding co-routine completion flag */
int addrTop; /* Top of the co-routine */
int j1; /* Jump instruction */
int rc; /* Result code */
Vdbe *v; /* VDBE under construction */
regYield = ++pParse->nMem;
regEof = ++pParse->nMem;
v = sqlite3GetVdbe(pParse);
addrTop = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_Integer, addrTop+2, regYield); /* X <- A */
VdbeComment((v, "Co-routine entry point"));
sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof); /* EOF <- 0 */
VdbeComment((v, "Co-routine completion flag"));
sqlite3SelectDestInit(pDest, SRT_Coroutine, regYield);
j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
rc = sqlite3Select(pParse, pSelect, pDest);
assert( pParse->nErr==0 || rc );
if( pParse->db->mallocFailed && rc==SQLITE_OK ) rc = SQLITE_NOMEM;
if( rc ) return rc;
sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */
sqlite3VdbeAddOp1(v, OP_Yield, regYield); /* yield X */
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort);
VdbeComment((v, "End of coroutine"));
sqlite3VdbeJumpHere(v, j1); /* label B: */
return rc;
}
/* Forward declaration */
static int xferOptimization(
Parse *pParse, /* Parser context */
@@ -392,6 +488,7 @@ static int xferOptimization(
** and the SELECT clause does not read from <table> at any time.
** The generated code follows this template:
**
** EOF <- 0
** X <- A
** goto B
** A: setup for the SELECT
@@ -400,9 +497,12 @@ static int xferOptimization(
** yield X
** end loop
** cleanup after the SELECT
** end-coroutine X
** EOF <- 1
** yield X
** goto A
** B: open write cursor to <table> and its indices
** C: yield X, at EOF goto D
** C: yield X
** if EOF goto D
** insert the select result into <table> from R..R+n
** goto C
** D: cleanup
@@ -413,6 +513,7 @@ static int xferOptimization(
** we have to use a intermediate table to store the results of
** the select. The template is like this:
**
** EOF <- 0
** X <- A
** goto B
** A: setup for the SELECT
@@ -421,9 +522,12 @@ static int xferOptimization(
** yield X
** end loop
** cleanup after the SELECT
** end co-routine R
** EOF <- 1
** yield X
** halt-error
** B: open temp table
** L: yield X, at EOF goto M
** L: yield X
** if EOF goto M
** insert row from R..R+n into temp table
** goto L
** M: open write cursor to <table> and its indices
@@ -453,16 +557,16 @@ void sqlite3Insert(
int iIdxCur = 0; /* First index cursor */
int ipkColumn = -1; /* Column that is the INTEGER PRIMARY KEY */
int endOfLoop; /* Label for the end of the insertion loop */
int useTempTable = 0; /* Store SELECT results in intermediate table */
int srcTab = 0; /* Data comes from this temporary cursor if >=0 */
int addrInsTop = 0; /* Jump to label "D" */
int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */
int addrSelect = 0; /* Address of coroutine that implements the SELECT */
SelectDest dest; /* Destination for SELECT on rhs of INSERT */
int iDb; /* Index of database holding TABLE */
Db *pDb; /* The database containing table being inserted into */
u8 useTempTable = 0; /* Store SELECT results in intermediate table */
u8 appendFlag = 0; /* True if the insert is likely to be an append */
u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */
u8 bIdListInOrder = 1; /* True if IDLIST is in table order */
int appendFlag = 0; /* True if the insert is likely to be an append */
int withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */
ExprList *pList = 0; /* List of VALUES() to be inserted */
/* Register allocations */
@@ -472,6 +576,7 @@ void sqlite3Insert(
int regIns; /* Block of regs holding rowid+data being inserted */
int regRowid; /* registers holding insert rowid */
int regData; /* register holding first column to insert */
int regEof = 0; /* Register recording end of SELECT data */
int *aRegIdx = 0; /* One register allocated to each index */
#ifndef SQLITE_OMIT_TRIGGER
@@ -574,56 +679,6 @@ void sqlite3Insert(
*/
regAutoinc = autoIncBegin(pParse, iDb, pTab);
/* Allocate registers for holding the rowid of the new row,
** the content of the new row, and the assemblied row record.
*/
regRowid = regIns = pParse->nMem+1;
pParse->nMem += pTab->nCol + 1;
if( IsVirtual(pTab) ){
regRowid++;
pParse->nMem++;
}
regData = regRowid+1;
/* If the INSERT statement included an IDLIST term, then make sure
** all elements of the IDLIST really are columns of the table and
** remember the column indices.
**
** If the table has an INTEGER PRIMARY KEY column and that column
** is named in the IDLIST, then record in the ipkColumn variable
** the index into IDLIST of the primary key column. ipkColumn is
** the index of the primary key as it appears in IDLIST, not as
** is appears in the original table. (The index of the INTEGER
** PRIMARY KEY in the original table is pTab->iPKey.)
*/
if( pColumn ){
for(i=0; i<pColumn->nId; i++){
pColumn->a[i].idx = -1;
}
for(i=0; i<pColumn->nId; i++){
for(j=0; j<pTab->nCol; j++){
if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
pColumn->a[i].idx = j;
if( i!=j ) bIdListInOrder = 0;
if( j==pTab->iPKey ){
ipkColumn = i; assert( !withoutRowid );
}
break;
}
}
if( j>=pTab->nCol ){
if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){
ipkColumn = i;
}else{
sqlite3ErrorMsg(pParse, "table %S has no column named %s",
pTabList, 0, pColumn->a[i].zName);
pParse->checkSchema = 1;
goto insert_cleanup;
}
}
}
}
/* Figure out how many columns of data are supplied. If the data
** is coming from a SELECT statement, then generate a co-routine that
** produces a single row of the SELECT on each invocation. The
@@ -631,24 +686,14 @@ void sqlite3Insert(
*/
if( pSelect ){
/* Data is coming from a SELECT. Generate a co-routine to run the SELECT */
int regYield; /* Register holding co-routine entry-point */
int addrTop; /* Top of the co-routine */
int rc; /* Result code */
int rc = sqlite3CodeCoroutine(pParse, pSelect, &dest);
if( rc ) goto insert_cleanup;
regYield = ++pParse->nMem;
addrTop = sqlite3VdbeCurrentAddr(v) + 1;
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
dest.iSdst = bIdListInOrder ? regData : 0;
dest.nSdst = pTab->nCol;
rc = sqlite3Select(pParse, pSelect, &dest);
regEof = dest.iSDParm + 1;
regFromSelect = dest.iSdst;
assert( pParse->nErr==0 || rc );
if( rc || db->mallocFailed ) goto insert_cleanup;
sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
assert( pSelect->pEList );
nColumn = pSelect->pEList->nExpr;
assert( dest.nSdst==nColumn );
/* Set useTempTable to TRUE if the result of the SELECT statement
** should be written into a temporary table (template 4). Set to
@@ -659,7 +704,7 @@ void sqlite3Insert(
** of the tables being read by the SELECT statement. Also use a
** temp table in the case of row triggers.
*/
if( pTrigger || readsTable(pParse, iDb, pTab) ){
if( pTrigger || readsTable(pParse, addrSelect, iDb, pTab) ){
useTempTable = 1;
}
@@ -669,25 +714,31 @@ void sqlite3Insert(
** here is from the 4th template:
**
** B: open temp table
** L: yield X, goto M at EOF
** L: yield X
** if EOF goto M
** insert row from R..R+n into temp table
** goto L
** M: ...
**
** Use OP_OpenEphemeral, not OP_OpenHash, so that srcTab behaves as
** a FIFO.
*/
int regRec; /* Register to hold packed record */
int regTempRowid; /* Register to hold temp table ROWID */
int addrL; /* Label "L" */
int addrTop; /* Label "L" */
int addrIf; /* Address of jump to M */
srcTab = pParse->nTab++;
regRec = sqlite3GetTempReg(pParse);
regTempRowid = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
addrL = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v);
addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
addrIf = sqlite3VdbeAddOp1(v, OP_If, regEof);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrL);
sqlite3VdbeJumpHere(v, addrL);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
sqlite3VdbeJumpHere(v, addrIf);
sqlite3ReleaseTempReg(pParse, regRec);
sqlite3ReleaseTempReg(pParse, regTempRowid);
}
@@ -708,14 +759,6 @@ void sqlite3Insert(
}
}
/* If there is no IDLIST term but the table has an integer primary
** key, the set the ipkColumn variable to the integer primary key
** column index in the original table definition.
*/
if( pColumn==0 && nColumn>0 ){
ipkColumn = pTab->iPKey;
}
/* Make sure the number of columns in the source data matches the number
** of columns to be inserted into the table.
*/
@@ -734,6 +777,52 @@ void sqlite3Insert(
sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);
goto insert_cleanup;
}
/* If the INSERT statement included an IDLIST term, then make sure
** all elements of the IDLIST really are columns of the table and
** remember the column indices.
**
** If the table has an INTEGER PRIMARY KEY column and that column
** is named in the IDLIST, then record in the ipkColumn variable
** the index into IDLIST of the primary key column. ipkColumn is
** the index of the primary key as it appears in IDLIST, not as
** is appears in the original table. (The index of the INTEGER
** PRIMARY KEY in the original table is pTab->iPKey.)
*/
if( pColumn ){
for(i=0; i<pColumn->nId; i++){
pColumn->a[i].idx = -1;
}
for(i=0; i<pColumn->nId; i++){
for(j=0; j<pTab->nCol; j++){
if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
pColumn->a[i].idx = j;
if( j==pTab->iPKey ){
ipkColumn = i; assert( !withoutRowid );
}
break;
}
}
if( j>=pTab->nCol ){
if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){
ipkColumn = i;
}else{
sqlite3ErrorMsg(pParse, "table %S has no column named %s",
pTabList, 0, pColumn->a[i].zName);
pParse->checkSchema = 1;
goto insert_cleanup;
}
}
}
}
/* If there is no IDLIST term but the table has an integer primary
** key, the set the ipkColumn variable to the integer primary key
** column index in the original table definition.
*/
if( pColumn==0 && nColumn>0 ){
ipkColumn = pTab->iPKey;
}
/* Initialize the count of rows to be inserted
*/
@@ -761,27 +850,39 @@ void sqlite3Insert(
/* This block codes the top of loop only. The complete loop is the
** following pseudocode (template 4):
**
** rewind temp table, if empty goto D
** rewind temp table
** C: loop over rows of intermediate table
** transfer values form intermediate table into <table>
** end loop
** D: ...
*/
addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab); VdbeCoverage(v);
addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab);
addrCont = sqlite3VdbeCurrentAddr(v);
}else if( pSelect ){
/* This block codes the top of loop only. The complete loop is the
** following pseudocode (template 3):
**
** C: yield X, at EOF goto D
** C: yield X
** if EOF goto D
** insert the select result into <table> from R..R+n
** goto C
** D: ...
*/
addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
VdbeCoverage(v);
addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
addrInsTop = sqlite3VdbeAddOp1(v, OP_If, regEof);
}
/* Allocate registers for holding the rowid of the new row,
** the content of the new row, and the assemblied row record.
*/
regRowid = regIns = pParse->nMem+1;
pParse->nMem += pTab->nCol + 1;
if( IsVirtual(pTab) ){
regRowid++;
pParse->nMem++;
}
regData = regRowid+1;
/* Run the BEFORE and INSTEAD OF triggers, if there are any
*/
endOfLoop = sqlite3VdbeMakeLabel(v);
@@ -805,10 +906,10 @@ void sqlite3Insert(
assert( pSelect==0 ); /* Otherwise useTempTable is true */
sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols);
}
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v);
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols);
sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v);
sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols);
}
/* Cannot have triggers on a virtual table. If it were possible,
@@ -842,7 +943,8 @@ void sqlite3Insert(
** table column affinities.
*/
if( !isView ){
sqlite3TableAffinity(v, pTab, regCols+1);
sqlite3VdbeAddOp2(v, OP_Affinity, regCols+1, pTab->nCol);
sqlite3TableAffinityStr(v, pTab);
}
/* Fire BEFORE or INSTEAD OF triggers */
@@ -864,7 +966,7 @@ void sqlite3Insert(
if( useTempTable ){
sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regRowid);
}else if( pSelect ){
sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid);
sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+ipkColumn, regRowid);
}else{
VdbeOp *pOp;
sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid);
@@ -883,14 +985,14 @@ void sqlite3Insert(
if( !appendFlag ){
int j1;
if( !IsVirtual(pTab) ){
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v);
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid);
sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
sqlite3VdbeJumpHere(v, j1);
}else{
j1 = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2);
}
sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); VdbeCoverage(v);
sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid);
}
}else if( IsVirtual(pTab) || withoutRowid ){
sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid);
@@ -910,9 +1012,8 @@ void sqlite3Insert(
/* The value of the INTEGER PRIMARY KEY column is always a NULL.
** Whenever this column is read, the rowid will be substituted
** in its place. Hence, fill this column with a NULL to avoid
** taking up data space with information that will never be used.
** As there may be shallow copies of this value, make it a soft-NULL */
sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore);
** taking up data space with information that will never be used. */
sqlite3VdbeAddOp2(v, OP_Null, 0, iRegStore);
continue;
}
if( pColumn==0 ){
@@ -929,13 +1030,11 @@ void sqlite3Insert(
}
}
if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){
sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore);
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, iRegStore);
}else if( useTempTable ){
sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore);
}else if( pSelect ){
if( regFromSelect!=regData ){
sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore);
}
sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore);
}else{
sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore);
}
@@ -981,7 +1080,7 @@ void sqlite3Insert(
*/
sqlite3VdbeResolveLabel(v, endOfLoop);
if( useTempTable ){
sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont);
sqlite3VdbeJumpHere(v, addrInsTop);
sqlite3VdbeAddOp1(v, OP_Close, srcTab);
}else if( pSelect ){
@@ -1148,7 +1247,6 @@ void sqlite3GenerateConstraintChecks(
int ipkTop = 0; /* Top of the rowid change constraint check */
int ipkBottom = 0; /* Bottom of the rowid change constraint check */
u8 isUpdate; /* True if this is an UPDATE operation */
u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */
int regRowid = -1; /* Register holding ROWID value */
isUpdate = regOldData!=0;
@@ -1203,17 +1301,15 @@ void sqlite3GenerateConstraintChecks(
sqlite3VdbeAddOp4(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError,
regNewData+1+i, zMsg, P4_DYNAMIC);
sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
VdbeCoverage(v);
break;
}
case OE_Ignore: {
sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
VdbeCoverage(v);
break;
}
default: {
assert( onError==OE_Replace );
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i); VdbeCoverage(v);
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i);
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
sqlite3VdbeJumpHere(v, j1);
break;
@@ -1265,8 +1361,6 @@ void sqlite3GenerateConstraintChecks(
** it might have changed. Skip the conflict logic below if the rowid
** is unchanged. */
sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
VdbeCoverage(v);
}
/* If the response to a rowid conflict is REPLACE but the response
@@ -1286,7 +1380,6 @@ void sqlite3GenerateConstraintChecks(
/* Check to see if the new rowid already exists in the table. Skip
** the following conflict logic if it does not. */
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
VdbeCoverage(v);
/* Generate code that deals with a rowid collision */
switch( onError ){
@@ -1365,10 +1458,6 @@ void sqlite3GenerateConstraintChecks(
int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */
if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */
if( bAffinityDone==0 ){
sqlite3TableAffinity(v, pTab, regNewData+1);
bAffinityDone = 1;
}
iThisCur = iIdxCur+ix;
addrUniqueOk = sqlite3VdbeMakeLabel(v);
@@ -1399,6 +1488,7 @@ void sqlite3GenerateConstraintChecks(
VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName));
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
VdbeComment((v, "for %s", pIdx->zName));
sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn);
@@ -1426,7 +1516,7 @@ void sqlite3GenerateConstraintChecks(
/* Check to see if the new index entry will be unique */
sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
regIdx, pIdx->nKeyCol); VdbeCoverage(v);
regIdx, pIdx->nKeyCol);
/* Generate code to handle collisions */
regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField);
@@ -1437,8 +1527,6 @@ void sqlite3GenerateConstraintChecks(
** is different from old-rowid */
if( isUpdate ){
sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
VdbeCoverage(v);
}
}else{
int x;
@@ -1474,9 +1562,6 @@ void sqlite3GenerateConstraintChecks(
sqlite3VdbeAddOp4(v, op,
regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
VdbeCoverageIf(v, op==OP_Eq);
VdbeCoverageIf(v, op==OP_Ne);
}
}
}
@@ -1548,17 +1633,14 @@ void sqlite3CompleteInsertion(
int regData; /* Content registers (after the rowid) */
int regRec; /* Register holding assemblied record for the table */
int i; /* Loop counter */
u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
if( aRegIdx[i]==0 ) continue;
bAffinityDone = 1;
if( pIdx->pPartIdxWhere ){
sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
VdbeCoverage(v);
}
sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]);
pik_flags = 0;
@@ -1573,7 +1655,7 @@ void sqlite3CompleteInsertion(
regData = regNewData + 1;
regRec = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
if( !bAffinityDone ) sqlite3TableAffinity(v, pTab, 0);
sqlite3TableAffinityStr(v, pTab);
sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol);
if( pParse->nested ){
pik_flags = 0;
@@ -1942,17 +2024,16 @@ static int xferOptimization(
**
** (3) onError is something other than OE_Abort and OE_Rollback.
*/
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); VdbeCoverage(v);
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0);
emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
sqlite3VdbeJumpHere(v, addr1);
}
if( HasRowid(pSrc) ){
sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
if( pDest->iPKey>=0 ){
addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
VdbeCoverage(v);
sqlite3RowidConstraint(pParse, onError, pDest);
sqlite3VdbeJumpHere(v, addr2);
autoIncStep(pParse, regAutoinc, regRowid);
@@ -1966,7 +2047,7 @@ static int xferOptimization(
sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid);
sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
sqlite3VdbeChangeP4(v, -1, pDest->zName, 0);
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1);
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
}else{
@@ -1985,15 +2066,15 @@ static int xferOptimization(
sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx);
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
VdbeComment((v, "%s", pDestIdx->zName));
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
}
if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest);
sqlite3VdbeJumpHere(v, emptySrcTest);
sqlite3ReleaseTempReg(pParse, regRowid);
sqlite3ReleaseTempReg(pParse, regData);
if( emptyDestTest ){
-31
View File
@@ -515,13 +515,6 @@ int sqlite3_config(int op, ...){
}
#endif
case SQLITE_CONFIG_WORKER_THREADS: {
int n = va_arg(ap, int);
if( n>SQLITE_MAX_WORKER_THREADS ) n = SQLITE_MAX_WORKER_THREADS;
if( n>=0 ) sqlite3GlobalConfig.nWorker = n;
break;
}
default: {
rc = SQLITE_ERROR;
break;
@@ -807,7 +800,6 @@ static void disconnectAllVtab(sqlite3 *db){
}
}
}
sqlite3VtabUnlockList(db);
sqlite3BtreeLeaveAll(db);
#else
UNUSED_PARAMETER(db);
@@ -2504,7 +2496,6 @@ static int openDatabase(
db->nextAutovac = -1;
db->szMmap = sqlite3GlobalConfig.szMmap;
db->nextPagesize = 0;
db->nMaxSorterMmap = 0x7FFFFFFF;
db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
| SQLITE_AutoIndex
@@ -3316,28 +3307,6 @@ int sqlite3_test_control(int op, ...){
break;
}
/* sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr);
**
** Set the VDBE coverage callback function to xCallback with context
** pointer ptr.
*/
case SQLITE_TESTCTRL_VDBE_COVERAGE: {
#ifdef SQLITE_VDBE_COVERAGE
typedef void (*branch_callback)(void*,int,u8,u8);
sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback);
sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*);
#endif
break;
}
/* sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, nMax); */
case SQLITE_TESTCTRL_SORTER_MMAP: {
sqlite3 *db = va_arg(ap, sqlite3*);
db->nMaxSorterMmap = va_arg(ap, int);
break;
}
}
va_end(ap);
#endif /* SQLITE_OMIT_BUILTIN_TEST */
+1 -14
View File
@@ -248,7 +248,7 @@ static void *memsys5MallocUnsafe(int nByte){
** block. If not, then split a block of the next larger power of
** two in order to create a new free block of size iLogsize.
*/
for(iBin=iLogsize; iBin<=LOGMAX && mem5.aiFreelist[iBin]<0; iBin++){}
for(iBin=iLogsize; mem5.aiFreelist[iBin]<0 && iBin<=LOGMAX; iBin++){}
if( iBin>LOGMAX ){
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte);
@@ -275,12 +275,6 @@ static void *memsys5MallocUnsafe(int nByte){
if( mem5.maxCount<mem5.currentCount ) mem5.maxCount = mem5.currentCount;
if( mem5.maxOut<mem5.currentOut ) mem5.maxOut = mem5.currentOut;
#ifdef SQLITE_DEBUG
/* Make sure the allocated memory does not assume that it is set to zero
** or retains a value from a previous allocation */
memset(&mem5.zPool[i*mem5.szAtom], 0xAA, iFullSz);
#endif
/* Return a pointer to the allocated memory. */
return (void*)&mem5.zPool[i*mem5.szAtom];
}
@@ -338,13 +332,6 @@ static void memsys5FreeUnsafe(void *pOld){
}
size *= 2;
}
#ifdef SQLITE_DEBUG
/* Overwrite freed memory with the 0x55 bit pattern to verify that it is
** not used after being freed */
memset(&mem5.zPool[iBlock*mem5.szAtom], 0x55, size);
#endif
memsys5Link(iBlock, iLogsize);
}
+49 -59
View File
@@ -83,6 +83,32 @@
# endif
#endif
/*
** These #defines should enable >2GB file support on Posix if the
** underlying operating system supports it. If the OS lacks
** large file support, these should be no-ops.
**
** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
** on the compiler command line. This is necessary if you are compiling
** on a recent machine (ex: RedHat 7.2) but you want your code to work
** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2
** without this option, LFS is enable. But LFS does not exist in the kernel
** in RedHat 6.0, so the code won't work. Hence, for maximum binary
** portability you should omit LFS.
**
** The previous paragraph was written in 2005. (This paragraph is written
** on 2008-11-28.) These days, all Linux kernels support large files, so
** you should probably leave LFS enabled. But some embedded platforms might
** lack LFS in which case the SQLITE_DISABLE_LFS macro might still be useful.
*/
#ifndef SQLITE_DISABLE_LFS
# define _LARGE_FILE 1
# ifndef _FILE_OFFSET_BITS
# define _FILE_OFFSET_BITS 64
# endif
# define _LARGEFILE_SOURCE 1
#endif
/*
** standard include files.
*/
@@ -323,7 +349,6 @@ static int posixFchown(int fd, uid_t uid, gid_t gid){
/* Forward reference */
static int openDirectory(const char*, int*);
static int unixGetpagesize(void);
/*
** Many system calls are accessed through pointer-to-functions so that
@@ -447,9 +472,6 @@ static struct unix_syscall {
#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
#endif
{ "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 },
#define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent)
}; /* End of the overrideable system calls */
/*
@@ -4109,36 +4131,6 @@ static int unixShmSystemLock(
return rc;
}
/*
** Return the system page size.
**
** This function should not be called directly by other code in this file.
** Instead, it should be called via macro osGetpagesize().
*/
static int unixGetpagesize(void){
#if defined(_BSD_SOURCE)
return getpagesize();
#else
return (int)sysconf(_SC_PAGESIZE);
#endif
}
/*
** Return the minimum number of 32KB shm regions that should be mapped at
** a time, assuming that each mapping must be an integer multiple of the
** current system page-size.
**
** Usually, this is 1. The exception seems to be systems that are configured
** to use 64KB pages - in this case each mapping must cover at least two
** shm regions.
*/
static int unixShmRegionPerMap(void){
int shmsz = 32*1024; /* SHM region size */
int pgsz = osGetpagesize(); /* System page size */
assert( ((pgsz-1)&pgsz)==0 ); /* Page size must be a power of 2 */
if( pgsz<shmsz ) return 1;
return pgsz/shmsz;
}
/*
** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0.
@@ -4150,11 +4142,10 @@ static void unixShmPurge(unixFile *pFd){
unixShmNode *p = pFd->pInode->pShmNode;
assert( unixMutexHeld() );
if( p && p->nRef==0 ){
int nShmPerMap = unixShmRegionPerMap();
int i;
assert( p->pInode==pFd->pInode );
sqlite3_mutex_free(p->mutex);
for(i=0; i<p->nRegion; i+=nShmPerMap){
for(i=0; i<p->nRegion; i++){
if( p->h>=0 ){
osMunmap(p->apRegion[i], p->szRegion);
}else{
@@ -4361,8 +4352,6 @@ static int unixShmMap(
unixShm *p;
unixShmNode *pShmNode;
int rc = SQLITE_OK;
int nShmPerMap = unixShmRegionPerMap();
int nReqRegion;
/* If the shared-memory file has not yet been opened, open it now. */
if( pDbFd->pShm==0 ){
@@ -4378,12 +4367,9 @@ static int unixShmMap(
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;
if( pShmNode->nRegion<nReqRegion ){
if( pShmNode->nRegion<=iRegion ){
char **apNew; /* New apRegion[] array */
int nByte = nReqRegion*szRegion; /* Minimum required file size */
int nByte = (iRegion+1)*szRegion; /* Minimum required file size */
struct stat sStat; /* Used by fstat() */
pShmNode->szRegion = szRegion;
@@ -4432,19 +4418,17 @@ static int unixShmMap(
/* Map the requested memory region into this processes address space. */
apNew = (char **)sqlite3_realloc(
pShmNode->apRegion, nReqRegion*sizeof(char *)
pShmNode->apRegion, (iRegion+1)*sizeof(char *)
);
if( !apNew ){
rc = SQLITE_IOERR_NOMEM;
goto shmpage_out;
}
pShmNode->apRegion = apNew;
while( pShmNode->nRegion<nReqRegion ){
int nMap = szRegion*nShmPerMap;
int i;
while(pShmNode->nRegion<=iRegion){
void *pMem;
if( pShmNode->h>=0 ){
pMem = osMmap(0, nMap,
pMem = osMmap(0, szRegion,
pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE,
MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
);
@@ -4460,11 +4444,8 @@ static int unixShmMap(
}
memset(pMem, 0, szRegion);
}
for(i=0; i<nShmPerMap; i++){
pShmNode->apRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i];
}
pShmNode->nRegion += nShmPerMap;
pShmNode->apRegion[pShmNode->nRegion] = pMem;
pShmNode->nRegion++;
}
}
@@ -4678,6 +4659,19 @@ static void unixUnmapfile(unixFile *pFd){
}
}
/*
** Return the system page size.
*/
static int unixGetPagesize(void){
#if HAVE_MREMAP
return 512;
#elif defined(_BSD_SOURCE)
return getpagesize();
#else
return (int)sysconf(_SC_PAGESIZE);
#endif
}
/*
** Attempt to set the size of the memory mapping maintained by file
** descriptor pFd to nNew bytes. Any existing mapping is discarded.
@@ -4714,12 +4708,8 @@ static void unixRemapfile(
if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
if( pOrig ){
#if HAVE_MREMAP
i64 nReuse = pFd->mmapSize;
#else
const int szSyspage = osGetpagesize();
const int szSyspage = unixGetPagesize();
i64 nReuse = (pFd->mmapSize & ~(szSyspage-1));
#endif
u8 *pReq = &pOrig[nReuse];
/* Unmap any pages of the existing mapping that cannot be reused. */
@@ -7465,7 +7455,7 @@ int sqlite3_os_init(void){
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
assert( ArraySize(aSyscall)==25 );
assert( ArraySize(aSyscall)==24 );
/* Register all VFSes defined in the aVfs[] array */
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
+5 -32
View File
@@ -1279,13 +1279,6 @@ void sqlite3_win32_sleep(DWORD milliseconds){
#endif
}
DWORD sqlite3Win32Wait(HANDLE hObject){
DWORD rc;
while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
TRUE))==WAIT_IO_COMPLETION ){}
return rc;
}
/*
** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
** or WinCE. Return false (zero) for Win95, Win98, or WinME.
@@ -5142,29 +5135,15 @@ static int winFullPathname(
** Interfaces for opening a shared library, finding entry points
** within the shared library, and closing the shared library.
*/
/*
** Interfaces for opening a shared library, finding entry points
** within the shared library, and closing the shared library.
*/
static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
HANDLE h;
#if defined(__CYGWIN__)
int nFull = pVfs->mxPathname+1;
char *zFull = sqlite3MallocZero( nFull );
void *zConverted = 0;
if( zFull==0 ){
OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
return 0;
}
if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){
sqlite3_free(zFull);
OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
return 0;
}
zConverted = winConvertFromUtf8Filename(zFull);
sqlite3_free(zFull);
#else
void *zConverted = winConvertFromUtf8Filename(zFilename);
UNUSED_PARAMETER(pVfs);
#endif
if( zConverted==0 ){
OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
return 0;
}
if( osIsNT() ){
@@ -5179,7 +5158,6 @@ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
h = osLoadLibraryA((char*)zConverted);
}
#endif
OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h));
sqlite3_free(zConverted);
return (void*)h;
}
@@ -5188,17 +5166,12 @@ static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut);
}
static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
FARPROC proc;
UNUSED_PARAMETER(pVfs);
proc = osGetProcAddressA((HANDLE)pH, zSym);
OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n",
(void*)pH, zSym, (void*)proc));
return (void(*)(void))proc;
return (void(*)(void))osGetProcAddressA((HANDLE)pH, zSym);
}
static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
UNUSED_PARAMETER(pVfs);
osFreeLibrary((HANDLE)pHandle);
OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle));
}
#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
#define winDlOpen 0
+10 -11
View File
@@ -1624,11 +1624,12 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){
if( !zMaster
|| pPager->journalMode==PAGER_JOURNALMODE_MEMORY
|| !isOpen(pPager->jfd)
|| pPager->journalMode==PAGER_JOURNALMODE_OFF
){
return SQLITE_OK;
}
pPager->setMaster = 1;
assert( isOpen(pPager->jfd) );
assert( pPager->journalHdr <= pPager->journalOff );
/* Calculate the length in bytes and the checksum of zMaster */
@@ -1682,7 +1683,7 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){
** already in memory.
*/
static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
PgHdr *p = 0; /* Return value */
PgHdr *p; /* Return value */
/* It is not possible for a call to PcacheFetch() with createFlag==0 to
** fail, since no attempt to allocate dynamic memory will be made.
@@ -4888,17 +4889,15 @@ static int hasHotJournal(Pager *pPager, int *pExists){
if( rc==SQLITE_OK && !locked ){
Pgno nPage; /* Number of pages in database file */
/* Check the size of the database file. If it consists of 0 pages,
** then delete the journal file. See the header comment above for
** the reasoning here. Delete the obsolete journal file under
** a RESERVED lock to avoid race conditions and to avoid violating
** [H33020].
*/
rc = pagerPagecount(pPager, &nPage);
if( rc==SQLITE_OK ){
/* If the database is zero pages in size, that means that either (1) the
** journal is a remnant from a prior database with the same name where
** the database file but not the journal was deleted, or (2) the initial
** transaction that populates a new database is being rolled back.
** In either case, the journal file can be deleted. However, take care
** not to delete the journal file if it is already open due to
** journal_mode=PERSIST.
*/
if( nPage==0 && !jrnlOpen ){
if( nPage==0 ){
sqlite3BeginBenignMalloc();
if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){
sqlite3OsDelete(pVfs, pPager->zJournal, 0);
+8 -56
View File
@@ -412,47 +412,26 @@ cmd ::= select(X). {
%type oneselect {Select*}
%destructor oneselect {sqlite3SelectDelete(pParse->db, $$);}
select(A) ::= with(W) selectnowith(X). {
Select *p = X, *pNext, *pLoop;
if( p ){
int cnt = 0, mxSelect;
p->pWith = W;
if( p->pPrior ){
pNext = 0;
for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
pLoop->pNext = pNext;
pLoop->selFlags |= SF_Compound;
}
mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT];
if( mxSelect && cnt>mxSelect ){
sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
}
}
select(A) ::= with(W) selectnowith(X). {
if( X ){
X->pWith = W;
}else{
sqlite3WithDelete(pParse->db, W);
}
A = p;
A = X;
}
selectnowith(A) ::= oneselect(X). {A = X;}
%ifndef SQLITE_OMIT_COMPOUND_SELECT
selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z). {
Select *pRhs = Z;
if( pRhs && pRhs->pPrior ){
SrcList *pFrom;
Token x;
x.n = 0;
pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
}
if( pRhs ){
pRhs->op = (u8)Y;
pRhs->pPrior = X;
if( Z ){
Z->op = (u8)Y;
Z->pPrior = X;
if( Y!=TK_ALL ) pParse->hasCompound = 1;
}else{
sqlite3SelectDelete(pParse->db, X);
}
A = pRhs;
A = Z;
}
%type multiselect_op {int}
multiselect_op(A) ::= UNION(OP). {A = @OP;}
@@ -1020,33 +999,6 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
*/
A.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[N]);
sqlite3ExprDelete(pParse->db, X.pExpr);
}else if( Y->nExpr==1 ){
/* Expressions of the form:
**
** expr1 IN (?1)
** expr1 NOT IN (?2)
**
** with exactly one value on the RHS can be simplified to something
** like this:
**
** expr1 == ?1
** expr1 <> ?2
**
** But, the RHS of the == or <> is marked with the EP_Generic flag
** so that it may not contribute to the computation of comparison
** affinity or the collating sequence to use for comparison. Otherwise,
** the semantics would be subtly different from IN or NOT IN.
*/
Expr *pRHS = Y->a[0].pExpr;
Y->a[0].pExpr = 0;
sqlite3ExprListDelete(pParse->db, Y);
/* pRHS cannot be NULL because a malloc error would have been detected
** before now and control would have never reached this point */
if( ALWAYS(pRHS) ){
pRHS->flags &= ~EP_Collate;
pRHS->flags |= EP_Generic;
}
A.pExpr = sqlite3PExpr(pParse, N ? TK_NE : TK_EQ, X.pExpr, pRHS, 0);
}else{
A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
if( A.pExpr ){
+25 -31
View File
@@ -824,7 +824,6 @@ void sqlite3Pragma(
** size of historical compatibility.
*/
case PragTyp_DEFAULT_CACHE_SIZE: {
static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList getCacheSize[] = {
{ OP_Transaction, 0, 0, 0}, /* 0 */
{ OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */
@@ -842,7 +841,7 @@ void sqlite3Pragma(
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", SQLITE_STATIC);
pParse->nMem += 2;
addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize,iLn);
addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
sqlite3VdbeChangeP1(v, addr, iDb);
sqlite3VdbeChangeP1(v, addr+1, iDb);
sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE);
@@ -1087,7 +1086,6 @@ void sqlite3Pragma(
** file. Before writing to meta[6], check that meta[3] indicates
** that this really is an auto-vacuum capable database.
*/
static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList setMeta6[] = {
{ OP_Transaction, 0, 1, 0}, /* 0 */
{ OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE},
@@ -1097,7 +1095,7 @@ void sqlite3Pragma(
{ OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */
};
int iAddr;
iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn);
iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6);
sqlite3VdbeChangeP1(v, iAddr, iDb);
sqlite3VdbeChangeP1(v, iAddr+1, iDb);
sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4);
@@ -1123,10 +1121,10 @@ void sqlite3Pragma(
}
sqlite3BeginWriteOperation(pParse, 0, iDb);
sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1);
addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); VdbeCoverage(v);
addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb);
sqlite3VdbeAddOp1(v, OP_ResultRow, 1);
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr);
sqlite3VdbeJumpHere(v, addr);
break;
}
@@ -1697,7 +1695,7 @@ void sqlite3Pragma(
assert( pParse->nErr>0 || pFK==0 );
if( pFK ) break;
if( pParse->nTab<i ) pParse->nTab = i;
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v);
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0);
for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
pParent = sqlite3FindTable(db, pFK->zTo, zDb);
pIdx = 0;
@@ -1713,26 +1711,26 @@ void sqlite3Pragma(
if( iKey!=pTab->iPKey ){
sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
sqlite3ColumnDefault(v, pTab, iKey, regRow);
sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow,
sqlite3VdbeCurrentAddr(v)+3); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk);
sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow,
sqlite3VdbeCurrentAddr(v)+3);
}else{
sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
}
sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrOk);
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
}else{
for(j=0; j<pFK->nCol; j++){
sqlite3ExprCodeGetColumnOfTable(v, pTab, 0,
aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j);
sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk);
}
if( pParent ){
sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
sqlite3IndexAffinityStr(v,pIdx), pFK->nCol);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regRow, pFK->nCol, regKey);
sqlite3VdbeChangeP4(v, -1,
sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT);
sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
VdbeCoverage(v);
}
}
sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
@@ -1743,7 +1741,7 @@ void sqlite3Pragma(
sqlite3VdbeResolveLabel(v, addrOk);
sqlite3DbFree(db, aiCols);
}
sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1);
sqlite3VdbeJumpHere(v, addrTop);
}
}
@@ -1790,7 +1788,6 @@ void sqlite3Pragma(
** messages have been generated, output OK. Otherwise output the
** error message
*/
static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList endCode[] = {
{ OP_AddImm, 1, 0, 0}, /* 0 */
{ OP_IfNeg, 1, 0, 0}, /* 1 */
@@ -1839,7 +1836,6 @@ void sqlite3Pragma(
sqlite3CodeVerifySchema(pParse, i);
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */
VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
sqlite3VdbeJumpHere(v, addr);
@@ -1871,11 +1867,11 @@ void sqlite3Pragma(
/* Do the b-tree integrity checks */
sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
sqlite3VdbeChangeP5(v, (u8)i);
addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v);
addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
P4_DYNAMIC);
sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1);
sqlite3VdbeAddOp2(v, OP_Move, 2, 4);
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
sqlite3VdbeJumpHere(v, addr);
@@ -1893,7 +1889,6 @@ void sqlite3Pragma(
if( pTab->pIndex==0 ) continue;
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
sqlite3VdbeJumpHere(v, addr);
sqlite3ExprCacheClear(pParse);
@@ -1904,7 +1899,7 @@ void sqlite3Pragma(
sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */
}
pParse->nMem = MAX(pParse->nMem, 8+j);
sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0);
loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int jmp2, jmp3, jmp4;
@@ -1914,7 +1909,7 @@ void sqlite3Pragma(
pPrior = pIdx;
sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, 0, r1,
pIdx->nColumn); VdbeCoverage(v);
pIdx->nColumn);
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, "row ", P4_STATIC);
sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
@@ -1924,13 +1919,13 @@ void sqlite3Pragma(
sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, pIdx->zName, P4_TRANSIENT);
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
sqlite3VdbeAddOp0(v, OP_Halt);
sqlite3VdbeJumpHere(v, jmp4);
sqlite3VdbeJumpHere(v, jmp2);
sqlite3VdbeResolveLabel(v, jmp3);
}
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop);
sqlite3VdbeJumpHere(v, loopTop-1);
#ifndef SQLITE_OMIT_BTREECOUNT
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0,
@@ -1938,11 +1933,10 @@ void sqlite3Pragma(
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
if( pPk==pIdx ) continue;
addr = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2);
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3);
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT);
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
@@ -1951,7 +1945,7 @@ void sqlite3Pragma(
#endif /* SQLITE_OMIT_BTREECOUNT */
}
}
addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn);
addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
sqlite3VdbeChangeP2(v, addr, -mxErr);
sqlite3VdbeJumpHere(v, addr+1);
sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC);
@@ -2089,7 +2083,7 @@ void sqlite3Pragma(
{ OP_Integer, 0, 1, 0}, /* 1 */
{ OP_SetCookie, 0, 0, 1}, /* 2 */
};
int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0);
int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie);
sqlite3VdbeChangeP1(v, addr, iDb);
sqlite3VdbeChangeP1(v, addr+1, sqlite3Atoi(zRight));
sqlite3VdbeChangeP1(v, addr+2, iDb);
@@ -2101,7 +2095,7 @@ void sqlite3Pragma(
{ OP_ReadCookie, 0, 1, 0}, /* 1 */
{ OP_ResultRow, 1, 1, 0}
};
int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie, 0);
int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie);
sqlite3VdbeChangeP1(v, addr, iDb);
sqlite3VdbeChangeP1(v, addr+1, iDb);
sqlite3VdbeChangeP3(v, addr+1, iCookie);
+77 -84
View File
@@ -134,6 +134,20 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
}
#endif /* SQLITE_OMIT_FLOATING_POINT */
/*
** Append N space characters to the given string buffer.
*/
void sqlite3AppendSpace(StrAccum *pAccum, int N){
static const char zSpaces[] = " ";
while( N>=(int)sizeof(zSpaces)-1 ){
sqlite3StrAccumAppend(pAccum, zSpaces, sizeof(zSpaces)-1);
N -= sizeof(zSpaces)-1;
}
if( N>0 ){
sqlite3StrAccumAppend(pAccum, zSpaces, N);
}
}
/*
** Set the StrAccum object to an error mode.
*/
@@ -223,9 +237,11 @@ void sqlite3VXPrintf(
}
for(; (c=(*fmt))!=0; ++fmt){
if( c!='%' ){
int amt;
bufpt = (char *)fmt;
while( (c=(*++fmt))!='%' && c!=0 ){};
sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt));
amt = 1;
while( (c=(*++fmt))!='%' && c!=0 ) amt++;
sqlite3StrAccumAppend(pAccum, bufpt, amt);
if( c==0 ) break;
}
if( (c=(*++fmt))==0 ){
@@ -406,8 +422,10 @@ void sqlite3VXPrintf(
*(--bufpt) = zOrd[x*2];
}
{
const char *cset = &aDigits[infop->charset];
u8 base = infop->base;
register const char *cset; /* Use registers for speed */
register int base;
cset = &aDigits[infop->charset];
base = infop->base;
do{ /* Convert to ascii */
*(--bufpt) = cset[longvalue%base];
longvalue = longvalue/base;
@@ -711,89 +729,29 @@ void sqlite3VXPrintf(
** "length" characters long. The field width is "width". Do
** the output.
*/
width -= length;
if( width>0 && !flag_leftjustify ) sqlite3AppendSpace(pAccum, width);
sqlite3StrAccumAppend(pAccum, bufpt, length);
if( width>0 && flag_leftjustify ) sqlite3AppendSpace(pAccum, width);
if( !flag_leftjustify ){
register int nspace;
nspace = width-length;
if( nspace>0 ){
sqlite3AppendSpace(pAccum, nspace);
}
}
if( length>0 ){
sqlite3StrAccumAppend(pAccum, bufpt, length);
}
if( flag_leftjustify ){
register int nspace;
nspace = width-length;
if( nspace>0 ){
sqlite3AppendSpace(pAccum, nspace);
}
}
if( zExtra ) sqlite3_free(zExtra);
}/* End for loop over the format string */
} /* End of function */
/*
** Enlarge the memory allocation on a StrAccum object so that it is
** able to accept at least N more bytes of text.
**
** Return the number of bytes of text that StrAccum is able to accept
** after the attempted enlargement. The value returned might be zero.
*/
static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
char *zNew;
assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */
if( p->accError ){
testcase(p->accError==STRACCUM_TOOBIG);
testcase(p->accError==STRACCUM_NOMEM);
return 0;
}
if( !p->useMalloc ){
N = p->nAlloc - p->nChar - 1;
setStrAccumError(p, STRACCUM_TOOBIG);
return N;
}else{
char *zOld = (p->zText==p->zBase ? 0 : p->zText);
i64 szNew = p->nChar;
szNew += N + 1;
if( szNew > p->mxAlloc ){
sqlite3StrAccumReset(p);
setStrAccumError(p, STRACCUM_TOOBIG);
return 0;
}else{
p->nAlloc = (int)szNew;
}
if( p->useMalloc==1 ){
zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
}else{
zNew = sqlite3_realloc(zOld, p->nAlloc);
}
if( zNew ){
if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
p->zText = zNew;
}else{
sqlite3StrAccumReset(p);
setStrAccumError(p, STRACCUM_NOMEM);
return 0;
}
}
return N;
}
/*
** Append N space characters to the given string buffer.
*/
void sqlite3AppendSpace(StrAccum *p, int N){
if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return;
while( (N--)>0 ) p->zText[p->nChar++] = ' ';
}
/*
** The StrAccum "p" is not large enough to accept N new bytes of z[].
** So enlarge if first, then do the append.
**
** This is a helper routine to sqlite3StrAccumAppend() that does special-case
** work (enlarging the buffer) using tail recursion, so that the
** sqlite3StrAccumAppend() routine can use fast calling semantics.
*/
static void enlargeAndAppend(StrAccum *p, const char *z, int N){
N = sqlite3StrAccumEnlarge(p, N);
if( N>0 ){
memcpy(&p->zText[p->nChar], z, N);
p->nChar += N;
}
}
/*
** Append N bytes of text from z to the StrAccum object. Increase the
** size of the memory allocation for StrAccum if necessary.
** Append N bytes of text from z to the StrAccum object.
*/
void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
assert( z!=0 );
@@ -801,8 +759,43 @@ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
assert( N>=0 );
assert( p->accError==0 || p->nAlloc==0 );
if( p->nChar+N >= p->nAlloc ){
enlargeAndAppend(p,z,N);
return;
char *zNew;
if( p->accError ){
testcase(p->accError==STRACCUM_TOOBIG);
testcase(p->accError==STRACCUM_NOMEM);
return;
}
if( !p->useMalloc ){
N = p->nAlloc - p->nChar - 1;
setStrAccumError(p, STRACCUM_TOOBIG);
if( N<=0 ){
return;
}
}else{
char *zOld = (p->zText==p->zBase ? 0 : p->zText);
i64 szNew = p->nChar;
szNew += N + 1;
if( szNew > p->mxAlloc ){
sqlite3StrAccumReset(p);
setStrAccumError(p, STRACCUM_TOOBIG);
return;
}else{
p->nAlloc = (int)szNew;
}
if( p->useMalloc==1 ){
zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
}else{
zNew = sqlite3_realloc(zOld, p->nAlloc);
}
if( zNew ){
if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
p->zText = zNew;
}else{
sqlite3StrAccumReset(p);
setStrAccumError(p, STRACCUM_NOMEM);
return;
}
}
}
assert( p->zText );
memcpy(&p->zText[p->nChar], z, N);
+2 -4
View File
@@ -337,8 +337,6 @@ static int lookupName(
}else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){
pExpr->iTable = 0;
pTab = pParse->pTriggerTab;
}else{
pTab = 0;
}
if( pTab ){
@@ -382,8 +380,8 @@ static int lookupName(
/*
** Perhaps the name is a reference to the ROWID
*/
if( cnt==0 && cntTab==1 && pMatch && sqlite3IsRowid(zCol)
&& HasRowid(pMatch->pTab) ){
assert( pTab!=0 || cntTab==0 );
if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) && HasRowid(pTab) ){
cnt = 1;
pExpr->iColumn = -1; /* IMP: R-44911-55124 */
pExpr->affinity = SQLITE_AFF_INTEGER;
+299 -389
View File
File diff suppressed because it is too large Load Diff
+20 -312
View File
@@ -45,17 +45,14 @@
# include <sys/types.h>
#endif
#if defined(HAVE_READLINE) && HAVE_READLINE!=0
#ifdef HAVE_EDITLINE
# include <editline/editline.h>
#endif
#if defined(HAVE_READLINE) && HAVE_READLINE==1
# include <readline/readline.h>
# include <readline/history.h>
#else
# undef HAVE_READLINE
#endif
#if defined(HAVE_EDITLINE) && !defined(HAVE_READLINE)
# define HAVE_READLINE 1
# include <editline/readline.h>
#endif
#if !defined(HAVE_READLINE)
#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
# define add_history(X)
# define read_history(X)
# define write_history(X)
@@ -65,9 +62,7 @@
#if defined(_WIN32) || defined(WIN32)
# include <io.h>
#define isatty(h) _isatty(h)
#ifndef access
# define access(f,m) _access((f),(m))
#endif
#define access(f,m) _access((f),(m))
#undef popen
#define popen _popen
#undef pclose
@@ -418,7 +413,7 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
zResult = local_getline(zPrior, in);
}else{
zPrompt = isContinuation ? continuePrompt : mainPrompt;
#if defined(HAVE_READLINE)
#if defined(HAVE_READLINE) && HAVE_READLINE==1
free(zPrior);
zResult = readline(zPrompt);
if( zResult && *zResult ) add_history(zResult);
@@ -446,7 +441,6 @@ struct previous_mode_data {
struct callback_data {
sqlite3 *db; /* The database */
int echoOn; /* True to echo input commands */
int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL statement */
int statsOn; /* True to display memory stats before each finalize */
int cnt; /* Number of records displayed so far */
FILE *out; /* Write results here */
@@ -1011,7 +1005,7 @@ static int run_table_dump_query(
int nResult;
int i;
const char *z;
rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
if( rc!=SQLITE_OK || !pSelect ){
fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
@@ -1184,7 +1178,6 @@ static int str_in_array(const char *zStr, const char **azArray){
** * For each "Goto", if the jump destination is earlier in the program
** and ends on one of:
** Yield SeekGt SeekLt RowSetRead Rewind
** or if the P1 parameter is one instead of zero,
** then indent all opcodes between the earlier instruction
** and "Goto" by 2 spaces.
*/
@@ -1195,8 +1188,7 @@ static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){
int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
int iOp; /* Index of operation in p->aiIndent[] */
const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
"NextIfOpen", "PrevIfOpen", 0 };
const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 };
const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", "Rewind", 0 };
const char *azGoto[] = { "Goto", 0 };
@@ -1233,9 +1225,7 @@ static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){
if( str_in_array(zOp, azNext) ){
for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
}
if( str_in_array(zOp, azGoto) && p2op<p->nIndent
&& (abYield[p2op] || sqlite3_column_int(pSql, 2))
){
if( str_in_array(zOp, azGoto) && p2op<p->nIndent && abYield[p2op] ){
for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
}
}
@@ -1307,23 +1297,6 @@ static int shell_exec(
fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
}
/* Show the EXPLAIN QUERY PLAN if .eqp is on */
if( pArg && pArg->autoEQP ){
sqlite3_stmt *pExplain;
char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", sqlite3_sql(pStmt));
rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
if( rc==SQLITE_OK ){
while( sqlite3_step(pExplain)==SQLITE_ROW ){
fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
}
}
sqlite3_finalize(pExplain);
sqlite3_free(zEQP);
}
/* Output TESTCTRL_EXPLAIN text of requested */
if( pArg && pArg->mode==MODE_Explain ){
const char *zExplain = 0;
@@ -1480,7 +1453,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
zTableInfo = appendText(zTableInfo, zTable, '"');
zTableInfo = appendText(zTableInfo, ");", 0);
rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
free(zTableInfo);
if( rc!=SQLITE_OK || !pTableInfo ){
return 1;
@@ -1570,7 +1543,6 @@ static int run_schema_dump_query(
static char zHelp[] =
".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
".bail ON|OFF Stop after hitting an error. Default OFF\n"
".clone NEWDB Clone data into NEWDB from the existing database\n"
".databases List names and files of attached databases\n"
".dump ?TABLE? ... Dump the database in an SQL text format\n"
" If TABLE specified, only dump tables matching\n"
@@ -1610,7 +1582,6 @@ static char zHelp[] =
".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"
".schema ?TABLE? Show the CREATE statements\n"
" If TABLE specified, only show tables matching\n"
" LIKE pattern TABLE.\n"
@@ -1917,7 +1888,7 @@ static char *csv_read_one_field(CSVReader *p){
}
if( c=='\n' ){
p->nLine++;
if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
if( p->n>1 && p->z[p->n-1]=='\r' ) p->n--;
}
p->cTerm = c;
}
@@ -1925,221 +1896,6 @@ static char *csv_read_one_field(CSVReader *p){
return p->z;
}
/*
** Try to transfer data for table zTable. If an error is seen while
** moving forward, try to go backwards. The backwards movement won't
** work for WITHOUT ROWID tables.
*/
static void tryToCloneData(
struct callback_data *p,
sqlite3 *newDb,
const char *zTable
){
sqlite3_stmt *pQuery = 0;
sqlite3_stmt *pInsert = 0;
char *zQuery = 0;
char *zInsert = 0;
int rc;
int i, j, n;
int nTable = (int)strlen(zTable);
int k = 0;
int cnt = 0;
const int spinRate = 10000;
zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
if( rc ){
fprintf(stderr, "Error %d: %s on [%s]\n",
sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
zQuery);
goto end_data_xfer;
}
n = sqlite3_column_count(pQuery);
zInsert = sqlite3_malloc(200 + nTable + n*3);
if( zInsert==0 ){
fprintf(stderr, "out of memory\n");
goto end_data_xfer;
}
sqlite3_snprintf(200+nTable,zInsert,
"INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
i = (int)strlen(zInsert);
for(j=1; j<n; j++){
memcpy(zInsert+i, ",?", 2);
i += 2;
}
memcpy(zInsert+i, ");", 3);
rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
if( rc ){
fprintf(stderr, "Error %d: %s on [%s]\n",
sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
zQuery);
goto end_data_xfer;
}
for(k=0; k<2; k++){
while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
for(i=0; i<n; i++){
switch( sqlite3_column_type(pQuery, i) ){
case SQLITE_NULL: {
sqlite3_bind_null(pInsert, i+1);
break;
}
case SQLITE_INTEGER: {
sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
break;
}
case SQLITE_FLOAT: {
sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
break;
}
case SQLITE_TEXT: {
sqlite3_bind_text(pInsert, i+1,
(const char*)sqlite3_column_text(pQuery,i),
-1, SQLITE_STATIC);
break;
}
case SQLITE_BLOB: {
sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
sqlite3_column_bytes(pQuery,i),
SQLITE_STATIC);
break;
}
}
} /* End for */
rc = sqlite3_step(pInsert);
if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
sqlite3_errmsg(newDb));
}
sqlite3_reset(pInsert);
cnt++;
if( (cnt%spinRate)==0 ){
printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
fflush(stdout);
}
} /* End while */
if( rc==SQLITE_DONE ) break;
sqlite3_finalize(pQuery);
sqlite3_free(zQuery);
zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
zTable);
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
if( rc ){
fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
break;
}
} /* End for(k=0...) */
end_data_xfer:
sqlite3_finalize(pQuery);
sqlite3_finalize(pInsert);
sqlite3_free(zQuery);
sqlite3_free(zInsert);
}
/*
** Try to transfer all rows of the schema that match zWhere. For
** each row, invoke xForEach() on the object defined by that row.
** If an error is encountered while moving forward through the
** sqlite_master table, try again moving backwards.
*/
static void tryToCloneSchema(
struct callback_data *p,
sqlite3 *newDb,
const char *zWhere,
void (*xForEach)(struct callback_data*,sqlite3*,const char*)
){
sqlite3_stmt *pQuery = 0;
char *zQuery = 0;
int rc;
const unsigned char *zName;
const unsigned char *zSql;
char *zErrMsg = 0;
zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
" WHERE %s", zWhere);
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
if( rc ){
fprintf(stderr, "Error: (%d) %s on [%s]\n",
sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
zQuery);
goto end_schema_xfer;
}
while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
zName = sqlite3_column_text(pQuery, 0);
zSql = sqlite3_column_text(pQuery, 1);
printf("%s... ", zName); fflush(stdout);
sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
if( zErrMsg ){
fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
sqlite3_free(zErrMsg);
zErrMsg = 0;
}
if( xForEach ){
xForEach(p, newDb, (const char*)zName);
}
printf("done\n");
}
if( rc!=SQLITE_DONE ){
sqlite3_finalize(pQuery);
sqlite3_free(zQuery);
zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
" WHERE %s ORDER BY rowid DESC", zWhere);
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
if( rc ){
fprintf(stderr, "Error: (%d) %s on [%s]\n",
sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
zQuery);
goto end_schema_xfer;
}
while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
zName = sqlite3_column_text(pQuery, 0);
zSql = sqlite3_column_text(pQuery, 1);
printf("%s... ", zName); fflush(stdout);
sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
if( zErrMsg ){
fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
sqlite3_free(zErrMsg);
zErrMsg = 0;
}
if( xForEach ){
xForEach(p, newDb, (const char*)zName);
}
printf("done\n");
}
}
end_schema_xfer:
sqlite3_finalize(pQuery);
sqlite3_free(zQuery);
}
/*
** Open a new database file named "zNewDb". Try to recover as much information
** as possible out of the main database (which might be corrupt) and write it
** into zNewDb.
*/
static void tryToClone(struct callback_data *p, const char *zNewDb){
int rc;
sqlite3 *newDb = 0;
if( access(zNewDb,0)==0 ){
fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
return;
}
rc = sqlite3_open(zNewDb, &newDb);
if( rc ){
fprintf(stderr, "Cannot create output database: %s\n",
sqlite3_errmsg(newDb));
}else{
sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
tryToCloneSchema(p, newDb, "type!='table'", 0);
sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
}
sqlite3_close(newDb);
}
/*
** If an input line begins with "." then invoke this routine to
** process that line.
@@ -2182,9 +1938,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( nArg==0 ) return 0; /* no tokens, no error */
n = strlen30(azArg[0]);
c = azArg[0][0];
if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
|| (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
){
if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
const char *zDestFile = 0;
const char *zDb = 0;
sqlite3 *pDest;
@@ -2249,10 +2003,6 @@ static int do_meta_command(char *zLine, struct callback_data *p){
test_breakpoint();
}else
if( c=='c' && strncmp(azArg[0], "clone", n)==0 && nArg>1 && nArg<3 ){
tryToClone(p, azArg[1]);
}else
if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
struct callback_data data;
char *zErrMsg = 0;
@@ -2325,10 +2075,6 @@ static int do_meta_command(char *zLine, struct callback_data *p){
p->echoOn = booleanValue(azArg[1]);
}else
if( c=='e' && strncmp(azArg[0], "eqp", n)==0 && nArg>1 && nArg<3 ){
p->autoEQP = booleanValue(azArg[1]);
}else
if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
rc = 2;
@@ -2429,7 +2175,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
return 1;
}
nByte = strlen30(zSql);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
char cSep = '(';
@@ -2455,7 +2201,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
xCloser(sCsv.in);
return 1;
}
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
}
sqlite3_free(zSql);
if( rc ){
@@ -2482,7 +2228,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}
zSql[j++] = ')';
zSql[j] = 0;
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rc ){
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
@@ -2901,7 +2647,6 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
int i;
fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
fprintf(p->out,"%9.9s: %s\n","eqp", p->autoEQP ? "on" : "off");
fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
@@ -3534,30 +3279,9 @@ static void main_init(struct callback_data *data) {
sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
sqlite3_config(SQLITE_CONFIG_WORKER_THREADS, 4);
sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
}
/*
** Output text to the console in a font that attracts extra attention.
*/
#ifdef _WIN32
static void printBold(const char *zText){
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
SetConsoleTextAttribute(out,
FOREGROUND_RED|FOREGROUND_INTENSITY
);
printf("%s", zText);
SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
}
#else
static void printBold(const char *zText){
printf("\033[1m%s\033[0m", zText);
}
#endif
/*
** Get the argument to an --option. Throw an error and die if no argument
** is available.
@@ -3578,15 +3302,12 @@ int main(int argc, char **argv){
char *zFirstCmd = 0;
int i;
int rc = 0;
int warnInmemoryDb = 0;
#if USE_SYSTEM_SQLITE+0!=1
if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
sqlite3_sourceid(), SQLITE_SOURCE_ID);
exit(1);
}
#endif
Argv0 = argv[0];
main_init(&data);
stdin_is_interactive = isatty(0);
@@ -3675,15 +3396,9 @@ int main(int argc, char **argv){
if( data.zDbFilename==0 ){
#ifndef SQLITE_OMIT_MEMORYDB
data.zDbFilename = ":memory:";
warnInmemoryDb = argc==1;
#else
fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
return 1;
#endif
#ifdef SQLITE_SHELL_DBNAME_PROC
{ extern void SQLITE_SHELL_DBNAME_PROC(const char**);
SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
warnInmemoryDb = 0; }
#endif
}
data.out = stdout;
@@ -3740,8 +3455,6 @@ int main(int argc, char **argv){
data.showHeader = 0;
}else if( strcmp(z,"-echo")==0 ){
data.echoOn = 1;
}else if( strcmp(z,"-eqp")==0 ){
data.autoEQP = 1;
}else if( strcmp(z,"-stats")==0 ){
data.statsOn = 1;
}else if( strcmp(z,"-bail")==0 ){
@@ -3819,15 +3532,10 @@ int main(int argc, char **argv){
int nHistory;
printf(
"SQLite version %s %.19s\n" /*extra-version-info*/
"Enter \".help\" for usage hints.\n",
"Enter \".help\" for instructions\n"
"Enter SQL statements terminated with a \";\"\n",
sqlite3_libversion(), sqlite3_sourceid()
);
if( warnInmemoryDb ){
printf("Connected to a ");
printBold("transient in-memory database");
printf(".\nUse \".open FILENAME\" to reopen on a "
"persistent database.\n");
}
zHome = find_home_dir();
if( zHome ){
nHistory = strlen30(zHome) + 20;
@@ -3835,7 +3543,7 @@ int main(int argc, char **argv){
sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
}
}
#if defined(HAVE_READLINE)
#if defined(HAVE_READLINE) && HAVE_READLINE==1
if( zHistory ) read_history(zHistory);
#endif
rc = process_input(&data, 0);
+1 -14
View File
@@ -1715,16 +1715,6 @@ struct sqlite3_mem_methods {
** SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
** that specifies the maximum size of the created heap.
** </dl>
**
** [[SQLITE_CONFIG_WORKER_THREADS]]
** <dt>SQLITE_CONFIG_WORKER_THREADS
** <dd>^SQLITE_CONFIG_WORKER_THREADS takes a single argument of type int.
** It is used to set the number of background worker threads that may be
** launched when sorting large amounts of data. A value of 0 means launch
** no background threads at all. The maximum number of background threads
** allowed is configured at build-time by the SQLITE_MAX_WORKER_THREADS
** pre-processor option.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
@@ -1749,7 +1739,6 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */
#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
#define SQLITE_CONFIG_WORKER_THREADS 24 /* int nWorker */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -6128,9 +6117,7 @@ int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
#define SQLITE_TESTCTRL_SORTER_MMAP 22
#define SQLITE_TESTCTRL_LAST 22
#define SQLITE_TESTCTRL_LAST 20
/*
** CAPI3REF: SQLite Runtime Status
+43 -129
View File
@@ -12,6 +12,7 @@
** Internal interface definitions for SQLite.
**
*/
#include "sqlite3.h"
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -32,11 +33,6 @@
** in Red Hat 6.0, so the code won't work. Hence, for maximum binary
** portability you should omit LFS.
**
** The previous paragraph was written in 2005. (This paragraph is written
** on 2008-11-28.) These days, all Linux kernels support large files, so
** you should probably leave LFS enabled. But some embedded platforms might
** lack LFS in which case the SQLITE_DISABLE_LFS macro might still be useful.
**
** Similar is true for Mac OS X. LFS is only supported on Mac OS X 9 and later.
*/
#ifndef SQLITE_DISABLE_LFS
@@ -47,44 +43,6 @@
# define _LARGEFILE_SOURCE 1
#endif
/*
** For MinGW, check to see if we can include the header file containing its
** version information, among other things. Normally, this internal MinGW
** header file would [only] be included automatically by other MinGW header
** files; however, the contained version information is now required by this
** header file to work around binary compatibility issues (see below) and
** this is the only known way to reliably obtain it. This entire #if block
** would be completely unnecessary if there was any other way of detecting
** MinGW via their preprocessor (e.g. if they customized their GCC to define
** some MinGW-specific macros). When compiling for MinGW, either the
** _HAVE_MINGW_H or _HAVE__MINGW_H (note the extra underscore) macro must be
** defined; otherwise, detection of conditions specific to MinGW will be
** disabled.
*/
#if defined(_HAVE_MINGW_H)
# include "mingw.h"
#elif defined(_HAVE__MINGW_H)
# include "_mingw.h"
#endif
/*
** For MinGW version 4.x (and higher), check to see if the _USE_32BIT_TIME_T
** define is required to maintain binary compatibility with the MSVC runtime
** library in use (e.g. for Windows XP).
*/
#if !defined(_USE_32BIT_TIME_T) && !defined(_USE_64BIT_TIME_T) && \
defined(_WIN32) && !defined(_WIN64) && \
defined(__MINGW_MAJOR_VERSION) && __MINGW_MAJOR_VERSION >= 4 && \
defined(__MSVCRT__)
# define _USE_32BIT_TIME_T
#endif
/* The public SQLite interface. The _FILE_OFFSET_BITS macro must appear
** first in QNX. Also, the _USE_32BIT_TIME_T macro must appear first for
** MinGW.
*/
#include "sqlite3.h"
/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build
@@ -422,19 +380,6 @@
# define SQLITE_TEMP_STORE_xc 1 /* Exclude from ctime.c */
#endif
/*
** If no value has been provided for SQLITE_MAX_WORKER_THREADS, or if
** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it
** to zero.
*/
#if SQLITE_TEMP_STORE==3
# undef SQLITE_MAX_WORKER_THREADS
#endif
#ifndef SQLITE_MAX_WORKER_THREADS
# define SQLITE_MAX_WORKER_THREADS 0
#endif
/*
** GCC does not define the offsetof() macro so we'll have to do it
** ourselves.
@@ -801,7 +746,6 @@ typedef struct PrintfArguments PrintfArguments;
typedef struct RowSet RowSet;
typedef struct Savepoint Savepoint;
typedef struct Select Select;
typedef struct SQLiteThread SQLiteThread;
typedef struct SelectDest SelectDest;
typedef struct SrcList SrcList;
typedef struct StrAccum StrAccum;
@@ -981,7 +925,6 @@ struct sqlite3 {
int nChange; /* Value returned by sqlite3_changes() */
int nTotalChange; /* Value returned by sqlite3_total_changes() */
int aLimit[SQLITE_N_LIMIT]; /* Limits */
int nMaxSorterMmap; /* Maximum size of regions mapped by sorter */
struct sqlite3InitInfo { /* Information used during initialization */
int newTnum; /* Rootpage of table being initialized */
u8 iDb; /* Which db file is being initialized */
@@ -1140,7 +1083,8 @@ struct sqlite3 {
** Return true if it OK to factor constant expressions into the initialization
** code. The argument is a Parse object for the code generator.
*/
#define ConstFactorOk(P) ((P)->okConstFactor)
#define ConstFactorOk(P) \
((P)->cookieGoto>0 && OptimizationEnabled((P)->db,SQLITE_FactorOutConst))
/*
** Possible values for the sqlite.magic field.
@@ -1366,16 +1310,10 @@ struct CollSeq {
/*
** Additional bit values that can be ORed with an affinity without
** changing the affinity.
**
** The SQLITE_NOTNULL flag is a combination of NULLEQ and JUMPIFNULL.
** It causes an assert() to fire if either operand to a comparison
** operator is NULL. It is added to certain comparison operators to
** prove that the operands are always NOT NULL.
*/
#define SQLITE_JUMPIFNULL 0x08 /* jumps if either operand is NULL */
#define SQLITE_STOREP2 0x10 /* Store result in reg[P2] rather than jump */
#define SQLITE_NULLEQ 0x80 /* NULL=NULL */
#define SQLITE_NOTNULL 0x88 /* Assert that operands are never NULL */
/*
** An object of this type is created for each virtual table present in
@@ -1634,20 +1572,19 @@ struct KeyInfo {
**
** This structure holds a record that has already been disassembled
** into its constituent fields.
**
** The r1 and r2 member variables are only used by the optimized comparison
** functions vdbeRecordCompareInt() and vdbeRecordCompareString().
*/
struct UnpackedRecord {
KeyInfo *pKeyInfo; /* Collation and sort-order information */
u16 nField; /* Number of entries in apMem[] */
i8 default_rc; /* Comparison result if keys are equal */
u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
u8 flags; /* Boolean settings. UNPACKED_... below */
Mem *aMem; /* Values */
int r1; /* Value to return if (lhs > rhs) */
int r2; /* Value to return if (rhs < lhs) */
};
/*
** Allowed values of UnpackedRecord.flags
*/
#define UNPACKED_INCRKEY 0x01 /* Make this key an epsilon larger */
#define UNPACKED_PREFIX_MATCH 0x02 /* A prefix match is considered OK */
/*
** Each SQL index is represented in memory by an
@@ -1909,8 +1846,8 @@ struct Expr {
#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */
#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */
#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE opeartor */
/* unused 0x000200 */
#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
#define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */
@@ -1974,6 +1911,7 @@ struct Expr {
*/
struct ExprList {
int nExpr; /* Number of expressions on the list */
int iECursor; /* VDBE Cursor associated with this ExprList */
struct ExprList_item { /* For each expression in the list */
Expr *pExpr; /* The list of expressions */
char *zName; /* Token associated with this expression */
@@ -2066,8 +2004,8 @@ typedef u64 Bitmask;
** contains more than 63 columns and the 64-th or later column is used.
*/
struct SrcList {
int nSrc; /* Number of tables or subqueries in the FROM clause */
u32 nAlloc; /* Number of entries allocated in a[] below */
u8 nSrc; /* Number of tables or subqueries in the FROM clause */
u8 nAlloc; /* Number of entries allocated in a[] below */
struct SrcList_item {
Schema *pSchema; /* Schema to which this item is fixed */
char *zDatabase; /* Name of database holding this table */
@@ -2077,7 +2015,6 @@ struct SrcList {
Select *pSelect; /* A SELECT statement used in place of a table name */
int addrFillSub; /* Address of subroutine to manifest a subquery */
int regReturn; /* Register holding return address of addrFillSub */
int regResult; /* Registers holding results of a co-routine */
u8 jointype; /* Type of join between this able and the previous */
unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */
unsigned isCorrelated :1; /* True if sub-query is correlated */
@@ -2197,7 +2134,7 @@ struct Select {
u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
u16 selFlags; /* Various SF_* values */
int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */
int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */
u64 nSelectRow; /* Estimated number of result rows */
SrcList *pSrc; /* The FROM clause */
Expr *pWhere; /* The WHERE clause */
@@ -2206,6 +2143,7 @@ struct Select {
ExprList *pOrderBy; /* The ORDER BY clause */
Select *pPrior; /* Prior select in a compound select statement */
Select *pNext; /* Next select to the left in a compound */
Select *pRightmost; /* Right-most select in a compound select statement */
Expr *pLimit; /* LIMIT expression. NULL means not used. */
Expr *pOffset; /* OFFSET expression. NULL means not used. */
With *pWith; /* WITH clause attached to this select. Or NULL. */
@@ -2221,13 +2159,12 @@ struct Select {
#define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */
#define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */
#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
/* 0x0040 NOT USED */
#define SF_UseSorter 0x0040 /* Sort using a sorter */
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
/* 0x0100 NOT USED */
#define SF_Materialize 0x0100 /* NOT USED */
#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
#define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */
#define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */
#define SF_Compound 0x1000 /* Part of a compound query */
/*
@@ -2276,15 +2213,13 @@ struct Select {
** starting with pDest->iSdst.
**
** SRT_Table Store results in temporary table pDest->iSDParm.
** SRT_Fifo This is like SRT_EphemTab except that the table
** is assumed to already be open. SRT_Fifo has
** the additional property of being able to ignore
** the ORDER BY clause.
** This is like SRT_EphemTab except that the table
** is assumed to already be open.
**
** SRT_DistFifo Store results in a temporary table pDest->iSDParm.
** SRT_DistTable Store results in a temporary table pDest->iSDParm.
** But also use temporary table pDest->iSDParm+1 as
** a record of all prior results and ignore any duplicate
** rows. Name means: "Distinct Fifo".
** rows. Name means: "Distinct Table".
**
** SRT_Queue Store results in priority queue pDest->iSDParm (really
** an index). Append a sequence number so that all entries
@@ -2298,20 +2233,19 @@ struct Select {
#define SRT_Except 2 /* Remove result from a UNION index */
#define SRT_Exists 3 /* Store 1 if the result is not empty */
#define SRT_Discard 4 /* Do not save the results anywhere */
#define SRT_Fifo 5 /* Store result as data with an automatic rowid */
#define SRT_DistFifo 6 /* Like SRT_Fifo, but unique results only */
#define SRT_Queue 7 /* Store result in an queue */
#define SRT_DistQueue 8 /* Like SRT_Queue, but unique results only */
/* The ORDER BY clause is ignored for all of the above */
#define IgnorableOrderby(X) ((X->eDest)<=SRT_DistQueue)
#define IgnorableOrderby(X) ((X->eDest)<=SRT_Discard)
#define SRT_Output 9 /* Output each row of result */
#define SRT_Mem 10 /* Store result in a memory cell */
#define SRT_Set 11 /* Store results as keys in an index */
#define SRT_EphemTab 12 /* Create transient tab and store like SRT_Table */
#define SRT_Coroutine 13 /* Generate a single row of result */
#define SRT_Table 14 /* Store result as data with an automatic rowid */
#define SRT_Output 5 /* Output each row of result */
#define SRT_Mem 6 /* Store result in a memory cell */
#define SRT_Set 7 /* Store results as keys in an index */
#define SRT_EphemTab 8 /* Create transient tab and store like SRT_Table */
#define SRT_Coroutine 9 /* Generate a single row of result */
#define SRT_Table 10 /* Store result as data with an automatic rowid */
#define SRT_DistTable 11 /* Like SRT_Table, but unique results only */
#define SRT_Queue 12 /* Store result in an queue */
#define SRT_DistQueue 13 /* Like SRT_Queue, but unique results only */
/*
** An instance of this object describes where to put of the results of
@@ -2409,10 +2343,12 @@ struct Parse {
u8 checkSchema; /* Causes schema cookie check after an error */
u8 nested; /* Number of nested calls to the parser/code generator */
u8 nTempReg; /* Number of temporary registers in aTempReg[] */
u8 nTempInUse; /* Number of aTempReg[] currently checked out */
u8 nColCache; /* Number of entries in aColCache[] */
u8 iColCache; /* Next entry in aColCache[] to replace */
u8 isMultiWrite; /* True if statement may modify/insert multiple rows */
u8 mayAbort; /* True if statement may throw an ABORT exception */
u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
u8 okConstFactor; /* OK to factor out constants */
int aTempReg[8]; /* Holding area for temporary registers */
int nRangeReg; /* Size of the temporary register block */
int iRangeReg; /* First register in temporary register block */
@@ -2441,6 +2377,7 @@ struct Parse {
Token constraintName;/* Name of the constraint currently being parsed */
yDbMask writeMask; /* Start a write transaction on these databases */
yDbMask cookieMask; /* Bitmask of schema verified databases */
int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */
int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */
int regRowid; /* Register holding rowid of CREATE TABLE entry */
int regRoot; /* Register holding root page number for new objects */
@@ -2699,7 +2636,6 @@ struct Sqlite3Config {
int nPage; /* Number of pages in pPage[] */
int mxParserStack; /* maximum depth of the parser stack */
int sharedCacheEnabled; /* true if shared-cache mode enabled */
int nWorker; /* Number of worker threads to use */
/* The above might be initialized to non-zero. The following need to always
** initially be zero, however. */
int isInit; /* True after initialization has finished */
@@ -2716,13 +2652,6 @@ struct Sqlite3Config {
void(*xSqllog)(void*,sqlite3*,const char*, int);
void *pSqllogArg;
#endif
#ifdef SQLITE_VDBE_COVERAGE
/* The following callback (if not NULL) is invoked on every VDBE branch
** operation. Set the callback using SQLITE_TESTCTRL_VDBE_COVERAGE.
*/
void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx); /* Callback */
void *pVdbeBranchArg; /* 1st argument */
#endif
};
/*
@@ -3056,6 +2985,7 @@ void sqlite3DeleteTable(sqlite3*, Table*);
# define sqlite3AutoincrementBegin(X)
# define sqlite3AutoincrementEnd(X)
#endif
int sqlite3CodeCoroutine(Parse*, Select*, SelectDest*);
void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int);
void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*);
@@ -3103,12 +3033,11 @@ void sqlite3ExprCachePop(Parse*, int);
void sqlite3ExprCacheRemove(Parse*, int, int);
void sqlite3ExprCacheClear(Parse*);
void sqlite3ExprCacheAffinityChange(Parse*, int, int);
void sqlite3ExprCode(Parse*, Expr*, int);
void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
int sqlite3ExprCode(Parse*, Expr*, int);
void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8);
int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
int sqlite3ExprCodeTarget(Parse*, Expr*, int);
void sqlite3ExprCodeAndCache(Parse*, Expr*, int);
int sqlite3ExprCodeAndCache(Parse*, Expr*, int);
int sqlite3ExprCodeExprList(Parse*, ExprList*, int, u8);
#define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */
#define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */
@@ -3146,6 +3075,7 @@ int sqlite3ExprIsConstantNotJoin(Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*);
int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3ExprCanBeNull(const Expr*);
void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
int sqlite3IsRowid(const char*);
void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8);
@@ -3289,7 +3219,7 @@ int sqlite3VarintLen(u64 v);
const char *sqlite3IndexAffinityStr(Vdbe *, Index *);
void sqlite3TableAffinity(Vdbe*, Table*, int);
void sqlite3TableAffinityStr(Vdbe *, Table *);
char sqlite3CompareAffinity(Expr *pExpr, char aff2);
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
char sqlite3ExprAffinity(Expr *pExpr);
@@ -3308,7 +3238,7 @@ int sqlite3ReadSchema(Parse *pParse);
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*);
Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*);
Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
Expr *sqlite3ExprSkipCollate(Expr*);
int sqlite3CheckCollSeq(Parse *, CollSeq *);
@@ -3353,7 +3283,6 @@ void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*);
int sqlite3CodeSubselect(Parse *, Expr *, int, int);
void sqlite3SelectPrep(Parse*, Select*, NameContext*);
int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
int sqlite3ResolveExprNames(NameContext*, Expr*);
@@ -3549,7 +3478,7 @@ const char *sqlite3JournalModename(int);
#define IN_INDEX_EPH 2
#define IN_INDEX_INDEX_ASC 3
#define IN_INDEX_INDEX_DESC 4
int sqlite3FindInIndex(Parse *, Expr *, int*);
int sqlite3FindInIndex(Parse *, Expr *, int*, int);
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
@@ -3649,19 +3578,4 @@ SQLITE_EXTERN void (*sqlite3IoTrace)(const char*,...);
#define MEMTYPE_PCACHE 0x08 /* Page cache allocations */
#define MEMTYPE_DB 0x10 /* Uses sqlite3DbMalloc, not sqlite_malloc */
/*
** Threading interface
*/
#if SQLITE_MAX_WORKER_THREADS>0
int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*);
int sqlite3ThreadJoin(SQLiteThread*, void**);
#endif
/*
** Win32 interface
*/
#if SQLITE_OS_WIN
DWORD sqlite3Win32Wait(HANDLE hObject);
#endif
#endif /* _SQLITEINT_H_ */
+32 -38
View File
@@ -1025,7 +1025,7 @@ static int DbTransPostCmd(
** this method's logic. Not clear how this would be best handled.
*/
if( rc!=TCL_ERROR ){
Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0);
rc = TCL_ERROR;
}
sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0);
@@ -1675,8 +1675,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
*/
case DB_AUTHORIZER: {
#ifdef SQLITE_OMIT_AUTHORIZATION
Tcl_AppendResult(interp, "authorization not available in this build",
(char*)0);
Tcl_AppendResult(interp, "authorization not available in this build", 0);
return TCL_ERROR;
#else
if( objc>3 ){
@@ -1684,7 +1683,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
return TCL_ERROR;
}else if( objc==2 ){
if( pDb->zAuth ){
Tcl_AppendResult(interp, pDb->zAuth, (char*)0);
Tcl_AppendResult(interp, pDb->zAuth, 0);
}
}else{
char *zAuth;
@@ -1770,7 +1769,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
return TCL_ERROR;
}else if( objc==2 ){
if( pDb->zBusy ){
Tcl_AppendResult(interp, pDb->zBusy, (char*)0);
Tcl_AppendResult(interp, pDb->zBusy, 0);
}
}else{
char *zBusy;
@@ -1824,7 +1823,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}else{
if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){
Tcl_AppendResult( interp, "cannot convert \"",
Tcl_GetStringFromObj(objv[3],0), "\" to integer", (char*)0);
Tcl_GetStringFromObj(objv[3],0), "\" to integer", 0);
return TCL_ERROR;
}else{
if( n<0 ){
@@ -1838,8 +1837,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}
}else{
Tcl_AppendResult( interp, "bad option \"",
Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size",
(char*)0);
Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size", 0);
return TCL_ERROR;
}
break;
@@ -1936,7 +1934,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
return TCL_ERROR;
}else if( objc==2 ){
if( pDb->zCommit ){
Tcl_AppendResult(interp, pDb->zCommit, (char*)0);
Tcl_AppendResult(interp, pDb->zCommit, 0);
}
}else{
const char *zCommit;
@@ -2041,8 +2039,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
nSep = strlen30(zSep);
nNull = strlen30(zNull);
if( nSep==0 ){
Tcl_AppendResult(interp,"Error: non-null separator required for copy",
(char*)0);
Tcl_AppendResult(interp,"Error: non-null separator required for copy",0);
return TCL_ERROR;
}
if(strcmp(zConflict, "rollback") != 0 &&
@@ -2052,19 +2049,19 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
strcmp(zConflict, "replace" ) != 0 ) {
Tcl_AppendResult(interp, "Error: \"", zConflict,
"\", conflict-algorithm must be one of: rollback, "
"abort, fail, ignore, or replace", (char*)0);
"abort, fail, ignore, or replace", 0);
return TCL_ERROR;
}
zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
if( zSql==0 ){
Tcl_AppendResult(interp, "Error: no such table: ", zTable, (char*)0);
Tcl_AppendResult(interp, "Error: no such table: ", zTable, 0);
return TCL_ERROR;
}
nByte = strlen30(zSql);
rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rc ){
Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0);
Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0);
nCol = 0;
}else{
nCol = sqlite3_column_count(pStmt);
@@ -2075,7 +2072,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}
zSql = malloc( nByte + 50 + nCol*2 );
if( zSql==0 ) {
Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0);
Tcl_AppendResult(interp, "Error: can't malloc()", 0);
return TCL_ERROR;
}
sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?",
@@ -2090,7 +2087,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
free(zSql);
if( rc ){
Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0);
Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0);
sqlite3_finalize(pStmt);
return TCL_ERROR;
}
@@ -2102,7 +2099,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}
azCol = malloc( sizeof(azCol[0])*(nCol+1) );
if( azCol==0 ) {
Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0);
Tcl_AppendResult(interp, "Error: can't malloc()", 0);
fclose(in);
return TCL_ERROR;
}
@@ -2130,7 +2127,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
sqlite3_snprintf(nErr, zErr,
"Error: %s line %d: expected %d columns of data but found %d",
zFile, lineno, nCol, i+1);
Tcl_AppendResult(interp, zErr, (char*)0);
Tcl_AppendResult(interp, zErr, 0);
free(zErr);
}
zCommit = "ROLLBACK";
@@ -2150,7 +2147,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
rc = sqlite3_reset(pStmt);
free(zLine);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), (char*)0);
Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), 0);
zCommit = "ROLLBACK";
break;
}
@@ -2168,8 +2165,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}else{
/* failure, append lineno where failed */
sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno);
Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,
(char*)0);
Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,0);
rc = TCL_ERROR;
}
break;
@@ -2195,7 +2191,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
break;
#else
Tcl_AppendResult(interp, "extension loading is turned off at compile-time",
(char*)0);
0);
return TCL_ERROR;
#endif
}
@@ -2353,7 +2349,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
*/
case DB_INCRBLOB: {
#ifdef SQLITE_OMIT_INCRBLOB
Tcl_AppendResult(interp, "incrblob not available in this build", (char*)0);
Tcl_AppendResult(interp, "incrblob not available in this build", 0);
return TCL_ERROR;
#else
int isReadonly = 0;
@@ -2460,7 +2456,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
case DB_PROGRESS: {
if( objc==2 ){
if( pDb->zProgress ){
Tcl_AppendResult(interp, pDb->zProgress, (char*)0);
Tcl_AppendResult(interp, pDb->zProgress, 0);
}
}else if( objc==4 ){
char *zProgress;
@@ -2506,7 +2502,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
return TCL_ERROR;
}else if( objc==2 ){
if( pDb->zProfile ){
Tcl_AppendResult(interp, pDb->zProfile, (char*)0);
Tcl_AppendResult(interp, pDb->zProfile, 0);
}
}else{
char *zProfile;
@@ -2551,7 +2547,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
rc = sqlite3_rekey(pDb->db, pKey, nKey);
if( rc ){
Tcl_AppendResult(interp, sqlite3_errstr(rc), (char*)0);
Tcl_AppendResult(interp, sqlite3_errstr(rc), 0);
rc = TCL_ERROR;
}
#endif
@@ -2692,7 +2688,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
return TCL_ERROR;
}else if( objc==2 ){
if( pDb->zTrace ){
Tcl_AppendResult(interp, pDb->zTrace, (char*)0);
Tcl_AppendResult(interp, pDb->zTrace, 0);
}
}else{
char *zTrace;
@@ -2763,7 +2759,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0);
pDb->disableAuth--;
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0);
return TCL_ERROR;
}
pDb->nTransaction++;
@@ -2787,8 +2783,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
*/
case DB_UNLOCK_NOTIFY: {
#ifndef SQLITE_ENABLE_UNLOCK_NOTIFY
Tcl_AppendResult(interp, "unlock_notify not available in this build",
(char*)0);
Tcl_AppendResult(interp, "unlock_notify not available in this build", 0);
rc = TCL_ERROR;
#else
if( objc!=2 && objc!=3 ){
@@ -2811,7 +2806,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}
if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){
Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0);
rc = TCL_ERROR;
}
}
@@ -2940,14 +2935,14 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
if( objc==2 ){
zArg = Tcl_GetStringFromObj(objv[1], 0);
if( strcmp(zArg,"-version")==0 ){
Tcl_AppendResult(interp,sqlite3_libversion(), (char*)0);
Tcl_AppendResult(interp,sqlite3_libversion(),0);
return TCL_OK;
}
if( strcmp(zArg,"-has-codec")==0 ){
#ifdef SQLITE_HAS_CODEC
Tcl_AppendResult(interp,"1",(char*)0);
Tcl_AppendResult(interp,"1",0);
#else
Tcl_AppendResult(interp,"0",(char*)0);
Tcl_AppendResult(interp,"0",0);
#endif
return TCL_OK;
}
@@ -3429,7 +3424,7 @@ static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){
if( argc!=2 ){
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
" TEXT\"", (char*)0);
" TEXT\"", 0);
return TCL_ERROR;
}
MD5Init(&ctx);
@@ -3454,13 +3449,13 @@ static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){
if( argc!=2 ){
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
" FILENAME\"", (char*)0);
" FILENAME\"", 0);
return TCL_ERROR;
}
in = fopen(argv[1],"rb");
if( in==0 ){
Tcl_AppendResult(interp,"unable to open file \"", argv[1],
"\" for reading", (char*)0);
"\" for reading", 0);
return TCL_ERROR;
}
MD5Init(&ctx);
@@ -3778,7 +3773,6 @@ int TCLSH_MAIN(int argc, char **argv){
sqlite3_shutdown();
Tcl_FindExecutable(argv[0]);
Tcl_SetSystemEncoding(NULL, "utf-8");
interp = Tcl_CreateInterp();
#if TCLSH==2
-55
View File
@@ -2703,46 +2703,6 @@ bad_args:
return TCL_ERROR;
}
/*
** Usage: add_test_utf16bin_collate <db ptr>
**
** Add a utf-16 collation sequence named "utf16bin" to the database
** handle. This collation sequence compares arguments in the same way as the
** built-in collation "binary".
*/
static int test_utf16bin_collate_func(
void *pCtx,
int nA, const void *zA,
int nB, const void *zB
){
int nCmp = (nA>nB ? nB : nA);
int res = memcmp(zA, zB, nCmp);
if( res==0 ) res = nA - nB;
return res;
}
static int test_utf16bin_collate(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3 *db;
int rc;
if( objc!=2 ) goto bad_args;
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
rc = sqlite3_create_collation(db, "utf16bin", SQLITE_UTF16, 0,
test_utf16bin_collate_func
);
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
return TCL_OK;
bad_args:
Tcl_WrongNumArgs(interp, 1, objv, "DB");
return TCL_ERROR;
}
/*
** When the collation needed callback is invoked, record the name of
** the requested collating function here. The recorded name is linked
@@ -5884,7 +5844,6 @@ static int test_test_control(
int i;
} aVerb[] = {
{ "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT },
{ "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP },
};
int iVerb;
int iFlag;
@@ -5912,19 +5871,6 @@ static int test_test_control(
sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, val);
break;
}
case SQLITE_TESTCTRL_SORTER_MMAP: {
int val;
sqlite3 *db;
if( objc!=4 ){
Tcl_WrongNumArgs(interp, 2, objv, "DB LIMIT");
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR;
if( Tcl_GetIntFromObj(interp, objv[3], &val) ) return TCL_ERROR;
sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, val);
break;
}
}
Tcl_ResetResult(interp);
@@ -6535,7 +6481,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "add_test_collate", test_collate, 0 },
{ "add_test_collate_needed", test_collate_needed, 0 },
{ "add_test_function", test_function, 0 },
{ "add_test_utf16bin_collate", test_utf16bin_collate, 0 },
#endif
{ "sqlite3_test_errstr", test_errstr, 0 },
{ "tcl_variable_type", tcl_variable_type, 0 },
+1
View File
@@ -76,6 +76,7 @@ static int test_value_overhead(
val.flags = MEM_Str|MEM_Term|MEM_Static;
val.z = "hello world";
val.type = SQLITE_TEXT;
val.enc = SQLITE_UTF8;
for(i=0; i<repeat_count; i++){
-6
View File
@@ -99,12 +99,6 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "mmap", "0", TCL_GLOBAL_ONLY);
#endif
#if SQLITE_MAX_WORKER_THREADS>0
Tcl_SetVar2(interp, "sqlite_options", "worker_threads", "1", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "worker_threads", "0", TCL_GLOBAL_ONLY);
#endif
#if 1 /* def SQLITE_MEMDEBUG */
Tcl_SetVar2(interp, "sqlite_options", "memdebug", "1", TCL_GLOBAL_ONLY);
#else
+2
View File
@@ -499,6 +499,7 @@ static void test_extract(
mem.enc = ENC(db);
pHdr += sqlite3GetVarint(pHdr, &iSerialType);
pBody += sqlite3VdbeSerialGet(pBody, (u32)iSerialType, &mem);
sqlite3VdbeMemStoreType(&mem);
if( iCurrent==iIdx ){
sqlite3_result_value(context, &mem);
@@ -548,6 +549,7 @@ static void test_decode(
pHdr += sqlite3GetVarint(pHdr, &iSerialType);
pBody += sqlite3VdbeSerialGet(pBody, (u32)iSerialType, &mem);
sqlite3VdbeMemStoreType(&mem);
switch( sqlite3_value_type(&mem) ){
case SQLITE_TEXT:
pVal = Tcl_NewStringObj((const char*)sqlite3_value_text(&mem), -1);
-6
View File
@@ -91,9 +91,6 @@ static void statusFunc(
/*
** Extension load function.
*/
#ifdef _WIN32
__declspec(dllexport)
#endif
int testloadext_init(
sqlite3 *db,
char **pzErrMsg,
@@ -112,9 +109,6 @@ int testloadext_init(
/*
** Another extension entry point. This one always fails.
*/
#ifdef _WIN32
__declspec(dllexport)
#endif
int testbrokenext_init(
sqlite3 *db,
char **pzErrMsg,
-27
View File
@@ -1253,32 +1253,6 @@ static int test_config_cis(
return TCL_OK;
}
/*
** Usage: sqlite3_config_worker_threads N
*/
static int test_config_worker_threads(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int rc;
int nThread;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "N");
return TCL_ERROR;
}
if( Tcl_GetIntFromObj(interp, objv[1], &nThread) ){
return TCL_ERROR;
}
rc = sqlite3_config(SQLITE_CONFIG_WORKER_THREADS, nThread);
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
return TCL_OK;
}
/*
** Usage: sqlite3_dump_memsys3 FILENAME
** sqlite3_dump_memsys5 FILENAME
@@ -1532,7 +1506,6 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){
{ "sqlite3_config_error", test_config_error ,0 },
{ "sqlite3_config_uri", test_config_uri ,0 },
{ "sqlite3_config_cis", test_config_cis ,0 },
{ "sqlite3_config_worker_threads", test_config_worker_threads ,0 },
{ "sqlite3_db_config_lookaside",test_db_config_lookaside ,0 },
{ "sqlite3_dump_memsys3", test_dump_memsys3 ,3 },
{ "sqlite3_dump_memsys5", test_dump_memsys3 ,5 },
+1 -48
View File
@@ -67,11 +67,6 @@
** test_syscall list
** Return a list of all system calls. The list is constructed using
** the xNextSystemCall() VFS method.
**
** test_syscall pagesize PGSZ
** If PGSZ is a power of two greater than 256, install a wrapper around
** OS function getpagesize() that reports the system page size as PGSZ.
** Or, if PGSZ is less than zero, remove any wrapper already installed.
*/
#include "sqliteInt.h"
@@ -94,9 +89,7 @@ static struct TestSyscallGlobal {
int bPersist; /* 1 for persistent errors, 0 for transient */
int nCount; /* Fail after this many more calls */
int nFail; /* Number of failures that have occurred */
int pgsz;
sqlite3_syscall_ptr orig_getpagesize;
} gSyscall = { 0, 0, 0, 0, 0 };
} gSyscall = { 0, 0 };
static int ts_open(const char *, int, int);
static int ts_close(int fd);
@@ -657,45 +650,6 @@ static int test_syscall_defaultvfs(
return TCL_OK;
}
static int ts_getpagesize(void){
return gSyscall.pgsz;
}
static int test_syscall_pagesize(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
int pgsz;
if( objc!=3 ){
Tcl_WrongNumArgs(interp, 2, objv, "PGSZ");
return TCL_ERROR;
}
if( Tcl_GetIntFromObj(interp, objv[2], &pgsz) ){
return TCL_ERROR;
}
if( pgsz<0 ){
if( gSyscall.orig_getpagesize ){
pVfs->xSetSystemCall(pVfs, "getpagesize", gSyscall.orig_getpagesize);
}
}else{
if( pgsz<512 || (pgsz & (pgsz-1)) ){
Tcl_AppendResult(interp, "pgsz out of range", 0);
return TCL_ERROR;
}
gSyscall.orig_getpagesize = pVfs->xGetSystemCall(pVfs, "getpagesize");
gSyscall.pgsz = pgsz;
pVfs->xSetSystemCall(
pVfs, "getpagesize", (sqlite3_syscall_ptr)ts_getpagesize
);
}
return TCL_OK;
}
static int test_syscall(
void * clientData,
Tcl_Interp *interp,
@@ -714,7 +668,6 @@ static int test_syscall(
{ "exists", test_syscall_exists },
{ "list", test_syscall_list },
{ "defaultvfs", test_syscall_defaultvfs },
{ "pagesize", test_syscall_pagesize },
{ 0, 0 }
};
int iCmd;
-220
View File
@@ -1,220 +0,0 @@
/*
** 2012 July 21
**
** 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 presents a simple cross-platform threading interface for
** use internally by SQLite.
**
** A "thread" can be created using sqlite3ThreadCreate(). This thread
** runs independently of its creator until it is joined using
** sqlite3ThreadJoin(), at which point it terminates.
**
** Threads do not have to be real. It could be that the work of the
** "thread" is done by the main thread at either the sqlite3ThreadCreate()
** or sqlite3ThreadJoin() call. This is, in fact, what happens in
** single threaded systems. Nothing in SQLite requires multiple threads.
** This interface exists so that applications that want to take advantage
** of multiple cores can do so, while also allowing applications to stay
** single-threaded if desired.
*/
#include "sqliteInt.h"
#if SQLITE_MAX_WORKER_THREADS>0
/********************************* Unix Pthreads ****************************/
#if SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) && SQLITE_THREADSAFE>0
#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */
#include <pthread.h>
/* A running thread */
struct SQLiteThread {
pthread_t tid;
int done;
void *pOut;
};
/* Create a new thread */
int sqlite3ThreadCreate(
SQLiteThread **ppThread, /* OUT: Write the thread object here */
void *(*xTask)(void*), /* Routine to run in a separate thread */
void *pIn /* Argument passed into xTask() */
){
SQLiteThread *p;
assert( ppThread!=0 );
assert( xTask!=0 );
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
if( p==0 ) return SQLITE_NOMEM;
memset(p, 0, sizeof(*p));
if( sqlite3GlobalConfig.bCoreMutex==0
|| pthread_create(&p->tid, 0, xTask, pIn)!=0
){
p->done = 1;
p->pOut = xTask(pIn);
}
*ppThread = p;
return SQLITE_OK;
}
/* Get the results of the thread */
int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
int rc;
assert( ppOut!=0 );
if( p==0 ) return SQLITE_NOMEM;
if( p->done ){
*ppOut = p->pOut;
rc = SQLITE_OK;
}else{
rc = pthread_join(p->tid, ppOut);
}
sqlite3_free(p);
return rc ? SQLITE_ERROR : SQLITE_OK;
}
#endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */
/******************************** End Unix Pthreads *************************/
/********************************* Win32 Threads ****************************/
#if SQLITE_OS_WIN && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */
#include <process.h>
/* A running thread */
struct SQLiteThread {
uintptr_t tid; /* The thread handle */
void *(*xTask)(void*); /* The routine to run as a thread */
void *pIn; /* Argument to xTask */
void *pResult; /* Result of xTask */
};
/* Thread procedure Win32 compatibility shim */
static void sqlite3ThreadProc(
void *pArg /* IN: Pointer to the SQLiteThread structure */
){
SQLiteThread *p = (SQLiteThread *)pArg;
assert( p!=0 );
assert( p->xTask!=0 );
p->pResult = p->xTask(p->pIn);
_endthread();
}
/* Create a new thread */
int sqlite3ThreadCreate(
SQLiteThread **ppThread, /* OUT: Write the thread object here */
void *(*xTask)(void*), /* Routine to run in a separate thread */
void *pIn /* Argument passed into xTask() */
){
SQLiteThread *p;
assert( ppThread!=0 );
assert( xTask!=0 );
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
if( p==0 ) return SQLITE_NOMEM;
if( sqlite3GlobalConfig.bCoreMutex==0 ){
memset(p, 0, sizeof(*p));
}else{
p->xTask = xTask;
p->pIn = pIn;
p->tid = _beginthread(sqlite3ThreadProc, 0, p);
if( p->tid==(uintptr_t)-1 ){
memset(p, 0, sizeof(*p));
}
}
if( p->xTask==0 ){
p->pResult = xTask(pIn);
}
*ppThread = p;
return SQLITE_OK;
}
/* Get the results of the thread */
int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
DWORD rc;
assert( ppOut!=0 );
if( p==0 ) return SQLITE_NOMEM;
if( p->xTask==0 ){
rc = WAIT_OBJECT_0;
}else{
rc = sqlite3Win32Wait((HANDLE)p->tid);
assert( rc!=WAIT_IO_COMPLETION );
}
if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult;
sqlite3_free(p);
return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR;
}
#endif /* SQLITE_OS_WIN && !SQLITE_OS_WINRT */
/******************************** End Win32 Threads *************************/
/********************************* Single-Threaded **************************/
#ifndef SQLITE_THREADS_IMPLEMENTED
/*
** This implementation does not actually create a new thread. It does the
** work of the thread in the main thread, when either the thread is created
** or when it is joined
*/
/* A running thread */
struct SQLiteThread {
void *(*xTask)(void*); /* The routine to run as a thread */
void *pIn; /* Argument to xTask */
void *pResult; /* Result of xTask */
};
/* Create a new thread */
int sqlite3ThreadCreate(
SQLiteThread **ppThread, /* OUT: Write the thread object here */
void *(*xTask)(void*), /* Routine to run in a separate thread */
void *pIn /* Argument passed into xTask() */
){
SQLiteThread *p;
assert( ppThread!=0 );
assert( xTask!=0 );
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
if( p==0 ) return SQLITE_NOMEM;
if( (SQLITE_PTR_TO_INT(p)/17)&1 ){
p->xTask = xTask;
p->pIn = pIn;
}else{
p->xTask = 0;
p->pResult = xTask(pIn);
}
*ppThread = p;
return SQLITE_OK;
}
/* Get the results of the thread */
int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
assert( ppOut!=0 );
if( p==0 ) return SQLITE_NOMEM;
if( p->xTask ){
*ppOut = p->xTask(p->pIn);
}else{
*ppOut = p->pResult;
}
sqlite3_free(p);
return SQLITE_OK;
}
#endif /* !defined(SQLITE_THREADS_IMPLEMENTED) */
/****************************** End Single-Threaded *************************/
#endif /* SQLITE_MAX_WORKER_THREADS>0 */
+10 -3
View File
@@ -566,7 +566,6 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
assert( pTable!=0 );
if( (v = sqlite3GetVdbe(pParse))!=0 ){
int base;
static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList dropTrigger[] = {
{ OP_Rewind, 0, ADDR(9), 0},
{ OP_String8, 0, 1, 0}, /* 1 */
@@ -581,7 +580,7 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
sqlite3BeginWriteOperation(pParse, 0, iDb);
sqlite3OpenMasterTable(pParse, iDb);
base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger, iLn);
base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger);
sqlite3VdbeChangeP4(v, base+1, pTrigger->zName, P4_TRANSIENT);
sqlite3VdbeChangeP4(v, base+4, "trigger", P4_STATIC);
sqlite3ChangeCookie(pParse, iDb);
@@ -727,7 +726,15 @@ static int codeTriggerProgram(
** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy
*/
pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
assert( pParse->okConstFactor==0 );
/* Clear the cookieGoto flag. When coding triggers, the cookieGoto
** variable is used as a flag to indicate to sqlite3ExprCodeConstants()
** that it is not safe to refactor constants (this happens after the
** start of the first loop in the SQL statement is coded - at that
** point code may be conditionally executed, so it is no longer safe to
** initialize constant register values). */
assert( pParse->cookieGoto==0 || pParse->cookieGoto==-1 );
pParse->cookieGoto = 0;
switch( pStep->op ){
case TK_UPDATE: {
+9 -17
View File
@@ -390,7 +390,7 @@ void sqlite3Update(
regKey = iPk;
}else{
sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey,
sqlite3IndexAffinityStr(v, pPk), nPk);
sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, regKey);
}
sqlite3WhereEnd(pWInfo);
@@ -434,23 +434,18 @@ void sqlite3Update(
if( aToOpen[iDataCur-iBaseCur] ){
assert( pPk!=0 );
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
VdbeCoverageNeverTaken(v);
}
labelContinue = labelBreak;
sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
VdbeCoverage(v);
}else if( pPk ){
labelContinue = sqlite3VdbeMakeLabel(v);
sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak);
addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey);
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
VdbeCoverage(v);
}else{
labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak,
regOldRowid);
VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
VdbeCoverage(v);
}
/* If the record number will change, set register regNewRowid to
@@ -460,7 +455,7 @@ void sqlite3Update(
assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid );
if( chngRowid ){
sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); VdbeCoverage(v);
sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid);
}
/* Compute the old pre-UPDATE content of the row being changed, if that
@@ -529,7 +524,8 @@ void sqlite3Update(
** verified. One could argue that this is wrong.
*/
if( tmask&TRIGGER_BEFORE ){
sqlite3TableAffinity(v, pTab, regNew);
sqlite3VdbeAddOp2(v, OP_Affinity, regNew, pTab->nCol);
sqlite3TableAffinityStr(v, pTab);
sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
TRIGGER_BEFORE, pTab, regOldRowid, onError, labelContinue);
@@ -541,10 +537,8 @@ void sqlite3Update(
*/
if( pPk ){
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue,regKey,nKey);
VdbeCoverage(v);
}else{
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
VdbeCoverage(v);
}
/* If it did not delete it, the row-trigger may still have modified
@@ -580,7 +574,6 @@ void sqlite3Update(
}else{
j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
}
VdbeCoverageNeverTaken(v);
}
sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx);
@@ -624,7 +617,7 @@ void sqlite3Update(
/* Nothing to do at end-of-loop for a single-pass */
}else if( pPk ){
sqlite3VdbeResolveLabel(v, labelContinue);
sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop);
}else{
sqlite3VdbeAddOp2(v, OP_Goto, 0, labelContinue);
}
@@ -742,8 +735,7 @@ static void updateVirtualTable(
*/
assert( v );
ephemTab = pParse->nTab++;
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0));
sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
sqlite3VdbeAddOp2(v, OP_OpenHash, ephemTab, pTab->nCol+1+(pRowid!=0));
/* fill the ephemeral table
*/
@@ -753,7 +745,7 @@ static void updateVirtualTable(
/* Generate code to scan the ephemeral table and call VUpdate. */
iReg = ++pParse->nMem;
pParse->nMem += pTab->nCol+1;
addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0); VdbeCoverage(v);
addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0);
sqlite3VdbeAddOp3(v, OP_Column, ephemTab, 0, iReg);
sqlite3VdbeAddOp3(v, OP_Column, ephemTab, (pRowid?1:0), iReg+1);
for(i=0; i<pTab->nCol; i++){
@@ -763,7 +755,7 @@ static void updateVirtualTable(
sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVTab, P4_VTAB);
sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
sqlite3MayAbort(pParse);
sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1);
sqlite3VdbeJumpHere(v, addr);
sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
+2 -1
View File
@@ -317,7 +317,7 @@ int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
sqlite3VdbeMemRelease(pMem);
pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem);
pMem->enc = desiredEnc;
pMem->flags |= (MEM_Term);
pMem->flags |= (MEM_Term|MEM_Dyn);
pMem->z = (char*)zOut;
pMem->zMalloc = pMem->z;
@@ -445,6 +445,7 @@ char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte, u8 enc){
}
assert( (m.flags & MEM_Term)!=0 || db->mallocFailed );
assert( (m.flags & MEM_Str)!=0 || db->mallocFailed );
assert( (m.flags & MEM_Dyn)!=0 || db->mallocFailed );
assert( m.z || db->mallocFailed );
return m.z;
}
+5 -13
View File
@@ -1123,12 +1123,13 @@ int sqlite3AddInt64(i64 *pA, i64 iB){
testcase( iA>0 && LARGEST_INT64 - iA == iB );
testcase( iA>0 && LARGEST_INT64 - iA == iB - 1 );
if( iA>0 && LARGEST_INT64 - iA < iB ) return 1;
*pA += iB;
}else{
testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 1 );
testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 2 );
if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1;
*pA += iB;
}
*pA += iB;
return 0;
}
int sqlite3SubInt64(i64 *pA, i64 iB){
@@ -1152,18 +1153,9 @@ int sqlite3MulInt64(i64 *pA, i64 iB){
iA0 = iA % TWOPOWER32;
iB1 = iB/TWOPOWER32;
iB0 = iB % TWOPOWER32;
if( iA1==0 ){
if( iB1==0 ){
*pA *= iB;
return 0;
}
r = iA0*iB1;
}else if( iB1==0 ){
r = iA1*iB0;
}else{
/* If both iA1 and iB1 are non-zero, overflow will result */
return 1;
}
if( iA1*iB1 != 0 ) return 1;
assert( iA1*iB0==0 || iA0*iB1==0 );
r = iA1*iB0 + iA0*iB1;
testcase( r==(-TWOPOWER31)-1 );
testcase( r==(-TWOPOWER31) );
testcase( r==TWOPOWER31 );
+403 -509
View File
File diff suppressed because it is too large Load Diff
+3 -46
View File
@@ -65,12 +65,9 @@ struct VdbeOp {
char *zComment; /* Comment to improve readability */
#endif
#ifdef VDBE_PROFILE
u32 cnt; /* Number of times this instruction was executed */
int cnt; /* Number of times this instruction was executed */
u64 cycles; /* Total time spent executing this instruction */
#endif
#ifdef SQLITE_VDBE_COVERAGE
int iSrcLine; /* Source-code line that generated this opcode */
#endif
};
typedef struct VdbeOp VdbeOp;
@@ -170,7 +167,7 @@ int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno);
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
@@ -211,12 +208,9 @@ void sqlite3VdbeSetVarmask(Vdbe*, int);
#endif
void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*,int);
int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
typedef int (*RecordCompare)(int,const void*,UnpackedRecord*,int);
RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
#ifndef SQLITE_OMIT_TRIGGER
void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
#endif
@@ -244,41 +238,4 @@ void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
# define VdbeModuleComment(X)
#endif
/*
** The VdbeCoverage macros are used to set a coverage testing point
** for VDBE branch instructions. The coverage testing points are line
** numbers in the sqlite3.c source file. VDBE branch coverage testing
** only works with an amalagmation build. That's ok since a VDBE branch
** coverage build designed for testing the test suite only. No application
** should ever ship with VDBE branch coverage measuring turned on.
**
** VdbeCoverage(v) // Mark the previously coded instruction
** // as a branch
**
** VdbeCoverageIf(v, conditional) // Mark previous if conditional true
**
** VdbeCoverageAlwaysTaken(v) // Previous branch is always taken
**
** VdbeCoverageNeverTaken(v) // Previous branch is never taken
**
** Every VDBE branch operation must be tagged with one of the macros above.
** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and
** -DSQLITE_DEBUG then an ALWAYS() will fail in the vdbeTakeBranch()
** routine in vdbe.c, alerting the developer to the missed tag.
*/
#ifdef SQLITE_VDBE_COVERAGE
void sqlite3VdbeSetLineNumber(Vdbe*,int);
# define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__)
# define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__)
# define VdbeCoverageAlwaysTaken(v) sqlite3VdbeSetLineNumber(v,2);
# define VdbeCoverageNeverTaken(v) sqlite3VdbeSetLineNumber(v,1);
# define VDBE_OFFSET_LINENO(x) (__LINE__+x)
#else
# define VdbeCoverage(v)
# define VdbeCoverageIf(v,x)
# define VdbeCoverageAlwaysTaken(v)
# define VdbeCoverageNeverTaken(v)
# define VDBE_OFFSET_LINENO(x) 0
#endif
#endif
+9 -11
View File
@@ -72,10 +72,10 @@ struct VdbeCursor {
u8 nullRow; /* True if pointing to a row with no data */
u8 rowidIsValid; /* True if lastRowid is valid */
u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
Bool isEphemeral:1; /* True for an ephemeral table */
Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
Bool isTable:1; /* True if a table requiring integer keys */
Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */
Bool multiPseudo:1; /* Multi-register pseudo-cursor */
sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
i64 seqCount; /* Sequence counter */
i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
@@ -169,6 +169,7 @@ struct Mem {
} u;
int n; /* Number of characters in string value, excluding '\0' */
u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
u8 type; /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
#ifdef SQLITE_DEBUG
Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
@@ -195,10 +196,9 @@ struct Mem {
#define MEM_Int 0x0004 /* Value is an integer */
#define MEM_Real 0x0008 /* Value is a real number */
#define MEM_Blob 0x0010 /* Value is a BLOB */
#define MEM_AffMask 0x001f /* Mask of affinity bits */
#define MEM_RowSet 0x0020 /* Value is a RowSet object */
#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */
#define MEM_Undefined 0x0080 /* Value is undefined */
#define MEM_Invalid 0x0080 /* Value is undefined */
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
#define MEM_TypeMask 0x01ff /* Mask of type bits */
@@ -209,7 +209,7 @@ struct Mem {
** string is \000 or \u0000 terminated
*/
#define MEM_Term 0x0200 /* String rep is nul terminated */
#define MEM_Dyn 0x0400 /* Need to call Mem.xDel() on Mem.z */
#define MEM_Dyn 0x0400 /* Need to call sqliteFree() on Mem.z */
#define MEM_Static 0x0800 /* Mem.z points to a static string */
#define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */
#define MEM_Agg 0x2000 /* Mem.z points to an agg function context */
@@ -230,7 +230,7 @@ struct Mem {
** is for use inside assert() statements only.
*/
#ifdef SQLITE_DEBUG
#define memIsValid(M) ((M)->flags & MEM_Undefined)==0
#define memIsValid(M) ((M)->flags & MEM_Invalid)==0
#endif
/*
@@ -425,20 +425,19 @@ int sqlite3VdbeMemNumerify(Mem*);
int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*);
void sqlite3VdbeMemRelease(Mem *p);
void sqlite3VdbeMemReleaseExternal(Mem *p);
#define VdbeMemDynamic(X) \
(((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
#define VdbeMemRelease(X) \
if( VdbeMemDynamic(X) ) sqlite3VdbeMemReleaseExternal(X);
if((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame)) \
sqlite3VdbeMemReleaseExternal(X);
int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
const char *sqlite3OpcodeName(int);
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
int sqlite3VdbeCloseStatement(Vdbe *, int);
void sqlite3VdbeFrameDelete(VdbeFrame*);
int sqlite3VdbeFrameRestore(VdbeFrame *);
void sqlite3VdbeMemStoreType(Mem *pMem);
int sqlite3VdbeTransferError(Vdbe *p);
int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *);
void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *);
int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *);
void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
@@ -456,7 +455,6 @@ int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
#ifdef SQLITE_DEBUG
void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*);
int sqlite3VdbeCheckMemInvariants(Mem*);
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
+25 -61
View File
@@ -135,6 +135,7 @@ const void *sqlite3_value_blob(sqlite3_value *pVal){
Mem *p = (Mem*)pVal;
if( p->flags & (MEM_Blob|MEM_Str) ){
sqlite3VdbeMemExpandBlob(p);
p->flags &= ~MEM_Str;
p->flags |= MEM_Blob;
return p->n ? p->z : 0;
}else{
@@ -171,41 +172,7 @@ const void *sqlite3_value_text16le(sqlite3_value *pVal){
}
#endif /* SQLITE_OMIT_UTF16 */
int sqlite3_value_type(sqlite3_value* pVal){
static const u8 aType[] = {
SQLITE_BLOB, /* 0x00 */
SQLITE_NULL, /* 0x01 */
SQLITE_TEXT, /* 0x02 */
SQLITE_NULL, /* 0x03 */
SQLITE_INTEGER, /* 0x04 */
SQLITE_NULL, /* 0x05 */
SQLITE_INTEGER, /* 0x06 */
SQLITE_NULL, /* 0x07 */
SQLITE_FLOAT, /* 0x08 */
SQLITE_NULL, /* 0x09 */
SQLITE_FLOAT, /* 0x0a */
SQLITE_NULL, /* 0x0b */
SQLITE_INTEGER, /* 0x0c */
SQLITE_NULL, /* 0x0d */
SQLITE_INTEGER, /* 0x0e */
SQLITE_NULL, /* 0x0f */
SQLITE_BLOB, /* 0x10 */
SQLITE_NULL, /* 0x11 */
SQLITE_TEXT, /* 0x12 */
SQLITE_NULL, /* 0x13 */
SQLITE_INTEGER, /* 0x14 */
SQLITE_NULL, /* 0x15 */
SQLITE_INTEGER, /* 0x16 */
SQLITE_NULL, /* 0x17 */
SQLITE_FLOAT, /* 0x18 */
SQLITE_NULL, /* 0x19 */
SQLITE_FLOAT, /* 0x1a */
SQLITE_NULL, /* 0x1b */
SQLITE_INTEGER, /* 0x1c */
SQLITE_NULL, /* 0x1d */
SQLITE_INTEGER, /* 0x1e */
SQLITE_NULL, /* 0x1f */
};
return aType[pVal->flags&MEM_AffMask];
return pVal->type;
}
/**************************** sqlite3_result_ *******************************
@@ -726,30 +693,6 @@ int sqlite3_data_count(sqlite3_stmt *pStmt){
return pVm->nResColumn;
}
/*
** Return a pointer to static memory containing an SQL NULL value.
*/
static const Mem *columnNullValue(void){
/* Even though the Mem structure contains an element
** of type i64, on certain architectures (x86) with certain compiler
** switches (-Os), gcc may align this Mem object on a 4-byte boundary
** instead of an 8-byte one. This all works fine, except that when
** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s
** that a Mem structure is located on an 8-byte boundary. To prevent
** these assert()s from failing, when building with SQLITE_DEBUG defined
** using gcc, we force nullMem to be 8-byte aligned using the magical
** __attribute__((aligned(8))) macro. */
static const Mem nullMem
#if defined(SQLITE_DEBUG) && defined(__GNUC__)
__attribute__((aligned(8)))
#endif
= {0, "", (double)0, {0}, 0, MEM_Null, 0,
#ifdef SQLITE_DEBUG
0, 0, /* pScopyFrom, pFiller */
#endif
0, 0 };
return &nullMem;
}
/*
** Check to see if column iCol of the given statement is valid. If
@@ -766,11 +709,32 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
sqlite3_mutex_enter(pVm->db->mutex);
pOut = &pVm->pResultSet[i];
}else{
/* If the value passed as the second argument is out of range, return
** a pointer to the following static Mem object which contains the
** value SQL NULL. Even though the Mem structure contains an element
** of type i64, on certain architectures (x86) with certain compiler
** switches (-Os), gcc may align this Mem object on a 4-byte boundary
** instead of an 8-byte one. This all works fine, except that when
** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s
** that a Mem structure is located on an 8-byte boundary. To prevent
** these assert()s from failing, when building with SQLITE_DEBUG defined
** using gcc, we force nullMem to be 8-byte aligned using the magical
** __attribute__((aligned(8))) macro. */
static const Mem nullMem
#if defined(SQLITE_DEBUG) && defined(__GNUC__)
__attribute__((aligned(8)))
#endif
= {0, "", (double)0, {0}, 0, MEM_Null, SQLITE_NULL, 0,
#ifdef SQLITE_DEBUG
0, 0, /* pScopyFrom, pFiller */
#endif
0, 0 };
if( pVm && ALWAYS(pVm->db) ){
sqlite3_mutex_enter(pVm->db->mutex);
sqlite3Error(pVm->db, SQLITE_RANGE, 0);
}
pOut = (Mem*)columnNullValue();
pOut = (Mem*)&nullMem;
}
return pOut;
}
@@ -1167,7 +1131,7 @@ int sqlite3_bind_text16(
#endif /* SQLITE_OMIT_UTF16 */
int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
int rc;
switch( sqlite3_value_type((sqlite3_value*)pValue) ){
switch( pValue->type ){
case SQLITE_INTEGER: {
rc = sqlite3_bind_int64(pStmt, i, pValue->u.i);
break;
+85 -673
View File
File diff suppressed because it is too large Load Diff
+34 -27
View File
@@ -133,20 +133,22 @@ int sqlite3_blob_open(
** which closes the b-tree cursor and (possibly) commits the
** transaction.
*/
static const int iLn = VDBE_OFFSET_LINENO(4);
static const VdbeOpList openBlob[] = {
/* {OP_Transaction, 0, 0, 0}, // 0: Inserted separately */
{OP_TableLock, 0, 0, 0}, /* 1: Acquire a read or write lock */
{OP_Transaction, 0, 0, 0}, /* 0: Start a transaction */
{OP_VerifyCookie, 0, 0, 0}, /* 1: Check the schema cookie */
{OP_TableLock, 0, 0, 0}, /* 2: Acquire a read or write lock */
/* One of the following two instructions is replaced by an OP_Noop. */
{OP_OpenRead, 0, 0, 0}, /* 2: Open cursor 0 for reading */
{OP_OpenWrite, 0, 0, 0}, /* 3: Open cursor 0 for read/write */
{OP_Variable, 1, 1, 1}, /* 4: Push the rowid to the stack */
{OP_NotExists, 0, 10, 1}, /* 5: Seek the cursor */
{OP_Column, 0, 0, 1}, /* 6 */
{OP_ResultRow, 1, 0, 0}, /* 7 */
{OP_Goto, 0, 4, 0}, /* 8 */
{OP_Close, 0, 0, 0}, /* 9 */
{OP_Halt, 0, 0, 0}, /* 10 */
{OP_OpenRead, 0, 0, 0}, /* 3: Open cursor 0 for reading */
{OP_OpenWrite, 0, 0, 0}, /* 4: Open cursor 0 for read/write */
{OP_Variable, 1, 1, 1}, /* 5: Push the rowid to the stack */
{OP_NotExists, 0, 10, 1}, /* 6: Seek the cursor */
{OP_Column, 0, 0, 1}, /* 7 */
{OP_ResultRow, 1, 0, 0}, /* 8 */
{OP_Goto, 0, 5, 0}, /* 9 */
{OP_Close, 0, 0, 0}, /* 10 */
{OP_Halt, 0, 0, 0}, /* 11 */
};
int rc = SQLITE_OK;
@@ -259,31 +261,36 @@ int sqlite3_blob_open(
Vdbe *v = (Vdbe *)pBlob->pStmt;
int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob);
sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, flags,
pTab->pSchema->schema_cookie,
pTab->pSchema->iGeneration);
sqlite3VdbeChangeP5(v, 1);
sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn);
/* Configure the OP_Transaction */
sqlite3VdbeChangeP1(v, 0, iDb);
sqlite3VdbeChangeP2(v, 0, flags);
/* Configure the OP_VerifyCookie */
sqlite3VdbeChangeP1(v, 1, iDb);
sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie);
sqlite3VdbeChangeP3(v, 1, pTab->pSchema->iGeneration);
/* Make sure a mutex is held on the table to be accessed */
sqlite3VdbeUsesBtree(v, iDb);
/* Configure the OP_TableLock instruction */
#ifdef SQLITE_OMIT_SHARED_CACHE
sqlite3VdbeChangeToNoop(v, 1);
sqlite3VdbeChangeToNoop(v, 2);
#else
sqlite3VdbeChangeP1(v, 1, iDb);
sqlite3VdbeChangeP2(v, 1, pTab->tnum);
sqlite3VdbeChangeP3(v, 1, flags);
sqlite3VdbeChangeP4(v, 1, pTab->zName, P4_TRANSIENT);
sqlite3VdbeChangeP1(v, 2, iDb);
sqlite3VdbeChangeP2(v, 2, pTab->tnum);
sqlite3VdbeChangeP3(v, 2, flags);
sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT);
#endif
/* Remove either the OP_OpenWrite or OpenRead. Set the P2
** parameter of the other to pTab->tnum. */
sqlite3VdbeChangeToNoop(v, 3 - flags);
sqlite3VdbeChangeP2(v, 2 + flags, pTab->tnum);
sqlite3VdbeChangeP3(v, 2 + flags, iDb);
sqlite3VdbeChangeToNoop(v, 4 - flags);
sqlite3VdbeChangeP2(v, 3 + flags, pTab->tnum);
sqlite3VdbeChangeP3(v, 3 + flags, iDb);
/* Configure the number of columns. Configure the cursor to
** think that the table has one more column than it really
@@ -292,8 +299,8 @@ int sqlite3_blob_open(
** we can invoke OP_Column to fill in the vdbe cursors type
** and offset cache without causing any IO.
*/
sqlite3VdbeChangeP4(v, 2+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32);
sqlite3VdbeChangeP2(v, 6, pTab->nCol);
sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32);
sqlite3VdbeChangeP2(v, 7, pTab->nCol);
if( !db->mallocFailed ){
pParse->nVar = 1;
pParse->nMem = 1;
+149 -57
View File
@@ -18,42 +18,6 @@
#include "sqliteInt.h"
#include "vdbeInt.h"
#ifdef SQLITE_DEBUG
/*
** Check invariants on a Mem object.
**
** This routine is intended for use inside of assert() statements, like
** this: assert( sqlite3VdbeCheckMemInvariants(pMem) );
*/
int sqlite3VdbeCheckMemInvariants(Mem *p){
/* The MEM_Dyn bit is set if and only if Mem.xDel is a non-NULL destructor
** function for Mem.z
*/
assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
assert( (p->flags & MEM_Dyn)!=0 || p->xDel==0 );
/* If p holds a string or blob, the Mem.z must point to exactly
** one of the following:
**
** (1) Memory in Mem.zMalloc and managed by the Mem object
** (2) Memory to be freed using Mem.xDel
** (3) An ephermal string or blob
** (4) A static string or blob
*/
if( (p->flags & (MEM_Str|MEM_Blob)) && p->z!=0 ){
assert(
((p->z==p->zMalloc)? 1 : 0) +
((p->flags&MEM_Dyn)!=0 ? 1 : 0) +
((p->flags&MEM_Ephem)!=0 ? 1 : 0) +
((p->flags&MEM_Static)!=0 ? 1 : 0) == 1
);
}
return 1;
}
#endif
/*
** If pMem is an object with a valid string representation, this routine
** ensures the internal encoding for the string representation is
@@ -103,7 +67,12 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
** in pMem->z is discarded.
*/
int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
assert( sqlite3VdbeCheckMemInvariants(pMem) );
assert( 1 >=
((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) +
(((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) +
((pMem->flags&MEM_Ephem) ? 1 : 0) +
((pMem->flags&MEM_Static) ? 1 : 0)
);
assert( (pMem->flags&MEM_RowSet)==0 );
/* If the bPreserve flag is set to true, then the memory cell must already
@@ -121,8 +90,7 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
}
if( pMem->zMalloc==0 ){
VdbeMemRelease(pMem);
pMem->z = 0;
sqlite3VdbeMemRelease(pMem);
pMem->flags = MEM_Null;
return SQLITE_NOMEM;
}
@@ -131,13 +99,13 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
if( pMem->z && bPreserve && pMem->z!=pMem->zMalloc ){
memcpy(pMem->zMalloc, pMem->z, pMem->n);
}
if( (pMem->flags&MEM_Dyn)!=0 ){
assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC );
if( (pMem->flags&MEM_Dyn)!=0 && pMem->xDel ){
assert( pMem->xDel!=SQLITE_DYNAMIC );
pMem->xDel((void *)(pMem->z));
}
pMem->z = pMem->zMalloc;
pMem->flags &= ~(MEM_Dyn|MEM_Ephem|MEM_Static);
pMem->flags &= ~(MEM_Ephem|MEM_Static);
pMem->xDel = 0;
return SQLITE_OK;
}
@@ -306,9 +274,9 @@ void sqlite3VdbeMemReleaseExternal(Mem *p){
sqlite3VdbeMemFinalize(p, p->u.pDef);
assert( (p->flags & MEM_Agg)==0 );
sqlite3VdbeMemRelease(p);
}else if( p->flags&MEM_Dyn ){
}else if( p->flags&MEM_Dyn && p->xDel ){
assert( (p->flags&MEM_RowSet)==0 );
assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 );
assert( p->xDel!=SQLITE_DYNAMIC );
p->xDel((void *)p->z);
p->xDel = 0;
}else if( p->flags&MEM_RowSet ){
@@ -321,10 +289,9 @@ void sqlite3VdbeMemReleaseExternal(Mem *p){
/*
** Release any memory held by the Mem. This may leave the Mem in an
** inconsistent state, for example with (Mem.z==0) and
** (Mem.flags==MEM_Str).
** (Mem.type==SQLITE_TEXT).
*/
void sqlite3VdbeMemRelease(Mem *p){
assert( sqlite3VdbeCheckMemInvariants(p) );
VdbeMemRelease(p);
if( p->zMalloc ){
sqlite3DbFree(p->db, p->zMalloc);
@@ -513,6 +480,7 @@ void sqlite3VdbeMemSetNull(Mem *pMem){
sqlite3RowSetClear(pMem->u.pRowSet);
}
MemSetTypeFlag(pMem, MEM_Null);
pMem->type = SQLITE_NULL;
}
void sqlite3ValueSetNull(sqlite3_value *p){
sqlite3VdbeMemSetNull((Mem*)p);
@@ -525,6 +493,7 @@ void sqlite3ValueSetNull(sqlite3_value *p){
void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
sqlite3VdbeMemRelease(pMem);
pMem->flags = MEM_Blob|MEM_Zero;
pMem->type = SQLITE_BLOB;
pMem->n = 0;
if( n<0 ) n = 0;
pMem->u.nZero = n;
@@ -547,6 +516,7 @@ void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
sqlite3VdbeMemRelease(pMem);
pMem->u.i = val;
pMem->flags = MEM_Int;
pMem->type = SQLITE_INTEGER;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -561,6 +531,7 @@ void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
sqlite3VdbeMemRelease(pMem);
pMem->r = val;
pMem->flags = MEM_Real;
pMem->type = SQLITE_FLOAT;
}
}
#endif
@@ -616,7 +587,7 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
Mem *pX;
for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){
if( pX->pScopyFrom==pMem ){
pX->flags |= MEM_Undefined;
pX->flags |= MEM_Invalid;
pX->pScopyFrom = 0;
}
}
@@ -658,7 +629,6 @@ int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
VdbeMemRelease(pTo);
memcpy(pTo, pFrom, MEMCELLSIZE);
pTo->flags &= ~MEM_Dyn;
pTo->xDel = 0;
if( pTo->flags&(MEM_Str|MEM_Blob) ){
if( 0==(pFrom->flags&MEM_Static) ){
@@ -769,6 +739,7 @@ int sqlite3VdbeMemSetStr(
pMem->n = nByte;
pMem->flags = flags;
pMem->enc = (enc==0 ? SQLITE_UTF8 : enc);
pMem->type = (enc==0 ? SQLITE_BLOB : SQLITE_TEXT);
#ifndef SQLITE_OMIT_UTF16
if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
@@ -783,6 +754,119 @@ int sqlite3VdbeMemSetStr(
return SQLITE_OK;
}
/*
** Compare the values contained by the two memory cells, returning
** negative, zero or positive if pMem1 is less than, equal to, or greater
** than pMem2. Sorting order is NULL's first, followed by numbers (integers
** and reals) sorted numerically, followed by text ordered by the collating
** sequence pColl and finally blob's ordered by memcmp().
**
** Two NULL values are considered equal by this function.
*/
int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
int rc;
int f1, f2;
int combined_flags;
f1 = pMem1->flags;
f2 = pMem2->flags;
combined_flags = f1|f2;
assert( (combined_flags & MEM_RowSet)==0 );
/* If one value is NULL, it is less than the other. If both values
** are NULL, return 0.
*/
if( combined_flags&MEM_Null ){
return (f2&MEM_Null) - (f1&MEM_Null);
}
/* If one value is a number and the other is not, the number is less.
** If both are numbers, compare as reals if one is a real, or as integers
** if both values are integers.
*/
if( combined_flags&(MEM_Int|MEM_Real) ){
double r1, r2;
if( (f1 & f2 & MEM_Int)!=0 ){
if( pMem1->u.i < pMem2->u.i ) return -1;
if( pMem1->u.i > pMem2->u.i ) return 1;
return 0;
}
if( (f1&MEM_Real)!=0 ){
r1 = pMem1->r;
}else if( (f1&MEM_Int)!=0 ){
r1 = (double)pMem1->u.i;
}else{
return 1;
}
if( (f2&MEM_Real)!=0 ){
r2 = pMem2->r;
}else if( (f2&MEM_Int)!=0 ){
r2 = (double)pMem2->u.i;
}else{
return -1;
}
if( r1<r2 ) return -1;
if( r1>r2 ) return 1;
return 0;
}
/* If one value is a string and the other is a blob, the string is less.
** If both are strings, compare using the collating functions.
*/
if( combined_flags&MEM_Str ){
if( (f1 & MEM_Str)==0 ){
return 1;
}
if( (f2 & MEM_Str)==0 ){
return -1;
}
assert( pMem1->enc==pMem2->enc );
assert( pMem1->enc==SQLITE_UTF8 ||
pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );
/* The collation sequence must be defined at this point, even if
** the user deletes the collation sequence after the vdbe program is
** compiled (this was not always the case).
*/
assert( !pColl || pColl->xCmp );
if( pColl ){
if( pMem1->enc==pColl->enc ){
/* The strings are already in the correct encoding. Call the
** comparison function directly */
return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
}else{
const void *v1, *v2;
int n1, n2;
Mem c1;
Mem c2;
memset(&c1, 0, sizeof(c1));
memset(&c2, 0, sizeof(c2));
sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem);
sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem);
v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc);
n1 = v1==0 ? 0 : c1.n;
v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);
n2 = v2==0 ? 0 : c2.n;
rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
sqlite3VdbeMemRelease(&c1);
sqlite3VdbeMemRelease(&c2);
return rc;
}
}
/* If a NULL pointer was passed as the collate function, fall through
** to the blob case and use memcmp(). */
}
/* Both values must be blobs. Compare using memcmp(). */
rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n);
if( rc==0 ){
rc = pMem1->n - pMem2->n;
}
return rc;
}
/*
** Move data out of a btree key or data field and into a Mem structure.
** The data or key is taken from the entry that pCur is currently pointing
@@ -823,22 +907,22 @@ int sqlite3VdbeMemFromBtree(
sqlite3VdbeMemRelease(pMem);
pMem->z = &zData[offset];
pMem->flags = MEM_Blob|MEM_Ephem;
pMem->n = (int)amt;
}else if( SQLITE_OK==(rc = sqlite3VdbeMemGrow(pMem, amt+2, 0)) ){
pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term;
pMem->enc = 0;
pMem->type = SQLITE_BLOB;
if( key ){
rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);
}else{
rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);
}
if( rc==SQLITE_OK ){
pMem->z[amt] = 0;
pMem->z[amt+1] = 0;
pMem->flags = MEM_Blob|MEM_Term;
pMem->n = (int)amt;
}else{
pMem->z[amt] = 0;
pMem->z[amt+1] = 0;
if( rc!=SQLITE_OK ){
sqlite3VdbeMemRelease(pMem);
}
}
pMem->n = (int)amt;
return rc;
}
@@ -896,6 +980,7 @@ sqlite3_value *sqlite3ValueNew(sqlite3 *db){
Mem *p = sqlite3DbMallocZero(db, sizeof(*p));
if( p ){
p->flags = MEM_Null;
p->type = SQLITE_NULL;
p->db = db;
}
return p;
@@ -941,9 +1026,11 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
if( pRec->pKeyInfo ){
assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol );
assert( pRec->pKeyInfo->enc==ENC(db) );
pRec->flags = UNPACKED_PREFIX_MATCH;
pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord)));
for(i=0; i<nCol; i++){
pRec->aMem[i].flags = MEM_Null;
pRec->aMem[i].type = SQLITE_NULL;
pRec->aMem[i].db = db;
}
}else{
@@ -1016,6 +1103,7 @@ static int valueFromExpr(
zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken);
if( zVal==0 ) goto no_mem;
sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
if( op==TK_FLOAT ) pVal->type = SQLITE_FLOAT;
}
if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
@@ -1033,9 +1121,9 @@ static int valueFromExpr(
){
sqlite3VdbeMemNumerify(pVal);
if( pVal->u.i==SMALLEST_INT64 ){
pVal->flags &= ~MEM_Int;
pVal->flags &= MEM_Int;
pVal->flags |= MEM_Real;
pVal->r = (double)SMALLEST_INT64;
pVal->r = (double)LARGEST_INT64;
}else{
pVal->u.i = -pVal->u.i;
}
@@ -1061,6 +1149,9 @@ static int valueFromExpr(
}
#endif
if( pVal ){
sqlite3VdbeMemStoreType(pVal);
}
*ppVal = pVal;
return rc;
@@ -1224,6 +1315,7 @@ int sqlite3Stat4ProbeSetValue(
sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
}
pVal->db = pParse->db;
sqlite3VdbeMemStoreType((Mem*)pVal);
}
}
}else{
+431 -1561
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1306,7 +1306,7 @@ int sqlite3WalOpen(
sqlite3OsClose(pRet->pWalFd);
sqlite3_free(pRet);
}else{
int iDC = sqlite3OsDeviceCharacteristics(pDbFd);
int iDC = sqlite3OsDeviceCharacteristics(pRet->pWalFd);
if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; }
if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){
pRet->padToSectorBoundary = 0;
@@ -2677,7 +2677,7 @@ static int walWriteToLog(
iAmt -= iFirstAmt;
pContent = (void*)(iFirstAmt + (char*)pContent);
assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) );
rc = sqlite3OsSync(p->pFd, p->syncFlags & SQLITE_SYNC_MASK);
rc = sqlite3OsSync(p->pFd, p->syncFlags);
if( iAmt==0 || rc ) return rc;
}
rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset);
+254 -428
View File
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -121,7 +121,7 @@ struct WhereLoop {
struct { /* Information for virtual tables */
int idxNum; /* Index number */
u8 needFree; /* True if sqlite3_free(idxStr) is needed */
i8 isOrdered; /* True if satisfies ORDER BY */
u8 isOrdered; /* True if satisfies ORDER BY */
u16 omitMask; /* Terms that may be omitted */
char *idxStr; /* Index identifier string */
} vtab;
@@ -183,7 +183,8 @@ struct WherePath {
Bitmask revLoop; /* aLoop[]s that should be reversed for ORDER BY */
LogEst nRow; /* Estimated number of rows generated by this path */
LogEst rCost; /* Total cost of this path */
i8 isOrdered; /* No. of ORDER BY terms satisfied. -1 for unknown */
u8 isOrdered; /* True if this path satisfies ORDER BY */
u8 isOrderedValid; /* True if the isOrdered field is valid */
WhereLoop **aLoop; /* Array of WhereLoop objects implementing this path */
};
@@ -397,7 +398,7 @@ struct WhereInfo {
Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
LogEst nRowOut; /* Estimated number of output rows */
u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */
u8 bOBSat; /* ORDER BY satisfied by indices */
u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */
u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */
-21
View File
@@ -334,25 +334,4 @@ do_test alter4-8.2 {
}
} [list $::sql]
# Test that a default value equal to -1 multipied by the smallest possible
# 64-bit integer is correctly converted to a real.
do_execsql_test alter4-9.1 {
CREATE TABLE t5(
a INTEGER DEFAULT -9223372036854775808,
b INTEGER DEFAULT (-(-9223372036854775808))
);
INSERT INTO t5 DEFAULT VALUES;
}
do_execsql_test alter4-9.2 { SELECT typeof(a), a, typeof(b), b FROM t5; } {
integer -9223372036854775808
real 9.22337203685478e+18
}
do_execsql_test alter4-9.3 {
ALTER TABLE t5 ADD COLUMN c INTEGER DEFAULT (-(-9223372036854775808));
SELECT typeof(c), c FROM t5;
} {real 9.22337203685478e+18}
finish_test
-3
View File
@@ -326,7 +326,6 @@ do_execsql_test 6.2 {
reset_db
sqlite3_db_config_lookaside db 0 0 0
database_may_be_corrupt
do_execsql_test 7.1 {
CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a, b);
@@ -367,8 +366,6 @@ do_execsql_test 7.5 {
SELECT * FROM t1 WHERE a = 5;
} {5 5}
database_never_corrupt
#-------------------------------------------------------------------------
#
reset_db
-18
View File
@@ -16,7 +16,6 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix capi3
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
@@ -1222,23 +1221,6 @@ do_test capi3-19.1 {
sqlite3_prepare_tkt3134 db
} {}
# Test that calling sqlite3_column_blob() on a TEXT value does not change
# the return type of subsequent calls to sqlite3_column_type().
#
do_execsql_test 20.1 {
CREATE TABLE t4(x);
INSERT INTO t4 VALUES('abcdefghij');
}
do_test 20.2 {
set stmt [sqlite3_prepare db "SELECT * FROM t4" -1 dummy]
sqlite3_step $stmt
} {SQLITE_ROW}
do_test 20.3 { sqlite3_column_type $stmt 0 } {TEXT}
do_test 20.4 { sqlite3_column_blob $stmt 0 } {abcdefghij}
do_test 20.5 { sqlite3_column_type $stmt 0 } {TEXT}
do_test 20.6 { sqlite3_finalize $stmt } SQLITE_OK
# Tests of the interface when no VFS is registered.
#
if {![info exists tester_do_binarylog]} {
+1 -5
View File
@@ -20,11 +20,7 @@ source $testdir/tester.tcl
# Make sure the system encoding is utf-8. Otherwise, if the system encoding
# is other than utf-8, [file isfile $x] may not refer to the same file
# as [sqlite3 db $x].
#
# This is no longer needed here because it should be done within the test
# fixture executable itself, via Tcl_SetSystemEncoding.
#
# encoding system utf-8
encoding system utf-8
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
+8 -3
View File
@@ -47,12 +47,12 @@ do_test 1.2 {
catchsql {
SELECT c FROM t1 WHERE a>'abc';
}
} {1 {database disk image is malformed}}
} {0 {}}
do_test 1.3 {
catchsql {
PRAGMA integrity_check
}
} {1 {database disk image is malformed}}
} {0 ok}
do_test 1.4 {
catchsql {
SELECT c FROM t1 ORDER BY a;
@@ -71,6 +71,11 @@ do_test 2.1 {
catchsql {
SELECT rowid FROM t1 WHERE a='abc' and b='xyz123456789XYZ';
}
} {1 {database disk image is malformed}}
# The following test result is brittle. The point above is to try to
# force a buffer overread by a corrupt database file. If we get an
# incorrect answer from a corrupt database file, that is OK. If the
# result below changes, that just means that "undefined behavior" has
# changed.
} {0 52}
finish_test
+11 -13
View File
@@ -20,18 +20,6 @@ set testprefix corruptH
do_not_use_codec
database_may_be_corrupt
# The corruption migrations tested by the code in this file are not detected
# mmap mode.
#
# The reason is that in mmap mode, the different queries may use different
# PgHdr objects for the same page (same data, but different PgHdr container
# objects). And so the corruption is not detected.
#
if {[permutation]=="mmap"} {
finish_test
return
}
# Initialize the database.
#
do_execsql_test 1.1 {
@@ -64,7 +52,6 @@ do_test 1.2 {
} {}
do_test 1.3 {
breakpoint
db eval { PRAGMA secure_delete=1 }
list [catch {
db eval { SELECT * FROM t1 WHERE a IN (1, 2) } {
@@ -110,6 +97,9 @@ do_test 2.2 {
} {}
# The corruption migration caused by the test case below does not
# cause corruption to be detected in mmap mode.
#
# The trick here is that the root page of the tree scanned by the outer
# query is also currently on the free-list. So while the first seek on
# the table (for a==1) works, by the time the second is attempted The
@@ -119,7 +109,15 @@ do_test 2.2 {
# the cursor (as it is now marked with PgHdr.intKey==0) and returns
# SQLITE_CORRUPT.
#
# However, in mmap mode, the outer query and the inner queries use
# different PgHdr objects (same data, but different PgHdr container
# objects). And so the corruption is not detected. Instead, the second
# seek fails to find anything and only a single row is returned.
#
set res23 {1 {database disk image is malformed}}
if {[permutation]=="mmap"} {
set res23 {0 one}
}
do_test 2.3 {
list [catch {
set res [list]
-79
View File
@@ -1,79 +0,0 @@
# 2014-01-20
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix corruptI
if {[permutation]=="mmap"} {
finish_test
return
}
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec
database_may_be_corrupt
# Initialize the database.
#
do_execsql_test 1.1 {
PRAGMA page_size=1024;
PRAGMA auto_vacuum=0;
CREATE TABLE t1(a);
CREATE INDEX i1 ON t1(a);
INSERT INTO t1 VALUES('abcdefghijklmnop');
} {}
db close
do_test 1.2 {
set offset [hexio_get_int [hexio_read test.db [expr 2*1024 + 8] 2]]
set off [expr 2*1024 + $offset + 1]
hexio_write test.db $off 7f06
sqlite3 db test.db
catchsql { SELECT * FROM t1 WHERE a = 10 }
} {0 {}}
do_test 1.3 {
db close
set offset [hexio_get_int [hexio_read test.db [expr 2*1024 + 8] 2]]
set off [expr 2*1024 + $offset + 1]
hexio_write test.db $off FFFF7f02
sqlite3 db test.db
catchsql { SELECT * FROM t1 WHERE a = 10 }
} {1 {database disk image is malformed}}
do_test 2.0 {
execsql {
CREATE TABLE r(x);
INSERT INTO r VALUES('ABCDEFGHIJK');
CREATE INDEX r1 ON r(x);
}
set pg [db one {SELECT rootpage FROM sqlite_master WHERE name = 'r1'}]
} {5}
do_test 2.1 {
db close
set offset [hexio_get_int [hexio_read test.db [expr (5-1)*1024 + 8] 2]]
set off [expr (5-1)*1024 + $offset + 1]
hexio_write test.db $off FFFF0004
sqlite3 db test.db
catchsql { SELECT * FROM r WHERE x >= 10.0 }
} {1 {database disk image is malformed}}
do_test 2.2 {
catchsql { SELECT * FROM r WHERE x >= 10 }
} {1 {database disk image is malformed}}
finish_test
+4 -32
View File
@@ -51,12 +51,9 @@ proc do_temptables_test {tn sql temptables} {
set ret ""
db eval "EXPLAIN [set sql]" {
if {$opcode == "OpenEphemeral" || $opcode == "SorterOpen"} {
if {$p5 != "08" && $p5!="00"} { error "p5 = $p5" }
if {$p5 == "08"} {
lappend ret hash
} else {
lappend ret btree
}
lappend ret btree
} elseif {$opcode == "OpenHash"} {
lappend ret hash
}
}
set ret
@@ -162,7 +159,7 @@ do_execsql_test 2.0 {
foreach {tn sql temptables res} {
1 "a, b FROM t1" {} {A B a b}
2 "b, a FROM t1" {} {B A b a}
3 "a, b, c FROM t1" {hash} {A B C a b c}
3 "a, b, c FROM t1" {hash} {a b c A B C}
4 "a, b, c FROM t1 ORDER BY a, b, c" {btree} {A B C a b c}
5 "b FROM t1 WHERE a = 'a'" {} {b}
6 "b FROM t1 ORDER BY +b COLLATE binary" {btree hash} {B b}
@@ -197,29 +194,4 @@ do_test 3.1 {
}]
} {0}
#-------------------------------------------------------------------------
# Ticket [fccbde530a6583bf2748400919f1603d5425995c] (2014-01-08)
# The logic that computes DISTINCT sometimes thinks that a zeroblob()
# and a blob of all zeros are different when they should be the same.
#
do_execsql_test 4.1 {
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1(a INTEGER);
INSERT INTO t1 VALUES(3);
INSERT INTO t1 VALUES(2);
INSERT INTO t1 VALUES(1);
INSERT INTO t1 VALUES(2);
INSERT INTO t1 VALUES(3);
INSERT INTO t1 VALUES(1);
CREATE TABLE t2(x);
INSERT INTO t2
SELECT DISTINCT
CASE a WHEN 1 THEN x'0000000000'
WHEN 2 THEN zeroblob(5)
ELSE 'xyzzy' END
FROM t1;
SELECT quote(x) FROM t2 ORDER BY 1;
} {'xyzzy' X'0000000000'}
finish_test
-28
View File
@@ -219,32 +219,4 @@ do_execsql_test 5.2 {
SELECT count(*) FROM sqlite_master WHERE name LIKE 't8%';
} {0 6}
# At one point this was causing a memory leak.
#
foreach {tn sql} {
1 {}
2 { INSERT INTO ft(ft) VALUES('merge=2,2'); }
} {
reset_db
do_execsql_test 6.$tn.1 "
CREATE TABLE t1(x);
CREATE VIRTUAL TABLE ft USING fts3;
INSERT INTO ft VALUES('hello world');
$sql
"
db close
sqlite3 db test.db
do_execsql_test 6.$tn.2 { SELECT * FROM t1 } {}
do_test 6.$tn.3 {
sqlite3 db2 test.db
db2 eval { DROP TABLE t1 }
db2 close
set stmt [sqlite3_prepare db { SELECT * FROM ft } -1 dummy]
sqlite3_finalize $stmt
} {SQLITE_OK}
db close
}
finish_test
-11
View File
@@ -354,17 +354,6 @@ do_test fts3d-6.5 {
SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
}
} {xyz_content xyz_segdir xyz_segments}
# ALTER TABLE RENAME on an FTS3 table following an incr-merge op.
#
do_test fts3d-6.6 {
execsql { INSERT INTO xyz(xyz) VALUES('merge=2,2') }
sqlite3 db test.db
execsql {
ALTER TABLE xyz RENAME TO ott;
SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
}
} {ott_content ott_segdir ott_segments ott_stat}
finish_test
-5
View File
@@ -1361,9 +1361,4 @@ for {set i 65536} {$i<=0x10ffff} {incr i 139} {
do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i
}
# Test char().
#
do_execsql_test func-31.1 {
SELECT char(), length(char()), typeof(char())
} {{} 0 text}
finish_test
+1 -1
View File
@@ -29,7 +29,7 @@ ifcapable !subquery {
proc nEphemeral {sql} {
set nEph 0
foreach op [execsql "EXPLAIN $sql"] {
if {$op eq "OpenEphemeral"} {incr nEph}
if {$op eq "OpenEphemeral" || $op eq "OpenHash"} {incr nEph}
}
set nEph
}
-177
View File
@@ -159,181 +159,4 @@ do_test in4-3.12 {
execsql { SELECT * FROM t3 WHERE x IN (1, 2) AND y IN ()}
} {}
# Tests for "... IN (?)" and "... NOT IN (?)". In other words, tests
# for when the RHS of IN is a single expression. This should work the
# same as the == and <> operators.
#
do_execsql_test in4-3.21 {
SELECT * FROM t3 WHERE x=10 AND y IN (10);
} {10 10 10}
do_execsql_test in4-3.22 {
SELECT * FROM t3 WHERE x IN (10) AND y=10;
} {10 10 10}
do_execsql_test in4-3.23 {
SELECT * FROM t3 WHERE x IN (10) AND y IN (10);
} {10 10 10}
do_execsql_test in4-3.24 {
SELECT * FROM t3 WHERE x=1 AND y NOT IN (10);
} {1 1 1}
do_execsql_test in4-3.25 {
SELECT * FROM t3 WHERE x NOT IN (10) AND y=1;
} {1 1 1}
do_execsql_test in4-3.26 {
SELECT * FROM t3 WHERE x NOT IN (10) AND y NOT IN (10);
} {1 1 1}
# The query planner recognizes that "x IN (?)" only generates a
# single match and can use this information to optimize-out ORDER BY
# clauses.
#
do_execsql_test in4-3.31 {
DROP INDEX t3i1;
CREATE UNIQUE INDEX t3xy ON t3(x,y);
SELECT *, '|' FROM t3 A, t3 B
WHERE A.x=10 AND A.y IN (10)
AND B.x=1 AND B.y IN (1);
} {10 10 10 1 1 1 |}
do_execsql_test in4-3.32 {
EXPLAIN QUERY PLAN
SELECT *, '|' FROM t3 A, t3 B
WHERE A.x=10 AND A.y IN (10)
AND B.x=1 AND B.y IN (1);
} {~/B-TREE/} ;# No separate sorting pass
do_execsql_test in4-3.33 {
SELECT *, '|' FROM t3 A, t3 B
WHERE A.x IN (10) AND A.y=10
AND B.x IN (1) AND B.y=1;
} {10 10 10 1 1 1 |}
do_execsql_test in4-3.34 {
EXPLAIN QUERY PLAN
SELECT *, '|' FROM t3 A, t3 B
WHERE A.x IN (10) AND A.y=10
AND B.x IN (1) AND B.y=1;
} {~/B-TREE/} ;# No separate sorting pass
# An expression of the form "x IN (?,?)" creates an ephemeral table to
# hold the list of values on the RHS. But "x IN (?)" does not create
# an ephemeral table.
#
do_execsql_test in4-3.41 {
SELECT * FROM t3 WHERE x IN (10,11);
} {10 10 10}
do_execsql_test in4-3.42 {
EXPLAIN
SELECT * FROM t3 WHERE x IN (10,11);
} {/OpenEphemeral/}
do_execsql_test in4-3.43 {
SELECT * FROM t3 WHERE x IN (10);
} {10 10 10}
do_execsql_test in4-3.44 {
EXPLAIN
SELECT * FROM t3 WHERE x IN (10);
} {~/OpenEphemeral/}
do_execsql_test in4-3.45 {
SELECT * FROM t3 WHERE x NOT IN (10,11);
} {1 1 1}
do_execsql_test in4-3.46 {
EXPLAIN
SELECT * FROM t3 WHERE x NOT IN (10,11);
} {/OpenEphemeral/}
do_execsql_test in4-3.47 {
SELECT * FROM t3 WHERE x NOT IN (10);
} {1 1 1}
do_execsql_test in4-3.48 {
EXPLAIN
SELECT * FROM t3 WHERE x NOT IN (10);
} {~/OpenEphemeral/}
# Make sure that when "x IN (?)" is converted into "x==?" that collating
# sequence and affinity computations do not get messed up.
#
do_execsql_test in4-4.1 {
CREATE TABLE t4a(a TEXT, b TEXT COLLATE nocase, c);
INSERT INTO t4a VALUES('ABC','abc',1);
INSERT INTO t4a VALUES('def','xyz',2);
INSERT INTO t4a VALUES('ghi','ghi',3);
SELECT c FROM t4a WHERE a=b ORDER BY c;
} {3}
do_execsql_test in4-4.2 {
SELECT c FROM t4a WHERE b=a ORDER BY c;
} {1 3}
do_execsql_test in4-4.3 {
SELECT c FROM t4a WHERE (a||'')=b ORDER BY c;
} {1 3}
do_execsql_test in4-4.4 {
SELECT c FROM t4a WHERE (a||'')=(b||'') ORDER BY c;
} {3}
do_execsql_test in4-4.5 {
SELECT c FROM t4a WHERE a IN (b) ORDER BY c;
} {3}
do_execsql_test in4-4.6 {
SELECT c FROM t4a WHERE (a||'') IN (b) ORDER BY c;
} {3}
do_execsql_test in4-4.11 {
CREATE TABLE t4b(a TEXT, b NUMERIC, c);
INSERT INTO t4b VALUES('1.0',1,4);
SELECT c FROM t4b WHERE a=b;
} {4}
do_execsql_test in4-4.12 {
SELECT c FROM t4b WHERE b=a;
} {4}
do_execsql_test in4-4.13 {
SELECT c FROM t4b WHERE +a=b;
} {4}
do_execsql_test in4-4.14 {
SELECT c FROM t4b WHERE a=+b;
} {}
do_execsql_test in4-4.15 {
SELECT c FROM t4b WHERE +b=a;
} {}
do_execsql_test in4-4.16 {
SELECT c FROM t4b WHERE b=+a;
} {4}
do_execsql_test in4-4.17 {
SELECT c FROM t4b WHERE a IN (b);
} {}
do_execsql_test in4-4.18 {
SELECT c FROM t4b WHERE b IN (a);
} {4}
do_execsql_test in4-4.19 {
SELECT c FROM t4b WHERE +b IN (a);
} {}
do_execsql_test in4-5.1 {
CREATE TABLE t5(c INTEGER PRIMARY KEY, d TEXT COLLATE nocase);
INSERT INTO t5 VALUES(17, 'fuzz');
SELECT 1 FROM t5 WHERE 'fuzz' IN (d); -- match
SELECT 2 FROM t5 WHERE 'FUZZ' IN (d); -- no match
SELECT 3 FROM t5 WHERE d IN ('fuzz'); -- match
SELECT 4 FROM t5 WHERE d IN ('FUZZ'); -- match
} {1 3 4}
# An expression of the form "x IN (y)" can be used as "x=y" by the
# query planner when computing transitive constraints or to run the
# query using an index on y.
#
do_execsql_test in4-6.1 {
CREATE TABLE t6a(a INTEGER PRIMARY KEY, b);
INSERT INTO t6a VALUES(1,2),(3,4),(5,6);
CREATE TABLE t6b(c INTEGER PRIMARY KEY, d);
INSERT INTO t6b VALUES(4,44),(5,55),(6,66);
SELECT * FROM t6a, t6b WHERE a=3 AND b IN (c);
} {3 4 4 44}
do_execsql_test in4-6.1-eqp {
EXPLAIN QUERY PLAN
SELECT * FROM t6a, t6b WHERE a=3 AND b IN (c);
} {~/SCAN/}
do_execsql_test in4-6.2 {
SELECT * FROM t6a, t6b WHERE a=3 AND c IN (b);
} {3 4 4 44}
do_execsql_test in4-6.2-eqp {
EXPLAIN QUERY PLAN
SELECT * FROM t6a, t6b WHERE a=3 AND c IN (b);
} {~/SCAN/}
finish_test
+3 -3
View File
@@ -65,17 +65,17 @@ do_test in5-2.4 {
}
} {12a 56e}
do_test in5-2.5.1 {
regexp {OpenEphemeral} [db eval {
regexp {Open(Ephemeral|Hash)} [db eval {
EXPLAIN SELECT d FROM t2 WHERE a IN t3x AND b IN t1y AND c IN t1z
}]
} {1}
do_test in5-2.5.2 {
regexp {OpenEphemeral} [db eval {
regexp {Open(Ephemeral|Hash)} [db eval {
EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t3y AND c IN t1z
}]
} {1}
do_test in5-2.5.3 {
regexp {OpenEphemeral} [db eval {
regexp {Open(Ephemeral|Hash)} [db eval {
EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t3z
}]
} {1}
+1 -11
View File
@@ -398,21 +398,11 @@ ifcapable compound {
} {1 2 3 4 5 6 7 8 9}
do_test insert-10.2 {
catchsql {
INSERT INTO t10 VALUES(11,12,13), (14,15), (16,17,28);
INSERT INTO t10 VALUES(11,12,13), (14,15);
}
} {1 {all VALUES must have the same number of terms}}
}
# Need for the OP_SoftNull opcode
#
do_execsql_test insert-11.1 {
CREATE TABLE t11a AS SELECT '123456789' AS x;
CREATE TABLE t11b (a INTEGER PRIMARY KEY, b, c);
INSERT INTO t11b SELECT x, x, x FROM t11a;
SELECT quote(a), quote(b), quote(c) FROM t11b;
} {123456789 '123456789' '123456789'}
integrity_check insert-99.0
finish_test
+1 -1
View File
@@ -253,7 +253,7 @@ ifcapable vacuum {
#
do_test insert4-5.1 {
# Table does not exist.
catchsql { INSERT INTO t2 SELECT a, b FROM nosuchtable }
catchsql { INSERT INTO t2 SELECT * FROM nosuchtable }
} {1 {no such table: nosuchtable}}
do_test insert4-5.2 {
# Number of columns does not match.
-35
View File
@@ -641,39 +641,4 @@ do_test join-11.10 {
execsql { SELECT * FROM t2 NATURAL JOIN t1 }
} {1 one 2 two}
#-------------------------------------------------------------------------
# Test that at most 64 tables are allowed in a join.
#
do_execsql_test join-12.1 {
CREATE TABLE t14(x);
INSERT INTO t14 VALUES('abcdefghij');
}
proc jointest {tn nTbl res} {
set sql "SELECT 1 FROM [string repeat t14, [expr $nTbl-1]] t14;"
uplevel [list do_catchsql_test $tn $sql $res]
}
jointest join-12.2 30 {0 1}
jointest join-12.3 63 {0 1}
jointest join-12.4 64 {0 1}
jointest join-12.5 65 {1 {at most 64 tables in a join}}
jointest join-12.6 66 {1 {at most 64 tables in a join}}
jointest join-12.7 127 {1 {at most 64 tables in a join}}
jointest join-12.8 128 {1 {at most 64 tables in a join}}
jointest join-12.9 1000 {1 {at most 64 tables in a join}}
# If SQLite is built with SQLITE_MEMDEBUG, then the huge number of realloc()
# calls made by the following test cases are too time consuming to run.
# Without SQLITE_MEMDEBUG, realloc() is fast enough that these are not
# a problem.
ifcapable pragma&&compileoption_diags {
if {[lsearch [db eval {PRAGMA compile_options}] MEMDEBUG]<0} {
jointest join-12.10 65534 {1 {at most 64 tables in a join}}
jointest join-12.11 65535 {1 {too many references to "t14": max 65535}}
jointest join-12.12 65536 {1 {too many references to "t14": max 65535}}
jointest join-12.13 65537 {1 {too many references to "t14": max 65535}}
}
}
finish_test
-20
View File
@@ -616,24 +616,4 @@ do_test limit-13.81 {
db eval {SELECT z FROM v13c LIMIT 1 OFFSET 8}
} {}
do_execsql_test limit-14.1 {
SELECT 123 LIMIT 1 OFFSET 0
} {123}
do_execsql_test limit-14.2 {
SELECT 123 LIMIT 1 OFFSET 1
} {}
do_execsql_test limit-14.3 {
SELECT 123 LIMIT 0 OFFSET 0
} {}
do_execsql_test limit-14.4 {
SELECT 123 LIMIT 0 OFFSET 1
} {}
do_execsql_test limit-14.6 {
SELECT 123 LIMIT -1 OFFSET 0
} {123}
do_execsql_test limit-14.7 {
SELECT 123 LIMIT -1 OFFSET 1
} {}
finish_test
+4 -17
View File
@@ -66,12 +66,6 @@ if {$::tcl_platform(os) eq "Darwin"} {
set dlerror_nosymbol {dlsym(XXX, %2$s): symbol not found}
}
if {$::tcl_platform(platform) eq "windows"} {
set dlerror_nosuchfile {The specified module could not be found.*}
set dlerror_notadll {%%1 is not a valid Win32 application.*}
set dlerror_nosymbol {The specified procedure could not be found.*}
}
# Make sure the test extension actually exists. If it does not
# exist, try to create it. If unable to create it, then skip this
# test file.
@@ -173,7 +167,7 @@ do_test loadext-2.3 {
regsub {0x[1234567890abcdefABCDEF]*} $msg XXX msg
}
list $rc $msg
} /[list 1 [format $dlerror_nosymbol $testextension icecream]]/
} [list 1 [format $dlerror_nosymbol $testextension icecream]]
# Try to load an extension for which the entry point fails (returns non-zero)
#
@@ -273,17 +267,10 @@ do_malloc_test loadext-5 -tclprep {
} -tclbody {
if {[autoinstall_test_functions]==7} {error "out of memory"}
}
# On Windows, this malloc test must be skipped because the winDlOpen
# function itself can fail due to "out of memory" conditions.
#
if {$::tcl_platform(platform) ne "windows"} {
do_malloc_test loadext-6 -tclbody {
db enable_load_extension 1
sqlite3_load_extension db $::testextension testloadext_init
}
do_malloc_test loadext-6 -tclbody {
db enable_load_extension 1
sqlite3_load_extension db $::testextension testloadext_init
}
autoinstall_test_functions
finish_test
-22
View File
@@ -880,28 +880,6 @@ do_malloc_test 39 -tclprep {
db close
}
reset_db
add_test_utf16bin_collate db
do_execsql_test 40.1 {
CREATE TABLE t1(a);
INSERT INTO t1 VALUES('fghij');
INSERT INTO t1 VALUES('pqrst');
INSERT INTO t1 VALUES('abcde');
INSERT INTO t1 VALUES('uvwxy');
INSERT INTO t1 VALUES('klmno');
}
do_execsql_test 40.2 {
SELECT * FROM t1 ORDER BY 1 COLLATE utf16bin;
} {abcde fghij klmno pqrst uvwxy}
do_faultsim_test 40.3 -faults oom-trans* -body {
execsql {
SELECT * FROM t1 ORDER BY 1 COLLATE utf16bin;
}
} -test {
faultsim_test_result {0 {abcde fghij klmno pqrst uvwxy}}
faultsim_integrity_check
}
# Ensure that no file descriptors were leaked.
do_test malloc-99.X {
catch {db close}
+1 -22
View File
@@ -25,6 +25,7 @@ if {!$MEMDEBUG} {
return
}
# Construct a test database
#
forcedelete test.db.bu
@@ -115,28 +116,6 @@ ifcapable stat3 {
}
}
do_execsql_test 7.0 {
PRAGMA cache_size = 5;
}
do_faultsim_test 7 -faults oom-trans* -prep {
if {$iFail < 500} { set iFail 2000 }
if {$iFail > 1215} { set iFail 2000 }
} -body {
execsql {
WITH r(x,y) AS (
SELECT 1, randomblob(100)
UNION ALL
SELECT x+1, randomblob(100) FROM r
LIMIT 1000
)
SELECT count(x), length(y) FROM r GROUP BY (x%5)
}
} -test {
set res [list 200 100 200 100 200 100 200 100 200 100]
faultsim_test_result [list 0 $res]
}
# Ensure that no file descriptors were leaked.
do_test malloc-99.X {
catch {db close}
+2 -20
View File
@@ -64,28 +64,10 @@ do_execsql_test 1.7 {
EXPLAIN QUERY PLAN
SELECT DISTINCT c, b, a FROM t1 WHERE +a=0;
} {/B-TREE/}
# In some cases, it is faster to do repeated index lookups than it is to
# sort. But in other cases, it is faster to sort than to do repeated index
# lookups.
#
do_execsql_test 2.1a {
CREATE TABLE t2(a,b,c);
CREATE INDEX t2bc ON t2(b,c);
ANALYZE;
INSERT INTO sqlite_stat1 VALUES('t1','t1bc','1000000 10 9');
INSERT INTO sqlite_stat1 VALUES('t2','t2bc','100 10 5');
ANALYZE sqlite_master;
EXPLAIN QUERY PLAN
SELECT * FROM t2 WHERE a=0 ORDER BY a, b, c;
} {~/B-TREE/}
do_execsql_test 2.1b {
do_execsql_test 2.1 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a=0 ORDER BY a, b, c;
} {/B-TREE/}
} {~/B-TREE/}
do_execsql_test 2.2 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE +a=0 ORDER BY a, b, c;
-183
View File
@@ -1,183 +0,0 @@
# 2014-03-21
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing that the block-sort optimization.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix orderby6
# Run all tests twice. Once with a normal table and a second time
# with a WITHOUT ROWID table
#
foreach {tn rowidclause} {1 {} 2 {WITHOUT ROWID}} {
# Construct a table with 1000 rows and a split primary key
#
reset_db
do_test $tn.1 {
db eval "CREATE TABLE t1(a,b,c,PRIMARY KEY(b,c)) $rowidclause;"
db eval {
WITH RECURSIVE
cnt(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM cnt WHERE x<1000)
INSERT INTO t1 SELECT x, x%40, x/40 FROM cnt;
}
} {}
# Run various ORDER BY queries that can benefit from block-sort.
# Compare the output to the same output using a full-sort enforced
# by adding + to each term of the ORDER BY clause.
#
do_execsql_test $tn.2 {
SELECT b,a,c FROM t1 ORDER BY b,a,c;
} [db eval {SELECT b,a,c FROM t1 ORDER BY +b,+a,+c}]
do_execsql_test $tn.3 {
SELECT b,a,c FROM t1 ORDER BY b,c DESC,a;
} [db eval {SELECT b,a,c FROM t1 ORDER BY +b,+c DESC,+a}]
do_execsql_test $tn.4 {
SELECT b,a,c FROM t1 ORDER BY b DESC,c,a;
} [db eval {SELECT b,a,c FROM t1 ORDER BY +b DESC,+c,+a}]
do_execsql_test $tn.5 {
SELECT b,a,c FROM t1 ORDER BY b DESC,a,c;
} [db eval {SELECT b,a,c FROM t1 ORDER BY +b DESC,+a,+c}]
# LIMIT and OFFSET clauses on block-sort queries.
#
do_execsql_test $tn.11 {
SELECT a FROM t1 ORDER BY b, a LIMIT 10 OFFSET 20;
} {840 880 920 960 1000 1 41 81 121 161}
do_execsql_test $tn.11x {
SELECT a FROM t1 ORDER BY +b, a LIMIT 10 OFFSET 20;
} {840 880 920 960 1000 1 41 81 121 161}
do_execsql_test $tn.12 {
SELECT a FROM t1 ORDER BY b DESC, a LIMIT 10 OFFSET 20;
} {839 879 919 959 999 38 78 118 158 198}
do_execsql_test $tn.12 {
SELECT a FROM t1 ORDER BY +b DESC, a LIMIT 10 OFFSET 20;
} {839 879 919 959 999 38 78 118 158 198}
do_execsql_test $tn.13 {
SELECT a FROM t1 ORDER BY b, a DESC LIMIT 10 OFFSET 45;
} {161 121 81 41 1 962 922 882 842 802}
do_execsql_test $tn.13x {
SELECT a FROM t1 ORDER BY +b, a DESC LIMIT 10 OFFSET 45;
} {161 121 81 41 1 962 922 882 842 802}
do_execsql_test $tn.14 {
SELECT a FROM t1 ORDER BY b DESC, a LIMIT 10 OFFSET 45;
} {838 878 918 958 998 37 77 117 157 197}
do_execsql_test $tn.14x {
SELECT a FROM t1 ORDER BY +b DESC, a LIMIT 10 OFFSET 45;
} {838 878 918 958 998 37 77 117 157 197}
# Many test cases where the LIMIT+OFFSET window is in various
# alignments with block-sort boundaries.
#
foreach {tx limit offset orderby} {
1 10 24 {+b,+a}
2 10 25 {+b,+a}
3 10 26 {+b,+a}
4 10 39 {+b,+a}
5 10 40 {+b,+a}
6 10 41 {+b,+a}
7 27 24 {+b,+a}
8 27 49 {+b,+a}
11 10 24 {+b DESC,+a}
12 10 25 {+b DESC,+a}
13 10 26 {+b DESC,+a}
14 10 39 {+b DESC,+a}
15 10 40 {+b DESC,+a}
16 10 41 {+b DESC,+a}
17 27 24 {+b DESC,+a}
18 27 49 {+b DESC,+a}
21 10 24 {+b,+a DESC}
22 10 25 {+b,+a DESC}
23 10 26 {+b,+a DESC}
24 10 39 {+b,+a DESC}
25 10 40 {+b,+a DESC}
26 10 41 {+b,+a DESC}
27 27 24 {+b,+a DESC}
28 27 49 {+b,+a DESC}
31 10 24 {+b DESC,+a DESC}
32 10 25 {+b DESC,+a DESC}
33 10 26 {+b DESC,+a DESC}
34 10 39 {+b DESC,+a DESC}
35 10 40 {+b DESC,+a DESC}
36 10 41 {+b DESC,+a DESC}
37 27 24 {+b DESC,+a DESC}
38 27 49 {+b DESC,+a DESC}
} {
set sql1 "SELECT a FROM t1 ORDER BY $orderby LIMIT $limit OFFSET $offset;"
set sql2 [string map {+ {}} $sql1]
# puts $sql2\n$sql1\n[db eval $sql2]
do_test $tn.21.$tx {db eval $::sql2} [db eval $sql1]
}
########################################################################
# A second test table, t2, has many columns open to sorting.
do_test $tn.31 {
db eval "CREATE TABLE t2(a,b,c,d,e,f,PRIMARY KEY(b,c,d,e,f)) $rowidclause;"
db eval {
WITH RECURSIVE
cnt(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM cnt WHERE x<242)
INSERT INTO t2 SELECT x, x%3, (x/3)%3, (x/9)%3, (x/27)%3, (x/81)%3
FROM cnt;
}
} {}
do_execsql_test $tn.32 {
SELECT a FROM t2 ORDER BY b,c,d,e,f;
} [db eval {SELECT a FROM t2 ORDER BY +b,+c,+d,+e,+f;}]
do_execsql_test $tn.33 {
SELECT a FROM t2 ORDER BY b,c,d,e,+f;
} [db eval {SELECT a FROM t2 ORDER BY +b,+c,+d,+e,+f;}]
do_execsql_test $tn.34 {
SELECT a FROM t2 ORDER BY b,c,d,+e,+f;
} [db eval {SELECT a FROM t2 ORDER BY +b,+c,+d,+e,+f;}]
do_execsql_test $tn.35 {
SELECT a FROM t2 ORDER BY b,c,+d,+e,+f;
} [db eval {SELECT a FROM t2 ORDER BY +b,+c,+d,+e,+f;}]
do_execsql_test $tn.36 {
SELECT a FROM t2 ORDER BY b,+c,+d,+e,+f;
} [db eval {SELECT a FROM t2 ORDER BY +b,+c,+d,+e,+f;}]
do_execsql_test $tn.37 {
SELECT a FROM t2 ORDER BY b,c,d,e,f DESC;
} [db eval {SELECT a FROM t2 ORDER BY +b,+c,+d,+e,+f DESC;}]
do_execsql_test $tn.38 {
SELECT a FROM t2 ORDER BY b,c,d,e DESC,f;
} [db eval {SELECT a FROM t2 ORDER BY +b,+c,+d,+e DESC,+f;}]
do_execsql_test $tn.39 {
SELECT a FROM t2 ORDER BY b,c,d DESC,e,f;
} [db eval {SELECT a FROM t2 ORDER BY +b,+c,+d DESC,+e,+f;}]
do_execsql_test $tn.40 {
SELECT a FROM t2 ORDER BY b,c DESC,d,e,f;
} [db eval {SELECT a FROM t2 ORDER BY +b,+c DESC,+d,+e,+f;}]
do_execsql_test $tn.41 {
SELECT a FROM t2 ORDER BY b DESC,c,d,e,f;
} [db eval {SELECT a FROM t2 ORDER BY +b DESC,+c,+d,+e,+f;}]
do_execsql_test $tn.42 {
SELECT a FROM t2 ORDER BY b DESC,c DESC,d,e,f LIMIT 31;
} [db eval {SELECT a FROM t2 ORDER BY +b DESC,+c DESC,+d,+e,+f LIMIT 31}]
do_execsql_test $tn.43 {
SELECT a FROM t2 ORDER BY b,c,d,e,f DESC LIMIT 8 OFFSET 7;
} [db eval {SELECT a FROM t2 ORDER BY +b,+c,+d,+e,+f DESC LIMIT 8 OFFSET 7}]
}
finish_test
-1
View File
@@ -112,7 +112,6 @@ set allquicktests [test_set $alltests -exclude {
incrvacuum_ioerr.test autovacuum_crash.test btree8.test shared_err.test
vtab_err.test walslow.test walcrash.test walcrash3.test
walthread.test rtree3.test indexfault.test securedel2.test
sort3.test
}]
if {[info exists ::env(QUICKTEST_INCLUDE)]} {
set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)]
+5 -13
View File
@@ -1575,8 +1575,6 @@ do_test pragma-20.8 {
forcedelete data_dir
} ;# endif windows
database_may_be_corrupt
do_test 21.1 {
# Create a corrupt database in testerr.db. And a non-corrupt at test.db.
#
@@ -1602,16 +1600,11 @@ Multiple uses for byte 672 of page 15}
set auxerr {*** in database aux ***
Multiple uses for byte 672 of page 15}
set mainerr {/{\*\*\* in database main \*\*\*
Multiple uses for byte 672 of page 15}.*/}
set auxerr {/{\*\*\* in database aux \*\*\*
Multiple uses for byte 672 of page 15}.*/}
do_test 22.2 {
catch { db close }
sqlite3 db testerr.db
execsql { PRAGMA integrity_check }
} $mainerr
} [list $mainerr]
do_test 22.3.1 {
catch { db close }
@@ -1620,13 +1613,13 @@ do_test 22.3.1 {
ATTACH 'testerr.db' AS 'aux';
PRAGMA integrity_check;
}
} $auxerr
} [list $auxerr]
do_test 22.3.2 {
execsql { PRAGMA main.integrity_check; }
} {ok}
do_test 22.3.3 {
execsql { PRAGMA aux.integrity_check; }
} $auxerr
} [list $auxerr]
do_test 22.4.1 {
catch { db close }
@@ -1635,10 +1628,10 @@ do_test 22.4.1 {
ATTACH 'test.db' AS 'aux';
PRAGMA integrity_check;
}
} $mainerr
} [list $mainerr]
do_test 22.4.2 {
execsql { PRAGMA main.integrity_check; }
} $mainerr
} [list $mainerr]
do_test 22.4.3 {
execsql { PRAGMA aux.integrity_check; }
} {ok}
@@ -1687,5 +1680,4 @@ do_test 23.5 {
}
} {0 0 t1 y {} {NO ACTION} {NO ACTION} NONE}
database_never_corrupt
finish_test
-36
View File
@@ -824,40 +824,4 @@ do_test select4-13.1 {
}
} {1 2}
# 2014-02-18: Make sure compound SELECTs work with VALUES clauses
#
do_execsql_test select4-14.1 {
CREATE TABLE t14(a,b,c);
INSERT INTO t14 VALUES(1,2,3),(4,5,6);
SELECT * FROM t14 INTERSECT VALUES(3,2,1),(2,3,1),(1,2,3),(2,1,3);
} {1 2 3}
do_execsql_test select4-14.2 {
SELECT * FROM t14 INTERSECT VALUES(1,2,3);
} {1 2 3}
do_execsql_test select4-14.3 {
SELECT * FROM t14
UNION VALUES(3,2,1),(2,3,1),(1,2,3),(7,8,9),(4,5,6)
UNION SELECT * FROM t14 ORDER BY 1, 2, 3
} {1 2 3 2 3 1 3 2 1 4 5 6 7 8 9}
do_execsql_test select4-14.4 {
SELECT * FROM t14
UNION VALUES(3,2,1)
UNION SELECT * FROM t14 ORDER BY 1, 2, 3
} {1 2 3 3 2 1 4 5 6}
do_execsql_test select4-14.5 {
SELECT * FROM t14 EXCEPT VALUES(3,2,1),(2,3,1),(1,2,3),(2,1,3);
} {4 5 6}
do_execsql_test select4-14.6 {
SELECT * FROM t14 EXCEPT VALUES(1,2,3)
} {4 5 6}
do_execsql_test select4-14.7 {
SELECT * FROM t14 EXCEPT VALUES(1,2,3) EXCEPT VALUES(4,5,6)
} {}
do_execsql_test select4-14.8 {
SELECT * FROM t14 EXCEPT VALUES('a','b','c') EXCEPT VALUES(4,5,6)
} {1 2 3}
do_execsql_test select4-14.9 {
SELECT * FROM t14 UNION ALL VALUES(3,2,1),(2,3,1),(1,2,3),(2,1,3);
} {1 2 3 4 5 6 3 2 1 2 3 1 1 2 3 2 1 3}
finish_test
-17
View File
@@ -1292,22 +1292,5 @@ do_test selectA-3.97 {
ORDER BY y COLLATE NOCASE DESC,x,z)))
}
} {MAD}
do_execsql_test selectA-3.98 {
WITH RECURSIVE
xyz(n) AS (
SELECT upper((SELECT x FROM (
SELECT x,y,z FROM t2
INTERSECT SELECT a,b,c FROM t3
EXCEPT SELECT c,b,a FROM t1
UNION SELECT a,b,c FROM t3
INTERSECT SELECT a,b,c FROM t3
EXCEPT SELECT c,b,a FROM t1
UNION SELECT a,b,c FROM t3
ORDER BY y COLLATE NOCASE DESC,x,z)))
UNION ALL
SELECT n || '+' FROM xyz WHERE length(n)<5
)
SELECT n FROM xyz ORDER BY +n;
} {MAD MAD+ MAD++}
finish_test
-49
View File
@@ -1,49 +0,0 @@
# 2014-03-03
#
# 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 verifies that an OP_Copy operation is used instead of OP_SCopy
# in a compound select in a case where the source register might be changed
# before the copy is used.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix selectF
do_execsql_test 1 {
BEGIN TRANSACTION;
CREATE TABLE t1(a, b, c);
INSERT INTO "t1" VALUES(1,'one','I');
CREATE TABLE t2(d, e, f);
INSERT INTO "t2" VALUES(5,'ten','XX');
INSERT INTO "t2" VALUES(6,NULL,NULL);
CREATE INDEX i1 ON t1(b, a);
COMMIT;
}
#explain_i {
# SELECT * FROM t2
# UNION ALL
# SELECT * FROM t1 WHERE a<5
# ORDER BY 2, 1
#}
do_execsql_test 2 {
SELECT * FROM t2
UNION ALL
SELECT * FROM t1 WHERE a<5
ORDER BY 2, 1
} {6 {} {} 1 one I 5 ten XX}
finish_test
+1 -1
View File
@@ -105,7 +105,7 @@ do_test shell1-1.7.1 {
set rc [lindex $res 0]
list $rc \
[regexp {SQLite version} $res] \
[regexp {Enter ".help" for usage hints} $res]
[regexp {Enter SQL statements} $res]
} {0 1 1}
# -batch force batch I/O

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