Compare commits

..

2 Commits

Author SHA1 Message Date
drh 52afa8ff09 Merge the latest trunk changes, especially the RTREE enhancement to use
sqlite3_blob objects.

FossilOrigin-Name: 61bd2a885da45e7fa4f02ea1c44d6706faa6bf46
2017-02-04 14:30:57 +00:00
drh c5fd65d3f7 Add the sqlite3_blob_reset() interface. Enhance the behavior of sqlite3_blob
objects so that they can go active again after encountering an error by
rerunning sqlite3_blob_reopen().  More work needed on the documentation.

FossilOrigin-Name: 53b77838f05b4805b956b5763c75af434662fb20
2017-02-02 23:57:40 +00:00
95 changed files with 1083 additions and 4971 deletions
-1
View File
@@ -566,7 +566,6 @@ SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
DBFUZZ_OPT =
+14 -30
View File
@@ -745,7 +745,6 @@ RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
!IF $(DEBUG)>2
TCC = $(TCC) -DSQLITE_DEBUG=1
TCC = $(TCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE
RCC = $(RCC) -DSQLITE_DEBUG=1
!ENDIF
@@ -1510,13 +1509,9 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_
#
MPTESTER_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS5
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
KV_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
DBSELFTEST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
ST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0
# Standard options to testfixture.
#
@@ -1559,7 +1554,7 @@ $(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
sqlite3.def: libsqlite3.lib
echo EXPORTS > sqlite3.def
dumpbin /all libsqlite3.lib \
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset)?_[^@]*)(?:@\d+)?$$" \1 \
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_[^@]*)(?:@\d+)?$$" \1 \
| sort >> sqlite3.def
# <</block2>>
@@ -1586,9 +1581,6 @@ sourcetest: srcck1.exe sqlite3.c
fuzzershell.exe: $(TOP)\tool\fuzzershell.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) $(TOP)\tool\fuzzershell.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
dbfuzz.exe: $(TOP)\test\dbfuzz.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(DBFUZZ_COMPILE_OPTS) $(TOP)\test\dbfuzz.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
fuzzcheck.exe: $(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
@@ -2185,54 +2177,46 @@ testloadext.dll: testloadext.lo
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo
showdb.exe: $(TOP)\tool\showdb.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\tool\showdb.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
showstat4.exe: $(TOP)\tool\showstat4.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\tool\showstat4.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
showjournal.exe: $(TOP)\tool\showjournal.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\tool\showjournal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
showwal.exe: $(TOP)\tool\showwal.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\tool\showwal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
changeset.exe: $(TOP)\ext\session\changeset.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 \
changeset.exe: $(TOP)\ext\session\changeset.c $(SQLITE3C)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\ext\session\changeset.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
fts3view.exe: $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
rollback-test.exe: $(TOP)\tool\rollback-test.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\tool\rollback-test.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
LogEst.exe: $(TOP)\tool\logest.c $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS)
$(LTLINK) $(NO_WARN) -Fe$@ $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS)
wordcount.exe: $(TOP)\test\wordcount.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\test\wordcount.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
speedtest1.exe: $(TOP)\test\speedtest1.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(ST_COMPILE_OPTS) -DSQLITE_OMIT_LOAD_EXTENSION \
$(LTLINK) $(NO_WARN) -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\test\speedtest1.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
kvtest.exe: $(TOP)\test\kvtest.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(KV_COMPILE_OPTS) \
$(TOP)\test\kvtest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
dbselftest.exe: $(TOP)\test\dbselftest.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(DBSELFTEST_COMPILE_OPTS) $(TOP)\test\dbselftest.c $(SQLITE3C)
rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU \
$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU -Fe$@ \
$(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
moreclean: clean
+1 -1
View File
@@ -1 +1 @@
3.18.0
3.17.0
+1 -1
View File
@@ -950,7 +950,7 @@ Replace.exe:
sqlite3.def: Replace.exe $(LIBOBJ)
echo EXPORTS > sqlite3.def
dumpbin /all $(LIBOBJ) \
| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
| .\Replace.exe "^\s+/EXPORT:_?(sqlite3_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
| sort >> sqlite3.def
$(SQLITE3EXE): $(TOP)\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
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.69 for sqlite 3.18.0.
# Generated by GNU Autoconf 2.69 for sqlite 3.17.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -726,8 +726,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.18.0'
PACKAGE_STRING='sqlite 3.18.0'
PACKAGE_VERSION='3.17.0'
PACKAGE_STRING='sqlite 3.17.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1463,7 +1463,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.18.0 to adapt to many kinds of systems.
\`configure' configures sqlite 3.17.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1528,7 +1528,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.18.0:";;
short | recursive ) echo "Configuration of sqlite 3.17.0:";;
esac
cat <<\_ACEOF
@@ -1652,7 +1652,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.18.0
sqlite configure 3.17.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2071,7 +2071,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.18.0, which was
It was created by sqlite $as_me 3.17.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -12151,7 +12151,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=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.18.0, which was
This file was extended by sqlite $as_me 3.17.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -12217,7 +12217,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
sqlite config.status 3.18.0
sqlite config.status 3.17.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
+15 -40
View File
@@ -492,7 +492,6 @@ static int fts3DisconnectMethod(sqlite3_vtab *pVtab){
assert( p->pSegments==0 );
/* Free any prepared statements held */
sqlite3_finalize(p->pSeekStmt);
for(i=0; i<SizeofArray(p->aStmt); i++){
sqlite3_finalize(p->aStmt[i]);
}
@@ -1681,26 +1680,6 @@ static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
return SQLITE_OK;
}
/*
** Finalize the statement handle at pCsr->pStmt.
**
** Or, if that statement handle is one created by fts3CursorSeekStmt(),
** and the Fts3Table.pSeekStmt slot is currently NULL, save the statement
** pointer there instead of finalizing it.
*/
static void fts3CursorFinalizeStmt(Fts3Cursor *pCsr){
if( pCsr->bSeekStmt ){
Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
if( p->pSeekStmt==0 ){
p->pSeekStmt = pCsr->pStmt;
sqlite3_reset(pCsr->pStmt);
pCsr->pStmt = 0;
}
pCsr->bSeekStmt = 0;
}
sqlite3_finalize(pCsr->pStmt);
}
/*
** Close the cursor. For additional information see the documentation
** on the xClose method of the virtual table interface.
@@ -1708,7 +1687,7 @@ static void fts3CursorFinalizeStmt(Fts3Cursor *pCsr){
static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
Fts3Cursor *pCsr = (Fts3Cursor *)pCursor;
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
fts3CursorFinalizeStmt(pCsr);
sqlite3_finalize(pCsr->pStmt);
sqlite3Fts3ExprFree(pCsr->pExpr);
sqlite3Fts3FreeDeferredTokens(pCsr);
sqlite3_free(pCsr->aDoclist);
@@ -1726,23 +1705,20 @@ static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
**
** (or the equivalent for a content=xxx table) and set pCsr->pStmt to
** it. If an error occurs, return an SQLite error code.
**
** Otherwise, set *ppStmt to point to pCsr->pStmt and return SQLITE_OK.
*/
static int fts3CursorSeekStmt(Fts3Cursor *pCsr){
static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){
int rc = SQLITE_OK;
if( pCsr->pStmt==0 ){
Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
char *zSql;
if( p->pSeekStmt ){
pCsr->pStmt = p->pSeekStmt;
p->pSeekStmt = 0;
}else{
zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
if( !zSql ) return SQLITE_NOMEM;
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
sqlite3_free(zSql);
}
if( rc==SQLITE_OK ) pCsr->bSeekStmt = 1;
zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
if( !zSql ) return SQLITE_NOMEM;
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
sqlite3_free(zSql);
}
*ppStmt = pCsr->pStmt;
return rc;
}
@@ -1754,7 +1730,9 @@ static int fts3CursorSeekStmt(Fts3Cursor *pCsr){
static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
int rc = SQLITE_OK;
if( pCsr->isRequireSeek ){
rc = fts3CursorSeekStmt(pCsr);
sqlite3_stmt *pStmt = 0;
rc = fts3CursorSeekStmt(pCsr, &pStmt);
if( rc==SQLITE_OK ){
sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
pCsr->isRequireSeek = 0;
@@ -3212,7 +3190,7 @@ static int fts3FilterMethod(
assert( iIdx==nVal );
/* In case the cursor has been used before, clear it now. */
fts3CursorFinalizeStmt(pCsr);
sqlite3_finalize(pCsr->pStmt);
sqlite3_free(pCsr->aDoclist);
sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
sqlite3Fts3ExprFree(pCsr->pExpr);
@@ -3280,7 +3258,7 @@ static int fts3FilterMethod(
rc = SQLITE_NOMEM;
}
}else if( eSearch==FTS3_DOCID_SEARCH ){
rc = fts3CursorSeekStmt(pCsr);
rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt);
if( rc==SQLITE_OK ){
rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons);
}
@@ -3408,10 +3386,8 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
const u32 nMinMerge = 64; /* Minimum amount of incr-merge work to do */
Fts3Table *p = (Fts3Table*)pVtab;
int rc;
i64 iLastRowid = sqlite3_last_insert_rowid(p->db);
int rc = sqlite3Fts3PendingTermsFlush(p);
rc = sqlite3Fts3PendingTermsFlush(p);
if( rc==SQLITE_OK
&& p->nLeafAdd>(nMinMerge/16)
&& p->nAutoincrmerge && p->nAutoincrmerge!=0xff
@@ -3426,7 +3402,6 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge);
}
sqlite3Fts3SegmentsClose(p);
sqlite3_set_last_insert_rowid(p->db, iLastRowid);
return rc;
}
-2
View File
@@ -230,7 +230,6 @@ struct Fts3Table {
** statements is run and reset within a single virtual table API call.
*/
sqlite3_stmt *aStmt[40];
sqlite3_stmt *pSeekStmt; /* Cache for fts3CursorSeekStmt() */
char *zReadExprlist;
char *zWriteExprlist;
@@ -300,7 +299,6 @@ struct Fts3Cursor {
i16 eSearch; /* Search strategy (see below) */
u8 isEof; /* True if at End Of Results */
u8 isRequireSeek; /* True if must seek pStmt to %_content row */
u8 bSeekStmt; /* True if pStmt is a seek */
sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */
Fts3Expr *pExpr; /* Parsed MATCH query string */
int iLangid; /* Language being queried for */
+1 -3
View File
@@ -30,9 +30,7 @@ typedef short i16;
typedef sqlite3_int64 i64;
typedef sqlite3_uint64 u64;
#ifndef ArraySize
# define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
#endif
#define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
#define testcase(x)
#define ALWAYS(x) 1
+2 -13
View File
@@ -1110,10 +1110,7 @@ static int fts5ExprNodeNext_OR(
|| (bFromValid && fts5RowidCmp(pExpr, p1->iRowid, iFrom)<0)
){
int rc = fts5ExprNodeNext(pExpr, p1, bFromValid, iFrom);
if( rc!=SQLITE_OK ){
pNode->bNomatch = 0;
return rc;
}
if( rc!=SQLITE_OK ) return rc;
}
}
}
@@ -1144,10 +1141,7 @@ static int fts5ExprNodeTest_AND(
if( cmp>0 ){
/* Advance pChild until it points to iLast or laster */
rc = fts5ExprNodeNext(pExpr, pChild, 1, iLast);
if( rc!=SQLITE_OK ){
pAnd->bNomatch = 0;
return rc;
}
if( rc!=SQLITE_OK ) return rc;
}
/* If the child node is now at EOF, so is the parent AND node. Otherwise,
@@ -1186,8 +1180,6 @@ static int fts5ExprNodeNext_AND(
int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom);
if( rc==SQLITE_OK ){
rc = fts5ExprNodeTest_AND(pExpr, pNode);
}else{
pNode->bNomatch = 0;
}
return rc;
}
@@ -1230,9 +1222,6 @@ static int fts5ExprNodeNext_NOT(
if( rc==SQLITE_OK ){
rc = fts5ExprNodeTest_NOT(pExpr, pNode);
}
if( rc!=SQLITE_OK ){
pNode->bNomatch = 0;
}
return rc;
}
+15 -10
View File
@@ -545,6 +545,11 @@ int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){
}
}
/* Write the averages record */
if( rc==SQLITE_OK ){
rc = fts5StorageSaveTotals(p);
}
return rc;
}
@@ -748,6 +753,11 @@ int sqlite3Fts5StorageIndexInsert(
}
sqlite3_free(buf.p);
/* Write the averages record */
if( rc==SQLITE_OK ){
rc = fts5StorageSaveTotals(p);
}
return rc;
}
@@ -1082,17 +1092,12 @@ int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){
** Flush any data currently held in-memory to disk.
*/
int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit){
int rc = SQLITE_OK;
i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db);
if( p->bTotalsValid ){
rc = fts5StorageSaveTotals(p);
if( bCommit ) p->bTotalsValid = 0;
if( bCommit && p->bTotalsValid ){
int rc = fts5StorageSaveTotals(p);
p->bTotalsValid = 0;
if( rc!=SQLITE_OK ) return rc;
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5IndexSync(p->pIndex, bCommit);
}
sqlite3_set_last_insert_rowid(p->pConfig->db, iLastRowid);
return rc;
return sqlite3Fts5IndexSync(p->pIndex, bCommit);
}
int sqlite3Fts5StorageRollback(Fts5Storage *p){
-87
View File
@@ -1,87 +0,0 @@
# 2016 February 2
#
# 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 is focused on OOM errors.
#
source [file join [file dirname [info script]] fts5_common.tcl]
source $testdir/malloc_common.tcl
set testprefix fts5faultA
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
foreach_detail_mode $testprefix {
if {"%DETAIL%"=="none"} continue
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE o1 USING fts5(a, b, c, detail=%DETAIL%);
INSERT INTO o1(o1, rank) VALUES('pgsz', 32);
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 )
INSERT INTO o1 SELECT 'A', 'B', 'C' FROM s;
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 )
INSERT INTO o1 SELECT 'C', 'A', 'B' FROM s;
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 )
INSERT INTO o1 SELECT 'B', 'C', 'A' FROM s;
}
do_faultsim_test 1 -faults int* -prep {
sqlite3 db test.db
} -body {
execsql { SELECT count(*) FROM o1('a') }
} -test {
faultsim_test_result {0 180} {1 {vtable constructor failed: o1}}
}
do_faultsim_test 2 -faults int* -prep {
sqlite3 db test.db
} -body {
execsql { SELECT * FROM o1('a:a AND {b c}:b') ORDER BY rank }
expr 1
} -test {
faultsim_test_result {0 1} {1 {vtable constructor failed: o1}}
}
do_faultsim_test 3 -faults int* -prep {
sqlite3 db test.db
} -body {
execsql { SELECT * FROM o1('{b c}:b NOT a:a') ORDER BY rank }
expr 1
} -test {
faultsim_test_result {0 1} {1 {vtable constructor failed: o1}}
}
do_faultsim_test 4 -faults int* -prep {
sqlite3 db test.db
} -body {
execsql { SELECT * FROM o1('b:b OR a:a') }
expr 1
} -test {
faultsim_test_result {0 1} {1 {vtable constructor failed: o1}}
}
do_faultsim_test 5 -faults int* -prep {
sqlite3 db test.db
} -body {
execsql { SELECT count(*) FROM o1('c:b') }
expr 1
} -test {
faultsim_test_result {0 1} {1 {vtable constructor failed: o1}}
}
}
finish_test
-73
View File
@@ -1,73 +0,0 @@
# 2017 Feb 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.
#
#***********************************************************************
#
# Tests of the last_insert_rowid functionality with fts5.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5lastrowid
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(str);
}
do_execsql_test 1.1 {
INSERT INTO t1 VALUES('one string');
INSERT INTO t1 VALUES('two string');
INSERT INTO t1 VALUES('three string');
SELECT last_insert_rowid();
} {3}
do_execsql_test 1.2 {
BEGIN;
INSERT INTO t1 VALUES('one string');
INSERT INTO t1 VALUES('two string');
INSERT INTO t1 VALUES('three string');
COMMIT;
SELECT last_insert_rowid();
} {6}
do_execsql_test 1.3 {
INSERT INTO t1(rowid, str) VALUES(-22, 'some more text');
SELECT last_insert_rowid();
} {-22}
do_execsql_test 1.4 {
BEGIN;
INSERT INTO t1(rowid, str) VALUES(45, 'some more text');
INSERT INTO t1(rowid, str) VALUES(46, 'some more text');
INSERT INTO t1(rowid, str) VALUES(222, 'some more text');
SELECT last_insert_rowid();
COMMIT;
SELECT last_insert_rowid();
} {222 222}
do_execsql_test 1.5 {
CREATE TABLE x1(x);
INSERT INTO x1 VALUES('john'), ('paul'), ('george'), ('ringo');
INSERT INTO t1 SELECT x FROM x1;
SELECT last_insert_rowid();
} {226}
do_execsql_test 1.6 {
INSERT INTO t1(rowid, str) SELECT rowid+10, x FROM x1;
SELECT last_insert_rowid();
} {14}
finish_test
-710
View File
@@ -1,710 +0,0 @@
/*
** 2017-03-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 SQLite extension implements a functions that compute SHA1 hashes.
** Two SQL functions are implemented:
**
** sha3(X,SIZE)
** sha3_query(Y,SIZE)
**
** The sha3(X) function computes the SHA3 hash of the input X, or NULL if
** X is NULL.
**
** The sha3_query(Y) function evalutes all queries in the SQL statements of Y
** and returns a hash of their results.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#include <stdarg.h>
typedef sqlite3_uint64 u64;
/******************************************************************************
** The Hash Engine
*/
/*
** Macros to determine whether the machine is big or little endian,
** and whether or not that determination is run-time or compile-time.
**
** For best performance, an attempt is made to guess at the byte-order
** using C-preprocessor macros. If that is unsuccessful, or if
** -DSHA3_BYTEORDER=0 is set, then byte-order is determined
** at run-time.
*/
#ifndef SHA3_BYTEORDER
# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
defined(__arm__)
# define SHA3_BYTEORDER 1234
# elif defined(sparc) || defined(__ppc__)
# define SHA3_BYTEORDER 4321
# else
# define SHA3_BYTEORDER 0
# endif
#endif
/*
** State structure for a SHA3 hash in progress
*/
typedef struct SHA3Context SHA3Context;
struct SHA3Context {
union {
u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */
unsigned char x[1600]; /* ... or 1600 bytes */
} u;
unsigned nRate; /* Bytes of input accepted per Keccak iteration */
unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */
unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */
};
/*
** A single step of the Keccak mixing function for a 1600-bit state
*/
static void KeccakF1600Step(SHA3Context *p){
int i;
u64 B0, B1, B2, B3, B4;
u64 C0, C1, C2, C3, C4;
u64 D0, D1, D2, D3, D4;
static const u64 RC[] = {
0x0000000000000001ULL, 0x0000000000008082ULL,
0x800000000000808aULL, 0x8000000080008000ULL,
0x000000000000808bULL, 0x0000000080000001ULL,
0x8000000080008081ULL, 0x8000000000008009ULL,
0x000000000000008aULL, 0x0000000000000088ULL,
0x0000000080008009ULL, 0x000000008000000aULL,
0x000000008000808bULL, 0x800000000000008bULL,
0x8000000000008089ULL, 0x8000000000008003ULL,
0x8000000000008002ULL, 0x8000000000000080ULL,
0x000000000000800aULL, 0x800000008000000aULL,
0x8000000080008081ULL, 0x8000000000008080ULL,
0x0000000080000001ULL, 0x8000000080008008ULL
};
# define A00 (p->u.s[0])
# define A01 (p->u.s[1])
# define A02 (p->u.s[2])
# define A03 (p->u.s[3])
# define A04 (p->u.s[4])
# define A10 (p->u.s[5])
# define A11 (p->u.s[6])
# define A12 (p->u.s[7])
# define A13 (p->u.s[8])
# define A14 (p->u.s[9])
# define A20 (p->u.s[10])
# define A21 (p->u.s[11])
# define A22 (p->u.s[12])
# define A23 (p->u.s[13])
# define A24 (p->u.s[14])
# define A30 (p->u.s[15])
# define A31 (p->u.s[16])
# define A32 (p->u.s[17])
# define A33 (p->u.s[18])
# define A34 (p->u.s[19])
# define A40 (p->u.s[20])
# define A41 (p->u.s[21])
# define A42 (p->u.s[22])
# define A43 (p->u.s[23])
# define A44 (p->u.s[24])
# define ROL64(a,x) ((a<<x)|(a>>(64-x)))
for(i=0; i<24; i+=4){
C0 = A00^A10^A20^A30^A40;
C1 = A01^A11^A21^A31^A41;
C2 = A02^A12^A22^A32^A42;
C3 = A03^A13^A23^A33^A43;
C4 = A04^A14^A24^A34^A44;
D0 = C4^ROL64(C1, 1);
D1 = C0^ROL64(C2, 1);
D2 = C1^ROL64(C3, 1);
D3 = C2^ROL64(C4, 1);
D4 = C3^ROL64(C0, 1);
B0 = (A00^D0);
B1 = ROL64((A11^D1), 44);
B2 = ROL64((A22^D2), 43);
B3 = ROL64((A33^D3), 21);
B4 = ROL64((A44^D4), 14);
A00 = B0 ^((~B1)& B2 );
A00 ^= RC[i];
A11 = B1 ^((~B2)& B3 );
A22 = B2 ^((~B3)& B4 );
A33 = B3 ^((~B4)& B0 );
A44 = B4 ^((~B0)& B1 );
B2 = ROL64((A20^D0), 3);
B3 = ROL64((A31^D1), 45);
B4 = ROL64((A42^D2), 61);
B0 = ROL64((A03^D3), 28);
B1 = ROL64((A14^D4), 20);
A20 = B0 ^((~B1)& B2 );
A31 = B1 ^((~B2)& B3 );
A42 = B2 ^((~B3)& B4 );
A03 = B3 ^((~B4)& B0 );
A14 = B4 ^((~B0)& B1 );
B4 = ROL64((A40^D0), 18);
B0 = ROL64((A01^D1), 1);
B1 = ROL64((A12^D2), 6);
B2 = ROL64((A23^D3), 25);
B3 = ROL64((A34^D4), 8);
A40 = B0 ^((~B1)& B2 );
A01 = B1 ^((~B2)& B3 );
A12 = B2 ^((~B3)& B4 );
A23 = B3 ^((~B4)& B0 );
A34 = B4 ^((~B0)& B1 );
B1 = ROL64((A10^D0), 36);
B2 = ROL64((A21^D1), 10);
B3 = ROL64((A32^D2), 15);
B4 = ROL64((A43^D3), 56);
B0 = ROL64((A04^D4), 27);
A10 = B0 ^((~B1)& B2 );
A21 = B1 ^((~B2)& B3 );
A32 = B2 ^((~B3)& B4 );
A43 = B3 ^((~B4)& B0 );
A04 = B4 ^((~B0)& B1 );
B3 = ROL64((A30^D0), 41);
B4 = ROL64((A41^D1), 2);
B0 = ROL64((A02^D2), 62);
B1 = ROL64((A13^D3), 55);
B2 = ROL64((A24^D4), 39);
A30 = B0 ^((~B1)& B2 );
A41 = B1 ^((~B2)& B3 );
A02 = B2 ^((~B3)& B4 );
A13 = B3 ^((~B4)& B0 );
A24 = B4 ^((~B0)& B1 );
C0 = A00^A20^A40^A10^A30;
C1 = A11^A31^A01^A21^A41;
C2 = A22^A42^A12^A32^A02;
C3 = A33^A03^A23^A43^A13;
C4 = A44^A14^A34^A04^A24;
D0 = C4^ROL64(C1, 1);
D1 = C0^ROL64(C2, 1);
D2 = C1^ROL64(C3, 1);
D3 = C2^ROL64(C4, 1);
D4 = C3^ROL64(C0, 1);
B0 = (A00^D0);
B1 = ROL64((A31^D1), 44);
B2 = ROL64((A12^D2), 43);
B3 = ROL64((A43^D3), 21);
B4 = ROL64((A24^D4), 14);
A00 = B0 ^((~B1)& B2 );
A00 ^= RC[i+1];
A31 = B1 ^((~B2)& B3 );
A12 = B2 ^((~B3)& B4 );
A43 = B3 ^((~B4)& B0 );
A24 = B4 ^((~B0)& B1 );
B2 = ROL64((A40^D0), 3);
B3 = ROL64((A21^D1), 45);
B4 = ROL64((A02^D2), 61);
B0 = ROL64((A33^D3), 28);
B1 = ROL64((A14^D4), 20);
A40 = B0 ^((~B1)& B2 );
A21 = B1 ^((~B2)& B3 );
A02 = B2 ^((~B3)& B4 );
A33 = B3 ^((~B4)& B0 );
A14 = B4 ^((~B0)& B1 );
B4 = ROL64((A30^D0), 18);
B0 = ROL64((A11^D1), 1);
B1 = ROL64((A42^D2), 6);
B2 = ROL64((A23^D3), 25);
B3 = ROL64((A04^D4), 8);
A30 = B0 ^((~B1)& B2 );
A11 = B1 ^((~B2)& B3 );
A42 = B2 ^((~B3)& B4 );
A23 = B3 ^((~B4)& B0 );
A04 = B4 ^((~B0)& B1 );
B1 = ROL64((A20^D0), 36);
B2 = ROL64((A01^D1), 10);
B3 = ROL64((A32^D2), 15);
B4 = ROL64((A13^D3), 56);
B0 = ROL64((A44^D4), 27);
A20 = B0 ^((~B1)& B2 );
A01 = B1 ^((~B2)& B3 );
A32 = B2 ^((~B3)& B4 );
A13 = B3 ^((~B4)& B0 );
A44 = B4 ^((~B0)& B1 );
B3 = ROL64((A10^D0), 41);
B4 = ROL64((A41^D1), 2);
B0 = ROL64((A22^D2), 62);
B1 = ROL64((A03^D3), 55);
B2 = ROL64((A34^D4), 39);
A10 = B0 ^((~B1)& B2 );
A41 = B1 ^((~B2)& B3 );
A22 = B2 ^((~B3)& B4 );
A03 = B3 ^((~B4)& B0 );
A34 = B4 ^((~B0)& B1 );
C0 = A00^A40^A30^A20^A10;
C1 = A31^A21^A11^A01^A41;
C2 = A12^A02^A42^A32^A22;
C3 = A43^A33^A23^A13^A03;
C4 = A24^A14^A04^A44^A34;
D0 = C4^ROL64(C1, 1);
D1 = C0^ROL64(C2, 1);
D2 = C1^ROL64(C3, 1);
D3 = C2^ROL64(C4, 1);
D4 = C3^ROL64(C0, 1);
B0 = (A00^D0);
B1 = ROL64((A21^D1), 44);
B2 = ROL64((A42^D2), 43);
B3 = ROL64((A13^D3), 21);
B4 = ROL64((A34^D4), 14);
A00 = B0 ^((~B1)& B2 );
A00 ^= RC[i+2];
A21 = B1 ^((~B2)& B3 );
A42 = B2 ^((~B3)& B4 );
A13 = B3 ^((~B4)& B0 );
A34 = B4 ^((~B0)& B1 );
B2 = ROL64((A30^D0), 3);
B3 = ROL64((A01^D1), 45);
B4 = ROL64((A22^D2), 61);
B0 = ROL64((A43^D3), 28);
B1 = ROL64((A14^D4), 20);
A30 = B0 ^((~B1)& B2 );
A01 = B1 ^((~B2)& B3 );
A22 = B2 ^((~B3)& B4 );
A43 = B3 ^((~B4)& B0 );
A14 = B4 ^((~B0)& B1 );
B4 = ROL64((A10^D0), 18);
B0 = ROL64((A31^D1), 1);
B1 = ROL64((A02^D2), 6);
B2 = ROL64((A23^D3), 25);
B3 = ROL64((A44^D4), 8);
A10 = B0 ^((~B1)& B2 );
A31 = B1 ^((~B2)& B3 );
A02 = B2 ^((~B3)& B4 );
A23 = B3 ^((~B4)& B0 );
A44 = B4 ^((~B0)& B1 );
B1 = ROL64((A40^D0), 36);
B2 = ROL64((A11^D1), 10);
B3 = ROL64((A32^D2), 15);
B4 = ROL64((A03^D3), 56);
B0 = ROL64((A24^D4), 27);
A40 = B0 ^((~B1)& B2 );
A11 = B1 ^((~B2)& B3 );
A32 = B2 ^((~B3)& B4 );
A03 = B3 ^((~B4)& B0 );
A24 = B4 ^((~B0)& B1 );
B3 = ROL64((A20^D0), 41);
B4 = ROL64((A41^D1), 2);
B0 = ROL64((A12^D2), 62);
B1 = ROL64((A33^D3), 55);
B2 = ROL64((A04^D4), 39);
A20 = B0 ^((~B1)& B2 );
A41 = B1 ^((~B2)& B3 );
A12 = B2 ^((~B3)& B4 );
A33 = B3 ^((~B4)& B0 );
A04 = B4 ^((~B0)& B1 );
C0 = A00^A30^A10^A40^A20;
C1 = A21^A01^A31^A11^A41;
C2 = A42^A22^A02^A32^A12;
C3 = A13^A43^A23^A03^A33;
C4 = A34^A14^A44^A24^A04;
D0 = C4^ROL64(C1, 1);
D1 = C0^ROL64(C2, 1);
D2 = C1^ROL64(C3, 1);
D3 = C2^ROL64(C4, 1);
D4 = C3^ROL64(C0, 1);
B0 = (A00^D0);
B1 = ROL64((A01^D1), 44);
B2 = ROL64((A02^D2), 43);
B3 = ROL64((A03^D3), 21);
B4 = ROL64((A04^D4), 14);
A00 = B0 ^((~B1)& B2 );
A00 ^= RC[i+3];
A01 = B1 ^((~B2)& B3 );
A02 = B2 ^((~B3)& B4 );
A03 = B3 ^((~B4)& B0 );
A04 = B4 ^((~B0)& B1 );
B2 = ROL64((A10^D0), 3);
B3 = ROL64((A11^D1), 45);
B4 = ROL64((A12^D2), 61);
B0 = ROL64((A13^D3), 28);
B1 = ROL64((A14^D4), 20);
A10 = B0 ^((~B1)& B2 );
A11 = B1 ^((~B2)& B3 );
A12 = B2 ^((~B3)& B4 );
A13 = B3 ^((~B4)& B0 );
A14 = B4 ^((~B0)& B1 );
B4 = ROL64((A20^D0), 18);
B0 = ROL64((A21^D1), 1);
B1 = ROL64((A22^D2), 6);
B2 = ROL64((A23^D3), 25);
B3 = ROL64((A24^D4), 8);
A20 = B0 ^((~B1)& B2 );
A21 = B1 ^((~B2)& B3 );
A22 = B2 ^((~B3)& B4 );
A23 = B3 ^((~B4)& B0 );
A24 = B4 ^((~B0)& B1 );
B1 = ROL64((A30^D0), 36);
B2 = ROL64((A31^D1), 10);
B3 = ROL64((A32^D2), 15);
B4 = ROL64((A33^D3), 56);
B0 = ROL64((A34^D4), 27);
A30 = B0 ^((~B1)& B2 );
A31 = B1 ^((~B2)& B3 );
A32 = B2 ^((~B3)& B4 );
A33 = B3 ^((~B4)& B0 );
A34 = B4 ^((~B0)& B1 );
B3 = ROL64((A40^D0), 41);
B4 = ROL64((A41^D1), 2);
B0 = ROL64((A42^D2), 62);
B1 = ROL64((A43^D3), 55);
B2 = ROL64((A44^D4), 39);
A40 = B0 ^((~B1)& B2 );
A41 = B1 ^((~B2)& B3 );
A42 = B2 ^((~B3)& B4 );
A43 = B3 ^((~B4)& B0 );
A44 = B4 ^((~B0)& B1 );
}
}
/*
** Initialize a new hash. iSize determines the size of the hash
** in bits and should be one of 224, 256, 384, or 512. Or iSize
** can be zero to use the default hash size of 256 bits.
*/
static void SHA3Init(SHA3Context *p, int iSize){
memset(p, 0, sizeof(*p));
if( iSize>=128 && iSize<=512 ){
p->nRate = (1600 - ((iSize + 31)&~31)*2)/8;
}else{
p->nRate = (1600 - 2*256)/8;
}
#if SHA3_BYTEORDER==1234
/* Known to be little-endian at compile-time. No-op */
#elif SHA3_BYTEORDER==4321
p->ixMask = 7; /* Big-endian */
#else
{
static unsigned int one = 1;
if( 1==*(unsigned char*)&one ){
/* Little endian. No byte swapping. */
p->ixMask = 0;
}else{
/* Big endian. Byte swap. */
p->ixMask = 7;
}
}
#endif
}
/*
** Make consecutive calls to the SHA3Update function to add new content
** to the hash
*/
static void SHA3Update(
SHA3Context *p,
const unsigned char *aData,
unsigned int nData
){
unsigned int i = 0;
#if SHA3_BYTEORDER==1234
if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){
for(; i+7<nData; i+=8){
p->u.s[p->nLoaded/8] ^= *(u64*)&aData[i];
p->nLoaded += 8;
if( p->nLoaded>=p->nRate ){
KeccakF1600Step(p);
p->nLoaded = 0;
}
}
}
#endif
for(; i<nData; i++){
#if SHA3_BYTEORDER==1234
p->u.x[p->nLoaded] ^= aData[i];
#elif SHA3_BYTEORDER==4321
p->u.x[p->nLoaded^0x07] ^= aData[i];
#else
p->u.x[p->nLoaded^p->ixMask] ^= aData[i];
#endif
p->nLoaded++;
if( p->nLoaded==p->nRate ){
KeccakF1600Step(p);
p->nLoaded = 0;
}
}
}
/*
** After all content has been added, invoke SHA3Final() to compute
** the final hash. The function returns a pointer to the binary
** hash value.
*/
static unsigned char *SHA3Final(SHA3Context *p){
unsigned int i;
if( p->nLoaded==p->nRate-1 ){
const unsigned char c1 = 0x86;
SHA3Update(p, &c1, 1);
}else{
const unsigned char c2 = 0x06;
const unsigned char c3 = 0x80;
SHA3Update(p, &c2, 1);
p->nLoaded = p->nRate - 1;
SHA3Update(p, &c3, 1);
}
for(i=0; i<p->nRate; i++){
p->u.x[i+p->nRate] = p->u.x[i^p->ixMask];
}
return &p->u.x[p->nRate];
}
/* End of the hashing logic
*****************************************************************************/
/*
** Implementation of the sha3(X,SIZE) function.
**
** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default
** size is 256. If X is a BLOB, it is hashed as is.
** For all other non-NULL types of input, X is converted into a UTF-8 string
** and the string is hashed without the trailing 0x00 terminator. The hash
** of a NULL value is NULL.
*/
static void sha3Func(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
SHA3Context cx;
int eType = sqlite3_value_type(argv[0]);
int nByte = sqlite3_value_bytes(argv[0]);
int iSize;
if( argc==1 ){
iSize = 256;
}else{
iSize = sqlite3_value_int(argv[1]);
if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){
sqlite3_result_error(context, "SHA3 size should be one of: 224 256 "
"384 512", -1);
return;
}
}
if( eType==SQLITE_NULL ) return;
SHA3Init(&cx, iSize);
if( eType==SQLITE_BLOB ){
SHA3Update(&cx, sqlite3_value_blob(argv[0]), nByte);
}else{
SHA3Update(&cx, sqlite3_value_text(argv[0]), nByte);
}
sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
}
/* Compute a string using sqlite3_vsnprintf() with a maximum length
** of 50 bytes and add it to the hash.
*/
static void hash_step_vformat(
SHA3Context *p, /* Add content to this context */
const char *zFormat,
...
){
va_list ap;
int n;
char zBuf[50];
va_start(ap, zFormat);
sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap);
va_end(ap);
n = (int)strlen(zBuf);
SHA3Update(p, (unsigned char*)zBuf, n);
}
/*
** Implementation of the sha3_query(SQL,SIZE) function.
**
** This function compiles and runs the SQL statement(s) given in the
** argument. The results are hashed using a SIZE-bit SHA3. The default
** size is 256.
**
** The format of the byte stream that is hashed is summarized as follows:
**
** S<n>:<sql>
** R
** N
** I<int>
** F<ieee-float>
** B<size>:<bytes>
** T<size>:<text>
**
** <sql> is the original SQL text for each statement run and <n> is
** the size of that text. The SQL text is UTF-8. A single R character
** occurs before the start of each row. N means a NULL value.
** I mean an 8-byte little-endian integer <int>. F is a floating point
** number with an 8-byte little-endian IEEE floating point value <ieee-float>.
** B means blobs of <size> bytes. T means text rendered as <size>
** bytes of UTF-8. The <n> and <size> values are expressed as an ASCII
** text integers.
**
** For each SQL statement in the X input, there is one S segment. Each
** S segment is followed by zero or more R segments, one for each row in the
** result set. After each R, there are one or more N, I, F, B, or T segments,
** one for each column in the result set. Segments are concatentated directly
** with no delimiters of any kind.
*/
static void sha3QueryFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
sqlite3 *db = sqlite3_context_db_handle(context);
const char *zSql = (const char*)sqlite3_value_text(argv[0]);
sqlite3_stmt *pStmt = 0;
int nCol; /* Number of columns in the result set */
int i; /* Loop counter */
int rc;
int n;
const char *z;
SHA3Context cx;
int iSize;
if( argc==1 ){
iSize = 256;
}else{
iSize = sqlite3_value_int(argv[1]);
if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){
sqlite3_result_error(context, "SHA3 size should be one of: 224 256 "
"384 512", -1);
return;
}
}
if( zSql==0 ) return;
SHA3Init(&cx, iSize);
while( zSql[0] ){
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
if( rc ){
char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
zSql, sqlite3_errmsg(db));
sqlite3_finalize(pStmt);
sqlite3_result_error(context, zMsg, -1);
sqlite3_free(zMsg);
return;
}
if( !sqlite3_stmt_readonly(pStmt) ){
char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt));
sqlite3_finalize(pStmt);
sqlite3_result_error(context, zMsg, -1);
sqlite3_free(zMsg);
return;
}
nCol = sqlite3_column_count(pStmt);
z = sqlite3_sql(pStmt);
n = (int)strlen(z);
hash_step_vformat(&cx,"S%d:",n);
SHA3Update(&cx,(unsigned char*)z,n);
/* Compute a hash over the result of the query */
while( SQLITE_ROW==sqlite3_step(pStmt) ){
SHA3Update(&cx,(const unsigned char*)"R",1);
for(i=0; i<nCol; i++){
switch( sqlite3_column_type(pStmt,i) ){
case SQLITE_NULL: {
SHA3Update(&cx, (const unsigned char*)"N",1);
break;
}
case SQLITE_INTEGER: {
sqlite3_uint64 u;
int j;
unsigned char x[9];
sqlite3_int64 v = sqlite3_column_int64(pStmt,i);
memcpy(&u, &v, 8);
for(j=8; j>=1; j--){
x[j] = u & 0xff;
u >>= 8;
}
x[0] = 'I';
SHA3Update(&cx, x, 9);
break;
}
case SQLITE_FLOAT: {
sqlite3_uint64 u;
int j;
unsigned char x[9];
double r = sqlite3_column_double(pStmt,i);
memcpy(&u, &r, 8);
for(j=8; j>=1; j--){
x[j] = u & 0xff;
u >>= 8;
}
x[0] = 'F';
SHA3Update(&cx,x,9);
break;
}
case SQLITE_TEXT: {
int n2 = sqlite3_column_bytes(pStmt, i);
const unsigned char *z2 = sqlite3_column_text(pStmt, i);
hash_step_vformat(&cx,"T%d:",n2);
SHA3Update(&cx, z2, n2);
break;
}
case SQLITE_BLOB: {
int n2 = sqlite3_column_bytes(pStmt, i);
const unsigned char *z2 = sqlite3_column_blob(pStmt, i);
hash_step_vformat(&cx,"B%d:",n2);
SHA3Update(&cx, z2, n2);
break;
}
}
}
}
sqlite3_finalize(pStmt);
}
sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
}
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_shathree_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, "sha3", 1, SQLITE_UTF8, 0,
sha3Func, 0, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "sha3", 2, SQLITE_UTF8, 0,
sha3Func, 0, 0);
}
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "sha3_query", 1, SQLITE_UTF8, 0,
sha3QueryFunc, 0, 0);
}
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "sha3_query", 2, SQLITE_UTF8, 0,
sha3QueryFunc, 0, 0);
}
return rc;
}
-106
View File
@@ -1,106 +0,0 @@
# 2017 March 02
#
# 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.
#
#***********************************************************************
#
if {![info exists testdir]} {
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl
set ::testprefix rbucrash2
db close
forcedelete test.db-oal rbu.db
sqlite3_shutdown
sqlite3_config_uri 1
reset_db
# Set up a target database and an rbu update database. The target
# db is the usual "test.db", the rbu db is "test.db2".
#
forcedelete test.db2
do_execsql_test 1.0 {
CREATE TABLE t1(a, b, c, PRIMARY KEY(a), UNIQUE(b));
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(4, 5, 6);
INSERT INTO t1 VALUES(7, 8, 9);
ATTACH 'test.db2' AS rbu;
CREATE TABLE rbu.data_t1(a, b, c, rbu_control);
INSERT INTO data_t1 VALUES('one', randomblob(3500), NULL, 0);
INSERT INTO data_t1 VALUES('two', randomblob(3500), NULL, 0);
INSERT INTO data_t1 VALUES('three', randomblob(3500), NULL, 0);
INSERT INTO data_t1 VALUES('four', randomblob(3500), NULL, 0);
INSERT INTO data_t1 VALUES('five', randomblob(3500), NULL, 0);
INSERT INTO data_t1 VALUES('six', randomblob(3500), NULL, 0);
}
db_save_and_close
proc do_rbu_crash_test2 {tn script} {
foreach {f blksz} {
test.db 512
test.db2 512
test.db 4096
test.db2 4096
} {
set bDone 0
for {set iDelay 1} {$bDone==0} {incr iDelay} {
forcedelete test.db2 test.db2-journal test.db test.db-oal test.db-wal
db_restore
set res [
crashsql -file $f -delay $iDelay -tclbody $script -dflt 1 -opendb {} \
-blocksize $blksz {}
]
set bDone 1
if {$res == "1 {child process exited abnormally}"} {
set bDone 0
} elseif {$res != "0 {}"} {
error "unexected catchsql result: $res"
}
sqlite3rbu rbu test.db test.db2
while {[rbu step]=="SQLITE_OK"} {}
rbu close
sqlite3 db test.db
do_execsql_test $tn.delay=$iDelay.f=$f.blksz=$blksz {
PRAGMA integrity_check;
} {ok}
db close
}
}
}
for {set x 1} {$x < 10} {incr x} {
do_rbu_crash_test2 1.$x {
sqlite3rbu rbu test.db test.db2
while {[rbu step]=="SQLITE_OK"} {
rbu savestate
}
rbu close
}
}
for {set x 1} {$x < 2} {incr x} {
do_rbu_crash_test2 2.$x {
sqlite3rbu rbu test.db test.db2
while {[rbu step]=="SQLITE_OK"} {
rbu close
sqlite3rbu rbu test.db test.db2
}
rbu close
}
}
finish_test
-2
View File
@@ -40,7 +40,6 @@ proc create_rbu1 {filename} {
do_execsql_test 1.0 {
PRAGMA page_size = 4096;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
}
@@ -267,7 +266,6 @@ foreach bReopen {0 1} {
do_test 3.$bReopen.1.0 {
reset_db
execsql {
PRAGMA page_size = 4096;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
+3 -50
View File
@@ -356,7 +356,6 @@ struct sqlite3rbu {
RbuObjIter objiter; /* Iterator for skipping through tbl/idx */
const char *zVfsName; /* Name of automatically created rbu vfs */
rbu_file *pTargetFd; /* File handle open on target db */
int nPagePerSector; /* Pages per sector for pTargetFd */
i64 iOalSz;
i64 nPhaseOneStep;
@@ -2621,23 +2620,6 @@ static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){
if( p->nFrame==0 || (pState && pState->iWalCksum!=p->iWalCksum) ){
p->rc = SQLITE_DONE;
p->eStage = RBU_STAGE_DONE;
}else{
int nSectorSize;
sqlite3_file *pDb = p->pTargetFd->pReal;
sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal;
assert( p->nPagePerSector==0 );
nSectorSize = pDb->pMethods->xSectorSize(pDb);
if( nSectorSize>p->pgsz ){
p->nPagePerSector = nSectorSize / p->pgsz;
}else{
p->nPagePerSector = 1;
}
/* Call xSync() on the wal file. This causes SQLite to sync the
** directory in which the target database and the wal file reside, in
** case it has not been synced since the rename() call in
** rbuMoveOalFile(). */
p->rc = pWal->pMethods->xSync(pWal, SQLITE_SYNC_NORMAL);
}
}
}
@@ -3293,26 +3275,9 @@ int sqlite3rbu_step(sqlite3rbu *p){
p->rc = SQLITE_DONE;
}
}else{
/* At one point the following block copied a single frame from the
** wal file to the database file. So that one call to sqlite3rbu_step()
** checkpointed a single frame.
**
** However, if the sector-size is larger than the page-size, and the
** application calls sqlite3rbu_savestate() or close() immediately
** after this step, then rbu_step() again, then a power failure occurs,
** then the database page written here may be damaged. Work around
** this by checkpointing frames until the next page in the aFrame[]
** lies on a different disk sector to the current one. */
u32 iSector;
do{
RbuFrame *pFrame = &p->aFrame[p->nStep];
iSector = (pFrame->iDbPage-1) / p->nPagePerSector;
rbuCheckpointFrame(p, pFrame);
p->nStep++;
}while( p->nStep<p->nFrame
&& iSector==((p->aFrame[p->nStep].iDbPage-1) / p->nPagePerSector)
&& p->rc==SQLITE_OK
);
RbuFrame *pFrame = &p->aFrame[p->nStep];
rbuCheckpointFrame(p, pFrame);
p->nStep++;
}
p->nProgress++;
}
@@ -3753,12 +3718,6 @@ int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg);
}
/* Sync the db file if currently doing an incremental checkpoint */
if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){
sqlite3_file *pDb = p->pTargetFd->pReal;
p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
}
rbuSaveState(p, p->eStage);
if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_OAL ){
@@ -3883,12 +3842,6 @@ int sqlite3rbu_savestate(sqlite3rbu *p){
if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, 0);
}
/* Sync the db file */
if( rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){
sqlite3_file *pDb = p->pTargetFd->pReal;
rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
}
p->rc = rc;
rbuSaveState(p, p->eStage);
rc = p->rc;
+59 -30
View File
@@ -68,7 +68,6 @@
#ifndef SQLITE_AMALGAMATION
#include "sqlite3rtree.h"
typedef sqlite3_int64 i64;
typedef sqlite3_uint64 u64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
@@ -368,19 +367,25 @@ struct RtreeMatchArg {
# define MIN(x,y) ((x) > (y) ? (y) : (x))
#endif
/* What version of GCC is being used. 0 means GCC is not being used .
** Note that the GCC_VERSION macro will also be set correctly when using
** clang, since clang works hard to be gcc compatible. So the gcc
** optimizations will also work when compiling with clang.
*/
/* What version of GCC is being used. 0 means GCC is not being used */
#ifndef GCC_VERSION
#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
#ifdef __GNUC__
# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__)
#else
# define GCC_VERSION 0
#endif
#endif
/* What version of CLANG is being used. 0 means CLANG is not being used */
#ifndef CLANG_VERSION
#if defined(__clang__) && !defined(_WIN32)
# define CLANG_VERSION \
(__clang_major__*1000000+__clang_minor__*1000+__clang_patchlevel__)
#else
# define CLANG_VERSION 0
#endif
#endif
/* The testcase() macro should already be defined in the amalgamation. If
** it is not, make it a no-op.
*/
@@ -398,22 +403,23 @@ struct RtreeMatchArg {
** at run-time.
*/
#ifndef SQLITE_BYTEORDER
#if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
defined(__arm__)
#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
defined(__arm__)) && !defined(SQLITE_RUNTIME_BYTEORDER)
# define SQLITE_BYTEORDER 1234
#elif defined(sparc) || defined(__ppc__)
# define SQLITE_BYTEORDER 4321
#else
# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */
#endif
#if (defined(sparc) || defined(__ppc__)) \
&& !defined(SQLITE_RUNTIME_BYTEORDER)
# define SQLITE_BYTEORDER 4321
#endif
# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */
#endif
/* What version of MSVC is being used. 0 means MSVC is not being used */
#ifndef MSVC_VERSION
#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
#if defined(_MSC_VER)
# define MSVC_VERSION _MSC_VER
#else
# define MSVC_VERSION 0
@@ -431,8 +437,11 @@ static void readCoord(u8 *p, RtreeCoord *pCoord){
assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */
#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
pCoord->u = _byteswap_ulong(*(u32*)p);
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
pCoord->u = __builtin_bswap32(*(u32*)p);
#elif SQLITE_BYTEORDER==1234
pCoord->u = ((pCoord->u>>24)&0xff)|((pCoord->u>>8)&0xff00)|
((pCoord->u&0xff)<<24)|((pCoord->u&0xff00)<<8);
#elif SQLITE_BYTEORDER==4321
pCoord->u = *(u32*)p;
#else
@@ -447,17 +456,21 @@ static void readCoord(u8 *p, RtreeCoord *pCoord){
static i64 readInt64(u8 *p){
#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
u64 x;
testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */
memcpy(&x, p, 8);
return (i64)_byteswap_uint64(x);
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
u64 x;
testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */
memcpy(&x, p, 8);
return (i64)__builtin_bswap64(x);
#elif SQLITE_BYTEORDER==4321
i64 x;
testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */
memcpy(&x, p, 8);
return x;
#else
testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */
return (
(((i64)p[0]) << 56) +
(((i64)p[1]) << 48) +
@@ -476,16 +489,17 @@ static i64 readInt64(u8 *p){
** 64 bit integer. The value returned is the number of bytes written
** to the argument buffer (always 2, 4 and 8 respectively).
*/
static void writeInt16(u8 *p, int i){
static int writeInt16(u8 *p, int i){
p[0] = (i>> 8)&0xFF;
p[1] = (i>> 0)&0xFF;
return 2;
}
static int writeCoord(u8 *p, RtreeCoord *pCoord){
u32 i;
assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */
assert( sizeof(RtreeCoord)==4 );
assert( sizeof(u32)==4 );
#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
#if SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
i = __builtin_bswap32(pCoord->u);
memcpy(p, &i, 4);
#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
@@ -504,7 +518,8 @@ static int writeCoord(u8 *p, RtreeCoord *pCoord){
return 4;
}
static int writeInt64(u8 *p, i64 i){
#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* Not always 8-byte aligned */
#if SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
i = (i64)__builtin_bswap64((u64)i);
memcpy(p, &i, 8);
#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
@@ -1060,7 +1075,7 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){
c.u = _byteswap_ulong(*(u32*)a); \
r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
}
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
#define RTREE_DECODE_COORD(eInt, a, r) { \
RtreeCoord c; /* Coordinate decoded */ \
c.u = __builtin_bswap32(*(u32*)a); \
@@ -1294,7 +1309,7 @@ static int rtreeSearchPointCompare(
}
/*
** Interchange two search points in a cursor.
** Interchange to search points in a cursor.
*/
static void rtreeSearchPointSwap(RtreeCursor *p, int i, int j){
RtreeSearchPoint t = p->aPoint[i];
@@ -1601,6 +1616,7 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
if( i==0 ){
sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell));
}else{
if( rc ) return rc;
nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c);
#ifndef SQLITE_RTREE_INT_ONLY
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
@@ -1795,6 +1811,19 @@ static int rtreeFilter(
return rc;
}
/*
** Set the pIdxInfo->estimatedRows variable to nRow. Unless this
** extension is currently being used by a version of SQLite too old to
** support estimatedRows. In that case this function is a no-op.
*/
static void setEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){
#if SQLITE_VERSION_NUMBER>=3008002
if( sqlite3_libversion_number()>=3008002 ){
pIdxInfo->estimatedRows = nRow;
}
#endif
}
/*
** Rtree virtual table module xBestIndex method. There are three
** table scan strategies to choose from (in order from most to
@@ -1874,7 +1903,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
** a single row.
*/
pIdxInfo->estimatedCost = 30.0;
pIdxInfo->estimatedRows = 1;
setEstimatedRows(pIdxInfo, 1);
return SQLITE_OK;
}
@@ -1906,7 +1935,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
nRow = pRtree->nRowEst >> (iIdx/2);
pIdxInfo->estimatedCost = (double)6.0 * (double)nRow;
pIdxInfo->estimatedRows = nRow;
setEstimatedRows(pIdxInfo, nRow);
return rc;
}
@@ -1945,12 +1974,12 @@ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){
** of the objects size in each dimension.
*/
static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){
RtreeDValue margin = 0;
int ii = pRtree->nDim2 - 2;
do{
RtreeDValue margin;
int ii;
margin = DCOORD(p->aCoord[1]) - DCOORD(p->aCoord[0]);
for(ii=2; ii<pRtree->nDim2; ii+=2){
margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
ii -= 2;
}while( ii>=0 );
}
return margin;
}
+1 -4
View File
@@ -63,10 +63,7 @@ do_test 1.2.1 {
INSERT INTO t1 VALUES(7, 8);
}
set ::log
} {}
do_test 1.2.2 {
db2 eval { SELECT * FROM t1 }
} {5 6 {} 7 8 {}}
} {SQLITE_SCHEMA {sqlite3changeset_apply(): table t1 has 3 columns, expected 2}}
do_test 1.3.0 {
execsql {
+6 -7
View File
@@ -33,11 +33,16 @@ proc do_changeset_invert_test {tn session res} {
proc do_conflict_test {tn args} {
proc xConflict {args} {
lappend ::xConflict $args
return ""
}
proc bgerror {args} { set ::background_error $args }
set O(-tables) [list]
set O(-sql) [list]
set O(-conflicts) [list]
set O(-policy) "OMIT"
array set V $args
foreach key [array names V] {
@@ -45,12 +50,6 @@ proc do_conflict_test {tn args} {
}
array set O $args
proc xConflict {args} [subst -nocommands {
lappend ::xConflict [set args]
return $O(-policy)
}]
proc bgerror {args} { set ::background_error $args }
sqlite3session S db main
foreach t $O(-tables) { S attach $t }
execsql $O(-sql)
-216
View File
@@ -1,216 +0,0 @@
# 2017 February 04
#
# 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.
#
#***********************************************************************
#
# Tests for the sessions module. Specifically, that a changeset can
# be applied after ALTER TABLE ADD COLUMN has been used to add
# columns to tables.
#
if {![info exists testdir]} {
set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl
ifcapable !session {finish_test; return}
set testprefix sessionat
db close
sqlite3_shutdown
test_sqlite3_log log
proc log {code msg} { lappend ::log $code $msg }
proc reset_test {} {
catch { db close }
catch { db2 close }
forcedelete test.db test.db2
sqlite3 db test.db
sqlite3 db2 test.db2
}
# Run all tests in this file twice. Once with "WITHOUT ROWID", and once
# with regular rowid tables.
#
# ?.1.*: Test that PK inconsistencies are detected if one or more of the PK
# columns are not present in the changeset.
#
# ?.2.*: Test that it is not possible to apply a changeset with N columns
# to a db with fewer than N columns.
#
# ?.3.*: Test some INSERT, UPDATE and DELETE operations that do not
# require conflict handling.
#
# ?.4.*: Test some INSERT, UPDATE and DELETE operations that do require
# conflict handling.
#
# ?.5.*: Test that attempting to concat two changesets with different
# numbers of columns for the same table is an error.
#
foreach {tn trailing} {
sessionat-ipk ""
sessionat-wor " WITHOUT ROWID "
} {
eval [string map [list %WR% $trailing] {
reset_test
#-----------------------------------------------------------------------
do_execsql_test $tn.1.0 {
CREATE TABLE t1(a, b, PRIMARY KEY(a)) %WR%;
}
do_execsql_test -db db2 $tn.1.1 {
CREATE TABLE t1(a, b, c, PRIMARY KEY(a, c)) %WR%;
}
do_test $tn.1.2 {
set ::log {}
do_then_apply_sql { INSERT INTO t1 VALUES('one', 'two') }
set ::log
} [list \
SQLITE_SCHEMA {sqlite3changeset_apply(): primary key mismatch for table t1}
]
do_execsql_test $tn.1.3 { SELECT * FROM t1 } {one two}
do_execsql_test -db db2 $tn.1.4 { SELECT * FROM t1 } {}
#-----------------------------------------------------------------------
do_execsql_test $tn.2.0 {
CREATE TABLE t2(x, y, z, PRIMARY KEY(x)) %WR%;
}
do_execsql_test -db db2 $tn.2.1 {
CREATE TABLE t2(x, y, PRIMARY KEY(x)) %WR%;
}
do_test $tn.2.2 {
db cache flush
set ::log {}
do_then_apply_sql { INSERT INTO t2 VALUES(1, 2, 3) }
set ::log
} [list SQLITE_SCHEMA \
{sqlite3changeset_apply(): table t2 has 2 columns, expected 3 or more}
]
do_execsql_test $tn.2.3 { SELECT * FROM t2 } {1 2 3}
do_execsql_test -db db2 $tn.2.4 { SELECT * FROM t2 } {}
#-----------------------------------------------------------------------
do_execsql_test $tn.3.0 {
CREATE TABLE t3(a, b, PRIMARY KEY(b)) %WR%;
}
do_execsql_test -db db2 $tn.3.1 {
CREATE TABLE t3(a, b, c DEFAULT 'D', PRIMARY KEY(b)) %WR%;
}
do_test $tn.3.2 {
do_then_apply_sql {
INSERT INTO t3 VALUES(1, 2);
INSERT INTO t3 VALUES(3, 4);
INSERT INTO t3 VALUES(5, 6);
};
db2 eval {SELECT * FROM t3}
} {1 2 D 3 4 D 5 6 D}
do_test $tn.3.3 {
do_then_apply_sql {
UPDATE t3 SET a=45 WHERE b=4;
DELETE FROM t3 WHERE a=5;
};
db2 eval {SELECT * FROM t3}
} {1 2 D 45 4 D}
#-----------------------------------------------------------------------
# 4.1: INSERT statements
# 4.2: DELETE statements
# 4.3: UPDATE statements
#
do_execsql_test $tn.4.1.0 {
CREATE TABLE t4(x INTEGER PRIMARY KEY, y) %WR%;
}
do_execsql_test -db db2 $tn.4.1.1 {
CREATE TABLE t4(x INTEGER PRIMARY KEY, y, z) %WR%;
INSERT INTO t4 VALUES(1, 2, 3);
INSERT INTO t4 VALUES(4, 5, 6);
}
do_conflict_test $tn.4.1.2 -tables t4 -sql {
INSERT INTO t4 VALUES(10, 20);
INSERT INTO t4 VALUES(4, 11);
} -conflicts {
{INSERT t4 CONFLICT {i 4 i 11} {i 4 i 5}}
}
do_execsql_test -db db2 $tn.4.1.3 {
SELECT * FROM t4 ORDER BY x
} {1 2 3 4 5 6 10 20 {}}
do_conflict_test $tn.4.1.4 -policy REPLACE -tables t4 -sql {
INSERT INTO t4 VALUES(1, 11);
} -conflicts {
{INSERT t4 CONFLICT {i 1 i 11} {i 1 i 2}}
}
do_execsql_test -db db2 $tn.4.1.5 {
SELECT * FROM t4 ORDER BY x
} {1 11 {} 4 5 6 10 20 {}}
do_execsql_test $tn.4.2.0 {
DELETE FROM t4;
INSERT INTO t4 VALUES(1, 'A');
INSERT INTO t4 VALUES(2, 'B');
INSERT INTO t4 VALUES(3, 'C');
INSERT INTO t4 VALUES(4, 'D');
}
do_execsql_test -db db2 $tn.4.2.1 {
DELETE FROM t4;
INSERT INTO t4 VALUES(1, 'A', 'a');
INSERT INTO t4 VALUES(3, 'C', 'c');
INSERT INTO t4 VALUES(4, 'E', 'd');
}
do_conflict_test $tn.4.2.2 -tables t4 -sql {
DELETE FROM t4 WHERE x=2;
DELETE FROM t4 WHERE x=4;
} -conflicts {
{DELETE t4 NOTFOUND {i 2 t B}}
{DELETE t4 DATA {i 4 t D} {i 4 t E}}
}
do_execsql_test $tn.4.3.0 {
CREATE TABLE t5(a, b, c PRIMARY KEY) %WR%;
INSERT INTO t5 VALUES(1,1,1), (2,2,2), (3,3,3), (4,4,4);
}
do_execsql_test -db db2 $tn.4.3.1 {
CREATE TABLE t5(a, b, c PRIMARY KEY, d CHECK(b!=10)) %WR%;
INSERT INTO t5 VALUES (2,2,2,2), (3,8,3,3), (4,4,4,4);
}
do_conflict_test $tn.4.3.2 -tables t5 -sql {
UPDATE t5 SET a=4 WHERE c=1;
UPDATE t5 SET b=9 WHERE c=3;
UPDATE t5 SET b=10 WHERE c=2;
} -conflicts {
{UPDATE t5 NOTFOUND {i 1 {} {} i 1} {i 4 {} {} {} {}}}
{UPDATE t5 DATA {{} {} i 3 i 3} {{} {} i 9 {} {}} {i 3 i 8 i 3}}
{UPDATE t5 CONSTRAINT {{} {} i 2 i 2} {{} {} i 10 {} {}}}
}
#-----------------------------------------------------------------------
do_execsql_test $tn.5.0 {
CREATE TABLE t6(a, b, c, PRIMARY KEY(a, b)) %WR%;
}
do_execsql_test -db db2 $tn.5.1 {
CREATE TABLE t6(a, b, c, d, e, PRIMARY KEY(a, b)) %WR%;
}
do_test $tn.5.2 {
set c1 [sql_exec_changeset db {
INSERT INTO t6 VALUES(1, 1, 1);
INSERT INTO t6 VALUES(2, 2, 2);
}]
set c2 [sql_exec_changeset db2 {
INSERT INTO t6 VALUES(3, 3, 3, 3, 3);
INSERT INTO t6 VALUES(4, 4, 4, 4, 4);
}]
list [catch { sqlite3changeset_concat $c1 $c2} msg] $msg
} {1 SQLITE_SCHEMA}
}]
}
finish_test
+12 -27
View File
@@ -3028,7 +3028,7 @@ int sqlite3changeset_conflict(
if( !pIter->pConflict ){
return SQLITE_MISUSE;
}
if( iVal<0 || iVal>=pIter->nCol ){
if( iVal<0 || iVal>=sqlite3_column_count(pIter->pConflict) ){
return SQLITE_RANGE;
}
*ppValue = sqlite3_column_value(pIter->pConflict, iVal);
@@ -3495,13 +3495,7 @@ static int sessionInsertRow(
sessionAppendStr(&buf, "INSERT INTO main.", &rc);
sessionAppendIdent(&buf, zTab, &rc);
sessionAppendStr(&buf, "(", &rc);
for(i=0; i<p->nCol; i++){
if( i!=0 ) sessionAppendStr(&buf, ", ", &rc);
sessionAppendIdent(&buf, p->azCol[i], &rc);
}
sessionAppendStr(&buf, ") VALUES(?", &rc);
sessionAppendStr(&buf, " VALUES(?", &rc);
for(i=1; i<p->nCol; i++){
sessionAppendStr(&buf, ", ?", &rc);
}
@@ -4047,17 +4041,11 @@ static int sessionChangesetApply(
nTab = (int)strlen(zTab);
sApply.azCol = (const char **)zTab;
}else{
int nMinCol = 0;
int i;
sqlite3changeset_pk(pIter, &abPK, 0);
rc = sessionTableInfo(
db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK
);
if( rc!=SQLITE_OK ) break;
for(i=0; i<sApply.nCol; i++){
if( sApply.abPK[i] ) nMinCol = i+1;
}
if( sApply.nCol==0 ){
schemaMismatch = 1;
@@ -4065,29 +4053,26 @@ static int sessionChangesetApply(
"sqlite3changeset_apply(): no such table: %s", zTab
);
}
else if( sApply.nCol<nCol ){
else if( sApply.nCol!=nCol ){
schemaMismatch = 1;
sqlite3_log(SQLITE_SCHEMA,
"sqlite3changeset_apply(): table %s has %d columns, "
"expected %d or more",
"sqlite3changeset_apply(): table %s has %d columns, expected %d",
zTab, sApply.nCol, nCol
);
}
else if( nCol<nMinCol || memcmp(sApply.abPK, abPK, nCol)!=0 ){
else if( memcmp(sApply.abPK, abPK, nCol)!=0 ){
schemaMismatch = 1;
sqlite3_log(SQLITE_SCHEMA, "sqlite3changeset_apply(): "
"primary key mismatch for table %s", zTab
);
}
else{
sApply.nCol = nCol;
if((rc = sessionSelectRow(db, zTab, &sApply))
|| (rc = sessionUpdateRow(db, zTab, &sApply))
|| (rc = sessionDeleteRow(db, zTab, &sApply))
|| (rc = sessionInsertRow(db, zTab, &sApply))
){
break;
}
else if(
(rc = sessionSelectRow(db, zTab, &sApply))
|| (rc = sessionUpdateRow(db, zTab, &sApply))
|| (rc = sessionDeleteRow(db, zTab, &sApply))
|| (rc = sessionInsertRow(db, zTab, &sApply))
){
break;
}
nTab = sqlite3Strlen30(zTab);
}
+9 -16
View File
@@ -319,8 +319,7 @@ int sqlite3session_changeset(
** the from-table, a DELETE record is added to the session object.
**
** <li> For each row (primary key) that exists in both tables, but features
** different non-PK values in each, an UPDATE record is added to the
** session.
** different in each, an UPDATE record is added to the session.
** </ul>
**
** To clarify, if this function is called and then a changeset constructed
@@ -905,7 +904,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
** <ul>
** <li> The table has the same name as the name recorded in the
** changeset, and
** <li> The table has at least as many columns as recorded in the
** <li> The table has the same number of columns as recorded in the
** changeset, and
** <li> The table has primary key columns in the same position as
** recorded in the changeset.
@@ -950,11 +949,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
** If a row with matching primary key values is found, but one or more of
** the non-primary key fields contains a value different from the original
** row value stored in the changeset, the conflict-handler function is
** invoked with [SQLITE_CHANGESET_DATA] as the second argument. If the
** database table has more columns than are recorded in the changeset,
** only the values of those non-primary key fields are compared against
** the current database contents - any trailing database table columns
** are ignored.
** invoked with [SQLITE_CHANGESET_DATA] as the second argument.
**
** If no row with matching primary key values is found in the database,
** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
@@ -969,9 +964,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
**
** <dt>INSERT Changes<dd>
** For each INSERT change, an attempt is made to insert the new row into
** the database. If the changeset row contains fewer fields than the
** database table, the trailing fields are populated with their default
** values.
** the database.
**
** If the attempt to insert the row fails because the database already
** contains a row with the same primary key values, the conflict handler
@@ -989,13 +982,13 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
** For each UPDATE change, this function checks if the target database
** contains a row with the same primary key value (or values) as the
** original row values stored in the changeset. If it does, and the values
** stored in all modified non-primary key columns also match the values
** stored in the changeset the row is updated within the target database.
** stored in all non-primary key columns also match the values stored in
** the changeset the row is updated within the target database.
**
** If a row with matching primary key values is found, but one or more of
** the modified non-primary key fields contains a value different from an
** original row value stored in the changeset, the conflict-handler function
** is invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
** the non-primary key fields contains a value different from an original
** row value stored in the changeset, the conflict-handler function is
** invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
** UPDATE changes only contain values for non-primary key fields that are
** to be modified, only those fields need to match the original values to
** avoid the SQLITE_CHANGESET_DATA conflict-handler callback.
-8
View File
@@ -21,10 +21,6 @@
*/
#ifdef SQLITE_USER_AUTHENTICATION
#ifdef __cplusplus
extern "C" {
#endif
/*
** If a database contains the SQLITE_USER table, then the
** sqlite3_user_authenticate() interface must be invoked with an
@@ -89,8 +85,4 @@ int sqlite3_user_delete(
const char *zUsername /* Username to remove */
);
#ifdef __cplusplus
} /* end of the 'extern "C"' block */
#endif
#endif /* SQLITE_USER_AUTHENTICATION */
+1 -2
View File
@@ -477,7 +477,6 @@ SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
DBFUZZ_OPT =
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
ST_OPT = -DSQLITE_THREADSAFE=0
@@ -899,7 +898,7 @@ speedtest1$(EXE): $(TOP)/test/speedtest1.c sqlite3.c
$(TCCX) -I. $(ST_OPT) -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.c $(THREADLIB)
kvtest$(EXE): $(TOP)/test/kvtest.c sqlite3.c
$(TCCX) -I. $(KV_OPT) -o kvtest$(EXE) $(TOP)/test/kvtest.c sqlite3.c $(THREADLIB)
$(TCCX) -I. $(KV+OPT) -o kvtest$(EXE) $(TOP)/test/kvtest.c sqlite3.c $(THREADLIB)
rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o
$(TCC) -I. -o rbu$(EXE) $(TOP)/ext/rbu/rbu.c sqlite3.o \
+88 -101
View File
@@ -1,17 +1,17 @@
C The\soutput\sof\sthe\s".dump"\scommand\sin\sthe\sCLI\squotes\snewline\sand\scarriage-return\ncharacters\susing\s"char(10)"\sand\s"char(13)".
D 2017-03-11T01:56:41.692
F Makefile.in 2dae2a56457c2885425a480e1053de8096aff924
C Merge\sthe\slatest\strunk\schanges,\sespecially\sthe\sRTREE\senhancement\sto\suse\nsqlite3_blob\sobjects.
D 2017-02-04T14:30:57.322
F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 9020fa41eb91f657ae0cc44145d0a2f3af520860
F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
F VERSION 3605fa447e4623f5ff4a6adc97b1fde9a257b8f2
F VERSION cddd8d88dc8202afa0ebc96da61fc4acbd1e96a5
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4
F autoconf/Makefile.msc 3de603bcec5c07462801a20fd7dc1b871400af99
F autoconf/Makefile.msc 3f29e0fc2a78e113250d79a5da375c1d8d8c06b0
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1
F autoconf/configure.ac cacf2616abf6e4a569bde2ef365c143caeec40bc
@@ -30,7 +30,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure b15d030a8ae2e672d76c97b6667dacb98934a467 x
F configure fcfa56d5d66668c9263dc007724f62acff06dc83 x
F configure.ac 605173e829ab64514ed89f9b53d0da1739d7b0a0
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html b5a3c07d33ecb8e019ce8f7660fe2dbbad9d7977
@@ -70,9 +70,9 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c 95c7041ea75d82d2d9a4cd058904ba889751f5b8
F ext/fts3/fts3.c 5a8cafedffd101e9946f8909ecf8d34aaa383b4d
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h eb2502000148e80913b965db3e59f29251266d0a
F ext/fts3/fts3Int.h 89d0bd4595a0de384dac78e94b803de12586e8dd
F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1
F ext/fts3/fts3_expr.c dfd571a24412779ac01f25c01d888c6ef7b2d0ef
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
@@ -98,15 +98,15 @@ F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8
F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
F ext/fts5/fts5.h 62f3e33ceeb9a428db139f9c012186b371da1cc7
F ext/fts5/fts5Int.h c629b24d2b92b99596f3b8e82289fddca06df6e1
F ext/fts5/fts5Int.h b2eda36e0f224365c8e23dc8f559311834f1c13f
F ext/fts5/fts5_aux.c 67acf8d51723cf28ffc3828210ba662df4b8d267
F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd
F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857
F ext/fts5/fts5_expr.c c6ecc2280162a3714d15dce2a8f2299f748b627c
F ext/fts5/fts5_expr.c 33f0e8063ac7360bcd71c0ff0dcbacdc05fffe50
F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2
F ext/fts5/fts5_index.c f67032a9a529ba52a545e6e3ab970764199c05d4
F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2
F ext/fts5/fts5_storage.c 8f0e65cb33bde8f449e1c9b4be4600d18b4da6e9
F ext/fts5/fts5_storage.c de0ed8a06738bde433afe11e92295ceaffbc4e58
F ext/fts5/fts5_tcl.c 4a901f00c8553740dba63511603f5527d741c26a
F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc
F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be
@@ -160,12 +160,10 @@ F ext/fts5/test/fts5fault8.test 6785af34bd1760de74e2824ea9c161965af78f85
F ext/fts5/test/fts5fault9.test e10e395428a9ea0596ebe752ff7123d16ab78e08
F ext/fts5/test/fts5faultA.test fa5d59c0ff62b7125cd14eee38ded1c46e15a7ea
F ext/fts5/test/fts5faultB.test 7f3bba790fa172073ac314f9b8ed197390b61eca
F ext/fts5/test/fts5faultD.test cc5d1225556e356615e719c612e845d41bff7d5a
F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741
F ext/fts5/test/fts5fuzz1.test bece4695fc169b61ab236ada7931c6e4942cbef9
F ext/fts5/test/fts5hash.test 06f9309ccb4d5050a131594e9e47d0b21456837d
F ext/fts5/test/fts5integrity.test f5e4f8d284385875068ad0f3e894ce43e9de835d
F ext/fts5/test/fts5lastrowid.test 4fac1aba696dd6c956e03b0cf91f6f1f3aaec494
F ext/fts5/test/fts5matchinfo.test f7dde99697bcb310ea8faa8eb2714d9f4dfc0e1b
F ext/fts5/test/fts5merge.test 9f65f090d214ff865c56bef4f864aaa1182af6e3
F ext/fts5/test/fts5merge2.test a6da3c16d694235938d1939f503cfa53f0943d75
@@ -225,7 +223,6 @@ F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb
F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35
F ext/misc/sha1.c 0b9e9b855354910d3ca467bf39099d570e73db56
F ext/misc/shathree.c 38aa4c3c3d3c3fc34b8ea367bed299d8d8a224b2
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
F ext/misc/spellfix.c a4723b6aff748a417b5091b68a46443265c40f0d
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
@@ -251,7 +248,6 @@ F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2
F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831
F ext/rbu/rbu_common.tcl a38e8e2d4a50fd6aaf151633714c1b1d2fae3ead
F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695
F ext/rbu/rbucrash2.test b2ecbdd7bb72c88bd217c65bd00dafa07f7f2d4d
F ext/rbu/rbudiff.test 3e605cf624d00d04d0fb1316a3acec4fbe3b3ac5
F ext/rbu/rbudor.test 99b05cc0df613e962c2c8085cfb05686a09cf315
F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89
@@ -259,16 +255,16 @@ F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06
F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca
F ext/rbu/rbufault4.test 34e70701cbec51571ffbd9fbf9d4e0f2ec495ca7
F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda
F ext/rbu/rbuprogress.test 1849d4e0e50616edf5ce75ce7db86622e656b5cf
F ext/rbu/rbuprogress.test e3e25fb7622641b8f2df7c6b7a7eb6fddfc46a4b
F ext/rbu/rburesume.test 8acb77f4a422ff55acfcfc9cc15a5cb210b1de83
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0
F ext/rbu/rbuvacuum2.test 2074ab14fe66e1c7e7210c62562650dcd215bbaa
F ext/rbu/sqlite3rbu.c 2a89efba9eeba8e6c89a498dc195e8efbdde2694
F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318
F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba
F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/rtree.c 3f3a595dba485e340246fa2c8ba330a6b9768b00
F ext/rtree/rtree.c 0c229d23ce7b9bc69365281689065f3cbbe4561e
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
@@ -294,7 +290,7 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a
F ext/session/session1.test c8a50e0e8581dc1a00e832aa59bb61f180404d44
F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0
F ext/session/session3.test ce9ce3dfa489473987f899e9f6a0f2db9bde3479
F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01
F ext/session/session4.test 457b02bdc349eb01151e54de014df77abd3c08c8
F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169
F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26
@@ -307,22 +303,21 @@ F ext/session/sessionD.test d4744c78334162851d2a2f285c7e603e31b49aa2
F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26
F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce
F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60
F ext/session/session_common.tcl 7776eda579773113b30c7abfd4545c445228cb73
F ext/session/session_common.tcl 9b696a341cf1d3744823715ed92bb19749b6c3d4
F ext/session/session_speed_test.c edc1f96fd5e0e4b16eb03e2a73041013d59e8723
F ext/session/sessionat.test b25d61d663ebc795506bf74079dc4ba0092fad25
F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7
F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0
F ext/session/sessionwor.test 2f3744236dc8b170a695b7d8ddc8c743c7e79fdc
F ext/session/sqlite3session.c 13642d9c754cc18f17e141f82860d269e2adf920
F ext/session/sqlite3session.h d4db650adfcc7a4360e9f12a09c2d117b1db6b53
F ext/session/sqlite3session.c c61a43396368ec00dc127f7bc647e9bd6a4ee5fb
F ext/session/sqlite3session.h 9345166bd8f80562145586cf817f707de5ecada2
F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk 0ec10b604f4668f7e85a358954babe75c94dc0d5
F main.mk afc52937b4e5fe08678e8d5a4fe4487d44e3bc61
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@@ -335,23 +330,23 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121
F src/analyze.c 6d8234916c29be943e6ea28b5bef67dff98d9905
F src/analyze.c ac7a5d7e3cee07d074697904e00e4a8ab7b2b4f5
F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43
F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
F src/btree.c e2bae0a03f73d119910fb35c9550987564065137
F src/btree.h bf64dfeeddeebdb775a5eba0098bbc00d073290d
F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0
F src/build.c 43f903c9082040ced2b421543cb0300c2973647d
F src/btree.c 9fe65ab418d99e80289f024016b5e5e74c3059dd
F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac
F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e
F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af
F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c a9984df73898c042a5cfc8f9d8e7723d02bc35c9
F src/date.c ee676e7694dfadbdd2fde1a258a71be8360ba5ae
F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a
F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e
F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d
F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c
F src/expr.c 8a29e9b72d4b642189999c41782cd6c5bc43512f
F src/expr.c d29114e9b709eaeaaa18553a5bbe60a19302aeef
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae
F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b
@@ -360,13 +355,13 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c 3ed64afc49c0a2221e397b9f65d231ffbef506fe
F src/legacy.c e88ed13c2d531decde75d42c2e35623fb9ce3cb0
F src/insert.c 444354c23d4d140a57d6eb46f34e376a7f8f62e8
F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258
F src/main.c 158326243c5ddc8b98a1e983fa488650cf76d760
F src/malloc.c 89c98e3619d362dcffa5c1c639b364b65b474751
F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0
F src/malloc.c fc1b9f445290f2145da48fc08730c26e6082b640
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c fd7cd6fe21d46fe0a4186367dd8dc26d87b787eb
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
@@ -376,44 +371,44 @@ F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23
F src/mutex_w32.c a898fa969823b100c0f5fdc57e54c9a1e419ab4d
F src/mutex_w32.c 5e6fe1c298fb5a8a15aaed4161d5759311431c17
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
F src/os.c add02933b1dce7a39a005b00a2f5364b763e9a24
F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820
F src/os_win.c 2a6c73eef01c51a048cc4ddccd57f981afbec18a
F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b
F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa
F src/parse.y 48b03113704ee8bd78ee6996d81de7fbee22e105
F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870
F src/parse.y 591704fce84f814d9a3642774c1f011d38f4149c
F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953
F src/pragma.c b7bf4f1dd9cdcdd3f72f0bdbce3502d69d0f48ba
F src/pragma.h c9c763958fec92b04125571472c9500b351c5f7f
F src/pragma.c 7831956012f5d764761fbd023e59b0ffc08f5e8d
F src/pragma.h 61aa5389118594bebb28120a6720401aee34ce1a
F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a
F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c
F src/printf.c ff10a9b9902cd2afe5f655f3013c6307d969b1fd
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c 3e518b962d932a997fae373366880fc028c75706
F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f
F src/shell.c 353f3cebb938099577494326e2853010512e0625
F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850
F src/shell.c a84e453c213f3e0d6935a582024da4e242f85a19
F src/sqlite.h.in 878b0f81f3f59d1f24c002127dd18740a81ba32a
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
F src/sqliteInt.h df268ce1d04df042cf43b557d2309eb0b71e86c4
F src/sqliteInt.h 3724c48e82605b471bbf7e41109b5850c6e89f31
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
F src/tclsqlite.c 6c2151b6d8d98e183a04466d40df8889c0574d79
F src/tclsqlite.c 418f5e5e0840425a7e5b33f3600dccd378a57549
F src/test1.c 8a98191a1da8e100f77cdb5cc716df67d405028d
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c d03f5b5da9a2410b7a91c64b0d3306ed28ab6fee
F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6
F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d
F src/test6.c 004ad42f121f693b8cbe060d1a330678abc61620
F src/test6.c 55aa2775c154415dcf4ed7cd1e19a193122b3a02
F src/test7.c 5612e9aecf934d6df7bba6ce861fdf5ba5456010
F src/test8.c 4f4904721167b32f7a4fa8c7b32a07a673d6cc86
F src/test9.c 12e5ba554d2d1cbe0158f6ab3f7ffcd7a86ee4e5
@@ -421,7 +416,7 @@ F src/test_async.c 195ab49da082053fdb0f949c114b806a49ca770a
F src/test_autoext.c 915d245e736652a219a907909bb6710f0d587871
F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0
F src/test_bestindex.c d23f80d334c59662af69191854c76b8d3d0c8c96
F src/test_blob.c f65ac717da2618691cf9dad094e6da0219dcd208
F src/test_blob.c 6a4c7920d1d9c6cc0f7aa50c89c4f80016aeda83
F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274
F src/test_config.c 83179ea845479b5be9a651d014649e3f2722a1fe
F src/test_delete.c af7eab5702f853fb1c62a5f7665e2234cf1ae17b
@@ -458,31 +453,31 @@ F src/test_windirent.c 17f91f5f2aa1bb7328abb49414c363b5d2a9d3ff
F src/test_windirent.h 5d67483a55442e31e1bde0f4a230e6e932ad5906
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c dc748c5afcb9e5beb3ef5651bc99a4622e30f6a1
F src/tokenize.c 25ccc63ae2c4163933221f3181c9982b47cd08d2
F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c
F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182
F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6
F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569
F src/vdbe.c f520378e510fd36bbf289921798dbc8f2b3dc30d
F src/util.c a88b0466fddf445ce752226d4698ca3faada620a
F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16
F src/vdbe.c e7b1e860140f1d1803c6f4176b1e8f3801f3a290
F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c
F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f
F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860
F src/vdbeaux.c 57361f2e761d92a254638bdbfc03fc68ae6aebc6
F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9
F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1
F src/vdbeaux.c b9a36e530e6525ca9d9a685bc7b1d01fa77b5cf8
F src/vdbeblob.c a0e2edbfff53935c5434e2bce031801decd0e6dd
F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd
F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face
F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
F src/vtab.c 007513c2ef52472fcdea6a741683d50662e82790
F src/vtab.c c4bbe0f870f52036553f8098aee0703997f0577a
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344
F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71
F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791
F src/where.c 1a3a8adb717a20f17c186f3baa22b0b5f3a5ab13
F src/whereInt.h 2d50c2b74a33be44cb68fdecee30b4d93552f1f4
F src/wherecode.c 677e95413c472c0b413023b6b69a47f40fce1b04
F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c
F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0
F src/where.c bc71775e23d23334e8f449aa31012d692dc09cb2
F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d
F src/wherecode.c 99a8ced164c75edf41b3a865a75381c9adb38b28
F src/whereexpr.c 35ad025389a632a3987a35617c878be3b3d70dc6
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -525,7 +520,6 @@ F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0
F test/auth.test c6ede04bee65637ff354b43fc1235aa560c0863e
F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1
F test/auth3.test 0d48b901cf111c14b4b1b5205c7d28f1a278190f
F test/autoanalyze1.test 1ba80d5e1412d46503566b70741a5eea060da929
F test/autoinc.test 6ae8fb69c9f656962464ae4e6667045d0dfc3b46
F test/autoindex1.test 14b63a9f1e405fe6d5bfc8c8d00249c2ebaf13ea
F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df
@@ -580,7 +574,7 @@ F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
F test/check.test 92b23a91fb7be12fba7ee9ce518217e2919a21da
F test/check.test 85a84bfc4be0e83f668747211c7cd45a6721d485
F test/close.test 83947daf3b700631f90f4850ddaab455be4af73d
F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
@@ -612,7 +606,7 @@ F test/corrupt8.test 2399dfe40d2c0c63af86706e30f3e6302a8d0516
F test/corrupt9.test 730a3db08d4ab9aa43392ea30d9c2b4879cbff85
F test/corruptA.test 53e56dafd180addcdadb402244b8cb9771d2ba26
F test/corruptB.test 73a8d6c0b9833697ecf16b63e3c5c05c945b5dec
F test/corruptC.test 46ec43bd90a02fd7b37ad8a7a949c55aa5717f89
F test/corruptC.test 4ef10844eba5213bd262f4d96784d7fcda114afe
F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040
F test/corruptE.test 82ccf4f8f543fdbedd4aa42c709cb077f7374c62
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
@@ -620,7 +614,6 @@ F test/corruptG.test adf79b669cbfd19e28c8191a610d083ae53a6d51
F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454
F test/corruptI.test 075fe1d75aa1d84e2949be56b6264376c41502e4
F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
F test/corruptK.test 814a59ec699d8546b4e29005fba3d16e933ef2fe
F test/cost.test 1eedbfd868f806f3fa08ff072b04cf270dcf61c8
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
F test/coveridxscan.test b629e896b14df2f000a99b8d170d80589c46562c
@@ -640,8 +633,8 @@ F test/csv01.test e0ba3caaa57e4c667a0b45977689fb8082f14348
F test/ctime.test ff6c38e822459d6ca743c34901caf57740b08b54
F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856
F test/cursorhint2.test 8457e93d97f665f23f97cdbc8477d16e3480331b
F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
F test/date.test a6a5a48b90907bca9fbcc79a30be5a715c1ab2fc
F test/dbfuzz.c 8cc2bdb818b4483a052f9f80f96be74cbd9a6e1d
F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5
F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
@@ -659,7 +652,7 @@ F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
F test/e_blobbytes.test 439a945953b35cb6948a552edaec4dc31fd70a05
F test/e_blobclose.test 4b3c8c60c2171164d472059c73e9f3c1844bb66d
F test/e_blobopen.test e95e1d40f995056f6f322cd5e1a1b83a27e1a145
F test/e_blobwrite.test 650ded42ee5e0c2dbf263583ce01adf280129599
F test/e_blobwrite.test 98c2f532be5b4e5f7b4d653f716bec06835b7957
F test/e_changes.test fd66105385153dbf21fdb35eb8ef6c3e1eade579
F test/e_createtable.test d4c6059d44dcd4b636de9aae322766062b471844
F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e
@@ -681,7 +674,6 @@ F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625
F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8
F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0
F test/e_walhook.test 4c0613a0c76e7a9d5c4c211e1b4cbcc1143914df
F test/emptytable.test a38110becbdfa6325cd65cb588dca658cd885f62
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473
F test/enc3.test 6807f7a7740a00361ca8d0ccd66bc60c8dc5f2b6
@@ -810,7 +802,6 @@ F test/fts4growth.test e5390da74619cacc389711bac9349640b32c4f9a
F test/fts4growth2.test 13ad4e76451af6e6906c95cdc725d01b00044269
F test/fts4incr.test 4e353a0bd886ea984e56fce9e77724fc923b8d0d
F test/fts4langid.test 65a7332c9bc257919e259a304aa8a38c41655b9d
F test/fts4lastrowid.test fa5e157955a3121615ef3e16ff5196e96c9e1e64
F test/fts4merge.test d2b39f6b1bd4a9738a13540e2d044cba11c43d47
F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891
F test/fts4merge3.test 8d9ccb4a3d41c4c617a149d6c4b13ad02de797d0
@@ -856,10 +847,10 @@ F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068
F test/in5.test 6c006e0bcd7351b69350ef566e65f244023489e9
F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822
F test/incrblob2.test a5ce5ed1d0b01e2ed347245a21170372528af0a5
F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4
F test/incrblob3.test f1b473c65d8bb43b5f4e2bdcc3f7fc3ac83fd19c
F test/incrblob4.test 21a52a6843a56cdcce968c6a86b72a7066d0e6ba
F test/incrblob_err.test 69f9247fed50278d48ea710d1a8f9cdb09e4c0b8
F test/incrblobfault.test 74dd8ac108304cea0b4a0df6df63a1567e558758
F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e
F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a
F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32
F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d
@@ -874,7 +865,7 @@ F test/index6.test b4fc812290067a578b98bb2667b676db89e202a7
F test/index7.test 7feababe16f2091b229c22aff2bcc1d4d6b9d2bb
F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985
F test/indexexpr1.test 038b3befa74e5a75126b6e9dd2ae5df61c1c7cf7
F test/indexexpr1.test 7d243fac508b4a99fb900ffe34eb488312cfce84
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371
@@ -911,7 +902,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac
F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a
F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
F test/kvtest.c b9a9822dda05a1aa481215a52e2fc93cd8b22ee5
F test/kvtest.c 7a3c38ee56b9cc45dc5a5edc50fd9bc9425659a9
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302
@@ -935,7 +926,7 @@ F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
F test/malloc.test 21c213365f2cca95ab2d7dc078dc8525f96065f8
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
F test/malloc5.test 192d0b5ee1d023a07d5164c34cf47d010da73da1
F test/malloc5.test 02ed7c5313f0a68d95f2dfca8c8962132bd1f04b
F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a
F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d
@@ -1006,7 +997,7 @@ F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f
F test/ossfuzz.c f04b9f236e51d4db701bdebe8ac01318c83102a8
F test/ossfuzz.c e469138f4be3e92df6173b79b3b216ab6e17b407
F test/ossshell.c d9f1a6f43e7bab45d6be857a5800f5d4a1861db3
F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d
@@ -1022,13 +1013,13 @@ F test/parser1.test 391b9bf9a229547a129c61ac345ed1a6f5eb1854
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
F test/permutations.test 46ad98770d3c04ce2418cab2cc527647bfe961a7
F test/permutations.test cd0b7bc04bf5e50d3a993d24c834d591f7d4f5fe
F test/pragma.test 1e94755164a3a3264cd39836de4bebcb7809e5f8
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed
F test/pragma4.test 6e85b6eab8e61ffc9c7db59d842276674e8e3264
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
F test/printf2.test 9e6db85f81c63f2367c34a9d7db384088bd374ad
F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
@@ -1109,7 +1100,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
F test/shell1.test bc1ca4161e1f459c9cd412d3f21f4ee635cf2322
F test/shell1.test 52ac23a345772ab0d6d3241a21a633fdaa3ed581
F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1
F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d
@@ -1144,7 +1135,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/speedtest1.c 7b1ab42b097b484c18d99e1d1c71a6a0c9c87a7a
F test/speedtest1.c 02fe15bb784c5276a083ffe9969cc51e0bce7644
F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
@@ -1176,7 +1167,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
F test/tester.tcl 581f0185434daf7026ccede4c07e8d1479186ec5
F test/tester.tcl 2a49c1aff731f380ea640106377e19611a1443ae
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@@ -1212,7 +1203,7 @@ F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84
F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f
F test/tkt-6bfb98dfc0.test 24780633627b5cfc0635a5500c2389ebfb563336
F test/tkt-752e1646fc.test ea78d88d14fe9866bdd991c634483334639e13bf
F test/tkt-78e04e52ea.test 1b2e6bf4f1d9887b216b6da774e5f25915ec8118
F test/tkt-78e04e52ea.test 813779f8888f3ca226df656c4eef078f9635f3c9
F test/tkt-7a31705a7e6.test e75a2bba4eec801b92c8040eb22096ac6d35e844
F test/tkt-7bbfb7d442.test 7b2cd79c7a17ae6750e75ec1a7846712a69c9d18
F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8
@@ -1381,7 +1372,7 @@ F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab
F test/vtab1.test ed4a576231d8a36e70fd18e2b79b621b31e7f22a
F test/vtab1.test 7c4b81abd88361ada9cbe414c459efca26be6bda
F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3
@@ -1396,7 +1387,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292
F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96
F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe
F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b
F test/vtabH.test 5f9253eb9e41ba9fe94f4aa3e9230191893d7764
F test/vtabH.test a2912cd3ea3386aecc3cb74ebfdfcc4e6d4b7dd3
F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
@@ -1472,10 +1463,10 @@ F test/wordcount.c 06efb84b7c48a4973c2c24ea06c93d00bce24389
F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa
F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e
F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
F tool/GetTclKit.bat 6afa640edc7810725aec61c3076ac617c4aaf0b7
F tool/GetTclKit.bat f94784e3bdc2f50c539266f5467cbf1f27612cb3
F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
F tool/addopcodes.tcl 10c889c4a65ec6c5604e4a47306fa77ff57ae189
F tool/build-all-msvc.bat c12328d06c45fec8baada5949e3d5af54bf8c887 x
F tool/build-all-msvc.bat 018c1b273458a90c8ba633c6f0c5654cfcb138bf x
F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
F tool/cg_anno.tcl f95b0006c52cf7f0496b506343415b6ee3cdcdd3 x
F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
@@ -1493,18 +1484,17 @@ F tool/lempar.c db1bdb4821f2d8fbd76e577cf3ab18642c8d08d1
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7
F tool/mkkeywordhash.c f7f3b342211ac6a14258b9726d5b97cf4f548f22
F tool/mkmsvcmin.tcl 95b37e202cbed873aa8ffdbb493b9db45927be2b
F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkpragmatab.tcl 2ffe6d5fdc2d3381621d6c77978ba054466e757f
F tool/mkpragmatab.tcl ebb4bfcd2f8010e0a3934b6118db4b5f2f5edf5c
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb
F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e
F tool/mksqlite3h.tcl b9836752c3d08f9fab2dfc0017ca9fd5d90ac863
F tool/mksqlite3h.tcl c006c4e5da57c649b24b689511dcd270dd7b0249
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
@@ -1562,10 +1552,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 7359fcacaadc349f520536311dcd1d0b5cea7673
R 21dd742a2e245e17ea4fce05d92294e6
T *branch * string-quoting-dump
T *sym-string-quoting-dump *
T -sym-trunk *
P 53b77838f05b4805b956b5763c75af434662fb20 97ccf3e4de11ffea46993cb7fb7ab559b9810705
R 2f9978803a25617be0ce666b2a1de5c0
U drh
Z 185539d207724f873d847ed122ae7c58
Z 44ad075deb400520ebcde6cf0102f52f
+1 -1
View File
@@ -1 +1 @@
8b2954dd8376e2de985cf5dedeb6eec32c430505
61bd2a885da45e7fa4f02ea1c44d6706faa6bf46
+30 -46
View File
@@ -290,7 +290,6 @@ struct Stat4Accum {
Stat4Sample *aBest; /* Array of nCol best samples */
int iMin; /* Index in a[] of entry with minimum score */
int nSample; /* Current number of samples */
int nMaxEqZero; /* Max leading 0 in anEq[] for any a[] entry */
int iGet; /* Index of current sample accessed by stat_get() */
Stat4Sample *a; /* Array of mxSample Stat4Sample objects */
sqlite3 *db; /* Database connection, for malloc() */
@@ -555,13 +554,6 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
assert( IsStat4 || nEqZero==0 );
#ifdef SQLITE_ENABLE_STAT4
/* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0
** values in the anEq[] array of any sample in Stat4Accum.a[]. In
** other words, if nMaxEqZero is n, then it is guaranteed that there
** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */
if( nEqZero>p->nMaxEqZero ){
p->nMaxEqZero = nEqZero;
}
if( pNew->isPSample==0 ){
Stat4Sample *pUpgrade = 0;
assert( pNew->anEq[pNew->iCol]>0 );
@@ -659,22 +651,12 @@ static void samplePushPrevious(Stat4Accum *p, int iChng){
}
}
/* Check that no sample contains an anEq[] entry with an index of
** p->nMaxEqZero or greater set to zero. */
/* Update the anEq[] fields of any samples already collected. */
for(i=p->nSample-1; i>=0; i--){
int j;
for(j=p->nMaxEqZero; j<p->nCol; j++) assert( p->a[i].anEq[j]>0 );
}
/* Update the anEq[] fields of any samples already collected. */
if( iChng<p->nMaxEqZero ){
for(i=p->nSample-1; i>=0; i--){
int j;
for(j=iChng; j<p->nCol; j++){
if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
}
for(j=iChng; j<p->nCol; j++){
if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
}
p->nMaxEqZero = iChng;
}
#endif
@@ -1388,14 +1370,27 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
if( i==1 ) continue; /* Do not analyze the TEMP database */
analyzeDatabase(pParse, i);
}
}else if( pName2->n==0 && (iDb = sqlite3FindDb(db, pName1))>=0 ){
/* Analyze the schema named as the argument */
analyzeDatabase(pParse, iDb);
}else if( pName2->n==0 ){
/* Form 2: Analyze the database or table named */
iDb = sqlite3FindDb(db, pName1);
if( iDb>=0 ){
analyzeDatabase(pParse, iDb);
}else{
z = sqlite3NameFromToken(db, pName1);
if( z ){
if( (pIdx = sqlite3FindIndex(db, z, 0))!=0 ){
analyzeTable(pParse, pIdx->pTable, pIdx);
}else if( (pTab = sqlite3LocateTable(pParse, 0, z, 0))!=0 ){
analyzeTable(pParse, pTab, 0);
}
sqlite3DbFree(db, z);
}
}
}else{
/* Form 3: Analyze the table or index named as an argument */
/* Form 3: Analyze the fully qualified table name */
iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName);
if( iDb>=0 ){
zDb = pName2->n ? db->aDb[iDb].zDbSName : 0;
zDb = db->aDb[iDb].zDbSName;
z = sqlite3NameFromToken(db, pTableName);
if( z ){
if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){
@@ -1405,11 +1400,10 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
}
sqlite3DbFree(db, z);
}
}
}
if( db->nSqlExec==0 && (v = sqlite3GetVdbe(pParse))!=0 ){
sqlite3VdbeAddOp0(v, OP_Expire);
}
}
v = sqlite3GetVdbe(pParse);
if( v ) sqlite3VdbeAddOp0(v, OP_Expire);
}
/*
@@ -1538,11 +1532,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
#endif
pIndex->bUnordered = 0;
decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
pIndex->hasStat1 = 1;
if( pIndex->pPartIdxWhere==0 ){
pTable->nRowLogEst = pIndex->aiRowLogEst[0];
pTable->tabFlags |= TF_HasStat1;
}
if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
}else{
Index fakeIdx;
fakeIdx.szIdxRow = pTable->szTabRow;
@@ -1551,7 +1541,6 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
#endif
decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx);
pTable->szTabRow = fakeIdx.szIdxRow;
pTable->tabFlags |= TF_HasStat1;
}
return 0;
@@ -1846,20 +1835,15 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
HashElem *i;
char *zSql;
int rc = SQLITE_OK;
Schema *pSchema = db->aDb[iDb].pSchema;
assert( iDb>=0 && iDb<db->nDb );
assert( db->aDb[iDb].pBt!=0 );
/* Clear any prior statistics */
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){
Table *pTab = sqliteHashData(i);
pTab->tabFlags &= ~TF_HasStat1;
}
for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
pIdx->hasStat1 = 0;
pIdx->aiRowLogEst[0] = 0;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3DeleteIndexSamples(db, pIdx);
pIdx->aSample = 0;
@@ -1882,9 +1866,9 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
/* Set appropriate defaults on all indexes not in the sqlite_stat1 table */
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx);
if( pIdx->aiRowLogEst[0]==0 ) sqlite3DefaultRowEst(pIdx);
}
/* Load the statistics from the sqlite_stat4 table. */
@@ -1894,7 +1878,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
rc = loadStat4(db, sInfo.zDatabase);
db->lookaside.bDisable--;
}
for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
sqlite3_free(pIdx->aiRowEst);
pIdx->aiRowEst = 0;
+16 -89
View File
@@ -1317,18 +1317,17 @@ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
/*
** Defragment the page given. This routine reorganizes cells within the
** page so that there are no free-blocks on the free-block list.
**
** Parameter nMaxFrag is the maximum amount of fragmented space that may be
** present in the page after this routine returns.
** Defragment the page given. All Cells are moved to the
** end of the page and all free space is collected into one
** big FreeBlk that occurs in between the header and cell
** pointer array and the cell content area.
**
** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a
** b-tree page so that there are no freeblocks or fragment bytes, all
** unused bytes are contained in the unallocated space region, and all
** cells are packed tightly at the end of the page.
*/
static int defragmentPage(MemPage *pPage, int nMaxFrag){
static int defragmentPage(MemPage *pPage){
int i; /* Loop counter */
int pc; /* Address of the i-th cell */
int hdr; /* Offset to the page header */
@@ -1343,6 +1342,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
int iCellFirst; /* First allowable cell index */
int iCellLast; /* Last possible cell index */
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
assert( pPage->pBt!=0 );
assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
@@ -1354,56 +1354,9 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
cellOffset = pPage->cellOffset;
nCell = pPage->nCell;
assert( nCell==get2byte(&data[hdr+3]) );
iCellFirst = cellOffset + 2*nCell;
usableSize = pPage->pBt->usableSize;
/* This block handles pages with two or fewer free blocks and nMaxFrag
** or fewer fragmented bytes. In this case it is faster to move the
** two (or one) blocks of cells using memmove() and add the required
** offsets to each pointer in the cell-pointer array than it is to
** reconstruct the entire page. */
if( (int)data[hdr+7]<=nMaxFrag ){
int iFree = get2byte(&data[hdr+1]);
if( iFree ){
int iFree2 = get2byte(&data[iFree]);
/* pageFindSlot() has already verified that free blocks are sorted
** in order of offset within the page, and that no block extends
** past the end of the page. Provided the two free slots do not
** overlap, this guarantees that the memmove() calls below will not
** overwrite the usableSize byte buffer, even if the database page
** is corrupt. */
assert( iFree2==0 || iFree2>iFree );
assert( iFree+get2byte(&data[iFree+2]) <= usableSize );
assert( iFree2==0 || iFree2+get2byte(&data[iFree2+2]) <= usableSize );
if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){
u8 *pEnd = &data[cellOffset + nCell*2];
u8 *pAddr;
int sz2 = 0;
int sz = get2byte(&data[iFree+2]);
int top = get2byte(&data[hdr+5]);
if( iFree2 ){
if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_BKPT;
sz2 = get2byte(&data[iFree2+2]);
assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize );
memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
sz += sz2;
}
cbrk = top+sz;
assert( cbrk+(iFree-top) <= usableSize );
memmove(&data[cbrk], &data[top], iFree-top);
for(pAddr=&data[cellOffset]; pAddr<pEnd; pAddr+=2){
pc = get2byte(pAddr);
if( pc<iFree ){ put2byte(pAddr, pc+sz); }
else if( pc<iFree2 ){ put2byte(pAddr, pc+sz2); }
}
goto defragment_out;
}
}
}
cbrk = usableSize;
iCellFirst = cellOffset + 2*nCell;
iCellLast = usableSize - 4;
for(i=0; i<nCell; i++){
u8 *pAddr; /* The i-th cell pointer */
@@ -1437,18 +1390,16 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
}
memcpy(&data[cbrk], &src[pc], size);
}
data[hdr+7] = 0;
defragment_out:
if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){
return SQLITE_CORRUPT_BKPT;
}
assert( cbrk>=iCellFirst );
put2byte(&data[hdr+5], cbrk);
data[hdr+1] = 0;
data[hdr+2] = 0;
data[hdr+7] = 0;
memset(&data[iCellFirst], 0, cbrk-iCellFirst);
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
if( cbrk-iCellFirst!=pPage->nFree ){
return SQLITE_CORRUPT_BKPT;
}
return SQLITE_OK;
}
@@ -1586,10 +1537,10 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
testcase( gap+2+nByte==top );
if( gap+2+nByte>top ){
assert( pPage->nCell>0 || CORRUPT_DB );
rc = defragmentPage(pPage, MIN(4, pPage->nFree - (2+nByte)));
rc = defragmentPage(pPage);
if( rc ) return rc;
top = get2byteNotZero(&data[hdr+5]);
assert( gap+2+nByte<=top );
assert( gap+nByte<=top );
}
@@ -4825,7 +4776,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
pCur, pCur->curPagerFlags);
}
#ifdef SQLITE_DEBUG
#if SQLITE_DEBUG
/*
** Page pParent is an internal (non-leaf) tree page. This function
** asserts that page number iChild is the left-child if the iIdx'th
@@ -5368,30 +5319,6 @@ int sqlite3BtreeEof(BtCursor *pCur){
return (CURSOR_VALID!=pCur->eState);
}
/*
** Return an estimate for the number of rows in the table that pCur is
** pointing to. Return a negative number if no estimate is currently
** available.
*/
i64 sqlite3BtreeRowCountEst(BtCursor *pCur){
i64 n;
u8 i;
assert( cursorOwnsBtShared(pCur) );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
/* Currently this interface is only called by the OP_IfSmaller
** opcode, and it that case the cursor will always be valid and
** will always point to a leaf node. */
if( NEVER(pCur->eState!=CURSOR_VALID) ) return -1;
if( NEVER(pCur->apPage[pCur->iPage]->leaf==0) ) return -1;
for(n=1, i=0; i<=pCur->iPage; i++){
n *= pCur->apPage[i]->nCell;
}
return n;
}
/*
** Advance the cursor to the next entry in the database. If
** successful then set *pRes=0. If the cursor
@@ -6236,7 +6163,7 @@ static int fillInCell(
** Use a call to btreeParseCellPtr() to verify that the values above
** were computed correctly.
*/
#ifdef SQLITE_DEBUG
#if SQLITE_DEBUG
{
CellInfo info;
pPage->xParseCell(pPage, pCell, &info);
@@ -7762,7 +7689,7 @@ static int balance_nonroot(
** free space needs to be up front.
*/
assert( nNew==1 || CORRUPT_DB );
rc = defragmentPage(apNew[0], -1);
rc = defragmentPage(apNew[0]);
testcase( rc!=SQLITE_OK );
assert( apNew[0]->nFree ==
(get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2)
-1
View File
@@ -296,7 +296,6 @@ u32 sqlite3BtreePayloadSize(BtCursor*);
char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
struct Pager *sqlite3BtreePager(Btree*);
i64 sqlite3BtreeRowCountEst(BtCursor*);
#ifndef SQLITE_OMIT_INCRBLOB
int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*);
+4 -2
View File
@@ -692,9 +692,11 @@ struct IntegrityCk {
*/
#if SQLITE_BYTEORDER==4321
# define get2byteAligned(x) (*(u16*)(x))
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4008000
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
&& GCC_VERSION>=4008000
# define get2byteAligned(x) __builtin_bswap16(*(u16*)(x))
#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
&& defined(_MSC_VER) && _MSC_VER>=1300
# define get2byteAligned(x) _byteswap_ushort(*(u16*)(x))
#else
# define get2byteAligned(x) ((x)[0]<<8 | (x)[1])
-4
View File
@@ -1115,7 +1115,6 @@ void sqlite3AddNotNull(Parse *pParse, int onError){
p = pParse->pNewTable;
if( p==0 || NEVER(p->nCol<1) ) return;
p->aCol[p->nCol-1].notNull = (u8)onError;
p->tabFlags |= TF_HasNotNull;
}
/*
@@ -3455,9 +3454,6 @@ void sqlite3DefaultRowEst(Index *pIdx){
int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol);
int i;
/* Indexes with default row estimates should not have stat1 data */
assert( !pIdx->hasStat1 );
/* Set the first entry (number of rows in the index) to the estimated
** number of rows in the table, or half the number of rows in the table
** for a partial index. But do not let the estimate drop below 10. */
+1 -1
View File
@@ -57,7 +57,7 @@ static const char * const azCompileOpt[] = {
#if SQLITE_COVERAGE_TEST
"COVERAGE_TEST",
#endif
#ifdef SQLITE_DEBUG
#if SQLITE_DEBUG
"DEBUG",
#endif
#if SQLITE_DEFAULT_LOCKING_MODE
+1 -2
View File
@@ -743,19 +743,18 @@ static int parseModifier(
** or month or year.
*/
if( sqlite3_strnicmp(z, "start of ", 9)!=0 ) break;
if( !p->validJD && !p->validYMD && !p->validHMS ) break;
z += 9;
computeYMD(p);
p->validHMS = 1;
p->h = p->m = 0;
p->s = 0.0;
p->rawS = 0;
p->validTZ = 0;
p->validJD = 0;
if( sqlite3_stricmp(z,"month")==0 ){
p->D = 1;
rc = 0;
}else if( sqlite3_stricmp(z,"year")==0 ){
computeYMD(p);
p->M = 1;
p->D = 1;
rc = 0;
+3 -14
View File
@@ -231,7 +231,7 @@ static char comparisonAffinity(Expr *pExpr){
aff = sqlite3CompareAffinity(pExpr->pRight, aff);
}else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff);
}else if( aff==0 ){
}else if( NEVER(aff==0) ){
aff = SQLITE_AFF_BLOB;
}
return aff;
@@ -2367,7 +2367,7 @@ static char *exprINAffinity(Parse *pParse, Expr *pExpr){
char *zRet;
assert( pExpr->op==TK_IN );
zRet = sqlite3DbMallocRaw(pParse->db, nVal+1);
zRet = sqlite3DbMallocZero(pParse->db, nVal+1);
if( zRet ){
int i;
for(i=0; i<nVal; i++){
@@ -3272,7 +3272,7 @@ void sqlite3ExprCodeGetColumnToReg(
void sqlite3ExprCacheClear(Parse *pParse){
int i;
#ifdef SQLITE_DEBUG
#if SQLITE_DEBUG
if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
printf("CLEAR\n");
}
@@ -4680,17 +4680,6 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
return 0;
}
/*
** Like sqlite3ExprCompare() except COLLATE operators at the top-level
** are ignored.
*/
int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){
return sqlite3ExprCompare(
sqlite3ExprSkipCollate(pA),
sqlite3ExprSkipCollate(pB),
iTab);
}
/*
** Return true if we can prove the pE2 will always be true if pE1 is
** true. Return false if we cannot complete the proof or if pE2 might
+4 -10
View File
@@ -1527,9 +1527,6 @@ void sqlite3GenerateConstraintChecks(
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
VdbeComment((v, "for %s", pIdx->zName));
#ifdef SQLITE_ENABLE_NULL_TRIM
if( pIdx->idxType==2 ) sqlite3SetMakeRecordP5(v, pIdx->pTable);
#endif
/* In an UPDATE operation, if this index is the PRIMARY KEY index
** of a WITHOUT ROWID table and there has been no change the
@@ -1685,11 +1682,8 @@ void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){
** version 2 and later (SQLite version 3.1.4, 2005-02-20). */
if( pTab->pSchema->file_format<2 ) return;
for(i=pTab->nCol-1; i>0; i--){
if( pTab->aCol[i].pDflt!=0 ) break;
if( pTab->aCol[i].colFlags & COLFLAG_PRIMKEY ) break;
}
sqlite3VdbeChangeP5(v, i+1);
for(i=pTab->nCol; i>1 && pTab->aCol[i-1].pDflt==0; i--){}
sqlite3VdbeChangeP5(v, i);
}
#endif
@@ -1979,7 +1973,7 @@ static int xferOptimization(
return 0; /* tab1 must not have triggers */
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pDest) ){
if( pDest->tabFlags & TF_Virtual ){
return 0; /* tab1 must not be a virtual table */
}
#endif
@@ -2041,7 +2035,7 @@ static int xferOptimization(
return 0; /* source and destination must both be WITHOUT ROWID or not */
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pSrc) ){
if( pSrc->tabFlags & TF_Virtual ){
return 0; /* tab2 must not be a virtual table */
}
#endif
+1 -2
View File
@@ -73,7 +73,7 @@ int sqlite3_exec(
(SQLITE_DONE==rc && !callbackIsInit
&& db->flags&SQLITE_NullCallback)) ){
if( !callbackIsInit ){
azCols = sqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*));
azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1);
if( azCols==0 ){
goto exec_out;
}
@@ -94,7 +94,6 @@ int sqlite3_exec(
goto exec_out;
}
}
azVals[i] = 0;
}
if( xCallback(pArg, nCol, azVals, azCols) ){
/* EVIDENCE-OF: R-38229-40159 If the callback function to
-15
View File
@@ -921,21 +921,6 @@ sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
return db->lastRowid;
}
/*
** Set the value returned by the sqlite3_last_insert_rowid() API function.
*/
void sqlite3_set_last_insert_rowid(sqlite3 *db, sqlite3_int64 iRowid){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return;
}
#endif
sqlite3_mutex_enter(db->mutex);
db->lastRowid = iRowid;
sqlite3_mutex_leave(db->mutex);
}
/*
** Return the number of changes in the most recent call to sqlite3_exec().
*/
+6 -21
View File
@@ -219,27 +219,12 @@ static void sqlite3MallocAlarm(int nByte){
*/
static void mallocWithAlarm(int n, void **pp){
void *p;
int nFull;
int nFull = 0;
assert( sqlite3_mutex_held(mem0.mutex) );
assert( n>0 );
/* In Firefox (circa 2017-02-08), xRoundup() is remapped to an internal
** implementation of malloc_good_size(), which must be called in debug
** mode and specifically when the DMD "Dark Matter Detector" is enabled
** or else a crash results. Hence, do not attempt to optimize out the
** following xRoundup() call. */
nFull = sqlite3GlobalConfig.m.xRoundup(n);
#ifdef SQLITE_MAX_MEMORY
if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nFull>SQLITE_MAX_MEMORY ){
*pp = 0;
return;
}
#endif
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
if( mem0.alarmThreshold>0 ){
sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
nFull = sqlite3GlobalConfig.m.xRoundup(n);
if( nUsed >= mem0.alarmThreshold - nFull ){
mem0.nearlyFull = 1;
sqlite3MallocAlarm(nFull);
@@ -247,11 +232,11 @@ static void mallocWithAlarm(int n, void **pp){
mem0.nearlyFull = 0;
}
}
p = sqlite3GlobalConfig.m.xMalloc(nFull);
p = sqlite3GlobalConfig.m.xMalloc(n);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
if( p==0 && mem0.alarmThreshold>0 ){
sqlite3MallocAlarm(nFull);
p = sqlite3GlobalConfig.m.xMalloc(nFull);
p = sqlite3GlobalConfig.m.xMalloc(n);
}
#endif
if( p ){
@@ -425,7 +410,7 @@ int sqlite3MallocSize(void *p){
int sqlite3DbMallocSize(sqlite3 *db, void *p){
assert( p!=0 );
if( db==0 || !isLookaside(db,p) ){
#ifdef SQLITE_DEBUG
#if SQLITE_DEBUG
if( db==0 ){
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
@@ -486,7 +471,7 @@ void sqlite3DbFree(sqlite3 *db, void *p){
}
if( isLookaside(db, p) ){
LookasideSlot *pBuf = (LookasideSlot*)p;
#ifdef SQLITE_DEBUG
#if SQLITE_DEBUG
/* Trash all content in the buffer being freed */
memset(p, 0xaa, db->lookaside.sz);
#endif
+2 -4
View File
@@ -125,9 +125,7 @@ static malloc_zone_t* _sqliteZone_;
*/
static void *sqlite3MemMalloc(int nByte){
#ifdef SQLITE_MALLOCSIZE
void *p;
testcase( ROUND8(nByte)==nByte );
p = SQLITE_MALLOC( nByte );
void *p = SQLITE_MALLOC( nByte );
if( p==0 ){
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
@@ -136,7 +134,7 @@ static void *sqlite3MemMalloc(int nByte){
#else
sqlite3_int64 *p;
assert( nByte>0 );
testcase( ROUND8(nByte)!=nByte );
nByte = ROUND8(nByte);
p = SQLITE_MALLOC( nByte+8 );
if( p ){
p[0] = nByte;
+8 -7
View File
@@ -87,7 +87,8 @@ void sqlite3MemoryBarrier(void){
SQLITE_MEMORY_BARRIER;
#elif defined(__GNUC__)
__sync_synchronize();
#elif MSVC_VERSION>=1300
#elif !defined(SQLITE_DISABLE_INTRINSIC) && \
defined(_MSC_VER) && _MSC_VER>=1300
_ReadWriteBarrier();
#elif defined(MemoryBarrier)
MemoryBarrier();
@@ -298,8 +299,8 @@ static void winMutexEnter(sqlite3_mutex *p){
p->owner = tid;
p->nRef++;
if( p->trace ){
OSTRACE(("ENTER-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
tid, p->id, p, p->trace, p->nRef));
OSTRACE(("ENTER-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n",
tid, p, p->trace, p->nRef));
}
#endif
}
@@ -341,8 +342,8 @@ static int winMutexTry(sqlite3_mutex *p){
#endif
#ifdef SQLITE_DEBUG
if( p->trace ){
OSTRACE(("TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n",
tid, p->id, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc)));
OSTRACE(("TRY-MUTEX tid=%lu, mutex=%p (%d), owner=%lu, nRef=%d, rc=%s\n",
tid, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc)));
}
#endif
return rc;
@@ -370,8 +371,8 @@ static void winMutexLeave(sqlite3_mutex *p){
LeaveCriticalSection(&p->mutex);
#ifdef SQLITE_DEBUG
if( p->trace ){
OSTRACE(("LEAVE-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
tid, p->id, p, p->trace, p->nRef));
OSTRACE(("LEAVE-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n",
tid, p, p->trace, p->nRef));
}
#endif
}
+7 -45
View File
@@ -352,34 +352,7 @@ struct winVfsAppData {
******************************************************************************
*/
#ifndef SQLITE_WIN32_HEAP_CREATE
# define SQLITE_WIN32_HEAP_CREATE (TRUE)
#endif
/*
* This is the maximum possible initial size of the Win32-specific heap, in
* bytes.
*/
#ifndef SQLITE_WIN32_HEAP_MAX_INIT_SIZE
# define SQLITE_WIN32_HEAP_MAX_INIT_SIZE (4294967295U)
#endif
/*
* This is the extra space for the initial size of the Win32-specific heap,
* in bytes. This value may be zero.
*/
#ifndef SQLITE_WIN32_HEAP_INIT_EXTRA
# define SQLITE_WIN32_HEAP_INIT_EXTRA (4194304)
#endif
/*
* Calculate the maximum legal cache size, in pages, based on the maximum
* possible initial heap size and the default page size, setting aside the
* needed extra space.
*/
#ifndef SQLITE_WIN32_MAX_CACHE_SIZE
# define SQLITE_WIN32_MAX_CACHE_SIZE (((SQLITE_WIN32_HEAP_MAX_INIT_SIZE) - \
(SQLITE_WIN32_HEAP_INIT_EXTRA)) / \
(SQLITE_DEFAULT_PAGE_SIZE))
# define SQLITE_WIN32_HEAP_CREATE (TRUE)
#endif
/*
@@ -388,36 +361,25 @@ struct winVfsAppData {
*/
#ifndef SQLITE_WIN32_CACHE_SIZE
# if SQLITE_DEFAULT_CACHE_SIZE>=0
# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE)
# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE)
# else
# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE))
# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE))
# endif
#endif
/*
* Make sure that the calculated cache size, in pages, cannot cause the
* initial size of the Win32-specific heap to exceed the maximum amount
* of memory that can be specified in the call to HeapCreate.
*/
#if SQLITE_WIN32_CACHE_SIZE>SQLITE_WIN32_MAX_CACHE_SIZE
# undef SQLITE_WIN32_CACHE_SIZE
# define SQLITE_WIN32_CACHE_SIZE (2000)
#endif
/*
* The initial size of the Win32-specific heap. This value may be zero.
*/
#ifndef SQLITE_WIN32_HEAP_INIT_SIZE
# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \
(SQLITE_DEFAULT_PAGE_SIZE) + \
(SQLITE_WIN32_HEAP_INIT_EXTRA))
# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \
(SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
#endif
/*
* The maximum size of the Win32-specific heap. This value may be zero.
*/
#ifndef SQLITE_WIN32_HEAP_MAX_SIZE
# define SQLITE_WIN32_HEAP_MAX_SIZE (0)
# define SQLITE_WIN32_HEAP_MAX_SIZE (0)
#endif
/*
@@ -425,7 +387,7 @@ struct winVfsAppData {
* zero for the default behavior.
*/
#ifndef SQLITE_WIN32_HEAP_FLAGS
# define SQLITE_WIN32_HEAP_FLAGS (0)
# define SQLITE_WIN32_HEAP_FLAGS (0)
#endif
+2 -2
View File
@@ -899,7 +899,7 @@ term(A) ::= INTEGER(X). {
A.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &X, 1);
A.zStart = X.z;
A.zEnd = X.z + X.n;
if( A.pExpr ) A.pExpr->flags |= EP_Leaf|EP_Resolved;
if( A.pExpr ) A.pExpr->flags |= EP_Leaf;
}
expr(A) ::= VARIABLE(X). {
if( !(X.z[0]=='#' && sqlite3Isdigit(X.z[1])) ){
@@ -1000,7 +1000,7 @@ expr(A) ::= expr(A) STAR|SLASH|REM(OP) expr(Y).
{spanBinaryExpr(pParse,@OP,&A,&Y);}
expr(A) ::= expr(A) CONCAT(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);}
%type likeop {Token}
likeop(A) ::= LIKE_KW|MATCH(A).
likeop(A) ::= LIKE_KW|MATCH(X). {A=X;/*A-overwrites-X*/}
likeop(A) ::= NOT LIKE_KW|MATCH(X). {A=X; A.n|=0x80000000; /*A-overwrite-X*/}
expr(A) ::= expr(A) likeop(OP) expr(Y). [LIKE_KW] {
ExprList *pList;
+1 -1
View File
@@ -104,7 +104,7 @@ struct PCache {
**
** assert( sqlite3PcachePageSanity(pPg) );
*/
#ifdef SQLITE_DEBUG
#if SQLITE_DEBUG
int sqlite3PcachePageSanity(PgHdr *pPg){
PCache *pCache;
assert( pPg!=0 );
+48 -198
View File
@@ -295,22 +295,6 @@ static const PragmaName *pragmaLocate(const char *zName){
return lwr>upr ? 0 : &aPragmaName[mid];
}
/*
** Helper subroutine for PRAGMA integrity_check:
**
** Generate code to output a single-column result row with the result
** held in register regResult. Decrement the result count and halt if
** the maximum number of result rows have been issued.
*/
static int integrityCheckResultRow(Vdbe *v, int regResult){
int addr;
sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 1);
addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1);
VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
return addr;
}
/*
** Process a pragma statement.
**
@@ -1114,33 +1098,29 @@ void sqlite3Pragma(
}
break;
#ifdef SQLITE_DEBUG
case PragTyp_STATS: {
Index *pIdx;
HashElem *i;
pParse->nMem = 5;
pParse->nMem = 4;
sqlite3CodeVerifySchema(pParse, iDb);
for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
Table *pTab = sqliteHashData(i);
sqlite3VdbeMultiLoad(v, 1, "ssiii",
sqlite3VdbeMultiLoad(v, 1, "ssii",
pTab->zName,
0,
pTab->szTabRow,
pTab->nRowLogEst,
pTab->tabFlags);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
pTab->nRowLogEst);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
sqlite3VdbeMultiLoad(v, 2, "siii",
sqlite3VdbeMultiLoad(v, 2, "sii",
pIdx->zName,
pIdx->szIdxRow,
pIdx->aiRowLogEst[0],
pIdx->hasStat1);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
pIdx->aiRowLogEst[0]);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
}
}
}
break;
#endif
case PragTyp_INDEX_INFO: if( zRight ){
Index *pIdx;
@@ -1397,17 +1377,9 @@ void sqlite3Pragma(
#endif
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/* PRAGMA integrity_check
** PRAGMA integrity_check(N)
** PRAGMA quick_check
** PRAGMA quick_check(N)
**
** Verify the integrity of the database.
**
** The "quick_check" is reduced version of
/* Pragma "quick_check" is reduced version of
** integrity_check designed to detect most database corruption
** without the overhead of cross-checking indexes. Quick_check
** is linear time wherease integrity_check is O(NlogN).
** without most of the overhead of a full integrity-check.
*/
case PragTyp_INTEGRITY_CHECK: {
int i, j, addr, mxErr;
@@ -1438,7 +1410,7 @@ void sqlite3Pragma(
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
}
}
sqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */
sqlite3VdbeAddOp2(v, OP_Integer, mxErr, 1); /* reg[1] holds errors left */
/* Do an integrity check on each database file */
for(i=0; i<db->nDb; i++){
@@ -1453,6 +1425,10 @@ void sqlite3Pragma(
if( iDb>=0 && i!=iDb ) continue;
sqlite3CodeVerifySchema(pParse, i);
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */
VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
sqlite3VdbeJumpHere(v, addr);
/* Do an integrity check of the B-Tree
**
@@ -1492,12 +1468,12 @@ void sqlite3Pragma(
P4_DYNAMIC);
sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1);
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
integrityCheckResultRow(v, 2);
sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
sqlite3VdbeJumpHere(v, addr);
/* Make sure all the indices are constructed correctly.
*/
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
Table *pTab = sqliteHashData(x);
Index *pIdx, *pPk;
Index *pPrior = 0;
@@ -1505,13 +1481,12 @@ void sqlite3Pragma(
int iDataCur, iIdxCur;
int r1 = -1;
if( pTab->pCheck==0
&& (pTab->tabFlags & TF_HasNotNull)==0
&& (pTab->pIndex==0 || isQuick)
){
continue; /* No additional checks needed for this table */
}
if( pTab->pIndex==0 ) continue;
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
sqlite3VdbeJumpHere(v, addr);
sqlite3ExprCacheClear(pParse);
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
1, 0, &iDataCur, &iIdxCur);
@@ -1526,42 +1501,24 @@ void sqlite3Pragma(
/* Verify that all NOT NULL columns really are NOT NULL */
for(j=0; j<pTab->nCol; j++){
char *zErr;
int jmp2;
int jmp2, jmp3;
if( j==pTab->iPKey ) continue;
if( pTab->aCol[j].notNull==0 ) continue;
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
pTab->aCol[j].zName);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
integrityCheckResultRow(v, 3);
sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
sqlite3VdbeAddOp0(v, OP_Halt);
sqlite3VdbeJumpHere(v, jmp2);
}
/* Verify CHECK constraints */
if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
int addrCkFault = sqlite3VdbeMakeLabel(v);
int addrCkOk = sqlite3VdbeMakeLabel(v);
ExprList *pCheck = pTab->pCheck;
char *zErr;
int k;
pParse->iSelfTab = iDataCur;
sqlite3ExprCachePush(pParse);
for(k=pCheck->nExpr-1; k>0; k--){
sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
}
sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk,
SQLITE_JUMPIFNULL);
sqlite3VdbeResolveLabel(v, addrCkFault);
zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
pTab->zName);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
integrityCheckResultRow(v, 3);
sqlite3VdbeResolveLabel(v, addrCkOk);
sqlite3ExprCachePop(pParse);
sqlite3VdbeJumpHere(v, jmp3);
}
/* Validate index entries for the current row */
for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; pIdx=pIdx->pNext, j++){
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int jmp2, jmp3, jmp4, jmp5;
int ckUniq = sqlite3VdbeMakeLabel(v);
if( pPk==pIdx ) continue;
@@ -1572,13 +1529,16 @@ void sqlite3Pragma(
/* Verify that an index entry exists for the current table row */
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1,
pIdx->nColumn); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
sqlite3VdbeLoadString(v, 3, "row ");
sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
sqlite3VdbeLoadString(v, 4, " missing from index ");
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName);
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
jmp4 = integrityCheckResultRow(v, 3);
sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
sqlite3VdbeAddOp0(v, OP_Halt);
sqlite3VdbeJumpHere(v, jmp2);
/* For UNIQUE indexes, verify that only one entry exists with the
** current key. The entry is unique if (1) any column is NULL
@@ -1599,6 +1559,7 @@ void sqlite3Pragma(
sqlite3VdbeJumpHere(v, jmp6);
sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1,
pIdx->nKeyCol); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
sqlite3VdbeGoto(v, jmp5);
sqlite3VdbeResolveLabel(v, uniqOk);
@@ -1609,18 +1570,19 @@ void sqlite3Pragma(
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, loopTop-1);
#ifndef SQLITE_OMIT_BTREECOUNT
if( !isQuick ){
sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
if( pPk==pIdx ) continue;
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
sqlite3VdbeLoadString(v, 3, pIdx->zName);
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
integrityCheckResultRow(v, 7);
sqlite3VdbeJumpHere(v, addr);
}
sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
if( pPk==pIdx ) continue;
addr = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
sqlite3VdbeLoadString(v, 3, pIdx->zName);
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
}
#endif /* SQLITE_OMIT_BTREECOUNT */
}
@@ -1629,7 +1591,7 @@ void sqlite3Pragma(
static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList endCode[] = {
{ OP_AddImm, 1, 0, 0}, /* 0 */
{ OP_IfNotZero, 1, 4, 0}, /* 1 */
{ OP_If, 1, 4, 0}, /* 1 */
{ OP_String8, 0, 3, 0}, /* 2 */
{ OP_ResultRow, 3, 1, 0}, /* 3 */
};
@@ -1637,7 +1599,7 @@ void sqlite3Pragma(
aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn);
if( aOp ){
aOp[0].p2 = 1-mxErr;
aOp[0].p2 = -mxErr;
aOp[2].p4type = P4_STATIC;
aOp[2].p4.z = "ok";
}
@@ -1862,118 +1824,6 @@ void sqlite3Pragma(
break;
}
/*
** PRAGMA optimize
** PRAGMA optimize(MASK)
** PRAGMA schema.optimize
** PRAGMA schema.optimize(MASK)
**
** Attempt to optimize the database. All schemas are optimized in the first
** two forms, and only the specified schema is optimized in the latter two.
**
** The details of optimizations performed by this pragma are expected
** to change and improve over time. Applications should anticipate that
** this pragma will perform new optimizations in future releases.
**
** The optional argument is a bitmask of optimizations to perform:
**
** 0x0001 Debugging mode. Do not actually perform any optimizations
** but instead return one line of text for each optimization
** that would have been done. Off by default.
**
** 0x0002 Run ANALYZE on tables that might benefit. On by default.
** See below for additional information.
**
** 0x0004 (Not yet implemented) Record usage and performance
** information from the current session in the
** database file so that it will be available to "optimize"
** pragmas run by future database connections.
**
** 0x0008 (Not yet implemented) Create indexes that might have
** been helpful to recent queries
**
** The default MASK is and always shall be 0xfffe. 0xfffe means perform all ** of the optimizations listed above except Debug Mode, including new
** optimizations that have not yet been invented. If new optimizations are
** ever added that should be off by default, those off-by-default
** optimizations will have bitmasks of 0x10000 or larger.
**
** DETERMINATION OF WHEN TO RUN ANALYZE
**
** In the current implementation, a table is analyzed if only if all of
** the following are true:
**
** (1) MASK bit 0x02 is set.
**
** (2) The query planner used sqlite_stat1-style statistics for one or
** more indexes of the table at some point during the lifetime of
** the current connection.
**
** (3) One or more indexes of the table are currently unanalyzed OR
** the number of rows in the table has increased by 25 times or more
** since the last time ANALYZE was run.
**
** The rules for when tables are analyzed are likely to change in
** future releases.
*/
case PragTyp_OPTIMIZE: {
int iDbLast; /* Loop termination point for the schema loop */
int iTabCur; /* Cursor for a table whose size needs checking */
HashElem *k; /* Loop over tables of a schema */
Schema *pSchema; /* The current schema */
Table *pTab; /* A table in the schema */
Index *pIdx; /* An index of the table */
LogEst szThreshold; /* Size threshold above which reanalysis is needd */
char *zSubSql; /* SQL statement for the OP_SqlExec opcode */
u32 opMask; /* Mask of operations to perform */
if( zRight ){
opMask = (u32)sqlite3Atoi(zRight);
if( (opMask & 0x02)==0 ) break;
}else{
opMask = 0xfffe;
}
iTabCur = pParse->nTab++;
for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){
if( iDb==1 ) continue;
sqlite3CodeVerifySchema(pParse, iDb);
pSchema = db->aDb[iDb].pSchema;
for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
pTab = (Table*)sqliteHashData(k);
/* If table pTab has not been used in a way that would benefit from
** having analysis statistics during the current session, then skip it.
** This also has the effect of skipping virtual tables and views */
if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue;
/* Reanalyze if the table is 25 times larger than the last analysis */
szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 );
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( !pIdx->hasStat1 ){
szThreshold = 0; /* Always analyze if any index lacks statistics */
break;
}
}
if( szThreshold ){
sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur,
sqlite3VdbeCurrentAddr(v)+2+(opMask&1), szThreshold);
VdbeCoverage(v);
}
zSubSql = sqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"",
db->aDb[iDb].zDbSName, pTab->zName);
if( opMask & 0x01 ){
int r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp4(v, OP_String8, 0, r1, 0, zSubSql, P4_DYNAMIC);
sqlite3VdbeAddOp2(v, OP_ResultRow, r1, 1);
}else{
sqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC);
}
}
}
sqlite3VdbeAddOp0(v, OP_Expire);
break;
}
/*
** PRAGMA busy_timeout
** PRAGMA busy_timeout = N
+59 -68
View File
@@ -30,11 +30,11 @@
#define PragTyp_LOCKING_MODE 22
#define PragTyp_PAGE_COUNT 23
#define PragTyp_MMAP_SIZE 24
#define PragTyp_OPTIMIZE 25
#define PragTyp_PAGE_SIZE 26
#define PragTyp_SECURE_DELETE 27
#define PragTyp_SHRINK_MEMORY 28
#define PragTyp_SOFT_HEAP_LIMIT 29
#define PragTyp_PAGE_SIZE 25
#define PragTyp_SECURE_DELETE 26
#define PragTyp_SHRINK_MEMORY 27
#define PragTyp_SOFT_HEAP_LIMIT 28
#define PragTyp_STATS 29
#define PragTyp_SYNCHRONOUS 30
#define PragTyp_TABLE_INFO 31
#define PragTyp_TEMP_STORE 32
@@ -48,7 +48,6 @@
#define PragTyp_REKEY 40
#define PragTyp_LOCK_STATUS 41
#define PragTyp_PARSER_TRACE 42
#define PragTyp_STATS 43
/* Property flags associated with various pragma. */
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
@@ -72,48 +71,47 @@ static const char *const pragCName[] = {
/* 4 */ "notnull",
/* 5 */ "dflt_value",
/* 6 */ "pk",
/* 7 */ "tbl", /* Used by: stats */
/* 8 */ "idx",
/* 9 */ "wdth",
/* 10 */ "hght",
/* 11 */ "flgs",
/* 12 */ "seqno", /* Used by: index_info */
/* 13 */ "cid",
/* 14 */ "name",
/* 15 */ "seqno", /* Used by: index_xinfo */
/* 16 */ "cid",
/* 17 */ "name",
/* 18 */ "desc",
/* 19 */ "coll",
/* 20 */ "key",
/* 21 */ "seq", /* Used by: index_list */
/* 22 */ "name",
/* 23 */ "unique",
/* 24 */ "origin",
/* 25 */ "partial",
/* 26 */ "seq", /* Used by: database_list */
/* 27 */ "name",
/* 28 */ "file",
/* 29 */ "seq", /* Used by: collation_list */
/* 30 */ "name",
/* 31 */ "id", /* Used by: foreign_key_list */
/* 32 */ "seq",
/* 33 */ "table",
/* 34 */ "from",
/* 35 */ "to",
/* 36 */ "on_update",
/* 37 */ "on_delete",
/* 38 */ "match",
/* 39 */ "table", /* Used by: foreign_key_check */
/* 40 */ "rowid",
/* 41 */ "parent",
/* 42 */ "fkid",
/* 43 */ "busy", /* Used by: wal_checkpoint */
/* 44 */ "log",
/* 45 */ "checkpointed",
/* 46 */ "timeout", /* Used by: busy_timeout */
/* 47 */ "database", /* Used by: lock_status */
/* 48 */ "status",
/* 7 */ "table", /* Used by: stats */
/* 8 */ "index",
/* 9 */ "width",
/* 10 */ "height",
/* 11 */ "seqno", /* Used by: index_info */
/* 12 */ "cid",
/* 13 */ "name",
/* 14 */ "seqno", /* Used by: index_xinfo */
/* 15 */ "cid",
/* 16 */ "name",
/* 17 */ "desc",
/* 18 */ "coll",
/* 19 */ "key",
/* 20 */ "seq", /* Used by: index_list */
/* 21 */ "name",
/* 22 */ "unique",
/* 23 */ "origin",
/* 24 */ "partial",
/* 25 */ "seq", /* Used by: database_list */
/* 26 */ "name",
/* 27 */ "file",
/* 28 */ "seq", /* Used by: collation_list */
/* 29 */ "name",
/* 30 */ "id", /* Used by: foreign_key_list */
/* 31 */ "seq",
/* 32 */ "table",
/* 33 */ "from",
/* 34 */ "to",
/* 35 */ "on_update",
/* 36 */ "on_delete",
/* 37 */ "match",
/* 38 */ "table", /* Used by: foreign_key_check */
/* 39 */ "rowid",
/* 40 */ "parent",
/* 41 */ "fkid",
/* 42 */ "busy", /* Used by: wal_checkpoint */
/* 43 */ "log",
/* 44 */ "checkpointed",
/* 45 */ "timeout", /* Used by: busy_timeout */
/* 46 */ "database", /* Used by: lock_status */
/* 47 */ "status",
};
/* Definitions of all built-in pragmas */
@@ -159,7 +157,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "busy_timeout",
/* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 46, 1,
/* ColNames: */ 45, 1,
/* iArg: */ 0 },
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "cache_size",
@@ -196,7 +194,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "collation_list",
/* ePragTyp: */ PragTyp_COLLATION_LIST,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 29, 2,
/* ColNames: */ 28, 2,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
@@ -231,7 +229,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "database_list",
/* ePragTyp: */ PragTyp_DATABASE_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
/* ColNames: */ 26, 3,
/* ColNames: */ 25, 3,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
@@ -268,14 +266,14 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "foreign_key_check",
/* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
/* ePragFlg: */ PragFlg_NeedSchema,
/* ColNames: */ 39, 4,
/* ColNames: */ 38, 4,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
{/* zName: */ "foreign_key_list",
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
/* ColNames: */ 31, 8,
/* ColNames: */ 30, 8,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
@@ -338,17 +336,17 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "index_info",
/* ePragTyp: */ PragTyp_INDEX_INFO,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
/* ColNames: */ 12, 3,
/* ColNames: */ 11, 3,
/* iArg: */ 0 },
{/* zName: */ "index_list",
/* ePragTyp: */ PragTyp_INDEX_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
/* ColNames: */ 21, 5,
/* ColNames: */ 20, 5,
/* iArg: */ 0 },
{/* zName: */ "index_xinfo",
/* ePragTyp: */ PragTyp_INDEX_INFO,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
/* ColNames: */ 15, 6,
/* ColNames: */ 14, 6,
/* iArg: */ 1 },
#endif
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
@@ -395,7 +393,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "lock_status",
/* ePragTyp: */ PragTyp_LOCK_STATUS,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 47, 2,
/* ColNames: */ 46, 2,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
@@ -414,13 +412,6 @@ static const PragmaName aPragmaName[] = {
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
{/* zName: */ "optimize",
/* ePragTyp: */ PragTyp_OPTIMIZE,
/* ePragFlg: */ PragFlg_Result1,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "page_count",
/* ePragTyp: */ PragTyp_PAGE_COUNT,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
@@ -519,11 +510,11 @@ static const PragmaName aPragmaName[] = {
/* iArg: */ SQLITE_SqlTrace },
#endif
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
{/* zName: */ "stats",
/* ePragTyp: */ PragTyp_STATS,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
/* ColNames: */ 7, 5,
/* ColNames: */ 7, 4,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
@@ -602,7 +593,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "wal_checkpoint",
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
/* ePragFlg: */ PragFlg_NeedSchema,
/* ColNames: */ 43, 3,
/* ColNames: */ 42, 3,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
@@ -613,4 +604,4 @@ static const PragmaName aPragmaName[] = {
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
#endif
};
/* Number of pragmas: 60 on by default, 74 total. */
/* Number of pragmas: 60 on by default, 73 total. */
+42 -55
View File
@@ -15,7 +15,7 @@
** Conversion types fall into various categories as defined by the
** following enumeration.
*/
#define etRADIX 0 /* non-decimal integer types. %x %o */
#define etRADIX 0 /* Integer types. %d, %x, %o, and so forth */
#define etFLOAT 1 /* Floating point. %f */
#define etEXP 2 /* Exponentional notation. %e and %E */
#define etGENERIC 3 /* Floating or exponential, depending on exponent. %g */
@@ -33,9 +33,8 @@
#define etPOINTER 13 /* The %p conversion */
#define etSQLESCAPE3 14 /* %w -> Strings with '\"' doubled */
#define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */
#define etDECIMAL 16 /* %d or %u, but not %x, %o */
#define etINVALID 17 /* Any unrecognized conversion type */
#define etINVALID 16 /* Any unrecognized conversion type */
/*
@@ -59,8 +58,8 @@ typedef struct et_info { /* Information about each format field */
/*
** Allowed values for et_info.flags
*/
#define FLAG_SIGNED 1 /* True if the value to convert is signed */
#define FLAG_STRING 4 /* Allow infinite precision */
#define FLAG_SIGNED 1 /* True if the value to convert is signed */
#define FLAG_STRING 4 /* Allow infinity precision */
/*
@@ -70,7 +69,7 @@ typedef struct et_info { /* Information about each format field */
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
static const char aPrefix[] = "-x0\000X0";
static const et_info fmtinfo[] = {
{ 'd', 10, 1, etDECIMAL, 0, 0 },
{ 'd', 10, 1, etRADIX, 0, 0 },
{ 's', 0, 4, etSTRING, 0, 0 },
{ 'g', 0, 1, etGENERIC, 30, 0 },
{ 'z', 0, 4, etDYNSTRING, 0, 0 },
@@ -79,7 +78,7 @@ static const et_info fmtinfo[] = {
{ 'w', 0, 4, etSQLESCAPE3, 0, 0 },
{ 'c', 0, 0, etCHARX, 0, 0 },
{ 'o', 8, 0, etRADIX, 0, 2 },
{ 'u', 10, 0, etDECIMAL, 0, 0 },
{ 'u', 10, 0, etRADIX, 0, 0 },
{ 'x', 16, 0, etRADIX, 16, 1 },
{ 'X', 16, 0, etRADIX, 0, 4 },
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -88,7 +87,7 @@ static const et_info fmtinfo[] = {
{ 'E', 0, 1, etEXP, 14, 0 },
{ 'G', 0, 1, etGENERIC, 14, 0 },
#endif
{ 'i', 10, 1, etDECIMAL, 0, 0 },
{ 'i', 10, 1, etRADIX, 0, 0 },
{ 'n', 0, 0, etSIZE, 0, 0 },
{ '%', 0, 0, etPERCENT, 0, 0 },
{ 'p', 16, 0, etPOINTER, 0, 1 },
@@ -180,13 +179,14 @@ void sqlite3VXPrintf(
int idx; /* A general purpose loop counter */
int width; /* Width of the current field */
etByte flag_leftjustify; /* True if "-" flag is present */
etByte flag_prefix; /* '+' or ' ' or 0 for prefix */
etByte flag_plussign; /* True if "+" flag is present */
etByte flag_blanksign; /* True if " " flag is present */
etByte flag_alternateform; /* True if "#" flag is present */
etByte flag_altform2; /* True if "!" flag is present */
etByte flag_zeropad; /* True if field width constant starts with zero */
etByte flag_long; /* 1 for the "l" flag, 2 for "ll", 0 by default */
etByte flag_long; /* True if "l" flag is present */
etByte flag_longlong; /* True if the "ll" flag is present */
etByte done; /* Loop termination flag */
etByte cThousand; /* Thousands separator for %d and %u */
etByte xtype = etINVALID; /* Conversion paradigm */
u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */
char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
@@ -229,18 +229,17 @@ void sqlite3VXPrintf(
break;
}
/* Find out what flags are present */
flag_leftjustify = flag_prefix = cThousand =
flag_leftjustify = flag_plussign = flag_blanksign =
flag_alternateform = flag_altform2 = flag_zeropad = 0;
done = 0;
do{
switch( c ){
case '-': flag_leftjustify = 1; break;
case '+': flag_prefix = '+'; break;
case ' ': flag_prefix = ' '; break;
case '+': flag_plussign = 1; break;
case ' ': flag_blanksign = 1; break;
case '#': flag_alternateform = 1; break;
case '!': flag_altform2 = 1; break;
case '0': flag_zeropad = 1; break;
case ',': cThousand = ','; break;
default: done = 1; break;
}
}while( !done && (c=(*++fmt))!=0 );
@@ -310,11 +309,13 @@ void sqlite3VXPrintf(
flag_long = 1;
c = *++fmt;
if( c=='l' ){
flag_long = 2;
flag_longlong = 1;
c = *++fmt;
}else{
flag_longlong = 0;
}
}else{
flag_long = 0;
flag_long = flag_longlong = 0;
}
/* Fetch the info entry for the field */
infop = &fmtinfo[0];
@@ -332,11 +333,15 @@ void sqlite3VXPrintf(
**
** flag_alternateform TRUE if a '#' is present.
** flag_altform2 TRUE if a '!' is present.
** flag_prefix '+' or ' ' or zero
** flag_plussign TRUE if a '+' is present.
** flag_leftjustify TRUE if a '-' is present or if the
** field width was negative.
** flag_zeropad TRUE if the width began with 0.
** flag_long 1 for "l", 2 for "ll"
** flag_long TRUE if the letter 'l' (ell) prefixed
** the conversion character.
** flag_longlong TRUE if the letter 'll' (ell ell) prefixed
** the conversion character.
** flag_blanksign TRUE if a ' ' is present.
** width The specified field width. This is
** always non-negative. Zero is the default.
** precision The specified precision. The default
@@ -346,24 +351,19 @@ void sqlite3VXPrintf(
*/
switch( xtype ){
case etPOINTER:
flag_long = sizeof(char*)==sizeof(i64) ? 2 :
sizeof(char*)==sizeof(long int) ? 1 : 0;
flag_longlong = sizeof(char*)==sizeof(i64);
flag_long = sizeof(char*)==sizeof(long int);
/* Fall through into the next case */
case etORDINAL:
case etRADIX:
cThousand = 0;
/* Fall through into the next case */
case etDECIMAL:
case etRADIX:
if( infop->flags & FLAG_SIGNED ){
i64 v;
if( bArgList ){
v = getIntArg(pArgList);
}else if( flag_longlong ){
v = va_arg(ap,i64);
}else if( flag_long ){
if( flag_long==2 ){
v = va_arg(ap,i64) ;
}else{
v = va_arg(ap,long int);
}
v = va_arg(ap,long int);
}else{
v = va_arg(ap,int);
}
@@ -376,17 +376,17 @@ void sqlite3VXPrintf(
prefix = '-';
}else{
longvalue = v;
prefix = flag_prefix;
if( flag_plussign ) prefix = '+';
else if( flag_blanksign ) prefix = ' ';
else prefix = 0;
}
}else{
if( bArgList ){
longvalue = (u64)getIntArg(pArgList);
}else if( flag_longlong ){
longvalue = va_arg(ap,u64);
}else if( flag_long ){
if( flag_long==2 ){
longvalue = va_arg(ap,u64);
}else{
longvalue = va_arg(ap,unsigned long int);
}
longvalue = va_arg(ap,unsigned long int);
}else{
longvalue = va_arg(ap,unsigned int);
}
@@ -396,11 +396,11 @@ void sqlite3VXPrintf(
if( flag_zeropad && precision<width-(prefix!=0) ){
precision = width-(prefix!=0);
}
if( precision<etBUFSIZE-10-etBUFSIZE/3 ){
if( precision<etBUFSIZE-10 ){
nOut = etBUFSIZE;
zOut = buf;
}else{
nOut = precision + 10 + precision/3;
nOut = precision + 10;
zOut = zExtra = sqlite3Malloc( nOut );
if( zOut==0 ){
setStrAccumError(pAccum, STRACCUM_NOMEM);
@@ -426,23 +426,8 @@ void sqlite3VXPrintf(
}while( longvalue>0 );
}
length = (int)(&zOut[nOut-1]-bufpt);
while( precision>length ){
for(idx=precision-length; idx>0; idx--){
*(--bufpt) = '0'; /* Zero pad */
length++;
}
if( cThousand ){
int nn = (length - 1)/3; /* Number of "," to insert */
int ix = (length - 1)%3 + 1;
bufpt -= nn;
for(idx=0; nn>0; idx++){
bufpt[idx] = bufpt[idx+nn];
ix--;
if( ix==0 ){
bufpt[++idx] = cThousand;
nn--;
ix = 3;
}
}
}
if( prefix ) *(--bufpt) = prefix; /* Add sign */
if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
@@ -469,7 +454,9 @@ void sqlite3VXPrintf(
realvalue = -realvalue;
prefix = '-';
}else{
prefix = flag_prefix;
if( flag_plussign ) prefix = '+';
else if( flag_blanksign ) prefix = ' ';
else prefix = 0;
}
if( xtype==etGENERIC && precision>0 ) precision--;
testcase( precision>0xfff );
+24 -30
View File
@@ -229,8 +229,7 @@ static int lookupName(
}
/* Start at the inner-most context and move outward until a match is found */
assert( pNC && cnt==0 );
do{
while( pNC && cnt==0 ){
ExprList *pEList;
SrcList *pSrcList = pNC->pSrcList;
@@ -415,11 +414,11 @@ static int lookupName(
/* Advance to the next name context. The loop will exit when either
** we have a match (cnt>0) or when we run out of name contexts.
*/
if( cnt ) break;
pNC = pNC->pNext;
nSubquery++;
}while( pNC );
if( cnt==0 ){
pNC = pNC->pNext;
nSubquery++;
}
}
/*
** If X and Y are NULL (in other words if only the column name Z is
@@ -609,38 +608,33 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
&& !defined(SQLITE_OMIT_SUBQUERY) */
/* A column name: ID
** Or table name and column name: ID.ID
** Or a database, table and column: ID.ID.ID
**
** The TK_ID and TK_OUT cases are combined so that there will only
** be one call to lookupName(). Then the compiler will in-line
** lookupName() for a size reduction and performance increase.
/* A lone identifier is the name of a column.
*/
case TK_ID: {
return lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr);
}
/* A table name and column name: ID.ID
** Or a database, table and column: ID.ID.ID
*/
case TK_ID:
case TK_DOT: {
const char *zColumn;
const char *zTable;
const char *zDb;
Expr *pRight;
if( pExpr->op==TK_ID ){
/* if( pSrcList==0 ) break; */
notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
pRight = pExpr->pRight;
if( pRight->op==TK_ID ){
zDb = 0;
zTable = 0;
zColumn = pExpr->u.zToken;
zTable = pExpr->pLeft->u.zToken;
zColumn = pRight->u.zToken;
}else{
notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
pRight = pExpr->pRight;
if( pRight->op==TK_ID ){
zDb = 0;
zTable = pExpr->pLeft->u.zToken;
zColumn = pRight->u.zToken;
}else{
assert( pRight->op==TK_DOT );
zDb = pExpr->pLeft->u.zToken;
zTable = pRight->pLeft->u.zToken;
zColumn = pRight->pRight->u.zToken;
}
assert( pRight->op==TK_DOT );
zDb = pExpr->pLeft->u.zToken;
zTable = pRight->pLeft->u.zToken;
zColumn = pRight->pRight->u.zToken;
}
return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
}
+240 -1446
View File
File diff suppressed because it is too large Load Diff
+89 -89
View File
@@ -2040,30 +2040,20 @@ int sqlite3_extended_result_codes(sqlite3*, int onoff);
** the table has a column of type [INTEGER PRIMARY KEY] then that column
** is another alias for the rowid.
**
** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of
** the most recent successful [INSERT] into a rowid table or [virtual table]
** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not
** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred
** on the database connection D, then sqlite3_last_insert_rowid(D) returns
** zero.
** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the
** most recent successful [INSERT] into a rowid table or [virtual table]
** on database connection D.
** ^Inserts into [WITHOUT ROWID] tables are not recorded.
** ^If no successful [INSERT]s into rowid tables
** have ever occurred on the database connection D,
** then sqlite3_last_insert_rowid(D) returns zero.
**
** As well as being set automatically as rows are inserted into database
** tables, the value returned by this function may be set explicitly by
** [sqlite3_set_last_insert_rowid()]
**
** Some virtual table implementations may INSERT rows into rowid tables as
** part of committing a transaction (e.g. to flush data accumulated in memory
** to disk). In this case subsequent calls to this function return the rowid
** associated with these internal INSERT operations, which leads to
** unintuitive results. Virtual table implementations that do write to rowid
** tables in this way can avoid this problem by restoring the original
** rowid value using [sqlite3_set_last_insert_rowid()] before returning
** control to the user.
**
** ^(If an [INSERT] occurs within a trigger then this routine will
** return the [rowid] of the inserted row as long as the trigger is
** running. Once the trigger program ends, the value returned
** by this routine reverts to what it was before the trigger was fired.)^
** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
** method, then this routine will return the [rowid] of the inserted
** row as long as the trigger or virtual table method is running.
** But once the trigger or virtual table method ends, the value returned
** by this routine reverts to what it was before the trigger or virtual
** table method began.)^
**
** ^An [INSERT] that fails due to a constraint violation is not a
** successful [INSERT] and does not change the value returned by this
@@ -2090,16 +2080,6 @@ int sqlite3_extended_result_codes(sqlite3*, int onoff);
*/
sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
/*
** CAPI3REF: Set the Last Insert Rowid value.
** METHOD: sqlite3
**
** The sqlite3_set_last_insert_rowid(D, R) method allows the application to
** set the value returned by calling sqlite3_last_insert_rowid(D) to R
** without inserting a row into the database.
*/
void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
/*
** CAPI3REF: Count The Number Of Rows Modified
** METHOD: sqlite3
@@ -6158,15 +6138,27 @@ int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
/*
** CAPI3REF: A Handle To An Open BLOB
** KEYWORDS: {BLOB handle} {BLOB handles}
** KEYWORDS: {BLOB handle} {BLOB handles} {sqlite3_blob object}
**
** An instance of this object represents a connection to a single
** column in a single row of a table that holds either a BLOB or string
** and on which [sqlite3_blob_open | incremental BLOB I/O] can be performed.
**
** An instance of this object represents an open BLOB on which
** [sqlite3_blob_open | incremental BLOB I/O] can be performed.
** ^Objects of this type are created by [sqlite3_blob_open()]
** and destroyed by [sqlite3_blob_close()].
** ^The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces
** can be used to read or write small subsections of the BLOB.
** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes.
**
** An sqlite3_blob object can be in two states: ACTIVE and RESET. When in
** the ACTIVE state, the object is pointing to a specific entry and is
** ready to do I/O. When RESET, the sqlite3_blob object is in standby mode,
** is not associated with any particular row of its table,
** and is not available for I/O.
**
** The sqlite3_blob object does not contain a mutex and so a single
** sqlite3_blob object may not be safely used by multiple threads
** concurrently.
*/
typedef struct sqlite3_blob sqlite3_blob;
@@ -6175,8 +6167,8 @@ typedef struct sqlite3_blob sqlite3_blob;
** METHOD: sqlite3
** CONSTRUCTOR: sqlite3_blob
**
** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
** in row iRow, column zColumn, table zTable in database zDb;
** ^(This interfaces creates an sqlite3_blob object pointing to the string
** or BLOB located in row iRow, column zColumn, table zTable in database zDb;
** in other words, the same BLOB that would be selected by:
**
** <pre>
@@ -6193,10 +6185,11 @@ typedef struct sqlite3_blob sqlite3_blob;
** and write access. ^If the flags parameter is zero, the BLOB is opened for
** read-only access.
**
** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored
** in *ppBlob. Otherwise an [error code] is returned and, unless the error
** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
** the API is not misused, it is always safe to call [sqlite3_blob_close()]
** ^(On success, [SQLITE_OK] is returned and the new [sqlite3_blob object]
** is stored in *ppBlob. Otherwise an [error code] is returned and
** *ppBlob is set to NULL.)^ ^Because *ppBlob is always set to either a
** valid sqlite3_blob object or NULL
** it is always safe to call [sqlite3_blob_close()]
** on *ppBlob after this function it returns.
**
** This function fails with SQLITE_ERROR if any of the following are true:
@@ -6228,7 +6221,8 @@ typedef struct sqlite3_blob sqlite3_blob;
**
** ^(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".
** then the BLOB handle is marked as "expired" and cannot be used
** successfully with first being [sqlite3_blob_reopen|reopened].
** This is true if any column of the row is changed, even a column
** other than the one the BLOB handle is open on.)^
** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
@@ -6240,7 +6234,8 @@ typedef struct sqlite3_blob sqlite3_blob;
** ^Use the [sqlite3_blob_bytes()] interface to determine the size of
** the opened blob. ^The size of a blob may not be changed by this
** interface. Use the [UPDATE] SQL command to change the size of a
** blob.
** blob. The [sqlite3_blob_bytes()] interface returns an arbitrary
** number when used on an expired sqlite3_blob object.
**
** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
** and the built-in [zeroblob] SQL function may be used to create a
@@ -6251,7 +6246,8 @@ typedef struct sqlite3_blob sqlite3_blob;
**
** See also: [sqlite3_blob_close()],
** [sqlite3_blob_reopen()], [sqlite3_blob_read()],
** [sqlite3_blob_bytes()], [sqlite3_blob_write()].
** [sqlite3_blob_bytes()], [sqlite3_blob_write()],
** [sqlite3_blob_reset()].
*/
int sqlite3_blob_open(
sqlite3*,
@@ -6264,24 +6260,23 @@ int sqlite3_blob_open(
);
/*
** CAPI3REF: Move a BLOB Handle to a New Row
** CAPI3REF: Move an sqlite3_blob object to a New Row
** METHOD: sqlite3_blob
**
** ^This function is used to move an existing [BLOB handle] so that it points
** ^This function updates an existing [sqlite3_blob object] so that it points
** to a different row of the same database table. ^The new row is identified
** by the rowid value passed as the second argument. Only the row can be
** changed. ^The database, table and column on which the blob handle is open
** remain the same. Moving an existing [BLOB handle] to a new row is
** remain the same. Moving an existing [sqlite3_blob object] to a new row is
** faster than closing the existing handle and opening a new one.
**
** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] -
** it must exist and there must be either a blob or text value stored in
** the nominated column.)^ ^If the new row is not present in the table, or if
** it does not contain a blob or text value, or if another error occurs, an
** SQLite error code is returned and the blob handle is considered aborted.
** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or
** [sqlite3_blob_reopen()] on an aborted blob handle immediately return
** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle
** SQLite error code is returned and the [sqlite3_blob object] is changed
** to the RESET state.
** ^Calling [sqlite3_blob_bytes()] on an aborted blob handle
** always returns zero.
**
** ^This function sets the database handle error code and message.
@@ -6289,38 +6284,52 @@ int sqlite3_blob_open(
int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
/*
** CAPI3REF: Close A BLOB Handle
** CAPI3REF: Close an sqlite3_blob object
** DESTRUCTOR: sqlite3_blob
**
** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed
** ^This function is the destructor for an [sqlite3_blob object].
** ^(The [sqlite3_blob object] is closed
** unconditionally. Even if this routine returns an error code, the
** handle is still closed.)^
** object is still closed.)^
**
** ^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
** ^If the sqlite3_blob object being closed was opened for read-write access,
** and is in the ACTIVE state,
** and if the database is in auto-commit mode and there are no other open
** read-write
** blob handles or active write statements, the current transaction is
** committed. ^If an error occurs while committing the transaction, an error
** code is returned and the transaction rolled back.
**
** Calling this function with an argument that is not a NULL pointer or an
** open blob handle results in undefined behaviour. ^Calling this routine
** Calling this function with an argument that is not a NULL pointer or a
** valid sqlite3_blob object pointer results in undefined behaviour.
** ^Calling this routine
** with a null pointer (such as would be returned by a failed call to
** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function
** is passed a valid open blob handle, the values returned by the
** is passed a valid sqlite3_blob objecct pointer, the values returned by the
** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
*/
int sqlite3_blob_close(sqlite3_blob *);
/*
** CAPI3REF: Return The Size Of An Open BLOB
** CAPI3REF: Reset an sqlite3_blob object
** METHOD: sqlite3_blob
**
** ^Returns the size in bytes of the BLOB accessible via the
** successfully opened [BLOB handle] in its only argument. ^The
** incremental blob I/O routines can only read or overwriting existing
** blob content; they cannot change the size of a blob.
** ^This function changes an [sqlite3_blob object] to the RESET state.
** ^If the [sqlite3_blob object] was already in the RESET state, then this
** routine is a harmless no-op.
*/
int sqlite3_blob_reset(sqlite3_blob *);
/*
** CAPI3REF: Return The Size Of A BLOB
** METHOD: sqlite3_blob
**
** This routine only works on a [BLOB handle] which has been created
** ^Returns the size in bytes of the BLOB or string accessible via the
** ACTIVE [sqlite3_blob object] in its only argument. ^The
** incremental blob I/O routines can only read or overwriting existing
** content; they cannot change the size of a blob or string.
**
** This routine only works on an [sqlite3_blob object] that has been created
** by a prior successful call to [sqlite3_blob_open()] and which has not
** been closed by [sqlite3_blob_close()]. Passing any other pointer in
** to this routine results in undefined and probably undesirable behavior.
@@ -6331,9 +6340,9 @@ int sqlite3_blob_bytes(sqlite3_blob *);
** CAPI3REF: Read Data From A BLOB Incrementally
** METHOD: sqlite3_blob
**
** ^(This function is used to read data from an open [BLOB handle] into a
** caller-supplied buffer. N bytes of data are copied into buffer Z
** from the open BLOB, starting at offset iOffset.)^
** ^(This function is used to read data from string or BLOB that an
** [sqlite3_blob object] is pointing to into a caller-supplied buffer.
** N bytes of data are copied into buffer Z starting at offset iOffset.)^
**
** ^If offset iOffset is less than N bytes from the end of the BLOB,
** [SQLITE_ERROR] is returned and no data is read. ^If N or iOffset is
@@ -6341,17 +6350,14 @@ int sqlite3_blob_bytes(sqlite3_blob *);
** ^The size of the blob (and hence the maximum value of N+iOffset)
** can be determined using the [sqlite3_blob_bytes()] interface.
**
** ^An attempt to read from an expired [BLOB handle] fails with an
** ^An attempt to read from an [sqlite3_blob object] that is in the RESET
** state, or from a database row that has changed since the most recent
** call to [sqlite3_blob_open()] or [sqlite3_blob_reopen()] fails with an
** error code of [SQLITE_ABORT].
**
** ^(On success, sqlite3_blob_read() returns SQLITE_OK.
** Otherwise, an [error code] or an [extended error code] is returned.)^
**
** This routine only works on a [BLOB handle] which has been created
** by a prior successful call to [sqlite3_blob_open()] and which has not
** been closed by [sqlite3_blob_close()]. Passing any other pointer in
** to this routine results in undefined and probably undesirable behavior.
**
** See also: [sqlite3_blob_write()].
*/
int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
@@ -6360,9 +6366,10 @@ int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
** CAPI3REF: Write Data Into A BLOB Incrementally
** METHOD: sqlite3_blob
**
** ^(This function is used to write data into an open [BLOB handle] from a
** caller-supplied buffer. N bytes of data are copied from the buffer Z
** into the open BLOB, starting at offset iOffset.)^
** ^(This function is used to write data from a caller-supplied buffer
** into a BLOB or string pointed to by an [sqlite3_blob object].
** N bytes of data are copied from the buffer Z
** into the BLOB or string, starting at offset iOffset.)^
**
** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
** Otherwise, an [error code] or an [extended error code] is returned.)^
@@ -6382,17 +6389,10 @@ int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less
** than zero [SQLITE_ERROR] is returned and no data is written.
**
** ^An attempt to write to an expired [BLOB handle] fails with an
** error code of [SQLITE_ABORT]. ^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.
**
** This routine only works on a [BLOB handle] which has been created
** by a prior successful call to [sqlite3_blob_open()] and which has not
** been closed by [sqlite3_blob_close()]. Passing any other pointer in
** to this routine results in undefined and probably undesirable behavior.
** ^An attempt to write into an [sqlite3_blob object] that is in the RESET
** state, or into a database row that has changed since the most recent
** call to [sqlite3_blob_open()] or [sqlite3_blob_reopen()] fails with an
** error code of [SQLITE_ABORT].
**
** See also: [sqlite3_blob_read()].
*/
+34 -52
View File
@@ -103,28 +103,19 @@
# define _LARGEFILE_SOURCE 1
#endif
/* The GCC_VERSION and MSVC_VERSION macros are used to
** conditionally include optimizations for each of these compilers. A
** value of 0 means that compiler is not being used. The
** SQLITE_DISABLE_INTRINSIC macro means do not use any compiler-specific
** optimizations, and hence set all compiler macros to 0
**
** There was once also a CLANG_VERSION macro. However, we learn that the
** version numbers in clang are for "marketing" only and are inconsistent
** and unreliable. Fortunately, all versions of clang also recognize the
** gcc version numbers and have reasonable settings for gcc version numbers,
** so the GCC_VERSION macro will be set to a correct non-zero value even
** when compiling with clang.
*/
#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
/* What version of GCC is being used. 0 means GCC is not being used */
#ifdef __GNUC__
# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__)
#else
# define GCC_VERSION 0
#endif
#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
# define MSVC_VERSION _MSC_VER
/* What version of CLANG is being used. 0 means CLANG is not being used */
#if defined(__clang__) && !defined(_WIN32)
# define CLANG_VERSION \
(__clang_major__*1000000+__clang_minor__*1000+__clang_patchlevel__)
#else
# define MSVC_VERSION 0
# define CLANG_VERSION 0
#endif
/* Needed for various definitions... */
@@ -256,7 +247,6 @@
# include <intrin.h>
# pragma intrinsic(_byteswap_ushort)
# pragma intrinsic(_byteswap_ulong)
# pragma intrinsic(_byteswap_uint64)
# pragma intrinsic(_ReadWriteBarrier)
# else
# include <cmnintrin.h>
@@ -797,35 +787,32 @@ typedef INT16_TYPE LogEst;
**
** For best performance, an attempt is made to guess at the byte-order
** using C-preprocessor macros. If that is unsuccessful, or if
** -DSQLITE_BYTEORDER=0 is set, then byte-order is determined
** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined
** at run-time.
*/
#ifndef SQLITE_BYTEORDER
# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
defined(__arm__)
# define SQLITE_BYTEORDER 1234
# elif defined(sparc) || defined(__ppc__)
# define SQLITE_BYTEORDER 4321
# else
# define SQLITE_BYTEORDER 0
# endif
#endif
#if SQLITE_BYTEORDER==4321
# define SQLITE_BIGENDIAN 1
# define SQLITE_LITTLEENDIAN 0
# define SQLITE_UTF16NATIVE SQLITE_UTF16BE
#elif SQLITE_BYTEORDER==1234
defined(__arm__)) && !defined(SQLITE_RUNTIME_BYTEORDER)
# define SQLITE_BYTEORDER 1234
# define SQLITE_BIGENDIAN 0
# define SQLITE_LITTLEENDIAN 1
# define SQLITE_UTF16NATIVE SQLITE_UTF16LE
#else
#endif
#if (defined(sparc) || defined(__ppc__)) \
&& !defined(SQLITE_RUNTIME_BYTEORDER)
# define SQLITE_BYTEORDER 4321
# define SQLITE_BIGENDIAN 1
# define SQLITE_LITTLEENDIAN 0
# define SQLITE_UTF16NATIVE SQLITE_UTF16BE
#endif
#if !defined(SQLITE_BYTEORDER)
# ifdef SQLITE_AMALGAMATION
const int sqlite3one = 1;
# else
extern const int sqlite3one;
# endif
# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */
# define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0)
# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)
# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
@@ -1333,7 +1320,6 @@ struct sqlite3 {
u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */
u8 mTrace; /* zero or more SQLITE_TRACE flags */
u8 skipBtreeMutex; /* True if no shared-cache backends */
u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */
int nextPagesize; /* Pagesize after VACUUM if >0 */
u32 magic; /* Magic number for detect library misuse */
int nChange; /* Value returned by sqlite3_changes() */
@@ -1849,7 +1835,6 @@ struct Table {
/* ... also used as column name list in a VIEW */
int tnum; /* Root BTree page for this table */
u32 nTabRef; /* Number of pointers to this Table */
u32 tabFlags; /* Mask of TF_* values */
i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */
i16 nCol; /* Number of columns in this table */
LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */
@@ -1857,6 +1842,7 @@ struct Table {
#ifdef SQLITE_ENABLE_COSTMULT
LogEst costMult; /* Cost multiplier for using this table */
#endif
u8 tabFlags; /* Mask of TF_* values */
u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
#ifndef SQLITE_OMIT_ALTERTABLE
int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */
@@ -1880,17 +1866,15 @@ struct Table {
** the TF_OOOHidden attribute would apply in this case. Such tables require
** special handling during INSERT processing.
*/
#define TF_Readonly 0x0001 /* Read-only system table */
#define TF_Ephemeral 0x0002 /* An ephemeral table */
#define TF_HasPrimaryKey 0x0004 /* Table has a primary key */
#define TF_Autoincrement 0x0008 /* Integer primary key is autoincrement */
#define TF_HasStat1 0x0010 /* nRowLogEst set from sqlite_stat1 */
#define TF_WithoutRowid 0x0020 /* No rowid. PRIMARY KEY is the key */
#define TF_NoVisibleRowid 0x0040 /* No user-visible "rowid" column */
#define TF_OOOHidden 0x0080 /* Out-of-Order hidden columns */
#define TF_StatsUsed 0x0100 /* Query planner decisions affected by
** Index.aiRowLogEst[] values */
#define TF_HasNotNull 0x0200 /* Contains NOT NULL constraints */
#define TF_Readonly 0x01 /* Read-only system table */
#define TF_Ephemeral 0x02 /* An ephemeral table */
#define TF_HasPrimaryKey 0x04 /* Table has a primary key */
#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
#define TF_Virtual 0x10 /* Is a virtual table */
#define TF_WithoutRowid 0x20 /* No rowid. PRIMARY KEY is the key */
#define TF_NoVisibleRowid 0x40 /* No user-visible "rowid" column */
#define TF_OOOHidden 0x80 /* Out-of-Order hidden columns */
/*
** Test to see whether or not a table is a virtual table. This is
@@ -1898,7 +1882,7 @@ struct Table {
** table support is omitted from the build.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
# define IsVirtual(X) ((X)->nModuleArg)
# define IsVirtual(X) (((X)->tabFlags & TF_Virtual)!=0)
#else
# define IsVirtual(X) 0
#endif
@@ -2133,7 +2117,6 @@ struct Index {
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 */
unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nSample; /* Number of elements in aSample[] */
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
@@ -2444,7 +2427,7 @@ struct Expr {
struct ExprList {
int nExpr; /* Number of expressions on the list */
struct ExprList_item { /* For each expression in the list */
Expr *pExpr; /* The parse tree for this expression */
Expr *pExpr; /* The list of expressions */
char *zName; /* Token associated with this expression */
char *zSpan; /* Original text of the expression */
u8 sortOrder; /* 1 for DESC or 0 for ASC */
@@ -3767,7 +3750,6 @@ void sqlite3Vacuum(Parse*,Token*);
int sqlite3RunVacuum(char**, sqlite3*, int);
char *sqlite3NameFromToken(sqlite3*, Token*);
int sqlite3ExprCompare(Expr*, Expr*, int);
int sqlite3ExprCompareSkip(Expr*, Expr*, int);
int sqlite3ExprListCompare(ExprList*, ExprList*, int);
int sqlite3ExprImpliesExpr(Expr*, Expr*, int);
void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
+4
View File
@@ -3405,6 +3405,10 @@ static int SQLITE_TCLAPI DbMain(
}
zErrMsg = 0;
p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
if( p==0 ){
Tcl_SetResult(interp, (char *)"malloc failed", TCL_STATIC);
return TCL_ERROR;
}
memset(p, 0, sizeof(*p));
zFile = Tcl_GetStringFromObj(objv[2], 0);
zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
+8 -13
View File
@@ -161,13 +161,13 @@ static CrashGlobal g = {0, 0, SQLITE_DEFAULT_SECTOR_SIZE, 0, 0};
static int sqlite3CrashTestEnable = 0;
static void *crash_malloc(int nByte){
return (void *)Tcl_AttemptAlloc((size_t)nByte);
return (void *)Tcl_Alloc((size_t)nByte);
}
static void crash_free(void *p){
Tcl_Free(p);
}
static void *crash_realloc(void *p, int n){
return (void *)Tcl_AttemptRealloc(p, (size_t)n);
return (void *)Tcl_Realloc(p, (size_t)n);
}
/*
@@ -315,9 +315,8 @@ static int writeListSync(CrashFile *pFile, int isCrash){
assert(pWrite->zBuf);
#ifdef TRACE_CRASHTEST
printf("Trashing %d sectors (%d bytes) @ %lld (sector %d) (%s)\n",
1+iLast-iFirst, (1+iLast-iFirst)*g.iSectorSize,
pWrite->iOffset, iFirst, pWrite->pFile->zName
printf("Trashing %d sectors @ %lld (sector %d) (%s)\n",
1+iLast-iFirst, pWrite->iOffset, iFirst, pWrite->pFile->zName
);
#endif
@@ -828,7 +827,7 @@ static int SQLITE_TCLAPI crashNowCmd(
}
/*
** tclcmd: sqlite_crash_enable ENABLE ?DEFAULT?
** tclcmd: sqlite_crash_enable ENABLE
**
** Parameter ENABLE must be a boolean value. If true, then the "crash"
** vfs is added to the system. If false, it is removed.
@@ -840,7 +839,6 @@ static int SQLITE_TCLAPI crashEnableCmd(
Tcl_Obj *CONST objv[]
){
int isEnable;
int isDefault = 0;
static sqlite3_vfs crashVfs = {
2, /* iVersion */
0, /* szOsFile */
@@ -864,17 +862,14 @@ static int SQLITE_TCLAPI crashEnableCmd(
0, /* xCurrentTimeInt64 */
};
if( objc!=2 && objc!=3 ){
Tcl_WrongNumArgs(interp, 1, objv, "ENABLE ?DEFAULT?");
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "ENABLE");
return TCL_ERROR;
}
if( Tcl_GetBooleanFromObj(interp, objv[1], &isEnable) ){
return TCL_ERROR;
}
if( objc==3 && Tcl_GetBooleanFromObj(interp, objv[2], &isDefault) ){
return TCL_ERROR;
}
if( (isEnable && crashVfs.pAppData) || (!isEnable && !crashVfs.pAppData) ){
return TCL_OK;
@@ -885,7 +880,7 @@ static int SQLITE_TCLAPI crashEnableCmd(
crashVfs.mxPathname = pOriginalVfs->mxPathname;
crashVfs.pAppData = (void *)pOriginalVfs;
crashVfs.szOsFile = sizeof(CrashFile) + pOriginalVfs->szOsFile;
sqlite3_vfs_register(&crashVfs, isDefault);
sqlite3_vfs_register(&crashVfs, 0);
}else{
crashVfs.pAppData = 0;
sqlite3_vfs_unregister(&crashVfs);
+1 -5
View File
@@ -239,11 +239,7 @@ static int SQLITE_TCLAPI test_blob_read(
}
if( nByte>0 ){
zBuf = (unsigned char *)Tcl_AttemptAlloc(nByte);
if( zBuf==0 ){
Tcl_AppendResult(interp, "out of memory", 0);
return TCL_ERROR;
}
zBuf = (unsigned char *)Tcl_Alloc(nByte);
}
rc = sqlite3_blob_read(pBlob, zBuf, nByte, iOffset);
if( rc==SQLITE_OK ){
+11 -12
View File
@@ -475,8 +475,8 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
*/
int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
int nErr = 0; /* Number of errors encountered */
int i; /* Loop counter */
void *pEngine; /* The LEMON-generated LALR(1) parser */
int n = 0; /* Length of the next token token */
int tokenType; /* type of the next token */
int lastTokenParsed = -1; /* type of the previous token */
sqlite3 *db = pParse->db; /* The database connection */
@@ -492,6 +492,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
}
pParse->rc = SQLITE_OK;
pParse->zTail = zSql;
i = 0;
assert( pzErrMsg!=0 );
/* sqlite3ParserTrace(stdout, "parser: "); */
#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
@@ -509,10 +510,12 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
assert( pParse->nVar==0 );
assert( pParse->pVList==0 );
while( 1 ){
if( zSql[0]!=0 ){
n = sqlite3GetToken((u8*)zSql, &tokenType);
mxSqlLen -= n;
if( mxSqlLen<0 ){
assert( i>=0 );
if( zSql[i]!=0 ){
pParse->sLastToken.z = &zSql[i];
pParse->sLastToken.n = sqlite3GetToken((u8*)&zSql[i],&tokenType);
i += pParse->sLastToken.n;
if( i>mxSqlLen ){
pParse->rc = SQLITE_TOOBIG;
break;
}
@@ -526,7 +529,6 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
}else{
tokenType = TK_SEMI;
}
zSql -= n;
}
if( tokenType>=TK_SPACE ){
assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
@@ -535,21 +537,18 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
break;
}
if( tokenType==TK_ILLEGAL ){
sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql);
sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"",
&pParse->sLastToken);
break;
}
zSql += n;
}else{
pParse->sLastToken.z = zSql;
pParse->sLastToken.n = n;
sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
lastTokenParsed = tokenType;
zSql += n;
if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
}
}
assert( nErr==0 );
pParse->zTail = zSql;
pParse->zTail = &zSql[i];
#ifdef YYTRACKMAXSTACKDEPTH
sqlite3_mutex_enter(sqlite3MallocMutex());
sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK,
+14 -7
View File
@@ -1140,11 +1140,13 @@ u32 sqlite3Get4byte(const u8 *p){
u32 x;
memcpy(&x,p,4);
return x;
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
&& (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
u32 x;
memcpy(&x,p,4);
return __builtin_bswap32(x);
#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
&& defined(_MSC_VER) && _MSC_VER>=1300
u32 x;
memcpy(&x,p,4);
return _byteswap_ulong(x);
@@ -1156,10 +1158,12 @@ u32 sqlite3Get4byte(const u8 *p){
void sqlite3Put4byte(unsigned char *p, u32 v){
#if SQLITE_BYTEORDER==4321
memcpy(p,&v,4);
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
&& (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
u32 x = __builtin_bswap32(v);
memcpy(p,&x,4);
#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
&& defined(_MSC_VER) && _MSC_VER>=1300
u32 x = _byteswap_ulong(v);
memcpy(p,&x,4);
#else
@@ -1275,7 +1279,8 @@ int sqlite3SafetyCheckSickOrOk(sqlite3 *db){
** overflow, leave *pA unchanged and return 1.
*/
int sqlite3AddInt64(i64 *pA, i64 iB){
#if GCC_VERSION>=5004000
#if !defined(SQLITE_DISABLE_INTRINSIC) \
&& (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000)
return __builtin_add_overflow(*pA, iB, pA);
#else
i64 iA = *pA;
@@ -1295,7 +1300,8 @@ int sqlite3AddInt64(i64 *pA, i64 iB){
#endif
}
int sqlite3SubInt64(i64 *pA, i64 iB){
#if GCC_VERSION>=5004000
#if !defined(SQLITE_DISABLE_INTRINSIC) \
&& (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000)
return __builtin_sub_overflow(*pA, iB, pA);
#else
testcase( iB==SMALLEST_INT64+1 );
@@ -1310,7 +1316,8 @@ int sqlite3SubInt64(i64 *pA, i64 iB){
#endif
}
int sqlite3MulInt64(i64 *pA, i64 iB){
#if GCC_VERSION>=5004000
#if !defined(SQLITE_DISABLE_INTRINSIC) \
&& (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000)
return __builtin_mul_overflow(*pA, iB, pA);
#else
i64 iA = *pA;
+2 -19
View File
@@ -98,25 +98,8 @@ static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){
*/
void sqlite3Vacuum(Parse *pParse, Token *pNm){
Vdbe *v = sqlite3GetVdbe(pParse);
int iDb = 0;
if( v==0 ) return;
if( pNm ){
#ifndef SQLITE_BUG_COMPATIBLE_20160819
/* Default behavior: Report an error if the argument to VACUUM is
** not recognized */
iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm);
if( iDb<0 ) return;
#else
/* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments
** to VACUUM are silently ignored. This is a back-out of a bug fix that
** occurred on 2016-08-19 (https://www.sqlite.org/src/info/083f9e6270).
** The buggy behavior is required for binary compatibility with some
** legacy applications. */
iDb = sqlite3FindDb(pParse->db, pNm);
if( iDb<0 ) iDb = 0;
#endif
}
if( iDb!=1 ){
int iDb = pNm ? sqlite3TwoPartName(pParse, pNm, pNm, &pNm) : 0;
if( v && (iDb>=2 || iDb==0) ){
sqlite3VdbeAddOp1(v, OP_Vacuum, iDb);
sqlite3VdbeUsesBtree(v, iDb);
}
+11 -50
View File
@@ -1669,21 +1669,21 @@ case OP_Function: {
for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
}
memAboutToChange(p, pOut);
memAboutToChange(p, pCtx->pOut);
#ifdef SQLITE_DEBUG
for(i=0; i<pCtx->argc; i++){
assert( memIsValid(pCtx->argv[i]) );
REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
}
#endif
MemSetTypeFlag(pOut, MEM_Null);
MemSetTypeFlag(pCtx->pOut, MEM_Null);
pCtx->fErrorOrAux = 0;
(*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */
/* If the function returned an error, throw an exception */
if( pCtx->fErrorOrAux ){
if( pCtx->isError ){
sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut));
sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
rc = pCtx->isError;
}
sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
@@ -1692,12 +1692,12 @@ case OP_Function: {
/* Copy the result of the function into register P3 */
if( pOut->flags & (MEM_Str|MEM_Blob) ){
sqlite3VdbeChangeEncoding(pOut, encoding);
if( sqlite3VdbeMemTooBig(pOut) ) goto too_big;
sqlite3VdbeChangeEncoding(pCtx->pOut, encoding);
if( sqlite3VdbeMemTooBig(pCtx->pOut) ) goto too_big;
}
REGISTER_TRACE(pOp->p3, pOut);
UPDATE_MAX_BLOBSIZE(pOut);
REGISTER_TRACE(pOp->p3, pCtx->pOut);
UPDATE_MAX_BLOBSIZE(pCtx->pOut);
break;
}
@@ -2198,7 +2198,7 @@ case OP_Compare: {
assert( pKeyInfo!=0 );
p1 = pOp->p1;
p2 = pOp->p2;
#ifdef SQLITE_DEBUG
#if SQLITE_DEBUG
if( aPermute ){
int k, mx = 0;
for(k=0; k<n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
@@ -4847,33 +4847,6 @@ case OP_Last: { /* jump */
break;
}
/* Opcode: IfSmaller P1 P2 P3 * *
**
** Estimate the number of rows in the table P1. Jump to P2 if that
** estimate is less than approximately 2**(0.1*P3).
*/
case OP_IfSmaller: { /* jump */
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
i64 sz;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
pCrsr = pC->uc.pCursor;
assert( pCrsr );
rc = sqlite3BtreeFirst(pCrsr, &res);
if( rc ) goto abort_due_to_error;
if( res==0 ){
sz = sqlite3BtreeRowCountEst(pCrsr);
if( ALWAYS(sz>=0) && sqlite3LogEst((u64)sz)<pOp->p3 ) res = 1;
}
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
break;
}
/* Opcode: SorterSort P1 P2 * * *
**
@@ -5518,18 +5491,6 @@ case OP_CreateTable: { /* out2 */
break;
}
/* Opcode: SqlExec * * * P4 *
**
** Run the SQL statement or statements specified in the P4 string.
*/
case OP_SqlExec: {
db->nSqlExec++;
rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0);
db->nSqlExec--;
if( rc ) goto abort_due_to_error;
break;
}
/* Opcode: ParseSchema P1 * * P4 *
**
** Read and parse all entries from the SQLITE_MASTER table of database P1
@@ -5650,7 +5611,7 @@ case OP_DropTrigger: {
** register P1 the text of an error message describing any problems.
** If no problems are found, store a NULL in register P1.
**
** The register P3 contains one less than the maximum number of allowed errors.
** The register P3 contains the maximum number of allowed errors.
** At most reg(P3) errors will be reported.
** In other words, the analysis stops as soon as reg(P1) errors are
** seen. Reg(P1) is updated with the number of errors remaining.
@@ -5683,14 +5644,14 @@ case OP_IntegrityCk: {
assert( pOp->p5<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p5) );
z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
(int)pnErr->u.i+1, &nErr);
(int)pnErr->u.i, &nErr);
pnErr->u.i -= nErr;
sqlite3VdbeMemSetNull(pIn1);
if( nErr==0 ){
assert( z==0 );
}else if( z==0 ){
goto no_mem;
}else{
pnErr->u.i -= nErr-1;
sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free);
}
UPDATE_MAX_BLOBSIZE(pIn1);
+6 -8
View File
@@ -154,8 +154,7 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
sqlite3VdbeMemRelease(&p->aVar[i]);
p->aVar[i].flags = MEM_Null;
}
assert( p->isPrepareV2 || p->expmask==0 );
if( p->expmask ){
if( p->isPrepareV2 && p->expmask ){
p->expired = 1;
}
sqlite3_mutex_leave(mutex);
@@ -1259,8 +1258,9 @@ static int vdbeUnbind(Vdbe *p, int i){
** as if there had been a schema change, on the first sqlite3_step() call
** following any change to the bindings of that parameter.
*/
assert( p->isPrepareV2 || p->expmask==0 );
if( p->expmask!=0 && (p->expmask & (i>=31 ? 0x80000000 : (u32)1<<i))!=0 ){
if( p->isPrepareV2 &&
((i<32 && p->expmask & ((u32)1 << i)) || p->expmask==0xffffffff)
){
p->expired = 1;
}
return SQLITE_OK;
@@ -1523,12 +1523,10 @@ int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
if( pFrom->nVar!=pTo->nVar ){
return SQLITE_ERROR;
}
assert( pTo->isPrepareV2 || pTo->expmask==0 );
if( pTo->expmask ){
if( pTo->isPrepareV2 && pTo->expmask ){
pTo->expired = 1;
}
assert( pFrom->isPrepareV2 || pFrom->expmask==0 );
if( pFrom->expmask ){
if( pFrom->isPrepareV2 && pFrom->expmask ){
pFrom->expired = 1;
}
return sqlite3TransferBindings(pFromStmt, pToStmt);
+7 -9
View File
@@ -57,7 +57,6 @@ void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){
void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
assert( isPrepareV2==1 || isPrepareV2==0 );
if( p==0 ) return;
if( !isPrepareV2 ) p->expmask = 0;
#if defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_ENABLE_SQLLOG)
if( !isPrepareV2 ) return;
#endif
@@ -86,7 +85,6 @@ void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
pA->zSql = pB->zSql;
pB->zSql = zTmp;
pB->isPrepareV2 = pA->isPrepareV2;
pB->expmask = pA->expmask;
}
/*
@@ -2611,13 +2609,13 @@ int sqlite3VdbeHalt(Vdbe *p){
** one, or the complete transaction if there is no statement transaction.
*/
if( p->magic!=VDBE_MAGIC_RUN ){
return SQLITE_OK;
}
if( db->mallocFailed ){
p->rc = SQLITE_NOMEM_BKPT;
}
closeAllCursors(p);
if( p->magic!=VDBE_MAGIC_RUN ){
return SQLITE_OK;
}
checkActiveVdbeCnt(db);
/* No commit or rollback needed if the program never started or if the
@@ -3564,7 +3562,7 @@ void sqlite3VdbeRecordUnpack(
p->nField = u;
}
#ifdef SQLITE_DEBUG
#if SQLITE_DEBUG
/*
** This function compares two index or table record keys in the same way
** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(),
@@ -3669,7 +3667,7 @@ debugCompareEnd:
}
#endif
#ifdef SQLITE_DEBUG
#if SQLITE_DEBUG
/*
** Count the number of fields (a.k.a. columns) in the record given by
** pKey,nKey. The verify that this count is less than or equal to the
@@ -4552,8 +4550,8 @@ sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){
*/
void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
assert( iVar>0 );
if( iVar>=32 ){
v->expmask |= 0x80000000;
if( iVar>32 ){
v->expmask = 0xffffffff;
}else{
v->expmask |= ((u32)1 << (iVar-1));
}
+46 -32
View File
@@ -23,7 +23,7 @@
*/
typedef struct Incrblob Incrblob;
struct Incrblob {
int nByte; /* Size of open blob, in bytes */
int nByte; /* Size of open blob if ACTIVE. -1 if RESET */
int iOffset; /* Byte offset of blob in cursor data */
u16 iCol; /* Table column this handle is open on */
BtCursor *pCsr; /* Cursor pointing at blob row */
@@ -33,7 +33,6 @@ struct Incrblob {
Table *pTab; /* Table object */
};
/*
** This function is used by both blob_open() and blob_reopen(). It seeks
** the b-tree cursor associated with blob handle p to point to row iRow.
@@ -82,8 +81,8 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
type==0?"null": type==7?"real": "integer"
);
rc = SQLITE_ERROR;
sqlite3_finalize(p->pStmt);
p->pStmt = 0;
sqlite3_reset(p->pStmt);
p->nByte = -1;
}else{
p->iOffset = pC->aType[p->iCol + pC->nField];
p->nByte = sqlite3VdbeSerialTypeLen(type);
@@ -94,9 +93,9 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
if( rc==SQLITE_ROW ){
rc = SQLITE_OK;
}else if( p->pStmt ){
rc = sqlite3_finalize(p->pStmt);
p->pStmt = 0;
}else if( p->nByte>=0 ){
rc = sqlite3_reset(p->pStmt);
p->nByte = -1;
if( rc==SQLITE_OK ){
zErr = sqlite3MPrintf(p->db, "no such rowid: %lld", iRow);
rc = SQLITE_ERROR;
@@ -157,6 +156,7 @@ int sqlite3_blob_open(
pParse->db = db;
sqlite3DbFree(db, zErr);
zErr = 0;
sqlite3_finalize(pBlob->pStmt);
sqlite3BtreeEnterAll(db);
pTab = sqlite3LocateTable(pParse, 0, zTable, zDb);
@@ -324,6 +324,7 @@ int sqlite3_blob_open(
pBlob->iCol = iCol;
pBlob->db = db;
pBlob->nByte = 0;
sqlite3BtreeLeaveAll(db);
if( db->mallocFailed ){
goto blob_open_out;
@@ -359,7 +360,7 @@ int sqlite3_blob_close(sqlite3_blob *pBlob){
if( p ){
db = p->db;
sqlite3_mutex_enter(db->mutex);
rc = sqlite3_finalize(p->pStmt);
rc = sqlite3VdbeFinalize((Vdbe*)p->pStmt);
sqlite3DbFree(db, p);
sqlite3_mutex_leave(db->mutex);
}else{
@@ -384,6 +385,10 @@ static int blobReadWrite(
sqlite3 *db;
if( p==0 ) return SQLITE_MISUSE_BKPT;
if( p->nByte<0 ){
/* The blob handle is in the RESET state. Always return SQLITE_ABORT. */
return SQLITE_ABORT;
}
db = p->db;
sqlite3_mutex_enter(db->mutex);
v = (Vdbe*)p->pStmt;
@@ -391,11 +396,6 @@ static int blobReadWrite(
if( n<0 || iOffset<0 || ((sqlite3_int64)iOffset+n)>p->nByte ){
/* Request is out of range. Return a transient error. */
rc = 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.
*/
rc = SQLITE_ABORT;
}else{
/* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is
** returned, clean-up the statement handle.
@@ -429,8 +429,8 @@ static int blobReadWrite(
rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
sqlite3BtreeLeaveCursor(p->pCsr);
if( rc==SQLITE_ABORT ){
sqlite3VdbeFinalize(v);
p->pStmt = 0;
sqlite3_reset(p->pStmt);
p->nByte = -1;
}else{
v->rc = rc;
}
@@ -458,14 +458,36 @@ int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
/*
** Query a blob handle for the size of the data.
**
** The Incrblob.nByte field is fixed for the lifetime of the Incrblob
** so no mutex is required for access.
** The Incrblob.nByte field is fixed for as long as the sqlite3_blob
** object is pointing to the same row, so no mutex is required for access.
**
** When the sqlite3_blob interface was first designed in 2007, we specified
** that sqlite3_blob_bytes() returned 0 when in the RESET state. It would
** have been better to return -1 in order to distinguish a RESET blob handle
** from an ACTIVE blob handle pointing to a zero-length string or blob.
** But, sadly, we cannot change that now without breaking compatibility.
** So 0 is returned for RESET blob handles and for ACTIVE blob handles
** pointing to zero-length blobs.
*/
int sqlite3_blob_bytes(sqlite3_blob *pBlob){
Incrblob *p = (Incrblob *)pBlob;
return (p && p->pStmt) ? p->nByte : 0;
return (p && p->pStmt && p->nByte>0) ? p->nByte : 0;
}
/*
** Move the sqlite3_blob object to the RESET state. This releases
** any locks and gets the object out of the way of commits and
** rollbacks.
*/
int sqlite3_blob_reset(sqlite3_blob *pBlob){
Incrblob *p = (Incrblob *)pBlob;
if( p->nByte>=0 ){
sqlite3_reset(p->pStmt);
p->nByte = -1;
}
return SQLITE_OK;
}
/*
** Move an existing blob handle to point to a different row of the same
** database table.
@@ -480,28 +502,20 @@ int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
int rc;
Incrblob *p = (Incrblob *)pBlob;
sqlite3 *db;
char *zErr;
if( p==0 ) return SQLITE_MISUSE_BKPT;
db = p->db;
sqlite3_mutex_enter(db->mutex);
if( p->pStmt==0 ){
/* If there is no statement handle, then the blob-handle has
** already been invalidated. Return SQLITE_ABORT in this case.
*/
rc = SQLITE_ABORT;
}else{
char *zErr;
rc = blobSeekToRow(p, iRow, &zErr);
if( rc!=SQLITE_OK ){
sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
sqlite3DbFree(db, zErr);
}
assert( rc!=SQLITE_SCHEMA );
rc = blobSeekToRow(p, iRow, &zErr);
if( rc!=SQLITE_OK ){
sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
sqlite3DbFree(db, zErr);
}
rc = sqlite3ApiExit(db, rc);
assert( rc==SQLITE_OK || p->pStmt==0 );
assert( rc==SQLITE_OK || p->nByte<0 );
sqlite3_mutex_leave(db->mutex);
return rc;
}
+10 -8
View File
@@ -339,7 +339,8 @@ void sqlite3VtabBeginParse(
iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
assert( iDb>=0 );
assert( pTable->nModuleArg==0 );
pTable->tabFlags |= TF_Virtual;
pTable->nModuleArg = 0;
addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
addModuleArgument(db, pTable, 0);
addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
@@ -627,7 +628,7 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
int rc;
assert( pTab );
if( !IsVirtual(pTab) || sqlite3GetVTable(db, pTab) ){
if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){
return SQLITE_OK;
}
@@ -697,7 +698,7 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
const char *zMod;
pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
assert( pTab && IsVirtual(pTab) && !pTab->pVTable );
assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable );
/* Locate the required virtual table module */
zMod = pTab->azModuleArg[0];
@@ -751,7 +752,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
return SQLITE_MISUSE_BKPT;
}
pTab = pCtx->pTab;
assert( IsVirtual(pTab) );
assert( (pTab->tabFlags & TF_Virtual)!=0 );
pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
if( pParse==0 ){
@@ -765,7 +766,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
&& pParse->pNewTable
&& !db->mallocFailed
&& !pParse->pNewTable->pSelect
&& !IsVirtual(pParse->pNewTable)
&& (pParse->pNewTable->tabFlags & TF_Virtual)==0
){
if( !pTab->aCol ){
Table *pNew = pParse->pNewTable;
@@ -1054,7 +1055,7 @@ FuncDef *sqlite3VtabOverloadFunction(
if( pExpr->op!=TK_COLUMN ) return pDef;
pTab = pExpr->pTab;
if( NEVER(pTab==0) ) return pDef;
if( !IsVirtual(pTab) ) return pDef;
if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef;
pVtab = sqlite3GetVTable(db, pTab)->pVtab;
assert( pVtab!=0 );
assert( pVtab->pModule!=0 );
@@ -1149,7 +1150,8 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
pMod->pEpoTab = pTab;
pTab->nTabRef = 1;
pTab->pSchema = db->aDb[0].pSchema;
assert( pTab->nModuleArg==0 );
pTab->tabFlags |= TF_Virtual;
pTab->nModuleArg = 0;
pTab->iPKey = -1;
addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
addModuleArgument(db, pTab, 0);
@@ -1220,7 +1222,7 @@ int sqlite3_vtab_config(sqlite3 *db, int op, ...){
if( !p ){
rc = SQLITE_MISUSE_BKPT;
}else{
assert( p->pTab==0 || IsVirtual(p->pTab) );
assert( p->pTab==0 || (p->pTab->tabFlags & TF_Virtual)!=0 );
p->pVTable->bConstraint = (u8)va_arg(ap, int);
}
break;
+2 -2
View File
@@ -27,11 +27,11 @@
**
** WRC_Continue Continue descending down the tree.
**
** WRC_Prune Do not descend into child nodes, but allow
** WRC_Prune Do not descend into child nodes. But allow
** the walk to continue with sibling nodes.
**
** WRC_Abort Do no more callbacks. Unwind the stack and
** return from the top-level walk call.
** return the top-level walk call.
**
** The return value from this routine is WRC_Abort to abandon the tree walk
** and WRC_Continue to continue.
+9 -24
View File
@@ -209,8 +209,7 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
if( pTerm->leftCursor==iCur
&& pTerm->u.leftColumn==iColumn
&& (iColumn!=XN_EXPR
|| sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
pScan->pIdxExpr,iCur)==0)
|| sqlite3ExprCompare(pTerm->pExpr->pLeft,pScan->pIdxExpr,iCur)==0)
&& (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
){
if( (pTerm->eOperator & WO_EQUIV)!=0
@@ -309,7 +308,6 @@ static WhereTerm *whereScanInit(
iColumn = pIdx->aiColumn[j];
if( iColumn==XN_EXPR ){
pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
pScan->zCollName = pIdx->azColl[j];
}else if( iColumn==pIdx->pTable->iPKey ){
iColumn = XN_ROWID;
}else if( iColumn>=0 ){
@@ -2387,11 +2385,6 @@ static int whereLoopAddBtreeIndex(
continue;
}
if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){
pBuilder->bldFlags |= SQLITE_BLDF_UNIQUE;
}else{
pBuilder->bldFlags |= SQLITE_BLDF_INDEXED;
}
pNew->wsFlags = saved_wsFlags;
pNew->u.btree.nEq = saved_nEq;
pNew->u.btree.nBtm = saved_nBtm;
@@ -2939,15 +2932,7 @@ static int whereLoopAddBtree(
}
}
pBuilder->bldFlags = 0;
rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);
if( pBuilder->bldFlags==SQLITE_BLDF_INDEXED ){
/* If a non-unique index is used, or if a prefix of the key for
** unique index is used (making the index functionally non-unique)
** then the sqlite_stat1 data becomes important for scoring the
** plan */
pTab->tabFlags |= TF_StatsUsed;
}
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3Stat4ProbeFree(pBuilder->pRec);
pBuilder->nRecValid = 0;
@@ -4127,9 +4112,9 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
&& nRowEst
){
Bitmask notUsed;
int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom,
int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinctSet, pFrom,
WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed);
if( rc==pWInfo->pResultSet->nExpr ){
if( rc==pWInfo->pDistinctSet->nExpr ){
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
}
}
@@ -4366,7 +4351,7 @@ WhereInfo *sqlite3WhereBegin(
SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
Expr *pWhere, /* The WHERE clause */
ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */
ExprList *pDistinctSet, /* Try not to output two rows that duplicate these */
u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */
int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number
** If WHERE_USE_LIMIT, then the limit amount */
@@ -4442,7 +4427,7 @@ WhereInfo *sqlite3WhereBegin(
pWInfo->pParse = pParse;
pWInfo->pTabList = pTabList;
pWInfo->pOrderBy = pOrderBy;
pWInfo->pResultSet = pResultSet;
pWInfo->pDistinctSet = pDistinctSet;
pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
pWInfo->nLevel = nTabList;
pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
@@ -4520,13 +4505,13 @@ WhereInfo *sqlite3WhereBegin(
if( db->mallocFailed ) goto whereBeginError;
if( wctrlFlags & WHERE_WANT_DISTINCT ){
if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pDistinctSet) ){
/* The DISTINCT marking is pointless. Ignore it. */
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
}else if( pOrderBy==0 ){
/* Try to ORDER BY the result set to make distinct processing easier */
pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
pWInfo->pOrderBy = pResultSet;
pWInfo->pOrderBy = pDistinctSet;
}
}
@@ -4602,10 +4587,10 @@ WhereInfo *sqlite3WhereBegin(
#endif
/* Attempt to omit tables from the join that do not effect the result */
if( pWInfo->nLevel>=2
&& pResultSet!=0
&& pDistinctSet!=0
&& OptimizationEnabled(db, SQLITE_OmitNoopJoin)
){
Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pDistinctSet);
if( sWLB.pOrderBy ){
tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
}
+1 -6
View File
@@ -395,13 +395,8 @@ struct WhereLoopBuilder {
UnpackedRecord *pRec; /* Probe for stat4 (if required) */
int nRecValid; /* Number of valid fields currently in pRec */
#endif
unsigned int bldFlags; /* SQLITE_BLDF_* flags */
};
/* Allowed values for WhereLoopBuider.bldFlags */
#define SQLITE_BLDF_INDEXED 0x0001 /* An index is used */
#define SQLITE_BLDF_UNIQUE 0x0002 /* All keys of a UNIQUE index used */
/*
** The WHERE clause processing routine has two halves. The
** first part does the start of the WHERE loop and the second
@@ -416,7 +411,7 @@ struct WhereInfo {
Parse *pParse; /* Parsing and code generating context */
SrcList *pTabList; /* List of tables in the join */
ExprList *pOrderBy; /* The ORDER BY clause or NULL */
ExprList *pResultSet; /* Result set of the query */
ExprList *pDistinctSet; /* DISTINCT over all these values */
LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
int iContinue; /* Jump here to continue with next record */
+2 -8
View File
@@ -1062,7 +1062,6 @@ Bitmask sqlite3WhereCodeOneLoopStart(
Vdbe *v; /* The prepared stmt under constructions */
struct SrcList_item *pTabItem; /* FROM clause term being coded */
int addrBrk; /* Jump here to break out of the loop */
int addrHalt; /* addrBrk for the outermost loop */
int addrCont; /* Jump here to continue with next cycle */
int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
int iReleaseReg = 0; /* Temp register to free before returning */
@@ -1104,11 +1103,6 @@ Bitmask sqlite3WhereCodeOneLoopStart(
VdbeComment((v, "init LEFT JOIN no-match flag"));
}
/* Compute a safe address to jump to if we discover that the table for
** this loop is empty and can never contribute content. */
for(j=iLevel; j>0 && pWInfo->a[j].iLeftJoin==0; j--){}
addrHalt = pWInfo->a[j].addrBrk;
/* Special case of a FROM clause subquery implemented as a co-routine */
if( pTabItem->fg.viaCoroutine ){
int regYield = pTabItem->regReturn;
@@ -1293,7 +1287,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3ExprCacheAffinityChange(pParse, r1, 1);
sqlite3ReleaseTempReg(pParse, rTemp);
}else{
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt);
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
VdbeCoverageIf(v, bRev==0);
VdbeCoverageIf(v, bRev!=0);
}
@@ -1939,7 +1933,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
codeCursorHint(pTabItem, pWInfo, pLevel, 0);
pLevel->op = aStep[bRev];
pLevel->p1 = iCur;
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrHalt);
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
VdbeCoverageIf(v, bRev==0);
VdbeCoverageIf(v, bRev!=0);
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
+10 -18
View File
@@ -213,6 +213,15 @@ static int isLikeOrGlob(
#endif
pList = pExpr->x.pList;
pLeft = pList->a[1].pExpr;
if( pLeft->op!=TK_COLUMN
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
|| IsVirtual(pLeft->pTab) /* Value might be numeric */
){
/* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must
** be the name of an indexed column with TEXT affinity. */
return 0;
}
assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */
pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr);
op = pRight->op;
@@ -229,23 +238,6 @@ static int isLikeOrGlob(
z = pRight->u.zToken;
}
if( z ){
/* If the RHS begins with a digit or a minus sign, then the LHS must
** be an ordinary column (not a virtual table column) with TEXT affinity.
** Otherwise the LHS might be numeric and "lhs >= rhs" would be false
** even though "lhs LIKE rhs" is true. But if the RHS does not start
** with a digit or '-', then "lhs LIKE rhs" will always be false if
** the LHS is numeric and so the optimization still works.
*/
if( sqlite3Isdigit(z[0]) || z[0]=='-' ){
if( pLeft->op!=TK_COLUMN
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
|| IsVirtual(pLeft->pTab) /* Value might be numeric */
){
sqlite3ValueFree(pVal);
return 0;
}
}
cnt = 0;
while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
cnt++;
@@ -874,7 +866,7 @@ static int exprMightBeIndexed(
if( pIdx->aColExpr==0 ) continue;
for(i=0; i<pIdx->nKeyCol; i++){
if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
if( sqlite3ExprCompare(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
*piCur = iCur;
*piColumn = XN_EXPR;
return 1;
-123
View File
@@ -1,123 +0,0 @@
# 2017-02-17
#
# 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 the logic used to estimate when
# running ANALYZE would be beneficial.
#
# Note that this test uses some hard-coded bitmask values from sqliteInt.h.
# If any of the following constants changes:
#
# define TF_HasStat1 0x0010
# define TF_StatsUsed 0x0100
#
# then some of the magic numbers in test results below might need to be
# adjusted.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# There is nothing to test if ANALYZE is disable for this build.
# These tests also use "PRAGMA stats" which are only enabled for
# debugging builds.
#
ifcapable {!debug || !analyze} {
finish_test
return
}
do_execsql_test autoanalyze1-100 {
-- Build up a test table with some indexes
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d);
CREATE UNIQUE INDEX t1bc ON t1(b,c);
CREATE INDEX t1d ON t1(d);
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
INSERT INTO t1(a,b,c,d) SELECT x, x, x, x FROM c;
-- Verify that the hasStat1 flag is clear on on indexes
SELECT idx, flgs FROM pragma_stats
WHERE idx IS NOT NULL
ORDER BY idx;
-- Verify that the TF_HasStat1 flag is clear on the table
SELECT tbl, (flgs & 0x10)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
} {t1bc 0 t1d 0 t1 0}
# No use of stat1 recorded so far
do_execsql_test autoanalyze1-110 {
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
} {0}
# Access using a unique index does not set the TF_StatsUsed flag.
#
do_execsql_test autoanalyze1-200 {
SELECT * FROM t1 WHERE a=55;
} {55 55 55 55}
do_execsql_test autoanalyze1-201 {
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
} {0}
do_execsql_test autoanalyze1-210 {
SELECT * FROM t1 WHERE a IN (55,199,299);
} {55 55 55 55}
do_execsql_test autoanalyze1-211 {
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
} {0}
do_execsql_test autoanalyze1-220 {
SELECT * FROM t1 WHERE (b,c)=(45,45);
} {45 45 45 45}
do_execsql_test autoanalyze1-221 {
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
} {0}
# Any use of the non-unique t1d index triggers the use of stats.
#
sqlite3 db test.db
do_execsql_test autoanalyze1-300 {
SELECT * FROM t1 WHERE d=45;
} {45 45 45 45}
do_execsql_test autoanalyze1-301 {
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
} {1}
sqlite3 db test.db
do_execsql_test autoanalyze1-310 {
SELECT * FROM t1 WHERE d=45 AND a=45;
} {45 45 45 45}
do_execsql_test autoanalyze1-311 {
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
} {0} ;# The ROWID lookup short-circuits the d=45 constraint
sqlite3 db test.db
do_execsql_test autoanalyze1-320 {
SELECT * FROM t1 WHERE d=45 AND a IN (45,46);
} {45 45 45 45}
do_execsql_test autoanalyze1-321 {
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
} {1}
# Any use of prefix of a unique index triggers the use of stats
#
sqlite3 db test.db
do_execsql_test autoanalyze1-400 {
SELECT * FROM t1 WHERE b=45;
} {45 45 45 45}
do_execsql_test autoanalyze1-401 {
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
} {1}
# The TF_StatsUsed flag is reset when the database is reopened
#
sqlite3 db test.db
do_execsql_test autoanalyze1-500 {
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
} {0}
finish_test
+2 -6
View File
@@ -309,15 +309,11 @@ do_test check-4.8 {
PRAGMA ignore_check_constraints=ON;
UPDATE t4 SET x=0, y=1;
SELECT * FROM t4;
PRAGMA integrity_check;
}
} {0 1 ok}
do_execsql_test check-4.8.1 {
PRAGMA ignore_check_constraints=OFF;
PRAGMA integrity_check;
} {{CHECK constraint failed in t4}}
} {0 1}
do_test check-4.9 {
catchsql {
PRAGMA ignore_check_constraints=OFF;
UPDATE t4 SET x=0, y=2;
}
} {1 {CHECK constraint failed: t4}}
+1 -1
View File
@@ -164,7 +164,7 @@ do_test corruptC-2.5 {
catchsql {BEGIN; UPDATE t2 SET y='abcdef-uvwxyz'; ROLLBACK;}
catchsql {PRAGMA integrity_check}
} {0 {{*** in database main ***
On tree page 4 cell 19: Extends off end of page}}}
Page 4: btreeInitPage() returns error code 11}}}
# {0 {{*** in database main ***
# Corruption detected in cell 710 on page 4
-113
View File
@@ -1,113 +0,0 @@
# 2017-03-03
#
# 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 corruptK
if {[permutation]=="mmap"} {
finish_test
return
}
# This module uses hard-coded offsets which do not work if the reserved_bytes
# value is nonzero.
if {[nonzero_reserved_bytes]} {finish_test; return;}
database_may_be_corrupt
# Initialize the database.
#
do_execsql_test 1.1 {
PRAGMA page_size=1024;
PRAGMA auto_vacuum=0;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(randomblob(20));
INSERT INTO t1 VALUES(randomblob(100)); -- make this into a free slot
INSERT INTO t1 VALUES(randomblob(27)); -- this one will be corrupt
INSERT INTO t1 VALUES(randomblob(800));
DELETE FROM t1 WHERE rowid=2; -- free the 100 byte slot
PRAGMA page_count
} {2}
# Corrupt the database so that the blob stored immediately before
# the free slot (rowid==3) has an overlarge length field. So that
# we can use sqlite3_blob_write() to manipulate the size field of
# the free slot.
#
# Then use sqlite3_blob_write() to set the size of said free slot
# to 24 bytes (instead of the actual 100).
#
# Then use the new 24 byte slot. Leaving the in-memory version of
# the page with zero free slots and a large nFree value. Then try
# to allocate another slot to get to defragmentPage().
#
do_test 1.2 {
db close
hexio_write test.db [expr 1024 + 0x360] 21
hexio_write test.db [expr 1024 + 0x363] [format %x [expr 31*2 + 12]]
sqlite3 db test.db
set fd [db incrblob t1 x 3]
fconfigure $fd -translation binary -encoding binary
seek $fd 30
puts -nonewline $fd "\x18"
close $fd
} {}
do_execsql_test 1.3 {
INSERT INTO t1 VALUES(randomblob(20));
}
do_catchsql_test 1.4 {
INSERT INTO t1 VALUES(randomblob(90));
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.1 {
PRAGMA page_size=1024;
PRAGMA auto_vacuum=0;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(randomblob(20));
INSERT INTO t1 VALUES(randomblob(20)); -- free this one
INSERT INTO t1 VALUES(randomblob(20));
INSERT INTO t1 VALUES(randomblob(20)); -- and this one
INSERT INTO t1 VALUES(randomblob(20)); -- corrupt this one.
DELETE FROM t1 WHERE rowid IN(2, 4);
PRAGMA page_count
} {2}
do_test 2.2 {
db close
hexio_write test.db [expr 1024 + 0x388] 53
hexio_write test.db [expr 1024 + 0x38A] 03812C
sqlite3 db test.db
set fd [db incrblob t1 x 5]
fconfigure $fd -translation binary -encoding binary
seek $fd 22
puts -nonewline $fd "\x5d"
close $fd
} {}
do_catchsql_test 2.3 {
INSERT INTO t1 VALUES(randomblob(900));
} {1 {database disk image is malformed}}
finish_test
-12
View File
@@ -596,17 +596,5 @@ datetest 16.29 {datetime(5373484,'-176546 months')} NULL
datetest 16.30 {datetime(5373484,'-14712 years')} {-4713-12-31 12:00:00}
datetest 16.31 {datetime(5373484,'-14713 years')} NULL
# 2017-03-02: Wrong 'start of day' computation.
# https://www.sqlite.org/src/info/6097cb92745327a1
#
datetest 17.1 {datetime(2457754, 'start of day')} {2016-12-31 00:00:00}
datetest 17.2 {datetime(2457828)} {2017-03-15 12:00:00}
datetest 17.3 {datetime(2457828,'start of day')} {2017-03-15 00:00:00}
datetest 17.4 {datetime(2457828,'start of month')} {2017-03-01 00:00:00}
datetest 17.5 {datetime(2457828,'start of year')} {2017-01-01 00:00:00}
datetest 17.6 {datetime(37,'start of year')} NULL
datetest 17.7 {datetime(38,'start of year')} {-4712-01-01 00:00:00}
finish_test
+4 -4
View File
@@ -458,7 +458,7 @@ static void StrAppend(Str *p, const char *z){
sqlite3_uint64 nNew;
if( p->oomErr ) return;
nNew = p->nAlloc*2 + 100 + n;
zNew = sqlite3_realloc64(p->z, nNew);
zNew = sqlite3_realloc(p->z, nNew);
if( zNew==0 ){
sqlite3_free(p->z);
memset(p, 0, sizeof(*p));
@@ -468,7 +468,7 @@ static void StrAppend(Str *p, const char *z){
p->z = zNew;
p->nAlloc = nNew;
}
memcpy(p->z + p->n, z, (int)n);
memcpy(p->z + p->n, z, n);
p->n += n;
p->z[p->n] = 0;
}
@@ -647,7 +647,7 @@ static void runSql(sqlite3 *db, const char *zSql, unsigned runFlags){
int main(int argc, char **argv){
int i; /* Loop counter */
int nDb = 0; /* Number of databases to fuzz */
char **azDb = 0; /* Names of the databases (limit: 20) */
const char **azDb = 0; /* Names of the databases (limit: 20) */
int verboseFlag = 0; /* True for extra output */
int noLookaside = 0; /* Disable lookaside if true */
int vdbeLimitFlag = 0; /* Stop after 100,000 VDBE ops */
@@ -660,7 +660,7 @@ int main(int argc, char **argv){
unsigned runFlags = 0; /* Flags passed to runSql */
for(i=1; i<argc; i++){
char *z = argv[i];
const char *z = argv[i];
if( z[0]!='-' ){
azDb = realloc(azDb, sizeof(azDb[0])*(nDb+1));
if( azDb==0 ) fatalError("out of memory");
+2 -2
View File
@@ -141,8 +141,8 @@ 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}
#blob_write_error_test 2.3.3 $B 5 $blob 5 \
# SQLITE_OK {not an error}
sqlite3_blob_close $B
# EVIDENCE-OF: R-08382-59936 Writes to the BLOB that occurred before the
-50
View File
@@ -1,50 +0,0 @@
# 2017-02-15
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Test cases to show that a join involving an empty table is very fast.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# Build some test data
#
do_execsql_test emptytable-100 {
CREATE TABLE t1(a);
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
INSERT INTO t1(a) SELECT x FROM c;
CREATE TABLE empty(x);
SELECT count(*) FROM t1;
} {100}
# Interrupt queries after 1M cycles to prevent burning excess CPU
proc stopDb {args} {
db interrupt
}
db progress 1000000 {stopDb}
# Prior to the query planner optimization on 2017-02-15, this query would
# take a ridiculous amount of time. If that optimization stops working,
# the result here will be in interrupt for running too long.
#
do_catchsql_test emptytable-110 {
SELECT count(*) FROM t1, t1, t1, t1, t1, t1, empty;
} {0 0}
do_catchsql_test emptytable-120 {
SELECT count(*) FROM t1, t1 LEFT JOIN empty;
} {0 10000}
do_catchsql_test emptytable-121 {
SELECT count(*) FROM t1, t1 LEFT JOIN t1, empty;
} {0 0}
finish_test
-73
View File
@@ -1,73 +0,0 @@
# 2017 Feb 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.
#
#***********************************************************************
#
# Tests of the last_insert_rowid functionality with fts4.
#
set testdir [file dirname $argv0]
source [file join [file dirname [info script]] tester.tcl]
set testprefix fts4lastrowid
ifcapable !fts3 {
finish_test
return
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts4(str);
}
do_execsql_test 1.1 {
INSERT INTO t1 VALUES('one string');
INSERT INTO t1 VALUES('two string');
INSERT INTO t1 VALUES('three string');
SELECT last_insert_rowid();
} {3}
do_execsql_test 1.2 {
BEGIN;
INSERT INTO t1 VALUES('one string');
INSERT INTO t1 VALUES('two string');
INSERT INTO t1 VALUES('three string');
COMMIT;
SELECT last_insert_rowid();
} {6}
do_execsql_test 1.3 {
INSERT INTO t1(rowid, str) VALUES(-22, 'some more text');
SELECT last_insert_rowid();
} {-22}
do_execsql_test 1.4 {
BEGIN;
INSERT INTO t1(rowid, str) VALUES(45, 'some more text');
INSERT INTO t1(rowid, str) VALUES(46, 'some more text');
INSERT INTO t1(rowid, str) VALUES(222, 'some more text');
SELECT last_insert_rowid();
COMMIT;
SELECT last_insert_rowid();
} {222 222}
do_execsql_test 1.5 {
CREATE TABLE x1(x);
INSERT INTO x1 VALUES('john'), ('paul'), ('george'), ('ringo');
INSERT INTO t1 SELECT x FROM x1;
SELECT last_insert_rowid();
} {226}
do_execsql_test 1.6 {
INSERT INTO t1(rowid, str) SELECT rowid+10, x FROM x1;
SELECT last_insert_rowid();
} {14}
finish_test
+9 -6
View File
@@ -62,7 +62,7 @@ do_test incrblob3-2.1.2 {
} {SQLITE_ERROR {no such rowid: 3}}
do_test incrblob3-2.1.3 {
list [catch {sqlite3_blob_reopen $::blob 1} msg] $msg
} {1 SQLITE_ABORT}
} {0 {}}
do_test incrblob3-2.1.4 { close $::blob } {}
do_execsql_test incrblob3-2.2.1 {
@@ -85,18 +85,21 @@ foreach {tn rowid type} {
do_test incrblob3-2.2.$tn.3 {
list [catch {sqlite3_blob_reopen $::blob 1} msg] $msg
} {1 SQLITE_ABORT}
} {0 {}}
do_test incrblob3-2.2.$tn.4 {
list [catch {sqlite3_blob_read $::blob 0 10} msg] $msg
} {1 SQLITE_ABORT}
} {0 {hello worl}}
do_test incrblob3-2.2.$tn.5 {
list [catch {sqlite3_blob_write $::blob 0 "abcd"} msg] $msg
} {1 SQLITE_ABORT}
} {0 {}}
do_test incrblob3-2.2.$tn.6 {
sqlite3_blob_bytes $::blob
} {0}
} {100}
do_test incrblob3-2.2.$tn.7 {
list [catch {sqlite3_blob_write $::blob 0 "hello"} msg] $msg
} {0 {}}
do_test incrblob3-2.2.$tn.7 { close $::blob } {}
do_test incrblob3-2.2.$tn.8 { close $::blob } {}
}
# Test that passing NULL to sqlite3_blob_XXX() APIs returns SQLITE_MISUSE.
+1 -1
View File
@@ -52,7 +52,7 @@ do_faultsim_test 2 -prep {
error [sqlite3_errmsg db]
}
} -test {
faultsim_test_result {1 {no such rowid: -1}} {1 {disk I/O error}}
faultsim_test_result {1 {no such rowid: -1}}
close $::blob
}
-10
View File
@@ -370,14 +370,4 @@ do_execsql_test indexexpr1-1200.4 {
0 0 0 2 0 4 2 0 2 2 4 0
}
# Ticket https://www.sqlite.org/src/tktview/eb703ba7b50c1a
# Incorrect result using an index on an expression with a collating function
#
do_execsql_test indexexpr1-1300.1 {
CREATE TABLE t1300(a INTEGER PRIMARY KEY, b);
INSERT INTO t1300 VALUES(1,'coffee'),(2,'COFFEE'),(3,'stress'),(4,'STRESS');
CREATE INDEX t1300bexpr ON t1300( substr(b,4) );
SELECT a FROM t1300 WHERE substr(b,4)='ess' COLLATE nocase ORDER BY +a;
} {3 4}
finish_test
+3 -3
View File
@@ -310,7 +310,7 @@ static int initMain(int argc, char **argv){
"WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<%d)"
" INSERT INTO kv(k,v) SELECT x, randomblob(%d+(random()%%(%d))) FROM c;\n"
"COMMIT;\n",
pgsz, nCount, sz, iVariance+1
pgsz, nCount, sz, iVariance
);
rc = sqlite3_exec(db, zSql, 0, 0, &zErrMsg);
if( rc ) fatalError("database create failed: %s", zErrMsg);
@@ -473,13 +473,13 @@ static unsigned char *readFile(const char *zName, int *pnByte){
if( in==0 ) return 0;
pBuf = sqlite3_malloc64( nIn );
if( pBuf==0 ) return 0;
nRead = fread(pBuf, (size_t)nIn, 1, in);
nRead = fread(pBuf, nIn, 1, in);
fclose(in);
if( nRead!=1 ){
sqlite3_free(pBuf);
return 0;
}
if( pnByte ) *pnByte = (int)nIn;
if( pnByte ) *pnByte = nIn;
return pBuf;
}
+2 -2
View File
@@ -236,12 +236,12 @@ do_test malloc5-4.2 {
db eval {PRAGMA cache_size=1}
db cache flush
sqlite3_release_memory
sqlite3_soft_heap_limit 200000
sqlite3_soft_heap_limit 100000
sqlite3_memory_highwater 1
execsql {SELECT * FROM abc}
set nMaxBytes [sqlite3_memory_highwater 1]
puts -nonewline " (Highwater mark: $nMaxBytes) "
expr $nMaxBytes <= 210000
expr $nMaxBytes <= 110000
} {1}
do_test malloc5-4.3 {
# Check that the content of table abc is at least roughly as expected.
+11 -30
View File
@@ -6,33 +6,12 @@
#include <stdint.h>
#include "sqlite3.h"
/* Return the current real-world time in milliseconds since the
** Julian epoch (-4714-11-24).
*/
static sqlite3_int64 timeOfDay(void){
static sqlite3_vfs *clockVfs = 0;
sqlite3_int64 t;
if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
clockVfs->xCurrentTimeInt64(clockVfs, &t);
}else{
double r;
clockVfs->xCurrentTime(clockVfs, &r);
t = (sqlite3_int64)(r*86400000.0);
}
return t;
}
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/*
** Progress handler callback.
**
** The argument is the cutoff-time after which all processing should
** stop. So return non-zero if the cut-off time is exceeded.
** Progress handler callback
*/
static int progress_handler(void *pReturn) {
sqlite3_int64 iCutoffTime = *(sqlite3_int64*)pReturn;
return timeOfDay()>=iCutoffTime;
return *(int*)pReturn;
}
#endif
@@ -52,13 +31,13 @@ static int exec_handler(void *pCnt, int argc, char **argv, char **namev){
** fuzzed input.
*/
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
int progressArg = 0; /* 1 causes progress handler abort */
int execCnt = 0; /* Abort row callback when count reaches zero */
char *zErrMsg = 0; /* Error message returned by sqlite_exec() */
sqlite3 *db; /* The database connection */
uint8_t uSelector; /* First byte of input data[] */
int rc; /* Return code from various interfaces */
char *zSql; /* Zero-terminated copy of data[] */
sqlite3_int64 iCutoff; /* Cutoff timer */
if( size<3 ) return 0; /* Early out if unsufficient data */
@@ -77,14 +56,16 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if( rc ) return 0;
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/* Invoke the progress handler every 500 thousand instructions (approximately
** 20 to 40 times per second) to check to see if we are taking too long.
*/
iCutoff = timeOfDay() + 10000; /* Now + 10 seconds */
sqlite3_progress_handler(db, 500000, progress_handler, (void*)&iCutoff);
/* Bit 0 of the selector enables progress callbacks. Bit 1 is the
** return code from progress callbacks */
if( uSelector & 1 ){
sqlite3_progress_handler(db, 4, progress_handler, (void*)&progressArg);
}
#endif
uSelector >>= 1;
progressArg = uSelector & 1; uSelector >>= 1;
/* Bit 1 of the selector enables foreign key constraints */
/* Bit 2 of the selector enables foreign key constraints */
sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, uSelector&1, &rc);
uSelector >>= 1;
-4
View File
@@ -754,10 +754,6 @@ test_suite "inmemory_journal" -description {
# This test assumes a journal file is created on disk.
delete_db.test
# This test depends on a successful recovery from the pager error
# state. Which is not possible with an in-memory journal
fts5fault1.test
}]
ifcapable mem3 {
-31
View File
@@ -116,37 +116,6 @@ do_execsql_test printf2-3.5 {
SELECT printf('|%7.8c|%-7.8c|','*','*');
} {|********|********|}
# The "," separator
do_execsql_test printf2-4.1 {
SELECT printf('|%,d|%,d|',0,-1);
} {|0|-1|}
do_execsql_test printf2-4.2 {
SELECT printf('|%,d|%,d|',12,-12);
} {|12|-12|}
do_execsql_test printf2-4.3 {
SELECT printf('|%,d|%,d|',123,-123);
} {|123|-123|}
do_execsql_test printf2-4.4 {
SELECT printf('|%,d|%,d|',1234,-1234);
} {|1,234|-1,234|}
do_execsql_test printf2-4.5 {
SELECT printf('|%,d|%,d|',12345,-12345);
} {|12,345|-12,345|}
do_execsql_test printf2-4.6 {
SELECT printf('|%,d|%,d|',123456,-123456);
} {|123,456|-123,456|}
do_execsql_test printf2-4.7 {
SELECT printf('|%,d|%,d|',1234567,-1234567);
} {|1,234,567|-1,234,567|}
do_execsql_test printf2-4.8 {
SELECT printf('|%,d|%,d|',12345678,-12345678);
} {|12,345,678|-12,345,678|}
do_execsql_test printf2-4.9 {
SELECT printf('|%,d|%,d|',123456789,-123456789);
} {|123,456,789|-123,456,789|}
do_execsql_test printf2-4.10 {
SELECT printf('|%,d|%,d|',1234567890,-1234567890);
} {|1,234,567,890|-1,234,567,890|}
+13 -126
View File
@@ -300,7 +300,7 @@ do_test shell1-3.4.2 {
do_test shell1-3.4.3 {
# too many arguments
catchcmd "test.db" ".dump FOO BAD"
} {1 {Usage: .dump ?--preserve-rowids? ?LIKE-PATTERN?}}
} {1 {Usage: .dump ?LIKE-PATTERN?}}
# .echo ON|OFF Turn command echo on or off
do_test shell1-3.5.1 {
@@ -740,132 +740,19 @@ do_test shell1-4.1 {
} {0 {PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES('');
INSERT INTO t1 VALUES(1);
INSERT INTO t1 VALUES(2.25);
INSERT INTO t1 VALUES('hello');
INSERT INTO t1 VALUES(X'807f');
INSERT INTO "t1" VALUES(NULL);
INSERT INTO "t1" VALUES('');
INSERT INTO "t1" VALUES(1);
INSERT INTO "t1" VALUES(2.25);
INSERT INTO "t1" VALUES('hello');
INSERT INTO "t1" VALUES(X'807F');
CREATE TABLE t3(x,y);
INSERT INTO t3 VALUES(1,NULL);
INSERT INTO t3 VALUES(2,'');
INSERT INTO t3 VALUES(3,1);
INSERT INTO t3 VALUES(4,2.25);
INSERT INTO t3 VALUES(5,'hello');
INSERT INTO t3 VALUES(6,X'807f');
COMMIT;}}
# The --preserve-rowids option to .dump
#
do_test shell1-4.1.1 {
catchcmd test.db {.dump --preserve-rowids}
} {0 {PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE t1(x);
INSERT INTO t1(rowid,x) VALUES(1,NULL);
INSERT INTO t1(rowid,x) VALUES(2,'');
INSERT INTO t1(rowid,x) VALUES(3,1);
INSERT INTO t1(rowid,x) VALUES(4,2.25);
INSERT INTO t1(rowid,x) VALUES(5,'hello');
INSERT INTO t1(rowid,x) VALUES(6,X'807f');
CREATE TABLE t3(x,y);
INSERT INTO t3(rowid,x,y) VALUES(1,1,NULL);
INSERT INTO t3(rowid,x,y) VALUES(2,2,'');
INSERT INTO t3(rowid,x,y) VALUES(3,3,1);
INSERT INTO t3(rowid,x,y) VALUES(4,4,2.25);
INSERT INTO t3(rowid,x,y) VALUES(5,5,'hello');
INSERT INTO t3(rowid,x,y) VALUES(6,6,X'807f');
COMMIT;}}
# If the table contains an INTEGER PRIMARY KEY, do not record a separate
# rowid column in the output.
#
do_test shell1-4.1.2 {
db close
forcedelete test2.db
sqlite3 db test2.db
db eval {
CREATE TABLE t1(x INTEGER PRIMARY KEY, y);
INSERT INTO t1 VALUES(1,null), (2,''), (3,1),
(4,2.25), (5,'hello'), (6,x'807f');
}
catchcmd test2.db {.dump --preserve-rowids}
} {0 {PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE t1(x INTEGER PRIMARY KEY, y);
INSERT INTO t1 VALUES(1,NULL);
INSERT INTO t1 VALUES(2,'');
INSERT INTO t1 VALUES(3,1);
INSERT INTO t1 VALUES(4,2.25);
INSERT INTO t1 VALUES(5,'hello');
INSERT INTO t1 VALUES(6,X'807f');
COMMIT;}}
# Verify that the table named [table] is correctly quoted and that
# an INTEGER PRIMARY KEY DESC is not an alias for the rowid.
#
do_test shell1-4.1.3 {
db close
forcedelete test2.db
sqlite3 db test2.db
db eval {
CREATE TABLE [table](x INTEGER PRIMARY KEY DESC, y);
INSERT INTO [table] VALUES(1,null), (12,''), (23,1),
(34,2.25), (45,'hello'), (56,x'807f');
}
catchcmd test2.db {.dump --preserve-rowids}
} {0 {PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE [table](x INTEGER PRIMARY KEY DESC, y);
INSERT INTO "table"(rowid,x,y) VALUES(1,1,NULL);
INSERT INTO "table"(rowid,x,y) VALUES(2,12,'');
INSERT INTO "table"(rowid,x,y) VALUES(3,23,1);
INSERT INTO "table"(rowid,x,y) VALUES(4,34,2.25);
INSERT INTO "table"(rowid,x,y) VALUES(5,45,'hello');
INSERT INTO "table"(rowid,x,y) VALUES(6,56,X'807f');
COMMIT;}}
# Do not record rowids for a WITHOUT ROWID table. Also check correct quoting
# of table names that contain odd characters.
#
do_test shell1-4.1.4 {
db close
forcedelete test2.db
sqlite3 db test2.db
db eval {
CREATE TABLE [ta<>ble](x INTEGER PRIMARY KEY, y) WITHOUT ROWID;
INSERT INTO [ta<>ble] VALUES(1,null), (12,''), (23,1),
(34,2.25), (45,'hello'), (56,x'807f');
}
catchcmd test2.db {.dump --preserve-rowids}
} {0 {PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE [ta<>ble](x INTEGER PRIMARY KEY, y) WITHOUT ROWID;
INSERT INTO "ta<>ble" VALUES(1,NULL);
INSERT INTO "ta<>ble" VALUES(12,'');
INSERT INTO "ta<>ble" VALUES(23,1);
INSERT INTO "ta<>ble" VALUES(34,2.25);
INSERT INTO "ta<>ble" VALUES(45,'hello');
INSERT INTO "ta<>ble" VALUES(56,X'807f');
COMMIT;}}
# Do not record rowids if the rowid is inaccessible
#
do_test shell1-4.1.5 {
db close
forcedelete test2.db
sqlite3 db test2.db
db eval {
CREATE TABLE t1(_ROWID_,rowid,oid);
INSERT INTO t1 VALUES(1,null,'alpha'), (12,'',99), (23,1,x'b0b1b2');
}
catchcmd test2.db {.dump --preserve-rowids}
} {0 {PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE t1(_ROWID_,rowid,oid);
INSERT INTO t1 VALUES(1,NULL,'alpha');
INSERT INTO t1 VALUES(12,'',99);
INSERT INTO t1 VALUES(23,1,X'b0b1b2');
INSERT INTO "t3" VALUES(1,NULL);
INSERT INTO "t3" VALUES(2,'');
INSERT INTO "t3" VALUES(3,1);
INSERT INTO "t3" VALUES(4,2.25);
INSERT INTO "t3" VALUES(5,'hello');
INSERT INTO "t3" VALUES(6,X'807F');
COMMIT;}}
# Test the output of ".mode insert"
+1 -272
View File
@@ -33,7 +33,7 @@ static const char zHelp[] =
" --size N Relative test size. Default=100\n"
" --stats Show statistics at the end\n"
" --temp N N from 0 to 9. 0: no temp table. 9: all temp tables\n"
" --testset T Run test-set T (main, cte, rtree, orm, debug)\n"
" --testset T Run test-set T\n"
" --trace Turn on SQL tracing\n"
" --threads N Use up to N threads for sorting\n"
" --utf16be Set text encoding to UTF-16BE\n"
@@ -1307,275 +1307,6 @@ void testset_rtree(int p1, int p2){
}
#endif /* SQLITE_ENABLE_RTREE */
/*
** A testset that does key/value storage on tables with many columns.
** This is the kind of workload generated by ORMs such as CoreData.
*/
void testset_orm(void){
unsigned i, j, n;
unsigned nRow;
unsigned x1, len;
char zNum[2000]; /* A number name */
static const char zType[] = /* Types for all non-PK columns, in order */
"IBBIIITIVVITBTBFBFITTFBTBVBVIFTBBFITFFVBIFIVBVVVBTVTIBBFFIVIBTB"
"TVTTFTVTVFFIITIFBITFTTFFFVBIIBTTITFTFFVVVFIIITVBBVFFTVVB";
nRow = n = g.szTest*250;
speedtest1_begin_test(100, "Fill %d rows", n);
speedtest1_exec(
"BEGIN;"
"CREATE TABLE ZLOOKSLIKECOREDATA ("
" ZPK INTEGER PRIMARY KEY,"
" ZTERMFITTINGHOUSINGCOMMAND INTEGER,"
" ZBRIEFGOBYDODGERHEIGHT BLOB,"
" ZCAPABLETRIPDOORALMOND BLOB,"
" ZDEPOSITPAIRCOLLEGECOMET INTEGER,"
" ZFRAMEENTERSIMPLEMOUTH INTEGER,"
" ZHOPEFULGATEHOLECHALK INTEGER,"
" ZSLEEPYUSERGRANDBOWL TIMESTAMP,"
" ZDEWPEACHCAREERCELERY INTEGER,"
" ZHANGERLITHIUMDINNERMEET VARCHAR,"
" ZCLUBRELEASELIZARDADVICE VARCHAR,"
" ZCHARGECLICKHUMANEHIRE INTEGER,"
" ZFINGERDUEPIZZAOPTION TIMESTAMP,"
" ZFLYINGDOCTORTABLEMELODY BLOB,"
" ZLONGFINLEAVEIMAGEOIL TIMESTAMP,"
" ZFAMILYVISUALOWNERMATTER BLOB,"
" ZGOLDYOUNGINITIALNOSE FLOAT,"
" ZCAUSESALAMITERMCYAN BLOB,"
" ZSPREADMOTORBISCUITBACON FLOAT,"
" ZGIFTICEFISHGLUEHAIR INTEGER,"
" ZNOTICEPEARPOLICYJUICE TIMESTAMP,"
" ZBANKBUFFALORECOVERORBIT TIMESTAMP,"
" ZLONGDIETESSAYNATURE FLOAT,"
" ZACTIONRANGEELEGANTNEUTRON BLOB,"
" ZCADETBRIGHTPLANETBANK TIMESTAMP,"
" ZAIRFORGIVEHEADFROG BLOB,"
" ZSHARKJUSTFRUITMOVIE VARCHAR,"
" ZFARMERMORNINGMIRRORCONCERN BLOB,"
" ZWOODPOETRYCOBBLERBENCH VARCHAR,"
" ZHAFNIUMSCRIPTSALADMOTOR INTEGER,"
" ZPROBLEMCLUBPOPOVERJELLY FLOAT,"
" ZEIGHTLEADERWORKERMOST TIMESTAMP,"
" ZGLASSRESERVEBARIUMMEAL BLOB,"
" ZCLAMBITARUGULAFAJITA BLOB,"
" ZDECADEJOYOUSWAVEHABIT FLOAT,"
" ZCOMPANYSUMMERFIBERELF INTEGER,"
" ZTREATTESTQUILLCHARGE TIMESTAMP,"
" ZBROWBALANCEKEYCHOWDER FLOAT,"
" ZPEACHCOPPERDINNERLAKE FLOAT,"
" ZDRYWALLBEYONDBROWNBOWL VARCHAR,"
" ZBELLYCRASHITEMLACK BLOB,"
" ZTENNISCYCLEBILLOFFICER INTEGER,"
" ZMALLEQUIPTHANKSGLUE FLOAT,"
" ZMISSREPLYHUMANLIVING INTEGER,"
" ZKIWIVISUALPRIDEAPPLE VARCHAR,"
" ZWISHHITSKINMOTOR BLOB,"
" ZCALMRACCOONPROGRAMDEBIT VARCHAR,"
" ZSHINYASSISTLIVINGCRAB VARCHAR,"
" ZRESOLVEWRISTWRAPAPPLE VARCHAR,"
" ZAPPEALSIMPLESECONDHOUSING BLOB,"
" ZCORNERANCHORTAPEDIVER TIMESTAMP,"
" ZMEMORYREQUESTSOURCEBIG VARCHAR,"
" ZTRYFACTKEEPMILK TIMESTAMP,"
" ZDIVERPAINTLEATHEREASY INTEGER,"
" ZSORTMISTYQUOTECABBAGE BLOB,"
" ZTUNEGASBUFFALOCAPITAL BLOB,"
" ZFILLSTOPLAWJOYFUL FLOAT,"
" ZSTEELCAREFULPLATENUMBER FLOAT,"
" ZGIVEVIVIDDIVINEMEANING INTEGER,"
" ZTREATPACKFUTURECONVERT VARCHAR,"
" ZCALMLYGEMFINISHEFFECT INTEGER,"
" ZCABBAGESOCKEASEMINUTE BLOB,"
" ZPLANETFAMILYPUREMEMORY TIMESTAMP,"
" ZMERRYCRACKTRAINLEADER BLOB,"
" ZMINORWAYPAPERCLASSY TIMESTAMP,"
" ZEAGLELINEMINEMAIL VARCHAR,"
" ZRESORTYARDGREENLET TIMESTAMP,"
" ZYARDOREGANOVIVIDJEWEL TIMESTAMP,"
" ZPURECAKEVIVIDNEATLY FLOAT,"
" ZASKCONTACTMONITORFUN TIMESTAMP,"
" ZMOVEWHOGAMMAINCH VARCHAR,"
" ZLETTUCEBIRDMEETDEBATE TIMESTAMP,"
" ZGENENATURALHEARINGKITE VARCHAR,"
" ZMUFFINDRYERDRAWFORTUNE FLOAT,"
" ZGRAYSURVEYWIRELOVE FLOAT,"
" ZPLIERSPRINTASKOREGANO INTEGER,"
" ZTRAVELDRIVERCONTESTLILY INTEGER,"
" ZHUMORSPICESANDKIDNEY TIMESTAMP,"
" ZARSENICSAMPLEWAITMUON INTEGER,"
" ZLACEADDRESSGROUNDCAREFUL FLOAT,"
" ZBAMBOOMESSWASABIEVENING BLOB,"
" ZONERELEASEAVERAGENURSE INTEGER,"
" ZRADIANTWHENTRYCARD TIMESTAMP,"
" ZREWARDINSIDEMANGOINTENSE FLOAT,"
" ZNEATSTEWPARTIRON TIMESTAMP,"
" ZOUTSIDEPEAHENCOUNTICE TIMESTAMP,"
" ZCREAMEVENINGLIPBRANCH FLOAT,"
" ZWHALEMATHAVOCADOCOPPER FLOAT,"
" ZLIFEUSELEAFYBELL FLOAT,"
" ZWEALTHLINENGLEEFULDAY VARCHAR,"
" ZFACEINVITETALKGOLD BLOB,"
" ZWESTAMOUNTAFFECTHEARING INTEGER,"
" ZDELAYOUTCOMEHORNAGENCY INTEGER,"
" ZBIGTHINKCONVERTECONOMY BLOB,"
" ZBASEGOUDAREGULARFORGIVE TIMESTAMP,"
" ZPATTERNCLORINEGRANDCOLBY TIMESTAMP,"
" ZCYANBASEFEEDADROIT INTEGER,"
" ZCARRYFLOORMINNOWDRAGON TIMESTAMP,"
" ZIMAGEPENCILOTHERBOTTOM FLOAT,"
" ZXENONFLIGHTPALEAPPLE TIMESTAMP,"
" ZHERRINGJOKEFEATUREHOPEFUL FLOAT,"
" ZCAPYEARLYRIVETBRUSH FLOAT,"
" ZAGEREEDFROGBASKET VARCHAR,"
" ZUSUALBODYHALIBUTDIAMOND VARCHAR,"
" ZFOOTTAPWORDENTRY VARCHAR,"
" ZDISHKEEPBLESTMONITOR FLOAT,"
" ZBROADABLESOLIDCASUAL INTEGER,"
" ZSQUAREGLEEFULCHILDLIGHT INTEGER,"
" ZHOLIDAYHEADPONYDETAIL INTEGER,"
" ZGENERALRESORTSKYOPEN TIMESTAMP,"
" ZGLADSPRAYKIDNEYGUPPY VARCHAR,"
" ZSWIMHEAVYMENTIONKIND BLOB,"
" ZMESSYSULFURDREAMFESTIVE BLOB,"
" ZSKYSKYCLASSICBRIEF VARCHAR,"
" ZDILLASKHOKILEMON FLOAT,"
" ZJUNIORSHOWPRESSNOVA FLOAT,"
" ZSIZETOEAWARDFRESH TIMESTAMP,"
" ZKEYFAILAPRICOTMETAL VARCHAR,"
" ZHANDYREPAIRPROTONAIRPORT VARCHAR,"
" ZPOSTPROTEINHANDLEACTOR BLOB"
");"
);
speedtest1_prepare(
"INSERT INTO ZLOOKSLIKECOREDATA(ZPK,ZAIRFORGIVEHEADFROG,"
"ZGIFTICEFISHGLUEHAIR,ZDELAYOUTCOMEHORNAGENCY,ZSLEEPYUSERGRANDBOWL,"
"ZGLASSRESERVEBARIUMMEAL,ZBRIEFGOBYDODGERHEIGHT,"
"ZBAMBOOMESSWASABIEVENING,ZFARMERMORNINGMIRRORCONCERN,"
"ZTREATPACKFUTURECONVERT,ZCAUSESALAMITERMCYAN,ZCALMRACCOONPROGRAMDEBIT,"
"ZHOLIDAYHEADPONYDETAIL,ZWOODPOETRYCOBBLERBENCH,ZHAFNIUMSCRIPTSALADMOTOR,"
"ZUSUALBODYHALIBUTDIAMOND,ZOUTSIDEPEAHENCOUNTICE,ZDIVERPAINTLEATHEREASY,"
"ZWESTAMOUNTAFFECTHEARING,ZSIZETOEAWARDFRESH,ZDEWPEACHCAREERCELERY,"
"ZSTEELCAREFULPLATENUMBER,ZCYANBASEFEEDADROIT,ZCALMLYGEMFINISHEFFECT,"
"ZHANDYREPAIRPROTONAIRPORT,ZGENENATURALHEARINGKITE,ZBROADABLESOLIDCASUAL,"
"ZPOSTPROTEINHANDLEACTOR,ZLACEADDRESSGROUNDCAREFUL,ZIMAGEPENCILOTHERBOTTOM,"
"ZPROBLEMCLUBPOPOVERJELLY,ZPATTERNCLORINEGRANDCOLBY,ZNEATSTEWPARTIRON,"
"ZAPPEALSIMPLESECONDHOUSING,ZMOVEWHOGAMMAINCH,ZTENNISCYCLEBILLOFFICER,"
"ZSHARKJUSTFRUITMOVIE,ZKEYFAILAPRICOTMETAL,ZCOMPANYSUMMERFIBERELF,"
"ZTERMFITTINGHOUSINGCOMMAND,ZRESORTYARDGREENLET,ZCABBAGESOCKEASEMINUTE,"
"ZSQUAREGLEEFULCHILDLIGHT,ZONERELEASEAVERAGENURSE,ZBIGTHINKCONVERTECONOMY,"
"ZPLIERSPRINTASKOREGANO,ZDECADEJOYOUSWAVEHABIT,ZDRYWALLBEYONDBROWNBOWL,"
"ZCLUBRELEASELIZARDADVICE,ZWHALEMATHAVOCADOCOPPER,ZBELLYCRASHITEMLACK,"
"ZLETTUCEBIRDMEETDEBATE,ZCAPABLETRIPDOORALMOND,ZRADIANTWHENTRYCARD,"
"ZCAPYEARLYRIVETBRUSH,ZAGEREEDFROGBASKET,ZSWIMHEAVYMENTIONKIND,"
"ZTRAVELDRIVERCONTESTLILY,ZGLADSPRAYKIDNEYGUPPY,ZBANKBUFFALORECOVERORBIT,"
"ZFINGERDUEPIZZAOPTION,ZCLAMBITARUGULAFAJITA,ZLONGFINLEAVEIMAGEOIL,"
"ZLONGDIETESSAYNATURE,ZJUNIORSHOWPRESSNOVA,ZHOPEFULGATEHOLECHALK,"
"ZDEPOSITPAIRCOLLEGECOMET,ZWEALTHLINENGLEEFULDAY,ZFILLSTOPLAWJOYFUL,"
"ZTUNEGASBUFFALOCAPITAL,ZGRAYSURVEYWIRELOVE,ZCORNERANCHORTAPEDIVER,"
"ZREWARDINSIDEMANGOINTENSE,ZCADETBRIGHTPLANETBANK,ZPLANETFAMILYPUREMEMORY,"
"ZTREATTESTQUILLCHARGE,ZCREAMEVENINGLIPBRANCH,ZSKYSKYCLASSICBRIEF,"
"ZARSENICSAMPLEWAITMUON,ZBROWBALANCEKEYCHOWDER,ZFLYINGDOCTORTABLEMELODY,"
"ZHANGERLITHIUMDINNERMEET,ZNOTICEPEARPOLICYJUICE,ZSHINYASSISTLIVINGCRAB,"
"ZLIFEUSELEAFYBELL,ZFACEINVITETALKGOLD,ZGENERALRESORTSKYOPEN,"
"ZPURECAKEVIVIDNEATLY,ZKIWIVISUALPRIDEAPPLE,ZMESSYSULFURDREAMFESTIVE,"
"ZCHARGECLICKHUMANEHIRE,ZHERRINGJOKEFEATUREHOPEFUL,ZYARDOREGANOVIVIDJEWEL,"
"ZFOOTTAPWORDENTRY,ZWISHHITSKINMOTOR,ZBASEGOUDAREGULARFORGIVE,"
"ZMUFFINDRYERDRAWFORTUNE,ZACTIONRANGEELEGANTNEUTRON,ZTRYFACTKEEPMILK,"
"ZPEACHCOPPERDINNERLAKE,ZFRAMEENTERSIMPLEMOUTH,ZMERRYCRACKTRAINLEADER,"
"ZMEMORYREQUESTSOURCEBIG,ZCARRYFLOORMINNOWDRAGON,ZMINORWAYPAPERCLASSY,"
"ZDILLASKHOKILEMON,ZRESOLVEWRISTWRAPAPPLE,ZASKCONTACTMONITORFUN,"
"ZGIVEVIVIDDIVINEMEANING,ZEIGHTLEADERWORKERMOST,ZMISSREPLYHUMANLIVING,"
"ZXENONFLIGHTPALEAPPLE,ZSORTMISTYQUOTECABBAGE,ZEAGLELINEMINEMAIL,"
"ZFAMILYVISUALOWNERMATTER,ZSPREADMOTORBISCUITBACON,ZDISHKEEPBLESTMONITOR,"
"ZMALLEQUIPTHANKSGLUE,ZGOLDYOUNGINITIALNOSE,ZHUMORSPICESANDKIDNEY)"
"VALUES(?1,?26,?20,?93,?8,?33,?3,?81,?28,?60,?18,?47,?109,?29,?30,?104,?86,"
"?54,?92,?117,?9,?58,?97,?61,?119,?73,?107,?120,?80,?99,?31,?96,?85,?50,?71,"
"?42,?27,?118,?36,?2,?67,?62,?108,?82,?94,?76,?35,?40,?11,?88,?41,?72,?4,"
"?83,?102,?103,?112,?77,?111,?22,?13,?34,?15,?23,?116,?7,?5,?90,?57,?56,"
"?75,?51,?84,?25,?63,?37,?87,?114,?79,?38,?14,?10,?21,?48,?89,?91,?110,"
"?69,?45,?113,?12,?101,?68,?105,?46,?95,?74,?24,?53,?39,?6,?64,?52,?98,"
"?65,?115,?49,?70,?59,?32,?44,?100,?55,?66,?16,?19,?106,?43,?17,?78);"
);
for(i=0; i<n; i++){
x1 = speedtest1_random();
speedtest1_numbername(x1%1000, zNum, sizeof(zNum));
len = (int)strlen(zNum);
sqlite3_bind_int(g.pStmt, 1, i^0xf);
for(j=0; zType[j]; j++){
switch( zType[j] ){
case 'I':
case 'T':
sqlite3_bind_int64(g.pStmt, j+2, x1);
break;
case 'F':
sqlite3_bind_double(g.pStmt, j+2, (double)x1);
break;
case 'V':
case 'B':
sqlite3_bind_text64(g.pStmt, j+2, zNum, len,
SQLITE_STATIC, SQLITE_UTF8);
break;
}
}
speedtest1_run();
}
speedtest1_exec("COMMIT;");
speedtest1_end_test();
n = g.szTest*250;
speedtest1_begin_test(110, "Query %d rows by rowid", n);
speedtest1_prepare(
"SELECT ZCYANBASEFEEDADROIT,ZJUNIORSHOWPRESSNOVA,ZCAUSESALAMITERMCYAN,"
"ZHOPEFULGATEHOLECHALK,ZHUMORSPICESANDKIDNEY,ZSWIMHEAVYMENTIONKIND,"
"ZMOVEWHOGAMMAINCH,ZAPPEALSIMPLESECONDHOUSING,ZHAFNIUMSCRIPTSALADMOTOR,"
"ZNEATSTEWPARTIRON,ZLONGFINLEAVEIMAGEOIL,ZDEWPEACHCAREERCELERY,"
"ZXENONFLIGHTPALEAPPLE,ZCALMRACCOONPROGRAMDEBIT,ZUSUALBODYHALIBUTDIAMOND,"
"ZTRYFACTKEEPMILK,ZWEALTHLINENGLEEFULDAY,ZLONGDIETESSAYNATURE,"
"ZLIFEUSELEAFYBELL,ZTREATPACKFUTURECONVERT,ZMEMORYREQUESTSOURCEBIG,"
"ZYARDOREGANOVIVIDJEWEL,ZDEPOSITPAIRCOLLEGECOMET,ZSLEEPYUSERGRANDBOWL,"
"ZBRIEFGOBYDODGERHEIGHT,ZCLUBRELEASELIZARDADVICE,ZCAPABLETRIPDOORALMOND,"
"ZDRYWALLBEYONDBROWNBOWL,ZASKCONTACTMONITORFUN,ZKIWIVISUALPRIDEAPPLE,"
"ZNOTICEPEARPOLICYJUICE,ZPEACHCOPPERDINNERLAKE,ZSTEELCAREFULPLATENUMBER,"
"ZGLADSPRAYKIDNEYGUPPY,ZCOMPANYSUMMERFIBERELF,ZTENNISCYCLEBILLOFFICER,"
"ZIMAGEPENCILOTHERBOTTOM,ZWESTAMOUNTAFFECTHEARING,ZDIVERPAINTLEATHEREASY,"
"ZSKYSKYCLASSICBRIEF,ZMESSYSULFURDREAMFESTIVE,ZMERRYCRACKTRAINLEADER,"
"ZBROADABLESOLIDCASUAL,ZGLASSRESERVEBARIUMMEAL,ZTUNEGASBUFFALOCAPITAL,"
"ZBANKBUFFALORECOVERORBIT,ZTREATTESTQUILLCHARGE,ZBAMBOOMESSWASABIEVENING,"
"ZREWARDINSIDEMANGOINTENSE,ZEAGLELINEMINEMAIL,ZCALMLYGEMFINISHEFFECT,"
"ZKEYFAILAPRICOTMETAL,ZFINGERDUEPIZZAOPTION,ZCADETBRIGHTPLANETBANK,"
"ZGOLDYOUNGINITIALNOSE,ZMISSREPLYHUMANLIVING,ZEIGHTLEADERWORKERMOST,"
"ZFRAMEENTERSIMPLEMOUTH,ZBIGTHINKCONVERTECONOMY,ZFACEINVITETALKGOLD,"
"ZPOSTPROTEINHANDLEACTOR,ZHERRINGJOKEFEATUREHOPEFUL,ZCABBAGESOCKEASEMINUTE,"
"ZMUFFINDRYERDRAWFORTUNE,ZPROBLEMCLUBPOPOVERJELLY,ZGIVEVIVIDDIVINEMEANING,"
"ZGENENATURALHEARINGKITE,ZGENERALRESORTSKYOPEN,ZLETTUCEBIRDMEETDEBATE,"
"ZBASEGOUDAREGULARFORGIVE,ZCHARGECLICKHUMANEHIRE,ZPLANETFAMILYPUREMEMORY,"
"ZMINORWAYPAPERCLASSY,ZCAPYEARLYRIVETBRUSH,ZSIZETOEAWARDFRESH,"
"ZARSENICSAMPLEWAITMUON,ZSQUAREGLEEFULCHILDLIGHT,ZSHINYASSISTLIVINGCRAB,"
"ZCORNERANCHORTAPEDIVER,ZDECADEJOYOUSWAVEHABIT,ZTRAVELDRIVERCONTESTLILY,"
"ZFLYINGDOCTORTABLEMELODY,ZSHARKJUSTFRUITMOVIE,ZFAMILYVISUALOWNERMATTER,"
"ZFARMERMORNINGMIRRORCONCERN,ZGIFTICEFISHGLUEHAIR,ZOUTSIDEPEAHENCOUNTICE,"
"ZSPREADMOTORBISCUITBACON,ZWISHHITSKINMOTOR,ZHOLIDAYHEADPONYDETAIL,"
"ZWOODPOETRYCOBBLERBENCH,ZAIRFORGIVEHEADFROG,ZBROWBALANCEKEYCHOWDER,"
"ZDISHKEEPBLESTMONITOR,ZCLAMBITARUGULAFAJITA,ZPLIERSPRINTASKOREGANO,"
"ZRADIANTWHENTRYCARD,ZDELAYOUTCOMEHORNAGENCY,ZPURECAKEVIVIDNEATLY,"
"ZPATTERNCLORINEGRANDCOLBY,ZHANDYREPAIRPROTONAIRPORT,ZAGEREEDFROGBASKET,"
"ZSORTMISTYQUOTECABBAGE,ZFOOTTAPWORDENTRY,ZRESOLVEWRISTWRAPAPPLE,"
"ZDILLASKHOKILEMON,ZFILLSTOPLAWJOYFUL,ZACTIONRANGEELEGANTNEUTRON,"
"ZRESORTYARDGREENLET,ZCREAMEVENINGLIPBRANCH,ZWHALEMATHAVOCADOCOPPER,"
"ZGRAYSURVEYWIRELOVE,ZBELLYCRASHITEMLACK,ZHANGERLITHIUMDINNERMEET,"
"ZCARRYFLOORMINNOWDRAGON,ZMALLEQUIPTHANKSGLUE,ZTERMFITTINGHOUSINGCOMMAND,"
"ZONERELEASEAVERAGENURSE,ZLACEADDRESSGROUNDCAREFUL"
" FROM ZLOOKSLIKECOREDATA WHERE ZPK=?1;"
);
for(i=0; i<n; i++){
x1 = speedtest1_random()%nRow;
sqlite3_bind_int(g.pStmt, 1, x1);
speedtest1_run();
}
speedtest1_end_test();
}
/*
** A testset used for debugging speedtest1 itself.
*/
@@ -1879,8 +1610,6 @@ int main(int argc, char **argv){
testset_main();
}else if( strcmp(zTSet,"debug1")==0 ){
testset_debug1();
}else if( strcmp(zTSet,"orm")==0 ){
testset_orm();
}else if( strcmp(zTSet,"cte")==0 ){
testset_cte();
}else if( strcmp(zTSet,"rtree")==0 ){
+4 -33
View File
@@ -919,37 +919,10 @@ proc normalize_list {L} {
set L2
}
# Either:
#
# do_execsql_test TESTNAME SQL ?RES?
# do_execsql_test -db DB TESTNAME SQL ?RES?
#
proc do_execsql_test {args} {
set db db
if {[lindex $args 0]=="-db"} {
set db [lindex $args 1]
set args [lrange $args 2 end]
}
if {[llength $args]==2} {
foreach {testname sql} $args {}
set result ""
} elseif {[llength $args]==3} {
foreach {testname sql result} $args {}
} else {
error [string trim {
wrong # args: should be "do_execsql_test ?-db DB? testname sql ?result?"
}]
}
proc do_execsql_test {testname sql {result {}}} {
fix_testname testname
uplevel do_test \
[list $testname] \
[list "execsql {$sql} $db"] \
[list [list {*}$result]]
uplevel do_test [list $testname] [list "execsql {$sql}"] [list [list {*}$result]]
}
proc do_catchsql_test {testname sql result} {
fix_testname testname
uplevel do_test [list $testname] [list "catchsql {$sql}"] [list $result]
@@ -1533,7 +1506,6 @@ proc crashsql {args} {
set tclbody {}
set crashfile ""
set dc ""
set dfltvfs 0
set sql [lindex $args end]
for {set ii 0} {$ii < [llength $args]-1} {incr ii 2} {
@@ -1547,8 +1519,7 @@ proc crashsql {args} {
elseif {$n>1 && [string first $z -file]==0} {set crashfile $z2} \
elseif {$n>1 && [string first $z -tclbody]==0} {set tclbody $z2} \
elseif {$n>1 && [string first $z -blocksize]==0} {set blocksize "-s $z2" } \
elseif {$n>1 && [string first $z -characteristics]==0} {set dc "-c {$z2}" }\
elseif {$n>1 && [string first $z -dfltvfs]==0} {set dfltvfs $z2 }\
elseif {$n>1 && [string first $z -characteristics]==0} {set dc "-c {$z2}" } \
else { error "Unrecognized option: $z" }
}
@@ -1562,7 +1533,7 @@ proc crashsql {args} {
set cfile [string map {\\ \\\\} [file nativename [file join [get_pwd] $crashfile]]]
set f [open crash.tcl w]
puts $f "sqlite3_crash_enable 1 $dfltvfs"
puts $f "sqlite3_crash_enable 1"
puts $f "sqlite3_crashparams $blocksize $dc $crashdelay $cfile"
puts $f "sqlite3_test_control_pending_byte $::sqlite_pending_byte"
+1 -1
View File
@@ -42,7 +42,7 @@ do_test tkt-78e04-1.3 {
} {}
do_test tkt-78e04-1.4 {
execsql {
EXPLAIN QUERY PLAN SELECT "" FROM "" WHERE "" LIKE '1abc%';
EXPLAIN QUERY PLAN SELECT "" FROM "" WHERE "" LIKE 'abc%';
}
} {0 0 0 {SCAN TABLE USING COVERING INDEX i1}}
do_test tkt-78e04-1.5 {
+14 -14
View File
@@ -1295,25 +1295,25 @@ do_execsql_test 18.1.0 {
CREATE INDEX i6 ON t6(b, a);
INSERT INTO t6 VALUES(1, 'Peter');
INSERT INTO t6 VALUES(2, 'Andrew');
INSERT INTO t6 VALUES(3, '8James');
INSERT INTO t6 VALUES(4, '8John');
INSERT INTO t6 VALUES(3, 'James');
INSERT INTO t6 VALUES(4, 'John');
INSERT INTO t6 VALUES(5, 'Phillip');
INSERT INTO t6 VALUES(6, 'Bartholomew');
CREATE VIRTUAL TABLE e6 USING echo(t6);
}
foreach {tn sql res filter} {
1.1 "SELECT a FROM e6 WHERE b>'8James'" {4 2 6 1 5}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} 8James}
1.1 "SELECT a FROM e6 WHERE b>'James'" {4 1 5}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} James}
1.2 "SELECT a FROM e6 WHERE b>='8' AND b<'9'" {3 4}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ?} 8 9}
1.2 "SELECT a FROM e6 WHERE b>='J' AND b<'K'" {3 4}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ?} J K}
1.3 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8J%}
1.3 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} J%}
1.4 "SELECT a FROM e6 WHERE b LIKE '8j%'" {3 4}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8j%}
1.4 "SELECT a FROM e6 WHERE b LIKE 'j%'" {3 4}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} j%}
} {
set echo_module {}
do_execsql_test 18.$tn.1 $sql $res
@@ -1322,11 +1322,11 @@ foreach {tn sql res filter} {
do_execsql_test 18.2.0 { PRAGMA case_sensitive_like = ON }
foreach {tn sql res filter} {
2.1 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8J%}
2.1 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} J%}
2.2 "SELECT a FROM e6 WHERE b LIKE '8j%'" {}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8j%}
2.2 "SELECT a FROM e6 WHERE b LIKE 'j%'" {}
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} j%}
} {
set echo_module {}
do_execsql_test 18.$tn.1 $sql $res
+4 -4
View File
@@ -31,14 +31,14 @@ do_execsql_test 1.0 {
}
foreach {tn sql expect} {
1 "SELECT * FROM e6 WHERE b LIKE '8abc'" {
1 "SELECT * FROM e6 WHERE b LIKE 'abc'" {
xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?}
xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8abc
xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} abc
}
2 "SELECT * FROM e6 WHERE b GLOB '8abc'" {
2 "SELECT * FROM e6 WHERE b GLOB 'abc'" {
xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?}
xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} 8abc
xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} abc
}
} {
do_test 1.$tn {
+1 -13
View File
@@ -124,7 +124,7 @@ IF NOT EXIST "%FRAMEWORKDIR%\csc.exe" (
GOTO errors
)
CALL :fn_PrependToPath FRAMEWORKDIR
SET PATH=%FRAMEWORKDIR%;%PATH%
:skip_addToPath
@@ -246,18 +246,6 @@ GOTO no_errors
ENDLOCAL && SET %1=%VALUE%
GOTO :EOF
:fn_PrependToPath
IF NOT DEFINED %1 GOTO :EOF
SETLOCAL
SET __ECHO_CMD=ECHO %%%1%%
FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO (
SET VALUE=%%V
)
SET VALUE=%VALUE:"=%
REM "
ENDLOCAL && SET PATH=%VALUE%;%PATH%
GOTO :EOF
:fn_ResetErrorLevel
VERIFY > NUL
GOTO :EOF
+1 -5
View File
@@ -460,7 +460,7 @@ FOR %%P IN (%PLATFORMS%) DO (
REM
REM NOTE: Reset the PATH here to the absolute bare minimum required.
REM
CALL :fn_ResetPath
SET PATH=%TOOLPATH%;%SystemRoot%\System32;%SystemRoot%
REM
REM NOTE: This is the inner loop. There are normally two iterations, one
@@ -818,10 +818,6 @@ GOTO no_errors
CALL :fn_ResetErrorLevel
GOTO :EOF
:fn_ResetPath
SET PATH=%TOOLPATH%;%SystemRoot%\System32;%SystemRoot%
GOTO :EOF
:fn_AppendVariable
SET __ECHO_CMD=ECHO %%%1%%
IF DEFINED %1 (
-41
View File
@@ -1,41 +0,0 @@
/*
** Link this program against an SQLite library of unknown provenance in order
** to display the compile-time maximum values for various settings.
*/
#include "sqlite3.h"
#include <stdio.h>
static const struct {
int eCode;
char *zName;
} aLimit[] = {
{ SQLITE_LIMIT_LENGTH, "SQLITE_MAX_LENGTH" },
{ SQLITE_LIMIT_SQL_LENGTH, "SQLITE_MAX_SQL_LENGTH" },
{ SQLITE_LIMIT_COLUMN, "SQLITE_MAX_COLUMN" },
{ SQLITE_LIMIT_EXPR_DEPTH, "SQLITE_MAX_EXPR_DEPTH" },
{ SQLITE_LIMIT_COMPOUND_SELECT, "SQLITE_MAX_COMPOUND_SELECT" },
{ SQLITE_LIMIT_VDBE_OP, "SQLITE_MAX_VDBE_OP" },
{ SQLITE_LIMIT_FUNCTION_ARG, "SQLITE_MAX_FUNCTION_ARG" },
{ SQLITE_LIMIT_ATTACHED, "SQLITE_MAX_ATTACHED" },
{ SQLITE_LIMIT_LIKE_PATTERN_LENGTH, "SQLITE_MAX_LIKE_PATTERN_LENGTH" },
{ SQLITE_LIMIT_VARIABLE_NUMBER, "SQLITE_MAX_VARIABLE_NUMBER" },
{ SQLITE_LIMIT_TRIGGER_DEPTH, "SQLITE_MAX_TRIGGER_DEPTH" },
{ SQLITE_LIMIT_WORKER_THREADS, "SQLITE_MAX_WORKER_THREADS" },
};
static int maxLimit(sqlite3 *db, int eCode){
int iOrig = sqlite3_limit(db, eCode, 0x7fffffff);
return sqlite3_limit(db, eCode, iOrig);
}
int main(int argc, char **argv){
sqlite3 *db;
int j, rc;
rc = sqlite3_open(":memory:", &db);
if( rc==SQLITE_OK ){
for(j=0; j<sizeof(aLimit)/sizeof(aLimit[0]); j++){
printf("%-35s %10d\n", aLimit[j].zName, maxLimit(db, aLimit[j].eCode));
}
sqlite3_close(db);
}
}
+1 -1
View File
@@ -83,7 +83,7 @@ Replace.exe:
sqlite3.def: Replace.exe $(LIBOBJ)
echo EXPORTS > sqlite3.def
dumpbin /all $(LIBOBJ) \\
| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \\
| .\Replace.exe "^\s+/EXPORT:_?(sqlite3_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \\
| sort >> sqlite3.def
}]]
+2 -5
View File
@@ -225,8 +225,8 @@ set pragma_def {
NAME: stats
FLAG: NeedSchema Result0 SchemaReq
COLS: tbl idx wdth hght flgs
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
COLS: table index width height
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
NAME: index_info
TYPE: INDEX_INFO
@@ -361,9 +361,6 @@ set pragma_def {
NAME: threads
FLAG: Result0
NAME: optimize
FLAG: Result1
}
# Open the output file
+2 -10
View File
@@ -73,13 +73,7 @@ close $in
# Set up patterns for recognizing API declarations.
#
set varpattern {^[a-zA-Z][a-zA-Z_0-9 *]+sqlite3_[_a-zA-Z0-9]+(\[|;| =)}
set declpattern1 {^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3_[_a-zA-Z0-9]+)(\(.*)$}
set declpattern2 \
{^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3session_[_a-zA-Z0-9]+)(\(.*)$}
set declpattern3 \
{^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3changeset_[_a-zA-Z0-9]+)(\(.*)$}
set declpattern {^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3_[_a-zA-Z0-9]+)(\(.*)$}
# Force the output to use unix line endings, even on Windows.
fconfigure stdout -translation lf
@@ -127,9 +121,7 @@ foreach file $filelist {
if {[regexp $varpattern $line] && ![regexp {^ *typedef} $line]} {
set line "SQLITE_API $line"
} else {
if {[regexp $declpattern1 $line all rettype funcname rest] || \
[regexp $declpattern2 $line all rettype funcname rest] || \
[regexp $declpattern3 $line all rettype funcname rest]} {
if {[regexp $declpattern $line all rettype funcname rest]} {
set line SQLITE_API
append line " " [string trim $rettype]
if {[string index $rettype end] ne "*"} {