1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Merge all recent trunk fixes and enhancements into the sessions branch.

FossilOrigin-Name: e65e65f9bc9b4bf5c9dd6e3a77a0d5f03c40e006
This commit is contained in:
drh
2015-04-15 14:14:38 +00:00
38 changed files with 684 additions and 313 deletions

View File

@@ -1 +1 @@
3.8.9
3.8.10

18
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.62 for sqlite 3.8.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'`\\"

View File

@@ -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;
@@ -3527,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);
}

View File

@@ -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)

View File

@@ -1,12 +1,12 @@
C Merge\sall\srecent\strunk\senhancements\sinto\sthe\ssessions\sbranch.
D 2015-04-12T01:33:37.792
C Merge\sall\srecent\strunk\sfixes\sand\senhancements\sinto\sthe\ssessions\sbranch.
D 2015-04-15T14:14:38.449
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 7e23076b9c9dd5c1901c78cf6cdd64d616e5a539
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc 5b2ac9066d9d67427eb98d7e4bf3790c4db51810
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 57d863c3bd360e575ecc293570af7c9b0bdd2209
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
@@ -172,7 +172,7 @@ F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk 3ffc109d70c73c8c1149d7f9c880e22edb8d6c43
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,21 +186,21 @@ 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 fa4795bc795077388aa4e746e1b25ef97bc10489
F src/build.c 01b969b20a44a3d9620e597d9af8242348123540
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575
F src/ctime.c 98f89724adc891a1a4c655bee04e33e716e05887
F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac
F src/delete.c 5075d88557eb4e2a7fdb2b61a96142830d8589b8
F src/expr.c d09dac67d53c78880ba31d56e8ba2be3a6490553
F src/expr.c 8800584340a9b4f4c0ca55c360de751c6da0b11a
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 3343d551a8d810782257244fb33f2ce191493c39
F src/func.c 1414c24c873c48796ad45942257a179a423ba42f
@@ -208,7 +208,7 @@ F src/global.c 4f77cadbc5427d00139ba43d0f3979804cbb700e
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c 7d953730a7b8e6ff5db0d5a372ebc303f85488b7
F src/insert.c 6663d6885c1e28b503153ff5d817f61cdc1aa901
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
@@ -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,16 +241,16 @@ 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 c4d839ad62f4986891601a21ce629a760f226682
F src/sqlite.h.in 64287a2b3432550264a743addbf4162a692fdd1c
F src/sqlite.h.in 679a3abfef9c13a989728fd27f308a3e3f00e232
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
F src/sqliteInt.h f415bc20c6ac85a255f03aa145476655da6f4098
@@ -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/tokenize.c a8234a67577308935cdf13e618cd66556f5f45d1
F src/trigger.c 69a91bed7c94e46223e37ffccfeeb35e34b999ac
F src/update.c d207deb7a031f698104bee879de0632b611e72dd
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
F src/vdbe.c e09d0a7738b0bc469c573d43af501835afa47956
F src/vdbe.c f3f2e466c962cbb1f774526d24d963b06dd46a96
F src/vdbe.h 01d8c35cb877faca74331bb690f0327493c2cb50
F src/vdbeInt.h 96e4303a96c6f983e36e1fe32657b2c547f5c8f1
F src/vdbeapi.c d95f2bb43d01a91d93231cde181811b38182202e
F src/vdbeaux.c 70d414ecc1a345f71a52c7e5e4e1bdfa184081ca
F src/vdbeblob.c ab33f9b57cfce7dddb23853090186da614be4846
F src/vdbemem.c 149e585645c3f3ef063f2b7251646388cfe3d47d
F src/vdbesort.c 5a729a15fb46b1759e13be49a10441172628e593
F src/vdbesort.c 2e7f683464fd5db3be4beaa1ff2d39e24fcb64b8
F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
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 9952e4749f481707595692f2f13d3ce3b64ffdc8
F src/where.c 8ba8ff31dc9bf1b69fe771d35d8764d5a1efd310
F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c
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
@@ -617,9 +617,9 @@ 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
@@ -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 aa41c095d26822b8a51aa4c82904a14347961be6
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
@@ -812,11 +812,11 @@ F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
F test/permutations.test e5e9f708879336e10095ded8d61966007f4a2c5c
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
@@ -857,7 +857,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
@@ -867,7 +867,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
@@ -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
@@ -1258,7 +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 51c05cc1435507736b8b5a41a0498016041b3e48
F tool/sqldiff.c 5c16cf3a1f566873abbdecac0d13a6691437564f
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
F tool/symbols.sh c5a617b8c61a0926747a56c65f5671ef8ac0e148
@@ -1269,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 805baa57e5d2e97dccddc08eb72f2564df4802e8 e527d96a1e098ade4e9d124b630a8c2ea2ac9b36
R 730bdca262b89d29bd7fd3c2449cd70e
P 5f14f34f072921e229bc20a5185c0cdb3f464c04 bd06eeb8d06237dc2d54d8a03e8bf525cb811c9e
R 9a2dfdee602d304934edbae48280a16c
U drh
Z 0af95f43348b30e9069146170d9a1be7
Z 3665d5b1b05a141bd80e3d7f627d8145

