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:
@@ -536,6 +536,9 @@ sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h
|
||||
-o $@ $(TOP)/src/shell.c libsqlite3.la \
|
||||
$(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
|
||||
$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
|
||||
$(TLIBS) -rpath "$(libdir)"
|
||||
|
@@ -42,8 +42,8 @@ DYNAMIC_SHELL = 0
|
||||
#
|
||||
!IFNDEF NO_WARN
|
||||
!IF $(USE_FULLWARN)!=0
|
||||
NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4152 -wd4189 -wd4206 -wd4210
|
||||
NO_WARN = $(NO_WARN) -wd4232 -wd4244 -wd4305 -wd4306 -wd4702 -wd4706
|
||||
NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206
|
||||
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4244 -wd4305 -wd4306 -wd4702 -wd4706
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
@@ -453,11 +453,13 @@ RCC = $(RCC) -I$(TOP)\ext\rtree
|
||||
# options are necessary in order to allow debugging symbols to
|
||||
# work correctly with Visual Studio when using the amalgamation.
|
||||
#
|
||||
!IFNDEF MKSQLITE3C_ARGS
|
||||
!IF $(DEBUG)>1
|
||||
MKSQLITE3C_ARGS = --linemacros
|
||||
!ELSE
|
||||
MKSQLITE3C_ARGS =
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# Define -DNDEBUG to compile without debugging (i.e., for production usage)
|
||||
# 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 \
|
||||
/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
|
||||
$(LTLINK) $(SHELL_COMPILE_OPTS) $(TOP)\mptest\mptest.c \
|
||||
/link $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
||||
|
18
configure
vendored
18
configure
vendored
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.62 for sqlite 3.8.9.
|
||||
# Generated by GNU Autoconf 2.62 for sqlite 3.8.10.
|
||||
#
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
@@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='sqlite'
|
||||
PACKAGE_TARNAME='sqlite'
|
||||
PACKAGE_VERSION='3.8.9'
|
||||
PACKAGE_STRING='sqlite 3.8.9'
|
||||
PACKAGE_VERSION='3.8.10'
|
||||
PACKAGE_STRING='sqlite 3.8.10'
|
||||
PACKAGE_BUGREPORT=''
|
||||
|
||||
# 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.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
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]...
|
||||
|
||||
@@ -1546,7 +1546,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of sqlite 3.8.9:";;
|
||||
short | recursive ) echo "Configuration of sqlite 3.8.10:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1660,7 +1660,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlite configure 3.8.9
|
||||
sqlite configure 3.8.10
|
||||
generated by GNU Autoconf 2.62
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
$ $0 $@
|
||||
@@ -13953,7 +13953,7 @@ exec 6>&1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by sqlite $as_me 3.8.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
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -14006,7 +14006,7 @@ Report bugs to <bug-autoconf@gnu.org>."
|
||||
_ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_version="\\
|
||||
sqlite config.status 3.8.9
|
||||
sqlite config.status 3.8.10
|
||||
configured by $0, generated by GNU Autoconf 2.62,
|
||||
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
|
||||
|
||||
|
@@ -313,6 +313,13 @@ static int fts3EvalStart(Fts3Cursor *pCsr);
|
||||
static int fts3TermSegReaderCursor(
|
||||
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].
|
||||
** 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( quote=='[' ) quote = ']';
|
||||
|
||||
while( ALWAYS(z[iIn]) ){
|
||||
while( z[iIn] ){
|
||||
if( z[iIn]==quote ){
|
||||
if( z[iIn+1]!=quote ) break;
|
||||
z[iOut++] = quote;
|
||||
@@ -1019,7 +1026,8 @@ static int fts3ContentColumns(
|
||||
const char *zTbl, /* Name of content table */
|
||||
const char ***pazCol, /* OUT: Malloc'd array of column names */
|
||||
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 */
|
||||
char *zSql; /* "SELECT *" statement on zTbl */
|
||||
@@ -1030,6 +1038,9 @@ static int fts3ContentColumns(
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
*pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
|
||||
}
|
||||
}
|
||||
sqlite3_free(zSql);
|
||||
|
||||
@@ -1281,7 +1292,7 @@ static int fts3InitVtab(
|
||||
if( nCol==0 ){
|
||||
sqlite3_free((void*)aCol);
|
||||
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
|
||||
** column from the aCol[] array. */
|
||||
@@ -3523,6 +3534,8 @@ static void fts3SnippetFunc(
|
||||
}
|
||||
if( !zEllipsis || !zEnd || !zStart ){
|
||||
sqlite3_result_error_nomem(pContext);
|
||||
}else if( nToken==0 ){
|
||||
sqlite3_result_text(pContext, "", -1, SQLITE_STATIC);
|
||||
}else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){
|
||||
sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken);
|
||||
}
|
||||
|
@@ -134,6 +134,11 @@ SQLITE_EXTENSION_INIT3
|
||||
#ifdef SQLITE_COVERAGE_TEST
|
||||
# define ALWAYS(x) (1)
|
||||
# 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
|
||||
# define ALWAYS(x) (x)
|
||||
# define NEVER(x) (x)
|
||||
|
4
main.mk
4
main.mk
@@ -408,6 +408,10 @@ sqlite3$(EXE): $(TOP)/src/shell.c libsqlite3.a sqlite3.h
|
||||
$(TOP)/src/shell.c \
|
||||
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
|
||||
$(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
|
||||
$(TLIBS) $(THREADLIB)
|
||||
|
117
manifest
117
manifest
@@ -1,12 +1,12 @@
|
||||
C Merge\sall\schanges\sfor\sversion\s3.8.9\sinto\sthe\sota-update\sbranch.
|
||||
D 2015-04-08T14:01:07.788
|
||||
C Merge\sall\srecent\strunk\senhancements\sand\sfixes\sinto\sthe\sota-update\sbranch.
|
||||
D 2015-04-15T14:26:04.771
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 00d12636df7a5b08af09116bcd6c7bfd49b8b3b4
|
||||
F Makefile.in 5f78b1ab81b64e7c57a75d170832443e66c0880a
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
F Makefile.msc a8d817fa486d8c88dfbd19ae6a6567d9d350de39
|
||||
F Makefile.msc 0078f5781538e07ea38683439f38d5f5ab79ab6e
|
||||
F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858
|
||||
F README.md d58e3bebc0a4145e0f2a87994015fdb575a8e866
|
||||
F VERSION 319eb1ced4b4d17a67730f2b7b85f15c1346cb60
|
||||
F VERSION 2e244662b71e6e68a5c29b014ebc5b7564f4cc5a
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
@@ -38,7 +38,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||
F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0
|
||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||
F configure 8b18c2378805a1d8aaca85d293671f450dd3c723 x
|
||||
F configure 2ea5f5b58dd106da449ab598ab6e515339d7fa2a x
|
||||
F configure.ac 0b775d383c536bbaafc1e46dd3cbb81a7ea11aeb
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
|
||||
@@ -78,9 +78,9 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
|
||||
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
|
||||
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
|
||||
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
||||
F ext/fts3/fts3.c 23bd9d37a777342f5c22a648e9b4b005dde9e58f
|
||||
F ext/fts3/fts3.c 4bd75289875b63c04f943d6ed7c31737da99cd74
|
||||
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_expr.c 40123785eaa3ebd4c45c9b23407cc44ac0c49905
|
||||
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
|
||||
@@ -170,9 +170,9 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk 19443a29765ee87f4a4dca28818c6bbff34f738d
|
||||
F main.mk 95e9c8295b3ce06c0cbe6977b2b3ed8407cfe217
|
||||
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
|
||||
F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5
|
||||
F mkopcodeh.awk d5e22023b5238985bb54a72d33e0ac71fe4f8a32
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
@@ -186,29 +186,29 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c d23d6b6991f66b383934f137fd4384d93fb98c81
|
||||
F src/analyze.c 91540f835163d5369ccbae78e2e6c74d0dd53c1d
|
||||
F src/attach.c 880f9b8641a829c563e52dd13c452ce457ae4dd8
|
||||
F src/attach.c 3c1053a4cf1c3ca05c8c1d74a94cb688d763cef2
|
||||
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
||||
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
|
||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
||||
F src/btree.c 2caf598165f3608fde8abac2b243826616ce54b7
|
||||
F src/btree.c 67648f6532c2da79d3b3fb6853aa1a0c3ba0e1ad
|
||||
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
||||
F src/btreeInt.h 973a22a6fd61350b454ad614832b1f0a5e25a1e4
|
||||
F src/build.c 0419bba592c22f6d00e6d57a2ca7136720d02c1a
|
||||
F src/build.c 01b969b20a44a3d9620e597d9af8242348123540
|
||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||
F src/complete.c 198a0066ba60ab06fc00fba1998d870a4d575463
|
||||
F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575
|
||||
F src/ctime.c 98f89724adc891a1a4c655bee04e33e716e05887
|
||||
F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac
|
||||
F src/delete.c 37964e6c1d73ff49cbea9ff690c9605fb15f600e
|
||||
F src/expr.c d09dac67d53c78880ba31d56e8ba2be3a6490553
|
||||
F src/expr.c 8800584340a9b4f4c0ca55c360de751c6da0b11a
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c e0444b61bed271a76840cbe6182df93a9baa3f12
|
||||
F src/fkey.c 3343d551a8d810782257244fb33f2ce191493c39
|
||||
F src/func.c 1414c24c873c48796ad45942257a179a423ba42f
|
||||
F src/global.c 4f77cadbc5427d00139ba43d0f3979804cbb700e
|
||||
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
||||
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
F src/insert.c 5b9243a33726008cc4132897d2be371db12a13be
|
||||
F src/insert.c 305dd3f9539d0affa4bf1c14cc7dffb34867e040
|
||||
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
|
||||
F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
|
||||
@@ -221,7 +221,7 @@ F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||
F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534
|
||||
F src/mem5.c 61eeb90134f9a5be6c2e68d8daae7628b25953fb
|
||||
F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85
|
||||
F src/msvc.h e78002098966e39b2fd9915bd70b7bc3ec8398b7
|
||||
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
|
||||
F src/mutex.c 19bf9acba69ca2f367c3761080f8a9f0cf4670a8
|
||||
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
|
||||
F src/mutex_noop.c 529bab0743c3321c940f32c3464de494fd38cfa9
|
||||
@@ -232,7 +232,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8
|
||||
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
|
||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||
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.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c 4120a49ecd37697e28f5ed807f470b9c0b88410c
|
||||
@@ -241,19 +241,19 @@ F src/parse.y 1299c66e7b1707322ccd8af43a359b8fb0d46d72
|
||||
F src/pcache.c 10539fb959849ad6efff80050541cab3d25089d4
|
||||
F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
|
||||
F src/pcache1.c 69d137620a305f814398bd29a0c998038c0695e9
|
||||
F src/pragma.c ac4f3f856b4234e85f55b0f069698a4766011100
|
||||
F src/pragma.c 3965ae4e82bed39fb97ce04c5fe18c9bc3ee6a88
|
||||
F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f
|
||||
F src/prepare.c 173a5a499138451b2561614ecb87d78f9f4644b9
|
||||
F src/printf.c 8ae1fa9d30c1200a9268a390ba9e9cea9197b27a
|
||||
F src/printf.c 08fa675c200aac29e561c6153f91f909ed17612f
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c 41aa91af56d960e9414ce1d7c17cfb68e0d1c6cb
|
||||
F src/resolve.c 66cfe49a9c3b449ef13b89a8c47036a4ed167eab
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c c28c52e353287434fac8473e56ee4be848d12c9d
|
||||
F src/select.c 93260bc9e7e0e6dfe1b7cb8815b0ed4cad8be9e3
|
||||
F src/shell.c 84a1593bd86aaa14f4da8a8f9b16fbc239d262aa
|
||||
F src/sqlite.h.in 2814e6b51c5a6176eecae4a7d5b7bfaf142283c8
|
||||
F src/sqlite.h.in 3be4d9a7d38ef83fadd4aadd7ef3c6039e165da7
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
||||
F src/sqliteInt.h 107b02ed6c64162b653acc2368e982de529e14f6
|
||||
F src/sqliteInt.h 90b7bfd89d7307cd0750663da419ba4bb81e7379
|
||||
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
||||
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
|
||||
F src/table.c e7a09215315a978057fb42c640f890160dbcc45e
|
||||
@@ -305,27 +305,27 @@ F src/test_vfs.c b7e6831e6fcf04c5090accff30640ec5c9630739
|
||||
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481
|
||||
F src/tokenize.c a8d270b06e5f709930f7b67cf70a847969cb5bf3
|
||||
F src/trigger.c 25571661fdeae8c7f975ff40ffec205520a3f92f
|
||||
F src/tokenize.c a8234a67577308935cdf13e618cd66556f5f45d1
|
||||
F src/trigger.c 69a91bed7c94e46223e37ffccfeeb35e34b999ac
|
||||
F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13
|
||||
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
|
||||
F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e
|
||||
F src/vacuum.c 9460b9de7b2d4e34b0d374894aa6c8a0632be8ec
|
||||
F src/vdbe.c 86ae6f4774410868af41bd839b72b7081ff03e78
|
||||
F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3
|
||||
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
|
||||
F src/vdbe.c 3f3afd12d4794cb51fe13dc948b1172a5eb71a94
|
||||
F src/vdbe.h 7e538ecf47dccb307ea2d087c3ddc2dd8d70e79d
|
||||
F src/vdbeInt.h 9cbaa84f53ddd2d09a0cf61a94337a3a035d08a0
|
||||
F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75
|
||||
F src/vdbeaux.c 413dc496248ac18eb0c19e35e86bb1ffd47b8907
|
||||
F src/vdbeaux.c a20504ae52392459fa08402fda3f195f19d7c79d
|
||||
F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90
|
||||
F src/vdbemem.c c0dc81285b7571b0a31c40f17846fe2397ec1cd9
|
||||
F src/vdbesort.c 919717d7599fa31d343ec28bffd0f9e91a4ff5f6
|
||||
F src/vdbesort.c 2e7f683464fd5db3be4beaa1ff2d39e24fcb64b8
|
||||
F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
|
||||
F src/vtab.c 62d49237bd8f3be4863815a39387b0f9897fa5e1
|
||||
F src/vtab.c 9ca557215e8591ceb66e0b7c0a579c6df1e54b2d
|
||||
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
||||
F src/wal.c 878c8e1a51cb2ec45c395d26b7d5cd9e1a098e4a
|
||||
F src/wal.c 753995db83247f20361a8e8a874990b21a75abd9
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
|
||||
F src/where.c bc7276b6e7d4d50055e17cba1d495f804737f872
|
||||
F src/where.c 7e5d9a5690e71c39bfc4afea9f351766299dbf2f
|
||||
F src/whereInt.h 1fca2f8c649f0ee38fd52332659d0e7deb11d428
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
@@ -367,7 +367,7 @@ F test/auth.test 855233ef26eb3601b6886567ea4e326c72959360
|
||||
F test/auth2.test 264c6af53cad9aba5218c68bbe18036e39007bfa
|
||||
F test/auth3.test 5cfa94ed90c6617c42b7ba4b133fd79678b251c7
|
||||
F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7
|
||||
F test/autoindex1.test 7008c9f604141fdabe31b7bb95b5ff31b518251f
|
||||
F test/autoindex1.test 14b63a9f1e405fe6d5bfc8c8d00249c2ebaf13ea
|
||||
F test/autoindex2.test af7e595c6864cc6ef5fc38d5db579a3e34940cb8
|
||||
F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972
|
||||
F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf
|
||||
@@ -417,9 +417,9 @@ F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763
|
||||
F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815
|
||||
F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4
|
||||
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
|
||||
F test/collate1.test 7fcfe78f9613dc4a7e247d6bd27749955f108741
|
||||
F test/collate1.test 08c18e7512a5a32c97938854263fa15362eeb846
|
||||
F test/collate2.test 9aaa410a00734e48bcb27f3872617d6f69b2a621
|
||||
F test/collate3.test 79558a286362cb9ed603c6fa543f1cda7f563f0f
|
||||
F test/collate3.test 89defc49983ddfbf0a0555aca8c0521a676f56a5
|
||||
F test/collate4.test f04d5168685f2eef637ecfa2d4ddf8ec0d600177
|
||||
F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6
|
||||
F test/collate6.test 8be65a182abaac8011a622131486dafb8076e907
|
||||
@@ -523,7 +523,7 @@ F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7
|
||||
F test/filectrl.test 14fa712e42c4cb791e09dfd58a6a03efb47ef13a
|
||||
F test/filefmt.test cb34663f126cbc2d358af552dcaf5c72769b0146
|
||||
F test/fkey1.test e1d1fa84cde579185ea01358436839703e415a5b
|
||||
F test/fkey2.test 1db212cda86b0d3ce72714001f7b6381c321341c
|
||||
F test/fkey2.test 223c624e7eccee21e89c98d4d127ac88d774b940
|
||||
F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
|
||||
F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
|
||||
F test/fkey5.test 56bcb5a6e8b725b17febc267fb041a6695e86853
|
||||
@@ -617,14 +617,14 @@ F test/fts3prefix2.test e1f0a822ca661dced7f12ce392e14eaf65609dce
|
||||
F test/fts3query.test c838b18f2b859e15fd31c64be3d79ef1556803ca
|
||||
F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0
|
||||
F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e
|
||||
F test/fts3snippet.test 03c2f3be7d3b7c8bb105ed237f204833392bd57f
|
||||
F test/fts3snippet.test 63dbd687d5bf5191f1b8e6a0977aa9c1e28a7004
|
||||
F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca
|
||||
F test/fts3tok1.test c551043de056b0b1582a54e878991f57bad074bc
|
||||
F test/fts3tok1.test 178c050199af8c05299b1ad572514ce1c54b7827
|
||||
F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d
|
||||
F test/fts3varint.test 752c08ed5d32c5d7dc211b056f4ed68a76b7e36e
|
||||
F test/fts4aa.test 10aac8e9d62c7357590acfabe3fad01e9a9ce1cb
|
||||
F test/fts4check.test 74d77f6cdb768ac49df5afda575cef14ae3d239a
|
||||
F test/fts4content.test 2e7252557d6d24afa101d9ba1de710d6140e6d06
|
||||
F test/fts4content.test abb0c77bc3da3df64fec72e00844d2257a90025d
|
||||
F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01
|
||||
F test/fts4growth.test df10fde9f47cf5c71861e63fd8efcd573c4f7e53
|
||||
F test/fts4growth2.test 2f063be1902a73cd087355837c52fed42ac11a5d
|
||||
@@ -651,11 +651,11 @@ F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
|
||||
F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36
|
||||
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
|
||||
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
|
||||
F test/hexlit.test f9ecde8145bfc2341573473256c74ae37a200497
|
||||
F test/hexlit.test 1d312fa816dfd3650a3bb488093bc09a0c927f67
|
||||
F test/hook.test 162d7cef7a2d2b04839fe14402934e6a1b79442f
|
||||
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
|
||||
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
|
||||
F test/in.test 047c4671328e9032ab95666a67021adbbd36e98e
|
||||
F test/in.test b52fa96bcf6cebc5c8829c822315d0f87af9c6c2
|
||||
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
|
||||
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
|
||||
F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068
|
||||
@@ -761,7 +761,7 @@ F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd
|
||||
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
|
||||
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
|
||||
F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f
|
||||
F test/misc1.test f3f59b3941c84a10860c06c07e86ad367a74ec92
|
||||
F test/misc1.test 9abcae9a0b8785d6fa92925dbb19c309ae9ea077
|
||||
F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d
|
||||
F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d
|
||||
F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6
|
||||
@@ -786,10 +786,10 @@ F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf
|
||||
F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161
|
||||
F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
|
||||
F test/notnull.test f8fcf58669ddba79274daa2770d61dfad8274f62
|
||||
F test/null.test a8b09b8ed87852742343b33441a9240022108993
|
||||
F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3
|
||||
F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1
|
||||
F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
|
||||
F test/orderby1.test eb246e377612b21a418fbea57047ba8ea88aaa6b
|
||||
F test/orderby1.test 870e150450437d3980badbde3d0166b81d9e33f6
|
||||
F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04
|
||||
F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99
|
||||
F test/orderby4.test 4d39bfbaaa3ae64d026ca2ff166353d2edca4ba4
|
||||
@@ -813,11 +813,11 @@ F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
|
||||
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
F test/permutations.test 0e2dc2aab7b1043bd2b4404f51651c31da007e52
|
||||
F test/pragma.test ad99d05e411c7687302124be56f3b362204be041
|
||||
F test/pragma.test e6605ce89c66db930aef561e43a22281a09ffc66
|
||||
F test/pragma2.test f624a496a95ee878e81e59961eade66d5c00c028
|
||||
F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c
|
||||
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
|
||||
F test/printf2.test b4acd4bf8734243257f01ddefa17c4fb090acc8a
|
||||
F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054
|
||||
F test/progress.test a282973d1d17f08071bc58a77d6b80f2a81c354d
|
||||
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
|
||||
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
|
||||
@@ -858,7 +858,7 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
|
||||
F test/select1.test fc2a61f226a649393664ad54bc5376631801517c
|
||||
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
|
||||
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
|
||||
F test/select4.test e20e8ce47b558de80616102ef273704cf0d48a3b
|
||||
F test/select4.test 16fa1cafb942f42294ec85cbb78954c2f2d15a44
|
||||
F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
|
||||
F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
|
||||
F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d
|
||||
@@ -868,7 +868,7 @@ F test/selectA.test e452bdb975f488ea46d091382a9185b5853ed2c7
|
||||
F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25
|
||||
F test/selectC.test 871fb55d884d3de5943c4057ebd22c2459e71977
|
||||
F test/selectD.test b0f02a04ef7737decb24e08be2c39b9664b43394
|
||||
F test/selectE.test fc02a1eb04c8eb537091482644b7d778ae8759b7
|
||||
F test/selectE.test a8730ca330fcf40ace158f134f4fe0eb00c7edbf
|
||||
F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3
|
||||
F test/selectG.test e8600e379589e85e9fefd2fe4d44a4cdd63f6982
|
||||
F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118
|
||||
@@ -1126,7 +1126,7 @@ F test/uri.test 23662b7b61958b0f0e47082de7d06341ccf85d5b
|
||||
F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9
|
||||
F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae
|
||||
F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d
|
||||
F test/vacuum2.test af432e6e3bfc0ea20a80cb86a03c7d9876d38324
|
||||
F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b
|
||||
F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d
|
||||
F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
|
||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||
@@ -1190,7 +1190,7 @@ F test/where9.test 729c3ba9b47e8f9f1aab96bae7dad2a524f1d1a2
|
||||
F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b
|
||||
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
|
||||
F test/whereC.test d6f4ecd4fa2d9429681a5b22a25d2bda8e86ab8a
|
||||
F test/whereD.test fd9120e262f9da3c45940f52aefeef4d15b904e5
|
||||
F test/whereD.test 9eba1f9b18e5b19a0b0bcaae5e8c037260195f2b
|
||||
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
|
||||
F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7
|
||||
F test/whereG.test 69f5ec4b15760a8c860f80e2d55525669390aab3
|
||||
@@ -1203,7 +1203,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
|
||||
F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c
|
||||
F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
|
||||
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
|
||||
F test/with1.test 9df5cd8a62148b3d9ef8597aea563e3863018bcd
|
||||
F test/with1.test a86bf7f9288ba759a25ee57221d3bffaca36032a
|
||||
F test/with2.test ee227a663586aa09771cafd4fa269c5217eaf775
|
||||
F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991
|
||||
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_rowid6.test db0dbf03c49030aa3c1ba5f618620334bd2baf5f
|
||||
F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda
|
||||
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
|
||||
F test/zeroblob.test fb3c0e4ab172d386954deda24c03f500e121d80d
|
||||
F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac
|
||||
F tool/build-all-msvc.bat 72e05bc8deca39a547884485c086b915f50a91ed x
|
||||
F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
|
||||
@@ -1258,6 +1258,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
|
||||
F tool/sqldiff.c 5c16cf3a1f566873abbdecac0d13a6691437564f
|
||||
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
|
||||
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
|
||||
F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
|
||||
@@ -1268,7 +1269,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 4e8796af7d40d6ca423e07c68877035e4aa2485c 8a8ffc862e96f57aa698f93de10dee28e69f6e09
|
||||
R 5f5852d5f7f1cc470ab35b77b2f9115f
|
||||
P ec9d907a57fcea72c8a64e521e8a1b5777d67568 bd06eeb8d06237dc2d54d8a03e8bf525cb811c9e
|
||||
R 6f95f9c15975aab2be755a8183ba89a7
|
||||
U drh
|
||||
Z 0c6fb869959322b1de7ded76db4a0dc3
|
||||
Z 38e5b36fa5e6d50108fc54dc3af0e0b9
|
||||
|
@@ -1 +1 @@
|
||||
ec9d907a57fcea72c8a64e521e8a1b5777d67568
|
||||
9bd3e4453d4ad416f7e3f08f0bd283d34f1c319c
|
@@ -72,7 +72,6 @@
|
||||
sub("\r","",name)
|
||||
op[name] = -1 # op[x] holds the numeric value for OP symbol x
|
||||
jump[name] = 0
|
||||
out2_prerelease[name] = 0
|
||||
in1[name] = 0
|
||||
in2[name] = 0
|
||||
in3[name] = 0
|
||||
@@ -92,8 +91,6 @@
|
||||
sub(",","",x)
|
||||
if(x=="jump"){
|
||||
jump[name] = 1
|
||||
}else if(x=="out2-prerelease"){
|
||||
out2_prerelease[name] = 1
|
||||
}else if(x=="in1"){
|
||||
in1[name] = 1
|
||||
}else if(x=="in2"){
|
||||
@@ -194,13 +191,12 @@ END {
|
||||
name = def[i]
|
||||
a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0
|
||||
if( jump[name] ) a0 = 1;
|
||||
if( out2_prerelease[name] ) a1 = 2;
|
||||
if( in1[name] ) a2 = 4;
|
||||
if( in2[name] ) a3 = 8;
|
||||
if( in3[name] ) a4 = 16;
|
||||
if( out2[name] ) a5 = 32;
|
||||
if( out3[name] ) a6 = 64;
|
||||
bv[i] = a0+a1+a2+a3+a4+a5+a6+a7;
|
||||
if( in1[name] ) a2 = 2;
|
||||
if( in2[name] ) a3 = 4;
|
||||
if( in3[name] ) a4 = 8;
|
||||
if( out2[name] ) a5 = 16;
|
||||
if( out3[name] ) a6 = 32;
|
||||
bv[i] = a0+a1+a2+a3+a4+a5+a6;
|
||||
}
|
||||
print "\n"
|
||||
print "/* Properties such as \"out2\" or \"jump\" that are specified in"
|
||||
@@ -208,12 +204,11 @@ END {
|
||||
print "** are encoded into bitvectors as follows:"
|
||||
print "*/"
|
||||
print "#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */"
|
||||
print "#define OPFLG_OUT2_PRERELEASE 0x0002 /* out2-prerelease: */"
|
||||
print "#define OPFLG_IN1 0x0004 /* in1: P1 is an input */"
|
||||
print "#define OPFLG_IN2 0x0008 /* in2: P2 is an input */"
|
||||
print "#define OPFLG_IN3 0x0010 /* in3: P3 is an input */"
|
||||
print "#define OPFLG_OUT2 0x0020 /* out2: P2 is an output */"
|
||||
print "#define OPFLG_OUT3 0x0040 /* out3: P3 is an output */"
|
||||
print "#define OPFLG_IN1 0x0002 /* in1: P1 is an input */"
|
||||
print "#define OPFLG_IN2 0x0004 /* in2: P2 is an input */"
|
||||
print "#define OPFLG_IN3 0x0008 /* in3: P3 is an input */"
|
||||
print "#define OPFLG_OUT2 0x0010 /* out2: P2 is an output */"
|
||||
print "#define OPFLG_OUT3 0x0020 /* out3: P3 is an output */"
|
||||
print "#define OPFLG_INITIALIZER {\\"
|
||||
for(i=0; i<=max; i++){
|
||||
if( i%8==0 ) printf("/* %3d */",i)
|
||||
|
@@ -298,7 +298,7 @@ static void detachFunc(
|
||||
sqlite3BtreeClose(pDb->pBt);
|
||||
pDb->pBt = 0;
|
||||
pDb->pSchema = 0;
|
||||
sqlite3ResetAllSchemasOfConnection(db);
|
||||
sqlite3CollapseDatabaseArray(db);
|
||||
return;
|
||||
|
||||
detach_error:
|
||||
|
@@ -6735,7 +6735,6 @@ static int balance_nonroot(
|
||||
}else if( iParentIdx==i ){
|
||||
nxDiv = i-2+bBulk;
|
||||
}else{
|
||||
assert( bBulk==0 );
|
||||
nxDiv = iParentIdx-1;
|
||||
}
|
||||
i = 2-bBulk;
|
||||
|
@@ -226,7 +226,7 @@ void sqlite3FinishCoding(Parse *pParse){
|
||||
|
||||
/* 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 */
|
||||
/* A minimum of one cursor is required if autoincrement is used
|
||||
* See ticket [a696379c1f08866] */
|
||||
@@ -2763,7 +2763,8 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
||||
addr2 = sqlite3VdbeCurrentAddr(v);
|
||||
}
|
||||
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);
|
||||
sqlite3ReleaseTempReg(pParse, regRecord);
|
||||
sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
|
||||
@@ -3776,7 +3777,6 @@ void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){
|
||||
void sqlite3SrcListShiftJoinType(SrcList *p){
|
||||
if( p ){
|
||||
int i;
|
||||
assert( p->a || p->nSrc==0 );
|
||||
for(i=p->nSrc-1; i>0; i--){
|
||||
p->a[i].jointype = p->a[i-1].jointype;
|
||||
}
|
||||
|
@@ -269,7 +269,7 @@ int sqlite3_complete(const char *zSql){
|
||||
int sqlite3_complete16(const void *zSql){
|
||||
sqlite3_value *pVal;
|
||||
char const *zSql8;
|
||||
int rc = SQLITE_NOMEM;
|
||||
int rc;
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTOINIT
|
||||
rc = sqlite3_initialize();
|
||||
|
@@ -1691,7 +1691,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){
|
||||
** ephemeral table.
|
||||
*/
|
||||
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 */
|
||||
Table *pTab; /* Table <table>. */
|
||||
Expr *pExpr; /* Expression <column> */
|
||||
@@ -2016,6 +2016,7 @@ int sqlite3CodeSubselect(
|
||||
pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
|
||||
&sqlite3IntTokens[1]);
|
||||
pSel->iLimit = 0;
|
||||
pSel->selFlags &= ~SF_AllValues;
|
||||
if( sqlite3Select(pParse, pSel, &dest) ){
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1184,7 +1184,8 @@ static Trigger *fkActionTrigger(
|
||||
|
||||
iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
|
||||
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;
|
||||
|
||||
tToCol.n = sqlite3Strlen30(tToCol.z);
|
||||
|
49
src/insert.c
49
src/insert.c
@@ -1765,6 +1765,7 @@ static int xferOptimization(
|
||||
int onError, /* How to handle constraint errors */
|
||||
int iDbDest /* The database of pDest */
|
||||
){
|
||||
sqlite3 *db = pParse->db;
|
||||
ExprList *pEList; /* The result set of the SELECT */
|
||||
Table *pSrc; /* The table in the FROM clause of SELECT */
|
||||
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
|
||||
** 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;
|
||||
}
|
||||
#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 */
|
||||
}
|
||||
|
||||
@@ -1927,7 +1928,7 @@ static int xferOptimization(
|
||||
#ifdef SQLITE_TEST
|
||||
sqlite3_xferopt_count++;
|
||||
#endif
|
||||
iDbSrc = sqlite3SchemaToIndex(pParse->db, pSrc->pSchema);
|
||||
iDbSrc = sqlite3SchemaToIndex(db, pSrc->pSchema);
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
sqlite3CodeVerifySchema(pParse, iDbSrc);
|
||||
iSrc = pParse->nTab++;
|
||||
@@ -1937,14 +1938,18 @@ static int xferOptimization(
|
||||
regRowid = sqlite3GetTempReg(pParse);
|
||||
sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
|
||||
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) */
|
||||
|| (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */
|
||||
){
|
||||
)){
|
||||
/* In some circumstances, we are able to run the xfer optimization
|
||||
** only if the destination table is initially empty. This code makes
|
||||
** that determination. Conditions under which the destination must
|
||||
** be empty:
|
||||
** only if the destination table is initially empty. Unless the
|
||||
** SQLITE_Vacuum flag is set, this block generates code to make
|
||||
** that determination. If SQLITE_Vacuum is set, then the destination
|
||||
** table is always empty.
|
||||
**
|
||||
** Conditions under which the destination must be empty:
|
||||
**
|
||||
** (1) There is no INTEGER PRIMARY KEY but there are indices.
|
||||
** (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);
|
||||
}
|
||||
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
|
||||
u8 useSeekResult = 0;
|
||||
for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
|
||||
if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
|
||||
}
|
||||
@@ -2000,7 +2006,34 @@ static int xferOptimization(
|
||||
VdbeComment((v, "%s", pDestIdx->zName));
|
||||
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
|
||||
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);
|
||||
sqlite3VdbeChangeP5(v, useSeekResult);
|
||||
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
|
||||
sqlite3VdbeJumpHere(v, addr1);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#pragma warning(disable : 4055)
|
||||
#pragma warning(disable : 4100)
|
||||
#pragma warning(disable : 4127)
|
||||
#pragma warning(disable : 4130)
|
||||
#pragma warning(disable : 4152)
|
||||
#pragma warning(disable : 4189)
|
||||
#pragma warning(disable : 4206)
|
||||
|
@@ -91,6 +91,17 @@
|
||||
# include <sys/param.h>
|
||||
#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
|
||||
# include <sys/ioctl.h>
|
||||
# include <semaphore.h>
|
||||
@@ -6602,8 +6613,10 @@ int sqlite3_hostid_num = 0;
|
||||
|
||||
#define PROXY_HOSTIDLEN 16 /* conch file host id length */
|
||||
|
||||
#ifdef HAVE_GETHOSTUUID
|
||||
/* Not always defined in the headers as it ought to be */
|
||||
extern int gethostuuid(uuid_t id, const struct timespec *wait);
|
||||
#endif
|
||||
|
||||
/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN
|
||||
** 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){
|
||||
assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
|
||||
memset(pHostID, 0, PROXY_HOSTIDLEN);
|
||||
# if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
|
||||
(__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
|
||||
#ifdef HAVE_GETHOSTUUID
|
||||
{
|
||||
struct timespec timeout = {1, 0}; /* 1 sec timeout */
|
||||
if( gethostuuid(pHostID, &timeout) ){
|
||||
|
@@ -1041,7 +1041,7 @@ void sqlite3Pragma(
|
||||
}else if( pPk==0 ){
|
||||
k = 1;
|
||||
}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_ResultRow, 1, 6);
|
||||
|
@@ -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.
|
||||
*/
|
||||
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( N>=0 );
|
||||
assert( p->accError==0 || p->nAlloc==0 );
|
||||
|
@@ -460,6 +460,7 @@ static int lookupName(
|
||||
if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){
|
||||
pExpr->op = TK_STRING;
|
||||
pExpr->pTab = 0;
|
||||
pExpr->iTable = -1;
|
||||
return WRC_Prune;
|
||||
}
|
||||
|
||||
@@ -993,9 +994,11 @@ static int resolveCompoundOrderBy(
|
||||
if( pItem->pExpr==pE ){
|
||||
pItem->pExpr = pNew;
|
||||
}else{
|
||||
assert( pItem->pExpr->op==TK_COLLATE );
|
||||
assert( pItem->pExpr->pLeft==pE );
|
||||
pItem->pExpr->pLeft = pNew;
|
||||
Expr *pParent = pItem->pExpr;
|
||||
assert( pParent->op==TK_COLLATE );
|
||||
while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft;
|
||||
assert( pParent->pLeft==pE );
|
||||
pParent->pLeft = pNew;
|
||||
}
|
||||
sqlite3ExprDelete(db, pE);
|
||||
pItem->u.x.iOrderByCol = (u16)iCol;
|
||||
@@ -1195,7 +1198,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||||
** after the names have been resolved. */
|
||||
if( p->selFlags & SF_Converted ){
|
||||
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 );
|
||||
pSub->pOrderBy = p->pOrderBy;
|
||||
p->pOrderBy = 0;
|
||||
|
@@ -3071,7 +3071,7 @@ static int multiSelectOrderBy(
|
||||
/*** TBD: Insert subroutine calls to close cursors on incomplete
|
||||
**** subqueries ****/
|
||||
explainComposite(pParse, p->op, iSub1, iSub2, 0);
|
||||
return SQLITE_OK;
|
||||
return pParse->nErr!=0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3883,6 +3883,7 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){
|
||||
pNew->pOrderBy = 0;
|
||||
p->pPrior = 0;
|
||||
p->pNext = 0;
|
||||
p->pWith = 0;
|
||||
p->selFlags &= ~SF_Compound;
|
||||
assert( (p->selFlags & SF_Converted)==0 );
|
||||
p->selFlags |= SF_Converted;
|
||||
|
100
src/sqlite.h.in
100
src/sqlite.h.in
@@ -270,6 +270,7 @@ typedef sqlite_uint64 sqlite3_uint64;
|
||||
|
||||
/*
|
||||
** CAPI3REF: Closing A Database Connection
|
||||
** DESTRUCTOR: sqlite3
|
||||
**
|
||||
** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
|
||||
** for the [sqlite3] object.
|
||||
@@ -321,6 +322,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
|
||||
|
||||
/*
|
||||
** CAPI3REF: One-Step Query Execution Interface
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** The sqlite3_exec() interface is a convenience wrapper around
|
||||
** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()],
|
||||
@@ -1383,6 +1385,7 @@ int sqlite3_config(int, ...);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Configure database connections
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** The sqlite3_db_config() interface is used to make configuration
|
||||
** 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
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^The sqlite3_extended_result_codes() routine enables or disables the
|
||||
** [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
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
|
||||
** has a unique 64-bit signed
|
||||
@@ -1940,6 +1945,7 @@ sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Count The Number Of Rows Modified
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^This function returns the number of rows modified, inserted or
|
||||
** deleted by the most recently completed INSERT, UPDATE or DELETE
|
||||
@@ -1992,6 +1998,7 @@ int sqlite3_changes(sqlite3*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Total Number Of Rows Modified
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^This function returns the total number of rows inserted, modified or
|
||||
** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed
|
||||
@@ -2015,6 +2022,7 @@ int sqlite3_total_changes(sqlite3*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Interrupt A Long-Running Query
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^This function causes any pending database operation to abort and
|
||||
** 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
|
||||
** KEYWORDS: {busy-handler callback} {busy handler}
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
|
||||
** 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
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps
|
||||
** 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
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** This is a legacy interface that is preserved for backwards compatibility.
|
||||
** Use of this interface is not recommended.
|
||||
@@ -2507,6 +2518,7 @@ void sqlite3_randomness(int N, void *P);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Compile-Time Authorization Callbacks
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^This routine registers an authorizer callback with a particular
|
||||
** [database connection], supplied in the first argument.
|
||||
@@ -2663,6 +2675,7 @@ int sqlite3_set_authorizer(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Tracing And Profiling Functions
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** These routines register callback functions that can be used for
|
||||
** tracing and profiling the execution of SQL statements.
|
||||
@@ -2695,6 +2708,7 @@ SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
|
||||
|
||||
/*
|
||||
** CAPI3REF: Query Progress Callbacks
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
|
||||
** 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
|
||||
** CONSTRUCTOR: sqlite3
|
||||
**
|
||||
** ^These routines open an SQLite database file as specified by the
|
||||
** 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
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^If the most recent sqlite3_* API call associated with
|
||||
** [database connection] D failed, then the sqlite3_errcode(D) interface
|
||||
@@ -3058,33 +3074,34 @@ const void *sqlite3_errmsg16(sqlite3*);
|
||||
const char *sqlite3_errstr(int);
|
||||
|
||||
/*
|
||||
** CAPI3REF: SQL Statement Object
|
||||
** CAPI3REF: Prepared Statement Object
|
||||
** KEYWORDS: {prepared statement} {prepared statements}
|
||||
**
|
||||
** An instance of this object represents a single SQL statement.
|
||||
** This object is variously known as a "prepared statement" or a
|
||||
** "compiled SQL statement" or simply as a "statement".
|
||||
** An instance of this object represents a single SQL statement that
|
||||
** has been compiled into binary form and is ready to be evaluated.
|
||||
**
|
||||
** 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>
|
||||
** <li> Create the object using [sqlite3_prepare_v2()] or a related
|
||||
** function.
|
||||
** <li> Bind values to [host parameters] using the sqlite3_bind_*()
|
||||
** <li> Create the prepared statement object using [sqlite3_prepare_v2()].
|
||||
** <li> Bind values to [parameters] using the sqlite3_bind_*()
|
||||
** interfaces.
|
||||
** <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.
|
||||
** <li> Destroy the object using [sqlite3_finalize()].
|
||||
** </ol>
|
||||
**
|
||||
** Refer to documentation on individual methods above for additional
|
||||
** information.
|
||||
*/
|
||||
typedef struct sqlite3_stmt sqlite3_stmt;
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-time Limits
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^(This interface allows the size of various constructs to be limited
|
||||
** 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
|
||||
** KEYWORDS: {SQL statement compiler}
|
||||
** METHOD: sqlite3
|
||||
** CONSTRUCTOR: sqlite3_stmt
|
||||
**
|
||||
** To execute an SQL query, it must first be compiled into a byte-code
|
||||
** program using one of these routines.
|
||||
@@ -3303,6 +3322,7 @@ int sqlite3_prepare16_v2(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Retrieving Statement SQL
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** ^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
|
||||
@@ -3312,6 +3332,7 @@ const char *sqlite3_sql(sqlite3_stmt *pStmt);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Determine If An SQL Statement Writes The Database
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
|
||||
** 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
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
|
||||
** [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
|
||||
** KEYWORDS: {host parameter} {host parameters} {host parameter name}
|
||||
** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** ^(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
|
||||
@@ -3535,6 +3558,7 @@ int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Number Of SQL Parameters
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** ^This routine can be used to find the number of [SQL parameters]
|
||||
** 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
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** ^The sqlite3_bind_parameter_name(P,N) interface returns
|
||||
** 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
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** ^Return the index of an SQL parameter given its name. ^The
|
||||
** 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
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset
|
||||
** 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
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** ^Return the number of columns in the result set returned by the
|
||||
** [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
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** ^These routines return the name assigned to a particular column
|
||||
** 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
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** ^These routines provide a means to determine the database, table, and
|
||||
** 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
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** ^(The first parameter is a [prepared statement].
|
||||
** 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
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** After a [prepared statement] has been prepared using either
|
||||
** [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
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** ^The sqlite3_data_count(P) interface returns the number of columns in the
|
||||
** 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
|
||||
** KEYWORDS: {column access functions}
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** 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
|
||||
** DESTRUCTOR: sqlite3_stmt
|
||||
**
|
||||
** ^The sqlite3_finalize() function is called to delete a [prepared statement].
|
||||
** ^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
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** The sqlite3_reset() function is called to reset a [prepared statement]
|
||||
** 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: {application-defined SQL function}
|
||||
** KEYWORDS: {application-defined SQL functions}
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^These functions (collectively known as "function creation routines")
|
||||
** 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
|
||||
** METHOD: sqlite3_value
|
||||
**
|
||||
** The C-language implementation of SQL functions and aggregates uses
|
||||
** 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
|
||||
** METHOD: sqlite3_context
|
||||
**
|
||||
** Implementations of aggregate SQL functions use this
|
||||
** 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
|
||||
** METHOD: sqlite3_context
|
||||
**
|
||||
** ^The sqlite3_user_data() interface returns a copy of
|
||||
** 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
|
||||
** METHOD: sqlite3_context
|
||||
**
|
||||
** ^The sqlite3_context_db_handle() interface returns a copy of
|
||||
** the pointer to the [database connection] (the 1st parameter)
|
||||
@@ -4387,6 +4428,7 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Function Auxiliary Data
|
||||
** METHOD: sqlite3_context
|
||||
**
|
||||
** These functions may be used by (non-aggregate) SQL functions 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
|
||||
** METHOD: sqlite3_context
|
||||
**
|
||||
** These routines are used by the xFunc or xFinal callbacks that
|
||||
** implement SQL functions and aggregates. See
|
||||
@@ -4594,6 +4637,7 @@ void sqlite3_result_zeroblob(sqlite3_context*, int n);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Define New Collating Sequences
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^These functions add, remove, or modify a [collation] associated
|
||||
** with the [database connection] specified as the first argument.
|
||||
@@ -4696,6 +4740,7 @@ int sqlite3_create_collation16(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Collation Needed Callbacks
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^To avoid having to register all collation sequences before a database
|
||||
** 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
|
||||
** KEYWORDS: {autocommit mode}
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^The sqlite3_get_autocommit() interface returns non-zero or
|
||||
** 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
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** ^The sqlite3_db_handle interface returns the [database connection] handle
|
||||
** 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
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename
|
||||
** 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
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^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
|
||||
@@ -4962,6 +5011,7 @@ int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Find the next prepared statement
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^This interface returns a pointer to the next [prepared statement] after
|
||||
** 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
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^The sqlite3_commit_hook() interface registers a callback
|
||||
** 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
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^The sqlite3_update_hook() interface registers a callback function
|
||||
** 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
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap
|
||||
** 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
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns
|
||||
** information about column C of table T in database D
|
||||
@@ -5287,6 +5341,7 @@ int sqlite3_table_column_metadata(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Load An Extension
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^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
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^So as not to open security holes in older applications that are
|
||||
** 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
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^These routines are used to register a new [virtual table module] name.
|
||||
** ^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
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^(Virtual tables can provide alternative implementations of functions
|
||||
** 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
|
||||
** METHOD: sqlite3
|
||||
** CONSTRUCTOR: sqlite3_blob
|
||||
**
|
||||
** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
|
||||
** 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
|
||||
** METHOD: sqlite3_blob
|
||||
**
|
||||
** ^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
|
||||
@@ -5820,6 +5881,7 @@ SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Close A BLOB Handle
|
||||
** DESTRUCTOR: sqlite3_blob
|
||||
**
|
||||
** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed
|
||||
** 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
|
||||
** METHOD: sqlite3_blob
|
||||
**
|
||||
** ^Returns the size in bytes of the BLOB accessible via 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
|
||||
** METHOD: sqlite3_blob
|
||||
**
|
||||
** ^(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
|
||||
@@ -5885,6 +5949,7 @@ int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Write Data Into A BLOB Incrementally
|
||||
** METHOD: sqlite3_blob
|
||||
**
|
||||
** ^(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
|
||||
@@ -6212,6 +6277,7 @@ int sqlite3_mutex_notheld(sqlite3_mutex*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Retrieve the mutex for a database connection
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^This interface returns a pointer the [sqlite3_mutex] object that
|
||||
** 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
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^The [sqlite3_file_control()] interface makes a direct call to the
|
||||
** xFileControl method for the [sqlite3_io_methods] object associated
|
||||
@@ -6439,6 +6506,7 @@ int sqlite3_status64(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Database Connection Status
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^This interface is used to retrieve runtime status information
|
||||
** 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
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** ^(Each prepared statement maintains various
|
||||
** [SQLITE_STMTSTATUS counters] that measure the number
|
||||
@@ -7070,6 +7139,7 @@ int sqlite3_backup_pagecount(sqlite3_backup *p);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Unlock Notification
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^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
|
||||
@@ -7240,6 +7310,7 @@ void sqlite3_log(int iErrCode, const char *zFormat, ...);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Write-Ahead Log Commit Hook
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^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.
|
||||
@@ -7279,6 +7350,7 @@ void *sqlite3_wal_hook(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Configure an auto-checkpoint
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
|
||||
** [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
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to
|
||||
** [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
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^(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
|
||||
@@ -7584,6 +7658,7 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Prepared Statement Scan Status
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** This interface returns information about the predicted and measured
|
||||
** performance for pStmt. Advanced applications can use this
|
||||
@@ -7621,6 +7696,7 @@ SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Zero Scan-Status Counters
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
|
||||
**
|
||||
|
@@ -1226,6 +1226,7 @@ struct sqlite3 {
|
||||
#define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */
|
||||
#define SQLITE_QueryOnly 0x02000000 /* Disable database changes */
|
||||
#define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */
|
||||
#define SQLITE_Vacuum 0x08000000 /* Currently in a VACUUM */
|
||||
|
||||
|
||||
/*
|
||||
|
@@ -430,10 +430,8 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
break;
|
||||
}
|
||||
case TK_ILLEGAL: {
|
||||
sqlite3DbFree(db, *pzErrMsg);
|
||||
*pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"",
|
||||
sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"",
|
||||
&pParse->sLastToken);
|
||||
nErr++;
|
||||
goto abort_parse;
|
||||
}
|
||||
case TK_SEMI: {
|
||||
@@ -451,7 +449,8 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
}
|
||||
}
|
||||
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 ){
|
||||
sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
|
||||
pParse->zTail = &zSql[i];
|
||||
|
@@ -680,7 +680,6 @@ static SrcList *targetSrcList(
|
||||
pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
|
||||
if( pSrc ){
|
||||
assert( pSrc->nSrc>0 );
|
||||
assert( pSrc->a!=0 );
|
||||
iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
|
||||
if( iDb==0 || iDb>=2 ){
|
||||
sqlite3 *db = pParse->db;
|
||||
|
@@ -250,6 +250,8 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|
||||
** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
|
||||
** the contents to the temporary database.
|
||||
*/
|
||||
assert( (db->flags & SQLITE_Vacuum)==0 );
|
||||
db->flags |= SQLITE_Vacuum;
|
||||
rc = execExecSql(db, pzErrMsg,
|
||||
"SELECT 'INSERT INTO vacuum_db.' || quote(name) "
|
||||
"|| ' SELECT * FROM main.' || quote(name) || ';'"
|
||||
@@ -257,6 +259,8 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|
||||
"WHERE type = 'table' AND name!='sqlite_sequence' "
|
||||
" AND coalesce(rootpage,1)>0"
|
||||
);
|
||||
assert( (db->flags & SQLITE_Vacuum)!=0 );
|
||||
db->flags &= ~SQLITE_Vacuum;
|
||||
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
||||
|
||||
/* Copy over the sequence table
|
||||
|
299
src/vdbe.c
299
src/vdbe.c
@@ -514,6 +514,21 @@ static int checkSavepointCount(sqlite3 *db){
|
||||
}
|
||||
#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.
|
||||
@@ -522,9 +537,8 @@ static int checkSavepointCount(sqlite3 *db){
|
||||
int sqlite3VdbeExec(
|
||||
Vdbe *p /* The VDBE */
|
||||
){
|
||||
int pc=0; /* The program counter */
|
||||
Op *aOp = p->aOp; /* Copy of p->aOp */
|
||||
Op *pOp; /* Current operation */
|
||||
Op *pOp = aOp; /* Current operation */
|
||||
int rc = SQLITE_OK; /* Value to return */
|
||||
sqlite3 *db = p->db; /* The database */
|
||||
u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
|
||||
@@ -600,23 +614,22 @@ int sqlite3VdbeExec(
|
||||
}
|
||||
sqlite3EndBenignMalloc();
|
||||
#endif
|
||||
for(pc=p->pc; rc==SQLITE_OK; pc++){
|
||||
assert( pc>=0 && pc<p->nOp );
|
||||
for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){
|
||||
assert( pOp>=aOp && pOp<&aOp[p->nOp]);
|
||||
if( db->mallocFailed ) goto no_mem;
|
||||
#ifdef VDBE_PROFILE
|
||||
start = sqlite3Hwtime();
|
||||
#endif
|
||||
nVmStep++;
|
||||
pOp = &aOp[pc];
|
||||
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
if( p->anExec ) p->anExec[pc]++;
|
||||
if( p->anExec ) p->anExec[(int)(pOp-aOp)]++;
|
||||
#endif
|
||||
|
||||
/* Only allow tracing if SQLITE_DEBUG is defined.
|
||||
*/
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( db->flags & SQLITE_VdbeTrace ){
|
||||
sqlite3VdbePrintOp(stdout, pc, pOp);
|
||||
sqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -633,23 +646,9 @@ int sqlite3VdbeExec(
|
||||
}
|
||||
#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 */
|
||||
#ifdef SQLITE_DEBUG
|
||||
assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
|
||||
if( (pOp->opflags & OPFLG_IN1)!=0 ){
|
||||
assert( pOp->p1>0 );
|
||||
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
|
||||
** 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.
|
||||
**
|
||||
** 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.
|
||||
*/
|
||||
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,
|
||||
** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon
|
||||
@@ -778,9 +778,13 @@ case OP_Gosub: { /* jump */
|
||||
assert( VdbeMemDynamic(pIn1)==0 );
|
||||
memAboutToChange(p, pIn1);
|
||||
pIn1->flags = MEM_Int;
|
||||
pIn1->u.i = pc;
|
||||
pIn1->u.i = (int)(pOp-aOp);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -792,7 +796,7 @@ case OP_Gosub: { /* jump */
|
||||
case OP_Return: { /* in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
assert( pIn1->flags==MEM_Int );
|
||||
pc = (int)pIn1->u.i;
|
||||
pOp = &aOp[pIn1->u.i];
|
||||
pIn1->flags = MEM_Undefined;
|
||||
break;
|
||||
}
|
||||
@@ -816,7 +820,7 @@ case OP_InitCoroutine: { /* jump */
|
||||
assert( !VdbeMemDynamic(pOut) );
|
||||
pOut->u.i = pOp->p3 - 1;
|
||||
pOut->flags = MEM_Int;
|
||||
if( pOp->p2 ) pc = pOp->p2 - 1;
|
||||
if( pOp->p2 ) goto jump_to_p2;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -836,7 +840,7 @@ case OP_EndCoroutine: { /* in1 */
|
||||
pCaller = &aOp[pIn1->u.i];
|
||||
assert( pCaller->opcode==OP_Yield );
|
||||
assert( pCaller->p2>=0 && pCaller->p2<p->nOp );
|
||||
pc = pCaller->p2 - 1;
|
||||
pOp = &aOp[pCaller->p2 - 1];
|
||||
pIn1->flags = MEM_Undefined;
|
||||
break;
|
||||
}
|
||||
@@ -860,9 +864,9 @@ case OP_Yield: { /* in1, jump */
|
||||
assert( VdbeMemDynamic(pIn1)==0 );
|
||||
pIn1->flags = MEM_Int;
|
||||
pcDest = (int)pIn1->u.i;
|
||||
pIn1->u.i = pc;
|
||||
pIn1->u.i = (int)(pOp - aOp);
|
||||
REGISTER_TRACE(pOp->p1, pIn1);
|
||||
pc = pcDest;
|
||||
pOp = &aOp[pcDest];
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -913,30 +917,34 @@ case OP_HaltIfNull: { /* in3 */
|
||||
case OP_Halt: {
|
||||
const char *zType;
|
||||
const char *zLogFmt;
|
||||
VdbeFrame *pFrame;
|
||||
int pcx;
|
||||
|
||||
pcx = (int)(pOp - aOp);
|
||||
if( pOp->p1==SQLITE_OK && p->pFrame ){
|
||||
/* Halt the sub-program. Return control to the parent frame. */
|
||||
VdbeFrame *pFrame = p->pFrame;
|
||||
pFrame = p->pFrame;
|
||||
p->pFrame = pFrame->pParent;
|
||||
p->nFrame--;
|
||||
sqlite3VdbeSetChanges(db, p->nChange);
|
||||
pc = sqlite3VdbeFrameRestore(pFrame);
|
||||
pcx = sqlite3VdbeFrameRestore(pFrame);
|
||||
lastRowid = db->lastRowid;
|
||||
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
|
||||
** instruction is set to OE_Ignore, then the sub-program is throwing
|
||||
** an IGNORE exception. In this case jump to the address specified
|
||||
** as the p2 of the calling OP_Program. */
|
||||
pc = p->aOp[pc].p2-1;
|
||||
pcx = p->aOp[pcx].p2-1;
|
||||
}
|
||||
aOp = p->aOp;
|
||||
aMem = p->aMem;
|
||||
pOp = &aOp[pcx];
|
||||
break;
|
||||
}
|
||||
p->rc = pOp->p1;
|
||||
p->errorAction = (u8)pOp->p2;
|
||||
p->pc = pc;
|
||||
p->pc = pcx;
|
||||
if( p->rc ){
|
||||
if( pOp->p5 ){
|
||||
static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
|
||||
@@ -960,7 +968,7 @@ case OP_Halt: {
|
||||
}else{
|
||||
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);
|
||||
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 );
|
||||
rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
|
||||
}
|
||||
pOp = &aOp[pcx];
|
||||
goto vdbe_return;
|
||||
}
|
||||
|
||||
@@ -979,7 +988,8 @@ case OP_Halt: {
|
||||
**
|
||||
** 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;
|
||||
break;
|
||||
}
|
||||
@@ -990,7 +1000,8 @@ case OP_Integer: { /* out2-prerelease */
|
||||
** P4 is a pointer to a 64-bit integer value.
|
||||
** Write that value into register P2.
|
||||
*/
|
||||
case OP_Int64: { /* out2-prerelease */
|
||||
case OP_Int64: { /* out2 */
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
assert( pOp->p4.pI64!=0 );
|
||||
pOut->u.i = *pOp->p4.pI64;
|
||||
break;
|
||||
@@ -1003,7 +1014,8 @@ case OP_Int64: { /* out2-prerelease */
|
||||
** P4 is a pointer to a 64-bit floating point value.
|
||||
** 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;
|
||||
assert( !sqlite3IsNaN(*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
|
||||
** 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 );
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
pOp->opcode = OP_String;
|
||||
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
|
||||
** of a string, as if it had been CAST.
|
||||
*/
|
||||
case OP_String: { /* out2-prerelease */
|
||||
case OP_String: { /* out2 */
|
||||
assert( pOp->p4.z!=0 );
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
|
||||
pOut->z = pOp->p4.z;
|
||||
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
|
||||
** OP_Ne or OP_Eq.
|
||||
*/
|
||||
case OP_Null: { /* out2-prerelease */
|
||||
case OP_Null: { /* out2 */
|
||||
int cnt;
|
||||
u16 nullFlag;
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
cnt = pOp->p3-pOp->p2;
|
||||
assert( pOp->p3<=(p->nMem-p->nCursor) );
|
||||
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
|
||||
** blob in register P2.
|
||||
*/
|
||||
case OP_Blob: { /* out2-prerelease */
|
||||
case OP_Blob: { /* out2 */
|
||||
assert( pOp->p1 <= SQLITE_MAX_LENGTH );
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
|
||||
pOut->enc = encoding;
|
||||
UPDATE_MAX_BLOBSIZE(pOut);
|
||||
@@ -1139,7 +1155,7 @@ case OP_Blob: { /* out2-prerelease */
|
||||
** If the parameter is named, then its name appears in P4.
|
||||
** The P4 value is used by sqlite3_bind_parameter_name().
|
||||
*/
|
||||
case OP_Variable: { /* out2-prerelease */
|
||||
case OP_Variable: { /* out2 */
|
||||
Mem *pVar; /* Value being transferred */
|
||||
|
||||
assert( pOp->p1>0 && pOp->p1<=p->nVar );
|
||||
@@ -1148,6 +1164,7 @@ case OP_Variable: { /* out2-prerelease */
|
||||
if( sqlite3VdbeMemTooBig(pVar) ){
|
||||
goto too_big;
|
||||
}
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
|
||||
UPDATE_MAX_BLOBSIZE(pOut);
|
||||
break;
|
||||
@@ -1324,7 +1341,7 @@ case OP_ResultRow: {
|
||||
|
||||
/* Return SQLITE_ROW
|
||||
*/
|
||||
p->pc = pc + 1;
|
||||
p->pc = (int)(pOp - aOp) + 1;
|
||||
rc = SQLITE_ROW;
|
||||
goto vdbe_return;
|
||||
}
|
||||
@@ -1570,7 +1587,7 @@ case OP_Function: {
|
||||
|
||||
assert( pOp->p4type==P4_FUNCDEF );
|
||||
ctx.pFunc = pOp->p4.pFunc;
|
||||
ctx.iOp = pc;
|
||||
ctx.iOp = (int)(pOp - aOp);
|
||||
ctx.pVdbe = p;
|
||||
MemSetTypeFlag(ctx.pOut, MEM_Null);
|
||||
ctx.fErrorOrAux = 0;
|
||||
@@ -1584,7 +1601,7 @@ case OP_Function: {
|
||||
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
|
||||
rc = ctx.isError;
|
||||
}
|
||||
sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
|
||||
sqlite3VdbeDeleteAuxData(p, (int)(pOp - aOp), pOp->p1);
|
||||
}
|
||||
|
||||
/* Copy the result of the function into register P3 */
|
||||
@@ -1713,8 +1730,7 @@ case OP_MustBeInt: { /* jump, in1 */
|
||||
rc = SQLITE_MISMATCH;
|
||||
goto abort_due_to_error;
|
||||
}else{
|
||||
pc = pOp->p2 - 1;
|
||||
break;
|
||||
goto jump_to_p2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1900,7 +1916,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
||||
}else{
|
||||
VdbeBranchTaken(2,3);
|
||||
if( pOp->p5 & SQLITE_JUMPIFNULL ){
|
||||
pc = pOp->p2-1;
|
||||
goto jump_to_p2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1952,6 +1968,12 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
||||
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 ){
|
||||
pOut = &aMem[pOp->p2];
|
||||
memAboutToChange(p, pOut);
|
||||
@@ -1961,14 +1983,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
||||
}else{
|
||||
VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -2063,11 +2080,11 @@ case OP_Compare: {
|
||||
*/
|
||||
case OP_Jump: { /* jump */
|
||||
if( iCompare<0 ){
|
||||
pc = pOp->p1 - 1; VdbeBranchTaken(0,3);
|
||||
VdbeBranchTaken(0,3); pOp = &aOp[pOp->p1 - 1];
|
||||
}else if( iCompare==0 ){
|
||||
pc = pOp->p2 - 1; VdbeBranchTaken(1,3);
|
||||
VdbeBranchTaken(1,3); pOp = &aOp[pOp->p2 - 1];
|
||||
}else{
|
||||
pc = pOp->p3 - 1; VdbeBranchTaken(2,3);
|
||||
VdbeBranchTaken(2,3); pOp = &aOp[pOp->p3 - 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2177,7 +2194,7 @@ case OP_Once: { /* jump */
|
||||
assert( pOp->p1<p->nOnceFlag );
|
||||
VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2);
|
||||
if( p->aOnceFlag[pOp->p1] ){
|
||||
pc = pOp->p2-1;
|
||||
goto jump_to_p2;
|
||||
}else{
|
||||
p->aOnceFlag[pOp->p1] = 1;
|
||||
}
|
||||
@@ -2212,7 +2229,7 @@ case OP_IfNot: { /* jump, in1 */
|
||||
}
|
||||
VdbeBranchTaken(c!=0, 2);
|
||||
if( c ){
|
||||
pc = pOp->p2-1;
|
||||
goto jump_to_p2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2226,7 +2243,7 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2);
|
||||
if( (pIn1->flags & MEM_Null)!=0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
goto jump_to_p2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2240,7 +2257,7 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
VdbeBranchTaken( (pIn1->flags & MEM_Null)==0, 2);
|
||||
if( (pIn1->flags & MEM_Null)==0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
goto jump_to_p2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2578,7 +2595,7 @@ case OP_MakeRecord: {
|
||||
u64 nData; /* Number of bytes of data space */
|
||||
int nHdr; /* Number of bytes of header space */
|
||||
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 */
|
||||
u32 serial_type; /* Type field */
|
||||
Mem *pData0; /* First field to be combined into the record */
|
||||
@@ -2670,7 +2687,7 @@ case OP_MakeRecord: {
|
||||
if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
|
||||
}
|
||||
nByte = nHdr+nData;
|
||||
if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
|
||||
if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
|
||||
goto too_big;
|
||||
}
|
||||
|
||||
@@ -2721,7 +2738,7 @@ case OP_MakeRecord: {
|
||||
** opened by cursor P1 in register P2
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_BTREECOUNT
|
||||
case OP_Count: { /* out2-prerelease */
|
||||
case OP_Count: { /* out2 */
|
||||
i64 nEntry;
|
||||
BtCursor *pCrsr;
|
||||
|
||||
@@ -2729,6 +2746,7 @@ case OP_Count: { /* out2-prerelease */
|
||||
assert( pCrsr );
|
||||
nEntry = 0; /* Not needed. Only used to silence a warning. */
|
||||
rc = sqlite3BtreeCount(pCrsr, &nEntry);
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
pOut->u.i = nEntry;
|
||||
break;
|
||||
}
|
||||
@@ -2842,7 +2860,7 @@ case OP_Savepoint: {
|
||||
}
|
||||
db->autoCommit = 1;
|
||||
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
|
||||
p->pc = pc;
|
||||
p->pc = (int)(pOp - aOp);
|
||||
db->autoCommit = 0;
|
||||
p->rc = rc = SQLITE_BUSY;
|
||||
goto vdbe_return;
|
||||
@@ -2961,7 +2979,7 @@ case OP_AutoCommit: {
|
||||
}else{
|
||||
db->autoCommit = (u8)desiredAutoCommit;
|
||||
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
|
||||
p->pc = pc;
|
||||
p->pc = (int)(pOp - aOp);
|
||||
db->autoCommit = (u8)(1-desiredAutoCommit);
|
||||
p->rc = rc = SQLITE_BUSY;
|
||||
goto vdbe_return;
|
||||
@@ -3038,7 +3056,7 @@ case OP_Transaction: {
|
||||
if( pBt ){
|
||||
rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
|
||||
if( rc==SQLITE_BUSY ){
|
||||
p->pc = pc;
|
||||
p->pc = (int)(pOp - aOp);
|
||||
p->rc = rc = SQLITE_BUSY;
|
||||
goto vdbe_return;
|
||||
}
|
||||
@@ -3117,7 +3135,7 @@ case OP_Transaction: {
|
||||
** must be started or there must be an open cursor) before
|
||||
** executing this instruction.
|
||||
*/
|
||||
case OP_ReadCookie: { /* out2-prerelease */
|
||||
case OP_ReadCookie: { /* out2 */
|
||||
int iMeta;
|
||||
int iDb;
|
||||
int iCookie;
|
||||
@@ -3131,6 +3149,7 @@ case OP_ReadCookie: { /* out2-prerelease */
|
||||
assert( DbMaskTest(p->btreeMask, iDb) );
|
||||
|
||||
sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
pOut->u.i = iMeta;
|
||||
break;
|
||||
}
|
||||
@@ -3452,7 +3471,7 @@ case OP_SequenceTest: {
|
||||
pC = p->apCsr[pOp->p1];
|
||||
assert( pC->pSorter );
|
||||
if( (pC->seqCount++)==0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
goto jump_to_p2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -3629,7 +3648,7 @@ case OP_SeekGT: { /* jump, in3 */
|
||||
if( (pIn3->flags & MEM_Real)==0 ){
|
||||
/* If the P3 value cannot be converted into any kind of a number,
|
||||
** 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;
|
||||
}
|
||||
|
||||
@@ -3720,7 +3739,7 @@ case OP_SeekGT: { /* jump, in3 */
|
||||
assert( pOp->p2>0 );
|
||||
VdbeBranchTaken(res!=0,2);
|
||||
if( res ){
|
||||
pc = pOp->p2 - 1;
|
||||
goto jump_to_p2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -3814,6 +3833,7 @@ case OP_NoConflict: /* jump, in3 */
|
||||
case OP_NotFound: /* jump, in3 */
|
||||
case OP_Found: { /* jump, in3 */
|
||||
int alreadyExists;
|
||||
int takeJump;
|
||||
int ii;
|
||||
VdbeCursor *pC;
|
||||
int res;
|
||||
@@ -3836,7 +3856,7 @@ case OP_Found: { /* jump, in3 */
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
assert( pC->pCursor!=0 );
|
||||
assert( pC->isTable==0 );
|
||||
pFree = 0; /* Not needed. Only used to suppress a compiler warning. */
|
||||
pFree = 0;
|
||||
if( pOp->p4.i>0 ){
|
||||
r.pKeyInfo = pC->pKeyInfo;
|
||||
r.nField = (u16)pOp->p4.i;
|
||||
@@ -3859,21 +3879,20 @@ case OP_Found: { /* jump, in3 */
|
||||
sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
|
||||
}
|
||||
pIdxKey->default_rc = 0;
|
||||
takeJump = 0;
|
||||
if( pOp->opcode==OP_NoConflict ){
|
||||
/* For the OP_NoConflict opcode, take the jump if any of the
|
||||
** input fields are NULL, since any key with a NULL will not
|
||||
** conflict */
|
||||
for(ii=0; ii<pIdxKey->nField; ii++){
|
||||
if( pIdxKey->aMem[ii].flags & MEM_Null ){
|
||||
pc = pOp->p2 - 1; VdbeBranchTaken(1,2);
|
||||
takeJump = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res);
|
||||
if( pOp->p4.i==0 ){
|
||||
sqlite3DbFree(db, pFree);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
break;
|
||||
}
|
||||
@@ -3884,10 +3903,10 @@ case OP_Found: { /* jump, in3 */
|
||||
pC->cacheStatus = CACHE_STALE;
|
||||
if( pOp->opcode==OP_Found ){
|
||||
VdbeBranchTaken(alreadyExists!=0,2);
|
||||
if( alreadyExists ) pc = pOp->p2 - 1;
|
||||
if( alreadyExists ) goto jump_to_p2;
|
||||
}else{
|
||||
VdbeBranchTaken(alreadyExists==0,2);
|
||||
if( !alreadyExists ) pc = pOp->p2 - 1;
|
||||
VdbeBranchTaken(takeJump||alreadyExists==0,2);
|
||||
if( takeJump || !alreadyExists ) goto jump_to_p2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -3936,10 +3955,8 @@ case OP_NotExists: { /* jump, in3 */
|
||||
pC->cacheStatus = CACHE_STALE;
|
||||
pC->deferredMoveto = 0;
|
||||
VdbeBranchTaken(res!=0,2);
|
||||
if( res!=0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
pC->seekResult = res;
|
||||
if( res!=0 ) goto jump_to_p2;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3951,9 +3968,10 @@ case OP_NotExists: { /* jump, in3 */
|
||||
** The sequence number on the cursor is incremented after this
|
||||
** instruction.
|
||||
*/
|
||||
case OP_Sequence: { /* out2-prerelease */
|
||||
case OP_Sequence: { /* out2 */
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
assert( p->apCsr[pOp->p1]!=0 );
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
|
||||
break;
|
||||
}
|
||||
@@ -3974,7 +3992,7 @@ case OP_Sequence: { /* out2-prerelease */
|
||||
** generated record number. This P3 mechanism is used to help implement the
|
||||
** AUTOINCREMENT feature.
|
||||
*/
|
||||
case OP_NewRowid: { /* out2-prerelease */
|
||||
case OP_NewRowid: { /* out2 */
|
||||
i64 v; /* The new rowid */
|
||||
VdbeCursor *pC; /* Cursor of table to get the new rowid */
|
||||
int res; /* Result of an sqlite3BtreeLast() */
|
||||
@@ -3984,6 +4002,7 @@ case OP_NewRowid: { /* out2-prerelease */
|
||||
|
||||
v = 0;
|
||||
res = 0;
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
assert( pC!=0 );
|
||||
@@ -4297,9 +4316,7 @@ case OP_SorterCompare: {
|
||||
res = 0;
|
||||
rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res);
|
||||
VdbeBranchTaken(res!=0,2);
|
||||
if( res ){
|
||||
pc = pOp->p2-1;
|
||||
}
|
||||
if( res ) goto jump_to_p2;
|
||||
break;
|
||||
};
|
||||
|
||||
@@ -4428,12 +4445,13 @@ case OP_RowData: {
|
||||
** be a separate OP_VRowid opcode for use with virtual tables, but this
|
||||
** one opcode now works for both table types.
|
||||
*/
|
||||
case OP_Rowid: { /* out2-prerelease */
|
||||
case OP_Rowid: { /* out2 */
|
||||
VdbeCursor *pC;
|
||||
i64 v;
|
||||
sqlite3_vtab *pVtab;
|
||||
const sqlite3_module *pModule;
|
||||
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
assert( pC!=0 );
|
||||
@@ -4486,7 +4504,7 @@ case OP_NullRow: {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: Last P1 P2 * * *
|
||||
/* Opcode: Last P1 P2 P3 * *
|
||||
**
|
||||
** 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.
|
||||
@@ -4513,12 +4531,13 @@ case OP_Last: { /* jump */
|
||||
pC->nullRow = (u8)res;
|
||||
pC->deferredMoveto = 0;
|
||||
pC->cacheStatus = CACHE_STALE;
|
||||
pC->seekResult = pOp->p3;
|
||||
#ifdef SQLITE_DEBUG
|
||||
pC->seekOp = OP_Last;
|
||||
#endif
|
||||
if( pOp->p2>0 ){
|
||||
VdbeBranchTaken(res!=0,2);
|
||||
if( res ) pc = pOp->p2 - 1;
|
||||
if( res ) goto jump_to_p2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -4582,9 +4601,7 @@ case OP_Rewind: { /* jump */
|
||||
pC->nullRow = (u8)res;
|
||||
assert( pOp->p2>0 && pOp->p2<p->nOp );
|
||||
VdbeBranchTaken(res!=0,2);
|
||||
if( res ){
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
if( res ) goto jump_to_p2;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4695,11 +4712,11 @@ next_tail:
|
||||
VdbeBranchTaken(res==0,2);
|
||||
if( res==0 ){
|
||||
pC->nullRow = 0;
|
||||
pc = pOp->p2 - 1;
|
||||
p->aCounter[pOp->p5]++;
|
||||
#ifdef SQLITE_TEST
|
||||
sqlite3_search_count++;
|
||||
#endif
|
||||
goto jump_to_p2_and_check_for_interrupt;
|
||||
}else{
|
||||
pC->nullRow = 1;
|
||||
}
|
||||
@@ -4807,11 +4824,12 @@ case OP_IdxDelete: {
|
||||
**
|
||||
** See also: Rowid, MakeRecord.
|
||||
*/
|
||||
case OP_IdxRowid: { /* out2-prerelease */
|
||||
case OP_IdxRowid: { /* out2 */
|
||||
BtCursor *pCrsr;
|
||||
VdbeCursor *pC;
|
||||
i64 rowid;
|
||||
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
assert( pC!=0 );
|
||||
@@ -4924,9 +4942,7 @@ case OP_IdxGE: { /* jump */
|
||||
res++;
|
||||
}
|
||||
VdbeBranchTaken(res>0,2);
|
||||
if( res>0 ){
|
||||
pc = pOp->p2 - 1 ;
|
||||
}
|
||||
if( res>0 ) goto jump_to_p2;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4950,11 +4966,12 @@ case OP_IdxGE: { /* jump */
|
||||
**
|
||||
** See also: Clear
|
||||
*/
|
||||
case OP_Destroy: { /* out2-prerelease */
|
||||
case OP_Destroy: { /* out2 */
|
||||
int iMoved;
|
||||
int iDb;
|
||||
|
||||
assert( p->readOnly==0 );
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
pOut->flags = MEM_Null;
|
||||
if( db->nVdbeRead > db->nVDestroy+1 ){
|
||||
rc = SQLITE_LOCKED;
|
||||
@@ -5063,12 +5080,13 @@ case OP_ResetSorter: {
|
||||
**
|
||||
** See documentation on OP_CreateTable for additional information.
|
||||
*/
|
||||
case OP_CreateIndex: /* out2-prerelease */
|
||||
case OP_CreateTable: { /* out2-prerelease */
|
||||
case OP_CreateIndex: /* out2 */
|
||||
case OP_CreateTable: { /* out2 */
|
||||
int pgno;
|
||||
int flags;
|
||||
Db *pDb;
|
||||
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
pgno = 0;
|
||||
assert( pOp->p1>=0 && pOp->p1<db->nDb );
|
||||
assert( DbMaskTest(p->btreeMask, pOp->p1) );
|
||||
@@ -5294,12 +5312,12 @@ case OP_RowSetRead: { /* jump, in1, out3 */
|
||||
){
|
||||
/* The boolean index is empty */
|
||||
sqlite3VdbeMemSetNull(pIn1);
|
||||
pc = pOp->p2 - 1;
|
||||
VdbeBranchTaken(1,2);
|
||||
goto jump_to_p2_and_check_for_interrupt;
|
||||
}else{
|
||||
/* A value was pulled from the index */
|
||||
sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
|
||||
VdbeBranchTaken(0,2);
|
||||
sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
|
||||
}
|
||||
goto check_for_interrupt;
|
||||
}
|
||||
@@ -5350,10 +5368,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */
|
||||
if( iSet ){
|
||||
exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i);
|
||||
VdbeBranchTaken(exists!=0,2);
|
||||
if( exists ){
|
||||
pc = pOp->p2 - 1;
|
||||
break;
|
||||
}
|
||||
if( exists ) goto jump_to_p2;
|
||||
}
|
||||
if( iSet>=0 ){
|
||||
sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
|
||||
@@ -5442,7 +5457,7 @@ case OP_Program: { /* jump */
|
||||
pFrame->v = p;
|
||||
pFrame->nChildMem = nMem;
|
||||
pFrame->nChildCsr = pProgram->nCsr;
|
||||
pFrame->pc = pc;
|
||||
pFrame->pc = (int)(pOp - aOp);
|
||||
pFrame->aMem = p->aMem;
|
||||
pFrame->nMem = p->nMem;
|
||||
pFrame->apCsr = p->apCsr;
|
||||
@@ -5465,7 +5480,7 @@ case OP_Program: { /* jump */
|
||||
pFrame = pRt->u.pFrame;
|
||||
assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
|
||||
assert( pProgram->nCsr==pFrame->nChildCsr );
|
||||
assert( pc==pFrame->pc );
|
||||
assert( (int)(pOp - aOp)==pFrame->pc );
|
||||
}
|
||||
|
||||
p->nFrame++;
|
||||
@@ -5486,7 +5501,7 @@ case OP_Program: { /* jump */
|
||||
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
p->anExec = 0;
|
||||
#endif
|
||||
pc = -1;
|
||||
pOp = &aOp[-1];
|
||||
memset(p->aOnceFlag, 0, p->nOnceFlag);
|
||||
|
||||
break;
|
||||
@@ -5504,9 +5519,10 @@ case OP_Program: { /* jump */
|
||||
** the value of the P1 argument to the value of the P1 argument to the
|
||||
** calling OP_Program instruction.
|
||||
*/
|
||||
case OP_Param: { /* out2-prerelease */
|
||||
case OP_Param: { /* out2 */
|
||||
VdbeFrame *pFrame;
|
||||
Mem *pIn;
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
pFrame = p->pFrame;
|
||||
pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1];
|
||||
sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem);
|
||||
@@ -5550,10 +5566,10 @@ case OP_FkCounter: {
|
||||
case OP_FkIfZero: { /* jump */
|
||||
if( pOp->p1 ){
|
||||
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{
|
||||
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;
|
||||
}
|
||||
@@ -5604,9 +5620,7 @@ case OP_IfPos: { /* jump, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
assert( pIn1->flags&MEM_Int );
|
||||
VdbeBranchTaken( pIn1->u.i>0, 2);
|
||||
if( pIn1->u.i>0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
if( pIn1->u.i>0 ) goto jump_to_p2;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -5621,9 +5635,7 @@ case OP_IfNeg: { /* jump, in1 */
|
||||
assert( pIn1->flags&MEM_Int );
|
||||
pIn1->u.i += pOp->p3;
|
||||
VdbeBranchTaken(pIn1->u.i<0, 2);
|
||||
if( pIn1->u.i<0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
if( pIn1->u.i<0 ) goto jump_to_p2;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -5640,7 +5652,7 @@ case OP_IfNotZero: { /* jump, in1 */
|
||||
VdbeBranchTaken(pIn1->u.i<0, 2);
|
||||
if( pIn1->u.i ){
|
||||
pIn1->u.i += pOp->p3;
|
||||
pc = pOp->p2 - 1;
|
||||
goto jump_to_p2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -5656,9 +5668,7 @@ case OP_DecrJumpZero: { /* jump, in1 */
|
||||
assert( pIn1->flags&MEM_Int );
|
||||
pIn1->u.i--;
|
||||
VdbeBranchTaken(pIn1->u.i==0, 2);
|
||||
if( pIn1->u.i==0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
if( pIn1->u.i==0 ) goto jump_to_p2;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -5674,9 +5684,7 @@ case OP_JumpZeroIncr: { /* jump, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
assert( pIn1->flags&MEM_Int );
|
||||
VdbeBranchTaken(pIn1->u.i==0, 2);
|
||||
if( (pIn1->u.i++)==0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
if( (pIn1->u.i++)==0 ) goto jump_to_p2;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -5718,7 +5726,7 @@ case OP_AggStep: {
|
||||
ctx.pOut = &t;
|
||||
ctx.isError = 0;
|
||||
ctx.pVdbe = p;
|
||||
ctx.iOp = pc;
|
||||
ctx.iOp = (int)(pOp - aOp);
|
||||
ctx.skipFlag = 0;
|
||||
(ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
|
||||
if( ctx.isError ){
|
||||
@@ -5813,7 +5821,7 @@ case OP_Checkpoint: {
|
||||
**
|
||||
** 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 */
|
||||
Pager *pPager; /* Pager associated with pBt */
|
||||
int eNew; /* New journal mode */
|
||||
@@ -5822,6 +5830,7 @@ case OP_JournalMode: { /* out2-prerelease */
|
||||
const char *zFilename; /* Name of database file for pPager */
|
||||
#endif
|
||||
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
eNew = pOp->p3;
|
||||
assert( eNew==PAGER_JOURNALMODE_DELETE
|
||||
|| eNew==PAGER_JOURNALMODE_TRUNCATE
|
||||
@@ -5938,8 +5947,8 @@ case OP_IncrVacuum: { /* jump */
|
||||
rc = sqlite3BtreeIncrVacuum(pBt);
|
||||
VdbeBranchTaken(rc==SQLITE_DONE,2);
|
||||
if( rc==SQLITE_DONE ){
|
||||
pc = pOp->p2 - 1;
|
||||
rc = SQLITE_OK;
|
||||
goto jump_to_p2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -6149,25 +6158,19 @@ case OP_VFilter: { /* jump */
|
||||
iQuery = (int)pQuery->u.i;
|
||||
|
||||
/* Invoke the xFilter method */
|
||||
{
|
||||
res = 0;
|
||||
apArg = p->apArg;
|
||||
for(i = 0; i<nArg; i++){
|
||||
apArg[i] = &pArgc[i+1];
|
||||
}
|
||||
|
||||
rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
|
||||
sqlite3VtabImportErrmsg(p, pVtab);
|
||||
if( rc==SQLITE_OK ){
|
||||
res = pModule->xEof(pVtabCursor);
|
||||
}
|
||||
VdbeBranchTaken(res!=0,2);
|
||||
if( res ){
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
}
|
||||
pCur->nullRow = 0;
|
||||
|
||||
VdbeBranchTaken(res!=0,2);
|
||||
if( res ) goto jump_to_p2;
|
||||
break;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
@@ -6254,7 +6257,7 @@ case OP_VNext: { /* jump */
|
||||
VdbeBranchTaken(!res,2);
|
||||
if( !res ){
|
||||
/* If there is data, jump to P2 */
|
||||
pc = pOp->p2 - 1;
|
||||
goto jump_to_p2_and_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.
|
||||
*/
|
||||
case OP_Pagecount: { /* out2-prerelease */
|
||||
case OP_Pagecount: { /* out2 */
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt);
|
||||
break;
|
||||
}
|
||||
@@ -6393,10 +6397,11 @@ case OP_Pagecount: { /* out2-prerelease */
|
||||
**
|
||||
** Store the maximum page count after the change in register P2.
|
||||
*/
|
||||
case OP_MaxPgcnt: { /* out2-prerelease */
|
||||
case OP_MaxPgcnt: { /* out2 */
|
||||
unsigned int newMax;
|
||||
Btree *pBt;
|
||||
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
pBt = db->aDb[pOp->p1].pBt;
|
||||
newMax = 0;
|
||||
if( pOp->p3 ){
|
||||
@@ -6425,9 +6430,6 @@ case OP_Init: { /* jump */
|
||||
char *zTrace;
|
||||
char *z;
|
||||
|
||||
if( pOp->p2 ){
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_TRACE
|
||||
if( db->xTrace
|
||||
&& !p->doingRerun
|
||||
@@ -6455,6 +6457,7 @@ case OP_Init: { /* jump */
|
||||
}
|
||||
#endif /* SQLITE_DEBUG */
|
||||
#endif /* SQLITE_OMIT_TRACE */
|
||||
if( pOp->p2 ) goto jump_to_p2;
|
||||
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.
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
assert( pc>=-1 && pc<p->nOp );
|
||||
assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp] );
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( db->flags & SQLITE_VdbeTrace ){
|
||||
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]);
|
||||
}
|
||||
if( pOp->opflags & OPFLG_OUT3 ){
|
||||
@@ -6521,7 +6524,7 @@ vdbe_error_halt:
|
||||
p->rc = rc;
|
||||
testcase( sqlite3GlobalConfig.xLog!=0 );
|
||||
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
|
||||
pc, p->zSql, p->zErrMsg);
|
||||
(int)(pOp - aOp), p->zSql, p->zErrMsg);
|
||||
sqlite3VdbeHalt(p);
|
||||
if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
|
||||
rc = SQLITE_ERROR;
|
||||
|
@@ -213,6 +213,7 @@ int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
|
||||
|
||||
void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
|
||||
int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
|
||||
int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int);
|
||||
UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
|
||||
|
||||
typedef int (*RecordCompare)(int,const void*,UnpackedRecord*);
|
||||
|
@@ -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
|
||||
** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db).
|
||||
*/
|
||||
static int vdbeRecordCompareWithSkip(
|
||||
int sqlite3VdbeRecordCompareWithSkip(
|
||||
int nKey1, const void *pKey1, /* Left key */
|
||||
UnpackedRecord *pPKey2, /* Right key */
|
||||
int bSkip /* If true, skip the first field */
|
||||
@@ -3771,7 +3771,7 @@ int sqlite3VdbeRecordCompare(
|
||||
int nKey1, const void *pKey1, /* Left 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 ){
|
||||
/* The first fields of the two keys are equal. Compare the trailing
|
||||
** fields. */
|
||||
res = vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
|
||||
res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
|
||||
}else{
|
||||
/* The first fields of the two keys are equal and there are no trailing
|
||||
** fields. Return pPKey2->default_rc in this case. */
|
||||
@@ -3907,7 +3907,7 @@ static int vdbeRecordCompareString(
|
||||
res = nStr - pPKey2->aMem[0].n;
|
||||
if( res==0 ){
|
||||
if( pPKey2->nField>1 ){
|
||||
res = vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
|
||||
res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
|
||||
}else{
|
||||
res = pPKey2->default_rc;
|
||||
}
|
||||
|
230
src/vdbesort.c
230
src/vdbesort.c
@@ -291,6 +291,7 @@ struct MergeEngine {
|
||||
** after the thread has finished are not dire. So we don't worry about
|
||||
** memory barriers and such here.
|
||||
*/
|
||||
typedef int (*SorterCompare)(SortSubtask*,int*,const void*,int,const void*,int);
|
||||
struct SortSubtask {
|
||||
SQLiteThread *pThread; /* Background thread, if any */
|
||||
int bDone; /* Set if thread is finished but not joined */
|
||||
@@ -298,10 +299,12 @@ struct SortSubtask {
|
||||
UnpackedRecord *pUnpacked; /* Space to unpack a record */
|
||||
SorterList list; /* List for thread to write to a PMA */
|
||||
int nPMA; /* Number of PMAs currently in file */
|
||||
SorterCompare xCompare; /* Compare function to use */
|
||||
SorterFile file; /* Temp file for level-0 PMAs */
|
||||
SorterFile file2; /* Space for other PMAs */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** Main sorter structure. A single instance of this is allocated for each
|
||||
** sorter cursor created by the VDBE.
|
||||
@@ -328,9 +331,13 @@ struct VdbeSorter {
|
||||
u8 bUseThreads; /* True to use background threads */
|
||||
u8 iPrev; /* Previous thread used to flush PMA */
|
||||
u8 nTask; /* Size of aTask[] array */
|
||||
u8 typeMask;
|
||||
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
|
||||
** PMA, in sorted order. The next key to be read is cached in nKey/aKey.
|
||||
@@ -742,32 +749,162 @@ static int vdbePmaReaderInit(
|
||||
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,
|
||||
** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences
|
||||
** used by the comparison. Return the result of the comparison.
|
||||
**
|
||||
** Before returning, object (pTask->pUnpacked) is populated with the
|
||||
** unpacked version of key2. Or, if pKey2 is passed a NULL pointer, then it
|
||||
** is assumed that the (pTask->pUnpacked) structure already contains the
|
||||
** unpacked key to use as key2.
|
||||
** If IN/OUT parameter *pbKey2Cached is true when this function is called,
|
||||
** it is assumed that (pTask->pUnpacked) contains the unpacked version
|
||||
** of key2. If it is false, (pTask->pUnpacked) is populated with the unpacked
|
||||
** version of key2 and *pbKey2Cached set to true before returning.
|
||||
**
|
||||
** If an OOM error is encountered, (pTask->pUnpacked->error_rc) is set
|
||||
** to SQLITE_NOMEM.
|
||||
*/
|
||||
static int vdbeSorterCompare(
|
||||
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( pKey2 ){
|
||||
if( !*pbKey2Cached ){
|
||||
sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2);
|
||||
*pbKey2Cached = 1;
|
||||
}
|
||||
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.
|
||||
**
|
||||
@@ -835,9 +972,13 @@ int sqlite3VdbeSorterInit(
|
||||
pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
|
||||
memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
|
||||
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->nTask = nWorker + 1;
|
||||
pSorter->iPrev = nWorker-1;
|
||||
pSorter->bUseThreads = (pSorter->nTask>1);
|
||||
pSorter->db = db;
|
||||
for(i=0; i<pSorter->nTask; i++){
|
||||
@@ -863,6 +1004,12 @@ int sqlite3VdbeSorterInit(
|
||||
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;
|
||||
@@ -887,30 +1034,24 @@ static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){
|
||||
*/
|
||||
static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){
|
||||
sqlite3DbFree(db, pTask->pUnpacked);
|
||||
pTask->pUnpacked = 0;
|
||||
#if SQLITE_MAX_WORKER_THREADS>0
|
||||
/* 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 */
|
||||
if( pTask->list.aMemory ){
|
||||
sqlite3_free(pTask->list.aMemory);
|
||||
pTask->list.aMemory = 0;
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
assert( pTask->list.aMemory==0 );
|
||||
vdbeSorterRecordFree(0, pTask->list.pList);
|
||||
}
|
||||
pTask->list.pList = 0;
|
||||
if( pTask->file.pFd ){
|
||||
sqlite3OsCloseFree(pTask->file.pFd);
|
||||
pTask->file.pFd = 0;
|
||||
pTask->file.iEof = 0;
|
||||
}
|
||||
if( 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
|
||||
@@ -1090,6 +1231,7 @@ void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){
|
||||
for(i=0; i<pSorter->nTask; i++){
|
||||
SortSubtask *pTask = &pSorter->aTask[i];
|
||||
vdbeSortSubtaskCleanup(db, pTask);
|
||||
pTask->pSorter = pSorter;
|
||||
}
|
||||
if( pSorter->list.aMemory==0 ){
|
||||
vdbeSorterRecordFree(0, pSorter->list.pList);
|
||||
@@ -1199,28 +1341,42 @@ static void vdbeSorterMerge(
|
||||
){
|
||||
SorterRecord *pFinal = 0;
|
||||
SorterRecord **pp = &pFinal;
|
||||
void *pVal2 = p2 ? SRVAL(p2) : 0;
|
||||
int bCached = 0;
|
||||
|
||||
while( p1 && p2 ){
|
||||
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 ){
|
||||
*pp = p1;
|
||||
pp = &p1->u.pNext;
|
||||
p1 = p1->u.pNext;
|
||||
pVal2 = 0;
|
||||
}else{
|
||||
*pp = p2;
|
||||
pp = &p2->u.pNext;
|
||||
p2 = p2->u.pNext;
|
||||
if( p2==0 ) break;
|
||||
pVal2 = SRVAL(p2);
|
||||
bCached = 0;
|
||||
}
|
||||
}
|
||||
*pp = p1 ? p1 : p2;
|
||||
*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
|
||||
** 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);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
|
||||
p = pList->pList;
|
||||
pTask->xCompare = vdbeSorterGetCompare(pTask->pSorter);
|
||||
|
||||
aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *));
|
||||
if( !aSlot ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
p = pList->pList;
|
||||
while( p ){
|
||||
SorterRecord *pNext;
|
||||
if( pList->aMemory ){
|
||||
@@ -1454,13 +1612,12 @@ static int vdbeMergeEngineStep(
|
||||
int i; /* Index of aTree[] to recalculate */
|
||||
PmaReader *pReadr1; /* First 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
|
||||
** advanced (iPrev) and the one next to it in the array. */
|
||||
pReadr1 = &pMerger->aReadr[(iPrev & 0xFFFE)];
|
||||
pReadr2 = &pMerger->aReadr[(iPrev | 0x0001)];
|
||||
pKey2 = pReadr2->aKey;
|
||||
|
||||
for(i=(pMerger->nTree+iPrev)/2; i>0; i=i/2){
|
||||
/* Compare pReadr1 and pReadr2. Store the result in variable iRes. */
|
||||
@@ -1470,8 +1627,8 @@ static int vdbeMergeEngineStep(
|
||||
}else if( pReadr2->pFd==0 ){
|
||||
iRes = -1;
|
||||
}else{
|
||||
iRes = vdbeSorterCompare(pTask,
|
||||
pReadr1->aKey, pReadr1->nKey, pKey2, pReadr2->nKey
|
||||
iRes = pTask->xCompare(pTask, &bCached,
|
||||
pReadr1->aKey, pReadr1->nKey, pReadr2->aKey, pReadr2->nKey
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1493,9 +1650,9 @@ static int vdbeMergeEngineStep(
|
||||
if( iRes<0 || (iRes==0 && pReadr1<pReadr2) ){
|
||||
pMerger->aTree[i] = (int)(pReadr1 - pMerger->aReadr);
|
||||
pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
|
||||
pKey2 = pReadr2->aKey;
|
||||
bCached = 0;
|
||||
}else{
|
||||
if( pReadr1->pFd ) pKey2 = 0;
|
||||
if( pReadr1->pFd ) bCached = 0;
|
||||
pMerger->aTree[i] = (int)(pReadr2 - pMerger->aReadr);
|
||||
pReadr1 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
|
||||
}
|
||||
@@ -1602,6 +1759,16 @@ int sqlite3VdbeSorterWrite(
|
||||
int bFlush; /* True to flush contents of memory to PMA */
|
||||
int nReq; /* Bytes of memory 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 );
|
||||
|
||||
@@ -1867,10 +2034,12 @@ static void vdbeMergeEngineCompare(
|
||||
}else if( p2->pFd==0 ){
|
||||
iRes = i1;
|
||||
}else{
|
||||
SortSubtask *pTask = pMerger->pTask;
|
||||
int bCached = 0;
|
||||
int res;
|
||||
assert( pMerger->pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */
|
||||
res = vdbeSorterCompare(
|
||||
pMerger->pTask, p1->aKey, p1->nKey, p2->aKey, p2->nKey
|
||||
assert( pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */
|
||||
res = pTask->xCompare(
|
||||
pTask, &bCached, p1->aKey, p1->nKey, p2->aKey, p2->nKey
|
||||
);
|
||||
if( res<=0 ){
|
||||
iRes = i1;
|
||||
@@ -2288,6 +2457,11 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
|
||||
MergeEngine *pMain = 0;
|
||||
#if SQLITE_MAX_WORKER_THREADS
|
||||
sqlite3 *db = pTask0->pSorter->db;
|
||||
int i;
|
||||
SorterCompare xCompare = vdbeSorterGetCompare(pSorter);
|
||||
for(i=0; i<pSorter->nTask; i++){
|
||||
pSorter->aTask[i].xCompare = xCompare;
|
||||
}
|
||||
#endif
|
||||
|
||||
rc = vdbeSorterMergeTreeBuild(pSorter, &pMain);
|
||||
|
34
src/vtab.c
34
src/vtab.c
@@ -24,6 +24,8 @@
|
||||
struct VtabCtx {
|
||||
VTable *pVTable; /* The virtual table being constructed */
|
||||
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**),
|
||||
char **pzErr
|
||||
){
|
||||
VtabCtx sCtx, *pPriorCtx;
|
||||
VtabCtx sCtx;
|
||||
VTable *pVTable;
|
||||
int rc;
|
||||
const char *const*azArg = (const char *const*)pTab->azModuleArg;
|
||||
int nArg = pTab->nModuleArg;
|
||||
char *zErr = 0;
|
||||
char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
|
||||
char *zModuleName;
|
||||
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 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -516,11 +530,13 @@ static int vtabCallConstructor(
|
||||
assert( xConstruct );
|
||||
sCtx.pTab = pTab;
|
||||
sCtx.pVTable = pVTable;
|
||||
pPriorCtx = db->pVtabCtx;
|
||||
sCtx.pPrior = db->pVtabCtx;
|
||||
sCtx.bDeclared = 0;
|
||||
db->pVtabCtx = &sCtx;
|
||||
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
|
||||
db->pVtabCtx = pPriorCtx;
|
||||
db->pVtabCtx = sCtx.pPrior;
|
||||
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
|
||||
assert( sCtx.pTab==pTab );
|
||||
|
||||
if( SQLITE_OK!=rc ){
|
||||
if( zErr==0 ){
|
||||
@@ -536,7 +552,7 @@ static int vtabCallConstructor(
|
||||
memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0]));
|
||||
pVTable->pVtab->pModule = pMod->pModule;
|
||||
pVTable->nRef = 1;
|
||||
if( sCtx.pTab ){
|
||||
if( sCtx.bDeclared==0 ){
|
||||
const char *zFormat = "vtable constructor did not declare schema: %s";
|
||||
*pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
|
||||
sqlite3VtabUnlock(pVTable);
|
||||
@@ -706,8 +722,8 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
|
||||
** virtual table module.
|
||||
*/
|
||||
int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
|
||||
VtabCtx *pCtx;
|
||||
Parse *pParse;
|
||||
|
||||
int rc = SQLITE_OK;
|
||||
Table *pTab;
|
||||
char *zErr = 0;
|
||||
@@ -718,11 +734,13 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
|
||||
}
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){
|
||||
pCtx = db->pVtabCtx;
|
||||
if( !pCtx || pCtx->bDeclared ){
|
||||
sqlite3Error(db, SQLITE_MISUSE);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
pTab = pCtx->pTab;
|
||||
assert( (pTab->tabFlags & TF_Virtual)!=0 );
|
||||
|
||||
pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
|
||||
@@ -745,7 +763,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
|
||||
pParse->pNewTable->nCol = 0;
|
||||
pParse->pNewTable->aCol = 0;
|
||||
}
|
||||
db->pVtabCtx->pTab = 0;
|
||||
pCtx->bDeclared = 1;
|
||||
}else{
|
||||
sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
|
||||
sqlite3DbFree(db, zErr);
|
||||
|
@@ -1730,6 +1730,14 @@ static int walCheckpoint(
|
||||
mxSafeFrame = pWal->hdr.mxFrame;
|
||||
mxPage = pWal->hdr.nPage;
|
||||
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];
|
||||
if( mxSafeFrame>y ){
|
||||
assert( y<=pWal->hdr.mxFrame );
|
||||
|
@@ -1534,7 +1534,7 @@ static int findIndexCol(
|
||||
&& p->iTable==iBase
|
||||
){
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1808,7 +1808,7 @@ static void constructAutomaticIndex(
|
||||
idxCols |= cMask;
|
||||
pIdx->aiColumn[n] = pTerm->u.leftColumn;
|
||||
pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
|
||||
pIdx->azColl[n] = ALWAYS(pColl) ? pColl->zName : "BINARY";
|
||||
pIdx->azColl[n] = pColl ? pColl->zName : "BINARY";
|
||||
n++;
|
||||
}
|
||||
}
|
||||
@@ -4786,7 +4786,7 @@ static int whereLoopAddBtreeIndex(
|
||||
}else if( eOp & (WO_EQ) ){
|
||||
pNew->wsFlags |= WHERE_COLUMN_EQ;
|
||||
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;
|
||||
}else{
|
||||
pNew->wsFlags |= WHERE_ONEROW;
|
||||
@@ -6245,7 +6245,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
pWInfo->revMask = pFrom->revLoop;
|
||||
}
|
||||
if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
|
||||
&& pWInfo->nOBSat==pWInfo->pOrderBy->nExpr
|
||||
&& pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && nLoop>0
|
||||
){
|
||||
Bitmask revMask = 0;
|
||||
int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy,
|
||||
|
@@ -512,5 +512,12 @@ do_execsql_test autoindex1-901 {
|
||||
WHERE t1.x IN (1,2,3);
|
||||
} {/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
|
||||
|
@@ -385,6 +385,20 @@ do_execsql_test 6.8 {
|
||||
SELECT x, y FROM c1 ORDER BY y COLLATE """""""";
|
||||
} {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
|
||||
|
||||
|
||||
|
@@ -32,7 +32,7 @@ source $testdir/tester.tcl
|
||||
#
|
||||
do_test collate3-1.0 {
|
||||
execsql {
|
||||
CREATE TABLE collate3t1(c1);
|
||||
CREATE TABLE collate3t1(c1 UNIQUE);
|
||||
}
|
||||
} {}
|
||||
do_test collate3-1.1 {
|
||||
@@ -40,6 +40,11 @@ do_test collate3-1.1 {
|
||||
SELECT * FROM collate3t1 ORDER BY 1 collate 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 {
|
||||
catchsql {
|
||||
CREATE TABLE collate3t2(c1 collate garbage);
|
||||
|
@@ -746,10 +746,10 @@ do_test fkey2-10.2.2 {
|
||||
drop_all_tables
|
||||
do_test fkey2-11.1.1 {
|
||||
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);
|
||||
|
||||
INSERT INTO t1 VALUES(10, 100);
|
||||
INSERT INTO t1 VALUES(10, 100, 'abc', 'def', 'ghi');
|
||||
INSERT INTO t2 VALUES(10, 100);
|
||||
UPDATE t1 SET a = 15;
|
||||
SELECT * FROM t2;
|
||||
|
@@ -538,6 +538,25 @@ do_execsql_test 3.4 {
|
||||
SELECT snippet(t3) FROM t3 WHERE t3 MATCH 'one OR two OR three';
|
||||
} {{[<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
|
||||
finish_test
|
||||
|
||||
|
@@ -110,5 +110,15 @@ do_catchsql_test 2.1 {
|
||||
SELECT * FROM t4;
|
||||
} {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
|
||||
|
@@ -48,6 +48,9 @@ ifcapable !fts3 {
|
||||
#
|
||||
# 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 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
@@ -406,7 +409,7 @@ do_execsql_test 5.1.7 {
|
||||
#
|
||||
do_catchsql_test 6.1.1 {
|
||||
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 {
|
||||
CREATE TABLE t7(one, two);
|
||||
@@ -433,7 +436,7 @@ do_execsql_test 6.2.3 {
|
||||
}
|
||||
do_catchsql_test 6.2.4 {
|
||||
SELECT * FROM ft7;
|
||||
} {1 {vtable constructor failed: ft7}}
|
||||
} {1 {no such table: main.t7}}
|
||||
do_execsql_test 6.2.5 {
|
||||
CREATE TABLE t7(x, y);
|
||||
INSERT INTO t7 VALUES('A B', 'B A');
|
||||
@@ -622,4 +625,15 @@ do_execsql_test 10.7 {
|
||||
{...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
|
||||
|
||||
|
@@ -109,6 +109,11 @@ do_execsql_test hexlit-301 {
|
||||
do_catchsql_test hexlist-400 {
|
||||
SELECT 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
|
||||
|
@@ -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 {
|
||||
db nullvalue ""
|
||||
|
@@ -639,4 +639,9 @@ do_catchsql_test misc1-21.2 {
|
||||
VALUES(0,0x0MATCH#0;
|
||||
} {1 {near ";": syntax error}}
|
||||
|
||||
# 2015-04-15
|
||||
do_execsql_test misc1-22.1 {
|
||||
SELECT ""+3 FROM (SELECT ""+5);
|
||||
} {3}
|
||||
|
||||
finish_test
|
||||
|
@@ -278,6 +278,23 @@ do_test null-8.15 {
|
||||
}
|
||||
} {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
|
||||
|
@@ -463,6 +463,9 @@ do_execsql_test 5.1 {
|
||||
do_execsql_test 5.2 {
|
||||
SELECT 5 UNION ALL SELECT 3 ORDER BY 1
|
||||
} {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)
|
||||
# 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;
|
||||
} {~/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
|
||||
|
@@ -752,6 +752,16 @@ do_test pragma-6.7 {
|
||||
{3 four REAL 0 X'abcdef' 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
|
||||
# Miscellaneous tests
|
||||
#
|
||||
|
@@ -58,6 +58,9 @@ do_execsql_test printf2-1.10 {
|
||||
do_execsql_test printf2-1.11 {
|
||||
SELECT printf('%lld%n',314159.2653,'hi');
|
||||
} {314159}
|
||||
do_execsql_test printf2-1.12 {
|
||||
SELECT printf('%n',0);
|
||||
} {{}}
|
||||
|
||||
# EVIDENCE-OF: R-17002-27534 The %z format is interchangeable with %s.
|
||||
#
|
||||
|
@@ -799,6 +799,11 @@ do_test select4-11.15 {
|
||||
SELECT x FROM t2
|
||||
}
|
||||
} {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 {
|
||||
sqlite3 db2 :memory:
|
||||
@@ -863,5 +868,12 @@ do_execsql_test select4-14.8 {
|
||||
do_execsql_test select4-14.9 {
|
||||
SELECT * FROM t14 UNION ALL VALUES(3,2,1),(2,3,1),(1,2,3),(2,1,3);
|
||||
} {1 2 3 4 5 6 3 2 1 2 3 1 1 2 3 2 1 3}
|
||||
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
|
||||
|
@@ -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
|
||||
|
@@ -15,6 +15,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix vacuum2
|
||||
|
||||
# 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).
|
||||
@@ -227,5 +228,24 @@ do_test vacuum2-5.4 {
|
||||
lappend res2 $res
|
||||
} {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
|
||||
|
@@ -129,11 +129,11 @@ do_execsql_test 3.0 {
|
||||
|
||||
do_searchcount_test 3.1 {
|
||||
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 {
|
||||
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 {
|
||||
SELECT y FROM t4 WHERE x='a'
|
||||
@@ -142,24 +142,24 @@ do_searchcount_test 3.4.2 {
|
||||
SELECT a, b FROM t3 WHERE
|
||||
(a=1 AND b=(SELECT y FROM t4 WHERE x='a'))
|
||||
OR (a=2 AND b='two')
|
||||
} {1 one 2 two search 4}
|
||||
} {1 one 2 two search 6}
|
||||
do_searchcount_test 3.4.3 {
|
||||
SELECT a, b FROM t3 WHERE
|
||||
(a=2 AND b='two')
|
||||
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 {
|
||||
SELECT a, b FROM t3 WHERE
|
||||
(a=2 AND b=(SELECT y FROM t4 WHERE x='b'))
|
||||
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 {
|
||||
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 {
|
||||
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)
|
||||
# LEFT JOIN with an OR in the ON clause causes segfault
|
||||
|
@@ -843,4 +843,10 @@ do_catchsql_test 13.3 {
|
||||
SELECT i FROM c;
|
||||
} {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
|
||||
|
@@ -255,5 +255,14 @@ do_test zeroblob-9.8 {
|
||||
db eval {SELECT zeroblob(2) IN (zeroblob(2))}
|
||||
} {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
|
||||
|
1217
tool/sqldiff.c
Normal file
1217
tool/sqldiff.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user