1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-05 15:55:57 +03:00

Merge all recent trunk enhancements and fixes into the ota-update branch.

FossilOrigin-Name: 9bd3e4453d4ad416f7e3f08f0bd283d34f1c319c
This commit is contained in:
drh
2015-04-15 14:26:04 +00:00
56 changed files with 2125 additions and 349 deletions

View File

@@ -536,6 +536,9 @@ sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h
-o $@ $(TOP)/src/shell.c libsqlite3.la \ -o $@ $(TOP)/src/shell.c libsqlite3.la \
$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)" $(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"
sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
$(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS)
mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \ $(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
$(TLIBS) -rpath "$(libdir)" $(TLIBS) -rpath "$(libdir)"

View File

@@ -42,8 +42,8 @@ DYNAMIC_SHELL = 0
# #
!IFNDEF NO_WARN !IFNDEF NO_WARN
!IF $(USE_FULLWARN)!=0 !IF $(USE_FULLWARN)!=0
NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4152 -wd4189 -wd4206 -wd4210 NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206
NO_WARN = $(NO_WARN) -wd4232 -wd4244 -wd4305 -wd4306 -wd4702 -wd4706 NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4244 -wd4305 -wd4306 -wd4702 -wd4706
!ENDIF !ENDIF
!ENDIF !ENDIF
@@ -453,11 +453,13 @@ RCC = $(RCC) -I$(TOP)\ext\rtree
# options are necessary in order to allow debugging symbols to # options are necessary in order to allow debugging symbols to
# work correctly with Visual Studio when using the amalgamation. # work correctly with Visual Studio when using the amalgamation.
# #
!IFNDEF MKSQLITE3C_ARGS
!IF $(DEBUG)>1 !IF $(DEBUG)>1
MKSQLITE3C_ARGS = --linemacros MKSQLITE3C_ARGS = --linemacros
!ELSE !ELSE
MKSQLITE3C_ARGS = MKSQLITE3C_ARGS =
!ENDIF !ENDIF
!ENDIF
# Define -DNDEBUG to compile without debugging (i.e., for production usage) # Define -DNDEBUG to compile without debugging (i.e., for production usage)
# Omitting the define will cause extra debugging code to be inserted and # Omitting the define will cause extra debugging code to be inserted and
@@ -1154,6 +1156,9 @@ sqlite3.exe: $(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c \ $(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c \
/link /pdb:sqlite3sh.pdb $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS) /link /pdb:sqlite3sh.pdb $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
sqldiff.exe: $(TOP)\tool\sqldiff.c sqlite3.c sqlite3.h
$(LTLINK) $(TOP)\tool\sqldiff.c sqlite3.c
mptester.exe: $(TOP)\mptest\mptest.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h mptester.exe: $(TOP)\mptest\mptest.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
$(LTLINK) $(SHELL_COMPILE_OPTS) $(TOP)\mptest\mptest.c \ $(LTLINK) $(SHELL_COMPILE_OPTS) $(TOP)\mptest\mptest.c \
/link $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS) /link $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)

View File

@@ -1 +1 @@
3.8.9 3.8.10

18
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.62 for sqlite 3.8.9. # Generated by GNU Autoconf 2.62 for sqlite 3.8.10.
# #
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
@@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package. # Identity of this package.
PACKAGE_NAME='sqlite' PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite' PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.8.9' PACKAGE_VERSION='3.8.10'
PACKAGE_STRING='sqlite 3.8.9' PACKAGE_STRING='sqlite 3.8.10'
PACKAGE_BUGREPORT='' PACKAGE_BUGREPORT=''
# Factoring default headers for most tests. # Factoring default headers for most tests.
@@ -1481,7 +1481,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # 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. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures sqlite 3.8.9 to adapt to many kinds of systems. \`configure' configures sqlite 3.8.10 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1546,7 +1546,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.8.9:";; short | recursive ) echo "Configuration of sqlite 3.8.10:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@@ -1660,7 +1660,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
sqlite configure 3.8.9 sqlite configure 3.8.10
generated by GNU Autoconf 2.62 generated by GNU Autoconf 2.62
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1674,7 +1674,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by sqlite $as_me 3.8.9, which was It was created by sqlite $as_me 3.8.10, which was
generated by GNU Autoconf 2.62. Invocation command line was generated by GNU Autoconf 2.62. Invocation command line was
$ $0 $@ $ $0 $@
@@ -13953,7 +13953,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by sqlite $as_me 3.8.9, which was This file was extended by sqlite $as_me 3.8.10, which was
generated by GNU Autoconf 2.62. Invocation command line was generated by GNU Autoconf 2.62. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@@ -14006,7 +14006,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\ ac_cs_version="\\
sqlite config.status 3.8.9 sqlite config.status 3.8.10
configured by $0, generated by GNU Autoconf 2.62, configured by $0, generated by GNU Autoconf 2.62,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

View File

