Compare commits

..

1 Commits

Author SHA1 Message Date
drh 68edfafdc6 Draw the TreeView debugging graphs using unicode box-drawing characters.
FossilOrigin-Name: 0efc6859d104e1b12ec4bce5bb6db4e91f0837b5
2014-09-30 21:24:28 +00:00
143 changed files with 1895 additions and 8329 deletions
-2
View File
@@ -359,7 +359,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 \
@@ -395,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 \
-2
View File
@@ -828,7 +828,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 \
@@ -864,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'`\\"
+1 -2
View File
@@ -3116,7 +3116,6 @@ static int fts3FilterMethod(
/* In case the cursor has been used before, clear it now. */
sqlite3_finalize(pCsr->pStmt);
sqlite3_free(pCsr->aDoclist);
sqlite3_free(pCsr->aMatchinfo);
sqlite3Fts3ExprFree(pCsr->pExpr);
memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
@@ -4427,7 +4426,7 @@ static int fts3EvalIncrPhraseNext(
bMaxSet = 1;
}
}
assert( rc!=SQLITE_OK || (p->nToken>=1 && a[p->nToken-1].bIgnore==0) );
assert( rc!=SQLITE_OK || a[p->nToken-1].bIgnore==0 );
assert( rc!=SQLITE_OK || bMaxSet );
/* Keep advancing iterators until they all point to the same document */
+1 -1
View File
@@ -190,7 +190,7 @@ static int getNextToken(
/* Set variable i to the maximum number of bytes of input to tokenize. */
for(i=0; i<n; i++){
if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break;
if( z[i]=='"' ) break;
if( z[i]=='*' || z[i]=='"' ) break;
}
*pnConsumed = i;
+1 -1
View File
@@ -183,7 +183,7 @@ static int isVowel(const char *z){
** by a consonant.
**
** In this routine z[] is in reverse order. So we are really looking
** for an instance of a consonant followed by a vowel.
** for an instance of of a consonant followed by a vowel.
*/
static int m_gt_0(const char *z){
while( isVowel(z) ){ z++; }
-122
View File
@@ -1,122 +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 */
sqlite3_int64 nAlloc; /* Number of bytes allocated for z[] */
sqlite3_int64 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( (sqlite3_int64)sz+p->nUsed+p->szSep+1 > p->nAlloc ){
char *zNew;
p->nAlloc = p->nAlloc*2 + sz + p->szSep + 1;
/* Using sqlite3_realloc64() would be better, but it is a recent
** addition and will cause a segfault if loaded by an older version
** of SQLite. */
zNew = p->nAlloc<=0x7fffffff ? sqlite3_realloc(p->z, (int)p->nAlloc) : 0;
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, (int)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 \
+125 -149
View File
@@ -1,12 +1,12 @@
C Add\scode\sto\scheck\sthe\svalidity\sof\sCollSeq\sobjects\sduring\sruntime.\s\sThis\scode\nwas\snot\sable\sto\sdetect\sanomalies\ssuch\sas\scame\sup\sas\sa\sresult\sof\nticket\s[e4a18565a36884b00edf66541f38c693827968ab]\sso\sit\sis\sput\sinto\sa\sbranch\nfor\shistorical\sreference,\swith\sthe\sintent\sof\sleaving\sit\sout\sof\strunk.
D 2014-12-05T14:36:15.903
C Draw\sthe\sTreeView\sdebugging\sgraphs\susing\sunicode\sbox-drawing\scharacters.
D 2014-09-30T21:24:28.680
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 6c4f961fa91d0b4fa121946a19f9e5eac2f2f809
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc 10720782f88648bf2b5dcedf4c1524b067d43e47
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
@@ -78,15 +78,15 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c 8b6cceb3e0be22da26d83a3cec0e0e337e6b8ec6
F ext/fts3/fts3.c 2f5e925bdb9d6d3e488c5a981af60cad4f9cdfe7
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h 53d4eca1fb23eab00681fb028fb82eb5705c1e21
F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365
F ext/fts3/fts3_expr.c 40123785eaa3ebd4c45c9b23407cc44ac0c49905
F ext/fts3/fts3_expr.c 351395fad6fcb16ecfc61db0861008a70101330c
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5
F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
F ext/fts3/fts3_porter.c 7f8b4bf5af7c0f20f73b8e87e14fa9298f52e290
F ext/fts3/fts3_snippet.c 51beb5c1498176fd9caccaf1c75b55cb803a985a
F ext/fts3/fts3_term.c a521f75132f9a495bdca1bdd45949b3191c52763
F ext/fts3/fts3_test.c 8a3a78c4458b2d7c631fcf4b152a5cd656fa7038
@@ -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 f971962e92ebb8b0a4e6b62949463ee454d88fa2
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 f7d774356ba5a14e7ad4fb637681af16875ad88f
F src/analyze.c 6290a109be876daaa242cd7216f97240f5401776
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 44b58cd798a32579816ce274e415de262df9843d
F src/btree.h e31a3a3ebdedb1caf9bda3ad5dbab3db9b780f6e
F src/btreeInt.h 3363e18fd76f69a27a870b25221b2345b3fd4d21
F src/build.c 67bb05b1077e0cdaccb2e36bfcbe7a5df9ed31e8
F src/callback.c 759c9aff944f72fd7fb810594d95af1092a8433a
F src/complete.c c4ba6e0626bb94bc77a0861735f3382fcf7cc818
F src/ctime.c df19848891c8a553c80e6f5a035e768280952d1a
F src/date.c 93594514aae68de117ca4a2a0d6cc63eddf26744
F src/delete.c 0750b1eb4d96cd3fb2c798599a3a7c85e92f1417
F src/expr.c 00da3072f362b06f39ce4052baa1d4ce2bb36d1c
F src/btree.c ede8348a7d623257ee6c06ca4796ceaee13b8657
F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8
F src/btreeInt.h 1bd7957161a1346a914f1f09231610e777a8e58d
F src/build.c bde83dd5cf812e310a7e5ad2846790a14745bef4
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
F src/complete.c 535183afb3c75628b78ce82612931ac7cdf26f14
F src/ctime.c bb434068b5308a857b181c2d204a320ff0d6c638
F src/date.c 57a7f9ba9f6b4d5268f5e411739066a611f99036
F src/delete.c fae81cc2eb14b75267d4f47d3cfc9ae02aae726f
F src/expr.c 46a8ca93361d09f2ec6d9b7d524751510569d737
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7
F src/func.c 6d3c4ebd72aa7923ce9b110a7dc15f9b8c548430
F src/global.c 6ded36dda9466fc1c9a3c5492ded81d79bf3977d
F src/func.c ba47c1671ab3cfdafa6e9d6ee490939ea578adee
F src/global.c 5110fa12e09729b84eee0191c984ec4008e21937
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 fa9f0e511a64caf66b8e7bb835c55172e7d61527
F src/malloc.c 740db54387204c9a2eb67c6d98e68b08e9ef4eab
F src/main.c 4a507a467cc20979579e4320ca6466b8ed0be268
F src/malloc.c 5bb99ee1e08ad58e457063cf79ce521db0e24195
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c faf615aafd8be74a71494dfa027c113ea5c6615f
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
F src/mem2.c dce31758da87ec2cfa52ba4c5df1aed6e07d8e8f
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 0a4042ef35f322e86fa01f6c8884c5e645b911e7
F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21
F src/pager.c 7a5c5bc0e29b9b16834f5558a9d5d22bbae59a08
F src/pager.h d1eee3c3f741be247ce6d82752a178515fc8578b
F src/parse.y 5dfead8aed90cb0c7c1115898ee2266804daff45
F src/pcache.c ace1b67632deeaa84859b4c16c27711dfb7db3d4
F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
F src/pcache1.c facbdd3ecc09c8f750089d941305694301328e98
F src/pragma.c d54cdd40b63d608f2d95b7482c710690e3593a73
F src/prepare.c b7b7bf020bd4c962f7c8aed5a3c542c7dfe9f9c7
F src/printf.c 9e75a6a0b55bf61cfff7d7e19d89834a1b938236
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c f6c46d3434439ab2084618d603e6d6dbeb0d6ada
F src/pager.c caab007743821d96752597c9cfd7351654697b06
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
F src/parse.y ce1494308578d2f10a68cd8debc9fc156dda1094
F src/pcache.c 4121a0571c18581ee9f82f086d5e2030051ebd6a
F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a
F src/pcache1.c dab8ab930d4a73b99768d881185994f34b80ecaa
F src/pragma.c 3f3e959390a10c0131676f0e307acce372777e0f
F src/prepare.c 6ef0cf2f9274982988ed6b7cab1be23147e94196
F src/printf.c ecbec6fce896305839ca1420ae09ef845dcb832d
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c a3466128b52a86c466e47ac1a19e2174f7b5cf89
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
F src/select.c f377fb8a5c73c10678ea74f3400f7913943e3d75
F src/shell.c 45d9c9bd7cde07845af957f2d849933b990773cf
F src/sqlite.h.in 6ec654324cb490ea3d8a7be28b8c7d37fe4ad282
F src/select.c f11533162b57ed5ed37f549add34cbcdf51f6712
F src/shell.c 38f627b0885191357f55902a3ac199de90d79715
F src/sqlite.h.in 159f2cb9eef74b6c99aeeb4c071e7745835f04f6
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
F src/sqliteInt.h ef42a0515a846ab2a670bda705be494d7acc2535
F src/sqliteInt.h 5a430c5443717d7c5e2c224f9dcc2534348dc3f6
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 81712116e826b0089bb221b018929536b2b5406f
F src/table.c f142bba7903e93ca8d113a5b8877a108ad1a27dc
F src/tclsqlite.c 0a874655dd39a9875e39c5d3c464db662171d228
F src/test1.c c24d7f67252348d756773a6dbe23a61b4552f709
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2e99ef7ef16187e17033d9398dc962ce22dab5cb
F src/tclsqlite.c c67d310c833046cccc192125d64ad422ab882684
F src/test1.c 523cd70ded28db71af9a30ec184cbe0957de9575
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 6f721f0337b96d58e81ff69bba101113c8168c2b
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 22dded4283dc4b25422f6444cdcb8d6b1ea0b5ff
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 1a9e671c9cfc259e4d2affc71f7df4a4c00a842c
F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3
F src/vdbeInt.h 9bb69ff2447c34b6ccc58b34ec35b615f86ead78
F src/vdbeapi.c 07acb615d1e4170e71fc1b0d087f3c53a1ad8e83
F src/vdbeaux.c 7e0a097ac7cf716300128f18147ef9af7c9d1130
F src/vdbeblob.c 4af4bfb71f6df7778397b4a0ebc1879793276778
F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f
F src/vdbesort.c 42c166f7ca78cb643c7f4e4bdfa83c59d363d1a6
F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8
F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a
F src/vdbe.c 93eeb6f9c3a3084133225a196f220454d71cca10
F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327
F src/vdbeInt.h 0b97a3190f8fbf460655985a9183019f5a702754
F src/vdbeapi.c e9e33b59834e3edc8790209765e069874c269d9d
F src/vdbeaux.c 5b687d7b5beaaa5b97189edf25cf08c311834933
F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4
F src/vdbemem.c 1e105dacf5190fc85a8ec2107c0dcc1884e75099
F src/vdbesort.c 5c1bacf90578d22b630fbf6ed98ccf60d83435ef
F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
F src/vtab.c c08ec66f45919eaa726bf88aa53eb08379d607f9
F src/wal.c 847692349eb6e1fb8543dbc97e69ddbfa4cc7ea7
F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f
F src/wal.c 10e7de7ce90865a68153f001a61f1d985cd17983
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
F src/where.c d67fe69dd1bb32ad3d488a8c5bc803a29814f357
F src/whereInt.h d3633e9b592103241b74b0ec76185f3e5b8b62e0
F src/where.c 2f42fe0d19303e0f5ce29aff3afbd3e43cbd6efb
F src/whereInt.h 124d970450955a6982e174b07c320ae6d62a595c
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7
@@ -323,13 +321,11 @@ 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
F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93
F test/analyzeD.test 08f9d0bee4e118a66fff3a32d02dbe0ee0a2b594
F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
@@ -346,17 +342,15 @@ F test/auth2.test 264c6af53cad9aba5218c68bbe18036e39007bfa
F test/auth3.test 5cfa94ed90c6617c42b7ba4b133fd79678b251c7
F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7
F test/autoindex1.test 6ff78b94f43a59616c06c11c55b12935173506d7
F test/autoindex2.test af7e595c6864cc6ef5fc38d5db579a3e34940cb8
F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972
F test/autoindex4.test fc807f9efd158bec60f5dfdf34ebe46fb274612d
F test/autoindex2.test 60d2fc6f38364308ce73a9beb01b47ded38697de
F test/autoindex3.test 8254f689c3241081fad52b7bea18ba53e07e14a2
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
@@ -366,7 +360,6 @@ F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
F test/bigsort.test 835478d0ce83bd1e5b05c90571dedd9871a09196
F test/bind.test 3c7b320969000c441a70952b0b15938fbb66237c
F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0
F test/bitvec.test 75894a880520164d73b1305c1c3f96882615e142
@@ -379,15 +372,14 @@ F test/boundary3.tcl 23361e108a125dca9c4080c2feb884fe54d69243
F test/boundary3.test 56ef82096b4329aca2be74fa1e2b0f762ea0eb45
F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983
F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b
F test/btree01.test e08b3613540145b353f20c81cb18ead54ff12e0f
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
@@ -426,8 +418,8 @@ 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/corruptI.test 221ad8b7f0a9ac6b80fc577e73b5ad8cdea31243
F test/corruptH.test 88ed71a086e13591c917aac6de32750e7c7281cb
F test/corruptI.test 0afbba50bfae006094cc548b4605f521c1179502
F test/cost.test 19d314526616ce4473eb4e4e450fcb94499ce318
F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
@@ -454,14 +446,9 @@ F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240
F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
F test/distinct.test 175d49ee783febaf368192dfe7f5afbc68910230
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_createtable.test 181653f6f45e3adde73f8686600ce5ad7515466b
F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a
F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412
F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306
@@ -473,11 +460,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_uri.test a2c92d80093a7efdcfbb11093651cbea87097b6b
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
@@ -489,7 +474,7 @@ F test/exclusive.test c7ebbc756eacf544c108b15eed64d7d4e5f86b75
F test/exclusive2.test 32798111aae78a5deec980eee383213f189df308
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30
F test/expr.test c4b9bf0cc60b26862475e19999fbd2609ca8259c
F test/expr.test 67c9fd6f8f829e239dc8b0f4a08a73c08b09196d
F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9
F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7
F test/filectrl.test 14fa712e42c4cb791e09dfd58a6a03efb47ef13a
@@ -500,7 +485,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
@@ -575,13 +560,13 @@ F test/fts3e.test 1f6c6ac9cc8b772ca256e6b22aaeed50c9350851
F test/fts3expr.test 3401d47b229c4504424caf362cc4ff704cad4162
F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a
F test/fts3expr3.test 9e91b8edbcb197bf2e92161aa7696446d96dce5f
F test/fts3expr4.test e1be1248566f43c252d4404d52914f1fc4bfa065
F test/fts3expr4.test 0713d94ab951ed88a8c3629a4889a48c55c4067c
F test/fts3fault.test cb72dccb0a3b9f730f16c5240f3fcb9303eb1660
F test/fts3fault2.test 3198eef2804deea7cac8403e771d9cbcb752d887
F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641
F test/fts3join.test 53e66a0c21eb568580674a43b21c059acb26f499
F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6
F test/fts3matchinfo.test 58544fa4d254000fa4e7f494b0a832f7ba61d45e
F test/fts3matchinfo.test ff423e73faab8fc6d7adeefedf74dd8e2b0b14e0
F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905
F test/fts3prefix.test b36d4f00b128a51e7b386cc013a874246d9d7dc1
F test/fts3prefix2.test e1f0a822ca661dced7f12ce392e14eaf65609dce
@@ -629,7 +614,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
@@ -644,7 +629,7 @@ F test/index.test 4d990005a67a36984e4f1a5f1bdccea8d08da4ee
F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
F test/index3.test 55a90cff99834305e8141df7afaef39674b57062
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
F test/index5.test 25b0b451aceed4ac5f7d49f856f6de7257470b3e
F test/index5.test fc07c14193c0430814e7a08b5da46888ee795c33
F test/index6.test fb370966ac3cd0989053dd5385757b5c3e24ab6a
F test/index7.test 917cf1e1c7439bb155abbeabec511b28945e157b
F test/indexedby.test b2f22f3e693a53813aa3f50b812eb609ba6df1ec
@@ -661,7 +646,7 @@ F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc
F test/intpkey.test 7506090fc08e028712a8bf47e5f54111947e3844
F test/io.test 3a7abcef18727cc0f2399e04b0e8903eccae50f8
F test/ioerr.test 2a24bd6ed5a8b062e64bfe1f6cf94fb25e92210d
F test/ioerr2.test 2593563599e2cc6b6b4fcf5878b177bdd5d8df26
F test/ioerr2.test 9d71166f8466eda510f1af6137bdabaa82b5408d
F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
@@ -670,7 +655,7 @@ F test/join.test 52d4d49f86d0cf46926672878c4eaf0da399104a
F test/join2.test f2171c265e57ee298a27e57e7051d22962f9f324
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
F test/join5.test 5df23eba184f159ed9705a954957e765a10c141d
F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe
F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
F test/journal1.test 69abc726c51b4a0409189f9a85191205297c0577
F test/journal2.test ae06f566c28552c313ded3fee79a6c69e6d049b1
@@ -690,7 +675,7 @@ F test/lock.test 87af515b0c4cf928576d0f89946d67d7c265dfb4
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00
F test/lock4.test e175ae13865bc87680607563bafba21f31a26f12
F test/lock5.test c6c5e0ebcb21c61a572870cc86c0cb9f14cede38
F test/lock5.test 5ad6a1f536036ff1be915cfdd41481aeafda3273
F test/lock6.test ad5b387a3a8096afd3c68a55b9535056431b0cf5
F test/lock7.test 49f1eaff1cdc491cc5dee3669f3c671d9f172431
F test/lock_common.tcl 0c270b121d40959fa2f3add382200c27045b3d95
@@ -705,7 +690,7 @@ F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a
F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d
F test/malloc9.test 2307c6ee3703b0a21391f3ea92388b4b73f9105e
F test/mallocA.test 672cd7dedb63771bade3a6f557f851a4ad161d4a
F test/mallocA.test c049224adeb0244b8f6eb770c1fa6ac40f9b3518
F test/mallocAll.test 98f1be74bc9f49a858bc4f361fc58e26486798be
F test/mallocB.test bc475ab850cda896142ab935bbfbc74c24e51ed6
F test/mallocC.test 3dffe16532f109293ce1ccecd0c31dca55ef08c4
@@ -736,9 +721,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 fc2754d38892f7dac30c22db3616c2764f117d66
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
@@ -765,7 +749,6 @@ F test/orderby5.test 8f08a54836d21fb7c70245360751aedd1c2286fb
F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859
F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
F test/ovfl.test 4f7ca651cba5c059a12d8c67dddd49bec5747799
F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
@@ -778,11 +761,11 @@ F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54
F test/permutations.test 4e12d43f4639ea8a0e366d9c64e0009afe2eb544
F test/pragma.test 49ac8a73c0daa574824538fed28727d1259fe735
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,23 +780,20 @@ F test/rdonly.test dd30a4858d8e0fbad2304c2bd74a33d4df36412a
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
F test/releasetest.mk 2eced2f9ae701fd0a29e714a241760503ccba25a
F test/releasetest.tcl a4279c890698584feb2ffc86735857a4e4474180
F test/releasetest.tcl a0df0dfc5e3ee83ade87b9cc96db41b52d590b9e
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 db3db281486c925095f305aad09fe806e5188ff3
F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285
F test/savepoint7.test fbf319a7b2dda089ec5be30a424a0e95f121d423
F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481
F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5
F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38
@@ -846,11 +826,10 @@ F test/shared7.test a81e99f83e6c51b02ac99c96fb3a2a7b5978c956
F test/shared8.test 00a07bf5e1337ecf72e94542bdefdc330d7a2538
F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21
F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506
F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
F test/shell1.test ab6025d941f9c84c5b83412c6b4d8b57f78dfa3a
F test/shell2.test 12b8bf901b0e3a8ac58cf5c0c63a0a388d4d1862
F test/shell1.test d60946b5fde4d85fe06db7331dfe89011f564350
F test/shell2.test c57da3a381c099b02c813ba156298d5c2f5c93a3
F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29
F test/shell4.test 8a9c08976291e6c6c808b4d718f4a8b299f339f5
F test/shell5.test 15a419cc1df21c892ed64f5596ae7a501f2816f2
@@ -858,15 +837,14 @@ 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/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24
F test/sort.test c4400e7533748f6bd7413851ff148645e82b9e2d
F test/sort2.test 84a92eebf697feee9c6697746918c7d67373eea1
F test/sort.test 15e1d3014abc3f6d4357ed81b93b82117aefd235
F test/sort2.test 269f4f50c6e468cc32b302ae7ff0add8338ec6de
F test/sort3.test 6178ade30810ac9166fcdf14b7065e49c0f534e2
F test/sort4.test 6c37d85f7cd28d50cce222fcab84ccd771e105cb
F test/sort5.test a448240a42b49239edc00f85d6d7ac7a1b261e1f
@@ -879,9 +857,9 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/speedtest1.c e4e2aa37ff66bad9f414a50a8cb9edfaac65c9e5
F test/speedtest1.c 83f6b3318f7ee60e52b978b5a5e5dd7e83dfb7ee
F test/spellfix.test 24f676831acddd2f4056a598fd731a72c6311f49
F test/sqllimits1.test 9014524e7ab16e2a4976b13397db4c29cc29c6d9
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
F test/subquery.test 666fdecceac258f5fd84bed09a64e49d9f37edd9
@@ -892,7 +870,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
@@ -952,7 +930,6 @@ F test/tkt-b1d3a2e531.test 8f7576e41ca179289ee1a8fee28386fd8e4b0550
F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0
F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3
F test/tkt-b75a9ca6b0.test 97cc2d5eeaf82799eb42138c0a1ff64370238ce4
F test/tkt-ba7cbfaedc.test e76d88e572e489ee0d64fe4caf4af18b3d1dc688
F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898
F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d
F test/tkt-c48d99d690.test ba61977d62ab612fc515b3c488a6fbd6464a2447
@@ -962,7 +939,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
@@ -1057,7 +1034,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
@@ -1067,7 +1044,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
@@ -1081,7 +1058,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
@@ -1092,7 +1069,7 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
F test/view.test f311691d696a5cc27e3c1b875cec1b0866b4ccd9
F test/vtab1.test 1cef14310144718812351a61c5cfb4ba8494a171
F test/vtab1.test b631d147b198cfd7903ab5fed028eb2a3d321dc6
F test/vtab2.test 7bcffc050da5c68f4f312e49e443063e2d391c0d
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275
@@ -1114,7 +1091,7 @@ F test/wal.test 885f32b2b390b30b4aa3dbb0e568f8f78d40f5cc
F test/wal2.test 1f841d2048080d32f552942e333fd99ce541dada
F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
F test/wal5.test 174cc1512e304a7dfa28ac30527e28ea02fc37df
F test/wal5.test 8f888b50f66b78821e61ed0e233ded5de378224b
F test/wal6.test 527581f5527bf9c24394991e2be83000aace5f9e
F test/wal64k.test 163655ecd2cb8afef4737cac2a40fdd2eeaf20b8
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
@@ -1155,7 +1132,7 @@ F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7
F test/whereG.test 69f5ec4b15760a8c860f80e2d55525669390aab3
F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
F test/whereI.test 1d89199697919d4930be05a71e7fe620f114e622
F test/whereJ.test 55a3221706a7ab706293f17cc8f96da563bf0767
F test/whereJ.test 63599653dfefe4e74ebb358db753417fe0aa8a49
F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c
@@ -1168,7 +1145,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
@@ -1203,7 +1180,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
@@ -1218,16 +1195,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-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891
F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 71f589e3f82a07513425e212072f32748c0732d4
R 02b8ea23886487ef9860b5ee40d238ab
T *branch * collseq-checking
T *sym-collseq-checking *
T -sym-fix-stale-keyinfo-cache *
P 5ce05757aac80b99c3b2141cd301809f8e28e661
R 762197ef191f38dcf6716ed39705f21d
T *branch * box-character-graph
T *sym-box-character-graph *
T -sym-trunk *
U drh
Z 74adfe1c6f95aa3cd0aa6e2d3a771e07
Z 6b87c74938e16927939c272619e5f8d2
+1 -1
View File
@@ -1 +1 @@
68b23c3d41ce9303f42251d0c199181312e148f9
0efc6859d104e1b12ec4bce5bb6db4e91f0837b5
+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
+34 -65
View File
@@ -1437,7 +1437,7 @@ static void decodeIntArray(
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( z==0 ) z = "";
#else
assert( z!=0 );
if( NEVER(z==0) ) z = "";
#endif
for(i=0; *z && i<nOut; i++){
v = 0;
@@ -1446,39 +1446,36 @@ static void decodeIntArray(
z++;
}
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( aOut ) aOut[i] = v;
if( aLog ) aLog[i] = sqlite3LogEst(v);
if( aOut ){
aOut[i] = v;
}else
#else
assert( aOut==0 );
UNUSED_PARAMETER(aOut);
assert( aLog!=0 );
aLog[i] = sqlite3LogEst(v);
#endif
{
aLog[i] = sqlite3LogEst(v);
}
if( *z==' ' ) z++;
}
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
assert( pIndex!=0 ); {
assert( pIndex!=0 );
#else
if( pIndex ){
if( pIndex )
#endif
pIndex->bUnordered = 0;
pIndex->noSkipScan = 0;
while( z[0] ){
if( sqlite3_strglob("unordered*", z)==0 ){
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 ){
pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
}
#endif
while( z[0]!=0 && z[0]!=' ' ) z++;
while( z[0]==' ' ) z++;
while( z[0] ){
if( sqlite3_strglob("unordered*", z)==0 ){
pIndex->bUnordered = 1;
}else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
}
#ifdef SQLITE_ENABLE_COSTMULT
else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
}
#endif
while( z[0]!=0 && z[0]!=' ' ) z++;
while( z[0]==' ' ) z++;
}
}
@@ -1519,17 +1516,8 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
z = argv[2];
if( pIndex ){
int nCol = pIndex->nKeyCol+1;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(
sizeof(tRowcnt) * nCol
);
if( aiRowEst==0 ) pInfo->db->mallocFailed = 1;
#else
tRowcnt * const aiRowEst = 0;
#endif
pIndex->bUnordered = 0;
decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex);
if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
}else{
Index fakeIdx;
@@ -1588,39 +1576,25 @@ static void initAvgEq(Index *pIdx){
pIdx->aAvgEq[nCol] = 1;
}
for(iCol=0; iCol<nCol; iCol++){
int nSample = pIdx->nSample;
int i; /* Used to iterate through samples */
tRowcnt sumEq = 0; /* Sum of the nEq values */
tRowcnt nSum = 0; /* Number of terms contributing to sumEq */
tRowcnt avgEq = 0;
tRowcnt nRow; /* Number of rows in index */
i64 nSum100 = 0; /* Number of terms contributing to sumEq */
i64 nDist100; /* Number of distinct values in index */
if( pIdx->aiRowEst==0 || pIdx->aiRowEst[iCol+1]==0 ){
nRow = pFinal->anLt[iCol];
nDist100 = (i64)100 * pFinal->anDLt[iCol];
nSample--;
}else{
nRow = pIdx->aiRowEst[0];
nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1];
}
pIdx->nRowEst0 = nRow;
tRowcnt nDLt = pFinal->anDLt[iCol];
/* Set nSum to the number of distinct (iCol+1) field prefixes that
** occur in the stat4 table for this index. Set sumEq to the sum of
** the nEq values for column iCol for the same set (adding the value
** only once where there exist duplicate prefixes). */
for(i=0; i<nSample; i++){
if( i==(pIdx->nSample-1)
|| aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol]
){
** occur in the stat4 table for this index before pFinal. Set
** sumEq to the sum of the nEq values for column iCol for the same
** set (adding the value only once where there exist duplicate
** prefixes). */
for(i=0; i<(pIdx->nSample-1); i++){
if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){
sumEq += aSample[i].anEq[iCol];
nSum100 += 100;
nSum++;
}
}
if( nDist100>nSum100 ){
avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100);
if( nDLt>nSum ){
avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum);
}
if( avgEq==0 ) avgEq = 1;
pIdx->aAvgEq[iCol] = avgEq;
@@ -1866,17 +1840,12 @@ 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);
db->lookaside.bEnabled = lookasideEnabled;
}
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
sqlite3_free(pIdx->aiRowEst);
pIdx->aiRowEst = 0;
}
#endif
if( rc==SQLITE_NOMEM ){
-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;
}
+393 -846
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*);
+3 -9
View File
@@ -436,7 +436,7 @@ struct BtShared {
BtLock *pLock; /* List of locks held on this shared-btree struct */
Btree *pWriter; /* Btree with currently open write transaction */
#endif
u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */
u8 *pTmpSpace; /* BtShared.pageSize bytes of space for tmp use */
};
/*
@@ -489,11 +489,6 @@ struct CellInfo {
**
** Fields in this structure are accessed under the BtShared.mutex
** found at self->pBt->mutex.
**
** skipNext meaning:
** eState==SKIPNEXT && skipNext>0: Next sqlite3BtreeNext() is no-op.
** eState==SKIPNEXT && skipNext<0: Next sqlite3BtreePrevious() is no-op.
** eState==FAULT: Cursor fault with skipNext as error code.
*/
struct BtCursor {
Btree *pBtree; /* The Btree to which this cursor belongs */
@@ -506,8 +501,7 @@ struct BtCursor {
void *pKey; /* Saved key that was cursor last known position */
Pgno pgnoRoot; /* The root page of this tree */
int nOvflAlloc; /* Allocated size of aOverflow[] array */
int skipNext; /* Prev() is noop if negative. Next() is noop if positive.
** Error code if eState==CURSOR_FAULT */
int skipNext; /* Prev() is noop if negative. Next() is noop if positive */
u8 curFlags; /* zero or more BTCF_* flags defined below */
u8 eState; /* One of the CURSOR_XXX constants (see below) */
u8 hints; /* As configured by CursorSetHints() */
@@ -553,7 +547,7 @@ struct BtCursor {
** on a different connection that shares the BtShared cache with this
** cursor. The error has left the cache in an inconsistent state.
** Do nothing else with this cursor. Any attempt to use the cursor
** should return the error code stored in BtCursor.skipNext
** should return the error code stored in BtCursor.skip
*/
#define CURSOR_INVALID 0
#define CURSOR_VALID 1
+2 -9
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
@@ -439,9 +435,6 @@ static void freeIndex(sqlite3 *db, Index *p){
sqlite3ExprDelete(db, p->pPartIdxWhere);
sqlite3DbFree(db, p->zColAff);
if( p->isResized ) sqlite3DbFree(db, p->azColl);
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3_free(p->aiRowEst);
#endif
sqlite3DbFree(db, p);
}
@@ -2751,7 +2744,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
}else{
addr2 = sqlite3VdbeCurrentAddr(v);
}
sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3ReleaseTempReg(pParse, regRecord);
+2 -30
View File
@@ -102,7 +102,7 @@ CollSeq *sqlite3GetCollSeq(
if( p && !p->xCmp && synthCollSeq(db, p) ){
p = 0;
}
assert( p==0 || (sqlite3ValidCollSeq(p) && p->xCmp!=0) );
assert( !p || p->xCmp );
if( p==0 ){
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
}
@@ -186,31 +186,6 @@ static CollSeq *findCollSeqEntry(
return pColl;
}
#ifdef SQLITE_DEBUG
/*
** The following routine does sanity checking on a CollSeq object and
** returns 1 if everything looks ok and 0 if the CollSeq object appears
** to be corrupt. This routine is used only inside of assert() statements.
*/
int sqlite3ValidCollSeq(const CollSeq *p){
/* The CollSeq must be one of a triple and the zName field must
** point to the first byte after that triple
*/
int n = (int)(p->zName - (char*)p)/sizeof(CollSeq);
if( n<=0 || n>3 ) return 0;
/* Check for valid enc values */
if( p->enc==SQLITE_UTF8 ) return 1;
if( p->enc==SQLITE_UTF16LE ) return 1;
if( p->enc==SQLITE_UTF16BE ) return 1;
if( p->enc==(SQLITE_UTF16LE|SQLITE_UTF16_ALIGNED) ) return 1;
if( p->enc==(SQLITE_UTF16BE|SQLITE_UTF16_ALIGNED) ) return 1;
/* Otherwise, malformed */
return 0;
}
#endif /* SQLITE_DEBUG */
/*
** Parameter zName points to a UTF-8 encoded string nName bytes long.
** Return the CollSeq* pointer for the collation sequence named zName
@@ -240,10 +215,7 @@ CollSeq *sqlite3FindCollSeq(
}
assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
if( pColl ){
pColl += enc-1;
assert( sqlite3ValidCollSeq(pColl) );
}
if( pColl ) pColl += enc-1;
return pColl;
}
-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.
-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
@@ -391,13 +388,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);
}
+35 -60
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);
}
/*
@@ -1414,8 +1393,7 @@ int sqlite3ExprCanBeNull(const Expr *p){
return 0;
case TK_COLUMN:
assert( p->pTab!=0 );
return ExprHasProperty(p, EP_CanBeNull) ||
(p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
return p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0;
default:
return 1;
}
@@ -1858,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);
@@ -3004,10 +2983,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
#ifndef SQLITE_OMIT_FLOATING_POINT
/* If the column has REAL affinity, it may currently be stored as an
** integer. Use OP_RealAffinity to make sure it is really real.
**
** EVIDENCE-OF: R-60985-57662 SQLite will convert the value back to
** floating point when extracting it from the record. */
** integer. Use OP_RealAffinity to make sure it is really real. */
if( pExpr->iColumn>=0
&& pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL
){
@@ -3363,7 +3339,6 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
case TK_LSHIFT: zBinOp = "LSHIFT"; break;
case TK_RSHIFT: zBinOp = "RSHIFT"; break;
case TK_CONCAT: zBinOp = "CONCAT"; break;
case TK_DOT: zBinOp = "DOT"; break;
case TK_UMINUS: zUniOp = "UMINUS"; break;
case TK_UPLUS: zUniOp = "UPLUS"; break;
+2 -2
View File
@@ -157,8 +157,8 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
default: {
/* Because sqlite3_value_double() returns 0.0 if the argument is not
** something that can be converted into a number, we have:
** IMP: R-01992-00519 Abs(X) returns 0.0 if X is a string or blob
** that cannot be converted to a numeric value.
** IMP: R-57326-31541 Abs(X) return 0.0 if X is a string or blob that
** cannot be converted to a numeric value.
*/
double rVal = sqlite3_value_double(argv[0]);
if( rVal<0 ) rVal = -rVal;
+2 -17
View File
@@ -129,25 +129,10 @@ const unsigned char sqlite3CtypeMap[256] = {
};
#endif
/* EVIDENCE-OF: R-02982-34736 In order to maintain full backwards
** compatibility for legacy applications, the URI filename capability is
** disabled by default.
**
** 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 +222,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;
+49 -302
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
@@ -522,25 +476,12 @@ int sqlite3_config(int op, ...){
break;
}
/* EVIDENCE-OF: R-55548-33817 The compile-time setting for URI filenames
** can be changed at start-time using the
** sqlite3_config(SQLITE_CONFIG_URI,1) or
** 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 +496,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 +593,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 +602,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++){
@@ -773,20 +691,13 @@ static int binCollFunc(
){
int rc, n;
n = nKey1<nKey2 ? nKey1 : nKey2;
/* EVIDENCE-OF: R-65033-28449 The built-in BINARY collation compares
** strings byte by byte using the memcmp() function from the standard C
** library. */
rc = memcmp(pKey1, pKey2, n);
if( rc==0 ){
if( padFlag
&& allSpaces(((char*)pKey1)+n, nKey1-n)
&& allSpaces(((char*)pKey2)+n, nKey2-n)
){
/* EVIDENCE-OF: R-31624-24737 RTRIM is like BINARY except that extra
** spaces at the end of either string do not change the result. In other
** words, strings will compare equal to one another as long as they
** differ only in the number of spaces at the end.
*/
/* Leave rc unchanged at 0 */
}else{
rc = nKey1 - nKey2;
}
@@ -821,12 +732,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;
}
@@ -834,12 +739,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;
}
@@ -847,12 +746,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;
}
@@ -1034,13 +927,7 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
if( pDb->pBt ){
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
if( j!=1 && pDb->pSchema ){
/* Must clear the KeyInfo cache. See ticket [e4a18565a36884b00edf] */
for(i=sqliteHashFirst(&pDb->pSchema->idxHash); i; i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
sqlite3KeyInfoUnref(pIdx->pKeyInfo);
pIdx->pKeyInfo = 0;
}
if( j!=1 ){
pDb->pSchema = 0;
}
}
@@ -1124,15 +1011,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();
@@ -1143,7 +1028,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;
@@ -1151,7 +1035,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
if( sqlite3BtreeIsInTrans(p) ){
inTrans = 1;
}
sqlite3BtreeRollback(p, tripCode, !schemaChange);
sqlite3BtreeRollback(p, tripCode);
}
}
sqlite3VtabRollback(db);
@@ -1407,9 +1291,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;
@@ -1431,12 +1312,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;
@@ -1457,9 +1332,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;
@@ -1473,12 +1345,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;
}
@@ -1616,12 +1482,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));
@@ -1658,10 +1518,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);
@@ -1693,12 +1549,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,
@@ -1720,13 +1570,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;
@@ -1748,13 +1591,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;
@@ -1775,13 +1611,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;
@@ -1800,13 +1629,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;
@@ -1825,13 +1647,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;
@@ -1878,9 +1693,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{
@@ -1901,12 +1713,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;
@@ -1934,21 +1740,14 @@ 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;
assert( SQLITE_CHECKPOINT_PASSIVE==0 );
assert( SQLITE_CHECKPOINT_FULL==1 );
assert( SQLITE_CHECKPOINT_RESTART==2 );
assert( SQLITE_CHECKPOINT_TRUNCATE==3 );
if( eMode<SQLITE_CHECKPOINT_PASSIVE || eMode>SQLITE_CHECKPOINT_TRUNCATE ){
/* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint
** mode: */
assert( SQLITE_CHECKPOINT_FULL>SQLITE_CHECKPOINT_PASSIVE );
assert( SQLITE_CHECKPOINT_FULL<SQLITE_CHECKPOINT_RESTART );
assert( SQLITE_CHECKPOINT_PASSIVE+2==SQLITE_CHECKPOINT_RESTART );
if( eMode<SQLITE_CHECKPOINT_PASSIVE || eMode>SQLITE_CHECKPOINT_RESTART ){
return SQLITE_MISUSE;
}
@@ -1976,9 +1775,7 @@ int sqlite3_wal_checkpoint_v2(
** checkpointed.
*/
int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
/* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to
** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */
return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0);
return sqlite3_wal_checkpoint_v2(db, zDb, SQLITE_CHECKPOINT_PASSIVE, 0, 0);
}
#ifndef SQLITE_OMIT_WAL
@@ -2339,12 +2136,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
@@ -2421,9 +2212,8 @@ int sqlite3ParseUri(
assert( *pzErrMsg==0 );
if( ((flags & SQLITE_OPEN_URI) /* IMP: R-48725-32206 */
|| sqlite3GlobalConfig.bOpenUri) /* IMP: R-51689-46548 */
&& nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */
if( ((flags & SQLITE_OPEN_URI) || sqlite3GlobalConfig.bOpenUri)
&& nUri>=5 && memcmp(zUri, "file:", 5)==0
){
char *zOpt;
int eState; /* Parser state when parsing URI */
@@ -2631,9 +2421,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();
@@ -2656,9 +2443,7 @@ static int openDatabase(
testcase( (1<<(flags&7))==0x02 ); /* READONLY */
testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
if( ((1<<(flags&7)) & 0x46)==0 ){
return SQLITE_MISUSE_BKPT; /* IMP: R-65497-44594 */
}
if( ((1<<(flags&7)) & 0x46)==0 ) return SQLITE_MISUSE_BKPT;
if( sqlite3GlobalConfig.bCoreMutex==0 ){
isThreadsafe = 0;
@@ -2748,24 +2533,20 @@ static int openDatabase(
/* Add the default collation sequence BINARY. BINARY works for both UTF-8
** and UTF-16, so add a version for each to avoid any unnecessary
** conversions. The only error that can occur here is a malloc() failure.
**
** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating
** functions:
*/
createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0);
createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0);
createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0);
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
if( db->mallocFailed ){
goto opendb_out;
}
/* EVIDENCE-OF: R-08308-17224 The default collating function for all
** strings is BINARY.
*/
db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
assert( db->pDfltColl!=0 );
/* Also add a UTF-8 case-insensitive collation sequence. */
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
/* Parse the filename/URI argument. */
db->openFlags = flags;
rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
@@ -2927,15 +2708,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);
@@ -2965,7 +2744,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;
}
/*
@@ -2980,10 +2765,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);
@@ -3005,10 +2786,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);
@@ -3031,9 +2808,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;
@@ -3052,9 +2826,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;
@@ -3081,12 +2852,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;
}
@@ -3269,9 +3034,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);
@@ -3285,9 +3047,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 ){
@@ -3630,7 +3389,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);
@@ -3686,12 +3445,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;
}
@@ -3701,12 +3454,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;
}
+25 -27
View File
@@ -310,7 +310,7 @@ void *sqlite3Malloc(u64 n){
}else{
p = sqlite3GlobalConfig.m.xMalloc((int)n);
}
assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-11148-40995 */
assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-04675-44850 */
return p;
}
@@ -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
@@ -448,27 +447,25 @@ static int isLookaside(sqlite3 *db, void *p){
*/
int sqlite3MallocSize(void *p){
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
return sqlite3GlobalConfig.m.xSize(p);
}
int sqlite3DbMallocSize(sqlite3 *db, void *p){
if( db==0 ){
assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
return sqlite3MallocSize(p);
}else{
assert( sqlite3_mutex_held(db->mutex) );
if( isLookaside(db, p) ){
return db->lookaside.sz;
}else{
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
return sqlite3GlobalConfig.m.xSize(p);
}
}
}
sqlite3_uint64 sqlite3_msize(void *p){
assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p);
}
@@ -477,8 +474,8 @@ sqlite3_uint64 sqlite3_msize(void *p){
*/
void sqlite3_free(void *p){
if( p==0 ) return; /* IMP: R-49053-54554 */
assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
assert( sqlite3MemdebugNoType(p, ~MEMTYPE_HEAP) );
if( sqlite3GlobalConfig.bMemstat ){
sqlite3_mutex_enter(mem0.mutex);
sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
@@ -522,8 +519,8 @@ void sqlite3DbFree(sqlite3 *db, void *p){
return;
}
}
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
sqlite3_free(p);
@@ -535,13 +532,11 @@ void sqlite3DbFree(sqlite3 *db, void *p){
void *sqlite3Realloc(void *pOld, u64 nBytes){
int nOld, nNew, nDiff;
void *pNew;
assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) );
if( pOld==0 ){
return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */
return sqlite3Malloc(nBytes); /* IMP: R-28354-25769 */
}
if( nBytes==0 ){
sqlite3_free(pOld); /* IMP: R-26507-47431 */
sqlite3_free(pOld); /* IMP: R-31593-10574 */
return 0;
}
if( nBytes>=0x7fffff00 ){
@@ -563,6 +558,8 @@ void *sqlite3Realloc(void *pOld, u64 nBytes){
mem0.alarmThreshold-nDiff ){
sqlite3MallocAlarm(nDiff);
}
assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) );
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
if( pNew==0 && mem0.alarmCallback ){
sqlite3MallocAlarm((int)nBytes);
@@ -576,7 +573,7 @@ void *sqlite3Realloc(void *pOld, u64 nBytes){
}else{
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
}
assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-11148-40995 */
assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-04675-44850 */
return pNew;
}
@@ -588,7 +585,7 @@ void *sqlite3_realloc(void *pOld, int n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
if( n<0 ) n = 0; /* IMP: R-26507-47431 */
if( n<0 ) n = 0;
return sqlite3Realloc(pOld, n);
}
void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){
@@ -675,8 +672,8 @@ void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){
if( !p && db ){
db->mallocFailed = 1;
}
sqlite3MemdebugSetType(p,
(db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP);
sqlite3MemdebugSetType(p, MEMTYPE_DB |
((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
return p;
}
@@ -702,14 +699,15 @@ void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){
sqlite3DbFree(db, p);
}
}else{
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( sqlite3MemdebugNoType(p, ~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
pNew = sqlite3_realloc64(p, n);
if( !pNew ){
sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP);
db->mallocFailed = 1;
}
sqlite3MemdebugSetType(pNew,
sqlite3MemdebugSetType(pNew, MEMTYPE_DB |
(db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
}
}
+2 -2
View File
@@ -394,7 +394,7 @@ void sqlite3MemdebugSetType(void *p, u8 eType){
** This routine is designed for use within an assert() statement, to
** verify the type of an allocation. For example:
**
** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
** assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
*/
int sqlite3MemdebugHasType(void *p, u8 eType){
int rc = 1;
@@ -416,7 +416,7 @@ int sqlite3MemdebugHasType(void *p, u8 eType){
** This routine is designed for use within an assert() statement, to
** verify the type of an allocation. For example:
**
** assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
** assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
*/
int sqlite3MemdebugNoType(void *p, u8 eType){
int rc = 1;
-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);
+11 -23
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 },
@@ -950,11 +943,7 @@ static struct win_syscall {
#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
DWORD))aSyscall[63].pCurrent)
#if !SQLITE_OS_WINCE
{ "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
#else
{ "WaitForSingleObjectEx", (SYSCALL)0, 0 },
#endif
#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
BOOL))aSyscall[64].pCurrent)
@@ -977,7 +966,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 +1030,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 },
@@ -1297,8 +1286,7 @@ void sqlite3_win32_sleep(DWORD milliseconds){
#endif
}
#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
SQLITE_THREADSAFE>0
#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
DWORD sqlite3Win32Wait(HANDLE hObject){
DWORD rc;
while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
+4 -28
View File
@@ -1941,14 +1941,6 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
rc = SQLITE_OK;
}else{
rc = sqlite3OsTruncate(pPager->jfd, 0);
if( rc==SQLITE_OK && pPager->fullSync ){
/* Make sure the new file size is written into the inode right away.
** Otherwise the journal might resurrect following a power loss and
** cause the last transaction to roll back. See
** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773
*/
rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
}
}
pPager->journalOff = 0;
}else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
@@ -2899,7 +2891,7 @@ static int readDbPage(PgHdr *pPg, u32 iFrame){
**
** For an encrypted database, the situation is more complex: bytes
** 24..39 of the database are white noise. But the probability of
** white noise equaling 16 bytes of 0xff is vanishingly small so
** white noising equaling 16 bytes of 0xff is vanishingly small so
** we should still be ok.
*/
memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers));
@@ -3626,15 +3618,13 @@ int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){
if( rc==SQLITE_OK ){
pager_reset(pPager);
sqlite3PageFree(pPager->pTmpSpace);
pPager->pTmpSpace = pNew;
rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
}
if( rc==SQLITE_OK ){
sqlite3PageFree(pPager->pTmpSpace);
pPager->pTmpSpace = pNew;
pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
pPager->pageSize = pageSize;
}else{
sqlite3PageFree(pNew);
}
}
@@ -6847,18 +6837,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.
*/
@@ -7075,8 +7053,7 @@ int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
int rc = SQLITE_OK;
if( pPager->pWal ){
rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
(eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
pPager->pBusyHandlerArg,
pPager->xBusyHandler, pPager->pBusyHandlerArg,
pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
pnLog, pnCkpt
);
@@ -7258,5 +7235,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
+1 -1
View File
@@ -961,7 +961,7 @@ expr(A) ::= expr(X) NOT NULL(E). {spanUnaryPostfix(&A,pParse,TK_NOTNULL,&X,&E);}
** unary TK_ISNULL or TK_NOTNULL expression. */
static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
sqlite3 *db = pParse->db;
if( pY && pA && pY->op==TK_NULL ){
if( db->mallocFailed==0 && pY->op==TK_NULL ){
pA->op = (u8)op;
sqlite3ExprDelete(db, pA->pRight);
pA->pRight = 0;
-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_ */
+1 -6
View File
@@ -688,7 +688,7 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
if( createFlag==1 && (
nPinned>=pGroup->mxPinned
|| nPinned>=pCache->n90pct
|| (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclable<nPinned)
|| pcache1UnderMemoryPressure(pCache)
)){
return 0;
}
@@ -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
+1 -3
View File
@@ -2195,7 +2195,7 @@ void sqlite3Pragma(
#ifndef SQLITE_OMIT_WAL
/*
** PRAGMA [database.]wal_checkpoint = passive|full|restart|truncate
** PRAGMA [database.]wal_checkpoint = passive|full|restart
**
** Checkpoint the database.
*/
@@ -2207,8 +2207,6 @@ void sqlite3Pragma(
eMode = SQLITE_CHECKPOINT_FULL;
}else if( sqlite3StrICmp(zRight, "restart")==0 ){
eMode = SQLITE_CHECKPOINT_RESTART;
}else if( sqlite3StrICmp(zRight, "truncate")==0 ){
eMode = SQLITE_CHECKPOINT_TRUNCATE;
}
}
sqlite3VdbeSetNumCols(v, 3);
+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 ){
+29 -49
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);
@@ -1128,9 +1100,17 @@ void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
acc.useMalloc = 0;
if( p ){
for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4);
if( p->bLine[i] ){
sqlite3StrAccumAppend(&acc, "\342\224\202 ", 5);
}else{
sqlite3StrAccumAppend(&acc, " ", 3);
}
}
if( p->bLine[i] ){
sqlite3StrAccumAppend(&acc, "\342\224\234\342\224\200 ", 7);
}else{
sqlite3StrAccumAppend(&acc, "\342\224\224\342\224\200 ", 7);
}
sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
}
va_start(ap, zFormat);
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 -8
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);
}
}
@@ -320,10 +320,6 @@ static int lookupName(
if( pMatch ){
pExpr->iTable = pMatch->iCursor;
pExpr->pTab = pMatch->pTab;
assert( (pMatch->jointype & JT_RIGHT)==0 ); /* RIGHT JOIN not (yet) supported */
if( (pMatch->jointype & JT_LEFT)!=0 ){
ExprSetProperty(pExpr, EP_CanBeNull);
}
pSchema = pExpr->pTab->pSchema;
}
} /* if( pSrcList ) */
@@ -588,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);
}
/*
@@ -720,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
+9 -3
View File
@@ -1181,6 +1181,7 @@ static void generateSortTail(
int nKey;
int iSortTab; /* Sorter cursor to read from */
int nSortData; /* Trailing values to read from sorter */
u8 p5; /* p5 parameter for 1st OP_Column */
int i;
int bSeq; /* True if sorter record includes seq. no. */
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
@@ -1214,16 +1215,19 @@ static void generateSortTail(
addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
VdbeCoverage(v);
codeOffset(v, p->iOffset, addrContinue);
sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab);
sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
p5 = OPFLAG_CLEARCACHE;
bSeq = 0;
}else{
addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
codeOffset(v, p->iOffset, addrContinue);
iSortTab = iTab;
p5 = 0;
bSeq = 1;
}
for(i=0; i<nSortData; i++){
sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
if( i==0 ) sqlite3VdbeChangeP5(v, p5);
VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
}
switch( eDest ){
@@ -4829,7 +4833,7 @@ int sqlite3Select(
**
** is transformed to:
**
** SELECT xyz FROM ... GROUP BY xyz ORDER BY xyz
** SELECT xyz FROM ... GROUP BY xyz
**
** The second form is preferred as a single index (or temp-table) may be
** used for both the ORDER BY and DISTINCT processing. As originally
@@ -4842,6 +4846,7 @@ int sqlite3Select(
p->selFlags &= ~SF_Distinct;
p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
pGroupBy = p->pGroupBy;
sSort.pOrderBy = 0;
/* Notice that even thought SF_Distinct has been cleared from p->selFlags,
** the sDistinct.isTnct is still set. Hence, isTnct represents the
** original setting of the SF_Distinct flag, not the current setting */
@@ -5151,11 +5156,12 @@ int sqlite3Select(
addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
sqlite3ExprCacheClear(pParse);
if( groupBySort ){
sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, sortOut,sortPTab);
sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut);
}
for(j=0; j<pGroupBy->nExpr; j++){
if( groupBySort ){
sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
}else{
sAggInfo.directMode = 1;
sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
+61 -183
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;
@@ -892,7 +882,7 @@ static int shell_callback(
}
fprintf(p->out,"%s",p->newline);
}
if( nArg>0 ){
if( azArg>0 ){
for(i=0; i<nArg; i++){
output_csv(p, azArg[i], i<nArg-1);
}
@@ -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");
}
@@ -3822,7 +3725,6 @@ static int process_input(ShellState *p, FILE *in){
if( nSql ){
if( !_all_whitespace(zSql) ){
fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
errCnt++;
}
free(zSql);
}
@@ -3838,8 +3740,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();
@@ -4038,12 +3939,10 @@ int main(int argc, char **argv){
char *zErrMsg = 0;
ShellState data;
const char *zInitFile = 0;
char *zFirstCmd = 0;
int i;
int rc = 0;
int warnInmemoryDb = 0;
int readStdin = 1;
int nCmd = 0;
char **azCmd = 0;
#if USE_SYSTEM_SQLITE+0!=1
if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
@@ -4063,18 +3962,6 @@ int main(int argc, char **argv){
signal(SIGINT, interrupt_handler);
#endif
#ifdef SQLITE_SHELL_DBNAME_PROC
{
/* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
** of a C-function that will provide the name of the database file. Use
** this compile-time option to embed this shell program in larger
** applications. */
extern void SQLITE_SHELL_DBNAME_PROC(const char**);
SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
warnInmemoryDb = 0;
}
#endif
/* Do an initial pass through the command-line argument to locate
** the name of the database file, the name of the initialization file,
** the size of the alternative malloc heap,
@@ -4086,18 +3973,15 @@ int main(int argc, char **argv){
if( z[0]!='-' ){
if( data.zDbFilename==0 ){
data.zDbFilename = z;
}else{
/* Excesss arguments are interpreted as SQL (or dot-commands) and
** mean that nothing is read from stdin */
readStdin = 0;
nCmd++;
azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
if( azCmd==0 ){
fprintf(stderr, "out of memory\n");
exit(1);
}
azCmd[nCmd-1] = z;
continue;
}
if( zFirstCmd==0 ){
zFirstCmd = z;
continue;
}
fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
fprintf(stderr,"Use -help for a list of options.\n");
return 1;
}
if( z[1]=='-' ) z++;
if( strcmp(z,"-separator")==0
@@ -4187,6 +4071,11 @@ int main(int argc, char **argv){
#else
fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
return 1;
#endif
#ifdef SQLITE_SHELL_DBNAME_PROC
{ extern void SQLITE_SHELL_DBNAME_PROC(const char**);
SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
warnInmemoryDb = 0; }
#endif
}
data.out = stdout;
@@ -4250,8 +4139,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 ){
@@ -4284,10 +4171,6 @@ int main(int argc, char **argv){
}else if( strcmp(z,"-help")==0 ){
usage(1);
}else if( strcmp(z,"-cmd")==0 ){
/* Run commands that follow -cmd first and separately from commands
** that simply appear on the command-line. This seems goofy. It would
** be better if all commands ran in the order that they appear. But
** we retain the goofy behavior for historical compatibility. */
if( i==argc-1 ) break;
z = cmdline_option_value(argc,argv,++i);
if( z[0]=='.' ){
@@ -4311,28 +4194,23 @@ int main(int argc, char **argv){
}
}
if( !readStdin ){
/* Run all arguments that do not begin with '-' as if they were separate
** command-line inputs, except for the argToSkip argument which contains
** the database filename.
if( zFirstCmd ){
/* Run just the command that follows the database name
*/
for(i=0; i<nCmd; i++){
if( azCmd[i][0]=='.' ){
rc = do_meta_command(azCmd[i], &data);
if( rc ) return rc==2 ? 0 : rc;
}else{
open_db(&data, 0);
rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
if( zErrMsg!=0 ){
fprintf(stderr,"Error: %s\n", zErrMsg);
return rc!=0 ? rc : 1;
}else if( rc!=0 ){
fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
return rc;
}
if( zFirstCmd[0]=='.' ){
rc = do_meta_command(zFirstCmd, &data);
if( rc==2 ) rc = 0;
}else{
open_db(&data, 0);
rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
if( zErrMsg!=0 ){
fprintf(stderr,"Error: %s\n", zErrMsg);
return rc!=0 ? rc : 1;
}else if( rc!=0 ){
fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
return rc;
}
}
free(azCmd);
}else{
/* Run commands received from standard input
*/
+305 -453
View File
File diff suppressed because it is too large Load Diff
+14 -21
View File
@@ -159,7 +159,7 @@
*/
#if defined(__GNUC__)
# define SQLITE_NOINLINE __attribute__((noinline))
#elif defined(_MSC_VER) && _MSC_VER>=1310
#elif defined(_MSC_VER)
# define SQLITE_NOINLINE __declspec(noinline)
#else
# define SQLITE_NOINLINE
@@ -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,14 +1796,11 @@ 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 */
tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */
IndexSample *aSample; /* Samples of the left-most key */
tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this index */
tRowcnt nRowEst0; /* Non-logarithmic number of rows in the index */
#endif
};
@@ -2000,7 +1998,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[] */
@@ -2015,7 +2013,7 @@ struct Expr {
/*
** The following are the meanings of bits in the Expr.flags field.
*/
#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
#define EP_FromJoin 0x000001 /* Originated in ON or USING clause of a join */
#define EP_Agg 0x000002 /* Contains one or more aggregate functions */
#define EP_Resolved 0x000004 /* IDs have been resolved to COLUMNs */
#define EP_Error 0x000008 /* Expression contains one or more errors */
@@ -2035,7 +2033,6 @@ struct Expr {
#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
#define EP_Constant 0x080000 /* Node is a constant */
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
/*
** These macros can be used to test, set, or clear bits in the
@@ -2668,6 +2665,7 @@ struct AuthContext {
#define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
#define OPFLAG_APPEND 0x08 /* This is likely to be an append */
#define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */
#define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */
#define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
@@ -2893,11 +2891,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;
@@ -3298,7 +3294,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);
@@ -3453,9 +3448,6 @@ const char *sqlite3ErrName(int);
const char *sqlite3ErrStr(int);
int sqlite3ReadSchema(Parse *pParse);
#if defined(SQLITE_DEBUG)
int sqlite3ValidCollSeq(const CollSeq*);
#endif
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
@@ -3547,7 +3539,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);
@@ -3807,9 +3799,10 @@ SQLITE_EXTERN void (*sqlite3IoTrace)(const char*,...);
# define sqlite3MemdebugNoType(X,Y) 1
#endif
#define MEMTYPE_HEAP 0x01 /* General heap allocations */
#define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */
#define MEMTYPE_LOOKASIDE 0x02 /* Might have been lookaside memory */
#define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */
#define MEMTYPE_PCACHE 0x08 /* Page cache allocations */
#define MEMTYPE_DB 0x10 /* Uses sqlite3DbMalloc, not sqlite_malloc */
/*
** Threading interface
+3 -13
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: {
@@ -221,7 +213,7 @@ int sqlite3_db_status(
}
db->pnBytesFreed = 0;
*pHighwater = 0; /* IMP: R-64479-57858 */
*pHighwater = 0;
*pCurrent = nByte;
break;
@@ -246,9 +238,7 @@ int sqlite3_db_status(
sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
}
}
*pHighwater = 0; /* IMP: R-42420-56072 */
/* IMP: R-54100-20147 */
/* IMP: R-29431-39229 */
*pHighwater = 0;
*pCurrent = nRet;
break;
}
@@ -258,7 +248,7 @@ int sqlite3_db_status(
** have been satisfied. The *pHighwater is always set to zero.
*/
case SQLITE_DBSTATUS_DEFERRED_FKS: {
*pHighwater = 0; /* IMP: R-11967-56545 */
*pHighwater = 0;
*pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
break;
}
-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);
+156 -99
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
**
@@ -3638,7 +3715,6 @@ static int test_prepare_v2(
){
sqlite3 *db;
const char *zSql;
char *zCopy = 0; /* malloc() copy of zSql */
int bytes;
const char *zTail = 0;
sqlite3_stmt *pStmt = 0;
@@ -3654,21 +3730,7 @@ static int test_prepare_v2(
zSql = Tcl_GetString(objv[2]);
if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
/* Instead of using zSql directly, make a copy into a buffer obtained
** directly from malloc(). The idea is to make it easier for valgrind
** to spot buffer overreads. */
if( bytes>=0 ){
zCopy = malloc(bytes);
memcpy(zCopy, zSql, bytes);
}else{
int n = (int)strlen(zSql) + 1;
zCopy = malloc(n);
memcpy(zCopy, zSql, n);
}
rc = sqlite3_prepare_v2(db, zCopy, bytes, &pStmt, objc>=5 ? &zTail : 0);
free(zCopy);
zTail = &zSql[(zTail - zCopy)];
rc = sqlite3_prepare_v2(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0);
assert(rc==SQLITE_OK || pStmt==0);
Tcl_ResetResult(interp);
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
@@ -5451,11 +5513,10 @@ static int test_limit(
{ "SQLITE_LIMIT_LIKE_PATTERN_LENGTH", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
{ "SQLITE_LIMIT_VARIABLE_NUMBER", SQLITE_LIMIT_VARIABLE_NUMBER },
{ "SQLITE_LIMIT_TRIGGER_DEPTH", SQLITE_LIMIT_TRIGGER_DEPTH },
{ "SQLITE_LIMIT_WORKER_THREADS", SQLITE_LIMIT_WORKER_THREADS },
/* Out of range test cases */
{ "SQLITE_LIMIT_TOOSMALL", -1, },
{ "SQLITE_LIMIT_TOOBIG", SQLITE_LIMIT_WORKER_THREADS+1 },
{ "SQLITE_LIMIT_TOOBIG", SQLITE_LIMIT_TRIGGER_DEPTH+1 },
};
int i, id;
int val;
@@ -5690,11 +5751,10 @@ static int test_wal_checkpoint_v2(
int nCkpt = -555;
Tcl_Obj *pRet;
const char * aMode[] = { "passive", "full", "restart", "truncate", 0 };
const char * aMode[] = { "passive", "full", "restart", 0 };
assert( SQLITE_CHECKPOINT_PASSIVE==0 );
assert( SQLITE_CHECKPOINT_FULL==1 );
assert( SQLITE_CHECKPOINT_RESTART==2 );
assert( SQLITE_CHECKPOINT_TRUNCATE==3 );
if( objc!=3 && objc!=4 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB MODE ?NAME?");
@@ -6232,8 +6292,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 ){
@@ -6276,7 +6335,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*);
@@ -6292,7 +6350,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 },
@@ -6780,7 +6837,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
@@ -6805,10 +6866,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;
}
-13
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
@@ -656,7 +644,6 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
LINKVAR( DEFAULT_FILE_FORMAT );
LINKVAR( MAX_ATTACHED );
LINKVAR( MAX_DEFAULT_PAGE_SIZE );
LINKVAR( MAX_WORKER_THREADS );
{
static const int cv_TEMP_STORE = SQLITE_TEMP_STORE;
+4 -4
View File
@@ -98,14 +98,14 @@ 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_WINRT && SQLITE_THREADSAFE>0
#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */
#include <process.h>
/* A running thread */
struct SQLiteThread {
void *tid; /* The thread handle */
uintptr_t tid; /* The thread handle */
unsigned id; /* The thread identifier */
void *(*xTask)(void*); /* The routine to run as a thread */
void *pIn; /* Argument to xTask */
@@ -153,7 +153,7 @@ int sqlite3ThreadCreate(
}else{
p->xTask = xTask;
p->pIn = pIn;
p->tid = (void*)_beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
p->tid = _beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
if( p->tid==0 ){
memset(p, 0, sizeof(*p));
}
@@ -191,7 +191,7 @@ 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_WINRT */
/******************************** 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
+80 -119
View File
@@ -214,7 +214,6 @@ static VdbeCursor *allocateCursor(
memset(pCx, 0, sizeof(VdbeCursor));
pCx->iDb = iDb;
pCx->nField = nField;
pCx->aOffset = &pCx->aType[nField];
if( isBtreeCursor ){
pCx->pCursor = (BtCursor*)
&pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
@@ -608,9 +607,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.
*/
@@ -1562,7 +1558,7 @@ case OP_Function: {
ctx.pVdbe = p;
MemSetTypeFlag(ctx.pOut, MEM_Null);
ctx.fErrorOrAux = 0;
db->lastRowid = lastRowid;
assert( db->lastRowid==lastRowid );
(*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */
@@ -2280,7 +2276,7 @@ case OP_Column: {
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( p2<pC->nField );
aOffset = pC->aOffset;
aOffset = pC->aType + pC->nField;
#ifndef SQLITE_OMIT_VIRTUALTABLE
assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */
#endif
@@ -2291,7 +2287,7 @@ case OP_Column: {
/* If the cursor cache is stale, bring it up-to-date */
rc = sqlite3VdbeCursorMoveto(pC);
if( rc ) goto abort_due_to_error;
if( pC->cacheStatus!=p->cacheCtr ){
if( pC->cacheStatus!=p->cacheCtr || (pOp->p5&OPFLAG_CLEARCACHE)!=0 ){
if( pC->nullRow ){
if( pCrsr==0 ){
assert( pC->pseudoTableReg>0 );
@@ -2301,7 +2297,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{
@@ -2336,6 +2332,14 @@ case OP_Column: {
pC->iHdrOffset = getVarint32(pC->aRow, offset);
pC->nHdrParsed = 0;
aOffset[0] = offset;
if( avail<offset ){
/* pC->aRow does not have to hold the entire row, but it does at least
** need to cover the header of the record. If pC->aRow does not contain
** the complete header, then set it to zero, forcing the header to be
** dynamically allocated. */
pC->aRow = 0;
pC->szRow = 0;
}
/* Make sure a corrupt database has not given us an oversize header.
** Do this now to avoid an oversize memory allocation.
@@ -2350,22 +2354,6 @@ case OP_Column: {
rc = SQLITE_CORRUPT_BKPT;
goto op_column_error;
}
if( avail<offset ){
/* pC->aRow does not have to hold the entire row, but it does at least
** need to cover the header of the record. If pC->aRow does not contain
** the complete header, then set it to zero, forcing the header to be
** dynamically allocated. */
pC->aRow = 0;
pC->szRow = 0;
}
/* The following goto is an optimization. It can be omitted and
** everything will still work. But OP_Column is measurably faster
** by skipping the subsequent conditional, which is always true.
*/
assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */
goto op_column_read_header;
}
/* Make sure at least the first p2+1 entries of the header have been
@@ -2375,7 +2363,6 @@ case OP_Column: {
/* If there is more header available for parsing in the record, try
** to extract additional fields up through the p2+1-th field
*/
op_column_read_header:
if( pC->iHdrOffset<aOffset[0] ){
/* Make sure zData points to enough of the record to cover the header. */
if( pC->aRow==0 ){
@@ -2420,16 +2407,15 @@ case OP_Column: {
sMem.flags = MEM_Null;
}
/* The record is corrupt if any of the following are true:
** (1) the bytes of the header extend past the declared header size
** (zHdr>zEndHdr)
** (2) the entire header was used but not all data was used
** (zHdr==zEndHdr && offset!=pC->payloadSize)
** (3) the end of the data extends beyond the end of the record.
** (offset > pC->payloadSize)
/* If we have read more header data than was contained in the header,
** or if the end of the last field appears to be past the end of the
** record, or if the end of the last field appears to be before the end
** of the record (when all fields present), then we must be dealing
** with a corrupt database.
*/
if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset!=pC->payloadSize))
if( (zHdr > zEndHdr)
|| (offset > pC->payloadSize)
|| (zHdr==zEndHdr && offset!=pC->payloadSize)
){
rc = SQLITE_CORRUPT_BKPT;
goto op_column_error;
@@ -2444,7 +2430,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;
}
@@ -2620,7 +2606,7 @@ case OP_MakeRecord: {
pRec = pLast;
do{
assert( memIsValid(pRec) );
pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format);
serial_type = sqlite3VdbeSerialType(pRec, file_format);
len = sqlite3VdbeSerialTypeLen(serial_type);
if( pRec->flags & MEM_Zero ){
if( nData ){
@@ -2636,10 +2622,7 @@ case OP_MakeRecord: {
nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
}while( (--pRec)>=pData0 );
/* EVIDENCE-OF: R-22564-11647 The header begins with a single varint
** which determines the total number of bytes in the header. The varint
** value is the size of the header in bytes including the size varint
** itself. */
/* Add the initial header varint and total the size */
testcase( nHdr==126 );
testcase( nHdr==127 );
if( nHdr<=126 ){
@@ -2672,12 +2655,8 @@ case OP_MakeRecord: {
assert( pData0<=pLast );
pRec = pData0;
do{
serial_type = pRec->uTemp;
/* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
** additional varints, one per column. */
serial_type = sqlite3VdbeSerialType(pRec, file_format);
i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
/* EVIDENCE-OF: R-64536-51728 The values for each column in the record
** immediately follow the header. */
j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
}while( (++pRec)<=pLast );
assert( i==nHdr );
@@ -2832,18 +2811,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_ROLLBACK,
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);
@@ -2851,7 +2823,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);
@@ -3248,7 +3220,7 @@ case OP_OpenWrite: {
|| p->readOnly==0 );
if( p->expired ){
rc = SQLITE_ABORT_ROLLBACK;
rc = SQLITE_ABORT;
break;
}
@@ -3582,6 +3554,7 @@ case OP_SeekGT: { /* jump, in3 */
applyNumericAffinity(pIn3, 0);
}
iKey = sqlite3VdbeIntValue(pIn3);
pC->rowidIsValid = 0;
/* If the P3 value could not be converted into an integer without
** loss of information, then special processing is required... */
@@ -3617,10 +3590,13 @@ case OP_SeekGT: { /* jump, in3 */
}
}
rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
pC->movetoTarget = iKey; /* Used by OP_Delete */
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
if( res==0 ){
pC->rowidIsValid = 1;
pC->lastRowid = iKey;
}
}else{
nField = pOp->p4.i;
assert( pOp->p4type==P4_INT32 );
@@ -3650,6 +3626,7 @@ case OP_SeekGT: { /* jump, in3 */
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
pC->rowidIsValid = 0;
}
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
@@ -3661,6 +3638,7 @@ case OP_SeekGT: { /* jump, in3 */
res = 0;
rc = sqlite3BtreeNext(pC->pCursor, &res);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
pC->rowidIsValid = 0;
}else{
res = 0;
}
@@ -3670,6 +3648,7 @@ case OP_SeekGT: { /* jump, in3 */
res = 0;
rc = sqlite3BtreePrevious(pC->pCursor, &res);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
pC->rowidIsValid = 0;
}else{
/* res might be negative because the table is empty. Check to
** see if this is the case.
@@ -3706,6 +3685,7 @@ case OP_Seek: { /* in2 */
pC->nullRow = 0;
pIn2 = &aMem[pOp->p2];
pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
pC->rowidIsValid = 0;
pC->deferredMoveto = 1;
break;
}
@@ -3812,10 +3792,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 );
ExpandBlob(pIn3);
assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */
sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
}
pIdxKey->default_rc = 0;
@@ -3891,13 +3871,15 @@ case OP_NotExists: { /* jump, in3 */
res = 0;
iKey = pIn3->u.i;
rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
pC->movetoTarget = iKey; /* Used by OP_Delete */
pC->lastRowid = pIn3->u.i;
pC->rowidIsValid = res==0 ?1:0;
pC->nullRow = 0;
pC->cacheStatus = CACHE_STALE;
pC->deferredMoveto = 0;
VdbeBranchTaken(res!=0,2);
if( res!=0 ){
pc = pOp->p2 - 1;
assert( pC->rowidIsValid==0 );
}
pC->seekResult = res;
break;
@@ -4045,6 +4027,7 @@ case OP_NewRowid: { /* out2-prerelease */
}
assert( v>0 ); /* EV: R-40812-03570 */
}
pC->rowidIsValid = 0;
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
}
@@ -4149,6 +4132,7 @@ case OP_InsertInt: {
pData->z, pData->n, nZero,
(pOp->p5 & OPFLAG_APPEND)!=0, seekResult
);
pC->rowidIsValid = 0;
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
@@ -4185,32 +4169,33 @@ case OP_InsertInt: {
** using OP_NotFound prior to invoking this opcode.
*/
case OP_Delete: {
i64 iKey;
VdbeCursor *pC;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
assert( pC->deferredMoveto==0 );
iKey = pC->lastRowid; /* Only used for the update hook */
/* The OP_Delete opcode always follows an OP_NotExists or OP_Last or
** OP_Column on the same table without any intervening operations that
** might move or invalidate the cursor. Hence cursor pC is always pointing
** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation
** below is always a no-op and cannot fail. We will run it anyhow, though,
** to guard against future changes to the code generator.
**/
assert( pC->deferredMoveto==0 );
rc = sqlite3VdbeCursorMoveto(pC);
if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
#ifdef SQLITE_DEBUG
/* The seek operation that positioned the cursor prior to OP_Delete will
** have also set the pC->movetoTarget field to the rowid of the row that
** is being deleted */
if( pOp->p4.z && pC->isTable ){
i64 iKey = 0;
sqlite3BtreeKeySize(pC->pCursor, &iKey);
assert( pC->movetoTarget==iKey );
}
#endif
rc = sqlite3BtreeDelete(pC->pCursor);
pC->cacheStatus = CACHE_STALE;
/* Invoke the update-hook if required. */
if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){
db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget);
db->aDb[pC->iDb].zName, pOp->p4.z, iKey);
assert( pC->iDb>=0 );
}
if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
@@ -4263,17 +4248,10 @@ case OP_SorterCompare: {
break;
};
/* Opcode: SorterData P1 P2 P3 * *
/* Opcode: SorterData P1 P2 * * *
** Synopsis: r[P2]=data
**
** Write into register P2 the current sorter data for sorter cursor P1.
** Then clear the column header cache on cursor P3.
**
** This opcode is normally use to move a record out of the sorter and into
** a register that is the source for a pseudo-table cursor created using
** OpenPseudo. That pseudo-table cursor is the one that is identified by
** parameter P3. Clearing the P3 column cache as part of this opcode saves
** us from having to issue a separate NullRow instruction to clear that cache.
*/
case OP_SorterData: {
VdbeCursor *pC;
@@ -4283,8 +4261,6 @@ case OP_SorterData: {
assert( isSorter(pC) );
rc = sqlite3VdbeSorterRowkey(pC, pOut);
assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
break;
}
@@ -4331,20 +4307,16 @@ case OP_RowData: {
assert( pC->pseudoTableReg==0 );
assert( pC->pCursor!=0 );
pCrsr = pC->pCursor;
assert( sqlite3BtreeCursorIsValid(pCrsr) );
/* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
** OP_Rewind/Op_Next with no intervening instructions that might invalidate
** the cursor. If this where not the case, on of the following assert()s
** would fail. Should this ever change (because of changes in the code
** generator) then the fix would be to insert a call to
** sqlite3VdbeCursorMoveto().
** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always
** a no-op and can never fail. But we leave it in place as a safety.
*/
assert( pC->deferredMoveto==0 );
assert( sqlite3BtreeCursorIsValid(pCrsr) );
#if 0 /* Not required due to the previous to assert() statements */
rc = sqlite3VdbeCursorMoveto(pC);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
#endif
if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
if( pC->isTable==0 ){
assert( !pC->isTable );
@@ -4361,8 +4333,7 @@ case OP_RowData: {
goto too_big;
}
}
testcase( n==0 );
if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){
if( sqlite3VdbeMemClearAndResize(pOut, n) ){
goto no_mem;
}
pOut->n = n;
@@ -4413,14 +4384,14 @@ case OP_Rowid: { /* out2-prerelease */
#endif /* SQLITE_OMIT_VIRTUALTABLE */
}else{
assert( pC->pCursor!=0 );
rc = sqlite3VdbeCursorRestore(pC);
rc = sqlite3VdbeCursorMoveto(pC);
if( rc ) goto abort_due_to_error;
if( pC->nullRow ){
pOut->flags = MEM_Null;
break;
if( pC->rowidIsValid ){
v = pC->lastRowid;
}else{
rc = sqlite3BtreeKeySize(pC->pCursor, &v);
assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */
}
rc = sqlite3BtreeKeySize(pC->pCursor, &v);
assert( rc==SQLITE_OK ); /* Always so because of CursorRestore() above */
}
pOut->u.i = v;
break;
@@ -4439,6 +4410,7 @@ case OP_NullRow: {
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
pC->nullRow = 1;
pC->rowidIsValid = 0;
pC->cacheStatus = CACHE_STALE;
if( pC->pCursor ){
sqlite3BtreeClearCursor(pC->pCursor);
@@ -4472,6 +4444,7 @@ case OP_Last: { /* jump */
rc = sqlite3BtreeLast(pCrsr, &res);
pC->nullRow = (u8)res;
pC->deferredMoveto = 0;
pC->rowidIsValid = 0;
pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_DEBUG
pC->seekOp = OP_Last;
@@ -4509,9 +4482,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
@@ -4538,6 +4511,7 @@ case OP_Rewind: { /* jump */
rc = sqlite3BtreeFirst(pCrsr, &res);
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
pC->rowidIsValid = 0;
}
pC->nullRow = (u8)res;
assert( pOp->p2>0 && pOp->p2<p->nOp );
@@ -4663,6 +4637,7 @@ next_tail:
}else{
pC->nullRow = 1;
}
pC->rowidIsValid = 0;
goto check_for_interrupt;
}
@@ -4778,16 +4753,10 @@ case OP_IdxRowid: { /* out2-prerelease */
pCrsr = pC->pCursor;
assert( pCrsr!=0 );
pOut->flags = MEM_Null;
assert( pC->isTable==0 );
rc = sqlite3VdbeCursorMoveto(pC);
if( NEVER(rc) ) goto abort_due_to_error;
assert( pC->deferredMoveto==0 );
/* sqlite3VbeCursorRestore() can only fail if the record has been deleted
** out from under the cursor. That will never happend for an IdxRowid
** opcode, hence the NEVER() arround the check of the return value.
*/
rc = sqlite3VdbeCursorRestore(pC);
if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
assert( pC->isTable==0 );
if( !pC->nullRow ){
rowid = 0; /* Not needed. Only used to silence a warning. */
rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid);
@@ -5427,9 +5396,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++){
@@ -5447,7 +5413,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];
@@ -5458,9 +5423,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);
@@ -5705,8 +5667,8 @@ case OP_AggFinal: {
/* Opcode: Checkpoint P1 P2 P3 * *
**
** Checkpoint database P1. This is a no-op if P1 is not currently in
** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL,
** RESTART, or TRUNCATE. Write 1 or 0 into mem[P3] if the checkpoint returns
** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL
** or RESTART. Write 1 or 0 into mem[P3] if the checkpoint returns
** SQLITE_BUSY or not, respectively. Write the number of pages in the
** WAL after the checkpoint into mem[P3+1] and the number of pages
** in the WAL that have been checkpointed after the checkpoint
@@ -5724,7 +5686,6 @@ case OP_Checkpoint: {
assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
|| pOp->p2==SQLITE_CHECKPOINT_FULL
|| pOp->p2==SQLITE_CHECKPOINT_RESTART
|| pOp->p2==SQLITE_CHECKPOINT_TRUNCATE
);
rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]);
if( rc==SQLITE_BUSY ){
-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
+4 -21
View File
@@ -73,6 +73,7 @@ struct VdbeCursor {
#endif
i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */
u8 nullRow; /* True if pointing to a row with no data */
u8 rowidIsValid; /* True if lastRowid is valid */
u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
Bool isEphemeral:1; /* True for an ephemeral table */
Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
@@ -82,6 +83,7 @@ struct VdbeCursor {
sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
i64 seqCount; /* Sequence counter */
i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
i64 lastRowid; /* Rowid being deleted by OP_Delete */
VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */
/* Cached information about the header for the data record that the
@@ -98,7 +100,6 @@ struct VdbeCursor {
u32 szRow; /* Byte available in aRow */
u32 iHdrOffset; /* Offset to next unparsed byte of the header */
const u8 *aRow; /* Data for the current row, if all on one page */
u32 *aOffset; /* Pointer to aType[nField] */
u32 aType[1]; /* Type values for all entries in the record */
/* 2*nField extra array elements allocated for aType[], beyond the one
** static element declared in the structure. nField total array slots for
@@ -132,7 +133,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 +145,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))])
@@ -177,7 +176,7 @@ struct Mem {
/* ShallowCopy only needs to copy the information above */
char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
int szMalloc; /* Size of the zMalloc allocation */
u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */
int iPadding1; /* Padding for 8-byte alignment */
sqlite3 *db; /* The associated database connection */
void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
#ifdef SQLITE_DEBUG
@@ -297,16 +296,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 +368,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
};
/*
@@ -400,7 +384,6 @@ struct Vdbe {
void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
void sqliteVdbePopStack(Vdbe*,int);
int sqlite3VdbeCursorMoveto(VdbeCursor*);
int sqlite3VdbeCursorRestore(VdbeCursor*);
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
void sqlite3VdbePrintOp(FILE*, int, Op*);
#endif
+5 -96
View File
@@ -318,7 +318,6 @@ void sqlite3_result_text64(
){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
assert( xDel!=SQLITE_DYNAMIC );
if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE;
if( n>0x7fffffff ){
(void)invokeValueDestructor(z, xDel, pCtx);
}else{
@@ -966,19 +965,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 +1434,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 +1449,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 */
+13 -91
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
@@ -1054,7 +1026,6 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
CollSeq *pColl = pKeyInfo->aColl[j];
const char *zColl = pColl ? pColl->zName : "nil";
int n = sqlite3Strlen30(zColl);
assert( pColl==0 || sqlite3ValidCollSeq(pColl) );
if( n==6 && memcmp(zColl,"BINARY",6)==0 ){
zColl = "B";
n = 1;
@@ -1724,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);
}
@@ -1743,7 +1711,7 @@ void sqlite3VdbeMakeReady(
p->aVar[n].db = db;
}
}
if( p->azVar && pParse->nzVar>0 ){
if( p->azVar ){
p->nzVar = pParse->nzVar;
memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0]));
memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0]));
@@ -1777,7 +1745,7 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
sqlite3BtreeCloseCursor(pCx->pCursor);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
else if( pCx->pVtabCursor ){
if( pCx->pVtabCursor ){
sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
p->inVtabMethod = 1;
@@ -1794,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;
@@ -1807,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;
}
@@ -1824,10 +1788,9 @@ static void closeAllCursors(Vdbe *p){
VdbeFrame *pFrame;
for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
sqlite3VdbeFrameRestore(pFrame);
p->pFrame = 0;
p->nFrame = 0;
}
assert( p->nFrame==0 );
p->pFrame = 0;
p->nFrame = 0;
if( p->apCsr ){
int i;
@@ -1849,7 +1812,7 @@ static void closeAllCursors(Vdbe *p){
}
/* Delete any auxdata allocations made by the VM */
if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p, -1, 0);
sqlite3VdbeDeleteAuxData(p, -1, 0);
assert( p->pAuxData==0 );
}
@@ -2375,7 +2338,6 @@ int sqlite3VdbeHalt(Vdbe *p){
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
sqlite3CloseSavepoints(db);
db->autoCommit = 1;
p->nChange = 0;
}
}
}
@@ -2416,7 +2378,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;
@@ -2425,7 +2386,6 @@ int sqlite3VdbeHalt(Vdbe *p){
}
}else{
sqlite3RollbackAll(db, SQLITE_OK);
p->nChange = 0;
}
db->nStatement = 0;
}else if( eStatementOp==0 ){
@@ -2437,7 +2397,6 @@ int sqlite3VdbeHalt(Vdbe *p){
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
sqlite3CloseSavepoints(db);
db->autoCommit = 1;
p->nChange = 0;
}
}
@@ -2458,7 +2417,6 @@ int sqlite3VdbeHalt(Vdbe *p){
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
sqlite3CloseSavepoints(db);
db->autoCommit = 1;
p->nChange = 0;
}
}
@@ -2720,12 +2678,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
}
/*
@@ -2766,7 +2718,9 @@ static int SQLITE_NOINLINE handleDeferredMoveto(VdbeCursor *p){
assert( p->isTable );
rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
if( rc ) return rc;
p->lastRowid = p->movetoTarget;
if( res!=0 ) return SQLITE_CORRUPT_BKPT;
p->rowidIsValid = 1;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
@@ -2792,17 +2746,6 @@ static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){
return rc;
}
/*
** Check to ensure that the cursor is valid. Restore the cursor
** if need be. Return any I/O error from the restore operation.
*/
int sqlite3VdbeCursorRestore(VdbeCursor *p){
if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
return handleMovedCursor(p);
}
return SQLITE_OK;
}
/*
** Make sure the cursor p is ready to read or write the row to which it
** was last positioned. Return an error code if an OOM fault or I/O error
@@ -2820,7 +2763,7 @@ int sqlite3VdbeCursorMoveto(VdbeCursor *p){
if( p->deferredMoveto ){
return handleDeferredMoveto(p);
}
if( p->pCursor && sqlite3BtreeCursorHasMoved(p->pCursor) ){
if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
return handleMovedCursor(p);
}
return SQLITE_OK;
@@ -2884,7 +2827,9 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
i64 i = pMem->u.i;
u64 u;
if( i<0 ){
u = ~i;
if( i<(-MAX_6BYTE) ) return 6;
/* Previous test prevents: u = -(-9223372036854775808) */
u = -i;
}else{
u = i;
}
@@ -3050,14 +2995,10 @@ static u32 SQLITE_NOINLINE serialGet(
u32 y = FOUR_BYTE_UINT(buf+4);
x = (x<<32) + y;
if( serial_type==6 ){
/* EVIDENCE-OF: R-29851-52272 Value is a big-endian 64-bit
** twos-complement integer. */
pMem->u.i = *(i64*)&x;
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
}else{
/* EVIDENCE-OF: R-57343-49114 Value is a big-endian IEEE 754-2008 64-bit
** floating point number. */
#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
/* Verify that integers and floating point values use the same
** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
@@ -3085,46 +3026,35 @@ u32 sqlite3VdbeSerialGet(
switch( serial_type ){
case 10: /* Reserved for future use */
case 11: /* Reserved for future use */
case 0: { /* Null */
/* EVIDENCE-OF: R-24078-09375 Value is a NULL. */
case 0: { /* NULL */
pMem->flags = MEM_Null;
break;
}
case 1: {
/* EVIDENCE-OF: R-44885-25196 Value is an 8-bit twos-complement
** integer. */
case 1: { /* 1-byte signed integer */
pMem->u.i = ONE_BYTE_INT(buf);
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return 1;
}
case 2: { /* 2-byte signed integer */
/* EVIDENCE-OF: R-49794-35026 Value is a big-endian 16-bit
** twos-complement integer. */
pMem->u.i = TWO_BYTE_INT(buf);
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return 2;
}
case 3: { /* 3-byte signed integer */
/* EVIDENCE-OF: R-37839-54301 Value is a big-endian 24-bit
** twos-complement integer. */
pMem->u.i = THREE_BYTE_INT(buf);
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return 3;
}
case 4: { /* 4-byte signed integer */
/* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit
** twos-complement integer. */
pMem->u.i = FOUR_BYTE_INT(buf);
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return 4;
}
case 5: { /* 6-byte signed integer */
/* EVIDENCE-OF: R-50385-09674 Value is a big-endian 48-bit
** twos-complement integer. */
pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf);
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
@@ -3138,17 +3068,11 @@ u32 sqlite3VdbeSerialGet(
}
case 8: /* Integer 0 */
case 9: { /* Integer 1 */
/* EVIDENCE-OF: R-12976-22893 Value is the integer 0. */
/* EVIDENCE-OF: R-18143-12121 Value is the integer 1. */
pMem->u.i = serial_type-8;
pMem->flags = MEM_Int;
return 0;
}
default: {
/* EVIDENCE-OF: R-14606-31564 Value is a BLOB that is (N-12)/2 bytes in
** length.
** EVIDENCE-OF: R-28401-00140 Value is a string in the text encoding and
** (N-13)/2 bytes in length. */
static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem };
pMem->z = (char *)buf;
pMem->n = (serial_type-12)/2;
@@ -3359,7 +3283,6 @@ static int vdbeCompareMemString(
const CollSeq *pColl,
u8 *prcErr /* If an OOM occurs, set to SQLITE_NOMEM */
){
assert( sqlite3ValidCollSeq(pColl) );
if( pMem1->enc==pColl->enc ){
/* The strings are already in the correct encoding. Call the
** comparison function directly */
@@ -3475,7 +3398,6 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
assert( !pColl || pColl->xCmp );
if( pColl ){
assert( sqlite3ValidCollSeq(pColl) );
return vdbeCompareMemString(pMem1, pMem2, pColl, 0);
}
/* If a NULL pointer was passed as the collate function, fall through
+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;
+5 -12
View File
@@ -31,10 +31,7 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
*/
assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
/* MEM_Dyn may only be set if Mem.szMalloc==0. In this way we
** ensure that if Mem.szMalloc>0 then it is safe to do
** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn.
** That saves a few cycles in inner loops. */
/* MEM_Dyn may only be set if Mem.szMalloc==0 */
assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );
/* Cannot be both MEM_Int and MEM_Real at the same time */
@@ -143,7 +140,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
}
}
if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){
if( pMem->z && bPreserve && pMem->z!=pMem->zMalloc ){
memcpy(pMem->zMalloc, pMem->z, pMem->n);
}
if( (pMem->flags&MEM_Dyn)!=0 ){
@@ -170,8 +167,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
** if unable to complete the resizing.
*/
int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
assert( szNew>0 );
assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 );
assert( szNew>=0 );
if( pMem->szMalloc<szNew ){
return sqlite3VdbeMemGrow(pMem, szNew, 0);
}
@@ -895,10 +891,7 @@ int sqlite3VdbeMemSetStr(
if( nByte>iLimit ){
return SQLITE_TOOBIG;
}
testcase( nAlloc==0 );
testcase( nAlloc==31 );
testcase( nAlloc==32 );
if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){
if( sqlite3VdbeMemClearAndResize(pMem, nAlloc) ){
return SQLITE_NOMEM;
}
memcpy(pMem->z, z, nAlloc);
@@ -1001,7 +994,7 @@ int sqlite3VdbeMemFromBtree(
** Convert it into a string with encoding enc and return a pointer
** to a zero-terminated version of that string.
*/
static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
assert( pVal!=0 );
assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
+8 -13
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
@@ -147,13 +147,6 @@
# define SQLITE_DEBUG_SORTER_THREADS 1
#endif
/*
** Hard-coded maximum amount of data to accumulate in memory before flushing
** to a level 0 PMA. The purpose of this limit is to prevent various integer
** overflows. 512MiB.
*/
#define SQLITE_MAX_MXPMASIZE (1<<29)
/*
** Private objects used by the sorter
*/
@@ -852,11 +845,13 @@ int sqlite3VdbeSorterInit(
pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz;
mxCache = db->aDb[0].pSchema->cache_size;
if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING;
pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_MXPMASIZE);
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 );
@@ -2297,7 +2292,7 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
assert( pSorter->bUseThreads==0 || pSorter->nTask>1 );
if( pSorter->bUseThreads ){
int iTask;
PmaReader *pReadr = 0;
PmaReader *pReadr;
SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1];
rc = vdbeSortAllocUnpacked(pLast);
if( rc==SQLITE_OK ){
+2 -22
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);
}
@@ -332,12 +326,7 @@ void sqlite3VtabBeginParse(
addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
addModuleArgument(db, pTable, 0);
addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0)
|| (pParse->sNameToken.z==pName1->z && pName2->z==0)
);
pParse->sNameToken.n = (int)(
&pModuleName->z[pModuleName->n] - pParse->sNameToken.z
);
pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z);
#ifndef SQLITE_OMIT_AUTHORIZATION
/* Creating a virtual table invokes the authorization callback twice.
@@ -530,7 +519,6 @@ static int vtabCallConstructor(
}else if( ALWAYS(pVTable->pVtab) ){
/* Justification of ALWAYS(): A correct vtab constructor must allocate
** the sqlite3_vtab object if successful. */
memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0]));
pVTable->pVtab->pModule = pMod->pModule;
pVTable->nRef = 1;
if( sCtx.pTab ){
@@ -709,9 +697,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);
@@ -1068,9 +1053,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 );
@@ -1086,10 +1068,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: {
+40 -92
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);
@@ -1623,38 +1623,6 @@ static int walPagesize(Wal *pWal){
return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
}
/*
** The following is guaranteed when this function is called:
**
** a) the WRITER lock is held,
** b) the entire log file has been checkpointed, and
** c) any existing readers are reading exclusively from the database
** file - there are no readers that may attempt to read a frame from
** the log file.
**
** This function updates the shared-memory structures so that the next
** client to write to the database (which may be this one) does so by
** writing frames into the start of the log file.
**
** The value of parameter salt1 is used as the aSalt[1] value in the
** new wal-index header. It should be passed a pseudo-random value (i.e.
** one obtained from sqlite3_randomness()).
*/
static void walRestartHdr(Wal *pWal, u32 salt1){
volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
int i; /* Loop counter */
u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */
pWal->nCkpt++;
pWal->hdr.mxFrame = 0;
sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
memcpy(&pWal->hdr.aSalt[1], &salt1, 4);
walIndexWriteHdr(pWal);
pInfo->nBackfill = 0;
pInfo->aReadMark[1] = 0;
for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
assert( pInfo->aReadMark[0]==0 );
}
/*
** Copy as much content as we can from the WAL back into the database file
** in response to an sqlite3_wal_checkpoint() request or the equivalent.
@@ -1689,7 +1657,7 @@ static void walRestartHdr(Wal *pWal, u32 salt1){
static int walCheckpoint(
Wal *pWal, /* Wal connection */
int eMode, /* One of PASSIVE, FULL or RESTART */
int (*xBusy)(void*), /* Function to call when busy */
int (*xBusyCall)(void*), /* Function to call when busy */
void *pBusyArg, /* Context argument for xBusyHandler */
int sync_flags, /* Flags for OsSync() (or 0) */
u8 *zBuf /* Temporary buffer to use */
@@ -1703,6 +1671,7 @@ static int walCheckpoint(
u32 mxPage; /* Max database page to write */
int i; /* Loop counter */
volatile WalCkptInfo *pInfo; /* The checkpoint status information */
int (*xBusy)(void*) = 0; /* Function to call when waiting for locks */
szPage = walPagesize(pWal);
testcase( szPage<=32768 );
@@ -1717,9 +1686,7 @@ static int walCheckpoint(
}
assert( pIter );
/* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
** in the SQLITE_CHECKPOINT_PASSIVE mode. */
assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
if( eMode!=SQLITE_CHECKPOINT_PASSIVE ) xBusy = xBusyCall;
/* Compute in mxSafeFrame the index of the last frame of the WAL that is
** safe to write into the database. Frames beyond mxSafeFrame might
@@ -1808,38 +1775,19 @@ static int walCheckpoint(
rc = SQLITE_OK;
}
/* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the
** entire wal file has been copied into the database file, then block
** until all readers have finished using the wal file. This ensures that
** the next process to write to the database restarts the wal file.
/* If this is an SQLITE_CHECKPOINT_RESTART operation, and the entire wal
** file has been copied into the database file, then block until all
** readers have finished using the wal file. This ensures that the next
** process to write to the database restarts the wal file.
*/
if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){
assert( pWal->writeLock );
if( pInfo->nBackfill<pWal->hdr.mxFrame ){
rc = SQLITE_BUSY;
}else if( eMode>=SQLITE_CHECKPOINT_RESTART ){
u32 salt1;
sqlite3_randomness(4, &salt1);
}else if( eMode==SQLITE_CHECKPOINT_RESTART ){
assert( mxSafeFrame==pWal->hdr.mxFrame );
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1);
if( rc==SQLITE_OK ){
if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){
/* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as
** SQLITE_CHECKPOINT_RESTART with the addition that it also
** truncates the log file to zero bytes just prior to a
** successful return.
**
** In theory, it might be safe to do this without updating the
** wal-index header in shared memory, as all subsequent reader or
** writer clients should see that the entire log file has been
** checkpointed and behave accordingly. This seems unsafe though,
** as it would leave the system in a state where the contents of
** the wal-index header do not match the contents of the
** file-system. To avoid this, update the wal-index header to
** indicate that the log file contains zero valid frames. */
walRestartHdr(pWal, salt1);
rc = sqlite3OsTruncate(pWal->pWalFd, 0);
}
walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
}
}
@@ -2577,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;
}
@@ -2625,6 +2574,7 @@ int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){
return rc;
}
/*
** This function is called just before writing a set of frames to the log
** file (see sqlite3WalFrames()). It checks to see if, instead of appending
@@ -2657,8 +2607,20 @@ static int walRestartLog(Wal *pWal){
** In theory it would be Ok to update the cache of the header only
** at this point. But updating the actual wal-index header is also
** safe and means there is no special case for sqlite3WalUndo()
** to handle if this transaction is rolled back. */
walRestartHdr(pWal, salt1);
** to handle if this transaction is rolled back.
*/
int i; /* Loop counter */
u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */
pWal->nCkpt++;
pWal->hdr.mxFrame = 0;
sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
aSalt[1] = salt1;
walIndexWriteHdr(pWal);
pInfo->nBackfill = 0;
pInfo->aReadMark[1] = 0;
for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
assert( pInfo->aReadMark[0]==0 );
walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
}else if( rc!=SQLITE_BUSY ){
return rc;
@@ -2946,7 +2908,7 @@ int sqlite3WalFrames(
*/
int sqlite3WalCheckpoint(
Wal *pWal, /* Wal connection */
int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */
int eMode, /* PASSIVE, FULL or RESTART */
int (*xBusy)(void*), /* Function to call when busy */
void *pBusyArg, /* Context argument for xBusyHandler */
int sync_flags, /* Flags to sync db file with (or 0) */
@@ -2958,42 +2920,29 @@ int sqlite3WalCheckpoint(
int rc; /* Return code */
int isChanged = 0; /* True if a new wal-index header is loaded */
int eMode2 = eMode; /* Mode to pass to walCheckpoint() */
int (*xBusy2)(void*) = xBusy; /* Busy handler for eMode2 */
assert( pWal->ckptLock==0 );
assert( pWal->writeLock==0 );
/* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
** in the SQLITE_CHECKPOINT_PASSIVE mode. */
assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
if( pWal->readOnly ) return SQLITE_READONLY;
WALTRACE(("WAL%p: checkpoint begins\n", pWal));
/* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
** "checkpoint" lock on the database file. */
rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
if( rc ){
/* EVIDENCE-OF: R-10421-19736 If any other process is running a
** checkpoint operation at the same time, the lock cannot be obtained and
** SQLITE_BUSY is returned.
** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
** it will not be invoked in this case.
*/
testcase( rc==SQLITE_BUSY );
testcase( xBusy!=0 );
/* Usually this is SQLITE_BUSY meaning that another thread or process
** is already running a checkpoint, or maybe a recovery. But it might
** also be SQLITE_IOERR. */
return rc;
}
pWal->ckptLock = 1;
/* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
** TRUNCATE modes also obtain the exclusive "writer" lock on the database
** file.
/* If this is a blocking-checkpoint, then obtain the write-lock as well
** to prevent any writers from running while the checkpoint is underway.
** This has to be done before the call to walIndexReadHdr() below.
**
** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
** immediately, and a busy-handler is configured, it is invoked and the
** writer lock retried until either the busy-handler returns 0 or the
** lock is successfully obtained.
** If the writer lock cannot be obtained, then a passive checkpoint is
** run instead. Since the checkpointer is not holding the writer lock,
** there is no point in blocking waiting for any readers. Assuming no
** other error occurs, this function will return SQLITE_BUSY to the caller.
*/
if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
@@ -3001,7 +2950,6 @@ int sqlite3WalCheckpoint(
pWal->writeLock = 1;
}else if( rc==SQLITE_BUSY ){
eMode2 = SQLITE_CHECKPOINT_PASSIVE;
xBusy2 = 0;
rc = SQLITE_OK;
}
}
@@ -3019,7 +2967,7 @@ int sqlite3WalCheckpoint(
if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
rc = SQLITE_CORRUPT_BKPT;
}else{
rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
rc = walCheckpoint(pWal, eMode2, xBusy, pBusyArg, sync_flags, zBuf);
}
/* If no error occurred, set the output variables. */
+195 -315
View File
File diff suppressed because it is too large Load Diff
+2 -6
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
};
/*
@@ -118,6 +115,7 @@ struct WhereLoop {
union {
struct { /* Information for internal btree tables */
u16 nEq; /* Number of equality constraints */
u16 nSkip; /* Number of initial index columns to skip */
Index *pIndex; /* Index used, or NULL */
} btree;
struct { /* Information for virtual tables */
@@ -130,13 +128,12 @@ struct WhereLoop {
} u;
u32 wsFlags; /* WHERE_* flags describing the plan */
u16 nLTerm; /* Number of entries in aLTerm[] */
u16 nSkip; /* Number of NULL aLTerm[] entries */
/**** whereLoopXfer() copies fields above ***********************/
# define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot)
u16 nLSlot; /* Number of slots allocated for aLTerm[] */
WhereTerm **aLTerm; /* WhereTerms used */
WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */
WhereTerm *aLTermSpace[3]; /* Initial aLTerm[] space */
WhereTerm *aLTermSpace[4]; /* Initial aLTerm[] space */
};
/* This object holds the prerequisites and the cost of running a
@@ -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}
-117
View File
@@ -1,117 +0,0 @@
# 2005 July 22
#
# 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.
# This file implements tests for the ANALYZE command.
#
# $Id: analyze.test,v 1.9 2008/08/11 18:44:58 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix analyzeD
ifcapable {!stat4} {
finish_test
return
}
# Set up a table with the following properties:
#
# * Contains 1000 rows.
# * Column a contains even integers between 0 and 18, inclusive (so that
# a=? for any such integer matches 100 rows).
# * Column b contains integers between 0 and 9, inclusive.
# * Column c contains integers between 0 and 199, inclusive (so that
# for any such integer, c=? matches 5 rows).
# * Then add 7 rows with a new value for "a" - 3001. The stat4 table will
# not contain any samples with a=3001.
#
do_execsql_test 1.0 {
CREATE TABLE t1(a, b, c);
}
do_test 1.1 {
for {set i 1} {$i < 1000} {incr i} {
set c [expr $i % 200]
execsql { INSERT INTO t1(a, b, c) VALUES( 2*($i/100), $i%10, $c ) }
}
execsql {
INSERT INTO t1 VALUES(3001, 3001, 3001);
INSERT INTO t1 VALUES(3001, 3001, 3002);
INSERT INTO t1 VALUES(3001, 3001, 3003);
INSERT INTO t1 VALUES(3001, 3001, 3004);
INSERT INTO t1 VALUES(3001, 3001, 3005);
INSERT INTO t1 VALUES(3001, 3001, 3006);
INSERT INTO t1 VALUES(3001, 3001, 3007);
CREATE INDEX t1_ab ON t1(a, b);
CREATE INDEX t1_c ON t1(c);
ANALYZE;
}
} {}
# With full ANALYZE data, SQLite sees that c=150 (5 rows) is better than
# a=3001 (7 rows).
#
do_eqp_test 1.2 {
SELECT * FROM t1 WHERE a=3001 AND c=150;
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_c (c=?)}
}
do_test 1.3 {
execsql { DELETE FROM sqlite_stat1 }
db close
sqlite3 db test.db
} {}
# Without stat1, because 3001 is larger than all samples in the stat4
# table, SQLite things that a=3001 matches just 1 row. So it (incorrectly)
# chooses it over the c=150 index (5 rows). Even with stat1 data, things
# worked this way before commit [e6f7f97dbc].
#
do_eqp_test 1.4 {
SELECT * FROM t1 WHERE a=3001 AND c=150;
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_ab (a=?)}
}
do_test 1.5 {
execsql {
UPDATE t1 SET a=13 WHERE a = 3001;
ANALYZE;
}
} {}
do_eqp_test 1.6 {
SELECT * FROM t1 WHERE a=13 AND c=150;
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_c (c=?)}
}
do_test 1.7 {
execsql { DELETE FROM sqlite_stat1 }
db close
sqlite3 db test.db
} {}
# Same test as 1.4, except this time the 7 rows that match the a=? condition
# do not feature larger values than all rows in the stat4 table. So SQLite
# gets this right, even without stat1 data.
do_eqp_test 1.8 {
SELECT * FROM t1 WHERE a=13 AND c=150;
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_c (c=?)}
}
finish_test
-242
View File
@@ -1,242 +0,0 @@
# 2014-10-08
#
# 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 tests for using STAT4 information
# on a descending index in a range query.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix analyzeE
ifcapable {!stat4} {
finish_test
return
}
# Verify that range queries on an ASCENDING index will use the
# index only if the range covers only a small fraction of the
# entries.
#
do_execsql_test analyzeE-1.0 {
CREATE TABLE t1(a,b);
WITH RECURSIVE
cnt(x) AS (VALUES(1000) UNION ALL SELECT x+1 FROM cnt WHERE x<2000)
INSERT INTO t1(a,b) SELECT x, x FROM cnt;
CREATE INDEX t1a ON t1(a);
ANALYZE;
} {}
do_execsql_test analyzeE-1.1 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 500 AND 2500;
} {/SCAN TABLE t1/}
do_execsql_test analyzeE-1.2 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 2900 AND 3000;
} {/SEARCH TABLE t1 USING INDEX t1a/}
do_execsql_test analyzeE-1.3 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 1700 AND 1750;
} {/SEARCH TABLE t1 USING INDEX t1a/}
do_execsql_test analyzeE-1.4 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 1 AND 500
} {/SEARCH TABLE t1 USING INDEX t1a/}
do_execsql_test analyzeE-1.5 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 3000 AND 3000000
} {/SEARCH TABLE t1 USING INDEX t1a/}
do_execsql_test analyzeE-1.6 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a<500
} {/SEARCH TABLE t1 USING INDEX t1a/}
do_execsql_test analyzeE-1.7 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a>2500
} {/SEARCH TABLE t1 USING INDEX t1a/}
do_execsql_test analyzeE-1.8 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a>1900
} {/SEARCH TABLE t1 USING INDEX t1a/}
do_execsql_test analyzeE-1.9 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a>1100
} {/SCAN TABLE t1/}
do_execsql_test analyzeE-1.10 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a<1100
} {/SEARCH TABLE t1 USING INDEX t1a/}
do_execsql_test analyzeE-1.11 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a<1900
} {/SCAN TABLE t1/}
# Verify that everything works the same on a DESCENDING index.
#
do_execsql_test analyzeE-2.0 {
DROP INDEX t1a;
CREATE INDEX t1a ON t1(a DESC);
ANALYZE;
} {}
do_execsql_test analyzeE-2.1 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 500 AND 2500;
} {/SCAN TABLE t1/}
do_execsql_test analyzeE-2.2 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 2900 AND 3000;
} {/SEARCH TABLE t1 USING INDEX t1a/}
do_execsql_test analyzeE-2.3 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 1700 AND 1750;
} {/SEARCH TABLE t1 USING INDEX t1a/}
do_execsql_test analyzeE-2.4 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 1 AND 500
} {/SEARCH TABLE t1 USING INDEX t1a/}
do_execsql_test analyzeE-2.5 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 3000 AND 3000000
} {/SEARCH TABLE t1 USING INDEX t1a/}
do_execsql_test analyzeE-2.6 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a<500
} {/SEARCH TABLE t1 USING INDEX t1a/}
do_execsql_test analyzeE-2.7 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a>2500
} {/SEARCH TABLE t1 USING INDEX t1a/}
do_execsql_test analyzeE-2.8 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a>1900
} {/SEARCH TABLE t1 USING INDEX t1a/}
do_execsql_test analyzeE-2.9 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a>1100
} {/SCAN TABLE t1/}
do_execsql_test analyzeE-2.10 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a<1100
} {/SEARCH TABLE t1 USING INDEX t1a/}
do_execsql_test analyzeE-2.11 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a<1900
} {/SCAN TABLE t1/}
# Now do a range query on the second term of an ASCENDING index
# where the first term is constrained by equality.
#
do_execsql_test analyzeE-3.0 {
DROP TABLE t1;
CREATE TABLE t1(a,b,c);
WITH RECURSIVE
cnt(x) AS (VALUES(1000) UNION ALL SELECT x+1 FROM cnt WHERE x<2000)
INSERT INTO t1(a,b,c) SELECT x, x, 123 FROM cnt;
CREATE INDEX t1ca ON t1(c,a);
ANALYZE;
} {}
do_execsql_test analyzeE-3.1 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 500 AND 2500 AND c=123;
} {/SCAN TABLE t1/}
do_execsql_test analyzeE-3.2 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 2900 AND 3000 AND c=123;
} {/SEARCH TABLE t1 USING INDEX t1ca/}
do_execsql_test analyzeE-3.3 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 1700 AND 1750 AND c=123;
} {/SEARCH TABLE t1 USING INDEX t1ca/}
do_execsql_test analyzeE-3.4 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 1 AND 500 AND c=123
} {/SEARCH TABLE t1 USING INDEX t1ca/}
do_execsql_test analyzeE-3.5 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 3000 AND 3000000 AND c=123
} {/SEARCH TABLE t1 USING INDEX t1ca/}
do_execsql_test analyzeE-3.6 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a<500 AND c=123
} {/SEARCH TABLE t1 USING INDEX t1ca/}
do_execsql_test analyzeE-3.7 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a>2500 AND c=123
} {/SEARCH TABLE t1 USING INDEX t1ca/}
do_execsql_test analyzeE-3.8 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a>1900 AND c=123
} {/SEARCH TABLE t1 USING INDEX t1ca/}
do_execsql_test analyzeE-3.9 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a>1100 AND c=123
} {/SCAN TABLE t1/}
do_execsql_test analyzeE-3.10 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a<1100 AND c=123
} {/SEARCH TABLE t1 USING INDEX t1ca/}
do_execsql_test analyzeE-3.11 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a<1900 AND c=123
} {/SCAN TABLE t1/}
# Repeat the 3.x tests using a DESCENDING index
#
do_execsql_test analyzeE-4.0 {
DROP INDEX t1ca;
CREATE INDEX t1ca ON t1(c ASC,a DESC);
ANALYZE;
} {}
do_execsql_test analyzeE-4.1 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 500 AND 2500 AND c=123;
} {/SCAN TABLE t1/}
do_execsql_test analyzeE-4.2 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 2900 AND 3000 AND c=123;
} {/SEARCH TABLE t1 USING INDEX t1ca/}
do_execsql_test analyzeE-4.3 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 1700 AND 1750 AND c=123;
} {/SEARCH TABLE t1 USING INDEX t1ca/}
do_execsql_test analyzeE-4.4 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 1 AND 500 AND c=123
} {/SEARCH TABLE t1 USING INDEX t1ca/}
do_execsql_test analyzeE-4.5 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a BETWEEN 3000 AND 3000000 AND c=123
} {/SEARCH TABLE t1 USING INDEX t1ca/}
do_execsql_test analyzeE-4.6 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a<500 AND c=123
} {/SEARCH TABLE t1 USING INDEX t1ca/}
do_execsql_test analyzeE-4.7 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a>2500 AND c=123
} {/SEARCH TABLE t1 USING INDEX t1ca/}
do_execsql_test analyzeE-4.8 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a>1900 AND c=123
} {/SEARCH TABLE t1 USING INDEX t1ca/}
do_execsql_test analyzeE-4.9 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a>1100 AND c=123
} {/SCAN TABLE t1/}
do_execsql_test analyzeE-4.10 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a<1100 AND c=123
} {/SEARCH TABLE t1 USING INDEX t1ca/}
do_execsql_test analyzeE-4.11 {
EXPLAIN QUERY PLAN
SELECT * FROM t1 WHERE a<1900 AND c=123
} {/SCAN TABLE t1/}
finish_test
+44
View File
@@ -224,4 +224,48 @@ do_execsql_test autoindex2-120 {
# on t3 and reordering the tables so that t3 was in the outer loop and
# implementing the ORDER BY clause using a B-Tree.
do_execsql_test autoindex2-120 {
EXPLAIN QUERY PLAN
SELECT
t1_id,
t1.did,
param2,
param3,
t1.ptime,
t1.trange,
t1.exmass,
t1.mass,
t1.vstatus,
type,
subtype,
t1.deviation,
t1.formula,
dparam1,
reserve1,
reserve2,
param4,
t1.last_operation,
t1.admin_uuid,
t1.previous_value,
t1.job_id,
client_did,
t1.last_t1,
t1.data_t1,
t1.previous_date,
param5,
param6,
mgr_uuid
FROM
t3,
t2,
t1
WHERE
t1.ptime > 1393520400
AND param3<>9001
AND t3.flg7 = 1
AND t1.did = t2.did
AND t2.uid = t3.uid
ORDER BY t1.ptime desc LIMIT 500;
} {0 0 2 {SEARCH TABLE t1 USING INDEX t1x1 (ptime>?)} 0 1 1 {SEARCH TABLE t2 USING INDEX t2x0 (did=?)} 0 2 0 {SEARCH TABLE t3 USING INDEX t3x0 (uid=?)}}
finish_test
-34
View File
@@ -17,7 +17,6 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix autoindex3
# The t1b and t2d indexes are not very selective. It used to be that
# the autoindex mechanism would create automatic indexes on t1(b) or
@@ -55,38 +54,5 @@ do_execsql_test autoindex3-140 {
EXPLAIN QUERY PLAN SELECT * FROM t1, t2 WHERE d IN (5,b) AND x=y;
} {/AUTO/}
reset_db
do_execsql_test 210 {
CREATE TABLE v(b, d, e);
CREATE TABLE u(a, b, c);
ANALYZE sqlite_master;
INSERT INTO "sqlite_stat1" VALUES('u','uab','40000 400 1');
INSERT INTO "sqlite_stat1" VALUES('v','vbde','40000 400 1 1');
INSERT INTO "sqlite_stat1" VALUES('v','ve','40000 21');
CREATE INDEX uab on u(a, b);
CREATE INDEX ve on v(e);
CREATE INDEX vbde on v(b,d,e);
DROP TABLE IF EXISTS sqlite_stat4;
ANALYZE sqlite_master;
}
# At one point, SQLite was using the inferior plan:
#
# 0|0|1|SEARCH TABLE v USING INDEX ve (e>?)
# 0|1|0|SEARCH TABLE u USING COVERING INDEX uab (ANY(a) AND b=?)
#
# on the basis that the real index "uab" must be better than the automatic
# index. This is not right - a skip-scan is not necessarily better than an
# automatic index scan.
#
do_eqp_test 220 {
select count(*) from u, v where u.b = v.b and v.e > 34;
} {
0 0 1 {SEARCH TABLE v USING INDEX ve (e>?)}
0 1 0 {SEARCH TABLE u USING AUTOMATIC COVERING INDEX (b=?)}
}
finish_test
-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
-43
View File
@@ -1,43 +0,0 @@
# 2014 November 26
#
# 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 bigsort
#--------------------------------------------------------------------
# At one point there was an overflow problem if the product of the
# cache-size and page-size was larger than 2^31. Causing an infinite
# loop if the product was also an integer multiple of 2^32, or
# inefficiency otherwise.
#
do_execsql_test 1.0 {
PRAGMA page_size = 1024;
CREATE TABLE t1(a, b);
BEGIN;
WITH data(x,y) AS (
SELECT 1, zeroblob(10000)
UNION ALL
SELECT x+1, y FROM data WHERE x < 300000
)
INSERT INTO t1 SELECT * FROM data;
COMMIT;
}
do_execsql_test 1.1 {
PRAGMA cache_size = 4194304;
CREATE INDEX i1 ON t1(a, b);
}
finish_test
-132
View File
@@ -1,132 +0,0 @@
# 2014-11-27
#
# 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 contains test cases for b-tree logic.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix btree01
# The refactoring on the b-tree balance() routine in check-in
# http://www.sqlite.org/src/info/face33bea1ba3a (2014-10-27)
# caused the integrity_check on the following SQL to fail.
#
do_execsql_test btree01-1.1 {
PRAGMA page_size=65536;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b BLOB);
WITH RECURSIVE
c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30)
INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c;
UPDATE t1 SET b=zeroblob(3000);
UPDATE t1 SET b=zeroblob(64000) WHERE a=2;
PRAGMA integrity_check;
} {ok}
# The previous test is sufficient to prevent a regression. But we
# add a number of additional tests to stress the balancer in similar
# ways, looking for related problems.
#
for {set i 1} {$i<=30} {incr i} {
do_test btree01-1.2.$i {
db eval {
DELETE FROM t1;
WITH RECURSIVE
c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30)
INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c;
UPDATE t1 SET b=zeroblob(3000);
UPDATE t1 SET b=zeroblob(64000) WHERE a=$::i;
PRAGMA integrity_check;
}
} {ok}
}
for {set i 1} {$i<=30} {incr i} {
do_test btree01-1.3.$i {
db eval {
DELETE FROM t1;
WITH RECURSIVE
c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30)
INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c;
UPDATE t1 SET b=zeroblob(2000);
UPDATE t1 SET b=zeroblob(64000) WHERE a=$::i;
PRAGMA integrity_check;
}
} {ok}
}
for {set i 1} {$i<=30} {incr i} {
do_test btree01-1.4.$i {
db eval {
DELETE FROM t1;
WITH RECURSIVE
c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30)
INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c;
UPDATE t1 SET b=zeroblob(6499) WHERE (a%3)==0;
UPDATE t1 SET b=zeroblob(6499) WHERE (a%3)==1;
UPDATE t1 SET b=zeroblob(6499) WHERE (a%3)==2;
UPDATE t1 SET b=zeroblob(64000) WHERE a=$::i;
PRAGMA integrity_check;
}
} {ok}
}
for {set i 1} {$i<=30} {incr i} {
do_test btree01-1.5.$i {
db eval {
DELETE FROM t1;
WITH RECURSIVE
c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30)
INSERT INTO t1(a,b) SELECT i, zeroblob(6542) FROM c;
UPDATE t1 SET b=zeroblob(2331);
UPDATE t1 SET b=zeroblob(65496) WHERE a=$::i;
PRAGMA integrity_check;
}
} {ok}
}
for {set i 1} {$i<=30} {incr i} {
do_test btree01-1.6.$i {
db eval {
DELETE FROM t1;
WITH RECURSIVE
c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30)
INSERT INTO t1(a,b) SELECT i, zeroblob(6542) FROM c;
UPDATE t1 SET b=zeroblob(2332);
UPDATE t1 SET b=zeroblob(65496) WHERE a=$::i;
PRAGMA integrity_check;
}
} {ok}
}
for {set i 1} {$i<=30} {incr i} {
do_test btree01-1.7.$i {
db eval {
DELETE FROM t1;
WITH RECURSIVE
c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30)
INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c;
UPDATE t1 SET b=zeroblob(1);
UPDATE t1 SET b=zeroblob(65000) WHERE a=$::i;
PRAGMA integrity_check;
}
} {ok}
}
for {set i 1} {$i<=31} {incr i} {
do_test btree01-1.8.$i {
db eval {
DELETE FROM t1;
WITH RECURSIVE
c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<31)
INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c;
UPDATE t1 SET b=zeroblob(4000);
UPDATE t1 SET b=zeroblob(65000) WHERE a=$::i;
PRAGMA integrity_check;
}
} {ok}
}
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) } {
+27 -30
View File
@@ -75,34 +75,31 @@ do_test 2.2 {
catchsql { SELECT * FROM r WHERE x >= 10 }
} {1 {database disk image is malformed}}
if {[db one {SELECT sqlite_compileoption_used('ENABLE_OVERSIZE_CELL_CHECK')}]} {
# The following tests only work if OVERSIZE_CELL_CHECK is disabled
} else {
reset_db
do_execsql_test 3.1 {
PRAGMA auto_vacuum=0;
PRAGMA page_size = 512;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
WITH s(a, b) AS (
SELECT 2, 'abcdefghij'
UNION ALL
SELECT a+2, b FROM s WHERe a < 40
)
INSERT INTO t1 SELECT * FROM s;
} {}
do_test 3.2 {
hexio_write test.db [expr 512+3] 0054
db close
sqlite3 db test.db
execsql { INSERT INTO t1 VALUES(5, 'klmnopqrst') }
execsql { INSERT INTO t1 VALUES(7, 'klmnopqrst') }
} {}
db close
sqlite3 db test.db
do_catchsql_test 3.3 {
INSERT INTO t1 VALUES(9, 'klmnopqrst');
} {1 {database disk image is malformed}}
} ;# end-if !defined(ENABLE_OVERSIZE_CELL_CHECK)
reset_db
do_execsql_test 3.1 {
PRAGMA page_size = 512;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
WITH s(a, b) AS (
SELECT 2, 'abcdefghij'
UNION ALL
SELECT a+2, b FROM s WHERe a < 40
)
INSERT INTO t1 SELECT * FROM s;
} {}
do_test 3.2 {
hexio_write test.db [expr 512+3] 0054
db close
sqlite3 db test.db
execsql { INSERT INTO t1 VALUES(5, 'klmnopqrst') }
execsql { INSERT INTO t1 VALUES(7, 'klmnopqrst') }
} {}
db close
sqlite3 db test.db
do_catchsql_test 3.2 {
INSERT INTO t1 VALUES(9, 'klmnopqrst');
} {1 {database disk image is malformed}}
finish_test
-30
View File
@@ -222,34 +222,4 @@ do_execsql_test 4.1 {
SELECT quote(x) FROM t2 ORDER BY 1;
} {'xyzzy' X'0000000000'}
#----------------------------------------------------------------------------
# Ticket [c5ea805691bfc4204b1cb9e9aa0103bd48bc7d34] (2014-12-04)
# Make sure that DISTINCT works together with ORDER BY and descending
# indexes.
#
do_execsql_test 5.1 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(x);
INSERT INTO t1(x) VALUES(3),(1),(5),(2),(6),(4),(5),(1),(3);
CREATE INDEX t1x ON t1(x DESC);
SELECT DISTINCT x FROM t1 ORDER BY x ASC;
} {1 2 3 4 5 6}
do_execsql_test 5.2 {
SELECT DISTINCT x FROM t1 ORDER BY x DESC;
} {6 5 4 3 2 1}
do_execsql_test 5.3 {
SELECT DISTINCT x FROM t1 ORDER BY x;
} {1 2 3 4 5 6}
do_execsql_test 5.4 {
DROP INDEX t1x;
CREATE INDEX t1x ON t1(x ASC);
SELECT DISTINCT x FROM t1 ORDER BY x ASC;
} {1 2 3 4 5 6}
do_execsql_test 5.5 {
SELECT DISTINCT x FROM t1 ORDER BY x DESC;
} {6 5 4 3 2 1}
do_execsql_test 5.6 {
SELECT DISTINCT x FROM t1 ORDER BY x;
} {1 2 3 4 5 6}
finish_test
-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
+7 -8
View File
@@ -862,11 +862,11 @@ do_createtable_tests 3.2.3 -query {
3 "INSERT INTO t1 DEFAULT VALUES" {NULL NULL NULL}
}
# EVIDENCE-OF: R-07343-35026 An explicit DEFAULT clause may specify that
# EVIDENCE-OF: R-62940-43005 An explicit DEFAULT clause may specify that
# the default value is NULL, a string constant, a blob constant, a
# signed-number, or any constant expression enclosed in parentheses. A
# default value may also be one of the special case-independent keywords
# CURRENT_TIME, CURRENT_DATE or CURRENT_TIMESTAMP.
# signed-number, or any constant expression enclosed in parentheses. An
# explicit default value may also be one of the special case-independent
# keywords CURRENT_TIME, CURRENT_DATE or CURRENT_TIMESTAMP.
#
do_execsql_test e_createtable-3.3.1 {
CREATE TABLE t4(
@@ -884,9 +884,9 @@ do_execsql_test e_createtable-3.3.1 {
);
} {}
# EVIDENCE-OF: R-18415-27776 For the purposes of the DEFAULT clause, an
# expression is considered constant if it does contains no sub-queries,
# column or table references, bound parameters, or string literals
# EVIDENCE-OF: R-36381-62919 For the purposes of the DEFAULT clause, an
# expression is considered constant provided that it does not contain
# any sub-queries, column or table references, or string literals
# enclosed in double-quotes instead of single-quotes.
#
do_createtable_tests 3.4.1 -error {
@@ -896,7 +896,6 @@ do_createtable_tests 3.4.1 -error {
2 {CREATE TABLE t5(x DEFAULT ( "abc" ))} {}
3 {CREATE TABLE t5(x DEFAULT ( 1 IN (SELECT 1) ))} {}
4 {CREATE TABLE t5(x DEFAULT ( EXISTS (SELECT 1) ))} {}
5 {CREATE TABLE t5(x DEFAULT ( x!=?1 ))} {}
}
do_createtable_tests 3.4.2 -repair {
catchsql { DROP TABLE t5 }
-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
-3
View File
@@ -125,9 +125,6 @@ if {$tcl_platform(platform) == "unix"} {
sqlite3_shutdown
sqlite3_config_uri 1
# EVIDENCE-OF: R-06842-00595 If the URI contains an authority, then it
# must be either an empty string or the string "localhost".
#
# EVIDENCE-OF: R-17482-00398 If the authority is not an empty string or
# "localhost", an error is returned to the caller.
#
-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
-4
View File
@@ -205,10 +205,6 @@ test_expr expr-1.125 {i1=6, i2=NULL} \
test_expr expr-1.126 {i1=8, i2=8} \
{CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} no
do_catchsql_test expr-1.127 {
SELECT 1 IS #1;
} {1 {near "#1": syntax error}}
ifcapable floatingpoint {if {[working_64bit_int]} {
test_expr expr-1.200\
{i1=9223372036854775806, i2=1} {i1+i2} 9223372036854775807
-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
+3 -28
View File
@@ -24,16 +24,12 @@ ifcapable !fts3||!icu {
set sqlite_fts3_enable_parentheses 1
proc test_fts3expr {tokenizer expr} {
db one {SELECT fts3_exprtest($tokenizer, $expr, 'a', 'b', 'c')}
proc test_icu_fts3expr {expr} {
db one {SELECT fts3_exprtest('icu', $expr, 'a', 'b', 'c')}
}
proc do_icu_expr_test {tn expr res} {
uplevel [list do_test $tn [list test_fts3expr icu $expr] [list {*}$res]]
}
proc do_simple_expr_test {tn expr res} {
uplevel [list do_test $tn [list test_fts3expr simple $expr] [list {*}$res]]
uplevel [list do_test $tn [list test_icu_fts3expr $expr] $res]
}
#-------------------------------------------------------------------------
@@ -57,26 +53,5 @@ do_icu_expr_test 2.1 {
f (e NEAR/2 a)
} {AND {AND {AND {PHRASE 3 0 f} {PHRASE 3 0 (}} {NEAR/2 {PHRASE 3 0 e} {PHRASE 3 0 a}}} {PHRASE 3 0 )}}
#-------------------------------------------------------------------------
#
do_simple_expr_test 3.1 {*lOl* *h4h*} {
AND {PHRASE 3 0 lol+} {PHRASE 3 0 h4h+}
}
do_icu_expr_test 3.2 {*lOl* *h4h*} {
AND {AND {AND {PHRASE 3 0 *} {PHRASE 3 0 lol+}} {PHRASE 3 0 *}} {PHRASE 3 0 h4h+}
}
do_simple_expr_test 3.3 { * } { }
do_simple_expr_test 3.4 { *a } { PHRASE 3 0 a }
do_simple_expr_test 3.5 { a*b } { AND {PHRASE 3 0 a+} {PHRASE 3 0 b} }
do_simple_expr_test 3.6 { *a*b } { AND {PHRASE 3 0 a+} {PHRASE 3 0 b} }
do_simple_expr_test 3.7 { *"abc" } { PHRASE 3 0 abc }
do_simple_expr_test 3.8 { "abc"* } { PHRASE 3 0 abc }
do_simple_expr_test 3.8 { "ab*c" } { PHRASE 3 0 ab+ c }
do_icu_expr_test 3.9 { "ab*c" } { PHRASE 3 0 ab+ * c }
do_icu_expr_test 3.10 { ab*c } { AND {PHRASE 3 0 ab+} {PHRASE 3 0 c}}
finish_test

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