Compare commits

..

1 Commits

Author SHA1 Message Date
mistachkin cafc3647a9 The _beginthreadex() / _endthreadex() functions should only be used when compiling with MSVC.
FossilOrigin-Name: 1a5a5da3315e6fe768b8527e46c4d24c6d0e71fb
2014-10-22 16:25:09 +00:00
98 changed files with 1152 additions and 5913 deletions
-1
View File
@@ -394,7 +394,6 @@ TESTSRC = \
TESTSRC += \
$(TOP)/ext/misc/amatch.c \
$(TOP)/ext/misc/closure.c \
$(TOP)/ext/misc/eval.c \
$(TOP)/ext/misc/fileio.c \
$(TOP)/ext/misc/fuzzer.c \
$(TOP)/ext/misc/ieee754.c \
-1
View File
@@ -863,7 +863,6 @@ TESTSRC = \
TESTEXT = \
$(TOP)\ext\misc\amatch.c \
$(TOP)\ext\misc\closure.c \
$(TOP)\ext\misc\eval.c \
$(TOP)\ext\misc\fileio.c \
$(TOP)\ext\misc\fuzzer.c \
$(TOP)\ext\misc\ieee754.c \
+1 -1
View File
@@ -1 +1 @@
3.8.8
3.8.7
Vendored
+9 -9
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.62 for sqlite 3.8.8.
# Generated by GNU Autoconf 2.62 for sqlite 3.8.7.
#
# 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.8'
PACKAGE_STRING='sqlite 3.8.8'
PACKAGE_VERSION='3.8.7'
PACKAGE_STRING='sqlite 3.8.7'
PACKAGE_BUGREPORT=''
# Factoring default headers for most tests.
@@ -1483,7 +1483,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures sqlite 3.8.8 to adapt to many kinds of systems.
\`configure' configures sqlite 3.8.7 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1548,7 +1548,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.8.8:";;
short | recursive ) echo "Configuration of sqlite 3.8.7:";;
esac
cat <<\_ACEOF
@@ -1664,7 +1664,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.8.8
sqlite configure 3.8.7
generated by GNU Autoconf 2.62
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1678,7 +1678,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by sqlite $as_me 3.8.8, which was
It was created by sqlite $as_me 3.8.7, which was
generated by GNU Autoconf 2.62. Invocation command line was
$ $0 $@
@@ -14021,7 +14021,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by sqlite $as_me 3.8.8, which was
This file was extended by sqlite $as_me 3.8.7, which was
generated by GNU Autoconf 2.62. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -14074,7 +14074,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
sqlite config.status 3.8.8
sqlite config.status 3.8.7
configured by $0, generated by GNU Autoconf 2.62,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
-119
View File
@@ -1,119 +0,0 @@
/*
** 2014-11-10
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
******************************************************************************
**
** This SQLite extension implements SQL function eval() which runs
** SQL statements recursively.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <string.h>
/*
** Structure used to accumulate the output
*/
struct EvalResult {
char *z; /* Accumulated output */
const char *zSep; /* Separator */
int szSep; /* Size of the separator string */
int nAlloc; /* Number of bytes allocated for z[] */
int nUsed; /* Number of bytes of z[] actually used */
};
/*
** Callback from sqlite_exec() for the eval() function.
*/
static int callback(void *pCtx, int argc, char **argv, char **colnames){
struct EvalResult *p = (struct EvalResult*)pCtx;
int i;
for(i=0; i<argc; i++){
const char *z = argv[i] ? argv[i] : "";
size_t sz = strlen(z);
if( sz+p->nUsed+p->szSep+1 > p->nAlloc ){
char *zNew;
p->nAlloc = p->nAlloc*2 + sz + p->szSep + 1;
zNew = sqlite3_realloc(p->z, p->nAlloc);
if( zNew==0 ){
sqlite3_free(p->z);
memset(p, 0, sizeof(*p));
return 1;
}
p->z = zNew;
}
if( p->nUsed>0 ){
memcpy(&p->z[p->nUsed], p->zSep, p->szSep);
p->nUsed += p->szSep;
}
memcpy(&p->z[p->nUsed], z, sz);
p->nUsed += sz;
}
return 0;
}
/*
** Implementation of the eval(X) and eval(X,Y) SQL functions.
**
** Evaluate the SQL text in X. Return the results, using string
** Y as the separator. If Y is omitted, use a single space character.
*/
static void sqlEvalFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const char *zSql;
sqlite3 *db;
char *zErr = 0;
int rc;
struct EvalResult x;
memset(&x, 0, sizeof(x));
x.zSep = " ";
zSql = (const char*)sqlite3_value_text(argv[0]);
if( zSql==0 ) return;
if( argc>1 ){
x.zSep = (const char*)sqlite3_value_text(argv[1]);
if( x.zSep==0 ) return;
}
x.szSep = (int)strlen(x.zSep);
db = sqlite3_context_db_handle(context);
rc = sqlite3_exec(db, zSql, callback, &x, &zErr);
if( rc!=SQLITE_OK ){
sqlite3_result_error(context, zErr, -1);
sqlite3_free(zErr);
}else if( x.zSep==0 ){
sqlite3_result_error_nomem(context);
sqlite3_free(x.z);
}else{
sqlite3_result_text(context, x.z, x.nUsed, sqlite3_free);
}
}
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_eval_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
rc = sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0,
sqlEvalFunc, 0, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0,
sqlEvalFunc, 0, 0);
}
return rc;
}
+1 -1
View File
@@ -102,7 +102,7 @@ do_eqp_test rtree6.2.4.2 {
SELECT * FROM t1,t2 WHERE v=10 and x1<10 and x2>10
} {
0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0E1}
0 1 1 {SEARCH TABLE t2 USING AUTOMATIC PARTIAL COVERING INDEX (v=?)}
0 1 1 {SEARCH TABLE t2 USING AUTOMATIC COVERING INDEX (v=?)}
}
do_eqp_test rtree6.2.5 {
-2
View File
@@ -246,7 +246,6 @@ TESTSRC = \
$(TOP)/src/test_autoext.c \
$(TOP)/src/test_async.c \
$(TOP)/src/test_backup.c \
$(TOP)/src/test_blob.c \
$(TOP)/src/test_btree.c \
$(TOP)/src/test_config.c \
$(TOP)/src/test_demovfs.c \
@@ -281,7 +280,6 @@ TESTSRC = \
TESTSRC += \
$(TOP)/ext/misc/amatch.c \
$(TOP)/ext/misc/closure.c \
$(TOP)/ext/misc/eval.c \
$(TOP)/ext/misc/fileio.c \
$(TOP)/ext/misc/fuzzer.c \
$(TOP)/ext/misc/ieee754.c \
+88 -104
View File
@@ -1,12 +1,12 @@
C Adding\sthe\s"noskipscan"\stoken\sto\san\ssqlite_stat1.stat\sfield\sprevents\san\nindex\sfor\sbeing\sused\swith\sthe\sskip-scan\salgorithm.
D 2014-11-15T19:08:13.305
C The\s_beginthreadex()\s/\s_endthreadex()\sfunctions\sshould\sonly\sbe\sused\swhen\scompiling\swith\sMSVC.
D 2014-10-22T16:25:09.852
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc 788f1288633a0c3c3cbbe0f3e4827d033f7ba530
F Makefile.msc e31dee24038965fb6269d6d61073fd6b7e331dec
F Makefile.vxworks 034289efa9d591b04b1a73598623119c306cbba0
F README.md 64f270c43c38c46de749e419c22f0ae2f4499fe8
F VERSION d846487aff892625eb8e75960234e7285f0462fe
F VERSION 53a0b870e7f16d3b06623c31d233a304c163a6af
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 0921066a13130082764ab4ab6456f7b5bebe56de
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure 4343c810cc772571210af75d1a8f7c2eb711d75a x
F configure ad59a5f48b3c59a92b5506040a22fbe3f733a9d8 x
F configure.ac 4cf9f60785143fa141b10962ccc885d973792e9a
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
@@ -109,7 +109,6 @@ F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
F ext/misc/amatch.c 678056a4bfcd83c4e82dea81d37543cd1d6dbee1
F ext/misc/closure.c 636024302cde41b2bf0c542f81c40c624cfb7012
F ext/misc/compress.c 76e45655f4046e756064ab10c62e18f2eb846b9f
F ext/misc/eval.c 04e630bde869aa1fec6b993d40591f963be2f868
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
F ext/misc/fuzzer.c 136533c53cfce0957f0b48fa11dba27e21c5c01d
F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e
@@ -131,7 +130,7 @@ F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
F ext/rtree/rtree3.test a494da55c30ee0bc9b01a91c80c81b387b22d2dc
F ext/rtree/rtree4.test c8fe384f60ebd49540a5fecc990041bf452eb6e0
F ext/rtree/rtree5.test 6a510494f12454bf57ef28f45bc7764ea279431e
F ext/rtree/rtree6.test 773a90db2dce6a8353dd0d5b64bca69b29761196
F ext/rtree/rtree6.test 0cfbdf27ee086bf16a3da2c6f2d5b3d6473cb27e
F ext/rtree/rtree7.test 1fa710b9e6bf997a0c1a537b81be7bb6fded1971
F ext/rtree/rtree8.test db79c812f9e4a11f9b1f3f9934007884610a713a
F ext/rtree/rtree9.test d86ebf08ff6328895613ed577dd8a2a37c472c34
@@ -152,7 +151,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk 084976077a4aa3bd985154b5423e7aed88e4a2e9
F main.mk bbc8b6000ed143a1a8d31d3b4995c359a3188fa1
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
@@ -164,29 +163,29 @@ F mptest/mptest.c 499a74af4be293b7c1c7c3d40f332b67227dd739
F mptest/multiwrite01.test 499ad0310da8dff8e8f98d2e272fc2a8aa741b2e
F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c ba266a779bc7ce10e52e59e7d3dc79fa342e8fdb
F src/analyze.c 951fd859852dfbced4a58b73954f168eeb9d0772
F src/analyze.c 567c94b763b67f7abda06dbf0ba34b0343ed9447
F src/attach.c f4e94df2d1826feda65eb0939f7f6f5f923a0ad9
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c 7ddee9c7d505e07e959a575b18498f17c71e53ea
F src/auth.c d8abcde53426275dab6243b441256fcd8ccbebb2
F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5
F src/btree.c d5d991b518fa5bebc64037dfeb98a48051d864d7
F src/btree.h e31a3a3ebdedb1caf9bda3ad5dbab3db9b780f6e
F src/btree.c 1b1123cba0c65caa0baa51e71b8c089e3167c3ed
F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8
F src/btreeInt.h 026d0129724e8f265fdc60d44ec240cf5a4e6179
F src/build.c 67bb05b1077e0cdaccb2e36bfcbe7a5df9ed31e8
F src/build.c 9dc2bd94347b878c89627000c92b0c8d97ec2919
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
F src/complete.c c4ba6e0626bb94bc77a0861735f3382fcf7cc818
F src/ctime.c df19848891c8a553c80e6f5a035e768280952d1a
F src/date.c 93594514aae68de117ca4a2a0d6cc63eddf26744
F src/delete.c 0750b1eb4d96cd3fb2c798599a3a7c85e92f1417
F src/expr.c a3ff05db5709d628c23890db862e30f3dd9dc428
F src/complete.c 535183afb3c75628b78ce82612931ac7cdf26f14
F src/ctime.c cc296efb42c55f03e439bf4b99d5eb37d4429db9
F src/date.c 57a7f9ba9f6b4d5268f5e411739066a611f99036
F src/delete.c fae81cc2eb14b75267d4f47d3cfc9ae02aae726f
F src/expr.c fc204d08af06437ddaffe5a1b1f1f6f9e1a55d6d
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7
F src/func.c ba47c1671ab3cfdafa6e9d6ee490939ea578adee
F src/global.c 6ded36dda9466fc1c9a3c5492ded81d79bf3977d
F src/global.c 01c1f36ecfcf10770db648422a8852c222308bb9
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
@@ -195,50 +194,50 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
F src/loadext.c de741e66e5ddc1598d904d7289239696e40ed994
F src/main.c d3310d5ed56e246bf1589e47eeaca8be582bd4b8
F src/malloc.c 740db54387204c9a2eb67c6d98e68b08e9ef4eab
F src/main.c bbe872b0ac0007bed0ebe1936fc493b039ad4f51
F src/malloc.c 3c3ac67969612493d435e14b6832793209afd2ec
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c faf615aafd8be74a71494dfa027c113ea5c6615f
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534
F src/mem5.c 61eeb90134f9a5be6c2e68d8daae7628b25953fb
F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85
F src/mutex.c 19bf9acba69ca2f367c3761080f8a9f0cf4670a8
F src/mutex.c 84a073c9a23a8d7bdd2ea832522d1730df18812c
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
F src/mutex_noop.c f3f09fd7a2eb4287cfc799753ffc30380e7b71a1
F src/mutex_unix.c 551e2f25f0fa0ee8fd7a43f50fc3d8be00e95dde
F src/mutex_unix.c 1b10d5413dfc794364a8adf3eb3a192926b43fa3
F src/mutex_w32.c 06bfff9a3a83b53389a51a967643db3967032e1e
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8
F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
F src/os_unix.c fb587121840f690101336879adfa6d0b2cd0e8c7
F src/os_win.c a9e500dd963fb1f67d7860e58b5772abe6123862
F src/os_win.c a019caaae2bcbbc0cc4c39af6e7d7e43d8426053
F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21
F src/pager.c 8d97b3633f098fef817656dcbf167ca904511d78
F src/pager.h d1eee3c3f741be247ce6d82752a178515fc8578b
F src/pager.c a98547ad9b1b5dbbc5e7d1c520be041b5d2c0926
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
F src/parse.y 5dfead8aed90cb0c7c1115898ee2266804daff45
F src/pcache.c ace1b67632deeaa84859b4c16c27711dfb7db3d4
F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
F src/pcache1.c facbdd3ecc09c8f750089d941305694301328e98
F src/pcache.c 4121a0571c18581ee9f82f086d5e2030051ebd6a
F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a
F src/pcache1.c e412cb585f777c840ddce0500eddc5c6043c2bb5
F src/pragma.c 3f3e959390a10c0131676f0e307acce372777e0f
F src/prepare.c b7b7bf020bd4c962f7c8aed5a3c542c7dfe9f9c7
F src/printf.c 9e75a6a0b55bf61cfff7d7e19d89834a1b938236
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c 4965007d6497b6a4d7a6d98751cc39712885f952
F src/prepare.c 6ef0cf2f9274982988ed6b7cab1be23147e94196
F src/printf.c 6b79bbd063dcbadca4cf617a4cde255bcc13ea64
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c a3466128b52a86c466e47ac1a19e2174f7b5cf89
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
F src/select.c 428165951748151e87a15295b7357221433e311b
F src/shell.c bc28d5992109717c87804e2eb1a08a7c8cc7a2fd
F src/sqlite.h.in 0c5c0df7e4e436dfc5592511325bf4a96f6a638d
F src/shell.c 282f8f5278e0c78eb442217531172ec9e1538796
F src/sqlite.h.in 4a5e5158c189d2bcd45c7c4607c2c0eb6d25c153
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
F src/sqliteInt.h c9e95b8fa9aee30d46387735c5be73fa58886e38
F src/sqliteInt.h d6d423b0f62846eb441236bc15417aeede2ebbdc
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 81712116e826b0089bb221b018929536b2b5406f
F src/table.c f142bba7903e93ca8d113a5b8877a108ad1a27dc
F src/tclsqlite.c 0a874655dd39a9875e39c5d3c464db662171d228
F src/test1.c 6b0469b8e06c77b1de1d3e4a3834cf26edea9cc7
F src/status.c 961d5926e5a8fda611d385ec22c226b8635cd1cb
F src/table.c 2e99ef7ef16187e17033d9398dc962ce22dab5cb
F src/tclsqlite.c c67d310c833046cccc192125d64ad422ab882684
F src/test1.c 518db4305d76b29dd9da3f022ca899c8fcdf9fc7
F src/test2.c 98049e51a17dc62606a99a9eb95ee477f9996712
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
@@ -250,9 +249,8 @@ F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8
F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e
F src/test_blob.c 1f2e3e25255b731c4fcf15ee7990d06347cb6c09
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
F src/test_config.c 035c17a173937d019b8dfc1d524f9d3fc8123504
F src/test_config.c a4cdebe093474c02eecc5e4008b1a22198edf975
F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
@@ -284,28 +282,28 @@ F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb
F src/test_vfs.c f84075a388527892ff184988f43b69ce69b8083c
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 6de09362b657f19ba83e5fa521ee715787ce9fee
F src/threads.c 2fa8433e5f766d272d25f722b2a18b1c3e123b7e
F src/tokenize.c cc9016e5007fc5e76789079616d2f26741bcc689
F src/trigger.c 25571661fdeae8c7f975ff40ffec205520a3f92f
F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13
F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c 3b627daa45c7308c1e36e3dbaa3f9ce7e5c7fa73
F src/vacuum.c 9b30ec729337dd012ed88d4c292922c8ef9cf00c
F src/vdbe.c 5e47308836e9bb5fdb4835fdf88eeab071848d3f
F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3
F src/vdbeInt.h 9bb69ff2447c34b6ccc58b34ec35b615f86ead78
F src/vdbeapi.c 07acb615d1e4170e71fc1b0d087f3c53a1ad8e83
F src/vdbeaux.c 9b0a251b6dfab349dd6c6efb40062eb7386b26f5
F src/vdbeblob.c 4af4bfb71f6df7778397b4a0ebc1879793276778
F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8
F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a
F src/vdbe.c 5ee15a66ce07e0482b92aa29e4dd0c5827a22d79
F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327
F src/vdbeInt.h e2a060a55ee18a6ab973353a5e2ec7ee569bf787
F src/vdbeapi.c 37a6c6ae284a97bcace365f2f0a225680c0499d9
F src/vdbeaux.c edbb7a9c8b2a8f7a68ac75c2475edd4040266b76
F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4
F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f
F src/vdbesort.c 87f3923483113d1c95d84640becb4e4946f27d9a
F src/vdbesort.c 975aeffa99acb0991b2f288d30294756bff41438
F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
F src/vtab.c 2a30791bbd7926b589401bd09c3abb33de563793
F src/wal.c fa090966140602f03a621f87d82ee69e66ca63b5
F src/vtab.c cb0c194303fea276b48d7d4b6d970b5a96bde8de
F src/wal.c 10e7de7ce90865a68153f001a61f1d985cd17983
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
F src/where.c cb89128d24ddb5fe3ca290166d66968f2dc0c3c8
F src/whereInt.h d3633e9b592103241b74b0ec76185f3e5b8b62e0
F src/where.c 5099c42e24c63969b3cf3b52e18c1a36cb841a34
F src/whereInt.h 4b459cdbfc9b01f5f27673a35f9967e4dea917e8
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7
@@ -323,7 +321,7 @@ F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213
F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f
F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f
F test/analyze8.test c05a461d0a6b05991106467d0c47480f2e709c82
F test/analyze8.test 093d15c1c888eed5034304a98c992f7360130b88
F test/analyze9.test 72795c8113604b5dcd47a1498a61d6d7fb5d041a
F test/analyzeA.test 3335697f6700c7052295cfd0067fc5b2aacddf9a
F test/analyzeB.test 8bf35ee0a548aea831bf56762cb8e7fdb1db083d
@@ -348,15 +346,13 @@ F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7
F test/autoindex1.test 6ff78b94f43a59616c06c11c55b12935173506d7
F test/autoindex2.test 60d2fc6f38364308ce73a9beb01b47ded38697de
F test/autoindex3.test 8254f689c3241081fad52b7bea18ba53e07e14a2
F test/autoindex4.test fc807f9efd158bec60f5dfdf34ebe46fb274612d
F test/autovacuum.test 941892505d2c0f410a0cb5970dfa1c7c4e5f6e74
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
F test/backcompat.test 19a1f337c68419b020a7481dd272a472c4ad8ef4
F test/backup.test b79299a536a4c6d919094786595b95be56d02014
F test/backup.test c9cdd23a495864b9edf75a9fa66f5cb7e10fcf62
F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf
F test/backup4.test 2a2e4a64388090b152de753fd9e123f28f6a3bd4
F test/backup5.test ee5da6d7fe5082f5b9b0bbfa31d016f52412a2e4
F test/backup_ioerr.test 4c3c7147cee85b024ecf6e150e090c32fdbb5135
F test/backup_malloc.test 7162d604ec2b4683c4b3799a48657fb8b5e2d450
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
@@ -382,10 +378,10 @@ F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738
F test/capi3.test f0718f4f90d0efdc980119bfbdf1d7f1541ee5ef
F test/capi3.test 71bcf2fbd36a9732f617766dfd752552c8e491b5
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
F test/capi3c.test fdc0d67a2cb8e8fc400d5b7735e330161ea057a2
F test/capi3d.test a82b6321c50a1cfc848e386fa2c851893606f68c
F test/capi3c.test a21869e4d50d5dbb7e566e328fc0bc7c2efa6a32
F test/capi3d.test c84af0c49267f9c3fbf4c1c46aa647646023811e
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763
@@ -424,7 +420,7 @@ F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040
F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
F test/corruptG.test 1ab3bf97ee7bdba70e0ff3ba2320657df55d1804
F test/corruptH.test 5dd4fa98c6c1ed33b178f9e8a48c4fdd3cfc9067
F test/corruptH.test 88ed71a086e13591c917aac6de32750e7c7281cb
F test/corruptI.test 221ad8b7f0a9ac6b80fc577e73b5ad8cdea31243
F test/cost.test 19d314526616ce4473eb4e4e450fcb94499ce318
F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5
@@ -454,11 +450,6 @@ F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
F test/distinct.test 086e70c765f172e8974e9f83b9ac5ca03c154e77
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
F test/e_blobbytes.test 9bea1d3e2b20f3010b04abba58f6ba172301f49f
F test/e_blobclose.test df756753f571bc30e42e3a6cba2807576e49e716
F test/e_blobopen.test 234f960d90235a9b51ec3ca1e062e8541dd558d8
F test/e_blobwrite.test 615b405f29feb2cfb5a1f03dab7933258294fa26
F test/e_changes.test fd66105385153dbf21fdb35eb8ef6c3e1eade579
F test/e_createtable.test c7e67b49e6cf92473c8fb30ab26143e9e2128cf7
F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a
F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412
@@ -471,11 +462,9 @@ F test/e_reindex.test 396b7b4f0a66863b4e95116a67d93b227193e589
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
F test/e_select.test 52692ff3849541e828ad4661fe3773a9b8711763
F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f
F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10
F test/e_update.test 312cb8f5ccfe41515a6bb092f8ea562a9bd54d52
F test/e_uri.test 5ae33760fb2039c61aa2d90886f1664664173585
F test/e_vacuum.test 5bfbdc21b65c0abf24398d0ba31dc88d93ca77a9
F test/e_wal.test 0967f0b8f1dfda871dc7b9b5574198f1f4f7d69a
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473
F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40
@@ -498,7 +487,7 @@ F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
F test/fkey5.test 8a1fde4e7721ae00b05b3178888833726ca2df8d
F test/fkey6.test abb59f866c1b44926fd02d1fdd217d831fe04f48
F test/fkey7.test 72e915890ee4a005daaf3002cb208e8fe973ac13
F test/fkey7.test e31d0e71a41c1d29349a16448d6c420e2c53a8fc
F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749
F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb
F test/fts-9fd058691.test 78b887e30ae6816df0e1fed6259de4b5a64ad33c
@@ -627,7 +616,7 @@ F test/in.test 047c4671328e9032ab95666a67021adbbd36e98e
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068
F test/in5.test 1de657472fa9ac2924be25c2c959ac5ca1aae554
F test/in5.test 99f9a40af01711b06d2d614ecfe96129f334fba3
F test/incrblob.test e81846d214f3637622620fbde7cd526781cfe328
F test/incrblob2.test bf4d549aa4a466d7fbe3e3a3693d3861263d5600
F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4
@@ -734,9 +723,8 @@ F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6
F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
F test/misc7.test edd0b63e2ee29a256900b0514f6fff27e19e9bb2
F test/misc8.test e838ec20c9c988bc94812fdb89af26409c20931b
F test/misuse.test 3c34719944ba045cc6c188a4852ba04680728912
F test/mmap1.test 1bfd611b9841eafb44f7d83c0788e146d84a33c9
F test/mmap1.test 93d167b328255cbe6679fe1e1a23be1b1197d07b
F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022
F test/mmap3.test c92273e16eb8d23c1d55c9815b446bb72ef0512e
F test/mmapfault.test d4c9eff9cd8c2dc14bc43e71e042f175b0a26fe3
@@ -780,7 +768,7 @@ F test/permutations.test cef25f5e8499a15846eccd06785f17f4180407ab
F test/pragma.test 19d0241a007bcdd77fc2606ec60fc60357e7fc8b
F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
F test/printf2.test b4acd4bf8734243257f01ddefa17c4fb090acc8a
F test/printf2.test bed79b4c3e5da08ba88ad637c0bf62586843cfb1
F test/progress.test a282973d1d17f08071bc58a77d6b80f2a81c354d
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
@@ -797,21 +785,18 @@ F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
F test/releasetest.mk 2eced2f9ae701fd0a29e714a241760503ccba25a
F test/releasetest.tcl a4279c890698584feb2ffc86735857a4e4474180
F test/resolver01.test 33abf37ff8335e6bf98f2b45a0af3e06996ccd9a
F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea
F test/rollback2.test fc14cf6d1a2b250d2735ef16124b971bce152f14
F test/rollbackfault.test 6a004f71087cc399296cffbb5429ea6da655ae65
F test/rollback.test e9504a009a202c3ed711da2e6879ff60c5a4669c
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
F test/rowid.test 742b5741584a8a44fd83e856cc2896688401d645
F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798
F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09
F test/savepoint.test c671fdbd34cd3bfe1518a777526ada595180cf8d
F test/savepoint.test 51d3900dc071a7c2ad4248578a5925631b476313
F test/savepoint2.test 9b8543940572a2f01a18298c3135ad0c9f4f67d7
F test/savepoint3.test e328085853b14898d78ceea00dfe7db18bb6a9ec
F test/savepoint4.test c8f8159ade6d2acd9128be61e1230f1c1edc6cc0
F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd
F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7
F test/savepoint7.test 1c8f26b1e2a4221b0214e222ce12a97a59918eb2
F test/scanstatus.test a6dd739bc4d9638e8f5c2493b518057f2b681655
F test/savepoint7.test fbf319a7b2dda089ec5be30a424a0e95f121d423
F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481
F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5
F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38
@@ -855,15 +840,15 @@ F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
F test/skipscan1.test 2ddfe5d168462170c4487f534e2a99fb006b2076
F test/skipscan1.test 7e15e1cc524524e7b2c4595ec85c75501d22f4ff
F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a
F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5
F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2
F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b
F test/skipscan6.test 3a891b45d6df266ced861a2ad9d03fca2bc7fcc5
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24
F test/sort.test c4400e7533748f6bd7413851ff148645e82b9e2d
F test/sort2.test 84a92eebf697feee9c6697746918c7d67373eea1
F test/sort2.test 269f4f50c6e468cc32b302ae7ff0add8338ec6de
F test/sort3.test 6178ade30810ac9166fcdf14b7065e49c0f534e2
F test/sort4.test 6c37d85f7cd28d50cce222fcab84ccd771e105cb
F test/sort5.test a448240a42b49239edc00f85d6d7ac7a1b261e1f
@@ -889,7 +874,7 @@ F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c
F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6
F test/table.test 06271d61eb13871490d38168433c1ef3dd82bb2a
F test/table.test 2a1d2fa52c531de5915f28023747d9a8c27b6f31
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43
@@ -959,7 +944,7 @@ F test/tkt-d635236375.test 9d37e988b47d87505bc9445be0ca447002df5d09
F test/tkt-d82e3f3721.test bcc0dfba658d15bab30fd4a9320c9e35d214ce30
F test/tkt-f3e5abed55.test d5a0126118142d13e27f6ce9f4c47096e9321c00
F test/tkt-f67b41381a.test a23bc124c981662db712167bacd0ed8ad11abac9
F test/tkt-f777251dc7a.test d1a8fc3eefb7a9e64d19ff24d5c8c94c34a632fb
F test/tkt-f777251dc7a.test af6531446c64bfd268416f07b4df7be7f9c749d2
F test/tkt-f7b4edec.test d998a08ff2b18b7f62edce8e3044317c45efe6c7
F test/tkt-f973c7ac31.test 28ef85c7f015477916795246d8286aeda39d4ead
F test/tkt-fa7bf5ec.test 9102dfea58aa371d78969da735f9392c57e2e035
@@ -1054,7 +1039,7 @@ F test/trace.test 73a5508100f7fccfbc3f8018d5f6963ed478eea0
F test/trace2.test 93b47ca6996c66b47f57224cfb146f34e07df382
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
F test/trans3.test 373ac5183cc56be69f48ae44090e7f672939f732
F test/transitive1.test 03f532954f46cdf5608f7766bff0b0c52bf2a7cd
F test/trigger1.test dc47573ac79ffe0ee3eecaa517d70d8dacbccd03
F test/trigger2.test 5cd7d69a7ba1143ee045e4ae2963ff32ae4c87a6
@@ -1064,7 +1049,7 @@ F test/trigger5.test 619391a3e9fc194081d22cefd830d811e7badf83
F test/trigger6.test 0e411654f122552da6590f0b4e6f781048a4a9b9
F test/trigger7.test b39e6dee1debe0ff9c2ef66326668f149f07c9c4
F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4
F test/trigger9.test 2226ec795a33b0460ab5cf8891e9054cc7edef41
F test/trigger9.test 5b0789f1c5c4600961f8e68511b825b87be53e31
F test/triggerA.test fe5597f47ee21bacb4936dc827994ed94161e332
F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe
F test/triggerC.test a68980c5955d62ee24be6f97129d824f199f9a4c
@@ -1078,7 +1063,7 @@ F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264
F test/unique2.test 41e7f83c6827605991160a31380148a9fc5f1339
F test/unixexcl.test cd6c765f75e50e8e2c2ba763149e5d340ea19825
F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8
F test/update.test 6c68446b8a0a33d522a7c72b320934596a2d7d32
F test/update.test 1b6c488a8f993d090b7ee9ad0e234faa161b3aeb
F test/uri.test 23662b7b61958b0f0e47082de7d06341ccf85d5b
F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9
F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae
@@ -1165,7 +1150,7 @@ F test/without_rowid1.test 7862e605753c8d25329f665fa09072e842183151
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
F test/without_rowid3.test 1081aabf60a1e1123b7f9a8f6ae19954351843b0
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
F test/without_rowid5.test 61256715b686359df48ca1742db50cc7e3e7b862
F test/without_rowid5.test b4a639a367f04d382d20e8f44fc1be4f2d57d107
F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac
@@ -1200,7 +1185,7 @@ F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
F tool/showdb.c bd073a78bce714a0e42d92ea474b3eb8cb53be5d
F tool/showjournal.c 053eb1cc774710c6890b7dd6293300cc297b16a5
F tool/showstat4.c 9515faa8ec176599d4a8288293ba8ec61f7b728a
F tool/showstat4.c c39279d6bd37cb999b634f0064f6f86ad7af008f
F tool/showwal.c 85cb36d4fe3e93e2fbd63e786e0d1ce42d0c4fad
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b
@@ -1215,16 +1200,15 @@ F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003
F tool/vdbe-compress.tcl 5926c71f9c12d2ab73ef35c29376e756eb68361c
F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 55e453aadbb676dda07f0fa537d39ce184ef636c
R 59717354988087765927b6c6b6246253
T *branch * noskipscan-token
T *sym-noskipscan-token *
P 3c933bf95f291f7957580d823dce92c981375a5c
R af2834bb71df32c5023a7384a0a52a6c
T *branch * msvcThreads
T *sym-msvcThreads *
T -sym-trunk *
U drh
Z 9d226c4fa6bf82a1f1a22a271191f33c
U mistachkin
Z fb1887a94bcdc5356b2224d0baf2a2e1
+1 -1
View File
@@ -1 +1 @@
00fe09505792cd0d104b2da9d040f023e30fa871
1a5a5da3315e6fe768b8527e46c4d24c6d0e71fb
+38 -45
View File
@@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH SQLITE3 1 "Fri Oct 31 10:41:31 EDT 2014"
.TH SQLITE3 1 "Mon Jan 31 11:14:00 2014"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@@ -49,7 +49,7 @@ a table named "memos" and insert a couple of records into that table:
$
.B sqlite3 mydata.db
.br
SQLite version 3.8.8
SQLite version 3.8.3
.br
Enter ".help" for instructions
.br
@@ -107,29 +107,26 @@ the '.help' command. For example:
sqlite>
.B .help
.nf
.tr %.
%backup ?DB? FILE Backup DB (default "main") to FILE
%bail on|off Stop after hitting an error. Default OFF
%clone NEWDB Clone data into NEWDB from the existing database
%databases List names and files of attached databases
%dump ?TABLE? ... Dump the database in an SQL text format
.cc |
.backup ?DB? FILE Backup DB (default "main") to FILE
.bail ON|OFF Stop after hitting an error. Default OFF
.databases List names and files of attached databases
.dump ?TABLE? ... Dump the database in an SQL text format
If TABLE specified, only dump tables matching
LIKE pattern TABLE.
%echo on|off Turn command echo on or off
%eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN
%exit Exit this program
%explain ?on|off? Turn output mode suitable for EXPLAIN on or off.
.echo ON|OFF Turn command echo on or off
.exit Exit this program
.explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.
With no args, it turns EXPLAIN on.
%fullschema Show schema and the content of sqlite_stat tables
%headers on|off Turn display of headers on or off
%help Show this message
%import FILE TABLE Import data from FILE into TABLE
%indices ?TABLE? Show names of all indices
.header(s) ON|OFF Turn display of headers on or off
.help Show this message
.import FILE TABLE Import data from FILE into TABLE
.indices ?TABLE? Show names of all indices
If TABLE specified, only show indices for tables
matching LIKE pattern TABLE.
%load FILE ?ENTRY? Load an extension library
%log FILE|off Turn logging on or off. FILE can be stderr/stdout
%mode MODE ?TABLE? Set output mode where MODE is one of:
.load FILE ?ENTRY? Load an extension library
.log FILE|off Turn logging on or off. FILE can be stderr/stdout
.mode MODE ?TABLE? Set output mode where MODE is one of:
csv Comma-separated values
column Left-aligned columns. (See .width)
html HTML <table> code
@@ -138,35 +135,31 @@ sqlite>
list Values delimited by .separator string
tabs Tab-separated values
tcl TCL list elements
%nullvalue STRING Use STRING in place of NULL values
%once FILENAME Output for the next SQL command only to FILENAME
%open ?FILENAME? Close existing database and reopen FILENAME
%output ?FILENAME? Send output to FILENAME or stdout
%print STRING... Print literal STRING
%prompt MAIN CONTINUE Replace the standard prompts
%quit Exit this program
%read FILENAME Execute SQL in FILENAME
%restore ?DB? FILE Restore content of DB (default "main") from FILE
%save FILE Write in-memory database into FILE
%schema ?TABLE? Show the CREATE statements
.nullvalue STRING Use STRING in place of NULL values
.open ?FILENAME? Close existing database and reopen FILENAME
.output FILENAME Send output to FILENAME
.output stdout Send output to the screen
.print STRING... Print literal STRING
.prompt MAIN CONTINUE Replace the standard prompts
.quit Exit this program
.read FILENAME Execute SQL in FILENAME
.restore ?DB? FILE Restore content of DB (default "main") from FILE
.schema ?TABLE? Show the CREATE statements
If TABLE specified, only show tables matching
LIKE pattern TABLE.
%separator STRING ?NL? Change separator used by output mode and .import
NL is the end-of-line mark for CSV
%shell CMD ARGS... Run CMD ARGS... in a system shell
%show Show the current values for various settings
%stats on|off Turn stats on or off
%system CMD ARGS... Run CMD ARGS... in a system shell
%tables ?TABLE? List names of tables
.separator STRING Change separator used by output mode and .import
.show Show the current values for various settings
.stats ON|OFF Turn stats on or off
.tables ?TABLE? List names of tables
If TABLE specified, only list tables matching
LIKE pattern TABLE.
%timeout MS Try opening locked tables for MS milliseconds
%timer on|off Turn SQL timer on or off
%trace FILE|off Output each SQL statement as it is run
%vfsname ?AUX? Print the name of the VFS stack
%width NUM1 NUM2 ... Set column widths for "column" mode
Negative values right-justify
.timeout MS Try opening locked tables for MS milliseconds
.trace FILE|off Output each SQL statement as it is run
.vfsname ?AUX? Print the name of the VFS stack
.width NUM1 NUM2 ... Set column widths for "column" mode
.timer ON|OFF Turn the CPU timer measurement on or off
sqlite>
|cc .
.sp
.fi
.SH OPTIONS
@@ -276,7 +269,7 @@ o If the -init option is present, the specified file is processed.
o All other command line options are processed.
.SH SEE ALSO
http://www.sqlite.org/cli.html
http://www.sqlite.org/
.br
The sqlite3-doc package.
.SH AUTHOR
+1 -3
View File
@@ -1466,8 +1466,6 @@ static void decodeIntArray(
pIndex->bUnordered = 1;
}else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
}else if( sqlite3_strglob("noskipscan*", z)==0 ){
pIndex->noSkipScan = 1;
}
#ifdef SQLITE_ENABLE_COSTMULT
else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
@@ -1863,7 +1861,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
/* Load the statistics from the sqlite_stat4 table. */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){
if( rc==SQLITE_OK ){
int lookasideEnabled = db->lookaside.bEnabled;
db->lookaside.bEnabled = 0;
rc = loadStat4(db, sInfo.zDatabase);
-3
View File
@@ -72,9 +72,6 @@ int sqlite3_set_authorizer(
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pArg
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
db->xAuth = (sqlite3_xauth)xAuth;
db->pAuthArg = pArg;
+6 -45
View File
@@ -122,20 +122,6 @@ static int setDestPgsz(sqlite3_backup *p){
return rc;
}
/*
** Check that there is no open read-transaction on the b-tree passed as the
** second argument. If there is not, return SQLITE_OK. Otherwise, if there
** is an open read-transaction, return SQLITE_ERROR and leave an error
** message in database handle db.
*/
static int checkReadTransaction(sqlite3 *db, Btree *p){
if( sqlite3BtreeIsInReadTrans(p) ){
sqlite3ErrorWithMsg(db, SQLITE_ERROR, "destination database is in use");
return SQLITE_ERROR;
}
return SQLITE_OK;
}
/*
** Create an sqlite3_backup process to copy the contents of zSrcDb from
** connection handle pSrcDb to zDestDb in pDestDb. If successful, return
@@ -152,13 +138,6 @@ sqlite3_backup *sqlite3_backup_init(
){
sqlite3_backup *p; /* Value to return */
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(pSrcDb)||!sqlite3SafetyCheckOk(pDestDb) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
/* Lock the source database handle. The destination database
** handle is not locked in this routine, but it is locked in
** sqlite3_backup_step(). The user is required to ensure that no
@@ -195,15 +174,12 @@ sqlite3_backup *sqlite3_backup_init(
p->iNext = 1;
p->isAttached = 0;
if( 0==p->pSrc || 0==p->pDest
|| setDestPgsz(p)==SQLITE_NOMEM
|| checkReadTransaction(pDestDb, p->pDest)!=SQLITE_OK
){
if( 0==p->pSrc || 0==p->pDest || setDestPgsz(p)==SQLITE_NOMEM ){
/* One (or both) of the named databases did not exist or an OOM
** error was hit. Or there is a transaction open on the destination
** database. The error has already been written into the pDestDb
** handle. All that is left to do here is free the sqlite3_backup
** structure. */
** error was hit. The error has already been written into the
** pDestDb handle. All that is left to do here is free the
** sqlite3_backup structure.
*/
sqlite3_free(p);
p = 0;
}
@@ -358,9 +334,6 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
int pgszSrc = 0; /* Source page size */
int pgszDest = 0; /* Destination page size */
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(p->pSrcDb->mutex);
sqlite3BtreeEnter(p->pSrc);
if( p->pDestDb ){
@@ -624,7 +597,7 @@ int sqlite3_backup_finish(sqlite3_backup *p){
}
/* If a transaction is still open on the Btree, roll it back. */
sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0);
sqlite3BtreeRollback(p->pDest, SQLITE_OK);
/* Set the error code of the destination database handle. */
rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
@@ -650,12 +623,6 @@ int sqlite3_backup_finish(sqlite3_backup *p){
** call to sqlite3_backup_step().
*/
int sqlite3_backup_remaining(sqlite3_backup *p){
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
return p->nRemaining;
}
@@ -664,12 +631,6 @@ int sqlite3_backup_remaining(sqlite3_backup *p){
** recent call to sqlite3_backup_step().
*/
int sqlite3_backup_pagecount(sqlite3_backup *p){
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
return p->nPagecount;
}
+351 -678
View File
File diff suppressed because it is too large Load Diff
+2 -3
View File
@@ -83,7 +83,7 @@ int sqlite3BtreeBeginTrans(Btree*,int);
int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
int sqlite3BtreeCommitPhaseTwo(Btree*, int);
int sqlite3BtreeCommit(Btree*);
int sqlite3BtreeRollback(Btree*,int,int);
int sqlite3BtreeRollback(Btree*,int);
int sqlite3BtreeBeginStmt(Btree*,int);
int sqlite3BtreeCreateTable(Btree*, int*, int flags);
int sqlite3BtreeIsInTrans(Btree*);
@@ -116,7 +116,7 @@ int sqlite3BtreeIncrVacuum(Btree *);
int sqlite3BtreeDropTable(Btree*, int, int*);
int sqlite3BtreeClearTable(Btree*, int, int*);
int sqlite3BtreeClearTableOfCursor(BtCursor*);
int sqlite3BtreeTripAllCursors(Btree*, int, int);
void sqlite3BtreeTripAllCursors(Btree*, int);
void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
@@ -196,7 +196,6 @@ void sqlite3BtreeClearCursor(BtCursor *);
int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask);
int sqlite3BtreeIsReadonly(Btree *pBt);
int sqlite3HeaderSizeBtree(void);
#ifndef NDEBUG
int sqlite3BtreeCursorIsValid(BtCursor*);
+1 -5
View File
@@ -307,11 +307,7 @@ int sqlite3UserAuthTable(const char *zTable){
Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
Table *p = 0;
int i;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || zName==0 ) return 0;
#endif
assert( zName!=0 );
/* All mutexes are required for schema access. Make sure we hold them. */
assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) );
#if SQLITE_USER_AUTHENTICATION
-7
View File
@@ -105,13 +105,6 @@ int sqlite3_complete(const char *zSql){
u8 state = 0; /* Current state, using numbers defined in header comment */
u8 token; /* Value of the next token */
#ifdef SQLITE_ENABLE_API_ARMOR
if( zSql==0 ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
#ifndef SQLITE_OMIT_TRIGGER
/* A complex statement machine used to detect the end of a CREATE TRIGGER
** statement. This is the normal case.
+3 -10
View File
@@ -63,9 +63,6 @@ static const char * const azCompileOpt[] = {
#ifdef SQLITE_DISABLE_LFS
"DISABLE_LFS",
#endif
#ifdef SQLITE_ENABLE_API_ARMOR
"ENABLE_API_ARMOR",
#endif
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
"ENABLE_ATOMIC_WRITE",
#endif
@@ -158,6 +155,9 @@ static const char * const azCompileOpt[] = {
#ifdef SQLITE_MAX_SCHEMA_RETRY
"MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY),
#endif
#ifdef SQLITE_MAX_WORKER_THREADS
"MAX_WORKER_THREADS=" CTIMEOPT_VAL(SQLITE_MAX_WORKER_THREADS),
#endif
#ifdef SQLITE_MEMDEBUG
"MEMDEBUG",
#endif
@@ -391,13 +391,6 @@ static const char * const azCompileOpt[] = {
*/
int sqlite3_compileoption_used(const char *zOptName){
int i, n;
#ifdef SQLITE_ENABLE_API_ARMOR
if( zOptName==0 ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
n = sqlite3Strlen30(zOptName);
+4 -4
View File
@@ -16,7 +16,7 @@
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** SQLite processes all times and dates as julian day numbers. The
** SQLite processes all times and dates as Julian Day numbers. The
** dates and times are stored as the number of days since noon
** in Greenwich on November 24, 4714 B.C. according to the Gregorian
** calendar system.
@@ -31,7 +31,7 @@
**
** The Gregorian calendar system is used for all dates and times,
** even those that predate the Gregorian calendar. Historians usually
** use the julian calendar for dates prior to 1582-10-15 and for some
** use the Julian calendar for dates prior to 1582-10-15 and for some
** dates afterwards, depending on locale. Beware of this difference.
**
** The conversion algorithms are implemented based on descriptions
@@ -304,7 +304,7 @@ static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
}
/*
** Attempt to parse the given string into a julian day number. Return
** Attempt to parse the given string into a Julian Day Number. Return
** the number of errors.
**
** The following are acceptable forms for the input string:
@@ -875,7 +875,7 @@ static void dateFunc(
** %f ** fractional seconds SS.SSS
** %H hour 00-24
** %j day of year 000-366
** %J ** julian day number
** %J ** Julian day number
** %m month 01-12
** %M minute 00-59
** %s seconds since 1970-01-01
+1 -1
View File
@@ -481,7 +481,7 @@ void sqlite3DeleteFrom(
assert( nKey==nPk ); /* OP_Found will use an unpacked key */
assert( !IsVirtual(pTab) );
if( aToOpen[iDataCur-iTabCur] ){
assert( pPk!=0 || pTab->pSelect!=0 );
assert( pPk!=0 );
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
VdbeCoverage(v);
}
+33 -53
View File
@@ -1210,24 +1210,20 @@ void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
}
/*
** These routines are Walker callbacks used to check expressions to
** see if they are "constant" for some definition of constant. The
** Walker.eCode value determines the type of "constant" we are looking
** for.
** These routines are Walker callbacks. Walker.u.pi is a pointer
** to an integer. These routines are checking an expression to see
** if it is a constant. Set *Walker.u.i to 0 if the expression is
** not constant.
**
** These callback routines are used to implement the following:
**
** sqlite3ExprIsConstant() pWalker->eCode==1
** sqlite3ExprIsConstantNotJoin() pWalker->eCode==2
** sqlite3ExprRefOneTableOnly() pWalker->eCode==3
** sqlite3ExprIsConstantOrFunction() pWalker->eCode==4 or 5
**
** In all cases, the callbacks set Walker.eCode=0 and abort if the expression
** is found to not be a constant.
** sqlite3ExprIsConstant() pWalker->u.i==1
** sqlite3ExprIsConstantNotJoin() pWalker->u.i==2
** sqlite3ExprIsConstantOrFunction() pWalker->u.i==3 or 4
**
** The sqlite3ExprIsConstantOrFunction() is used for evaluating expressions
** in a CREATE TABLE statement. The Walker.eCode value is 5 when parsing
** an existing schema and 4 when processing a new statement. A bound
** in a CREATE TABLE statement. The Walker.u.i value is 4 when parsing
** an existing schema and 3 when processing a new statement. A bound
** parameter raises an error for new statements, but is silently converted
** to NULL for existing schemas. This allows sqlite_master tables that
** contain a bound parameter because they were generated by older versions
@@ -1236,25 +1232,23 @@ void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
*/
static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
/* If pWalker->eCode is 2 then any term of the expression that comes from
** the ON or USING clauses of a left join disqualifies the expression
/* If pWalker->u.i is 2 then any term of the expression that comes from
** the ON or USING clauses of a join disqualifies the expression
** from being considered constant. */
if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_FromJoin) ){
pWalker->eCode = 0;
if( pWalker->u.i==2 && ExprHasProperty(pExpr, EP_FromJoin) ){
pWalker->u.i = 0;
return WRC_Abort;
}
switch( pExpr->op ){
/* Consider functions to be constant if all their arguments are constant
** and either pWalker->eCode==4 or 5 or the function has the
** SQLITE_FUNC_CONST flag. */
** and either pWalker->u.i==3 or 4 or the function as the SQLITE_FUNC_CONST
** flag. */
case TK_FUNCTION:
if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_Constant) ){
if( pWalker->u.i>=3 || ExprHasProperty(pExpr,EP_Constant) ){
return WRC_Continue;
}else{
pWalker->eCode = 0;
return WRC_Abort;
}
/* Fall through */
case TK_ID:
case TK_COLUMN:
case TK_AGG_FUNCTION:
@@ -1263,22 +1257,18 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
testcase( pExpr->op==TK_COLUMN );
testcase( pExpr->op==TK_AGG_FUNCTION );
testcase( pExpr->op==TK_AGG_COLUMN );
if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){
return WRC_Continue;
}else{
pWalker->eCode = 0;
return WRC_Abort;
}
pWalker->u.i = 0;
return WRC_Abort;
case TK_VARIABLE:
if( pWalker->eCode==5 ){
if( pWalker->u.i==4 ){
/* Silently convert bound parameters that appear inside of CREATE
** statements into a NULL when parsing the CREATE statement text out
** of the sqlite_master table */
pExpr->op = TK_NULL;
}else if( pWalker->eCode==4 ){
}else if( pWalker->u.i==3 ){
/* A bound parameter in a CREATE statement that originates from
** sqlite3_prepare() causes an error */
pWalker->eCode = 0;
pWalker->u.i = 0;
return WRC_Abort;
}
/* Fall through */
@@ -1290,22 +1280,21 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
}
static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){
UNUSED_PARAMETER(NotUsed);
pWalker->eCode = 0;
pWalker->u.i = 0;
return WRC_Abort;
}
static int exprIsConst(Expr *p, int initFlag, int iCur){
static int exprIsConst(Expr *p, int initFlag){
Walker w;
memset(&w, 0, sizeof(w));
w.eCode = initFlag;
w.u.i = initFlag;
w.xExprCallback = exprNodeIsConstant;
w.xSelectCallback = selectNodeIsConstant;
w.u.iCur = iCur;
sqlite3WalkExpr(&w, p);
return w.eCode;
return w.u.i;
}
/*
** Walk an expression tree. Return non-zero if the expression is constant
** Walk an expression tree. Return 1 if the expression is constant
** and 0 if it involves variables or function calls.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
@@ -1313,31 +1302,21 @@ static int exprIsConst(Expr *p, int initFlag, int iCur){
** a constant.
*/
int sqlite3ExprIsConstant(Expr *p){
return exprIsConst(p, 1, 0);
return exprIsConst(p, 1);
}
/*
** Walk an expression tree. Return non-zero if the expression is constant
** Walk an expression tree. Return 1 if the expression is constant
** that does no originate from the ON or USING clauses of a join.
** Return 0 if it involves variables or function calls or terms from
** an ON or USING clause.
*/
int sqlite3ExprIsConstantNotJoin(Expr *p){
return exprIsConst(p, 2, 0);
return exprIsConst(p, 2);
}
/*
** Walk an expression tree. Return non-zero if the expression constant
** for any single row of the table with cursor iCur. In other words, the
** expression must not refer to any non-deterministic function nor any
** table other than iCur.
*/
int sqlite3ExprIsTableConstant(Expr *p, int iCur){
return exprIsConst(p, 3, iCur);
}
/*
** Walk an expression tree. Return non-zero if the expression is constant
** Walk an expression tree. Return 1 if the expression is constant
** or a function call with constant arguments. Return and 0 if there
** are any variables.
**
@@ -1347,7 +1326,7 @@ int sqlite3ExprIsTableConstant(Expr *p, int iCur){
*/
int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
assert( isInit==0 || isInit==1 );
return exprIsConst(p, 4+isInit, 0);
return exprIsConst(p, 3+isInit);
}
/*
@@ -1857,6 +1836,7 @@ int sqlite3CodeSubselect(
assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
pSelect->iLimit = 0;
testcase( pSelect->selFlags & SF_Distinct );
pSelect->selFlags &= ~SF_Distinct;
testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
if( sqlite3Select(pParse, pSelect, &dest) ){
sqlite3KeyInfoUnref(pKeyInfo);
+2 -10
View File
@@ -135,19 +135,11 @@ const unsigned char sqlite3CtypeMap[256] = {
**
** EVIDENCE-OF: R-38799-08373 URI filenames can be enabled or disabled
** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options.
**
** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
** SQLITE_USE_URI symbol defined.
*/
#ifndef SQLITE_USE_URI
# define SQLITE_USE_URI 0
#endif
/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
** that compile-time option is omitted.
*/
#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
#endif
@@ -237,8 +229,8 @@ const Token sqlite3IntTokens[] = {
**
** IMPORTANT: Changing the pending byte to any value other than
** 0x40000000 results in an incompatible database file format!
** Changing the pending byte during operation will result in undefined
** and incorrect behavior.
** Changing the pending byte during operating results in undefined
** and dileterious behavior.
*/
#ifndef SQLITE_OMIT_WSD
int sqlite3PendingByte = 0x40000000;
+37 -261
View File
@@ -329,17 +329,15 @@ int sqlite3_config(int op, ...){
switch( op ){
/* Mutex configuration options are only available in a threadsafe
** compile.
** compile.
*/
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-54466-46756 */
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0
case SQLITE_CONFIG_SINGLETHREAD: {
/* Disable all mutexing */
sqlite3GlobalConfig.bCoreMutex = 0;
sqlite3GlobalConfig.bFullMutex = 0;
break;
}
#endif
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-20520-54086 */
case SQLITE_CONFIG_MULTITHREAD: {
/* Disable mutexing of database connections */
/* Enable mutexing of core data structures */
@@ -347,23 +345,17 @@ int sqlite3_config(int op, ...){
sqlite3GlobalConfig.bFullMutex = 0;
break;
}
#endif
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-59593-21810 */
case SQLITE_CONFIG_SERIALIZED: {
/* Enable all mutexing */
sqlite3GlobalConfig.bCoreMutex = 1;
sqlite3GlobalConfig.bFullMutex = 1;
break;
}
#endif
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-63666-48755 */
case SQLITE_CONFIG_MUTEX: {
/* Specify an alternative mutex implementation */
sqlite3GlobalConfig.mutex = *va_arg(ap, sqlite3_mutex_methods*);
break;
}
#endif
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-14450-37597 */
case SQLITE_CONFIG_GETMUTEX: {
/* Retrieve the current mutex implementation */
*va_arg(ap, sqlite3_mutex_methods*) = sqlite3GlobalConfig.mutex;
@@ -371,61 +363,37 @@ int sqlite3_config(int op, ...){
}
#endif
case SQLITE_CONFIG_MALLOC: {
/* EVIDENCE-OF: R-55594-21030 The SQLITE_CONFIG_MALLOC option takes a
** single argument which is a pointer to an instance of the
** sqlite3_mem_methods structure. The argument specifies alternative
** low-level memory allocation routines to be used in place of the memory
** allocation routines built into SQLite. */
/* Specify an alternative malloc implementation */
sqlite3GlobalConfig.m = *va_arg(ap, sqlite3_mem_methods*);
break;
}
case SQLITE_CONFIG_GETMALLOC: {
/* EVIDENCE-OF: R-51213-46414 The SQLITE_CONFIG_GETMALLOC option takes a
** single argument which is a pointer to an instance of the
** sqlite3_mem_methods structure. The sqlite3_mem_methods structure is
** filled with the currently defined memory allocation routines. */
/* Retrieve the current malloc() implementation */
if( sqlite3GlobalConfig.m.xMalloc==0 ) sqlite3MemSetDefault();
*va_arg(ap, sqlite3_mem_methods*) = sqlite3GlobalConfig.m;
break;
}
case SQLITE_CONFIG_MEMSTATUS: {
/* EVIDENCE-OF: R-61275-35157 The SQLITE_CONFIG_MEMSTATUS option takes
** single argument of type int, interpreted as a boolean, which enables
** or disables the collection of memory allocation statistics. */
/* Enable or disable the malloc status collection */
sqlite3GlobalConfig.bMemstat = va_arg(ap, int);
break;
}
case SQLITE_CONFIG_SCRATCH: {
/* EVIDENCE-OF: R-08404-60887 There are three arguments to
** SQLITE_CONFIG_SCRATCH: A pointer an 8-byte aligned memory buffer from
** which the scratch allocations will be drawn, the size of each scratch
** allocation (sz), and the maximum number of scratch allocations (N). */
/* Designate a buffer for scratch memory space */
sqlite3GlobalConfig.pScratch = va_arg(ap, void*);
sqlite3GlobalConfig.szScratch = va_arg(ap, int);
sqlite3GlobalConfig.nScratch = va_arg(ap, int);
break;
}
case SQLITE_CONFIG_PAGECACHE: {
/* EVIDENCE-OF: R-31408-40510 There are three arguments to
** SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory, the size
** of each page buffer (sz), and the number of pages (N). */
/* Designate a buffer for page cache memory space */
sqlite3GlobalConfig.pPage = va_arg(ap, void*);
sqlite3GlobalConfig.szPage = va_arg(ap, int);
sqlite3GlobalConfig.nPage = va_arg(ap, int);
break;
}
case SQLITE_CONFIG_PCACHE_HDRSZ: {
/* EVIDENCE-OF: R-39100-27317 The SQLITE_CONFIG_PCACHE_HDRSZ option takes
** a single parameter which is a pointer to an integer and writes into
** that integer the number of extra bytes per page required for each page
** in SQLITE_CONFIG_PAGECACHE. */
*va_arg(ap, int*) =
sqlite3HeaderSizeBtree() +
sqlite3HeaderSizePcache() +
sqlite3HeaderSizePcache1();
break;
}
case SQLITE_CONFIG_PCACHE: {
/* no-op */
@@ -438,18 +406,11 @@ int sqlite3_config(int op, ...){
}
case SQLITE_CONFIG_PCACHE2: {
/* EVIDENCE-OF: R-63325-48378 The SQLITE_CONFIG_PCACHE2 option takes a
** single argument which is a pointer to an sqlite3_pcache_methods2
** object. This object specifies the interface to a custom page cache
** implementation. */
/* Specify an alternative page cache implementation */
sqlite3GlobalConfig.pcache2 = *va_arg(ap, sqlite3_pcache_methods2*);
break;
}
case SQLITE_CONFIG_GETPCACHE2: {
/* EVIDENCE-OF: R-22035-46182 The SQLITE_CONFIG_GETPCACHE2 option takes a
** single argument which is a pointer to an sqlite3_pcache_methods2
** object. SQLite copies of the current page cache implementation into
** that object. */
if( sqlite3GlobalConfig.pcache2.xInit==0 ){
sqlite3PCacheSetDefault();
}
@@ -457,14 +418,9 @@ int sqlite3_config(int op, ...){
break;
}
/* EVIDENCE-OF: R-06626-12911 The SQLITE_CONFIG_HEAP option is only
** available if SQLite is compiled with either SQLITE_ENABLE_MEMSYS3 or
** SQLITE_ENABLE_MEMSYS5 and returns SQLITE_ERROR if invoked otherwise. */
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
case SQLITE_CONFIG_HEAP: {
/* EVIDENCE-OF: R-19854-42126 There are three arguments to
** SQLITE_CONFIG_HEAP: An 8-byte aligned pointer to the memory, the
** number of bytes in the memory buffer, and the minimum allocation size. */
/* Designate a buffer for heap memory space */
sqlite3GlobalConfig.pHeap = va_arg(ap, void*);
sqlite3GlobalConfig.nHeap = va_arg(ap, int);
sqlite3GlobalConfig.mnReq = va_arg(ap, int);
@@ -477,19 +433,17 @@ int sqlite3_config(int op, ...){
}
if( sqlite3GlobalConfig.pHeap==0 ){
/* EVIDENCE-OF: R-49920-60189 If the first pointer (the memory pointer)
** is NULL, then SQLite reverts to using its default memory allocator
** (the system malloc() implementation), undoing any prior invocation of
** SQLITE_CONFIG_MALLOC.
**
** Setting sqlite3GlobalConfig.m to all zeros will cause malloc to
** revert to its default implementation when sqlite3_initialize() is run
/* If the heap pointer is NULL, then restore the malloc implementation
** back to NULL pointers too. This will cause the malloc to go
** back to its default implementation when sqlite3_initialize() is
** run.
*/
memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m));
}else{
/* EVIDENCE-OF: R-61006-08918 If the memory pointer is not NULL then the
** alternative memory allocator is engaged to handle all of SQLites
** memory allocation needs. */
/* The heap pointer is not NULL, then install one of the
** mem5.c/mem3.c methods. The enclosing #if guarantees at
** least one of these methods is currently enabled.
*/
#ifdef SQLITE_ENABLE_MEMSYS3
sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3();
#endif
@@ -528,19 +482,11 @@ int sqlite3_config(int op, ...){
** sqlite3_config(SQLITE_CONFIG_URI,0) configuration calls.
*/
case SQLITE_CONFIG_URI: {
/* EVIDENCE-OF: R-25451-61125 The SQLITE_CONFIG_URI option takes a single
** argument of type int. If non-zero, then URI handling is globally
** enabled. If the parameter is zero, then URI handling is globally
** disabled. */
sqlite3GlobalConfig.bOpenUri = va_arg(ap, int);
break;
}
case SQLITE_CONFIG_COVERING_INDEX_SCAN: {
/* EVIDENCE-OF: R-36592-02772 The SQLITE_CONFIG_COVERING_INDEX_SCAN
** option takes a single integer argument which is interpreted as a
** boolean in order to enable or disable the use of covering indices for
** full table scans in the query optimizer. */
sqlite3GlobalConfig.bUseCis = va_arg(ap, int);
break;
}
@@ -555,33 +501,20 @@ int sqlite3_config(int op, ...){
#endif
case SQLITE_CONFIG_MMAP_SIZE: {
/* EVIDENCE-OF: R-58063-38258 SQLITE_CONFIG_MMAP_SIZE takes two 64-bit
** integer (sqlite3_int64) values that are the default mmap size limit
** (the default setting for PRAGMA mmap_size) and the maximum allowed
** mmap size limit. */
sqlite3_int64 szMmap = va_arg(ap, sqlite3_int64);
sqlite3_int64 mxMmap = va_arg(ap, sqlite3_int64);
/* EVIDENCE-OF: R-53367-43190 If either argument to this option is
** negative, then that argument is changed to its compile-time default.
**
** EVIDENCE-OF: R-34993-45031 The maximum allowed mmap size will be
** silently truncated if necessary so that it does not exceed the
** compile-time maximum mmap size set by the SQLITE_MAX_MMAP_SIZE
** compile-time option.
*/
if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ) mxMmap = SQLITE_MAX_MMAP_SIZE;
if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ){
mxMmap = SQLITE_MAX_MMAP_SIZE;
}
sqlite3GlobalConfig.mxMmap = mxMmap;
if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE;
if( szMmap>mxMmap) szMmap = mxMmap;
sqlite3GlobalConfig.mxMmap = mxMmap;
sqlite3GlobalConfig.szMmap = szMmap;
break;
}
#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC) /* IMP: R-04780-55815 */
#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC)
case SQLITE_CONFIG_WIN32_HEAPSIZE: {
/* EVIDENCE-OF: R-34926-03360 SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit
** unsigned integer value that specifies the maximum size of the created
** heap. */
sqlite3GlobalConfig.nHeap = va_arg(ap, int);
break;
}
@@ -665,12 +598,6 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
** Return the mutex associated with a database connection.
*/
sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
return db->mutex;
}
@@ -680,10 +607,6 @@ sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
*/
int sqlite3_db_release_memory(sqlite3 *db){
int i;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
sqlite3BtreeEnterAll(db);
for(i=0; i<db->nDb; i++){
@@ -814,12 +737,6 @@ static int nocaseCollatingFunc(
** Return the ROWID of the most recent insert
*/
sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
return db->lastRowid;
}
@@ -827,12 +744,6 @@ sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
** Return the number of changes in the most recent call to sqlite3_exec().
*/
int sqlite3_changes(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
return db->nChange;
}
@@ -840,12 +751,6 @@ int sqlite3_changes(sqlite3 *db){
** Return the number of changes since the database handle was opened.
*/
int sqlite3_total_changes(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
return db->nTotalChange;
}
@@ -1111,15 +1016,13 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
/*
** Rollback all database files. If tripCode is not SQLITE_OK, then
** any write cursors are invalidated ("tripped" - as in "tripping a circuit
** any open cursors are invalidated ("tripped" - as in "tripping a circuit
** breaker") and made to return tripCode if there are any further
** attempts to use that cursor. Read cursors remain open and valid
** but are "saved" in case the table pages are moved around.
** attempts to use that cursor.
*/
void sqlite3RollbackAll(sqlite3 *db, int tripCode){
int i;
int inTrans = 0;
int schemaChange;
assert( sqlite3_mutex_held(db->mutex) );
sqlite3BeginBenignMalloc();
@@ -1130,7 +1033,6 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
** the database rollback and schema reset, which can cause false
** corruption reports in some cases. */
sqlite3BtreeEnterAll(db);
schemaChange = (db->flags & SQLITE_InternChanges)!=0 && db->init.busy==0;
for(i=0; i<db->nDb; i++){
Btree *p = db->aDb[i].pBt;
@@ -1138,7 +1040,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
if( sqlite3BtreeIsInTrans(p) ){
inTrans = 1;
}
sqlite3BtreeRollback(p, tripCode, !schemaChange);
sqlite3BtreeRollback(p, tripCode);
}
}
sqlite3VtabRollback(db);
@@ -1394,9 +1296,6 @@ int sqlite3_busy_handler(
int (*xBusy)(void*,int),
void *pArg
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE;
#endif
sqlite3_mutex_enter(db->mutex);
db->busyHandler.xFunc = xBusy;
db->busyHandler.pArg = pArg;
@@ -1418,12 +1317,6 @@ void sqlite3_progress_handler(
int (*xProgress)(void*),
void *pArg
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return;
}
#endif
sqlite3_mutex_enter(db->mutex);
if( nOps>0 ){
db->xProgress = xProgress;
@@ -1444,9 +1337,6 @@ void sqlite3_progress_handler(
** specified number of milliseconds before returning 0.
*/
int sqlite3_busy_timeout(sqlite3 *db, int ms){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
if( ms>0 ){
sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
db->busyTimeout = ms;
@@ -1460,12 +1350,6 @@ int sqlite3_busy_timeout(sqlite3 *db, int ms){
** Cause any pending operation to stop at its earliest opportunity.
*/
void sqlite3_interrupt(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return;
}
#endif
db->u1.isInterrupted = 1;
}
@@ -1603,12 +1487,6 @@ int sqlite3_create_function_v2(
){
int rc = SQLITE_ERROR;
FuncDestructor *pArg = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
return SQLITE_MISUSE_BKPT;
}
#endif
sqlite3_mutex_enter(db->mutex);
if( xDestroy ){
pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor));
@@ -1645,10 +1523,6 @@ int sqlite3_create_function16(
){
int rc;
char *zFunc8;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || zFunctionName==0 ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE);
@@ -1680,12 +1554,6 @@ int sqlite3_overload_function(
){
int nName = sqlite3Strlen30(zName);
int rc = SQLITE_OK;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || zName==0 || nArg<-2 ){
return SQLITE_MISUSE_BKPT;
}
#endif
sqlite3_mutex_enter(db->mutex);
if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
@@ -1707,13 +1575,6 @@ int sqlite3_overload_function(
*/
void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
void *pOld;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
sqlite3_mutex_enter(db->mutex);
pOld = db->pTraceArg;
db->xTrace = xTrace;
@@ -1735,13 +1596,6 @@ void *sqlite3_profile(
void *pArg
){
void *pOld;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
sqlite3_mutex_enter(db->mutex);
pOld = db->pProfileArg;
db->xProfile = xProfile;
@@ -1762,13 +1616,6 @@ void *sqlite3_commit_hook(
void *pArg /* Argument to the function */
){
void *pOld;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
sqlite3_mutex_enter(db->mutex);
pOld = db->pCommitArg;
db->xCommitCallback = xCallback;
@@ -1787,13 +1634,6 @@ void *sqlite3_update_hook(
void *pArg /* Argument to the function */
){
void *pRet;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
sqlite3_mutex_enter(db->mutex);
pRet = db->pUpdateArg;
db->xUpdateCallback = xCallback;
@@ -1812,13 +1652,6 @@ void *sqlite3_rollback_hook(
void *pArg /* Argument to the function */
){
void *pRet;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
sqlite3_mutex_enter(db->mutex);
pRet = db->pRollbackArg;
db->xRollbackCallback = xCallback;
@@ -1865,9 +1698,6 @@ int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(nFrame);
#else
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
if( nFrame>0 ){
sqlite3_wal_hook(db, sqlite3WalDefaultHook, SQLITE_INT_TO_PTR(nFrame));
}else{
@@ -1888,12 +1718,6 @@ void *sqlite3_wal_hook(
){
#ifndef SQLITE_OMIT_WAL
void *pRet;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
sqlite3_mutex_enter(db->mutex);
pRet = db->pWalArg;
db->xWalCallback = xCallback;
@@ -1921,10 +1745,6 @@ int sqlite3_wal_checkpoint_v2(
int rc; /* Return code */
int iDb = SQLITE_MAX_ATTACHED; /* sqlite3.aDb[] index of db to checkpoint */
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
/* Initialize the output variables to -1 in case an error occurs. */
if( pnLog ) *pnLog = -1;
if( pnCkpt ) *pnCkpt = -1;
@@ -2321,12 +2141,6 @@ static const int aHardLimit[] = {
int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
int oldLimit;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return -1;
}
#endif
/* EVIDENCE-OF: R-30189-54097 For each limit category SQLITE_LIMIT_NAME
** there is a hard upper bound set at compile-time by a C preprocessor
@@ -2403,8 +2217,7 @@ int sqlite3ParseUri(
assert( *pzErrMsg==0 );
if( ((flags & SQLITE_OPEN_URI) /* IMP: R-48725-32206 */
|| sqlite3GlobalConfig.bOpenUri) /* IMP: R-51689-46548 */
if( ((flags & SQLITE_OPEN_URI) || sqlite3GlobalConfig.bOpenUri)
&& nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */
){
char *zOpt;
@@ -2613,9 +2426,6 @@ static int openDatabase(
char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */
char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */
#ifdef SQLITE_ENABLE_API_ARMOR
if( ppDb==0 ) return SQLITE_MISUSE_BKPT;
#endif
*ppDb = 0;
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite3_initialize();
@@ -2905,15 +2715,13 @@ int sqlite3_open16(
sqlite3_value *pVal;
int rc;
#ifdef SQLITE_ENABLE_API_ARMOR
if( ppDb==0 ) return SQLITE_MISUSE_BKPT;
#endif
assert( zFilename );
assert( ppDb );
*ppDb = 0;
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite3_initialize();
if( rc ) return rc;
#endif
if( zFilename==0 ) zFilename = "\000\000";
pVal = sqlite3ValueNew(0);
sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
@@ -2943,7 +2751,13 @@ int sqlite3_create_collation(
void* pCtx,
int(*xCompare)(void*,int,const void*,int,const void*)
){
return sqlite3_create_collation_v2(db, zName, enc, pCtx, xCompare, 0);
int rc;
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, 0);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
}
/*
@@ -2958,10 +2772,6 @@ int sqlite3_create_collation_v2(
void(*xDel)(void*)
){
int rc;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xDel);
@@ -2983,10 +2793,6 @@ int sqlite3_create_collation16(
){
int rc = SQLITE_OK;
char *zName8;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE);
@@ -3009,9 +2815,6 @@ int sqlite3_collation_needed(
void *pCollNeededArg,
void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*)
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
db->xCollNeeded = xCollNeeded;
db->xCollNeeded16 = 0;
@@ -3030,9 +2833,6 @@ int sqlite3_collation_needed16(
void *pCollNeededArg,
void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*)
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
db->xCollNeeded = 0;
db->xCollNeeded16 = xCollNeeded16;
@@ -3059,12 +2859,6 @@ int sqlite3_global_recover(void){
** by the next COMMIT or ROLLBACK.
*/
int sqlite3_get_autocommit(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
return db->autoCommit;
}
@@ -3247,9 +3041,6 @@ int sqlite3_sleep(int ms){
** Enable or disable the extended result codes.
*/
int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
db->errMask = onoff ? 0xffffffff : 0xff;
sqlite3_mutex_leave(db->mutex);
@@ -3263,9 +3054,6 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
int rc = SQLITE_ERROR;
Btree *pBtree;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
pBtree = sqlite3DbNameToBtree(db, zDbName);
if( pBtree ){
@@ -3608,7 +3396,7 @@ int sqlite3_test_control(int op, ...){
** returns a NULL pointer.
*/
const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
if( zFilename==0 || zParam==0 ) return 0;
if( zFilename==0 ) return 0;
zFilename += sqlite3Strlen30(zFilename) + 1;
while( zFilename[0] ){
int x = strcmp(zFilename, zParam);
@@ -3664,12 +3452,6 @@ Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
** connection.
*/
const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
return pBt ? sqlite3BtreeGetFilename(pBt) : 0;
}
@@ -3679,12 +3461,6 @@ const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
** no such database exists.
*/
int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return -1;
}
#endif
Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
return pBt ? sqlite3BtreeIsReadonly(pBt) : -1;
}
+5 -6
View File
@@ -377,12 +377,11 @@ void *sqlite3ScratchMalloc(int n){
#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
/* EVIDENCE-OF: R-12970-05880 SQLite will not use more than one scratch
** buffers per thread.
**
** This can only be checked in single-threaded mode.
*/
assert( scratchAllocOut==0 );
/* Verify that no more than two scratch allocations per thread
** are outstanding at one time. (This is only checked in the
** single-threaded case since checking in the multi-threaded case
** would be much more complicated.) */
assert( scratchAllocOut<=1 );
if( p ) scratchAllocOut++;
#endif
-1
View File
@@ -82,7 +82,6 @@ int sqlite3MutexEnd(void){
sqlite3_mutex *sqlite3_mutex_alloc(int id){
#ifndef SQLITE_OMIT_AUTOINIT
if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0;
if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0;
#endif
return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
}
+2 -6
View File
@@ -175,12 +175,8 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
break;
}
default: {
#ifdef SQLITE_ENABLE_API_ARMOR
if( iType-2<0 || iType-2>=ArraySize(staticMutexes) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
assert( iType-2 >= 0 );
assert( iType-2 < ArraySize(staticMutexes) );
p = &staticMutexes[iType-2];
#if SQLITE_MUTEX_NREF
p->id = iType;
-4
View File
@@ -361,10 +361,6 @@ int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
int rc = sqlite3_initialize();
if( rc ) return rc;
#endif
#ifdef SQLITE_ENABLE_API_ARMOR
if( pVfs==0 ) return SQLITE_MISUSE_BKPT;
#endif
MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
sqlite3_mutex_enter(mutex);
vfsUnlink(pVfs);
+10 -17
View File
@@ -34,11 +34,6 @@
with SQLITE_OMIT_WAL."
#endif
#if !SQLITE_OS_WINNT && SQLITE_MAX_MMAP_SIZE>0
# error "Memory mapped files require support from the Windows NT kernel,\
compile with SQLITE_MAX_MMAP_SIZE=0."
#endif
/*
** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
** based on the sub-platform)?
@@ -168,11 +163,10 @@
/*
** Do we need to manually define the Win32 file mapping APIs for use with WAL
** mode or memory mapped files (e.g. these APIs are available in the Windows
** CE SDK; however, they are not present in the header file)?
** mode (e.g. these APIs are available in the Windows CE SDK; however, they
** are not present in the header file)?
*/
#if SQLITE_WIN32_FILEMAPPING_API && \
(!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
#if SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL)
/*
** Two of the file mapping APIs are different under WinRT. Figure out which
** set we need.
@@ -200,7 +194,7 @@ WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
** This file mapping API is common to both Win32 and WinRT.
*/
WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
#endif /* SQLITE_WIN32_FILEMAPPING_API */
#endif /* SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) */
/*
** Some Microsoft compilers lack this definition.
@@ -493,7 +487,7 @@ static struct win_syscall {
LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
(!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
!defined(SQLITE_OMIT_WAL))
{ "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 },
#else
{ "CreateFileMappingA", (SYSCALL)0, 0 },
@@ -503,7 +497,7 @@ static struct win_syscall {
DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
(!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
!defined(SQLITE_OMIT_WAL))
{ "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 },
#else
{ "CreateFileMappingW", (SYSCALL)0, 0 },
@@ -843,8 +837,7 @@ static struct win_syscall {
LPOVERLAPPED))aSyscall[48].pCurrent)
#endif
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && \
(!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
{ "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 },
#else
{ "MapViewOfFile", (SYSCALL)0, 0 },
@@ -914,7 +907,7 @@ static struct win_syscall {
#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
LPOVERLAPPED))aSyscall[58].pCurrent)
#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
{ "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 },
#else
{ "UnmapViewOfFile", (SYSCALL)0, 0 },
@@ -977,7 +970,7 @@ static struct win_syscall {
#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent)
#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
{ "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 },
#else
{ "MapViewOfFileFromApp", (SYSCALL)0, 0 },
@@ -1041,7 +1034,7 @@ static struct win_syscall {
#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent)
#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
{ "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
#else
{ "CreateFileMappingFromApp", (SYSCALL)0, 0 },
-13
View File
@@ -6847,18 +6847,6 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
}
#endif
/*
** The page handle passed as the first argument refers to a dirty page
** with a page number other than iNew. This function changes the page's
** page number to iNew and sets the value of the PgHdr.flags field to
** the value passed as the third parameter.
*/
void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){
assert( pPg->pgno!=iNew );
pPg->flags = flags;
sqlite3PcacheMove(pPg, iNew);
}
/*
** Return a pointer to the data for the specified page.
*/
@@ -7257,5 +7245,4 @@ int sqlite3PagerWalFramesize(Pager *pPager){
}
#endif
#endif /* SQLITE_OMIT_DISKIO */
-2
View File
@@ -188,8 +188,6 @@ int sqlite3SectorSize(sqlite3_file *);
/* Functions used to truncate the database file. */
void sqlite3PagerTruncateImage(Pager*,Pgno);
void sqlite3PagerRekey(DbPage*, Pgno, u16);
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
void *sqlite3PagerCodec(DbPage *);
#endif
-7
View File
@@ -651,13 +651,6 @@ void sqlite3PcacheShrink(PCache *pCache){
sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
}
/*
** Return the size of the header added by this middleware layer
** in the page-cache hierarchy.
*/
int sqlite3HeaderSizePcache(void){ return sizeof(PgHdr); }
#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
/*
** For all dirty pages currently in the cache, invoke the specified
-4
View File
@@ -160,8 +160,4 @@ void sqlite3PcacheStats(int*,int*,int*,int*);
void sqlite3PCacheSetDefault(void);
/* Return the header size */
int sqlite3HeaderSizePcache(void);
int sqlite3HeaderSizePcache1(void);
#endif /* _PCACHE_H_ */
-5
View File
@@ -981,11 +981,6 @@ void sqlite3PCacheSetDefault(void){
sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods);
}
/*
** Return the size of the header on each page of this PCACHE implementation.
*/
int sqlite3HeaderSizePcache1(void){ return sizeof(PgHdr1); }
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
** This function is called to free superfluous dynamically allocated memory
+4 -9
View File
@@ -709,12 +709,9 @@ static int sqlite3LockAndPrepare(
const char **pzTail /* OUT: End of parsed string */
){
int rc;
#ifdef SQLITE_ENABLE_API_ARMOR
if( ppStmt==0 ) return SQLITE_MISUSE_BKPT;
#endif
assert( ppStmt!=0 );
*ppStmt = 0;
if( !sqlite3SafetyCheckOk(db)||zSql==0 ){
if( !sqlite3SafetyCheckOk(db) ){
return SQLITE_MISUSE_BKPT;
}
sqlite3_mutex_enter(db->mutex);
@@ -821,11 +818,9 @@ static int sqlite3Prepare16(
const char *zTail8 = 0;
int rc = SQLITE_OK;
#ifdef SQLITE_ENABLE_API_ARMOR
if( ppStmt==0 ) return SQLITE_MISUSE_BKPT;
#endif
assert( ppStmt );
*ppStmt = 0;
if( !sqlite3SafetyCheckOk(db)||zSql==0 ){
if( !sqlite3SafetyCheckOk(db) ){
return SQLITE_MISUSE_BKPT;
}
if( nBytes>=0 ){
+19 -47
View File
@@ -21,7 +21,11 @@
** the glibc version so the glibc version is definitely preferred.
*/
#if !defined(HAVE_STRCHRNUL)
# define HAVE_STRCHRNUL 0
# if defined(linux)
# define HAVE_STRCHRNUL 1
# else
# define HAVE_STRCHRNUL 0
# endif
#endif
@@ -212,7 +216,7 @@ void sqlite3VXPrintf(
const et_info *infop; /* Pointer to the appropriate info structure */
char *zOut; /* Rendering buffer */
int nOut; /* Size of the rendering buffer */
char *zExtra = 0; /* Malloced memory used by some conversion */
char *zExtra; /* Malloced memory used by some conversion */
#ifndef SQLITE_OMIT_FLOATING_POINT
int exp, e2; /* exponent of real numbers */
int nsd; /* Number of significant digits returned */
@@ -223,13 +227,6 @@ void sqlite3VXPrintf(
PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */
char buf[etBUFSIZE]; /* Conversion buffer */
#ifdef SQLITE_ENABLE_API_ARMOR
if( ap==0 ){
(void)SQLITE_MISUSE_BKPT;
sqlite3StrAccumReset(pAccum);
return;
}
#endif
bufpt = 0;
if( bFlags ){
if( (bArgList = (bFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){
@@ -336,6 +333,7 @@ void sqlite3VXPrintf(
break;
}
}
zExtra = 0;
/*
** At this point, variables are initialized as follows:
@@ -626,16 +624,13 @@ void sqlite3VXPrintf(
}else{
c = va_arg(ap,int);
}
if( precision>1 ){
width -= precision-1;
if( width>1 && !flag_leftjustify ){
sqlite3AppendChar(pAccum, width-1, ' ');
width = 0;
}
sqlite3AppendChar(pAccum, precision-1, c);
buf[0] = (char)c;
if( precision>=0 ){
for(idx=1; idx<precision; idx++) buf[idx] = (char)c;
length = precision;
}else{
length =1;
}
length = 1;
buf[0] = c;
bufpt = buf;
break;
case etSTRING:
@@ -736,14 +731,11 @@ void sqlite3VXPrintf(
** the output.
*/
width -= length;
if( width>0 && !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
if( width>0 && !flag_leftjustify ) sqlite3AppendSpace(pAccum, width);
sqlite3StrAccumAppend(pAccum, bufpt, length);
if( width>0 && flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
if( width>0 && flag_leftjustify ) sqlite3AppendSpace(pAccum, width);
if( zExtra ){
sqlite3_free(zExtra);
zExtra = 0;
}
if( zExtra ) sqlite3_free(zExtra);
}/* End for loop over the format string */
} /* End of function */
@@ -770,11 +762,6 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
char *zOld = (p->zText==p->zBase ? 0 : p->zText);
i64 szNew = p->nChar;
szNew += N + 1;
if( szNew+p->nChar<=p->mxAlloc ){
/* Force exponential buffer size growth as long as it does not overflow,
** to avoid having to call this routine too often */
szNew += p->nChar;
}
if( szNew > p->mxAlloc ){
sqlite3StrAccumReset(p);
setStrAccumError(p, STRACCUM_TOOBIG);
@@ -791,7 +778,6 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
assert( p->zText!=0 || p->nChar==0 );
if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
p->zText = zNew;
p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
}else{
sqlite3StrAccumReset(p);
setStrAccumError(p, STRACCUM_NOMEM);
@@ -802,11 +788,11 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
}
/*
** Append N copies of character c to the given string buffer.
** Append N space characters to the given string buffer.
*/
void sqlite3AppendChar(StrAccum *p, int N, char c){
void sqlite3AppendSpace(StrAccum *p, int N){
if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return;
while( (N--)>0 ) p->zText[p->nChar++] = c;
while( (N--)>0 ) p->zText[p->nChar++] = ' ';
}
/*
@@ -961,13 +947,6 @@ char *sqlite3_vmprintf(const char *zFormat, va_list ap){
char *z;
char zBase[SQLITE_PRINT_BUF_SIZE];
StrAccum acc;
#ifdef SQLITE_ENABLE_API_ARMOR
if( zFormat==0 ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
@@ -1010,13 +989,6 @@ char *sqlite3_mprintf(const char *zFormat, ...){
char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
StrAccum acc;
if( n<=0 ) return zBuf;
#ifdef SQLITE_ENABLE_API_ARMOR
if( zBuf==0 || zFormat==0 ) {
(void)SQLITE_MISUSE_BKPT;
if( zBuf && n>0 ) zBuf[0] = 0;
return zBuf;
}
#endif
sqlite3StrAccumInit(&acc, zBuf, n, 0);
acc.useMalloc = 0;
sqlite3VXPrintf(&acc, 0, zFormat, ap);
+4 -12
View File
@@ -48,19 +48,11 @@ void sqlite3_randomness(int N, void *pBuf){
#endif
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex;
#endif
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return;
#endif
#if SQLITE_THREADSAFE
mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
#endif
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
sqlite3_mutex_enter(mutex);
if( N<=0 || pBuf==0 ){
#endif
if( N<=0 ){
wsdPrng.isInit = 0;
sqlite3_mutex_leave(mutex);
return;
+4 -4
View File
@@ -28,7 +28,7 @@
** is a helper function - a callback for the tree walker.
*/
static int incrAggDepth(Walker *pWalker, Expr *pExpr){
if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n;
if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.i;
return WRC_Continue;
}
static void incrAggFunctionDepth(Expr *pExpr, int N){
@@ -36,7 +36,7 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){
Walker w;
memset(&w, 0, sizeof(w));
w.xExprCallback = incrAggDepth;
w.u.n = N;
w.u.i = N;
sqlite3WalkExpr(&w, pExpr);
}
}
@@ -584,7 +584,7 @@ static int exprProbability(Expr *p){
sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8);
assert( r>=0.0 );
if( r>1.0 ) return -1;
return (int)(r*134217728.0);
return (int)(r*1000.0);
}
/*
@@ -716,7 +716,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent to
** likelihood(X,0.9375). */
/* TUNING: unlikely() probability is 0.0625. likely() is 0.9375 */
pExpr->iTable = pDef->zName[0]=='u' ? 8388608 : 125829120;
pExpr->iTable = pDef->zName[0]=='u' ? 62 : 938;
}
}
#ifndef SQLITE_OMIT_AUTHORIZATION
+32 -132
View File
@@ -172,8 +172,7 @@ static HANDLE hProcess;
static FILETIME ftKernelBegin;
static FILETIME ftUserBegin;
static sqlite3_int64 ftWallBegin;
typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
LPFILETIME, LPFILETIME);
typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
static GETPROCTIMES getProcessTimesAddr = NULL;
/*
@@ -184,16 +183,15 @@ static int hasTimer(void){
if( getProcessTimesAddr ){
return 1;
} else {
/* GetProcessTimes() isn't supported in WIN95 and some other Windows
** versions. See if the version we are running on has it, and if it
** does, save off a pointer to it and the current process handle.
/* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
** See if the version we are running on has it, and if it does, save off
** a pointer to it and the current process handle.
*/
hProcess = GetCurrentProcess();
if( hProcess ){
HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
if( NULL != hinstLib ){
getProcessTimesAddr =
(GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
if( NULL != getProcessTimesAddr ){
return 1;
}
@@ -210,8 +208,7 @@ static int hasTimer(void){
static void beginTimer(void){
if( enableTimer && getProcessTimesAddr ){
FILETIME ftCreation, ftExit;
getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
&ftKernelBegin,&ftUserBegin);
getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
ftWallBegin = timeOfDay();
}
}
@@ -230,7 +227,7 @@ static void endTimer(void){
if( enableTimer && getProcessTimesAddr){
FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
sqlite3_int64 ftWallEnd = timeOfDay();
getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
printf("Run Time: real %.3f user %f sys %f\n",
(ftWallEnd - ftWallBegin)*0.001,
timeDiff(&ftUserBegin, &ftUserEnd),
@@ -460,7 +457,6 @@ struct ShellState {
int echoOn; /* True to echo input commands */
int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
int statsOn; /* True to display memory stats before each finalize */
int scanstatsOn; /* True to display scan stats before each finalize */
int outCount; /* Revert to stdout when reaching zero */
int cnt; /* Number of records displayed so far */
FILE *out; /* Write results here */
@@ -729,13 +725,7 @@ static void interrupt_handler(int NotUsed){
** This is the callback routine that the shell
** invokes for each row of a query result.
*/
static int shell_callback(
void *pArg,
int nArg, /* Number of result columns */
char **azArg, /* Text of each result column */
char **azCol, /* Column names */
int *aiType /* Column types */
){
static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
int i;
ShellState *p = (ShellState*)pArg;
@@ -1114,77 +1104,57 @@ static int display_stats(
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
fprintf(pArg->out,
"Memory Used: %d (max %d) bytes\n",
iCur, iHiwtr);
fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
iCur, iHiwtr);
fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
if( pArg->shellFlgs & SHFLG_Pagecache ){
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
fprintf(pArg->out,
"Number of Pcache Pages Used: %d (max %d) pages\n",
iCur, iHiwtr);
fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
}
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
fprintf(pArg->out,
"Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
iCur, iHiwtr);
fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
if( pArg->shellFlgs & SHFLG_Scratch ){
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n",
iCur, iHiwtr);
fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
}
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
fprintf(pArg->out,
"Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
iCur, iHiwtr);
fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Largest Allocation: %d bytes\n",
iHiwtr);
fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
iHiwtr);
fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
iHiwtr);
fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
#ifdef YYTRACKMAXSTACKDEPTH
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
iCur, iHiwtr);
fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
#endif
}
if( pArg && pArg->out && db ){
if( pArg->shellFlgs & SHFLG_Lookaside ){
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
&iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n",
iCur, iHiwtr);
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
&iCur, &iHiwtr, bReset);
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
&iCur, &iHiwtr, bReset);
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
&iCur, &iHiwtr, bReset);
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
}
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Pager Heap Usage: %d bytes\n",iCur);
iHiwtr = iCur = -1;
fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
fprintf(pArg->out, "Page cache hits: %d\n", iCur);
iHiwtr = iCur = -1;
@@ -1195,19 +1165,18 @@ static int display_stats(
fprintf(pArg->out, "Page cache writes: %d\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Schema Heap Usage: %d bytes\n",iCur);
fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",iCur);
fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
}
if( pArg && pArg->out && db && pArg->pStmt ){
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
bReset);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
fprintf(pArg->out, "Sort Operations: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
@@ -1216,51 +1185,6 @@ static int display_stats(
return 0;
}
/*
** Display scan stats.
*/
static void display_scanstats(
sqlite3 *db, /* Database to query */
ShellState *pArg /* Pointer to ShellState */
){
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
int i, k, n, mx;
fprintf(pArg->out, "-------- scanstats --------\n");
mx = 0;
for(k=0; k<=mx; k++){
double rEstLoop = 1.0;
for(i=n=0; 1; i++){
sqlite3_stmt *p = pArg->pStmt;
sqlite3_int64 nLoop, nVisit;
double rEst;
int iSid;
const char *zExplain;
if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
break;
}
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
if( iSid>mx ) mx = iSid;
if( iSid!=k ) continue;
if( n==0 ){
rEstLoop = (double)nLoop;
if( k>0 ) fprintf(pArg->out, "-------- subquery %d -------\n", k);
}
n++;
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
rEstLoop *= rEst;
fprintf(pArg->out,
" nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
);
}
}
fprintf(pArg->out, "---------------------------\n");
#endif
}
/*
** Parameter azArray points to a zero-terminated array of strings. zStr
** points to a single nul-terminated string. Return non-zero if zStr
@@ -1302,8 +1226,7 @@ static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
"NextIfOpen", "PrevIfOpen", 0 };
const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
"Rewind", 0 };
const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead", "Rewind", 0 };
const char *azGoto[] = { "Goto", 0 };
/* Try to figure out if this is really an EXPLAIN statement. If this
@@ -1416,8 +1339,7 @@ static int shell_exec(
/* Show the EXPLAIN QUERY PLAN if .eqp is on */
if( pArg && pArg->autoEQP ){
sqlite3_stmt *pExplain;
char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
sqlite3_sql(pStmt));
char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", sqlite3_sql(pStmt));
rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
if( rc==SQLITE_OK ){
while( sqlite3_step(pExplain)==SQLITE_ROW ){
@@ -1501,11 +1423,6 @@ static int shell_exec(
display_stats(db, pArg, 0);
}
/* print loop-counters if required */
if( pArg && pArg->scanstatsOn ){
display_scanstats(db, pArg);
}
/* Finalize the statement just executed. If this fails, save a
** copy of the error message. Otherwise, set zSql to point to the
** next statement to execute. */
@@ -1716,7 +1633,6 @@ static char zHelp[] =
".read FILENAME Execute SQL in FILENAME\n"
".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
".save FILE Write in-memory database into FILE\n"
".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
".schema ?TABLE? Show the CREATE statements\n"
" If TABLE specified, only show tables matching\n"
" LIKE pattern TABLE.\n"
@@ -3098,19 +3014,6 @@ static int do_meta_command(char *zLine, ShellState *p){
sqlite3_close(pSrc);
}else
if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
if( nArg==2 ){
p->scanstatsOn = booleanValue(azArg[1]);
#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
fprintf(stderr, "Warning: .scanstats not available in this build.\n");
#endif
}else{
fprintf(stderr, "Usage: .scanstats on|off\n");
rc = 1;
}
}else
if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
ShellState data;
char *zErrMsg = 0;
@@ -3368,7 +3271,7 @@ static int do_meta_command(char *zLine, ShellState *p){
for(i=0; i<nPrintRow; i++){
for(j=i; j<nRow; j+=nPrintRow){
char *zSp = j<nPrintRow ? "" : " ";
fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
}
fprintf(p->out, "\n");
}
@@ -3838,8 +3741,7 @@ static char *find_home_dir(void){
static char *home_dir = NULL;
if( home_dir ) return home_dir;
#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
&& !defined(__RTP__) && !defined(_WRS_KERNEL)
#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
{
struct passwd *pwent;
uid_t uid = getuid();
@@ -4238,8 +4140,6 @@ int main(int argc, char **argv){
data.autoEQP = 1;
}else if( strcmp(z,"-stats")==0 ){
data.statsOn = 1;
}else if( strcmp(z,"-scanstats")==0 ){
data.scanstatsOn = 1;
}else if( strcmp(z,"-bail")==0 ){
bail_on_error = 1;
}else if( strcmp(z,"-version")==0 ){
+173 -303
View File
@@ -52,7 +52,7 @@ extern "C" {
/*
** These no-op macros are used in front of interfaces to mark those
** interfaces as either deprecated or experimental. New applications
** should not use deprecated interfaces - they are supported for backwards
** should not use deprecated interfaces - they are support for backwards
** compatibility only. Application writers should be aware that
** experimental interfaces are subject to change in point releases.
**
@@ -1499,27 +1499,25 @@ struct sqlite3_mem_methods {
** SQLITE_CONFIG_SERIALIZED configuration option.</dd>
**
** [[SQLITE_CONFIG_MALLOC]] <dt>SQLITE_CONFIG_MALLOC</dt>
** <dd> ^(The SQLITE_CONFIG_MALLOC option takes a single argument which is
** a pointer to an instance of the [sqlite3_mem_methods] structure.
** The argument specifies
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mem_methods] structure. The argument specifies
** alternative low-level memory allocation routines to be used in place of
** the memory allocation routines built into SQLite.)^ ^SQLite makes
** its own private copy of the content of the [sqlite3_mem_methods] structure
** before the [sqlite3_config()] call returns.</dd>
**
** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt>
** <dd> ^(The SQLITE_CONFIG_GETMALLOC option takes a single argument which
** is a pointer to an instance of the [sqlite3_mem_methods] structure.
** The [sqlite3_mem_methods]
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mem_methods] structure. The [sqlite3_mem_methods]
** structure is filled with the currently defined memory allocation routines.)^
** This option can be used to overload the default memory allocation
** routines with a wrapper that simulations memory allocation failure or
** tracks memory usage, for example. </dd>
**
** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int,
** interpreted as a boolean, which enables or disables the collection of
** memory allocation statistics. ^(When memory allocation statistics are disabled, the
** <dd> ^This option takes single argument of type int, interpreted as a
** boolean, which enables or disables the collection of memory allocation
** statistics. ^(When memory allocation statistics are disabled, the
** following SQLite interfaces become non-operational:
** <ul>
** <li> [sqlite3_memory_used()]
@@ -1533,65 +1531,53 @@ struct sqlite3_mem_methods {
** </dd>
**
** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
** <dd> ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer
** that SQLite can use for scratch memory. ^(There are three arguments
** to SQLITE_CONFIG_SCRATCH: A pointer an 8-byte
** <dd> ^This option specifies a static memory buffer that SQLite can use for
** scratch memory. There are three arguments: A pointer an 8-byte
** aligned memory buffer from which the scratch allocations will be
** drawn, the size of each scratch allocation (sz),
** and the maximum number of scratch allocations (N).)^
** and the maximum number of scratch allocations (N). The sz
** argument must be a multiple of 16.
** The first argument must be a pointer to an 8-byte aligned buffer
** of at least sz*N bytes of memory.
** ^SQLite will not use more than one scratch buffers per thread.
** ^SQLite will never request a scratch buffer that is more than 6
** times the database page size.
** ^If SQLite needs needs additional
** ^SQLite will use no more than two scratch buffers per thread. So
** N should be set to twice the expected maximum number of threads.
** ^SQLite will never require a scratch buffer that is more than 6
** times the database page size. ^If SQLite needs needs additional
** scratch memory beyond what is provided by this configuration option, then
** [sqlite3_malloc()] will be used to obtain the memory needed.<p>
** ^When the application provides any amount of scratch memory using
** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large
** [sqlite3_malloc|heap allocations].
** This can help [Robson proof|prevent memory allocation failures] due to heap
** fragmentation in low-memory embedded systems.
** </dd>
** [sqlite3_malloc()] will be used to obtain the memory needed.</dd>
**
** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a static memory buffer
** that SQLite can use for the database page cache with the default page
** cache implementation.
** <dd> ^This option specifies a static memory buffer that SQLite can use for
** the database page cache with the default page cache implementation.
** This configuration should not be used if an application-define page
** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2]
** configuration option.
** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned
** cache implementation is loaded using the SQLITE_CONFIG_PCACHE2 option.
** There are three arguments to this option: A pointer to 8-byte aligned
** memory, the size of each page buffer (sz), and the number of pages (N).
** The sz argument should be the size of the largest database page
** (a power of two between 512 and 32768) plus some extra bytes for each
** page header. ^The number of extra bytes needed by the page header
** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option
** to [sqlite3_config()].
** ^It is harmless, apart from the wasted memory,
** for the sz parameter to be larger than necessary. The first
** argument should pointer to an 8-byte aligned block of memory that
** is at least sz*N bytes of memory, otherwise subsequent behavior is
** undefined.
** (a power of two between 512 and 32768) plus a little extra for each
** page header. ^The page header size is 20 to 40 bytes depending on
** the host architecture. ^It is harmless, apart from the wasted memory,
** to make sz a little too large. The first
** argument should point to an allocation of at least sz*N bytes of memory.
** ^SQLite will use the memory provided by the first argument to satisfy its
** memory needs for the first N pages that it adds to cache. ^If additional
** page cache memory is needed beyond what is provided by this option, then
** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd>
** SQLite goes to [sqlite3_malloc()] for the additional storage space.
** The pointer in the first argument must
** be aligned to an 8-byte boundary or subsequent behavior of SQLite
** will be undefined.</dd>
**
** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer
** that SQLite will use for all of its dynamic memory allocation needs
** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].
** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled
** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns
** [SQLITE_ERROR] if invoked otherwise.
** ^There are three arguments to SQLITE_CONFIG_HEAP:
** An 8-byte aligned pointer to the memory,
** <dd> ^This option specifies a static memory buffer that SQLite will use
** for all of its dynamic memory allocation needs beyond those provided
** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].
** There are three arguments: An 8-byte aligned pointer to the memory,
** the number of bytes in the memory buffer, and the minimum allocation size.
** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts
** to using its default memory allocator (the system malloc() implementation),
** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. ^If the
** memory pointer is not NULL then the alternative memory
** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
** allocator is engaged to handle all of SQLites memory allocation needs.
** The first pointer (the memory pointer) must be aligned to an 8-byte
** boundary or subsequent behavior of SQLite will be undefined.
@@ -1599,9 +1585,9 @@ struct sqlite3_mem_methods {
** for the minimum allocation size are 2**5 through 2**8.</dd>
**
** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a
** pointer to an instance of the [sqlite3_mutex_methods] structure.
** The argument specifies alternative low-level mutex routines to be used in place
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mutex_methods] structure. The argument specifies
** alternative low-level mutex routines to be used in place
** the mutex routines built into SQLite.)^ ^SQLite makes a copy of the
** content of the [sqlite3_mutex_methods] structure before the call to
** [sqlite3_config()] returns. ^If SQLite is compiled with
@@ -1611,8 +1597,8 @@ struct sqlite3_mem_methods {
** return [SQLITE_ERROR].</dd>
**
** [[SQLITE_CONFIG_GETMUTEX]] <dt>SQLITE_CONFIG_GETMUTEX</dt>
** <dd> ^(The SQLITE_CONFIG_GETMUTEX option takes a single argument which
** is a pointer to an instance of the [sqlite3_mutex_methods] structure. The
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mutex_methods] structure. The
** [sqlite3_mutex_methods]
** structure is filled with the currently defined mutex routines.)^
** This option can be used to overload the default mutex allocation
@@ -1624,24 +1610,24 @@ struct sqlite3_mem_methods {
** return [SQLITE_ERROR].</dd>
**
** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt>
** <dd> ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine
** the default size of lookaside memory on each [database connection].
** The first argument is the
** <dd> ^(This option takes two arguments that determine the default
** memory allocation for the lookaside memory allocator on each
** [database connection]. The first argument is the
** size of each lookaside buffer slot and the second is the number of
** slots allocated to each database connection.)^ ^(SQLITE_CONFIG_LOOKASIDE
** sets the <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
** option to [sqlite3_db_config()] can be used to change the lookaside
** slots allocated to each database connection.)^ ^(This option sets the
** <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
** verb to [sqlite3_db_config()] can be used to change the lookaside
** configuration on individual connections.)^ </dd>
**
** [[SQLITE_CONFIG_PCACHE2]] <dt>SQLITE_CONFIG_PCACHE2</dt>
** <dd> ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is
** a pointer to an [sqlite3_pcache_methods2] object. This object specifies
** the interface to a custom page cache implementation.)^
** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd>
** <dd> ^(This option takes a single argument which is a pointer to
** an [sqlite3_pcache_methods2] object. This object specifies the interface
** to a custom page cache implementation.)^ ^SQLite makes a copy of the
** object and uses it for page cache memory allocations.</dd>
**
** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt>
** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which
** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies of the current
** <dd> ^(This option takes a single argument which is a pointer to an
** [sqlite3_pcache_methods2] object. SQLite copies of the current
** page cache implementation into that object.)^ </dd>
**
** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt>
@@ -1665,10 +1651,10 @@ struct sqlite3_mem_methods {
** function must be threadsafe. </dd>
**
** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
** <dd>^(The SQLITE_CONFIG_URI option takes a single argument of type int.
** If non-zero, then URI handling is globally enabled. If the parameter is zero,
** then URI handling is globally disabled.)^ ^If URI handling is globally enabled,
** all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or
** <dd>^(This option takes a single argument of type int. If non-zero, then
** URI handling is globally enabled. If the parameter is zero, then URI handling
** is globally disabled.)^ ^If URI handling is globally enabled, all filenames
** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or
** specified as part of [ATTACH] commands are interpreted as URIs, regardless
** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
** connection is opened. ^If it is globally disabled, filenames are
@@ -1678,10 +1664,9 @@ struct sqlite3_mem_methods {
** [SQLITE_USE_URI] symbol defined.)^
**
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
** <dd>^The SQLITE_CONFIG_COVERING_INDEX_SCAN option takes a single integer
** argument which is interpreted as a boolean in order to enable or disable
** the use of covering indices for full table scans in the query optimizer.
** ^The default setting is determined
** <dd>^This option takes a single integer argument which is interpreted as
** a boolean in order to enable or disable the use of covering indices for
** full table scans in the query optimizer. ^The default setting is determined
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
** if that compile-time option is omitted.
** The ability to disable the use of covering indices for full table scans
@@ -1721,28 +1706,19 @@ struct sqlite3_mem_methods {
** ^The default setting can be overridden by each database connection using
** either the [PRAGMA mmap_size] command, or by using the
** [SQLITE_FCNTL_MMAP_SIZE] file control. ^(The maximum allowed mmap size
** will be silently truncated if necessary so that it does not exceed the
** compile-time maximum mmap size set by the
** cannot be changed at run-time. Nor may the maximum allowed mmap size
** exceed the compile-time maximum mmap size set by the
** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^
** ^If either argument to this option is negative, then that argument is
** changed to its compile-time default.
**
** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE
** <dd>^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is
** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro defined.
** ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
** <dd>^This option is only available if SQLite is compiled for Windows
** with the [SQLITE_WIN32_MALLOC] pre-processor macro defined.
** SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
** that specifies the maximum size of the created heap.
** </dl>
**
** [[SQLITE_CONFIG_PCACHE_HDRSZ]]
** <dt>SQLITE_CONFIG_PCACHE_HDRSZ
** <dd>^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which
** is a pointer to an integer and writes into that integer the number of extra
** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE]. The amount of
** extra space required can change depending on the compiler,
** target platform, and SQLite version.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
@@ -1767,7 +1743,6 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */
#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
#define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -1895,45 +1870,47 @@ sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
/*
** CAPI3REF: Count The Number Of Rows Modified
**
** ^This function returns the number of rows modified, inserted or
** deleted by the most recently completed INSERT, UPDATE or DELETE
** statement on the database connection specified by the only parameter.
** ^Executing any other type of SQL statement does not modify the value
** returned by this function.
** ^This function returns the number of database rows that were changed
** or inserted or deleted by the most recently completed SQL statement
** on the [database connection] specified by the first parameter.
** ^(Only changes that are directly specified by the [INSERT], [UPDATE],
** or [DELETE] statement are counted. Auxiliary changes caused by
** triggers or [foreign key actions] are not counted.)^ Use the
** [sqlite3_total_changes()] function to find the total number of changes
** including changes caused by triggers and foreign key actions.
**
** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
** considered - auxiliary changes caused by [CREATE TRIGGER | triggers],
** [foreign key actions] or [REPLACE] constraint resolution are not counted.
**
** Changes to a view that are intercepted by
** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value
** returned by sqlite3_changes() immediately after an INSERT, UPDATE or
** DELETE statement run on a view is always zero. Only changes made to real
** tables are counted.
** ^Changes to a view that are simulated by an [INSTEAD OF trigger]
** are not counted. Only real table changes are counted.
**
** Things are more complicated if the sqlite3_changes() function is
** executed while a trigger program is running. This may happen if the
** program uses the [changes() SQL function], or if some other callback
** function invokes sqlite3_changes() directly. Essentially:
**
** <ul>
** <li> ^(Before entering a trigger program the value returned by
** sqlite3_changes() function is saved. After the trigger program
** has finished, the original value is restored.)^
**
** <li> ^(Within a trigger program each INSERT, UPDATE and DELETE
** statement sets the value returned by sqlite3_changes()
** upon completion as normal. Of course, this value will not include
** any changes performed by sub-triggers, as the sqlite3_changes()
** value will be saved and restored after each sub-trigger has run.)^
** </ul>
**
** ^This means that if the changes() SQL function (or similar) is used
** by the first INSERT, UPDATE or DELETE statement within a trigger, it
** returns the value as set when the calling statement began executing.
** ^If it is used by the second or subsequent such statement within a trigger
** program, the value returned reflects the number of rows modified by the
** previous INSERT, UPDATE or DELETE statement within the same trigger.
** ^(A "row change" is a change to a single row of a single table
** caused by an INSERT, DELETE, or UPDATE statement. Rows that
** are changed as side effects of [REPLACE] constraint resolution,
** rollback, ABORT processing, [DROP TABLE], or by any other
** mechanisms do not count as direct row changes.)^
**
** A "trigger context" is a scope of execution that begins and
** ends with the script of a [CREATE TRIGGER | trigger].
** Most SQL statements are
** evaluated outside of any trigger. This is the "top level"
** trigger context. If a trigger fires from the top level, a
** new trigger context is entered for the duration of that one
** trigger. Subtriggers create subcontexts for their duration.
**
** ^Calling [sqlite3_exec()] or [sqlite3_step()] recursively does
** not create a new trigger context.
**
** ^This function returns the number of direct row changes in the
** most recent INSERT, UPDATE, or DELETE statement within the same
** trigger context.
**
** ^Thus, when called from the top level, this function returns the
** number of changes in the most recent INSERT, UPDATE, or DELETE
** that also occurred at the top level. ^(Within the body of a trigger,
** the sqlite3_changes() interface can be called to find the number of
** changes in the most recently completed INSERT, UPDATE, or DELETE
** statement within the body of the same trigger.
** However, the number returned does not include changes
** caused by subtriggers since those have their own context.)^
**
** See also the [sqlite3_total_changes()] interface, the
** [count_changes pragma], and the [changes() SQL function].
@@ -1947,17 +1924,20 @@ int sqlite3_changes(sqlite3*);
/*
** CAPI3REF: Total Number Of Rows Modified
**
** ^This function returns the total number of rows inserted, modified or
** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed
** since the database connection was opened, including those executed as
** part of trigger programs. ^Executing any other type of SQL statement
** does not affect the value returned by sqlite3_total_changes().
**
** ^Changes made as part of [foreign key actions] are included in the
** count, but those made as part of REPLACE constraint resolution are
** not. ^Changes to a view that are intercepted by INSTEAD OF triggers
** are not counted.
**
** ^This function returns the number of row changes caused by [INSERT],
** [UPDATE] or [DELETE] statements since the [database connection] was opened.
** ^(The count returned by sqlite3_total_changes() includes all changes
** from all [CREATE TRIGGER | trigger] contexts and changes made by
** [foreign key actions]. However,
** the count does not include changes used to implement [REPLACE] constraints,
** do rollbacks or ABORT processing, or [DROP TABLE] processing. The
** count does not include rows of views that fire an [INSTEAD OF trigger],
** though if the INSTEAD OF trigger makes changes of its own, those changes
** are counted.)^
** ^The sqlite3_total_changes() function counts the changes as soon as
** the statement that makes them is completed (when the statement handle
** is passed to [sqlite3_reset()] or [sqlite3_finalize()]).
**
** See also the [sqlite3_changes()] interface, the
** [count_changes pragma], and the [total_changes() SQL function].
**
@@ -2435,14 +2415,13 @@ sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
** applications to access the same PRNG for other purposes.
**
** ^A call to this routine stores N bytes of randomness into buffer P.
** ^The P parameter can be a NULL pointer.
** ^If N is less than one, then P can be a NULL pointer.
**
** ^If this routine has not been previously called or if the previous
** call had N less than one or a NULL pointer for P, then the PRNG is
** seeded using randomness obtained from the xRandomness method of
** the default [sqlite3_vfs] object.
** ^If the previous call to this routine had an N of 1 or more and a
** non-NULL P then the pseudo-randomness is generated
** call had N less than one, then the PRNG is seeded using randomness
** obtained from the xRandomness method of the default [sqlite3_vfs] object.
** ^If the previous call to this routine had an N of 1 or more then
** the pseudo-randomness is generated
** internally and without recourse to the [sqlite3_vfs] xRandomness
** method.
*/
@@ -5657,42 +5636,26 @@ typedef struct sqlite3_blob sqlite3_blob;
** SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
** </pre>)^
**
** ^(Parameter zDb is not the filename that contains the database, but
** rather the symbolic name of the database. For attached databases, this is
** the name that appears after the AS keyword in the [ATTACH] statement.
** For the main database file, the database name is "main". For TEMP
** tables, the database name is "temp".)^
**
** ^If the flags parameter is non-zero, then the BLOB is opened for read
** and write access. ^If the flags parameter is zero, the BLOB is opened for
** read-only access.
** and write access. ^If it is zero, the BLOB is opened for read access.
** ^It is not possible to open a column that is part of an index or primary
** key for writing. ^If [foreign key constraints] are enabled, it is
** not possible to open a column that is part of a [child key] for writing.
**
** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored
** in *ppBlob. Otherwise an [error code] is returned and, unless the error
** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
** the API is not misused, it is always safe to call [sqlite3_blob_close()]
** on *ppBlob after this function it returns.
**
** This function fails with SQLITE_ERROR if any of the following are true:
** <ul>
** <li> ^(Database zDb does not exist)^,
** <li> ^(Table zTable does not exist within database zDb)^,
** <li> ^(Table zTable is a WITHOUT ROWID table)^,
** <li> ^(Column zColumn does not exist)^,
** <li> ^(Row iRow is not present in the table)^,
** <li> ^(The specified column of row iRow contains a value that is not
** a TEXT or BLOB value)^,
** <li> ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE
** constraint and the blob is being opened for read/write access)^,
** <li> ^([foreign key constraints | Foreign key constraints] are enabled,
** column zColumn is part of a [child key] definition and the blob is
** being opened for read/write access)^.
** </ul>
**
** ^Unless it returns SQLITE_MISUSE, this function sets the
** [database connection] error code and message accessible via
** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions.
** ^Note that the database name is not the filename that contains
** the database but rather the symbolic name of the database that
** appears after the AS keyword when the database is connected using [ATTACH].
** ^For the main database file, the database name is "main".
** ^For TEMP tables, the database name is "temp".
**
** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is written
** to *ppBlob. Otherwise an [error code] is returned and *ppBlob is set
** to be a null pointer.)^
** ^This function sets the [database connection] error code and message
** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()] and related
** functions. ^Note that the *ppBlob variable is always initialized in a
** way that makes it safe to invoke [sqlite3_blob_close()] on *ppBlob
** regardless of the success or failure of this routine.
**
** ^(If the row that a BLOB handle points to is modified by an
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
@@ -5710,9 +5673,13 @@ typedef struct sqlite3_blob sqlite3_blob;
** interface. Use the [UPDATE] SQL command to change the size of a
** blob.
**
** ^The [sqlite3_blob_open()] interface will fail for a [WITHOUT ROWID]
** table. Incremental BLOB I/O is not possible on [WITHOUT ROWID] tables.
**
** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
** and the built-in [zeroblob] SQL function may be used to create a
** zero-filled blob to read or write using the incremental-blob interface.
** and the built-in [zeroblob] SQL function can be used, if desired,
** to create an empty, zero-filled blob in which to read or write using
** this interface.
**
** To avoid a resource leak, every open [BLOB handle] should eventually
** be released by a call to [sqlite3_blob_close()].
@@ -5754,22 +5721,24 @@ SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
/*
** CAPI3REF: Close A BLOB Handle
**
** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed
** unconditionally. Even if this routine returns an error code, the
** handle is still closed.)^
** ^Closes an open [BLOB handle].
**
** ^If the blob handle being closed was opened for read-write access, and if
** the database is in auto-commit mode and there are no other open read-write
** blob handles or active write statements, the current transaction is
** committed. ^If an error occurs while committing the transaction, an error
** code is returned and the transaction rolled back.
** ^Closing a BLOB shall cause the current transaction to commit
** if there are no other BLOBs, no pending prepared statements, and the
** database connection is in [autocommit mode].
** ^If any writes were made to the BLOB, they might be held in cache
** until the close operation if they will fit.
**
** Calling this function with an argument that is not a NULL pointer or an
** open blob handle results in undefined behaviour. ^Calling this routine
** with a null pointer (such as would be returned by a failed call to
** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function
** is passed a valid open blob handle, the values returned by the
** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
** ^(Closing the BLOB often forces the changes
** out to disk and so if any I/O errors occur, they will likely occur
** at the time when the BLOB is closed. Any errors that occur during
** closing are reported as a non-zero return value.)^
**
** ^(The BLOB is closed unconditionally. Even if this routine returns
** an error code, the BLOB is still closed.)^
**
** ^Calling this routine with a null pointer (such as would be returned
** by a failed call to [sqlite3_blob_open()]) is a harmless no-op.
*/
int sqlite3_blob_close(sqlite3_blob *);
@@ -5819,27 +5788,21 @@ int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
/*
** CAPI3REF: Write Data Into A BLOB Incrementally
**
** ^(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
** into the open BLOB, starting at offset iOffset.)^
**
** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
** Otherwise, an [error code] or an [extended error code] is returned.)^
** ^Unless SQLITE_MISUSE is returned, this function sets the
** [database connection] error code and message accessible via
** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions.
** ^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
** into the open BLOB, starting at offset iOffset.
**
** ^If the [BLOB handle] passed as the first argument was not opened for
** writing (the flags parameter to [sqlite3_blob_open()] was zero),
** this function returns [SQLITE_READONLY].
**
** This function may only modify the contents of the BLOB; it is
** ^This function may only modify the contents of the BLOB; it is
** not possible to increase the size of a BLOB using this API.
** ^If offset iOffset is less than N bytes from the end of the BLOB,
** [SQLITE_ERROR] is returned and no data is written. The size of the
** BLOB (and hence the maximum value of N+iOffset) can be determined
** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less
** than zero [SQLITE_ERROR] is returned and no data is written.
** [SQLITE_ERROR] is returned and no data is written. ^If N is
** less than zero [SQLITE_ERROR] is returned and no data is written.
** The size of the BLOB (and hence the maximum value of N+iOffset)
** can be determined using the [sqlite3_blob_bytes()] interface.
**
** ^An attempt to write to an expired [BLOB handle] fails with an
** error code of [SQLITE_ABORT]. ^Writes to the BLOB that occurred
@@ -5848,6 +5811,9 @@ int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
** have been overwritten by the statement that expired the BLOB handle
** or by other independent statements.
**
** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
** Otherwise, an [error code] or an [extended error code] is returned.)^
**
** This routine only works on a [BLOB handle] which has been created
** by a prior successful call to [sqlite3_blob_open()] and which has not
** been closed by [sqlite3_blob_close()]. Passing any other pointer in
@@ -6848,10 +6814,6 @@ typedef struct sqlite3_backup sqlite3_backup;
** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
** an error.
**
** ^A call to sqlite3_backup_init() will fail, returning SQLITE_ERROR, if
** there is already a read or read-write transaction open on the
** destination database.
**
** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is
** returned and an error code and error message are stored in the
** destination [database connection] D.
@@ -7444,98 +7406,6 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
/* #define SQLITE_ABORT 4 // Also an error code */
#define SQLITE_REPLACE 5
/*
** CAPI3REF: Prepared Statement Scan Status Opcodes
** KEYWORDS: {scanstatus options}
**
** The following constants can be used for the T parameter to the
** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a
** different metric for sqlite3_stmt_scanstatus() to return.
**
** <dl>
** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set to the
** total number of times that the X-th loop has run.</dd>
**
** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt>
** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set to the
** total number of rows examined by all iterations of the X-th loop.</dd>
**
** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt>
** <dd>^The "double" variable pointed to by the T parameter will be set to the
** query planner's estimate for the average number of rows output from each
** iteration of the X-th loop. If the query planner's estimates was accurate,
** then this value will approximate the quotient NVISIT/NLOOP and the
** product of this value for all prior loops with the same SELECTID will
** be the NLOOP value for the current loop.
**
** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt>
** <dd>^The "const char *" variable pointed to by the T parameter will be set to
** a zero-terminated UTF-8 string containing the name of the index or table used
** for the X-th loop.
**
** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt>
** <dd>^The "const char *" variable pointed to by the T parameter will be set to
** a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] description
** for the X-th loop.
**
** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
** <dd>^The "int" variable pointed to by the T parameter will be set to the
** "select-id" for the X-th loop. The select-id identifies which query or
** subquery the loop is part of. The main query has a select-id of zero.
** The select-id is the same value as is output in the first column
** of an [EXPLAIN QUERY PLAN] query.
** </dl>
*/
#define SQLITE_SCANSTAT_NLOOP 0
#define SQLITE_SCANSTAT_NVISIT 1
#define SQLITE_SCANSTAT_EST 2
#define SQLITE_SCANSTAT_NAME 3
#define SQLITE_SCANSTAT_EXPLAIN 4
#define SQLITE_SCANSTAT_SELECTID 5
/*
** CAPI3REF: Prepared Statement Scan Status
**
** Return status data for a single loop within query pStmt.
**
** The "iScanStatusOp" parameter determines which status information to return.
** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior of
** this interface is undefined.
** ^The requested measurement is written into a variable pointed to by
** the "pOut" parameter.
** Parameter "idx" identifies the specific loop to retrieve statistics for.
** Loops are numbered starting from zero. ^If idx is out of range - less than
** zero or greater than or equal to the total number of loops used to implement
** the statement - a non-zero value is returned and the variable that pOut
** points to is unchanged.
**
** ^Statistics might not be available for all loops in all statements. ^In cases
** where there exist loops with no available statistics, this function behaves
** as if the loop did not exist - it returns non-zero and leave the variable
** that pOut points to unchanged.
**
** This API is only available if the library is built with pre-processor
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
**
** See also: [sqlite3_stmt_scanstatus_reset()]
*/
SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus(
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
int idx, /* Index of loop to report on */
int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
void *pOut /* Result written here */
);
/*
** CAPI3REF: Zero Scan-Status Counters
**
** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
**
** This API is only available if the library is built with pre-processor
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
*/
SQLITE_EXPERIMENTAL void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
/*
+9 -12
View File
@@ -193,9 +193,10 @@
#endif
/*
** EVIDENCE-OF: R-25715-37072 Memory allocation statistics are enabled by
** default unless SQLite is compiled with SQLITE_DEFAULT_MEMSTATUS=0 in
** which case memory allocation statistics are disabled by default.
** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1.
** It determines whether or not the features related to
** SQLITE_CONFIG_MEMSTATUS are available by default or not. This value can
** be overridden at runtime using the sqlite3_config() API.
*/
#if !defined(SQLITE_DEFAULT_MEMSTATUS)
# define SQLITE_DEFAULT_MEMSTATUS 1
@@ -562,7 +563,7 @@ typedef INT8_TYPE i8; /* 1-byte signed integer */
** gives a possible range of values of approximately 1.0e986 to 1e-986.
** But the allowed values are "grainy". Not every value is representable.
** For example, quantities 16 and 17 are both represented by a LogEst
** of 40. However, since LogEst quantities are suppose to be estimates,
** of 40. However, since LogEst quantaties are suppose to be estimates,
** not exact values, this imprecision is not a problem.
**
** "LogEst" is short for "Logarithmic Estimate".
@@ -1213,7 +1214,7 @@ struct sqlite3 {
#define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */
#define SQLITE_Transitive 0x0200 /* Transitive constraints */
#define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */
#define SQLITE_Stat34 0x0800 /* Use STAT3 or STAT4 data */
#define SQLITE_Stat3 0x0800 /* Use the SQLITE_STAT3 table */
#define SQLITE_AllOpts 0xffff /* All optimizations */
/*
@@ -1795,7 +1796,6 @@ struct Index {
unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */
unsigned isResized:1; /* True if resizeIndexObject() has been called */
unsigned isCovering:1; /* True if this is a covering index */
unsigned noSkipScan:1; /* Do not try to use skip-scan if true */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nSample; /* Number of elements in aSample[] */
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
@@ -2000,7 +2000,7 @@ struct Expr {
int iTable; /* TK_COLUMN: cursor number of table holding column
** TK_REGISTER: register number
** TK_TRIGGER: 1 -> new, 0 -> old
** EP_Unlikely: 134217728 times likelihood */
** EP_Unlikely: 1000 times likelihood */
ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
** TK_VARIABLE: variable number (always >= 1). */
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
@@ -2892,11 +2892,9 @@ struct Walker {
void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */
Parse *pParse; /* Parser context. */
int walkerDepth; /* Number of subqueries */
u8 eCode; /* A small processing code */
union { /* Extra data for callback */
NameContext *pNC; /* Naming context */
int n; /* A counter */
int iCur; /* A cursor number */
int i; /* Integer value */
SrcList *pSrcList; /* FROM clause */
struct SrcCount *pSrcCount; /* Counting column references */
} u;
@@ -3297,7 +3295,6 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
int sqlite3ExprIsConstant(Expr*);
int sqlite3ExprIsConstantNotJoin(Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
int sqlite3ExprIsTableConstant(Expr*,int);
int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3ExprCanBeNull(const Expr*);
int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
@@ -3543,7 +3540,7 @@ int sqlite3OpenTempDatabase(Parse *);
void sqlite3StrAccumInit(StrAccum*, char*, int, int);
void sqlite3StrAccumAppend(StrAccum*,const char*,int);
void sqlite3StrAccumAppendAll(StrAccum*,const char*);
void sqlite3AppendChar(StrAccum*,int,char);
void sqlite3AppendSpace(StrAccum*,int);
char *sqlite3StrAccumFinish(StrAccum*);
void sqlite3StrAccumReset(StrAccum*);
void sqlite3SelectDestInit(SelectDest*,int,int);
-8
View File
@@ -86,9 +86,6 @@ int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
if( op<0 || op>=ArraySize(wsdStat.nowValue) ){
return SQLITE_MISUSE_BKPT;
}
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
#endif
*pCurrent = wsdStat.nowValue[op];
*pHighwater = wsdStat.mxValue[op];
if( resetFlag ){
@@ -108,11 +105,6 @@ int sqlite3_db_status(
int resetFlag /* Reset high-water mark if true */
){
int rc = SQLITE_OK; /* Return code */
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
sqlite3_mutex_enter(db->mutex);
switch( op ){
case SQLITE_DBSTATUS_LOOKASIDE_USED: {
-3
View File
@@ -126,9 +126,6 @@ int sqlite3_get_table(
int rc;
TabResult res;
#ifdef SQLITE_ENABLE_API_ARMOR
if( pazResult==0 ) return SQLITE_MISUSE_BKPT;
#endif
*pazResult = 0;
if( pnColumn ) *pnColumn = 0;
if( pnRow ) *pnRow = 0;
-44
View File
@@ -3641,45 +3641,6 @@ static int db_use_legacy_prepare_cmd(
Tcl_ResetResult(interp);
return TCL_OK;
}
/*
** Tclcmd: db_last_stmt_ptr DB
**
** If the statement cache associated with database DB is not empty,
** return the text representation of the most recently used statement
** handle.
*/
static int db_last_stmt_ptr(
ClientData cd,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
extern int sqlite3TestMakePointerStr(Tcl_Interp*, char*, void*);
Tcl_CmdInfo cmdInfo;
SqliteDb *pDb;
sqlite3_stmt *pStmt = 0;
char zBuf[100];
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB");
return TCL_ERROR;
}
if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0);
return TCL_ERROR;
}
pDb = (SqliteDb*)cmdInfo.objClientData;
if( pDb->stmtList ) pStmt = pDb->stmtList->pStmt;
if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ){
return TCL_ERROR;
}
Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
return TCL_OK;
}
#endif
/*
@@ -3725,7 +3686,6 @@ static void init_all(Tcl_Interp *interp){
extern int Sqlitetest9_Init(Tcl_Interp*);
extern int Sqlitetestasync_Init(Tcl_Interp*);
extern int Sqlitetest_autoext_Init(Tcl_Interp*);
extern int Sqlitetest_blob_Init(Tcl_Interp*);
extern int Sqlitetest_demovfs_Init(Tcl_Interp *);
extern int Sqlitetest_func_Init(Tcl_Interp*);
extern int Sqlitetest_hexio_Init(Tcl_Interp*);
@@ -3769,7 +3729,6 @@ static void init_all(Tcl_Interp *interp){
Sqlitetest9_Init(interp);
Sqlitetestasync_Init(interp);
Sqlitetest_autoext_Init(interp);
Sqlitetest_blob_Init(interp);
Sqlitetest_demovfs_Init(interp);
Sqlitetest_func_Init(interp);
Sqlitetest_hexio_Init(interp);
@@ -3801,9 +3760,6 @@ static void init_all(Tcl_Interp *interp){
Tcl_CreateObjCommand(
interp, "db_use_legacy_prepare", db_use_legacy_prepare_cmd, 0, 0
);
Tcl_CreateObjCommand(
interp, "db_last_stmt_ptr", db_last_stmt_ptr, 0, 0
);
#ifdef SQLITE_SSE
Sqlitetestsse_Init(interp);
+153 -79
View File
@@ -1651,6 +1651,154 @@ static int blobHandleFromObj(
return TCL_OK;
}
/*
** sqlite3_blob_bytes CHANNEL
*/
static int test_blob_bytes(
ClientData clientData, /* Not used */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3_blob *pBlob;
int nByte;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL");
return TCL_ERROR;
}
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
nByte = sqlite3_blob_bytes(pBlob);
Tcl_SetObjResult(interp, Tcl_NewIntObj(nByte));
return TCL_OK;
}
/*
** sqlite3_blob_close CHANNEL
*/
static int test_blob_close(
ClientData clientData, /* Not used */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3_blob *pBlob;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL");
return TCL_ERROR;
}
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
sqlite3_blob_close(pBlob);
return TCL_OK;
}
/*
** sqlite3_blob_read CHANNEL OFFSET N
**
** This command is used to test the sqlite3_blob_read() in ways that
** the Tcl channel interface does not. The first argument should
** be the name of a valid channel created by the [incrblob] method
** of a database handle. This function calls sqlite3_blob_read()
** to read N bytes from offset OFFSET from the underlying SQLite
** blob handle.
**
** On success, a byte-array object containing the read data is
** returned. On failure, the interpreter result is set to the
** text representation of the returned error code (i.e. "SQLITE_NOMEM")
** and a Tcl exception is thrown.
*/
static int test_blob_read(
ClientData clientData, /* Not used */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3_blob *pBlob;
int nByte;
int iOffset;
unsigned char *zBuf = 0;
int rc;
if( objc!=4 ){
Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET N");
return TCL_ERROR;
}
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset)
|| TCL_OK!=Tcl_GetIntFromObj(interp, objv[3], &nByte)
){
return TCL_ERROR;
}
if( nByte>0 ){
zBuf = (unsigned char *)Tcl_Alloc(nByte);
}
rc = sqlite3_blob_read(pBlob, zBuf, nByte, iOffset);
if( rc==SQLITE_OK ){
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zBuf, nByte));
}else{
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
}
Tcl_Free((char *)zBuf);
return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
}
/*
** sqlite3_blob_write CHANNEL OFFSET DATA ?NDATA?
**
** This command is used to test the sqlite3_blob_write() in ways that
** the Tcl channel interface does not. The first argument should
** be the name of a valid channel created by the [incrblob] method
** of a database handle. This function calls sqlite3_blob_write()
** to write the DATA byte-array to the underlying SQLite blob handle.
** at offset OFFSET.
**
** On success, an empty string is returned. On failure, the interpreter
** result is set to the text representation of the returned error code
** (i.e. "SQLITE_NOMEM") and a Tcl exception is thrown.
*/
static int test_blob_write(
ClientData clientData, /* Not used */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3_blob *pBlob;
int iOffset;
int rc;
unsigned char *zBuf;
int nBuf;
if( objc!=4 && objc!=5 ){
Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET DATA ?NDATA?");
return TCL_ERROR;
}
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) ){
return TCL_ERROR;
}
zBuf = Tcl_GetByteArrayFromObj(objv[3], &nBuf);
if( objc==5 && Tcl_GetIntFromObj(interp, objv[4], &nBuf) ){
return TCL_ERROR;
}
rc = sqlite3_blob_write(pBlob, zBuf, nBuf, iOffset);
if( rc!=SQLITE_OK ){
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
}
return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
}
static int test_blob_reopen(
ClientData clientData, /* Not used */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
@@ -2153,77 +2301,6 @@ static int test_stmt_status(
return TCL_OK;
}
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
/*
** Usage: sqlite3_stmt_scanstatus STMT IDX
*/
static int test_stmt_scanstatus(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3_stmt *pStmt; /* First argument */
int idx; /* Second argument */
const char *zName;
const char *zExplain;
sqlite3_int64 nLoop;
sqlite3_int64 nVisit;
double rEst;
int res;
if( objc!=3 ){
Tcl_WrongNumArgs(interp, 1, objv, "STMT IDX");
return TCL_ERROR;
}
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
res = sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop);
if( res==0 ){
Tcl_Obj *pRet = Tcl_NewObj();
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("nLoop", -1));
Tcl_ListObjAppendElement(0, pRet, Tcl_NewWideIntObj(nLoop));
sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("nVisit", -1));
Tcl_ListObjAppendElement(0, pRet, Tcl_NewWideIntObj(nVisit));
sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_EST, (void*)&rEst);
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("nEst", -1));
Tcl_ListObjAppendElement(0, pRet, Tcl_NewDoubleObj(rEst));
sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_NAME, (void*)&zName);
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("zName", -1));
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zName, -1));
sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("zExplain", -1));
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zExplain, -1));
Tcl_SetObjResult(interp, pRet);
}else{
Tcl_ResetResult(interp);
}
return TCL_OK;
}
/*
** Usage: sqlite3_stmt_scanstatus_reset STMT
*/
static int test_stmt_scanstatus_reset(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3_stmt *pStmt; /* First argument */
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "STMT");
return TCL_ERROR;
}
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
sqlite3_stmt_scanstatus_reset(pStmt);
return TCL_OK;
}
#endif
/*
** Usage: sqlite3_next_stmt DB STMT
**
@@ -6216,8 +6293,7 @@ static int optimization_control(
{ "transitive", SQLITE_Transitive },
{ "subquery-coroutine", SQLITE_SubqCoroutine },
{ "omit-noop-join", SQLITE_OmitNoopJoin },
{ "stat3", SQLITE_Stat34 },
{ "stat4", SQLITE_Stat34 },
{ "stat3", SQLITE_Stat3 },
};
if( objc!=4 ){
@@ -6260,7 +6336,6 @@ static int tclLoadStaticExtensionCmd(
){
extern int sqlite3_amatch_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_closure_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_eval_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_fileio_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_fuzzer_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_ieee_init(sqlite3*,char**,const sqlite3_api_routines*);
@@ -6276,7 +6351,6 @@ static int tclLoadStaticExtensionCmd(
} aExtension[] = {
{ "amatch", sqlite3_amatch_init },
{ "closure", sqlite3_closure_init },
{ "eval", sqlite3_eval_init },
{ "fileio", sqlite3_fileio_init },
{ "fuzzer", sqlite3_fuzzer_init },
{ "ieee754", sqlite3_ieee_init },
@@ -6764,7 +6838,11 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_table_column_metadata", test_table_column_metadata, 0 },
#endif
#ifndef SQLITE_OMIT_INCRBLOB
{ "sqlite3_blob_read", test_blob_read, 0 },
{ "sqlite3_blob_write", test_blob_write, 0 },
{ "sqlite3_blob_reopen", test_blob_reopen, 0 },
{ "sqlite3_blob_bytes", test_blob_bytes, 0 },
{ "sqlite3_blob_close", test_blob_close, 0 },
#endif
{ "pcache_stats", test_pcache_stats, 0 },
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
@@ -6789,10 +6867,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_user_change", test_user_change, 0 },
{ "sqlite3_user_delete", test_user_delete, 0 },
#endif
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
{ "sqlite3_stmt_scanstatus", test_stmt_scanstatus, 0 },
{ "sqlite3_stmt_scanstatus_reset", test_stmt_scanstatus_reset, 0 },
#endif
};
static int bitmask_size = sizeof(Bitmask)*8;
-319
View File
@@ -1,319 +0,0 @@
/*
** 2014 October 30
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
/* These functions are implemented in main.c. */
extern const char *sqlite3ErrName(int);
/* From test1.c: */
extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
extern void *sqlite3TestTextToPtr(const char *z);
/*
** Return a pointer to a buffer containing a text representation of the
** pointer passed as the only argument. The original pointer may be extracted
** from the text using sqlite3TestTextToPtr().
*/
static char *ptrToText(void *p){
static char buf[100];
sqlite3_snprintf(sizeof(buf)-1, buf, "%p", p);
return buf;
}
/*
** Attempt to extract a blob handle (type sqlite3_blob*) from the Tcl
** object passed as the second argument. If successful, set *ppBlob to
** point to the blob handle and return TCL_OK. Otherwise, store an error
** message in the tcl interpreter and return TCL_ERROR. The final value
** of *ppBlob is undefined in this case.
**
** If the object contains a string that begins with "incrblob_", then it
** is assumed to be the name of a Tcl channel opened using the [db incrblob]
** command (see tclsqlite.c). Otherwise, it is assumed to be a pointer
** encoded using the ptrToText() routine or similar.
*/
static int blobHandleFromObj(
Tcl_Interp *interp,
Tcl_Obj *pObj,
sqlite3_blob **ppBlob
){
char *z;
int n;
z = Tcl_GetStringFromObj(pObj, &n);
if( n==0 ){
*ppBlob = 0;
}else if( n>9 && 0==memcmp("incrblob_", z, 9) ){
int notUsed;
Tcl_Channel channel;
ClientData instanceData;
channel = Tcl_GetChannel(interp, z, &notUsed);
if( !channel ) return TCL_ERROR;
Tcl_Flush(channel);
Tcl_Seek(channel, 0, SEEK_SET);
instanceData = Tcl_GetChannelInstanceData(channel);
*ppBlob = *((sqlite3_blob **)instanceData);
}else{
*ppBlob = (sqlite3_blob*)sqlite3TestTextToPtr(z);
}
return TCL_OK;
}
/*
** Like Tcl_GetString(), except that if the string is 0 bytes in size, a
** NULL Pointer is returned.
*/
static char *blobStringFromObj(Tcl_Obj *pObj){
int n;
char *z;
z = Tcl_GetStringFromObj(pObj, &n);
return (n ? z : 0);
}
/*
** sqlite3_blob_open DB DATABASE TABLE COLUMN ROWID FLAGS VARNAME
**
** Tcl test harness for the sqlite3_blob_open() function.
*/
static int test_blob_open(
ClientData clientData, /* Not used */
Tcl_Interp *interp, /* Calling TCL interpreter */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3 *db;
const char *zDb;
const char *zTable;
const char *zColumn;
sqlite_int64 iRowid;
int flags;
const char *zVarname;
int nVarname;
sqlite3_blob *pBlob = (sqlite3_blob*)0xFFFFFFFF;
int rc;
if( objc!=8 ){
const char *zUsage = "DB DATABASE TABLE COLUMN ROWID FLAGS VARNAME";
Tcl_WrongNumArgs(interp, 1, objv, zUsage);
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
zDb = Tcl_GetString(objv[2]);
zTable = blobStringFromObj(objv[3]);
zColumn = Tcl_GetString(objv[4]);
if( Tcl_GetWideIntFromObj(interp, objv[5], &iRowid) ) return TCL_ERROR;
if( Tcl_GetIntFromObj(interp, objv[6], &flags) ) return TCL_ERROR;
zVarname = Tcl_GetStringFromObj(objv[7], &nVarname);
if( nVarname>0 ){
rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRowid, flags, &pBlob);
Tcl_SetVar(interp, zVarname, ptrToText(pBlob), 0);
}else{
rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRowid, flags, 0);
}
if( rc==SQLITE_OK ){
Tcl_ResetResult(interp);
}else{
Tcl_SetResult(interp, (char*)sqlite3ErrName(rc), TCL_VOLATILE);
return TCL_ERROR;
}
return TCL_OK;
}
/*
** sqlite3_blob_close HANDLE
*/
static int test_blob_close(
ClientData clientData, /* Not used */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3_blob *pBlob;
int rc;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
return TCL_ERROR;
}
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
rc = sqlite3_blob_close(pBlob);
if( rc ){
Tcl_SetResult(interp, (char*)sqlite3ErrName(rc), TCL_VOLATILE);
}else{
Tcl_ResetResult(interp);
}
return TCL_OK;
}
/*
** sqlite3_blob_bytes HANDLE
*/
static int test_blob_bytes(
ClientData clientData, /* Not used */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3_blob *pBlob;
int nByte;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
return TCL_ERROR;
}
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
nByte = sqlite3_blob_bytes(pBlob);
Tcl_SetObjResult(interp, Tcl_NewIntObj(nByte));
return TCL_OK;
}
/*
** sqlite3_blob_read CHANNEL OFFSET N
**
** This command is used to test the sqlite3_blob_read() in ways that
** the Tcl channel interface does not. The first argument should
** be the name of a valid channel created by the [incrblob] method
** of a database handle. This function calls sqlite3_blob_read()
** to read N bytes from offset OFFSET from the underlying SQLite
** blob handle.
**
** On success, a byte-array object containing the read data is
** returned. On failure, the interpreter result is set to the
** text representation of the returned error code (i.e. "SQLITE_NOMEM")
** and a Tcl exception is thrown.
*/
static int test_blob_read(
ClientData clientData, /* Not used */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3_blob *pBlob;
int nByte;
int iOffset;
unsigned char *zBuf = 0;
int rc;
if( objc!=4 ){
Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET N");
return TCL_ERROR;
}
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset)
|| TCL_OK!=Tcl_GetIntFromObj(interp, objv[3], &nByte)
){
return TCL_ERROR;
}
if( nByte>0 ){
zBuf = (unsigned char *)Tcl_Alloc(nByte);
}
rc = sqlite3_blob_read(pBlob, zBuf, nByte, iOffset);
if( rc==SQLITE_OK ){
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zBuf, nByte));
}else{
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
}
Tcl_Free((char *)zBuf);
return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
}
/*
** sqlite3_blob_write HANDLE OFFSET DATA ?NDATA?
**
** This command is used to test the sqlite3_blob_write() in ways that
** the Tcl channel interface does not. The first argument should
** be the name of a valid channel created by the [incrblob] method
** of a database handle. This function calls sqlite3_blob_write()
** to write the DATA byte-array to the underlying SQLite blob handle.
** at offset OFFSET.
**
** On success, an empty string is returned. On failure, the interpreter
** result is set to the text representation of the returned error code
** (i.e. "SQLITE_NOMEM") and a Tcl exception is thrown.
*/
static int test_blob_write(
ClientData clientData, /* Not used */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3_blob *pBlob;
int iOffset;
int rc;
unsigned char *zBuf;
int nBuf;
if( objc!=4 && objc!=5 ){
Tcl_WrongNumArgs(interp, 1, objv, "HANDLE OFFSET DATA ?NDATA?");
return TCL_ERROR;
}
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) ){
return TCL_ERROR;
}
zBuf = Tcl_GetByteArrayFromObj(objv[3], &nBuf);
if( objc==5 && Tcl_GetIntFromObj(interp, objv[4], &nBuf) ){
return TCL_ERROR;
}
rc = sqlite3_blob_write(pBlob, zBuf, nBuf, iOffset);
if( rc!=SQLITE_OK ){
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
}
return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
}
/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest_blob_Init(Tcl_Interp *interp){
static struct {
char *zName;
Tcl_ObjCmdProc *xProc;
} aObjCmd[] = {
{ "sqlite3_blob_open", test_blob_open },
{ "sqlite3_blob_close", test_blob_close },
{ "sqlite3_blob_bytes", test_blob_bytes },
{ "sqlite3_blob_read", test_blob_read },
{ "sqlite3_blob_write", test_blob_write },
};
int i;
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
}
return TCL_OK;
}
-12
View File
@@ -155,12 +155,6 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "analyze", "1", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_ENABLE_API_ARMOR
Tcl_SetVar2(interp, "sqlite_options", "api_armor", "1", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "api_armor", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
Tcl_SetVar2(interp, "sqlite_options", "atomicwrite", "1", TCL_GLOBAL_ONLY);
#else
@@ -490,12 +484,6 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
Tcl_SetVar2(interp, "sqlite_options", "stat3", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
Tcl_SetVar2(interp, "sqlite_options", "scanstatus", "1", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "scanstatus", "0", TCL_GLOBAL_ONLY);
#endif
#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
# if defined(__APPLE__)
# define SQLITE_ENABLE_LOCKING_STYLE 1
+4 -2
View File
@@ -98,7 +98,8 @@ int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
/********************************* Win32 Threads ****************************/
#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
SQLITE_THREADSAFE>0 && defined(_MSC_VER)
#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */
#include <process.h>
@@ -191,7 +192,8 @@ int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR;
}
#endif /* SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT */
#endif /* SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
SQLITE_THREADSAFE>0 && defined(_MSC_VER) */
/******************************** End Win32 Threads *************************/
+2 -2
View File
@@ -431,8 +431,8 @@ void sqlite3Update(
/* Top of the update loop */
if( okOnePass ){
if( aToOpen[iDataCur-iBaseCur] && !isView ){
assert( pPk );
if( aToOpen[iDataCur-iBaseCur] ){
assert( pPk!=0 );
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
VdbeCoverageNeverTaken(v);
}
-10
View File
@@ -251,11 +251,6 @@ int sqlite3Dequote(char *z){
*/
int sqlite3_stricmp(const char *zLeft, const char *zRight){
register unsigned char *a, *b;
if( zLeft==0 ){
return zRight ? -1 : 0;
}else if( zRight==0 ){
return 1;
}
a = (unsigned char *)zLeft;
b = (unsigned char *)zRight;
while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
@@ -263,11 +258,6 @@ int sqlite3_stricmp(const char *zLeft, const char *zRight){
}
int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
register unsigned char *a, *b;
if( zLeft==0 ){
return zRight ? -1 : 0;
}else if( zRight==0 ){
return 1;
}
a = (unsigned char *)zLeft;
b = (unsigned char *)zRight;
while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
+1 -1
View File
@@ -94,7 +94,7 @@ static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
** overwriting the database with the vacuumed content.
**
** Only 1x temporary space and only 1x writes would be required if
** the copy of step (3) were replaced by deleting the original database
** the copy of step (3) were replace by deleting the original database
** and renaming the transient database as the original. But that will
** not work if other processes are attached to the original database.
** And a power loss in between deleting the original and renaming the
+10 -27
View File
@@ -608,9 +608,6 @@ int sqlite3VdbeExec(
#endif
nVmStep++;
pOp = &aOp[pc];
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
if( p->anExec ) p->anExec[pc]++;
#endif
/* Only allow tracing if SQLITE_DEBUG is defined.
*/
@@ -2301,7 +2298,7 @@ case OP_Column: {
pC->payloadSize = pC->szRow = avail = pReg->n;
pC->aRow = (u8*)pReg->z;
}else{
sqlite3VdbeMemSetNull(pDest);
MemSetTypeFlag(pDest, MEM_Null);
goto op_column_out;
}
}else{
@@ -2444,7 +2441,7 @@ case OP_Column: {
if( pOp->p4type==P4_MEM ){
sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
}else{
sqlite3VdbeMemSetNull(pDest);
MemSetTypeFlag(pDest, MEM_Null);
}
goto op_column_out;
}
@@ -2825,17 +2822,11 @@ case OP_Savepoint: {
db->isTransactionSavepoint = 0;
rc = p->rc;
}else{
int isSchemaChange;
iSavepoint = db->nSavepoint - iSavepoint - 1;
if( p1==SAVEPOINT_ROLLBACK ){
isSchemaChange = (db->flags & SQLITE_InternChanges)!=0;
for(ii=0; ii<db->nDb; ii++){
rc = sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, SQLITE_ABORT,
isSchemaChange==0);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, SQLITE_ABORT);
}
}else{
isSchemaChange = 0;
}
for(ii=0; ii<db->nDb; ii++){
rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
@@ -2843,7 +2834,7 @@ case OP_Savepoint: {
goto abort_due_to_error;
}
}
if( isSchemaChange ){
if( p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
sqlite3ExpirePreparedStatements(db);
sqlite3ResetAllSchemasOfConnection(db);
db->flags = (db->flags | SQLITE_InternChanges);
@@ -3240,7 +3231,7 @@ case OP_OpenWrite: {
|| p->readOnly==0 );
if( p->expired ){
rc = SQLITE_ABORT_ROLLBACK;
rc = SQLITE_ABORT;
break;
}
@@ -3804,11 +3795,10 @@ case OP_Found: { /* jump, in3 */
}else{
pIdxKey = sqlite3VdbeAllocUnpackedRecord(
pC->pKeyInfo, aTempRec, sizeof(aTempRec), &pFree
);
);
if( pIdxKey==0 ) goto no_mem;
assert( pIn3->flags & MEM_Blob );
/* assert( (pIn3->flags & MEM_Zero)==0 ); // zeroblobs already expanded */
ExpandBlob(pIn3);
assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */
sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
}
pIdxKey->default_rc = 0;
@@ -4498,9 +4488,9 @@ case OP_Sort: { /* jump */
**
** The next use of the Rowid or Column or Next instruction for P1
** will refer to the first entry in the database table or index.
** If the table or index is empty, jump immediately to P2.
** If the table or index is not empty, fall through to the following
** instruction.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
**
** This opcode leaves the cursor configured to move in forward order,
** from the beginning toward the end. In other words, the cursor is
@@ -5416,9 +5406,6 @@ case OP_Program: { /* jump */
pFrame->token = pProgram->token;
pFrame->aOnceFlag = p->aOnceFlag;
pFrame->nOnceFlag = p->nOnceFlag;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
pFrame->anExec = p->anExec;
#endif
pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
@@ -5436,7 +5423,6 @@ case OP_Program: { /* jump */
pFrame->pParent = p->pFrame;
pFrame->lastRowid = lastRowid;
pFrame->nChange = p->nChange;
pFrame->nDbChange = p->db->nChange;
p->nChange = 0;
p->pFrame = pFrame;
p->aMem = aMem = &VdbeFrameMem(pFrame)[-1];
@@ -5447,9 +5433,6 @@ case OP_Program: { /* jump */
p->nOp = pProgram->nOp;
p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
p->nOnceFlag = pProgram->nOnce;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
p->anExec = 0;
#endif
pc = -1;
memset(p->aOnceFlag, 0, p->nOnceFlag);
-6
View File
@@ -282,10 +282,4 @@ void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
# define VDBE_OFFSET_LINENO(x) 0
#endif
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const char*);
#else
# define sqlite3VdbeScanStatus(a,b,c,d,e)
#endif
#endif
+1 -18
View File
@@ -132,7 +132,6 @@ struct VdbeFrame {
Vdbe *v; /* VM this frame belongs to */
VdbeFrame *pParent; /* Parent of this frame, or NULL if parent is main */
Op *aOp; /* Program instructions for parent frame */
i64 *anExec; /* Event counters from parent frame */
Mem *aMem; /* Array of memory cells for parent frame */
u8 *aOnceFlag; /* Array of OP_Once flags for parent frame */
VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */
@@ -145,8 +144,7 @@ struct VdbeFrame {
int nOnceFlag; /* Number of entries in aOnceFlag */
int nChildMem; /* Number of memory cells for child frame */
int nChildCsr; /* Number of cursors for child frame */
int nChange; /* Statement changes (Vdbe.nChange) */
int nDbChange; /* Value of db->nChange */
int nChange; /* Statement changes (Vdbe.nChanges) */
};
#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
@@ -297,16 +295,6 @@ struct Explain {
*/
typedef unsigned bft; /* Bit Field Type */
typedef struct ScanStatus ScanStatus;
struct ScanStatus {
int addrExplain; /* OP_Explain for loop */
int addrLoop; /* Address of "loops" counter */
int addrVisit; /* Address of "rows visited" counter */
int iSelectID; /* The "Select-ID" for this loop */
LogEst nEst; /* Estimated output rows per loop */
char *zName; /* Name of table or index */
};
/*
** An instance of the virtual machine. This structure contains the complete
** state of the virtual machine.
@@ -379,11 +367,6 @@ struct Vdbe {
int nOnceFlag; /* Size of array aOnceFlag[] */
u8 *aOnceFlag; /* Flags for OP_Once */
AuxData *pAuxData; /* Linked list of auxdata allocations */
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
i64 *anExec; /* Number of times each op has been executed */
int nScan; /* Entries in aScan[] */
ScanStatus *aScan; /* Scan definitions for sqlite3_stmt_scanstatus() */
#endif
};
/*
+5 -95
View File
@@ -966,19 +966,11 @@ static const void *columnName(
const void *(*xFunc)(Mem*),
int useType
){
const void *ret;
Vdbe *p;
const void *ret = 0;
Vdbe *p = (Vdbe *)pStmt;
int n;
sqlite3 *db;
#ifdef SQLITE_ENABLE_API_ARMOR
if( pStmt==0 ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
ret = 0;
p = (Vdbe *)pStmt;
db = p->db;
sqlite3 *db = p->db;
assert( db!=0 );
n = sqlite3_column_count(pStmt);
if( N<n && N>=0 ){
@@ -1443,12 +1435,6 @@ int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
*/
sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
sqlite3_stmt *pNext;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(pDb) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
sqlite3_mutex_enter(pDb->mutex);
if( pStmt==0 ){
pNext = (sqlite3_stmt*)pDb->pVdbe;
@@ -1464,83 +1450,7 @@ sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
*/
int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
Vdbe *pVdbe = (Vdbe*)pStmt;
u32 v;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !pStmt ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
v = pVdbe->aCounter[op];
u32 v = pVdbe->aCounter[op];
if( resetFlag ) pVdbe->aCounter[op] = 0;
return (int)v;
}
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
/*
** Return status data for a single loop within query pStmt.
*/
int sqlite3_stmt_scanstatus(
sqlite3_stmt *pStmt, /* Prepared statement being queried */
int idx, /* Index of loop to report on */
int iScanStatusOp, /* Which metric to return */
void *pOut /* OUT: Write the answer here */
){
Vdbe *p = (Vdbe*)pStmt;
ScanStatus *pScan;
if( idx<0 || idx>=p->nScan ) return 1;
pScan = &p->aScan[idx];
switch( iScanStatusOp ){
case SQLITE_SCANSTAT_NLOOP: {
*(sqlite3_int64*)pOut = p->anExec[pScan->addrLoop];
break;
}
case SQLITE_SCANSTAT_NVISIT: {
*(sqlite3_int64*)pOut = p->anExec[pScan->addrVisit];
break;
}
case SQLITE_SCANSTAT_EST: {
double r = 1.0;
LogEst x = pScan->nEst;
while( x<100 ){
x += 10;
r *= 0.5;
}
*(double*)pOut = r*sqlite3LogEstToInt(x);
break;
}
case SQLITE_SCANSTAT_NAME: {
*(const char**)pOut = pScan->zName;
break;
}
case SQLITE_SCANSTAT_EXPLAIN: {
if( pScan->addrExplain ){
*(const char**)pOut = p->aOp[ pScan->addrExplain ].p4.z;
}else{
*(const char**)pOut = 0;
}
break;
}
case SQLITE_SCANSTAT_SELECTID: {
if( pScan->addrExplain ){
*(int*)pOut = p->aOp[ pScan->addrExplain ].p1;
}else{
*(int*)pOut = -1;
}
break;
}
default: {
return 1;
}
}
return 0;
}
/*
** Zero all counters associated with the sqlite3_stmt_scanstatus() data.
*/
void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
memset(p->anExec, 0, p->nOp * sizeof(i64));
}
#endif /* SQLITE_ENABLE_STMT_SCANSTATUS */
-46
View File
@@ -597,34 +597,6 @@ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp, int iLineno){
return addr;
}
#if defined(SQLITE_ENABLE_STMT_SCANSTATUS)
/*
** Add an entry to the array of counters managed by sqlite3_stmt_scanstatus().
*/
void sqlite3VdbeScanStatus(
Vdbe *p, /* VM to add scanstatus() to */
int addrExplain, /* Address of OP_Explain (or 0) */
int addrLoop, /* Address of loop counter */
int addrVisit, /* Address of rows visited counter */
LogEst nEst, /* Estimated number of output rows */
const char *zName /* Name of table or index being scanned */
){
int nByte = (p->nScan+1) * sizeof(ScanStatus);
ScanStatus *aNew;
aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte);
if( aNew ){
ScanStatus *pNew = &aNew[p->nScan++];
pNew->addrExplain = addrExplain;
pNew->addrLoop = addrLoop;
pNew->addrVisit = addrVisit;
pNew->nEst = nEst;
pNew->zName = sqlite3DbStrDup(p->db, zName);
p->aScan = aNew;
}
}
#endif
/*
** Change the value of the P1 operand for a specific instruction.
** This routine is useful when a large program is loaded from a
@@ -1723,9 +1695,6 @@ void sqlite3VdbeMakeReady(
p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
&zCsr, zEnd, &nByte);
p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, &zCsr, zEnd, &nByte);
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
p->anExec = allocSpace(p->anExec, p->nOp*sizeof(i64), &zCsr, zEnd, &nByte);
#endif
if( nByte ){
p->pFree = sqlite3DbMallocZero(db, nByte);
}
@@ -1793,9 +1762,6 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
*/
int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
Vdbe *v = pFrame->v;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
v->anExec = pFrame->anExec;
#endif
v->aOnceFlag = pFrame->aOnceFlag;
v->nOnceFlag = pFrame->nOnceFlag;
v->aOp = pFrame->aOp;
@@ -1806,7 +1772,6 @@ int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
v->nCursor = pFrame->nCursor;
v->db->lastRowid = pFrame->lastRowid;
v->nChange = pFrame->nChange;
v->db->nChange = pFrame->nDbChange;
return pFrame->pc;
}
@@ -2374,7 +2339,6 @@ int sqlite3VdbeHalt(Vdbe *p){
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
sqlite3CloseSavepoints(db);
db->autoCommit = 1;
p->nChange = 0;
}
}
}
@@ -2415,7 +2379,6 @@ int sqlite3VdbeHalt(Vdbe *p){
}else if( rc!=SQLITE_OK ){
p->rc = rc;
sqlite3RollbackAll(db, SQLITE_OK);
p->nChange = 0;
}else{
db->nDeferredCons = 0;
db->nDeferredImmCons = 0;
@@ -2424,7 +2387,6 @@ int sqlite3VdbeHalt(Vdbe *p){
}
}else{
sqlite3RollbackAll(db, SQLITE_OK);
p->nChange = 0;
}
db->nStatement = 0;
}else if( eStatementOp==0 ){
@@ -2436,7 +2398,6 @@ int sqlite3VdbeHalt(Vdbe *p){
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
sqlite3CloseSavepoints(db);
db->autoCommit = 1;
p->nChange = 0;
}
}
@@ -2457,7 +2418,6 @@ int sqlite3VdbeHalt(Vdbe *p){
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
sqlite3CloseSavepoints(db);
db->autoCommit = 1;
p->nChange = 0;
}
}
@@ -2719,12 +2679,6 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
sqlite3DbFree(db, p->aColName);
sqlite3DbFree(db, p->zSql);
sqlite3DbFree(db, p->pFree);
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
for(i=0; i<p->nScan; i++){
sqlite3DbFree(db, p->aScan[i].zName);
}
sqlite3DbFree(db, p->aScan);
#endif
}
/*
+2 -6
View File
@@ -153,11 +153,6 @@ int sqlite3_blob_open(
Parse *pParse = 0;
Incrblob *pBlob = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || ppBlob==0 || zTable==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
flags = !!flags; /* flags = (flags ? 1 : 0); */
*ppBlob = 0;
@@ -376,6 +371,7 @@ static int blobReadWrite(
if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){
/* Request is out of range. Return a transient error. */
rc = SQLITE_ERROR;
sqlite3Error(db, SQLITE_ERROR);
}else if( v==0 ){
/* If there is no statement handle, then the blob-handle has
** already been invalidated. Return SQLITE_ABORT in this case.
@@ -393,10 +389,10 @@ static int blobReadWrite(
sqlite3VdbeFinalize(v);
p->pStmt = 0;
}else{
db->errCode = rc;
v->rc = rc;
}
}
sqlite3Error(db, rc);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
+6 -4
View File
@@ -100,7 +100,7 @@
** The sorter is running in multi-threaded mode if (a) the library was built
** with pre-processor symbol SQLITE_MAX_WORKER_THREADS set to a value greater
** than zero, and (b) worker threads have been enabled at runtime by calling
** "PRAGMA threads=N" with some value of N greater than 0.
** sqlite3_config(SQLITE_CONFIG_WORKER_THREADS, ...).
**
** When Rewind() is called, any data remaining in memory is flushed to a
** final PMA. So at this point the data is stored in some number of sorted
@@ -847,9 +847,11 @@ int sqlite3VdbeSorterInit(
if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING;
pSorter->mxPmaSize = mxCache * pgsz;
/* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
** large heap allocations.
/* If the application has not configure scratch memory using
** SQLITE_CONFIG_SCRATCH then we assume it is OK to do large memory
** allocations. If scratch memory has been configured, then assume
** large memory allocations should be avoided to prevent heap
** fragmentation.
*/
if( sqlite3GlobalConfig.pScratch==0 ){
assert( pSorter->iMemory==0 );
+1 -15
View File
@@ -81,9 +81,6 @@ int sqlite3_create_module(
const sqlite3_module *pModule, /* The definition of the module */
void *pAux /* Context pointer for xCreate/xConnect */
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
#endif
return createModule(db, zName, pModule, pAux, 0);
}
@@ -97,9 +94,6 @@ int sqlite3_create_module_v2(
void *pAux, /* Context pointer for xCreate/xConnect */
void (*xDestroy)(void *) /* Module destructor function */
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
#endif
return createModule(db, zName, pModule, pAux, xDestroy);
}
@@ -704,9 +698,6 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
Table *pTab;
char *zErr = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){
sqlite3Error(db, SQLITE_MISUSE);
@@ -1063,9 +1054,6 @@ int sqlite3_vtab_on_conflict(sqlite3 *db){
static const unsigned char aMap[] = {
SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE
};
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
assert( OE_Rollback==1 && OE_Abort==2 && OE_Fail==3 );
assert( OE_Ignore==4 && OE_Replace==5 );
assert( db->vtabOnConflict>=1 && db->vtabOnConflict<=5 );
@@ -1081,10 +1069,8 @@ int sqlite3_vtab_config(sqlite3 *db, int op, ...){
va_list ap;
int rc = SQLITE_OK;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
va_start(ap, op);
switch( op ){
case SQLITE_VTAB_CONSTRAINT_SUPPORT: {
+6 -5
View File
@@ -1504,7 +1504,7 @@ static void walMergesort(
** Free an iterator allocated by walIteratorInit().
*/
static void walIteratorFree(WalIterator *p){
sqlite3_free(p);
sqlite3ScratchFree(p);
}
/*
@@ -1539,7 +1539,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
nByte = sizeof(WalIterator)
+ (nSegment-1)*sizeof(struct WalSegment)
+ iLast*sizeof(ht_slot);
p = (WalIterator *)sqlite3_malloc(nByte);
p = (WalIterator *)sqlite3ScratchMalloc(nByte);
if( !p ){
return SQLITE_NOMEM;
}
@@ -1549,7 +1549,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
/* Allocate temporary space used by the merge-sort routine. This block
** of memory will be freed before this function returns.
*/
aTmp = (ht_slot *)sqlite3_malloc(
aTmp = (ht_slot *)sqlite3ScratchMalloc(
sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
);
if( !aTmp ){
@@ -1586,7 +1586,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
p->aSegment[i].aPgno = (u32 *)aPgno;
}
}
sqlite3_free(aTmp);
sqlite3ScratchFree(aTmp);
if( rc!=SQLITE_OK ){
walIteratorFree(p);
@@ -2506,7 +2506,7 @@ int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){
memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr));
for(iFrame=pWal->hdr.mxFrame+1;
rc==SQLITE_OK && iFrame<=iMax;
ALWAYS(rc==SQLITE_OK) && iFrame<=iMax;
iFrame++
){
/* This call cannot fail. Unless the page for which the page number
@@ -2525,6 +2525,7 @@ int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){
}
if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
}
assert( rc==SQLITE_OK );
return rc;
}
+51 -139
View File
@@ -225,7 +225,7 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
}
pTerm = &pWC->a[idx = pWC->nTerm++];
if( p && ExprHasProperty(p, EP_Unlikely) ){
pTerm->truthProb = sqlite3LogEst(p->iTable) - 270;
pTerm->truthProb = sqlite3LogEst(p->iTable) - 99;
}else{
pTerm->truthProb = 1;
}
@@ -756,15 +756,6 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
}
}
/*
** Mark term iChild as being a child of term iParent
*/
static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){
pWC->a[iChild].iParent = iParent;
pWC->a[iChild].truthProb = pWC->a[iParent].truthProb;
pWC->a[iParent].nChild++;
}
#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
/*
** Analyze a term that consists of two or more OR-connected
@@ -1062,7 +1053,8 @@ static void exprAnalyzeOrTerm(
testcase( idxNew==0 );
exprAnalyze(pSrc, pWC, idxNew);
pTerm = &pWC->a[idxTerm];
markTermAsChild(pWC, idxNew, idxTerm);
pWC->a[idxNew].iParent = idxTerm;
pTerm->nChild = 1;
}else{
sqlite3ExprListDelete(db, pList);
}
@@ -1164,8 +1156,9 @@ static void exprAnalyze(
idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
if( idxNew==0 ) return;
pNew = &pWC->a[idxNew];
markTermAsChild(pWC, idxNew, idxTerm);
pNew->iParent = idxTerm;
pTerm = &pWC->a[idxTerm];
pTerm->nChild = 1;
pTerm->wtFlags |= TERM_COPIED;
if( pExpr->op==TK_EQ
&& !ExprHasProperty(pExpr, EP_FromJoin)
@@ -1222,8 +1215,9 @@ static void exprAnalyze(
testcase( idxNew==0 );
exprAnalyze(pSrc, pWC, idxNew);
pTerm = &pWC->a[idxTerm];
markTermAsChild(pWC, idxNew, idxTerm);
pWC->a[idxNew].iParent = idxTerm;
}
pTerm->nChild = 2;
}
#endif /* SQLITE_OMIT_BETWEEN_OPTIMIZATION */
@@ -1298,8 +1292,9 @@ static void exprAnalyze(
exprAnalyze(pSrc, pWC, idxNew2);
pTerm = &pWC->a[idxTerm];
if( isComplete ){
markTermAsChild(pWC, idxNew1, idxTerm);
markTermAsChild(pWC, idxNew2, idxTerm);
pWC->a[idxNew1].iParent = idxTerm;
pWC->a[idxNew2].iParent = idxTerm;
pTerm->nChild = 2;
}
}
#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */
@@ -1332,8 +1327,9 @@ static void exprAnalyze(
pNewTerm->leftCursor = pLeft->iTable;
pNewTerm->u.leftColumn = pLeft->iColumn;
pNewTerm->eOperator = WO_MATCH;
markTermAsChild(pWC, idxNew, idxTerm);
pNewTerm->iParent = idxTerm;
pTerm = &pWC->a[idxTerm];
pTerm->nChild = 1;
pTerm->wtFlags |= TERM_COPIED;
pNewTerm->prereqAll = pTerm->prereqAll;
}
@@ -1354,7 +1350,7 @@ static void exprAnalyze(
if( pExpr->op==TK_NOTNULL
&& pExpr->pLeft->op==TK_COLUMN
&& pExpr->pLeft->iColumn>=0
&& OptimizationEnabled(db, SQLITE_Stat34)
&& OptimizationEnabled(db, SQLITE_Stat3)
){
Expr *pNewExpr;
Expr *pLeft = pExpr->pLeft;
@@ -1373,8 +1369,9 @@ static void exprAnalyze(
pNewTerm->leftCursor = pLeft->iTable;
pNewTerm->u.leftColumn = pLeft->iColumn;
pNewTerm->eOperator = WO_GT;
markTermAsChild(pWC, idxNew, idxTerm);
pNewTerm->iParent = idxTerm;
pTerm = &pWC->a[idxTerm];
pTerm->nChild = 1;
pTerm->wtFlags |= TERM_COPIED;
pNewTerm->prereqAll = pTerm->prereqAll;
}
@@ -1594,8 +1591,6 @@ static void constructAutomaticIndex(
Bitmask idxCols; /* Bitmap of columns used for indexing */
Bitmask extraCols; /* Bitmap of additional columns */
u8 sentWarning = 0; /* True if a warnning has been issued */
Expr *pPartial = 0; /* Partial Index Expression */
int iContinue = 0; /* Jump here to skip excluded rows */
/* Generate code to skip over the creation and initialization of the
** transient index on 2nd and subsequent iterations of the loop. */
@@ -1611,12 +1606,6 @@ static void constructAutomaticIndex(
pLoop = pLevel->pWLoop;
idxCols = 0;
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
if( pLoop->prereq==0
&& (pTerm->wtFlags & TERM_VIRTUAL)==0
&& sqlite3ExprIsTableConstant(pTerm->pExpr, pSrc->iCursor) ){
pPartial = sqlite3ExprAnd(pParse->db, pPartial,
sqlite3ExprDup(pParse->db, pTerm->pExpr, 0));
}
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
int iCol = pTerm->u.leftColumn;
Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
@@ -1629,9 +1618,7 @@ static void constructAutomaticIndex(
sentWarning = 1;
}
if( (idxCols & cMask)==0 ){
if( whereLoopResize(pParse->db, pLoop, nKeyCol+1) ){
goto end_auto_index_create;
}
if( whereLoopResize(pParse->db, pLoop, nKeyCol+1) ) return;
pLoop->aLTerm[nKeyCol++] = pTerm;
idxCols |= cMask;
}
@@ -1651,7 +1638,7 @@ static void constructAutomaticIndex(
** if they go out of sync.
*/
extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1));
mxBitCol = MIN(BMS-1,pTable->nCol);
mxBitCol = (pTable->nCol >= BMS-1) ? BMS-1 : pTable->nCol;
testcase( pTable->nCol==BMS-1 );
testcase( pTable->nCol==BMS-2 );
for(i=0; i<mxBitCol; i++){
@@ -1660,10 +1647,11 @@ static void constructAutomaticIndex(
if( pSrc->colUsed & MASKBIT(BMS-1) ){
nKeyCol += pTable->nCol - BMS + 1;
}
pLoop->wsFlags |= WHERE_COLUMN_EQ | WHERE_IDX_ONLY;
/* Construct the Index object to describe this index */
pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+1, 0, &zNotUsed);
if( pIdx==0 ) goto end_auto_index_create;
if( pIdx==0 ) return;
pLoop->u.btree.pIndex = pIdx;
pIdx->zName = "auto-index";
pIdx->pTable = pTable;
@@ -1715,29 +1703,18 @@ static void constructAutomaticIndex(
VdbeComment((v, "for %s", pTable->zName));
/* Fill the automatic index with content */
sqlite3ExprCachePush(pParse);
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
if( pPartial ){
iContinue = sqlite3VdbeMakeLabel(v);
sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL);
pLoop->wsFlags |= WHERE_PARTIALIDX;
}
regRecord = sqlite3GetTempReg(pParse);
sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0);
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
sqlite3VdbeJumpHere(v, addrTop);
sqlite3ReleaseTempReg(pParse, regRecord);
sqlite3ExprCachePop(pParse);
/* Jump here when skipping the initialization */
sqlite3VdbeJumpHere(v, addrInit);
end_auto_index_create:
sqlite3ExprDelete(pParse->db, pPartial);
}
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
@@ -1897,6 +1874,7 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
}
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the location of a particular key among all keys in an
@@ -1905,10 +1883,9 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
** aStat[0] Est. number of rows less than pVal
** aStat[1] Est. number of rows equal to pVal
**
** Return the index of the sample that is the smallest sample that
** is greater than or equal to pRec.
** Return SQLITE_OK on success.
*/
static int whereKeyStats(
static void whereKeyStats(
Parse *pParse, /* Database connection */
Index *pIdx, /* Index to consider domain of */
UnpackedRecord *pRec, /* Vector of values to consider */
@@ -1990,7 +1967,6 @@ static int whereKeyStats(
}
aStat[0] = iLower + iGap;
}
return i;
}
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
@@ -2141,7 +2117,7 @@ static int whereRangeSkipScanEst(
** If either of the upper or lower bound is not present, then NULL is passed in
** place of the corresponding WhereTerm.
**
** The value in (pBuilder->pNew->u.btree.nEq) is the number of the index
** The value in (pBuilder->pNew->u.btree.nEq) is the index of the index
** column subject to the range constraint. Or, equivalently, the number of
** equality constraints optimized by the proposed index scan. For example,
** assuming index p is on t1(a, b), and the SQL query is:
@@ -2157,7 +2133,7 @@ static int whereRangeSkipScanEst(
**
** When this function is called, *pnOut is set to the sqlite3LogEst() of the
** number of rows that the index scan is expected to visit without
** considering the range constraints. If nEq is 0, then *pnOut is the number of
** considering the range constraints. If nEq is 0, this is the number of
** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced)
** to account for the range constraints pLower and pUpper.
**
@@ -2181,7 +2157,10 @@ static int whereRangeScanEst(
Index *p = pLoop->u.btree.pIndex;
int nEq = pLoop->u.btree.nEq;
if( p->nSample>0 && nEq<p->nSampleCol ){
if( p->nSample>0
&& nEq<p->nSampleCol
&& OptimizationEnabled(pParse->db, SQLITE_Stat3)
){
if( nEq==pBuilder->nRecValid ){
UnpackedRecord *pRec = pBuilder->pRec;
tRowcnt a[2];
@@ -2197,19 +2176,15 @@ static int whereRangeScanEst(
** is not a simple variable or literal value), the lower bound of the
** range is $P. Due to a quirk in the way whereKeyStats() works, even
** if $L is available, whereKeyStats() is called for both ($P) and
** ($P:$L) and the larger of the two returned values is used.
** ($P:$L) and the larger of the two returned values used.
**
** Similarly, iUpper is to be set to the estimate of the number of rows
** less than the upper bound of the range query. Where the upper bound
** is either ($P) or ($P:$U). Again, even if $U is available, both values
** of iUpper are requested of whereKeyStats() and the smaller used.
**
** The number of rows between the two bounds is then just iUpper-iLower.
*/
tRowcnt iLower; /* Rows less than the lower bound */
tRowcnt iUpper; /* Rows less than the upper bound */
int iLwrIdx = -2; /* aSample[] for the lower bound */
int iUprIdx = -1; /* aSample[] for the upper bound */
tRowcnt iLower;
tRowcnt iUpper;
if( pRec ){
testcase( pRec->nField!=pBuilder->nRecValid );
@@ -2247,7 +2222,7 @@ static int whereRangeScanEst(
rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
if( rc==SQLITE_OK && bOk ){
tRowcnt iNew;
iLwrIdx = whereKeyStats(pParse, p, pRec, 0, a);
whereKeyStats(pParse, p, pRec, 0, a);
iNew = a[0] + ((pLower->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
if( iNew>iLower ) iLower = iNew;
nOut--;
@@ -2262,7 +2237,7 @@ static int whereRangeScanEst(
rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
if( rc==SQLITE_OK && bOk ){
tRowcnt iNew;
iUprIdx = whereKeyStats(pParse, p, pRec, 1, a);
whereKeyStats(pParse, p, pRec, 1, a);
iNew = a[0] + ((pUpper->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
if( iNew<iUpper ) iUpper = iNew;
nOut--;
@@ -2274,11 +2249,6 @@ static int whereRangeScanEst(
if( rc==SQLITE_OK ){
if( iUpper>iLower ){
nNew = sqlite3LogEst(iUpper - iLower);
/* TUNING: If both iUpper and iLower are derived from the same
** sample, then assume they are 4x more selective. This brings
** the estimated selectivity more in line with what it would be
** if estimated without the use of STAT3/4 tables. */
if( iLwrIdx==iUprIdx ) nNew -= 20; assert( 20==sqlite3LogEst(4) );
}else{
nNew = 10; assert( 10==sqlite3LogEst(2) );
}
@@ -2303,15 +2273,12 @@ static int whereRangeScanEst(
nNew = whereRangeAdjust(pLower, nOut);
nNew = whereRangeAdjust(pUpper, nNew);
/* TUNING: If there is both an upper and lower limit and neither limit
** has an application-defined likelihood(), assume the range is
/* TUNING: If there is both an upper and lower limit, assume the range is
** reduced by an additional 75%. This means that, by default, an open-ended
** range query (e.g. col > ?) is assumed to match 1/4 of the rows in the
** index. While a closed range (e.g. col BETWEEN ? AND ?) is estimated to
** match 1/64 of the index. */
if( pLower && pLower->truthProb>0 && pUpper && pUpper->truthProb>0 ){
nNew -= 20;
}
if( pLower && pUpper ) nNew -= 20;
nOut -= (pLower!=0) + (pUpper!=0);
if( nNew<10 ) nNew = 10;
@@ -2816,14 +2783,11 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop, Table *pTab){
/*
** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
** command, or if either SQLITE_DEBUG or SQLITE_ENABLE_STMT_SCANSTATUS was
** defined at compile-time. If it is not a no-op, a single OP_Explain opcode
** is added to the output to describe the table scan strategy in pLevel.
**
** If an OP_Explain opcode is added to the VM, its address is returned.
** Otherwise, if no OP_Explain is coded, zero is returned.
** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single
** record is added to the output to describe the table scan strategy in
** pLevel.
*/
static int explainOneScan(
static void explainOneScan(
Parse *pParse, /* Parse context */
SrcList *pTabList, /* Table list this loop refers to */
WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */
@@ -2831,8 +2795,7 @@ static int explainOneScan(
int iFrom, /* Value for "from" column of output */
u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */
){
int ret = 0;
#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
#ifndef SQLITE_DEBUG
if( pParse->explain==2 )
#endif
{
@@ -2849,7 +2812,7 @@ static int explainOneScan(
pLoop = pLevel->pWLoop;
flags = pLoop->wsFlags;
if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return 0;
if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;
isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
|| ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
@@ -2878,8 +2841,6 @@ static int explainOneScan(
if( isSearch ){
zFmt = "PRIMARY KEY";
}
}else if( flags & WHERE_PARTIALIDX ){
zFmt = "AUTOMATIC PARTIAL COVERING INDEX";
}else if( flags & WHERE_AUTO_INDEX ){
zFmt = "AUTOMATIC COVERING INDEX";
}else if( flags & WHERE_IDX_ONLY ){
@@ -2921,46 +2882,13 @@ static int explainOneScan(
}
#endif
zMsg = sqlite3StrAccumFinish(&str);
ret = sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg,P4_DYNAMIC);
sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
}
return ret;
}
#else
# define explainOneScan(u,v,w,x,y,z) 0
# define explainOneScan(u,v,w,x,y,z)
#endif /* SQLITE_OMIT_EXPLAIN */
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
/*
** Configure the VM passed as the first argument with an
** sqlite3_stmt_scanstatus() entry corresponding to the scan used to
** implement level pLvl. Argument pSrclist is a pointer to the FROM
** clause that the scan reads data from.
**
** If argument addrExplain is not 0, it must be the address of an
** OP_Explain instruction that describes the same loop.
*/
static void addScanStatus(
Vdbe *v, /* Vdbe to add scanstatus entry to */
SrcList *pSrclist, /* FROM clause pLvl reads data from */
WhereLevel *pLvl, /* Level to add scanstatus() entry for */
int addrExplain /* Address of OP_Explain (or 0) */
){
const char *zObj = 0;
WhereLoop *pLoop = pLvl->pWLoop;
if( (pLoop->wsFlags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
zObj = pLoop->u.btree.pIndex->zName;
}else{
zObj = pSrclist->a[pLvl->iFrom].zName;
}
sqlite3VdbeScanStatus(
v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj
);
}
#else
# define addScanStatus(a, b, c, d) ((void)d)
#endif
/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
@@ -3627,11 +3555,9 @@ static Bitmask codeOneLoopStart(
assert( pSubWInfo || pParse->nErr || db->mallocFailed );
if( pSubWInfo ){
WhereLoop *pSubLoop;
int addrExplain = explainOneScan(
explainOneScan(
pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
);
addScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain);
/* This is the sub-WHERE clause body. First skip over
** duplicate rows from prior sub-WHERE clauses, and record the
** rowid (or PRIMARY KEY) for the current row so that the same
@@ -3762,10 +3688,6 @@ static Bitmask codeOneLoopStart(
}
}
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
pLevel->addrVisit = sqlite3VdbeCurrentAddr(v);
#endif
/* Insert code to test every subexpression that can be completely
** computed using the current set of tables.
*/
@@ -4016,11 +3938,10 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
}
/*
** Return TRUE if all of the following are true:
** Return TRUE if both of the following are true:
**
** (1) X has the same or lower cost that Y
** (2) X is a proper subset of Y
** (3) X skips at least as many columns as Y
**
** By "proper subset" we mean that X uses fewer WHERE clause terms
** than Y and that every WHERE clause term used by X is also used
@@ -4028,9 +3949,7 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
**
** If X is a proper subset of Y then Y is a better choice and ought
** to have a lower cost. This routine returns TRUE when that cost
** relationship is inverted and needs to be adjusted. The third rule
** was added because if X uses skip-scan less than Y it still might
** deserve a lower cost even if it is a proper subset of Y.
** relationship is inverted and needs to be adjusted.
*/
static int whereLoopCheaperProperSubset(
const WhereLoop *pX, /* First WhereLoop to compare */
@@ -4040,7 +3959,6 @@ static int whereLoopCheaperProperSubset(
if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){
return 0; /* X is not a subset of Y */
}
if( pY->nSkip > pX->nSkip ) return 0;
if( pX->rRun >= pY->rRun ){
if( pX->rRun > pY->rRun ) return 0; /* X costs more than Y */
if( pX->nOut > pY->nOut ) return 0; /* X costs more than Y */
@@ -4076,7 +3994,9 @@ static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){
if( (p->wsFlags & WHERE_INDEXED)==0 ) continue;
if( whereLoopCheaperProperSubset(p, pTemplate) ){
/* Adjust pTemplate cost downward so that it is cheaper than its
** subset p. */
** subset p. Except, do not adjust the cost estimate downward for
** a loop that skips more columns. */
if( pTemplate->nSkip>p->nSkip ) continue;
WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n",
pTemplate->rRun, pTemplate->nOut, p->rRun, p->nOut-1));
pTemplate->rRun = p->rRun;
@@ -4502,6 +4422,7 @@ static int whereLoopAddBtreeIndex(
if( nInMul==0
&& pProbe->nSample
&& pNew->u.btree.nEq<=pProbe->nSampleCol
&& OptimizationEnabled(db, SQLITE_Stat3)
&& ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
){
Expr *pExpr = pTerm->pExpr;
@@ -4587,7 +4508,6 @@ static int whereLoopAddBtreeIndex(
assert( 42==sqlite3LogEst(18) );
if( saved_nEq==saved_nSkip
&& saved_nEq+1<pProbe->nKeyCol
&& pProbe->noSkipScan==0
&& pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */
&& (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
){
@@ -6470,10 +6390,7 @@ WhereInfo *sqlite3WhereBegin(
*/
notReady = ~(Bitmask)0;
for(ii=0; ii<nTabList; ii++){
int addrExplain;
int wsFlags;
pLevel = &pWInfo->a[ii];
wsFlags = pLevel->pWLoop->wsFlags;
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
constructAutomaticIndex(pParse, &pWInfo->sWC,
@@ -6481,15 +6398,10 @@ WhereInfo *sqlite3WhereBegin(
if( db->mallocFailed ) goto whereBeginError;
}
#endif
addrExplain = explainOneScan(
pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags
);
explainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags);
pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
notReady = codeOneLoopStart(pWInfo, ii, notReady);
pWInfo->iContinue = pLevel->addrCont;
if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_ONETABLE_ONLY)==0 ){
addScanStatus(v, pTabList, pLevel, addrExplain);
}
}
/* Done. */
-4
View File
@@ -85,9 +85,6 @@ struct WhereLevel {
} u;
struct WhereLoop *pWLoop; /* The selected WhereLoop object */
Bitmask notReady; /* FROM entries not usable at this level */
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
int addrVisit; /* Address at which row is visited */
#endif
};
/*
@@ -462,4 +459,3 @@ struct WhereInfo {
#define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */
#define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */
#define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/
#define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */
+4 -4
View File
@@ -86,23 +86,23 @@ do_test 2.1 {
# range.
#
# Test 3.2 is a little unstable. It depends on the planner estimating
# that (b BETWEEN 30 AND 34) will match more rows than (c BETWEEN
# that (b BETWEEN 50 AND 54) will match more rows than (c BETWEEN
# 800000 AND 900000). Which is a pretty close call (50 vs. 32), so
# the planner could get it wrong with an unlucky set of samples. This
# case happens to work, but others ("b BETWEEN 40 AND 44" for example)
# will fail.
#
do_execsql_test 3.0 {
SELECT count(*) FROM t1 WHERE b BETWEEN 30 AND 34;
SELECT count(*) FROM t1 WHERE b BETWEEN 50 AND 54;
SELECT count(*) FROM t1 WHERE c BETWEEN 0 AND 100000;
SELECT count(*) FROM t1 WHERE c BETWEEN 800000 AND 900000;
} {50 376 32}
do_test 3.1 {
eqp {SELECT * FROM t1 WHERE b BETWEEN 30 AND 34 AND c BETWEEN 0 AND 100000}
eqp {SELECT * FROM t1 WHERE b BETWEEN 50 AND 54 AND c BETWEEN 0 AND 100000}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}}
do_test 3.2 {
eqp {SELECT * FROM t1
WHERE b BETWEEN 30 AND 34 AND c BETWEEN 800000 AND 900000}
WHERE b BETWEEN 50 AND 54 AND c BETWEEN 800000 AND 900000}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}}
do_test 3.3 {
eqp {SELECT * FROM t1 WHERE a=100 AND c BETWEEN 0 AND 100000}
-52
View File
@@ -1,52 +0,0 @@
# 2014-10-24
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
#
# This file implements regression tests for SQLite library. The
# focus of this script is testing automatic index creation logic,
# and specifically creation of automatic partial indexes.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_execsql_test autoindex4-1.0 {
CREATE TABLE t1(a,b);
INSERT INTO t1 VALUES(123,'abc'),(234,'def'),(234,'ghi'),(345,'jkl');
CREATE TABLE t2(x,y);
INSERT INTO t2 VALUES(987,'zyx'),(654,'wvu'),(987,'rqp');
SELECT *, '|' FROM t1, t2 WHERE a=234 AND x=987 ORDER BY +b;
} {234 def 987 rqp | 234 def 987 zyx | 234 ghi 987 rqp | 234 ghi 987 zyx |}
do_execsql_test autoindex4-1.1 {
SELECT *, '|' FROM t1, t2 WHERE a=234 AND x=555;
} {}
do_execsql_test autoindex4-1.2 {
SELECT *, '|' FROM t1 LEFT JOIN t2 ON a=234 AND x=555;
} {123 abc {} {} | 234 def {} {} | 234 ghi {} {} | 345 jkl {} {} |}
do_execsql_test autoindex4-1.3 {
SELECT *, '|' FROM t1 LEFT JOIN t2 ON x=555 WHERE a=234;
} {234 def {} {} | 234 ghi {} {} |}
do_execsql_test autoindex4-1.4 {
SELECT *, '|' FROM t1 LEFT JOIN t2 WHERE a=234 AND x=555;
} {}
do_execsql_test autoindex4-2.0 {
CREATE TABLE t3(e,f);
INSERT INTO t3 VALUES(123,654),(555,444),(234,987);
SELECT (SELECT count(*) FROM t1, t2 WHERE a=e AND x=f), e, f, '|'
FROM t3
ORDER BY rowid;
} {1 123 654 | 0 555 444 | 4 234 987 |}
finish_test
-1
View File
@@ -217,7 +217,6 @@ foreach nPagePerStep {1 200} {
INSERT INTO ${file_dest}.t1 VALUES(1, randstr(1000,1000))
" $db_dest
}
execsql COMMIT $db_dest
}
# Backup the source database.
-65
View File
@@ -1,65 +0,0 @@
# 2014 November 13
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix backup5
forcedelete test2.db
do_execsql_test 1.0 {
CREATE TABLE t1(a, b);
CREATE TABLE t2(a, b);
INSERT INTO t2 VALUES(1, 1);
INSERT INTO t2 VALUES(2, 2);
INSERT INTO t2 VALUES(3, 3);
}
do_test 1.1 {
forcecopy test.db test.db2
db eval {
DROP TABLE t2;
INSERT INTO t1 VALUES(zeroblob(1000), zeroblob(1000));
INSERT INTO t1 VALUES(randomblob(1000), randomblob(1000));
}
} {}
do_test 1.2 {
sqlite3 db2 test.db2
set stmt [sqlite3_prepare_v2 db2 "SELECT * FROM t2" -1 dummy]
sqlite3_step $stmt
} {SQLITE_ROW}
do_test 1.3 {
list [catch { sqlite3_backup B db2 main db main } msg] $msg
} {1 {sqlite3_backup_init() failed}}
do_test 1.4 {
sqlite3_errmsg db2
} {destination database is in use}
do_test 1.5 {
sqlite3_reset $stmt
sqlite3_backup B db2 main db main
B step 200
B finish
} {SQLITE_OK}
do_test 1.6 {
list [sqlite3_step $stmt] [sqlite3_finalize $stmt]
} {SQLITE_ERROR SQLITE_ERROR}
do_test 1.7 {
sqlite3_errmsg db2
} {no such table: t2}
finish_test
+3 -3
View File
@@ -912,7 +912,7 @@ do_test capi3-11.9.3 {
} 1
do_test capi3-11.10 {
sqlite3_step $STMT
} {SQLITE_ROW}
} {SQLITE_ERROR}
ifcapable !autoreset {
# If SQLITE_OMIT_AUTORESET is defined, then the statement must be
# reset() before it can be passed to step() again.
@@ -921,11 +921,11 @@ ifcapable !autoreset {
}
do_test capi3-11.11 {
sqlite3_step $STMT
} {SQLITE_DONE}
} {SQLITE_ROW}
do_test capi3-11.12 {
sqlite3_step $STMT
sqlite3_step $STMT
} {SQLITE_ROW}
} {SQLITE_DONE}
do_test capi3-11.13 {
sqlite3_finalize $STMT
} {SQLITE_OK}
+3 -3
View File
@@ -863,7 +863,7 @@ do_test capi3c-11.9.3 {
} 1
do_test capi3c-11.10 {
sqlite3_step $STMT
} {SQLITE_ROW}
} {SQLITE_ABORT}
ifcapable !autoreset {
# If SQLITE_OMIT_AUTORESET is defined, then the statement must be
# reset() before it can be passed to step() again.
@@ -872,11 +872,11 @@ ifcapable !autoreset {
}
do_test capi3c-11.11 {
sqlite3_step $STMT
} {SQLITE_DONE}
} {SQLITE_ROW}
do_test capi3c-11.12 {
sqlite3_step $STMT
sqlite3_step $STMT
} {SQLITE_ROW}
} {SQLITE_DONE}
do_test capi3c-11.13 {
sqlite3_finalize $STMT
} {SQLITE_OK}
+1
View File
@@ -155,6 +155,7 @@ do_execsql_test capi3d-4.1 {
}
do_test capi3d-4.2.1 {
breakpoint
set ::s1 [sqlite3_prepare_v2 db "ROLLBACK" -1 notused]
sqlite3_step $::s1
} {SQLITE_DONE}
+1
View File
@@ -64,6 +64,7 @@ do_test 1.2 {
} {}
do_test 1.3 {
breakpoint
db eval { PRAGMA secure_delete=1 }
list [catch {
db eval { SELECT * FROM t1 WHERE a IN (1, 2) } {
-76
View File
@@ -1,76 +0,0 @@
# 2014 October 30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix e_blobbytes
do_execsql_test 1.0 {
CREATE TABLE q1(r INTEGER PRIMARY KEY, s TEXT);
WITH d(a, b) AS (
SELECT 0, ''
UNION ALL
SELECT a+1, b||'.' FROM d WHERE a<10000
)
INSERT INTO q1 SELECT * FROM d;
}
# EVIDENCE-OF: R-07796-55423 Returns the size in bytes of the BLOB
# accessible via the successfully opened BLOB handle in its only
# argument.
#
proc check_blob_size {tn rowid bytes} {
uplevel [list do_test $tn [subst -nocommands {
sqlite3_blob_open db main q1 s $rowid 0 B
set res [sqlite3_blob_bytes [set B]]
sqlite3_blob_close [set B]
set res
}] $bytes]
}
check_blob_size 1.1 43 43
check_blob_size 1.2 391 391
check_blob_size 1.3 6349 6349
check_blob_size 1.4 2621 2621
check_blob_size 1.5 7771 7771
check_blob_size 1.6 7949 7949
check_blob_size 1.7 4374 4374
check_blob_size 1.8 2578 2578
check_blob_size 1.9 7004 7004
check_blob_size 1.10 2180 2180
check_blob_size 1.11 3796 3796
check_blob_size 1.12 7101 7101
check_blob_size 1.13 7449 7449
check_blob_size 1.14 7224 7224
check_blob_size 1.15 3038 3038
check_blob_size 1.16 1083 1083
check_blob_size 1.17 5157 5157
check_blob_size 1.18 6686 6686
check_blob_size 1.19 6592 6592
check_blob_size 1.20 0 0
# EVIDENCE-OF: R-53088-19343 The incremental blob I/O routines can only
# read or overwriting existing blob content; they cannot change the size
# of a blob.
#
# Also demonstrated in other e_blobXXX.test files.
#
do_test 2.1 {
sqlite3_blob_open db main q1 s 86 1 B
list [catch { sqlite3_blob_write $B 86 "1" 1 } msg] $msg
} {1 SQLITE_ERROR}
sqlite3_blob_close $B
finish_test
-171
View File
@@ -1,171 +0,0 @@
# 2014 October 30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix e_blobclose
set dots [string repeat . 40]
do_execsql_test 1.0 {
CREATE TABLE x1(a INTEGER PRIMARY KEY, b DOTS);
INSERT INTO x1 VALUES(-1, $dots);
INSERT INTO x1 VALUES(-10, $dots);
INSERT INTO x1 VALUES(-100, $dots);
INSERT INTO x1 VALUES(-1000, $dots);
INSERT INTO x1 VALUES(-10000, $dots);
}
# EVIDENCE-OF: R-03145-46390 This function closes an open BLOB handle.
#
# It's not clear how to test that a blob handle really is closed.
# Attempting to use a closed blob handle will likely crash the process.
# Assume here that if the SHARED lock on the db file is released,
# the blob handle has been closed.
#
do_execsql_test 1.1 { PRAGMA lock_status } {main unlocked temp closed}
sqlite3_blob_open db main x1 b -1 0 B
do_execsql_test 1.2 { PRAGMA lock_status } {main shared temp closed}
sqlite3_blob_close $B
do_execsql_test 1.3 { PRAGMA lock_status } {main unlocked temp closed}
# EVIDENCE-OF: R-34027-00617 If the blob handle being closed was opened
# for read-write access, and if the database is in auto-commit mode and
# there are no other open read-write blob handles or active write
# statements, the current transaction is committed.
#
# 2.1.*: Transaction is not committed if there are other open
# read-write blob handles.
#
# 2.2.*: Transaction is not committed if not in auto-commit mode.
#
# 2.3.*: Active write statements.
#
do_test 2.1.1 {
sqlite3_blob_open db main x1 b -100 1 B1
sqlite3_blob_open db main x1 b -1000 1 B2
sqlite3_blob_open db main x1 b -10000 1 B3
sqlite3_blob_open db main x1 b -10000 0 B4 ;# B4 is read-only!
execsql { PRAGMA lock_status }
} {main reserved temp closed}
do_test 2.1.2 {
sqlite3_blob_close $B1
execsql { PRAGMA lock_status }
} {main reserved temp closed}
do_test 2.1.3 {
sqlite3_blob_close $B2
execsql { PRAGMA lock_status }
} {main reserved temp closed}
do_test 2.1.4 {
sqlite3_blob_close $B3
execsql { PRAGMA lock_status }
} {main shared temp closed}
do_test 2.1.5 {
sqlite3_blob_close $B4
execsql { PRAGMA lock_status }
} {main unlocked temp closed}
do_test 2.2.1 {
sqlite3_blob_open db main x1 b -100 1 B1
execsql { PRAGMA lock_status }
} {main reserved temp closed}
do_test 2.2.2 {
execsql { BEGIN }
sqlite3_blob_close $B1
execsql { PRAGMA lock_status }
} {main reserved temp closed}
do_test 2.2.3 {
execsql { COMMIT }
execsql { PRAGMA lock_status }
} {main unlocked temp closed}
proc val {} {
sqlite3_blob_close $::B
db eval { PRAGMA lock_status }
}
db func val val
do_test 2.3.1 {
sqlite3_blob_open db main x1 b -100 1 B
execsql { PRAGMA lock_status }
} {main reserved temp closed}
do_test 2.3.2 {
execsql { INSERT INTO x1 VALUES(15, val()) }
execsql { PRAGMA lock_status }
} {main unlocked temp closed}
do_test 2.3.3 {
execsql { SELECT * FROM x1 WHERE a = 15 }
} {15 {main reserved temp closed}}
# A reader does not inhibit commit.
do_test 2.3.4 {
sqlite3_blob_open db main x1 b -100 1 B
execsql { PRAGMA lock_status }
} {main reserved temp closed}
do_test 2.3.5 {
execsql { SELECT a, val() FROM x1 LIMIT 1 }
} {-10000 {main shared temp closed}}
do_test 3.1 {
sqlite3_blob_open db main x1 b -10 1 B
execsql {
INSERT INTO x1 VALUES(1, 'abc');
SELECT * FROM x1 WHERE a=1;
}
} {1 abc}
do_test 3.2 {
sqlite3_blob_write $B 0 "abcdefghij" 10
execsql { SELECT * FROM x1 WHERE a=-10 }
} {-10 abcdefghij..............................}
do_test 3.3 {
sqlite3 db2 test.db
execsql { BEGIN ; SELECT * FROM x1 } db2
sqlite3_blob_close $B
} {SQLITE_BUSY}
# EVIDENCE-OF: R-41959-38737 Otherwise, if this function is passed a
# valid open blob handle, the values returned by the sqlite3_errcode()
# and sqlite3_errmsg() functions are set before returning.
#
do_test 3.4 {
list [sqlite3_errcode db] [sqlite3_errmsg db]
} {SQLITE_BUSY {database is locked}}
# EVIDENCE-OF: R-37801-37633 The BLOB handle is closed unconditionally.
# Even if this routine returns an error code, the handle is still
# closed.
#
# Test that the lock has been released. Assume this means the handle
# is closed, even though blob_close() returned SQLITE_BUSY.
#
do_execsql_test 3.4 { PRAGMA lock_status } {main unlocked temp closed}
# EVIDENCE-OF: R-35111-05628 If an error occurs while committing the
# transaction, an error code is returned and the transaction rolled
# back.
#
# Row 1 is removed (it was inserted this transaction) and row -10
# is restored to its original state. Transaction has been rolled back.
#
do_execsql_test 3.5 {
SELECT * FROM x1 WHERE a IN (1, -10);
} {-10 ........................................}
# EVIDENCE-OF: R-25894-51060 Calling this routine with a null pointer
# (such as would be returned by a failed call to sqlite3_blob_open()) is
# a harmless no-op.
#
do_test 4.0 { sqlite3_blob_close 0 } {}
finish_test
-549
View File
@@ -1,549 +0,0 @@
# 2014 October 30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix e_blobopen
forcedelete test.db2
do_execsql_test 1.0 {
ATTACH 'test.db2' AS aux;
CREATE TABLE main.t1(a INTEGER PRIMARY KEY, b TEXT, c BLOB);
CREATE TEMP TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c BLOB);
CREATE TABLE aux.t1(a INTEGER PRIMARY KEY, b TEXT, c BLOB);
CREATE TABLE main.x1(a INTEGER PRIMARY KEY, b TEXT, c BLOB);
CREATE TEMP TABLE x2(a INTEGER PRIMARY KEY, b TEXT, c BLOB);
CREATE TABLE aux.x3(a INTEGER PRIMARY KEY, b TEXT, c BLOB);
INSERT INTO main.t1 VALUES(1, 'main one', X'0101');
INSERT INTO main.t1 VALUES(2, 'main two', X'0102');
INSERT INTO main.t1 VALUES(3, 'main three', X'0103');
INSERT INTO main.t1 VALUES(4, 'main four', X'0104');
INSERT INTO main.t1 VALUES(5, 'main five', X'0105');
INSERT INTO main.x1 VALUES(1, 'x main one', X'000101');
INSERT INTO main.x1 VALUES(2, 'x main two', X'000102');
INSERT INTO main.x1 VALUES(3, 'x main three', X'000103');
INSERT INTO main.x1 VALUES(4, 'x main four', X'000104');
INSERT INTO main.x1 VALUES(5, 'x main five', X'000105');
INSERT INTO temp.t1 VALUES(1, 'temp one', X'0201');
INSERT INTO temp.t1 VALUES(2, 'temp two', X'0202');
INSERT INTO temp.t1 VALUES(3, 'temp three', X'0203');
INSERT INTO temp.t1 VALUES(4, 'temp four', X'0204');
INSERT INTO temp.t1 VALUES(5, 'temp five', X'0205');
INSERT INTO temp.x2 VALUES(1, 'x temp one', X'000201');
INSERT INTO temp.x2 VALUES(2, 'x temp two', X'000202');
INSERT INTO temp.x2 VALUES(3, 'x temp three', X'000203');
INSERT INTO temp.x2 VALUES(4, 'x temp four', X'000204');
INSERT INTO temp.x2 VALUES(5, 'x temp five', X'000205');
INSERT INTO aux.t1 VALUES(1, 'aux one', X'0301');
INSERT INTO aux.t1 VALUES(2, 'aux two', X'0302');
INSERT INTO aux.t1 VALUES(3, 'aux three', X'0303');
INSERT INTO aux.t1 VALUES(4, 'aux four', X'0304');
INSERT INTO aux.t1 VALUES(5, 'aux five', X'0305');
INSERT INTO aux.x3 VALUES(1, 'x aux one', X'000301');
INSERT INTO aux.x3 VALUES(2, 'x aux two', X'000302');
INSERT INTO aux.x3 VALUES(3, 'x aux three', X'000303');
INSERT INTO aux.x3 VALUES(4, 'x aux four', X'000304');
INSERT INTO aux.x3 VALUES(5, 'x aux five', X'000305');
}
#-------------------------------------------------------------------------
# EVIDENCE-OF: R-37639-55938 This interfaces opens a handle to the BLOB
# located in row iRow, column zColumn, table zTable in database zDb; in
# other words, the same BLOB that would be selected by: SELECT zColumn
# FROM zDb.zTable WHERE rowid = iRow;
#
proc read_blob {zDb zTab zCol iRow} {
sqlite3_blob_open db $zDb $zTab $zCol $iRow 0 B
set nByte [sqlite3_blob_bytes $B]
set data [sqlite3_blob_read $B 0 $nByte]
sqlite3_blob_close $B
return $data
}
do_test 1.1.1 { read_blob main t1 b 1 } "main one"
do_test 1.1.2 { read_blob main t1 c 1 } "\01\01"
do_test 1.1.3 { read_blob temp t1 b 1 } "temp one"
do_test 1.1.4 { read_blob temp t1 c 1 } "\02\01"
do_test 1.1.6 { read_blob aux t1 b 1 } "aux one"
do_test 1.1.7 { read_blob aux t1 c 1 } "\03\01"
do_test 1.2.1 { read_blob main t1 b 4 } "main four"
do_test 1.2.2 { read_blob main t1 c 4 } "\01\04"
do_test 1.2.3 { read_blob temp t1 b 4 } "temp four"
do_test 1.2.4 { read_blob temp t1 c 4 } "\02\04"
do_test 1.2.6 { read_blob aux t1 b 4 } "aux four"
do_test 1.2.7 { read_blob aux t1 c 4 } "\03\04"
do_test 1.3.1 { read_blob main x1 b 2 } "x main two"
do_test 1.3.2 { read_blob main x1 c 2 } "\00\01\02"
do_test 1.3.3 { read_blob temp x2 b 2 } "x temp two"
do_test 1.3.4 { read_blob temp x2 c 2 } "\00\02\02"
do_test 1.3.6 { read_blob aux x3 b 2 } "x aux two"
do_test 1.3.7 { read_blob aux x3 c 2 } "\00\03\02"
#-------------------------------------------------------------------------
# EVIDENCE-OF: R-27234-05761 Parameter zDb is not the filename that
# contains the database, but rather the symbolic name of the database.
# For attached databases, this is the name that appears after the AS
# keyword in the ATTACH statement. For the main database file, the
# database name is "main". For TEMP tables, the database name is "temp".
#
# The test cases immediately above demonstrate that the database name
# for the main db, for TEMP tables and for those in attached databases
# is correct. The following tests check that filenames cannot be
# used as well.
#
do_test 2.1 {
list [catch { sqlite3_blob_open db "test.db" t1 b 1 0 B } msg] $msg
} {1 SQLITE_ERROR}
do_test 2.2 {
list [catch { sqlite3_blob_open db "test.db2" t1 b 1 0 B } msg] $msg
} {1 SQLITE_ERROR}
#-------------------------------------------------------------------------
# EVIDENCE-OF: R-50854-53979 If the flags parameter is non-zero, then
# the BLOB is opened for read and write access.
#
# EVIDENCE-OF: R-03922-41160 If the flags parameter is zero, the BLOB is
# opened for read-only access.
#
foreach {tn iRow flags} {
1 1 0
2 2 1
3 3 -1
4 4 2147483647
5 5 -2147483648
} {
do_test 3.$tn.1 {
sqlite3_blob_open db main x1 c $iRow $flags B
set n [sqlite3_blob_bytes $B]
sqlite3_blob_read $B 0 $n
} [binary format ccc 0 1 $iRow]
if {$flags==0} {
# Blob was opened for read-only access - writing returns an error.
do_test 3.$tn.2 {
list [catch { sqlite3_blob_write $B 0 xxx 3 } msg] $msg
} {1 SQLITE_READONLY}
do_execsql_test 3.$tn.3 {
SELECT c FROM x1 WHERE a=$iRow;
} [binary format ccc 0 1 $iRow]
} else {
# Blob was opened for read/write access - writing succeeds
do_test 3.$tn.4 {
list [catch { sqlite3_blob_write $B 0 xxx 3 } msg] $msg
} {0 {}}
do_execsql_test 3.$tn.5 {
SELECT c FROM x1 WHERE a=$iRow;
} {xxx}
}
sqlite3_blob_close $B
}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 4.0 {
CREATE TABLE t1(x, y);
INSERT INTO t1 VALUES('abcd', 152);
INSERT INTO t1 VALUES(NULL, X'00010203');
INSERT INTO t1 VALUES('', 154.2);
CREATE TABLE t2(x PRIMARY KEY, y) WITHOUT ROWID;
INSERT INTO t2 VALUES(1, 'blob');
CREATE TABLE t3(a PRIMARY KEY, b, c, d, e, f, UNIQUE(e, f));
INSERT INTO t3 VALUES('aaaa', 'bbbb', 'cccc', 'dddd', 'eeee', 'ffff');
CREATE INDEX t3b ON t3(b);
CREATE TABLE p1(x PRIMARY KEY);
INSERT INTO p1 VALUES('abc');
CREATE TABLE c1(a INTEGER PRIMARY KEY, b REFERENCES p1);
INSERT INTO c1 VALUES(45, 'abc');
}
proc test_blob_open {tn zDb zTab zCol iRow flags errcode errmsg} {
global B
set B "0x1234"
if {$errcode=="SQLITE_OK"} {
set expected "0 {}"
} else {
set expected "1 $errcode"
}
set ::res [list [
catch { sqlite3_blob_open db $zDb $zTab $zCol $iRow $flags B } msg
] $msg]
do_test 4.$tn.1 { set ::res } $expected
# EVIDENCE-OF: R-08940-21305 Unless it returns SQLITE_MISUSE, this
# function sets the database connection error code and message
# accessible via sqlite3_errcode() and sqlite3_errmsg() and related
# functions.
#
# This proc (test_blob_open) is used below to test various error and
# non-error conditions. But never SQLITE_MISUSE conditions. So these
# test cases are considered as partly verifying the requirement above.
# See below for a test of the SQLITE_MISUSE case.
#
do_test 4.$tn.2 {
sqlite3_errcode db
} $errcode
do_test 4.$tn.3 {
sqlite3_errmsg db
} $errmsg
# EVIDENCE-OF: R-31086-35521 On success, SQLITE_OK is returned and the
# new BLOB handle is stored in *ppBlob. Otherwise an error code is
# returned and, unless the error code is SQLITE_MISUSE, *ppBlob is set
# to NULL.
#
do_test 4.$tn.4 {
expr {$B == "0"}
} [expr {$errcode != "SQLITE_OK"}]
# EVIDENCE-OF: R-63421-15521 This means that, provided the API is not
# misused, it is always safe to call sqlite3_blob_close() on *ppBlob
# after this function it returns.
do_test 4.$tn.5 {
sqlite3_blob_close $B
} {}
}
# EVIDENCE-OF: R-31204-44780 Database zDb does not exist
test_blob_open 1 nosuchdb t1 x 1 0 SQLITE_ERROR "no such table: nosuchdb.t1"
# EVIDENCE-OF: R-28676-08005 Table zTable does not exist within database zDb
test_blob_open 2 main tt1 x 1 0 SQLITE_ERROR "no such table: main.tt1"
# EVIDENCE-OF: R-40134-30296 Table zTable is a WITHOUT ROWID table
test_blob_open 3 main t2 y 1 0 SQLITE_ERROR \
"cannot open table without rowid: t2"
# EVIDENCE-OF: R-56376-21261 Column zColumn does not exist
test_blob_open 4 main t1 z 2 0 SQLITE_ERROR "no such column: \"z\""
# EVIDENCE-OF: R-28258-23166 Row iRow is not present in the table
test_blob_open 5 main t1 y 6 0 SQLITE_ERROR "no such rowid: 6"
# EVIDENCE-OF: R-11683-62380 The specified column of row iRow contains a
# value that is not a TEXT or BLOB value
test_blob_open 6 main t1 x 2 0 SQLITE_ERROR "cannot open value of type null"
test_blob_open 7 main t1 y 1 0 SQLITE_ERROR "cannot open value of type integer"
test_blob_open 8 main t1 y 3 0 SQLITE_ERROR "cannot open value of type real"
# EVIDENCE-OF: R-34146-30782 Column zColumn is part of an index, PRIMARY
# KEY or UNIQUE constraint and the blob is being opened for read/write
# access
#
# Test cases 8.1.* show that such columns can be opened for read-access.
# Tests 8.2.* show that read-write access is different. Columns "c" and "c"
# are not part of an index, PK or UNIQUE constraint, so they work in both
# cases.
#
test_blob_open 8.1.1 main t3 a 1 0 SQLITE_OK "not an error"
test_blob_open 8.1.2 main t3 b 1 0 SQLITE_OK "not an error"
test_blob_open 8.1.3 main t3 c 1 0 SQLITE_OK "not an error"
test_blob_open 8.1.4 main t3 d 1 0 SQLITE_OK "not an error"
test_blob_open 8.1.5 main t3 e 1 0 SQLITE_OK "not an error"
test_blob_open 8.1.6 main t3 f 1 0 SQLITE_OK "not an error"
set cannot "cannot open indexed column for writing"
test_blob_open 8.2.1 main t3 a 1 8 SQLITE_ERROR $cannot
test_blob_open 8.2.2 main t3 b 1 8 SQLITE_ERROR $cannot
test_blob_open 8.2.3 main t3 c 1 8 SQLITE_OK "not an error"
test_blob_open 8.2.4 main t3 d 1 8 SQLITE_OK "not an error"
test_blob_open 8.2.5 main t3 e 1 8 SQLITE_ERROR $cannot
test_blob_open 8.2.6 main t3 f 1 8 SQLITE_ERROR $cannot
# EVIDENCE-OF: R-50117-55204 Foreign key constraints are enabled, column
# zColumn is part of a child key definition and the blob is being opened
# for read/write access
#
# 9.1: FK disabled, read-only access.
# 9.2: FK disabled, read-only access.
# 9.3: FK enabled, read/write access.
# 9.4: FK enabled, read/write access.
#
test_blob_open 9.1 main c1 b 45 0 SQLITE_OK "not an error"
test_blob_open 9.2 main c1 b 45 1 SQLITE_OK "not an error"
execsql { PRAGMA foreign_keys = ON }
test_blob_open 9.3 main c1 b 45 0 SQLITE_OK "not an error"
test_blob_open 9.4 main c1 b 45 1 SQLITE_ERROR \
"cannot open foreign key column for writing"
#-------------------------------------------------------------------------
# EVIDENCE-OF: R-08940-21305 Unless it returns SQLITE_MISUSE, this
# function sets the database connection error code and message
# accessible via sqlite3_errcode() and sqlite3_errmsg() and related
# functions.
#
# This requirement is partially verified by the many uses of test
# command [test_blob_open] above. All that is left is to verify the
# SQLITE_MISUSE case.
#
# SQLITE_MISUSE is only returned if SQLITE_ENABLE_API_ARMOR is defined
# during compilation.
#
ifcapable api_armor {
sqlite3_blob_open db main t1 x 1 0 B
do_test 10.1.1 {
list [catch {sqlite3_blob_open $B main t1 x 1 0 B2} msg] $msg
} {1 SQLITE_MISUSE}
do_test 10.1.2 {
list [sqlite3_errcode db] [sqlite3_errmsg db]
} {SQLITE_OK {not an error}}
sqlite3_blob_close $B
do_test 10.2.1 {
list [catch {sqlite3_blob_open db main {} x 1 0 B} msg] $msg
} {1 SQLITE_MISUSE}
do_test 10.2.2 {
list [sqlite3_errcode db] [sqlite3_errmsg db]
} {SQLITE_OK {not an error}}
}
#-------------------------------------------------------------------------
# EVIDENCE-OF: R-50542-62589 If the row that a BLOB handle points to is
# modified by an UPDATE, DELETE, or by ON CONFLICT side-effects then the
# BLOB handle is marked as "expired". This is true if any column of the
# row is changed, even a column other than the one the BLOB handle is
# open on.
#
# EVIDENCE-OF: R-48367-20048 Calls to sqlite3_blob_read() and
# sqlite3_blob_write() for an expired BLOB handle fail with a return
# code of SQLITE_ABORT.
#
# 11.2: read-only handle, DELETE.
# 11.3: read-only handle, UPDATE.
# 11.4: read-only handle, REPLACE.
# 11.5: read/write handle, DELETE.
# 11.6: read/write handle, UPDATE.
# 11.7: read/write handle, REPLACE.
#
do_execsql_test 11.1 {
CREATE TABLE b1(a INTEGER PRIMARY KEY, b, c UNIQUE);
INSERT INTO b1 VALUES(1, '1234567890', 1);
INSERT INTO b1 VALUES(2, '1234567890', 2);
INSERT INTO b1 VALUES(3, '1234567890', 3);
INSERT INTO b1 VALUES(4, '1234567890', 4);
INSERT INTO b1 VALUES(5, '1234567890', 5);
INSERT INTO b1 VALUES(6, '1234567890', 6);
CREATE TABLE b2(a INTEGER PRIMARY KEY, b, c UNIQUE);
INSERT INTO b2 VALUES(1, '1234567890', 1);
INSERT INTO b2 VALUES(2, '1234567890', 2);
INSERT INTO b2 VALUES(3, '1234567890', 3);
INSERT INTO b2 VALUES(4, '1234567890', 4);
INSERT INTO b2 VALUES(5, '1234567890', 5);
INSERT INTO b2 VALUES(6, '1234567890', 6);
}
do_test 11.2.1 {
sqlite3_blob_open db main b1 b 2 0 B
sqlite3_blob_read $B 0 10
} {1234567890}
do_test 11.2.2 {
# Deleting a different row does not invalidate the blob handle.
execsql { DELETE FROM b1 WHERE a = 1 }
sqlite3_blob_read $B 0 10
} {1234567890}
do_test 11.2.3 {
execsql { DELETE FROM b1 WHERE a = 2 }
list [catch { sqlite3_blob_read $B 0 10 } msg] $msg
} {1 SQLITE_ABORT}
do_test 11.2.4 {
sqlite3_blob_close $B
} {}
do_test 11.3.1 {
sqlite3_blob_open db main b1 b 3 0 B
sqlite3_blob_read $B 0 10
} {1234567890}
do_test 11.3.2 {
# Updating a different row
execsql { UPDATE b1 SET c = 42 WHERE a=4 }
sqlite3_blob_read $B 0 10
} {1234567890}
do_test 11.3.3 {
execsql { UPDATE b1 SET c = 43 WHERE a=3 }
list [catch { sqlite3_blob_read $B 0 10 } msg] $msg
} {1 SQLITE_ABORT}
do_test 11.3.4 {
sqlite3_blob_close $B
} {}
do_test 11.4.1 {
sqlite3_blob_open db main b1 b 6 0 B
sqlite3_blob_read $B 0 10
} {1234567890}
do_test 11.4.2 {
# Replace a different row
execsql { INSERT OR REPLACE INTO b1 VALUES(10, 'abcdefghij', 5) }
sqlite3_blob_read $B 0 10
} {1234567890}
do_test 11.4.3 {
execsql { INSERT OR REPLACE INTO b1 VALUES(11, 'abcdefghij', 6) }
list [catch { sqlite3_blob_read $B 0 10 } msg] $msg
} {1 SQLITE_ABORT}
do_test 11.4.4 {
sqlite3_blob_close $B
} {}
do_test 11.4.1 {
sqlite3_blob_open db main b2 b 2 1 B
sqlite3_blob_write $B 0 "abcdefghij"
} {}
do_test 11.4.2 {
# Deleting a different row does not invalidate the blob handle.
execsql { DELETE FROM b2 WHERE a = 1 }
sqlite3_blob_write $B 0 "ABCDEFGHIJ"
} {}
do_test 11.4.3 {
execsql { DELETE FROM b2 WHERE a = 2 }
list [catch { sqlite3_blob_write $B 0 "0987654321" } msg] $msg
} {1 SQLITE_ABORT}
do_test 11.4.4 {
sqlite3_blob_close $B
} {}
do_test 11.5.1 {
sqlite3_blob_open db main b2 b 3 1 B
sqlite3_blob_write $B 0 "abcdefghij"
} {}
do_test 11.5.2 {
# Updating a different row
execsql { UPDATE b2 SET c = 42 WHERE a=4 }
sqlite3_blob_write $B 0 "ABCDEFGHIJ"
} {}
do_test 11.5.3 {
execsql { UPDATE b2 SET c = 43 WHERE a=3 }
list [catch { sqlite3_blob_write $B 0 "0987654321" } msg] $msg
} {1 SQLITE_ABORT}
do_test 11.5.4 {
sqlite3_blob_close $B
} {}
do_test 11.6.1 {
sqlite3_blob_open db main b2 b 6 1 B
sqlite3_blob_write $B 0 "abcdefghij"
} {}
do_test 11.6.2 {
# Replace a different row
execsql { INSERT OR REPLACE INTO b2 VALUES(10, 'abcdefghij', 5) }
sqlite3_blob_write $B 0 "ABCDEFGHIJ"
} {}
do_test 11.6.3 {
execsql { INSERT OR REPLACE INTO b2 VALUES(11, 'abcdefghij', 6) }
list [catch { sqlite3_blob_write $B 0 "0987654321" } msg] $msg
} {1 SQLITE_ABORT}
do_test 11.6.4 {
sqlite3_blob_close $B
} {}
#-------------------------------------------------------------------------
# EVIDENCE-OF: R-45408-40694 Changes written into a BLOB prior to the
# BLOB expiring are not rolled back by the expiration of the BLOB. Such
# changes will eventually commit if the transaction continues to
# completion.
#
do_execsql_test 12.1 {
CREATE TABLE b3(x INTEGER PRIMARY KEY, y TEXT, z INTEGER);
INSERT INTO b3 VALUES(22, '..........', NULL);
}
do_test 12.2 {
sqlite3_blob_open db main b3 y 22 1 B
sqlite3_blob_write $B 0 "xxxxx" 5
} {}
do_execsql_test 12.3 {
UPDATE b3 SET z = 'not null';
}
do_test 12.4 {
list [catch {sqlite3_blob_write $B 5 "xxxxx" 5} msg] $msg
} {1 SQLITE_ABORT}
do_execsql_test 12.5 {
SELECT * FROM b3;
} {22 xxxxx..... {not null}}
do_test 12.5 {
sqlite3_blob_close $B
} {}
do_execsql_test 12.6 {
SELECT * FROM b3;
} {22 xxxxx..... {not null}}
#-------------------------------------------------------------------------
# EVIDENCE-OF: R-58813-55036 The sqlite3_bind_zeroblob() and
# sqlite3_result_zeroblob() interfaces and the built-in zeroblob SQL
# function may be used to create a zero-filled blob to read or write
# using the incremental-blob interface.
#
do_execsql_test 13.1 {
CREATE TABLE c2(i INTEGER PRIMARY KEY, j);
INSERT INTO c2 VALUES(10, zeroblob(24));
}
do_test 13.2 {
set stmt [sqlite3_prepare_v2 db "INSERT INTO c2 VALUES(11, ?)" -1]
sqlite3_bind_zeroblob $stmt 1 45
sqlite3_step $stmt
sqlite3_finalize $stmt
} {SQLITE_OK}
# The blobs can be read:
#
do_test 13.3.1 {
sqlite3_blob_open db main c2 j 10 1 B
sqlite3_blob_open db main c2 j 11 1 B2
list [sqlite3_blob_bytes $B] [sqlite3_blob_bytes $B2]
} {24 45}
do_test 13.3.2 {
sqlite3_blob_read $B 0 24
} [string repeat [binary format c 0] 24]
do_test 13.3.3 {
sqlite3_blob_read $B2 0 45
} [string repeat [binary format c 0] 45]
# And also written:
#
do_test 13.4.1 {
sqlite3_blob_write $B 0 [string repeat [binary format c 1] 24]
} {}
do_test 13.4.2 {
sqlite3_blob_write $B2 0 [string repeat [binary format c 1] 45]
} {}
do_test 13.5 {
sqlite3_blob_close $B
sqlite3_blob_close $B2
execsql { SELECT j FROM c2 }
} [list \
[string repeat [binary format c 1] 24] \
[string repeat [binary format c 1] 45] \
]
finish_test
-204
View File
@@ -1,204 +0,0 @@
# 2014 October 30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix e_blobwrite
#--------------------------------------------------------------------------
# EVIDENCE-OF: R-62898-22698 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 into the open BLOB, starting at offset
# iOffset.
#
set dots [string repeat . 40]
do_execsql_test 1.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, t TEXT);
INSERT INTO t1 VALUES(-1, $dots);
INSERT INTO t1 VALUES(-2, $dots);
INSERT INTO t1 VALUES(-3, $dots);
INSERT INTO t1 VALUES(-4, $dots);
INSERT INTO t1 VALUES(-5, $dots);
INSERT INTO t1 VALUES(-6, $dots);
}
proc blob_write_test {tn id iOffset blob nData final} {
sqlite3_blob_open db main t1 t $id 1 B
# EVIDENCE-OF: R-45864-01884 On success, sqlite3_blob_write() returns
# SQLITE_OK. Otherwise, an error code or an extended error code is
# returned.
#
# This block tests the SQLITE_OK case in the requirement above (the
# Tcl sqlite3_blob_write() wrapper uses an empty string in place of
# "SQLITE_OK"). The error cases are tested by the "blob_write_error_test"
# tests below.
#
set res [sqlite3_blob_write $B $iOffset $blob $nData]
uplevel [list do_test $tn.1 [list set {} $res] {}]
sqlite3_blob_close $B
uplevel [list do_execsql_test $tn.3 "SELECT t FROM t1 WHERE a=$id" $final]
}
set blob "0123456789012345678901234567890123456789"
blob_write_test 1.1 -1 0 $blob 10 { 0123456789.............................. }
blob_write_test 1.2 -2 8 $blob 10 { ........0123456789...................... }
blob_write_test 1.3 -3 8 $blob 1 { ........0............................... }
blob_write_test 1.4 -4 18 $blob 22 { ..................0123456789012345678901 }
blob_write_test 1.5 -5 18 $blob 0 { ........................................ }
blob_write_test 1.6 -6 0 $blob 40 { 0123456789012345678901234567890123456789 }
proc blob_write_error_test {tn B iOffset blob nData errcode errmsg} {
# In cases where the underlying sqlite3_blob_write() function returns
# SQLITE_OK, the Tcl wrapper returns an empty string. If the underlying
# function returns an error, the Tcl wrapper throws an exception with
# the error code as the Tcl exception message.
#
if {$errcode=="SQLITE_OK"} {
set ret ""
set isError 0
} else {
set ret $errcode
set isError 1
}
set cmd [list sqlite3_blob_write $B $iOffset $blob $nData]
uplevel [list do_test $tn.1 [subst -nocommands {
list [catch {$cmd} msg] [set msg]
}] [list $isError $ret]]
# EVIDENCE-OF: R-34782-18311 Unless SQLITE_MISUSE is returned, this
# function sets the database connection error code and message
# accessible via sqlite3_errcode() and sqlite3_errmsg() and related
# functions.
#
if {$errcode == "SQLITE_MISUSE"} { error "test proc misuse!" }
uplevel [list do_test $tn.2 [list sqlite3_errcode db] $errcode]
uplevel [list do_test $tn.3 [list sqlite3_errmsg db] $errmsg]
}
do_execsql_test 2.0 {
CREATE TABLE t2(a TEXT, b INTEGER PRIMARY KEY);
INSERT INTO t2 VALUES($dots, 43);
INSERT INTO t2 VALUES($dots, 44);
INSERT INTO t2 VALUES($dots, 45);
}
# EVIDENCE-OF: R-63341-57517 If the BLOB handle passed as the first
# argument was not opened for writing (the flags parameter to
# sqlite3_blob_open() was zero), this function returns SQLITE_READONLY.
#
sqlite3_blob_open db main t2 a 43 0 B
blob_write_error_test 2.1 $B 0 $blob 10 \
SQLITE_READONLY {attempt to write a readonly database}
sqlite3_blob_close $B
# EVIDENCE-OF: R-29804-27366 If offset iOffset is less than N bytes from
# the end of the BLOB, SQLITE_ERROR is returned and no data is written.
#
sqlite3_blob_open db main t2 a 44 3 B
blob_write_error_test 2.2.1 $B 31 $blob 10 \
SQLITE_ERROR {SQL logic error or missing database}
# Make a successful write to the blob handle. This shows that the
# sqlite3_errcode() and sqlite3_errmsg() values are set even if the
# blob_write() call succeeds (see requirement in the [blob_write_error_test]
# proc).
blob_write_error_test 2.2.1 $B 30 $blob 10 SQLITE_OK {not an error}
# EVIDENCE-OF: R-58570-38916 If N or iOffset are less than zero
# SQLITE_ERROR is returned and no data is written.
#
blob_write_error_test 2.2.2 $B 31 $blob -1 \
SQLITE_ERROR {SQL logic error or missing database}
blob_write_error_test 2.2.3 $B 20 $blob 10 SQLITE_OK {not an error}
blob_write_error_test 2.2.4 $B -1 $blob 10 \
SQLITE_ERROR {SQL logic error or missing database}
sqlite3_blob_close $B
# EVIDENCE-OF: R-20958-54138 An attempt to write to an expired BLOB
# handle fails with an error code of SQLITE_ABORT.
#
do_test 2.3 {
sqlite3_blob_open db main t2 a 43 0 B
execsql { DELETE FROM t2 WHERE b=43 }
} {}
blob_write_error_test 2.3.1 $B 5 $blob 5 \
SQLITE_ABORT {callback requested query abort}
do_test 2.3.2 {
execsql { SELECT 1, 2, 3 }
sqlite3_errcode db
} {SQLITE_OK}
blob_write_error_test 2.3.3 $B 5 $blob 5 \
SQLITE_ABORT {callback requested query abort}
sqlite3_blob_close $B
# EVIDENCE-OF: R-08382-59936 Writes to the BLOB that occurred before the
# BLOB handle expired are not rolled back by the expiration of the
# handle, though of course those changes might have been overwritten by
# the statement that expired the BLOB handle or by other independent
# statements.
#
# 3.1.*: not rolled back,
# 3.2.*: overwritten.
#
do_execsql_test 3.0 {
CREATE TABLE t3(i INTEGER PRIMARY KEY, j TEXT, k TEXT);
INSERT INTO t3 VALUES(1, $dots, $dots);
INSERT INTO t3 VALUES(2, $dots, $dots);
SELECT * FROM t3 WHERE i=1;
} {
1
........................................
........................................
}
sqlite3_blob_open db main t3 j 1 1 B
blob_write_error_test 3.1.1 $B 5 $blob 10 SQLITE_OK {not an error}
do_execsql_test 3.1.2 {
UPDATE t3 SET k = 'xyz' WHERE i=1;
SELECT * FROM t3 WHERE i=1;
} {
1 .....0123456789......................... xyz
}
blob_write_error_test 3.1.3 $B 15 $blob 10 \
SQLITE_ABORT {callback requested query abort}
sqlite3_blob_close $B
do_execsql_test 3.1.4 {
SELECT * FROM t3 WHERE i=1;
} {
1 .....0123456789......................... xyz
}
sqlite3_blob_open db main t3 j 2 1 B
blob_write_error_test 3.2.1 $B 5 $blob 10 SQLITE_OK {not an error}
do_execsql_test 3.2.2 {
UPDATE t3 SET j = 'xyz' WHERE i=2;
SELECT * FROM t3 WHERE i=2;
} {
2 xyz ........................................
}
blob_write_error_test 3.2.3 $B 15 $blob 10 \
SQLITE_ABORT {callback requested query abort}
sqlite3_blob_close $B
do_execsql_test 3.2.4 {
SELECT * FROM t3 WHERE i=2;
} {
2 xyz ........................................
}
finish_test
-441
View File
@@ -1,441 +0,0 @@
# 2011 October 28
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix e_changes
# Like [do_execsql_test], except it appends the value returned by
# [db changes] to the result of executing the SQL script.
#
proc do_changes_test {tn sql res} {
uplevel [list \
do_test $tn "concat \[execsql {$sql}\] \[db changes\]" $res
]
}
#--------------------------------------------------------------------------
# EVIDENCE-OF: R-15996-49369 This function returns the number of rows
# modified, inserted or deleted by the most recently completed INSERT,
# UPDATE or DELETE statement on the database connection specified by the
# only parameter.
#
do_execsql_test 1.0 {
CREATE TABLE t1(a, b);
CREATE TABLE t2(x, y, PRIMARY KEY(x, y)) WITHOUT ROWID;
CREATE INDEX i1 ON t1(a);
CREATE INDEX i2 ON t2(y);
}
foreach {tn schema} {
1 {
CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(b);
}
2 {
CREATE TABLE t1(a, b, PRIMARY KEY(a, b)) WITHOUT ROWID;
CREATE INDEX i1 ON t1(b);
}
} {
reset_db
execsql $schema
# Insert 1 row.
do_changes_test 1.$tn.1 { INSERT INTO t1 VALUES(0, 0) } 1
# Insert 10 rows.
do_changes_test 1.$tn.2 {
WITH rows(i, j) AS (
SELECT 1, 1 UNION ALL SELECT i+1, j+i FROM rows WHERE i<10
)
INSERT INTO t1 SELECT * FROM rows
} 10
# Modify 5 rows.
do_changes_test 1.$tn.3 {
UPDATE t1 SET b=b+1 WHERE a<5;
} 5
# Delete 4 rows
do_changes_test 1.$tn.4 {
DELETE FROM t1 WHERE a>6
} 4
# Check the "on the database connecton specified" part of hte
# requirement - changes made by other connections do not show up in
# the return value of sqlite3_changes().
do_test 1.$tn.5 {
sqlite3 db2 test.db
execsql { INSERT INTO t1 VALUES(-1, -1) } db2
db2 changes
} 1
do_test 1.$tn.6 {
db changes
} 4
db2 close
# Test that statements that modify no rows because they hit UNIQUE
# constraints set the sqlite3_changes() value to 0. Regardless of
# whether or not they are executed inside an explicit transaction.
#
# 1.$tn.8-9: outside of a transaction
# 1.$tn.10-12: inside a transaction
#
do_changes_test 1.$tn.7 {
CREATE UNIQUE INDEX i2 ON t1(a);
} 4
do_catchsql_test 1.$tn.8 {
INSERT INTO t1 VALUES('a', 0), ('b', 0), ('c', 0), (0, 11);
} {1 {UNIQUE constraint failed: t1.a}}
do_test 1.$tn.9 { db changes } 0
do_catchsql_test 1.$tn.10 {
BEGIN;
INSERT INTO t1 VALUES('a', 0), ('b', 0), ('c', 0), (0, 11);
} {1 {UNIQUE constraint failed: t1.a}}
do_test 1.$tn.11 { db changes } 0
do_changes_test 1.$tn.12 COMMIT 0
}
#--------------------------------------------------------------------------
# EVIDENCE-OF: R-44877-05564 Executing any other type of SQL statement
# does not modify the value returned by this function.
#
reset_db
do_changes_test 2.1 { CREATE TABLE t1(x) } 0
do_changes_test 2.2 {
WITH d(y) AS (SELECT 1 UNION ALL SELECT y+1 FROM d WHERE y<47)
INSERT INTO t1 SELECT y FROM d;
} 47
# The statement above set changes() to 47. Check that none of the following
# modify this.
do_changes_test 2.3 { SELECT count(x) FROM t1 } {47 47}
do_changes_test 2.4 { DROP TABLE t1 } 47
do_changes_test 2.5 { CREATE TABLE t1(x) } 47
do_changes_test 2.6 { ALTER TABLE t1 ADD COLUMN b } 47
#--------------------------------------------------------------------------
# EVIDENCE-OF: R-53938-27527 Only changes made directly by the INSERT,
# UPDATE or DELETE statement are considered - auxiliary changes caused
# by triggers, foreign key actions or REPLACE constraint resolution are
# not counted.
#
# 3.1.*: triggers
# 3.2.*: foreign key actions
# 3.3.*: replace constraints
#
reset_db
do_execsql_test 3.1.0 {
CREATE TABLE log(x);
CREATE TABLE p1(one PRIMARY KEY, two);
CREATE TRIGGER tr_ai AFTER INSERT ON p1 BEGIN
INSERT INTO log VALUES('insert');
END;
CREATE TRIGGER tr_bd BEFORE DELETE ON p1 BEGIN
INSERT INTO log VALUES('delete');
END;
CREATE TRIGGER tr_au AFTER UPDATE ON p1 BEGIN
INSERT INTO log VALUES('update');
END;
}
do_changes_test 3.1.1 {
INSERT INTO p1 VALUES('a', 'A'), ('b', 'B'), ('c', 'C');
} 3
do_changes_test 3.1.2 {
UPDATE p1 SET two = two||two;
} 3
do_changes_test 3.1.3 {
DELETE FROM p1 WHERE one IN ('a', 'c');
} 2
do_execsql_test 3.1.4 {
-- None of the inserts on table log were counted.
SELECT count(*) FROM log
} 8
do_execsql_test 3.2.0 {
DELETE FROM p1;
INSERT INTO p1 VALUES('a', 'A'), ('b', 'B'), ('c', 'C');
CREATE TABLE c1(a, b, FOREIGN KEY(a) REFERENCES p1 ON DELETE SET NULL);
CREATE TABLE c2(a, b, FOREIGN KEY(a) REFERENCES p1 ON DELETE SET DEFAULT);
CREATE TABLE c3(a, b, FOREIGN KEY(a) REFERENCES p1 ON DELETE CASCADE);
INSERT INTO c1 VALUES('a', 'aaa');
INSERT INTO c2 VALUES('b', 'bbb');
INSERT INTO c3 VALUES('c', 'ccc');
INSERT INTO p1 VALUES('d', 'D'), ('e', 'E'), ('f', 'F');
CREATE TABLE c4(a, b, FOREIGN KEY(a) REFERENCES p1 ON UPDATE SET NULL);
CREATE TABLE c5(a, b, FOREIGN KEY(a) REFERENCES p1 ON UPDATE SET DEFAULT);
CREATE TABLE c6(a, b, FOREIGN KEY(a) REFERENCES p1 ON UPDATE CASCADE);
INSERT INTO c4 VALUES('d', 'aaa');
INSERT INTO c5 VALUES('e', 'bbb');
INSERT INTO c6 VALUES('f', 'ccc');
PRAGMA foreign_keys = ON;
}
do_changes_test 3.2.1 { DELETE FROM p1 WHERE one = 'a' } 1
do_changes_test 3.2.2 { DELETE FROM p1 WHERE one = 'b' } 1
do_changes_test 3.2.3 { DELETE FROM p1 WHERE one = 'c' } 1
do_execsql_test 3.2.4 {
SELECT * FROM c1;
SELECT * FROM c2;
SELECT * FROM c3;
} {{} aaa {} bbb}
do_changes_test 3.2.5 { UPDATE p1 SET one = 'g' WHERE one = 'd' } 1
do_changes_test 3.2.6 { UPDATE p1 SET one = 'h' WHERE one = 'e' } 1
do_changes_test 3.2.7 { UPDATE p1 SET one = 'i' WHERE one = 'f' } 1
do_execsql_test 3.2.8 {
SELECT * FROM c4;
SELECT * FROM c5;
SELECT * FROM c6;
} {{} aaa {} bbb i ccc}
do_execsql_test 3.3.0 {
CREATE TABLE r1(a UNIQUE, b UNIQUE);
INSERT INTO r1 VALUES('i', 'i');
INSERT INTO r1 VALUES('ii', 'ii');
INSERT INTO r1 VALUES('iii', 'iii');
INSERT INTO r1 VALUES('iv', 'iv');
INSERT INTO r1 VALUES('v', 'v');
INSERT INTO r1 VALUES('vi', 'vi');
INSERT INTO r1 VALUES('vii', 'vii');
}
do_changes_test 3.3.1 { INSERT OR REPLACE INTO r1 VALUES('i', 1) } 1
do_changes_test 3.3.2 { INSERT OR REPLACE INTO r1 VALUES('iv', 'v') } 1
do_changes_test 3.3.3 { UPDATE OR REPLACE r1 SET b='v' WHERE a='iii' } 1
do_changes_test 3.3.4 { UPDATE OR REPLACE r1 SET b='vi',a='vii' WHERE a='ii' } 1
do_execsql_test 3.3.5 {
SELECT * FROM r1 ORDER BY a;
} {i 1 iii v vii vi}
#--------------------------------------------------------------------------
# EVIDENCE-OF: R-09813-48563 The value returned by sqlite3_changes()
# immediately after an INSERT, UPDATE or DELETE statement run on a view
# is always zero.
#
reset_db
do_execsql_test 4.1 {
CREATE TABLE log(log);
CREATE TABLE t1(x, y);
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t1 VALUES(3, 4);
INSERT INTO t1 VALUES(5, 6);
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE TRIGGER v1_i INSTEAD OF INSERT ON v1 BEGIN
INSERT INTO log VALUES('insert');
END;
CREATE TRIGGER v1_u INSTEAD OF UPDATE ON v1 BEGIN
INSERT INTO log VALUES('update'), ('update');
END;
CREATE TRIGGER v1_d INSTEAD OF DELETE ON v1 BEGIN
INSERT INTO log VALUES('delete'), ('delete'), ('delete');
END;
}
do_changes_test 4.2.1 { INSERT INTO t1 SELECT * FROM t1 } 3
do_changes_test 4.2.2 { INSERT INTO v1 VALUES(1, 2) } 0
do_changes_test 4.3.1 { INSERT INTO t1 SELECT * FROM t1 } 6
do_changes_test 4.3.2 { UPDATE v1 SET y='xyz' WHERE x=1 } 0
do_changes_test 4.4.1 { INSERT INTO t1 SELECT * FROM t1 } 12
do_changes_test 4.4.2 { DELETE FROM v1 WHERE x=5 } 0
#--------------------------------------------------------------------------
# EVIDENCE-OF: R-32918-61474 Before entering a trigger program the value
# returned by sqlite3_changes() function is saved. After the trigger
# program has finished, the original value is restored.
#
reset_db
db func my_changes my_changes
set ::changes [list]
proc my_changes {x} {
set res [db changes]
lappend ::changes $x $res
return $res
}
do_execsql_test 5.1.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
CREATE TABLE t2(x);
INSERT INTO t1 VALUES(1, NULL);
INSERT INTO t1 VALUES(2, NULL);
INSERT INTO t1 VALUES(3, NULL);
CREATE TRIGGER AFTER UPDATE ON t1 BEGIN
INSERT INTO t2 VALUES('a'), ('b'), ('c');
SELECT my_changes('trigger');
END;
}
do_execsql_test 5.1.1 {
INSERT INTO t2 VALUES('a'), ('b');
UPDATE t1 SET b = my_changes('update');
SELECT * FROM t1;
} {1 2 2 2 3 2}
# Value is being restored to "2" when the trigger program exits.
do_test 5.1.2 {
set ::changes
} {update 2 trigger 3 update 2 trigger 3 update 2 trigger 3}
reset_db
do_execsql_test 5.2.0 {
CREATE TABLE t1(a, b);
CREATE TABLE log(x);
INSERT INTO t1 VALUES(1, 0);
INSERT INTO t1 VALUES(2, 0);
INSERT INTO t1 VALUES(3, 0);
CREATE TRIGGER t1_a_u AFTER UPDATE ON t1 BEGIN
INSERT INTO log VALUES(old.b || ' -> ' || new.b || ' c = ' || changes() );
END;
CREATE TABLE t2(a);
INSERT INTO t2 VALUES(1), (2), (3);
UPDATE t1 SET b = changes();
}
do_execsql_test 5.2.1 {
SELECT * FROM t1;
} {1 3 2 3 3 3}
do_execsql_test 5.2.2 {
SELECT * FROM log;
} {{0 -> 3 c = 3} {0 -> 3 c = 3} {0 -> 3 c = 3}}
#--------------------------------------------------------------------------
# EVIDENCE-OF: R-17146-37073 Within a trigger program each INSERT,
# UPDATE and DELETE statement sets the value returned by
# sqlite3_changes() upon completion as normal. Of course, this value
# will not include any changes performed by sub-triggers, as the
# sqlite3_changes() value will be saved and restored after each
# sub-trigger has run.
reset_db
do_execsql_test 6.0 {
CREATE TABLE t1(a, b);
CREATE TABLE t2(a, b);
CREATE TABLE t3(a, b);
CREATE TABLE log(x);
CREATE TRIGGER t1_i BEFORE INSERT ON t1 BEGIN
INSERT INTO t2 VALUES(new.a, new.b), (new.a, new.b);
INSERT INTO log VALUES('t2->' || changes());
END;
CREATE TRIGGER t2_i AFTER INSERT ON t2 BEGIN
INSERT INTO t3 VALUES(new.a, new.b), (new.a, new.b), (new.a, new.b);
INSERT INTO log VALUES('t3->' || changes());
END;
CREATE TRIGGER t1_u AFTER UPDATE ON t1 BEGIN
UPDATE t2 SET b=new.b WHERE a=old.a;
INSERT INTO log VALUES('t2->' || changes());
END;
CREATE TRIGGER t2_u BEFORE UPDATE ON t2 BEGIN
UPDATE t3 SET b=new.b WHERE a=old.a;
INSERT INTO log VALUES('t3->' || changes());
END;
CREATE TRIGGER t1_d AFTER DELETE ON t1 BEGIN
DELETE FROM t2 WHERE a=old.a AND b=old.b;
INSERT INTO log VALUES('t2->' || changes());
END;
CREATE TRIGGER t2_d BEFORE DELETE ON t2 BEGIN
DELETE FROM t3 WHERE a=old.a AND b=old.b;
INSERT INTO log VALUES('t3->' || changes());
END;
}
do_changes_test 6.1 {
INSERT INTO t1 VALUES('+', 'o');
SELECT * FROM log;
} {t3->3 t3->3 t2->2 1}
do_changes_test 6.2 {
DELETE FROM log;
UPDATE t1 SET b='*';
SELECT * FROM log;
} {t3->6 t3->6 t2->2 1}
do_changes_test 6.3 {
DELETE FROM log;
DELETE FROM t1;
SELECT * FROM log;
} {t3->6 t3->0 t2->2 1}
#--------------------------------------------------------------------------
# EVIDENCE-OF: R-43399-09409 This means that if the changes() SQL
# function (or similar) is used by the first INSERT, UPDATE or DELETE
# statement within a trigger, it returns the value as set when the
# calling statement began executing.
#
# EVIDENCE-OF: R-53215-27584 If it is used by the second or subsequent
# such statement within a trigger program, the value returned reflects
# the number of rows modified by the previous INSERT, UPDATE or DELETE
# statement within the same trigger.
#
reset_db
do_execsql_test 7.1 {
CREATE TABLE q1(t);
CREATE TABLE q2(u, v);
CREATE TABLE q3(w);
CREATE TRIGGER q2_insert BEFORE INSERT ON q2 BEGIN
/* changes() returns value from previous I/U/D in callers context */
INSERT INTO q1 VALUES('1:' || changes());
/* changes() returns value of previous I/U/D in this context */
INSERT INTO q3 VALUES(changes()), (2), (3);
INSERT INTO q1 VALUES('2:' || changes());
INSERT INTO q3 VALUES(changes() + 3), (changes()+4);
SELECT 'this does not affect things!';
INSERT INTO q1 VALUES('3:' || changes());
UPDATE q3 SET w = w+10 WHERE w%2;
INSERT INTO q1 VALUES('4:' || changes());
DELETE FROM q3;
INSERT INTO q1 VALUES('5:' || changes());
END;
}
do_execsql_test 7.2 {
INSERT INTO q2 VALUES('x', 'y');
SELECT * FROM q1;
} {
1:0 2:3 3:2 4:3 5:5
}
do_execsql_test 7.3 {
DELETE FROM q1;
INSERT INTO q2 VALUES('x', 'y');
SELECT * FROM q1;
} {
1:5 2:3 3:2 4:3 5:5
}
finish_test
-213
View File
@@ -1,213 +0,0 @@
# 2011 May 06
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix e_totalchanges
# Like [do_execsql_test], except it appends the value returned by
# [db total_changes] to the result of executing the SQL script.
#
proc do_tc_test {tn sql res} {
uplevel [list \
do_test $tn "concat \[execsql {$sql}\] \[db total_changes\]" $res
]
}
do_execsql_test 1.0 {
CREATE TABLE t1(a, b);
CREATE INDEX t1_b ON t1(b);
CREATE TABLE t2(x, y, PRIMARY KEY(x, y)) WITHOUT ROWID;
CREATE INDEX t2_y ON t2(y);
}
#--------------------------------------------------------------------------
# EVIDENCE-OF: R-65438-26258 This function returns the total number of
# rows inserted, modified or deleted by all INSERT, UPDATE or DELETE
# statements completed since the database connection was opened,
# including those executed as part of trigger programs.
#
# 1.1.*: different types of I/U/D statements,
# 1.2.*: trigger programs.
#
do_tc_test 1.1.1 {
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t1 VALUES(3, 4);
UPDATE t1 SET a = a+1;
DELETE FROM t1;
} {6}
do_tc_test 1.1.2 {
DELETE FROM t1
} {6}
do_tc_test 1.1.3 {
WITH data(a,b) AS (
SELECT 0, 0 UNION ALL SELECT a+1, b+1 FROM data WHERE a<99
)
INSERT INTO t1 SELECT * FROM data;
} {106}
do_tc_test 1.1.4 {
INSERT INTO t2 SELECT * FROM t1 WHERE a<50;
UPDATE t2 SET y=y+1;
} {206}
do_tc_test 1.1.5 {
DELETE FROM t2 WHERE y<=25
} {231}
do_execsql_test 1.2.1 {
DELETE FROM t1;
DELETE FROM t2;
}
sqlite3 db test.db ; # To reset total_changes
do_tc_test 1.2.2 {
CREATE TABLE log(detail);
CREATE TRIGGER t1_after_insert AFTER INSERT ON t1 BEGIN
INSERT INTO log VALUES('inserted into t1');
END;
CREATE TRIGGER t1_before_delete BEFORE DELETE ON t1 BEGIN
INSERT INTO log VALUES('deleting from t1');
INSERT INTO log VALUES('here we go!');
END;
CREATE TRIGGER t1_after_update AFTER UPDATE ON t1 BEGIN
INSERT INTO log VALUES('update');
DELETE FROM log;
END;
INSERT INTO t1 VALUES('a', 'b'); -- 1 + 1
UPDATE t1 SET b='c'; -- 1 + 1 + 2
DELETE FROM t1; -- 1 + 1 + 1
} {9}
#--------------------------------------------------------------------------
# EVIDENCE-OF: R-61766-15253 Executing any other type of SQL statement
# does not affect the value returned by sqlite3_total_changes().
do_tc_test 2.1 {
INSERT INTO t1 VALUES(1, 2), (3, 4);
INSERT INTO t2 VALUES(1, 2), (3, 4);
} {15}
do_tc_test 2.2 {
SELECT count(*) FROM t1;
} {2 15}
do_tc_test 2.3 {
CREATE TABLE t4(a, b);
ALTER TABLE t4 ADD COLUMN c;
CREATE INDEX i4 ON t4(c);
ALTER TABLE t4 RENAME TO t5;
ANALYZE;
BEGIN;
DROP TABLE t2;
ROLLBACK;
VACUUM;
} {15}
#--------------------------------------------------------------------------
# EVIDENCE-OF: R-36043-10590 Changes made as part of foreign key
# actions are included in the count, but those made as part of REPLACE
# constraint resolution are not.
#
# 3.1.*: foreign key actions
# 3.2.*: REPLACE constraints.
#
sqlite3 db test.db ; # To reset total_changes
do_tc_test 3.1.1 {
CREATE TABLE p1(c PRIMARY KEY, d);
CREATE TABLE c1(a, b, FOREIGN KEY(a) REFERENCES p1 ON DELETE SET NULL);
CREATE TABLE c2(a, b, FOREIGN KEY(a) REFERENCES p1 ON DELETE CASCADE);
CREATE TABLE c3(a, b, FOREIGN KEY(a) REFERENCES p1 ON DELETE SET DEFAULT);
INSERT INTO p1 VALUES(1, 'one');
INSERT INTO p1 VALUES(2, 'two');
INSERT INTO p1 VALUES(3, 'three');
INSERT INTO p1 VALUES(4, 'four');
INSERT INTO c1 VALUES(1, 'i');
INSERT INTO c2 VALUES(2, 'ii');
INSERT INTO c3 VALUES(3, 'iii');
PRAGMA foreign_keys = ON;
} {7}
do_tc_test 3.1.2 { DELETE FROM p1 WHERE c=1; } {9}
do_tc_test 3.1.3 { DELETE FROM p1 WHERE c=2; } {11}
do_tc_test 3.1.4 { DELETE FROM p1 WHERE c=3; } {13}
do_tc_test 3.1.5 { DELETE FROM p1 WHERE c=4; } {14} ; # only 1 this time.
sqlite3 db test.db ; # To reset total_changes
do_tc_test 3.1.6 {
DROP TABLE c1;
DROP TABLE c2;
DROP TABLE c3;
CREATE TABLE c1(a, b, FOREIGN KEY(a) REFERENCES p1 ON UPDATE SET NULL);
CREATE TABLE c2(a, b, FOREIGN KEY(a) REFERENCES p1 ON UPDATE CASCADE);
CREATE TABLE c3(a, b, FOREIGN KEY(a) REFERENCES p1 ON UPDATE SET DEFAULT);
INSERT INTO p1 VALUES(1, 'one');
INSERT INTO p1 VALUES(2, 'two');
INSERT INTO p1 VALUES(3, 'three');
INSERT INTO p1 VALUES(4, 'four');
INSERT INTO c1 VALUES(1, 'i');
INSERT INTO c2 VALUES(2, 'ii');
INSERT INTO c3 VALUES(3, 'iii');
PRAGMA foreign_keys = ON;
} {7}
do_tc_test 3.1.7 { UPDATE p1 SET c=c+4 WHERE c=1; } {9}
do_tc_test 3.1.8 { UPDATE p1 SET c=c+4 WHERE c=2; } {11}
do_tc_test 3.1.9 { UPDATE p1 SET c=c+4 WHERE c=3; } {13}
do_tc_test 3.1.10 { UPDATE p1 SET c=c+4 WHERE c=4; } {14} ; # only 1 this time.
sqlite3 db test.db ; # To reset total_changes
do_tc_test 3.2.1 {
CREATE TABLE t3(a UNIQUE, b UNIQUE);
INSERT INTO t3 VALUES('one', 'one');
INSERT INTO t3 VALUES('two', 'two');
INSERT OR REPLACE INTO t3 VALUES('one', 'two');
} {3}
do_tc_test 3.2.2 {
INSERT INTO t3 VALUES('three', 'one');
UPDATE OR REPLACE t3 SET b='two' WHERE b='one';
SELECT * FROM t3;
} {three two 5}
#--------------------------------------------------------------------------
# EVIDENCE-OF: R-54872-08741 Changes to a view that are intercepted by
# INSTEAD OF triggers are not counted.
#
sqlite3 db test.db ; # To reset total_changes
do_tc_test 4.1 {
CREATE TABLE t6(x);
CREATE VIEW v1 AS SELECT * FROM t6;
CREATE TRIGGER v1_tr1 INSTEAD OF INSERT ON v1 BEGIN
SELECT 'no-op';
END;
INSERT INTO v1 VALUES('a');
INSERT INTO v1 VALUES('b');
} {0}
do_tc_test 4.2 {
CREATE TRIGGER v1_tr2 INSTEAD OF INSERT ON v1 BEGIN
INSERT INTO t6 VALUES(new.x);
END;
INSERT INTO v1 VALUES('c');
INSERT INTO v1 VALUES('d');
} {2}
finish_test
-229
View File
@@ -1,229 +0,0 @@
# 2011 May 06
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix e_wal
db close
testvfs oldvfs -iversion 1
# EVIDENCE-OF: R-58297-14483 WAL databases can be created, read, and
# written even if shared memory is unavailable as long as the
# locking_mode is set to EXCLUSIVE before the first attempted access.
#
# EVIDENCE-OF: R-00449-33772 This feature allows WAL databases to be
# created, read, and written by legacy VFSes that lack the "version 2"
# shared-memory methods xShmMap, xShmLock, xShmBarrier, and xShmUnmap on
# the sqlite3_io_methods object.
#
# 1.1: "create" tests.
# 1.2: "read" tests.
# 1.3: "write" tests.
#
# All three done with VFS "oldvfs", which has iVersion==1 and so does
# not support shared memory.
#
sqlite3 db test.db -vfs oldvfs
do_execsql_test 1.1.1 {
PRAGMA journal_mode = WAL;
} {delete}
do_execsql_test 1.1.2 {
PRAGMA locking_mode = EXCLUSIVE;
PRAGMA journal_mode = WAL;
} {exclusive wal}
do_execsql_test 1.1.3 {
CREATE TABLE t1(x, y);
INSERT INTO t1 VALUES(1, 2);
} {}
do_test 1.1.4 {
list [file exists test.db-shm] [file exists test.db-wal]
} {0 1}
do_test 1.2.1 {
db close
sqlite3 db test.db -vfs oldvfs
catchsql { SELECT * FROM t1 }
} {1 {unable to open database file}}
do_test 1.2.2 {
execsql { PRAGMA locking_mode = EXCLUSIVE }
execsql { SELECT * FROM t1 }
} {1 2}
do_test 1.2.3 {
list [file exists test.db-shm] [file exists test.db-wal]
} {0 1}
do_test 1.3.1 {
db close
sqlite3 db test.db -vfs oldvfs
catchsql { INSERT INTO t1 VALUES(3, 4) }
} {1 {unable to open database file}}
do_test 1.3.2 {
execsql { PRAGMA locking_mode = EXCLUSIVE }
execsql { INSERT INTO t1 VALUES(3, 4) }
execsql { SELECT * FROM t1 }
} {1 2 3 4}
do_test 1.3.3 {
list [file exists test.db-shm] [file exists test.db-wal]
} {0 1}
# EVIDENCE-OF: R-31969-57825 If EXCLUSIVE locking mode is set prior to
# the first WAL-mode database access, then SQLite never attempts to call
# any of the shared-memory methods and hence no shared-memory wal-index
# is ever created.
#
db close
sqlite3 db test.db
do_execsql_test 2.1.1 {
PRAGMA locking_mode = EXCLUSIVE;
SELECT * FROM t1;
} {exclusive 1 2 3 4}
do_test 2.1.2 {
list [file exists test.db-shm] [file exists test.db-wal]
} {0 1}
# EVIDENCE-OF: R-36328-16367 In that case, the database connection
# remains in EXCLUSIVE mode as long as the journal mode is WAL; attempts
# to change the locking mode using "PRAGMA locking_mode=NORMAL;" are
# no-ops.
#
do_execsql_test 2.2.1 {
PRAGMA locking_mode = NORMAL;
SELECT * FROM t1;
} {exclusive 1 2 3 4}
do_test 2.2.2 {
sqlite3 db2 test.db
catchsql {SELECT * FROM t1} db2
} {1 {database is locked}}
db2 close
# EVIDENCE-OF: R-63522-46088 The only way to change out of EXCLUSIVE
# locking mode is to first change out of WAL journal mode.
#
do_execsql_test 2.3.1 {
PRAGMA journal_mode = DELETE;
SELECT * FROM t1;
} {delete 1 2 3 4}
do_test 2.3.2 {
sqlite3 db2 test.db
catchsql {SELECT * FROM t1} db2
} {1 {database is locked}}
do_execsql_test 2.3.3 {
PRAGMA locking_mode = NORMAL;
SELECT * FROM t1;
} {normal 1 2 3 4}
do_test 2.3.4 {
sqlite3 db2 test.db
catchsql {SELECT * FROM t1} db2
} {0 {1 2 3 4}}
db2 close
db close
# EVIDENCE-OF: R-57239-11845 If NORMAL locking mode is in effect for the
# first WAL-mode database access, then the shared-memory wal-index is
# created.
#
do_test 3.0 {
sqlite3 db test.db
execsql { PRAGMA journal_mode = WAL }
db close
} {}
do_test 3.1 {
sqlite3 db test.db
execsql { SELECT * FROM t1 }
list [file exists test.db-shm] [file exists test.db-wal]
} {1 1}
# EVIDENCE-OF: R-13779-07711 As long as exactly one connection is using
# a shared-memory wal-index, the locking mode can be changed freely
# between NORMAL and EXCLUSIVE.
#
do_execsql_test 3.2.1 {
PRAGMA locking_mode = EXCLUSIVE;
PRAGMA locking_mode = NORMAL;
PRAGMA locking_mode = EXCLUSIVE;
INSERT INTO t1 VALUES(5, 6);
} {exclusive normal exclusive}
do_test 3.2.2 {
sqlite3 db2 test.db
catchsql { SELECT * FROM t1 } db2
} {1 {database is locked}}
# EVIDENCE-OF: R-10993-11647 It is only when the shared-memory wal-index
# is omitted, when the locking mode is EXCLUSIVE prior to the first
# WAL-mode database access, that the locking mode is stuck in EXCLUSIVE.
#
do_execsql_test 3.2.3 {
PRAGMA locking_mode = NORMAL;
SELECT * FROM t1;
} {normal 1 2 3 4 5 6}
do_test 3.2.4 {
catchsql { SELECT * FROM t1 } db2
} {0 {1 2 3 4 5 6}}
do_catchsql_test 3.2.5 {
PRAGMA locking_mode = EXCLUSIVE;
INSERT INTO t1 VALUES(7, 8);
} {1 {database is locked}}
db2 close
# EVIDENCE-OF: R-46197-42811 This means that the underlying VFS must
# support the "version 2" shared-memory.
#
# EVIDENCE-OF: R-55316-21772 If the VFS does not support shared-memory
# methods, then the attempt to open a database that is already in WAL
# mode, or the attempt convert a database into WAL mode, will fail.
#
db close
do_test 3.4.1 {
sqlite3 db test.db -vfs oldvfs
catchsql { SELECT * FROM t1 }
} {1 {unable to open database file}}
db close
do_test 3.4.2 {
forcedelete test.db2
sqlite3 db test.db2 -vfs oldvfs
catchsql { PRAGMA journal_mode = WAL }
} {0 delete}
db close
# EVIDENCE-OF: R-22428-28959 To prevent older versions of SQLite from
# trying to recover a WAL-mode database (and making matters worse) the
# database file format version numbers (bytes 18 and 19 in the database
# header) are increased from 1 to 2 in WAL mode.
#
reset_db
do_execsql_test 4.1.1 { CREATE TABLE t1(x, y) }
do_test 4.1.2 { hexio_read test.db 18 2 } {0101}
do_execsql_test 4.1.3 { PRAGMA journal_mode = wAL } {wal}
do_test 4.1.4 { hexio_read test.db 18 2 } {0202}
# EVIDENCE-OF: R-02535-05811 One can explicitly change out of WAL mode
# using a pragma such as this: PRAGMA journal_mode=DELETE;
#
do_execsql_test 4.2.1 { INSERT INTO t1 VALUES(1, 1); } {}
do_test 4.2.2 { file exists test.db-wal } {1}
do_execsql_test 4.2.3 { PRAGMA journal_mode = delete } {delete}
do_test 4.2.4 { file exists test.db-wal } {0}
# EVIDENCE-OF: R-60175-02388 Deliberately changing out of WAL mode
# changes the database file format version numbers back to 1 so that
# older versions of SQLite can once again access the database file.
#
do_test 4.3 { hexio_read test.db 18 2 } {0101}
finish_test
-17
View File
@@ -50,22 +50,5 @@ do_tblsread_test 1.3 { UPDATE par SET a=? WHERE b=? } {c1 c2 par}
do_tblsread_test 1.4 { UPDATE par SET c=? WHERE b=? } {c3 par}
do_tblsread_test 1.5 { UPDATE par SET a=?,b=?,c=? WHERE b=? } {c1 c2 c3 par s1}
ifcapable incrblob {
do_execsql_test 2.0 {
CREATE TABLE pX(x PRIMARY KEY);
CREATE TABLE cX(a INTEGER PRIMARY KEY, b REFERENCES pX);
}
do_catchsql_test 2.1 {
INSERT INTO cX VALUES(11, zeroblob(40));
} {1 {FOREIGN KEY constraint failed}}
do_test 2.2 {
set stmt [sqlite3_prepare_v2 db "INSERT INTO cX VALUES(11, ?)" -1]
sqlite3_bind_zeroblob $stmt 1 45
sqlite3_step $stmt
sqlite3_finalize $stmt
} {SQLITE_CONSTRAINT}
}
finish_test
-48
View File
@@ -12,7 +12,6 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix in5
do_test in5-1.1 {
execsql {
@@ -136,51 +135,4 @@ do_test in5-5.3 {
}]
} {0}
#-------------------------------------------------------------------------
# At one point SQLite was removing the DISTINCT keyword from expressions
# similar to:
#
# <expr1> IN (SELECT DISTINCT <expr2> FROM...)
#
# However, there are a few obscure cases where this is incorrect. For
# example, if the SELECT features a LIMIT clause, or if the collation
# sequence or affinity used by the DISTINCT does not match the one used
# by the IN(...) expression.
#
do_execsql_test 6.1.1 {
CREATE TABLE t1(a COLLATE nocase);
INSERT INTO t1 VALUES('one');
INSERT INTO t1 VALUES('ONE');
}
do_execsql_test 6.1.2 {
SELECT count(*) FROM t1 WHERE a COLLATE BINARY IN (SELECT DISTINCT a FROM t1)
} {1}
do_execsql_test 6.2.1 {
CREATE TABLE t3(a, b);
INSERT INTO t3 VALUES(1, 1);
INSERT INTO t3 VALUES(1, 2);
INSERT INTO t3 VALUES(1, 3);
INSERT INTO t3 VALUES(2, 4);
INSERT INTO t3 VALUES(2, 5);
INSERT INTO t3 VALUES(2, 6);
INSERT INTO t3 VALUES(3, 7);
INSERT INTO t3 VALUES(3, 8);
INSERT INTO t3 VALUES(3, 9);
}
do_execsql_test 6.2.2 {
SELECT count(*) FROM t3 WHERE b IN (SELECT DISTINCT a FROM t3 LIMIT 5);
} {3}
do_execsql_test 6.2.3 {
SELECT count(*) FROM t3 WHERE b IN (SELECT a FROM t3 LIMIT 5);
} {2}
do_execsql_test 6.3.1 {
CREATE TABLE x1(a);
CREATE TABLE x2(b);
INSERT INTO x1 VALUES(1), (1), (2);
INSERT INTO x2 VALUES(1), (2);
SELECT count(*) FROM x2 WHERE b IN (SELECT DISTINCT a FROM x1 LIMIT 2);
} {2}
finish_test
-61
View File
@@ -1,61 +0,0 @@
# 2014-11-10
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
# The focus of this script is testing the "eval.c" loadable extension.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
load_static_extension db eval
do_execsql_test misc8-1.0 {
CREATE TABLE t1(a,b,c);
INSERT INTO t1 VALUES(1,2,3),(4,5,6);
SELECT quote(eval('SELECT * FROM t1 ORDER BY a','-abc-'));
} {'1-abc-2-abc-3-abc-4-abc-5-abc-6'}
do_execsql_test misc8-1.1 {
SELECT quote(eval('SELECT * FROM t1 ORDER BY a'));
} {{'1 2 3 4 5 6'}}
do_catchsql_test misc8-1.2 {
SELECT quote(eval('SELECT d FROM t1 ORDER BY a'));
} {1 {no such column: d}}
do_execsql_test misc8-1.3 {
INSERT INTO t1 VALUES(7,null,9);
SELECT eval('SELECT * FROM t1 ORDER BY a',',');
} {1,2,3,4,5,6,7,,9}
do_catchsql_test misc8-1.4 {
BEGIN;
INSERT INTO t1 VALUES(10,11,12);
SELECT a, coalesce(b, eval('ROLLBACK; SELECT ''bam'';')), c
FROM t1 ORDER BY a;
} {0 {1 2 3 4 5 6 7 bam 9}}
do_catchsql_test misc8-1.5 {
INSERT INTO t1 VALUES(10,11,12);
SELECT a, coalesce(b, eval('SELECT ''bam''')), c
FROM t1
ORDER BY rowid;
} {0 {1 2 3 4 5 6 7 bam 9 10 11 12}}
do_catchsql_test misc8-1.6 {
SELECT a, coalesce(b, eval('DELETE FROM t1; SELECT ''bam''')), c
FROM t1
ORDER BY rowid;
} {0 {1 2 3 4 5 6 7 bam {}}}
do_catchsql_test misc8-1.7 {
INSERT INTO t1 VALUES(1,2,3),(4,5,6),(7,null,9);
BEGIN;
CREATE TABLE t2(x);
SELECT a, coalesce(b, eval('ROLLBACK; SELECT ''bam''')), c
FROM t1
ORDER BY rowid;
} {1 {abort due to ROLLBACK}}
finish_test
+42 -44
View File
@@ -33,7 +33,7 @@ proc register_rblob_code {dbname seed} {
set ::rcnt $seed
proc rblob {n} {
set ::rcnt [expr (([set ::rcnt] << 3) + [set ::rcnt] + 456) & 0xFFFFFFFF]
set str [format %.8x [expr [set ::rcnt] ^ 0xbdf20da3]]
set str [format %.8x [expr [set ::rcnt] ^ 0xbdf20da3]]
string range [string repeat [set str] [expr [set n]/4]] 1 [set n]
}
$dbname func rblob rblob
@@ -42,7 +42,7 @@ proc register_rblob_code {dbname seed} {
# For cases 1.1 and 1.4, the number of pages read using xRead() is 4 on
# unix and 9 on windows. The difference is that windows only ever maps
# an integer number of OS pages (i.e. creates mappings that are a multiple
# an integer number of OS pages (i.e. creates mappings that are a multiple
# of 4KB in size). Whereas on unix any sized mapping may be created.
#
foreach {t mmap_size nRead c2init} {
@@ -106,52 +106,50 @@ foreach {t mmap_size nRead c2init} {
set ::rcnt 0
proc rblob {n} {
set ::rcnt [expr (($::rcnt << 3) + $::rcnt + 456) & 0xFFFFFFFF]
set str [format %.8x [expr $::rcnt ^ 0xbdf20da3]]
set str [format %.8x [expr $::rcnt ^ 0xbdf20da3]]
string range [string repeat $str [expr $n/4]] 1 $n
}
reset_db
db func rblob rblob
ifcapable wal {
do_execsql_test 2.1 {
PRAGMA auto_vacuum = 1;
PRAGMA mmap_size = 67108864;
PRAGMA journal_mode = wal;
CREATE TABLE t1(a, b, UNIQUE(a, b));
INSERT INTO t1 VALUES(rblob(500), rblob(500));
INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 2
INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 4
INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 8
INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 16
INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 32
do_execsql_test 2.1 {
PRAGMA auto_vacuum = 1;
PRAGMA mmap_size = 67108864;
PRAGMA journal_mode = wal;
CREATE TABLE t1(a, b, UNIQUE(a, b));
INSERT INTO t1 VALUES(rblob(500), rblob(500));
INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 2
INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 4
INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 8
INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 16
INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 32
PRAGMA wal_checkpoint;
} {67108864 wal 0 103 103}
do_execsql_test 2.2 {
PRAGMA auto_vacuum;
SELECT count(*) FROM t1;
} {1 32}
if {[permutation] != "inmemory_journal"} {
do_test 2.3 {
sqlite3 db2 test.db
db2 func rblob rblob
db2 eval {
DELETE FROM t1 WHERE (rowid%4);
PRAGMA wal_checkpoint;
}
db2 eval {
INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 16
SELECT count(*) FROM t1;
}
} {16}
do_execsql_test 2.4 {
PRAGMA wal_checkpoint;
} {67108864 wal 0 103 103}
do_execsql_test 2.2 {
PRAGMA auto_vacuum;
SELECT count(*) FROM t1;
} {1 32}
if {[permutation] != "inmemory_journal"} {
do_test 2.3 {
sqlite3 db2 test.db
db2 func rblob rblob
db2 eval {
DELETE FROM t1 WHERE (rowid%4);
PRAGMA wal_checkpoint;
}
db2 eval {
INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 16
SELECT count(*) FROM t1;
}
} {16}
do_execsql_test 2.4 {
PRAGMA wal_checkpoint;
} {0 24 24}
db2 close
}
} {0 24 24}
db2 close
}
reset_db
@@ -229,7 +227,7 @@ do_test 4.4 {
do_execsql_test 4.5 { COMMIT }
#-------------------------------------------------------------------------
# Ensure that existing cursors holding xFetch() references are not
# Ensure that existing cursors holding xFetch() references are not
# confused if those pages are moved to make way for the root page of a
# new table or index.
#
@@ -298,7 +296,7 @@ foreach {tn1 mmap1 mmap2} {
sql1 "PRAGMA mmap_size = $mmap1"
sql2 "PRAGMA mmap_size = $mmap2"
do_test $tn1.$tn {
do_test $tn1.$tn {
for {set i 1} {$i <= 100} {incr i} {
if {$i % 2} {
set c1 sql1
@@ -313,7 +311,7 @@ foreach {tn1 mmap1 mmap2} {
UPDATE t2 SET x = (SELECT md5sum(a) FROM t1);
}
set res [$c2 {
set res [$c2 {
SELECT count(*) FROM t1;
SELECT x == (SELECT md5sum(a) FROM t1) FROM t2;
PRAGMA integrity_check;
-20
View File
@@ -95,25 +95,5 @@ do_execsql_test printf2-2.3 {
SELECT printf('%s=(%d/%g/%s)',a) FROM t1 ORDER BY a;
} {-1=(0/0/) 1=(0/0/) 1.5=(0/0/) abc=(0/0/)}
# The precision of the %c conversion causes the character to repeat.
#
do_execsql_test printf2-3.1 {
SELECT printf('|%110.100c|','*');
} {{| ****************************************************************************************************|}}
do_execsql_test printf2-3.2 {
SELECT printf('|%-110.100c|','*');
} {{|**************************************************************************************************** |}}
do_execsql_test printf2-3.3 {
SELECT printf('|%9.8c|%-9.8c|','*','*');
} {{| ********|******** |}}
do_execsql_test printf2-3.4 {
SELECT printf('|%8.8c|%-8.8c|','*','*');
} {|********|********|}
do_execsql_test printf2-3.5 {
SELECT printf('|%7.8c|%-7.8c|','*','*');
} {|********|********|}
finish_test
+2 -2
View File
@@ -60,11 +60,11 @@ ifcapable conflict {
#
do_test rollback-1.5 {
sqlite3_step $STMT
} {SQLITE_ROW}
} {SQLITE_ERROR}
# Restart the SELECT statement
#
do_test rollback-1.6 { sqlite3_reset $STMT } {SQLITE_OK}
do_test rollback-1.6 { sqlite3_reset $STMT } {SQLITE_ABORT}
} else {
do_test rollback-1.6 { sqlite3_reset $STMT } {SQLITE_OK}
}
-157
View File
@@ -1,157 +0,0 @@
# 2014 November 12
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file containst tests to verify that ROLLBACK or ROLLBACK TO
# operations interact correctly with ongoing SELECT statements.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix rollback2
proc int2hex {i} { format %.2X $i }
db func int2hex int2hex
do_execsql_test 1.0 {
SELECT int2hex(0), int2hex(100), int2hex(255)
} {00 64 FF}
do_execsql_test 1.1 {
CREATE TABLE t1(i, h);
CREATE INDEX i1 ON t1(h);
WITH data(a, b) AS (
SELECT 1, int2hex(1)
UNION ALL
SELECT a+1, int2hex(a+1) FROM data WHERE a<40
)
INSERT INTO t1 SELECT * FROM data;
} {}
# do_rollback_test ID SWITCHES
#
# where SWITCHES are:
#
# -setup SQL script to open transaction and begin writing.
# -select SELECT to execute after -setup script
# -result Expected result of -select statement
# -rollback Use this SQL command ("ROLLBACK" or "ROLLBACK TO ...") to
# rollback the transaction in the middle of the -select statment
# execution.
#
proc do_rollback_test {tn args} {
set A(-setup) ""
set A(-select) ""
set A(-result) ""
set A(-rollback) ROLLBACK
array set O $args
foreach k [array names O] {
if {[info exists A($k)]==0} { error "unknown option: $k" }
set A($k) $O($k)
}
for {set iRollback 0} 1 {incr iRollback} {
catch { db eval ROLLBACK }
set res [list]
db eval $A(-setup)
set i 0
db eval $A(-select) x {
if {$i==$iRollback} { db eval $A(-rollback) }
foreach k $x(*) { lappend res $x($k) }
incr i
}
do_test $tn.$iRollback [list set {} $res] [list {*}$A(-result)]
if {$i < $iRollback} break
}
}
do_rollback_test 2.1 -setup {
BEGIN;
DELETE FROM t1 WHERE (i%2)==1;
} -select {
SELECT i FROM t1 WHERE (i%2)==0
} -result {
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40
}
do_rollback_test 2.2 -setup {
BEGIN;
DELETE FROM t1 WHERE (i%4)==1;
SAVEPOINT one;
DELETE FROM t1 WHERE (i%2)==1;
} -rollback {
ROLLBACK TO one;
} -select {
SELECT i FROM t1 WHERE (i%2)==0
} -result {
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40
}
#--------------------------------------------------------------------
# Try with some index scans
#
do_eqp_test 3.1 {
SELECT i FROM t1 WHERE (i%2)==0 ORDER BY h DESC;
} {0 0 0 {SCAN TABLE t1 USING INDEX i1}}
do_rollback_test 3.2 -setup {
BEGIN;
DELETE FROM t1 WHERE (i%2)==1;
} -select {
SELECT i FROM t1 WHERE (i%2)==0 ORDER BY h DESC;
} -result {
40 38 36 34 32 30 28 26 24 22 20 18 16 14 12 10 8 6 4 2
}
do_rollback_test 3.3 -setup {
BEGIN;
DELETE FROM t1 WHERE (i%4)==1;
SAVEPOINT one;
DELETE FROM t1 WHERE (i%2)==1;
} -rollback {
ROLLBACK TO one;
} -select {
SELECT i FROM t1 WHERE (i%2)==0 ORDER BY h DESC;
} -result {
40 38 36 34 32 30 28 26 24 22 20 18 16 14 12 10 8 6 4 2
}
#--------------------------------------------------------------------
# Now with some index scans that feature overflow keys.
#
set leader [string repeat "abcdefghij" 70]
do_execsql_test 4.1 { UPDATE t1 SET h = $leader || h; }
do_eqp_test 4.2 {
SELECT i FROM t1 WHERE (i%2)==0 ORDER BY h ASC;
} {0 0 0 {SCAN TABLE t1 USING INDEX i1}}
do_rollback_test 4.3 -setup {
BEGIN;
DELETE FROM t1 WHERE (i%2)==1;
} -select {
SELECT i FROM t1 WHERE (i%2)==0 ORDER BY h ASC;
} -result {
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40
}
do_rollback_test 4.4 -setup {
BEGIN;
DELETE FROM t1 WHERE (i%4)==1;
SAVEPOINT one;
DELETE FROM t1 WHERE (i%2)==1;
} -rollback {
ROLLBACK TO one;
} -select {
SELECT i FROM t1 WHERE (i%2)==0 ORDER BY h ASC;
} -result {
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40
}
finish_test
-84
View File
@@ -1,84 +0,0 @@
# 2014-11-12
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Test that errors encountered during a ROLLBACK operation correctly
# affect ongoing SQL statements.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
set testprefix rollbackfault
proc int2hex {i} { format %.2X $i }
db func int2hex int2hex
do_execsql_test 1.0 {
SELECT int2hex(0), int2hex(100), int2hex(255)
} {00 64 FF}
do_execsql_test 1.1 {
CREATE TABLE t1(i, h);
CREATE INDEX i1 ON t1(h);
WITH data(a, b) AS (
SELECT 1, int2hex(1)
UNION ALL
SELECT a+1, int2hex(a+1) FROM data WHERE a<40
)
INSERT INTO t1 SELECT * FROM data;
} {}
foreach f {oom ioerr} {
do_faultsim_test 1.2 -faults $f* -prep {
set sql1 { SELECT i FROM t1 WHERE (i%2)==0 }
set sql2 { SELECT i FROM t1 WHERE (i%2)==0 ORDER BY h }
set ::s1 [sqlite3_prepare db $sql1 -1 dummy]
set ::s2 [sqlite3_prepare db $sql2 -1 dummy]
for {set i 0} {$i < 10} {incr i} { sqlite3_step $::s1 }
for {set i 0} {$i < 3} {incr i} { sqlite3_step $::s2 }
execsql {
BEGIN; DELETE FROM t1 WHERE (i%2)
}
} -body {
execsql { ROLLBACK }
} -test {
set res1 [list]
set res2 [list]
while {"SQLITE_ROW" == [sqlite3_step $::s1]} {
lappend res1 [sqlite3_column_text $::s1 0]
}
while {"SQLITE_ROW" == [sqlite3_step $::s2]} {
lappend res2 [sqlite3_column_text $::s2 0]
}
set rc1 [sqlite3_finalize $::s1]
set rc2 [sqlite3_finalize $::s2]
catchsql { ROLLBACK }
if {$rc1=="SQLITE_OK" && $rc2=="SQLITE_OK"
&& $res1=="22 24 26 28 30 32 34 36 38 40"
&& $res2=="8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40"
} {
# This is Ok.
} elseif {$rc1!="SQLITE_OK" && $rc2!="SQLITE_OK" && $res1=="" &&$res2==""} {
# Also Ok.
} else {
error "statements don't look right"
}
}
}
finish_test
+1 -1
View File
@@ -315,7 +315,7 @@ ifcapable incrblob {
do_test savepoint-5.3.2.3 {
set rc [catch {seek $fd 0; read $fd} res]
set rc
} {0}
} {1}
do_test savepoint-5.3.3 {
catchsql {RELEASE def}
} {0 {}}
+2 -4
View File
@@ -30,7 +30,6 @@ do_test savepoint7-1.1 {
db eval {SELECT * FROM t1} {
db eval {
SAVEPOINT x2;
CREATE TABLE IF NOT EXISTS t3(xyz);
INSERT INTO t2 VALUES($a,$b,$c);
RELEASE x2;
}
@@ -47,7 +46,7 @@ do_test savepoint7-1.2 {
RELEASE x2;
}
}
db eval {SELECT * FROM t2;}
db eval {SELECT * FROM t2}
} {1 2 3 4 5 6 7 8 9}
do_test savepoint7-1.3 {
@@ -66,7 +65,7 @@ do_test savepoint7-1.3 {
# queries in outer contexts.
#
do_test savepoint7-2.1 {
db eval {DELETE FROM t2; SAVEPOINT x1; CREATE TABLE t4(abc);}
db eval {DELETE FROM t2; SAVEPOINT x1;}
set rc [catch {
db eval {SELECT * FROM t1} {
db eval {
@@ -86,7 +85,6 @@ do_test savepoint7-2.2 {
db eval {SELECT * FROM t1} {
db eval {
SAVEPOINT x2;
CREATE TABLE t5(pqr);
INSERT INTO t2 VALUES($a,$b,$c);
ROLLBACK TO x2;
}
-398
View File
@@ -1,398 +0,0 @@
# 2014 November 1
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix scanstatus
ifcapable !scanstatus {
finish_test
return
}
do_execsql_test 1.0 {
CREATE TABLE t1(a, b);
CREATE TABLE t2(x, y);
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t1 VALUES(3, 4);
INSERT INTO t2 VALUES('a', 'b');
INSERT INTO t2 VALUES('c', 'd');
INSERT INTO t2 VALUES('e', 'f');
}
proc do_scanstatus_test {tn res} {
set stmt [db_last_stmt_ptr db]
set idx 0
set ret [list]
while {1} {
set r [sqlite3_stmt_scanstatus $stmt $idx]
if {[llength $r]==0} break
lappend ret {*}$r
incr idx
}
uplevel [list do_test $tn [list set {} $ret] [list {*}$res]]
}
do_execsql_test 1.1 { SELECT count(*) FROM t1, t2; } 6
do_scanstatus_test 1.2 {
nLoop 1 nVisit 2 nEst 1048576.0 zName t1 zExplain {SCAN TABLE t1}
nLoop 2 nVisit 6 nEst 1048576.0 zName t2 zExplain {SCAN TABLE t2}
}
do_execsql_test 1.3 {
ANALYZE;
SELECT count(*) FROM t1, t2;
} 6
do_scanstatus_test 1.4 {
nLoop 1 nVisit 2 nEst 2.0 zName t1 zExplain {SCAN TABLE t1}
nLoop 2 nVisit 6 nEst 3.0 zName t2 zExplain {SCAN TABLE t2}
}
do_execsql_test 1.5 { ANALYZE }
do_execsql_test 1.6 {
SELECT count(*) FROM t1, t2 WHERE t2.rowid>1;
} 4
do_scanstatus_test 1.7 {
nLoop 1 nVisit 2 nEst 2.0 zName t2 zExplain
{SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid>?)}
nLoop 2 nVisit 4 nEst 2.0 zName t1 zExplain {SCAN TABLE t1}
}
do_execsql_test 1.8 {
SELECT count(*) FROM t1, t2 WHERE t2.rowid>1;
} 4
do_scanstatus_test 1.9 {
nLoop 2 nVisit 4 nEst 2.0 zName t2 zExplain
{SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid>?)}
nLoop 4 nVisit 8 nEst 2.0 zName t1 zExplain {SCAN TABLE t1}
}
do_test 1.9 {
sqlite3_stmt_scanstatus_reset [db_last_stmt_ptr db]
} {}
do_scanstatus_test 1.10 {
nLoop 0 nVisit 0 nEst 2.0 zName t2 zExplain
{SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid>?)}
nLoop 0 nVisit 0 nEst 2.0 zName t1 zExplain {SCAN TABLE t1}
}
#-------------------------------------------------------------------------
# Try a few different types of scans.
#
reset_db
do_execsql_test 2.1 {
CREATE TABLE x1(i INTEGER PRIMARY KEY, j);
INSERT INTO x1 VALUES(1, 'one');
INSERT INTO x1 VALUES(2, 'two');
INSERT INTO x1 VALUES(3, 'three');
INSERT INTO x1 VALUES(4, 'four');
CREATE INDEX x1j ON x1(j);
SELECT * FROM x1 WHERE i=2;
} {2 two}
do_scanstatus_test 2.2 {
nLoop 1 nVisit 1 nEst 1.0 zName x1
zExplain {SEARCH TABLE x1 USING INTEGER PRIMARY KEY (rowid=?)}
}
do_execsql_test 2.3.1 {
SELECT * FROM x1 WHERE j='two'
} {2 two}
do_scanstatus_test 2.3.2 {
nLoop 1 nVisit 1 nEst 10.0 zName x1j
zExplain {SEARCH TABLE x1 USING COVERING INDEX x1j (j=?)}
}
do_execsql_test 2.4.1 {
SELECT * FROM x1 WHERE j<'two'
} {4 four 1 one 3 three}
do_scanstatus_test 2.4.2 {
nLoop 1 nVisit 3 nEst 262144.0 zName x1j
zExplain {SEARCH TABLE x1 USING COVERING INDEX x1j (j<?)}
}
do_execsql_test 2.5.1 {
SELECT * FROM x1 WHERE j>='two'
} {2 two}
do_scanstatus_test 2.5.2 {
nLoop 1 nVisit 1 nEst 262144.0 zName x1j
zExplain {SEARCH TABLE x1 USING COVERING INDEX x1j (j>?)}
}
do_execsql_test 2.6.1 {
SELECT * FROM x1 WHERE j BETWEEN 'three' AND 'two'
} {3 three 2 two}
do_scanstatus_test 2.6.2 {
nLoop 1 nVisit 2 nEst 16384.0 zName x1j
zExplain {SEARCH TABLE x1 USING COVERING INDEX x1j (j>? AND j<?)}
}
do_execsql_test 2.7.1 {
CREATE TABLE x2(i INTEGER, j, k);
INSERT INTO x2 SELECT i, j, i || ' ' || j FROM x1;
CREATE INDEX x2j ON x2(j);
CREATE INDEX x2ij ON x2(i, j);
SELECT * FROM x2 WHERE j BETWEEN 'three' AND 'two'
} {3 three {3 three} 2 two {2 two}}
do_scanstatus_test 2.7.2 {
nLoop 1 nVisit 2 nEst 16384.0 zName x2j
zExplain {SEARCH TABLE x2 USING INDEX x2j (j>? AND j<?)}
}
do_execsql_test 2.8.1 {
SELECT * FROM x2 WHERE i=1 AND j='two'
}
do_scanstatus_test 2.8.2 {
nLoop 1 nVisit 0 nEst 8.0 zName x2ij
zExplain {SEARCH TABLE x2 USING INDEX x2ij (i=? AND j=?)}
}
do_execsql_test 2.9.1 {
SELECT * FROM x2 WHERE i=5 AND j='two'
}
do_scanstatus_test 2.9.2 {
nLoop 1 nVisit 0 nEst 8.0 zName x2ij
zExplain {SEARCH TABLE x2 USING INDEX x2ij (i=? AND j=?)}
}
do_execsql_test 2.10.1 {
SELECT * FROM x2 WHERE i=3 AND j='three'
} {3 three {3 three}}
do_scanstatus_test 2.10.2 {
nLoop 1 nVisit 1 nEst 8.0 zName x2ij
zExplain {SEARCH TABLE x2 USING INDEX x2ij (i=? AND j=?)}
}
#-------------------------------------------------------------------------
# Try with queries that use the OR optimization.
#
do_execsql_test 3.1 {
CREATE TABLE a1(a, b, c, d);
CREATE INDEX a1a ON a1(a);
CREATE INDEX a1bc ON a1(b, c);
WITH d(x) AS (SELECT 1 UNION ALL SELECT x+1 AS n FROM d WHERE n<=100)
INSERT INTO a1 SELECT x, x, x, x FROM d;
}
do_execsql_test 3.2.1 {
SELECT d FROM a1 WHERE (a=4 OR b=13)
} {4 13}
do_scanstatus_test 3.2.2 {
nLoop 1 nVisit 1 nEst 10.0 zName a1a
zExplain {SEARCH TABLE a1 USING INDEX a1a (a=?)}
nLoop 1 nVisit 1 nEst 10.0 zName a1bc
zExplain {SEARCH TABLE a1 USING INDEX a1bc (b=?)}
}
do_execsql_test 3.2.1 {
SELECT count(*) FROM a1 WHERE (a BETWEEN 4 AND 12) OR (b BETWEEN 40 AND 60)
} {30}
do_scanstatus_test 3.2.2 {
nLoop 1 nVisit 9 nEst 16384.0 zName a1a
zExplain {SEARCH TABLE a1 USING INDEX a1a (a>? AND a<?)}
nLoop 1 nVisit 21 nEst 16384.0 zName a1bc
zExplain {SEARCH TABLE a1 USING INDEX a1bc (b>? AND b<?)}
}
do_execsql_test 3.3.1 {
SELECT count(*) FROM a1 AS x, a1 AS y
WHERE (x.a BETWEEN 4 AND 12) AND (y.b BETWEEN 1 AND 10)
} {90}
do_scanstatus_test 3.2.2 {
nLoop 1 nVisit 10 nEst 16384.0 zName a1bc
zExplain {SEARCH TABLE a1 AS y USING COVERING INDEX a1bc (b>? AND b<?)}
nLoop 10 nVisit 90 nEst 16384.0 zName a1a
zExplain {SEARCH TABLE a1 AS x USING COVERING INDEX a1a (a>? AND a<?)}
}
do_execsql_test 3.4.1 {
SELECT count(*) FROM a1 WHERE a IN (1, 5, 10, 15);
} {4}
do_scanstatus_test 3.4.2 {
nLoop 1 nVisit 4 nEst 40.0 zName a1a
zExplain {SEARCH TABLE a1 USING COVERING INDEX a1a (a=?)}
}
do_execsql_test 3.4.1 {
SELECT count(*) FROM a1 WHERE rowid IN (1, 5, 10, 15);
} {4}
do_scanstatus_test 3.4.2 {
nLoop 1 nVisit 4 nEst 4.0 zName a1
zExplain {SEARCH TABLE a1 USING INTEGER PRIMARY KEY (rowid=?)}
}
#-------------------------------------------------------------------------
# Test that scanstatus() data is not available for searches performed
# by triggers.
#
# It is available for searches performed as part of FK processing, but
# not FK action processing.
#
do_execsql_test 4.0 {
CREATE TABLE t1(a, b, c);
CREATE TABLE t2(x PRIMARY KEY, y, z);
CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
SELECT * FROM t2 WHERE x BETWEEN 20 AND 40;
END;
WITH d(x) AS (SELECT 1 UNION ALL SELECT x+1 AS n FROM d WHERE n<=100)
INSERT INTO t2 SELECT x, x*2, x*3 FROM d;
}
do_execsql_test 4.1.1 { INSERT INTO t1 VALUES(1, 2, 3); }
do_scanstatus_test 4.1.2 { }
do_execsql_test 4.2 {
CREATE TABLE p1(x PRIMARY KEY);
INSERT INTO p1 VALUES(1), (2), (3), (4);
CREATE TABLE c1(y REFERENCES p1);
INSERT INTO c1 VALUES(1), (2), (3);
PRAGMA foreign_keys=on;
}
do_execsql_test 4.2.1 { DELETE FROM p1 WHERE x=4 }
do_scanstatus_test 4.2.2 {
nLoop 1 nVisit 1 nEst 1.0 zName sqlite_autoindex_p1_1
zExplain {SEARCH TABLE p1 USING INDEX sqlite_autoindex_p1_1 (x=?)}
nLoop 1 nVisit 3 nEst 524288.0 zName c1 zExplain {SCAN TABLE c1}
}
#-------------------------------------------------------------------------
# Further tests of different scan types.
#
reset_db
proc tochar {i} {
set alphabet {a b c d e f g h i j k l m n o p q r s t u v w x y z}
return [lindex $alphabet [expr $i % [llength $alphabet]]]
}
db func tochar tochar
do_execsql_test 5.0 {
CREATE TABLE t1(a PRIMARY KEY, b, c);
INSERT INTO t1 VALUES(0, 1, 'a');
INSERT INTO t1 VALUES(1, 0, 'b');
INSERT INTO t1 VALUES(2, 1, 'c');
INSERT INTO t1 VALUES(3, 0, 'd');
INSERT INTO t1 VALUES(4, 1, 'e');
INSERT INTO t1 VALUES(5, 0, 'a');
INSERT INTO t1 VALUES(6, 1, 'b');
INSERT INTO t1 VALUES(7, 0, 'c');
INSERT INTO t1 VALUES(8, 1, 'd');
INSERT INTO t1 VALUES(9, 0, 'e');
CREATE INDEX t1bc ON t1(b, c);
CREATE TABLE t2(x, y);
CREATE INDEX t2xy ON t2(x, y);
WITH data(i, x, y) AS (
SELECT 0, 0, tochar(0)
UNION ALL
SELECT i+1, (i+1)%2, tochar(i+1) FROM data WHERE i<500
) INSERT INTO t2 SELECT x, y FROM data;
CREATE TABLE t3(x, y);
INSERT INTO t3 SELECT * FROM t2;
ANALYZE;
}
do_execsql_test 5.1.1 {
SELECT count(*) FROM t1 WHERE a IN (SELECT b FROM t1 AS ii)
} {2}
do_scanstatus_test 5.1.2 {
nLoop 1 nVisit 10 nEst 10.0 zName t1bc
zExplain {SCAN TABLE t1 AS ii USING COVERING INDEX t1bc}
nLoop 1 nVisit 2 nEst 8.0 zName sqlite_autoindex_t1_1
zExplain {SEARCH TABLE t1 USING COVERING INDEX sqlite_autoindex_t1_1 (a=?)}
}
do_execsql_test 5.2.1 {
SELECT count(*) FROM t1 WHERE a IN (0, 1)
} {2}
do_scanstatus_test 5.2.2 {
nLoop 1 nVisit 2 nEst 2.0 zName sqlite_autoindex_t1_1
zExplain {SEARCH TABLE t1 USING COVERING INDEX sqlite_autoindex_t1_1 (a=?)}
}
do_eqp_test 5.3.1 {
SELECT count(*) FROM t2 WHERE y = 'j';
} {0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)}}
do_execsql_test 5.3.2 {
SELECT count(*) FROM t2 WHERE y = 'j';
} {19}
do_scanstatus_test 5.3.3 {
nLoop 1 nVisit 19 nEst 56.0 zName t2xy zExplain
{SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)}
}
do_eqp_test 5.4.1 {
SELECT count(*) FROM t1, t2 WHERE y = c;
} {
0 0 0 {SCAN TABLE t1 USING COVERING INDEX t1bc}
0 1 1 {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)}
}
do_execsql_test 5.4.2 {
SELECT count(*) FROM t1, t2 WHERE y = c;
} {200}
do_scanstatus_test 5.4.3 {
nLoop 1 nVisit 10 nEst 10.0 zName t1bc
zExplain {SCAN TABLE t1 USING COVERING INDEX t1bc}
nLoop 10 nVisit 200 nEst 56.0 zName t2xy
zExplain {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)}
}
do_eqp_test 5.5.1 {
SELECT count(*) FROM t1, t3 WHERE y = c;
} {
0 0 1 {SCAN TABLE t3}
0 1 0 {SEARCH TABLE t1 USING AUTOMATIC COVERING INDEX (c=?)}
}
do_execsql_test 5.5.2 {
SELECT count(*) FROM t1, t3 WHERE y = c;
} {200}
do_scanstatus_test 5.5.3 {
nLoop 1 nVisit 501 nEst 480.0 zName t3 zExplain {SCAN TABLE t3}
nLoop 501 nVisit 200 nEst 20.0 zName auto-index zExplain
{SEARCH TABLE t1 USING AUTOMATIC COVERING INDEX (c=?)}
}
#-------------------------------------------------------------------------
# Virtual table scans
#
ifcapable fts3 {
do_execsql_test 6.0 {
CREATE VIRTUAL TABLE ft1 USING fts4;
INSERT INTO ft1 VALUES('a d c f g h e i f c');
INSERT INTO ft1 VALUES('g c h b g b f f f g');
INSERT INTO ft1 VALUES('h h c c h f a e d d');
INSERT INTO ft1 VALUES('e j i j i e b c f g');
INSERT INTO ft1 VALUES('g f b g j c h a d f');
INSERT INTO ft1 VALUES('j i a e g f a i a c');
INSERT INTO ft1 VALUES('f d g g j j c a h g');
INSERT INTO ft1 VALUES('b d h a d j j j b i');
INSERT INTO ft1 VALUES('j e a b j e c b c i');
INSERT INTO ft1 VALUES('a d e f b j j c g d');
}
do_execsql_test 6.1.1 {
SELECT count(*) FROM ft1 WHERE ft1 MATCH 'd'
} {6}
do_scanstatus_test 6.1.2 {
nLoop 1 nVisit 6 nEst 24.0 zName ft1 zExplain
{SCAN TABLE ft1 VIRTUAL TABLE INDEX 3:}
}
}
finish_test
-19
View File
@@ -273,23 +273,4 @@ do_execsql_test skipscan1-6.3 {
EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=1;
} {~/ANY/}
# If the sqlite_stat1 entry includes the "noskipscan" token, then never use
# skipscan with that index.
#
do_execsql_test skipscan1-7.1 {
UPDATE sqlite_stat1 SET stat='500000 125000 1 sz=100';
ANALYZE sqlite_master;
EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=1;
} {/ANY/}
do_execsql_test skipscan1-7.2 {
UPDATE sqlite_stat1 SET stat='500000 125000 1 noskipscan sz=100';
ANALYZE sqlite_master;
EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=1;
} {~/ANY/}
do_execsql_test skipscan1-7.3 {
UPDATE sqlite_stat1 SET stat='500000 125000 1 sz=100 noskipscan';
ANALYZE sqlite_master;
EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=1;
} {~/ANY/}
finish_test
-55
View File
@@ -141,60 +141,5 @@ do_execsql_test 2.2 {
} {/INDEX good .bb=. AND aa=. AND dd>. AND dd<../}
# Create a table containing 100 rows. Column "a" contains a copy of the
# rowid value - sequentially increasing integers from 1 to 100. Column
# "b" contains the value of (a % 5). Columns "c" and "d" both contain
# constant values (i.e. the same for every row).
#
# Then create a second table t2. t2 is the same as t3 except for the
# order in which the indexes are created.
#
do_execsql_test 3.0 {
CREATE TABLE t3(a, b, c, d);
CREATE INDEX t3_ba ON t3(b, a, c);
CREATE INDEX t3_a ON t3(a);
WITH d(a, b) AS (
SELECT 1, 1
UNION ALL
SELECT a+1, (a+1) % 5 FROM d WHERE a<100
)
INSERT INTO t3 SELECT a, b, 'c', 'd' FROM d;
CREATE TABLE t2(a, b, c, d);
CREATE INDEX t2_a ON t2(a);
CREATE INDEX t2_ba ON t2(b, a, c);
INSERT INTO t2 SELECT * FROM t3;
ANALYZE;
SELECT * FROM sqlite_stat1;
} {
t2 t2_ba {100 20 1 1}
t2 t2_a {100 1}
t3 t3_a {100 1}
t3 t3_ba {100 20 1 1}
}
# Use index "t3_a", as (a=?) is expected to match only a single row.
#
do_eqp_test 3.1 {
SELECT * FROM t3 WHERE a = ? AND c = ?
} {
0 0 0 {SEARCH TABLE t3 USING INDEX t3_a (a=?)}
}
# The same query on table t2. This should use index "t2_a", for the
# same reason. At one point though, it was mistakenly using a skip-scan.
#
do_eqp_test 3.2 {
SELECT * FROM t2 WHERE a = ? AND c = ?
} {
0 0 0 {SEARCH TABLE t2 USING INDEX t2_a (a=?)}
}
finish_test
finish_test
+1
View File
@@ -62,6 +62,7 @@ foreach {tn script} {
do_execsql_test $tn.2.4 { PRAGMA integrity_check } {ok}
breakpoint
do_execsql_test $tn.3 {
PRAGMA cache_size = 5;
WITH r(x,y) AS (
+1 -17
View File
@@ -11,6 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this file is testing the CREATE TABLE statement.
#
# $Id: table.test,v 1.53 2009/06/05 17:09:12 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -772,21 +773,4 @@ do_catchsql_test table-16.7 {
INSERT INTO t16 DEFAULT VALUES;
} {1 {unknown function: group_concat()}}
# Ticket [https://www.sqlite.org/src/info/094d39a4c95ee4abbc417f04214617675ba15c63]
# describes a assertion fault that occurs on a CREATE TABLE .. AS SELECT statement.
# the following test verifies that the problem has been fixed.
#
do_execsql_test table-17.1 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a TEXT);
INSERT INTO t1(a) VALUES(1),(2);
DROP TABLE IF EXISTS t2;
CREATE TABLE t2(x TEXT, y TEXT);
INSERT INTO t2(x,y) VALUES(3,4);
DROP TABLE IF EXISTS t3;
CREATE TABLE t3 AS
SELECT a AS p, coalesce(y,a) AS q FROM t1 LEFT JOIN t2 ON a=x;
SELECT p, q, '|' FROM t3 ORDER BY p;
} {1 1 | 2 2 |}
finish_test
+1 -2
View File
@@ -40,7 +40,6 @@ db function force_rollback force_rollback
do_test tkt-f7772-1.2 {
catchsql {
BEGIN IMMEDIATE;
CREATE TABLE xyzzy(abc);
SELECT x, force_rollback(), EXISTS(SELECT 1 FROM t3 WHERE w=x) FROM t2;
}
} {1 {abort due to ROLLBACK}}
@@ -68,7 +67,7 @@ do_test tkt-f7772-2.2 {
catchsql {
SELECT x, force_rollback(), EXISTS(SELECT 1 FROM t3 WHERE w=x) FROM t2
}
} {1 {abort due to ROLLBACK}}
} {1 {callback requested query abort}}
do_test tkt-f7772-2.3 {
sqlite3_get_autocommit db
} {1}
+1 -1
View File
@@ -52,7 +52,7 @@ do_test trans3-1.4 {
db eval {SELECT * FROM t1}
} {1 2 3 4}
do_test trans3-1.5 {
db eval {BEGIN; CREATE TABLE xyzzy(abc);}
db eval BEGIN
db eval {INSERT INTO t1 VALUES(5);}
set ::ecode {}
set x [catch {
-33
View File
@@ -32,7 +32,6 @@ ifcapable {!trigger} {
finish_test
return
}
set ::testprefix trigger9
proc has_rowdata {sql} {
expr {[lsearch [execsql "explain $sql"] RowData]>=0}
@@ -221,36 +220,4 @@ ifcapable compound {
} {2}
}
reset_db
do_execsql_test 4.1 {
CREATE TABLE t1(a, b);
CREATE TABLE log(x);
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t1 VALUES(3, 4);
CREATE VIEW v1 AS SELECT a, b FROM t1;
CREATE TRIGGER tr1 INSTEAD OF DELETE ON v1 BEGIN
INSERT INTO log VALUES('delete');
END;
CREATE TRIGGER tr2 INSTEAD OF UPDATE ON v1 BEGIN
INSERT INTO log VALUES('update');
END;
CREATE TRIGGER tr3 INSTEAD OF INSERT ON v1 BEGIN
INSERT INTO log VALUES('insert');
END;
}
do_execsql_test 4.2 {
DELETE FROM v1 WHERE rowid=1;
} {}
do_execsql_test 4.3 {
UPDATE v1 SET a=b WHERE rowid=2;
} {}
finish_test
-14
View File
@@ -604,19 +604,5 @@ do_test update-14.4 {
} ;# ifcapable {trigger}
# Ticket [https://www.sqlite.org/src/tktview/43107840f1c02] on 2014-10-29
# An assertion fault on UPDATE
#
do_execsql_test update-15.1 {
CREATE TABLE t15(a INTEGER PRIMARY KEY, b);
INSERT INTO t15(a,b) VALUES(10,'abc'),(20,'def'),(30,'ghi');
ALTER TABLE t15 ADD COLUMN c;
CREATE INDEX t15c ON t15(c);
INSERT INTO t15(a,b)
VALUES(5,'zyx'),(15,'wvu'),(25,'tsr'),(35,'qpo');
UPDATE t15 SET c=printf("y%d",a) WHERE c IS NULL;
SELECT a,b,c,'|' FROM t15 ORDER BY a;
} {5 zyx y5 | 10 abc y10 | 15 wvu y15 | 20 def y20 | 25 tsr y25 | 30 ghi y30 | 35 qpo y35 |}
finish_test
+2 -1
View File
@@ -185,7 +185,8 @@ do_execsql_test without_rowid5-5.9 {
# EVIDENCE-OF: R-12643-30541 The incremental blob I/O mechanism does not
# work for WITHOUT ROWID tables.
#
# EVIDENCE-OF: R-40134-30296 Table zTable is a WITHOUT ROWID table
# EVIDENCE-OF: R-25760-33257 The sqlite3_blob_open() interface will fail
# for a WITHOUT ROWID table.
#
do_execsql_test without_rowid5-6.1 {
CREATE TABLE b1(a INTEGER PRIMARY KEY, b BLOB) WITHOUT ROWID;
+4 -5
View File
@@ -39,7 +39,6 @@ int main(int argc, char **argv){
int nSample;
i64 iVal;
const char *zSep;
int iRow = 0;
if( argc!=2 ){
fprintf(stderr, "Usage: %s DATABASE-FILE\n", argv[0]);
@@ -61,13 +60,13 @@ int main(int argc, char **argv){
}
while( SQLITE_ROW==sqlite3_step(pStmt) ){
if( zIdx==0 || strcmp(zIdx, (const char*)sqlite3_column_text(pStmt,0))!=0 ){
if( zIdx ) printf("\n**************************************"
"**************\n\n");
if( zIdx ) printf("\n");
sqlite3_free(zIdx);
zIdx = sqlite3_mprintf("%s", sqlite3_column_text(pStmt,0));
iRow = 0;
printf("%s:\n", zIdx);
}else{
printf(" -----------------------------------------------------------\n");
}
printf("%s sample %d ------------------------------------\n", zIdx, ++iRow);
printf(" nEq = %s\n", sqlite3_column_text(pStmt,1));
printf(" nLt = %s\n", sqlite3_column_text(pStmt,2));
printf(" nDLt = %s\n", sqlite3_column_text(pStmt,3));
-123
View File
@@ -1,123 +0,0 @@
/*
** A utility program to translate SQLite varints into decimal and decimal
** integers into varints.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 i64;
typedef unsigned __int64 u64;
#else
typedef long long int i64;
typedef unsigned long long int u64;
#endif
static int hexValue(char c){
if( c>='0' && c<='9' ) return c - '0';
if( c>='a' && c<='f' ) return c - 'a' + 10;
if( c>='A' && c<='F' ) return c - 'A' + 10;
return -1;
}
static char toHex(unsigned char c){
return "0123456789abcdef"[c&0xf];
}
static int putVarint(unsigned char *p, u64 v){
int i, j, n;
unsigned char buf[10];
if( v & (((u64)0xff000000)<<32) ){
p[8] = (unsigned char)v;
v >>= 8;
for(i=7; i>=0; i--){
p[i] = (unsigned char)((v & 0x7f) | 0x80);
v >>= 7;
}
return 9;
}
n = 0;
do{
buf[n++] = (unsigned char)((v & 0x7f) | 0x80);
v >>= 7;
}while( v!=0 );
buf[0] &= 0x7f;
for(i=0, j=n-1; j>=0; j--, i++){
p[i] = buf[j];
}
return n;
}
int main(int argc, char **argv){
int i;
u64 x;
u64 uX = 0;
i64 iX;
int n;
unsigned char zHex[20];
if( argc==1 ){
fprintf(stderr,
"Usage:\n"
" %s HH HH HH ... Convert varint to decimal\n"
" %s DDDDD Convert decimal to varint\n"
" Add '+' or '-' before DDDDD to disambiguate.\n",
argv[0], argv[0]);
exit(1);
}
if( argc>2
|| (strlen(argv[1])==2 && hexValue(argv[1][0])>=0 && hexValue(argv[1][1])>=0)
){
/* Hex to decimal */
for(i=1; i<argc && i<9; i++){
if( strlen(argv[i])!=2 ){
fprintf(stderr, "Not a hex byte: %s\n", argv[i]);
exit(1);
}
x = (hexValue(argv[i][0])<<4) + hexValue(argv[i][1]);
uX = (uX<<7) + (x&0x7f);
if( (x&0x80)==0 ) break;
}
if( i==9 && i<argc ){
if( strlen(argv[i])!=2 ){
fprintf(stderr, "Not a hex byte: %s\n", argv[i]);
exit(1);
}
x = (hexValue(argv[i][0])<<4) + hexValue(argv[i][1]);
uX = (uX<<8) + x;
}
i++;
if( i<argc ){
fprintf(stderr, "Extra arguments: %s...\n", argv[i]);
exit(1);
}
}else{
char *z = argv[1];
int sign = 1;
if( z[0]=='+' ) z++;
else if( z[0]=='-' ){ z++; sign = -1; }
uX = 0;
while( z[0] ){
if( z[0]<'0' || z[0]>'9' ){
fprintf(stderr, "Not a decimal number: %s", argv[1]);
exit(1);
}
uX = uX*10 + z[0] - '0';
z++;
}
if( sign<0 ){
memcpy(&iX, &uX, 8);
iX = -iX;
memcpy(&uX, &iX, 8);
}
}
n = putVarint(zHex, uX);
printf("%lld =", (i64)uX);
for(i=0; i<n; i++){
printf(" %c%c", toHex(zHex[i]>>4), toHex(zHex[i]&0x0f));
}
printf("\n");
return 0;
}