@@ -313,6 +313,13 @@ static int fts3EvalStart(Fts3Cursor *pCsr);
static int fts3TermSegReaderCursor( static int fts3TermSegReaderCursor(
Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **); Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **);
#ifndef SQLITE_AMALGAMATION
# if defined(SQLITE_DEBUG)
int sqlite3Fts3Always(int b) { assert( b ); return b; }
int sqlite3Fts3Never(int b) { assert( !b ); return b; }
# endif
#endif
/* /*
** Write a 64-bit variable-length integer to memory starting at p[0]. ** Write a 64-bit variable-length integer to memory starting at p[0].
** The length of data written will be between 1 and FTS3_VARINT_MAX bytes. ** The length of data written will be between 1 and FTS3_VARINT_MAX bytes.
@@ -422,7 +429,7 @@ void sqlite3Fts3Dequote(char *z){
/* If the first byte was a '[', then the close-quote character is a ']' */ /* If the first byte was a '[', then the close-quote character is a ']' */
if( quote=='[' ) quote = ']'; if( quote=='[' ) quote = ']';
while( ALWAYS(z[iIn]) ){ while( z[iIn] ){
if( z[iIn]==quote ){ if( z[iIn]==quote ){
if( z[iIn+1]!=quote ) break; if( z[iIn+1]!=quote ) break;
z[iOut++] = quote; z[iOut++] = quote;
@@ -1019,7 +1026,8 @@ static int fts3ContentColumns(
const char *zTbl, /* Name of content table */ const char *zTbl, /* Name of content table */
const char ***pazCol, /* OUT: Malloc'd array of column names */ const char ***pazCol, /* OUT: Malloc'd array of column names */
int *pnCol, /* OUT: Size of array *pazCol */ int *pnCol, /* OUT: Size of array *pazCol */
int *pnStr /* OUT: Bytes of string content */ int *pnStr, /* OUT: Bytes of string content */
char **pzErr /* OUT: error message */
){ ){
int rc = SQLITE_OK; /* Return code */ int rc = SQLITE_OK; /* Return code */
char *zSql; /* "SELECT *" statement on zTbl */ char *zSql; /* "SELECT *" statement on zTbl */
@@ -1030,6 +1038,9 @@ static int fts3ContentColumns(
rc = SQLITE_NOMEM; rc = SQLITE_NOMEM;
}else{ }else{
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
if( rc!=SQLITE_OK ){
*pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
}
} }
sqlite3_free(zSql); sqlite3_free(zSql);
@@ -1281,7 +1292,7 @@ static int fts3InitVtab(
if( nCol==0 ){ if( nCol==0 ){
sqlite3_free((void*)aCol); sqlite3_free((void*)aCol);
aCol = 0; aCol = 0;
rc = fts3ContentColumns(db, argv[1], zContent, &aCol, &nCol, &nString); rc = fts3ContentColumns(db, argv[1], zContent,&aCol,&nCol,&nString,pzErr);
/* If a languageid= option was specified, remove the language id /* If a languageid= option was specified, remove the language id
** column from the aCol[] array. */ ** column from the aCol[] array. */
@@ -3523,6 +3534,8 @@ static void fts3SnippetFunc(
} }
if( !zEllipsis || !zEnd || !zStart ){ if( !zEllipsis || !zEnd || !zStart ){
sqlite3_result_error_nomem(pContext); sqlite3_result_error_nomem(pContext);
}else if( nToken==0 ){
sqlite3_result_text(pContext, "", -1, SQLITE_STATIC);
}else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){ }else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){
sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken); sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken);
} }

View File

@@ -134,6 +134,11 @@ SQLITE_EXTENSION_INIT3
#ifdef SQLITE_COVERAGE_TEST #ifdef SQLITE_COVERAGE_TEST
# define ALWAYS(x) (1) # define ALWAYS(x) (1)
# define NEVER(X) (0) # define NEVER(X) (0)
#elif defined(SQLITE_DEBUG)
# define ALWAYS(x) sqlite3Fts3Always((x)!=0)
# define NEVER(x) sqlite3Fts3Never((x)!=0)
int sqlite3Fts3Always(int b);
int sqlite3Fts3Never(int b);
#else #else
# define ALWAYS(x) (x) # define ALWAYS(x) (x)
# define NEVER(x) (x) # define NEVER(x) (x)

View File

@@ -408,6 +408,10 @@ sqlite3$(EXE): $(TOP)/src/shell.c libsqlite3.a sqlite3.h
$(TOP)/src/shell.c \ $(TOP)/src/shell.c \
libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB) libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB)
sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
$(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \
$(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB)
mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
$(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \ $(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
$(TLIBS) $(THREADLIB) $(TLIBS) $(THREADLIB)

117
manifest
View File

@@ -1,12 +1,12 @@
C Merge\sall\schanges\sfor\sversion\s3.8.9\sinto\sthe\sota-update\sbranch. C Merge\sall\srecent\strunk\senhancements\sand\sfixes\sinto\sthe\sota-update\sbranch.
D 2015-04-08T14:01:07.788 D 2015-04-15T14:26:04.771
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 00d12636df7a5b08af09116bcd6c7bfd49b8b3b4 F Makefile.in 5f78b1ab81b64e7c57a75d170832443e66c0880a
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc a8d817fa486d8c88dfbd19ae6a6567d9d350de39 F Makefile.msc 0078f5781538e07ea38683439f38d5f5ab79ab6e
F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858 F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858
F README.md d58e3bebc0a4145e0f2a87994015fdb575a8e866 F README.md d58e3bebc0a4145e0f2a87994015fdb575a8e866
F VERSION 319eb1ced4b4d17a67730f2b7b85f15c1346cb60 F VERSION 2e244662b71e6e68a5c29b014ebc5b7564f4cc5a
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811 F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
@@ -38,7 +38,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0 F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure 8b18c2378805a1d8aaca85d293671f450dd3c723 x F configure 2ea5f5b58dd106da449ab598ab6e515339d7fa2a x
F configure.ac 0b775d383c536bbaafc1e46dd3cbb81a7ea11aeb F configure.ac 0b775d383c536bbaafc1e46dd3cbb81a7ea11aeb
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1 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.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314 F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c 23bd9d37a777342f5c22a648e9b4b005dde9e58f F ext/fts3/fts3.c 4bd75289875b63c04f943d6ed7c31737da99cd74
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h 394858c12a17740f7a1f6bd372c4606d4425a8d1 F ext/fts3/fts3Int.h 3626655d6ba903a3919bb44e1c38e5f0f9d6be82
F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365 F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365
F ext/fts3/fts3_expr.c 40123785eaa3ebd4c45c9b23407cc44ac0c49905 F ext/fts3/fts3_expr.c 40123785eaa3ebd4c45c9b23407cc44ac0c49905
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60 F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
@@ -170,9 +170,9 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk 19443a29765ee87f4a4dca28818c6bbff34f738d F main.mk 95e9c8295b3ce06c0cbe6977b2b3ed8407cfe217
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5 F mkopcodeh.awk d5e22023b5238985bb54a72d33e0ac71fe4f8a32
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@@ -186,29 +186,29 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c d23d6b6991f66b383934f137fd4384d93fb98c81 F src/alter.c d23d6b6991f66b383934f137fd4384d93fb98c81
F src/analyze.c 91540f835163d5369ccbae78e2e6c74d0dd53c1d F src/analyze.c 91540f835163d5369ccbae78e2e6c74d0dd53c1d
F src/attach.c 880f9b8641a829c563e52dd13c452ce457ae4dd8 F src/attach.c 3c1053a4cf1c3ca05c8c1d74a94cb688d763cef2
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3 F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
F src/btree.c 2caf598165f3608fde8abac2b243826616ce54b7 F src/btree.c 67648f6532c2da79d3b3fb6853aa1a0c3ba0e1ad
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
F src/btreeInt.h 973a22a6fd61350b454ad614832b1f0a5e25a1e4 F src/btreeInt.h 973a22a6fd61350b454ad614832b1f0a5e25a1e4
F src/build.c 0419bba592c22f6d00e6d57a2ca7136720d02c1a F src/build.c 01b969b20a44a3d9620e597d9af8242348123540
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
F src/complete.c 198a0066ba60ab06fc00fba1998d870a4d575463 F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575
F src/ctime.c 98f89724adc891a1a4c655bee04e33e716e05887 F src/ctime.c 98f89724adc891a1a4c655bee04e33e716e05887
F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac
F src/delete.c 37964e6c1d73ff49cbea9ff690c9605fb15f600e F src/delete.c 37964e6c1d73ff49cbea9ff690c9605fb15f600e
F src/expr.c d09dac67d53c78880ba31d56e8ba2be3a6490553 F src/expr.c 8800584340a9b4f4c0ca55c360de751c6da0b11a
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c e0444b61bed271a76840cbe6182df93a9baa3f12 F src/fkey.c 3343d551a8d810782257244fb33f2ce191493c39
F src/func.c 1414c24c873c48796ad45942257a179a423ba42f F src/func.c 1414c24c873c48796ad45942257a179a423ba42f
F src/global.c 4f77cadbc5427d00139ba43d0f3979804cbb700e F src/global.c 4f77cadbc5427d00139ba43d0f3979804cbb700e
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c 5b9243a33726008cc4132897d2be371db12a13be F src/insert.c 305dd3f9539d0affa4bf1c14cc7dffb34867e040
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770 F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
@@ -221,7 +221,7 @@ F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534 F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534
F src/mem5.c 61eeb90134f9a5be6c2e68d8daae7628b25953fb F src/mem5.c 61eeb90134f9a5be6c2e68d8daae7628b25953fb
F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85 F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85
F src/msvc.h e78002098966e39b2fd9915bd70b7bc3ec8398b7 F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
F src/mutex.c 19bf9acba69ca2f367c3761080f8a9f0cf4670a8 F src/mutex.c 19bf9acba69ca2f367c3761080f8a9f0cf4670a8
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85 F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
F src/mutex_noop.c 529bab0743c3321c940f32c3464de494fd38cfa9 F src/mutex_noop.c 529bab0743c3321c940f32c3464de494fd38cfa9
@@ -232,7 +232,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
F src/os_unix.c 25b80a3d167da44226a2084dc9e89a6cb1f02e2e F src/os_unix.c 5ed7e2e453c2980909a6b2c80dc55764b50819a8
F src/os_win.c 03d27be3a20048ef52a648d5f0a15f5edda9f2a3 F src/os_win.c 03d27be3a20048ef52a648d5f0a15f5edda9f2a3
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
F src/pager.c 4120a49ecd37697e28f5ed807f470b9c0b88410c F src/pager.c 4120a49ecd37697e28f5ed807f470b9c0b88410c
@@ -241,19 +241,19 @@ F src/parse.y 1299c66e7b1707322ccd8af43a359b8fb0d46d72
F src/pcache.c 10539fb959849ad6efff80050541cab3d25089d4 F src/pcache.c 10539fb959849ad6efff80050541cab3d25089d4
F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8 F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
F src/pcache1.c 69d137620a305f814398bd29a0c998038c0695e9 F src/pcache1.c 69d137620a305f814398bd29a0c998038c0695e9
F src/pragma.c ac4f3f856b4234e85f55b0f069698a4766011100 F src/pragma.c 3965ae4e82bed39fb97ce04c5fe18c9bc3ee6a88
F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f
F src/prepare.c 173a5a499138451b2561614ecb87d78f9f4644b9 F src/prepare.c 173a5a499138451b2561614ecb87d78f9f4644b9
F src/printf.c 8ae1fa9d30c1200a9268a390ba9e9cea9197b27a F src/printf.c 08fa675c200aac29e561c6153f91f909ed17612f
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c 41aa91af56d960e9414ce1d7c17cfb68e0d1c6cb F src/resolve.c 66cfe49a9c3b449ef13b89a8c47036a4ed167eab
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
F src/select.c c28c52e353287434fac8473e56ee4be848d12c9d F src/select.c 93260bc9e7e0e6dfe1b7cb8815b0ed4cad8be9e3
F src/shell.c 84a1593bd86aaa14f4da8a8f9b16fbc239d262aa F src/shell.c 84a1593bd86aaa14f4da8a8f9b16fbc239d262aa
F src/sqlite.h.in 2814e6b51c5a6176eecae4a7d5b7bfaf142283c8 F src/sqlite.h.in 3be4d9a7d38ef83fadd4aadd7ef3c6039e165da7
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
F src/sqliteInt.h 107b02ed6c64162b653acc2368e982de529e14f6 F src/sqliteInt.h 90b7bfd89d7307cd0750663da419ba4bb81e7379
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
F src/table.c e7a09215315a978057fb42c640f890160dbcc45e F src/table.c e7a09215315a978057fb42c640f890160dbcc45e
@@ -305,27 +305,27 @@ F src/test_vfs.c b7e6831e6fcf04c5090accff30640ec5c9630739
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481 F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481
F src/tokenize.c a8d270b06e5f709930f7b67cf70a847969cb5bf3 F src/tokenize.c a8234a67577308935cdf13e618cd66556f5f45d1
F src/trigger.c 25571661fdeae8c7f975ff40ffec205520a3f92f F src/trigger.c 69a91bed7c94e46223e37ffccfeeb35e34b999ac
F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13 F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e
F src/vacuum.c 9460b9de7b2d4e34b0d374894aa6c8a0632be8ec F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
F src/vdbe.c 86ae6f4774410868af41bd839b72b7081ff03e78 F src/vdbe.c 3f3afd12d4794cb51fe13dc948b1172a5eb71a94
F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3 F src/vdbe.h 7e538ecf47dccb307ea2d087c3ddc2dd8d70e79d
F src/vdbeInt.h 9cbaa84f53ddd2d09a0cf61a94337a3a035d08a0 F src/vdbeInt.h 9cbaa84f53ddd2d09a0cf61a94337a3a035d08a0
F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75 F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75
F src/vdbeaux.c 413dc496248ac18eb0c19e35e86bb1ffd47b8907 F src/vdbeaux.c a20504ae52392459fa08402fda3f195f19d7c79d
F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90
F src/vdbemem.c c0dc81285b7571b0a31c40f17846fe2397ec1cd9 F src/vdbemem.c c0dc81285b7571b0a31c40f17846fe2397ec1cd9
F src/vdbesort.c 919717d7599fa31d343ec28bffd0f9e91a4ff5f6 F src/vdbesort.c 2e7f683464fd5db3be4beaa1ff2d39e24fcb64b8
F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010 F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
F src/vtab.c 62d49237bd8f3be4863815a39387b0f9897fa5e1 F src/vtab.c 9ca557215e8591ceb66e0b7c0a579c6df1e54b2d
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
F src/wal.c 878c8e1a51cb2ec45c395d26b7d5cd9e1a098e4a F src/wal.c 753995db83247f20361a8e8a874990b21a75abd9
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
F src/where.c bc7276b6e7d4d50055e17cba1d495f804737f872 F src/where.c 7e5d9a5690e71c39bfc4afea9f351766299dbf2f
F src/whereInt.h 1fca2f8c649f0ee38fd52332659d0e7deb11d428 F src/whereInt.h 1fca2f8c649f0ee38fd52332659d0e7deb11d428
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -367,7 +367,7 @@ F test/auth.test 855233ef26eb3601b6886567ea4e326c72959360
F test/auth2.test 264c6af53cad9aba5218c68bbe18036e39007bfa F test/auth2.test 264c6af53cad9aba5218c68bbe18036e39007bfa
F test/auth3.test 5cfa94ed90c6617c42b7ba4b133fd79678b251c7 F test/auth3.test 5cfa94ed90c6617c42b7ba4b133fd79678b251c7
F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7 F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7
F test/autoindex1.test 7008c9f604141fdabe31b7bb95b5ff31b518251f F test/autoindex1.test 14b63a9f1e405fe6d5bfc8c8d00249c2ebaf13ea
F test/autoindex2.test af7e595c6864cc6ef5fc38d5db579a3e34940cb8 F test/autoindex2.test af7e595c6864cc6ef5fc38d5db579a3e34940cb8
F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972 F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972
F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf
@@ -417,9 +417,9 @@ F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763
F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815 F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815
F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4 F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
F test/collate1.test 7fcfe78f9613dc4a7e247d6bd27749955f108741 F test/collate1.test 08c18e7512a5a32c97938854263fa15362eeb846
F test/collate2.test 9aaa410a00734e48bcb27f3872617d6f69b2a621 F test/collate2.test 9aaa410a00734e48bcb27f3872617d6f69b2a621
F test/collate3.test 79558a286362cb9ed603c6fa543f1cda7f563f0f F test/collate3.test 89defc49983ddfbf0a0555aca8c0521a676f56a5
F test/collate4.test f04d5168685f2eef637ecfa2d4ddf8ec0d600177 F test/collate4.test f04d5168685f2eef637ecfa2d4ddf8ec0d600177
F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6 F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6
F test/collate6.test 8be65a182abaac8011a622131486dafb8076e907 F test/collate6.test 8be65a182abaac8011a622131486dafb8076e907
@@ -523,7 +523,7 @@ F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7
F test/filectrl.test 14fa712e42c4cb791e09dfd58a6a03efb47ef13a F test/filectrl.test 14fa712e42c4cb791e09dfd58a6a03efb47ef13a
F test/filefmt.test cb34663f126cbc2d358af552dcaf5c72769b0146 F test/filefmt.test cb34663f126cbc2d358af552dcaf5c72769b0146
F test/fkey1.test e1d1fa84cde579185ea01358436839703e415a5b F test/fkey1.test e1d1fa84cde579185ea01358436839703e415a5b
F test/fkey2.test 1db212cda86b0d3ce72714001f7b6381c321341c F test/fkey2.test 223c624e7eccee21e89c98d4d127ac88d774b940
F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49 F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
F test/fkey5.test 56bcb5a6e8b725b17febc267fb041a6695e86853 F test/fkey5.test 56bcb5a6e8b725b17febc267fb041a6695e86853
@@ -617,14 +617,14 @@ F test/fts3prefix2.test e1f0a822ca661dced7f12ce392e14eaf65609dce
F test/fts3query.test c838b18f2b859e15fd31c64be3d79ef1556803ca F test/fts3query.test c838b18f2b859e15fd31c64be3d79ef1556803ca
F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0 F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0
F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e
F test/fts3snippet.test 03c2f3be7d3b7c8bb105ed237f204833392bd57f F test/fts3snippet.test 63dbd687d5bf5191f1b8e6a0977aa9c1e28a7004
F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca
F test/fts3tok1.test c551043de056b0b1582a54e878991f57bad074bc F test/fts3tok1.test 178c050199af8c05299b1ad572514ce1c54b7827
F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d
F test/fts3varint.test 752c08ed5d32c5d7dc211b056f4ed68a76b7e36e F test/fts3varint.test 752c08ed5d32c5d7dc211b056f4ed68a76b7e36e
F test/fts4aa.test 10aac8e9d62c7357590acfabe3fad01e9a9ce1cb F test/fts4aa.test 10aac8e9d62c7357590acfabe3fad01e9a9ce1cb
F test/fts4check.test 74d77f6cdb768ac49df5afda575cef14ae3d239a F test/fts4check.test 74d77f6cdb768ac49df5afda575cef14ae3d239a
F test/fts4content.test 2e7252557d6d24afa101d9ba1de710d6140e6d06 F test/fts4content.test abb0c77bc3da3df64fec72e00844d2257a90025d
F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01 F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01
F test/fts4growth.test df10fde9f47cf5c71861e63fd8efcd573c4f7e53 F test/fts4growth.test df10fde9f47cf5c71861e63fd8efcd573c4f7e53
F test/fts4growth2.test 2f063be1902a73cd087355837c52fed42ac11a5d F test/fts4growth2.test 2f063be1902a73cd087355837c52fed42ac11a5d
@@ -651,11 +651,11 @@ F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36 F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
F test/hexlit.test f9ecde8145bfc2341573473256c74ae37a200497 F test/hexlit.test 1d312fa816dfd3650a3bb488093bc09a0c927f67
F test/hook.test 162d7cef7a2d2b04839fe14402934e6a1b79442f F test/hook.test 162d7cef7a2d2b04839fe14402934e6a1b79442f
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
F test/in.test 047c4671328e9032ab95666a67021adbbd36e98e F test/in.test b52fa96bcf6cebc5c8829c822315d0f87af9c6c2
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068 F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068
@@ -761,7 +761,7 @@ F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354 F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f
F test/misc1.test f3f59b3941c84a10860c06c07e86ad367a74ec92 F test/misc1.test 9abcae9a0b8785d6fa92925dbb19c309ae9ea077
F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d
F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d
F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6 F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6
@@ -786,10 +786,10 @@ F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf
F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161
F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
F test/notnull.test f8fcf58669ddba79274daa2770d61dfad8274f62 F test/notnull.test f8fcf58669ddba79274daa2770d61dfad8274f62
F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3
F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1
F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394 F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
F test/orderby1.test eb246e377612b21a418fbea57047ba8ea88aaa6b F test/orderby1.test 870e150450437d3980badbde3d0166b81d9e33f6
F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04 F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04
F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99 F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99
F test/orderby4.test 4d39bfbaaa3ae64d026ca2ff166353d2edca4ba4 F test/orderby4.test 4d39bfbaaa3ae64d026ca2ff166353d2edca4ba4
@@ -813,11 +813,11 @@ F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
F test/permutations.test 0e2dc2aab7b1043bd2b4404f51651c31da007e52 F test/permutations.test 0e2dc2aab7b1043bd2b4404f51651c31da007e52
F test/pragma.test ad99d05e411c7687302124be56f3b362204be041 F test/pragma.test e6605ce89c66db930aef561e43a22281a09ffc66
F test/pragma2.test f624a496a95ee878e81e59961eade66d5c00c028 F test/pragma2.test f624a496a95ee878e81e59961eade66d5c00c028
F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
F test/printf2.test b4acd4bf8734243257f01ddefa17c4fb090acc8a F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054
F test/progress.test a282973d1d17f08071bc58a77d6b80f2a81c354d F test/progress.test a282973d1d17f08071bc58a77d6b80f2a81c354d
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
@@ -858,7 +858,7 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
F test/select1.test fc2a61f226a649393664ad54bc5376631801517c F test/select1.test fc2a61f226a649393664ad54bc5376631801517c
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054 F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
F test/select4.test e20e8ce47b558de80616102ef273704cf0d48a3b F test/select4.test 16fa1cafb942f42294ec85cbb78954c2f2d15a44
F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535 F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0 F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d
@@ -868,7 +868,7 @@ F test/selectA.test e452bdb975f488ea46d091382a9185b5853ed2c7
F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25 F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25
F test/selectC.test 871fb55d884d3de5943c4057ebd22c2459e71977 F test/selectC.test 871fb55d884d3de5943c4057ebd22c2459e71977
F test/selectD.test b0f02a04ef7737decb24e08be2c39b9664b43394 F test/selectD.test b0f02a04ef7737decb24e08be2c39b9664b43394
F test/selectE.test fc02a1eb04c8eb537091482644b7d778ae8759b7 F test/selectE.test a8730ca330fcf40ace158f134f4fe0eb00c7edbf
F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3 F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3
F test/selectG.test e8600e379589e85e9fefd2fe4d44a4cdd63f6982 F test/selectG.test e8600e379589e85e9fefd2fe4d44a4cdd63f6982
F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118 F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118
@@ -1126,7 +1126,7 @@ F test/uri.test 23662b7b61958b0f0e47082de7d06341ccf85d5b
F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9 F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9
F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae
F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d
F test/vacuum2.test af432e6e3bfc0ea20a80cb86a03c7d9876d38324 F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b
F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d
F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
@@ -1190,7 +1190,7 @@ F test/where9.test 729c3ba9b47e8f9f1aab96bae7dad2a524f1d1a2
F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5 F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
F test/whereC.test d6f4ecd4fa2d9429681a5b22a25d2bda8e86ab8a F test/whereC.test d6f4ecd4fa2d9429681a5b22a25d2bda8e86ab8a
F test/whereD.test fd9120e262f9da3c45940f52aefeef4d15b904e5 F test/whereD.test 9eba1f9b18e5b19a0b0bcaae5e8c037260195f2b
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7 F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7
F test/whereG.test 69f5ec4b15760a8c860f80e2d55525669390aab3 F test/whereG.test 69f5ec4b15760a8c860f80e2d55525669390aab3
@@ -1203,7 +1203,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c
F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972 F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
F test/with1.test 9df5cd8a62148b3d9ef8597aea563e3863018bcd F test/with1.test a86bf7f9288ba759a25ee57221d3bffaca36032a
F test/with2.test ee227a663586aa09771cafd4fa269c5217eaf775 F test/with2.test ee227a663586aa09771cafd4fa269c5217eaf775
F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991 F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991
F test/without_rowid1.test 7862e605753c8d25329f665fa09072e842183151 F test/without_rowid1.test 7862e605753c8d25329f665fa09072e842183151
@@ -1213,7 +1213,7 @@ F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
F test/without_rowid5.test 61256715b686359df48ca1742db50cc7e3e7b862 F test/without_rowid5.test 61256715b686359df48ca1742db50cc7e3e7b862
F test/without_rowid6.test db0dbf03c49030aa3c1ba5f618620334bd2baf5f F test/without_rowid6.test db0dbf03c49030aa3c1ba5f618620334bd2baf5f
F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 F test/zeroblob.test fb3c0e4ab172d386954deda24c03f500e121d80d
F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac
F tool/build-all-msvc.bat 72e05bc8deca39a547884485c086b915f50a91ed x F tool/build-all-msvc.bat 72e05bc8deca39a547884485c086b915f50a91ed x
F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
@@ -1258,6 +1258,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
F tool/sqldiff.c 5c16cf3a1f566873abbdecac0d13a6691437564f
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
@@ -1268,7 +1269,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 4e8796af7d40d6ca423e07c68877035e4aa2485c 8a8ffc862e96f57aa698f93de10dee28e69f6e09 P ec9d907a57fcea72c8a64e521e8a1b5777d67568 bd06eeb8d06237dc2d54d8a03e8bf525cb811c9e
R 5f5852d5f7f1cc470ab35b77b2f9115f R 6f95f9c15975aab2be755a8183ba89a7
U drh U drh
Z 0c6fb869959322b1de7ded76db4a0dc3 Z 38e5b36fa5e6d50108fc54dc3af0e0b9

View File

@@ -1 +1 @@
ec9d907a57fcea72c8a64e521e8a1b5777d67568 9bd3e4453d4ad416f7e3f08f0bd283d34f1c319c

View File

@@ -72,7 +72,6 @@
sub("\r","",name) sub("\r","",name)
op[name] = -1 # op[x] holds the numeric value for OP symbol x op[name] = -1 # op[x] holds the numeric value for OP symbol x
jump[name] = 0 jump[name] = 0
out2_prerelease[name] = 0
in1[name] = 0 in1[name] = 0
in2[name] = 0 in2[name] = 0
in3[name] = 0 in3[name] = 0
@@ -92,8 +91,6 @@
sub(",","",x) sub(",","",x)
if(x=="jump"){ if(x=="jump"){
jump[name] = 1 jump[name] = 1
}else if(x=="out2-prerelease"){
out2_prerelease[name] = 1
}else if(x=="in1"){ }else if(x=="in1"){
in1[name] = 1 in1[name] = 1
}else if(x=="in2"){ }else if(x=="in2"){
@@ -194,13 +191,12 @@ END {
name = def[i] name = def[i]
a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0 a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0
if( jump[name] ) a0 = 1; if( jump[name] ) a0 = 1;
if( out2_prerelease[name] ) a1 = 2; if( in1[name] ) a2 = 2;
if( in1[name] ) a2 = 4; if( in2[name] ) a3 = 4;
if( in2[name] ) a3 = 8; if( in3[name] ) a4 = 8;
if( in3[name] ) a4 = 16; if( out2[name] ) a5 = 16;
if( out2[name] ) a5 = 32; if( out3[name] ) a6 = 32;
if( out3[name] ) a6 = 64; bv[i] = a0+a1+a2+a3+a4+a5+a6;
bv[i] = a0+a1+a2+a3+a4+a5+a6+a7;
} }
print "\n" print "\n"
print "/* Properties such as \"out2\" or \"jump\" that are specified in" print "/* Properties such as \"out2\" or \"jump\" that are specified in"
@@ -208,12 +204,11 @@ END {
print "** are encoded into bitvectors as follows:" print "** are encoded into bitvectors as follows:"
print "*/" print "*/"
print "#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */" print "#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */"
print "#define OPFLG_OUT2_PRERELEASE 0x0002 /* out2-prerelease: */" print "#define OPFLG_IN1 0x0002 /* in1: P1 is an input */"
print "#define OPFLG_IN1 0x0004 /* in1: P1 is an input */" print "#define OPFLG_IN2 0x0004 /* in2: P2 is an input */"
print "#define OPFLG_IN2 0x0008 /* in2: P2 is an input */" print "#define OPFLG_IN3 0x0008 /* in3: P3 is an input */"
print "#define OPFLG_IN3 0x0010 /* in3: P3 is an input */" print "#define OPFLG_OUT2 0x0010 /* out2: P2 is an output */"
print "#define OPFLG_OUT2 0x0020 /* out2: P2 is an output */" print "#define OPFLG_OUT3 0x0020 /* out3: P3 is an output */"
print "#define OPFLG_OUT3 0x0040 /* out3: P3 is an output */"
print "#define OPFLG_INITIALIZER {\\" print "#define OPFLG_INITIALIZER {\\"
for(i=0; i<=max; i++){ for(i=0; i<=max; i++){
if( i%8==0 ) printf("/* %3d */",i) if( i%8==0 ) printf("/* %3d */",i)

View File

@@ -298,7 +298,7 @@ static void detachFunc(
sqlite3BtreeClose(pDb->pBt); sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0; pDb->pBt = 0;
pDb->pSchema = 0; pDb->pSchema = 0;
sqlite3ResetAllSchemasOfConnection(db); sqlite3CollapseDatabaseArray(db);
return; return;
detach_error: detach_error:

View File

@@ -6735,7 +6735,6 @@ static int balance_nonroot(
}else if( iParentIdx==i ){ }else if( iParentIdx==i ){
nxDiv = i-2+bBulk; nxDiv = i-2+bBulk;
}else{ }else{
assert( bBulk==0 );
nxDiv = iParentIdx-1; nxDiv = iParentIdx-1;
} }
i = 2-bBulk; i = 2-bBulk;

View File

@@ -226,7 +226,7 @@ void sqlite3FinishCoding(Parse *pParse){
/* Get the VDBE program ready for execution /* Get the VDBE program ready for execution
*/ */
if( v && ALWAYS(pParse->nErr==0) && !db->mallocFailed ){ if( v && pParse->nErr==0 && !db->mallocFailed ){
assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */ assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */
/* A minimum of one cursor is required if autoincrement is used /* A minimum of one cursor is required if autoincrement is used
* See ticket [a696379c1f08866] */ * See ticket [a696379c1f08866] */
@@ -2763,7 +2763,8 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
addr2 = sqlite3VdbeCurrentAddr(v); addr2 = sqlite3VdbeCurrentAddr(v);
} }
sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx); sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1); sqlite3VdbeAddOp3(v, OP_Last, iIdx, 0, -1);
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3ReleaseTempReg(pParse, regRecord); sqlite3ReleaseTempReg(pParse, regRecord);
sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
@@ -3776,7 +3777,6 @@ void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){
void sqlite3SrcListShiftJoinType(SrcList *p){ void sqlite3SrcListShiftJoinType(SrcList *p){
if( p ){ if( p ){
int i; int i;
assert( p->a || p->nSrc==0 );
for(i=p->nSrc-1; i>0; i--){ for(i=p->nSrc-1; i>0; i--){
p->a[i].jointype = p->a[i-1].jointype; p->a[i].jointype = p->a[i-1].jointype;
} }

View File

@@ -269,7 +269,7 @@ int sqlite3_complete(const char *zSql){
int sqlite3_complete16(const void *zSql){ int sqlite3_complete16(const void *zSql){
sqlite3_value *pVal; sqlite3_value *pVal;
char const *zSql8; char const *zSql8;
int rc = SQLITE_NOMEM; int rc;
#ifndef SQLITE_OMIT_AUTOINIT #ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite3_initialize(); rc = sqlite3_initialize();

View File

@@ -1691,7 +1691,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){
** ephemeral table. ** ephemeral table.
*/ */
p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0); p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){ if( pParse->nErr==0 && isCandidateForInOpt(p) ){
sqlite3 *db = pParse->db; /* Database connection */ sqlite3 *db = pParse->db; /* Database connection */
Table *pTab; /* Table <table>. */ Table *pTab; /* Table <table>. */
Expr *pExpr; /* Expression <column> */ Expr *pExpr; /* Expression <column> */
@@ -2016,6 +2016,7 @@ int sqlite3CodeSubselect(
pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
&sqlite3IntTokens[1]); &sqlite3IntTokens[1]);
pSel->iLimit = 0; pSel->iLimit = 0;
pSel->selFlags &= ~SF_AllValues;
if( sqlite3Select(pParse, pSel, &dest) ){ if( sqlite3Select(pParse, pSel, &dest) ){
return 0; return 0;
} }

View File

@@ -1184,7 +1184,8 @@ static Trigger *fkActionTrigger(
iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
assert( iFromCol>=0 ); assert( iFromCol>=0 );
tToCol.z = pIdx ? pTab->aCol[pIdx->aiColumn[i]].zName : "oid"; assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) );
tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName;
tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName; tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName;
tToCol.n = sqlite3Strlen30(tToCol.z); tToCol.n = sqlite3Strlen30(tToCol.z);

View File

@@ -1765,6 +1765,7 @@ static int xferOptimization(
int onError, /* How to handle constraint errors */ int onError, /* How to handle constraint errors */
int iDbDest /* The database of pDest */ int iDbDest /* The database of pDest */
){ ){
sqlite3 *db = pParse->db;
ExprList *pEList; /* The result set of the SELECT */ ExprList *pEList; /* The result set of the SELECT */
Table *pSrc; /* The table in the FROM clause of SELECT */ Table *pSrc; /* The table in the FROM clause of SELECT */
Index *pSrcIdx, *pDestIdx; /* Source and destination indices */ Index *pSrcIdx, *pDestIdx; /* Source and destination indices */
@@ -1912,11 +1913,11 @@ static int xferOptimization(
** the extra complication to make this rule less restrictive is probably ** the extra complication to make this rule less restrictive is probably
** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e] ** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
*/ */
if( (pParse->db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){ if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){
return 0; return 0;
} }
#endif #endif
if( (pParse->db->flags & SQLITE_CountRows)!=0 ){ if( (db->flags & SQLITE_CountRows)!=0 ){
return 0; /* xfer opt does not play well with PRAGMA count_changes */ return 0; /* xfer opt does not play well with PRAGMA count_changes */
} }
@@ -1927,7 +1928,7 @@ static int xferOptimization(
#ifdef SQLITE_TEST #ifdef SQLITE_TEST
sqlite3_xferopt_count++; sqlite3_xferopt_count++;
#endif #endif
iDbSrc = sqlite3SchemaToIndex(pParse->db, pSrc->pSchema); iDbSrc = sqlite3SchemaToIndex(db, pSrc->pSchema);
v = sqlite3GetVdbe(pParse); v = sqlite3GetVdbe(pParse);
sqlite3CodeVerifySchema(pParse, iDbSrc); sqlite3CodeVerifySchema(pParse, iDbSrc);
iSrc = pParse->nTab++; iSrc = pParse->nTab++;
@@ -1937,14 +1938,18 @@ static int xferOptimization(
regRowid = sqlite3GetTempReg(pParse); regRowid = sqlite3GetTempReg(pParse);
sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
assert( HasRowid(pDest) || destHasUniqueIdx ); assert( HasRowid(pDest) || destHasUniqueIdx );
if( (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */ if( (db->flags & SQLITE_Vacuum)==0 && (
(pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */
|| destHasUniqueIdx /* (2) */ || destHasUniqueIdx /* (2) */
|| (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */ || (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */
){ )){
/* In some circumstances, we are able to run the xfer optimization /* In some circumstances, we are able to run the xfer optimization
** only if the destination table is initially empty. This code makes ** only if the destination table is initially empty. Unless the
** that determination. Conditions under which the destination must ** SQLITE_Vacuum flag is set, this block generates code to make
** be empty: ** that determination. If SQLITE_Vacuum is set, then the destination
** table is always empty.
**
** Conditions under which the destination must be empty:
** **
** (1) There is no INTEGER PRIMARY KEY but there are indices. ** (1) There is no INTEGER PRIMARY KEY but there are indices.
** (If the destination is not initially empty, the rowid fields ** (If the destination is not initially empty, the rowid fields
@@ -1987,6 +1992,7 @@ static int xferOptimization(
sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName); sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName);
} }
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
u8 useSeekResult = 0;
for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){ for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
} }
@@ -2000,7 +2006,34 @@ static int xferOptimization(
VdbeComment((v, "%s", pDestIdx->zName)); VdbeComment((v, "%s", pDestIdx->zName));
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData); sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
if( db->flags & SQLITE_Vacuum ){
/* This INSERT command is part of a VACUUM operation, which guarantees
** that the destination table is empty. If all indexed columns use
** collation sequence BINARY, then it can also be assumed that the
** index will be populated by inserting keys in strictly sorted
** order. In this case, instead of seeking within the b-tree as part
** of every OP_IdxInsert opcode, an OP_Last is added before the
** OP_IdxInsert to seek to the point within the b-tree where each key
** should be inserted. This is faster.
**
** If any of the indexed columns use a collation sequence other than
** BINARY, this optimization is disabled. This is because the user
** might change the definition of a collation sequence and then run
** a VACUUM command. In that case keys may not be written in strictly
** sorted order. */
int i;
for(i=0; i<pSrcIdx->nColumn; i++){
char *zColl = pSrcIdx->azColl[i];
assert( zColl!=0 );
if( sqlite3_stricmp("BINARY", zColl) ) break;
}
if( i==pSrcIdx->nColumn ){
useSeekResult = OPFLAG_USESEEKRESULT;
sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
}
}
sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1); sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
sqlite3VdbeChangeP5(v, useSeekResult);
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);

View File

@@ -20,6 +20,7 @@
#pragma warning(disable : 4055) #pragma warning(disable : 4055)
#pragma warning(disable : 4100) #pragma warning(disable : 4100)
#pragma warning(disable : 4127) #pragma warning(disable : 4127)
#pragma warning(disable : 4130)
#pragma warning(disable : 4152) #pragma warning(disable : 4152)
#pragma warning(disable : 4189) #pragma warning(disable : 4189)
#pragma warning(disable : 4206) #pragma warning(disable : 4206)

View File

@@ -91,6 +91,17 @@
# include <sys/param.h> # include <sys/param.h>
#endif /* SQLITE_ENABLE_LOCKING_STYLE */ #endif /* SQLITE_ENABLE_LOCKING_STYLE */
#if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
(__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
# if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \
&& (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))
# define HAVE_GETHOSTUUID 1
# else
# warning "gethostuuid() is disabled."
# endif
#endif
#if OS_VXWORKS #if OS_VXWORKS
# include <sys/ioctl.h> # include <sys/ioctl.h>
# include <semaphore.h> # include <semaphore.h>
@@ -6602,8 +6613,10 @@ int sqlite3_hostid_num = 0;
#define PROXY_HOSTIDLEN 16 /* conch file host id length */ #define PROXY_HOSTIDLEN 16 /* conch file host id length */
#ifdef HAVE_GETHOSTUUID
/* Not always defined in the headers as it ought to be */ /* Not always defined in the headers as it ought to be */
extern int gethostuuid(uuid_t id, const struct timespec *wait); extern int gethostuuid(uuid_t id, const struct timespec *wait);
#endif
/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN /* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN
** bytes of writable memory. ** bytes of writable memory.
@@ -6611,8 +6624,7 @@ extern int gethostuuid(uuid_t id, const struct timespec *wait);
static int proxyGetHostID(unsigned char *pHostID, int *pError){ static int proxyGetHostID(unsigned char *pHostID, int *pError){
assert(PROXY_HOSTIDLEN == sizeof(uuid_t)); assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
memset(pHostID, 0, PROXY_HOSTIDLEN); memset(pHostID, 0, PROXY_HOSTIDLEN);
# if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \ #ifdef HAVE_GETHOSTUUID
(__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
{ {
struct timespec timeout = {1, 0}; /* 1 sec timeout */ struct timespec timeout = {1, 0}; /* 1 sec timeout */
if( gethostuuid(pHostID, &timeout) ){ if( gethostuuid(pHostID, &timeout) ){

View File

@@ -1041,7 +1041,7 @@ void sqlite3Pragma(
}else if( pPk==0 ){ }else if( pPk==0 ){
k = 1; k = 1;
}else{ }else{
for(k=1; ALWAYS(k<=pTab->nCol) && pPk->aiColumn[k-1]!=i; k++){} for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
} }
sqlite3VdbeAddOp2(v, OP_Integer, k, 6); sqlite3VdbeAddOp2(v, OP_Integer, k, 6);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);

View File

@@ -826,7 +826,7 @@ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
** size of the memory allocation for StrAccum if necessary. ** size of the memory allocation for StrAccum if necessary.
*/ */
void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
assert( z!=0 ); assert( z!=0 || N==0 );
assert( p->zText!=0 || p->nChar==0 || p->accError ); assert( p->zText!=0 || p->nChar==0 || p->accError );
assert( N>=0 ); assert( N>=0 );
assert( p->accError==0 || p->nAlloc==0 ); assert( p->accError==0 || p->nAlloc==0 );

View File

@@ -460,6 +460,7 @@ static int lookupName(
if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){ if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){
pExpr->op = TK_STRING; pExpr->op = TK_STRING;
pExpr->pTab = 0; pExpr->pTab = 0;
pExpr->iTable = -1;
return WRC_Prune; return WRC_Prune;
} }
@@ -993,9 +994,11 @@ static int resolveCompoundOrderBy(
if( pItem->pExpr==pE ){ if( pItem->pExpr==pE ){
pItem->pExpr = pNew; pItem->pExpr = pNew;
}else{ }else{
assert( pItem->pExpr->op==TK_COLLATE ); Expr *pParent = pItem->pExpr;
assert( pItem->pExpr->pLeft==pE ); assert( pParent->op==TK_COLLATE );
pItem->pExpr->pLeft = pNew; while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft;
assert( pParent->pLeft==pE );
pParent->pLeft = pNew;
} }
sqlite3ExprDelete(db, pE); sqlite3ExprDelete(db, pE);
pItem->u.x.iOrderByCol = (u16)iCol; pItem->u.x.iOrderByCol = (u16)iCol;
@@ -1195,7 +1198,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
** after the names have been resolved. */ ** after the names have been resolved. */
if( p->selFlags & SF_Converted ){ if( p->selFlags & SF_Converted ){
Select *pSub = p->pSrc->a[0].pSelect; Select *pSub = p->pSrc->a[0].pSelect;
assert( p->pSrc->nSrc==1 && isCompound==0 && p->pOrderBy ); assert( p->pSrc->nSrc==1 && p->pOrderBy );
assert( pSub->pPrior && pSub->pOrderBy==0 ); assert( pSub->pPrior && pSub->pOrderBy==0 );
pSub->pOrderBy = p->pOrderBy; pSub->pOrderBy = p->pOrderBy;
p->pOrderBy = 0; p->pOrderBy = 0;

View File

@@ -3071,7 +3071,7 @@ static int multiSelectOrderBy(
/*** TBD: Insert subroutine calls to close cursors on incomplete /*** TBD: Insert subroutine calls to close cursors on incomplete
**** subqueries ****/ **** subqueries ****/
explainComposite(pParse, p->op, iSub1, iSub2, 0); explainComposite(pParse, p->op, iSub1, iSub2, 0);
return SQLITE_OK; return pParse->nErr!=0;
} }
#endif #endif
@@ -3883,6 +3883,7 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){
pNew->pOrderBy = 0; pNew->pOrderBy = 0;
p->pPrior = 0; p->pPrior = 0;
p->pNext = 0; p->pNext = 0;
p->pWith = 0;
p->selFlags &= ~SF_Compound; p->selFlags &= ~SF_Compound;
assert( (p->selFlags & SF_Converted)==0 ); assert( (p->selFlags & SF_Converted)==0 );
p->selFlags |= SF_Converted; p->selFlags |= SF_Converted;

View File

@@ -270,6 +270,7 @@ typedef sqlite_uint64 sqlite3_uint64;
/* /*
** CAPI3REF: Closing A Database Connection ** CAPI3REF: Closing A Database Connection
** DESTRUCTOR: sqlite3
** **
** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors ** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
** for the [sqlite3] object. ** for the [sqlite3] object.
@@ -321,6 +322,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
/* /*
** CAPI3REF: One-Step Query Execution Interface ** CAPI3REF: One-Step Query Execution Interface
** METHOD: sqlite3
** **
** The sqlite3_exec() interface is a convenience wrapper around ** The sqlite3_exec() interface is a convenience wrapper around
** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()],
@@ -1383,6 +1385,7 @@ int sqlite3_config(int, ...);
/* /*
** CAPI3REF: Configure database connections ** CAPI3REF: Configure database connections
** METHOD: sqlite3
** **
** The sqlite3_db_config() interface is used to make configuration ** The sqlite3_db_config() interface is used to make configuration
** changes to a [database connection]. The interface is similar to ** changes to a [database connection]. The interface is similar to
@@ -1880,6 +1883,7 @@ struct sqlite3_mem_methods {
/* /*
** CAPI3REF: Enable Or Disable Extended Result Codes ** CAPI3REF: Enable Or Disable Extended Result Codes
** METHOD: sqlite3
** **
** ^The sqlite3_extended_result_codes() routine enables or disables the ** ^The sqlite3_extended_result_codes() routine enables or disables the
** [extended result codes] feature of SQLite. ^The extended result ** [extended result codes] feature of SQLite. ^The extended result
@@ -1889,6 +1893,7 @@ int sqlite3_extended_result_codes(sqlite3*, int onoff);
/* /*
** CAPI3REF: Last Insert Rowid ** CAPI3REF: Last Insert Rowid
** METHOD: sqlite3
** **
** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables) ** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
** has a unique 64-bit signed ** has a unique 64-bit signed
@@ -1940,6 +1945,7 @@ sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
/* /*
** CAPI3REF: Count The Number Of Rows Modified ** CAPI3REF: Count The Number Of Rows Modified
** METHOD: sqlite3
** **
** ^This function returns the number of rows modified, inserted or ** ^This function returns the number of rows modified, inserted or
** deleted by the most recently completed INSERT, UPDATE or DELETE ** deleted by the most recently completed INSERT, UPDATE or DELETE
@@ -1992,6 +1998,7 @@ int sqlite3_changes(sqlite3*);
/* /*
** CAPI3REF: Total Number Of Rows Modified ** CAPI3REF: Total Number Of Rows Modified
** METHOD: sqlite3
** **
** ^This function returns the total number of rows inserted, modified or ** ^This function returns the total number of rows inserted, modified or
** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed ** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed
@@ -2015,6 +2022,7 @@ int sqlite3_total_changes(sqlite3*);
/* /*
** CAPI3REF: Interrupt A Long-Running Query ** CAPI3REF: Interrupt A Long-Running Query
** METHOD: sqlite3
** **
** ^This function causes any pending database operation to abort and ** ^This function causes any pending database operation to abort and
** return at its earliest opportunity. This routine is typically ** return at its earliest opportunity. This routine is typically
@@ -2091,6 +2099,7 @@ int sqlite3_complete16(const void *sql);
/* /*
** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
** KEYWORDS: {busy-handler callback} {busy handler} ** KEYWORDS: {busy-handler callback} {busy handler}
** METHOD: sqlite3
** **
** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X ** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
** that might be invoked with argument P whenever ** that might be invoked with argument P whenever
@@ -2150,6 +2159,7 @@ int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
/* /*
** CAPI3REF: Set A Busy Timeout ** CAPI3REF: Set A Busy Timeout
** METHOD: sqlite3
** **
** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps ** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps
** for a specified amount of time when a table is locked. ^The handler ** for a specified amount of time when a table is locked. ^The handler
@@ -2172,6 +2182,7 @@ int sqlite3_busy_timeout(sqlite3*, int ms);
/* /*
** CAPI3REF: Convenience Routines For Running Queries ** CAPI3REF: Convenience Routines For Running Queries
** METHOD: sqlite3
** **
** This is a legacy interface that is preserved for backwards compatibility. ** This is a legacy interface that is preserved for backwards compatibility.
** Use of this interface is not recommended. ** Use of this interface is not recommended.
@@ -2507,6 +2518,7 @@ void sqlite3_randomness(int N, void *P);
/* /*
** CAPI3REF: Compile-Time Authorization Callbacks ** CAPI3REF: Compile-Time Authorization Callbacks
** METHOD: sqlite3
** **
** ^This routine registers an authorizer callback with a particular ** ^This routine registers an authorizer callback with a particular
** [database connection], supplied in the first argument. ** [database connection], supplied in the first argument.
@@ -2663,6 +2675,7 @@ int sqlite3_set_authorizer(
/* /*
** CAPI3REF: Tracing And Profiling Functions ** CAPI3REF: Tracing And Profiling Functions
** METHOD: sqlite3
** **
** These routines register callback functions that can be used for ** These routines register callback functions that can be used for
** tracing and profiling the execution of SQL statements. ** tracing and profiling the execution of SQL statements.
@@ -2695,6 +2708,7 @@ SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
/* /*
** CAPI3REF: Query Progress Callbacks ** CAPI3REF: Query Progress Callbacks
** METHOD: sqlite3
** **
** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback ** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
** function X to be invoked periodically during long running calls to ** function X to be invoked periodically during long running calls to
@@ -2728,6 +2742,7 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
/* /*
** CAPI3REF: Opening A New Database Connection ** CAPI3REF: Opening A New Database Connection
** CONSTRUCTOR: sqlite3
** **
** ^These routines open an SQLite database file as specified by the ** ^These routines open an SQLite database file as specified by the
** filename argument. ^The filename argument is interpreted as UTF-8 for ** filename argument. ^The filename argument is interpreted as UTF-8 for
@@ -3013,6 +3028,7 @@ sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
/* /*
** CAPI3REF: Error Codes And Messages ** CAPI3REF: Error Codes And Messages
** METHOD: sqlite3
** **
** ^If the most recent sqlite3_* API call associated with ** ^If the most recent sqlite3_* API call associated with
** [database connection] D failed, then the sqlite3_errcode(D) interface ** [database connection] D failed, then the sqlite3_errcode(D) interface
@@ -3058,33 +3074,34 @@ const void *sqlite3_errmsg16(sqlite3*);
const char *sqlite3_errstr(int); const char *sqlite3_errstr(int);
/* /*
** CAPI3REF: SQL Statement Object ** CAPI3REF: Prepared Statement Object
** KEYWORDS: {prepared statement} {prepared statements} ** KEYWORDS: {prepared statement} {prepared statements}
** **
** An instance of this object represents a single SQL statement. ** An instance of this object represents a single SQL statement that
** This object is variously known as a "prepared statement" or a ** has been compiled into binary form and is ready to be evaluated.
** "compiled SQL statement" or simply as a "statement".
** **
** The life of a statement object goes something like this: ** Think of each SQL statement as a separate computer program. The
** original SQL text is source code. A prepared statement object
** is the compiled object code. All SQL must be converted into a
** prepared statement before it can be run.
**
** The life-cycle of a prepared statement object usually goes like this:
** **
** <ol> ** <ol>
** <li> Create the object using [sqlite3_prepare_v2()] or a related ** <li> Create the prepared statement object using [sqlite3_prepare_v2()].
** function. ** <li> Bind values to [parameters] using the sqlite3_bind_*()
** <li> Bind values to [host parameters] using the sqlite3_bind_*()
** interfaces. ** interfaces.
** <li> Run the SQL by calling [sqlite3_step()] one or more times. ** <li> Run the SQL by calling [sqlite3_step()] one or more times.
** <li> Reset the statement using [sqlite3_reset()] then go back ** <li> Reset the prepared statement using [sqlite3_reset()] then go back
** to step 2. Do this zero or more times. ** to step 2. Do this zero or more times.
** <li> Destroy the object using [sqlite3_finalize()]. ** <li> Destroy the object using [sqlite3_finalize()].
** </ol> ** </ol>
**
** Refer to documentation on individual methods above for additional
** information.
*/ */
typedef struct sqlite3_stmt sqlite3_stmt; typedef struct sqlite3_stmt sqlite3_stmt;
/* /*
** CAPI3REF: Run-time Limits ** CAPI3REF: Run-time Limits
** METHOD: sqlite3
** **
** ^(This interface allows the size of various constructs to be limited ** ^(This interface allows the size of various constructs to be limited
** on a connection by connection basis. The first parameter is the ** on a connection by connection basis. The first parameter is the
@@ -3196,6 +3213,8 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
/* /*
** CAPI3REF: Compiling An SQL Statement ** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler} ** KEYWORDS: {SQL statement compiler}
** METHOD: sqlite3
** CONSTRUCTOR: sqlite3_stmt
** **
** To execute an SQL query, it must first be compiled into a byte-code ** To execute an SQL query, it must first be compiled into a byte-code
** program using one of these routines. ** program using one of these routines.
@@ -3303,6 +3322,7 @@ int sqlite3_prepare16_v2(
/* /*
** CAPI3REF: Retrieving Statement SQL ** CAPI3REF: Retrieving Statement SQL
** METHOD: sqlite3_stmt
** **
** ^This interface can be used to retrieve a saved copy of the original ** ^This interface can be used to retrieve a saved copy of the original
** SQL text used to create a [prepared statement] if that statement was ** SQL text used to create a [prepared statement] if that statement was
@@ -3312,6 +3332,7 @@ const char *sqlite3_sql(sqlite3_stmt *pStmt);
/* /*
** CAPI3REF: Determine If An SQL Statement Writes The Database ** CAPI3REF: Determine If An SQL Statement Writes The Database
** METHOD: sqlite3_stmt
** **
** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if ** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
** and only if the [prepared statement] X makes no direct changes to ** and only if the [prepared statement] X makes no direct changes to
@@ -3343,6 +3364,7 @@ int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
/* /*
** CAPI3REF: Determine If A Prepared Statement Has Been Reset ** CAPI3REF: Determine If A Prepared Statement Has Been Reset
** METHOD: sqlite3_stmt
** **
** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the ** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
** [prepared statement] S has been stepped at least once using ** [prepared statement] S has been stepped at least once using
@@ -3417,6 +3439,7 @@ typedef struct sqlite3_context sqlite3_context;
** CAPI3REF: Binding Values To Prepared Statements ** CAPI3REF: Binding Values To Prepared Statements
** KEYWORDS: {host parameter} {host parameters} {host parameter name} ** KEYWORDS: {host parameter} {host parameters} {host parameter name}
** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
** METHOD: sqlite3_stmt
** **
** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants,
** literals may be replaced by a [parameter] that matches one of following ** literals may be replaced by a [parameter] that matches one of following
@@ -3535,6 +3558,7 @@ int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
/* /*
** CAPI3REF: Number Of SQL Parameters ** CAPI3REF: Number Of SQL Parameters
** METHOD: sqlite3_stmt
** **
** ^This routine can be used to find the number of [SQL parameters] ** ^This routine can be used to find the number of [SQL parameters]
** in a [prepared statement]. SQL parameters are tokens of the ** in a [prepared statement]. SQL parameters are tokens of the
@@ -3555,6 +3579,7 @@ int sqlite3_bind_parameter_count(sqlite3_stmt*);
/* /*
** CAPI3REF: Name Of A Host Parameter ** CAPI3REF: Name Of A Host Parameter
** METHOD: sqlite3_stmt
** **
** ^The sqlite3_bind_parameter_name(P,N) interface returns ** ^The sqlite3_bind_parameter_name(P,N) interface returns
** the name of the N-th [SQL parameter] in the [prepared statement] P. ** the name of the N-th [SQL parameter] in the [prepared statement] P.
@@ -3582,6 +3607,7 @@ const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
/* /*
** CAPI3REF: Index Of A Parameter With A Given Name ** CAPI3REF: Index Of A Parameter With A Given Name
** METHOD: sqlite3_stmt
** **
** ^Return the index of an SQL parameter given its name. ^The ** ^Return the index of an SQL parameter given its name. ^The
** index value returned is suitable for use as the second ** index value returned is suitable for use as the second
@@ -3598,6 +3624,7 @@ int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
/* /*
** CAPI3REF: Reset All Bindings On A Prepared Statement ** CAPI3REF: Reset All Bindings On A Prepared Statement
** METHOD: sqlite3_stmt
** **
** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset ** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset
** the [sqlite3_bind_blob | bindings] on a [prepared statement]. ** the [sqlite3_bind_blob | bindings] on a [prepared statement].
@@ -3607,6 +3634,7 @@ int sqlite3_clear_bindings(sqlite3_stmt*);
/* /*
** CAPI3REF: Number Of Columns In A Result Set ** CAPI3REF: Number Of Columns In A Result Set
** METHOD: sqlite3_stmt
** **
** ^Return the number of columns in the result set returned by the ** ^Return the number of columns in the result set returned by the
** [prepared statement]. ^This routine returns 0 if pStmt is an SQL ** [prepared statement]. ^This routine returns 0 if pStmt is an SQL
@@ -3618,6 +3646,7 @@ int sqlite3_column_count(sqlite3_stmt *pStmt);
/* /*
** CAPI3REF: Column Names In A Result Set ** CAPI3REF: Column Names In A Result Set
** METHOD: sqlite3_stmt
** **
** ^These routines return the name assigned to a particular column ** ^These routines return the name assigned to a particular column
** in the result set of a [SELECT] statement. ^The sqlite3_column_name() ** in the result set of a [SELECT] statement. ^The sqlite3_column_name()
@@ -3647,6 +3676,7 @@ const void *sqlite3_column_name16(sqlite3_stmt*, int N);
/* /*
** CAPI3REF: Source Of Data In A Query Result ** CAPI3REF: Source Of Data In A Query Result
** METHOD: sqlite3_stmt
** **
** ^These routines provide a means to determine the database, table, and ** ^These routines provide a means to determine the database, table, and
** table column that is the origin of a particular result column in ** table column that is the origin of a particular result column in
@@ -3699,6 +3729,7 @@ const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
/* /*
** CAPI3REF: Declared Datatype Of A Query Result ** CAPI3REF: Declared Datatype Of A Query Result
** METHOD: sqlite3_stmt
** **
** ^(The first parameter is a [prepared statement]. ** ^(The first parameter is a [prepared statement].
** If this statement is a [SELECT] statement and the Nth column of the ** If this statement is a [SELECT] statement and the Nth column of the
@@ -3731,6 +3762,7 @@ const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
/* /*
** CAPI3REF: Evaluate An SQL Statement ** CAPI3REF: Evaluate An SQL Statement
** METHOD: sqlite3_stmt
** **
** After a [prepared statement] has been prepared using either ** After a [prepared statement] has been prepared using either
** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy ** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy
@@ -3810,6 +3842,7 @@ int sqlite3_step(sqlite3_stmt*);
/* /*
** CAPI3REF: Number of columns in a result set ** CAPI3REF: Number of columns in a result set
** METHOD: sqlite3_stmt
** **
** ^The sqlite3_data_count(P) interface returns the number of columns in the ** ^The sqlite3_data_count(P) interface returns the number of columns in the
** current row of the result set of [prepared statement] P. ** current row of the result set of [prepared statement] P.
@@ -3863,6 +3896,7 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
/* /*
** CAPI3REF: Result Values From A Query ** CAPI3REF: Result Values From A Query
** KEYWORDS: {column access functions} ** KEYWORDS: {column access functions}
** METHOD: sqlite3_stmt
** **
** These routines form the "result set" interface. ** These routines form the "result set" interface.
** **
@@ -4035,6 +4069,7 @@ sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
/* /*
** CAPI3REF: Destroy A Prepared Statement Object ** CAPI3REF: Destroy A Prepared Statement Object
** DESTRUCTOR: sqlite3_stmt
** **
** ^The sqlite3_finalize() function is called to delete a [prepared statement]. ** ^The sqlite3_finalize() function is called to delete a [prepared statement].
** ^If the most recent evaluation of the statement encountered no errors ** ^If the most recent evaluation of the statement encountered no errors
@@ -4062,6 +4097,7 @@ int sqlite3_finalize(sqlite3_stmt *pStmt);
/* /*
** CAPI3REF: Reset A Prepared Statement Object ** CAPI3REF: Reset A Prepared Statement Object
** METHOD: sqlite3_stmt
** **
** The sqlite3_reset() function is called to reset a [prepared statement] ** The sqlite3_reset() function is called to reset a [prepared statement]
** object back to its initial state, ready to be re-executed. ** object back to its initial state, ready to be re-executed.
@@ -4091,6 +4127,7 @@ int sqlite3_reset(sqlite3_stmt *pStmt);
** KEYWORDS: {function creation routines} ** KEYWORDS: {function creation routines}
** KEYWORDS: {application-defined SQL function} ** KEYWORDS: {application-defined SQL function}
** KEYWORDS: {application-defined SQL functions} ** KEYWORDS: {application-defined SQL functions}
** METHOD: sqlite3
** **
** ^These functions (collectively known as "function creation routines") ** ^These functions (collectively known as "function creation routines")
** are used to add SQL functions or aggregates or to redefine the behavior ** are used to add SQL functions or aggregates or to redefine the behavior
@@ -4260,6 +4297,7 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
/* /*
** CAPI3REF: Obtaining SQL Function Parameter Values ** CAPI3REF: Obtaining SQL Function Parameter Values
** METHOD: sqlite3_value
** **
** The C-language implementation of SQL functions and aggregates uses ** The C-language implementation of SQL functions and aggregates uses
** this set of interface routines to access the parameter values on ** this set of interface routines to access the parameter values on
@@ -4318,6 +4356,7 @@ int sqlite3_value_numeric_type(sqlite3_value*);
/* /*
** CAPI3REF: Obtain Aggregate Function Context ** CAPI3REF: Obtain Aggregate Function Context
** METHOD: sqlite3_context
** **
** Implementations of aggregate SQL functions use this ** Implementations of aggregate SQL functions use this
** routine to allocate memory for storing their state. ** routine to allocate memory for storing their state.
@@ -4362,6 +4401,7 @@ void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
/* /*
** CAPI3REF: User Data For Functions ** CAPI3REF: User Data For Functions
** METHOD: sqlite3_context
** **
** ^The sqlite3_user_data() interface returns a copy of ** ^The sqlite3_user_data() interface returns a copy of
** the pointer that was the pUserData parameter (the 5th parameter) ** the pointer that was the pUserData parameter (the 5th parameter)
@@ -4376,6 +4416,7 @@ void *sqlite3_user_data(sqlite3_context*);
/* /*
** CAPI3REF: Database Connection For Functions ** CAPI3REF: Database Connection For Functions
** METHOD: sqlite3_context
** **
** ^The sqlite3_context_db_handle() interface returns a copy of ** ^The sqlite3_context_db_handle() interface returns a copy of
** the pointer to the [database connection] (the 1st parameter) ** the pointer to the [database connection] (the 1st parameter)
@@ -4387,6 +4428,7 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
/* /*
** CAPI3REF: Function Auxiliary Data ** CAPI3REF: Function Auxiliary Data
** METHOD: sqlite3_context
** **
** These functions may be used by (non-aggregate) SQL functions to ** These functions may be used by (non-aggregate) SQL functions to
** associate metadata with argument values. If the same value is passed to ** associate metadata with argument values. If the same value is passed to
@@ -4459,6 +4501,7 @@ typedef void (*sqlite3_destructor_type)(void*);
/* /*
** CAPI3REF: Setting The Result Of An SQL Function ** CAPI3REF: Setting The Result Of An SQL Function
** METHOD: sqlite3_context
** **
** These routines are used by the xFunc or xFinal callbacks that ** These routines are used by the xFunc or xFinal callbacks that
** implement SQL functions and aggregates. See ** implement SQL functions and aggregates. See
@@ -4594,6 +4637,7 @@ void sqlite3_result_zeroblob(sqlite3_context*, int n);
/* /*
** CAPI3REF: Define New Collating Sequences ** CAPI3REF: Define New Collating Sequences
** METHOD: sqlite3
** **
** ^These functions add, remove, or modify a [collation] associated ** ^These functions add, remove, or modify a [collation] associated
** with the [database connection] specified as the first argument. ** with the [database connection] specified as the first argument.
@@ -4696,6 +4740,7 @@ int sqlite3_create_collation16(
/* /*
** CAPI3REF: Collation Needed Callbacks ** CAPI3REF: Collation Needed Callbacks
** METHOD: sqlite3
** **
** ^To avoid having to register all collation sequences before a database ** ^To avoid having to register all collation sequences before a database
** can be used, a single callback function may be registered with the ** can be used, a single callback function may be registered with the
@@ -4903,6 +4948,7 @@ SQLITE_EXTERN char *sqlite3_data_directory;
/* /*
** CAPI3REF: Test For Auto-Commit Mode ** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode} ** KEYWORDS: {autocommit mode}
** METHOD: sqlite3
** **
** ^The sqlite3_get_autocommit() interface returns non-zero or ** ^The sqlite3_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode, ** zero if the given database connection is or is not in autocommit mode,
@@ -4925,6 +4971,7 @@ int sqlite3_get_autocommit(sqlite3*);
/* /*
** CAPI3REF: Find The Database Handle Of A Prepared Statement ** CAPI3REF: Find The Database Handle Of A Prepared Statement
** METHOD: sqlite3_stmt
** **
** ^The sqlite3_db_handle interface returns the [database connection] handle ** ^The sqlite3_db_handle interface returns the [database connection] handle
** to which a [prepared statement] belongs. ^The [database connection] ** to which a [prepared statement] belongs. ^The [database connection]
@@ -4937,6 +4984,7 @@ sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
/* /*
** CAPI3REF: Return The Filename For A Database Connection ** CAPI3REF: Return The Filename For A Database Connection
** METHOD: sqlite3
** **
** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename ** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename
** associated with database N of connection D. ^The main database file ** associated with database N of connection D. ^The main database file
@@ -4953,6 +5001,7 @@ const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
/* /*
** CAPI3REF: Determine if a database is read-only ** CAPI3REF: Determine if a database is read-only
** METHOD: sqlite3
** **
** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N ** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N
** of connection D is read-only, 0 if it is read/write, or -1 if N is not ** of connection D is read-only, 0 if it is read/write, or -1 if N is not
@@ -4962,6 +5011,7 @@ int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
/* /*
** CAPI3REF: Find the next prepared statement ** CAPI3REF: Find the next prepared statement
** METHOD: sqlite3
** **
** ^This interface returns a pointer to the next [prepared statement] after ** ^This interface returns a pointer to the next [prepared statement] after
** pStmt associated with the [database connection] pDb. ^If pStmt is NULL ** pStmt associated with the [database connection] pDb. ^If pStmt is NULL
@@ -4977,6 +5027,7 @@ sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
/* /*
** CAPI3REF: Commit And Rollback Notification Callbacks ** CAPI3REF: Commit And Rollback Notification Callbacks
** METHOD: sqlite3
** **
** ^The sqlite3_commit_hook() interface registers a callback ** ^The sqlite3_commit_hook() interface registers a callback
** function to be invoked whenever a transaction is [COMMIT | committed]. ** function to be invoked whenever a transaction is [COMMIT | committed].
@@ -5026,6 +5077,7 @@ void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
/* /*
** CAPI3REF: Data Change Notification Callbacks ** CAPI3REF: Data Change Notification Callbacks
** METHOD: sqlite3
** **
** ^The sqlite3_update_hook() interface registers a callback function ** ^The sqlite3_update_hook() interface registers a callback function
** with the [database connection] identified by the first argument ** with the [database connection] identified by the first argument
@@ -5132,6 +5184,7 @@ int sqlite3_release_memory(int);
/* /*
** CAPI3REF: Free Memory Used By A Database Connection ** CAPI3REF: Free Memory Used By A Database Connection
** METHOD: sqlite3
** **
** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap ** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap
** memory as possible from database connection D. Unlike the ** memory as possible from database connection D. Unlike the
@@ -5209,6 +5262,7 @@ SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
/* /*
** CAPI3REF: Extract Metadata About A Column Of A Table ** CAPI3REF: Extract Metadata About A Column Of A Table
** METHOD: sqlite3
** **
** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns ** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns
** information about column C of table T in database D ** information about column C of table T in database D
@@ -5287,6 +5341,7 @@ int sqlite3_table_column_metadata(
/* /*
** CAPI3REF: Load An Extension ** CAPI3REF: Load An Extension
** METHOD: sqlite3
** **
** ^This interface loads an SQLite extension library from the named file. ** ^This interface loads an SQLite extension library from the named file.
** **
@@ -5328,6 +5383,7 @@ int sqlite3_load_extension(
/* /*
** CAPI3REF: Enable Or Disable Extension Loading ** CAPI3REF: Enable Or Disable Extension Loading
** METHOD: sqlite3
** **
** ^So as not to open security holes in older applications that are ** ^So as not to open security holes in older applications that are
** unprepared to deal with [extension loading], and as a means of disabling ** unprepared to deal with [extension loading], and as a means of disabling
@@ -5577,6 +5633,7 @@ struct sqlite3_index_info {
/* /*
** CAPI3REF: Register A Virtual Table Implementation ** CAPI3REF: Register A Virtual Table Implementation
** METHOD: sqlite3
** **
** ^These routines are used to register a new [virtual table module] name. ** ^These routines are used to register a new [virtual table module] name.
** ^Module names must be registered before ** ^Module names must be registered before
@@ -5673,6 +5730,7 @@ int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
/* /*
** CAPI3REF: Overload A Function For A Virtual Table ** CAPI3REF: Overload A Function For A Virtual Table
** METHOD: sqlite3
** **
** ^(Virtual tables can provide alternative implementations of functions ** ^(Virtual tables can provide alternative implementations of functions
** using the [xFindFunction] method of the [virtual table module]. ** using the [xFindFunction] method of the [virtual table module].
@@ -5715,6 +5773,8 @@ typedef struct sqlite3_blob sqlite3_blob;
/* /*
** CAPI3REF: Open A BLOB For Incremental I/O ** CAPI3REF: Open A BLOB For Incremental I/O
** METHOD: sqlite3
** CONSTRUCTOR: sqlite3_blob
** **
** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located ** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
** in row iRow, column zColumn, table zTable in database zDb; ** in row iRow, column zColumn, table zTable in database zDb;
@@ -5796,6 +5856,7 @@ int sqlite3_blob_open(
/* /*
** CAPI3REF: Move a BLOB Handle to a New Row ** CAPI3REF: Move a BLOB Handle to a New Row
** METHOD: sqlite3_blob
** **
** ^This function is used to move an existing blob handle so that it points ** ^This function is used to move an existing blob handle so that it points
** to a different row of the same database table. ^The new row is identified ** to a different row of the same database table. ^The new row is identified
@@ -5820,6 +5881,7 @@ SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
/* /*
** CAPI3REF: Close A BLOB Handle ** CAPI3REF: Close A BLOB Handle
** DESTRUCTOR: sqlite3_blob
** **
** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed ** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed
** unconditionally. Even if this routine returns an error code, the ** unconditionally. Even if this routine returns an error code, the
@@ -5842,6 +5904,7 @@ int sqlite3_blob_close(sqlite3_blob *);
/* /*
** CAPI3REF: Return The Size Of An Open BLOB ** CAPI3REF: Return The Size Of An Open BLOB
** METHOD: sqlite3_blob
** **
** ^Returns the size in bytes of the BLOB accessible via the ** ^Returns the size in bytes of the BLOB accessible via the
** successfully opened [BLOB handle] in its only argument. ^The ** successfully opened [BLOB handle] in its only argument. ^The
@@ -5857,6 +5920,7 @@ int sqlite3_blob_bytes(sqlite3_blob *);
/* /*
** CAPI3REF: Read Data From A BLOB Incrementally ** CAPI3REF: Read Data From A BLOB Incrementally
** METHOD: sqlite3_blob
** **
** ^(This function is used to read data from an open [BLOB handle] into a ** ^(This function is used to read data from an open [BLOB handle] into a
** caller-supplied buffer. N bytes of data are copied into buffer Z ** caller-supplied buffer. N bytes of data are copied into buffer Z
@@ -5885,6 +5949,7 @@ int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
/* /*
** CAPI3REF: Write Data Into A BLOB Incrementally ** CAPI3REF: Write Data Into A BLOB Incrementally
** METHOD: sqlite3_blob
** **
** ^(This function is used to write data into an open [BLOB handle] from a ** ^(This function is used to write data into an open [BLOB handle] from a
** caller-supplied buffer. N bytes of data are copied from the buffer Z ** caller-supplied buffer. N bytes of data are copied from the buffer Z
@@ -6212,6 +6277,7 @@ int sqlite3_mutex_notheld(sqlite3_mutex*);
/* /*
** CAPI3REF: Retrieve the mutex for a database connection ** CAPI3REF: Retrieve the mutex for a database connection
** METHOD: sqlite3
** **
** ^This interface returns a pointer the [sqlite3_mutex] object that ** ^This interface returns a pointer the [sqlite3_mutex] object that
** serializes access to the [database connection] given in the argument ** serializes access to the [database connection] given in the argument
@@ -6223,6 +6289,7 @@ sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
/* /*
** CAPI3REF: Low-Level Control Of Database Files ** CAPI3REF: Low-Level Control Of Database Files
** METHOD: sqlite3
** **
** ^The [sqlite3_file_control()] interface makes a direct call to the ** ^The [sqlite3_file_control()] interface makes a direct call to the
** xFileControl method for the [sqlite3_io_methods] object associated ** xFileControl method for the [sqlite3_io_methods] object associated
@@ -6439,6 +6506,7 @@ int sqlite3_status64(
/* /*
** CAPI3REF: Database Connection Status ** CAPI3REF: Database Connection Status
** METHOD: sqlite3
** **
** ^This interface is used to retrieve runtime status information ** ^This interface is used to retrieve runtime status information
** about a single [database connection]. ^The first argument is the ** about a single [database connection]. ^The first argument is the
@@ -6567,6 +6635,7 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
/* /*
** CAPI3REF: Prepared Statement Status ** CAPI3REF: Prepared Statement Status
** METHOD: sqlite3_stmt
** **
** ^(Each prepared statement maintains various ** ^(Each prepared statement maintains various
** [SQLITE_STMTSTATUS counters] that measure the number ** [SQLITE_STMTSTATUS counters] that measure the number
@@ -7070,6 +7139,7 @@ int sqlite3_backup_pagecount(sqlite3_backup *p);
/* /*
** CAPI3REF: Unlock Notification ** CAPI3REF: Unlock Notification
** METHOD: sqlite3
** **
** ^When running in shared-cache mode, a database operation may fail with ** ^When running in shared-cache mode, a database operation may fail with
** an [SQLITE_LOCKED] error if the required locks on the shared-cache or ** an [SQLITE_LOCKED] error if the required locks on the shared-cache or
@@ -7240,6 +7310,7 @@ void sqlite3_log(int iErrCode, const char *zFormat, ...);
/* /*
** CAPI3REF: Write-Ahead Log Commit Hook ** CAPI3REF: Write-Ahead Log Commit Hook
** METHOD: sqlite3
** **
** ^The [sqlite3_wal_hook()] function is used to register a callback that ** ^The [sqlite3_wal_hook()] function is used to register a callback that
** is invoked each time data is committed to a database in wal mode. ** is invoked each time data is committed to a database in wal mode.
@@ -7279,6 +7350,7 @@ void *sqlite3_wal_hook(
/* /*
** CAPI3REF: Configure an auto-checkpoint ** CAPI3REF: Configure an auto-checkpoint
** METHOD: sqlite3
** **
** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around ** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
** [sqlite3_wal_hook()] that causes any database on [database connection] D ** [sqlite3_wal_hook()] that causes any database on [database connection] D
@@ -7309,6 +7381,7 @@ int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
/* /*
** CAPI3REF: Checkpoint a database ** CAPI3REF: Checkpoint a database
** METHOD: sqlite3
** **
** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to ** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to
** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ ** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^
@@ -7330,6 +7403,7 @@ int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
/* /*
** CAPI3REF: Checkpoint a database ** CAPI3REF: Checkpoint a database
** METHOD: sqlite3
** **
** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint ** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint
** operation on database X of [database connection] D in mode M. Status ** operation on database X of [database connection] D in mode M. Status
@@ -7584,6 +7658,7 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
/* /*
** CAPI3REF: Prepared Statement Scan Status ** CAPI3REF: Prepared Statement Scan Status
** METHOD: sqlite3_stmt
** **
** This interface returns information about the predicted and measured ** This interface returns information about the predicted and measured
** performance for pStmt. Advanced applications can use this ** performance for pStmt. Advanced applications can use this
@@ -7621,6 +7696,7 @@ SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus(
/* /*
** CAPI3REF: Zero Scan-Status Counters ** CAPI3REF: Zero Scan-Status Counters
** METHOD: sqlite3_stmt
** **
** ^Zero all [sqlite3_stmt_scanstatus()] related event counters. ** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
** **

View File

@@ -1226,6 +1226,7 @@ struct sqlite3 {
#define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */ #define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */
#define SQLITE_QueryOnly 0x02000000 /* Disable database changes */ #define SQLITE_QueryOnly 0x02000000 /* Disable database changes */
#define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */ #define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */
#define SQLITE_Vacuum 0x08000000 /* Currently in a VACUUM */
/* /*

View File

@@ -430,10 +430,8 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
break; break;
} }
case TK_ILLEGAL: { case TK_ILLEGAL: {
sqlite3DbFree(db, *pzErrMsg); sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"",
*pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"",
&pParse->sLastToken); &pParse->sLastToken);
nErr++;
goto abort_parse; goto abort_parse;
} }
case TK_SEMI: { case TK_SEMI: {
@@ -451,7 +449,8 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
} }
} }
abort_parse: abort_parse:
if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){ assert( nErr==0 );
if( zSql[i]==0 && pParse->rc==SQLITE_OK ){
if( lastTokenParsed!=TK_SEMI ){ if( lastTokenParsed!=TK_SEMI ){
sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse); sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
pParse->zTail = &zSql[i]; pParse->zTail = &zSql[i];

View File

@@ -680,7 +680,6 @@ static SrcList *targetSrcList(
pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0); pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
if( pSrc ){ if( pSrc ){
assert( pSrc->nSrc>0 ); assert( pSrc->nSrc>0 );
assert( pSrc->a!=0 );
iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema); iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
if( iDb==0 || iDb>=2 ){ if( iDb==0 || iDb>=2 ){
sqlite3 *db = pParse->db; sqlite3 *db = pParse->db;

View File

@@ -250,6 +250,8 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
** the contents to the temporary database. ** the contents to the temporary database.
*/ */
assert( (db->flags & SQLITE_Vacuum)==0 );
db->flags |= SQLITE_Vacuum;
rc = execExecSql(db, pzErrMsg, rc = execExecSql(db, pzErrMsg,
"SELECT 'INSERT INTO vacuum_db.' || quote(name) " "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
"|| ' SELECT * FROM main.' || quote(name) || ';'" "|| ' SELECT * FROM main.' || quote(name) || ';'"
@@ -257,6 +259,8 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
"WHERE type = 'table' AND name!='sqlite_sequence' " "WHERE type = 'table' AND name!='sqlite_sequence' "
" AND coalesce(rootpage,1)>0" " AND coalesce(rootpage,1)>0"
); );
assert( (db->flags & SQLITE_Vacuum)!=0 );
db->flags &= ~SQLITE_Vacuum;
if( rc!=SQLITE_OK ) goto end_of_vacuum; if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Copy over the sequence table /* Copy over the sequence table

View File

@@ -514,6 +514,21 @@ static int checkSavepointCount(sqlite3 *db){
} }
#endif #endif
/*
** Return the register of pOp->p2 after first preparing it to be
** overwritten with an integer value.
*/
static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){
Mem *pOut;
assert( pOp->p2>0 );
assert( pOp->p2<=(p->nMem-p->nCursor) );
pOut = &p->aMem[pOp->p2];
memAboutToChange(p, pOut);
if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
pOut->flags = MEM_Int;
return pOut;
}
/* /*
** Execute as much of a VDBE program as we can. ** Execute as much of a VDBE program as we can.
@@ -522,9 +537,8 @@ static int checkSavepointCount(sqlite3 *db){
int sqlite3VdbeExec( int sqlite3VdbeExec(
Vdbe *p /* The VDBE */ Vdbe *p /* The VDBE */
){ ){
int pc=0; /* The program counter */
Op *aOp = p->aOp; /* Copy of p->aOp */ Op *aOp = p->aOp; /* Copy of p->aOp */
Op *pOp; /* Current operation */ Op *pOp = aOp; /* Current operation */
int rc = SQLITE_OK; /* Value to return */ int rc = SQLITE_OK; /* Value to return */
sqlite3 *db = p->db; /* The database */ sqlite3 *db = p->db; /* The database */
u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
@@ -600,23 +614,22 @@ int sqlite3VdbeExec(
} }
sqlite3EndBenignMalloc(); sqlite3EndBenignMalloc();
#endif #endif
for(pc=p->pc; rc==SQLITE_OK; pc++){ for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){
assert( pc>=0 && pc<p->nOp ); assert( pOp>=aOp && pOp<&aOp[p->nOp]);
if( db->mallocFailed ) goto no_mem; if( db->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE #ifdef VDBE_PROFILE
start = sqlite3Hwtime(); start = sqlite3Hwtime();
#endif #endif
nVmStep++; nVmStep++;
pOp = &aOp[pc];
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
if( p->anExec ) p->anExec[pc]++; if( p->anExec ) p->anExec[(int)(pOp-aOp)]++;
#endif #endif
/* Only allow tracing if SQLITE_DEBUG is defined. /* Only allow tracing if SQLITE_DEBUG is defined.
*/ */
#ifdef SQLITE_DEBUG #ifdef SQLITE_DEBUG
if( db->flags & SQLITE_VdbeTrace ){ if( db->flags & SQLITE_VdbeTrace ){
sqlite3VdbePrintOp(stdout, pc, pOp); sqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp);
} }
#endif #endif
@@ -633,23 +646,9 @@ int sqlite3VdbeExec(
} }
#endif #endif
/* On any opcode with the "out2-prerelease" tag, free any
** external allocations out of mem[p2] and set mem[p2] to be
** an undefined integer. Opcodes will either fill in the integer
** value or convert mem[p2] to a different type.
*/
assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){
assert( pOp->p2>0 );
assert( pOp->p2<=(p->nMem-p->nCursor) );
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
pOut->flags = MEM_Int;
}
/* Sanity checking on other operands */ /* Sanity checking on other operands */
#ifdef SQLITE_DEBUG #ifdef SQLITE_DEBUG
assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
if( (pOp->opflags & OPFLG_IN1)!=0 ){ if( (pOp->opflags & OPFLG_IN1)!=0 ){
assert( pOp->p1>0 ); assert( pOp->p1>0 );
assert( pOp->p1<=(p->nMem-p->nCursor) ); assert( pOp->p1<=(p->nMem-p->nCursor) );
@@ -705,7 +704,7 @@ int sqlite3VdbeExec(
** **
** Other keywords in the comment that follows each case are used to ** Other keywords in the comment that follows each case are used to
** construct the OPFLG_INITIALIZER value that initializes opcodeProperty[]. ** construct the OPFLG_INITIALIZER value that initializes opcodeProperty[].
** Keywords include: in1, in2, in3, out2_prerelease, out2, out3. See ** Keywords include: in1, in2, in3, out2, out3. See
** the mkopcodeh.awk script for additional information. ** the mkopcodeh.awk script for additional information.
** **
** Documentation about VDBE opcodes is generated by scanning this file ** Documentation about VDBE opcodes is generated by scanning this file
@@ -733,7 +732,8 @@ int sqlite3VdbeExec(
** to the current line should be indented for EXPLAIN output. ** to the current line should be indented for EXPLAIN output.
*/ */
case OP_Goto: { /* jump */ case OP_Goto: { /* jump */
pc = pOp->p2 - 1; jump_to_p2_and_check_for_interrupt:
pOp = &aOp[pOp->p2 - 1];
/* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev, /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon
@@ -778,9 +778,13 @@ case OP_Gosub: { /* jump */
assert( VdbeMemDynamic(pIn1)==0 ); assert( VdbeMemDynamic(pIn1)==0 );
memAboutToChange(p, pIn1); memAboutToChange(p, pIn1);
pIn1->flags = MEM_Int; pIn1->flags = MEM_Int;
pIn1->u.i = pc; pIn1->u.i = (int)(pOp-aOp);
REGISTER_TRACE(pOp->p1, pIn1); REGISTER_TRACE(pOp->p1, pIn1);
pc = pOp->p2 - 1;
/* Most jump operations do a goto to this spot in order to update
** the pOp pointer. */
jump_to_p2:
pOp = &aOp[pOp->p2 - 1];
break; break;
} }
@@ -792,7 +796,7 @@ case OP_Gosub: { /* jump */
case OP_Return: { /* in1 */ case OP_Return: { /* in1 */
pIn1 = &aMem[pOp->p1]; pIn1 = &aMem[pOp->p1];
assert( pIn1->flags==MEM_Int ); assert( pIn1->flags==MEM_Int );
pc = (int)pIn1->u.i; pOp = &aOp[pIn1->u.i];
pIn1->flags = MEM_Undefined; pIn1->flags = MEM_Undefined;
break; break;
} }
@@ -816,7 +820,7 @@ case OP_InitCoroutine: { /* jump */
assert( !VdbeMemDynamic(pOut) ); assert( !VdbeMemDynamic(pOut) );
pOut->u.i = pOp->p3 - 1; pOut->u.i = pOp->p3 - 1;
pOut->flags = MEM_Int; pOut->flags = MEM_Int;
if( pOp->p2 ) pc = pOp->p2 - 1; if( pOp->p2 ) goto jump_to_p2;
break; break;
} }
@@ -836,7 +840,7 @@ case OP_EndCoroutine: { /* in1 */
pCaller = &aOp[pIn1->u.i]; pCaller = &aOp[pIn1->u.i];
assert( pCaller->opcode==OP_Yield ); assert( pCaller->opcode==OP_Yield );
assert( pCaller->p2>=0 && pCaller->p2<p->nOp ); assert( pCaller->p2>=0 && pCaller->p2<p->nOp );
pc = pCaller->p2 - 1; pOp = &aOp[pCaller->p2 - 1];
pIn1->flags = MEM_Undefined; pIn1->flags = MEM_Undefined;
break; break;
} }
@@ -860,9 +864,9 @@ case OP_Yield: { /* in1, jump */
assert( VdbeMemDynamic(pIn1)==0 ); assert( VdbeMemDynamic(pIn1)==0 );
pIn1->flags = MEM_Int; pIn1->flags = MEM_Int;
pcDest = (int)pIn1->u.i; pcDest = (int)pIn1->u.i;
pIn1->u.i = pc; pIn1->u.i = (int)(pOp - aOp);
REGISTER_TRACE(pOp->p1, pIn1); REGISTER_TRACE(pOp->p1, pIn1);
pc = pcDest; pOp = &aOp[pcDest];
break; break;
} }
@@ -913,30 +917,34 @@ case OP_HaltIfNull: { /* in3 */
case OP_Halt: { case OP_Halt: {
const char *zType; const char *zType;
const char *zLogFmt; const char *zLogFmt;
VdbeFrame *pFrame;
int pcx;
pcx = (int)(pOp - aOp);
if( pOp->p1==SQLITE_OK && p->pFrame ){ if( pOp->p1==SQLITE_OK && p->pFrame ){
/* Halt the sub-program. Return control to the parent frame. */ /* Halt the sub-program. Return control to the parent frame. */
VdbeFrame *pFrame = p->pFrame; pFrame = p->pFrame;
p->pFrame = pFrame->pParent; p->pFrame = pFrame->pParent;
p->nFrame--; p->nFrame--;
sqlite3VdbeSetChanges(db, p->nChange); sqlite3VdbeSetChanges(db, p->nChange);
pc = sqlite3VdbeFrameRestore(pFrame); pcx = sqlite3VdbeFrameRestore(pFrame);
lastRowid = db->lastRowid; lastRowid = db->lastRowid;
if( pOp->p2==OE_Ignore ){ if( pOp->p2==OE_Ignore ){
/* Instruction pc is the OP_Program that invoked the sub-program /* Instruction pcx is the OP_Program that invoked the sub-program
** currently being halted. If the p2 instruction of this OP_Halt ** currently being halted. If the p2 instruction of this OP_Halt
** instruction is set to OE_Ignore, then the sub-program is throwing ** instruction is set to OE_Ignore, then the sub-program is throwing
** an IGNORE exception. In this case jump to the address specified ** an IGNORE exception. In this case jump to the address specified
** as the p2 of the calling OP_Program. */ ** as the p2 of the calling OP_Program. */
pc = p->aOp[pc].p2-1; pcx = p->aOp[pcx].p2-1;
} }
aOp = p->aOp; aOp = p->aOp;
aMem = p->aMem; aMem = p->aMem;
pOp = &aOp[pcx];
break; break;
} }
p->rc = pOp->p1; p->rc = pOp->p1;
p->errorAction = (u8)pOp->p2; p->errorAction = (u8)pOp->p2;
p->pc = pc; p->pc = pcx;
if( p->rc ){ if( p->rc ){
if( pOp->p5 ){ if( pOp->p5 ){
static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK", static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
@@ -960,7 +968,7 @@ case OP_Halt: {
}else{ }else{
sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType); sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType);
} }
sqlite3_log(pOp->p1, zLogFmt, pc, p->zSql, p->zErrMsg); sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg);
} }
rc = sqlite3VdbeHalt(p); rc = sqlite3VdbeHalt(p);
assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
@@ -971,6 +979,7 @@ case OP_Halt: {
assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 ); assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 );
rc = p->rc ? SQLITE_ERROR : SQLITE_DONE; rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
} }
pOp = &aOp[pcx];
goto vdbe_return; goto vdbe_return;
} }
@@ -979,7 +988,8 @@ case OP_Halt: {
** **
** The 32-bit integer value P1 is written into register P2. ** The 32-bit integer value P1 is written into register P2.
*/ */
case OP_Integer: { /* out2-prerelease */ case OP_Integer: { /* out2 */
pOut = out2Prerelease(p, pOp);
pOut->u.i = pOp->p1; pOut->u.i = pOp->p1;
break; break;
} }
@@ -990,7 +1000,8 @@ case OP_Integer: { /* out2-prerelease */
** P4 is a pointer to a 64-bit integer value. ** P4 is a pointer to a 64-bit integer value.
** Write that value into register P2. ** Write that value into register P2.
*/ */
case OP_Int64: { /* out2-prerelease */ case OP_Int64: { /* out2 */
pOut = out2Prerelease(p, pOp);
assert( pOp->p4.pI64!=0 ); assert( pOp->p4.pI64!=0 );
pOut->u.i = *pOp->p4.pI64; pOut->u.i = *pOp->p4.pI64;
break; break;
@@ -1003,7 +1014,8 @@ case OP_Int64: { /* out2-prerelease */
** P4 is a pointer to a 64-bit floating point value. ** P4 is a pointer to a 64-bit floating point value.
** Write that value into register P2. ** Write that value into register P2.
*/ */
case OP_Real: { /* same as TK_FLOAT, out2-prerelease */ case OP_Real: { /* same as TK_FLOAT, out2 */
pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Real; pOut->flags = MEM_Real;
assert( !sqlite3IsNaN(*pOp->p4.pReal) ); assert( !sqlite3IsNaN(*pOp->p4.pReal) );
pOut->u.r = *pOp->p4.pReal; pOut->u.r = *pOp->p4.pReal;
@@ -1019,8 +1031,9 @@ case OP_Real: { /* same as TK_FLOAT, out2-prerelease */
** this transformation, the length of string P4 is computed and stored ** this transformation, the length of string P4 is computed and stored
** as the P1 parameter. ** as the P1 parameter.
*/ */
case OP_String8: { /* same as TK_STRING, out2-prerelease */ case OP_String8: { /* same as TK_STRING, out2 */
assert( pOp->p4.z!=0 ); assert( pOp->p4.z!=0 );
pOut = out2Prerelease(p, pOp);
pOp->opcode = OP_String; pOp->opcode = OP_String;
pOp->p1 = sqlite3Strlen30(pOp->p4.z); pOp->p1 = sqlite3Strlen30(pOp->p4.z);
@@ -1057,8 +1070,9 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */
** the same sequence of bytes, it is merely interpreted as a BLOB instead ** the same sequence of bytes, it is merely interpreted as a BLOB instead
** of a string, as if it had been CAST. ** of a string, as if it had been CAST.
*/ */
case OP_String: { /* out2-prerelease */ case OP_String: { /* out2 */
assert( pOp->p4.z!=0 ); assert( pOp->p4.z!=0 );
pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Str|MEM_Static|MEM_Term; pOut->flags = MEM_Str|MEM_Static|MEM_Term;
pOut->z = pOp->p4.z; pOut->z = pOp->p4.z;
pOut->n = pOp->p1; pOut->n = pOp->p1;
@@ -1086,9 +1100,10 @@ case OP_String: { /* out2-prerelease */
** NULL values will not compare equal even if SQLITE_NULLEQ is set on ** NULL values will not compare equal even if SQLITE_NULLEQ is set on
** OP_Ne or OP_Eq. ** OP_Ne or OP_Eq.
*/ */
case OP_Null: { /* out2-prerelease */ case OP_Null: { /* out2 */
int cnt; int cnt;
u16 nullFlag; u16 nullFlag;
pOut = out2Prerelease(p, pOp);
cnt = pOp->p3-pOp->p2; cnt = pOp->p3-pOp->p2;
assert( pOp->p3<=(p->nMem-p->nCursor) ); assert( pOp->p3<=(p->nMem-p->nCursor) );
pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
@@ -1123,8 +1138,9 @@ case OP_SoftNull: {
** P4 points to a blob of data P1 bytes long. Store this ** P4 points to a blob of data P1 bytes long. Store this
** blob in register P2. ** blob in register P2.
*/ */
case OP_Blob: { /* out2-prerelease */ case OP_Blob: { /* out2 */
assert( pOp->p1 <= SQLITE_MAX_LENGTH ); assert( pOp->p1 <= SQLITE_MAX_LENGTH );
pOut = out2Prerelease(p, pOp);
sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
pOut->enc = encoding; pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut); UPDATE_MAX_BLOBSIZE(pOut);
@@ -1139,7 +1155,7 @@ case OP_Blob: { /* out2-prerelease */
** If the parameter is named, then its name appears in P4. ** If the parameter is named, then its name appears in P4.
** The P4 value is used by sqlite3_bind_parameter_name(). ** The P4 value is used by sqlite3_bind_parameter_name().
*/ */
case OP_Variable: { /* out2-prerelease */ case OP_Variable: { /* out2 */
Mem *pVar; /* Value being transferred */ Mem *pVar; /* Value being transferred */
assert( pOp->p1>0 && pOp->p1<=p->nVar ); assert( pOp->p1>0 && pOp->p1<=p->nVar );
@@ -1148,6 +1164,7 @@ case OP_Variable: { /* out2-prerelease */
if( sqlite3VdbeMemTooBig(pVar) ){ if( sqlite3VdbeMemTooBig(pVar) ){
goto too_big; goto too_big;
} }
pOut = out2Prerelease(p, pOp);
sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static); sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut); UPDATE_MAX_BLOBSIZE(pOut);
break; break;
@@ -1324,7 +1341,7 @@ case OP_ResultRow: {
/* Return SQLITE_ROW /* Return SQLITE_ROW
*/ */
p->pc = pc + 1; p->pc = (int)(pOp - aOp) + 1;
rc = SQLITE_ROW; rc = SQLITE_ROW;
goto vdbe_return; goto vdbe_return;
} }
@@ -1570,7 +1587,7 @@ case OP_Function: {
assert( pOp->p4type==P4_FUNCDEF ); assert( pOp->p4type==P4_FUNCDEF );
ctx.pFunc = pOp->p4.pFunc; ctx.pFunc = pOp->p4.pFunc;
ctx.iOp = pc; ctx.iOp = (int)(pOp - aOp);
ctx.pVdbe = p; ctx.pVdbe = p;
MemSetTypeFlag(ctx.pOut, MEM_Null); MemSetTypeFlag(ctx.pOut, MEM_Null);
ctx.fErrorOrAux = 0; ctx.fErrorOrAux = 0;
@@ -1584,7 +1601,7 @@ case OP_Function: {
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut)); sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
rc = ctx.isError; rc = ctx.isError;
} }
sqlite3VdbeDeleteAuxData(p, pc, pOp->p1); sqlite3VdbeDeleteAuxData(p, (int)(pOp - aOp), pOp->p1);
} }
/* Copy the result of the function into register P3 */ /* Copy the result of the function into register P3 */
@@ -1713,8 +1730,7 @@ case OP_MustBeInt: { /* jump, in1 */
rc = SQLITE_MISMATCH; rc = SQLITE_MISMATCH;
goto abort_due_to_error; goto abort_due_to_error;
}else{ }else{
pc = pOp->p2 - 1; goto jump_to_p2;
break;
} }
} }
} }
@@ -1900,7 +1916,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
}else{ }else{
VdbeBranchTaken(2,3); VdbeBranchTaken(2,3);
if( pOp->p5 & SQLITE_JUMPIFNULL ){ if( pOp->p5 & SQLITE_JUMPIFNULL ){
pc = pOp->p2-1; goto jump_to_p2;
} }
} }
break; break;
@@ -1952,6 +1968,12 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
default: res = res>=0; break; default: res = res>=0; break;
} }
/* Undo any changes made by applyAffinity() to the input registers. */
assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
pIn1->flags = flags1;
assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) );
pIn3->flags = flags3;
if( pOp->p5 & SQLITE_STOREP2 ){ if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2]; pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut); memAboutToChange(p, pOut);
@@ -1961,14 +1983,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
}else{ }else{
VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3); VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
if( res ){ if( res ){
pc = pOp->p2-1; goto jump_to_p2;
} }
} }
/* Undo any changes made by applyAffinity() to the input registers. */
assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
pIn1->flags = flags1;
assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) );
pIn3->flags = flags3;
break; break;
} }
@@ -2063,11 +2080,11 @@ case OP_Compare: {
*/ */
case OP_Jump: { /* jump */ case OP_Jump: { /* jump */
if( iCompare<0 ){ if( iCompare<0 ){
pc = pOp->p1 - 1; VdbeBranchTaken(0,3); VdbeBranchTaken(0,3); pOp = &aOp[pOp->p1 - 1];
}else if( iCompare==0 ){ }else if( iCompare==0 ){
pc = pOp->p2 - 1; VdbeBranchTaken(1,3); VdbeBranchTaken(1,3); pOp = &aOp[pOp->p2 - 1];
}else{ }else{
pc = pOp->p3 - 1; VdbeBranchTaken(2,3); VdbeBranchTaken(2,3); pOp = &aOp[pOp->p3 - 1];
} }
break; break;
} }
@@ -2177,7 +2194,7 @@ case OP_Once: { /* jump */
assert( pOp->p1<p->nOnceFlag ); assert( pOp->p1<p->nOnceFlag );
VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2); VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2);
if( p->aOnceFlag[pOp->p1] ){ if( p->aOnceFlag[pOp->p1] ){
pc = pOp->p2-1; goto jump_to_p2;
}else{ }else{
p->aOnceFlag[pOp->p1] = 1; p->aOnceFlag[pOp->p1] = 1;
} }
@@ -2212,7 +2229,7 @@ case OP_IfNot: { /* jump, in1 */
} }
VdbeBranchTaken(c!=0, 2); VdbeBranchTaken(c!=0, 2);
if( c ){ if( c ){
pc = pOp->p2-1; goto jump_to_p2;
} }
break; break;
} }
@@ -2226,7 +2243,7 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
pIn1 = &aMem[pOp->p1]; pIn1 = &aMem[pOp->p1];
VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2); VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2);
if( (pIn1->flags & MEM_Null)!=0 ){ if( (pIn1->flags & MEM_Null)!=0 ){
pc = pOp->p2 - 1; goto jump_to_p2;
} }
break; break;
} }
@@ -2240,7 +2257,7 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
pIn1 = &aMem[pOp->p1]; pIn1 = &aMem[pOp->p1];
VdbeBranchTaken( (pIn1->flags & MEM_Null)==0, 2); VdbeBranchTaken( (pIn1->flags & MEM_Null)==0, 2);
if( (pIn1->flags & MEM_Null)==0 ){ if( (pIn1->flags & MEM_Null)==0 ){
pc = pOp->p2 - 1; goto jump_to_p2;
} }
break; break;
} }
@@ -2578,7 +2595,7 @@ case OP_MakeRecord: {
u64 nData; /* Number of bytes of data space */ u64 nData; /* Number of bytes of data space */
int nHdr; /* Number of bytes of header space */ int nHdr; /* Number of bytes of header space */
i64 nByte; /* Data space required for this record */ i64 nByte; /* Data space required for this record */
int nZero; /* Number of zero bytes at the end of the record */ i64 nZero; /* Number of zero bytes at the end of the record */
int nVarint; /* Number of bytes in a varint */ int nVarint; /* Number of bytes in a varint */
u32 serial_type; /* Type field */ u32 serial_type; /* Type field */
Mem *pData0; /* First field to be combined into the record */ Mem *pData0; /* First field to be combined into the record */
@@ -2670,7 +2687,7 @@ case OP_MakeRecord: {
if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++; if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
} }
nByte = nHdr+nData; nByte = nHdr+nData;
if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big; goto too_big;
} }
@@ -2721,7 +2738,7 @@ case OP_MakeRecord: {
** opened by cursor P1 in register P2 ** opened by cursor P1 in register P2
*/ */
#ifndef SQLITE_OMIT_BTREECOUNT #ifndef SQLITE_OMIT_BTREECOUNT
case OP_Count: { /* out2-prerelease */ case OP_Count: { /* out2 */
i64 nEntry; i64 nEntry;
BtCursor *pCrsr; BtCursor *pCrsr;
@@ -2729,6 +2746,7 @@ case OP_Count: { /* out2-prerelease */
assert( pCrsr ); assert( pCrsr );
nEntry = 0; /* Not needed. Only used to silence a warning. */ nEntry = 0; /* Not needed. Only used to silence a warning. */
rc = sqlite3BtreeCount(pCrsr, &nEntry); rc = sqlite3BtreeCount(pCrsr, &nEntry);
pOut = out2Prerelease(p, pOp);
pOut->u.i = nEntry; pOut->u.i = nEntry;
break; break;
} }
@@ -2842,7 +2860,7 @@ case OP_Savepoint: {
} }
db->autoCommit = 1; db->autoCommit = 1;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
p->pc = pc; p->pc = (int)(pOp - aOp);
db->autoCommit = 0; db->autoCommit = 0;
p->rc = rc = SQLITE_BUSY; p->rc = rc = SQLITE_BUSY;
goto vdbe_return; goto vdbe_return;
@@ -2961,7 +2979,7 @@ case OP_AutoCommit: {
}else{ }else{
db->autoCommit = (u8)desiredAutoCommit; db->autoCommit = (u8)desiredAutoCommit;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
p->pc = pc; p->pc = (int)(pOp - aOp);
db->autoCommit = (u8)(1-desiredAutoCommit); db->autoCommit = (u8)(1-desiredAutoCommit);
p->rc = rc = SQLITE_BUSY; p->rc = rc = SQLITE_BUSY;
goto vdbe_return; goto vdbe_return;
@@ -3038,7 +3056,7 @@ case OP_Transaction: {
if( pBt ){ if( pBt ){
rc = sqlite3BtreeBeginTrans(pBt, pOp->p2); rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
if( rc==SQLITE_BUSY ){ if( rc==SQLITE_BUSY ){
p->pc = pc; p->pc = (int)(pOp - aOp);
p->rc = rc = SQLITE_BUSY; p->rc = rc = SQLITE_BUSY;
goto vdbe_return; goto vdbe_return;
} }
@@ -3117,7 +3135,7 @@ case OP_Transaction: {
** must be started or there must be an open cursor) before ** must be started or there must be an open cursor) before
** executing this instruction. ** executing this instruction.
*/ */
case OP_ReadCookie: { /* out2-prerelease */ case OP_ReadCookie: { /* out2 */
int iMeta; int iMeta;
int iDb; int iDb;
int iCookie; int iCookie;
@@ -3131,6 +3149,7 @@ case OP_ReadCookie: { /* out2-prerelease */
assert( DbMaskTest(p->btreeMask, iDb) ); assert( DbMaskTest(p->btreeMask, iDb) );
sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
pOut = out2Prerelease(p, pOp);
pOut->u.i = iMeta; pOut->u.i = iMeta;
break; break;
} }
@@ -3452,7 +3471,7 @@ case OP_SequenceTest: {
pC = p->apCsr[pOp->p1]; pC = p->apCsr[pOp->p1];
assert( pC->pSorter ); assert( pC->pSorter );
if( (pC->seqCount++)==0 ){ if( (pC->seqCount++)==0 ){
pc = pOp->p2 - 1; goto jump_to_p2;
} }
break; break;
} }
@@ -3629,7 +3648,7 @@ case OP_SeekGT: { /* jump, in3 */
if( (pIn3->flags & MEM_Real)==0 ){ if( (pIn3->flags & MEM_Real)==0 ){
/* If the P3 value cannot be converted into any kind of a number, /* If the P3 value cannot be converted into any kind of a number,
** then the seek is not possible, so jump to P2 */ ** then the seek is not possible, so jump to P2 */
pc = pOp->p2 - 1; VdbeBranchTaken(1,2); VdbeBranchTaken(1,2); goto jump_to_p2;
break; break;
} }
@@ -3720,7 +3739,7 @@ case OP_SeekGT: { /* jump, in3 */
assert( pOp->p2>0 ); assert( pOp->p2>0 );
VdbeBranchTaken(res!=0,2); VdbeBranchTaken(res!=0,2);
if( res ){ if( res ){
pc = pOp->p2 - 1; goto jump_to_p2;
} }
break; break;
} }
@@ -3814,6 +3833,7 @@ case OP_NoConflict: /* jump, in3 */
case OP_NotFound: /* jump, in3 */ case OP_NotFound: /* jump, in3 */
case OP_Found: { /* jump, in3 */ case OP_Found: { /* jump, in3 */
int alreadyExists; int alreadyExists;
int takeJump;
int ii; int ii;
VdbeCursor *pC; VdbeCursor *pC;
int res; int res;
@@ -3836,7 +3856,7 @@ case OP_Found: { /* jump, in3 */
pIn3 = &aMem[pOp->p3]; pIn3 = &aMem[pOp->p3];
assert( pC->pCursor!=0 ); assert( pC->pCursor!=0 );
assert( pC->isTable==0 ); assert( pC->isTable==0 );
pFree = 0; /* Not needed. Only used to suppress a compiler warning. */ pFree = 0;
if( pOp->p4.i>0 ){ if( pOp->p4.i>0 ){
r.pKeyInfo = pC->pKeyInfo; r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp->p4.i; r.nField = (u16)pOp->p4.i;
@@ -3859,21 +3879,20 @@ case OP_Found: { /* jump, in3 */
sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey); sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
} }
pIdxKey->default_rc = 0; pIdxKey->default_rc = 0;
takeJump = 0;
if( pOp->opcode==OP_NoConflict ){ if( pOp->opcode==OP_NoConflict ){
/* For the OP_NoConflict opcode, take the jump if any of the /* For the OP_NoConflict opcode, take the jump if any of the
** input fields are NULL, since any key with a NULL will not ** input fields are NULL, since any key with a NULL will not
** conflict */ ** conflict */
for(ii=0; ii<pIdxKey->nField; ii++){ for(ii=0; ii<pIdxKey->nField; ii++){
if( pIdxKey->aMem[ii].flags & MEM_Null ){ if( pIdxKey->aMem[ii].flags & MEM_Null ){
pc = pOp->p2 - 1; VdbeBranchTaken(1,2); takeJump = 1;
break; break;
} }
} }
} }
rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res); rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res);
if( pOp->p4.i==0 ){ sqlite3DbFree(db, pFree);
sqlite3DbFree(db, pFree);
}
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
break; break;
} }
@@ -3884,10 +3903,10 @@ case OP_Found: { /* jump, in3 */
pC->cacheStatus = CACHE_STALE; pC->cacheStatus = CACHE_STALE;
if( pOp->opcode==OP_Found ){ if( pOp->opcode==OP_Found ){
VdbeBranchTaken(alreadyExists!=0,2); VdbeBranchTaken(alreadyExists!=0,2);
if( alreadyExists ) pc = pOp->p2 - 1; if( alreadyExists ) goto jump_to_p2;
}else{ }else{
VdbeBranchTaken(alreadyExists==0,2); VdbeBranchTaken(takeJump||alreadyExists==0,2);
if( !alreadyExists ) pc = pOp->p2 - 1; if( takeJump || !alreadyExists ) goto jump_to_p2;
} }
break; break;
} }
@@ -3936,10 +3955,8 @@ case OP_NotExists: { /* jump, in3 */
pC->cacheStatus = CACHE_STALE; pC->cacheStatus = CACHE_STALE;
pC->deferredMoveto = 0; pC->deferredMoveto = 0;
VdbeBranchTaken(res!=0,2); VdbeBranchTaken(res!=0,2);
if( res!=0 ){
pc = pOp->p2 - 1;
}
pC->seekResult = res; pC->seekResult = res;
if( res!=0 ) goto jump_to_p2;
break; break;
} }
@@ -3951,9 +3968,10 @@ case OP_NotExists: { /* jump, in3 */
** The sequence number on the cursor is incremented after this ** The sequence number on the cursor is incremented after this
** instruction. ** instruction.
*/ */
case OP_Sequence: { /* out2-prerelease */ case OP_Sequence: { /* out2 */
assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( p->apCsr[pOp->p1]!=0 ); assert( p->apCsr[pOp->p1]!=0 );
pOut = out2Prerelease(p, pOp);
pOut->u.i = p->apCsr[pOp->p1]->seqCount++; pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
break; break;
} }
@@ -3974,7 +3992,7 @@ case OP_Sequence: { /* out2-prerelease */
** generated record number. This P3 mechanism is used to help implement the ** generated record number. This P3 mechanism is used to help implement the
** AUTOINCREMENT feature. ** AUTOINCREMENT feature.
*/ */
case OP_NewRowid: { /* out2-prerelease */ case OP_NewRowid: { /* out2 */
i64 v; /* The new rowid */ i64 v; /* The new rowid */
VdbeCursor *pC; /* Cursor of table to get the new rowid */ VdbeCursor *pC; /* Cursor of table to get the new rowid */
int res; /* Result of an sqlite3BtreeLast() */ int res; /* Result of an sqlite3BtreeLast() */
@@ -3984,6 +4002,7 @@ case OP_NewRowid: { /* out2-prerelease */
v = 0; v = 0;
res = 0; res = 0;
pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1]; pC = p->apCsr[pOp->p1];
assert( pC!=0 ); assert( pC!=0 );
@@ -4297,9 +4316,7 @@ case OP_SorterCompare: {
res = 0; res = 0;
rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res); rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res);
VdbeBranchTaken(res!=0,2); VdbeBranchTaken(res!=0,2);
if( res ){ if( res ) goto jump_to_p2;
pc = pOp->p2-1;
}
break; break;
}; };
@@ -4428,12 +4445,13 @@ case OP_RowData: {
** be a separate OP_VRowid opcode for use with virtual tables, but this ** be a separate OP_VRowid opcode for use with virtual tables, but this
** one opcode now works for both table types. ** one opcode now works for both table types.
*/ */
case OP_Rowid: { /* out2-prerelease */ case OP_Rowid: { /* out2 */
VdbeCursor *pC; VdbeCursor *pC;
i64 v; i64 v;
sqlite3_vtab *pVtab; sqlite3_vtab *pVtab;
const sqlite3_module *pModule; const sqlite3_module *pModule;
pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1]; pC = p->apCsr[pOp->p1];
assert( pC!=0 ); assert( pC!=0 );
@@ -4486,7 +4504,7 @@ case OP_NullRow: {
break; break;
} }
/* Opcode: Last P1 P2 * * * /* Opcode: Last P1 P2 P3 * *
** **
** The next use of the Rowid or Column or Prev instruction for P1 ** The next use of the Rowid or Column or Prev instruction for P1
** will refer to the last entry in the database table or index. ** will refer to the last entry in the database table or index.
@@ -4513,12 +4531,13 @@ case OP_Last: { /* jump */
pC->nullRow = (u8)res; pC->nullRow = (u8)res;
pC->deferredMoveto = 0; pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE; pC->cacheStatus = CACHE_STALE;
pC->seekResult = pOp->p3;
#ifdef SQLITE_DEBUG #ifdef SQLITE_DEBUG
pC->seekOp = OP_Last; pC->seekOp = OP_Last;
#endif #endif
if( pOp->p2>0 ){ if( pOp->p2>0 ){
VdbeBranchTaken(res!=0,2); VdbeBranchTaken(res!=0,2);
if( res ) pc = pOp->p2 - 1; if( res ) goto jump_to_p2;
} }
break; break;
} }
@@ -4582,9 +4601,7 @@ case OP_Rewind: { /* jump */
pC->nullRow = (u8)res; pC->nullRow = (u8)res;
assert( pOp->p2>0 && pOp->p2<p->nOp ); assert( pOp->p2>0 && pOp->p2<p->nOp );
VdbeBranchTaken(res!=0,2); VdbeBranchTaken(res!=0,2);
if( res ){ if( res ) goto jump_to_p2;
pc = pOp->p2 - 1;
}
break; break;
} }
@@ -4695,11 +4712,11 @@ next_tail:
VdbeBranchTaken(res==0,2); VdbeBranchTaken(res==0,2);
if( res==0 ){ if( res==0 ){
pC->nullRow = 0; pC->nullRow = 0;
pc = pOp->p2 - 1;
p->aCounter[pOp->p5]++; p->aCounter[pOp->p5]++;
#ifdef SQLITE_TEST #ifdef SQLITE_TEST
sqlite3_search_count++; sqlite3_search_count++;
#endif #endif
goto jump_to_p2_and_check_for_interrupt;
}else{ }else{
pC->nullRow = 1; pC->nullRow = 1;
} }
@@ -4807,11 +4824,12 @@ case OP_IdxDelete: {
** **
** See also: Rowid, MakeRecord. ** See also: Rowid, MakeRecord.
*/ */
case OP_IdxRowid: { /* out2-prerelease */ case OP_IdxRowid: { /* out2 */
BtCursor *pCrsr; BtCursor *pCrsr;
VdbeCursor *pC; VdbeCursor *pC;
i64 rowid; i64 rowid;
pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1]; pC = p->apCsr[pOp->p1];
assert( pC!=0 ); assert( pC!=0 );
@@ -4924,9 +4942,7 @@ case OP_IdxGE: { /* jump */
res++; res++;
} }
VdbeBranchTaken(res>0,2); VdbeBranchTaken(res>0,2);
if( res>0 ){ if( res>0 ) goto jump_to_p2;
pc = pOp->p2 - 1 ;
}
break; break;
} }
@@ -4950,11 +4966,12 @@ case OP_IdxGE: { /* jump */
** **
** See also: Clear ** See also: Clear
*/ */
case OP_Destroy: { /* out2-prerelease */ case OP_Destroy: { /* out2 */
int iMoved; int iMoved;
int iDb; int iDb;
assert( p->readOnly==0 ); assert( p->readOnly==0 );
pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Null; pOut->flags = MEM_Null;
if( db->nVdbeRead > db->nVDestroy+1 ){ if( db->nVdbeRead > db->nVDestroy+1 ){
rc = SQLITE_LOCKED; rc = SQLITE_LOCKED;
@@ -5063,12 +5080,13 @@ case OP_ResetSorter: {
** **
** See documentation on OP_CreateTable for additional information. ** See documentation on OP_CreateTable for additional information.
*/ */
case OP_CreateIndex: /* out2-prerelease */ case OP_CreateIndex: /* out2 */
case OP_CreateTable: { /* out2-prerelease */ case OP_CreateTable: { /* out2 */
int pgno; int pgno;
int flags; int flags;
Db *pDb; Db *pDb;
pOut = out2Prerelease(p, pOp);
pgno = 0; pgno = 0;
assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p1) ); assert( DbMaskTest(p->btreeMask, pOp->p1) );
@@ -5294,12 +5312,12 @@ case OP_RowSetRead: { /* jump, in1, out3 */
){ ){
/* The boolean index is empty */ /* The boolean index is empty */
sqlite3VdbeMemSetNull(pIn1); sqlite3VdbeMemSetNull(pIn1);
pc = pOp->p2 - 1;
VdbeBranchTaken(1,2); VdbeBranchTaken(1,2);
goto jump_to_p2_and_check_for_interrupt;
}else{ }else{
/* A value was pulled from the index */ /* A value was pulled from the index */
sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
VdbeBranchTaken(0,2); VdbeBranchTaken(0,2);
sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
} }
goto check_for_interrupt; goto check_for_interrupt;
} }
@@ -5350,10 +5368,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */
if( iSet ){ if( iSet ){
exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i); exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i);
VdbeBranchTaken(exists!=0,2); VdbeBranchTaken(exists!=0,2);
if( exists ){ if( exists ) goto jump_to_p2;
pc = pOp->p2 - 1;
break;
}
} }
if( iSet>=0 ){ if( iSet>=0 ){
sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
@@ -5442,7 +5457,7 @@ case OP_Program: { /* jump */
pFrame->v = p; pFrame->v = p;
pFrame->nChildMem = nMem; pFrame->nChildMem = nMem;
pFrame->nChildCsr = pProgram->nCsr; pFrame->nChildCsr = pProgram->nCsr;
pFrame->pc = pc; pFrame->pc = (int)(pOp - aOp);
pFrame->aMem = p->aMem; pFrame->aMem = p->aMem;
pFrame->nMem = p->nMem; pFrame->nMem = p->nMem;
pFrame->apCsr = p->apCsr; pFrame->apCsr = p->apCsr;
@@ -5465,7 +5480,7 @@ case OP_Program: { /* jump */
pFrame = pRt->u.pFrame; pFrame = pRt->u.pFrame;
assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem ); assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
assert( pProgram->nCsr==pFrame->nChildCsr ); assert( pProgram->nCsr==pFrame->nChildCsr );
assert( pc==pFrame->pc ); assert( (int)(pOp - aOp)==pFrame->pc );
} }
p->nFrame++; p->nFrame++;
@@ -5486,7 +5501,7 @@ case OP_Program: { /* jump */
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
p->anExec = 0; p->anExec = 0;
#endif #endif
pc = -1; pOp = &aOp[-1];
memset(p->aOnceFlag, 0, p->nOnceFlag); memset(p->aOnceFlag, 0, p->nOnceFlag);
break; break;
@@ -5504,9 +5519,10 @@ case OP_Program: { /* jump */
** the value of the P1 argument to the value of the P1 argument to the ** the value of the P1 argument to the value of the P1 argument to the
** calling OP_Program instruction. ** calling OP_Program instruction.
*/ */
case OP_Param: { /* out2-prerelease */ case OP_Param: { /* out2 */
VdbeFrame *pFrame; VdbeFrame *pFrame;
Mem *pIn; Mem *pIn;
pOut = out2Prerelease(p, pOp);
pFrame = p->pFrame; pFrame = p->pFrame;
pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1]; pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1];
sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem); sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem);
@@ -5550,10 +5566,10 @@ case OP_FkCounter: {
case OP_FkIfZero: { /* jump */ case OP_FkIfZero: { /* jump */
if( pOp->p1 ){ if( pOp->p1 ){
VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2); VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2);
if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1; if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) goto jump_to_p2;
}else{ }else{
VdbeBranchTaken(p->nFkConstraint==0 && db->nDeferredImmCons==0, 2); VdbeBranchTaken(p->nFkConstraint==0 && db->nDeferredImmCons==0, 2);
if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1; if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) goto jump_to_p2;
} }
break; break;
} }
@@ -5604,9 +5620,7 @@ case OP_IfPos: { /* jump, in1 */
pIn1 = &aMem[pOp->p1]; pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int ); assert( pIn1->flags&MEM_Int );
VdbeBranchTaken( pIn1->u.i>0, 2); VdbeBranchTaken( pIn1->u.i>0, 2);
if( pIn1->u.i>0 ){ if( pIn1->u.i>0 ) goto jump_to_p2;
pc = pOp->p2 - 1;
}
break; break;
} }
@@ -5621,9 +5635,7 @@ case OP_IfNeg: { /* jump, in1 */
assert( pIn1->flags&MEM_Int ); assert( pIn1->flags&MEM_Int );
pIn1->u.i += pOp->p3; pIn1->u.i += pOp->p3;
VdbeBranchTaken(pIn1->u.i<0, 2); VdbeBranchTaken(pIn1->u.i<0, 2);
if( pIn1->u.i<0 ){ if( pIn1->u.i<0 ) goto jump_to_p2;
pc = pOp->p2 - 1;
}
break; break;
} }
@@ -5640,7 +5652,7 @@ case OP_IfNotZero: { /* jump, in1 */
VdbeBranchTaken(pIn1->u.i<0, 2); VdbeBranchTaken(pIn1->u.i<0, 2);
if( pIn1->u.i ){ if( pIn1->u.i ){
pIn1->u.i += pOp->p3; pIn1->u.i += pOp->p3;
pc = pOp->p2 - 1; goto jump_to_p2;
} }
break; break;
} }
@@ -5656,9 +5668,7 @@ case OP_DecrJumpZero: { /* jump, in1 */
assert( pIn1->flags&MEM_Int ); assert( pIn1->flags&MEM_Int );
pIn1->u.i--; pIn1->u.i--;
VdbeBranchTaken(pIn1->u.i==0, 2); VdbeBranchTaken(pIn1->u.i==0, 2);
if( pIn1->u.i==0 ){ if( pIn1->u.i==0 ) goto jump_to_p2;
pc = pOp->p2 - 1;
}
break; break;
} }
@@ -5674,9 +5684,7 @@ case OP_JumpZeroIncr: { /* jump, in1 */
pIn1 = &aMem[pOp->p1]; pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int ); assert( pIn1->flags&MEM_Int );
VdbeBranchTaken(pIn1->u.i==0, 2); VdbeBranchTaken(pIn1->u.i==0, 2);
if( (pIn1->u.i++)==0 ){ if( (pIn1->u.i++)==0 ) goto jump_to_p2;
pc = pOp->p2 - 1;
}
break; break;
} }
@@ -5718,7 +5726,7 @@ case OP_AggStep: {
ctx.pOut = &t; ctx.pOut = &t;
ctx.isError = 0; ctx.isError = 0;
ctx.pVdbe = p; ctx.pVdbe = p;
ctx.iOp = pc; ctx.iOp = (int)(pOp - aOp);
ctx.skipFlag = 0; ctx.skipFlag = 0;
(ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */ (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
if( ctx.isError ){ if( ctx.isError ){
@@ -5813,7 +5821,7 @@ case OP_Checkpoint: {
** **
** Write a string containing the final journal-mode to register P2. ** Write a string containing the final journal-mode to register P2.
*/ */
case OP_JournalMode: { /* out2-prerelease */ case OP_JournalMode: { /* out2 */
Btree *pBt; /* Btree to change journal mode of */ Btree *pBt; /* Btree to change journal mode of */
Pager *pPager; /* Pager associated with pBt */ Pager *pPager; /* Pager associated with pBt */
int eNew; /* New journal mode */ int eNew; /* New journal mode */
@@ -5822,6 +5830,7 @@ case OP_JournalMode: { /* out2-prerelease */
const char *zFilename; /* Name of database file for pPager */ const char *zFilename; /* Name of database file for pPager */
#endif #endif
pOut = out2Prerelease(p, pOp);
eNew = pOp->p3; eNew = pOp->p3;
assert( eNew==PAGER_JOURNALMODE_DELETE assert( eNew==PAGER_JOURNALMODE_DELETE
|| eNew==PAGER_JOURNALMODE_TRUNCATE || eNew==PAGER_JOURNALMODE_TRUNCATE
@@ -5938,8 +5947,8 @@ case OP_IncrVacuum: { /* jump */
rc = sqlite3BtreeIncrVacuum(pBt); rc = sqlite3BtreeIncrVacuum(pBt);
VdbeBranchTaken(rc==SQLITE_DONE,2); VdbeBranchTaken(rc==SQLITE_DONE,2);
if( rc==SQLITE_DONE ){ if( rc==SQLITE_DONE ){
pc = pOp->p2 - 1;
rc = SQLITE_OK; rc = SQLITE_OK;
goto jump_to_p2;
} }
break; break;
} }
@@ -6149,25 +6158,19 @@ case OP_VFilter: { /* jump */
iQuery = (int)pQuery->u.i; iQuery = (int)pQuery->u.i;
/* Invoke the xFilter method */ /* Invoke the xFilter method */
{ res = 0;
res = 0; apArg = p->apArg;
apArg = p->apArg; for(i = 0; i<nArg; i++){
for(i = 0; i<nArg; i++){ apArg[i] = &pArgc[i+1];
apArg[i] = &pArgc[i+1]; }
} rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
sqlite3VtabImportErrmsg(p, pVtab);
rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg); if( rc==SQLITE_OK ){
sqlite3VtabImportErrmsg(p, pVtab); res = pModule->xEof(pVtabCursor);
if( rc==SQLITE_OK ){
res = pModule->xEof(pVtabCursor);
}
VdbeBranchTaken(res!=0,2);
if( res ){
pc = pOp->p2 - 1;
}
} }
pCur->nullRow = 0; pCur->nullRow = 0;
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
break; break;
} }
#endif /* SQLITE_OMIT_VIRTUALTABLE */ #endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -6254,7 +6257,7 @@ case OP_VNext: { /* jump */
VdbeBranchTaken(!res,2); VdbeBranchTaken(!res,2);
if( !res ){ if( !res ){
/* If there is data, jump to P2 */ /* If there is data, jump to P2 */
pc = pOp->p2 - 1; goto jump_to_p2_and_check_for_interrupt;
} }
goto check_for_interrupt; goto check_for_interrupt;
} }
@@ -6377,7 +6380,8 @@ case OP_VUpdate: {
** **
** Write the current number of pages in database P1 to memory cell P2. ** Write the current number of pages in database P1 to memory cell P2.
*/ */
case OP_Pagecount: { /* out2-prerelease */ case OP_Pagecount: { /* out2 */
pOut = out2Prerelease(p, pOp);
pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt); pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt);
break; break;
} }
@@ -6393,10 +6397,11 @@ case OP_Pagecount: { /* out2-prerelease */
** **
** Store the maximum page count after the change in register P2. ** Store the maximum page count after the change in register P2.
*/ */
case OP_MaxPgcnt: { /* out2-prerelease */ case OP_MaxPgcnt: { /* out2 */
unsigned int newMax; unsigned int newMax;
Btree *pBt; Btree *pBt;
pOut = out2Prerelease(p, pOp);
pBt = db->aDb[pOp->p1].pBt; pBt = db->aDb[pOp->p1].pBt;
newMax = 0; newMax = 0;
if( pOp->p3 ){ if( pOp->p3 ){
@@ -6425,9 +6430,6 @@ case OP_Init: { /* jump */
char *zTrace; char *zTrace;
char *z; char *z;
if( pOp->p2 ){
pc = pOp->p2 - 1;
}
#ifndef SQLITE_OMIT_TRACE #ifndef SQLITE_OMIT_TRACE
if( db->xTrace if( db->xTrace
&& !p->doingRerun && !p->doingRerun
@@ -6455,6 +6457,7 @@ case OP_Init: { /* jump */
} }
#endif /* SQLITE_DEBUG */ #endif /* SQLITE_DEBUG */
#endif /* SQLITE_OMIT_TRACE */ #endif /* SQLITE_OMIT_TRACE */
if( pOp->p2 ) goto jump_to_p2;
break; break;
} }
@@ -6497,12 +6500,12 @@ default: { /* This is really OP_Noop and OP_Explain */
** the evaluator loop. So we can leave it out when NDEBUG is defined. ** the evaluator loop. So we can leave it out when NDEBUG is defined.
*/ */
#ifndef NDEBUG #ifndef NDEBUG
assert( pc>=-1 && pc<p->nOp ); assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp] );
#ifdef SQLITE_DEBUG #ifdef SQLITE_DEBUG
if( db->flags & SQLITE_VdbeTrace ){ if( db->flags & SQLITE_VdbeTrace ){
if( rc!=0 ) printf("rc=%d\n",rc); if( rc!=0 ) printf("rc=%d\n",rc);
if( pOp->opflags & (OPFLG_OUT2_PRERELEASE|OPFLG_OUT2) ){ if( pOp->opflags & (OPFLG_OUT2) ){
registerTrace(pOp->p2, &aMem[pOp->p2]); registerTrace(pOp->p2, &aMem[pOp->p2]);
} }
if( pOp->opflags & OPFLG_OUT3 ){ if( pOp->opflags & OPFLG_OUT3 ){
@@ -6521,7 +6524,7 @@ vdbe_error_halt:
p->rc = rc; p->rc = rc;
testcase( sqlite3GlobalConfig.xLog!=0 ); testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(rc, "statement aborts at %d: [%s] %s", sqlite3_log(rc, "statement aborts at %d: [%s] %s",
pc, p->zSql, p->zErrMsg); (int)(pOp - aOp), p->zSql, p->zErrMsg);
sqlite3VdbeHalt(p); sqlite3VdbeHalt(p);
if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1; if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
rc = SQLITE_ERROR; rc = SQLITE_ERROR;

View File

@@ -213,6 +213,7 @@ int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int);
UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **); UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); typedef int (*RecordCompare)(int,const void*,UnpackedRecord*);

View File

@@ -3585,7 +3585,7 @@ static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){
** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the ** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the
** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db). ** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db).
*/ */
static int vdbeRecordCompareWithSkip( int sqlite3VdbeRecordCompareWithSkip(
int nKey1, const void *pKey1, /* Left key */ int nKey1, const void *pKey1, /* Left key */
UnpackedRecord *pPKey2, /* Right key */ UnpackedRecord *pPKey2, /* Right key */
int bSkip /* If true, skip the first field */ int bSkip /* If true, skip the first field */
@@ -3771,7 +3771,7 @@ int sqlite3VdbeRecordCompare(
int nKey1, const void *pKey1, /* Left key */ int nKey1, const void *pKey1, /* Left key */
UnpackedRecord *pPKey2 /* Right key */ UnpackedRecord *pPKey2 /* Right key */
){ ){
return vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0); return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0);
} }
@@ -3859,7 +3859,7 @@ static int vdbeRecordCompareInt(
}else if( pPKey2->nField>1 ){ }else if( pPKey2->nField>1 ){
/* The first fields of the two keys are equal. Compare the trailing /* The first fields of the two keys are equal. Compare the trailing
** fields. */ ** fields. */
res = vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
}else{ }else{
/* The first fields of the two keys are equal and there are no trailing /* The first fields of the two keys are equal and there are no trailing
** fields. Return pPKey2->default_rc in this case. */ ** fields. Return pPKey2->default_rc in this case. */
@@ -3907,7 +3907,7 @@ static int vdbeRecordCompareString(
res = nStr - pPKey2->aMem[0].n; res = nStr - pPKey2->aMem[0].n;
if( res==0 ){ if( res==0 ){
if( pPKey2->nField>1 ){ if( pPKey2->nField>1 ){
res = vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
}else{ }else{
res = pPKey2->default_rc; res = pPKey2->default_rc;
} }

View File

@@ -291,6 +291,7 @@ struct MergeEngine {
** after the thread has finished are not dire. So we don't worry about ** after the thread has finished are not dire. So we don't worry about
** memory barriers and such here. ** memory barriers and such here.
*/ */
typedef int (*SorterCompare)(SortSubtask*,int*,const void*,int,const void*,int);
struct SortSubtask { struct SortSubtask {
SQLiteThread *pThread; /* Background thread, if any */ SQLiteThread *pThread; /* Background thread, if any */
int bDone; /* Set if thread is finished but not joined */ int bDone; /* Set if thread is finished but not joined */
@@ -298,10 +299,12 @@ struct SortSubtask {
UnpackedRecord *pUnpacked; /* Space to unpack a record */ UnpackedRecord *pUnpacked; /* Space to unpack a record */
SorterList list; /* List for thread to write to a PMA */ SorterList list; /* List for thread to write to a PMA */
int nPMA; /* Number of PMAs currently in file */ int nPMA; /* Number of PMAs currently in file */
SorterCompare xCompare; /* Compare function to use */
SorterFile file; /* Temp file for level-0 PMAs */ SorterFile file; /* Temp file for level-0 PMAs */
SorterFile file2; /* Space for other PMAs */ SorterFile file2; /* Space for other PMAs */
}; };
/* /*
** Main sorter structure. A single instance of this is allocated for each ** Main sorter structure. A single instance of this is allocated for each
** sorter cursor created by the VDBE. ** sorter cursor created by the VDBE.
@@ -328,9 +331,13 @@ struct VdbeSorter {
u8 bUseThreads; /* True to use background threads */ u8 bUseThreads; /* True to use background threads */
u8 iPrev; /* Previous thread used to flush PMA */ u8 iPrev; /* Previous thread used to flush PMA */
u8 nTask; /* Size of aTask[] array */ u8 nTask; /* Size of aTask[] array */
u8 typeMask;
SortSubtask aTask[1]; /* One or more subtasks */ SortSubtask aTask[1]; /* One or more subtasks */
}; };
#define SORTER_TYPE_INTEGER 0x01
#define SORTER_TYPE_TEXT 0x02
/* /*
** An instance of the following object is used to read records out of a ** An instance of the following object is used to read records out of a
** PMA, in sorted order. The next key to be read is cached in nKey/aKey. ** PMA, in sorted order. The next key to be read is cached in nKey/aKey.
@@ -742,32 +749,162 @@ static int vdbePmaReaderInit(
return rc; return rc;
} }
/*
** A version of vdbeSorterCompare() that assumes that it has already been
** determined that the first field of key1 is equal to the first field of
** key2.
*/
static int vdbeSorterCompareTail(
SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2 /* Right side of comparison */
){
UnpackedRecord *r2 = pTask->pUnpacked;
if( *pbKey2Cached==0 ){
sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2);
*pbKey2Cached = 1;
}
return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1);
}
/* /*
** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2, ** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2,
** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences ** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences
** used by the comparison. Return the result of the comparison. ** used by the comparison. Return the result of the comparison.
** **
** Before returning, object (pTask->pUnpacked) is populated with the ** If IN/OUT parameter *pbKey2Cached is true when this function is called,
** unpacked version of key2. Or, if pKey2 is passed a NULL pointer, then it ** it is assumed that (pTask->pUnpacked) contains the unpacked version
** is assumed that the (pTask->pUnpacked) structure already contains the ** of key2. If it is false, (pTask->pUnpacked) is populated with the unpacked
** unpacked key to use as key2. ** version of key2 and *pbKey2Cached set to true before returning.
** **
** If an OOM error is encountered, (pTask->pUnpacked->error_rc) is set ** If an OOM error is encountered, (pTask->pUnpacked->error_rc) is set
** to SQLITE_NOMEM. ** to SQLITE_NOMEM.
*/ */
static int vdbeSorterCompare( static int vdbeSorterCompare(
SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
const void *pKey1, int nKey1, /* Left side of comparison */ const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2 /* Right side of comparison */ const void *pKey2, int nKey2 /* Right side of comparison */
){ ){
UnpackedRecord *r2 = pTask->pUnpacked; UnpackedRecord *r2 = pTask->pUnpacked;
if( pKey2 ){ if( !*pbKey2Cached ){
sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2);
*pbKey2Cached = 1;
} }
return sqlite3VdbeRecordCompare(nKey1, pKey1, r2); return sqlite3VdbeRecordCompare(nKey1, pKey1, r2);
} }
/*
** A specially optimized version of vdbeSorterCompare() that assumes that
** the first field of each key is a TEXT value and that the collation
** sequence to compare them with is BINARY.
*/
static int vdbeSorterCompareText(
SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2 /* Right side of comparison */
){
const u8 * const p1 = (const u8 * const)pKey1;
const u8 * const p2 = (const u8 * const)pKey2;
const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */
const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */
int n1;
int n2;
int res;
getVarint32(&p1[1], n1); n1 = (n1 - 13) / 2;
getVarint32(&p2[1], n2); n2 = (n2 - 13) / 2;
res = memcmp(v1, v2, MIN(n1, n2));
if( res==0 ){
res = n1 - n2;
}
if( res==0 ){
if( pTask->pSorter->pKeyInfo->nField>1 ){
res = vdbeSorterCompareTail(
pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
);
}
}else{
if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
res = res * -1;
}
}
return res;
}
/*
** A specially optimized version of vdbeSorterCompare() that assumes that
** the first field of each key is an INTEGER value.
*/
static int vdbeSorterCompareInt(
SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2 /* Right side of comparison */
){
const u8 * const p1 = (const u8 * const)pKey1;
const u8 * const p2 = (const u8 * const)pKey2;
const int s1 = p1[1]; /* Left hand serial type */
const int s2 = p2[1]; /* Right hand serial type */
const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */
const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */
int res; /* Return value */
assert( (s1>0 && s1<7) || s1==8 || s1==9 );
assert( (s2>0 && s2<7) || s2==8 || s2==9 );
if( s1>7 && s2>7 ){
res = s1 - s2;
}else{
if( s1==s2 ){
if( (*v1 ^ *v2) & 0x80 ){
/* The two values have different signs */
res = (*v1 & 0x80) ? -1 : +1;
}else{
/* The two values have the same sign. Compare using memcmp(). */
static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8 };
int i;
res = 0;
for(i=0; i<aLen[s1]; i++){
if( (res = v1[i] - v2[i]) ) break;
}
}
}else{
if( s2>7 ){
res = +1;
}else if( s1>7 ){
res = -1;
}else{
res = s1 - s2;
}
assert( res!=0 );
if( res>0 ){
if( *v1 & 0x80 ) res = -1;
}else{
if( *v2 & 0x80 ) res = +1;
}
}
}
if( res==0 ){
if( pTask->pSorter->pKeyInfo->nField>1 ){
res = vdbeSorterCompareTail(
pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
);
}
}else if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
res = res * -1;
}
return res;
}
/* /*
** Initialize the temporary index cursor just opened as a sorter cursor. ** Initialize the temporary index cursor just opened as a sorter cursor.
** **
@@ -835,9 +972,13 @@ int sqlite3VdbeSorterInit(
pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz); pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo); memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
pKeyInfo->db = 0; pKeyInfo->db = 0;
if( nField && nWorker==0 ) pKeyInfo->nField = nField; if( nField && nWorker==0 ){
pKeyInfo->nXField += (pKeyInfo->nField - nField);
pKeyInfo->nField = nField;
}
pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
pSorter->nTask = nWorker + 1; pSorter->nTask = nWorker + 1;
pSorter->iPrev = nWorker-1;
pSorter->bUseThreads = (pSorter->nTask>1); pSorter->bUseThreads = (pSorter->nTask>1);
pSorter->db = db; pSorter->db = db;
for(i=0; i<pSorter->nTask; i++){ for(i=0; i<pSorter->nTask; i++){
@@ -863,6 +1004,12 @@ int sqlite3VdbeSorterInit(
if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM; if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM;
} }
} }
if( (pKeyInfo->nField+pKeyInfo->nXField)<13
&& (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl)
){
pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT;
}
} }
return rc; return rc;
@@ -887,30 +1034,24 @@ static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){
*/ */
static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){ static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){
sqlite3DbFree(db, pTask->pUnpacked); sqlite3DbFree(db, pTask->pUnpacked);
pTask->pUnpacked = 0;
#if SQLITE_MAX_WORKER_THREADS>0 #if SQLITE_MAX_WORKER_THREADS>0
/* pTask->list.aMemory can only be non-zero if it was handed memory /* pTask->list.aMemory can only be non-zero if it was handed memory
** from the main thread. That only occurs SQLITE_MAX_WORKER_THREADS>0 */ ** from the main thread. That only occurs SQLITE_MAX_WORKER_THREADS>0 */
if( pTask->list.aMemory ){ if( pTask->list.aMemory ){
sqlite3_free(pTask->list.aMemory); sqlite3_free(pTask->list.aMemory);
pTask->list.aMemory = 0;
}else }else
#endif #endif
{ {
assert( pTask->list.aMemory==0 ); assert( pTask->list.aMemory==0 );
vdbeSorterRecordFree(0, pTask->list.pList); vdbeSorterRecordFree(0, pTask->list.pList);
} }
pTask->list.pList = 0;
if( pTask->file.pFd ){ if( pTask->file.pFd ){
sqlite3OsCloseFree(pTask->file.pFd); sqlite3OsCloseFree(pTask->file.pFd);
pTask->file.pFd = 0;
pTask->file.iEof = 0;
} }
if( pTask->file2.pFd ){ if( pTask->file2.pFd ){
sqlite3OsCloseFree(pTask->file2.pFd); sqlite3OsCloseFree(pTask->file2.pFd);
pTask->file2.pFd = 0;
pTask->file2.iEof = 0;
} }
memset(pTask, 0, sizeof(SortSubtask));
} }
#ifdef SQLITE_DEBUG_SORTER_THREADS #ifdef SQLITE_DEBUG_SORTER_THREADS
@@ -1090,6 +1231,7 @@ void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){
for(i=0; i<pSorter->nTask; i++){ for(i=0; i<pSorter->nTask; i++){
SortSubtask *pTask = &pSorter->aTask[i]; SortSubtask *pTask = &pSorter->aTask[i];
vdbeSortSubtaskCleanup(db, pTask); vdbeSortSubtaskCleanup(db, pTask);
pTask->pSorter = pSorter;
} }
if( pSorter->list.aMemory==0 ){ if( pSorter->list.aMemory==0 ){
vdbeSorterRecordFree(0, pSorter->list.pList); vdbeSorterRecordFree(0, pSorter->list.pList);
@@ -1199,28 +1341,42 @@ static void vdbeSorterMerge(
){ ){
SorterRecord *pFinal = 0; SorterRecord *pFinal = 0;
SorterRecord **pp = &pFinal; SorterRecord **pp = &pFinal;
void *pVal2 = p2 ? SRVAL(p2) : 0; int bCached = 0;
while( p1 && p2 ){ while( p1 && p2 ){
int res; int res;
res = vdbeSorterCompare(pTask, SRVAL(p1), p1->nVal, pVal2, p2->nVal); res = pTask->xCompare(
pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal
);
if( res<=0 ){ if( res<=0 ){
*pp = p1; *pp = p1;
pp = &p1->u.pNext; pp = &p1->u.pNext;
p1 = p1->u.pNext; p1 = p1->u.pNext;
pVal2 = 0;
}else{ }else{
*pp = p2; *pp = p2;
pp = &p2->u.pNext; pp = &p2->u.pNext;
p2 = p2->u.pNext; p2 = p2->u.pNext;
if( p2==0 ) break; bCached = 0;
pVal2 = SRVAL(p2);
} }
} }
*pp = p1 ? p1 : p2; *pp = p1 ? p1 : p2;
*ppOut = pFinal; *ppOut = pFinal;
} }
/*
** Return the SorterCompare function to compare values collected by the
** sorter object passed as the only argument.
*/
static SorterCompare vdbeSorterGetCompare(VdbeSorter *p){
if( p->typeMask==SORTER_TYPE_INTEGER ){
return vdbeSorterCompareInt;
}else if( p->typeMask==SORTER_TYPE_TEXT ){
return vdbeSorterCompareText;
}
return vdbeSorterCompare;
}
/* /*
** Sort the linked list of records headed at pTask->pList. Return ** Sort the linked list of records headed at pTask->pList. Return
** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if ** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if
@@ -1235,12 +1391,14 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
rc = vdbeSortAllocUnpacked(pTask); rc = vdbeSortAllocUnpacked(pTask);
if( rc!=SQLITE_OK ) return rc; if( rc!=SQLITE_OK ) return rc;
p = pList->pList;
pTask->xCompare = vdbeSorterGetCompare(pTask->pSorter);
aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *)); aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *));
if( !aSlot ){ if( !aSlot ){
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
p = pList->pList;
while( p ){ while( p ){
SorterRecord *pNext; SorterRecord *pNext;
if( pList->aMemory ){ if( pList->aMemory ){
@@ -1454,13 +1612,12 @@ static int vdbeMergeEngineStep(
int i; /* Index of aTree[] to recalculate */ int i; /* Index of aTree[] to recalculate */
PmaReader *pReadr1; /* First PmaReader to compare */ PmaReader *pReadr1; /* First PmaReader to compare */
PmaReader *pReadr2; /* Second PmaReader to compare */ PmaReader *pReadr2; /* Second PmaReader to compare */
u8 *pKey2; /* To pReadr2->aKey, or 0 if record cached */ int bCached = 0;
/* Find the first two PmaReaders to compare. The one that was just /* Find the first two PmaReaders to compare. The one that was just
** advanced (iPrev) and the one next to it in the array. */ ** advanced (iPrev) and the one next to it in the array. */
pReadr1 = &pMerger->aReadr[(iPrev & 0xFFFE)]; pReadr1 = &pMerger->aReadr[(iPrev & 0xFFFE)];
pReadr2 = &pMerger->aReadr[(iPrev | 0x0001)]; pReadr2 = &pMerger->aReadr[(iPrev | 0x0001)];
pKey2 = pReadr2->aKey;
for(i=(pMerger->nTree+iPrev)/2; i>0; i=i/2){ for(i=(pMerger->nTree+iPrev)/2; i>0; i=i/2){
/* Compare pReadr1 and pReadr2. Store the result in variable iRes. */ /* Compare pReadr1 and pReadr2. Store the result in variable iRes. */
@@ -1470,8 +1627,8 @@ static int vdbeMergeEngineStep(
}else if( pReadr2->pFd==0 ){ }else if( pReadr2->pFd==0 ){
iRes = -1; iRes = -1;
}else{ }else{
iRes = vdbeSorterCompare(pTask, iRes = pTask->xCompare(pTask, &bCached,
pReadr1->aKey, pReadr1->nKey, pKey2, pReadr2->nKey pReadr1->aKey, pReadr1->nKey, pReadr2->aKey, pReadr2->nKey
); );
} }
@@ -1493,9 +1650,9 @@ static int vdbeMergeEngineStep(
if( iRes<0 || (iRes==0 && pReadr1<pReadr2) ){ if( iRes<0 || (iRes==0 && pReadr1<pReadr2) ){
pMerger->aTree[i] = (int)(pReadr1 - pMerger->aReadr); pMerger->aTree[i] = (int)(pReadr1 - pMerger->aReadr);
pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ]; pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
pKey2 = pReadr2->aKey; bCached = 0;
}else{ }else{
if( pReadr1->pFd ) pKey2 = 0; if( pReadr1->pFd ) bCached = 0;
pMerger->aTree[i] = (int)(pReadr2 - pMerger->aReadr); pMerger->aTree[i] = (int)(pReadr2 - pMerger->aReadr);
pReadr1 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ]; pReadr1 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
} }
@@ -1602,6 +1759,16 @@ int sqlite3VdbeSorterWrite(
int bFlush; /* True to flush contents of memory to PMA */ int bFlush; /* True to flush contents of memory to PMA */
int nReq; /* Bytes of memory required */ int nReq; /* Bytes of memory required */
int nPMA; /* Bytes of PMA space required */ int nPMA; /* Bytes of PMA space required */
int t; /* serial type of first record field */
getVarint32((const u8*)&pVal->z[1], t);
if( t>0 && t<10 && t!=7 ){
pSorter->typeMask &= SORTER_TYPE_INTEGER;
}else if( t>10 && (t & 0x01) ){
pSorter->typeMask &= SORTER_TYPE_TEXT;
}else{
pSorter->typeMask = 0;
}
assert( pSorter ); assert( pSorter );
@@ -1867,10 +2034,12 @@ static void vdbeMergeEngineCompare(
}else if( p2->pFd==0 ){ }else if( p2->pFd==0 ){
iRes = i1; iRes = i1;
}else{ }else{
SortSubtask *pTask = pMerger->pTask;
int bCached = 0;
int res; int res;
assert( pMerger->pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */ assert( pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */
res = vdbeSorterCompare( res = pTask->xCompare(
pMerger->pTask, p1->aKey, p1->nKey, p2->aKey, p2->nKey pTask, &bCached, p1->aKey, p1->nKey, p2->aKey, p2->nKey
); );
if( res<=0 ){ if( res<=0 ){
iRes = i1; iRes = i1;
@@ -2288,6 +2457,11 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
MergeEngine *pMain = 0; MergeEngine *pMain = 0;
#if SQLITE_MAX_WORKER_THREADS #if SQLITE_MAX_WORKER_THREADS
sqlite3 *db = pTask0->pSorter->db; sqlite3 *db = pTask0->pSorter->db;
int i;
SorterCompare xCompare = vdbeSorterGetCompare(pSorter);
for(i=0; i<pSorter->nTask; i++){
pSorter->aTask[i].xCompare = xCompare;
}
#endif #endif
rc = vdbeSorterMergeTreeBuild(pSorter, &pMain); rc = vdbeSorterMergeTreeBuild(pSorter, &pMain);

View File

@@ -24,6 +24,8 @@
struct VtabCtx { struct VtabCtx {
VTable *pVTable; /* The virtual table being constructed */ VTable *pVTable; /* The virtual table being constructed */
Table *pTab; /* The Table object to which the virtual table belongs */ Table *pTab; /* The Table object to which the virtual table belongs */
VtabCtx *pPrior; /* Parent context (if any) */
int bDeclared; /* True after sqlite3_declare_vtab() is called */
}; };
/* /*
@@ -487,15 +489,27 @@ static int vtabCallConstructor(
int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**), int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
char **pzErr char **pzErr
){ ){
VtabCtx sCtx, *pPriorCtx; VtabCtx sCtx;
VTable *pVTable; VTable *pVTable;
int rc; int rc;
const char *const*azArg = (const char *const*)pTab->azModuleArg; const char *const*azArg = (const char *const*)pTab->azModuleArg;
int nArg = pTab->nModuleArg; int nArg = pTab->nModuleArg;
char *zErr = 0; char *zErr = 0;
char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName); char *zModuleName;
int iDb; int iDb;
VtabCtx *pCtx;
/* Check that the virtual-table is not already being initialized */
for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){
if( pCtx->pTab==pTab ){
*pzErr = sqlite3MPrintf(db,
"vtable constructor called recursively: %s", pTab->zName
);
return SQLITE_LOCKED;
}
}
zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
if( !zModuleName ){ if( !zModuleName ){
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
@@ -516,11 +530,13 @@ static int vtabCallConstructor(
assert( xConstruct ); assert( xConstruct );
sCtx.pTab = pTab; sCtx.pTab = pTab;
sCtx.pVTable = pVTable; sCtx.pVTable = pVTable;
pPriorCtx = db->pVtabCtx; sCtx.pPrior = db->pVtabCtx;
sCtx.bDeclared = 0;
db->pVtabCtx = &sCtx; db->pVtabCtx = &sCtx;
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
db->pVtabCtx = pPriorCtx; db->pVtabCtx = sCtx.pPrior;
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
assert( sCtx.pTab==pTab );
if( SQLITE_OK!=rc ){ if( SQLITE_OK!=rc ){
if( zErr==0 ){ if( zErr==0 ){
@@ -536,7 +552,7 @@ static int vtabCallConstructor(
memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0])); memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0]));
pVTable->pVtab->pModule = pMod->pModule; pVTable->pVtab->pModule = pMod->pModule;
pVTable->nRef = 1; pVTable->nRef = 1;
if( sCtx.pTab ){ if( sCtx.bDeclared==0 ){
const char *zFormat = "vtable constructor did not declare schema: %s"; const char *zFormat = "vtable constructor did not declare schema: %s";
*pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
sqlite3VtabUnlock(pVTable); sqlite3VtabUnlock(pVTable);
@@ -706,8 +722,8 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
** virtual table module. ** virtual table module.
*/ */
int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
VtabCtx *pCtx;
Parse *pParse; Parse *pParse;
int rc = SQLITE_OK; int rc = SQLITE_OK;
Table *pTab; Table *pTab;
char *zErr = 0; char *zErr = 0;
@@ -718,11 +734,13 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
} }
#endif #endif
sqlite3_mutex_enter(db->mutex); sqlite3_mutex_enter(db->mutex);
if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){ pCtx = db->pVtabCtx;
if( !pCtx || pCtx->bDeclared ){
sqlite3Error(db, SQLITE_MISUSE); sqlite3Error(db, SQLITE_MISUSE);
sqlite3_mutex_leave(db->mutex); sqlite3_mutex_leave(db->mutex);
return SQLITE_MISUSE_BKPT; return SQLITE_MISUSE_BKPT;
} }
pTab = pCtx->pTab;
assert( (pTab->tabFlags & TF_Virtual)!=0 ); assert( (pTab->tabFlags & TF_Virtual)!=0 );
pParse = sqlite3StackAllocZero(db, sizeof(*pParse)); pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
@@ -745,7 +763,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
pParse->pNewTable->nCol = 0; pParse->pNewTable->nCol = 0;
pParse->pNewTable->aCol = 0; pParse->pNewTable->aCol = 0;
} }
db->pVtabCtx->pTab = 0; pCtx->bDeclared = 1;
}else{ }else{
sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr); sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
sqlite3DbFree(db, zErr); sqlite3DbFree(db, zErr);

View File

@@ -1730,6 +1730,14 @@ static int walCheckpoint(
mxSafeFrame = pWal->hdr.mxFrame; mxSafeFrame = pWal->hdr.mxFrame;
mxPage = pWal->hdr.nPage; mxPage = pWal->hdr.nPage;
for(i=1; i<WAL_NREADER; i++){ for(i=1; i<WAL_NREADER; i++){
/* Thread-sanitizer reports that the following is an unsafe read,
** as some other thread may be in the process of updating the value
** of the aReadMark[] slot. The assumption here is that if that is
** happening, the other client may only be increasing the value,
** not decreasing it. So assuming either that either the "old" or
** "new" version of the value is read, and not some arbitrary value
** that would never be written by a real client, things are still
** safe. */
u32 y = pInfo->aReadMark[i]; u32 y = pInfo->aReadMark[i];
if( mxSafeFrame>y ){ if( mxSafeFrame>y ){
assert( y<=pWal->hdr.mxFrame ); assert( y<=pWal->hdr.mxFrame );

View File

@@ -1534,7 +1534,7 @@ static int findIndexCol(
&& p->iTable==iBase && p->iTable==iBase
){ ){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr); CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){ if( pColl && 0==sqlite3StrICmp(pColl->zName, zColl) ){
return i; return i;
} }
} }
@@ -1808,7 +1808,7 @@ static void constructAutomaticIndex(
idxCols |= cMask; idxCols |= cMask;
pIdx->aiColumn[n] = pTerm->u.leftColumn; pIdx->aiColumn[n] = pTerm->u.leftColumn;
pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
pIdx->azColl[n] = ALWAYS(pColl) ? pColl->zName : "BINARY"; pIdx->azColl[n] = pColl ? pColl->zName : "BINARY";
n++; n++;
} }
} }
@@ -4786,7 +4786,7 @@ static int whereLoopAddBtreeIndex(
}else if( eOp & (WO_EQ) ){ }else if( eOp & (WO_EQ) ){
pNew->wsFlags |= WHERE_COLUMN_EQ; pNew->wsFlags |= WHERE_COLUMN_EQ;
if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){ if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){
if( iCol>=0 && !IsUniqueIndex(pProbe) ){ if( iCol>=0 && pProbe->uniqNotNull==0 ){
pNew->wsFlags |= WHERE_UNQ_WANTED; pNew->wsFlags |= WHERE_UNQ_WANTED;
}else{ }else{
pNew->wsFlags |= WHERE_ONEROW; pNew->wsFlags |= WHERE_ONEROW;
@@ -6245,7 +6245,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
pWInfo->revMask = pFrom->revLoop; pWInfo->revMask = pFrom->revLoop;
} }
if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP) if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
&& pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && nLoop>0
){ ){
Bitmask revMask = 0; Bitmask revMask = 0;
int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy,

View File

@@ -512,5 +512,12 @@ do_execsql_test autoindex1-901 {
WHERE t1.x IN (1,2,3); WHERE t1.x IN (1,2,3);
} {/USING AUTOMATIC COVERING INDEX/} } {/USING AUTOMATIC COVERING INDEX/}
# 2015-04-15: A NULL CollSeq pointer in automatic index creation.
#
do_execsql_test autoindex1-920 {
CREATE TABLE t920(x);
INSERT INTO t920 VALUES(3),(4),(5);
SELECT * FROM t920,(SELECT 0 FROM t920),(VALUES(9)) WHERE 5 IN (x);
} {5 0 9 5 0 9 5 0 9}
finish_test finish_test

View File

@@ -385,6 +385,20 @@ do_execsql_test 6.8 {
SELECT x, y FROM c1 ORDER BY y COLLATE """"""""; SELECT x, y FROM c1 ORDER BY y COLLATE """""""";
} {2 abb 1 ABC 4 WXY 3 wxz} } {2 abb 1 ABC 4 WXY 3 wxz}
# 2015-04-15: Nested COLLATE operators
#
do_execsql_test 7.0 {
SELECT 'abc' UNION ALL SELECT 'DEF'
ORDER BY 1 COLLATE nocase COLLATE nocase COLLATE nocase COLLATE nocase;
} {abc DEF}
do_execsql_test 7.1 {
SELECT 'abc' UNION ALL SELECT 'DEF'
ORDER BY 1 COLLATE nocase COLLATE nocase COLLATE nocase COLLATE binary;
} {DEF abc}
do_execsql_test 7.2 {
SELECT 'abc' UNION ALL SELECT 'DEF'
ORDER BY 1 COLLATE binary COLLATE binary COLLATE binary COLLATE nocase;
} {abc DEF}
finish_test finish_test

View File

@@ -32,7 +32,7 @@ source $testdir/tester.tcl
# #
do_test collate3-1.0 { do_test collate3-1.0 {
execsql { execsql {
CREATE TABLE collate3t1(c1); CREATE TABLE collate3t1(c1 UNIQUE);
} }
} {} } {}
do_test collate3-1.1 { do_test collate3-1.1 {
@@ -40,6 +40,11 @@ do_test collate3-1.1 {
SELECT * FROM collate3t1 ORDER BY 1 collate garbage; SELECT * FROM collate3t1 ORDER BY 1 collate garbage;
} }
} {1 {no such collation sequence: garbage}} } {1 {no such collation sequence: garbage}}
do_test collate3-1.1.2 {
catchsql {
SELECT DISTINCT c1 COLLATE garbage FROM collate3t1;
}
} {1 {no such collation sequence: garbage}}
do_test collate3-1.2 { do_test collate3-1.2 {
catchsql { catchsql {
CREATE TABLE collate3t2(c1 collate garbage); CREATE TABLE collate3t2(c1 collate garbage);

View File

@@ -746,10 +746,10 @@ do_test fkey2-10.2.2 {
drop_all_tables drop_all_tables
do_test fkey2-11.1.1 { do_test fkey2-11.1.1 {
execsql { execsql {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b); CREATE TABLE t1(a INTEGER PRIMARY KEY, b, rowid, _rowid_, oid);
CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(a) ON UPDATE CASCADE); CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(a) ON UPDATE CASCADE);
INSERT INTO t1 VALUES(10, 100); INSERT INTO t1 VALUES(10, 100, 'abc', 'def', 'ghi');
INSERT INTO t2 VALUES(10, 100); INSERT INTO t2 VALUES(10, 100);
UPDATE t1 SET a = 15; UPDATE t1 SET a = 15;
SELECT * FROM t2; SELECT * FROM t2;

View File

@@ -538,6 +538,25 @@ do_execsql_test 3.4 {
SELECT snippet(t3) FROM t3 WHERE t3 MATCH 'one OR two OR three'; SELECT snippet(t3) FROM t3 WHERE t3 MATCH 'one OR two OR three';
} {{[<b>one</b> <b>two</b> <b>three</b>]}} } {{[<b>one</b> <b>two</b> <b>three</b>]}}
#-------------------------------------------------------------------------
# Request a snippet 0 tokens in size. This is always an empty string.
do_execsql_test 4.1 {
CREATE VIRTUAL TABLE t4 USING fts4;
INSERT INTO t4 VALUES('a b c d');
SELECT snippet(t4, '[', ']', '...', 0, 0) FROM t4 WHERE t4 MATCH 'b';
} {{}}
do_test 4.2 {
set x35 [string trim [string repeat "x " 35]]
execsql "INSERT INTO t4 VALUES('$x35 E $x35 F $x35 G $x35');"
llength [db one {
SELECT snippet(t4, '', '', '', 0, 64) FROM t4 WHERE t4 MATCH 'E'
}]
} {64}
set sqlite_fts3_enable_parentheses 0 set sqlite_fts3_enable_parentheses 0
finish_test finish_test

View File

@@ -110,5 +110,15 @@ do_catchsql_test 2.1 {
SELECT * FROM t4; SELECT * FROM t4;
} {1 {SQL logic error or missing database}} } {1 {SQL logic error or missing database}}
do_catchsql_test 2.2 {
CREATE VIRTUAL TABLE t USING fts4(tokenize=simple"");
} {0 {}}
ifcapable fts3_unicode {
do_catchsql_test 2.3 {
CREATE VIRTUAL TABLE u USING fts4(tokenize=unicode61"");
} {1 {unknown tokenizer}}
}
finish_test finish_test

View File

@@ -48,6 +48,9 @@ ifcapable !fts3 {
# #
# 9.* - Test using content=xxx where xxx is a virtual table. # 9.* - Test using content=xxx where xxx is a virtual table.
# #
# 11.* - Test that circular references (e.g. "t1(content=t1)") are
# detected.
#
do_execsql_test 1.1.1 { do_execsql_test 1.1.1 {
CREATE TABLE t1(a, b, c); CREATE TABLE t1(a, b, c);
@@ -406,7 +409,7 @@ do_execsql_test 5.1.7 {
# #
do_catchsql_test 6.1.1 { do_catchsql_test 6.1.1 {
CREATE VIRTUAL TABLE ft7 USING fts4(content=t7); CREATE VIRTUAL TABLE ft7 USING fts4(content=t7);
} {1 {vtable constructor failed: ft7}} } {1 {no such table: main.t7}}
do_execsql_test 6.2.1 { do_execsql_test 6.2.1 {
CREATE TABLE t7(one, two); CREATE TABLE t7(one, two);
@@ -433,7 +436,7 @@ do_execsql_test 6.2.3 {
} }
do_catchsql_test 6.2.4 { do_catchsql_test 6.2.4 {
SELECT * FROM ft7; SELECT * FROM ft7;
} {1 {vtable constructor failed: ft7}} } {1 {no such table: main.t7}}
do_execsql_test 6.2.5 { do_execsql_test 6.2.5 {
CREATE TABLE t7(x, y); CREATE TABLE t7(x, y);
INSERT INTO t7 VALUES('A B', 'B A'); INSERT INTO t7 VALUES('A B', 'B A');
@@ -622,4 +625,15 @@ do_execsql_test 10.7 {
{...c d [e] f g...} {...c d [e] f g...}
} }
#-------------------------------------------------------------------------
# Test cases 11.*
#
reset_db
do_catchsql_test 11.1 {
CREATE VIRTUAL TABLE x1 USING fts4(content=x1);
} {1 {vtable constructor called recursively: x1}}
finish_test finish_test

View File

@@ -109,6 +109,11 @@ do_execsql_test hexlit-301 {
do_catchsql_test hexlist-400 { do_catchsql_test hexlist-400 {
SELECT 0x10000000000000000; SELECT 0x10000000000000000;
} {1 {hex literal too big: 0x10000000000000000}} } {1 {hex literal too big: 0x10000000000000000}}
do_catchsql_test hexlist-410 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(1+0x10000000000000000);
} {1 {hex literal too big: 0x10000000000000000}}
finish_test finish_test

View File

@@ -615,6 +615,12 @@ do_test in-13.14 {
} }
} {} } {}
do_test in-13.15 {
catchsql {
SELECT 0 WHERE (SELECT 0,0) OR (0 IN (1,2));
}
} {1 {only a single result allowed for a SELECT that is part of an expression}}
do_test in-13.X { do_test in-13.X {
db nullvalue "" db nullvalue ""

View File

@@ -639,4 +639,9 @@ do_catchsql_test misc1-21.2 {
VALUES(0,0x0MATCH#0; VALUES(0,0x0MATCH#0;
} {1 {near ";": syntax error}} } {1 {near ";": syntax error}}
# 2015-04-15
do_execsql_test misc1-22.1 {
SELECT ""+3 FROM (SELECT ""+5);
} {3}
finish_test finish_test

View File

@@ -278,6 +278,23 @@ do_test null-8.15 {
} }
} {1} } {1}
do_execsql_test null-9.1 {
CREATE TABLE t5(a, b, c);
CREATE UNIQUE INDEX t5ab ON t5(a, b);
INSERT INTO t5 VALUES(1, NULL, 'one');
INSERT INTO t5 VALUES(1, NULL, 'i');
INSERT INTO t5 VALUES(NULL, 'x', 'two');
INSERT INTO t5 VALUES(NULL, 'x', 'ii');
}
do_execsql_test null-9.2 {
SELECT * FROM t5 WHERE a = 1 AND b IS NULL;
} {1 {} one 1 {} i}
do_execsql_test null-9.3 {
SELECT * FROM t5 WHERE a IS NULL AND b = 'x';
} {{} x two {} x ii}
finish_test finish_test

View File

@@ -463,6 +463,9 @@ do_execsql_test 5.1 {
do_execsql_test 5.2 { do_execsql_test 5.2 {
SELECT 5 UNION ALL SELECT 3 ORDER BY 1 SELECT 5 UNION ALL SELECT 3 ORDER BY 1
} {3 5} } {3 5}
do_execsql_test 5.3 {
SELECT 986 AS x GROUP BY X ORDER BY X
} {986}
# The following test (originally derived from a single test within fuzz.test) # The following test (originally derived from a single test within fuzz.test)
# verifies that a PseudoTable cursor is not closed prematurely in a deeply # verifies that a PseudoTable cursor is not closed prematurely in a deeply
@@ -495,5 +498,34 @@ do_execsql_test 7.0 {
SELECT * FROM t7 WHERE a=?1 ORDER BY rowid; SELECT * FROM t7 WHERE a=?1 ORDER BY rowid;
} {~/ORDER BY/} } {~/ORDER BY/}
#-------------------------------------------------------------------------
# Test a partial sort large enough to cause the sorter to spill data
# to disk.
#
reset_db
do_execsql_test 8.0 {
PRAGMA cache_size = 5;
CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a);
}
do_eqp_test 8.1 {
SELECT * FROM t1 ORDER BY a, b;
} {
0 0 0 {SCAN TABLE t1 USING INDEX i1}
0 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY}
}
do_execsql_test 8.2 {
WITH cnt(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM cnt WHERE i<10000
)
INSERT INTO t1 SELECT i%2, randomblob(500) FROM cnt;
}
do_test 8.3 {
db eval { SELECT * FROM t1 ORDER BY a, b } { incr res $a }
set res
} 5000
finish_test finish_test

View File

@@ -752,6 +752,16 @@ do_test pragma-6.7 {
{3 four REAL 0 X'abcdef' 0} \ {3 four REAL 0 X'abcdef' 0} \
{4 five {} 0 CURRENT_TIME 0} \ {4 five {} 0 CURRENT_TIME 0} \
] ]
do_test pragma-6.8 {
execsql {
CREATE TABLE t68(a,b,c,PRIMARY KEY(a,b,a,c));
PRAGMA table_info(t68);
}
} [concat \
{0 a {} 0 {} 1} \
{1 b {} 0 {} 2} \
{2 c {} 0 {} 4} \
]
} ;# ifcapable schema_pragmas } ;# ifcapable schema_pragmas
# Miscellaneous tests # Miscellaneous tests
# #

View File

@@ -58,6 +58,9 @@ do_execsql_test printf2-1.10 {
do_execsql_test printf2-1.11 { do_execsql_test printf2-1.11 {
SELECT printf('%lld%n',314159.2653,'hi'); SELECT printf('%lld%n',314159.2653,'hi');
} {314159} } {314159}
do_execsql_test printf2-1.12 {
SELECT printf('%n',0);
} {{}}
# EVIDENCE-OF: R-17002-27534 The %z format is interchangeable with %s. # EVIDENCE-OF: R-17002-27534 The %z format is interchangeable with %s.
# #

View File

@@ -799,6 +799,11 @@ do_test select4-11.15 {
SELECT x FROM t2 SELECT x FROM t2
} }
} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}} } {1 {SELECTs to the left and right of UNION do not have the same number of result columns}}
do_test select4-11.16 {
catchsql {
INSERT INTO t2(rowid) VALUES(2) UNION SELECT 3,4 UNION SELECT 5,6 ORDER BY 1;
}
} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}}
do_test select4-12.1 { do_test select4-12.1 {
sqlite3 db2 :memory: sqlite3 db2 :memory:
@@ -863,5 +868,12 @@ do_execsql_test select4-14.8 {
do_execsql_test select4-14.9 { do_execsql_test select4-14.9 {
SELECT * FROM t14 UNION ALL VALUES(3,2,1),(2,3,1),(1,2,3),(2,1,3); 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} } {1 2 3 4 5 6 3 2 1 2 3 1 1 2 3 2 1 3}
do_execsql_test select4-14.10 {
SELECT (VALUES(1),(2),(3),(4))
} {1}
do_execsql_test select4-14.11 {
SELECT (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4)
} {1}
finish_test finish_test

View File

@@ -92,4 +92,9 @@ do_test selectE-2.2 {
} }
} {} } {}
do_catchsql_test selectE-3.1 {
SELECT 1 EXCEPT SELECT 2 ORDER BY 1 COLLATE nocase EXCEPT SELECT 3;
} {1 {ORDER BY clause should come after EXCEPT not before}}
finish_test finish_test