View File

@@ -1 +1 @@
5f14f34f072921e229bc20a5185c0cdb3f464c04
e65e65f9bc9b4bf5c9dd6e3a77a0d5f03c40e006

View File

@@ -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)

View File

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

View File

@@ -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;

View File

@@ -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] */

View File

@@ -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;
}

View File

@@ -2036,7 +2036,8 @@ static int xferOptimization(
int i;
for(i=0; i<pSrcIdx->nColumn; i++){
char *zColl = pSrcIdx->azColl[i];
if( zColl && sqlite3_stricmp("BINARY", zColl) ) break;
assert( zColl!=0 );
if( sqlite3_stricmp("BINARY", zColl) ) break;
}
if( i==pSrcIdx->nColumn ){
useSeekResult = OPFLAG_USESEEKRESULT;

View File

@@ -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) ){

View File

@@ -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);

View File

@@ -826,7 +826,7 @@ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
** size of the memory allocation for StrAccum if necessary.
*/
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 );

View File

@@ -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;

View File

@@ -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;

View File

@@ -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()],
@@ -1378,6 +1380,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
@@ -1875,6 +1878,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
@@ -1884,6 +1888,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
@@ -1935,6 +1940,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
@@ -1987,6 +1993,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
@@ -2010,6 +2017,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
@@ -2086,6 +2094,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
@@ -2145,6 +2154,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
@@ -2167,6 +2177,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.
@@ -2502,6 +2513,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.
@@ -2658,6 +2670,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.
@@ -2690,6 +2703,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
@@ -2723,6 +2737,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
@@ -3008,6 +3023,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
@@ -3053,33 +3069,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
@@ -3191,6 +3208,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.
@@ -3298,6 +3317,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
@@ -3307,6 +3327,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
@@ -3338,6 +3359,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
@@ -3412,6 +3434,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
@@ -3530,6 +3553,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
@@ -3550,6 +3574,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.
@@ -3577,6 +3602,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
@@ -3593,6 +3619,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].
@@ -3602,6 +3629,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
@@ -3613,6 +3641,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()
@@ -3642,6 +3671,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
@@ -3694,6 +3724,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
@@ -3726,6 +3757,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
@@ -3805,6 +3837,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.
@@ -3858,6 +3891,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.
**
@@ -4030,6 +4064,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
@@ -4057,6 +4092,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.
@@ -4086,6 +4122,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
@@ -4255,6 +4292,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
@@ -4313,6 +4351,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.
@@ -4357,6 +4396,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)
@@ -4371,6 +4411,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)
@@ -4382,6 +4423,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
@@ -4454,6 +4496,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
@@ -4589,6 +4632,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.
@@ -4691,6 +4735,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
@@ -4898,6 +4943,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,
@@ -4920,6 +4966,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]
@@ -4932,6 +4979,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
@@ -4948,6 +4996,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
@@ -4957,6 +5006,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
@@ -4972,6 +5022,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].
@@ -5021,6 +5072,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
@@ -5127,6 +5179,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
@@ -5204,6 +5257,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
@@ -5282,6 +5336,7 @@ int sqlite3_table_column_metadata(
/*
** CAPI3REF: Load An Extension
** METHOD: sqlite3
**
** ^This interface loads an SQLite extension library from the named file.
**
@@ -5323,6 +5378,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
@@ -5572,6 +5628,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
@@ -5668,6 +5725,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].
@@ -5710,6 +5768,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;
@@ -5791,6 +5851,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
@@ -5815,6 +5876,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
@@ -5837,6 +5899,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
@@ -5852,6 +5915,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
@@ -5880,6 +5944,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
@@ -6207,6 +6272,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
@@ -6218,6 +6284,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
@@ -6434,6 +6501,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
@@ -6562,6 +6630,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
@@ -7065,6 +7134,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
@@ -7235,6 +7305,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.
@@ -7274,6 +7345,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
@@ -7304,6 +7376,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).)^
@@ -7325,6 +7398,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
@@ -7579,6 +7653,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
@@ -7616,6 +7691,7 @@ SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus(
/*
** CAPI3REF: Zero Scan-Status Counters
** METHOD: sqlite3_stmt
**
** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
**

View File

@@ -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];

View File

@@ -524,6 +524,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.
@@ -532,9 +547,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 */
@@ -610,23 +624,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
@@ -643,23 +656,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) );
@@ -715,7 +714,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
@@ -743,7 +742,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
@@ -788,9 +788,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;
}
@@ -802,7 +806,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;
}
@@ -826,7 +830,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;
}
@@ -846,7 +850,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;
}
@@ -870,9 +874,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;
}
@@ -923,30 +927,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",
@@ -970,7 +978,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 );
@@ -981,6 +989,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;
}
@@ -989,7 +998,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;
}
@@ -1000,7 +1010,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;
@@ -1013,7 +1024,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;
@@ -1029,8 +1041,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);
@@ -1067,8 +1080,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;
@@ -1096,9 +1110,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;
@@ -1133,8 +1148,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);
@@ -1149,7 +1165,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 );
@@ -1158,6 +1174,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;
@@ -1334,7 +1351,7 @@ case OP_ResultRow: {
/* Return SQLITE_ROW
*/
p->pc = pc + 1;
p->pc = (int)(pOp - aOp) + 1;
rc = SQLITE_ROW;
goto vdbe_return;
}
@@ -1580,7 +1597,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;
@@ -1594,7 +1611,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 */
@@ -1723,8 +1740,7 @@ case OP_MustBeInt: { /* jump, in1 */
rc = SQLITE_MISMATCH;
goto abort_due_to_error;
}else{
pc = pOp->p2 - 1;
break;
goto jump_to_p2;
}
}
}
@@ -1910,7 +1926,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;
@@ -1962,6 +1978,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);
@@ -1971,14 +1993,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;
}
@@ -2073,11 +2090,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;
}
@@ -2187,7 +2204,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;
}
@@ -2222,7 +2239,7 @@ case OP_IfNot: { /* jump, in1 */
}
VdbeBranchTaken(c!=0, 2);
if( c ){
pc = pOp->p2-1;
goto jump_to_p2;
}
break;
}
@@ -2236,7 +2253,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;
}
@@ -2250,7 +2267,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;
}
@@ -2731,7 +2748,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;
@@ -2739,6 +2756,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;
}
@@ -2852,7 +2870,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;
@@ -2971,7 +2989,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;
@@ -3048,7 +3066,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;
}
@@ -3127,7 +3145,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;
@@ -3141,6 +3159,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;
}
@@ -3462,7 +3481,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;
}
@@ -3639,7 +3658,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;
}
@@ -3730,7 +3749,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;
}
@@ -3824,6 +3843,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;
@@ -3846,7 +3866,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;
@@ -3869,21 +3889,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;
}
@@ -3894,10 +3913,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;
}
@@ -3946,10 +3965,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;
}
@@ -3961,9 +3978,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;
}
@@ -3984,7 +4002,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() */
@@ -3994,6 +4012,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 );
@@ -4357,9 +4376,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;
};
@@ -4488,12 +4505,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 );
@@ -4579,7 +4597,7 @@ case OP_Last: { /* jump */
#endif
if( pOp->p2>0 ){
VdbeBranchTaken(res!=0,2);
if( res ) pc = pOp->p2 - 1;
if( res ) goto jump_to_p2;
}
break;
}
@@ -4643,9 +4661,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;
}
@@ -4756,11 +4772,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;
}
@@ -4868,11 +4884,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 );
@@ -4985,9 +5002,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;
}
@@ -5011,11 +5026,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;
@@ -5124,12 +5140,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) );
@@ -5355,12 +5372,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;
}
@@ -5411,10 +5428,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);
@@ -5503,7 +5517,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;
@@ -5526,7 +5540,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++;
@@ -5547,7 +5561,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;
@@ -5565,9 +5579,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);
@@ -5611,10 +5626,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;
}
@@ -5665,9 +5680,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;
}
@@ -5682,9 +5695,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;
}
@@ -5701,7 +5712,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;
}
@@ -5717,9 +5728,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;
}
@@ -5735,9 +5744,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;
}
@@ -5779,7 +5786,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 ){
@@ -5874,7 +5881,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 */
@@ -5883,6 +5890,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
@@ -5999,8 +6007,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;
}
@@ -6210,25 +6218,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 */
@@ -6315,7 +6317,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;
}
@@ -6438,7 +6440,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;
}
@@ -6454,10 +6457,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 ){
@@ -6486,9 +6490,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
@@ -6516,6 +6517,7 @@ case OP_Init: { /* jump */
}
#endif /* SQLITE_DEBUG */
#endif /* SQLITE_OMIT_TRACE */
if( pOp->p2 ) goto jump_to_p2;
break;
}
@@ -6558,12 +6560,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 ){
@@ -6582,7 +6584,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;

View File

@@ -882,10 +882,11 @@ static int vdbeSorterCompareInt(
}else{
res = s1 - s2;
}
assert( res!=0 );
if( res>0 ){
if( *v1 & 0x80 ) res = -1;
}else if( res<0 ){
}else{
if( *v2 & 0x80 ) res = +1;
}
}