View File

@@ -15,6 +15,7 @@
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
set testprefix vacuum2
# Do not use a codec for tests in this file, as the database file is # 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). # manipulated directly using tcl scripts (using the [hexio_write] command).
@@ -227,5 +228,24 @@ do_test vacuum2-5.4 {
lappend res2 $res lappend res2 $res
} {1 2 3 4 5 6 7 8 9 10 {1 {cannot VACUUM - SQL statements in progress}}} } {1 2 3 4 5 6 7 8 9 10 {1 {cannot VACUUM - SQL statements in progress}}}
#-------------------------------------------------------------------------
# Check that if the definition of a collation sequence is changed and
# VACUUM run, records are store in the (new) correct order following the
# VACUUM. Even if the modified collation is attached to a PK of a WITHOUT
# ROWID table.
proc cmp {lhs rhs} { string compare $lhs $rhs }
db collate cmp cmp
do_execsql_test 6.0 {
CREATE TABLE t6(x PRIMARY KEY COLLATE cmp, y) WITHOUT ROWID;
CREATE INDEX t6y ON t6(y);
INSERT INTO t6 VALUES('i', 'one');
INSERT INTO t6 VALUES('ii', 'one');
INSERT INTO t6 VALUES('iii', 'one');
}
integrity_check 6.1
proc cmp {lhs rhs} { string compare $rhs $lhs }
do_execsql_test 6.2 VACUUM
integrity_check 6.3
finish_test finish_test

View File

@@ -129,11 +129,11 @@ do_execsql_test 3.0 {
do_searchcount_test 3.1 { do_searchcount_test 3.1 {
SELECT a, b FROM t3 WHERE (a=1 AND b='one') OR (a=2 AND b='two') SELECT a, b FROM t3 WHERE (a=1 AND b='one') OR (a=2 AND b='two')
} {1 one 2 two search 2} } {1 one 2 two search 4}
do_searchcount_test 3.2 { do_searchcount_test 3.2 {
SELECT a, c FROM t3 WHERE (a=1 AND b='one') OR (a=2 AND b='two') SELECT a, c FROM t3 WHERE (a=1 AND b='one') OR (a=2 AND b='two')
} {1 i 2 ii search 4} } {1 i 2 ii search 6}
do_searchcount_test 3.4.1 { do_searchcount_test 3.4.1 {
SELECT y FROM t4 WHERE x='a' SELECT y FROM t4 WHERE x='a'
@@ -142,24 +142,24 @@ do_searchcount_test 3.4.2 {
SELECT a, b FROM t3 WHERE SELECT a, b FROM t3 WHERE
(a=1 AND b=(SELECT y FROM t4 WHERE x='a')) (a=1 AND b=(SELECT y FROM t4 WHERE x='a'))
OR (a=2 AND b='two') OR (a=2 AND b='two')
} {1 one 2 two search 4} } {1 one 2 two search 6}
do_searchcount_test 3.4.3 { do_searchcount_test 3.4.3 {
SELECT a, b FROM t3 WHERE SELECT a, b FROM t3 WHERE
(a=2 AND b='two') (a=2 AND b='two')
OR (a=1 AND b=(SELECT y FROM t4 WHERE x='a')) OR (a=1 AND b=(SELECT y FROM t4 WHERE x='a'))
} {2 two 1 one search 4} } {2 two 1 one search 6}
do_searchcount_test 3.4.4 { do_searchcount_test 3.4.4 {
SELECT a, b FROM t3 WHERE SELECT a, b FROM t3 WHERE
(a=2 AND b=(SELECT y FROM t4 WHERE x='b')) (a=2 AND b=(SELECT y FROM t4 WHERE x='b'))
OR (a=1 AND b=(SELECT y FROM t4 WHERE x='a')) OR (a=1 AND b=(SELECT y FROM t4 WHERE x='a'))
} {2 two 1 one search 6} } {2 two 1 one search 8}
do_searchcount_test 3.5.1 { do_searchcount_test 3.5.1 {
SELECT a, b FROM t3 WHERE (a=1 AND b='one') OR rowid=4 SELECT a, b FROM t3 WHERE (a=1 AND b='one') OR rowid=4
} {1 one 2 two search 2} } {1 one 2 two search 3}
do_searchcount_test 3.5.2 { do_searchcount_test 3.5.2 {
SELECT a, c FROM t3 WHERE (a=1 AND b='one') OR rowid=4 SELECT a, c FROM t3 WHERE (a=1 AND b='one') OR rowid=4
} {1 i 2 ii search 2} } {1 i 2 ii search 3}
# Ticket [d02e1406a58ea02d] (2012-10-04) # Ticket [d02e1406a58ea02d] (2012-10-04)
# LEFT JOIN with an OR in the ON clause causes segfault # LEFT JOIN with an OR in the ON clause causes segfault

View File

@@ -843,4 +843,10 @@ do_catchsql_test 13.3 {
SELECT i FROM c; SELECT i FROM c;
} {1 {table c has 1 values for 2 columns}} } {1 {table c has 1 values for 2 columns}}
# 2015-04-12
#
do_execsql_test 14.1 {
WITH x AS (SELECT * FROM t) SELECT 0 EXCEPT SELECT 0 ORDER BY 1 COLLATE binary;
} {}
finish_test finish_test

View File

@@ -255,5 +255,14 @@ do_test zeroblob-9.8 {
db eval {SELECT zeroblob(2) IN (zeroblob(2))} db eval {SELECT zeroblob(2) IN (zeroblob(2))}
} {1} } {1}
# Oversized zeroblob records
#
do_test zeroblob-10.1 {
db eval {
CREATE TABLE t10(a,b,c);
}
catchsql {INSERT INTO t10 VALUES(zeroblob(1e9),zeroblob(1e9),zeroblob(1e9))}
} {1 {string or blob too big}}
finish_test finish_test

1217
tool/sqldiff.c Normal file

File diff suppressed because it is too large Load Diff