View File

@@ -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 );

View File

@@ -1532,7 +1532,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;
}
}
@@ -1806,7 +1806,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++;
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

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

View File

@@ -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

View File

@@ -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
#

View File

@@ -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.
#

View File

@@ -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

View File

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

View File

@@ -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

View File

@@ -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

View File

@@ -356,18 +356,18 @@ static char **columnNames(const char *zDb, const char *zTab, int *pnPKey){
/*
** Print the sqlite3_value X as an SQL literal.
*/
static void printQuoted(sqlite3_value *X){
static void printQuoted(FILE *out, sqlite3_value *X){
switch( sqlite3_value_type(X) ){
case SQLITE_FLOAT: {
double r1;
char zBuf[50];
r1 = sqlite3_value_double(X);
sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1);
printf("%s", zBuf);
fprintf(out, "%s", zBuf);
break;
}
case SQLITE_INTEGER: {
printf("%lld", sqlite3_value_int64(X));
fprintf(out, "%lld", sqlite3_value_int64(X));
break;
}
case SQLITE_BLOB: {
@@ -375,13 +375,13 @@ static void printQuoted(sqlite3_value *X){
int nBlob = sqlite3_value_bytes(X);
if( zBlob ){
int i;
printf("x'");
fprintf(out, "x'");
for(i=0; i<nBlob; i++){
printf("%02x", zBlob[i]);
fprintf(out, "%02x", zBlob[i]);
}
printf("'");
fprintf(out, "'");
}else{
printf("NULL");
fprintf(out, "NULL");
}
break;
}
@@ -390,21 +390,21 @@ static void printQuoted(sqlite3_value *X){
int i, j;
if( zArg==0 ){
printf("NULL");
fprintf(out, "NULL");
}else{
printf("'");
fprintf(out, "'");
for(i=j=0; zArg[i]; i++){
if( zArg[i]=='\'' ){
printf("%.*s'", i-j+1, &zArg[j]);
fprintf(out, "%.*s'", i-j+1, &zArg[j]);
j = i+1;
}
}
printf("%s'", &zArg[j]);
fprintf(out, "%s'", &zArg[j]);
}
break;
}
case SQLITE_NULL: {
printf("NULL");
fprintf(out, "NULL");
break;
}
}
@@ -413,7 +413,7 @@ static void printQuoted(sqlite3_value *X){
/*
** Output SQL that will recreate the aux.zTab table.
*/
static void dump_table(const char *zTab){
static void dump_table(const char *zTab, FILE *out){
char *zId = safeId(zTab); /* Name of the table */
char **az = 0; /* List of columns */
int nPk; /* Number of true primary key columns */
@@ -425,7 +425,7 @@ static void dump_table(const char *zTab){
pStmt = db_prepare("SELECT sql FROM aux.sqlite_master WHERE name=%Q", zTab);
if( SQLITE_ROW==sqlite3_step(pStmt) ){
printf("%s;\n", sqlite3_column_text(pStmt,0));
fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
}
sqlite3_finalize(pStmt);
if( !g.bSchemaOnly ){
@@ -461,14 +461,14 @@ static void dump_table(const char *zTab){
}
nCol = sqlite3_column_count(pStmt);
while( SQLITE_ROW==sqlite3_step(pStmt) ){
printf("%s",ins.z);
fprintf(out, "%s",ins.z);
zSep = "(";
for(i=0; i<nCol; i++){
printf("%s",zSep);
printQuoted(sqlite3_column_value(pStmt,i));
fprintf(out, "%s",zSep);
printQuoted(out, sqlite3_column_value(pStmt,i));
zSep = ",";
}
printf(");\n");
fprintf(out, ");\n");
}
sqlite3_finalize(pStmt);
strFree(&ins);
@@ -477,7 +477,7 @@ static void dump_table(const char *zTab){
" WHERE type='index' AND tbl_name=%Q AND sql IS NOT NULL",
zTab);
while( SQLITE_ROW==sqlite3_step(pStmt) ){
printf("%s;\n", sqlite3_column_text(pStmt,0));
fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
}
sqlite3_finalize(pStmt);
}
@@ -486,7 +486,7 @@ static void dump_table(const char *zTab){
/*
** Compute all differences for a single table.
*/
static void diff_one_table(const char *zTab){
static void diff_one_table(const char *zTab, FILE *out){
char *zId = safeId(zTab); /* Name of table (translated for us in SQL) */
char **az = 0; /* Columns in main */
char **az2 = 0; /* Columns in aux */
@@ -524,14 +524,14 @@ static void diff_one_table(const char *zTab){
if( sqlite3_table_column_metadata(g.db,"aux",zTab,0,0,0,0,0,0) ){
if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
/* Table missing from second database. */
printf("DROP TABLE %s;\n", zId);
fprintf(out, "DROP TABLE %s;\n", zId);
}
goto end_diff_one_table;
}
if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
/* Table missing from source */
dump_table(zTab);
dump_table(zTab, out);
goto end_diff_one_table;
}
@@ -548,8 +548,8 @@ static void diff_one_table(const char *zTab){
|| az[n]
){
/* Schema mismatch */
printf("DROP TABLE %s;\n", zId);
dump_table(zTab);
fprintf(out, "DROP TABLE %s;\n", zId);
dump_table(zTab, out);
goto end_diff_one_table;
}
@@ -642,7 +642,7 @@ static void diff_one_table(const char *zTab){
zTab, zTab);
while( SQLITE_ROW==sqlite3_step(pStmt) ){
char *z = safeId((const char*)sqlite3_column_text(pStmt,0));
printf("DROP INDEX %s;\n", z);
fprintf(out, "DROP INDEX %s;\n", z);
sqlite3_free(z);
}
sqlite3_finalize(pStmt);
@@ -654,39 +654,39 @@ static void diff_one_table(const char *zTab){
int iType = sqlite3_column_int(pStmt, nPk);
if( iType==1 || iType==2 ){
if( iType==1 ){ /* Change the content of a row */
printf("UPDATE %s", zId);
fprintf(out, "UPDATE %s", zId);
zSep = " SET";
for(i=nPk+1; i<nQ; i+=2){
if( sqlite3_column_int(pStmt,i)==0 ) continue;
printf("%s %s=", zSep, az2[(i+nPk-1)/2]);
fprintf(out, "%s %s=", zSep, az2[(i+nPk-1)/2]);
zSep = ",";
printQuoted(sqlite3_column_value(pStmt,i+1));
printQuoted(out, sqlite3_column_value(pStmt,i+1));
}
}else{ /* Delete a row */
printf("DELETE FROM %s", zId);
fprintf(out, "DELETE FROM %s", zId);
}
zSep = " WHERE";
for(i=0; i<nPk; i++){
printf("%s %s=", zSep, az2[i]);
printQuoted(sqlite3_column_value(pStmt,i));
fprintf(out, "%s %s=", zSep, az2[i]);
printQuoted(out, sqlite3_column_value(pStmt,i));
zSep = ",";
}
printf(";\n");
fprintf(out, ";\n");
}else{ /* Insert a row */
printf("INSERT INTO %s(%s", zId, az2[0]);
for(i=1; az2[i]; i++) printf(",%s", az2[i]);
printf(") VALUES");
fprintf(out, "INSERT INTO %s(%s", zId, az2[0]);
for(i=1; az2[i]; i++) fprintf(out, ",%s", az2[i]);
fprintf(out, ") VALUES");
zSep = "(";
for(i=0; i<nPk2; i++){
printf("%s", zSep);
fprintf(out, "%s", zSep);
zSep = ",";
printQuoted(sqlite3_column_value(pStmt,i));
printQuoted(out, sqlite3_column_value(pStmt,i));
}
for(i=nPk2+2; i<nQ; i+=2){
printf(",");
printQuoted(sqlite3_column_value(pStmt,i));
fprintf(out, ",");
printQuoted(out, sqlite3_column_value(pStmt,i));
}
printf(");\n");
fprintf(out, ");\n");
}
}
sqlite3_finalize(pStmt);
@@ -702,7 +702,7 @@ static void diff_one_table(const char *zTab){
" AND sql IS NOT NULL)",
zTab, zTab);
while( SQLITE_ROW==sqlite3_step(pStmt) ){
printf("%s;\n", sqlite3_column_text(pStmt,0));
fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
}
sqlite3_finalize(pStmt);
@@ -714,6 +714,141 @@ end_diff_one_table:
return;
}
/*
** Display a summary of differences between two versions of the same
** table table.
**
** * Number of rows changed
** * Number of rows added
** * Number of rows deleted
** * Number of identical rows
*/
static void summarize_one_table(const char *zTab, FILE *out){
char *zId = safeId(zTab); /* Name of table (translated for us in SQL) */
char **az = 0; /* Columns in main */
char **az2 = 0; /* Columns in aux */
int nPk; /* Primary key columns in main */
int nPk2; /* Primary key columns in aux */
int n; /* Number of columns in main */
int n2; /* Number of columns in aux */
int i; /* Loop counter */
const char *zSep; /* Separator string */
Str sql; /* Comparison query */
sqlite3_stmt *pStmt; /* Query statement to do the diff */
sqlite3_int64 nUpdate; /* Number of updated rows */
sqlite3_int64 nUnchanged; /* Number of unmodified rows */
sqlite3_int64 nDelete; /* Number of deleted rows */
sqlite3_int64 nInsert; /* Number of inserted rows */
strInit(&sql);
if( sqlite3_table_column_metadata(g.db,"aux",zTab,0,0,0,0,0,0) ){
if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
/* Table missing from second database. */
fprintf(out, "%s: missing from second database\n", zTab);
}
goto end_summarize_one_table;
}
if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
/* Table missing from source */
fprintf(out, "%s: missing from first database\n", zTab);
goto end_summarize_one_table;
}
az = columnNames("main", zTab, &nPk);
az2 = columnNames("aux", zTab, &nPk2);
if( az && az2 ){
for(n=0; az[n]; n++){
if( sqlite3_stricmp(az[n],az2[n])!=0 ) break;
}
}
if( az==0
|| az2==0
|| nPk!=nPk2
|| az[n]
){
/* Schema mismatch */
fprintf(out, "%s: incompatible schema\n", zTab);
goto end_summarize_one_table;
}
/* Build the comparison query */
for(n2=n; az[n2]; n2++){}
strPrintf(&sql, "SELECT 1, count(*)");
if( n2==nPk2 ){
strPrintf(&sql, ", 0\n");
}else{
zSep = ", sum(";
for(i=nPk; az[i]; i++){
strPrintf(&sql, "%sA.%s IS NOT B.%s", zSep, az[i], az[i]);
zSep = " OR ";
}
strPrintf(&sql, ")\n");
}
strPrintf(&sql, " FROM main.%s A, aux.%s B\n", zId, zId);
zSep = " WHERE";
for(i=0; i<nPk; i++){
strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
zSep = " AND";
}
strPrintf(&sql, " UNION ALL\n");
strPrintf(&sql, "SELECT 2, count(*), 0\n");
strPrintf(&sql, " FROM main.%s A\n", zId);
strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM aux.%s B ", zId);
zSep = "WHERE";
for(i=0; i<nPk; i++){
strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
zSep = " AND";
}
strPrintf(&sql, ")\n");
strPrintf(&sql, " UNION ALL\n");
strPrintf(&sql, "SELECT 3, count(*), 0\n");
strPrintf(&sql, " FROM aux.%s B\n", zId);
strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM main.%s A ", zId);
zSep = "WHERE";
for(i=0; i<nPk; i++){
strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
zSep = " AND";
}
strPrintf(&sql, ")\n ORDER BY 1;\n");
if( (g.fDebug & DEBUG_DIFF_SQL)!=0 ){
printf("SQL for %s:\n%s\n", zId, sql.z);
goto end_summarize_one_table;
}
/* Run the query and output difference summary */
pStmt = db_prepare(sql.z);
nUpdate = 0;
nInsert = 0;
nDelete = 0;
nUnchanged = 0;
while( SQLITE_ROW==sqlite3_step(pStmt) ){
switch( sqlite3_column_int(pStmt,0) ){
case 1:
nUpdate = sqlite3_column_int64(pStmt,2);
nUnchanged = sqlite3_column_int64(pStmt,1) - nUpdate;
break;
case 2:
nDelete = sqlite3_column_int64(pStmt,1);
break;
case 3:
nInsert = sqlite3_column_int64(pStmt,1);
break;
}
}
sqlite3_finalize(pStmt);
fprintf(out, "%s: %lld changes, %lld inserts, %lld deletes, %lld unchanged\n",
zTab, nUpdate, nInsert, nDelete, nUnchanged);
end_summarize_one_table:
strFree(&sql);
sqlite3_free(zId);
namelistFree(az);
namelistFree(az2);
return;
}
/*
** Write a 64-bit signed integer as a varint onto out
*/
@@ -978,6 +1113,7 @@ static void showHelp(void){
" --changeset FILE Write a CHANGESET into FILE\n"
" --primarykey Use schema-defined PRIMARY KEYs\n"
" --schema Show only differences in the schema\n"
" --summary Show only a summary of the differences\n"
" --table TAB Show only differences in table TAB\n"
);
}
@@ -991,7 +1127,8 @@ int main(int argc, char **argv){
char *zSql;
sqlite3_stmt *pStmt;
char *zTab = 0;
FILE *out = 0;
FILE *out = stdout;
void (*xDiff)(const char*,FILE*) = diff_one_table;
g.zArgv0 = argv[0];
for(i=1; i<argc; i++){
@@ -1002,6 +1139,7 @@ int main(int argc, char **argv){
if( strcmp(z,"changeset")==0 ){
out = fopen(argv[++i], "wb");
if( out==0 ) cmdlineError("cannot open: %s", argv[i]);
xDiff = changeset_one_table;
}else
if( strcmp(z,"debug")==0 ){
g.fDebug = strtol(argv[++i], 0, 0);
@@ -1016,6 +1154,9 @@ int main(int argc, char **argv){
if( strcmp(z,"schema")==0 ){
g.bSchemaOnly = 1;
}else
if( strcmp(z,"summary")==0 ){
xDiff = summarize_one_table;
}else
if( strcmp(z,"table")==0 ){
zTab = argv[++i];
}else
@@ -1052,11 +1193,7 @@ int main(int argc, char **argv){
}
if( zTab ){
if( out ){
changeset_one_table(zTab, out);
}else{
diff_one_table(zTab);
}
xDiff(zTab, out);
}else{
/* Handle tables one by one */
pStmt = db_prepare(
@@ -1068,12 +1205,7 @@ int main(int argc, char **argv){
" ORDER BY name"
);
while( SQLITE_ROW==sqlite3_step(pStmt) ){
const char *zTab = (const char*)sqlite3_column_text(pStmt,0);
if( out ){
changeset_one_table(zTab, out);
}else{
diff_one_table(zTab);
}
xDiff((const char*)sqlite3_column_text(pStmt,0), out);
}
sqlite3_finalize(pStmt);
}