Compare commits
175 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f8f8a576bd | |||
| ee6c5e5ae7 | |||
| a31d3554c5 | |||
| 5f6a4ea2e2 | |||
| 0086e07865 | |||
| ec3dda5b11 | |||
| 74e1b861ad | |||
| 505ae9def8 | |||
| a677eecad3 | |||
| 0d950af311 | |||
| af8664020a | |||
| 3e36480232 | |||
| f236b21f4b | |||
| 37874d7dcc | |||
| 2ebb550824 | |||
| f7c92e82d2 | |||
| 6fcb9f3ad9 | |||
| 546738f855 | |||
| 35fb866ea3 | |||
| 2a0c16f276 | |||
| 4fcb9caa60 | |||
| 4780b9ad46 | |||
| 95da9d5d46 | |||
| b6ce71bd26 | |||
| 3722b3abf1 | |||
| b6e0286c49 | |||
| 8c754a3613 | |||
| ae8e45cb0c | |||
| 9105fd5189 | |||
| dac7e69dc2 | |||
| 5976b2c805 | |||
| 5df8428069 | |||
| 87ca8067af | |||
| c324d44690 | |||
| 8328369740 | |||
| cc491f4b1b | |||
| 9e9a67adb0 | |||
| 5b32bdff80 | |||
| cc3f3d1f05 | |||
| 217ca657d8 | |||
| cc5979dbd3 | |||
| 15750a26fa | |||
| 4043cfef75 | |||
| 11d88e68ab | |||
| 42d2fce7f5 | |||
| 725dd72400 | |||
| a3fcc000cb | |||
| d4da4936cd | |||
| 27e80a3b68 | |||
| b9fc45534d | |||
| 908e7c43a7 | |||
| 87ae34ba1a | |||
| 7c2321fdf3 | |||
| 3c1970fcee | |||
| b8a8d523cb | |||
| 554a19dbee | |||
| 6e11892db8 | |||
| 41428a97b8 | |||
| 30842990b2 | |||
| c5a93d4c85 | |||
| 14c865e859 | |||
| b6299681c6 | |||
| 3251a2031b | |||
| cb99c57a66 | |||
| 044388cf98 | |||
| 3728b84c03 | |||
| 51755a78a9 | |||
| 690f04a0d7 | |||
| af97c3f35a | |||
| 5eae1d1b33 | |||
| 175b8f06f7 | |||
| 1c269a9ff8 | |||
| 679c9613f6 | |||
| e7e48dc629 | |||
| 0e3c50c5dc | |||
| 74c490e045 | |||
| 2712b022ab | |||
| 55220a6c70 | |||
| a2de66c6b4 | |||
| f32105708e | |||
| 9ce3c8ac26 | |||
| 915e434c35 | |||
| 96fb16eecd | |||
| 5978a7a525 | |||
| 0a8d06a93f | |||
| 2046a77365 | |||
| 81506b88b8 | |||
| 1194904b81 | |||
| 2b96b6969a | |||
| 72d1eac673 | |||
| 3cbbd195ca | |||
| 45f3b3cf1d | |||
| 192418bd49 | |||
| 55b4c827fa | |||
| 9f8c028221 | |||
| 2e6d83bc49 | |||
| e6e96b1b45 | |||
| ade54d68ee | |||
| 0bf6549cd1 | |||
| ddd7421c91 | |||
| d744ee0b50 | |||
| 401593e348 | |||
| 71f059c880 | |||
| 45cb2aa98c | |||
| 9252df4969 | |||
| 7e35e81dcb | |||
| 9c3bb59f76 | |||
| 2ad07d96b6 | |||
| 822bc969f6 | |||
| 8fbcb04811 | |||
| 8279fe8a4b | |||
| ed9d12dbc2 | |||
| a79a0e733f | |||
| 337cc3992a | |||
| 122c514271 | |||
| f71a243a60 | |||
| ac713403fd | |||
| b8293a5bee | |||
| dff1d5b61b | |||
| bfe33f80dd | |||
| 00c12a51e3 | |||
| 9443dbc493 | |||
| 01c08bcacd | |||
| 95063c2867 | |||
| 1c70f71e12 | |||
| 9378818d89 | |||
| e209457295 | |||
| e0ae3f69eb | |||
| cda50737f4 | |||
| 7f6f12bdd3 | |||
| 75b0821e99 | |||
| 1e60261cfb | |||
| fd15e18d7f | |||
| 7fc296aa66 | |||
| bcb0e64c82 | |||
| e04c1ec52a | |||
| c5cc870ef8 | |||
| 9bf022d57c | |||
| 750c6ba5e5 | |||
| a1ac03590b | |||
| b555b0806e | |||
| 4509ffa362 | |||
| 996f5ccb33 | |||
| 09ea1256ec | |||
| 8b65e5919d | |||
| 3db3d12cd1 | |||
| 19d9a3ca6c | |||
| 7b1904e35d | |||
| 1ff9407198 | |||
| 4d02b5f7d0 | |||
| 55f66b341a | |||
| 2cd02a5d2a | |||
| 993b48e2b7 | |||
| e464802d49 | |||
| ec9b2a132b | |||
| 08e2e8e680 | |||
| 0088574271 | |||
| 8f245174a3 | |||
| 5e61c1b741 | |||
| ea38f4f4cc | |||
| df9d32441a | |||
| 4f9adee289 | |||
| 8616cff6c8 | |||
| 648d629953 | |||
| 01fd42beef | |||
| 52d9a3c213 | |||
| 76fd7be3a3 | |||
| 7f88a24dc6 | |||
| c1da4397d6 | |||
| 6488271f05 | |||
| 8117f113bc | |||
| 1efcc9dd96 | |||
| b28c4e564a | |||
| 16e12c573d | |||
| 6ba7ab0d25 |
@@ -609,7 +609,6 @@ SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DESERIALIZE
|
||||
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
|
||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
|
||||
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
||||
|
||||
+1
-2
@@ -73,7 +73,7 @@ API_ARMOR = 0
|
||||
!IFNDEF NO_WARN
|
||||
!IF $(USE_FULLWARN)!=0
|
||||
NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206
|
||||
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4305 -wd4306 -wd4702 -wd4706
|
||||
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4244 -wd4305 -wd4306 -wd4702 -wd4706
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
@@ -351,7 +351,6 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
|
||||
!ENDIF
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
|
||||
|
||||
@@ -73,7 +73,7 @@ API_ARMOR = 0
|
||||
!IFNDEF NO_WARN
|
||||
!IF $(USE_FULLWARN)!=0
|
||||
NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206
|
||||
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4305 -wd4306 -wd4702 -wd4706
|
||||
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4244 -wd4305 -wd4306 -wd4702 -wd4706
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for sqlite 3.29.0.
|
||||
# Generated by GNU Autoconf 2.69 for sqlite 3.30.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.29.0'
|
||||
PACKAGE_STRING='sqlite 3.29.0'
|
||||
PACKAGE_VERSION='3.30.0'
|
||||
PACKAGE_STRING='sqlite 3.30.0'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -1466,7 +1466,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.29.0 to adapt to many kinds of systems.
|
||||
\`configure' configures sqlite 3.30.0 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1531,7 +1531,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of sqlite 3.29.0:";;
|
||||
short | recursive ) echo "Configuration of sqlite 3.30.0:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1657,7 +1657,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlite configure 3.29.0
|
||||
sqlite configure 3.30.0
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2076,7 +2076,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.29.0, which was
|
||||
It was created by sqlite $as_me 3.30.0, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -12232,7 +12232,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.29.0, which was
|
||||
This file was extended by sqlite $as_me 3.30.0, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -12298,7 +12298,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.29.0
|
||||
sqlite config.status 3.30.0
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
@@ -134,6 +134,7 @@ do_setup_rec_test $tn.5 {
|
||||
SEARCH TABLE t1 USING COVERING INDEX t1_idx_000123a7 (a=?)
|
||||
}
|
||||
|
||||
if 0 {
|
||||
do_setup_rec_test $tn.6 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
} {
|
||||
@@ -142,6 +143,7 @@ do_setup_rec_test $tn.6 {
|
||||
CREATE INDEX t1_idx_00000061 ON t1(a);
|
||||
SEARCH TABLE t1 USING COVERING INDEX t1_idx_00000061
|
||||
}
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.7 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
|
||||
@@ -433,10 +433,10 @@ static void fts3SnippetDetails(
|
||||
|
||||
while( iCsr<(iStart+pIter->nSnippet) && iCsr>=iStart ){
|
||||
int j;
|
||||
u64 mPhrase = (u64)1 << i;
|
||||
u64 mPhrase = (u64)1 << (i%64);
|
||||
u64 mPos = (u64)1 << (iCsr - iStart);
|
||||
assert( iCsr>=iStart && (iCsr - iStart)<=64 );
|
||||
assert( i>=0 && i<=64 );
|
||||
assert( i>=0 );
|
||||
if( (mCover|mCovered)&mPhrase ){
|
||||
iScore++;
|
||||
}else{
|
||||
|
||||
@@ -3941,6 +3941,7 @@ static int fts3AppendToNode(
|
||||
|
||||
nPrefix = fts3PrefixCompress(pPrev->a, pPrev->n, zTerm, nTerm);
|
||||
nSuffix = nTerm - nPrefix;
|
||||
if( nSuffix<=0 ) return FTS_CORRUPT_VTAB;
|
||||
memcpy(pPrev->a, zTerm, nTerm);
|
||||
pPrev->n = nTerm;
|
||||
|
||||
|
||||
@@ -178,6 +178,7 @@ struct Fts5Config {
|
||||
char *zContentExprlist;
|
||||
Fts5Tokenizer *pTok;
|
||||
fts5_tokenizer *pTokApi;
|
||||
int bLock; /* True when table is preparing statement */
|
||||
|
||||
/* Values loaded from the %_config table */
|
||||
int iCookie; /* Incremented when %_config is modified */
|
||||
|
||||
@@ -690,6 +690,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
|
||||
}else{
|
||||
/* TODO1: Fix this */
|
||||
pRet->p[nByte] = 0x00;
|
||||
pRet->p[nByte+1] = 0x00;
|
||||
pRet->szLeaf = fts5GetU16(&pRet->p[2]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,6 +536,13 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
|
||||
assert( SQLITE_INDEX_CONSTRAINT_GE<SQLITE_INDEX_CONSTRAINT_MATCH );
|
||||
assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH );
|
||||
|
||||
if( pConfig->bLock ){
|
||||
pTab->base.zErrMsg = sqlite3_mprintf(
|
||||
"recursively defined fts5 content table"
|
||||
);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
/* Set idxFlags flags for all WHERE clause terms that will be used. */
|
||||
for(i=0; i<pInfo->nConstraint; i++){
|
||||
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
|
||||
@@ -925,7 +932,7 @@ static int fts5CursorFirstSorted(
|
||||
**
|
||||
** If SQLite a built-in statement cache, this wouldn't be a problem. */
|
||||
rc = fts5PrepareStatement(&pSorter->pStmt, pConfig,
|
||||
"SELECT rowid, rank FROM %Q.%Q ORDER BY %s(%s%s%s) %s",
|
||||
"SELECT rowid, rank FROM %Q.%Q ORDER BY %s(\"%w\"%s%s) %s",
|
||||
pConfig->zDb, pConfig->zName, zRank, pConfig->zName,
|
||||
(zRankArgs ? ", " : ""),
|
||||
(zRankArgs ? zRankArgs : ""),
|
||||
|
||||
@@ -138,7 +138,9 @@ static int fts5StorageGetStmt(
|
||||
}else{
|
||||
int f = SQLITE_PREPARE_PERSISTENT;
|
||||
if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB;
|
||||
p->pConfig->bLock++;
|
||||
rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0);
|
||||
p->pConfig->bLock--;
|
||||
sqlite3_free(zSql);
|
||||
if( rc!=SQLITE_OK && pzErrMsg ){
|
||||
*pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
|
||||
|
||||
@@ -253,5 +253,20 @@ do_execsql_test 6.2 {
|
||||
SELECT name FROM sqlite_master;
|
||||
} {}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Check that an fts5 table cannot be its own content table.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 7.1 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(a, c=t1 );
|
||||
INSERT INTO t1( a ) VALUES('abc');
|
||||
}
|
||||
do_catchsql_test 7.2 {
|
||||
SELECT * FROM t1;
|
||||
} {1 {recursively defined fts5 content table}}
|
||||
do_catchsql_test 7.3 {
|
||||
SELECT * FROM t1('abc');
|
||||
} {1 {recursively defined fts5 content table}}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
+237
-31
@@ -767,7 +767,7 @@ SELECT * FROM t1 WHERE t1 MATCH 'abandon';
|
||||
|
||||
do_catchsql_test 13.1 {
|
||||
SELECT * FROM t1 WHERE t1 MATCH 'abandon';
|
||||
} {1 {vtable constructor failed: t1}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -958,7 +958,7 @@ do_test 15.0 {
|
||||
|
||||
do_catchsql_test 15.1 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check');
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
#
|
||||
@@ -3903,19 +3903,19 @@ do_test 33.0 {
|
||||
| end crash-fed6e90021ba5d.db
|
||||
}]} {}
|
||||
|
||||
do_execsql_test 33.1 {
|
||||
do_catchsql_test 33.1 {
|
||||
CREATE VIRTUAL TABLE t2 USING fts5vocab('t1','row');
|
||||
CREATE VIRTUAL TABLE t3 USING fts5vocab('t1','col');
|
||||
CREATE VIRTUAL TABLE t4 USING fts5vocab('t1','instance');
|
||||
}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
do_catchsql_test 33.2 {
|
||||
SELECT * FROM t2;
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
do_catchsql_test 33.3 {
|
||||
SELECT * FROM t2, t3, t4 WHERE t2.term=t3.term AND t3.term=t4.term;
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -4637,17 +4637,17 @@ do_test 37.0 {
|
||||
|
||||
do_catchsql_test 37.1 {
|
||||
SELECT * FROM t3;
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 37.0 {
|
||||
do_execsql_test 37a.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(b, c);
|
||||
INSERT INTO t1 VALUES('a', 'b');
|
||||
SELECT quote(block) FROM t1_data WHERE rowid=10;
|
||||
} {X'000000000101010001010101'}
|
||||
|
||||
do_execsql_test 37.1 {
|
||||
do_execsql_test 37a.1 {
|
||||
UPDATE t1_data SET block = X'FFFFFFFF0101010001010101' WHERE rowid = 10;
|
||||
SELECT rowid FROM t1('a');
|
||||
} {1}
|
||||
@@ -4894,7 +4894,7 @@ do_test 38.0 {
|
||||
|
||||
do_catchsql_test 38.1 {
|
||||
UPDATE t1 SET b=quote(zeroblob(200)) WHERE t1 MATCH 'thread*';
|
||||
} {0 {}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -5326,16 +5326,16 @@ do_test 40.0 {
|
||||
| end crash2.txt.db
|
||||
}]} {}
|
||||
|
||||
do_execsql_test 40.1 {
|
||||
do_catchsql_test 40.1 {
|
||||
BEGIN;
|
||||
INSERT INTO t1(b) VALUES(X'819192e578de3fa24af3733ca8769291a0fee3669f9fddefc5cba913e4225d4b6ce2b04f26b87fad3ee6f9b7d90a1ea62a169bf41e5d32707a6ca5c3d05e4bde05c9d89eaaa8c50e74333d2e9fcd7dfe95528a3a016aac1102d825c5cd70cf99d8a88e0ea7f798d4334386518b7ad359beb168b93aba059a2a3bd93112d65b44c12b9904ea786b204d80531cdf0504bf9b203dbe927061974caf7b9f30cbc3397b61f802e732012a6663d41c3607d6f1c0dbcfd489adac05ca500c0b04439d894cd93a840159225ef73b627e178b9f84b3ffe66cf22a963a8368813ff7961fc47f573211ccec95e0220dcbb3bf429f4a50ba54d7a53784ac51bf');
|
||||
INSERT INTO t1(b) VALUES(X'c8ae0d0e7c3175946e62ba2b449511d4eb504079984a20f77969f62206c9f3d7ea25358ab705e6978627290b6d48db9032f815a06a79a4f4b809841a0942eed12954ed166f666111812a508abc3bec87958846edaec0a6fe14564bc0a4b78f1c35ebcacca6bae29cc37ae9b59d8a2d7593af1e47dda0ece2268a98d20febafad037964f139851f9a57f48b3706b01721769071991412044cd6006f1d72eb6eb4aa5ad77e378176db8c15575fbeee47165e38a7c6c5a557ac2dfe11813976eaf6741cf593a9e457053a3c34cddfbe605a6e25419f993de8374fafcd3636509d8416a51dc7bcc14cfca322ae343078f47e23522431c17d0da0c033');
|
||||
INSERT INTO t1(b) VALUES(X'dc29a94e873a45a4243fce9b912aaefbadf1d0423e0345793874b356eeb500b92fb05284c1601fe9bad3143f72162f10242cec27c44ebf764c8fc9fb0824e32c4161472a4f914f579e0e8274f08ca1a02e59b9d8eec1f31061f9ccb9ed97a6f06534e991f7992c761489e6a7724f6e9c2b581e77487ded3a986d53c4419bbd3e9747cee300e670dd7294874c77e2ed48da68eaa6c3ec954a09ac410493d98e34d6686e54fbbe80696705f10e040c66093efb40746b33600685c94c664c7942835a9e954866121d5dcfb2cb12e92521ea3df175ee17072502dad9b9c1565f801b2179799011eb7418bfa00323e3157589e648ff7378be233c79b7');
|
||||
}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
do_catchsql_test 40.2 {
|
||||
INSERT INTO t1(a,b) VALUES(1,11),(2,22),(3, true ),(4,44);
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -5789,7 +5789,7 @@ do_test 43.0 {
|
||||
|
||||
do_catchsql_test 43.1 {
|
||||
INSERT INTO t1(t1) VALUES('optimize');
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -6047,7 +6047,7 @@ do_catchsql_test 45.2 {
|
||||
INSERT INTO t1(t1, rank) VALUES('merge', 5);
|
||||
INSERT INTO t1(t1, rank) VALUES('merge', 5);
|
||||
INSERT INTO t1(t1, rank) VALUES('merge', 5);
|
||||
} {0 {}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -6265,7 +6265,7 @@ do_test 46.0 {
|
||||
|
||||
do_catchsql_test 46.1 {
|
||||
SELECT snippet(t1,'[','', '--',-1,10) FROM t1('*');
|
||||
} {0 {{}}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -6418,7 +6418,7 @@ do_test 47.0 {
|
||||
|
||||
do_catchsql_test 47.1 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check');
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
do_catchsql_test 47.2 {
|
||||
SELECT count(*) FROM (
|
||||
@@ -6426,7 +6426,7 @@ do_catchsql_test 47.2 {
|
||||
highlight(t1, 2, '[', ']') FROM t1('g h')
|
||||
WHERE rank MATCH 'bm25(1.0, 1.0)' ORDER BY rank
|
||||
)
|
||||
} {0 3}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -7130,7 +7130,7 @@ do_test 52.0 {
|
||||
|
||||
do_catchsql_test 52.1 {
|
||||
SELECT fts5_decode(id, block) FROM t1_data;
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -7346,7 +7346,7 @@ do_test 53.0 {
|
||||
do_catchsql_test 53.1 {
|
||||
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x<>1 FROM c WHERE x<10)
|
||||
INSERT INTO t1(a) SELECT randomblob(3000) FROM c;
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -7562,7 +7562,7 @@ do_test 54.0 {
|
||||
|
||||
do_catchsql_test 54.1 {
|
||||
SELECT rowid==-1 FROM t1('t*');
|
||||
} {0 {0 0 0}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -7777,10 +7777,10 @@ do_test 55.0 {
|
||||
| end crash-b366b5ac0d3887.db
|
||||
}]} {}
|
||||
|
||||
do_execsql_test 55.1 {
|
||||
do_catchsql_test 55.1 {
|
||||
SAVEPOINT one;
|
||||
DELETE FROM t1 WHERE a MATCH 'ts';
|
||||
}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
do_execsql_test 55.2 {
|
||||
ROLLBACK TO one;
|
||||
@@ -8013,7 +8013,7 @@ do_test 56.1 {
|
||||
set res "1 {database disk image is malformed}"
|
||||
}
|
||||
set res
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -8131,7 +8131,7 @@ do_test 57.0 {
|
||||
|
||||
do_catchsql_test 57.1 {
|
||||
INSERT INTO t1(t1) VALUES('optimize')
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -8339,9 +8339,9 @@ do_test 58.0 {
|
||||
| end crash-5a5acd0ab42d31.db
|
||||
}]} {}
|
||||
|
||||
do_execsql_test 58.1 {
|
||||
do_catchsql_test 58.1 {
|
||||
SELECT * FROM t1('t*');
|
||||
} {{} {} {} {} {} {}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
do_test 59.0 {
|
||||
@@ -8948,13 +8948,13 @@ do_test 61.0 {
|
||||
| end crash-e5fa281edabddf.db
|
||||
}]} {}
|
||||
|
||||
do_execsql_test 61.1 {
|
||||
do_catchsql_test 61.1 {
|
||||
CREATE VIRTUAL TABLE t3 USING fts5vocab('t1'(),'col' );
|
||||
}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
do_catchsql_test 61.2 {
|
||||
SELECT * FROM t3 ORDER BY rowid;
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
breakpoint
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -9159,7 +9159,213 @@ do_test 62.0 {
|
||||
do_catchsql_test 62.1 {
|
||||
WITH c(x) AS (VALUES(false) UNION ALL SELECT x+1 FROM c WHERE x<72)
|
||||
INSERT INTO t1(a) SELECT randomblob(2829) FROM c;
|
||||
} {0 {}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
do_test 63.0 {
|
||||
sqlite3 db {}
|
||||
db deserialize [decode_hexdb {
|
||||
.open --hexdb
|
||||
| size 24576 pagesize 4096 filename crash-8230e6c3b368f5.db
|
||||
| page 1 offset 0
|
||||
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
|
||||
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
|
||||
| 96: 00 00 00 00 0d 00 00 00 06 0e 0f 00 0f aa 0f 53 ...............S
|
||||
| 112: 0e e8 0e 8b 0e 33 0e 0f 00 00 00 00 00 00 00 00 .....3..........
|
||||
| 3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 ................
|
||||
| 3600: 06 06 17 11 11 01 31 74 61 62 7c 65 62 63 62 62 ......1tab|ebcbb
|
||||
| 3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62 .CREATE TABLE bb
|
||||
| 3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65 (a)V.......table
|
||||
| 3648: 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 6f 6e 66 t1_configt1_conf
|
||||
| 3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 ig.CREATE TABLE
|
||||
| 3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52 't1_config'(k PR
|
||||
| 3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49 IMARY KEY, v) WI
|
||||
| 3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21 THOUT ROWID[...!
|
||||
| 3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 63 73 !...tablet1_docs
|
||||
| 3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52 izet1_docsize.CR
|
||||
| 3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 9d EATE TABLE 't1_.
|
||||
| 3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47 ocsize'(id INTEG
|
||||
| 3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
|
||||
| 3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81 sz BLOB)i.......
|
||||
| 3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69 -tablet1_idxt1_i
|
||||
| 3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 dx.CREATE TABLE
|
||||
| 3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20 't1_idx'(segid,
|
||||
| 3872: 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 52 49 4d term, pgno, PRIM
|
||||
| 3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74 ARY KEY(segid, t
|
||||
| 3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f erm)) WITHOUT RO
|
||||
| 3920: 57 49 44 55 02 07 17 1b 1b 01 81 01 74 61 62 6c WIDU........tabl
|
||||
| 3936: 65 64 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02 ed1_datat1_data.
|
||||
| 3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 CREATE TABLE 't1
|
||||
| 3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45 _data'(id INTEGE
|
||||
| 3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 R PRIMARY KEY, b
|
||||
| 4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 10 11 lock BLOB)T.....
|
||||
| 4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41 ...tablet1t1CREA
|
||||
| 4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 TE VIRTUAL TABLE
|
||||
| 4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61 t1 USING fts5(a
|
||||
| 4064: 2c 62 2c 70 72 65 66 69 78 3d 22 31 2c 32 2c 33 ,b,prefix=.1,2,3
|
||||
| 4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29 ,4., content=..)
|
||||
| page 2 offset 4096
|
||||
| 0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4 ..j.7.L....L....
|
||||
| 16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ad ...m.K.,........
|
||||
| 32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5 ...l.K.)........
|
||||
| 48: 0d 97 0d 76 0d 54 0d 31 0d 15 0c f3 0c d3 0c b5 ...v.T.1........
|
||||
| 64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0 ...s.T.2........
|
||||
| 80: 0b 8d 0b 7e 0b 48 0b 2e 0b 0b 0a ef 0a cc 0a ad ...~.H..........
|
||||
| 96: 0a 8c 0a 6d 0a 4d 0a 2b 0a 0c 09 ec 09 ca 09 a8 ...m.M.+........
|
||||
| 112: 09 86 09 63 0f f1 00 00 00 00 00 00 00 00 00 00 ...c............
|
||||
| 2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00 ................
|
||||
| 2384: 30 00 00 00 01 01 03 35 00 03 01 01 12 02 01 12 0......5........
|
||||
| 2400: 03 01 11 1c 8c 80 80 80 80 10 03 00 3e 00 00 00 ............>...
|
||||
| 2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68 ....4tabl.....wh
|
||||
| 2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c er.............<
|
||||
| 2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e .....4fts4.....n
|
||||
| 2464: 75 6d 62 03 06 01 04 09 1b 8c 80 80 80 80 0e 03 umb.............
|
||||
| 2480: 00 3c 00 00 00 16 04 33 74 68 65 13 06 01 01 04 .<.....3the.....
|
||||
| 2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80 ..whe...........
|
||||
| 2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01 ...<.....3num...
|
||||
| 2528: 01 05 01 03 75 61 62 03 02 03 04 0a 19 8c 80 80 ....uab.........
|
||||
| 2544: 80 80 0c 03 00 38 00 00 00 14 03 32 ec 68 03 02 .....8.....2.h..
|
||||
| 2560: 04 00 04 33 66 74 73 03 02 02 04 07 18 8c 80 80 ...3fts.........
|
||||
| 2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02 .....6.....2ta..
|
||||
| 2592: 03 02 01 68 03 06 01 01 04 04 17 1b 8c 80 80 80 ...h............
|
||||
| 2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01 ....<.....2nu...
|
||||
| 2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80 ....of..........
|
||||
| 2640: 80 80 80 09 03 00 38 00 00 00 14 03 32 66 74 03 ......8.....2ft.
|
||||
| 2656: 02 02 01 02 69 73 03 06 01 01 03 04 07 18 8c 80 ....is..........
|
||||
| 2672: 80 80 80 08 03 00 36 00 00 00 13 02 31 74 03 08 ......6.....1t..
|
||||
| 2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80 ......w.........
|
||||
| 2704: 80 80 07 03 00 3a 00 00 00 15 02 31 6e 03 08 01 .....:.....1n...
|
||||
| 2720: 01 02 05 01 01 6f 03 06 01 01 06 04 09 18 8c 80 .....o..........
|
||||
| 2736: 80 80 80 06 03 00 36 00 00 00 13 04 02 31 66 03 ......6......1f.
|
||||
| 2752: 02 02 01 01 69 03 06 01 01 03 05 06 1c 8c 80 80 ....i...........
|
||||
| 2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03 .....>.....0the.
|
||||
| 2784: 06 01 01 04 01 05 77 68 65 72 65 03 02 04 0a 15 ......where.....
|
||||
| 2800: 8c 80 80 80 80 04 03 00 30 00 00 00 11 01 01 06 ........0.......
|
||||
| 2816: 06 30 74 61 62 6c 65 03 02 03 07 1c 8c 80 80 80 .0table.........
|
||||
| 2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65 ....>.....0numbe
|
||||
| 2848: 72 03 06 01 01 05 01 02 6f 66 03 06 04 0d 13 8c r.......of......
|
||||
| 2864: 80 80 80 80 02 03 00 2c 00 00 00 0f 01 01 03 02 .......,........
|
||||
| 2880: 30 6e 03 06 01 01 02 07 1b 8c 80 80 80 80 01 03 0n..............
|
||||
| 2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03 .<.....0fts4aux.
|
||||
| 2912: 02 02 01 02 69 73 03 06 04 0c 00 00 00 14 2a 00 ....is........*.
|
||||
| 2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88 .....$..........
|
||||
| 2944: 80 80 80 80 12 03 00 16 00 00 00 05 02 1c 88 80 ................
|
||||
| 2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77 ......>.....4row
|
||||
| 2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b s.......ther....
|
||||
| 2992: 15 88 80 80 80 80 10 03 00 30 00 00 00 11 02 01 .........0......
|
||||
| 3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80 ...4betw........
|
||||
| 3024: 80 80 0f 03 00 3c 00 00 00 16 04 04 33 72 6f 77 .....<......3row
|
||||
| 3040: 02 06 01 01 05 01 03 74 68 64 02 08 05 0a 1b 88 .......thd......
|
||||
| 3056: 80 80 80 80 0e 03 00 3c 00 00 00 16 01 01 02 04 .......<........
|
||||
| 3072: 33 61 72 65 02 02 03 01 03 62 65 74 02 02 07 08 3are.....bet....
|
||||
| 3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 03 32 .........<.....2
|
||||
| 3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06 th........3and..
|
||||
| 3120: 04 0a 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16 ...........<....
|
||||
| 3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01 .2in.......ro...
|
||||
| 3152: 01 43 04 09 18 88 80 80 80 80 0b 03 00 36 00 00 .C...........6..
|
||||
| 3168: 00 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02 ....2ar.....be..
|
||||
| 3184: 04 05 07 1b 88 80 80 80 80 0a 03 00 3c 00 00 00 ............<...
|
||||
| 3200: 16 02 31 74 02 08 02 01 01 07 00 03 32 61 6e 02 ..1t........2an.
|
||||
| 3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00 ..............8.
|
||||
| 3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06 ....1n.......r..
|
||||
| 3248: 01 01 05 04 08 17 88 80 80 80 80 08 03 00 34 00 ..............4.
|
||||
| 3264: 00 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01 ....1b.....i....
|
||||
| 3280: 06 04 06 19 88 80 80 80 80 07 03 00 38 00 00 00 ............8...
|
||||
| 3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01 ...12.....a.....
|
||||
| 3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00 ............<...
|
||||
| 3328: 16 06 30 74 68 65 72 65 02 02 01 00 02 30 21 02 ..0there.....0!.
|
||||
| 3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00 ..............0.
|
||||
| 3360: 00 00 11 01 01 05 04 30 74 68 65 02 06 01 01 07 .......0the.....
|
||||
| 3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01 ..........>.....
|
||||
| 3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73 ...0n.......rows
|
||||
| 3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 51 .............<.Q
|
||||
| 3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02 ...0between.....
|
||||
| 3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a in.............:
|
||||
| 3456: 00 00 00 15 04 30 61 6e 64 02 06 01 01 02 02 02 .....0and.......
|
||||
| 3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00 re..............
|
||||
| 3488: 34 00 00 00 12 02 30 31 02 06 01 01 04 01 01 32 4.....01.......2
|
||||
| 3504: 02 02 05 04 08 08 84 80 80 80 80 12 03 00 16 00 ................
|
||||
| 3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00 .............<..
|
||||
| 3536: 00 16 05 34 74 51 62 6c 01 06 01 01 05 02 03 65 ...4tQbl.......e
|
||||
| 3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c rm.............<
|
||||
| 3568: 00 00 00 16 05 34 65 17 63 68 01 02 03 01 04 70 .....4e.ch.....p
|
||||
| 3584: 72 65 73 01 02 05 04 09 1a 84 80 80 80 80 0f 03 res.............
|
||||
| 3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02 .:.....3ter.....
|
||||
| 3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e he..............
|
||||
| 3632: 03 00 3c 00 00 00 16 04 33 70 72 65 01 02 05 01 ..<.....3pre....
|
||||
| 3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80 .tab............
|
||||
| 3664: 80 0d 03 00 3a 00 00 00 15 04 33 66 6f 72 01 03 ....:.....3for..
|
||||
| 3680: 02 02 02 74 73 01 06 01 01 04 04 08 1b 84 80 80 ...ts...........
|
||||
| 3696: 80 80 0c 03 00 3c 00 00 00 16 03 32 74 68 01 06 .....<.....2th..
|
||||
| 3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 84 .....3eac.......
|
||||
| 3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 .......6.....2ta
|
||||
| 3744: 01 06 01 01 05 02 01 65 01 02 04 04 09 19 84 80 .......e........
|
||||
| 3760: 80 80 80 0a 03 00 38 00 00 00 14 03 32 69 6e 01 ......8.....2in.
|
||||
| 3776: 06 01 01 02 01 02 70 72 01 02 05 04 09 18 84 80 ......pr........
|
||||
| 3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01 ......6.....2fo.
|
||||
| 3808: 02 02 02 01 74 01 06 01 01 04 04 07 1b 84 80 80 ....t...........
|
||||
| 3824: 80 80 08 03 00 3c 00 00 00 16 02 31 74 01 0a 04 .....<.....1t...
|
||||
| 3840: 01 01 03 04 00 03 32 65 61 01 02 03 04 0a 17 84 ......2ea.......
|
||||
| 3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01 .......4.....1i.
|
||||
| 3872: 06 01 01 02 01 01 70 01 02 05 04 08 18 84 80 80 ......p.........
|
||||
| 3888: 80 80 06 03 00 36 00 00 00 12 02 31 65 01 02 02 .....6.....1e...
|
||||
| 3904: 01 01 66 01 08 02 01 01 04 04 06 1b 84 80 80 80 ..f.............
|
||||
| 3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01 ....<.....0term.
|
||||
| 3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80 ....he..........
|
||||
| 3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 74 61 62 ............0tab
|
||||
| 3968: 6c 65 01 06 01 01 05 04 15 84 80 80 80 80 03 03 le..............
|
||||
| 3984: 00 30 00 00 00 11 02 08 30 70 72 65 73 65 6e 74 .0......0present
|
||||
| 4000: 01 02 05 05 1b 84 80 80 80 80 02 03 00 3c 00 00 .............<..
|
||||
| 4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e ...0fts.......in
|
||||
| 4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a ...............:
|
||||
| 4048: 00 00 00 15 05 30 65 61 63 68 01 02 03 01 03 66 .....0each.....f
|
||||
| 4064: 6f 72 01 02 01 f4 09 06 01 03 00 12 03 0b 0f 00 or..............
|
||||
| 4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04 ................
|
||||
| page 3 offset 8192
|
||||
| 0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1 ....2.O.........
|
||||
| 16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f b1 0f a9 0f a0 ................
|
||||
| 32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f .........x.q.h._
|
||||
| 48: 0f 56 0f 4d 0f 41 0f 38 0f 2f 0f 26 0f 1d 0f 13 .V.M.A.8./.&....
|
||||
| 64: 0f 0a 0f 01 0e f7 0e ee 0e e6 0e dd 0e d6 0e cd ................
|
||||
| 80: 0e c3 0e ba 0e b0 0e a8 0e 9f 0e 00 00 00 00 00 ................
|
||||
| 3648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................
|
||||
| 3664: 04 01 10 01 03 34 74 20 07 04 01 0e 01 03 34 1e .....4t ......4.
|
||||
| 3680: 09 04 01 12 01 03 33 74 68 1c 08 04 01 10 01 03 ......3th.......
|
||||
| 3696: 33 6e 1a 08 04 01 10 01 03 32 77 18 08 04 01 10 3n.......2w.....
|
||||
| 3712: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04 ..2t.......2n...
|
||||
| 3728: 01 0e 01 03 32 12 08 04 01 10 01 03 31 74 10 07 ....2.......1t..
|
||||
| 3744: f4 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 31 0c .....1n.......1.
|
||||
| 3760: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03 ......0th.......
|
||||
| 3776: 30 74 08 09 04 01 12 01 03 30 6e 75 06 08 04 01 0t.......0nu....
|
||||
| 3792: 10 01 03 30 6e 04 06 04 01 0c 01 03 02 08 04 01 ...0n...........
|
||||
| 3808: 10 01 02 34 73 22 07 04 01 0e 01 02 34 20 08 04 ...4s.......4 ..
|
||||
| 3824: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72 ....3r.......3ar
|
||||
| 3840: 1c 08 04 01 10 01 02 32 74 1a 08 04 01 10 01 02 .......2t.......
|
||||
| 3856: 32 69 18 09 04 01 12 01 02 32 61 72 16 08 04 01 2i.......2ar....
|
||||
| 3872: 10 01 02 31 74 14 08 04 01 10 01 02 31 6e 12 08 ...1t.......1n..
|
||||
| 3888: 04 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32 .....1b.......12
|
||||
| 3904: 0e 0b 04 01 16 01 02 30 74 00 00 00 00 00 00 00 .......0t.......
|
||||
| page 4 offset 12288
|
||||
| 4064: 00 00 00 00 00 00 00 00 00 00 00 05 02 03 00 10 ................
|
||||
| 4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04 ................
|
||||
| page 5 offset 16384
|
||||
| 0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00 ................
|
||||
| 4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70 ...............p
|
||||
| 4080: 67 73 7a 08 0b 03 1b 01 76 65 72 73 69 6f 6e 04 gsz.....version.
|
||||
| end crash-8230e6c3b368f5.db
|
||||
}]} {}
|
||||
|
||||
do_catchsql_test 63.1 {
|
||||
SELECT * FROM t1 WHERE b MATCH 'thead*thead*theSt*';
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
do_catchsql_test 63.2 {
|
||||
INSERT INTO t1(t1) VALUES('optimize');
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
do_catchsql_test 63.3 {
|
||||
SELECT * FROM t1 WHERE b MATCH 'thead*thead*theSt*';
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
sqlite3_fts5_may_be_corrupt 0
|
||||
finish_test
|
||||
|
||||
@@ -162,4 +162,22 @@ do_execsql_test 5.1 {
|
||||
SELECT rowid FROM ttt('word') WHERE rowid BETWEEN 30 AND 40 ORDER BY rank;
|
||||
} {30 31 32 33 34 35 36 37 38 39 40}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 6.0 {
|
||||
CREATE VIRTUAL TABLE "My.Table" USING fts5(Text);
|
||||
|
||||
INSERT INTO "My.Table" VALUES ('hello this is a test');
|
||||
INSERT INTO "My.Table" VALUES ('of trying to order by');
|
||||
INSERT INTO "My.Table" VALUES ('rank on an fts5 table');
|
||||
INSERT INTO "My.Table" VALUES ('that have periods in');
|
||||
INSERT INTO "My.Table" VALUES ('the table names.');
|
||||
INSERT INTO "My.Table" VALUES ('table table table');
|
||||
}
|
||||
do_execsql_test 6.1 {
|
||||
SELECT * FROM "My.Table" WHERE Text MATCH 'table' ORDER BY rank;
|
||||
} {
|
||||
{table table table} {the table names.} {rank on an fts5 table}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
+2
-2
@@ -43,10 +43,10 @@ LSMTESTSRC = $(LSMDIR)/lsm-test/lsmtest1.c $(LSMDIR)/lsm-test/lsmtest2.c \
|
||||
|
||||
# all: lsm.so
|
||||
|
||||
LSMOPTS += -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR) -DHAVE_ZLIB
|
||||
LSMOPTS += -fPIC -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR) -DHAVE_ZLIB
|
||||
|
||||
lsm.so: $(LSMOBJ)
|
||||
$(TCCX) -shared -o lsm.so $(LSMOBJ)
|
||||
$(TCCX) -shared -fPIC -o lsm.so $(LSMOBJ)
|
||||
|
||||
%.o: $(LSMDIR)/%.c $(LSMHDR) sqlite3.h
|
||||
$(TCCX) $(LSMOPTS) -c $<
|
||||
|
||||
+1
-1
@@ -842,7 +842,7 @@ static int lsm1BestIndex(
|
||||
|
||||
const struct sqlite3_index_constraint *pConstraint;
|
||||
pConstraint = pIdxInfo->aConstraint;
|
||||
for(i=0; i<pIdxInfo->nConstraint && idxNum<16; i++, pConstraint++){
|
||||
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
|
||||
if( pConstraint->usable==0 ) continue;
|
||||
if( pConstraint->iColumn!=0 ) continue;
|
||||
switch( pConstraint->op ){
|
||||
|
||||
@@ -88,6 +88,65 @@ do_execsql_test 210 {
|
||||
do_execsql_test 211 {
|
||||
SELECT quote(a), quote(lsm1_key), quote(lsm1_value), '|' FROM x1;
|
||||
} {'12' X'3132' X'05320000000000000A401FFB42ABE9DB' | '15' X'3135' X'4284C6' | '8' X'38' X'2162616E6A6F1633323105' |}
|
||||
do_execsql_test 212 {
|
||||
SELECT quote(a), quote(lsm1_key), quote(lsm1_value) FROM x1 WHERE a='12';
|
||||
} {'12' X'3132' X'05320000000000000A401FFB42ABE9DB'}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
forcedelete testlsm.db
|
||||
load_lsm1_vtab db
|
||||
do_execsql_test 300 {
|
||||
CREATE VIRTUAL TABLE x1 USING lsm1(testlsm.db,a,TEXT,b,c,d);
|
||||
}
|
||||
do_eqp_test 310 {
|
||||
SELECT * FROM x1 WHERE a=?
|
||||
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 0:}
|
||||
|
||||
do_eqp_test 320 {
|
||||
SELECT * FROM x1 WHERE a>?
|
||||
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 2:}
|
||||
|
||||
do_eqp_test 330 {
|
||||
SELECT * FROM x1 WHERE a<?
|
||||
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 3:}
|
||||
do_eqp_test 340 {
|
||||
SELECT * FROM x1 WHERE a BETWEEN ? AND ?
|
||||
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 1:}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
forcedelete testlsm.db
|
||||
load_lsm1_vtab db
|
||||
do_execsql_test 400 {
|
||||
CREATE VIRTUAL TABLE x1 USING lsm1(testlsm.db,a,TEXT,b);
|
||||
INSERT INTO x1 VALUES('one', 1);
|
||||
INSERT INTO x1 VALUES('two', 2);
|
||||
INSERT INTO x1 VALUES('three', 3);
|
||||
INSERT INTO x1 VALUES('four', 4);
|
||||
INSERT INTO x1 VALUES('five', 5);
|
||||
}
|
||||
do_execsql_test 410 {
|
||||
SELECT b FROM x1 WHERE a = 'two'
|
||||
} {2}
|
||||
do_execsql_test 411 {
|
||||
SELECT b FROM x1 WHERE a = 'one'
|
||||
} {1}
|
||||
do_execsql_test 412 {
|
||||
SELECT b FROM x1 WHERE a = 'five'
|
||||
} {5}
|
||||
|
||||
do_execsql_test 420 {
|
||||
SELECT b FROM x1 WHERE a BETWEEN 'one' AND 'three';
|
||||
} {1 3}
|
||||
do_execsql_test 421 {
|
||||
SELECT b FROM x1 WHERE a BETWEEN 'five' AND 'two';
|
||||
} {5 4 1 3 2}
|
||||
do_execsql_test 421 {
|
||||
SELECT b FROM x1 WHERE a > 'five';
|
||||
} {4 1 3 2}
|
||||
do_execsql_test 421 {
|
||||
SELECT b FROM x1 WHERE a <= 'three';
|
||||
} {3 1 4 5}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
|
||||
#ifndef SQLITE_AMALGAMATION
|
||||
/*
|
||||
** The "u32" type must be an unsigned 32-bit integer. Adjust this
|
||||
*/
|
||||
@@ -47,6 +48,8 @@ typedef unsigned int u32;
|
||||
typedef short int s16;
|
||||
typedef unsigned short int u16;
|
||||
|
||||
#endif /* SQLITE_AMALGAMATION */
|
||||
|
||||
|
||||
/*
|
||||
** The width of a hash window in bytes. The algorithm only works if this
|
||||
|
||||
@@ -1083,6 +1083,7 @@ static JsonNode *jsonLookupStep(
|
||||
const char *zKey;
|
||||
JsonNode *pRoot = &pParse->aNode[iRoot];
|
||||
if( zPath[0]==0 ) return pRoot;
|
||||
if( pRoot->jnFlags & JNODE_REPLACE ) return 0;
|
||||
if( zPath[0]=='.' ){
|
||||
if( pRoot->eType!=JSON_OBJECT ) return 0;
|
||||
zPath++;
|
||||
|
||||
+2
-2
@@ -610,7 +610,7 @@ static const char *re_subcompile_string(ReCompiled *p){
|
||||
** regular expression. Applications should invoke this routine once
|
||||
** for every call to re_compile() to avoid memory leaks.
|
||||
*/
|
||||
void re_free(ReCompiled *pRe){
|
||||
static void re_free(ReCompiled *pRe){
|
||||
if( pRe ){
|
||||
sqlite3_free(pRe->aOp);
|
||||
sqlite3_free(pRe->aArg);
|
||||
@@ -624,7 +624,7 @@ void re_free(ReCompiled *pRe){
|
||||
** compiled regular expression in *ppRe. Return NULL on success or an
|
||||
** error message if something goes wrong.
|
||||
*/
|
||||
const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
|
||||
static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
|
||||
ReCompiled *pRe;
|
||||
const char *zErr;
|
||||
int i, j;
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
# 2014 August 30
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] rbu_common.tcl]
|
||||
set ::testprefix rbuexpr
|
||||
|
||||
db close
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_uri 1
|
||||
|
||||
sqlite3 db test.db
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b, c PRIMARY KEY);
|
||||
CREATE INDEX i1 ON t1(a, null, b+1);
|
||||
CREATE INDEX i2 ON t1(a+1, b+1, c+1);
|
||||
|
||||
INSERT INTO t1 VALUES(1, 2, 3);
|
||||
INSERT INTO t1 VALUES(4, 5, 6);
|
||||
INSERT INTO t1 VALUES(7, 8, 9);
|
||||
INSERT INTO t1 VALUES(10, 11, 12);
|
||||
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
|
||||
forcedelete rbu.db
|
||||
sqlite3 db2 rbu.db
|
||||
do_execsql_test -db db2 1.1 {
|
||||
CREATE TABLE data_t1(a, b, c, rbu_control);
|
||||
INSERT INTO data_t1 VALUES(13, 14, 15, 0);
|
||||
INSERT INTO data_t1 VALUES(NULL, NULL, 6, 1);
|
||||
INSERT INTO data_t1 VALUES(NULL, 'three', 3, '.x.');
|
||||
}
|
||||
db2 close
|
||||
db close
|
||||
|
||||
do_test 1.2 {
|
||||
run_rbu test.db rbu.db
|
||||
} {SQLITE_DONE}
|
||||
|
||||
sqlite3 db test.db
|
||||
|
||||
do_execsql_test 1.3 {
|
||||
SELECT * FROM t1 WHERE a=4;
|
||||
}
|
||||
|
||||
integrity_check 1.4
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE t1(c1, c2, c3, i INTEGER PRIMARY KEY);
|
||||
INSERT INTO t1 VALUES('one', 'one', 'one', 1);
|
||||
INSERT INTO t1 VALUES('two', 'two', 'two', 2);
|
||||
INSERT INTO t1 VALUES('three', 'three', 'three', 3);
|
||||
INSERT INTO t1 VALUES('four', 'four', 'four', 4);
|
||||
|
||||
CREATE INDEX i1 ON t1( substr(c1, 1, 2) );
|
||||
CREATE INDEX i2 ON t1( c1 || c2 || c3 );
|
||||
CREATE INDEX i3 ON t1( length(c1) + length(c2) - 1, c3||i );
|
||||
}
|
||||
|
||||
forcedelete rbu.db
|
||||
sqlite3 db2 rbu.db
|
||||
do_execsql_test -db db2 2.1 {
|
||||
CREATE TABLE data_t1(c1, c2, c3, i, rbu_control);
|
||||
INSERT INTO data_t1 VALUES(NULL, NULL, NULL, 2, 1);
|
||||
INSERT INTO data_t1 VALUES('thirty', NULL, NULL, 3, 'xx..');
|
||||
INSERT INTO data_t1 VALUES('five', 'five', 'five', 5, 0);
|
||||
}
|
||||
db2 close
|
||||
|
||||
db close
|
||||
|
||||
do_test 2.2 {
|
||||
run_rbu test.db rbu.db
|
||||
} {SQLITE_DONE}
|
||||
|
||||
sqlite3 db test.db
|
||||
integrity_check 2.3
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -40,6 +40,15 @@ foreach {tn without_rowid a b c d} {
|
||||
CREATE INDEX i1c3 ON t1(%C%) WHERE %C% IS NOT NULL;
|
||||
|
||||
CREATE INDEX i1c4 ON t1(%C%) WHERE %D% < 'd';
|
||||
CREATE INDEX i1c5 ON t1(
|
||||
%C% -- for (c = ... expressions
|
||||
) WHERE %D% < 'd';
|
||||
CREATE INDEX i1c6 ON t1(
|
||||
%C% /* Again, for (c=... expr */, %D%
|
||||
) WHERE %D% < 'd';
|
||||
|
||||
CREATE INDEX i1c7 ON t1(
|
||||
%C% /* As before, for (c=... "expr */) WHERE %D% < 'd';
|
||||
}
|
||||
|
||||
do_execsql_test $tn.1.1 {
|
||||
|
||||
@@ -414,5 +414,37 @@ foreach {bReopen} { 0 1 } {
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that sqlite3_bp_progress() works with an RBU vacuum if there
|
||||
# is an rbu_count table in the db being vacuumed.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 6.0 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
CREATE INDEX i1 ON t1(a);
|
||||
CREATE INDEX i2 ON t1(b);
|
||||
WITH s(i) AS (
|
||||
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100
|
||||
)
|
||||
INSERT INTO t1 SELECT i, i, i FROM s;
|
||||
CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID;
|
||||
INSERT INTO rbu_count VALUES('t1', (SELECT count(*) FROM t1));
|
||||
INSERT INTO rbu_count VALUES('rbu_count', 2);
|
||||
}
|
||||
|
||||
forcedelete state.db
|
||||
do_test 6.1 {
|
||||
set maxA 0
|
||||
set maxB 0
|
||||
sqlite3rbu_vacuum rbu test.db state.db
|
||||
while {[rbu step]=="SQLITE_OK"} {
|
||||
foreach {a b} [rbu bp_progress] {
|
||||
if {$a > $maxA} { set maxA $a }
|
||||
if {$b > $maxB} { set maxB $b }
|
||||
}
|
||||
}
|
||||
list [rbu close] $maxA $maxB
|
||||
} {SQLITE_DONE 10000 10000}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+97
-31
@@ -182,6 +182,7 @@
|
||||
typedef struct RbuFrame RbuFrame;
|
||||
typedef struct RbuObjIter RbuObjIter;
|
||||
typedef struct RbuState RbuState;
|
||||
typedef struct RbuSpan RbuSpan;
|
||||
typedef struct rbu_vfs rbu_vfs;
|
||||
typedef struct rbu_file rbu_file;
|
||||
typedef struct RbuUpdateStmt RbuUpdateStmt;
|
||||
@@ -226,6 +227,11 @@ struct RbuUpdateStmt {
|
||||
RbuUpdateStmt *pNext;
|
||||
};
|
||||
|
||||
struct RbuSpan {
|
||||
const char *zSpan;
|
||||
int nSpan;
|
||||
};
|
||||
|
||||
/*
|
||||
** An iterator of this type is used to iterate through all objects in
|
||||
** the target database that require updating. For each such table, the
|
||||
@@ -275,6 +281,9 @@ struct RbuObjIter {
|
||||
sqlite3_stmt *pInsert; /* Statement for INSERT operations */
|
||||
sqlite3_stmt *pDelete; /* Statement for DELETE ops */
|
||||
sqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zDataTbl */
|
||||
int nIdxCol;
|
||||
RbuSpan *aIdxCol;
|
||||
char *zIdxSql;
|
||||
|
||||
/* Last UPDATE used (for PK b-tree updates only), or NULL. */
|
||||
RbuUpdateStmt *pRbuUpdate;
|
||||
@@ -809,6 +818,8 @@ static void rbuObjIterClearStatements(RbuObjIter *pIter){
|
||||
sqlite3_free(pUp);
|
||||
pUp = pTmp;
|
||||
}
|
||||
sqlite3_free(pIter->aIdxCol);
|
||||
sqlite3_free(pIter->zIdxSql);
|
||||
|
||||
pIter->pSelect = 0;
|
||||
pIter->pInsert = 0;
|
||||
@@ -816,6 +827,9 @@ static void rbuObjIterClearStatements(RbuObjIter *pIter){
|
||||
pIter->pRbuUpdate = 0;
|
||||
pIter->pTmpInsert = 0;
|
||||
pIter->nCol = 0;
|
||||
pIter->nIdxCol = 0;
|
||||
pIter->aIdxCol = 0;
|
||||
pIter->zIdxSql = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -930,8 +944,8 @@ static void rbuTargetNameFunc(
|
||||
zIn = (const char*)sqlite3_value_text(argv[0]);
|
||||
if( zIn ){
|
||||
if( rbuIsVacuum(p) ){
|
||||
assert( argc==2 );
|
||||
if( 0==sqlite3_value_int(argv[1]) ){
|
||||
assert( argc==2 || argc==1 );
|
||||
if( argc==1 || 0==sqlite3_value_int(argv[1]) ){
|
||||
sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC);
|
||||
}
|
||||
}else{
|
||||
@@ -1089,14 +1103,15 @@ static void rbuAllocateIterArrays(sqlite3rbu *p, RbuObjIter *pIter, int nCol){
|
||||
static char *rbuStrndup(const char *zStr, int *pRc){
|
||||
char *zRet = 0;
|
||||
|
||||
assert( *pRc==SQLITE_OK );
|
||||
if( zStr ){
|
||||
size_t nCopy = strlen(zStr) + 1;
|
||||
zRet = (char*)sqlite3_malloc64(nCopy);
|
||||
if( zRet ){
|
||||
memcpy(zRet, zStr, nCopy);
|
||||
}else{
|
||||
*pRc = SQLITE_NOMEM;
|
||||
if( *pRc==SQLITE_OK ){
|
||||
if( zStr ){
|
||||
size_t nCopy = strlen(zStr) + 1;
|
||||
zRet = (char*)sqlite3_malloc64(nCopy);
|
||||
if( zRet ){
|
||||
memcpy(zRet, zStr, nCopy);
|
||||
}else{
|
||||
*pRc = SQLITE_NOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1268,6 +1283,9 @@ static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){
|
||||
while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
|
||||
int iCid = sqlite3_column_int(pXInfo, 1);
|
||||
if( iCid>=0 ) pIter->abIndexed[iCid] = 1;
|
||||
if( iCid==-2 ){
|
||||
memset(pIter->abIndexed, 0x01, sizeof(u8)*pIter->nTblCol);
|
||||
}
|
||||
}
|
||||
rbuFinalize(p, pXInfo);
|
||||
bIndex = 1;
|
||||
@@ -1679,29 +1697,37 @@ static char *rbuObjIterGetIndexCols(
|
||||
int iCid = sqlite3_column_int(pXInfo, 1);
|
||||
int bDesc = sqlite3_column_int(pXInfo, 3);
|
||||
const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
|
||||
const char *zCol;
|
||||
const char *zCol = 0;
|
||||
const char *zType;
|
||||
|
||||
if( iCid<0 ){
|
||||
/* An integer primary key. If the table has an explicit IPK, use
|
||||
** its name. Otherwise, use "rbu_rowid". */
|
||||
if( pIter->eType==RBU_PK_IPK ){
|
||||
int i;
|
||||
for(i=0; pIter->abTblPk[i]==0; i++);
|
||||
assert( i<pIter->nTblCol );
|
||||
zCol = pIter->azTblCol[i];
|
||||
}else if( rbuIsVacuum(p) ){
|
||||
zCol = "_rowid_";
|
||||
if( iCid==-2 ){
|
||||
int iSeq = sqlite3_column_int(pXInfo, 0);
|
||||
zRet = sqlite3_mprintf("%z%s(%.*s) COLLATE %Q", zRet, zCom,
|
||||
pIter->aIdxCol[iSeq].nSpan, pIter->aIdxCol[iSeq].zSpan, zCollate
|
||||
);
|
||||
zType = "";
|
||||
}else {
|
||||
if( iCid<0 ){
|
||||
/* An integer primary key. If the table has an explicit IPK, use
|
||||
** its name. Otherwise, use "rbu_rowid". */
|
||||
if( pIter->eType==RBU_PK_IPK ){
|
||||
int i;
|
||||
for(i=0; pIter->abTblPk[i]==0; i++);
|
||||
assert( i<pIter->nTblCol );
|
||||
zCol = pIter->azTblCol[i];
|
||||
}else if( rbuIsVacuum(p) ){
|
||||
zCol = "_rowid_";
|
||||
}else{
|
||||
zCol = "rbu_rowid";
|
||||
}
|
||||
zType = "INTEGER";
|
||||
}else{
|
||||
zCol = "rbu_rowid";
|
||||
zCol = pIter->azTblCol[iCid];
|
||||
zType = pIter->azTblType[iCid];
|
||||
}
|
||||
zType = "INTEGER";
|
||||
}else{
|
||||
zCol = pIter->azTblCol[iCid];
|
||||
zType = pIter->azTblType[iCid];
|
||||
zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom,zCol,zCollate);
|
||||
}
|
||||
|
||||
zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom, zCol, zCollate);
|
||||
if( pIter->bUnique==0 || sqlite3_column_int(pXInfo, 5) ){
|
||||
const char *zOrder = (bDesc ? " DESC" : "");
|
||||
zImpPK = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\"%s",
|
||||
@@ -2181,6 +2207,8 @@ static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){
|
||||
int rc = p->rc;
|
||||
char *zRet = 0;
|
||||
|
||||
assert( pIter->zIdxSql==0 && pIter->nIdxCol==0 && pIter->aIdxCol==0 );
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg,
|
||||
"SELECT trim(sql) FROM sqlite_master WHERE type='index' AND name=?"
|
||||
@@ -2190,21 +2218,50 @@ static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){
|
||||
int rc2;
|
||||
rc = sqlite3_bind_text(pStmt, 1, pIter->zIdx, -1, SQLITE_STATIC);
|
||||
if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||
const char *zSql = (const char*)sqlite3_column_text(pStmt, 0);
|
||||
char *zSql = (char*)sqlite3_column_text(pStmt, 0);
|
||||
if( zSql ){
|
||||
pIter->zIdxSql = zSql = rbuStrndup(zSql, &rc);
|
||||
}
|
||||
if( zSql ){
|
||||
int nParen = 0; /* Number of open parenthesis */
|
||||
int i;
|
||||
int iIdxCol = 0;
|
||||
int nIdxAlloc = 0;
|
||||
for(i=0; zSql[i]; i++){
|
||||
char c = zSql[i];
|
||||
|
||||
/* If necessary, grow the pIter->aIdxCol[] array */
|
||||
if( iIdxCol==nIdxAlloc ){
|
||||
RbuSpan *aIdxCol = (RbuSpan*)sqlite3_realloc(
|
||||
pIter->aIdxCol, (nIdxAlloc+16)*sizeof(RbuSpan)
|
||||
);
|
||||
if( aIdxCol==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
break;
|
||||
}
|
||||
pIter->aIdxCol = aIdxCol;
|
||||
nIdxAlloc += 16;
|
||||
}
|
||||
|
||||
if( c=='(' ){
|
||||
if( nParen==0 ){
|
||||
assert( iIdxCol==0 );
|
||||
pIter->aIdxCol[0].zSpan = &zSql[i+1];
|
||||
}
|
||||
nParen++;
|
||||
}
|
||||
else if( c==')' ){
|
||||
nParen--;
|
||||
if( nParen==0 ){
|
||||
int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan;
|
||||
pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}else if( c==',' && nParen==1 ){
|
||||
int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan;
|
||||
pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
|
||||
pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1];
|
||||
}else if( c=='"' || c=='\'' || c=='`' ){
|
||||
for(i++; 1; i++){
|
||||
if( zSql[i]==c ){
|
||||
@@ -2216,11 +2273,19 @@ static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){
|
||||
for(i++; 1; i++){
|
||||
if( zSql[i]==']' ) break;
|
||||
}
|
||||
}else if( c=='-' && zSql[i+1]=='-' ){
|
||||
for(i=i+2; zSql[i] && zSql[i]!='\n'; i++);
|
||||
if( zSql[i]=='\0' ) break;
|
||||
}else if( c=='/' && zSql[i+1]=='*' ){
|
||||
for(i=i+2; zSql[i] && (zSql[i]!='*' || zSql[i+1]!='/'); i++);
|
||||
if( zSql[i]=='\0' ) break;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if( zSql[i] ){
|
||||
zRet = rbuStrndup(&zSql[i], &rc);
|
||||
}
|
||||
pIter->nIdxCol = iIdxCol;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2265,11 +2330,11 @@ static int rbuObjIterPrepareAll(
|
||||
int nBind = 0;
|
||||
|
||||
assert( pIter->eType!=RBU_PK_VTAB );
|
||||
zPart = rbuObjIterGetIndexWhere(p, pIter);
|
||||
zCollist = rbuObjIterGetIndexCols(
|
||||
p, pIter, &zImposterCols, &zImposterPK, &zWhere, &nBind
|
||||
);
|
||||
zBind = rbuObjIterGetBindlist(p, nBind);
|
||||
zPart = rbuObjIterGetIndexWhere(p, pIter);
|
||||
|
||||
/* Create the imposter table used to write to this index. */
|
||||
sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1);
|
||||
@@ -3795,10 +3860,11 @@ static void rbuIndexCntFunc(
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
char *zErrmsg = 0;
|
||||
int rc;
|
||||
sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);
|
||||
|
||||
assert( nVal==1 );
|
||||
|
||||
rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &zErrmsg,
|
||||
rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg,
|
||||
sqlite3_mprintf("SELECT count(*) FROM sqlite_master "
|
||||
"WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0]))
|
||||
);
|
||||
@@ -3813,7 +3879,7 @@ static void rbuIndexCntFunc(
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_result_int(pCtx, nIndex);
|
||||
}else{
|
||||
sqlite3_result_error(pCtx, sqlite3_errmsg(p->dbMain), -1);
|
||||
sqlite3_result_error(pCtx, sqlite3_errmsg(db), -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+17
-4
@@ -669,7 +669,6 @@ static int nodeAcquire(
|
||||
** increase its reference count and return it.
|
||||
*/
|
||||
if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){
|
||||
assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
|
||||
if( pParent && !pNode->pParent ){
|
||||
if( nodeInParentChain(pNode, pParent) ){
|
||||
RTREE_IS_CORRUPT(pRtree);
|
||||
@@ -677,6 +676,9 @@ static int nodeAcquire(
|
||||
}
|
||||
pParent->nRef++;
|
||||
pNode->pParent = pParent;
|
||||
}else if( pParent && pNode->pParent && pParent!=pNode->pParent ){
|
||||
RTREE_IS_CORRUPT(pRtree);
|
||||
return SQLITE_CORRUPT_VTAB;
|
||||
}
|
||||
pNode->nRef++;
|
||||
*ppNode = pNode;
|
||||
@@ -1564,13 +1566,14 @@ static int rtreeStepToLeaf(RtreeCursor *pCur){
|
||||
|
||||
eInt = pRtree->eCoordType==RTREE_COORD_INT32;
|
||||
while( (p = rtreeSearchPointFirst(pCur))!=0 && p->iLevel>0 ){
|
||||
u8 *pCellData;
|
||||
pNode = rtreeNodeOfFirstSearchPoint(pCur, &rc);
|
||||
if( rc ) return rc;
|
||||
nCell = NCELL(pNode);
|
||||
assert( nCell<200 );
|
||||
pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell);
|
||||
while( p->iCell<nCell ){
|
||||
sqlite3_rtree_dbl rScore = (sqlite3_rtree_dbl)-1;
|
||||
u8 *pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell);
|
||||
eWithin = FULLY_WITHIN;
|
||||
for(ii=0; ii<nConstraint; ii++){
|
||||
RtreeConstraint *pConstraint = pCur->aConstraint + ii;
|
||||
@@ -1583,13 +1586,23 @@ static int rtreeStepToLeaf(RtreeCursor *pCur){
|
||||
}else{
|
||||
rtreeNonleafConstraint(pConstraint, eInt, pCellData, &eWithin);
|
||||
}
|
||||
if( eWithin==NOT_WITHIN ) break;
|
||||
if( eWithin==NOT_WITHIN ){
|
||||
p->iCell++;
|
||||
pCellData += pRtree->nBytesPerCell;
|
||||
break;
|
||||
}
|
||||
}
|
||||
p->iCell++;
|
||||
if( eWithin==NOT_WITHIN ) continue;
|
||||
p->iCell++;
|
||||
x.iLevel = p->iLevel - 1;
|
||||
if( x.iLevel ){
|
||||
x.id = readInt64(pCellData);
|
||||
for(ii=0; ii<pCur->nPoint; ii++){
|
||||
if( pCur->aPoint[ii].id==x.id ){
|
||||
RTREE_IS_CORRUPT(pRtree);
|
||||
return SQLITE_CORRUPT_VTAB;
|
||||
}
|
||||
}
|
||||
x.iCell = 0;
|
||||
}else{
|
||||
x.id = p->id;
|
||||
|
||||
@@ -465,6 +465,7 @@ do_test rtreefuzz001-100 {
|
||||
| end c1b.db
|
||||
}]
|
||||
catchsql {
|
||||
PRAGMA writable_schema = 1;
|
||||
SELECT rtreecheck('t1');
|
||||
}
|
||||
} {1 {SQL logic error}}
|
||||
@@ -774,4 +775,275 @@ do_test rtreefuzz001-400 {
|
||||
}
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_test rtreefuzz001-500 {
|
||||
sqlite3 db {}
|
||||
db deserialize [decode_hexdb {
|
||||
| size 16384 pagesize 4096 filename crash-2e81f5dce5cbd4.db
|
||||
| page 1 offset 0
|
||||
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
|
||||
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
|
||||
| 96: 00 00 00 00 0d 00 00 00 05 0e 6d 00 0f c8 0f 7b ..........m.....
|
||||
| 112: 0f 20 0e cd 0e 6d 00 00 00 00 00 00 00 00 00 00 . ...m..........
|
||||
| 3680: 00 00 00 00 00 00 00 00 00 00 00 00 00 5e 05 07 .............^..
|
||||
| 3696: 17 1f 1f 01 81 0b 74 61 62 6c 65 74 31 5f 70 61 ......tablet1_pa
|
||||
| 3712: 72 65 6e 74 74 31 5f 70 61 72 65 6e 74 05 43 52 rentt1_parent.CR
|
||||
| 3728: 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 70 EATE TABLE .t1_p
|
||||
| 3744: 61 72 65 6e 74 22 28 6e 6f 64 65 6e 6f 20 49 4e arent.(nodeno IN
|
||||
| 3760: 54 45 47 45 42 20 50 52 49 4d 41 52 59 20 4b 45 TEGEB PRIMARY KE
|
||||
| 3776: 59 2c 70 61 72 65 6e 74 6e 6f 64 65 29 51 04 06 Y,parentnode)Q..
|
||||
| 3792: 17 1b 1b 01 7b 74 61 62 6c 65 74 31 5f 6e 6f 64 .....tablet1_nod
|
||||
| 3808: 65 74 31 5f 6e 6f 64 65 04 43 52 45 41 54 45 20 et1_node.CREATE
|
||||
| 3824: 54 41 42 4c 45 20 22 74 31 5f 6e 6f 64 65 22 28 TABLE .t1_node.(
|
||||
| 3840: 6e 6f 64 65 6e 6f 20 49 4e 54 45 47 45 52 20 50 nodeno INTEGER P
|
||||
| 3856: 52 49 4d 41 52 59 20 4b 45 59 2c 64 61 74 61 29 RIMARY KEY,data)
|
||||
| 3872: 59 03 07 17 1d 1d 01 81 05 74 61 62 6c 65 84 31 Y........table.1
|
||||
| 3888: 5f 72 6f 77 69 64 74 31 5f 72 6f 87 69 64 03 43 _rowidt1_ro.id.C
|
||||
| 3904: 52 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f REATE TABLE .t1_
|
||||
| 3920: 72 6f 77 69 64 22 28 72 6f 77 69 64 20 49 4e 54 rowid.(rowid INT
|
||||
| 3936: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
|
||||
| 3952: 2c 6e f8 64 65 6e 6f 2c 61 30 29 4b 02 07 17 11 ,n.deno,a0)K....
|
||||
| 3968: 11 08 81 03 74 22 62 6c 65 74 31 74 31 43 52 45 ....t.blet1t1CRE
|
||||
| 3984: 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c ATE VIRTUAL TABL
|
||||
| 4000: 45 20 74 31 20 55 53 49 4e 47 20 72 74 72 65 65 E t1 USING rtree
|
||||
| 4016: 5f 69 33 32 28 69 cc 2c 78 30 2c 78 31 2c 79 30 _i32(i.,x0,x1,y0
|
||||
| 4032: 2c 79 31 2c 2b 65 78 29 36 01 06 17 17 17 01 4d ,y1,+ex)6......M
|
||||
| 4048: 74 61 62 6c 65 63 6f 6f 72 64 63 6f 6f 72 64 02 tablecoordcoord.
|
||||
| 4064: 43 52 45 41 54 45 20 54 41 42 4c 45 20 63 6f 6f CREATE TABLE coo
|
||||
| 4080: 71 64 28 76 20 49 4e 54 2c 20 77 20 49 4e 54 29 qd(v INT, w INT)
|
||||
| page 2 offset 4096
|
||||
| 4016: 00 00 00 00 00 00 00 00 00 00 00 05 0a 03 01 01 ................
|
||||
| 4032: 0a 02 05 09 03 01 01 09 02 05 08 03 01 01 08 02 ................
|
||||
| 4048: 05 07 03 01 01 07 02 05 06 03 11 01 06 02 05 05 ................
|
||||
| 4064: 03 01 01 05 02 05 04 03 01 01 04 02 05 03 03 01 ................
|
||||
| 4080: 01 03 02 05 02 03 01 01 02 02 04 01 03 09 01 02 ................
|
||||
| page 3 offset 8192
|
||||
| 0: 0d 0e 4f 00 64 0b 5a 12 0d bb 0d 84 0f eb 0d c6 ..O.d.Z.........
|
||||
| 16: 0f d7 0e cc 0f c1 0f b6 0f ab 0f 9f 0f 94 0d 8f ................
|
||||
| 32: 0f 86 0d d1 0f 62 0f 67 0f 5c 0f 51 1f 46 0f 3a .....b.g...Q.F.:
|
||||
| 48: 0f 30 0d 9a 0f 21 0d dc 0f 00 00 00 00 00 00 00 .0...!..........
|
||||
| 2896: 00 00 00 00 00 00 00 00 00 00 0a ce 1a 04 00 01 ................
|
||||
| 2912: 17 03 31 30 78 31 30 0a 4e 19 03 ff f1 15 03 31 ..10x10.N......1
|
||||
| 2928: 30 78 39 09 ce 18 04 00 01 15 03 31 30 78 38 09 0x9........10x8.
|
||||
| 2944: ce 17 04 00 01 15 03 31 30 78 37 09 ce 16 04 00 .......10x7.....
|
||||
| 2960: 12 15 03 31 30 78 36 09 ce 15 04 00 01 15 03 31 ...10x6........1
|
||||
| 2976: 30 78 35 09 ce 14 04 00 01 15 0d a1 30 78 34 09 0x5.........0x4.
|
||||
| 2992: ce 13 04 00 01 15 03 31 30 78 33 09 ce 12 04 00 .......10x3.....
|
||||
| 3008: 01 15 03 31 40 78 32 09 ce 11 04 00 01 15 03 31 ...1@x2........1
|
||||
| 3024: 30 78 31 09 c6 32 04 00 01 15 03 39 78 31 30 08 0x1..2.....9x10.
|
||||
| 3040: c6 31 04 00 01 13 03 39 78 39 08 c6 30 04 00 01 .1.....9x9..0...
|
||||
| 3056: 13 03 39 78 38 08 c6 2f 04 00 01 14 03 39 78 37 ..9x8../.....9x7
|
||||
| 3072: 08 c6 2e 04 00 01 13 03 39 78 36 08 c6 2d 04 00 ........9x6..-..
|
||||
| 3088: 01 13 03 39 78 34 f8 c6 2c 04 00 01 13 03 39 78 ...9x4..,.....9x
|
||||
| 3104: 34 08 c6 2b 04 00 60 13 03 39 79 13 08 c6 2a 04 4..+..`..9y...*.
|
||||
| 3120: 00 11 13 03 39 78 32 08 c6 29 04 00 01 13 03 39 ....9x2..).....9
|
||||
| 3136: 78 31 09 be 4a 04 00 01 15 03 38 78 31 30 08 be x1..J.....8x10..
|
||||
| 3152: 49 04 00 01 13 03 38 78 39 08 be 48 04 00 01 13 I.....8x9..H....
|
||||
| 3168: 03 38 77 98 08 be 47 04 00 01 14 23 38 78 37 08 .8w...G....#8x7.
|
||||
| 3184: be 46 04 00 01 13 03 38 78 36 08 be 45 04 00 01 .F.....8x6..E...
|
||||
| 3200: 13 03 38 78 35 08 be 44 04 00 01 13 03 38 78 34 ..8x5..D.....8x4
|
||||
| 3216: 08 be 43 04 00 01 13 03 38 78 33 08 be 42 04 00 ..C.....8x3..B..
|
||||
| 3232: 01 13 03 38 78 32 08 be 41 04 00 01 13 03 38 78 ...8x2..A.....8x
|
||||
| 3248: 31 09 b6 62 04 00 01 15 03 37 68 31 30 08 b6 61 1..b.....7h10..a
|
||||
| 3264: 04 00 01 13 03 37 79 39 08 b6 60 04 00 01 12 f3 .....7y9..`.....
|
||||
| 3280: 37 78 38 08 b6 5e 04 00 01 13 03 37 78 37 08 b6 7x8..^.....7x7..
|
||||
| 3296: 5e 04 00 01 13 03 37 78 36 08 b6 5d 04 00 01 13 ^.....7x6..]....
|
||||
| 3312: 03 37 78 35 08 b6 5c 04 00 00 13 03 37 78 34 08 .7x5........7x4.
|
||||
| 3328: b6 5b 04 00 01 13 03 37 78 33 08 b6 5a 04 00 01 .[.....7x3..Z...
|
||||
| 3344: 13 03 37 78 32 08 b6 59 04 00 01 13 03 37 78 31 ..7x2..Y.....7x1
|
||||
| 3360: 09 ae 7a 04 00 01 15 03 36 78 31 30 08 ae 79 04 ..z.....6x10..y.
|
||||
| 3376: 00 01 e2 03 36 78 39 08 ae 78 04 00 01 13 03 36 ....6x9..x.....6
|
||||
| 3392: 78 38 08 ae 77 04 00 01 13 03 36 78 37 08 ae 76 x8..w.....6x7..v
|
||||
| 3408: 04 00 01 13 03 36 78 36 08 ae 85 04 00 01 13 03 .....6x6........
|
||||
| 3424: 36 78 35 08 ae 73 f4 00 01 13 03 36 78 34 08 ae 6x5..s.....6x4..
|
||||
| 3440: 73 04 00 01 13 03 36 78 33 08 ae 72 04 00 01 13 s.....6x3..r....
|
||||
| 3456: 03 36 78 32 08 87 6a 04 00 01 13 02 3d e8 32 08 .6x2..j.....=.2.
|
||||
| 3472: 8f 52 04 00 01 13 02 32 78 32 08 97 3b 04 00 01 .R.....2x2..;...
|
||||
| 3488: 13 02 33 78 32 08 9f 22 04 00 01 13 02 34 78 32 ..3x2........4x2
|
||||
| 3504: 08 a7 0a 04 00 01 13 02 35 78 32 08 87 69 04 00 ........5x2..i..
|
||||
| 3520: 01 13 02 31 78 31 08 87 6c 04 00 01 13 02 31 78 ...1x1..l.....1x
|
||||
| 3536: 34 08 8f 54 04 00 01 13 02 32 78 34 08 97 3c 04 4..T.....2x4..<.
|
||||
| 3552: 00 01 12 f2 33 78 34 08 9f 24 04 00 01 13 02 34 ....3x4..$.....4
|
||||
| 3568: 78 34 08 a7 0c 04 00 01 13 02 35 78 34 0e 6c 00 x4........5x4.l.
|
||||
| 3584: 08 ae 71 04 00 01 13 03 36 78 31 09 a7 12 04 00 ..q.....6x1.....
|
||||
| 3600: 01 15 02 35 78 31 30 08 a7 11 04 00 01 13 02 35 ...5x10........5
|
||||
| 3616: 78 39 08 a7 10 04 00 01 13 02 35 78 38 08 a7 0f x9........5x8...
|
||||
| 3632: 04 00 01 14 02 35 78 37 08 a7 0e 04 00 01 13 02 .....5x7........
|
||||
| 3648: 35 78 36 08 a7 0d 04 00 01 13 02 35 78 35 0e 0e 5x6........5x5..
|
||||
| 3664: b3 00 08 00 01 00 03 08 a7 0b 04 00 01 13 02 35 ...............5
|
||||
| 3680: 78 33 0e d1 00 08 a7 09 04 00 01 13 02 35 78 31 x3...........5x1
|
||||
| 3696: 09 9f 2a 04 00 01 15 02 34 78 31 30 03 cf 29 04 ..*.....4x10..).
|
||||
| 3712: 00 01 13 02 34 78 39 08 9f 28 04 00 01 13 02 34 ....4x9..(.....4
|
||||
| 3728: 78 38 09 9f 27 04 00 01 13 02 34 78 37 08 9f 26 x8..'.....4x7..&
|
||||
| 3744: 04 00 01 13 0e a4 78 36 08 9f 25 04 00 01 13 02 ......x6..%.....
|
||||
| 3760: 34 78 35 0f 18 00 09 00 09 13 34 78 08 9f 23 04 4x5.......4x..#.
|
||||
| 3776: 00 01 13 02 34 78 33 0f 36 00 08 9f 21 04 00 01 ....4x3.6...!...
|
||||
| 3792: 13 02 34 78 31 09 97 42 04 00 01 15 02 33 78 31 ..4x1..B.....3x1
|
||||
| 3808: 30 08 97 41 04 00 01 13 02 33 78 39 08 97 40 04 0..A.....3x9..@.
|
||||
| 3824: 00 01 13 02 33 78 38 18 97 3f 04 00 01 13 02 33 ....3x8..?.....3
|
||||
| 3840: 78 37 08 97 3e 04 00 01 13 02 33 78 36 08 97 3d x7..>.....3x6..=
|
||||
| 3856: 04 00 01 13 02 33 78 35 1f 7d 00 09 00 09 13 33 .....3x5.......3
|
||||
| 3872: 78 07 97 3b 04 00 01 13 02 33 78 33 0f 9b 00 08 x..;.....3x3....
|
||||
| 3888: 97 39 04 00 01 13 02 33 78 31 09 8f 5a 04 00 01 .9.....3x1..Z...
|
||||
| 3904: 15 02 32 79 31 30 08 8f 59 04 00 01 13 fa 32 78 ..2y10..Y.....2x
|
||||
| 3920: 39 08 8f 58 04 00 01 13 02 32 78 38 08 8f 57 04 9..X.....2x8..W.
|
||||
| 3936: 00 01 13 02 32 78 37 08 8f 56 04 00 01 13 02 32 ....2x7..V.....2
|
||||
| 3952: 78 36 08 8f 55 04 00 01 13 02 32 78 35 0f e2 00 x6..U.....2x5...
|
||||
| 3968: 09 00 09 13 32 78 08 8f 53 04 00 01 13 02 32 78 ....2x..S.....2x
|
||||
| 3984: 33 00 00 00 08 8f 51 04 00 01 13 02 aa 78 31 09 3.....Q......x1.
|
||||
| 4000: 87 72 04 00 01 15 02 31 78 31 30 08 87 71 04 00 .r.....1x10..q..
|
||||
| 4016: 01 13 03 31 78 39 08 87 70 04 00 01 13 02 31 78 ...1x9..p.....1x
|
||||
| 4032: 38 08 87 6f 04 00 01 13 02 31 78 37 08 87 6e 04 8..o.....1x7..n.
|
||||
| 4048: 00 01 13 02 31 78 36 08 87 6d 04 00 01 13 02 31 ....1x6..m.....1
|
||||
| 4064: 7d 25 0f f9 00 08 ff f9 13 31 78 08 87 6b 04 00 .%.......1x..k..
|
||||
| 4080: 01 13 02 31 78 33 00 00 00 00 00 08 00 01 00 03 ...1x3..........
|
||||
| page 4 offset 12288
|
||||
| 0: 0d 00 00 00 03 01 87 00 0b 2d 06 5a 01 87 00 00 .........-.Z....
|
||||
| 384: 00 00 00 00 00 00 00 89 50 01 54 00 93 24 00 00 ........P.T..$..
|
||||
| 400: 00 32 00 00 00 00 00 00 23 2f 00 00 00 09 00 00 .2......#/......
|
||||
| 416: 00 0b 00 00 00 07 00 00 00 09 00 00 00 00 00 00 ................
|
||||
| 432: 23 2e 00 00 10 09 00 00 00 0b 00 00 00 06 00 00 #...............
|
||||
| 448: 00 08 00 00 00 00 00 00 23 2d 00 00 00 09 00 00 ........#-......
|
||||
| 464: 00 0b 00 00 00 05 00 00 00 07 00 00 00 00 00 00 ................
|
||||
| 480: 23 2c 00 00 00 09 00 00 00 0b 00 00 00 04 00 00 #,..............
|
||||
| 496: 00 06 00 00 00 00 00 00 23 2b 00 00 00 09 00 00 ........#+......
|
||||
| 512: 00 0b 00 00 00 03 00 00 00 05 00 00 00 00 00 00 ................
|
||||
| 528: 23 2a 00 00 00 09 00 00 00 0b 00 00 00 02 00 00 #*..............
|
||||
| 544: 00 04 00 00 00 00 00 00 23 29 00 00 00 09 00 00 ........#)......
|
||||
| 560: 00 0b 00 00 00 01 00 00 00 03 00 00 00 00 00 00 ................
|
||||
| 576: 1f 4a 00 00 00 08 00 00 00 0a 00 00 00 0a 00 00 .J..............
|
||||
| 592: 00 0c 00 00 00 00 00 00 0f 49 00 00 00 08 00 00 .........I......
|
||||
| 608: 00 0a 00 00 00 09 00 00 00 0b 00 00 00 00 00 00 ................
|
||||
| 624: 1f 48 00 00 00 08 00 00 00 0a 00 00 00 08 00 06 .H..............
|
||||
| 640: 00 0a 00 00 00 00 00 00 1f 47 00 00 00 08 00 00 .........G......
|
||||
| 656: 00 0a 00 00 00 07 00 00 00 09 00 00 00 00 00 00 ................
|
||||
| 672: 15 d6 00 00 00 08 00 00 00 0a 00 00 00 06 00 00 ................
|
||||
| 688: 00 08 00 00 00 00 00 00 1f 45 00 00 00 08 00 00 .........E......
|
||||
| 704: 00 0a 00 00 00 05 00 00 00 07 00 00 00 00 00 00 ................
|
||||
| 720: 1f 44 00 00 00 08 00 00 00 0a 00 00 00 04 00 00 .D..............
|
||||
| 736: 00 06 00 00 00 00 00 00 1f 43 00 00 00 07 ff ff .........C......
|
||||
| 752: f0 0a 00 00 00 03 00 00 00 05 00 00 00 00 00 00 ................
|
||||
| 768: 1f 42 00 00 00 08 00 00 00 0a 00 00 00 01 ff f0 .B..............
|
||||
| 784: 00 03 ff ff ff ff ff ff 1f 41 00 00 00 08 00 00 .........A......
|
||||
| 800: 00 0a 00 00 00 01 00 00 00 03 00 00 00 00 00 00 ................
|
||||
| 816: 1b 62 00 00 00 07 00 00 00 09 00 00 00 0a 00 00 .b..............
|
||||
| 832: 00 0c 05 00 00 00 00 00 1b 64 10 00 00 07 00 00 .........d......
|
||||
| 848: 00 09 00 00 00 09 00 00 00 0b 00 00 00 00 00 00 ................
|
||||
| 864: 1b 60 00 00 00 07 00 00 00 09 00 00 00 08 00 00 .`..............
|
||||
| 880: 00 0a 00 00 00 00 00 00 1b 5f 00 00 00 07 00 00 ........._......
|
||||
| 896: 00 09 00 00 00 07 00 00 00 09 00 00 00 00 00 00 ................
|
||||
| 912: 1b 5e 00 00 00 07 00 00 00 09 00 00 00 06 00 00 .^..............
|
||||
| 928: 00 08 00 00 00 00 00 00 1b 5d 00 00 00 08 00 00 .........]......
|
||||
| 944: 00 09 00 00 00 05 00 00 00 07 00 00 00 00 00 00 ................
|
||||
| 960: 1b 5c 00 00 00 07 00 00 00 09 00 00 00 04 00 00 ................
|
||||
| 976: 06 46 00 00 00 00 00 00 1b 5b 00 00 00 07 00 00 .F.......[......
|
||||
| 992: 00 09 00 00 00 03 00 00 00 04 ff f0 00 00 00 00 ................
|
||||
| 1008: 1b 5a 00 00 00 07 00 00 00 19 00 00 00 02 00 00 .Z..............
|
||||
| 1024: 00 04 00 00 00 00 00 00 1b 59 00 00 00 07 00 00 .........Y......
|
||||
| 1040: 00 09 00 00 00 01 00 00 00 03 00 00 00 00 ff f0 ................
|
||||
| 1056: 17 7a 00 00 00 06 00 00 00 08 00 00 00 0a 00 00 .z..............
|
||||
| 1072: 00 0c 00 00 00 00 00 00 17 79 00 00 00 06 00 00 .........y......
|
||||
| 1088: 00 08 00 00 00 09 00 00 00 0b 00 00 00 00 00 00 ................
|
||||
| 1104: 17 78 00 00 00 06 00 00 00 08 00 00 00 08 00 00 .x..............
|
||||
| 1120: 00 0a 00 00 00 00 00 00 17 77 00 00 00 06 10 00 .........w......
|
||||
| 1136: 00 08 00 00 00 07 00 09 c0 09 00 00 00 00 00 00 ................
|
||||
| 1152: 17 76 00 00 00 06 00 00 00 08 00 00 00 06 00 00 .v..............
|
||||
| 1168: 00 08 00 00 00 00 00 00 17 75 00 00 00 06 00 00 .........u......
|
||||
| 1184: 00 08 00 00 00 05 00 00 00 07 00 00 00 00 00 00 ................
|
||||
| 1200: 17 74 00 00 00 06 00 00 00 08 00 00 00 03 ff ff .t..............
|
||||
| 1216: f0 06 00 00 00 83 00 00 17 73 00 00 00 06 00 00 .........s......
|
||||
| 1232: 00 08 00 00 00 03 00 00 00 05 00 00 00 00 00 00 ................
|
||||
| 1248: 17 71 ff 00 00 06 00 00 10 08 00 00 00 02 00 00 .q..............
|
||||
| 1264: 00 04 00 00 c0 00 00 00 17 0d 00 00 00 06 00 00 ................
|
||||
| 1280: 00 08 00 00 e7 01 00 00 00 03 00 00 09 e0 00 00 ................
|
||||
| 1296: 23 30 00 00 00 09 00 00 00 0a 00 00 00 08 00 00 #0..............
|
||||
| 1312: 00 0a 00 00 00 00 bb 00 23 31 00 00 00 09 00 00 ........#1......
|
||||
| 1328: 00 0b 00 00 00 09 00 00 00 0b 00 00 00 00 00 00 ................
|
||||
| 1344: 23 32 00 00 00 09 00 00 00 0b 00 00 00 0a 00 00 #2..............
|
||||
| 1360: 00 0c 00 00 00 00 00 00 27 11 00 00 00 0a 00 00 ........'.......
|
||||
| 1376: 00 0c 00 00 00 01 00 08 c0 03 00 00 00 00 00 00 ................
|
||||
| 1392: 27 12 00 00 00 0a 00 00 00 0c 51 00 00 02 00 00 '.........Q.....
|
||||
| 1408: 00 04 6f 00 00 00 00 00 27 13 00 00 00 09 ff ff ..o.....'.......
|
||||
| 1424: 00 0c 00 00 00 03 00 00 00 05 00 00 00 00 00 00 ................
|
||||
| 1440: 27 14 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 '...............
|
||||
| 1616: 00 00 00 00 00 00 00 00 00 00 89 50 02 04 00 93 ...........P....
|
||||
| 1632: 24 00 00 00 32 00 00 00 00 00 00 23 8c 00 00 00 $...2......#....
|
||||
| 1648: 05 00 00 00 07 00 00 00 04 00 00 00 06 00 00 00 ................
|
||||
| 1664: 00 00 00 0f a4 00 00 00 04 00 00 00 06 00 00 00 ................
|
||||
| 1680: 04 00 00 00 06 00 00 00 00 00 00 0b bc 00 00 00 ................
|
||||
| 1696: 03 00 00 00 05 00 00 00 04 00 00 00 06 00 00 00 ................
|
||||
| 1712: 00 00 00 07 d4 00 00 00 02 00 00 00 04 00 00 00 ................
|
||||
| 1728: 04 00 00 00 06 00 00 00 10 00 00 03 ec 00 00 00 ................
|
||||
| 1744: 01 00 00 00 03 00 00 00 04 00 00 00 06 00 00 00 ................
|
||||
| 1760: 00 00 00 13 8d 00 00 00 05 00 00 00 07 00 00 00 ................
|
||||
| 1776: 05 00 00 00 07 00 00 00 00 00 00 0f a5 00 00 00 ................
|
||||
| 1792: 04 00 00 00 06 00 00 00 05 00 00 00 07 00 00 00 ................
|
||||
| 1808: 00 00 00 0b bd 00 00 00 03 00 00 00 05 00 00 00 ................
|
||||
| 1824: 05 00 00 00 07 00 00 00 00 00 00 07 d5 00 00 00 ................
|
||||
| 1840: 02 00 00 00 05 00 00 00 05 00 00 00 07 00 00 00 ................
|
||||
| 1856: 00 00 00 03 ed 00 00 00 01 00 00 00 03 00 00 00 ................
|
||||
| 1872: 05 00 00 00 07 00 00 00 00 00 00 13 8e 00 00 00 ................
|
||||
| 1888: 05 00 00 00 07 00 00 00 06 00 00 00 08 00 00 00 ................
|
||||
| 1904: 00 00 00 0f a6 00 00 00 04 00 00 00 06 00 00 00 ................
|
||||
| 1920: 06 00 00 00 07 ff ff 00 00 00 00 0b be 00 00 00 ................
|
||||
| 1936: 0b 40 00 00 05 00 00 00 06 00 00 00 08 00 00 00 .@..............
|
||||
| 1952: 00 00 00 07 d6 00 00 00 02 00 00 00 04 00 00 00 ................
|
||||
| 1968: 05 00 00 00 08 00 00 00 00 00 00 03 ee 00 00 00 ................
|
||||
| 1984: 01 00 00 00 02 ff ff 00 06 00 00 00 08 00 00 00 ................
|
||||
| 2000: 00 00 00 13 8f 00 00 00 05 00 00 00 07 00 00 00 ................
|
||||
| 2016: 07 00 00 00 09 00 00 00 00 00 00 0f a7 00 00 00 ................
|
||||
| 2032: 04 00 00 00 06 00 00 00 07 00 00 00 09 00 00 08 ................
|
||||
| 2048: 30 00 00 0b bf 00 00 00 03 00 00 00 05 00 00 00 0...............
|
||||
| 2064: 07 00 00 00 09 00 00 00 00 00 00 07 d7 00 00 00 ................
|
||||
| 2080: 02 00 00 00 04 00 00 00 07 00 00 00 09 00 00 00 ................
|
||||
| 2096: 00 00 00 03 ef 00 00 00 01 00 00 00 03 00 00 00 ................
|
||||
| 2112: 07 00 00 00 09 00 00 00 00 00 00 13 90 00 00 00 ................
|
||||
| 2128: 05 00 01 00 07 00 00 00 08 00 00 00 0a 00 00 00 ................
|
||||
| 2144: 00 00 00 0f a8 00 00 00 04 00 00 00 06 00 00 00 ................
|
||||
| 2160: 08 00 00 00 0a 00 00 00 00 00 00 0b f2 00 00 00 ................
|
||||
| 2176: 03 00 00 00 05 00 00 00 08 00 00 00 0a 00 00 01 ................
|
||||
| 2192: 00 00 00 07 d8 00 00 00 02 00 00 00 04 00 00 00 ................
|
||||
| 2208: 08 00 00 00 0a 00 00 00 00 00 00 03 f0 00 00 00 ................
|
||||
| 2224: 01 00 00 00 03 00 00 00 08 00 00 00 09 ff 00 00 ................
|
||||
| 2240: 00 00 00 13 91 00 00 00 05 00 00 00 07 00 00 00 ................
|
||||
| 2256: 09 00 00 00 0b 00 00 00 00 00 00 0f a9 00 00 00 ................
|
||||
| 2272: 04 00 00 00 06 00 00 00 09 00 00 00 0b 00 00 00 ................
|
||||
| 2288: 00 00 00 0b c1 00 00 00 03 00 00 00 05 00 00 00 ................
|
||||
| 2304: 09 00 00 00 0b 00 00 00 00 00 00 07 d9 00 00 00 ................
|
||||
| 2320: 02 00 00 00 04 00 00 00 09 00 00 00 0b 00 00 01 ................
|
||||
| 2336: 00 00 00 03 f0 ff ff 00 01 00 00 00 03 00 00 00 ................
|
||||
| 2352: 09 00 00 00 0b 00 00 00 00 00 00 13 92 00 00 00 ................
|
||||
| 2368: 05 00 00 00 07 00 00 00 0a 00 00 00 0c 00 00 00 ................
|
||||
| 2384: 00 00 00 0f aa 00 00 00 04 00 00 00 06 00 00 00 ................
|
||||
| 2400: 0a 00 00 00 0c 00 00 00 00 00 00 0b c2 00 00 00 ................
|
||||
| 2416: 03 00 00 00 05 00 00 00 0a 00 00 00 0c 00 00 00 ................
|
||||
| 2432: 00 00 00 07 da 00 00 00 02 00 00 00 04 00 00 00 ................
|
||||
| 2448: 0a 00 00 00 0c 00 00 00 00 00 00 03 f2 00 00 00 ................
|
||||
| 2464: 01 00 00 10 03 00 00 00 0a 00 00 00 0c 00 00 00 ................
|
||||
| 2480: 00 00 00 03 eb 00 00 00 01 00 00 00 03 00 00 00 ................
|
||||
| 2496: 03 00 00 00 05 00 00 00 00 00 00 07 d3 00 00 00 ................
|
||||
| 2512: 02 00 00 00 04 00 00 00 03 00 00 00 05 00 00 00 ................
|
||||
| 2528: 00 00 00 0b bb 00 00 00 03 00 00 00 05 00 00 00 ................
|
||||
| 2544: 03 00 00 00 05 00 00 00 00 00 00 0f a3 00 00 00 ................
|
||||
| 2560: 04 00 00 00 06 00 00 00 03 00 00 00 05 00 00 00 ................
|
||||
| 2576: 00 00 00 13 8b 00 00 00 05 00 00 00 07 00 00 00 ................
|
||||
| 2592: 03 00 00 00 05 00 00 00 00 00 00 03 ea 00 00 00 ................
|
||||
| 2608: 01 00 00 00 03 00 00 00 02 00 00 00 04 00 00 00 ................
|
||||
| 2624: 00 00 00 07 d2 00 00 00 02 00 00 00 04 00 00 00 ................
|
||||
| 2640: 02 00 00 00 04 00 00 00 00 00 00 0b ba 00 00 00 ................
|
||||
| 2656: 03 00 00 00 05 00 00 00 02 00 00 00 04 00 00 00 ................
|
||||
| 2672: 00 00 00 0f a1 ff ff ff 04 00 00 00 06 00 00 00 ................
|
||||
| 2688: 02 00 00 00 04 00 00 00 00 00 00 13 8a 00 00 00 ................
|
||||
| 2704: 05 00 00 00 06 ff ff ff f2 00 00 00 04 00 00 00 ................
|
||||
| 2720: 00 00 00 03 e9 00 00 00 01 00 00 00 03 00 00 00 ................
|
||||
| 2736: 01 00 00 00 03 00 00 00 00 00 00 07 d1 00 00 00 ................
|
||||
| 2848: 00 00 00 00 00 00 00 00 00 00 00 00 00 89 50 01 ..............P.
|
||||
| 2864: 04 00 93 24 00 01 00 02 00 00 00 00 00 00 00 02 ...$............
|
||||
| 2880: ff ff ff 06 00 00 00 0c 00 00 00 01 00 00 00 0b ................
|
||||
| 2896: 00 00 00 00 00 00 00 02 40 00 00 00 00 00 00 00 ........@.......
|
||||
| end crash-2e81f5dce5cbd4.db}]
|
||||
execsql { PRAGMA writable_schema = 1;}
|
||||
catchsql {UPDATE t1 SET ex= ex ISNULL}
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -1837,7 +1837,7 @@ static int sessionBufferGrow(SessionBuffer *p, size_t nByte, int *pRc){
|
||||
i64 nNew = p->nAlloc ? p->nAlloc : 128;
|
||||
do {
|
||||
nNew = nNew*2;
|
||||
}while( (nNew-p->nBuf)<nByte );
|
||||
}while( (size_t)(nNew-p->nBuf)<nByte );
|
||||
|
||||
aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew);
|
||||
if( 0==aNew ){
|
||||
|
||||
@@ -527,7 +527,6 @@ SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
|
||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
|
||||
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
C Version\s3.29.0
|
||||
D 2019-07-10T17:32:03.802
|
||||
C Attempt\sto\sparse\sthe\sNULLS\sLAST\sclause\smore\sefficiently.\s\sA\sfew\scycles\swere\nsaved,\sbut\sat\sthe\sexpense\sof\smore\scode.\s\sAnd\sthere\sis\sa\sbug\swas\sintroduced\nsomewhere.\s\sNot\sworth\scontinuing\sdown\sthis\sline.
|
||||
D 2019-08-23T21:11:11.924
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
F Makefile.in 4640daf826b80947a924ac44275c451ffc13007c7c866a5730c8ce5cf9e1dc74
|
||||
F Makefile.in 578f123620087ea459aa08fa872810a25ca7c0aaf16331de985bfcddb5f1e747
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 26957950b2b4f3b26e311eeea70437f85a77765f71d3a06489466d66ee321100
|
||||
F Makefile.msc a463dca3c50d8a36094fe5c8c39077907f530b54edfc5388c66c85e2cfc8dc04
|
||||
F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a
|
||||
F VERSION cc8cd90333c65cdf4cb346f356a2ce1eb0f5b7fa1d17a34d7350103e7320af1f
|
||||
F VERSION 4c516d84c2a5f26c477ed34c09ac4136630f71c68139631f2eb591b22eea7cf1
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
||||
@@ -15,7 +15,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
|
||||
F autoconf/Makefile.am e14b629addaa1ce372b72043f28f40de2e32b7e211b6e0fc18dbb87989197e40
|
||||
F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac
|
||||
F autoconf/Makefile.msc bea737cb2ed8802056ff44947c4963026307caff4d7382b9622e7928990a4a18
|
||||
F autoconf/Makefile.msc 3804b004efb6abd2d2e0f5f887dfc6ade3d1661f39335c0531df96e1ab61a062
|
||||
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
|
||||
F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1
|
||||
F autoconf/configure.ac 308de24343e76ecfbe9a67f8fcd4c5216b790d230c5d9ce10210b7d5965d6192
|
||||
@@ -34,7 +34,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
||||
F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6
|
||||
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
|
||||
F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559
|
||||
F configure 4a97fb6ccce582ebb3dc5a7e281e5e2823574dad851b8ccf814aa6de9f4c7ad2 x
|
||||
F configure 6f5136d2574d7aa08370021ab63be3ef8a8bf32af60594de08393b01feeb4bab x
|
||||
F configure.ac 3552d3aecade98a9d4b64bceb48ffb7726cbc85902efde956812942f060fbd0a
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
|
||||
@@ -47,7 +47,7 @@ F ext/async/sqlite3async.c 0f3070cc3f5ede78f2b9361fb3b629ce200d7d74
|
||||
F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef
|
||||
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
|
||||
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
|
||||
F ext/expert/expert1.test 358e416877a5693fb99d5514f5d88452b5239dc2196b74e0e926718502faef6d
|
||||
F ext/expert/expert1.test e2afc53a27610e8251e44c7f961806607a5490ff204b3db342740d558e052662
|
||||
F ext/expert/sqlite3expert.c 3da865f2286433588260f41e796422c611bceaca3a0bbf9139a619cf7d062c19
|
||||
F ext/expert/sqlite3expert.h af6354f8ee5c9e025024e63fec3bd640a802afcc3099a44d804752cf0791d811
|
||||
F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72
|
||||
@@ -90,7 +90,7 @@ F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6
|
||||
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
|
||||
F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116
|
||||
F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
|
||||
F ext/fts3/fts3_snippet.c 2f3a78b990f1c8658225618c8a0fa06ab60046688d6fb627a548e8ada9011150
|
||||
F ext/fts3/fts3_snippet.c 7963dd25ec81013c31f3c61697d0a1f3d06be21af3565774645c08d3dedf1fa7
|
||||
F ext/fts3/fts3_term.c f45a1e7c6ef464abb1231245d123dae12266b69e05cc56e14045b76591ae92d1
|
||||
F ext/fts3/fts3_test.c 73b16e229e517c1b1f0fb8e1046182a4e5dbc8dbe6eea8a5d4353fcce7dbbf39
|
||||
F ext/fts3/fts3_tokenize_vtab.c 1de9a61acfa2a0445ed989310c31839c57f6b6086dd9d5c97177ae734a17fd8b
|
||||
@@ -99,7 +99,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
|
||||
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
|
||||
F ext/fts3/fts3_unicode.c 4b9af6151c29b35ed09574937083cece7c31e911f69615e168a39677569b684d
|
||||
F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f
|
||||
F ext/fts3/fts3_write.c 9e88111ca9f70e4079880d842c8323bffc4968b39ee38c0a75962a3485af9333
|
||||
F ext/fts3/fts3_write.c 6efc4cd7dc554df06c35bfd3335503838645806a78fc33137a55eb97a8b2f3b2
|
||||
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
|
||||
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
|
||||
F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
|
||||
@@ -110,15 +110,15 @@ F ext/fts3/unicode/mkunicode.tcl bf7fcaa6d68e6d38223467983785d054f1cff4d9e3905dd
|
||||
F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb
|
||||
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
|
||||
F ext/fts5/fts5.h 7c9da96f2b9dcfa4dd94081fb2d87ec418d8cdb35b25df56756c334b6b558fd7
|
||||
F ext/fts5/fts5Int.h 5c26dce0ec9272fca726c6fddb92f634d0c912d4ca170330270d488a94b80416
|
||||
F ext/fts5/fts5Int.h d87fb17d12296613cdec2d1f4213ecd8840d3deb34837b6d3889b830d06baac4
|
||||
F ext/fts5/fts5_aux.c dcc627d8b6e3fc773db528ff67b39955dab7b51628f9dba8e15849e5bedfd7fa
|
||||
F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70
|
||||
F ext/fts5/fts5_config.c d7523cba5e66da077233c023aecbc3e6a37978ff75a18131c5ab5b1229d5bac7
|
||||
F ext/fts5/fts5_expr.c 840c88d55e78083a5e61a35968df877712ae28791b347eced1e98e3b337d2d3c
|
||||
F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75
|
||||
F ext/fts5/fts5_index.c 5a89e0341297fade9a8f2c7aecc1ebd2e7e0989da84ece4d287a153da73cf0e6
|
||||
F ext/fts5/fts5_main.c abd04720e2729ba5bab2648d9d541faab18f45d481ae21fc30f125b55e979d6b
|
||||
F ext/fts5/fts5_storage.c b24f6916fcdd68989a549f25962f286bdba9d9d59c7581567a6a0eb647cd07cc
|
||||
F ext/fts5/fts5_index.c cd363c2fa3e626c04a9b7c705ff50222b4cab052704938f6a24881602ed3ed0d
|
||||
F ext/fts5/fts5_main.c b2c42f1cef9673ecdd498b22c38483a4380bcf1701d1e61b021a2945f18e42e1
|
||||
F ext/fts5/fts5_storage.c 801b4e3cd33786a60a07b6b01f86d0fbdf7e68325054e08d17176293a8081e99
|
||||
F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95
|
||||
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
|
||||
F ext/fts5/fts5_test_tok.c f96c6e193c466711d6d7828d5f190407fe7ab897062d371426dd3036f01258e7
|
||||
@@ -154,10 +154,10 @@ F ext/fts5/test/fts5columnsize.test 45459ce4dd9fd853b6044cdc9674921bff89e3d840f3
|
||||
F ext/fts5/test/fts5config.test 60094712debc59286c59aef0e6cf511c37d866802776a825ce437d26afe0817f
|
||||
F ext/fts5/test/fts5conflict.test 655925678e630d3cdf145d18725a558971806416f453ac8410ca8c04d934238d
|
||||
F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c073e19b3ae9126b2f4
|
||||
F ext/fts5/test/fts5content.test 688d5ac7af194ebc67495daea76a69e3cd5480122c2320e72d41241b423b4116
|
||||
F ext/fts5/test/fts5content.test 9517cc527a8e8a33949652d5c7b5e251f8c3d5ae3f23f01d4320e30f29a0336b
|
||||
F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe
|
||||
F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f
|
||||
F ext/fts5/test/fts5corrupt3.test ee32b76e1b4beae8051f0bd5bc9cc9609667fdaed87886eda69b96b305d21897
|
||||
F ext/fts5/test/fts5corrupt3.test 99318789d84c678ed6388e61109b9f7b92c64419e87e4881093c01e219c5d397
|
||||
F ext/fts5/test/fts5corrupt4.test ea805c4d7c68b5f185b9db5d2060a7ae5875339738dd48203c92162f41e7ca91
|
||||
F ext/fts5/test/fts5delete.test cbf87e3b8867c4d5cfcaed975c7475fd3f99d072bce2075fcedf43d1f82af775
|
||||
F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e
|
||||
@@ -199,7 +199,7 @@ F ext/fts5/test/fts5porter.test 8d08010c28527db66bc3feebd2b8767504aaeb9b101a9863
|
||||
F ext/fts5/test/fts5porter2.test 0d251a673f02fa13ca7f011654873b3add20745f7402f108600a23e52d8c7457
|
||||
F ext/fts5/test/fts5prefix.test a0fa67b06650f2deaa7bf27745899d94e0fb547ad9ecbd08bfad98c04912c056
|
||||
F ext/fts5/test/fts5query.test ac363b17a442620bb0780e93c24f16a5f963dfe2f23dc85647b869efcfada728
|
||||
F ext/fts5/test/fts5rank.test ca5000241924ecc2882db33c60f4f3a62b1ee6b16b5a9c8c6ddd9b6b2138489c
|
||||
F ext/fts5/test/fts5rank.test c9fd4a1e36b4fa92d572ec13d846469b97da249d1c2f7fd3ee7e017ce46f2416
|
||||
F ext/fts5/test/fts5rebuild.test 55d6f17715cddbf825680dd6551efbc72ed916d8cf1cde40a46fc5d785b451e7
|
||||
F ext/fts5/test/fts5restart.test 835ecc8f449e3919f72509ab58056d0cedca40d1fe04108ccf8ac4c2ba41f415
|
||||
F ext/fts5/test/fts5rowid.test b8790ec170a8dc1942a15aef3db926a5f3061b1ff171013003d8297203a20ad6
|
||||
@@ -229,7 +229,7 @@ F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
|
||||
F ext/icu/README.txt a295e91db742b153e8dce8f7efd31d28ad1eea4df31ef4daa3eedc85be2f5138
|
||||
F ext/icu/icu.c c2c7592574c08cd1270d909b8fb8797f6ea1f49e931e71dbcc25506b9b224580
|
||||
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
|
||||
F ext/lsm1/Makefile 98b0a24b45e248283d6bea4b6cb3e58d7b394edd8e96a0ac28c5fa5104813bad
|
||||
F ext/lsm1/Makefile a553b728bba6c11201b795188c5708915cc4290f02b7df6ba7e8c4c943fd5cd9
|
||||
F ext/lsm1/Makefile.msc f8c878b467232226de288da320e1ac71c131f5ec91e08b21f502303347260013
|
||||
F ext/lsm1/lsm-test/README 87ea529d2abe615e856d4714bfe8bb185e6c2771b8612aa6298588b7b43e6f86
|
||||
F ext/lsm1/lsm-test/lsmtest.h cf58528ffe0cfe535e91b44584e2ec5fb1caacdabecef0d8dcf83bf83168bf28
|
||||
@@ -269,10 +269,10 @@ F ext/lsm1/lsm_str.c 65e361b488c87b10bf3e5c0070b14ffc602cf84f094880bece77bbf6678
|
||||
F ext/lsm1/lsm_tree.c 682679d7ef2b8b6f2fe77aeb532c8d29695bca671c220b0abac77069de5fb9fb
|
||||
F ext/lsm1/lsm_unix.c 57361bcf5b1a1a028f5d66571ee490e9064d2cfb145a2cc9e5ddade467bb551b
|
||||
F ext/lsm1/lsm_varint.c 43f954af668a66c7928b81597c14d6ad4be9fedbc276bbd80f52fa28a02fdb62
|
||||
F ext/lsm1/lsm_vtab.c 529255dc704289001b225d97e57e0cfa14b29c3f281c7349cfa8fdb655de79ae
|
||||
F ext/lsm1/lsm_vtab.c 169bfe7ef8e6c9de9c77e17c4c50c9ae55fb0167d80be3d1be82c991184b6f35
|
||||
F ext/lsm1/lsm_win32.c 0a4acbd7e8d136dd3a5753f0a9e7a9802263a9d96cef3278cf120bcaa724db7c
|
||||
F ext/lsm1/test/lsm1_common.tcl 5ed4bab07c93be2e4f300ebe46007ecf4b3e20bc5fbe1dedaf04a8774a6d8d82
|
||||
F ext/lsm1/test/lsm1_simple.test ca949efefa102f4644231dcd9291d8cda7699a4ce1006b26e0e3fcb72233f422
|
||||
F ext/lsm1/test/lsm1_simple.test a04d08e8661ae6fc53786c67f0bd102c6692f003e859dde03ed9ac3f12e066e5
|
||||
F ext/lsm1/tool/mklsm1c.tcl f31561bbee5349f0a554d1ad7236ac1991fc09176626f529f6078e07335398b0
|
||||
F ext/misc/README.md d6dd0fe1d8af77040216798a6a2b0c46c73054d2f0ea544fbbcdccf6f238c240
|
||||
F ext/misc/amatch.c 50a9ef2d38dabfa371f8c1904097d493271e63d58ccb0e9b79a4fa4a94e66660
|
||||
@@ -290,10 +290,10 @@ F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287
|
||||
F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e
|
||||
F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f
|
||||
F ext/misc/fileio.c 288e7230e0fe464d71b0694e2d8bdd3a353118ac2e31da3964b95f460f09915f
|
||||
F ext/misc/fossildelta.c 5c04d0a5657615daf4c6cd01c4281de8983dd28f6eed592b2691c10e3f6710e1
|
||||
F ext/misc/fossildelta.c 7708651072eb5620ab21bbfb518d184f27b2c29c0131b09b9a2d8852a8016430
|
||||
F ext/misc/fuzzer.c c4e27daf41433a64cad5265cd27dbcb891147e9994d0422200ce81ce9a54b625
|
||||
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
|
||||
F ext/misc/json1.c c99b5f04fccba87c1c8c5ab5c0e53eef37c0144086e33911290a67dfba541d59
|
||||
F ext/misc/json1.c 71ce4e39793b743fc7e4790bc3bab15598e95cab57ad8da4326fa640ae5e5310
|
||||
F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d
|
||||
F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b
|
||||
F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567
|
||||
@@ -302,7 +302,7 @@ F ext/misc/nextchar.c 279f80fe8ef5ba413242e2704e246503ac601f005eefb180d19e6c9203
|
||||
F ext/misc/normalize.c b4290464f542bae7a97b43f15bd197949b833ffd668b7c313631bd5d4610212c
|
||||
F ext/misc/percentile.c 148dd07286b16e50f232bb638a47850085ad37d51f270429905bd865e595d1ca
|
||||
F ext/misc/prefixes.c 7be86d17525cfae6ed462fc3c519efc44488ac329890f77491c8f82871f57e17
|
||||
F ext/misc/regexp.c 79345bf03496155a640ee0300d3307296761cebb5e115b4e342cc2fb5861ec10
|
||||
F ext/misc/regexp.c 653b6ab5e89bcb5d45f9ebe0747d7f8f3f5706cac963fcbc9a3ddbe5fdc1efa2
|
||||
F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
|
||||
F ext/misc/rot13.c 540a169cb0d74f15522a8930b0cccdcb37a4fd071d219a5a083a319fc6e8db77
|
||||
F ext/misc/scrub.c db9fff56fed322ca587d73727c6021b11ae79ce3f31b389e1d82891d144f22ad
|
||||
@@ -345,6 +345,7 @@ F ext/rbu/rbucrash.test 000981a1fe8a6e4d9a684232f6a129e66a3ef595f5ed74655e2f9c68
|
||||
F ext/rbu/rbucrash2.test efa143cc94228eb0266d3f1abfbee60a5838a84cef7cc3fcb8c145b74d96fd41
|
||||
F ext/rbu/rbudiff.test 156957851136b63c143478518dc1bda6c832103cdbe8ac1d7cdd47edb3cbe0a3
|
||||
F ext/rbu/rbudor.test e3e8623926012f43eebe51fedf06a102df2640750d971596b052495f2536db20
|
||||
F ext/rbu/rbuexpr.test 10d0420537c3bc7666e576d72adeffe7e86cfbb00dcc30aa9ce096c042415190
|
||||
F ext/rbu/rbufault.test 2d7f567b79d558f6e093c58808cab4354f8a174e3802f69e7790a9689b3c09f8
|
||||
F ext/rbu/rbufault2.test c81327a3ac2c385b9b954db3644d4e0df93eeebfc3de9f1f29975a1e73fd3d0c
|
||||
F ext/rbu/rbufault3.test b2fcc9db5c982b869f67d1d4688d8cb515d5b92f58011fff95665f2e62cec179
|
||||
@@ -352,8 +353,8 @@ F ext/rbu/rbufault4.test 03d2849c3df7d7bd14a622e789ff049e5080edd34a79cd432e01204
|
||||
F ext/rbu/rbufts.test 0ae8d1da191c75bd776b86e24456db0fb6e97b7c944259fae5407ea55d23c31d
|
||||
F ext/rbu/rbumisc.test 329986cf5dd51890c4eb906c2f960ebb773a79a64bed90f506b7c417825b37eb
|
||||
F ext/rbu/rbumulti.test 5fb139058f37ddc5a113c5b93238de915b769b7792de41b44c983bc7c18cf5b9
|
||||
F ext/rbu/rbupartial.test 1c8bd6d42615b94caf08f129f5817fa26975523f0f51bceda1dca90e8114c7c4
|
||||
F ext/rbu/rbuprogress.test 04614ff8820bab9c1ec1b7dbec1edc4b45474421d4fe7abbd2a879a9c02884f9
|
||||
F ext/rbu/rbupartial.test f25df014b8dbe3c5345851fba6e66f79ab237f57dc201b2d5f0dbae658ae5a4c
|
||||
F ext/rbu/rbuprogress.test 857cf1f8166c83ef977edb9ef4fc42d80f71fbd798652b46ae2f3a7031870f8d
|
||||
F ext/rbu/rburesume.test dbdc4ca504e9c76375a69e5f0d91205db967dcc509a5166ca80231f8fda49eb1
|
||||
F ext/rbu/rbusave.test f4190a1a86fccf84f723af5c93813365ae33feda35845ba107b59683d1cdd926
|
||||
F ext/rbu/rbusplit.test b37e7b40b38760881dc9c854bd40b4744c6b6cd74990754eca3bda0f407051e8
|
||||
@@ -362,7 +363,7 @@ F ext/rbu/rbuvacuum.test 55e101e90168c2b31df6c9638fe73dc7f7cc666b6142266d1563697
|
||||
F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b
|
||||
F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc
|
||||
F ext/rbu/rbuvacuum4.test a78898e438a44803eb2bc897ba3323373c9f277418e2d6d76e90f2f1dbccfd10
|
||||
F ext/rbu/sqlite3rbu.c 8741c0ee1496b41ff888b983a1a32547bc8822602603c68b3e524e5e0e287395
|
||||
F ext/rbu/sqlite3rbu.c f3a3e09f575157052813be667d6ab3b54f47fb02e6e1c9f767ad7bb8f1fb90b3
|
||||
F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812
|
||||
F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a
|
||||
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
|
||||
@@ -376,7 +377,7 @@ F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c3350
|
||||
F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/geopoly.c c591164125808f8bba9659e92665b78412cd263e654b6f05294f3a8da7cdd9fb
|
||||
F ext/rtree/rtree.c 78c0d989c32e5baac471f0463e83cda5006c7e71ded39d633b5fc001a301a26e
|
||||
F ext/rtree/rtree.c f8d9ea7d988c1002bff5acfac77d188f2f5d9eb025f24d5038a3d70a9c3f3d9d
|
||||
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
|
||||
F ext/rtree/rtree1.test 7573134f1b4f59df36c1b0a6de51268fd3b9c714d91f3811482263e734e416ea
|
||||
F ext/rtree/rtree2.test 5f25b01acd03470067a2d52783b2eb0a50bf836803d4342d20ca39e541220fe2
|
||||
@@ -400,7 +401,7 @@ F ext/rtree/rtree_util.tcl db734b4c5e75fed6acc56d9701f2235345acfdec750b5fc7b5879
|
||||
F ext/rtree/rtreecheck.test d67d5b3e9e45bfa8cd90734e8e9302144ac415b8e9176c6f02d4f92892ee8a35
|
||||
F ext/rtree/rtreecirc.test aec664eb21ae943aeb344191407afff5d392d3ae9d12b9a112ced0d9c5de298e
|
||||
F ext/rtree/rtreeconnect.test 225ad3fcb483d36cbee423a25052a6bbae762c9576ae9268332360c68c170d3d
|
||||
F ext/rtree/rtreefuzz001.test 836d87653851ae8e7b506d8bd3d62329548adc48ff9bc0a9051efd576710be7b
|
||||
F ext/rtree/rtreefuzz001.test eef1ed593bb15886cd5d5367a2f2492f81e315848896cdf7afb6e21454978827
|
||||
F ext/rtree/sqlite3rtree.h 03c8db3261e435fbddcfc961471795cbf12b24e03001d0015b2636b0f3881373
|
||||
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
||||
F ext/rtree/util/randomshape.tcl 54ee03d0d4a1c621806f7f44d5b78d2db8fac26e0e8687c36c4bd0203b27dbff
|
||||
@@ -435,7 +436,7 @@ F ext/session/sessioninvert.test ae1a003a9ab1f8d64227dbb5c3a4c97e65b561b01e7b295
|
||||
F ext/session/sessionrebase.test ccfa716b23bd1d3b03217ee58cfd90c78d4b99f53e6a9a2f05e82363b9142810
|
||||
F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5
|
||||
F ext/session/sessionwor.test 67b5ab91d4f93ce65ff1f58240ac5ddf73f8670facc1ffa49cef56293d52818d
|
||||
F ext/session/sqlite3session.c 3d9d3a414be386b87d83e642f4d93c8cbe83fe7b975d17b398f96caa1bfdc2cf
|
||||
F ext/session/sqlite3session.c a4dfb372f270df93422b0dc7666fd46849e6979b62a152f11287c21eed4ac21b
|
||||
F ext/session/sqlite3session.h 919be6649d39d6413ce7a63fc3e3bca3270e18bc2d57ad4040a70007b9e54397
|
||||
F ext/session/test_session.c 98797aba475a799376c9a42214f2d1debf2d0c3cb657d9c8bbf4f70bf3fb4aec
|
||||
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
||||
@@ -444,7 +445,7 @@ F ext/userauth/userauth.c f81aa5a3ecacf406f170c62a144405858f6f6de51dbdc0920134e6
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk 125adda36bb32c99dc3a11340bd029ef373b9523eac2b2af76087bfe82d4fdf8
|
||||
F main.mk 09716d345766a55b25ed157b14786526cf67c761c61d99c53e117196fb3b391a
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
@@ -456,37 +457,37 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c c1b5e5639b88dcc146db326315f2dea4f7f1c599e524eeb421d544927a0b1e86
|
||||
F src/analyze.c 58db66344a5c58dcabb57f26696f6f2993956c830446da40b444051d2fdaf644
|
||||
F src/attach.c 78e986baee90cb7b83fb9eafa79c22581a8ada14030fd633b0683c95cf11213c
|
||||
F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df
|
||||
F src/backup.c b1d37f6f7f5913944583733ed0f9e182f3ece0d42c27f46701142141a6e6fd33
|
||||
F src/alter.c 5c3031e45e80f79d7d54c2d32dd3c44926544d4f6a478858bfe4ee3191570190
|
||||
F src/analyze.c a3f4ea45cdb4e9df78d4ea7beb87ec8a7a46f494173b641cd28512a40a97bff2
|
||||
F src/attach.c a6f108eb7922fad920e8aba0cda56fb56d89d136d519be5177cd3bd3559f2566
|
||||
F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
|
||||
F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
|
||||
F src/btree.c 1dbc191e5c1d9bca84a956fed5d73924c574ae5390855009f067bd0f6422e462
|
||||
F src/btree.c 5cf994516c1b74928b9d15971573a8bc8595e1afec129184099976da603402de
|
||||
F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89
|
||||
F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f
|
||||
F src/build.c 23a0253ab53e62feadcc0c6f31e7e418ef9d4b92c82a1398e98433776b920a4e
|
||||
F src/build.c 86827bdbc275ade579e778e2d430c252659fffa25ea88f45884cbe5d32f36de2
|
||||
F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 37f3d21193c4f7d141d0691cced5b39c99951bfef78df9887faf9167b9c42f37
|
||||
F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251
|
||||
F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041
|
||||
F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7
|
||||
F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319
|
||||
F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf
|
||||
F src/expr.c 2756d2875ac5b7a7efcc54edea3c8a31f4126684ded18da6fb406f4d3780a5f5
|
||||
F src/expr.c 1ed0847f4842c56a2f18e9b096526297b85fdb7b7c058e59ac77dc4cec621b4a
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 0e14d4bef8eac2d87bbd517e492d9084c65008d117823f8922c5e7b2b599bd33
|
||||
F src/func.c 905c0424900979fade3731b4a271592059425c988cb7d5b245032253712dd7c8
|
||||
F src/global.c 1e942b1e6fb6a2a15e6015bda72be0abefc4b1339a8640a47b1b71b7f317917b
|
||||
F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e
|
||||
F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467
|
||||
F src/global.c d7a7a45a78ffe01302d61c271ed50474ef1b9d2d23bf17a46a58c8a1926424ee
|
||||
F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
|
||||
F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
|
||||
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c f20925c2c08144442dabeb73dcd0f5026f5f085d827f3d5635f7c45e5d195320
|
||||
F src/insert.c 81eec6acf4fbf0942bbab6804fe50df3e109acba40b8bbfb00fec9a14d0715a6
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c 22afc33c3a61b4fd80a60a54f1882688371e6bc64685df2696b008fce65a999c
|
||||
F src/main.c 591a0084b1a6b0ed6741f77181bd1a630ca10bb460420f00e8c11809da7df5b9
|
||||
F src/loadext.c a045bb3425a9a633cc0f78e93d9beda6866f4c0f15bfdee735aba7c6b39f5cc4
|
||||
F src/main.c 51c55eb579eac4180bfcc6242741084710911350d2cd0c3fdd0f9fde55442128
|
||||
F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||
@@ -494,7 +495,7 @@ F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
|
||||
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
|
||||
F src/memdb.c 02a5fcec19b9d40dd449ca802dc1b2e8f93f255fbf2a886277a3c3800d8d35db
|
||||
F src/memjournal.c 6f3d36a0a8f72f48f6c3c722f04301ac64f2515435fa42924293e46fc7994661
|
||||
F src/memjournal.c 7561c01c90958f3ba9bc6cb2d857123d932bdfa5539ea34427a0957b2e35154d
|
||||
F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8
|
||||
F src/mutex.c bae36f8af32c22ad80bbf0ccebec63c252b6a2b86e4d3e42672ff287ebf4a604
|
||||
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
|
||||
@@ -502,37 +503,37 @@ F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
|
||||
F src/mutex_unix.c aaf9ebc3f89df28483c52208497a99a02cc3650011422fc9d4c57e4392f7fe58
|
||||
F src/mutex_w32.c 7670d770c94bbfe8289bec9d7f1394c5a00a57c37f892aab6b6612d085255235
|
||||
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
|
||||
F src/os.c 8aeb0b0f40f8f5b0da03fe49706695adaf42d2f516ab95abc72e86c245e119de
|
||||
F src/os.c 20f7b32c1e8839999fa7e79756a6cdc3041b44d7fc635c25a1b9399180d1fbd9
|
||||
F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
|
||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
F src/os_unix.c f6e91b8fd82af7afbfd073c4974ad6cdb8e62d9f65ceddb45167835a0567fdc0
|
||||
F src/os_win.c 85d9e532d0444ab6c16d7431490c2e279e282aa0917b0e988996b1ae0de5c5a0
|
||||
F src/os_unix.c 4ec5b1305ced509ca52c4c0cb3aeabed2ed3972147b4090cf94eb31d48caeb53
|
||||
F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c 422fd8cfa59fb9173eff36a95878904a0eeb0dcc62ba49350acc8b1e51c4dc7b
|
||||
F src/pager.h 217921e81eb5fe455caa5cda96061959706bcdd29ddb57166198645ef7822ac3
|
||||
F src/parse.y 026e3e6fff32432166a4eae0bdb78ad09a53c84eb49acb44dc32e49b4c0b8a48
|
||||
F src/pcache.c fd2d0553b3222d6b9f7cb251079e5bca1299d1161da3027b525932d8bf46340a
|
||||
F src/parse.y 1e469e2b5164d38ae3356314616fb5dcde840732cae4250e83e56082904683c8
|
||||
F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
|
||||
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
|
||||
F src/pcache1.c e6373934cdafea272d94feb224344f9fd93ff94318221b64ccabd72d98b4672e
|
||||
F src/pragma.c 925bcac0afd98a0d4255c7524b93239ab4d83893d96f7f8fdccd78d4929a39bb
|
||||
F src/pragma.h 4a9fabff14db4487a734dfeeb4be984ce662bfdccfae16145b9c732327735e13
|
||||
F src/prepare.c 78027c6231fbb19ca186a5f5f0c0a1375d9c2cec0655273f9bd90d9ff74a34b3
|
||||
F src/pcache1.c 62714cbd1b7299a6e6a27a587b66b4fd3a836a84e1181e7f96f5c34a50917848
|
||||
F src/pragma.c b47bc7db02ab13d04c680aee424466b4e34f4ef5aa7b2e464876ec005806f98f
|
||||
F src/pragma.h 40962d65b645bb3f08c1f4c456effd01c6e7f073f68ea25177e0c95e181cff75
|
||||
F src/prepare.c 132484635a30f873ee7eccd47f93ed1932503863b93b28423b42332d81adffaf
|
||||
F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c 93b7bc7c45efa6322d92293361c51a873690daed50cf77eeff88a448246b0d5a
|
||||
F src/resolve.c 9891cf5fd155bb199f8b1ff5d1429b9f70484487f4c455bba94348d4cb6f829f
|
||||
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
|
||||
F src/select.c 62f21307b280791c50554c9fa3766758dd695ed66a05d2408d213355c7b0aa89
|
||||
F src/shell.c.in 82f8a473c01662f52233c6c75b9bf88d0d2cab276086d5d4ca6f2ff57a3e48eb
|
||||
F src/sqlite.h.in 83ebc8ab1a2e82d92214006ea2c15bf8a0604f3fac2c31dd9ce9021f568c71f2
|
||||
F src/select.c ae8713c846a51805130f3084146005cdd719573755593c148df6539129f8873c
|
||||
F src/shell.c.in e0f0758b6ab506d8ab12502fd2b8c55546bb9e4bb772374344a5a1b73f5bc2b9
|
||||
F src/sqlite.h.in 50fc0914ccd347437db9a0278a47d7541df3a45eb6e641e9680750c6f98dad27
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5
|
||||
F src/sqliteInt.h bf65dfa6565fae2e0d501088fc9c5212244adc1429a543827a16b2f5eaf41982
|
||||
F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31
|
||||
F src/sqliteInt.h f5a9c61f976a171654f429e4dac452b27a40a4250148d14a7ca3a918a4d9b31b
|
||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
F src/tclsqlite.c cfe7f93daf9d8787f65e099efb67d7cdfc2c35236dec5d3f6758520bd3519424
|
||||
F src/test1.c f57c229ad7878215d0b3bb5d59ffe94772c099ce5b5e147a4a59d3157923a988
|
||||
F src/tclsqlite.c 50c93be3e1c03b4e6cf6756e5197afcfe7f5cd0497d83a7ac317cde09e19b290
|
||||
F src/test1.c 8ce455da8dcec886a0e1e608da0fee7de67c8195b14517a8824a2a40c2d11fbf
|
||||
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
|
||||
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
|
||||
F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb
|
||||
@@ -547,7 +548,7 @@ F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0
|
||||
F src/test_bestindex.c 78809f11026f18a93fcfd798d9479cba37e1201c830260bf1edc674b2fa9b857
|
||||
F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31ce
|
||||
F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274
|
||||
F src/test_config.c 5ebafbcd5c75ac1c16bb0c8fe926dc325cc03e780943a88ca50e0d9a4fc4d2f5
|
||||
F src/test_config.c e25826d693039cdd45963de378cbf39e3af0e8aa7a8a6fc159876f4e7b5a4f8c
|
||||
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
|
||||
F src/test_demovfs.c 86142ba864d4297d54c5b2e972e74f3141ae4b30f05b3a95824184ed2d3d7f91
|
||||
F src/test_devsym.c 6109b45c3db3ef7b002320947ed448c027356ab8b885156ff535fd8684d4a571
|
||||
@@ -587,40 +588,40 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e
|
||||
F src/treeview.c cf03f9f6efb93288c7b9f17374ea48e4ce9111b0bc7e428d6850c3eee532b461
|
||||
F src/trigger.c bb034c08eca111e66a19cda045903a12547c1be2294b5570d794b869d9c44a73
|
||||
F src/treeview.c fc8c6c0a8a26afb3a97e3f844d65403dd27cf1450baf4415034fa4ccf00c4d7e
|
||||
F src/trigger.c d115eb6c1e2a22e116e0c6e34c35e5b2029238238e05b9708fe1567434da3230
|
||||
F src/update.c 3cb9150d2cf661d938e2f1b1749945f3faa767f88febdb739ab1793bbf895ff2
|
||||
F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
|
||||
F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507
|
||||
F src/util.c aef606a78b85d042138a841babbc0f98471b19b9a340b962e8fae307bc8cf3da
|
||||
F src/util.c fffdfa627be74d69ef425f92db124e7148af449bb8a3286e79577c42bca84061
|
||||
F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf
|
||||
F src/vdbe.c aaa36d1ac7d55baf007e9c03ee7c826834a51dfe7a56ba4c386318695dd87c99
|
||||
F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237
|
||||
F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17
|
||||
F src/vdbeapi.c f9161e5c77f512fbb80091ce8af621d19c9556bda5e734cffaac1198407400da
|
||||
F src/vdbeaux.c 3a803d75875031309204df90977059b12ffb706d16b4baa5e2d99f4353962582
|
||||
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
|
||||
F src/vdbemem.c f6f277d17d50972571d1394535d4c3d156fdea871d8f327f5b9479984054015a
|
||||
F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47
|
||||
F src/vdbe.c 237b6c27254449f0d703c5e20e4f8f2f8de0eb21bf72ce622efdd3aecd449ca1
|
||||
F src/vdbe.h 3f2b571e702e77e6bf031f0236e554aedfae643e991f69000320f481408455cf
|
||||
F src/vdbeInt.h e95de5129124d77f01439e6635012adfaf23c0017bff47296126143cf18bd0c6
|
||||
F src/vdbeapi.c 95001d0f84ee3cda344fed98ca0d7961deb4fc836b83495630d0af1f7cc4789e
|
||||
F src/vdbeaux.c 7ccf418141df1c7f87b0d69510523ae522abbe47c769d1b2c15120e88fac3eb9
|
||||
F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1
|
||||
F src/vdbemem.c 920285c3b7f5c64369e02da437dab71e9e91862df9c486541c14633739f91d75
|
||||
F src/vdbesort.c da75f505aba230060ce6472605a4aa6494f73eeb1071e1cc2643c3d4035e671b
|
||||
F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0
|
||||
F src/vtab.c 1fa256c6ddad7a81e2a4dc080d015d4b0a7135767717d311298e47f6fca64bb3
|
||||
F src/vtab.c 5a0b7193d586991b3db30e343d6b59959906bfe8658a6a0a85709b20ca50bb49
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c b09a2a9cab50efa08451a8c81d47052120ad5da174048c6d0b08d405384abdf2
|
||||
F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d
|
||||
F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
|
||||
F src/walker.c 7607f1a68130c028255d8d56094ea602fc402c79e1e35a46e6282849d90d5fe4
|
||||
F src/where.c 2f11eeb14335b7640f886b2fb441f54a94c35ab5cde8b53461a1074bfd587081
|
||||
F src/whereInt.h 1b728f71654ebf8421a1715497a587f02d6f538e819af58dc826908f8577e810
|
||||
F src/wherecode.c 37a1004237d630d785c47bba2290eac652a7a8b0047518eba3cb7c808b604c4a
|
||||
F src/whereexpr.c 5e559bdd24b06e3bc2e68f258bf751302954dc1e432daf71fdd8098a71462326
|
||||
F src/window.c 3408c0f606574d41033d461506bad68790239844b23e70610738a71152873d05
|
||||
F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd
|
||||
F src/where.c 10e21ac338582a4f87b2d09f09dd812c9bda0a0c4c456f54daeeee355afae733
|
||||
F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217
|
||||
F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b
|
||||
F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f
|
||||
F src/window.c 3ea716bb0dd5ffc8cdbaa48baffc525958b51bc61b2afd73a56baccfcd7ceb2f
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
F test/affinity2.test b03930d288e38b07f55023a58538ad174605695e98934bdab1facf6bd9ecc436
|
||||
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/aggnested.test 18b00de006597e960a6b27ccec51474ac66cf1070a87c1933e5694dc02190ef1
|
||||
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
||||
F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13
|
||||
F test/alter.test 93dee7c0ff9106fbd53a8bbf519107904b884050a99c4565412c58c37d68c802
|
||||
F test/alter.test 16ed8d2470193f34bc711e51506ff1211ebfab8025ca3b9510ff2aef139874cb
|
||||
F test/alter2.test a966ccfcddf9ce0a4e0e6ff1aca9e6e7948e0e242cd7e43fc091948521807687
|
||||
F test/alter3.test 4d79934d812eaeacc6f22781a080f8cfe012fdc3
|
||||
F test/alter4.test 7e93a21fe131e1dfeb317e90056856f96b10381fc7fe3a05e765569a23400433
|
||||
@@ -630,21 +631,19 @@ F test/altercol.test 54374d2ba18af25bb24e23acf18a60270d4ec120b7ec0558078b59d5aa1
|
||||
F test/alterlegacy.test 82022721ce0de29cedc9a7af63bc9fcc078b0ee000f8283b4b6ea9c3eab2f44b
|
||||
F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9
|
||||
F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b
|
||||
F test/altertab.test b6901287474841cffbd8f90b098d3bd7d8445868b42caeb01b27034698f7245f
|
||||
F test/altertab.test b2004ac589207fed7e19877bc3f1ad65142be482f269c176ee407e3b4a65f1a0
|
||||
F test/altertab2.test 8883693952f6d7fb5f754dbf1d694ed780aa883027bef04cb1fb99a3b88c9272
|
||||
F test/altertab3.test 7a2419829b2b908985b2c83d680388ef2eb9a74e446b68cee7b9b1551ae69078
|
||||
F test/altertab3.test c755ef31f8a61911331b46d71e43f6f3ef94af05c56314b168e47520355fa18e
|
||||
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
|
||||
F test/analyze.test 7168c8bffa5d5cbc53c05b7e9c7fcdd24b365a1bc5046ce80c45efa3c02e6b7c
|
||||
F test/analyze3.test ff62d9029e6deb2c914490c6b00caf7fae47cc85cdc046e4a0d0a4d4b87c71d8
|
||||
F test/analyze.test 547bb700f903107b38611b014ca645d6b5bb819f5210d7bf39c40802aafeb7d7
|
||||
F test/analyze3.test 01f0b122e3e54ad2544f14f7cc7dcb4c2cb8753cad5e88c6b8d49615b3fd6a2b
|
||||
F test/analyze4.test cdf88f3f72b0f0643a1ff6c730fc5af1e42464d47478d9fbac84c333f72c014e
|
||||
F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
|
||||
F test/analyze6.test 7b2667b879976ac4b90d8df80d5456328684f1f6f6fdef9469d6e53401f2f469
|
||||
F test/analyze7.test a37f4d9cb699a8af068ae02df1bb08bf844df8e98a92a8126cbff89e226879d8
|
||||
F test/analyze8.test e32a970564271114786703750e6939cf81dea4b8580874e38e9213ee092f6936
|
||||
F test/analyze5.test fa5131952303ac4146aba101b116b9c8cb89e2637531c334a6df7f7d19dddc0d
|
||||
F test/analyze6.test 6c3f7df2996cb6872f355a6ac1eb6d5de00a5a9288214bad7ef25c97d9cc72dc
|
||||
F test/analyze7.test 6ef0b12369f61ddeadc7d8a705c40e6b52cb29f63de3a4c56581b510b46b5783
|
||||
F test/analyze8.test 36ce54947710bd44e4f9484e1ad07e725ef01a9d7078b417c1bc884356febe4d
|
||||
F test/analyze9.test 9fbf0e0101eef4f5dc149769aa14e10b76ee06e7c28598264b32173cd1999a54
|
||||
F test/analyzeA.test 22a892d67bd2223126335b99774cce56ba91122cfe82446d2927afc43ad667dc
|
||||
F test/analyzeB.test a4c1c3048f6d9e090eb76e83eecb18bcf6d31a70
|
||||
F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93
|
||||
F test/analyzeC.test 489fe2ea3be3f17548e8dd895f1b41c9669b52de1b0861f5bffe6eec46eac710
|
||||
F test/analyzeD.test e50cd0b3e6063216cc0c88a1776e8645dc0bd65a6bb275769cbee33b7fd8d90c
|
||||
F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d
|
||||
F test/analyzeF.test 9e1a0537949eb5483642b1140a5c39e5b4025939024b935398471fa552f4dabb
|
||||
@@ -663,7 +662,7 @@ F test/attach2.test 256bd240da1835fb8408dd59fb7ef71f8358c7a756c46662434d11d07ba3
|
||||
F test/attach3.test c59d92791070c59272e00183b7353eeb94915976
|
||||
F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c
|
||||
F test/attachmalloc.test 12c4f028e570acf9e0a4b0b7fe6f536e21f3d5ebddcece423603d0569beaf438
|
||||
F test/auth.test 3310d9c08e928beca42d3eadaaf53cef619d9d275f598565a3758a21ce63138e
|
||||
F test/auth.test 2154625c05bc79f0e0ea72cb2358395a8041243caa0fd7ce7617d50da4331794
|
||||
F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1
|
||||
F test/auth3.test db21405b95257c24d29273b6b31d0efc59e1d337e3d5804ba2d1fd4897b1ae49
|
||||
F test/autoanalyze1.test b9cc3f32a990fa56669b668d237c6d53e983554ae80c0604992e18869a0b2dec
|
||||
@@ -725,9 +724,10 @@ F test/capi3d.test aba917805573a03deed961a21f07a5a84505ad0a616f7e3fc1508844a15bc
|
||||
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
|
||||
F test/cast.test 3619f0c58c2e4b2a94aa86e75607e497d34ef40ab74418e71aef7b4ca5155895
|
||||
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
|
||||
F test/check.test dcc952a127c394ce0de2aa634d26c78207e855327cc63a24d3638ca8fbfa641e
|
||||
F test/check.test e6527bed2b5557ffdbf5680765c4ae6fe61e9b68b7ee69a7f776787a4527b5da
|
||||
F test/checkfault.test da6cb3d50247169efcb20bdf57863a3ccfa1d27d9e55cd324f0680096970f014
|
||||
F test/chunksize.test 427d87791743486cbf0c3b8c625002f3255cb3a89c6eba655a98923b1387b760
|
||||
F test/close.test 799ea4599d2f5704b0a30f477d17c2c760d8523fa5d0c8be4a7df2a8cad787d8
|
||||
F test/close.test eccbad8ecd611d974cbf47278c3d4e5874faf02d811338d5d348af42d56d647c
|
||||
F test/closure01.test 9905883f1b171a4638f98fc764879f154e214a306d3d8daf412a15e7f3a9b1e0
|
||||
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
|
||||
F test/collate1.test f9b653f515ef3324a0c4e3c6adbf136bb1903622af678d482a60c11c9c054e6c
|
||||
@@ -742,7 +742,7 @@ F test/collate9.test 3adcc799229545940df2f25308dd1ad65869145a
|
||||
F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6
|
||||
F test/collateB.test 1e68906951b846570f29f20102ed91d29e634854ee47454d725f2151ecac0b95
|
||||
F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1
|
||||
F test/colname.test fb28b3687e03625425bc216edf8b186ce974aa71008e2aa1f426a7dcb75a601d
|
||||
F test/colname.test 87ad5458bb8709312dac0d6755fd30e8e4ca83298d0a9ef6e5c24277a3c3390e
|
||||
F test/conflict.test c7cc007e2af151516ddf38f7412fe10d473a694f55e3df437e2c7b31c2590e8d
|
||||
F test/conflict2.test bb0b94cf7196c64a3cbd815c66d3ee98c2fecd9c
|
||||
F test/conflict3.test a83db76a6c3503b2fa057c7bfb08c318d8a422202d8bc5b86226e078e5b49ff9
|
||||
@@ -767,7 +767,8 @@ F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454
|
||||
F test/corruptI.test a17bbf54fdde78d43cf3cc34b0057719fd4a173a3d824285b67dc5257c064c7b
|
||||
F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
|
||||
F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af
|
||||
F test/corruptL.test 15882a75d06de29df9ad33a3503eb0fe21efbd1afcd676949c0d82e1f4e55360
|
||||
F test/corruptL.test 865cb75ed971b72b5ee9ad9017befee6bd38794011cae69f00676d82c5a5dd69
|
||||
F test/corruptM.test 04a4061b1979283851953217e411187be79e50f5e5e3ef340c3f8e564173aae1
|
||||
F test/cost.test 51f4fcaae6e78ad5a57096831259ed6c760e2ac6876836e91c00030fad385b34
|
||||
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
|
||||
F test/countofview.test e17d6e6688cf74f22783c9ec6e788c0790ee4fbbaee713affd00b1ac0bb39b86
|
||||
@@ -793,11 +794,11 @@ F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
|
||||
F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10
|
||||
F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603
|
||||
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
|
||||
F test/dbfuzz001.test e32d14465f1c77712896fda6a1ccc0f037b481c191c1696a9c44f6c9e4964faf
|
||||
F test/dbfuzz001.test 42aad1dcef6219fbee86a9b7d08832c9bbb2e41508f6f128ae91745927276292
|
||||
F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee
|
||||
F test/dbfuzz2.c b93db9056ad057733463ba333f89d2d195a95155805065c5962422955d7fb011
|
||||
F test/dbfuzz2.c c2c9cb40082a77b7e95ffb8b2da1e93322efadfb1c8c1e0001c95a0af1e156c2
|
||||
F test/dbpage.test 650234ba683b9d82b899c6c51439819787e7609f17a0cc40e0080a7b6443bc38
|
||||
F test/dbstatus.test cd83aa623b8aab477269bc94cf8aa90c1e195a144561dd04a1620770aaa8524e
|
||||
F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759
|
||||
F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef
|
||||
F test/default.test 3e46c421eebefd2787c2f96673efabf792d360f3a1d5073918cbe450ce672a62
|
||||
F test/delete.test 31832b0c45ecb51a54348c68db173be462985901e6ed7f403d6d7a8f70ab4ef0
|
||||
@@ -810,7 +811,7 @@ F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
|
||||
F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
|
||||
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
|
||||
F test/distinct.test a1783b960ad8c15a77cd9f207be072898db1026c
|
||||
F test/distinct2.test df0bb52b754661ea84ec9ff488d48913c97bd31d83ca17ce0bf1334645e660cf
|
||||
F test/distinct2.test b854b442111bf362328981f55d39d0df13140383b112057f6e046e311f14e5c3
|
||||
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
|
||||
F test/e_blobbytes.test 439a945953b35cb6948a552edaec4dc31fd70a05
|
||||
F test/e_blobclose.test 4b3c8c60c2171164d472059c73e9f3c1844bb66d
|
||||
@@ -856,6 +857,10 @@ F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79
|
||||
F test/fallocate.test 37a62e396a68eeede8f8d2ecf23573a80faceb630788d314d0a073d862616717
|
||||
F test/filectrl.test 6e871c2d35dead1d9a88e176e8d2ca094fec6bb3
|
||||
F test/filefmt.test f393e80c4b8d493b7a7f8f3809a8425bbf4292af1f5140f01cb1427798a2bbd4
|
||||
F test/filter1.test 94a6d26588db0e4e7305e1f0985a99405e98dd034dc393dd6264603eed6645d4
|
||||
F test/filter2.tcl 44e525497ce07382915f01bd29ffd0fa49dab3adb87253b5e5103ba8f93393e8
|
||||
F test/filter2.test 485cf95d1f6d6ceee5632201ca52a71868599836f430cdee42e5f7f14666e30a
|
||||
F test/filterfault.test c08fb491d698e8df6c122c98f7db1c65ffcfcad2c1ab0e07fa8a5be1b34eaa8b
|
||||
F test/fkey1.test d11dbb8a93ead9b5c46ae5d02da016d61245d47662fb2d844c99214f6163f768
|
||||
F test/fkey2.test d35d1c81e7569bdd2b872e91750f7098117d2e8291369f70b7e3d50a0e523dc2
|
||||
F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
|
||||
@@ -863,7 +868,7 @@ F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
|
||||
F test/fkey5.test 24dd28eb3d9f1b5a174f47e9899ace5facb08373a4223593c8c631e6cf9f7d5a
|
||||
F test/fkey6.test d078a1e323a740062bed38df32b8a736fd320dc0
|
||||
F test/fkey7.test 64fb28da03da5dfe3cdef5967aa7e832c2507bf7fb8f0780cacbca1f2338d031
|
||||
F test/fkey8.test 1d44df25d3b9cba72db4b4324201daf6ae1fc8a85cb68146bd6669a977d8867d
|
||||
F test/fkey8.test 48ef829d63f5f7b37aabd4df9363ac05f65539d1da8c4a44251631769d920579
|
||||
F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749
|
||||
F test/fordelete.test eb93a2f34137bb87bdab88fcab06c0bd92719aff
|
||||
F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb
|
||||
@@ -930,8 +935,8 @@ F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f
|
||||
F test/fts3corrupt.test 46b9ddda7f6588fd5a5b1f4bb4fc0618dc45010e7dddb8a3a188baf3197177ae
|
||||
F test/fts3corrupt2.test bf55c3fa0b0dc8ea1c0fe5543623bd27714585da6a129038fd6999fe3b0d25f3
|
||||
F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f
|
||||
F test/fts3corrupt4.test c311911898e9ddac93fe71b947660a9716b285e2e600ad02810c231ff79a5925
|
||||
F test/fts3corrupt5.test 1911bd38381fe7eb28b204e7171937d09e113e5ceb018399ded9f42ec7e6ae66
|
||||
F test/fts3corrupt4.test d5389e14950e57333bfc972f262c90b5ba0e864a958df9e437e3aacd3a5570a7
|
||||
F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5
|
||||
F test/fts3cov.test cb932743da52a1c79a1ab8983e26c8121cf02263d6ff16e1f642e6f9b8348338
|
||||
F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f
|
||||
F test/fts3defer.test f4c20e4c7153d20a98ee49ee5f3faef624fefc9a067f8d8d629db380c4d9f1de
|
||||
@@ -943,7 +948,7 @@ F test/fts3expr.test ebae205a7a89446c32583bcd492dcb817b9f6b31819bb4dde2583bb99c7
|
||||
F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a
|
||||
F test/fts3expr3.test c4d4a7d6327418428c96e0a3a1137c251b8dfbf8
|
||||
F test/fts3expr4.test f5b2832549f01b1f7f73389fa21d4b875499bc95bf7c8b36271844888c6a0938
|
||||
F test/fts3expr5.test 1368738e3298a7ce0dee3a44d6ebb8f468b2a76f3d1dd18d4ea6d8bc2eeccc1b
|
||||
F test/fts3expr5.test a5b9a053becbdb8e973fbf4d6d3abaabeb42d511d1848bd57931f3e0a1cf983e
|
||||
F test/fts3fault.test 798e45af84be7978ca33d5bdc94246eb44724db24174b5d8e9b1ac46c57fb08d
|
||||
F test/fts3fault2.test 6a17a11d8034b1c4eca9f3091649273d56c49ff049e2173df8060f94341e9da0
|
||||
F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641
|
||||
@@ -960,7 +965,7 @@ F test/fts3query.test ca033ff2ebcc22c69d89032fb0bc1850997d31e7e60ecd26440796ba16
|
||||
F test/fts3rank.test cd99bc83a3c923c8d52afd90d86979cf05fc41849f892faeac3988055ef37b99
|
||||
F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0
|
||||
F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e
|
||||
F test/fts3snippet.test dace744104d1a44dc12dc9dd10b8d7542342df503d96942b7c4a55034e761789
|
||||
F test/fts3snippet.test 430bb5ace2b31ccd99de4d71775d956da832c114c4b3e39589748f114458647c
|
||||
F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca
|
||||
F test/fts3tok1.test a663f4cac22a9505400bc22aacb818d7055240409c28729669ea7d4cc2120d15
|
||||
F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d
|
||||
@@ -981,11 +986,11 @@ F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b
|
||||
F test/fts4noti.test 5553d7bb2e20bf4a06b23e849352efc022ce6309
|
||||
F test/fts4onepass.test d69ddc4ee3415e40b0c5d1d0408488a87614d4f63ba9c44f3e52db541d6b7cc7
|
||||
F test/fts4opt.test 0fd0cc84000743ff2a883b9b84b4a5be07249f0ba790c8848a757164cdd46b2a
|
||||
F test/fts4rename.test 6015a355ec3a11a51eb5b88802b3b2c1788786c54b77b17f3e077b7c93ff8611
|
||||
F test/fts4rename.test 15fd9985c2bce6dea20da2245b22029ec89bd4710ed317c4c53abbe3cfd0c880
|
||||
F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f757380429
|
||||
F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95
|
||||
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
|
||||
F test/func.test e4313baba80bf933e58eb89a7c617bec0f0c348c862b096ec4387f36e05ad0a6
|
||||
F test/func.test 0889128141b99b38aa9ce78445acfc4c1f9fbe9aa4f51d4c6aff88ae43cf125b
|
||||
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
|
||||
F test/func3.test 2bb0f31ab7baaed690b962a88544d7be6b34fa389364bc36a44e441ed3e3f1e6
|
||||
F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f
|
||||
@@ -998,15 +1003,15 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c
|
||||
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
|
||||
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
|
||||
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
|
||||
F test/fuzzcheck.c d0e76671ea5c3a766768b65d69f7d755aa614a98c17b84fa4496f4cd2e2fa515
|
||||
F test/fuzzcheck.c 3ad76298a80cda31d270dc5e4f31194fa38d507d3e9b3f355cf1c283895cd5a5
|
||||
F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664
|
||||
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
|
||||
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||
F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e42ed2
|
||||
F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5
|
||||
F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7
|
||||
F test/fuzzdata7.db babb1c560fef766171972c119c1bc3b7be20b134e2f46ae0c52390cd3059b6f4
|
||||
F test/fuzzdata8.db c69ca6d4bf1b25fd56ab432e9b96f2db0da752cfc6aa32700867f3a2d8a0514a
|
||||
F test/fuzzdata7.db e7a86fd83dda151d160445d542e32e5c6019c541b3a74c2a525b6ac640639711
|
||||
F test/fuzzdata8.db dc52be9b732f5bc1cdc0db0ff5b8e69b87bc8989b13a94eb8acaef63897a007c
|
||||
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
|
||||
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
|
||||
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
|
||||
@@ -1024,7 +1029,7 @@ F test/in.test 63e642e97bc22c8fd970752fb4f0b3992a957003ea87524fe69e5a700500c500
|
||||
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
|
||||
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
|
||||
F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068
|
||||
F test/in5.test 7ae37fcd4a5e198291c6ab5f31a5bb3d15397efe8b75a6736d7a95a7b8dd9e08
|
||||
F test/in5.test b32ce7f4a93f44c5dee94af16886d922cc16ebe33c8e1765c73d4049d0f4b40f
|
||||
F test/in6.test 62d943a02f722948f4410ee0b53c3cb39acd7c41afb083df8d7004238fe90a20
|
||||
F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822
|
||||
F test/incrblob2.test a494c9e848560039a23974b9119cfc2cf3ad3bd15cc2694ee6367ae537ef8f1f
|
||||
@@ -1042,16 +1047,16 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407
|
||||
F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0
|
||||
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
|
||||
F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7
|
||||
F test/index6.test a6cf96bb70bf57b2221e102060a18af46bc366f704722f410d6f42c13a75534a
|
||||
F test/index7.test 2222ccd1858097f734d6ac3d39117334fd1cc26460f92fced4ef57cd15c940c1
|
||||
F test/index6.test 7883c35749e3f38282572194ffdbe7d025b1e2938c1e67da2d408ff3c27d9a46
|
||||
F test/index7.test 1d764c0cca45f5a76150b08e127ccc8d52492cfa788b5fafed4be784a351b020
|
||||
F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
|
||||
F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721
|
||||
F test/indexedby.test a52c8c6abfae4fbfb51d99440de4ca1840dbacc606b05e29328a2a8ba7cd914e
|
||||
F test/indexexpr1.test 635261197bcdc19b9b2c59bbfa7227d525c00e9587faddb2d293c44d287ce60e
|
||||
F test/indexexpr1.test 0f293369ed6f56764cfc3db05685d45469d9e685ba87e3698527049ba359ae24
|
||||
F test/indexexpr2.test d319e7d1b1043403f39a20c892d512e02b5549c6004806b977030f2430c60208
|
||||
F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811
|
||||
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
F test/insert.test 9773604f8e1a2595f51488a5643c359d8a11dc55a11cb185910d93387d378458
|
||||
F test/insert.test 72004f6a900a25bd3f1ce9a72e73d02749644666a8ce6d6d2dba061137e5aa63
|
||||
F test/insert2.test 4d14b8f1b810a41995f6286b64a6943215d52208
|
||||
F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
|
||||
F test/insert4.test 7802ada6ba8738661b9f6c0e26858d3375b40cc7180289fd350644cd7a08fec9
|
||||
@@ -1059,11 +1064,11 @@ F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
|
||||
F test/insertfault.test ac63d14ea3b49c573673a572f4014b9117383a03e497c58f308b5c776e4a7f74
|
||||
F test/instr.test 9a8802f28437d8ade53fedfc47b2ca599b4e48ba
|
||||
F test/instrfault.test 0f870b218ea17cd477bb19ed330eecdb460dd53a
|
||||
F test/intarray.test 8319986182af37c8eb4879c6bfe9cf0074e9d43b193a4c728a0efa3417c53fb7
|
||||
F test/intarray.test bb976b0b3df0ebb6a2eddfb61768280440e672beba5460ed49679ea984ccf440
|
||||
F test/interrupt.test 16ea879ec728cb76414c148c5f24afd5d1f91054
|
||||
F test/interrupt2.test e4408ca770a6feafbadb0801e54a0dcd1a8d108d
|
||||
F test/intpkey.test ac71107a49a06492b69b82aafaf225400598d3c8
|
||||
F test/intreal.test 2c80b5c90c597e65c6606b333515261c73a534b6c527b7009e97ed6b78f8b79a
|
||||
F test/intreal.test 2a87e85a5949bd55e41ef04c58f5800587c5380bdbc559ff1c79b614b0e6a533
|
||||
F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc
|
||||
F test/ioerr.test 470fcc78e9cd352d162baf782fe301ea807d764241f58a48fc58109c2dfcdb6b
|
||||
F test/ioerr2.test 2593563599e2cc6b6b4fcf5878b177bdd5d8df26
|
||||
@@ -1072,7 +1077,7 @@ F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
|
||||
F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
|
||||
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
|
||||
F test/istrue.test 75327829744e65cc8700e69340b8e6c192e10e39dfae7ccb0e970d3c4f49090a
|
||||
F test/join.test d53a3662762eff50b65da8775201e609878a27dd0885a1ae7bcde9bb46cecbc5
|
||||
F test/join.test f505c78a793b0c807d534c1cacf71c7bf96aa734f78d091721f2a6859077b7e8
|
||||
F test/join2.test 10f7047e723ebd68b2f47189be8eed20451a6f665d8bf46f1774c640d1062417
|
||||
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
|
||||
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
|
||||
@@ -1087,13 +1092,13 @@ F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
||||
F test/json101.test 8f8977b00ba02f9a26c1d1f52f29f540f6d5eb162cbd5eb78bb805366d4ab26d
|
||||
F test/json102.test eeb54efa221e50b74a2d6fb9259963b48d7414dca3ce2fdfdeed45cb28487bc1
|
||||
F test/json103.test aff6b7a4c17d5a20b487a7bc1a274bfdc63b829413bdfb83bedac42ec7f67e3b
|
||||
F test/json104.test cf0dbd220cba81e6c3cf8bc326e2321049cec05ab0b529308d76f28a52529800
|
||||
F test/json104.test 317f4ec4b2d87afbba4d2460cf5be297aea76f2285eb618d276dbcd40a50950f
|
||||
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
||||
F test/kvtest.c 94da54bb66aae7a54e47cf7e4ea4acecc0f217560f79ad3abfcc0361d6d557ba
|
||||
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
||||
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
|
||||
F test/lemon-test01.y 58b764610fd934e189ffbb0bbfa33d171b9cb06019b55bdc04d090d6767e11d7
|
||||
F test/like.test 5013f18e7242fe118524fcf8e484b8827bcd5906b509d106f3587c7bfcf274ae
|
||||
F test/like.test 3d702d79bf871fa32985b1ce334294c587e3948d3ab972001e811a58577e8b3c
|
||||
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
|
||||
F test/like3.test 62bf82ac674b7d4126e73532e1ad96cdcd8e1752a4ed90b28a6f98305f5a66aa
|
||||
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
|
||||
@@ -1119,7 +1124,7 @@ F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
|
||||
F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a
|
||||
F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d
|
||||
F test/malloc9.test 2307c6ee3703b0a21391f3ea92388b4b73f9105e
|
||||
F test/mallocA.test 672cd7dedb63771bade3a6f557f851a4ad161d4a
|
||||
F test/mallocA.test aea76f2dd8bcc2d19748f6b911e876cefda74a563753bf26af046e9d34bb97e6
|
||||
F test/mallocAll.test 98f1be74bc9f49a858bc4f361fc58e26486798be
|
||||
F test/mallocB.test bc475ab850cda896142ab935bbfbc74c24e51ed6
|
||||
F test/mallocC.test 3dffe16532f109293ce1ccecd0c31dca55ef08c4
|
||||
@@ -1145,7 +1150,7 @@ F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08
|
||||
F test/minmax.test 6751e87b409fe11b02e70a306d846fa544e25a41
|
||||
F test/minmax2.test dae92964ac87c1d2ef978c582e81a95e11c00f1cbef68980bfb2abaf10315063
|
||||
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
|
||||
F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f
|
||||
F test/minmax4.test 272ca395257f05937dc96441c9dde4bc9fbf116a8d4fa02baeb0d13d50e36c87
|
||||
F test/misc1.test 7ce84b25df9872e7d7878613a96815d2ba5bc974ac4e15a50118dde8f3917599
|
||||
F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d
|
||||
F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d
|
||||
@@ -1177,6 +1182,7 @@ F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161
|
||||
F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
|
||||
F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18
|
||||
F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3
|
||||
F test/nulls1.test 5b978fbae9c73b497608c16f2636a2f71de6e2c914e4c78955cf022e39b7a0d5
|
||||
F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1
|
||||
F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823
|
||||
F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2
|
||||
@@ -1211,12 +1217,12 @@ F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
F test/permutations.test 4282fb00e5ac0f8c2cd1be62652f6da4ac03ce3c58b7d785fa17f4684492a0e0
|
||||
F test/pg_common.tcl 4740dc35190d6acdab14c097783331361301ab504a94d948f6afbb56ce0a51e8
|
||||
F test/pg_common.tcl 222a1bad1c41c308fa366313cd7b51b3be7e9b21c8736a421b974ac941693b54
|
||||
F test/pragma.test cf066fe0f7f5d49f4758de4986407b8676c61aaa7871599340d64f42a8edc352
|
||||
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
|
||||
F test/pragma3.test 8300aa9c63cff1027006ca34bf413a148abbd6dcd471fa9a1ded322fe18c0df9
|
||||
F test/pragma4.test 1cb4b32f1a304ed9e291d7c4d49c91c2c8dc1b9450e6d2c1198b2cc895d40d77
|
||||
F test/pragma5.test 824ce6ced5d6b7ec71abe37fc6005ff836fe39d638273dc5192b39864b9ee983
|
||||
F test/pragma5.test 2be6a44c91e8585ccb4c71c5f221ccebe0692a49557215a912916ed391188959
|
||||
F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8
|
||||
F test/prefixes.test b524a1c44bffec225b9aec98bd728480352aa8532ac4c15771fb85e8beef65d9
|
||||
F test/printf.test 0300699733e53101b2ce48800518427249edd4053bb50fa0621c6607482f0fdb
|
||||
@@ -1239,7 +1245,7 @@ F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
|
||||
F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c
|
||||
F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d
|
||||
F test/releasetest.tcl 968fc1e8fd23e113fb8a04379747f3a9f2c12d207b2de85aeff5a825962e1cd7 x
|
||||
F test/releasetest_data.tcl 146a73e8c8212f962b6558fee0711b895f11b607ee0610e6910781dc8f83797d
|
||||
F test/releasetest_data.tcl 4f55292d7e3e7995754373612a16b71f41be22dfded3a0375ccaf65c465d3765
|
||||
F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5eeb2b
|
||||
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
|
||||
F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
|
||||
@@ -1249,7 +1255,7 @@ F test/round1.test 768018b04522ca420b1aba8a24bd76091d269f3bce3902af3ec6ebcee41ab
|
||||
F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc
|
||||
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
|
||||
F test/rowid.test bfbd7b97d9267660be3c8f28507c4ed7f205196b8877c0db42df347c2e8845e3
|
||||
F test/rowvalue.test b8680f07d19c8c5223b808bba998faffcec6d505f5689ff6070280119173bb51
|
||||
F test/rowvalue.test a3e729d5c1f32da03bba15af1e3128218d2ba3c40d4f4ed5fa0497a713df68ea
|
||||
F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b
|
||||
F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256
|
||||
F test/rowvalue4.test 02e35f7762371c2f57ebd856aa056eac56cb27ef7715a0bb31eac1895a745356
|
||||
@@ -1269,7 +1275,7 @@ F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7
|
||||
F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa
|
||||
F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2
|
||||
F test/scanstatus.test 874e35011779b07725a47dbf1dd6282b0ca04af7e028fb0b534ee544b571be42
|
||||
F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481
|
||||
F test/schema.test 5dd11c96ba64744de955315d2e4f8992e447533690153b93377dffb2a5ef5431
|
||||
F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5
|
||||
F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38
|
||||
F test/schema4.test 3b26c9fa916abb6dadf894137adcf41b7796f7b9
|
||||
@@ -1278,7 +1284,7 @@ F test/schema6.test e4bd1f23d368695eb9e7b51ef6e02ca0642ea2ab4a52579959826b5e7dce
|
||||
F test/schemafault.test 1936bceca55ac82c5efbcc9fc91a1933e45c8d1e1d106b9a7e56c972a5a2a51e
|
||||
F test/securedel.test 2f70b2449186a1921bd01ec9da407fbfa98c3a7a5521854c300c194b2ff09384
|
||||
F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
|
||||
F test/select1.test 7d41f354998524070317207d4e2b68e725e4cf14a57835fc746d4bea686a8714
|
||||
F test/select1.test 703154cbf66d0a9fbbd5b771dc3d2c4d3700121d133d695958d4a9c5a33251e8
|
||||
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
|
||||
F test/select3.test 3905450067c28766bc83ee397f6d87342de868baa60f2bcfd00f286dfbd62cb9
|
||||
F test/select4.test 5389d9895968d1196c457d59b3ee6515d771d328
|
||||
@@ -1323,7 +1329,7 @@ F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
||||
F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
|
||||
F test/shrink.test 1b4330b1fd9e818c04726d45cb28db73087535ce
|
||||
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
|
||||
F test/skipscan1.test b1fef3046d555836712d4a3a7c8ae8193356c6a15bee59cb3976e4ee98596c97
|
||||
F test/skipscan1.test 2a64ca7b3e6246bb86b47c9051bfd324603b1b60675fe606513535267713e080
|
||||
F test/skipscan2.test 3eb703ce794f139e7b83567911046298bcde29606116727f9b700ce34f559d2d
|
||||
F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5
|
||||
F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2
|
||||
@@ -1383,9 +1389,9 @@ F test/tabfunc01.test 20e98ffe55f35d8d33fd834ca8bf9d4b637e560af8fcd00464b4154d90
|
||||
F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132
|
||||
F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4
|
||||
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
||||
F test/tclsqlite.test 5a06962d8f18edf4703931f6b7dacd83678d02fa5c8ced9a7958c007ad58626a
|
||||
F test/tclsqlite.test f9acb83122be0a7c4997ab7f17742507874dced95144c20217c2428553f110bb
|
||||
F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08
|
||||
F test/tempdb2.test 2479226e4cb96f4c663eccd2d12c077cf6bda29ca5cc69a8a58a06127105dd62
|
||||
F test/tempdb2.test 353864e96fd3ae2f70773d0ffbf8b1fe48589b02c2ec05013b540879410c3440
|
||||
F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900
|
||||
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
||||
F test/temptable2.test d2940417496e2b9548e01d09990763fbe88c316504033256d51493e1f1a5ce6a
|
||||
@@ -1451,7 +1457,7 @@ F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898
|
||||
F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d
|
||||
F test/tkt-c48d99d690.test ba61977d62ab612fc515b3c488a6fbd6464a2447
|
||||
F test/tkt-c694113d5.test 82c461924ada5c14866c47e85535b0b0923ba16a2e907e370061a5ca77f65d77
|
||||
F test/tkt-cbd054fa6b.test 06ccd57af3c0c7895d0f7dc844f13c51f8258885
|
||||
F test/tkt-cbd054fa6b.test 708475ef4d730a6853512c8ce363bcbd3becf0e26826e1f4cd46e2f52ff38edf
|
||||
F test/tkt-d11f09d36e.test d999b548fef885d1d1afa49a0e8544ecf436869d
|
||||
F test/tkt-d635236375.test 9d37e988b47d87505bc9445be0ca447002df5d09
|
||||
F test/tkt-d82e3f3721.test bcc0dfba658d15bab30fd4a9320c9e35d214ce30
|
||||
@@ -1566,7 +1572,7 @@ F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4
|
||||
F test/trigger9.test 2226ec795a33b0460ab5cf8891e9054cc7edef41
|
||||
F test/triggerA.test 837be862d8721f903dba3f3ceff05b32e0bee5214cf6ea3da5fadf12d3650e9d
|
||||
F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe
|
||||
F test/triggerC.test f1210921924f3a6aaa8c1538115fe56c9c448e8e3033bf0dab38ae78db937c41
|
||||
F test/triggerC.test 29f5a28d0fe39e6e2c01f6e1f53f08c0955170ae10a63ad023e33cb0a1682a51
|
||||
F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650
|
||||
F test/triggerE.test ede2e4bce4ba802337bd69d39447fa04a938e06d84a8bfc53c76850fc36ed86d
|
||||
F test/triggerF.test 5d76f0a8c428ff87a4d5ed52da06f6096a2c787a1e21b846111dfac4123de3ad
|
||||
@@ -1605,8 +1611,8 @@ F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2
|
||||
F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2
|
||||
F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62
|
||||
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
|
||||
F test/view.test 40d54c9ddf5b9fdee692bf936d3352159fe467838f92742aa1d08c7c7d1eac73
|
||||
F test/vtab1.test 47b935205d7b6290765973abd6fce0e13e94e040017099170f43f81886efa5ba
|
||||
F test/view.test 10ea54300a097d7c0337fd104abffe4a4786d1598b94017a37efe0e0d3e04dd5
|
||||
F test/vtab1.test c5d9e90ed02bcacd776dcbb7360199d290f7f53c26b484ddece543060c54319f
|
||||
F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082
|
||||
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
|
||||
F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3
|
||||
@@ -1621,7 +1627,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292
|
||||
F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96
|
||||
F test/vtabE.test 2a143fe75a11275781d1fd1988d86b66a3f69cb98f4add62e3da8fd0f637b45f
|
||||
F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b
|
||||
F test/vtabH.test e65540eed0f7434cdf0b160374570b51f3e3179548f0fa5e99b1d33f8dcdf9a0
|
||||
F test/vtabH.test 2efb5a24b0bb50796b21eca23032cfb77abfa4b0c03938e38ce5897abac404ca
|
||||
F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f
|
||||
F test/vtabJ.test d7b73675708cf63cfcb9d443bb451fc01a028347275b7311e51f9fdf3ca6757f
|
||||
F test/vtab_alter.test 736e66fb5ec7b4fee58229aa3ada2f27ec58bc58c00edae4836890c3784c6783
|
||||
@@ -1662,10 +1668,10 @@ F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cf
|
||||
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
|
||||
F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
|
||||
F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
|
||||
F test/walvfs.test c0faffda13d045a96dfc541347886bb1a3d6f3205857fc98e683edfab766ea88
|
||||
F test/walvfs.test f1accd66c876e3a0f6b4bef5b18d13411062d0ff0a0016e32bb41570474e99fc
|
||||
F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec
|
||||
F test/wapptest.tcl 56d2b7974ecd8cca3189a670f757306d5ff3334cc9fe3744f7a6ad7ae4380e8c x
|
||||
F test/where.test 0607caa5a1fbfe7b93b95705981b463a3a0408038f22ae6e9dc11b36902b0e95
|
||||
F test/wapptest.tcl 3090239c59379d41e1a0644feb6683082fdb86edfab0c668973f8003f22c0e5d x
|
||||
F test/where.test 19c709c9f0f6ed12c23f909f6592aa55fba34269d5a2898537aa27a22b9ce650
|
||||
F test/where2.test 478d2170637b9211f593120648858593bf2445a1
|
||||
F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c
|
||||
F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8
|
||||
@@ -1673,14 +1679,14 @@ F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
|
||||
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
|
||||
F test/where7.test 75722434c486ac9e74718caa6cce234f45ba34c0b6c0f9555b29eb8bb5f6ade1
|
||||
F test/where8.test 461ca40265ed996a6305da99bb024b0e41602bb586acf544c08f95922358e49f
|
||||
F test/where9.test 4fb43ad451758d9535693e110d4398fb6a6e3e153dc57bba5e61f884566c725f
|
||||
F test/where9.test 2c554b97bbdb2fdf26c57099f60db8a52bfcf7c147f2c256f9798fa0e267ca85
|
||||
F test/whereA.test 6c6a420ca7d313242f9b1bd471dc80e4d0f8323700ba9c78df0bb843d4daa3b4
|
||||
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
|
||||
F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6
|
||||
F test/whereD.test 711d4df58d6d4fb9b3f5ce040b818564198be002
|
||||
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
|
||||
F test/whereF.test 3d9412b1199d3e2bed34fcb76b4c48d0bf4df95d27e3f8dd27b6f8b4716d0d89
|
||||
F test/whereG.test 0158783235a6dd82fc0e37652b8522b186b9510594ac0a4bff0c4101b4396a52
|
||||
F test/whereG.test 4cda56de49f0c7d9a4f2590a3ddc5f79a7f2a03d2229d0f5bb5d3981ce57f293
|
||||
F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
|
||||
F test/whereI.test a2874062140ed4aba9ffae76e6190a3df6fc73d1373fdfa8fd632945082a5364
|
||||
F test/whereJ.test 88287550f6ee604422403b053455b1ad894eeaa5c35d348532dfa1439286cb9a
|
||||
@@ -1690,39 +1696,39 @@ F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864
|
||||
F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3
|
||||
F test/wherelimit.test 592081800806d297dd7449b1030c863d2883d6d42901837ccd2e5a9bd962edb0
|
||||
F test/wherelimit2.test 9bf0aa56cca40ea0e4c5e2915341355a2bbc0859ec4ce1589197fe2a9d94635f
|
||||
F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
|
||||
F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2aeee74
|
||||
F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
|
||||
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
|
||||
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
|
||||
F test/window1.test 8d453bfaa3f8f0873ba16ca1270c7368f18445065a0003a1b5954ac4e95797b4
|
||||
F test/window2.tcl 0c2918ef2a1640553fd791972d458356808a608418c64c02a0a379cecfc7fb0d
|
||||
F test/window2.test 96ef949f0197c025652f6c6e5812cdbfb948989bd40cf79cbb02104249a89513
|
||||
F test/window1.test 376a7c9c5b9df9868d92a6d9d455262e1b769f4410b19006f5f8c5507c2a7ed7
|
||||
F test/window2.tcl a44834af6267be6e14882311ef8790bf5047f1b9bc25685ee1762d48dc24f1e7
|
||||
F test/window2.test 2f3ae63e171dce7f2ac29a41020f4da413b1d7bdaba48ee124fd336b152e34c5
|
||||
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
|
||||
F test/window3.test e9959a993c8a71e96433be8daaa1827d78b8921e4f12debd7bdbeb3c856ef3cb
|
||||
F test/window4.tcl 5fbaab489677914ee5686b2008426e336daf88a2f58be7df92757f780a5ebf91
|
||||
F test/window4.test bf8f86586ce101bf98e2306e597fa24aadc96c58d70ba4d11f956cf8ca4e0be3
|
||||
F test/window4.tcl d732df0e81beedc0ba8a563ade68611d322d27303ad0c0c8e4444107c39e84ec
|
||||
F test/window4.test 807f3e6b15f9338e5b9742b87c5c7ca825b42b9657fde6096e890119370848e0
|
||||
F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652821e
|
||||
F test/window6.test 465e608c021020fb0948a90200e154cd787bc910449e3dafee44c9ca5bd407fe
|
||||
F test/window6.test f8d674254b23289cc17c84d79dec7eda7caa1dfb7836c43122cfdf3640d1df32
|
||||
F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d76108f
|
||||
F test/window7.test ce7f865241fdd1c5c4db869cd7bb2986c3be836bc2e73649a6846dd920f63e0f
|
||||
F test/window8.tcl 9e9a82ae9eea90a4a83481d641a812b974980c38f9247f3b89a6e3c8bed45518
|
||||
F test/window8.test df187dc19921f7be0ab709d531d681bd80ccaac96a913a89ecee8b272b91d43f
|
||||
F test/window9.test 06495ac733843849b1fca8a79d13ba330d04aba02099703198af2ba7e231f90c
|
||||
F test/windowerr.tcl abf4d6d0c6d360213af98ed7d538295d905689e83692106f3ece0e3afb9d7f36
|
||||
F test/windowerr.test 675b5e6debfc9370bfacb0b91e2a93a8923512f92600b16f4ea70a1cd9b8e6e4
|
||||
F test/windowfault.test 403693d7d951c5473f052f7ecddb61ed15ac9d212f238b8904ea270ba90f83e5
|
||||
F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd
|
||||
F test/window8.tcl 5884cc884f9605bf88c0d18a534894bf9342f72687bf1bc43ed0cab4c8af7973
|
||||
F test/window8.test 48590f3737d17eec503d77769c13ead15d12e8819820b1dc68afe8a3c5bc3250
|
||||
F test/window9.test 20a6b590be718b6bc98a5356d4396d6cdf19329c547da084fa225b92d68e1693
|
||||
F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0
|
||||
F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b
|
||||
F test/windowfault.test a90b397837209f15e54afa62e8be39b2759a0101fae04e05a08bcc50e243a452
|
||||
F test/with1.test d32792084dcb5f6c047d77bb8a032822ef9fe050ade07d0aeffa37753a05e3c9
|
||||
F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab
|
||||
F test/with3.test b5f1372097690c6ef84db2f13fc7e64a88c7263c3f88493605f90597e8a68d45
|
||||
F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
|
||||
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
|
||||
F test/without_rowid1.test 89d101a7c6e0802882002cf3713f405319ddb6b9f08449dcc08c6082c995cab1
|
||||
F test/without_rowid1.test f40c2757272ce171b88e4227f14450db2c4d42800d447baa7656a65562d2f8d9
|
||||
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
|
||||
F test/without_rowid3.test ea4b59dd1b0d7f5f5e4b7cca978cdb905752a9d7c57dc4344a591dba765a3691
|
||||
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
|
||||
F test/without_rowid5.test 89b1c587bd92a0590e440da33e7666bf4891572a
|
||||
F test/without_rowid6.test 1f99644e6508447fb050f73697350c7ceca3392e
|
||||
F test/without_rowid6.test 3c1bbf0eb81c672115933158b62b009e67cf1a7f8c2c612bbce63a7385efa18e
|
||||
F test/without_rowid7.test 0e0d7be00f05f54898e20e07bcc947cd97b42d7106021fa0d2897324bc6d330e
|
||||
F test/wordcount.c d721a4b6fae93e6e33449700bce1686bc23257c27425bc3ef1599dc912adec66
|
||||
F test/writecrash.test f1da7f7adfe8d7f09ea79b42e5ca6dcc41102f27f8e334ad71539501ddd910cc
|
||||
F test/zeroblob.test 07a5b11ab591d1f26c626945fb7f228f68b993533b2ada77273edf6ee29db174
|
||||
@@ -1751,7 +1757,7 @@ F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
||||
F tool/index_usage.c 9ec344d29cbeb03fdc0fce668eedfb7495792170de933adf95cf8d6904a166ad
|
||||
F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f
|
||||
F tool/lemon.c cc43148d2793ab93668e74a6a6319bb71c2e65c1ffcd6deeaa59e12be9362a43
|
||||
F tool/lempar.c 61af95b8fac2bfd59c09d55330e78f3f5e352d7aa80bf37404b96ef795be3fdc
|
||||
F tool/lempar.c 4b868d0a5eb9a67cd1b546274227c0d449dad073c663b331b686fa2253e1c86f
|
||||
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
|
||||
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
||||
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
|
||||
@@ -1759,12 +1765,12 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
|
||||
F tool/mkautoconfamal.sh 422fc365358a2e92876ffc62971a0ff28ed472fc8bcf9de0df921c736fdeca5e
|
||||
F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x
|
||||
F tool/mkctimec.tcl dd183b73ae1c28249669741c250525f0407e579a70482371668fd5f130d9feb3
|
||||
F tool/mkkeywordhash.c 537b1a11ec1829b51b633da3ba2cc889b4a3f7356b06a07423b6d4cce92c2350
|
||||
F tool/mkkeywordhash.c bc5bcc92ebcaf15345346be7cf2204b83ed649b5208234adb5e543c061209bbf
|
||||
F tool/mkmsvcmin.tcl cad0c7b54d7dd92bc87d59f36d4cc4f070eb2e625f14159dc2f5c4204e6a13ea
|
||||
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
|
||||
F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21
|
||||
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
|
||||
F tool/mkpragmatab.tcl 8250ef3df54aee09f6c6ed36cad390bb6dd20bbe71927d8bff069ed9fe0bbf98
|
||||
F tool/mkpragmatab.tcl f115d63ada8171f9da28dc8e34e043a1a159692d46b89f66b6e681140bc4683d
|
||||
F tool/mkshellc.tcl 70a9978e363b0f3280ca9ce1c46d72563ff479c1930a12a7375e3881b7325712
|
||||
F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
@@ -1831,10 +1837,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 6f328c35947d6b3a0741514757b8944692203e89bdb2e7f9bbce8ad9288be344
|
||||
R 3dc95c8af87e7b557da20a5426ebc03a
|
||||
T +bgcolor * #d0c0ff
|
||||
T +sym-release *
|
||||
T +sym-version-3.29.0 *
|
||||
P d26fdfa3bc5f8d9c4a6000462080b0dd508e5cae9a83e0d126be48195224da8c
|
||||
R e3fe5b60b5f6618296725ebf365cf8d1
|
||||
T *branch * dead-end
|
||||
T *sym-dead-end *
|
||||
T +closed *
|
||||
T -sym-nulls-last *
|
||||
U drh
|
||||
Z 4d356946c4c6edd871b6d6986b095a05
|
||||
Z d85e52aacc1f69d8551de2fefb926b64
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6
|
||||
12d2cf88714d8b61a0c6a0733406436100d84671d7aa7229eb9d815b0eeb77a1
|
||||
+2
-2
@@ -136,8 +136,8 @@ void sqlite3AlterRenameTable(
|
||||
if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
|
||||
goto exit_rename_table;
|
||||
}
|
||||
if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto
|
||||
exit_rename_table;
|
||||
if( SQLITE_OK!=sqlite3CheckObjectName(pParse,zName,"table",zName) ){
|
||||
goto exit_rename_table;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_VIEW
|
||||
|
||||
+76
-137
@@ -27,13 +27,13 @@
|
||||
** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled
|
||||
** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated.
|
||||
** The sqlite_stat2 table is superseded by sqlite_stat3, which is only
|
||||
** created and used by SQLite versions 3.7.9 and later and with
|
||||
** created and used by SQLite versions 3.7.9 through 3.29.0 when
|
||||
** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3
|
||||
** is a superset of sqlite_stat2. The sqlite_stat4 is an enhanced
|
||||
** version of sqlite_stat3 and is only available when compiled with
|
||||
** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.1 and later. It is
|
||||
** not possible to enable both STAT3 and STAT4 at the same time. If they
|
||||
** are both enabled, then STAT4 takes precedence.
|
||||
** is a superset of sqlite_stat2 and is also now deprecated. The
|
||||
** sqlite_stat4 is an enhanced version of sqlite_stat3 and is only
|
||||
** available when compiled with SQLITE_ENABLE_STAT4 and in SQLite
|
||||
** versions 3.8.1 and later. STAT4 is the only variant that is still
|
||||
** supported.
|
||||
**
|
||||
** For most applications, sqlite_stat1 provides all the statistics required
|
||||
** for the query planner to make good choices.
|
||||
@@ -144,17 +144,11 @@
|
||||
|
||||
#if defined(SQLITE_ENABLE_STAT4)
|
||||
# define IsStat4 1
|
||||
# define IsStat3 0
|
||||
#elif defined(SQLITE_ENABLE_STAT3)
|
||||
# define IsStat4 0
|
||||
# define IsStat3 1
|
||||
#else
|
||||
# define IsStat4 0
|
||||
# define IsStat3 0
|
||||
# undef SQLITE_STAT4_SAMPLES
|
||||
# define SQLITE_STAT4_SAMPLES 1
|
||||
#endif
|
||||
#define IsStat34 (IsStat3+IsStat4) /* 1 for STAT3 or STAT4. 0 otherwise */
|
||||
|
||||
/*
|
||||
** This routine generates code that opens the sqlite_statN tables.
|
||||
@@ -183,14 +177,10 @@ static void openStatTable(
|
||||
{ "sqlite_stat1", "tbl,idx,stat" },
|
||||
#if defined(SQLITE_ENABLE_STAT4)
|
||||
{ "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" },
|
||||
{ "sqlite_stat3", 0 },
|
||||
#elif defined(SQLITE_ENABLE_STAT3)
|
||||
{ "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" },
|
||||
{ "sqlite_stat4", 0 },
|
||||
#else
|
||||
{ "sqlite_stat3", 0 },
|
||||
{ "sqlite_stat4", 0 },
|
||||
#endif
|
||||
{ "sqlite_stat3", 0 },
|
||||
};
|
||||
int i;
|
||||
sqlite3 *db = pParse->db;
|
||||
@@ -271,7 +261,7 @@ typedef struct Stat4Sample Stat4Sample;
|
||||
struct Stat4Sample {
|
||||
tRowcnt *anEq; /* sqlite_stat4.nEq */
|
||||
tRowcnt *anDLt; /* sqlite_stat4.nDLt */
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
tRowcnt *anLt; /* sqlite_stat4.nLt */
|
||||
union {
|
||||
i64 iRowid; /* Rowid in main table of the key */
|
||||
@@ -302,7 +292,7 @@ struct Stat4Accum {
|
||||
|
||||
/* Reclaim memory used by a Stat4Sample
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
static void sampleClear(sqlite3 *db, Stat4Sample *p){
|
||||
assert( db!=0 );
|
||||
if( p->nRowid ){
|
||||
@@ -314,7 +304,7 @@ static void sampleClear(sqlite3 *db, Stat4Sample *p){
|
||||
|
||||
/* Initialize the BLOB value of a ROWID
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){
|
||||
assert( db!=0 );
|
||||
if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
|
||||
@@ -330,7 +320,7 @@ static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){
|
||||
|
||||
/* Initialize the INTEGER value of a ROWID.
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){
|
||||
assert( db!=0 );
|
||||
if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
|
||||
@@ -343,7 +333,7 @@ static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){
|
||||
/*
|
||||
** Copy the contents of object (*pFrom) into (*pTo).
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){
|
||||
pTo->isPSample = pFrom->isPSample;
|
||||
pTo->iCol = pFrom->iCol;
|
||||
@@ -364,7 +354,7 @@ static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){
|
||||
*/
|
||||
static void stat4Destructor(void *pOld){
|
||||
Stat4Accum *p = (Stat4Accum*)pOld;
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
int i;
|
||||
for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
|
||||
for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
|
||||
@@ -384,7 +374,7 @@ static void stat4Destructor(void *pOld){
|
||||
** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the
|
||||
** total number of columns in the table.
|
||||
**
|
||||
** Note 2: C is only used for STAT3 and STAT4.
|
||||
** Note 2: C is only used for STAT4.
|
||||
**
|
||||
** For indexes on ordinary rowid tables, N==K+1. But for indexes on
|
||||
** WITHOUT ROWID tables, N=K+P where P is the number of columns in the
|
||||
@@ -407,7 +397,7 @@ static void statInit(
|
||||
int nColUp; /* nCol rounded up for alignment */
|
||||
int n; /* Bytes of space to allocate */
|
||||
sqlite3 *db; /* Database connection */
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
int mxSample = SQLITE_STAT4_SAMPLES;
|
||||
#endif
|
||||
|
||||
@@ -424,7 +414,7 @@ static void statInit(
|
||||
n = sizeof(*p)
|
||||
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */
|
||||
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */
|
||||
+ sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */
|
||||
+ sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
|
||||
@@ -444,7 +434,7 @@ static void statInit(
|
||||
p->current.anDLt = (tRowcnt*)&p[1];
|
||||
p->current.anEq = &p->current.anDLt[nColUp];
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
{
|
||||
u8 *pSpace; /* Allocated space not yet assigned */
|
||||
int i; /* Used to iterate through p->aSample[] */
|
||||
@@ -479,7 +469,7 @@ static void statInit(
|
||||
sqlite3_result_blob(context, p, sizeof(*p), stat4Destructor);
|
||||
}
|
||||
static const FuncDef statInitFuncdef = {
|
||||
2+IsStat34, /* nArg */
|
||||
2+IsStat4, /* nArg */
|
||||
SQLITE_UTF8, /* funcFlags */
|
||||
0, /* pUserData */
|
||||
0, /* pNext */
|
||||
@@ -519,7 +509,7 @@ static int sampleIsBetterPost(
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
/*
|
||||
** Return true if pNew is to be preferred over pOld.
|
||||
**
|
||||
@@ -538,15 +528,11 @@ static int sampleIsBetter(
|
||||
assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) );
|
||||
|
||||
if( (nEqNew>nEqOld) ) return 1;
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
if( nEqNew==nEqOld ){
|
||||
if( pNew->iCol<pOld->iCol ) return 1;
|
||||
return (pNew->iCol==pOld->iCol && sampleIsBetterPost(pAccum, pNew, pOld));
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return (nEqNew==nEqOld && pNew->iHash>pOld->iHash);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -559,7 +545,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
|
||||
@@ -593,7 +578,6 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
|
||||
goto find_new_min;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If necessary, remove sample iMin to make room for the new sample. */
|
||||
if( p->nSample>=p->mxSample ){
|
||||
@@ -614,10 +598,8 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
|
||||
/* The "rows less-than" for the rowid column must be greater than that
|
||||
** for the last sample in the p->a[] array. Otherwise, the samples would
|
||||
** be out of order. */
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
assert( p->nSample==0
|
||||
|| pNew->anLt[p->nCol-1] > p->a[p->nSample-1].anLt[p->nCol-1] );
|
||||
#endif
|
||||
|
||||
/* Insert the new sample */
|
||||
pSample = &p->a[p->nSample];
|
||||
@@ -627,9 +609,7 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
|
||||
/* Zero the first nEqZero entries in the anEq[] array. */
|
||||
memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero);
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
find_new_min:
|
||||
#endif
|
||||
find_new_min:
|
||||
if( p->nSample>=p->mxSample ){
|
||||
int iMin = -1;
|
||||
for(i=0; i<p->mxSample; i++){
|
||||
@@ -642,7 +622,7 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
|
||||
p->iMin = iMin;
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
|
||||
#endif /* SQLITE_ENABLE_STAT4 */
|
||||
|
||||
/*
|
||||
** Field iChng of the index being scanned has changed. So at this point
|
||||
@@ -683,28 +663,7 @@ static void samplePushPrevious(Stat4Accum *p, int iChng){
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SQLITE_ENABLE_STAT3) && !defined(SQLITE_ENABLE_STAT4)
|
||||
if( iChng==0 ){
|
||||
tRowcnt nLt = p->current.anLt[0];
|
||||
tRowcnt nEq = p->current.anEq[0];
|
||||
|
||||
/* Check if this is to be a periodic sample. If so, add it. */
|
||||
if( (nLt/p->nPSample)!=(nLt+nEq)/p->nPSample ){
|
||||
p->current.isPSample = 1;
|
||||
sampleInsert(p, &p->current, 0);
|
||||
p->current.isPSample = 0;
|
||||
}else
|
||||
|
||||
/* Or if it is a non-periodic sample. Add it in this case too. */
|
||||
if( p->nSample<p->mxSample
|
||||
|| sampleIsBetter(p, &p->current, &p->a[p->iMin])
|
||||
){
|
||||
sampleInsert(p, &p->current, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifndef SQLITE_ENABLE_STAT4
|
||||
UNUSED_PARAMETER( p );
|
||||
UNUSED_PARAMETER( iChng );
|
||||
#endif
|
||||
@@ -724,7 +683,7 @@ static void samplePushPrevious(Stat4Accum *p, int iChng){
|
||||
** index being analyzed. The stat_get() SQL function will later be used to
|
||||
** extract relevant information for constructing the sqlite_statN tables.
|
||||
**
|
||||
** The R parameter is only used for STAT3 and STAT4
|
||||
** The R parameter is only used for STAT4
|
||||
*/
|
||||
static void statPush(
|
||||
sqlite3_context *context,
|
||||
@@ -756,14 +715,14 @@ static void statPush(
|
||||
}
|
||||
for(i=iChng; i<p->nCol; i++){
|
||||
p->current.anDLt[i]++;
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
p->current.anLt[i] += p->current.anEq[i];
|
||||
#endif
|
||||
p->current.anEq[i] = 1;
|
||||
}
|
||||
}
|
||||
p->nRow++;
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
|
||||
sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
|
||||
}else{
|
||||
@@ -796,7 +755,7 @@ static void statPush(
|
||||
#endif
|
||||
}
|
||||
static const FuncDef statPushFuncdef = {
|
||||
2+IsStat34, /* nArg */
|
||||
2+IsStat4, /* nArg */
|
||||
SQLITE_UTF8, /* funcFlags */
|
||||
0, /* pUserData */
|
||||
0, /* pNext */
|
||||
@@ -827,7 +786,7 @@ static const FuncDef statPushFuncdef = {
|
||||
** parameter will always be a poiner to a Stat4Accum object, never a
|
||||
** NULL.
|
||||
**
|
||||
** If neither STAT3 nor STAT4 are enabled, then J is always
|
||||
** If STAT4 is not enabled, then J is always
|
||||
** STAT_GET_STAT1 and is hence omitted and this routine becomes
|
||||
** a one-parameter function, stat_get(P), that always returns the
|
||||
** stat1 table entry information.
|
||||
@@ -838,8 +797,8 @@ static void statGet(
|
||||
sqlite3_value **argv
|
||||
){
|
||||
Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
/* STAT3 and STAT4 have a parameter on this routine. */
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
/* STAT4 has a parameter on this routine. */
|
||||
int eCall = sqlite3_value_int(argv[1]);
|
||||
assert( argc==2 );
|
||||
assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ
|
||||
@@ -894,7 +853,7 @@ static void statGet(
|
||||
|
||||
sqlite3_result_text(context, zRet, -1, sqlite3_free);
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
else if( eCall==STAT_GET_ROWID ){
|
||||
if( p->iGet<0 ){
|
||||
samplePushPrevious(p, 0);
|
||||
@@ -923,9 +882,7 @@ static void statGet(
|
||||
}
|
||||
}
|
||||
|
||||
if( IsStat3 ){
|
||||
sqlite3_result_int64(context, (i64)aCnt[0]);
|
||||
}else{
|
||||
{
|
||||
char *zRet = sqlite3MallocZero(p->nCol * 25);
|
||||
if( zRet==0 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
@@ -942,13 +899,13 @@ static void statGet(
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
|
||||
#endif /* SQLITE_ENABLE_STAT4 */
|
||||
#ifndef SQLITE_DEBUG
|
||||
UNUSED_PARAMETER( argc );
|
||||
#endif
|
||||
}
|
||||
static const FuncDef statGetFuncdef = {
|
||||
1+IsStat34, /* nArg */
|
||||
1+IsStat4, /* nArg */
|
||||
SQLITE_UTF8, /* funcFlags */
|
||||
0, /* pUserData */
|
||||
0, /* pNext */
|
||||
@@ -961,7 +918,7 @@ static const FuncDef statGetFuncdef = {
|
||||
|
||||
static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
|
||||
assert( regOut!=regStat4 && regOut!=regStat4+1 );
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1);
|
||||
#elif SQLITE_DEBUG
|
||||
assert( iParam==STAT_GET_STAT1 );
|
||||
@@ -970,7 +927,7 @@ static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
|
||||
#endif
|
||||
sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4, regOut,
|
||||
(char*)&statGetFuncdef, P4_FUNCDEF);
|
||||
sqlite3VdbeChangeP5(v, 1 + IsStat34);
|
||||
sqlite3VdbeChangeP5(v, 1 + IsStat4);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -997,7 +954,7 @@ static void analyzeOneTable(
|
||||
int regNewRowid = iMem++; /* Rowid for the inserted record */
|
||||
int regStat4 = iMem++; /* Register to hold Stat4Accum object */
|
||||
int regChng = iMem++; /* Index of changed index field */
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
int regRowid = iMem++; /* Rowid argument passed to stat_push() */
|
||||
#endif
|
||||
int regTemp = iMem++; /* Temporary use register */
|
||||
@@ -1131,16 +1088,16 @@ static void analyzeOneTable(
|
||||
** (3) the number of rows in the index,
|
||||
**
|
||||
**
|
||||
** The third argument is only used for STAT3 and STAT4
|
||||
** The third argument is only used for STAT4
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3);
|
||||
#endif
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2);
|
||||
sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4+1, regStat4,
|
||||
(char*)&statInitFuncdef, P4_FUNCDEF);
|
||||
sqlite3VdbeChangeP5(v, 2+IsStat34);
|
||||
sqlite3VdbeChangeP5(v, 2+IsStat4);
|
||||
|
||||
/* Implementation of the following:
|
||||
**
|
||||
@@ -1211,12 +1168,12 @@ static void analyzeOneTable(
|
||||
|
||||
/*
|
||||
** chng_addr_N:
|
||||
** regRowid = idx(rowid) // STAT34 only
|
||||
** stat_push(P, regChng, regRowid) // 3rd parameter STAT34 only
|
||||
** regRowid = idx(rowid) // STAT4 only
|
||||
** stat_push(P, regChng, regRowid) // 3rd parameter STAT4 only
|
||||
** Next csr
|
||||
** if !eof(csr) goto next_row;
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
assert( regRowid==(regStat4+2) );
|
||||
if( HasRowid(pTab) ){
|
||||
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
|
||||
@@ -1237,7 +1194,7 @@ static void analyzeOneTable(
|
||||
assert( regChng==(regStat4+1) );
|
||||
sqlite3VdbeAddOp4(v, OP_Function0, 1, regStat4, regTemp,
|
||||
(char*)&statPushFuncdef, P4_FUNCDEF);
|
||||
sqlite3VdbeChangeP5(v, 2+IsStat34);
|
||||
sqlite3VdbeChangeP5(v, 2+IsStat4);
|
||||
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
|
||||
|
||||
/* Add the entry to the stat1 table. */
|
||||
@@ -1251,8 +1208,8 @@ static void analyzeOneTable(
|
||||
#endif
|
||||
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
|
||||
|
||||
/* Add the entries to the stat3 or stat4 table. */
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
/* Add the entries to the stat4 table. */
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
{
|
||||
int regEq = regStat1;
|
||||
int regLt = regStat1+1;
|
||||
@@ -1275,21 +1232,17 @@ static void analyzeOneTable(
|
||||
callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
|
||||
sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
|
||||
VdbeCoverage(v);
|
||||
#ifdef SQLITE_ENABLE_STAT3
|
||||
sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, 0, regSample);
|
||||
#else
|
||||
for(i=0; i<nCol; i++){
|
||||
sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, i, regCol+i);
|
||||
}
|
||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol, regSample);
|
||||
#endif
|
||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
|
||||
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */
|
||||
sqlite3VdbeJumpHere(v, addrIsNull);
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
|
||||
#endif /* SQLITE_ENABLE_STAT4 */
|
||||
|
||||
/* End of analysis */
|
||||
sqlite3VdbeJumpHere(v, addrRewind);
|
||||
@@ -1464,7 +1417,7 @@ static void decodeIntArray(
|
||||
int i;
|
||||
tRowcnt v;
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
if( z==0 ) z = "";
|
||||
#else
|
||||
assert( z!=0 );
|
||||
@@ -1475,7 +1428,7 @@ static void decodeIntArray(
|
||||
v = v*10 + c - '0';
|
||||
z++;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
if( aOut ) aOut[i] = v;
|
||||
if( aLog ) aLog[i] = sqlite3LogEst(v);
|
||||
#else
|
||||
@@ -1486,7 +1439,7 @@ static void decodeIntArray(
|
||||
#endif
|
||||
if( *z==' ' ) z++;
|
||||
}
|
||||
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifndef SQLITE_ENABLE_STAT4
|
||||
assert( pIndex!=0 ); {
|
||||
#else
|
||||
if( pIndex ){
|
||||
@@ -1497,7 +1450,9 @@ static void decodeIntArray(
|
||||
if( sqlite3_strglob("unordered*", z)==0 ){
|
||||
pIndex->bUnordered = 1;
|
||||
}else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
|
||||
pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
|
||||
int sz = sqlite3Atoi(z+3);
|
||||
if( sz<2 ) sz = 2;
|
||||
pIndex->szIdxRow = sqlite3LogEst(sz);
|
||||
}else if( sqlite3_strglob("noskipscan*", z)==0 ){
|
||||
pIndex->noSkipScan = 1;
|
||||
}
|
||||
@@ -1551,7 +1506,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
|
||||
if( pIndex ){
|
||||
tRowcnt *aiRowEst = 0;
|
||||
int nCol = pIndex->nKeyCol+1;
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
/* Index.aiRowEst may already be set here if there are duplicate
|
||||
** sqlite_stat1 entries for this index. In that case just clobber
|
||||
** the old data with the new instead of allocating a new array. */
|
||||
@@ -1587,7 +1542,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
|
||||
** and its contents.
|
||||
*/
|
||||
void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
if( pIdx->aSample ){
|
||||
int j;
|
||||
for(j=0; j<pIdx->nSample; j++){
|
||||
@@ -1603,10 +1558,10 @@ void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
|
||||
#else
|
||||
UNUSED_PARAMETER(db);
|
||||
UNUSED_PARAMETER(pIdx);
|
||||
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
|
||||
#endif /* SQLITE_ENABLE_STAT4 */
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
/*
|
||||
** Populate the pIdx->aAvgEq[] array based on the samples currently
|
||||
** stored in pIdx->aSample[].
|
||||
@@ -1684,12 +1639,11 @@ static Index *findIndexOrPrimaryKey(
|
||||
}
|
||||
|
||||
/*
|
||||
** Load the content from either the sqlite_stat4 or sqlite_stat3 table
|
||||
** Load the content from either the sqlite_stat4
|
||||
** into the relevant Index.aSample[] arrays.
|
||||
**
|
||||
** Arguments zSql1 and zSql2 must point to SQL statements that return
|
||||
** data equivalent to the following (statements are different for stat3,
|
||||
** see the caller of this function for details):
|
||||
** data equivalent to the following:
|
||||
**
|
||||
** zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx
|
||||
** zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4
|
||||
@@ -1698,7 +1652,6 @@ static Index *findIndexOrPrimaryKey(
|
||||
*/
|
||||
static int loadStatTbl(
|
||||
sqlite3 *db, /* Database handle */
|
||||
int bStat3, /* Assume single column records only */
|
||||
const char *zSql1, /* SQL statement 1 (see above) */
|
||||
const char *zSql2, /* SQL statement 2 (see above) */
|
||||
const char *zDb /* Database name (e.g. "main") */
|
||||
@@ -1732,17 +1685,13 @@ static int loadStatTbl(
|
||||
if( zIndex==0 ) continue;
|
||||
nSample = sqlite3_column_int(pStmt, 1);
|
||||
pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
|
||||
assert( pIdx==0 || bStat3 || pIdx->nSample==0 );
|
||||
/* Index.nSample is non-zero at this point if data has already been
|
||||
** loaded from the stat4 table. In this case ignore stat3 data. */
|
||||
if( pIdx==0 || pIdx->nSample ) continue;
|
||||
if( bStat3==0 ){
|
||||
assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 );
|
||||
if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){
|
||||
nIdxCol = pIdx->nKeyCol;
|
||||
}else{
|
||||
nIdxCol = pIdx->nColumn;
|
||||
}
|
||||
assert( pIdx==0 || pIdx->nSample==0 );
|
||||
if( pIdx==0 ) continue;
|
||||
assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 );
|
||||
if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){
|
||||
nIdxCol = pIdx->nKeyCol;
|
||||
}else{
|
||||
nIdxCol = pIdx->nColumn;
|
||||
}
|
||||
pIdx->nSampleCol = nIdxCol;
|
||||
nByte = sizeof(IndexSample) * nSample;
|
||||
@@ -1784,9 +1733,8 @@ static int loadStatTbl(
|
||||
pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
|
||||
if( pIdx==0 ) continue;
|
||||
/* This next condition is true if data has already been loaded from
|
||||
** the sqlite_stat4 table. In this case ignore stat3 data. */
|
||||
** the sqlite_stat4 table. */
|
||||
nCol = pIdx->nSampleCol;
|
||||
if( bStat3 && nCol>1 ) continue;
|
||||
if( pIdx!=pPrevIdx ){
|
||||
initAvgEq(pPrevIdx);
|
||||
pPrevIdx = pIdx;
|
||||
@@ -1819,7 +1767,7 @@ static int loadStatTbl(
|
||||
}
|
||||
|
||||
/*
|
||||
** Load content from the sqlite_stat4 and sqlite_stat3 tables into
|
||||
** Load content from the sqlite_stat4 table into
|
||||
** the Index.aSample[] arrays of all indices.
|
||||
*/
|
||||
static int loadStat4(sqlite3 *db, const char *zDb){
|
||||
@@ -1827,37 +1775,28 @@ static int loadStat4(sqlite3 *db, const char *zDb){
|
||||
|
||||
assert( db->lookaside.bDisable );
|
||||
if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){
|
||||
rc = loadStatTbl(db, 0,
|
||||
rc = loadStatTbl(db,
|
||||
"SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx",
|
||||
"SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4",
|
||||
zDb
|
||||
);
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){
|
||||
rc = loadStatTbl(db, 1,
|
||||
"SELECT idx,count(*) FROM %Q.sqlite_stat3 GROUP BY idx",
|
||||
"SELECT idx,neq,nlt,ndlt,sqlite_record(sample) FROM %Q.sqlite_stat3",
|
||||
zDb
|
||||
);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
|
||||
#endif /* SQLITE_ENABLE_STAT4 */
|
||||
|
||||
/*
|
||||
** Load the content of the sqlite_stat1 and sqlite_stat3/4 tables. The
|
||||
** Load the content of the sqlite_stat1 and sqlite_stat4 tables. The
|
||||
** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
|
||||
** arrays. The contents of sqlite_stat3/4 are used to populate the
|
||||
** arrays. The contents of sqlite_stat4 are used to populate the
|
||||
** Index.aSample[] arrays.
|
||||
**
|
||||
** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR
|
||||
** is returned. In this case, even if SQLITE_ENABLE_STAT3/4 was defined
|
||||
** during compilation and the sqlite_stat3/4 table is present, no data is
|
||||
** is returned. In this case, even if SQLITE_ENABLE_STAT4 was defined
|
||||
** during compilation and the sqlite_stat4 table is present, no data is
|
||||
** read from it.
|
||||
**
|
||||
** If SQLITE_ENABLE_STAT3/4 was defined during compilation and the
|
||||
** If SQLITE_ENABLE_STAT4 was defined during compilation and the
|
||||
** sqlite_stat4 table is not present in the database, SQLITE_ERROR is
|
||||
** returned. However, in this case, data is read from the sqlite_stat1
|
||||
** table (if it is present) before returning.
|
||||
@@ -1885,7 +1824,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
||||
for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
|
||||
Index *pIdx = sqliteHashData(i);
|
||||
pIdx->hasStat1 = 0;
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
sqlite3DeleteIndexSamples(db, pIdx);
|
||||
pIdx->aSample = 0;
|
||||
#endif
|
||||
@@ -1913,7 +1852,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
||||
}
|
||||
|
||||
/* Load the statistics from the sqlite_stat4 table. */
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
if( rc==SQLITE_OK ){
|
||||
db->lookaside.bDisable++;
|
||||
rc = loadStat4(db, sInfo.zDatabase);
|
||||
|
||||
@@ -560,6 +560,7 @@ int sqlite3FixExpr(
|
||||
Expr *pExpr /* The expression to be fixed to one database */
|
||||
){
|
||||
while( pExpr ){
|
||||
ExprSetProperty(pExpr, EP_Indirect);
|
||||
if( pExpr->op==TK_VARIABLE ){
|
||||
if( pFix->pParse->db->init.busy ){
|
||||
pExpr->op = TK_NULL;
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ int sqlite3_set_authorizer(
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
db->xAuth = (sqlite3_xauth)xAuth;
|
||||
db->pAuthArg = pArg;
|
||||
sqlite3ExpirePreparedStatements(db, 0);
|
||||
if( db->xAuth ) sqlite3ExpirePreparedStatements(db, 1);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -619,8 +619,10 @@ int sqlite3_backup_finish(sqlite3_backup *p){
|
||||
}
|
||||
if( p->isAttached ){
|
||||
pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
|
||||
assert( pp!=0 );
|
||||
while( *pp!=p ){
|
||||
pp = &(*pp)->pNext;
|
||||
assert( pp!=0 );
|
||||
}
|
||||
*pp = p->pNext;
|
||||
}
|
||||
|
||||
+27
-17
@@ -1647,9 +1647,12 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
|
||||
if( (data[hdr+2] || data[hdr+1]) && gap+2<=top ){
|
||||
u8 *pSpace = pageFindSlot(pPage, nByte, &rc);
|
||||
if( pSpace ){
|
||||
assert( pSpace>=data && (pSpace - data)<65536 );
|
||||
*pIdx = (int)(pSpace - data);
|
||||
return SQLITE_OK;
|
||||
assert( pSpace+nByte<=data+pPage->pBt->usableSize );
|
||||
if( (*pIdx = (int)(pSpace-data))<=gap ){
|
||||
return SQLITE_CORRUPT_PAGE(pPage);
|
||||
}else{
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}else if( rc ){
|
||||
return rc;
|
||||
}
|
||||
@@ -4876,6 +4879,7 @@ static int accessPayload(
|
||||
assert( aWrite>=pBufStart ); /* due to (6) */
|
||||
memcpy(aSave, aWrite, 4);
|
||||
rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
|
||||
if( rc && nextPage>pBt->nPage ) rc = SQLITE_CORRUPT_BKPT;
|
||||
nextPage = get4byte(aWrite);
|
||||
memcpy(aWrite, aSave, 4);
|
||||
}else
|
||||
@@ -6664,12 +6668,7 @@ static void insertCell(
|
||||
assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) );
|
||||
assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) );
|
||||
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
|
||||
/* The cell should normally be sized correctly. However, when moving a
|
||||
** malformed cell from a leaf page to an interior page, if the cell size
|
||||
** wanted to be less than 4 but got rounded up to 4 on the leaf, then size
|
||||
** might be less than 8 (leaf-size + pointer) on the interior node. Hence
|
||||
** the term after the || in the following assert(). */
|
||||
assert( sz==pPage->xCellSize(pPage, pCell) || (sz==8 && iChild>0) );
|
||||
assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB );
|
||||
assert( pPage->nFree>=0 );
|
||||
if( pPage->nOverflow || sz+2>pPage->nFree ){
|
||||
if( pTemp ){
|
||||
@@ -6901,7 +6900,7 @@ static int rebuildPage(
|
||||
|
||||
assert( i<iEnd );
|
||||
j = get2byte(&aData[hdr+5]);
|
||||
if( NEVER(j>(u32)usableSize) ){ j = 0; }
|
||||
if( j>(u32)usableSize ){ j = 0; }
|
||||
memcpy(&pTmp[j], &aData[j], usableSize - j);
|
||||
|
||||
for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
|
||||
@@ -7676,7 +7675,7 @@ static int balance_nonroot(
|
||||
*/
|
||||
memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow));
|
||||
if( pOld->nOverflow>0 ){
|
||||
if( limit<pOld->aiOvfl[0] ){
|
||||
if( NEVER(limit<pOld->aiOvfl[0]) ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto balance_cleanup;
|
||||
}
|
||||
@@ -7962,6 +7961,8 @@ static int balance_nonroot(
|
||||
));
|
||||
|
||||
assert( sqlite3PagerIswriteable(pParent->pDbPage) );
|
||||
assert( nNew>=1 && nNew<=ArraySize(apNew) );
|
||||
assert( apNew[nNew-1]!=0 );
|
||||
put4byte(pRight, apNew[nNew-1]->pgno);
|
||||
|
||||
/* If the sibling pages are not leaves, ensure that the right-child pointer
|
||||
@@ -8307,11 +8308,13 @@ static int balance(BtCursor *pCur){
|
||||
VVA_ONLY( int balance_deeper_called = 0 );
|
||||
|
||||
do {
|
||||
int iPage = pCur->iPage;
|
||||
int iPage;
|
||||
MemPage *pPage = pCur->pPage;
|
||||
|
||||
if( NEVER(pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break;
|
||||
if( iPage==0 ){
|
||||
if( pPage->nOverflow==0 && pPage->nFree<=nMin ){
|
||||
break;
|
||||
}else if( (iPage = pCur->iPage)==0 ){
|
||||
if( pPage->nOverflow ){
|
||||
/* The root page of the b-tree is overfull. In this case call the
|
||||
** balance_deeper() function to create a new child for the root-page
|
||||
@@ -8332,8 +8335,6 @@ static int balance(BtCursor *pCur){
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}else if( pPage->nOverflow==0 && pPage->nFree<=nMin ){
|
||||
break;
|
||||
}else{
|
||||
MemPage * const pParent = pCur->apPage[iPage-1];
|
||||
int const iIdx = pCur->aiIdx[iPage-1];
|
||||
@@ -8475,7 +8476,9 @@ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){
|
||||
Pgno ovflPgno; /* Next overflow page to write */
|
||||
u32 ovflPageSize; /* Size to write on overflow page */
|
||||
|
||||
if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd ){
|
||||
if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd
|
||||
|| pCur->info.pPayload < pPage->aData + pPage->cellOffset
|
||||
){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
/* Overwrite the local portion first */
|
||||
@@ -8716,6 +8719,8 @@ int sqlite3BtreeInsert(
|
||||
memcpy(newCell, oldCell, 4);
|
||||
}
|
||||
rc = clearCell(pPage, oldCell, &info);
|
||||
testcase( pCur->curFlags & BTCF_ValidOvfl );
|
||||
invalidateOverflowCache(pCur);
|
||||
if( info.nSize==szNew && info.nLocal==info.nPayload
|
||||
&& (!ISAUTOVACUUM || szNew<pPage->minLocal)
|
||||
){
|
||||
@@ -8729,7 +8734,12 @@ int sqlite3BtreeInsert(
|
||||
** new entry uses overflow pages, as the insertCell() call below is
|
||||
** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry. */
|
||||
assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */
|
||||
if( oldCell+szNew > pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT;
|
||||
if( oldCell < pPage->aData+pPage->hdrOffset+10 ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
if( oldCell+szNew > pPage->aDataEnd ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
memcpy(oldCell, newCell, szNew);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
+91
-32
@@ -456,7 +456,7 @@ void sqlite3FreeIndex(sqlite3 *db, Index *p){
|
||||
sqlite3ExprListDelete(db, p->aColExpr);
|
||||
sqlite3DbFree(db, p->zColAff);
|
||||
if( p->isResized ) sqlite3DbFree(db, (void *)p->azColl);
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
sqlite3_free(p->aiRowEst);
|
||||
#endif
|
||||
sqlite3DbFree(db, p);
|
||||
@@ -829,13 +829,40 @@ int sqlite3WritableSchema(sqlite3 *db){
|
||||
** trigger). All names are legal except those that begin with the string
|
||||
** "sqlite_" (in upper, lower or mixed case). This portion of the namespace
|
||||
** is reserved for internal use.
|
||||
**
|
||||
** When parsing the sqlite_master table, this routine also checks to
|
||||
** make sure the "type", "name", and "tbl_name" columns are consistent
|
||||
** with the SQL.
|
||||
*/
|
||||
int sqlite3CheckObjectName(Parse *pParse, const char *zName){
|
||||
if( !pParse->db->init.busy && pParse->nested==0
|
||||
&& sqlite3WritableSchema(pParse->db)==0
|
||||
&& 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
|
||||
sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
|
||||
return SQLITE_ERROR;
|
||||
int sqlite3CheckObjectName(
|
||||
Parse *pParse, /* Parsing context */
|
||||
const char *zName, /* Name of the object to check */
|
||||
const char *zType, /* Type of this object */
|
||||
const char *zTblName /* Parent table name for triggers and indexes */
|
||||
){
|
||||
sqlite3 *db = pParse->db;
|
||||
if( sqlite3WritableSchema(db) || db->init.imposterTable ){
|
||||
/* Skip these error checks for writable_schema=ON */
|
||||
return SQLITE_OK;
|
||||
}
|
||||
if( db->init.busy ){
|
||||
if( sqlite3_stricmp(zType, db->init.azInit[0])
|
||||
|| sqlite3_stricmp(zName, db->init.azInit[1])
|
||||
|| sqlite3_stricmp(zTblName, db->init.azInit[2])
|
||||
){
|
||||
if( sqlite3Config.bExtraSchemaChecks ){
|
||||
sqlite3ErrorMsg(pParse, ""); /* corruptSchema() will supply the error */
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if( pParse->nested==0
|
||||
&& 0==sqlite3StrNICmp(zName, "sqlite_", 7)
|
||||
){
|
||||
sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s",
|
||||
zName);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -916,7 +943,7 @@ void sqlite3StartTable(
|
||||
}
|
||||
pParse->sNameToken = *pName;
|
||||
if( zName==0 ) return;
|
||||
if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
|
||||
if( sqlite3CheckObjectName(pParse, zName, isView?"view":"table", zName) ){
|
||||
goto begin_table_error;
|
||||
}
|
||||
if( db->init.iDb==1 ) isTemp = 1;
|
||||
@@ -1416,7 +1443,7 @@ void sqlite3AddPrimaryKey(
|
||||
pTab->keyConf = (u8)onError;
|
||||
assert( autoInc==0 || autoInc==1 );
|
||||
pTab->tabFlags |= autoInc*TF_Autoincrement;
|
||||
if( pList ) pParse->iPkSortOrder = pList->a[0].sortOrder;
|
||||
if( pList ) pParse->iPkSortOrder = pList->a[0].sortFlags;
|
||||
}else if( autoInc ){
|
||||
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||
sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
|
||||
@@ -1831,6 +1858,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||||
Index *pIdx;
|
||||
Index *pPk;
|
||||
int nPk;
|
||||
int nExtra;
|
||||
int i, j;
|
||||
sqlite3 *db = pParse->db;
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
@@ -1866,13 +1894,14 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||||
if( IN_RENAME_OBJECT ){
|
||||
sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey);
|
||||
}
|
||||
pList->a[0].sortOrder = pParse->iPkSortOrder;
|
||||
pList->a[0].sortFlags = pParse->iPkSortOrder;
|
||||
assert( pParse->pNewTable==pTab );
|
||||
pTab->iPKey = -1;
|
||||
sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
|
||||
SQLITE_IDXTYPE_PRIMARYKEY);
|
||||
if( db->mallocFailed || pParse->nErr ) return;
|
||||
pPk = sqlite3PrimaryKeyIndex(pTab);
|
||||
assert( pPk->nKeyCol==1 );
|
||||
}else{
|
||||
pPk = sqlite3PrimaryKeyIndex(pTab);
|
||||
assert( pPk!=0 );
|
||||
@@ -1887,6 +1916,8 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||||
pPk->nColumn--;
|
||||
}else{
|
||||
testcase( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) );
|
||||
pPk->azColl[j] = pPk->azColl[i];
|
||||
pPk->aSortOrder[j] = pPk->aSortOrder[i];
|
||||
pPk->aiColumn[j++] = pPk->aiColumn[i];
|
||||
}
|
||||
}
|
||||
@@ -1895,7 +1926,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||||
assert( pPk!=0 );
|
||||
pPk->isCovering = 1;
|
||||
if( !db->init.imposterTable ) pPk->uniqNotNull = 1;
|
||||
nPk = pPk->nKeyCol;
|
||||
nPk = pPk->nColumn = pPk->nKeyCol;
|
||||
|
||||
/* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
|
||||
** table entry. This is only required if currently generating VDBE
|
||||
@@ -1945,21 +1976,21 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||||
|
||||
/* Add all table columns to the PRIMARY KEY index
|
||||
*/
|
||||
if( nPk<pTab->nCol ){
|
||||
if( resizeIndexObject(db, pPk, pTab->nCol) ) return;
|
||||
for(i=0, j=nPk; i<pTab->nCol; i++){
|
||||
if( !hasColumn(pPk->aiColumn, j, i) ){
|
||||
assert( j<pPk->nColumn );
|
||||
pPk->aiColumn[j] = i;
|
||||
pPk->azColl[j] = sqlite3StrBINARY;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
assert( pPk->nColumn==j );
|
||||
assert( pTab->nCol==j );
|
||||
}else{
|
||||
pPk->nColumn = pTab->nCol;
|
||||
nExtra = 0;
|
||||
for(i=0; i<pTab->nCol; i++){
|
||||
if( !hasColumn(pPk->aiColumn, nPk, i) ) nExtra++;
|
||||
}
|
||||
if( resizeIndexObject(db, pPk, nPk+nExtra) ) return;
|
||||
for(i=0, j=nPk; i<pTab->nCol; i++){
|
||||
if( !hasColumn(pPk->aiColumn, j, i) ){
|
||||
assert( j<pPk->nColumn );
|
||||
pPk->aiColumn[j] = i;
|
||||
pPk->azColl[j] = sqlite3StrBINARY;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
assert( pPk->nColumn==j );
|
||||
assert( pTab->nCol<=j );
|
||||
recomputeColumnsNotIndexed(pPk);
|
||||
}
|
||||
|
||||
@@ -2156,7 +2187,7 @@ void sqlite3EndTable(
|
||||
addrTop = sqlite3VdbeCurrentAddr(v) + 1;
|
||||
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
|
||||
if( pParse->nErr ) return;
|
||||
pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
|
||||
pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect, SQLITE_AFF_BLOB);
|
||||
if( pSelTab==0 ) return;
|
||||
assert( p->aCol==0 );
|
||||
p->nCol = pSelTab->nCol;
|
||||
@@ -2420,10 +2451,10 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
xAuth = db->xAuth;
|
||||
db->xAuth = 0;
|
||||
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
|
||||
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE);
|
||||
db->xAuth = xAuth;
|
||||
#else
|
||||
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
|
||||
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE);
|
||||
#endif
|
||||
pParse->nTab = n;
|
||||
if( pTable->pCheck ){
|
||||
@@ -2439,7 +2470,8 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
&& pParse->nErr==0
|
||||
&& pTable->nCol==pSel->pEList->nExpr
|
||||
){
|
||||
sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel);
|
||||
sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel,
|
||||
SQLITE_AFF_NONE);
|
||||
}
|
||||
}else if( pSelTab ){
|
||||
/* CREATE VIEW name AS... without an argument list. Construct
|
||||
@@ -3121,6 +3153,28 @@ Index *sqlite3AllocateIndexObject(
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
** If expression list pList contains an expression that was parsed with
|
||||
** an explicit "NULLS FIRST" or "NULLS LAST" clause, leave an error in
|
||||
** pParse and return non-zero. Otherwise, return zero.
|
||||
*/
|
||||
int sqlite3HasExplicitNulls(Parse *pParse, ExprList *pList){
|
||||
if( pList ){
|
||||
int i;
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
u8 sf = pList->a[i].sortFlags;
|
||||
if( sf & (SQLITE_SO_BIGNULL|SQLITE_SO_SMALLNULL) ){
|
||||
sqlite3ErrorMsg(pParse, "unsupported use of NULLS %s",
|
||||
(sf & SQLITE_SO_BIGNULL)==(sf & SQLITE_SO_DESC) ?
|
||||
"FIRST" : "LAST"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Create a new index for an SQL table. pName1.pName2 is the name of the index
|
||||
** and pTblList is the name of the table that is to be indexed. Both will
|
||||
@@ -3172,6 +3226,9 @@ void sqlite3CreateIndex(
|
||||
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
|
||||
goto exit_create_index;
|
||||
}
|
||||
if( sqlite3HasExplicitNulls(pParse, pList) ){
|
||||
goto exit_create_index;
|
||||
}
|
||||
|
||||
/*
|
||||
** Find the table that is to be indexed. Return early if not found.
|
||||
@@ -3270,7 +3327,7 @@ void sqlite3CreateIndex(
|
||||
zName = sqlite3NameFromToken(db, pName);
|
||||
if( zName==0 ) goto exit_create_index;
|
||||
assert( pName->z!=0 );
|
||||
if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
|
||||
if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName,"index",pTab->zName) ){
|
||||
goto exit_create_index;
|
||||
}
|
||||
if( !IN_RENAME_OBJECT ){
|
||||
@@ -3454,7 +3511,7 @@ void sqlite3CreateIndex(
|
||||
goto exit_create_index;
|
||||
}
|
||||
pIndex->azColl[i] = zColl;
|
||||
requestedSortOrder = pListItem->sortOrder & sortOrderMask;
|
||||
requestedSortOrder = pListItem->sortFlags & sortOrderMask;
|
||||
pIndex->aSortOrder[i] = (u8)requestedSortOrder;
|
||||
}
|
||||
|
||||
@@ -3629,6 +3686,7 @@ void sqlite3CreateIndex(
|
||||
/* Gather the complete text of the CREATE INDEX statement into
|
||||
** the zStmt variable
|
||||
*/
|
||||
assert( pName!=0 || pStart==0 );
|
||||
if( pStart ){
|
||||
int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
|
||||
if( pName->z[n-1]==';' ) n--;
|
||||
@@ -4671,7 +4729,8 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
|
||||
const char *zColl = pIdx->azColl[i];
|
||||
pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 :
|
||||
sqlite3LocateCollSeq(pParse, zColl);
|
||||
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
|
||||
pKey->aSortFlags[i] = pIdx->aSortOrder[i];
|
||||
assert( 0==(pKey->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) );
|
||||
}
|
||||
if( pParse->nErr ){
|
||||
assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ );
|
||||
|
||||
@@ -306,8 +306,6 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#endif
|
||||
#if defined(SQLITE_ENABLE_STAT4)
|
||||
"ENABLE_STAT4",
|
||||
#elif defined(SQLITE_ENABLE_STAT3)
|
||||
"ENABLE_STAT3",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_STMTVTAB
|
||||
"ENABLE_STMTVTAB",
|
||||
|
||||
+135
-106
@@ -71,7 +71,7 @@ char sqlite3ExprAffinity(Expr *pExpr){
|
||||
pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
|
||||
);
|
||||
}
|
||||
return pExpr->affinity;
|
||||
return pExpr->affExpr;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -106,10 +106,22 @@ Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
|
||||
}
|
||||
|
||||
/*
|
||||
** Skip over any TK_COLLATE operators and any unlikely()
|
||||
** or likelihood() function at the root of an expression.
|
||||
** Skip over any TK_COLLATE operators.
|
||||
*/
|
||||
Expr *sqlite3ExprSkipCollate(Expr *pExpr){
|
||||
while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
|
||||
assert( pExpr->op==TK_COLLATE );
|
||||
pExpr = pExpr->pLeft;
|
||||
}
|
||||
return pExpr;
|
||||
}
|
||||
|
||||
/*
|
||||
** Skip over any TK_COLLATE operators and/or any unlikely()
|
||||
** or likelihood() or likely() functions at the root of an
|
||||
** expression.
|
||||
*/
|
||||
Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
|
||||
while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){
|
||||
if( ExprHasProperty(pExpr, EP_Unlikely) ){
|
||||
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
|
||||
@@ -230,7 +242,7 @@ int sqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2){
|
||||
*/
|
||||
char sqlite3CompareAffinity(Expr *pExpr, char aff2){
|
||||
char aff1 = sqlite3ExprAffinity(pExpr);
|
||||
if( aff1 && aff2 ){
|
||||
if( aff1>SQLITE_AFF_NONE && aff2>SQLITE_AFF_NONE ){
|
||||
/* Both sides of the comparison are columns. If one has numeric
|
||||
** affinity, use that. Otherwise use no affinity.
|
||||
*/
|
||||
@@ -239,15 +251,10 @@ char sqlite3CompareAffinity(Expr *pExpr, char aff2){
|
||||
}else{
|
||||
return SQLITE_AFF_BLOB;
|
||||
}
|
||||
}else if( !aff1 && !aff2 ){
|
||||
/* Neither side of the comparison is a column. Compare the
|
||||
** results directly.
|
||||
*/
|
||||
return SQLITE_AFF_BLOB;
|
||||
}else{
|
||||
/* One side is a column, the other is not. Use the columns affinity. */
|
||||
assert( aff1==0 || aff2==0 );
|
||||
return (aff1 + aff2);
|
||||
assert( aff1<=SQLITE_AFF_NONE || aff2<=SQLITE_AFF_NONE );
|
||||
return (aff1<=SQLITE_AFF_NONE ? aff2 : aff1) | SQLITE_AFF_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,14 +287,13 @@ static char comparisonAffinity(Expr *pExpr){
|
||||
*/
|
||||
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
|
||||
char aff = comparisonAffinity(pExpr);
|
||||
switch( aff ){
|
||||
case SQLITE_AFF_BLOB:
|
||||
return 1;
|
||||
case SQLITE_AFF_TEXT:
|
||||
return idx_affinity==SQLITE_AFF_TEXT;
|
||||
default:
|
||||
return sqlite3IsNumericAffinity(idx_affinity);
|
||||
if( aff<SQLITE_AFF_TEXT ){
|
||||
return 1;
|
||||
}
|
||||
if( aff==SQLITE_AFF_TEXT ){
|
||||
return idx_affinity==SQLITE_AFF_TEXT;
|
||||
}
|
||||
return sqlite3IsNumericAffinity(idx_affinity);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1040,15 +1046,18 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
|
||||
assert( p->x.pList==0 || p->pRight==0 );
|
||||
if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
|
||||
if( p->pRight ){
|
||||
assert( !ExprHasProperty(p, EP_WinFunc) );
|
||||
sqlite3ExprDeleteNN(db, p->pRight);
|
||||
}else if( ExprHasProperty(p, EP_xIsSelect) ){
|
||||
assert( !ExprHasProperty(p, EP_WinFunc) );
|
||||
sqlite3SelectDelete(db, p->x.pSelect);
|
||||
}else{
|
||||
sqlite3ExprListDelete(db, p->x.pList);
|
||||
}
|
||||
if( ExprHasProperty(p, EP_WinFunc) ){
|
||||
assert( p->op==TK_FUNCTION );
|
||||
sqlite3WindowDelete(db, p->y.pWin);
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
if( ExprHasProperty(p, EP_WinFunc) ){
|
||||
sqlite3WindowDelete(db, p->y.pWin);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
|
||||
@@ -1083,16 +1092,6 @@ static int exprStructSize(Expr *p){
|
||||
return EXPR_FULLSIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
** Copy the complete content of an Expr node, taking care not to read
|
||||
** past the end of the structure for a reduced-size version of the source
|
||||
** Expr.
|
||||
*/
|
||||
static void exprNodeCopy(Expr *pDest, Expr *pSrc){
|
||||
memset(pDest, 0, sizeof(Expr));
|
||||
memcpy(pDest, pSrc, exprStructSize(pSrc));
|
||||
}
|
||||
|
||||
/*
|
||||
** The dupedExpr*Size() routines each return the number of bytes required
|
||||
** to store a copy of an expression or expression tree. They differ in
|
||||
@@ -1332,10 +1331,13 @@ static With *withDup(sqlite3 *db, With *p){
|
||||
** objects found there, assembling them onto the linked list at Select->pWin.
|
||||
*/
|
||||
static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){
|
||||
if( pExpr->op==TK_FUNCTION && pExpr->y.pWin!=0 ){
|
||||
assert( ExprHasProperty(pExpr, EP_WinFunc) );
|
||||
pExpr->y.pWin->pNextWin = pWalker->u.pSelect->pWin;
|
||||
pWalker->u.pSelect->pWin = pExpr->y.pWin;
|
||||
if( pExpr->op==TK_FUNCTION && ExprHasProperty(pExpr, EP_WinFunc) ){
|
||||
Select *pSelect = pWalker->u.pSelect;
|
||||
Window *pWin = pExpr->y.pWin;
|
||||
assert( pWin );
|
||||
assert( IsWindowFunc(pExpr) );
|
||||
assert( pWin->ppThis==0 );
|
||||
sqlite3WindowLink(pSelect, pWin);
|
||||
}
|
||||
return WRC_Continue;
|
||||
}
|
||||
@@ -1409,7 +1411,7 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
|
||||
}
|
||||
pItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
|
||||
pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan);
|
||||
pItem->sortOrder = pOldItem->sortOrder;
|
||||
pItem->sortFlags = pOldItem->sortFlags;
|
||||
pItem->done = 0;
|
||||
pItem->bSpanIsTab = pOldItem->bSpanIsTab;
|
||||
pItem->bSorterRef = pOldItem->bSorterRef;
|
||||
@@ -1521,7 +1523,7 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
pNew->pWin = 0;
|
||||
pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn);
|
||||
if( p->pWin ) gatherSelectWindows(pNew);
|
||||
if( p->pWin && db->mallocFailed==0 ) gatherSelectWindows(pNew);
|
||||
#endif
|
||||
pNew->selId = p->selId;
|
||||
*pp = pNew;
|
||||
@@ -1663,14 +1665,14 @@ vector_append_error:
|
||||
** Set the sort order for the last element on the given ExprList.
|
||||
*/
|
||||
void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder){
|
||||
struct ExprList_item *pItem;
|
||||
if( p==0 ) return;
|
||||
assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC>=0 && SQLITE_SO_DESC>0 );
|
||||
assert( p->nExpr>0 );
|
||||
if( iSortOrder<0 ){
|
||||
assert( p->a[p->nExpr-1].sortOrder==SQLITE_SO_ASC );
|
||||
return;
|
||||
}
|
||||
p->a[p->nExpr-1].sortOrder = (u8)iSortOrder;
|
||||
assert( SQLITE_SO_DESC==KEYINFO_ORDER_DESC );
|
||||
assert( SQLITE_SO_BIGNULL==KEYINFO_ORDER_BIGNULL );
|
||||
|
||||
pItem = &p->a[p->nExpr-1];
|
||||
pItem->sortFlags = (u8)iSortOrder;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2169,8 +2171,12 @@ int sqlite3ExprCanBeNull(const Expr *p){
|
||||
*/
|
||||
int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){
|
||||
u8 op;
|
||||
int unaryMinus = 0;
|
||||
if( aff==SQLITE_AFF_BLOB ) return 1;
|
||||
while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; }
|
||||
while( p->op==TK_UPLUS || p->op==TK_UMINUS ){
|
||||
if( p->op==TK_UMINUS ) unaryMinus = 1;
|
||||
p = p->pLeft;
|
||||
}
|
||||
op = p->op;
|
||||
if( op==TK_REGISTER ) op = p->op2;
|
||||
switch( op ){
|
||||
@@ -2181,10 +2187,10 @@ int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){
|
||||
return aff==SQLITE_AFF_REAL || aff==SQLITE_AFF_NUMERIC;
|
||||
}
|
||||
case TK_STRING: {
|
||||
return aff==SQLITE_AFF_TEXT;
|
||||
return !unaryMinus && aff==SQLITE_AFF_TEXT;
|
||||
}
|
||||
case TK_BLOB: {
|
||||
return 1;
|
||||
return !unaryMinus;
|
||||
}
|
||||
case TK_COLUMN: {
|
||||
assert( p->iTable>=0 ); /* p cannot be part of a CHECK constraint */
|
||||
@@ -2797,9 +2803,9 @@ void sqlite3CodeRhsOfIN(
|
||||
int i;
|
||||
ExprList *pList = pExpr->x.pList;
|
||||
struct ExprList_item *pItem;
|
||||
int r1, r2, r3;
|
||||
int r1, r2;
|
||||
affinity = sqlite3ExprAffinity(pLeft);
|
||||
if( !affinity ){
|
||||
if( affinity<=SQLITE_AFF_NONE ){
|
||||
affinity = SQLITE_AFF_BLOB;
|
||||
}
|
||||
if( pKeyInfo ){
|
||||
@@ -2825,9 +2831,9 @@ void sqlite3CodeRhsOfIN(
|
||||
}
|
||||
|
||||
/* Evaluate the expression and insert it into the temp table */
|
||||
r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
|
||||
sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
|
||||
sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r3, 1);
|
||||
sqlite3ExprCode(pParse, pE2, r1);
|
||||
sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1);
|
||||
sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r1, 1);
|
||||
}
|
||||
sqlite3ReleaseTempReg(pParse, r1);
|
||||
sqlite3ReleaseTempReg(pParse, r2);
|
||||
@@ -3388,7 +3394,7 @@ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
|
||||
** the correct value for the expression.
|
||||
*/
|
||||
static void exprToRegister(Expr *pExpr, int iReg){
|
||||
Expr *p = sqlite3ExprSkipCollate(pExpr);
|
||||
Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr);
|
||||
p->op2 = p->op;
|
||||
p->op = TK_REGISTER;
|
||||
p->iTable = iReg;
|
||||
@@ -3489,7 +3495,7 @@ expr_code_doover:
|
||||
*/
|
||||
int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
|
||||
int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
|
||||
if( aff!=SQLITE_AFF_BLOB ){
|
||||
if( aff>SQLITE_AFF_BLOB ){
|
||||
static const char zAff[] = "B\000C\000D\000E";
|
||||
assert( SQLITE_AFF_BLOB=='A' );
|
||||
assert( SQLITE_AFF_TEXT=='B' );
|
||||
@@ -3792,7 +3798,7 @@ expr_code_doover:
|
||||
assert( nFarg==1 );
|
||||
aff = sqlite3ExprAffinity(pFarg->a[0].pExpr);
|
||||
sqlite3VdbeLoadString(v, target,
|
||||
aff ? azAff[aff-SQLITE_AFF_BLOB] : "none");
|
||||
(aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]);
|
||||
return target;
|
||||
}
|
||||
#endif
|
||||
@@ -4004,10 +4010,23 @@ expr_code_doover:
|
||||
break;
|
||||
}
|
||||
|
||||
/* TK_IF_NULL_ROW Expr nodes are inserted ahead of expressions
|
||||
** that derive from the right-hand table of a LEFT JOIN. The
|
||||
** Expr.iTable value is the table number for the right-hand table.
|
||||
** The expression is only evaluated if that table is not currently
|
||||
** on a LEFT JOIN NULL row.
|
||||
*/
|
||||
case TK_IF_NULL_ROW: {
|
||||
int addrINR;
|
||||
u8 okConstFactor = pParse->okConstFactor;
|
||||
addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable);
|
||||
/* Temporarily disable factoring of constant expressions, since
|
||||
** even though expressions may appear to be constant, they are not
|
||||
** really constant because they originate from the right-hand side
|
||||
** of a LEFT JOIN. */
|
||||
pParse->okConstFactor = 0;
|
||||
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
|
||||
pParse->okConstFactor = okConstFactor;
|
||||
sqlite3VdbeJumpHere(v, addrINR);
|
||||
sqlite3VdbeChangeP3(v, addrINR, inReg);
|
||||
break;
|
||||
@@ -4044,6 +4063,8 @@ expr_code_doover:
|
||||
Expr opCompare; /* The X==Ei expression */
|
||||
Expr *pX; /* The X expression */
|
||||
Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */
|
||||
Expr *pDel = 0;
|
||||
sqlite3 *db = pParse->db;
|
||||
|
||||
assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
|
||||
assert(pExpr->x.pList->nExpr > 0);
|
||||
@@ -4052,13 +4073,17 @@ expr_code_doover:
|
||||
nExpr = pEList->nExpr;
|
||||
endLabel = sqlite3VdbeMakeLabel(pParse);
|
||||
if( (pX = pExpr->pLeft)!=0 ){
|
||||
exprNodeCopy(&tempX, pX);
|
||||
pDel = sqlite3ExprDup(db, pX, 0);
|
||||
if( db->mallocFailed ){
|
||||
sqlite3ExprDelete(db, pDel);
|
||||
break;
|
||||
}
|
||||
testcase( pX->op==TK_COLUMN );
|
||||
exprToRegister(&tempX, exprCodeVector(pParse, &tempX, ®Free1));
|
||||
exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1));
|
||||
testcase( regFree1==0 );
|
||||
memset(&opCompare, 0, sizeof(opCompare));
|
||||
opCompare.op = TK_EQ;
|
||||
opCompare.pLeft = &tempX;
|
||||
opCompare.pLeft = pDel;
|
||||
pTest = &opCompare;
|
||||
/* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001:
|
||||
** The value in regFree1 might get SCopy-ed into the file result.
|
||||
@@ -4086,32 +4111,33 @@ expr_code_doover:
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
|
||||
}
|
||||
sqlite3ExprDelete(db, pDel);
|
||||
sqlite3VdbeResolveLabel(v, endLabel);
|
||||
break;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
case TK_RAISE: {
|
||||
assert( pExpr->affinity==OE_Rollback
|
||||
|| pExpr->affinity==OE_Abort
|
||||
|| pExpr->affinity==OE_Fail
|
||||
|| pExpr->affinity==OE_Ignore
|
||||
assert( pExpr->affExpr==OE_Rollback
|
||||
|| pExpr->affExpr==OE_Abort
|
||||
|| pExpr->affExpr==OE_Fail
|
||||
|| pExpr->affExpr==OE_Ignore
|
||||
);
|
||||
if( !pParse->pTriggerTab ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"RAISE() may only be used within a trigger-program");
|
||||
return 0;
|
||||
}
|
||||
if( pExpr->affinity==OE_Abort ){
|
||||
if( pExpr->affExpr==OE_Abort ){
|
||||
sqlite3MayAbort(pParse);
|
||||
}
|
||||
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
||||
if( pExpr->affinity==OE_Ignore ){
|
||||
if( pExpr->affExpr==OE_Ignore ){
|
||||
sqlite3VdbeAddOp4(
|
||||
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
|
||||
VdbeCoverage(v);
|
||||
}else{
|
||||
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER,
|
||||
pExpr->affinity, pExpr->u.zToken, 0, 0);
|
||||
pExpr->affExpr, pExpr->u.zToken, 0, 0);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -4176,7 +4202,7 @@ int sqlite3ExprCodeAtInit(
|
||||
*/
|
||||
int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
|
||||
int r2;
|
||||
pExpr = sqlite3ExprSkipCollate(pExpr);
|
||||
pExpr = sqlite3ExprSkipCollateAndLikely(pExpr);
|
||||
if( ConstFactorOk(pParse)
|
||||
&& pExpr->op!=TK_REGISTER
|
||||
&& sqlite3ExprIsConstantNotJoin(pExpr)
|
||||
@@ -4367,40 +4393,44 @@ static void exprCodeBetween(
|
||||
void (*xJump)(Parse*,Expr*,int,int), /* Action to take */
|
||||
int jumpIfNull /* Take the jump if the BETWEEN is NULL */
|
||||
){
|
||||
Expr exprAnd; /* The AND operator in x>=y AND x<=z */
|
||||
Expr exprAnd; /* The AND operator in x>=y AND x<=z */
|
||||
Expr compLeft; /* The x>=y term */
|
||||
Expr compRight; /* The x<=z term */
|
||||
Expr exprX; /* The x subexpression */
|
||||
int regFree1 = 0; /* Temporary use register */
|
||||
Expr *pDel = 0;
|
||||
sqlite3 *db = pParse->db;
|
||||
|
||||
memset(&compLeft, 0, sizeof(Expr));
|
||||
memset(&compRight, 0, sizeof(Expr));
|
||||
memset(&exprAnd, 0, sizeof(Expr));
|
||||
|
||||
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
|
||||
exprNodeCopy(&exprX, pExpr->pLeft);
|
||||
exprAnd.op = TK_AND;
|
||||
exprAnd.pLeft = &compLeft;
|
||||
exprAnd.pRight = &compRight;
|
||||
compLeft.op = TK_GE;
|
||||
compLeft.pLeft = &exprX;
|
||||
compLeft.pRight = pExpr->x.pList->a[0].pExpr;
|
||||
compRight.op = TK_LE;
|
||||
compRight.pLeft = &exprX;
|
||||
compRight.pRight = pExpr->x.pList->a[1].pExpr;
|
||||
exprToRegister(&exprX, exprCodeVector(pParse, &exprX, ®Free1));
|
||||
if( xJump ){
|
||||
xJump(pParse, &exprAnd, dest, jumpIfNull);
|
||||
}else{
|
||||
/* Mark the expression is being from the ON or USING clause of a join
|
||||
** so that the sqlite3ExprCodeTarget() routine will not attempt to move
|
||||
** it into the Parse.pConstExpr list. We should use a new bit for this,
|
||||
** for clarity, but we are out of bits in the Expr.flags field so we
|
||||
** have to reuse the EP_FromJoin bit. Bummer. */
|
||||
exprX.flags |= EP_FromJoin;
|
||||
sqlite3ExprCodeTarget(pParse, &exprAnd, dest);
|
||||
pDel = sqlite3ExprDup(db, pExpr->pLeft, 0);
|
||||
if( db->mallocFailed==0 ){
|
||||
exprAnd.op = TK_AND;
|
||||
exprAnd.pLeft = &compLeft;
|
||||
exprAnd.pRight = &compRight;
|
||||
compLeft.op = TK_GE;
|
||||
compLeft.pLeft = pDel;
|
||||
compLeft.pRight = pExpr->x.pList->a[0].pExpr;
|
||||
compRight.op = TK_LE;
|
||||
compRight.pLeft = pDel;
|
||||
compRight.pRight = pExpr->x.pList->a[1].pExpr;
|
||||
exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1));
|
||||
if( xJump ){
|
||||
xJump(pParse, &exprAnd, dest, jumpIfNull);
|
||||
}else{
|
||||
/* Mark the expression is being from the ON or USING clause of a join
|
||||
** so that the sqlite3ExprCodeTarget() routine will not attempt to move
|
||||
** it into the Parse.pConstExpr list. We should use a new bit for this,
|
||||
** for clarity, but we are out of bits in the Expr.flags field so we
|
||||
** have to reuse the EP_FromJoin bit. Bummer. */
|
||||
pDel->flags |= EP_FromJoin;
|
||||
sqlite3ExprCodeTarget(pParse, &exprAnd, dest);
|
||||
}
|
||||
sqlite3ReleaseTempReg(pParse, regFree1);
|
||||
}
|
||||
sqlite3ReleaseTempReg(pParse, regFree1);
|
||||
sqlite3ExprDelete(db, pDel);
|
||||
|
||||
/* Ensure adequate test coverage */
|
||||
testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1==0 );
|
||||
@@ -4839,20 +4869,17 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){
|
||||
return 2;
|
||||
}
|
||||
if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
|
||||
if( pA->op==TK_FUNCTION ){
|
||||
if( pA->op==TK_FUNCTION || pA->op==TK_AGG_FUNCTION ){
|
||||
if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
/* Justification for the assert():
|
||||
** window functions have p->op==TK_FUNCTION but aggregate functions
|
||||
** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate
|
||||
** function and a window function should have failed before reaching
|
||||
** this point. And, it is not possible to have a window function and
|
||||
** a scalar function with the same name and number of arguments. So
|
||||
** if we reach this point, either A and B both window functions or
|
||||
** neither are a window functions. */
|
||||
assert( ExprHasProperty(pA,EP_WinFunc)==ExprHasProperty(pB,EP_WinFunc) );
|
||||
assert( pA->op==pB->op );
|
||||
if( ExprHasProperty(pA,EP_WinFunc)!=ExprHasProperty(pB,EP_WinFunc) ){
|
||||
return 2;
|
||||
}
|
||||
if( ExprHasProperty(pA,EP_WinFunc) ){
|
||||
if( sqlite3WindowCompare(pParse,pA->y.pWin,pB->y.pWin)!=0 ) return 2;
|
||||
if( sqlite3WindowCompare(pParse, pA->y.pWin, pB->y.pWin, 1)!=0 ){
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}else if( pA->op==TK_NULL ){
|
||||
@@ -4906,7 +4933,7 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
|
||||
for(i=0; i<pA->nExpr; i++){
|
||||
Expr *pExprA = pA->a[i].pExpr;
|
||||
Expr *pExprB = pB->a[i].pExpr;
|
||||
if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
|
||||
if( pA->a[i].sortFlags!=pB->a[i].sortFlags ) return 1;
|
||||
if( sqlite3ExprCompare(0, pExprA, pExprB, iTab) ) return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -4918,8 +4945,8 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
|
||||
*/
|
||||
int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){
|
||||
return sqlite3ExprCompare(0,
|
||||
sqlite3ExprSkipCollate(pA),
|
||||
sqlite3ExprSkipCollate(pB),
|
||||
sqlite3ExprSkipCollateAndLikely(pA),
|
||||
sqlite3ExprSkipCollateAndLikely(pB),
|
||||
iTab);
|
||||
}
|
||||
|
||||
@@ -4935,7 +4962,9 @@ static int exprImpliesNotNull(
|
||||
){
|
||||
assert( p );
|
||||
assert( pNN );
|
||||
if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ) return 1;
|
||||
if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ){
|
||||
return pNN->op!=TK_NULL;
|
||||
}
|
||||
switch( p->op ){
|
||||
case TK_IN: {
|
||||
if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0;
|
||||
@@ -5125,7 +5154,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
|
||||
*/
|
||||
int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){
|
||||
Walker w;
|
||||
p = sqlite3ExprSkipCollate(p);
|
||||
p = sqlite3ExprSkipCollateAndLikely(p);
|
||||
while( p ){
|
||||
if( p->op==TK_NOTNULL ){
|
||||
p = p->pLeft;
|
||||
|
||||
+4
-3
@@ -478,13 +478,13 @@ static Expr *exprTableRegister(
|
||||
if( iCol>=0 && iCol!=pTab->iPKey ){
|
||||
pCol = &pTab->aCol[iCol];
|
||||
pExpr->iTable = regBase + iCol + 1;
|
||||
pExpr->affinity = pCol->affinity;
|
||||
pExpr->affExpr = pCol->affinity;
|
||||
zColl = pCol->zColl;
|
||||
if( zColl==0 ) zColl = db->pDfltColl->zName;
|
||||
pExpr = sqlite3ExprAddCollateString(pParse, pExpr, zColl);
|
||||
}else{
|
||||
pExpr->iTable = regBase;
|
||||
pExpr->affinity = SQLITE_AFF_INTEGER;
|
||||
pExpr->affExpr = SQLITE_AFF_INTEGER;
|
||||
}
|
||||
}
|
||||
return pExpr;
|
||||
@@ -1287,7 +1287,7 @@ static Trigger *fkActionTrigger(
|
||||
tFrom.n = nFrom;
|
||||
pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed");
|
||||
if( pRaise ){
|
||||
pRaise->affinity = OE_Abort;
|
||||
pRaise->affExpr = OE_Abort;
|
||||
}
|
||||
pSelect = sqlite3SelectNew(pParse,
|
||||
sqlite3ExprListAppend(pParse, 0, pRaise),
|
||||
@@ -1332,6 +1332,7 @@ static Trigger *fkActionTrigger(
|
||||
return 0;
|
||||
}
|
||||
assert( pStep!=0 );
|
||||
assert( pTrigger!=0 );
|
||||
|
||||
switch( action ){
|
||||
case OE_Restrict:
|
||||
|
||||
@@ -1986,9 +1986,6 @@ void sqlite3RegisterBuiltinFunctions(void){
|
||||
sqlite3AlterFunctions();
|
||||
#endif
|
||||
sqlite3WindowFunctions();
|
||||
#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
|
||||
sqlite3AnalyzeFunctions();
|
||||
#endif
|
||||
sqlite3RegisterDateTimeFunctions();
|
||||
sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc));
|
||||
|
||||
|
||||
@@ -214,6 +214,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
|
||||
SQLITE_USE_URI, /* bOpenUri */
|
||||
SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */
|
||||
0, /* bSmallMalloc */
|
||||
1, /* bExtraSchemaChecks */
|
||||
0x7ffffffe, /* mxStrlen */
|
||||
0, /* neverCorrupt */
|
||||
SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */
|
||||
@@ -260,6 +261,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
|
||||
0, /* bInternalFunctions */
|
||||
0x7ffffffe, /* iOnceResetThreshold */
|
||||
SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */
|
||||
0, /* iPrngSeed */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+10
-6
@@ -88,18 +88,18 @@ const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){
|
||||
}
|
||||
for(n=0; n<pIdx->nColumn; n++){
|
||||
i16 x = pIdx->aiColumn[n];
|
||||
char aff;
|
||||
if( x>=0 ){
|
||||
pIdx->zColAff[n] = pTab->aCol[x].affinity;
|
||||
aff = pTab->aCol[x].affinity;
|
||||
}else if( x==XN_ROWID ){
|
||||
pIdx->zColAff[n] = SQLITE_AFF_INTEGER;
|
||||
aff = SQLITE_AFF_INTEGER;
|
||||
}else{
|
||||
char aff;
|
||||
assert( x==XN_EXPR );
|
||||
assert( pIdx->aColExpr!=0 );
|
||||
aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr);
|
||||
if( aff==0 ) aff = SQLITE_AFF_BLOB;
|
||||
pIdx->zColAff[n] = aff;
|
||||
}
|
||||
if( aff<SQLITE_AFF_BLOB ) aff = SQLITE_AFF_BLOB;
|
||||
pIdx->zColAff[n] = aff;
|
||||
}
|
||||
pIdx->zColAff[n] = 0;
|
||||
}
|
||||
@@ -139,11 +139,12 @@ void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
|
||||
}
|
||||
|
||||
for(i=0; i<pTab->nCol; i++){
|
||||
assert( pTab->aCol[i].affinity!=0 );
|
||||
zColAff[i] = pTab->aCol[i].affinity;
|
||||
}
|
||||
do{
|
||||
zColAff[i--] = 0;
|
||||
}while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB );
|
||||
}while( i>=0 && zColAff[i]<=SQLITE_AFF_BLOB );
|
||||
pTab->zColAff = zColAff;
|
||||
}
|
||||
assert( zColAff!=0 );
|
||||
@@ -832,6 +833,9 @@ void sqlite3Insert(
|
||||
pTab->zName);
|
||||
goto insert_cleanup;
|
||||
}
|
||||
if( sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget) ){
|
||||
goto insert_cleanup;
|
||||
}
|
||||
pTabList->a[0].iCursor = iDataCur;
|
||||
pUpsert->pUpsertSrc = pTabList;
|
||||
pUpsert->regData = regData;
|
||||
|
||||
+3
-1
@@ -461,7 +461,9 @@ static const sqlite3_api_routines sqlite3Apis = {
|
||||
#endif
|
||||
/* Version 3.28.0 and later */
|
||||
sqlite3_stmt_isexplain,
|
||||
sqlite3_value_frombind
|
||||
sqlite3_value_frombind,
|
||||
/* Version 3.30.0 and later */
|
||||
sqlite3_drop_modules,
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+43
-10
@@ -836,6 +836,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
|
||||
} aFlagOp[] = {
|
||||
{ SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
|
||||
{ SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
|
||||
{ SQLITE_DBCONFIG_ENABLE_VIEW, SQLITE_EnableView },
|
||||
{ SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer },
|
||||
{ SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
|
||||
{ SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose },
|
||||
@@ -1235,11 +1236,8 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){
|
||||
Module *pMod = (Module *)sqliteHashData(i);
|
||||
if( pMod->xDestroy ){
|
||||
pMod->xDestroy(pMod->pAux);
|
||||
}
|
||||
sqlite3VtabEponymousTableClear(db, pMod);
|
||||
sqlite3DbFree(db, pMod);
|
||||
sqlite3VtabModuleUnref(db, pMod);
|
||||
}
|
||||
sqlite3HashClear(&db->aModule);
|
||||
#endif
|
||||
@@ -1720,7 +1718,8 @@ int sqlite3CreateFunc(
|
||||
}
|
||||
|
||||
assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
|
||||
extraFlags = enc & SQLITE_DETERMINISTIC;
|
||||
assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY );
|
||||
extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY);
|
||||
enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY);
|
||||
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
@@ -1783,6 +1782,7 @@ int sqlite3CreateFunc(
|
||||
p->u.pDestructor = pDestructor;
|
||||
p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags;
|
||||
testcase( p->funcFlags & SQLITE_DETERMINISTIC );
|
||||
testcase( p->funcFlags & SQLITE_DIRECTONLY );
|
||||
p->xSFunc = xSFunc ? xSFunc : xStep;
|
||||
p->xFinalize = xFinal;
|
||||
p->xValue = xValue;
|
||||
@@ -3075,6 +3075,7 @@ static int openDatabase(
|
||||
db->nMaxSorterMmap = 0x7FFFFFFF;
|
||||
db->flags |= SQLITE_ShortColNames
|
||||
| SQLITE_EnableTrigger
|
||||
| SQLITE_EnableView
|
||||
| SQLITE_CacheSpill
|
||||
|
||||
/* The SQLITE_DQS compile-time option determines the default settings
|
||||
@@ -3824,12 +3825,33 @@ int sqlite3_test_control(int op, ...){
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** Reset the PRNG back to its uninitialized state. The next call
|
||||
** to sqlite3_randomness() will reseed the PRNG using a single call
|
||||
** to the xRandomness method of the default VFS.
|
||||
/* sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, int x, sqlite3 *db);
|
||||
**
|
||||
** Control the seed for the pseudo-random number generator (PRNG) that
|
||||
** is built into SQLite. Cases:
|
||||
**
|
||||
** x!=0 && db!=0 Seed the PRNG to the current value of the
|
||||
** schema cookie in the main database for db, or
|
||||
** x if the schema cookie is zero. This case
|
||||
** is convenient to use with database fuzzers
|
||||
** as it allows the fuzzer some control over the
|
||||
** the PRNG seed.
|
||||
**
|
||||
** x!=0 && db==0 Seed the PRNG to the value of x.
|
||||
**
|
||||
** x==0 && db==0 Revert to default behavior of using the
|
||||
** xRandomness method on the primary VFS.
|
||||
**
|
||||
** This test-control also resets the PRNG so that the new seed will
|
||||
** be used for the next call to sqlite3_randomness().
|
||||
*/
|
||||
case SQLITE_TESTCTRL_PRNG_RESET: {
|
||||
case SQLITE_TESTCTRL_PRNG_SEED: {
|
||||
int x = va_arg(ap, int);
|
||||
int y;
|
||||
sqlite3 *db = va_arg(ap, sqlite3*);
|
||||
assert( db==0 || db->aDb[0].pSchema!=0 );
|
||||
if( db && (y = db->aDb[0].pSchema->schema_cookie)!=0 ){ x = y; }
|
||||
sqlite3Config.iPrngSeed = x;
|
||||
sqlite3_randomness(0,0);
|
||||
break;
|
||||
}
|
||||
@@ -4042,6 +4064,17 @@ int sqlite3_test_control(int op, ...){
|
||||
break;
|
||||
}
|
||||
|
||||
/* sqlite3_test_control(SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS, int);
|
||||
**
|
||||
** Set or clear a flag that causes SQLite to verify that type, name,
|
||||
** and tbl_name fields of the sqlite_master table. This is normally
|
||||
** on, but it is sometimes useful to turn it off for testing.
|
||||
*/
|
||||
case SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS: {
|
||||
sqlite3GlobalConfig.bExtraSchemaChecks = va_arg(ap, int);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the threshold at which OP_Once counters reset back to zero.
|
||||
** By default this is 0x7ffffffe (over 2 billion), but that value is
|
||||
** too big to test in a reasonable amount of time, so this control is
|
||||
|
||||
@@ -96,14 +96,9 @@ static int memjrnlRead(
|
||||
int iChunkOffset;
|
||||
FileChunk *pChunk;
|
||||
|
||||
#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
|
||||
|| defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
|
||||
if( (iAmt+iOfst)>p->endpoint.iOffset ){
|
||||
return SQLITE_IOERR_SHORT_READ;
|
||||
}
|
||||
#endif
|
||||
|
||||
assert( (iAmt+iOfst)<=p->endpoint.iOffset );
|
||||
assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 );
|
||||
if( p->readpoint.iOffset!=iOfst || iOfst==0 ){
|
||||
sqlite3_int64 iOff = 0;
|
||||
|
||||
@@ -258,7 +258,15 @@ void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
|
||||
}
|
||||
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
|
||||
int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
|
||||
return pVfs->xRandomness(pVfs, nByte, zBufOut);
|
||||
if( sqlite3Config.iPrngSeed ){
|
||||
memset(zBufOut, 0, nByte);
|
||||
if( ALWAYS(nByte>(signed)sizeof(unsigned)) ) nByte = sizeof(unsigned int);
|
||||
memcpy(zBufOut, &sqlite3Config.iPrngSeed, nByte);
|
||||
return SQLITE_OK;
|
||||
}else{
|
||||
return pVfs->xRandomness(pVfs, nByte, zBufOut);
|
||||
}
|
||||
|
||||
}
|
||||
int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
|
||||
return pVfs->xSleep(pVfs, nMicro);
|
||||
|
||||
+6
-3
@@ -521,13 +521,14 @@ static struct unix_syscall {
|
||||
#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
|
||||
# ifdef __ANDROID__
|
||||
{ "ioctl", (sqlite3_syscall_ptr)(int(*)(int, int, ...))ioctl, 0 },
|
||||
#define osIoctl ((int(*)(int,int,...))aSyscall[28].pCurrent)
|
||||
# else
|
||||
{ "ioctl", (sqlite3_syscall_ptr)ioctl, 0 },
|
||||
#define osIoctl ((int(*)(int,unsigned long,...))aSyscall[28].pCurrent)
|
||||
# endif
|
||||
#else
|
||||
{ "ioctl", (sqlite3_syscall_ptr)0, 0 },
|
||||
#endif
|
||||
#define osIoctl ((int(*)(int,int,...))aSyscall[28].pCurrent)
|
||||
|
||||
}; /* End of the overrideable system calls */
|
||||
|
||||
@@ -5769,6 +5770,7 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
|
||||
UnixUnusedFd **pp;
|
||||
assert( sqlite3_mutex_notheld(pInode->pLockMutex) );
|
||||
sqlite3_mutex_enter(pInode->pLockMutex);
|
||||
flags &= (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE);
|
||||
for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
|
||||
pUnused = *pp;
|
||||
if( pUnused ){
|
||||
@@ -6072,7 +6074,8 @@ static int unixOpen(
|
||||
|
||||
if( p->pPreallocatedUnused ){
|
||||
p->pPreallocatedUnused->fd = fd;
|
||||
p->pPreallocatedUnused->flags = flags;
|
||||
p->pPreallocatedUnused->flags =
|
||||
flags & (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE);
|
||||
}
|
||||
|
||||
if( isDelete ){
|
||||
@@ -7603,7 +7606,7 @@ static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
assert( 0 ); /* The call assures that only valid opcodes are sent */
|
||||
}
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
/*NOTREACHED*/ assert(0);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -4215,6 +4215,7 @@ static int winShmMap(
|
||||
rc = winOpenSharedMemory(pDbFd);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
pShm = pDbFd->pShm;
|
||||
assert( pShm!=0 );
|
||||
}
|
||||
pShmNode = pShm->pShmNode;
|
||||
|
||||
@@ -4517,6 +4518,7 @@ static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
|
||||
}
|
||||
}
|
||||
if( pFd->mmapSize >= iOff+nAmt ){
|
||||
assert( pFd->pMapRegion!=0 );
|
||||
*pp = &((u8 *)pFd->pMapRegion)[iOff];
|
||||
pFd->nFetchOut++;
|
||||
}
|
||||
|
||||
+50
-26
@@ -211,6 +211,7 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);}
|
||||
IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
|
||||
QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS
|
||||
ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
|
||||
NULLS FIRST LAST
|
||||
%ifdef SQLITE_OMIT_COMPOUND_SELECT
|
||||
EXCEPT INTERSECT UNION
|
||||
%endif SQLITE_OMIT_COMPOUND_SELECT
|
||||
@@ -458,6 +459,7 @@ cmd ::= select(X). {
|
||||
** SQLITE_LIMIT_COMPOUND_SELECT.
|
||||
*/
|
||||
static void parserDoubleLinkSelect(Parse *pParse, Select *p){
|
||||
assert( p!=0 );
|
||||
if( p->pPrior ){
|
||||
Select *pNext = 0, *pLoop;
|
||||
int mxSelect, cnt = 0;
|
||||
@@ -791,9 +793,15 @@ sortlist(A) ::= expr(Y) sortorder(Z). {
|
||||
|
||||
%type sortorder {int}
|
||||
|
||||
sortorder(A) ::= ASC. {A = SQLITE_SO_ASC;}
|
||||
sortorder(A) ::= DESC. {A = SQLITE_SO_DESC;}
|
||||
sortorder(A) ::= . {A = SQLITE_SO_UNDEFINED;}
|
||||
sortorder(A) ::= ASC. {A = SQLITE_SO_XASC;}
|
||||
sortorder(A) ::= ASC NULLS FIRST. {A = SQLITE_SO_XASC|SQLITE_SO_SMALLNULL;}
|
||||
sortorder(A) ::= ASC NULLS LAST. {A = SQLITE_SO_XASC|SQLITE_SO_BIGNULL;}
|
||||
sortorder(A) ::= DESC. {A = SQLITE_SO_DESC;}
|
||||
sortorder(A) ::= DESC NULLS FIRST. {A = SQLITE_SO_DESC|SQLITE_SO_BIGNULL;}
|
||||
sortorder(A) ::= DESC NULLS LAST. {A = SQLITE_SO_DESC|SQLITE_SO_SMALLNULL;}
|
||||
sortorder(A) ::= . {A = SQLITE_SO_ASC;}
|
||||
sortorder(A) ::= NULLS FIRST. {A = SQLITE_SO_XASC|SQLITE_SO_SMALLNULL;}
|
||||
sortorder(A) ::= NULLS LAST. {A = SQLITE_SO_XASC|SQLITE_SO_BIGNULL;}
|
||||
|
||||
%type groupby_opt {ExprList*}
|
||||
%destructor groupby_opt {sqlite3ExprListDelete(pParse->db, $$);}
|
||||
@@ -948,7 +956,7 @@ idlist(A) ::= nm(Y).
|
||||
if( p ){
|
||||
/* memset(p, 0, sizeof(Expr)); */
|
||||
p->op = (u8)op;
|
||||
p->affinity = 0;
|
||||
p->affExpr = 0;
|
||||
p->flags = EP_Leaf;
|
||||
p->iAgg = -1;
|
||||
p->pLeft = p->pRight = 0;
|
||||
@@ -1044,11 +1052,11 @@ expr(A) ::= id(X) LP STAR RP. {
|
||||
}
|
||||
|
||||
%ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP over_clause(Z). {
|
||||
expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP filter_over(Z). {
|
||||
A = sqlite3ExprFunction(pParse, Y, &X, D);
|
||||
sqlite3WindowAttach(pParse, A, Z);
|
||||
}
|
||||
expr(A) ::= id(X) LP STAR RP over_clause(Z). {
|
||||
expr(A) ::= id(X) LP STAR RP filter_over(Z). {
|
||||
A = sqlite3ExprFunction(pParse, 0, &X, 0);
|
||||
sqlite3WindowAttach(pParse, A, Z);
|
||||
}
|
||||
@@ -1340,7 +1348,7 @@ uniqueflag(A) ::= . {A = OE_None;}
|
||||
int sortOrder
|
||||
){
|
||||
ExprList *p = sqlite3ExprListAppend(pParse, pPrior, 0);
|
||||
if( (hasCollate || sortOrder!=SQLITE_SO_UNDEFINED)
|
||||
if( (hasCollate || sortOrder!=SQLITE_SO_ASC)
|
||||
&& pParse->db->init.busy==0
|
||||
){
|
||||
sqlite3ErrorMsg(pParse, "syntax error after column name \"%.*s\"",
|
||||
@@ -1507,13 +1515,13 @@ trigger_cmd(A) ::= scanpt(B) select(X) scanpt(E).
|
||||
expr(A) ::= RAISE LP IGNORE RP. {
|
||||
A = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
|
||||
if( A ){
|
||||
A->affinity = OE_Ignore;
|
||||
A->affExpr = OE_Ignore;
|
||||
}
|
||||
}
|
||||
expr(A) ::= RAISE LP raisetype(T) COMMA nm(Z) RP. {
|
||||
A = sqlite3ExprAlloc(pParse->db, TK_RAISE, &Z, 1);
|
||||
if( A ) {
|
||||
A->affinity = (char)T;
|
||||
A->affExpr = (char)T;
|
||||
}
|
||||
}
|
||||
%endif !SQLITE_OMIT_TRIGGER
|
||||
@@ -1657,8 +1665,14 @@ windowdefn(A) ::= nm(X) AS LP window(Y) RP. {
|
||||
%type part_opt {ExprList*}
|
||||
%destructor part_opt {sqlite3ExprListDelete(pParse->db, $$);}
|
||||
|
||||
%type filter_opt {Expr*}
|
||||
%destructor filter_opt {sqlite3ExprDelete(pParse->db, $$);}
|
||||
%type filter_clause {Expr*}
|
||||
%destructor filter_clause {sqlite3ExprDelete(pParse->db, $$);}
|
||||
|
||||
%type over_clause {Window*}
|
||||
%destructor over_clause {sqlite3WindowDelete(pParse->db, $$);}
|
||||
|
||||
%type filter_over {Window*}
|
||||
%destructor filter_over {sqlite3WindowDelete(pParse->db, $$);}
|
||||
|
||||
%type range_or_rows {int}
|
||||
|
||||
@@ -1724,25 +1738,35 @@ frame_exclude(A) ::= GROUP|TIES(X). {A = @X; /*A-overwrites-X*/}
|
||||
%destructor window_clause {sqlite3WindowListDelete(pParse->db, $$);}
|
||||
window_clause(A) ::= WINDOW windowdefn_list(B). { A = B; }
|
||||
|
||||
%type over_clause {Window*}
|
||||
%destructor over_clause {sqlite3WindowDelete(pParse->db, $$);}
|
||||
over_clause(A) ::= filter_opt(W) OVER LP window(Z) RP. {
|
||||
A = Z;
|
||||
assert( A!=0 );
|
||||
A->pFilter = W;
|
||||
filter_over(A) ::= filter_clause(F) over_clause(O). {
|
||||
O->pFilter = F;
|
||||
A = O;
|
||||
}
|
||||
over_clause(A) ::= filter_opt(W) OVER nm(Z). {
|
||||
filter_over(A) ::= over_clause(O). {
|
||||
A = O;
|
||||
}
|
||||
filter_over(A) ::= filter_clause(F). {
|
||||
A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
|
||||
if( A ){
|
||||
A->zName = sqlite3DbStrNDup(pParse->db, Z.z, Z.n);
|
||||
A->pFilter = W;
|
||||
A->eFrmType = TK_FILTER;
|
||||
A->pFilter = F;
|
||||
}else{
|
||||
sqlite3ExprDelete(pParse->db, W);
|
||||
sqlite3ExprDelete(pParse->db, F);
|
||||
}
|
||||
}
|
||||
|
||||
filter_opt(A) ::= . { A = 0; }
|
||||
filter_opt(A) ::= FILTER LP WHERE expr(X) RP. { A = X; }
|
||||
over_clause(A) ::= OVER LP window(Z) RP. {
|
||||
A = Z;
|
||||
assert( A!=0 );
|
||||
}
|
||||
over_clause(A) ::= OVER nm(Z). {
|
||||
A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
|
||||
if( A ){
|
||||
A->zName = sqlite3DbStrNDup(pParse->db, Z.z, Z.n);
|
||||
}
|
||||
}
|
||||
|
||||
filter_clause(A) ::= FILTER LP WHERE expr(X) RP. { A = X; }
|
||||
%endif /* SQLITE_OMIT_WINDOWFUNC */
|
||||
|
||||
/*
|
||||
@@ -1750,12 +1774,12 @@ filter_opt(A) ::= FILTER LP WHERE expr(X) RP. { A = X; }
|
||||
** are synthesized and do not actually appear in the grammar:
|
||||
*/
|
||||
%token
|
||||
TRUEFALSE /* True or false keyword */
|
||||
ISNOT /* Combination of IS and NOT */
|
||||
FUNCTION /* A function invocation */
|
||||
COLUMN /* Reference to a table column */
|
||||
AGG_FUNCTION /* An aggregate function */
|
||||
AGG_COLUMN /* An aggregated column */
|
||||
TRUEFALSE /* True or false keyword */
|
||||
ISNOT /* Combination of IS and NOT */
|
||||
FUNCTION /* A function invocation */
|
||||
UMINUS /* Unary minus */
|
||||
UPLUS /* Unary plus */
|
||||
TRUTH /* IS TRUE or IS FALSE or IS NOT TRUE or IS NOT FALSE */
|
||||
|
||||
@@ -262,6 +262,7 @@ int sqlite3PcacheInitialize(void){
|
||||
** built-in default page cache is used instead of the application defined
|
||||
** page cache. */
|
||||
sqlite3PCacheSetDefault();
|
||||
assert( sqlite3GlobalConfig.pcache2.xInit!=0 );
|
||||
}
|
||||
return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg);
|
||||
}
|
||||
|
||||
@@ -424,6 +424,7 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
|
||||
|
||||
assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
|
||||
if( pCache->pFree || (pCache->nPage==0 && pcache1InitBulk(pCache)) ){
|
||||
assert( pCache->pFree!=0 );
|
||||
p = pCache->pFree;
|
||||
pCache->pFree = p->pNext;
|
||||
p->pNext = 0;
|
||||
|
||||
+10
-1
@@ -1157,6 +1157,15 @@ void sqlite3Pragma(
|
||||
Index *pIdx;
|
||||
Table *pTab;
|
||||
pIdx = sqlite3FindIndex(db, zRight, zDb);
|
||||
if( pIdx==0 ){
|
||||
/* If there is no index named zRight, check to see if there is a
|
||||
** WITHOUT ROWID table named zRight, and if there is, show the
|
||||
** structure of the PRIMARY KEY index for that table. */
|
||||
pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
|
||||
if( pTab && !HasRowid(pTab) ){
|
||||
pIdx = sqlite3PrimaryKeyIndex(pTab);
|
||||
}
|
||||
}
|
||||
if( pIdx ){
|
||||
int iIdxDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
|
||||
int i;
|
||||
@@ -1236,7 +1245,7 @@ void sqlite3Pragma(
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef SQLITE_INTROSPECTION_PRAGMAS
|
||||
#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
|
||||
case PragTyp_FUNCTION_LIST: {
|
||||
int i;
|
||||
HashElem *j;
|
||||
|
||||
+4
-4
@@ -311,7 +311,7 @@ static const PragmaName aPragmaName[] = {
|
||||
/* iArg: */ SQLITE_FullFSync },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
|
||||
{/* zName: */ "function_list",
|
||||
/* ePragTyp: */ PragTyp_FUNCTION_LIST,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
@@ -435,7 +435,7 @@ static const PragmaName aPragmaName[] = {
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_VIRTUALTABLE)
|
||||
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
|
||||
{/* zName: */ "module_list",
|
||||
/* ePragTyp: */ PragTyp_MODULE_LIST,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
@@ -470,7 +470,7 @@ static const PragmaName aPragmaName[] = {
|
||||
/* iArg: */ SQLITE_ParserTrace },
|
||||
#endif
|
||||
#endif
|
||||
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
|
||||
{/* zName: */ "pragma_list",
|
||||
/* ePragTyp: */ PragTyp_PRAGMA_LIST,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
@@ -668,4 +668,4 @@ static const PragmaName aPragmaName[] = {
|
||||
/* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
|
||||
#endif
|
||||
};
|
||||
/* Number of pragmas: 62 on by default, 81 total. */
|
||||
/* Number of pragmas: 65 on by default, 81 total. */
|
||||
|
||||
+35
-27
@@ -64,9 +64,11 @@ int sqlite3IndexHasDuplicateRootPage(Index *pIndex){
|
||||
**
|
||||
** Each callback contains the following information:
|
||||
**
|
||||
** argv[0] = name of thing being created
|
||||
** argv[1] = root page number for table or index. 0 for trigger or view.
|
||||
** argv[2] = SQL text for the CREATE statement.
|
||||
** argv[0] = type of object: "table", "index", "trigger", or "view".
|
||||
** argv[1] = name of thing being created
|
||||
** argv[2] = associated table if an index or trigger
|
||||
** argv[3] = root page number for table or index. 0 for trigger or view.
|
||||
** argv[4] = SQL text for the CREATE statement.
|
||||
**
|
||||
*/
|
||||
int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
|
||||
@@ -74,21 +76,21 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
|
||||
sqlite3 *db = pData->db;
|
||||
int iDb = pData->iDb;
|
||||
|
||||
assert( argc==3 );
|
||||
assert( argc==5 );
|
||||
UNUSED_PARAMETER2(NotUsed, argc);
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
DbClearProperty(db, iDb, DB_Empty);
|
||||
pData->nInitRow++;
|
||||
if( db->mallocFailed ){
|
||||
corruptSchema(pData, argv[0], 0);
|
||||
corruptSchema(pData, argv[1], 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
assert( iDb>=0 && iDb<db->nDb );
|
||||
if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */
|
||||
if( argv[1]==0 ){
|
||||
corruptSchema(pData, argv[0], 0);
|
||||
}else if( sqlite3_strnicmp(argv[2],"create ",7)==0 ){
|
||||
if( argv[3]==0 ){
|
||||
corruptSchema(pData, argv[1], 0);
|
||||
}else if( sqlite3_strnicmp(argv[4],"create ",7)==0 ){
|
||||
/* Call the parser to process a CREATE TABLE, INDEX or VIEW.
|
||||
** But because db->init.busy is set to 1, no VDBE code is generated
|
||||
** or executed. All the parser does is build the internal data
|
||||
@@ -101,9 +103,10 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
|
||||
|
||||
assert( db->init.busy );
|
||||
db->init.iDb = iDb;
|
||||
db->init.newTnum = sqlite3Atoi(argv[1]);
|
||||
db->init.newTnum = sqlite3Atoi(argv[3]);
|
||||
db->init.orphanTrigger = 0;
|
||||
TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0);
|
||||
db->init.azInit = argv;
|
||||
TESTONLY(rcp = ) sqlite3_prepare(db, argv[4], -1, &pStmt, 0);
|
||||
rc = db->errCode;
|
||||
assert( (rc&0xFF)==(rcp&0xFF) );
|
||||
db->init.iDb = saved_iDb;
|
||||
@@ -112,17 +115,17 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
|
||||
if( db->init.orphanTrigger ){
|
||||
assert( iDb==1 );
|
||||
}else{
|
||||
pData->rc = rc;
|
||||
if( rc > pData->rc ) pData->rc = rc;
|
||||
if( rc==SQLITE_NOMEM ){
|
||||
sqlite3OomFault(db);
|
||||
}else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
|
||||
corruptSchema(pData, argv[0], sqlite3_errmsg(db));
|
||||
corruptSchema(pData, argv[1], sqlite3_errmsg(db));
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
}else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){
|
||||
corruptSchema(pData, argv[0], 0);
|
||||
}else if( argv[1]==0 || (argv[4]!=0 && argv[4][0]!=0) ){
|
||||
corruptSchema(pData, argv[1], 0);
|
||||
}else{
|
||||
/* If the SQL column is blank it means this is an index that
|
||||
** was created to be the PRIMARY KEY or to fulfill a UNIQUE
|
||||
@@ -131,13 +134,13 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
|
||||
** to do here is record the root page number for that index.
|
||||
*/
|
||||
Index *pIndex;
|
||||
pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zDbSName);
|
||||
pIndex = sqlite3FindIndex(db, argv[1], db->aDb[iDb].zDbSName);
|
||||
if( pIndex==0
|
||||
|| sqlite3GetInt32(argv[1],&pIndex->tnum)==0
|
||||
|| sqlite3GetInt32(argv[3],&pIndex->tnum)==0
|
||||
|| pIndex->tnum<2
|
||||
|| sqlite3IndexHasDuplicateRootPage(pIndex)
|
||||
){
|
||||
corruptSchema(pData, argv[0], pIndex?"invalid rootpage":"orphan index");
|
||||
corruptSchema(pData, argv[1], pIndex?"invalid rootpage":"orphan index");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -158,7 +161,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
|
||||
int size;
|
||||
#endif
|
||||
Db *pDb;
|
||||
char const *azArg[4];
|
||||
char const *azArg[6];
|
||||
int meta[5];
|
||||
InitData initData;
|
||||
const char *zMasterName;
|
||||
@@ -177,18 +180,20 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
|
||||
** table name will be inserted automatically by the parser so we can just
|
||||
** use the abbreviation "x" here. The parser will also automatically tag
|
||||
** the schema table as read-only. */
|
||||
azArg[0] = zMasterName = SCHEMA_TABLE(iDb);
|
||||
azArg[1] = "1";
|
||||
azArg[2] = "CREATE TABLE x(type text,name text,tbl_name text,"
|
||||
azArg[0] = "table";
|
||||
azArg[1] = zMasterName = SCHEMA_TABLE(iDb);
|
||||
azArg[2] = azArg[1];
|
||||
azArg[3] = "1";
|
||||
azArg[4] = "CREATE TABLE x(type text,name text,tbl_name text,"
|
||||
"rootpage int,sql text)";
|
||||
azArg[3] = 0;
|
||||
azArg[5] = 0;
|
||||
initData.db = db;
|
||||
initData.iDb = iDb;
|
||||
initData.rc = SQLITE_OK;
|
||||
initData.pzErrMsg = pzErrMsg;
|
||||
initData.mInitFlags = mFlags;
|
||||
initData.nInitRow = 0;
|
||||
sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
|
||||
sqlite3InitCallback(&initData, 5, (char **)azArg, 0);
|
||||
if( initData.rc ){
|
||||
rc = initData.rc;
|
||||
goto error_out;
|
||||
@@ -314,7 +319,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
|
||||
{
|
||||
char *zSql;
|
||||
zSql = sqlite3MPrintf(db,
|
||||
"SELECT name, rootpage, sql FROM \"%w\".%s ORDER BY rowid",
|
||||
"SELECT*FROM\"%w\".%s ORDER BY rowid",
|
||||
db->aDb[iDb].zDbSName, zMasterName);
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
{
|
||||
@@ -635,7 +640,10 @@ static int sqlite3Prepare(
|
||||
rc = sParse.rc;
|
||||
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
|
||||
/* Justification for the ALWAYS(): The only way for rc to be SQLITE_OK and
|
||||
** sParse.pVdbe to be NULL is if the input SQL is an empty string, but in
|
||||
** that case, sParse.explain will be false. */
|
||||
if( sParse.explain && rc==SQLITE_OK && ALWAYS(sParse.pVdbe) ){
|
||||
static const char * const azColName[] = {
|
||||
"addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
|
||||
"id", "parent", "notused", "detail"
|
||||
@@ -660,8 +668,8 @@ static int sqlite3Prepare(
|
||||
if( db->init.busy==0 ){
|
||||
sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags);
|
||||
}
|
||||
if( sParse.pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
|
||||
sqlite3VdbeFinalize(sParse.pVdbe);
|
||||
if( rc!=SQLITE_OK || db->mallocFailed ){
|
||||
if( sParse.pVdbe ) sqlite3VdbeFinalize(sParse.pVdbe);
|
||||
assert(!(*ppStmt));
|
||||
}else{
|
||||
*ppStmt = (sqlite3_stmt*)sParse.pVdbe;
|
||||
|
||||
+67
-43
@@ -381,7 +381,7 @@ static int lookupName(
|
||||
{
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
if( iCol<0 ){
|
||||
pExpr->affinity = SQLITE_AFF_INTEGER;
|
||||
pExpr->affExpr = SQLITE_AFF_INTEGER;
|
||||
}else if( pExpr->iTable==0 ){
|
||||
testcase( iCol==31 );
|
||||
testcase( iCol==32 );
|
||||
@@ -413,7 +413,7 @@ static int lookupName(
|
||||
){
|
||||
cnt = 1;
|
||||
pExpr->iColumn = -1;
|
||||
pExpr->affinity = SQLITE_AFF_INTEGER;
|
||||
pExpr->affExpr = SQLITE_AFF_INTEGER;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -689,7 +689,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
pExpr->y.pTab = pItem->pTab;
|
||||
pExpr->iTable = pItem->iCursor;
|
||||
pExpr->iColumn = -1;
|
||||
pExpr->affinity = SQLITE_AFF_INTEGER;
|
||||
pExpr->affExpr = SQLITE_AFF_INTEGER;
|
||||
break;
|
||||
}
|
||||
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
|
||||
@@ -749,7 +749,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
FuncDef *pDef; /* Information about the function */
|
||||
u8 enc = ENC(pParse->db); /* The database encoding */
|
||||
int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin));
|
||||
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0);
|
||||
#endif
|
||||
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
|
||||
zId = pExpr->u.zToken;
|
||||
nId = sqlite3Strlen30(zId);
|
||||
@@ -821,6 +823,15 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
** SQL is being compiled using sqlite3NestedParse() */
|
||||
no_such_func = 1;
|
||||
pDef = 0;
|
||||
}else
|
||||
if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0
|
||||
&& ExprHasProperty(pExpr, EP_Indirect)
|
||||
&& !IN_RENAME_OBJECT
|
||||
){
|
||||
/* Functions tagged with SQLITE_DIRECTONLY may not be used
|
||||
** inside of triggers and views */
|
||||
sqlite3ErrorMsg(pParse, "%s() prohibited in triggers and views",
|
||||
pDef->zName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -830,18 +841,18 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
|| (pDef->xValue==0 && pDef->xInverse==0)
|
||||
|| (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
|
||||
);
|
||||
if( pDef && pDef->xValue==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
|
||||
if( pDef && pDef->xValue==0 && pWin ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"%.*s() may not be used as a window function", nId, zId
|
||||
);
|
||||
pNC->nErr++;
|
||||
}else if(
|
||||
(is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
|
||||
|| (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pExpr->y.pWin)
|
||||
|| (is_agg && pExpr->y.pWin && (pNC->ncFlags & NC_AllowWin)==0)
|
||||
|| (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pWin)
|
||||
|| (is_agg && pWin && (pNC->ncFlags & NC_AllowWin)==0)
|
||||
){
|
||||
const char *zType;
|
||||
if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->y.pWin ){
|
||||
if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pWin ){
|
||||
zType = "window";
|
||||
}else{
|
||||
zType = "aggregate";
|
||||
@@ -869,34 +880,44 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
nId, zId);
|
||||
pNC->nErr++;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
else if( is_agg==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"FILTER may not be used with non-aggregate %.*s()",
|
||||
nId, zId
|
||||
);
|
||||
pNC->nErr++;
|
||||
}
|
||||
#endif
|
||||
if( is_agg ){
|
||||
/* Window functions may not be arguments of aggregate functions.
|
||||
** Or arguments of other window functions. But aggregate functions
|
||||
** may be arguments for window functions. */
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
pNC->ncFlags &= ~(NC_AllowWin | (!pExpr->y.pWin ? NC_AllowAgg : 0));
|
||||
pNC->ncFlags &= ~(NC_AllowWin | (!pWin ? NC_AllowAgg : 0));
|
||||
#else
|
||||
pNC->ncFlags &= ~NC_AllowAgg;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
else if( ExprHasProperty(pExpr, EP_WinFunc) ){
|
||||
is_agg = 1;
|
||||
}
|
||||
#endif
|
||||
sqlite3WalkExprList(pWalker, pList);
|
||||
if( is_agg ){
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
if( pExpr->y.pWin ){
|
||||
if( pWin ){
|
||||
Select *pSel = pNC->pWinSelect;
|
||||
assert( pWin==pExpr->y.pWin );
|
||||
if( IN_RENAME_OBJECT==0 ){
|
||||
sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
|
||||
}
|
||||
sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
|
||||
sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
|
||||
sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
|
||||
if( 0==pSel->pWin
|
||||
|| 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin)
|
||||
){
|
||||
pExpr->y.pWin->pNextWin = pSel->pWin;
|
||||
pSel->pWin = pExpr->y.pWin;
|
||||
sqlite3WindowUpdate(pParse, pSel->pWinDefn, pWin, pDef);
|
||||
}
|
||||
sqlite3WalkExprList(pWalker, pWin->pPartition);
|
||||
sqlite3WalkExprList(pWalker, pWin->pOrderBy);
|
||||
sqlite3WalkExpr(pWalker, pWin->pFilter);
|
||||
sqlite3WindowLink(pSel, pWin);
|
||||
pNC->ncFlags |= NC_HasWin;
|
||||
}else
|
||||
#endif /* SQLITE_OMIT_WINDOWFUNC */
|
||||
@@ -904,12 +925,17 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
NameContext *pNC2 = pNC;
|
||||
pExpr->op = TK_AGG_FUNCTION;
|
||||
pExpr->op2 = 0;
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
if( ExprHasProperty(pExpr, EP_WinFunc) ){
|
||||
sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
|
||||
}
|
||||
#endif
|
||||
while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
|
||||
pExpr->op2++;
|
||||
pNC2 = pNC2->pNext;
|
||||
}
|
||||
assert( pDef!=0 );
|
||||
if( pNC2 ){
|
||||
assert( pDef!=0 || IN_RENAME_OBJECT );
|
||||
if( pNC2 && pDef ){
|
||||
assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
|
||||
testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
|
||||
pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);
|
||||
@@ -947,7 +973,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
}
|
||||
case TK_IS:
|
||||
case TK_ISNOT: {
|
||||
Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
|
||||
Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight);
|
||||
assert( !ExprHasProperty(pExpr, EP_Reduced) );
|
||||
/* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
|
||||
** and "x IS NOT FALSE". */
|
||||
@@ -1158,7 +1184,7 @@ static int resolveCompoundOrderBy(
|
||||
int iCol = -1;
|
||||
Expr *pE, *pDup;
|
||||
if( pItem->done ) continue;
|
||||
pE = sqlite3ExprSkipCollate(pItem->pExpr);
|
||||
pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr);
|
||||
if( sqlite3ExprIsInteger(pE, &iCol) ){
|
||||
if( iCol<=0 || iCol>pEList->nExpr ){
|
||||
resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
|
||||
@@ -1252,7 +1278,7 @@ int sqlite3ResolveOrderGroupBy(
|
||||
ExprList *pEList;
|
||||
struct ExprList_item *pItem;
|
||||
|
||||
if( pOrderBy==0 || pParse->db->mallocFailed ) return 0;
|
||||
if( pOrderBy==0 || pParse->db->mallocFailed || IN_RENAME_OBJECT ) return 0;
|
||||
if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
|
||||
sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType);
|
||||
return 1;
|
||||
@@ -1274,17 +1300,13 @@ int sqlite3ResolveOrderGroupBy(
|
||||
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
/*
|
||||
** Walker callback for resolveRemoveWindows().
|
||||
** Walker callback for windowRemoveExprFromSelect().
|
||||
*/
|
||||
static int resolveRemoveWindowsCb(Walker *pWalker, Expr *pExpr){
|
||||
UNUSED_PARAMETER(pWalker);
|
||||
if( ExprHasProperty(pExpr, EP_WinFunc) ){
|
||||
Window **pp;
|
||||
for(pp=&pWalker->u.pSelect->pWin; *pp; pp=&(*pp)->pNextWin){
|
||||
if( *pp==pExpr->y.pWin ){
|
||||
*pp = (*pp)->pNextWin;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Window *pWin = pExpr->y.pWin;
|
||||
sqlite3WindowUnlinkFromSelect(pWin);
|
||||
}
|
||||
return WRC_Continue;
|
||||
}
|
||||
@@ -1293,16 +1315,18 @@ static int resolveRemoveWindowsCb(Walker *pWalker, Expr *pExpr){
|
||||
** Remove any Window objects owned by the expression pExpr from the
|
||||
** Select.pWin list of Select object pSelect.
|
||||
*/
|
||||
static void resolveRemoveWindows(Select *pSelect, Expr *pExpr){
|
||||
Walker sWalker;
|
||||
memset(&sWalker, 0, sizeof(Walker));
|
||||
sWalker.xExprCallback = resolveRemoveWindowsCb;
|
||||
sWalker.u.pSelect = pSelect;
|
||||
sqlite3WalkExpr(&sWalker, pExpr);
|
||||
static void windowRemoveExprFromSelect(Select *pSelect, Expr *pExpr){
|
||||
if( pSelect->pWin ){
|
||||
Walker sWalker;
|
||||
memset(&sWalker, 0, sizeof(Walker));
|
||||
sWalker.xExprCallback = resolveRemoveWindowsCb;
|
||||
sWalker.u.pSelect = pSelect;
|
||||
sqlite3WalkExpr(&sWalker, pExpr);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define resolveRemoveWindows(x,y)
|
||||
#endif
|
||||
# define windowRemoveExprFromSelect(a, b)
|
||||
#endif /* SQLITE_OMIT_WINDOWFUNC */
|
||||
|
||||
/*
|
||||
** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect.
|
||||
@@ -1339,7 +1363,7 @@ static int resolveOrderGroupBy(
|
||||
pParse = pNC->pParse;
|
||||
for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
|
||||
Expr *pE = pItem->pExpr;
|
||||
Expr *pE2 = sqlite3ExprSkipCollate(pE);
|
||||
Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pE);
|
||||
if( zType[0]!='G' ){
|
||||
iCol = resolveAsName(pParse, pSelect->pEList, pE2);
|
||||
if( iCol>0 ){
|
||||
@@ -1373,7 +1397,7 @@ static int resolveOrderGroupBy(
|
||||
/* Since this expresion is being changed into a reference
|
||||
** to an identical expression in the result set, remove all Window
|
||||
** objects belonging to the expression from the Select.pWin list. */
|
||||
resolveRemoveWindows(pSelect, pE);
|
||||
windowRemoveExprFromSelect(pSelect, pE);
|
||||
pItem->u.x.iOrderByCol = j+1;
|
||||
}
|
||||
}
|
||||
|
||||
+66
-30
@@ -102,6 +102,7 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){
|
||||
}
|
||||
#endif
|
||||
if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
|
||||
assert( p->pWin==0 );
|
||||
if( bFree ) sqlite3DbFreeNN(db, p);
|
||||
p = pPrior;
|
||||
bFree = 1;
|
||||
@@ -663,7 +664,7 @@ static void pushOntoSorter(
|
||||
if( pParse->db->mallocFailed ) return;
|
||||
pOp->p2 = nKey + nData;
|
||||
pKI = pOp->p4.pKeyInfo;
|
||||
memset(pKI->aSortOrder, 0, pKI->nKeyField); /* Makes OP_Jump testable */
|
||||
memset(pKI->aSortFlags, 0, pKI->nKeyField); /* Makes OP_Jump testable */
|
||||
sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
|
||||
testcase( pKI->nAllField > pKI->nKeyField+2 );
|
||||
pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat,
|
||||
@@ -1274,7 +1275,7 @@ KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
|
||||
int nExtra = (N+X)*(sizeof(CollSeq*)+1) - sizeof(CollSeq*);
|
||||
KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra);
|
||||
if( p ){
|
||||
p->aSortOrder = (u8*)&p->aColl[N+X];
|
||||
p->aSortFlags = (u8*)&p->aColl[N+X];
|
||||
p->nKeyField = (u16)N;
|
||||
p->nAllField = (u16)(N+X);
|
||||
p->enc = ENC(db);
|
||||
@@ -1351,7 +1352,7 @@ KeyInfo *sqlite3KeyInfoFromExprList(
|
||||
assert( sqlite3KeyInfoIsWriteable(pInfo) );
|
||||
for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){
|
||||
pInfo->aColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr);
|
||||
pInfo->aSortOrder[i-iStart] = pItem->sortOrder;
|
||||
pInfo->aSortFlags[i-iStart] = pItem->sortFlags;
|
||||
}
|
||||
}
|
||||
return pInfo;
|
||||
@@ -1643,8 +1644,6 @@ static const char *columnTypeImpl(
|
||||
|
||||
assert( pExpr!=0 );
|
||||
assert( pNC->pSrcList!=0 );
|
||||
assert( pExpr->op!=TK_AGG_COLUMN ); /* This routine runes before aggregates
|
||||
** are processed */
|
||||
switch( pExpr->op ){
|
||||
case TK_COLUMN: {
|
||||
/* The expression is a column. Locate the table the column is being
|
||||
@@ -1961,12 +1960,11 @@ int sqlite3ColumnsFromExprList(
|
||||
if( (zName = pEList->a[i].zName)!=0 ){
|
||||
/* If the column contains an "AS <name>" phrase, use <name> as the name */
|
||||
}else{
|
||||
Expr *pColExpr = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
|
||||
Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr);
|
||||
while( pColExpr->op==TK_DOT ){
|
||||
pColExpr = pColExpr->pRight;
|
||||
assert( pColExpr!=0 );
|
||||
}
|
||||
assert( pColExpr->op!=TK_AGG_COLUMN );
|
||||
if( pColExpr->op==TK_COLUMN ){
|
||||
/* For columns use the column name name */
|
||||
int iCol = pColExpr->iColumn;
|
||||
@@ -2034,7 +2032,8 @@ int sqlite3ColumnsFromExprList(
|
||||
void sqlite3SelectAddColumnTypeAndCollation(
|
||||
Parse *pParse, /* Parsing contexts */
|
||||
Table *pTab, /* Add column type information to this table */
|
||||
Select *pSelect /* SELECT used to determine types and collations */
|
||||
Select *pSelect, /* SELECT used to determine types and collations */
|
||||
char aff /* Default affinity for columns */
|
||||
){
|
||||
sqlite3 *db = pParse->db;
|
||||
NameContext sNC;
|
||||
@@ -2067,7 +2066,7 @@ void sqlite3SelectAddColumnTypeAndCollation(
|
||||
pCol->colFlags |= COLFLAG_HASTYPE;
|
||||
}
|
||||
}
|
||||
if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_BLOB;
|
||||
if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff;
|
||||
pColl = sqlite3ExprCollSeq(pParse, p);
|
||||
if( pColl && pCol->zColl==0 ){
|
||||
pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
|
||||
@@ -2080,7 +2079,7 @@ void sqlite3SelectAddColumnTypeAndCollation(
|
||||
** Given a SELECT statement, generate a Table structure that describes
|
||||
** the result set of that SELECT.
|
||||
*/
|
||||
Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
|
||||
Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, char aff){
|
||||
Table *pTab;
|
||||
sqlite3 *db = pParse->db;
|
||||
u64 savedFlags;
|
||||
@@ -2100,7 +2099,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
|
||||
pTab->zName = 0;
|
||||
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
|
||||
sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
|
||||
sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect);
|
||||
sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect, aff);
|
||||
pTab->iPKey = -1;
|
||||
if( db->mallocFailed ){
|
||||
sqlite3DeleteTable(db, pTab);
|
||||
@@ -2254,7 +2253,7 @@ static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){
|
||||
}
|
||||
assert( sqlite3KeyInfoIsWriteable(pRet) );
|
||||
pRet->aColl[i] = pColl;
|
||||
pRet->aSortOrder[i] = pOrderBy->a[i].sortOrder;
|
||||
pRet->aSortFlags[i] = pOrderBy->a[i].sortFlags;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2965,11 +2964,14 @@ static int generateOutputSubroutine(
|
||||
|
||||
/* If this is a scalar select that is part of an expression, then
|
||||
** store the results in the appropriate memory cell and break out
|
||||
** of the scan loop.
|
||||
** of the scan loop. Note that the select might return multiple columns
|
||||
** if it is the RHS of a row-value IN operator.
|
||||
*/
|
||||
case SRT_Mem: {
|
||||
assert( pIn->nSdst==1 || pParse->nErr>0 ); testcase( pIn->nSdst!=1 );
|
||||
sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1);
|
||||
if( pParse->nErr==0 ){
|
||||
testcase( pIn->nSdst>1 );
|
||||
sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, pIn->nSdst);
|
||||
}
|
||||
/* The LIMIT clause will jump out of the loop for us */
|
||||
break;
|
||||
}
|
||||
@@ -3226,7 +3228,7 @@ static int multiSelectOrderBy(
|
||||
assert( sqlite3KeyInfoIsWriteable(pKeyDup) );
|
||||
for(i=0; i<nExpr; i++){
|
||||
pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
|
||||
pKeyDup->aSortOrder[i] = 0;
|
||||
pKeyDup->aSortFlags[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3474,6 +3476,9 @@ static Expr *substExpr(
|
||||
pNew->iRightJoinTable = pExpr->iRightJoinTable;
|
||||
ExprSetProperty(pNew, EP_FromJoin);
|
||||
}
|
||||
if( pNew && ExprHasProperty(pExpr,EP_Generic) ){
|
||||
ExprSetProperty(pNew, EP_Generic);
|
||||
}
|
||||
sqlite3ExprDelete(db, pExpr);
|
||||
pExpr = pNew;
|
||||
}
|
||||
@@ -3949,6 +3954,7 @@ static int flattenSubquery(
|
||||
for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
|
||||
int nSubSrc;
|
||||
u8 jointype = 0;
|
||||
assert( pSub!=0 );
|
||||
pSubSrc = pSub->pSrc; /* FROM clause of subquery */
|
||||
nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */
|
||||
pSrc = pParent->pSrc; /* FROM clause of the outer query */
|
||||
@@ -4399,24 +4405,27 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
|
||||
ExprList *pEList = pFunc->x.pList; /* Arguments to agg function */
|
||||
const char *zFunc; /* Name of aggregate function pFunc */
|
||||
ExprList *pOrderBy;
|
||||
u8 sortOrder;
|
||||
u8 sortFlags;
|
||||
|
||||
assert( *ppMinMax==0 );
|
||||
assert( pFunc->op==TK_AGG_FUNCTION );
|
||||
if( pEList==0 || pEList->nExpr!=1 ) return eRet;
|
||||
assert( !IsWindowFunc(pFunc) );
|
||||
if( pEList==0 || pEList->nExpr!=1 || ExprHasProperty(pFunc, EP_WinFunc) ){
|
||||
return eRet;
|
||||
}
|
||||
zFunc = pFunc->u.zToken;
|
||||
if( sqlite3StrICmp(zFunc, "min")==0 ){
|
||||
eRet = WHERE_ORDERBY_MIN;
|
||||
sortOrder = SQLITE_SO_ASC;
|
||||
sortFlags = KEYINFO_ORDER_BIGNULL;
|
||||
}else if( sqlite3StrICmp(zFunc, "max")==0 ){
|
||||
eRet = WHERE_ORDERBY_MAX;
|
||||
sortOrder = SQLITE_SO_DESC;
|
||||
sortFlags = KEYINFO_ORDER_DESC;
|
||||
}else{
|
||||
return eRet;
|
||||
}
|
||||
*ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0);
|
||||
assert( pOrderBy!=0 || db->mallocFailed );
|
||||
if( pOrderBy ) pOrderBy->a[0].sortOrder = sortOrder;
|
||||
if( pOrderBy ) pOrderBy->a[0].sortFlags = sortFlags;
|
||||
return eRet;
|
||||
}
|
||||
|
||||
@@ -4450,7 +4459,7 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
|
||||
if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
|
||||
if( NEVER(pAggInfo->nFunc==0) ) return 0;
|
||||
if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0;
|
||||
if( pExpr->flags&EP_Distinct ) return 0;
|
||||
if( ExprHasProperty(pExpr, EP_Distinct|EP_WinFunc) ) return 0;
|
||||
|
||||
return pTab;
|
||||
}
|
||||
@@ -4897,6 +4906,10 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
u8 eCodeOrig = pWalker->eCode;
|
||||
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
|
||||
assert( pFrom->pSelect==0 );
|
||||
if( pTab->pSelect && (db->flags & SQLITE_EnableView)==0 ){
|
||||
sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited",
|
||||
pTab->zName);
|
||||
}
|
||||
pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
|
||||
nCol = pTab->nCol;
|
||||
pTab->nCol = -1;
|
||||
@@ -5190,7 +5203,8 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
|
||||
Select *pSel = pFrom->pSelect;
|
||||
if( pSel ){
|
||||
while( pSel->pPrior ) pSel = pSel->pPrior;
|
||||
sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel);
|
||||
sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel,
|
||||
SQLITE_AFF_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5330,6 +5344,12 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
|
||||
int regAgg;
|
||||
ExprList *pList = pF->pExpr->x.pList;
|
||||
assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
|
||||
assert( !IsWindowFunc(pF->pExpr) );
|
||||
if( ExprHasProperty(pF->pExpr, EP_WinFunc) ){
|
||||
Expr *pFilter = pF->pExpr->y.pWin->pFilter;
|
||||
addrNext = sqlite3VdbeMakeLabel(pParse);
|
||||
sqlite3ExprIfFalse(pParse, pFilter, addrNext, SQLITE_JUMPIFNULL);
|
||||
}
|
||||
if( pList ){
|
||||
nArg = pList->nExpr;
|
||||
regAgg = sqlite3GetTempRange(pParse, nArg);
|
||||
@@ -5339,7 +5359,9 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
|
||||
regAgg = 0;
|
||||
}
|
||||
if( pF->iDistinct>=0 ){
|
||||
addrNext = sqlite3VdbeMakeLabel(pParse);
|
||||
if( addrNext==0 ){
|
||||
addrNext = sqlite3VdbeMakeLabel(pParse);
|
||||
}
|
||||
testcase( nArg==0 ); /* Error condition */
|
||||
testcase( nArg>1 ); /* Also an error */
|
||||
codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
|
||||
@@ -5842,7 +5864,7 @@ int sqlite3Select(
|
||||
** assume the column name is non-NULL and segfault. The use of an empty
|
||||
** string for the fake column name seems safer.
|
||||
*/
|
||||
if( pItem->colUsed==0 ){
|
||||
if( pItem->colUsed==0 && pItem->zName!=0 ){
|
||||
sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase);
|
||||
}
|
||||
|
||||
@@ -5856,8 +5878,15 @@ int sqlite3Select(
|
||||
** technically harmless for it to be generated multiple times. The
|
||||
** following assert() will detect if something changes to cause
|
||||
** the same subquery to be coded multiple times, as a signal to the
|
||||
** developers to try to optimize the situation. */
|
||||
assert( pItem->addrFillSub==0 );
|
||||
** developers to try to optimize the situation.
|
||||
**
|
||||
** Update 2019-07-24:
|
||||
** See ticket https://sqlite.org/src/tktview/c52b09c7f38903b1311cec40.
|
||||
** The dbsqlfuzz fuzzer found a case where the same subquery gets
|
||||
** coded twice. So this assert() now becomes a testcase(). It should
|
||||
** be very rare, though.
|
||||
*/
|
||||
testcase( pItem->addrFillSub!=0 );
|
||||
|
||||
/* Increment Parse.nHeight by the height of the largest expression
|
||||
** tree referred to by this, the parent select. The child select
|
||||
@@ -5931,7 +5960,7 @@ int sqlite3Select(
|
||||
int retAddr;
|
||||
struct SrcList_item *pPrior;
|
||||
|
||||
assert( pItem->addrFillSub==0 );
|
||||
testcase( pItem->addrFillSub==0 ); /* Ticket c52b09c7f38903b1311 */
|
||||
pItem->regReturn = ++pParse->nMem;
|
||||
topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
|
||||
pItem->addrFillSub = topAddr+1;
|
||||
@@ -6222,9 +6251,16 @@ int sqlite3Select(
|
||||
minMaxFlag = WHERE_ORDERBY_NORMAL;
|
||||
}
|
||||
for(i=0; i<sAggInfo.nFunc; i++){
|
||||
assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
|
||||
Expr *pExpr = sAggInfo.aFunc[i].pExpr;
|
||||
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
|
||||
sNC.ncFlags |= NC_InAggFunc;
|
||||
sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
|
||||
sqlite3ExprAnalyzeAggList(&sNC, pExpr->x.pList);
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
assert( !IsWindowFunc(pExpr) );
|
||||
if( ExprHasProperty(pExpr, EP_WinFunc) ){
|
||||
sqlite3ExprAnalyzeAggregates(&sNC, pExpr->y.pWin->pFilter);
|
||||
}
|
||||
#endif
|
||||
sNC.ncFlags &= ~NC_InAggFunc;
|
||||
}
|
||||
sAggInfo.mxReg = pParse->nMem;
|
||||
|
||||
+130
-22
@@ -1256,12 +1256,12 @@ static void editFunc(
|
||||
}
|
||||
sz = sqlite3_value_bytes(argv[0]);
|
||||
if( bBin ){
|
||||
x = fwrite(sqlite3_value_blob(argv[0]), 1, sz, f);
|
||||
x = fwrite(sqlite3_value_blob(argv[0]), 1, (size_t)sz, f);
|
||||
}else{
|
||||
const char *z = (const char*)sqlite3_value_text(argv[0]);
|
||||
/* Remember whether or not the value originally contained \r\n */
|
||||
if( z && strstr(z,"\r\n")!=0 ) hasCRNL = 1;
|
||||
x = fwrite(sqlite3_value_text(argv[0]), 1, sz, f);
|
||||
x = fwrite(sqlite3_value_text(argv[0]), 1, (size_t)sz, f);
|
||||
}
|
||||
fclose(f);
|
||||
f = 0;
|
||||
@@ -1294,7 +1294,7 @@ static void editFunc(
|
||||
sqlite3_result_error_nomem(context);
|
||||
goto edit_func_end;
|
||||
}
|
||||
x = fread(p, 1, sz, f);
|
||||
x = fread(p, 1, (size_t)sz, f);
|
||||
fclose(f);
|
||||
f = 0;
|
||||
if( x!=sz ){
|
||||
@@ -3649,6 +3649,10 @@ static const char *(azHelp[]) = {
|
||||
" --row Trace each row (SQLITE_TRACE_ROW)",
|
||||
" --close Trace connection close (SQLITE_TRACE_CLOSE)",
|
||||
#endif /* SQLITE_OMIT_TRACE */
|
||||
#ifdef SQLITE_DEBUG
|
||||
".unmodule NAME ... Unregister virtual table modules",
|
||||
" --allexcept Unregister everything except those named",
|
||||
#endif
|
||||
".vfsinfo ?AUX? Information about the top-level VFS",
|
||||
".vfslist List all available VFSes",
|
||||
".vfsname ?AUX? Print the name of the VFS stack",
|
||||
@@ -3891,6 +3895,8 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){
|
||||
rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
|
||||
if( rc!=2 ) goto readHexDb_error;
|
||||
if( n<0 ) goto readHexDb_error;
|
||||
if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ) goto readHexDb_error;
|
||||
n = (n+pgsz-1)&~(pgsz-1); /* Round n up to the next multiple of pgsz */
|
||||
a = sqlite3_malloc( n ? n : 1 );
|
||||
if( a==0 ){
|
||||
utf8_printf(stderr, "Out of memory!\n");
|
||||
@@ -3975,6 +3981,23 @@ static void shellInt32(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Scalar function "shell_idquote(X)" returns string X quoted as an identifier,
|
||||
** using "..." with internal double-quote characters doubled.
|
||||
*/
|
||||
static void shellIdQuote(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
const char *zName = (const char*)sqlite3_value_text(argv[0]);
|
||||
UNUSED_PARAMETER(argc);
|
||||
if( zName ){
|
||||
char *z = sqlite3_mprintf("\"%w\"", zName);
|
||||
sqlite3_result_text(context, z, -1, sqlite3_free);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Scalar function "shell_escape_crnl" used by the .recover command.
|
||||
** The argument passed to this function is the output of built-in
|
||||
@@ -4151,6 +4174,8 @@ static void open_db(ShellState *p, int openFlags){
|
||||
shellEscapeCrnl, 0, 0);
|
||||
sqlite3_create_function(p->db, "shell_int32", 2, SQLITE_UTF8, 0,
|
||||
shellInt32, 0, 0);
|
||||
sqlite3_create_function(p->db, "shell_idquote", 1, SQLITE_UTF8, 0,
|
||||
shellIdQuote, 0, 0);
|
||||
#ifndef SQLITE_NOHAVE_SYSTEM
|
||||
sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
|
||||
editFunc, 0, 0);
|
||||
@@ -6328,6 +6353,10 @@ static RecoverTable *recoverNewTable(
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
|
||||
rc = sqlite3_open("", &dbtmp);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_create_function(dbtmp, "shell_idquote", 1, SQLITE_UTF8, 0,
|
||||
shellIdQuote, 0, 0);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_exec(dbtmp, "PRAGMA writable_schema = on", 0, 0, 0);
|
||||
}
|
||||
@@ -6384,18 +6413,18 @@ static RecoverTable *recoverNewTable(
|
||||
}
|
||||
}
|
||||
|
||||
pTab->zQuoted = shellMPrintf(&rc, "%Q", zName);
|
||||
pTab->zQuoted = shellMPrintf(&rc, "\"%w\"", zName);
|
||||
pTab->azlCol = (char**)shellMalloc(&rc, sizeof(char*) * (nSqlCol+1));
|
||||
pTab->nCol = nSqlCol;
|
||||
|
||||
if( bIntkey ){
|
||||
pTab->azlCol[0] = shellMPrintf(&rc, "%Q", zPk);
|
||||
pTab->azlCol[0] = shellMPrintf(&rc, "\"%w\"", zPk);
|
||||
}else{
|
||||
pTab->azlCol[0] = shellMPrintf(&rc, "");
|
||||
}
|
||||
i = 1;
|
||||
shellPreparePrintf(dbtmp, &rc, &pStmt,
|
||||
"SELECT %Q || group_concat(name, ', ') "
|
||||
"SELECT %Q || group_concat(shell_idquote(name), ', ') "
|
||||
" FILTER (WHERE cid!=%d) OVER (ORDER BY %s cid) "
|
||||
"FROM pragma_table_info(%Q)",
|
||||
bIntkey ? ", " : "", pTab->iPk,
|
||||
@@ -6509,7 +6538,7 @@ static RecoverTable *recoverOrphanTable(
|
||||
|
||||
pTab = (RecoverTable*)shellMalloc(pRc, sizeof(RecoverTable));
|
||||
if( pTab ){
|
||||
pTab->zQuoted = shellMPrintf(pRc, "%Q", zTab);
|
||||
pTab->zQuoted = shellMPrintf(pRc, "\"%w\"", zTab);
|
||||
pTab->nCol = nCol;
|
||||
pTab->iPk = -2;
|
||||
if( nCol>0 ){
|
||||
@@ -6587,6 +6616,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
|
||||
shellExecPrintf(pState->db, &rc,
|
||||
/* Attach an in-memory database named 'recovery'. Create an indexed
|
||||
** cache of the sqlite_dbptr virtual table. */
|
||||
"PRAGMA writable_schema = on;"
|
||||
"ATTACH %Q AS recovery;"
|
||||
"DROP TABLE IF EXISTS recovery.dbptr;"
|
||||
"DROP TABLE IF EXISTS recovery.freelist;"
|
||||
@@ -6617,6 +6647,21 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
|
||||
);
|
||||
}
|
||||
|
||||
/* If this is an auto-vacuum database, add all pointer-map pages to
|
||||
** the freelist table. Do this regardless of whether or not
|
||||
** --freelist-corrupt was specified. */
|
||||
shellExec(pState->db, &rc,
|
||||
"WITH ptrmap(pgno) AS ("
|
||||
" SELECT 2 WHERE shell_int32("
|
||||
" (SELECT data FROM sqlite_dbpage WHERE pgno=1), 13"
|
||||
" )"
|
||||
" UNION ALL "
|
||||
" SELECT pgno+1+(SELECT page_size FROM pragma_page_size)/5 AS pp "
|
||||
" FROM ptrmap WHERE pp<=(SELECT page_count FROM pragma_page_count)"
|
||||
")"
|
||||
"REPLACE INTO recovery.freelist SELECT pgno FROM ptrmap"
|
||||
);
|
||||
|
||||
shellExec(pState->db, &rc,
|
||||
"CREATE TABLE recovery.dbptr("
|
||||
" pgno, child, PRIMARY KEY(child, pgno)"
|
||||
@@ -6690,6 +6735,11 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
|
||||
** CREATE TABLE statements that extracted from the existing schema. */
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
/* ".recover" might output content in an order which causes immediate
|
||||
** foreign key constraints to be violated. So disable foreign-key
|
||||
** constraint enforcement to prevent problems when running the output
|
||||
** script. */
|
||||
raw_printf(pState->out, "PRAGMA foreign_keys=OFF;\n");
|
||||
raw_printf(pState->out, "BEGIN;\n");
|
||||
raw_printf(pState->out, "PRAGMA writable_schema = on;\n");
|
||||
shellPrepare(pState->db, &rc,
|
||||
@@ -6722,6 +6772,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
|
||||
);
|
||||
shellPrepare(pState->db, &rc,
|
||||
"SELECT max(field), group_concat(shell_escape_crnl(quote(value)), ', ')"
|
||||
", min(field) "
|
||||
"FROM sqlite_dbdata WHERE pgno = ? AND field != ?"
|
||||
"GROUP BY cell", &pCells
|
||||
);
|
||||
@@ -6740,6 +6791,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
|
||||
int bNoop = 0;
|
||||
RecoverTable *pTab;
|
||||
|
||||
assert( bIntkey==0 || bIntkey==1 );
|
||||
pTab = recoverFindTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop);
|
||||
if( bNoop || rc ) continue;
|
||||
if( pTab==0 ){
|
||||
@@ -6750,7 +6802,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
|
||||
if( pTab==0 ) break;
|
||||
}
|
||||
|
||||
if( 0==sqlite3_stricmp(pTab->zQuoted, "'sqlite_sequence'") ){
|
||||
if( 0==sqlite3_stricmp(pTab->zQuoted, "\"sqlite_sequence\"") ){
|
||||
raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n");
|
||||
}
|
||||
sqlite3_bind_int(pPages, 1, iRoot);
|
||||
@@ -6761,18 +6813,28 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
|
||||
sqlite3_bind_int(pCells, 1, iPgno);
|
||||
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){
|
||||
int nField = sqlite3_column_int(pCells, 0);
|
||||
int iMin = sqlite3_column_int(pCells, 2);
|
||||
const char *zVal = (const char*)sqlite3_column_text(pCells, 1);
|
||||
|
||||
RecoverTable *pTab2 = pTab;
|
||||
if( pTab!=pOrphan && (iMin<0)!=bIntkey ){
|
||||
if( pOrphan==0 ){
|
||||
pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan);
|
||||
}
|
||||
pTab2 = pOrphan;
|
||||
if( pTab2==0 ) break;
|
||||
}
|
||||
|
||||
nField = nField+1;
|
||||
if( pTab==pOrphan ){
|
||||
if( pTab2==pOrphan ){
|
||||
raw_printf(pState->out,
|
||||
"INSERT INTO %s VALUES(%d, %d, %d, %s%s%s);\n",
|
||||
pTab->zQuoted, iRoot, iPgno, nField,
|
||||
bIntkey ? "" : "NULL, ", zVal, pTab->azlCol[nField]
|
||||
pTab2->zQuoted, iRoot, iPgno, nField,
|
||||
iMin<0 ? "" : "NULL, ", zVal, pTab2->azlCol[nField]
|
||||
);
|
||||
}else{
|
||||
raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n",
|
||||
pTab->zQuoted, pTab->azlCol[nField], zVal
|
||||
pTab2->zQuoted, pTab2->azlCol[nField], zVal
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -6831,7 +6893,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
int nArg = 0;
|
||||
int n, c;
|
||||
int rc = 0;
|
||||
char *azArg[50];
|
||||
char *azArg[52];
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( p->expert.pExpert ){
|
||||
@@ -6841,7 +6903,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
|
||||
/* Parse the input line into tokens.
|
||||
*/
|
||||
while( zLine[h] && nArg<ArraySize(azArg) ){
|
||||
while( zLine[h] && nArg<ArraySize(azArg)-1 ){
|
||||
while( IsSpace(zLine[h]) ){ h++; }
|
||||
if( zLine[h]==0 ) break;
|
||||
if( zLine[h]=='\'' || zLine[h]=='"' ){
|
||||
@@ -6862,6 +6924,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
resolve_backslashes(azArg[nArg-1]);
|
||||
}
|
||||
}
|
||||
azArg[nArg] = 0;
|
||||
|
||||
/* Process the input line.
|
||||
*/
|
||||
@@ -7077,6 +7140,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
} aDbConfig[] = {
|
||||
{ "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
|
||||
{ "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
|
||||
{ "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW },
|
||||
{ "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
|
||||
{ "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
|
||||
{ "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
|
||||
@@ -7450,8 +7514,6 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
data.cMode = data.mode = MODE_Insert;
|
||||
data.zDestTable = "sqlite_stat1";
|
||||
shell_exec(&data, "SELECT * FROM sqlite_stat1", &zErrMsg);
|
||||
data.zDestTable = "sqlite_stat3";
|
||||
shell_exec(&data, "SELECT * FROM sqlite_stat3", &zErrMsg);
|
||||
data.zDestTable = "sqlite_stat4";
|
||||
shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg);
|
||||
raw_printf(p->out, "ANALYZE sqlite_master;\n");
|
||||
@@ -8388,7 +8450,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
zDiv = " UNION ALL ";
|
||||
appendText(&sSelect, "SELECT shell_add_schema(sql,", 0);
|
||||
if( sqlite3_stricmp(zDb, "main")!=0 ){
|
||||
appendText(&sSelect, zDb, '"');
|
||||
appendText(&sSelect, zDb, '\'');
|
||||
}else{
|
||||
appendText(&sSelect, "NULL", 0);
|
||||
}
|
||||
@@ -8397,11 +8459,11 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
appendText(&sSelect, " AS snum, ", 0);
|
||||
appendText(&sSelect, zDb, '\'');
|
||||
appendText(&sSelect, " AS sname FROM ", 0);
|
||||
appendText(&sSelect, zDb, '"');
|
||||
appendText(&sSelect, zDb, quoteChar(zDb));
|
||||
appendText(&sSelect, ".sqlite_master", 0);
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
#ifdef SQLITE_INTROSPECTION_PRAGMAS
|
||||
#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
|
||||
if( zName ){
|
||||
appendText(&sSelect,
|
||||
" UNION ALL SELECT shell_module_schema(name),"
|
||||
@@ -8872,8 +8934,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}else if( strcmp(zTab, "sqlite_stat1")==0 ){
|
||||
appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1"
|
||||
" ORDER BY tbl,idx;", 0);
|
||||
}else if( strcmp(zTab, "sqlite_stat3")==0
|
||||
|| strcmp(zTab, "sqlite_stat4")==0 ){
|
||||
}else if( strcmp(zTab, "sqlite_stat4")==0 ){
|
||||
appendText(&sQuery, "SELECT * FROM ", 0);
|
||||
appendText(&sQuery, zTab, 0);
|
||||
appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0);
|
||||
@@ -9110,6 +9171,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
/*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/
|
||||
/*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/
|
||||
{ "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" },
|
||||
{ "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,"BOOLEAN" },
|
||||
/*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" }, */
|
||||
{ "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"},
|
||||
{ "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN" },
|
||||
@@ -9120,9 +9182,9 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
{ "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" },
|
||||
#endif
|
||||
{ "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " },
|
||||
{ "prng_reset", SQLITE_TESTCTRL_PRNG_RESET, "" },
|
||||
{ "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" },
|
||||
{ "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" },
|
||||
{ "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED ?db?" },
|
||||
{ "reserve", SQLITE_TESTCTRL_RESERVE, "BYTES-OF-RESERVE" },
|
||||
};
|
||||
int testctrl = -1;
|
||||
@@ -9204,6 +9266,27 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
break;
|
||||
|
||||
/* sqlite3_test_control(int, int, sqlite3*) */
|
||||
case SQLITE_TESTCTRL_PRNG_SEED:
|
||||
if( nArg==3 || nArg==4 ){
|
||||
int ii = (int)integerValue(azArg[2]);
|
||||
sqlite3 *db;
|
||||
if( ii==0 && strcmp(azArg[2],"random")==0 ){
|
||||
sqlite3_randomness(sizeof(ii),&ii);
|
||||
printf("-- random seed: %d\n", ii);
|
||||
}
|
||||
if( nArg==3 ){
|
||||
db = 0;
|
||||
}else{
|
||||
db = p->db;
|
||||
/* Make sure the schema has been loaded */
|
||||
sqlite3_table_column_metadata(db, 0, "x", 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
rc2 = sqlite3_test_control(testctrl, ii, db);
|
||||
isOk = 3;
|
||||
}
|
||||
break;
|
||||
|
||||
/* sqlite3_test_control(int, int) */
|
||||
case SQLITE_TESTCTRL_ASSERT:
|
||||
case SQLITE_TESTCTRL_ALWAYS:
|
||||
@@ -9323,6 +9406,31 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}else
|
||||
#endif /* !defined(SQLITE_OMIT_TRACE) */
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){
|
||||
int ii;
|
||||
int lenOpt;
|
||||
char *zOpt;
|
||||
if( nArg<2 ){
|
||||
raw_printf(stderr, "Usage: .unmodule [--allexcept] NAME ...\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
open_db(p, 0);
|
||||
zOpt = azArg[1];
|
||||
if( zOpt[0]=='-' && zOpt[1]=='-' && zOpt[2]!=0 ) zOpt++;
|
||||
lenOpt = (int)strlen(zOpt);
|
||||
if( lenOpt>=3 && strncmp(zOpt, "-allexcept",lenOpt)==0 ){
|
||||
assert( azArg[nArg]==0 );
|
||||
sqlite3_drop_modules(p->db, nArg>2 ? (const char**)(azArg+2) : 0);
|
||||
}else{
|
||||
for(ii=1; ii<nArg; ii++){
|
||||
sqlite3_create_module(p->db, azArg[ii], 0, 0);
|
||||
}
|
||||
}
|
||||
}else
|
||||
#endif
|
||||
|
||||
#if SQLITE_USER_AUTHENTICATION
|
||||
if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
|
||||
if( nArg<2 ){
|
||||
|
||||
+53
-5
@@ -2093,6 +2093,17 @@ struct sqlite3_mem_methods {
|
||||
** following this call. The second parameter may be a NULL pointer, in
|
||||
** which case the trigger setting is not reported back. </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_ENABLE_VIEW]]
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt>
|
||||
** <dd> ^This option is used to enable or disable [CREATE VIEW | views].
|
||||
** There should be two additional arguments.
|
||||
** The first argument is an integer which is 0 to disable views,
|
||||
** positive to enable views or negative to leave the setting unchanged.
|
||||
** The second parameter is a pointer to an integer into which
|
||||
** is written 0 or 1 to indicate whether views are disabled or enabled
|
||||
** following this call. The second parameter may be a NULL pointer, in
|
||||
** which case the view setting is not reported back. </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
|
||||
** <dd> ^This option is used to enable or disable the
|
||||
@@ -2265,7 +2276,8 @@ struct sqlite3_mem_methods {
|
||||
#define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 1012 /* int int* */
|
||||
#define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */
|
||||
#define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */
|
||||
#define SQLITE_DBCONFIG_MAX 1014 /* Largest DBCONFIG */
|
||||
#define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */
|
||||
#define SQLITE_DBCONFIG_MAX 1015 /* Largest DBCONFIG */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Enable Or Disable Extended Result Codes
|
||||
@@ -3814,7 +3826,7 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
|
||||
** ^The specific value of WHERE-clause [parameter] might influence the
|
||||
** choice of query plan if the parameter is the left-hand side of a [LIKE]
|
||||
** or [GLOB] operator or if the parameter is compared to an indexed column
|
||||
** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
|
||||
** and the [SQLITE_ENABLE_STAT4] compile-time option is enabled.
|
||||
** </li>
|
||||
** </ol>
|
||||
**
|
||||
@@ -4848,6 +4860,9 @@ int sqlite3_reset(sqlite3_stmt *pStmt);
|
||||
** function that is not deterministic. The SQLite query planner is able to
|
||||
** perform additional optimizations on deterministic functions, so use
|
||||
** of the [SQLITE_DETERMINISTIC] flag is recommended where possible.
|
||||
** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY]
|
||||
** flag, which if present prevents the function from being invoked from
|
||||
** within VIEWs or TRIGGERs.
|
||||
**
|
||||
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
|
||||
** function can gain access to this pointer using [sqlite3_user_data()].)^
|
||||
@@ -4965,8 +4980,16 @@ int sqlite3_create_window_function(
|
||||
** [SQLITE_UTF8 | preferred text encoding] as the fourth argument
|
||||
** to [sqlite3_create_function()], [sqlite3_create_function16()], or
|
||||
** [sqlite3_create_function_v2()].
|
||||
**
|
||||
** The SQLITE_DETERMINISTIC flag means that the new function will always
|
||||
** maps the same inputs into the same output. The abs() function is
|
||||
** deterministic, for example, but randomblob() is not.
|
||||
**
|
||||
** The SQLITE_DIRECTONLY flag means that the function may only be invoked
|
||||
** from top-level SQL, and cannot be used in VIEWs or TRIGGERs.
|
||||
*/
|
||||
#define SQLITE_DETERMINISTIC 0x800
|
||||
#define SQLITE_DETERMINISTIC 0x000000800
|
||||
#define SQLITE_DIRECTONLY 0x000080000
|
||||
|
||||
/*
|
||||
** CAPI3REF: Deprecated Functions
|
||||
@@ -6612,6 +6635,12 @@ struct sqlite3_index_info {
|
||||
** ^The sqlite3_create_module()
|
||||
** interface is equivalent to sqlite3_create_module_v2() with a NULL
|
||||
** destructor.
|
||||
**
|
||||
** ^If the third parameter (the pointer to the sqlite3_module object) is
|
||||
** NULL then no new module is create and any existing modules with the
|
||||
** same name are dropped.
|
||||
**
|
||||
** See also: [sqlite3_drop_modules()]
|
||||
*/
|
||||
int sqlite3_create_module(
|
||||
sqlite3 *db, /* SQLite connection to register module with */
|
||||
@@ -6627,6 +6656,23 @@ int sqlite3_create_module_v2(
|
||||
void(*xDestroy)(void*) /* Module destructor function */
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Remove Unnecessary Virtual Table Implementations
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^The sqlite3_drop_modules(D,L) interface removes all virtual
|
||||
** table modules from database connection D except those named on list L.
|
||||
** The L parameter must be either NULL or a pointer to an array of pointers
|
||||
** to strings where the array is terminated by a single NULL pointer.
|
||||
** ^If the L parameter is NULL, then all virtual table modules are removed.
|
||||
**
|
||||
** See also: [sqlite3_create_module()]
|
||||
*/
|
||||
int sqlite3_drop_modules(
|
||||
sqlite3 *db, /* Remove modules from this connection */
|
||||
const char **azKeep /* Except, do not remove the ones named here */
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Virtual Table Instance Object
|
||||
** KEYWORDS: sqlite3_vtab
|
||||
@@ -7335,7 +7381,7 @@ int sqlite3_test_control(int op, ...);
|
||||
#define SQLITE_TESTCTRL_FIRST 5
|
||||
#define SQLITE_TESTCTRL_PRNG_SAVE 5
|
||||
#define SQLITE_TESTCTRL_PRNG_RESTORE 6
|
||||
#define SQLITE_TESTCTRL_PRNG_RESET 7
|
||||
#define SQLITE_TESTCTRL_PRNG_RESET 7 /* NOT USED */
|
||||
#define SQLITE_TESTCTRL_BITVEC_TEST 8
|
||||
#define SQLITE_TESTCTRL_FAULT_INSTALL 9
|
||||
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
|
||||
@@ -7358,7 +7404,9 @@ int sqlite3_test_control(int op, ...);
|
||||
#define SQLITE_TESTCTRL_IMPOSTER 25
|
||||
#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
|
||||
#define SQLITE_TESTCTRL_RESULT_INTREAL 27
|
||||
#define SQLITE_TESTCTRL_LAST 27 /* Largest TESTCTRL */
|
||||
#define SQLITE_TESTCTRL_PRNG_SEED 28
|
||||
#define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29
|
||||
#define SQLITE_TESTCTRL_LAST 29 /* Largest TESTCTRL */
|
||||
|
||||
/*
|
||||
** CAPI3REF: SQL Keyword Checking
|
||||
|
||||
@@ -322,6 +322,8 @@ struct sqlite3_api_routines {
|
||||
/* Version 3.28.0 and later */
|
||||
int (*stmt_isexplain)(sqlite3_stmt*);
|
||||
int (*value_frombind)(sqlite3_value*);
|
||||
/* Version 3.30.0 and later */
|
||||
int (*drop_modules)(sqlite3*,const char**);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -614,6 +616,8 @@ typedef int (*sqlite3_loadext_entry)(
|
||||
/* Version 3.28.0 and later */
|
||||
#define sqlite3_stmt_isexplain sqlite3_api->isexplain
|
||||
#define sqlite3_value_frombind sqlite3_api->frombind
|
||||
/* Version 3.30.0 and later */
|
||||
#define sqlite3_drop_modules sqlite3_api->drop_modules
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
||||
+104
-84
@@ -212,15 +212,15 @@
|
||||
** So we have to define the macros in different ways depending on the
|
||||
** compiler.
|
||||
*/
|
||||
#if defined(__PTRDIFF_TYPE__) /* This case should work for GCC */
|
||||
#if defined(HAVE_STDINT_H) /* Use this case if we have ANSI headers */
|
||||
# define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X))
|
||||
# define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X))
|
||||
#elif defined(__PTRDIFF_TYPE__) /* This case should work for GCC */
|
||||
# define SQLITE_INT_TO_PTR(X) ((void*)(__PTRDIFF_TYPE__)(X))
|
||||
# define SQLITE_PTR_TO_INT(X) ((int)(__PTRDIFF_TYPE__)(X))
|
||||
#elif !defined(__GNUC__) /* Works for compilers other than LLVM */
|
||||
# define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X])
|
||||
# define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0))
|
||||
#elif defined(HAVE_STDINT_H) /* Use this case if we have ANSI headers */
|
||||
# define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X))
|
||||
# define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X))
|
||||
#else /* Generates a warning - but it always works */
|
||||
# define SQLITE_INT_TO_PTR(X) ((void*)(X))
|
||||
# define SQLITE_PTR_TO_INT(X) ((int)(X))
|
||||
@@ -935,20 +935,6 @@ typedef INT16_TYPE LogEst;
|
||||
# define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Only one of SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4 can be defined.
|
||||
** Priority is given to SQLITE_ENABLE_STAT4. If either are defined, also
|
||||
** define SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
# undef SQLITE_ENABLE_STAT3
|
||||
# define SQLITE_ENABLE_STAT3_OR_STAT4 1
|
||||
#elif SQLITE_ENABLE_STAT3
|
||||
# define SQLITE_ENABLE_STAT3_OR_STAT4 1
|
||||
#elif SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
# undef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#endif
|
||||
|
||||
/*
|
||||
** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not
|
||||
** the Select query generator tracing logic is turned on.
|
||||
@@ -1412,6 +1398,7 @@ struct sqlite3 {
|
||||
unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */
|
||||
unsigned imposterTable : 1; /* Building an imposter table */
|
||||
unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */
|
||||
char **azInit; /* "type", "name", and "tbl_name" columns */
|
||||
} init;
|
||||
int nVdbeActive; /* Number of VDBEs currently running */
|
||||
int nVdbeRead; /* Number of active VDBEs that read or write */
|
||||
@@ -1550,16 +1537,17 @@ struct sqlite3 {
|
||||
#define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */
|
||||
#define SQLITE_DqsDDL 0x20000000 /* dbl-quoted strings allowed in DDL*/
|
||||
#define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/
|
||||
#define SQLITE_EnableView 0x80000000 /* Enable the use of views */
|
||||
|
||||
/* Flags used only if debugging */
|
||||
#define HI(X) ((u64)(X)<<32)
|
||||
#ifdef SQLITE_DEBUG
|
||||
#define SQLITE_SqlTrace HI(0x0001) /* Debug print SQL as it executes */
|
||||
#define SQLITE_VdbeListing HI(0x0002) /* Debug listings of VDBE progs */
|
||||
#define SQLITE_VdbeTrace HI(0x0004) /* True to trace VDBE execution */
|
||||
#define SQLITE_VdbeAddopTrace HI(0x0008) /* Trace sqlite3VdbeAddOp() calls */
|
||||
#define SQLITE_VdbeEQP HI(0x0010) /* Debug EXPLAIN QUERY PLAN */
|
||||
#define SQLITE_ParserTrace HI(0x0020) /* PRAGMA parser_trace=ON */
|
||||
#define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */
|
||||
#define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */
|
||||
#define SQLITE_VdbeTrace HI(0x0400000) /* True to trace VDBE execution */
|
||||
#define SQLITE_VdbeAddopTrace HI(0x0800000) /* Trace sqlite3VdbeAddOp() calls */
|
||||
#define SQLITE_VdbeEQP HI(0x1000000) /* Debug EXPLAIN QUERY PLAN */
|
||||
#define SQLITE_ParserTrace HI(0x2000000) /* PRAGMA parser_trace=ON */
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -1587,8 +1575,8 @@ struct sqlite3 {
|
||||
#define SQLITE_OmitNoopJoin 0x0100 /* Omit unused tables in joins */
|
||||
#define SQLITE_CountOfView 0x0200 /* The count-of-view optimization */
|
||||
#define SQLITE_CursorHints 0x0400 /* Add OP_CursorHint opcodes */
|
||||
#define SQLITE_Stat34 0x0800 /* Use STAT3 or STAT4 data */
|
||||
/* TH3 expects the Stat34 ^^^^^^ value to be 0x0800. Don't change it */
|
||||
#define SQLITE_Stat4 0x0800 /* Use STAT4 data */
|
||||
/* TH3 expects the Stat4 ^^^^^^ value to be 0x0800. Don't change it */
|
||||
#define SQLITE_PushDown 0x1000 /* The push-down optimization */
|
||||
#define SQLITE_SimplifyJoin 0x2000 /* Convert LEFT JOIN to JOIN */
|
||||
#define SQLITE_SkipScan 0x4000 /* Skip-scans */
|
||||
@@ -1676,6 +1664,7 @@ struct FuncDestructor {
|
||||
** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG
|
||||
** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG
|
||||
** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API
|
||||
** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API
|
||||
** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API
|
||||
*/
|
||||
#define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */
|
||||
@@ -1696,6 +1685,7 @@ struct FuncDestructor {
|
||||
#define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */
|
||||
#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */
|
||||
#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
|
||||
#define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */
|
||||
|
||||
/*
|
||||
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
|
||||
@@ -1809,6 +1799,7 @@ struct Savepoint {
|
||||
struct Module {
|
||||
const sqlite3_module *pModule; /* Callback pointers */
|
||||
const char *zName; /* Name passed to create_module() */
|
||||
int nRefModule; /* Number of pointers to this object */
|
||||
void *pAux; /* pAux passed to create_module() */
|
||||
void (*xDestroy)(void *); /* Module destructor function */
|
||||
Table *pEpoTab; /* Eponymous table for this module */
|
||||
@@ -1856,9 +1847,11 @@ struct CollSeq {
|
||||
/*
|
||||
** A sort order can be either ASC or DESC.
|
||||
*/
|
||||
#define SQLITE_SO_ASC 0 /* Sort in ascending order */
|
||||
#define SQLITE_SO_DESC 1 /* Sort in ascending order */
|
||||
#define SQLITE_SO_UNDEFINED -1 /* No sort order specified */
|
||||
#define SQLITE_SO_ASC 0 /* Sort in ascending order by default */
|
||||
#define SQLITE_SO_DESC 1 /* Sort in descending order */
|
||||
#define SQLITE_SO_BIGNULL 2 /* NULLs larger than all other values */
|
||||
#define SQLITE_SO_SMALLNULL 4 /* NULLs smaller, explicitly stated */
|
||||
#define SQLITE_SO_XASC 8 /* Actually holds the ASC keyword */
|
||||
|
||||
/*
|
||||
** Column affinity types.
|
||||
@@ -1874,11 +1867,12 @@ struct CollSeq {
|
||||
** Note also that the numeric types are grouped together so that testing
|
||||
** for a numeric type is a single comparison. And the BLOB type is first.
|
||||
*/
|
||||
#define SQLITE_AFF_BLOB 'A'
|
||||
#define SQLITE_AFF_TEXT 'B'
|
||||
#define SQLITE_AFF_NUMERIC 'C'
|
||||
#define SQLITE_AFF_INTEGER 'D'
|
||||
#define SQLITE_AFF_REAL 'E'
|
||||
#define SQLITE_AFF_NONE 0x40 /* '@' */
|
||||
#define SQLITE_AFF_BLOB 0x41 /* 'A' */
|
||||
#define SQLITE_AFF_TEXT 0x42 /* 'B' */
|
||||
#define SQLITE_AFF_NUMERIC 0x43 /* 'C' */
|
||||
#define SQLITE_AFF_INTEGER 0x44 /* 'D' */
|
||||
#define SQLITE_AFF_REAL 0x45 /* 'E' */
|
||||
|
||||
#define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC)
|
||||
|
||||
@@ -2146,10 +2140,13 @@ struct KeyInfo {
|
||||
u16 nKeyField; /* Number of key columns in the index */
|
||||
u16 nAllField; /* Total columns, including key plus others */
|
||||
sqlite3 *db; /* The database connection */
|
||||
u8 *aSortOrder; /* Sort order for each column. */
|
||||
u8 *aSortFlags; /* Sort order for each column. */
|
||||
CollSeq *aColl[1]; /* Collating sequence for each term of the key */
|
||||
};
|
||||
|
||||
#define KEYINFO_ORDER_DESC 0x01
|
||||
#define KEYINFO_ORDER_BIGNULL 0x02
|
||||
|
||||
/*
|
||||
** This object holds a record which has been parsed out into individual
|
||||
** fields, for the purposes of doing a comparison.
|
||||
@@ -2257,7 +2254,7 @@ struct Index {
|
||||
unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */
|
||||
unsigned bNoQuery:1; /* Do not use this index to optimize queries */
|
||||
unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
int nSample; /* Number of elements in aSample[] */
|
||||
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
|
||||
tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */
|
||||
@@ -2289,7 +2286,7 @@ struct Index {
|
||||
#define XN_EXPR (-2) /* Indexed column is an expression */
|
||||
|
||||
/*
|
||||
** Each sample stored in the sqlite_stat3 table is represented in memory
|
||||
** Each sample stored in the sqlite_stat4 table is represented in memory
|
||||
** using a structure of this type. See documentation at the top of the
|
||||
** analyze.c source file for additional information.
|
||||
*/
|
||||
@@ -2447,7 +2444,7 @@ typedef int ynVar;
|
||||
*/
|
||||
struct Expr {
|
||||
u8 op; /* Operation performed by this node */
|
||||
char affinity; /* The affinity of the column or 0 if not a column */
|
||||
char affExpr; /* affinity, or RAISE type */
|
||||
u32 flags; /* Various flags. EP_* See below */
|
||||
union {
|
||||
char *zToken; /* Token value. Zero terminated and dequoted */
|
||||
@@ -2491,7 +2488,7 @@ struct Expr {
|
||||
union {
|
||||
Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
|
||||
** for a column of an index on an expression */
|
||||
Window *pWin; /* TK_FUNCTION: Window definition for the func */
|
||||
Window *pWin; /* EP_WinFunc: Window/Filter defn for a function */
|
||||
struct { /* TK_IN, TK_SELECT, and TK_EXISTS */
|
||||
int iAddr; /* Subroutine entry address */
|
||||
int regReturn; /* Register used to hold return address */
|
||||
@@ -2506,36 +2503,37 @@ struct Expr {
|
||||
** EP_Agg == NC_HasAgg == SF_HasAgg
|
||||
** EP_Win == NC_HasWin
|
||||
*/
|
||||
#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
|
||||
#define EP_Distinct 0x000002 /* Aggregate function with DISTINCT keyword */
|
||||
#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */
|
||||
#define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */
|
||||
#define EP_Agg 0x000010 /* Contains one or more aggregate functions */
|
||||
#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
|
||||
#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
|
||||
#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
|
||||
#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */
|
||||
#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */
|
||||
#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
|
||||
#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
|
||||
#define EP_Skip 0x001000 /* Operator does not contribute to affinity */
|
||||
#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
|
||||
#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
|
||||
#define EP_Win 0x008000 /* Contains window functions */
|
||||
#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
|
||||
#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
|
||||
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
|
||||
#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
|
||||
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
|
||||
#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
|
||||
#define EP_Alias 0x400000 /* Is an alias for a result set column */
|
||||
#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
|
||||
#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
|
||||
#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
|
||||
#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
|
||||
#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
|
||||
#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
|
||||
#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
|
||||
#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
|
||||
#define EP_Distinct 0x000002 /* Aggregate function with DISTINCT keyword */
|
||||
#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */
|
||||
#define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */
|
||||
#define EP_Agg 0x000010 /* Contains one or more aggregate functions */
|
||||
#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
|
||||
#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
|
||||
#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
|
||||
#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */
|
||||
#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */
|
||||
#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
|
||||
#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
|
||||
#define EP_Skip 0x001000 /* Operator does not contribute to affinity */
|
||||
#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
|
||||
#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
|
||||
#define EP_Win 0x008000 /* Contains window functions */
|
||||
#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
|
||||
#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
|
||||
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
|
||||
#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
|
||||
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
|
||||
#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
|
||||
#define EP_Alias 0x400000 /* Is an alias for a result set column */
|
||||
#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
|
||||
#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
|
||||
#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
|
||||
#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
|
||||
#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
|
||||
#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
|
||||
#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
|
||||
#define EP_Indirect 0x40000000 /* Contained within a TRIGGER or a VIEW */
|
||||
|
||||
/*
|
||||
** The EP_Propagate mask is a set of properties that automatically propagate
|
||||
@@ -2579,6 +2577,14 @@ struct Expr {
|
||||
*/
|
||||
#define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */
|
||||
|
||||
/*
|
||||
** True if the expression passed as an argument was a function with
|
||||
** an OVER() clause (a window function).
|
||||
*/
|
||||
#define IsWindowFunc(p) ( \
|
||||
ExprHasProperty((p), EP_WinFunc) && p->y.pWin->eFrmType!=TK_FILTER \
|
||||
)
|
||||
|
||||
/*
|
||||
** A list of expressions. Each expression may optionally have a
|
||||
** name. An expr/name combination can be used in several ways, such
|
||||
@@ -2601,7 +2607,7 @@ struct ExprList {
|
||||
Expr *pExpr; /* The parse tree for this expression */
|
||||
char *zName; /* Token associated with this expression */
|
||||
char *zSpan; /* Original text of the expression */
|
||||
u8 sortOrder; /* 1 for DESC or 0 for ASC */
|
||||
u8 sortFlags; /* Mask of KEYINFO_ORDER_* flags */
|
||||
unsigned done :1; /* A flag to indicate when processing is finished */
|
||||
unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */
|
||||
unsigned reusable :1; /* Constant expression is reusable */
|
||||
@@ -2896,6 +2902,7 @@ struct Select {
|
||||
#define SF_Converted 0x10000 /* By convertCompoundSelectToSubquery() */
|
||||
#define SF_IncludeHidden 0x20000 /* Include hidden columns in output */
|
||||
#define SF_ComplexResult 0x40000 /* Result contains subquery or function */
|
||||
#define SF_WhereBegin 0x80000 /* Really a WhereBegin() call. Debug Only */
|
||||
|
||||
/*
|
||||
** The results of a SELECT can be distributed in several ways, as defined
|
||||
@@ -3400,11 +3407,12 @@ typedef struct {
|
||||
*/
|
||||
struct Sqlite3Config {
|
||||
int bMemstat; /* True to enable memory status */
|
||||
int bCoreMutex; /* True to enable core mutexing */
|
||||
int bFullMutex; /* True to enable full mutexing */
|
||||
int bOpenUri; /* True to interpret filenames as URIs */
|
||||
int bUseCis; /* Use covering indices for full-scans */
|
||||
int bSmallMalloc; /* Avoid large memory allocations if true */
|
||||
u8 bCoreMutex; /* True to enable core mutexing */
|
||||
u8 bFullMutex; /* True to enable full mutexing */
|
||||
u8 bOpenUri; /* True to interpret filenames as URIs */
|
||||
u8 bUseCis; /* Use covering indices for full-scans */
|
||||
u8 bSmallMalloc; /* Avoid large memory allocations if true */
|
||||
u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */
|
||||
int mxStrlen; /* Maximum string length */
|
||||
int neverCorrupt; /* Database is always well-formed */
|
||||
int szLookaside; /* Default lookaside buffer size */
|
||||
@@ -3456,6 +3464,7 @@ struct Sqlite3Config {
|
||||
int bInternalFunctions; /* Internal SQL functions are visible */
|
||||
int iOnceResetThreshold; /* When to reset OP_Once counters */
|
||||
u32 szSorterRef; /* Min size in bytes to use sorter-refs */
|
||||
unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -3552,10 +3561,11 @@ struct TreeView {
|
||||
#endif /* SQLITE_DEBUG */
|
||||
|
||||
/*
|
||||
** This object is used in various ways, all related to window functions
|
||||
** This object is used in various ways, most (but not all) related to window
|
||||
** functions.
|
||||
**
|
||||
** (1) A single instance of this structure is attached to the
|
||||
** the Expr.pWin field for each window function in an expression tree.
|
||||
** the Expr.y.pWin field for each window function in an expression tree.
|
||||
** This object holds the information contained in the OVER clause,
|
||||
** plus additional fields used during code generation.
|
||||
**
|
||||
@@ -3566,6 +3576,10 @@ struct TreeView {
|
||||
** (3) The terms of the WINDOW clause of a SELECT are instances of this
|
||||
** object on a linked list attached to Select.pWinDefn.
|
||||
**
|
||||
** (4) For an aggregate function with a FILTER clause, an instance
|
||||
** of this object is stored in Expr.y.pWin with eFrmType set to
|
||||
** TK_FILTER. In this case the only field used is Window.pFilter.
|
||||
**
|
||||
** The uses (1) and (2) are really the same Window object that just happens
|
||||
** to be accessible in two different ways. Use case (3) are separate objects.
|
||||
*/
|
||||
@@ -3581,6 +3595,7 @@ struct Window {
|
||||
u8 eExclude; /* TK_NO, TK_CURRENT, TK_TIES, TK_GROUP, or 0 */
|
||||
Expr *pStart; /* Expression for "<expr> PRECEDING" */
|
||||
Expr *pEnd; /* Expression for "<expr> FOLLOWING" */
|
||||
Window **ppThis; /* Pointer to this object in Select.pWin list */
|
||||
Window *pNextWin; /* Next window function belonging to this SELECT */
|
||||
Expr *pFilter; /* The FILTER expression */
|
||||
FuncDef *pFunc; /* The function */
|
||||
@@ -3600,10 +3615,12 @@ struct Window {
|
||||
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
void sqlite3WindowDelete(sqlite3*, Window*);
|
||||
void sqlite3WindowUnlinkFromSelect(Window*);
|
||||
void sqlite3WindowListDelete(sqlite3 *db, Window *p);
|
||||
Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8);
|
||||
void sqlite3WindowAttach(Parse*, Expr*, Window*);
|
||||
int sqlite3WindowCompare(Parse*, Window*, Window*);
|
||||
void sqlite3WindowLink(Select *pSel, Window *pWin);
|
||||
int sqlite3WindowCompare(Parse*, Window*, Window*, int);
|
||||
void sqlite3WindowCodeInit(Parse*, Window*);
|
||||
void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
|
||||
int sqlite3WindowRewrite(Parse*, Select*);
|
||||
@@ -3894,8 +3911,8 @@ void sqlite3CollapseDatabaseArray(sqlite3*);
|
||||
void sqlite3CommitInternalChanges(sqlite3*);
|
||||
void sqlite3DeleteColumnNames(sqlite3*,Table*);
|
||||
int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
|
||||
void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*);
|
||||
Table *sqlite3ResultSetOfSelect(Parse*,Select*);
|
||||
void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char);
|
||||
Table *sqlite3ResultSetOfSelect(Parse*,Select*,char);
|
||||
void sqlite3OpenMasterTable(Parse *, int);
|
||||
Index *sqlite3PrimaryKeyIndex(Table*);
|
||||
i16 sqlite3ColumnOfIndex(Index*, i16);
|
||||
@@ -4196,7 +4213,7 @@ LogEst sqlite3LogEstAdd(LogEst,LogEst);
|
||||
LogEst sqlite3LogEstFromDouble(double);
|
||||
#endif
|
||||
#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
|
||||
defined(SQLITE_ENABLE_STAT3_OR_STAT4) || \
|
||||
defined(SQLITE_ENABLE_STAT4) || \
|
||||
defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
|
||||
u64 sqlite3LogEstToInt(LogEst);
|
||||
#endif
|
||||
@@ -4262,9 +4279,10 @@ int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*);
|
||||
Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
|
||||
Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
|
||||
Expr *sqlite3ExprSkipCollate(Expr*);
|
||||
Expr *sqlite3ExprSkipCollateAndLikely(Expr*);
|
||||
int sqlite3CheckCollSeq(Parse *, CollSeq *);
|
||||
int sqlite3WritableSchema(sqlite3*);
|
||||
int sqlite3CheckObjectName(Parse *, const char *);
|
||||
int sqlite3CheckObjectName(Parse*, const char*,const char*,const char*);
|
||||
void sqlite3VdbeSetChanges(sqlite3 *, int);
|
||||
int sqlite3AddInt64(i64*,i64);
|
||||
int sqlite3SubInt64(i64*,i64);
|
||||
@@ -4351,6 +4369,7 @@ void sqlite3KeyInfoUnref(KeyInfo*);
|
||||
KeyInfo *sqlite3KeyInfoRef(KeyInfo*);
|
||||
KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*);
|
||||
KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int);
|
||||
int sqlite3HasExplicitNulls(Parse*, ExprList*);
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
int sqlite3KeyInfoIsWriteable(KeyInfo*);
|
||||
@@ -4383,8 +4402,7 @@ int sqlite3ExprCheckIN(Parse*, Expr*);
|
||||
# define sqlite3ExprCheckIN(x,y) SQLITE_OK
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
void sqlite3AnalyzeFunctions(void);
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
int sqlite3Stat4ProbeSetValue(
|
||||
Parse*,Index*,UnpackedRecord**,Expr*,int,int,int*);
|
||||
int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**);
|
||||
@@ -4431,6 +4449,7 @@ void sqlite3AutoLoadExtensions(sqlite3*);
|
||||
# define sqlite3VtabInSync(db) 0
|
||||
# define sqlite3VtabLock(X)
|
||||
# define sqlite3VtabUnlock(X)
|
||||
# define sqlite3VtabModuleUnref(D,X)
|
||||
# define sqlite3VtabUnlockList(X)
|
||||
# define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK
|
||||
# define sqlite3GetVTable(X,Y) ((VTable*)0)
|
||||
@@ -4442,6 +4461,7 @@ void sqlite3AutoLoadExtensions(sqlite3*);
|
||||
int sqlite3VtabCommit(sqlite3 *db);
|
||||
void sqlite3VtabLock(VTable *);
|
||||
void sqlite3VtabUnlock(VTable *);
|
||||
void sqlite3VtabModuleUnref(sqlite3*,Module*);
|
||||
void sqlite3VtabUnlockList(sqlite3*);
|
||||
int sqlite3VtabSavepoint(sqlite3 *, int, int);
|
||||
void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*);
|
||||
|
||||
+102
-24
@@ -1917,33 +1917,33 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
"authorizer", "backup", "bind_fallback",
|
||||
"busy", "cache", "changes",
|
||||
"close", "collate", "collation_needed",
|
||||
"commit_hook", "complete", "copy",
|
||||
"deserialize", "enable_load_extension", "errorcode",
|
||||
"eval", "exists", "function",
|
||||
"incrblob", "interrupt", "last_insert_rowid",
|
||||
"nullvalue", "onecolumn", "preupdate",
|
||||
"profile", "progress", "rekey",
|
||||
"restore", "rollback_hook", "serialize",
|
||||
"status", "timeout", "total_changes",
|
||||
"trace", "trace_v2", "transaction",
|
||||
"unlock_notify", "update_hook", "version",
|
||||
"wal_hook", 0
|
||||
"commit_hook", "complete", "config",
|
||||
"copy", "deserialize", "enable_load_extension",
|
||||
"errorcode", "eval", "exists",
|
||||
"function", "incrblob", "interrupt",
|
||||
"last_insert_rowid", "nullvalue", "onecolumn",
|
||||
"preupdate", "profile", "progress",
|
||||
"rekey", "restore", "rollback_hook",
|
||||
"serialize", "status", "timeout",
|
||||
"total_changes", "trace", "trace_v2",
|
||||
"transaction", "unlock_notify", "update_hook",
|
||||
"version", "wal_hook", 0
|
||||
};
|
||||
enum DB_enum {
|
||||
DB_AUTHORIZER, DB_BACKUP, DB_BIND_FALLBACK,
|
||||
DB_BUSY, DB_CACHE, DB_CHANGES,
|
||||
DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED,
|
||||
DB_COMMIT_HOOK, DB_COMPLETE, DB_COPY,
|
||||
DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION,DB_ERRORCODE,
|
||||
DB_EVAL, DB_EXISTS, DB_FUNCTION,
|
||||
DB_INCRBLOB, DB_INTERRUPT, DB_LAST_INSERT_ROWID,
|
||||
DB_NULLVALUE, DB_ONECOLUMN, DB_PREUPDATE,
|
||||
DB_PROFILE, DB_PROGRESS, DB_REKEY,
|
||||
DB_RESTORE, DB_ROLLBACK_HOOK, DB_SERIALIZE,
|
||||
DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES,
|
||||
DB_TRACE, DB_TRACE_V2, DB_TRANSACTION,
|
||||
DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION,
|
||||
DB_WAL_HOOK
|
||||
DB_COMMIT_HOOK, DB_COMPLETE, DB_CONFIG,
|
||||
DB_COPY, DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION,
|
||||
DB_ERRORCODE, DB_EVAL, DB_EXISTS,
|
||||
DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT,
|
||||
DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN,
|
||||
DB_PREUPDATE, DB_PROFILE, DB_PROGRESS,
|
||||
DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK,
|
||||
DB_SERIALIZE, DB_STATUS, DB_TIMEOUT,
|
||||
DB_TOTAL_CHANGES, DB_TRACE, DB_TRACE_V2,
|
||||
DB_TRANSACTION, DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK,
|
||||
DB_VERSION, DB_WAL_HOOK
|
||||
};
|
||||
/* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
|
||||
|
||||
@@ -2331,6 +2331,74 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
break;
|
||||
}
|
||||
|
||||
/* $db config ?OPTION? ?BOOLEAN?
|
||||
**
|
||||
** Configure the database connection using the sqlite3_db_config()
|
||||
** interface.
|
||||
*/
|
||||
case DB_CONFIG: {
|
||||
static const struct DbConfigChoices {
|
||||
const char *zName;
|
||||
int op;
|
||||
} aDbConfig[] = {
|
||||
{ "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
|
||||
{ "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
|
||||
{ "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW },
|
||||
{ "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
|
||||
{ "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
|
||||
{ "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
|
||||
{ "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG },
|
||||
{ "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP },
|
||||
{ "reset_database", SQLITE_DBCONFIG_RESET_DATABASE },
|
||||
{ "defensive", SQLITE_DBCONFIG_DEFENSIVE },
|
||||
{ "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA },
|
||||
{ "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE },
|
||||
{ "dqs_dml", SQLITE_DBCONFIG_DQS_DML },
|
||||
{ "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL },
|
||||
};
|
||||
Tcl_Obj *pResult;
|
||||
int ii;
|
||||
if( objc>4 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "?OPTION? ?BOOLEAN?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( objc==2 ){
|
||||
/* With no arguments, list all configuration options and with the
|
||||
** current value */
|
||||
pResult = Tcl_NewListObj(0,0);
|
||||
for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){
|
||||
int v = 0;
|
||||
sqlite3_db_config(pDb->db, aDbConfig[ii].op, -1, &v);
|
||||
Tcl_ListObjAppendElement(interp, pResult,
|
||||
Tcl_NewStringObj(aDbConfig[ii].zName,-1));
|
||||
Tcl_ListObjAppendElement(interp, pResult,
|
||||
Tcl_NewIntObj(v));
|
||||
}
|
||||
}else{
|
||||
const char *zOpt = Tcl_GetString(objv[2]);
|
||||
int onoff = -1;
|
||||
int v = 0;
|
||||
if( zOpt[0]=='-' ) zOpt++;
|
||||
for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){
|
||||
if( strcmp(aDbConfig[ii].zName, zOpt)==0 ) break;
|
||||
}
|
||||
if( ii>=sizeof(aDbConfig)/sizeof(aDbConfig[0]) ){
|
||||
Tcl_AppendResult(interp, "unknown config option: \"", zOpt,
|
||||
"\"", (void*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( objc==4 ){
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[3], &onoff) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
sqlite3_db_config(pDb->db, aDbConfig[ii].op, onoff, &v);
|
||||
pResult = Tcl_NewIntObj(v);
|
||||
}
|
||||
Tcl_SetObjResult(interp, pResult);
|
||||
break;
|
||||
}
|
||||
|
||||
/* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR?
|
||||
**
|
||||
** Copy data into table from filename, optionally using SEPARATOR
|
||||
@@ -2741,10 +2809,16 @@ deserialize_error:
|
||||
}
|
||||
|
||||
/*
|
||||
** $db function NAME [-argcount N] [-deterministic] SCRIPT
|
||||
** $db function NAME [OPTIONS] SCRIPT
|
||||
**
|
||||
** Create a new SQL function called NAME. Whenever that function is
|
||||
** called, invoke SCRIPT to evaluate the function.
|
||||
**
|
||||
** Options:
|
||||
** --argcount N Function has exactly N arguments
|
||||
** --deterministic The function is pure
|
||||
** --directonly Prohibit use inside triggers and views
|
||||
** --returntype TYPE Specify the return type of the function
|
||||
*/
|
||||
case DB_FUNCTION: {
|
||||
int flags = SQLITE_UTF8;
|
||||
@@ -2777,6 +2851,9 @@ deserialize_error:
|
||||
if( n>1 && strncmp(z, "-deterministic",n)==0 ){
|
||||
flags |= SQLITE_DETERMINISTIC;
|
||||
}else
|
||||
if( n>1 && strncmp(z, "-directonly",n)==0 ){
|
||||
flags |= SQLITE_DIRECTONLY;
|
||||
}else
|
||||
if( n>1 && strncmp(z, "-returntype", n)==0 ){
|
||||
const char *azType[] = {"integer", "real", "text", "blob", "any", 0};
|
||||
assert( SQLITE_INTEGER==1 && SQLITE_FLOAT==2 && SQLITE_TEXT==3 );
|
||||
@@ -2792,7 +2869,8 @@ deserialize_error:
|
||||
eType++;
|
||||
}else{
|
||||
Tcl_AppendResult(interp, "bad option \"", z,
|
||||
"\": must be -argcount, -deterministic or -returntype", (char*)0
|
||||
"\": must be -argcount, -deterministic, -directonly,"
|
||||
" or -returntype", (char*)0
|
||||
);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
+68
-3
@@ -1110,6 +1110,31 @@ static int SQLITE_TCLAPI test_create_function(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_drop_modules DB ?NAME ...?
|
||||
**
|
||||
** Invoke the sqlite3_drop_modules(D,L) interface on database
|
||||
** connection DB, in order to drop all modules except those named in
|
||||
** the argument.
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_drop_modules(
|
||||
void *NotUsed,
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int argc, /* Number of arguments */
|
||||
char **argv /* Text of each argument */
|
||||
){
|
||||
sqlite3 *db;
|
||||
|
||||
if( argc!=2 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" DB\"", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
|
||||
sqlite3_drop_modules(db, argc>2 ? (const char**)(argv+2) : 0);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Routines to implement the x_count() aggregate function.
|
||||
**
|
||||
@@ -6373,7 +6398,41 @@ static int SQLITE_TCLAPI reset_prng_state(
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3_test_control(SQLITE_TESTCTRL_PRNG_RESET);
|
||||
sqlite3_randomness(0,0);
|
||||
return TCL_OK;
|
||||
}
|
||||
/*
|
||||
** tclcmd: prng_seed INT ?DB?
|
||||
**
|
||||
** Set up the SQLITE_TESTCTRL_PRNG_SEED pragma with parameter INT and DB.
|
||||
** INT is an integer. DB is a database connection, or a NULL pointer if
|
||||
** omitted.
|
||||
**
|
||||
** When INT!=0 and DB!=0, set the PRNG seed to the value of the schema
|
||||
** cookie for DB, or to INT if the schema cookie happens to be zero.
|
||||
**
|
||||
** When INT!=0 and DB==0, set the PRNG seed to just INT.
|
||||
**
|
||||
** If INT==0 and DB==0 then use the default procedure of calling the
|
||||
** xRandomness method on the default VFS to get the PRNG seed.
|
||||
*/
|
||||
static int SQLITE_TCLAPI prng_seed(
|
||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
int i = 0;
|
||||
sqlite3 *db = 0;
|
||||
if( objc!=2 && objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "SEED ?DB?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_GetIntFromObj(interp,objv[0],&i) ) return TCL_ERROR;
|
||||
if( objc==3 && getDbPointer(interp, Tcl_GetString(objv[2]), &db) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, i, db);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -7139,8 +7198,7 @@ static int SQLITE_TCLAPI optimization_control(
|
||||
{ "order-by-idx-join", SQLITE_OrderByIdxJoin },
|
||||
{ "transitive", SQLITE_Transitive },
|
||||
{ "omit-noop-join", SQLITE_OmitNoopJoin },
|
||||
{ "stat3", SQLITE_Stat34 },
|
||||
{ "stat4", SQLITE_Stat34 },
|
||||
{ "stat4", SQLITE_Stat4 },
|
||||
{ "skip-scan", SQLITE_SkipScan },
|
||||
};
|
||||
|
||||
@@ -7740,6 +7798,11 @@ static int SQLITE_TCLAPI test_decode_hexdb(
|
||||
int pgsz;
|
||||
rc = sscanf(zIn+i, "| size %d pagesize %d", &n, &pgsz);
|
||||
if( rc!=2 ) continue;
|
||||
if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ){
|
||||
Tcl_AppendResult(interp, "bad 'pagesize' field", (void*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
n = (n+pgsz-1)&~(pgsz-1); /* Round n up to the next multiple of pgsz */
|
||||
if( n<512 ){
|
||||
Tcl_AppendResult(interp, "bad 'size' field", (void*)0);
|
||||
return TCL_ERROR;
|
||||
@@ -7822,6 +7885,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_close_v2", (Tcl_CmdProc*)sqlite_test_close_v2 },
|
||||
{ "sqlite3_create_function", (Tcl_CmdProc*)test_create_function },
|
||||
{ "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate },
|
||||
{ "sqlite3_drop_modules", (Tcl_CmdProc*)test_drop_modules },
|
||||
{ "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func },
|
||||
{ "sqlite_abort", (Tcl_CmdProc*)sqlite_abort },
|
||||
{ "sqlite_bind", (Tcl_CmdProc*)test_bind },
|
||||
@@ -7918,6 +7982,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "save_prng_state", save_prng_state, 0 },
|
||||
{ "restore_prng_state", restore_prng_state, 0 },
|
||||
{ "reset_prng_state", reset_prng_state, 0 },
|
||||
{ "prng_seed", prng_seed, 0 },
|
||||
{ "database_never_corrupt", database_never_corrupt, 0},
|
||||
{ "database_may_be_corrupt", database_may_be_corrupt, 0},
|
||||
{ "optimization_control", optimization_control,0},
|
||||
|
||||
@@ -585,12 +585,6 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "stat4", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
#if defined(SQLITE_ENABLE_STAT3) && !defined(SQLITE_ENABLE_STAT4)
|
||||
Tcl_SetVar2(interp, "sqlite_options", "stat3", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "stat3", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#if defined(SQLITE_ENABLE_STMTVTAB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
|
||||
Tcl_SetVar2(interp, "sqlite_options", "stmtvtab", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
|
||||
+26
-17
@@ -176,13 +176,17 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
|
||||
sqlite3TreeViewPush(pView, 1);
|
||||
}
|
||||
do{
|
||||
sqlite3TreeViewLine(pView,
|
||||
"SELECT%s%s (%u/%p) selFlags=0x%x nSelectRow=%d",
|
||||
((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
|
||||
((p->selFlags & SF_Aggregate) ? " agg_flag" : ""),
|
||||
p->selId, p, p->selFlags,
|
||||
(int)p->nSelectRow
|
||||
);
|
||||
if( p->selFlags & SF_WhereBegin ){
|
||||
sqlite3TreeViewLine(pView, "sqlite3WhereBegin()");
|
||||
}else{
|
||||
sqlite3TreeViewLine(pView,
|
||||
"SELECT%s%s (%u/%p) selFlags=0x%x nSelectRow=%d",
|
||||
((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
|
||||
((p->selFlags & SF_Aggregate) ? " agg_flag" : ""),
|
||||
p->selId, p, p->selFlags,
|
||||
(int)p->nSelectRow
|
||||
);
|
||||
}
|
||||
if( cnt++ ) sqlite3TreeViewPop(pView);
|
||||
if( p->pPrior ){
|
||||
n = 1000;
|
||||
@@ -199,7 +203,10 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
|
||||
if( p->pWinDefn ) n++;
|
||||
#endif
|
||||
}
|
||||
sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
|
||||
if( p->pEList ){
|
||||
sqlite3TreeViewExprList(pView, p->pEList, n>0, "result-set");
|
||||
}
|
||||
n--;
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
if( p->pWin ){
|
||||
Window *pX;
|
||||
@@ -395,12 +402,14 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
sqlite3TreeViewPop(pView);
|
||||
return;
|
||||
}
|
||||
if( pExpr->flags ){
|
||||
if( pExpr->flags || pExpr->affExpr ){
|
||||
if( ExprHasProperty(pExpr, EP_FromJoin) ){
|
||||
sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x iRJT=%d",
|
||||
pExpr->flags, pExpr->iRightJoinTable);
|
||||
sqlite3_snprintf(sizeof(zFlgs),zFlgs," fg.af=%x.%c iRJT=%d",
|
||||
pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n',
|
||||
pExpr->iRightJoinTable);
|
||||
}else{
|
||||
sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x",pExpr->flags);
|
||||
sqlite3_snprintf(sizeof(zFlgs),zFlgs," fg.af=%x.%c",
|
||||
pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
|
||||
}
|
||||
}else{
|
||||
zFlgs[0] = 0;
|
||||
@@ -548,10 +557,10 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
#endif
|
||||
}
|
||||
if( pExpr->op==TK_AGG_FUNCTION ){
|
||||
sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q",
|
||||
pExpr->op2, pExpr->u.zToken);
|
||||
sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s",
|
||||
pExpr->op2, pExpr->u.zToken, zFlgs);
|
||||
}else{
|
||||
sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken);
|
||||
sqlite3TreeViewLine(pView, "FUNCTION %Q%s", pExpr->u.zToken, zFlgs);
|
||||
}
|
||||
if( pFarg ){
|
||||
sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0);
|
||||
@@ -628,7 +637,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
case TK_RAISE: {
|
||||
const char *zType = "unk";
|
||||
switch( pExpr->affinity ){
|
||||
switch( pExpr->affExpr ){
|
||||
case OE_Rollback: zType = "rollback"; break;
|
||||
case OE_Abort: zType = "abort"; break;
|
||||
case OE_Fail: zType = "fail"; break;
|
||||
@@ -669,7 +678,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
|
||||
}else if( zUniOp ){
|
||||
sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs);
|
||||
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
|
||||
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
|
||||
}
|
||||
sqlite3TreeViewPop(pView);
|
||||
}
|
||||
|
||||
+9
-1
@@ -177,7 +177,11 @@ void sqlite3BeginTrigger(
|
||||
/* Check that the trigger name is not reserved and that no trigger of the
|
||||
** specified name exists */
|
||||
zName = sqlite3NameFromToken(db, pName);
|
||||
if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
|
||||
if( zName==0 ){
|
||||
assert( db->mallocFailed );
|
||||
goto trigger_cleanup;
|
||||
}
|
||||
if( sqlite3CheckObjectName(pParse, zName, "trigger", pTab->zName) ){
|
||||
goto trigger_cleanup;
|
||||
}
|
||||
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
||||
@@ -340,6 +344,7 @@ void sqlite3FinishTrigger(
|
||||
Trigger *pLink = pTrig;
|
||||
Hash *pHash = &db->aDb[iDb].pSchema->trigHash;
|
||||
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
||||
assert( pLink!=0 );
|
||||
pTrig = sqlite3HashInsert(pHash, zName, pTrig);
|
||||
if( pTrig ){
|
||||
sqlite3OomFault(db);
|
||||
@@ -458,6 +463,9 @@ TriggerStep *sqlite3TriggerInsertStep(
|
||||
pTriggerStep->pIdList = pColumn;
|
||||
pTriggerStep->pUpsert = pUpsert;
|
||||
pTriggerStep->orconf = orconf;
|
||||
if( pUpsert ){
|
||||
sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget);
|
||||
}
|
||||
}else{
|
||||
testcase( pColumn );
|
||||
sqlite3IdListDelete(db, pColumn);
|
||||
|
||||
+2
-2
@@ -1498,7 +1498,7 @@ LogEst sqlite3LogEstFromDouble(double x){
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
||||
#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
|
||||
defined(SQLITE_ENABLE_STAT3_OR_STAT4) || \
|
||||
defined(SQLITE_ENABLE_STAT4) || \
|
||||
defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
|
||||
/*
|
||||
** Convert a LogEst into an integer.
|
||||
@@ -1516,7 +1516,7 @@ u64 sqlite3LogEstToInt(LogEst x){
|
||||
defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
|
||||
if( x>60 ) return (u64)LARGEST_INT64;
|
||||
#else
|
||||
/* If only SQLITE_ENABLE_STAT3_OR_STAT4 is on, then the largest input
|
||||
/* If only SQLITE_ENABLE_STAT4 is on, then the largest input
|
||||
** possible to this routine is 310, resulting in a maximum x of 31 */
|
||||
assert( x<=60 );
|
||||
#endif
|
||||
|
||||
+137
-29
@@ -343,6 +343,7 @@ static void applyNumericAffinity(Mem *pRec, int bTryForInt){
|
||||
** Convert pRec to a text representation.
|
||||
**
|
||||
** SQLITE_AFF_BLOB:
|
||||
** SQLITE_AFF_NONE:
|
||||
** No-op. pRec is unchanged.
|
||||
*/
|
||||
static void applyAffinity(
|
||||
@@ -2226,9 +2227,14 @@ case OP_Compare: {
|
||||
REGISTER_TRACE(p2+idx, &aMem[p2+idx]);
|
||||
assert( i<pKeyInfo->nKeyField );
|
||||
pColl = pKeyInfo->aColl[i];
|
||||
bRev = pKeyInfo->aSortOrder[i];
|
||||
bRev = (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC);
|
||||
iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl);
|
||||
if( iCompare ){
|
||||
if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL)
|
||||
&& ((aMem[p1+idx].flags & MEM_Null) || (aMem[p2+idx].flags & MEM_Null))
|
||||
){
|
||||
iCompare = -iCompare;
|
||||
}
|
||||
if( bRev ) iCompare = -iCompare;
|
||||
break;
|
||||
}
|
||||
@@ -2812,15 +2818,27 @@ case OP_Affinity: {
|
||||
assert( pOp->p2>0 );
|
||||
assert( zAffinity[pOp->p2]==0 );
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
while( 1 /*edit-by-break*/ ){
|
||||
while( 1 /*exit-by-break*/ ){
|
||||
assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
|
||||
assert( memIsValid(pIn1) );
|
||||
applyAffinity(pIn1, zAffinity[0], encoding);
|
||||
if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){
|
||||
/* When applying REAL affinity, if the result is still MEM_Int,
|
||||
** indicate that REAL is actually desired */
|
||||
pIn1->flags |= MEM_IntReal;
|
||||
pIn1->flags &= ~MEM_Int;
|
||||
/* When applying REAL affinity, if the result is still an MEM_Int
|
||||
** that will fit in 6 bytes, then change the type to MEM_IntReal
|
||||
** so that we keep the high-resolution integer value but know that
|
||||
** the type really wants to be REAL. */
|
||||
testcase( pIn1->u.i==140737488355328LL );
|
||||
testcase( pIn1->u.i==140737488355327LL );
|
||||
testcase( pIn1->u.i==-140737488355328LL );
|
||||
testcase( pIn1->u.i==-140737488355329LL );
|
||||
if( pIn1->u.i<=140737488355327LL && pIn1->u.i>=-140737488355328LL ){
|
||||
pIn1->flags |= MEM_IntReal;
|
||||
pIn1->flags &= ~MEM_Int;
|
||||
}else{
|
||||
pIn1->u.r = (double)pIn1->u.i;
|
||||
pIn1->flags |= MEM_Real;
|
||||
pIn1->flags &= ~MEM_Int;
|
||||
}
|
||||
}
|
||||
REGISTER_TRACE((int)(pIn1-aMem), pIn1);
|
||||
zAffinity++;
|
||||
@@ -2927,14 +2945,36 @@ case OP_MakeRecord: {
|
||||
#endif
|
||||
|
||||
/* Loop through the elements that will make up the record to figure
|
||||
** out how much space is required for the new record.
|
||||
** out how much space is required for the new record. After this loop,
|
||||
** the Mem.uTemp field of each term should hold the serial-type that will
|
||||
** be used for that term in the generated record:
|
||||
**
|
||||
** Mem.uTemp value type
|
||||
** --------------- ---------------
|
||||
** 0 NULL
|
||||
** 1 1-byte signed integer
|
||||
** 2 2-byte signed integer
|
||||
** 3 3-byte signed integer
|
||||
** 4 4-byte signed integer
|
||||
** 5 6-byte signed integer
|
||||
** 6 8-byte signed integer
|
||||
** 7 IEEE float
|
||||
** 8 Integer constant 0
|
||||
** 9 Integer constant 1
|
||||
** 10,11 reserved for expansion
|
||||
** N>=12 and even BLOB
|
||||
** N>=13 and odd text
|
||||
**
|
||||
** The following additional values are computed:
|
||||
** nHdr Number of bytes needed for the record header
|
||||
** nData Number of bytes of data space needed for the record
|
||||
** nZero Zero bytes at the end of the record
|
||||
*/
|
||||
pRec = pLast;
|
||||
do{
|
||||
assert( memIsValid(pRec) );
|
||||
serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
|
||||
if( pRec->flags & MEM_Zero ){
|
||||
if( serial_type==0 ){
|
||||
if( pRec->flags & MEM_Null ){
|
||||
if( pRec->flags & MEM_Zero ){
|
||||
/* Values with MEM_Null and MEM_Zero are created by xColumn virtual
|
||||
** table methods that never invoke sqlite3_result_xxxxx() while
|
||||
** computing an unchanging column value in an UPDATE statement.
|
||||
@@ -2942,19 +2982,83 @@ case OP_MakeRecord: {
|
||||
** so that they can be passed through to xUpdate and have
|
||||
** a true sqlite3_value_nochange(). */
|
||||
assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB );
|
||||
serial_type = 10;
|
||||
}else if( nData ){
|
||||
if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
|
||||
pRec->uTemp = 10;
|
||||
}else{
|
||||
nZero += pRec->u.nZero;
|
||||
len -= pRec->u.nZero;
|
||||
pRec->uTemp = 0;
|
||||
}
|
||||
nHdr++;
|
||||
}else if( pRec->flags & (MEM_Int|MEM_IntReal) ){
|
||||
/* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
|
||||
i64 i = pRec->u.i;
|
||||
u64 uu;
|
||||
testcase( pRec->flags & MEM_Int );
|
||||
testcase( pRec->flags & MEM_IntReal );
|
||||
if( i<0 ){
|
||||
uu = ~i;
|
||||
}else{
|
||||
uu = i;
|
||||
}
|
||||
nHdr++;
|
||||
testcase( uu==127 ); testcase( uu==128 );
|
||||
testcase( uu==32767 ); testcase( uu==32768 );
|
||||
testcase( uu==8388607 ); testcase( uu==8388608 );
|
||||
testcase( uu==2147483647 ); testcase( uu==2147483648 );
|
||||
testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL );
|
||||
if( uu<=127 ){
|
||||
if( (i&1)==i && file_format>=4 ){
|
||||
pRec->uTemp = 8+(u32)uu;
|
||||
}else{
|
||||
nData++;
|
||||
pRec->uTemp = 1;
|
||||
}
|
||||
}else if( uu<=32767 ){
|
||||
nData += 2;
|
||||
pRec->uTemp = 2;
|
||||
}else if( uu<=8388607 ){
|
||||
nData += 3;
|
||||
pRec->uTemp = 3;
|
||||
}else if( uu<=2147483647 ){
|
||||
nData += 4;
|
||||
pRec->uTemp = 4;
|
||||
}else if( uu<=140737488355327LL ){
|
||||
nData += 6;
|
||||
pRec->uTemp = 5;
|
||||
}else{
|
||||
nData += 8;
|
||||
if( pRec->flags & MEM_IntReal ){
|
||||
/* If the value is IntReal and is going to take up 8 bytes to store
|
||||
** as an integer, then we might as well make it an 8-byte floating
|
||||
** point value */
|
||||
pRec->u.r = (double)pRec->u.i;
|
||||
pRec->flags &= ~MEM_IntReal;
|
||||
pRec->flags |= MEM_Real;
|
||||
pRec->uTemp = 7;
|
||||
}else{
|
||||
pRec->uTemp = 6;
|
||||
}
|
||||
}
|
||||
}else if( pRec->flags & MEM_Real ){
|
||||
nHdr++;
|
||||
nData += 8;
|
||||
pRec->uTemp = 7;
|
||||
}else{
|
||||
assert( db->mallocFailed || pRec->flags&(MEM_Str|MEM_Blob) );
|
||||
assert( pRec->n>=0 );
|
||||
len = (u32)pRec->n;
|
||||
serial_type = (len*2) + 12 + ((pRec->flags & MEM_Str)!=0);
|
||||
if( pRec->flags & MEM_Zero ){
|
||||
serial_type += pRec->u.nZero*2;
|
||||
if( nData ){
|
||||
if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
|
||||
len += pRec->u.nZero;
|
||||
}else{
|
||||
nZero += pRec->u.nZero;
|
||||
}
|
||||
}
|
||||
nData += len;
|
||||
nHdr += sqlite3VarintLen(serial_type);
|
||||
pRec->uTemp = serial_type;
|
||||
}
|
||||
nData += len;
|
||||
testcase( serial_type==127 );
|
||||
testcase( serial_type==128 );
|
||||
nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
|
||||
pRec->uTemp = serial_type;
|
||||
if( pRec==pData0 ) break;
|
||||
pRec--;
|
||||
}while(1);
|
||||
@@ -3290,7 +3394,7 @@ case OP_AutoCommit: {
|
||||
rc = SQLITE_ERROR;
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
break;
|
||||
/*NOTREACHED*/ assert(0);
|
||||
}
|
||||
|
||||
/* Opcode: Transaction P1 P2 P3 P4 P5
|
||||
@@ -4028,6 +4132,7 @@ case OP_SeekGT: { /* jump, in3, group */
|
||||
pC->deferredMoveto = 0;
|
||||
pC->cacheStatus = CACHE_STALE;
|
||||
if( pC->isTable ){
|
||||
u16 flags3, newType;
|
||||
/* The BTREE_SEEK_EQ flag is only set on index cursors */
|
||||
assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0
|
||||
|| CORRUPT_DB );
|
||||
@@ -4036,18 +4141,21 @@ case OP_SeekGT: { /* jump, in3, group */
|
||||
** blob, or NULL. But it needs to be an integer before we can do
|
||||
** the seek, so convert it. */
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){
|
||||
flags3 = pIn3->flags;
|
||||
if( (flags3 & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){
|
||||
applyNumericAffinity(pIn3, 0);
|
||||
}
|
||||
iKey = sqlite3VdbeIntValue(pIn3);
|
||||
iKey = sqlite3VdbeIntValue(pIn3); /* Get the integer key value */
|
||||
newType = pIn3->flags; /* Record the type after applying numeric affinity */
|
||||
pIn3->flags = flags3; /* But convert the type back to its original */
|
||||
|
||||
/* If the P3 value could not be converted into an integer without
|
||||
** loss of information, then special processing is required... */
|
||||
if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
|
||||
if( (pIn3->flags & MEM_Real)==0 ){
|
||||
if( (pIn3->flags & MEM_Null) || oc>=OP_SeekGE ){
|
||||
VdbeBranchTaken(1,2); goto jump_to_p2;
|
||||
break;
|
||||
if( (newType & (MEM_Int|MEM_IntReal))==0 ){
|
||||
if( (newType & MEM_Real)==0 ){
|
||||
if( (newType & MEM_Null) || oc>=OP_SeekGE ){
|
||||
VdbeBranchTaken(1,2);
|
||||
goto jump_to_p2;
|
||||
}else{
|
||||
rc = sqlite3BtreeLast(pC->uc.pCursor, &res);
|
||||
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
||||
@@ -5864,7 +5972,7 @@ case OP_ParseSchema: {
|
||||
initData.pzErrMsg = &p->zErrMsg;
|
||||
initData.mInitFlags = 0;
|
||||
zSql = sqlite3MPrintf(db,
|
||||
"SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
|
||||
"SELECT*FROM\"%w\".%s WHERE %s ORDER BY rowid",
|
||||
db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
|
||||
if( zSql==0 ){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
|
||||
+4
-4
@@ -222,10 +222,10 @@ VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno);
|
||||
# define sqlite3ExplainBreakpoint(A,B) /*no-op*/
|
||||
#endif
|
||||
void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
|
||||
void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
|
||||
void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
|
||||
void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
|
||||
void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
|
||||
void sqlite3VdbeChangeOpcode(Vdbe*, int addr, u8);
|
||||
void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
|
||||
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
|
||||
void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3);
|
||||
void sqlite3VdbeChangeP5(Vdbe*, u16 P5);
|
||||
void sqlite3VdbeJumpHere(Vdbe*, int addr);
|
||||
int sqlite3VdbeChangeToNoop(Vdbe*, int addr);
|
||||
|
||||
@@ -486,7 +486,6 @@ int sqlite3VdbeCursorMoveto(VdbeCursor**, int*);
|
||||
int sqlite3VdbeCursorRestore(VdbeCursor*);
|
||||
u32 sqlite3VdbeSerialTypeLen(u32);
|
||||
u8 sqlite3VdbeOneByteSerialTypeLen(u8);
|
||||
u32 sqlite3VdbeSerialType(Mem*, int, u32*);
|
||||
u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
|
||||
u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
|
||||
void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int);
|
||||
|
||||
+3
-3
@@ -844,7 +844,7 @@ int sqlite3_vtab_nochange(sqlite3_context *p){
|
||||
*/
|
||||
sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){
|
||||
int rc;
|
||||
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifndef SQLITE_ENABLE_STAT4
|
||||
sqlite3_int64 *piTime = &p->pVdbe->iCurrentTime;
|
||||
assert( p->pVdbe!=0 );
|
||||
#else
|
||||
@@ -909,7 +909,7 @@ void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
|
||||
AuxData *pAuxData;
|
||||
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
#if SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#if SQLITE_ENABLE_STAT4
|
||||
if( pCtx->pVdbe==0 ) return 0;
|
||||
#else
|
||||
assert( pCtx->pVdbe!=0 );
|
||||
@@ -943,7 +943,7 @@ void sqlite3_set_auxdata(
|
||||
Vdbe *pVdbe = pCtx->pVdbe;
|
||||
|
||||
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
if( pVdbe==0 ) goto failed;
|
||||
#else
|
||||
assert( pVdbe!=0 );
|
||||
|
||||
+48
-21
@@ -977,16 +977,16 @@ void sqlite3VdbeScanStatus(
|
||||
** Change the value of the opcode, or P1, P2, P3, or P5 operands
|
||||
** for a specific instruction.
|
||||
*/
|
||||
void sqlite3VdbeChangeOpcode(Vdbe *p, u32 addr, u8 iNewOpcode){
|
||||
void sqlite3VdbeChangeOpcode(Vdbe *p, int addr, u8 iNewOpcode){
|
||||
sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode;
|
||||
}
|
||||
void sqlite3VdbeChangeP1(Vdbe *p, u32 addr, int val){
|
||||
void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){
|
||||
sqlite3VdbeGetOp(p,addr)->p1 = val;
|
||||
}
|
||||
void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){
|
||||
void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
|
||||
sqlite3VdbeGetOp(p,addr)->p2 = val;
|
||||
}
|
||||
void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){
|
||||
void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){
|
||||
sqlite3VdbeGetOp(p,addr)->p3 = val;
|
||||
}
|
||||
void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){
|
||||
@@ -1493,14 +1493,16 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
case P4_KEYINFO: {
|
||||
int j;
|
||||
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
|
||||
assert( pKeyInfo->aSortOrder!=0 );
|
||||
assert( pKeyInfo->aSortFlags!=0 );
|
||||
sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField);
|
||||
for(j=0; j<pKeyInfo->nKeyField; j++){
|
||||
CollSeq *pColl = pKeyInfo->aColl[j];
|
||||
const char *zColl = pColl ? pColl->zName : "";
|
||||
if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
|
||||
sqlite3_str_appendf(&x, ",%s%s",
|
||||
pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
|
||||
sqlite3_str_appendf(&x, ",%s%s%s",
|
||||
(pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_DESC) ? "-" : "",
|
||||
(pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_BIGNULL)? "N." : "",
|
||||
zColl);
|
||||
}
|
||||
sqlite3_str_append(&x, ")", 1);
|
||||
break;
|
||||
@@ -1907,8 +1909,11 @@ int sqlite3VdbeList(
|
||||
** pick up the appropriate opcode. */
|
||||
int j;
|
||||
i -= p->nOp;
|
||||
assert( apSub!=0 );
|
||||
assert( nSub>0 );
|
||||
for(j=0; i>=apSub[j]->nOp; j++){
|
||||
i -= apSub[j]->nOp;
|
||||
assert( i<apSub[j]->nOp || j+1<nSub );
|
||||
}
|
||||
pOp = &apSub[j]->aOp[i];
|
||||
}
|
||||
@@ -3430,10 +3435,17 @@ int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){
|
||||
** of SQLite will not understand those serial types.
|
||||
*/
|
||||
|
||||
#if 0 /* Inlined into the OP_MakeRecord opcode */
|
||||
/*
|
||||
** Return the serial-type for the value stored in pMem.
|
||||
**
|
||||
** This routine might convert a large MEM_IntReal value into MEM_Real.
|
||||
**
|
||||
** 2019-07-11: The primary user of this subroutine was the OP_MakeRecord
|
||||
** opcode in the byte-code engine. But by moving this routine in-line, we
|
||||
** can omit some redundant tests and make that opcode a lot faster. So
|
||||
** this routine is now only used by the STAT3 logic and STAT3 support has
|
||||
** ended. The code is kept here for historical reference only.
|
||||
*/
|
||||
u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
|
||||
int flags = pMem->flags;
|
||||
@@ -3494,6 +3506,7 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
|
||||
*pLen = n;
|
||||
return ((n*2) + 12 + ((flags&MEM_Str)!=0));
|
||||
}
|
||||
#endif /* inlined into OP_MakeRecord */
|
||||
|
||||
/*
|
||||
** The sizes for serial types less than 128
|
||||
@@ -3802,7 +3815,7 @@ UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
|
||||
p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
|
||||
if( !p ) return 0;
|
||||
p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
|
||||
assert( pKeyInfo->aSortOrder!=0 );
|
||||
assert( pKeyInfo->aSortFlags!=0 );
|
||||
p->pKeyInfo = pKeyInfo;
|
||||
p->nField = pKeyInfo->nKeyField + 1;
|
||||
return p;
|
||||
@@ -3901,7 +3914,7 @@ static int vdbeRecordCompareDebug(
|
||||
if( szHdr1>98307 ) return SQLITE_CORRUPT;
|
||||
d1 = szHdr1;
|
||||
assert( pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB );
|
||||
assert( pKeyInfo->aSortOrder!=0 );
|
||||
assert( pKeyInfo->aSortFlags!=0 );
|
||||
assert( pKeyInfo->nKeyField>0 );
|
||||
assert( idx1<=szHdr1 || CORRUPT_DB );
|
||||
do{
|
||||
@@ -3932,7 +3945,12 @@ static int vdbeRecordCompareDebug(
|
||||
pKeyInfo->nAllField>i ? pKeyInfo->aColl[i] : 0);
|
||||
if( rc!=0 ){
|
||||
assert( mem1.szMalloc==0 ); /* See comment below */
|
||||
if( pKeyInfo->aSortOrder[i] ){
|
||||
if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL)
|
||||
&& ((mem1.flags & MEM_Null) || (pPKey2->aMem[i].flags & MEM_Null))
|
||||
){
|
||||
rc = -rc;
|
||||
}
|
||||
if( pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC ){
|
||||
rc = -rc; /* Invert the result for DESC sort order. */
|
||||
}
|
||||
goto debugCompareEnd;
|
||||
@@ -4308,7 +4326,7 @@ int sqlite3VdbeRecordCompareWithSkip(
|
||||
VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */
|
||||
assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField
|
||||
|| CORRUPT_DB );
|
||||
assert( pPKey2->pKeyInfo->aSortOrder!=0 );
|
||||
assert( pPKey2->pKeyInfo->aSortFlags!=0 );
|
||||
assert( pPKey2->pKeyInfo->nKeyField>0 );
|
||||
assert( idx1<=szHdr1 || CORRUPT_DB );
|
||||
do{
|
||||
@@ -4431,8 +4449,14 @@ int sqlite3VdbeRecordCompareWithSkip(
|
||||
}
|
||||
|
||||
if( rc!=0 ){
|
||||
if( pPKey2->pKeyInfo->aSortOrder[i] ){
|
||||
rc = -rc;
|
||||
int sortFlags = pPKey2->pKeyInfo->aSortFlags[i];
|
||||
if( sortFlags ){
|
||||
if( (sortFlags & KEYINFO_ORDER_BIGNULL)==0
|
||||
|| ((sortFlags & KEYINFO_ORDER_DESC)
|
||||
!=(serial_type==0 || (pRhs->flags&MEM_Null)))
|
||||
){
|
||||
rc = -rc;
|
||||
}
|
||||
}
|
||||
assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) );
|
||||
assert( mem1.szMalloc==0 ); /* See comment below */
|
||||
@@ -4600,7 +4624,11 @@ static int vdbeRecordCompareString(
|
||||
nCmp = MIN( pPKey2->aMem[0].n, nStr );
|
||||
res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp);
|
||||
|
||||
if( res==0 ){
|
||||
if( res>0 ){
|
||||
res = pPKey2->r2;
|
||||
}else if( res<0 ){
|
||||
res = pPKey2->r1;
|
||||
}else{
|
||||
res = nStr - pPKey2->aMem[0].n;
|
||||
if( res==0 ){
|
||||
if( pPKey2->nField>1 ){
|
||||
@@ -4614,10 +4642,6 @@ static int vdbeRecordCompareString(
|
||||
}else{
|
||||
res = pPKey2->r1;
|
||||
}
|
||||
}else if( res>0 ){
|
||||
res = pPKey2->r2;
|
||||
}else{
|
||||
res = pPKey2->r1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4649,7 +4673,10 @@ RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
|
||||
** header size is (12*5 + 1 + 1) bytes. */
|
||||
if( p->pKeyInfo->nAllField<=13 ){
|
||||
int flags = p->aMem[0].flags;
|
||||
if( p->pKeyInfo->aSortOrder[0] ){
|
||||
if( p->pKeyInfo->aSortFlags[0] ){
|
||||
if( p->pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL ){
|
||||
return sqlite3VdbeRecordCompare;
|
||||
}
|
||||
p->r1 = 1;
|
||||
p->r2 = -1;
|
||||
}else{
|
||||
@@ -4898,7 +4925,7 @@ void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
|
||||
** features such as 'now'.
|
||||
*/
|
||||
int sqlite3NotPureFunc(sqlite3_context *pCtx){
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
if( pCtx->pVdbe==0 ) return 1;
|
||||
#endif
|
||||
if( pCtx->pVdbe->aOp[pCtx->iOp].opcode==OP_PureFunc ){
|
||||
@@ -4995,7 +5022,7 @@ void sqlite3VdbePreUpdateHook(
|
||||
preupdate.keyinfo.db = db;
|
||||
preupdate.keyinfo.enc = ENC(db);
|
||||
preupdate.keyinfo.nKeyField = pTab->nCol;
|
||||
preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder;
|
||||
preupdate.keyinfo.aSortFlags = (u8*)&fakeSortOrder;
|
||||
preupdate.iKey1 = iKey1;
|
||||
preupdate.iKey2 = iKey2;
|
||||
preupdate.pTab = pTab;
|
||||
|
||||
+2
-1
@@ -355,11 +355,12 @@ int sqlite3_blob_close(sqlite3_blob *pBlob){
|
||||
sqlite3 *db;
|
||||
|
||||
if( p ){
|
||||
sqlite3_stmt *pStmt = p->pStmt;
|
||||
db = p->db;
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
rc = sqlite3_finalize(p->pStmt);
|
||||
sqlite3DbFree(db, p);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
rc = sqlite3_finalize(pStmt);
|
||||
}else{
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
|
||||
+9
-58
@@ -1303,7 +1303,7 @@ struct ValueNewStat4Ctx {
|
||||
** an sqlite3_value within the UnpackedRecord.a[] array.
|
||||
*/
|
||||
static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
if( p ){
|
||||
UnpackedRecord *pRec = p->ppRec[0];
|
||||
|
||||
@@ -1339,7 +1339,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
|
||||
}
|
||||
#else
|
||||
UNUSED_PARAMETER(p);
|
||||
#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */
|
||||
#endif /* defined(SQLITE_ENABLE_STAT4) */
|
||||
return sqlite3ValueNew(db);
|
||||
}
|
||||
|
||||
@@ -1363,7 +1363,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
|
||||
** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to
|
||||
** NULL and an SQLite error code returned.
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
static int valueFromFunction(
|
||||
sqlite3 *db, /* The database connection */
|
||||
Expr *p, /* The expression to evaluate */
|
||||
@@ -1446,7 +1446,7 @@ static int valueFromFunction(
|
||||
}
|
||||
#else
|
||||
# define valueFromFunction(a,b,c,d,e,f) SQLITE_OK
|
||||
#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */
|
||||
#endif /* defined(SQLITE_ENABLE_STAT4) */
|
||||
|
||||
/*
|
||||
** Extract a value from the supplied expression in the manner described
|
||||
@@ -1475,7 +1475,7 @@ static int valueFromExpr(
|
||||
|
||||
assert( pExpr!=0 );
|
||||
while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
|
||||
#if defined(SQLITE_ENABLE_STAT3_OR_STAT4)
|
||||
#if defined(SQLITE_ENABLE_STAT4)
|
||||
if( op==TK_REGISTER ) op = pExpr->op2;
|
||||
#else
|
||||
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
|
||||
@@ -1568,7 +1568,7 @@ static int valueFromExpr(
|
||||
0, SQLITE_DYNAMIC);
|
||||
}
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
else if( op==TK_FUNCTION && pCtx!=0 ){
|
||||
rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx);
|
||||
}
|
||||
@@ -1585,13 +1585,13 @@ static int valueFromExpr(
|
||||
return rc;
|
||||
|
||||
no_mem:
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
if( pCtx==0 || pCtx->pParse->nErr==0 )
|
||||
#endif
|
||||
sqlite3OomFault(db);
|
||||
sqlite3DbFree(db, zVal);
|
||||
assert( *ppVal==0 );
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
if( pCtx==0 ) sqlite3ValueFree(pVal);
|
||||
#else
|
||||
assert( pCtx==0 ); sqlite3ValueFree(pVal);
|
||||
@@ -1619,56 +1619,7 @@ int sqlite3ValueFromExpr(
|
||||
return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
/*
|
||||
** The implementation of the sqlite_record() function. This function accepts
|
||||
** a single argument of any type. The return value is a formatted database
|
||||
** record (a blob) containing the argument value.
|
||||
**
|
||||
** This is used to convert the value stored in the 'sample' column of the
|
||||
** sqlite_stat3 table to the record format SQLite uses internally.
|
||||
*/
|
||||
static void recordFunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
const int file_format = 1;
|
||||
u32 iSerial; /* Serial type */
|
||||
int nSerial; /* Bytes of space for iSerial as varint */
|
||||
u32 nVal; /* Bytes of space required for argv[0] */
|
||||
int nRet;
|
||||
sqlite3 *db;
|
||||
u8 *aRet;
|
||||
|
||||
UNUSED_PARAMETER( argc );
|
||||
iSerial = sqlite3VdbeSerialType(argv[0], file_format, &nVal);
|
||||
nSerial = sqlite3VarintLen(iSerial);
|
||||
db = sqlite3_context_db_handle(context);
|
||||
|
||||
nRet = 1 + nSerial + nVal;
|
||||
aRet = sqlite3DbMallocRawNN(db, nRet);
|
||||
if( aRet==0 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
}else{
|
||||
aRet[0] = nSerial+1;
|
||||
putVarint32(&aRet[1], iSerial);
|
||||
sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial);
|
||||
sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT);
|
||||
sqlite3DbFreeNN(db, aRet);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Register built-in functions used to help read ANALYZE data.
|
||||
*/
|
||||
void sqlite3AnalyzeFunctions(void){
|
||||
static FuncDef aAnalyzeTableFuncs[] = {
|
||||
FUNCTION(sqlite_record, 1, 0, 0, recordFunc),
|
||||
};
|
||||
sqlite3InsertBuiltinFuncs(aAnalyzeTableFuncs, ArraySize(aAnalyzeTableFuncs));
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
/*
|
||||
** Attempt to extract a value from pExpr and use it to construct *ppVal.
|
||||
**
|
||||
|
||||
+10
-4
@@ -829,7 +829,8 @@ static int vdbeSorterCompareText(
|
||||
);
|
||||
}
|
||||
}else{
|
||||
if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
|
||||
assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) );
|
||||
if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){
|
||||
res = res * -1;
|
||||
}
|
||||
}
|
||||
@@ -897,7 +898,8 @@ static int vdbeSorterCompareInt(
|
||||
pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
|
||||
);
|
||||
}
|
||||
}else if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
|
||||
}else if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){
|
||||
assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) );
|
||||
res = res * -1;
|
||||
}
|
||||
|
||||
@@ -1012,6 +1014,7 @@ int sqlite3VdbeSorterInit(
|
||||
|
||||
if( pKeyInfo->nAllField<13
|
||||
&& (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl)
|
||||
&& (pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL)==0
|
||||
){
|
||||
pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT;
|
||||
}
|
||||
@@ -1728,13 +1731,16 @@ static int vdbeSorterFlushPMA(VdbeSorter *pSorter){
|
||||
rc = vdbeSorterListToPMA(&pSorter->aTask[nWorker], &pSorter->list);
|
||||
}else{
|
||||
/* Launch a background thread for this operation */
|
||||
u8 *aMem = pTask->list.aMemory;
|
||||
void *pCtx = (void*)pTask;
|
||||
u8 *aMem;
|
||||
void *pCtx;
|
||||
|
||||
assert( pTask!=0 );
|
||||
assert( pTask->pThread==0 && pTask->bDone==0 );
|
||||
assert( pTask->list.pList==0 );
|
||||
assert( pTask->list.aMemory==0 || pSorter->list.aMemory!=0 );
|
||||
|
||||
aMem = pTask->list.aMemory;
|
||||
pCtx = (void*)pTask;
|
||||
pSorter->iPrev = (u8)(pTask - pSorter->aTask);
|
||||
pTask->list = pSorter->list;
|
||||
pSorter->list.pList = 0;
|
||||
|
||||
+64
-14
@@ -32,6 +32,9 @@ struct VtabCtx {
|
||||
** Construct and install a Module object for a virtual table. When this
|
||||
** routine is called, it is guaranteed that all appropriate locks are held
|
||||
** and the module is not already part of the connection.
|
||||
**
|
||||
** If there already exists a module with zName, replace it with the new one.
|
||||
** If pModule==0, then delete the module zName if it exists.
|
||||
*/
|
||||
Module *sqlite3VtabCreateModule(
|
||||
sqlite3 *db, /* Database in which module is registered */
|
||||
@@ -41,25 +44,36 @@ Module *sqlite3VtabCreateModule(
|
||||
void (*xDestroy)(void *) /* Module destructor function */
|
||||
){
|
||||
Module *pMod;
|
||||
int nName = sqlite3Strlen30(zName);
|
||||
pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1);
|
||||
if( pMod==0 ){
|
||||
sqlite3OomFault(db);
|
||||
Module *pDel;
|
||||
char *zCopy;
|
||||
if( pModule==0 ){
|
||||
zCopy = (char*)zName;
|
||||
pMod = 0;
|
||||
}else{
|
||||
Module *pDel;
|
||||
char *zCopy = (char *)(&pMod[1]);
|
||||
int nName = sqlite3Strlen30(zName);
|
||||
pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1);
|
||||
if( pMod==0 ){
|
||||
sqlite3OomFault(db);
|
||||
return 0;
|
||||
}
|
||||
zCopy = (char *)(&pMod[1]);
|
||||
memcpy(zCopy, zName, nName+1);
|
||||
pMod->zName = zCopy;
|
||||
pMod->pModule = pModule;
|
||||
pMod->pAux = pAux;
|
||||
pMod->xDestroy = xDestroy;
|
||||
pMod->pEpoTab = 0;
|
||||
pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
|
||||
assert( pDel==0 || pDel==pMod );
|
||||
if( pDel ){
|
||||
pMod->nRefModule = 1;
|
||||
}
|
||||
pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
|
||||
if( pDel ){
|
||||
if( pDel==pMod ){
|
||||
sqlite3OomFault(db);
|
||||
sqlite3DbFree(db, pDel);
|
||||
pMod = 0;
|
||||
}else{
|
||||
sqlite3VtabEponymousTableClear(db, pDel);
|
||||
sqlite3VtabModuleUnref(db, pDel);
|
||||
}
|
||||
}
|
||||
return pMod;
|
||||
@@ -80,11 +94,7 @@ static int createModule(
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
if( sqlite3HashFind(&db->aModule, zName) ){
|
||||
rc = SQLITE_MISUSE_BKPT;
|
||||
}else{
|
||||
(void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy);
|
||||
}
|
||||
(void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy);
|
||||
rc = sqlite3ApiExit(db, rc);
|
||||
if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
@@ -123,6 +133,44 @@ int sqlite3_create_module_v2(
|
||||
return createModule(db, zName, pModule, pAux, xDestroy);
|
||||
}
|
||||
|
||||
/*
|
||||
** External API to drop all virtual-table modules, except those named
|
||||
** on the azNames list.
|
||||
*/
|
||||
int sqlite3_drop_modules(sqlite3 *db, const char** azNames){
|
||||
HashElem *pThis, *pNext;
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
for(pThis=sqliteHashFirst(&db->aModule); pThis; pThis=pNext){
|
||||
Module *pMod = (Module*)sqliteHashData(pThis);
|
||||
pNext = sqliteHashNext(pThis);
|
||||
if( azNames ){
|
||||
int ii;
|
||||
for(ii=0; azNames[ii]!=0 && strcmp(azNames[ii],pMod->zName)!=0; ii++){}
|
||||
if( azNames[ii]!=0 ) continue;
|
||||
}
|
||||
createModule(db, pMod->zName, 0, 0, 0);
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Decrement the reference count on a Module object. Destroy the
|
||||
** module when the reference count reaches zero.
|
||||
*/
|
||||
void sqlite3VtabModuleUnref(sqlite3 *db, Module *pMod){
|
||||
assert( pMod->nRefModule>0 );
|
||||
pMod->nRefModule--;
|
||||
if( pMod->nRefModule==0 ){
|
||||
if( pMod->xDestroy ){
|
||||
pMod->xDestroy(pMod->pAux);
|
||||
}
|
||||
assert( pMod->pEpoTab==0 );
|
||||
sqlite3DbFree(db, pMod);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Lock the virtual table so that it cannot be disconnected.
|
||||
** Locks nest. Every lock should have a corresponding unlock.
|
||||
@@ -162,6 +210,7 @@ void sqlite3VtabUnlock(VTable *pVTab){
|
||||
pVTab->nRef--;
|
||||
if( pVTab->nRef==0 ){
|
||||
sqlite3_vtab *p = pVTab->pVtab;
|
||||
sqlite3VtabModuleUnref(pVTab->db, pVTab->pMod);
|
||||
if( p ){
|
||||
p->pModule->xDisconnect(p);
|
||||
}
|
||||
@@ -566,6 +615,7 @@ static int vtabCallConstructor(
|
||||
** the sqlite3_vtab object if successful. */
|
||||
memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0]));
|
||||
pVTable->pVtab->pModule = pMod->pModule;
|
||||
pMod->nRefModule++;
|
||||
pVTable->nRef = 1;
|
||||
if( sCtx.bDeclared==0 ){
|
||||
const char *zFormat = "vtable constructor did not declare schema: %s";
|
||||
|
||||
@@ -3478,6 +3478,7 @@ int sqlite3WalFrames(
|
||||
if( rc ) return rc;
|
||||
iOffset += szFrame;
|
||||
nExtra++;
|
||||
assert( pLast!=0 );
|
||||
}
|
||||
}
|
||||
if( bSync ){
|
||||
@@ -3510,6 +3511,7 @@ int sqlite3WalFrames(
|
||||
iFrame++;
|
||||
rc = walIndexAppend(pWal, iFrame, p->pgno);
|
||||
}
|
||||
assert( pLast!=0 || nExtra==0 );
|
||||
while( rc==SQLITE_OK && nExtra>0 ){
|
||||
iFrame++;
|
||||
nExtra--;
|
||||
|
||||
+28
-10
@@ -25,9 +25,22 @@
|
||||
static int walkWindowList(Walker *pWalker, Window *pList){
|
||||
Window *pWin;
|
||||
for(pWin=pList; pWin; pWin=pWin->pNextWin){
|
||||
if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
|
||||
if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
|
||||
if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
|
||||
int rc;
|
||||
rc = sqlite3WalkExprList(pWalker, pWin->pOrderBy);
|
||||
if( rc ) return WRC_Abort;
|
||||
rc = sqlite3WalkExprList(pWalker, pWin->pPartition);
|
||||
if( rc ) return WRC_Abort;
|
||||
rc = sqlite3WalkExpr(pWalker, pWin->pFilter);
|
||||
if( rc ) return WRC_Abort;
|
||||
|
||||
/* The next two are purely for calls to sqlite3RenameExprUnmap()
|
||||
** within sqlite3WindowOffsetExpr(). Because of constraints imposed
|
||||
** by sqlite3WindowOffsetExpr(), they can never fail. The results do
|
||||
** not matter anyhow. */
|
||||
rc = sqlite3WalkExpr(pWalker, pWin->pStart);
|
||||
if( NEVER(rc) ) return WRC_Abort;
|
||||
rc = sqlite3WalkExpr(pWalker, pWin->pEnd);
|
||||
if( NEVER(rc) ) return WRC_Abort;
|
||||
}
|
||||
return WRC_Continue;
|
||||
}
|
||||
@@ -63,18 +76,22 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
|
||||
if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
|
||||
assert( pExpr->x.pList==0 || pExpr->pRight==0 );
|
||||
if( pExpr->pRight ){
|
||||
assert( !ExprHasProperty(pExpr, EP_WinFunc) );
|
||||
pExpr = pExpr->pRight;
|
||||
continue;
|
||||
}else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
|
||||
assert( !ExprHasProperty(pExpr, EP_WinFunc) );
|
||||
if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
|
||||
}else if( pExpr->x.pList ){
|
||||
if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
|
||||
}
|
||||
}else{
|
||||
if( pExpr->x.pList ){
|
||||
if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
if( ExprHasProperty(pExpr, EP_WinFunc) ){
|
||||
if( walkWindowList(pWalker, pExpr->y.pWin) ) return WRC_Abort;
|
||||
}
|
||||
if( ExprHasProperty(pExpr, EP_WinFunc) ){
|
||||
if( walkWindowList(pWalker, pExpr->y.pWin) ) return WRC_Abort;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -116,8 +133,9 @@ int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){
|
||||
{
|
||||
Parse *pParse = pWalker->pParse;
|
||||
if( pParse && IN_RENAME_OBJECT ){
|
||||
/* The following may return WRC_Abort if there are unresolvable
|
||||
** symbols (e.g. a table that does not exist) in a window definition. */
|
||||
int rc = walkWindowList(pWalker, p->pWinDefn);
|
||||
assert( rc==WRC_Continue );
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
+76
-38
@@ -253,7 +253,8 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
|
||||
){
|
||||
if( (pTerm->eOperator & WO_EQUIV)!=0
|
||||
&& pScan->nEquiv<ArraySize(pScan->aiCur)
|
||||
&& (pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight))->op==TK_COLUMN
|
||||
&& (pX = sqlite3ExprSkipCollateAndLikely(pTerm->pExpr->pRight))->op
|
||||
==TK_COLUMN
|
||||
){
|
||||
int j;
|
||||
for(j=0; j<pScan->nEquiv; j++){
|
||||
@@ -449,7 +450,7 @@ static int findIndexCol(
|
||||
const char *zColl = pIdx->azColl[iCol];
|
||||
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
Expr *p = sqlite3ExprSkipCollate(pList->a[i].pExpr);
|
||||
Expr *p = sqlite3ExprSkipCollateAndLikely(pList->a[i].pExpr);
|
||||
if( p->op==TK_COLUMN
|
||||
&& p->iColumn==pIdx->aiColumn[iCol]
|
||||
&& p->iTable==iBase
|
||||
@@ -513,7 +514,7 @@ static int isDistinctRedundant(
|
||||
** current SELECT is a correlated sub-query.
|
||||
*/
|
||||
for(i=0; i<pDistinct->nExpr; i++){
|
||||
Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
|
||||
Expr *p = sqlite3ExprSkipCollateAndLikely(pDistinct->a[i].pExpr);
|
||||
if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1;
|
||||
}
|
||||
|
||||
@@ -933,6 +934,7 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
for(i=0; i<n; i++){
|
||||
Expr *pExpr = pOrderBy->a[i].pExpr;
|
||||
if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break;
|
||||
if( pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL ) break;
|
||||
}
|
||||
if( i==n){
|
||||
nOrderBy = n;
|
||||
@@ -1031,7 +1033,7 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
for(i=0; i<nOrderBy; i++){
|
||||
Expr *pExpr = pOrderBy->a[i].pExpr;
|
||||
pIdxOrderBy[i].iColumn = pExpr->iColumn;
|
||||
pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder;
|
||||
pIdxOrderBy[i].desc = pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC;
|
||||
}
|
||||
|
||||
*pmNoOmit = mNoOmit;
|
||||
@@ -1077,7 +1079,7 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
|
||||
}
|
||||
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
/*
|
||||
** Estimate the location of a particular key among all keys in an
|
||||
** index. Store the results in aStat as follows:
|
||||
@@ -1270,7 +1272,7 @@ static int whereKeyStats(
|
||||
pRec->nField = nField;
|
||||
return i;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
|
||||
#endif /* SQLITE_ENABLE_STAT4 */
|
||||
|
||||
/*
|
||||
** If it is not NULL, pTerm is a term that provides an upper or lower
|
||||
@@ -1296,7 +1298,7 @@ static LogEst whereRangeAdjust(WhereTerm *pTerm, LogEst nNew){
|
||||
}
|
||||
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
/*
|
||||
** Return the affinity for a single column of an index.
|
||||
*/
|
||||
@@ -1305,12 +1307,13 @@ char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){
|
||||
if( !pIdx->zColAff ){
|
||||
if( sqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB;
|
||||
}
|
||||
assert( pIdx->zColAff[iCol]!=0 );
|
||||
return pIdx->zColAff[iCol];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
/*
|
||||
** This function is called to estimate the number of rows visited by a
|
||||
** range-scan on a skip-scan index. For example:
|
||||
@@ -1416,7 +1419,7 @@ static int whereRangeSkipScanEst(
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
|
||||
#endif /* SQLITE_ENABLE_STAT4 */
|
||||
|
||||
/*
|
||||
** This function is used to estimate the number of rows that will be visited
|
||||
@@ -1469,12 +1472,12 @@ static int whereRangeScanEst(
|
||||
int nOut = pLoop->nOut;
|
||||
LogEst nNew;
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
Index *p = pLoop->u.btree.pIndex;
|
||||
int nEq = pLoop->u.btree.nEq;
|
||||
|
||||
if( p->nSample>0 && nEq<p->nSampleCol
|
||||
&& OptimizationEnabled(pParse->db, SQLITE_Stat34)
|
||||
if( p->nSample>0 && ALWAYS(nEq<p->nSampleCol)
|
||||
&& OptimizationEnabled(pParse->db, SQLITE_Stat4)
|
||||
){
|
||||
if( nEq==pBuilder->nRecValid ){
|
||||
UnpackedRecord *pRec = pBuilder->pRec;
|
||||
@@ -1572,7 +1575,7 @@ static int whereRangeScanEst(
|
||||
/* TUNING: If both iUpper and iLower are derived from the same
|
||||
** sample, then assume they are 4x more selective. This brings
|
||||
** the estimated selectivity more in line with what it would be
|
||||
** if estimated without the use of STAT3/4 tables. */
|
||||
** if estimated without the use of STAT4 tables. */
|
||||
if( iLwrIdx==iUprIdx ) nNew -= 20; assert( 20==sqlite3LogEst(4) );
|
||||
}else{
|
||||
nNew = 10; assert( 10==sqlite3LogEst(2) );
|
||||
@@ -1621,12 +1624,12 @@ static int whereRangeScanEst(
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
/*
|
||||
** Estimate the number of rows that will be returned based on
|
||||
** an equality constraint x=VALUE and where that VALUE occurs in
|
||||
** the histogram data. This only works when x is the left-most
|
||||
** column of an index and sqlite_stat3 histogram data is available
|
||||
** column of an index and sqlite_stat4 histogram data is available
|
||||
** for that index. When pExpr==NULL that means the constraint is
|
||||
** "x IS NULL" instead of "x=VALUE".
|
||||
**
|
||||
@@ -1684,9 +1687,9 @@ static int whereEqualScanEst(
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
|
||||
#endif /* SQLITE_ENABLE_STAT4 */
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
/*
|
||||
** Estimate the number of rows that will be returned based on
|
||||
** an IN constraint where the right-hand side of the IN operator
|
||||
@@ -1733,7 +1736,7 @@ static int whereInScanEst(
|
||||
assert( pBuilder->nRecValid==nRecValid );
|
||||
return rc;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
|
||||
#endif /* SQLITE_ENABLE_STAT4 */
|
||||
|
||||
|
||||
#ifdef WHERETRACE_ENABLED
|
||||
@@ -2270,6 +2273,7 @@ static void whereLoopOutputAdjust(
|
||||
|
||||
assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
|
||||
for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){
|
||||
assert( pTerm!=0 );
|
||||
if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break;
|
||||
if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue;
|
||||
if( (pTerm->prereqAll & notAllowed)!=0 ) continue;
|
||||
@@ -2453,7 +2457,7 @@ static int whereLoopAddBtreeIndex(
|
||||
LogEst rCostIdx;
|
||||
LogEst nOutUnadjusted; /* nOut before IN() and WHERE adjustments */
|
||||
int nIn = 0;
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
int nRecValid = pBuilder->nRecValid;
|
||||
#endif
|
||||
if( (eOp==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0)
|
||||
@@ -2611,7 +2615,7 @@ static int whereLoopAddBtreeIndex(
|
||||
** the value of pNew->nOut to account for pTerm (but not nIn/nInMul). */
|
||||
assert( pNew->nOut==saved_nOut );
|
||||
if( pNew->wsFlags & WHERE_COLUMN_RANGE ){
|
||||
/* Adjust nOut using stat3/stat4 data. Or, if there is no stat3/stat4
|
||||
/* Adjust nOut using stat4 data. Or, if there is no stat4
|
||||
** data, using some other estimate. */
|
||||
whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew);
|
||||
}else{
|
||||
@@ -2625,13 +2629,13 @@ static int whereLoopAddBtreeIndex(
|
||||
pNew->nOut += pTerm->truthProb;
|
||||
pNew->nOut -= nIn;
|
||||
}else{
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
tRowcnt nOut = 0;
|
||||
if( nInMul==0
|
||||
&& pProbe->nSample
|
||||
&& pNew->u.btree.nEq<=pProbe->nSampleCol
|
||||
&& ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
|
||||
&& OptimizationEnabled(db, SQLITE_Stat34)
|
||||
&& OptimizationEnabled(db, SQLITE_Stat4)
|
||||
){
|
||||
Expr *pExpr = pTerm->pExpr;
|
||||
if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){
|
||||
@@ -2668,6 +2672,7 @@ static int whereLoopAddBtreeIndex(
|
||||
** it to pNew->rRun, which is currently set to the cost of the index
|
||||
** seek only. Then, if this is a non-covering index, add the cost of
|
||||
** visiting the rows in the main table. */
|
||||
assert( pSrc->pTab->szTabRow>0 );
|
||||
rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
|
||||
pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx);
|
||||
if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
|
||||
@@ -2693,7 +2698,7 @@ static int whereLoopAddBtreeIndex(
|
||||
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
|
||||
}
|
||||
pNew->nOut = saved_nOut;
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
pBuilder->nRecValid = nRecValid;
|
||||
#endif
|
||||
}
|
||||
@@ -2766,7 +2771,7 @@ static int indexMightHelpWithOrderBy(
|
||||
if( pIndex->bUnordered ) return 0;
|
||||
if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0;
|
||||
for(ii=0; ii<pOB->nExpr; ii++){
|
||||
Expr *pExpr = sqlite3ExprSkipCollate(pOB->a[ii].pExpr);
|
||||
Expr *pExpr = sqlite3ExprSkipCollateAndLikely(pOB->a[ii].pExpr);
|
||||
if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){
|
||||
if( pExpr->iColumn<0 ) return 1;
|
||||
for(jj=0; jj<pIndex->nKeyCol; jj++){
|
||||
@@ -3066,7 +3071,7 @@ static int whereLoopAddBtree(
|
||||
** plan */
|
||||
pTab->tabFlags |= TF_StatsUsed;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
sqlite3Stat4ProbeFree(pBuilder->pRec);
|
||||
pBuilder->nRecValid = 0;
|
||||
pBuilder->pRec = 0;
|
||||
@@ -3694,8 +3699,8 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
|
||||
if( pLoop->u.vtab.isOrdered ) obSat = obDone;
|
||||
break;
|
||||
}else{
|
||||
pLoop->u.btree.nIdxCol = 0;
|
||||
}else if( wctrlFlags & WHERE_DISTINCTBY ){
|
||||
pLoop->u.btree.nDistinctCol = 0;
|
||||
}
|
||||
iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor;
|
||||
|
||||
@@ -3706,7 +3711,7 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
*/
|
||||
for(i=0; i<nOrderBy; i++){
|
||||
if( MASKBIT(i) & obSat ) continue;
|
||||
pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
|
||||
pOBExpr = sqlite3ExprSkipCollateAndLikely(pOrderBy->a[i].pExpr);
|
||||
if( pOBExpr->op!=TK_COLUMN ) continue;
|
||||
if( pOBExpr->iTable!=iCur ) continue;
|
||||
pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
|
||||
@@ -3743,7 +3748,8 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) );
|
||||
assert( pIndex->aiColumn[nColumn-1]==XN_ROWID
|
||||
|| !HasRowid(pIndex->pTable));
|
||||
isOrderDistinct = IsUniqueIndex(pIndex);
|
||||
isOrderDistinct = IsUniqueIndex(pIndex)
|
||||
&& (pLoop->wsFlags & WHERE_SKIPSCAN)==0;
|
||||
}
|
||||
|
||||
/* Loop through all columns of the index and deal with the ones
|
||||
@@ -3761,15 +3767,21 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
u16 eOp = pLoop->aLTerm[j]->eOperator;
|
||||
|
||||
/* Skip over == and IS and ISNULL terms. (Also skip IN terms when
|
||||
** doing WHERE_ORDERBY_LIMIT processing).
|
||||
** doing WHERE_ORDERBY_LIMIT processing). Except, IS and ISNULL
|
||||
** terms imply that the index is not UNIQUE NOT NULL in which case
|
||||
** the loop need to be marked as not order-distinct because it can
|
||||
** have repeated NULL rows.
|
||||
**
|
||||
** If the current term is a column of an ((?,?) IN (SELECT...))
|
||||
** expression for which the SELECT returns more than one column,
|
||||
** check that it is the only column used by this loop. Otherwise,
|
||||
** if it is one of two or more, none of the columns can be
|
||||
** considered to match an ORDER BY term. */
|
||||
** considered to match an ORDER BY term.
|
||||
*/
|
||||
if( (eOp & eqOpMask)!=0 ){
|
||||
if( eOp & WO_ISNULL ){
|
||||
if( eOp & (WO_ISNULL|WO_IS) ){
|
||||
testcase( eOp & WO_ISNULL );
|
||||
testcase( eOp & WO_IS );
|
||||
testcase( isOrderDistinct );
|
||||
isOrderDistinct = 0;
|
||||
}
|
||||
@@ -3795,7 +3807,7 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
*/
|
||||
if( pIndex ){
|
||||
iColumn = pIndex->aiColumn[j];
|
||||
revIdx = pIndex->aSortOrder[j];
|
||||
revIdx = pIndex->aSortOrder[j] & KEYINFO_ORDER_DESC;
|
||||
if( iColumn==pIndex->pTable->iPKey ) iColumn = XN_ROWID;
|
||||
}else{
|
||||
iColumn = XN_ROWID;
|
||||
@@ -3819,7 +3831,7 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
isMatch = 0;
|
||||
for(i=0; bOnce && i<nOrderBy; i++){
|
||||
if( MASKBIT(i) & obSat ) continue;
|
||||
pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
|
||||
pOBExpr = sqlite3ExprSkipCollateAndLikely(pOrderBy->a[i].pExpr);
|
||||
testcase( wctrlFlags & WHERE_GROUPBY );
|
||||
testcase( wctrlFlags & WHERE_DISTINCTBY );
|
||||
if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
|
||||
@@ -3837,7 +3849,9 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
|
||||
if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
|
||||
}
|
||||
pLoop->u.btree.nIdxCol = j+1;
|
||||
if( wctrlFlags & WHERE_DISTINCTBY ){
|
||||
pLoop->u.btree.nDistinctCol = j+1;
|
||||
}
|
||||
isMatch = 1;
|
||||
break;
|
||||
}
|
||||
@@ -3845,13 +3859,22 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
/* Make sure the sort order is compatible in an ORDER BY clause.
|
||||
** Sort order is irrelevant for a GROUP BY clause. */
|
||||
if( revSet ){
|
||||
if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0;
|
||||
if( (rev ^ revIdx)!=(pOrderBy->a[i].sortFlags&KEYINFO_ORDER_DESC) ){
|
||||
isMatch = 0;
|
||||
}
|
||||
}else{
|
||||
rev = revIdx ^ pOrderBy->a[i].sortOrder;
|
||||
rev = revIdx ^ (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC);
|
||||
if( rev ) *pRevMask |= MASKBIT(iLoop);
|
||||
revSet = 1;
|
||||
}
|
||||
}
|
||||
if( isMatch && (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL) ){
|
||||
if( j==pLoop->u.btree.nEq ){
|
||||
pLoop->wsFlags |= WHERE_BIGNULL_SORT;
|
||||
}else{
|
||||
isMatch = 0;
|
||||
}
|
||||
}
|
||||
if( isMatch ){
|
||||
if( iColumn==XN_ROWID ){
|
||||
testcase( distinctColumns==0 );
|
||||
@@ -4765,6 +4788,16 @@ WhereInfo *sqlite3WhereBegin(
|
||||
sqlite3DebugPrintf(", limit: %d", iAuxArg);
|
||||
}
|
||||
sqlite3DebugPrintf(")\n");
|
||||
if( sqlite3WhereTrace & 0x100 ){
|
||||
Select sSelect;
|
||||
memset(&sSelect, 0, sizeof(sSelect));
|
||||
sSelect.selFlags = SF_WhereBegin;
|
||||
sSelect.pSrc = pTabList;
|
||||
sSelect.pWhere = pWhere;
|
||||
sSelect.pOrderBy = pOrderBy;
|
||||
sSelect.pEList = pResultSet;
|
||||
sqlite3TreeViewSelect(0, &sSelect, 0);
|
||||
}
|
||||
}
|
||||
if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
|
||||
sqlite3WhereClausePrint(sWLB.pWC);
|
||||
@@ -5041,6 +5074,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
sqlite3VdbeSetP4KeyInfo(pParse, pIx);
|
||||
if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0
|
||||
&& (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0
|
||||
&& (pLoop->wsFlags & WHERE_BIGNULL_SORT)==0
|
||||
&& (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0
|
||||
&& pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED
|
||||
){
|
||||
@@ -5158,7 +5192,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
&& i==pWInfo->nLevel-1 /* Ticket [ef9318757b152e3] 2017-10-21 */
|
||||
&& (pLoop->wsFlags & WHERE_INDEXED)!=0
|
||||
&& (pIdx = pLoop->u.btree.pIndex)->hasStat1
|
||||
&& (n = pLoop->u.btree.nIdxCol)>0
|
||||
&& (n = pLoop->u.btree.nDistinctCol)>0
|
||||
&& pIdx->aiRowLogEst[n]>=36
|
||||
){
|
||||
int r1 = pParse->nMem+1;
|
||||
@@ -5182,6 +5216,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
VdbeCoverageIf(v, pLevel->op==OP_Next);
|
||||
VdbeCoverageIf(v, pLevel->op==OP_Prev);
|
||||
VdbeCoverageIf(v, pLevel->op==OP_VNext);
|
||||
if( pLevel->regBignull ){
|
||||
sqlite3VdbeResolveLabel(v, pLevel->addrBignull);
|
||||
sqlite3VdbeAddOp2(v, OP_IfNotZero, pLevel->regBignull, pLevel->p2-1);
|
||||
}
|
||||
#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
|
||||
if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
|
||||
#endif
|
||||
|
||||
+8
-5
@@ -71,13 +71,15 @@ struct WhereLevel {
|
||||
int addrCont; /* Jump here to continue with the next loop cycle */
|
||||
int addrFirst; /* First instruction of interior of the loop */
|
||||
int addrBody; /* Beginning of the body of this loop */
|
||||
int regBignull; /* big-null flag reg. True if a NULL-scan is needed */
|
||||
int addrBignull; /* Jump here for next part of big-null scan */
|
||||
#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
|
||||
u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */
|
||||
int addrLikeRep; /* LIKE range processing address */
|
||||
#endif
|
||||
u8 iFrom; /* Which entry in the FROM clause */
|
||||
u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */
|
||||
int p1, p2; /* Operands of the opcode used to ends the loop */
|
||||
int p1, p2; /* Operands of the opcode used to end the loop */
|
||||
union { /* Information that depends on pWLoop->wsFlags */
|
||||
struct {
|
||||
int nIn; /* Number of entries in aInLoop[] */
|
||||
@@ -128,7 +130,7 @@ struct WhereLoop {
|
||||
u16 nEq; /* Number of equality constraints */
|
||||
u16 nBtm; /* Size of BTM vector */
|
||||
u16 nTop; /* Size of TOP vector */
|
||||
u16 nIdxCol; /* Index column used for ORDER BY */
|
||||
u16 nDistinctCol; /* Index columns used to sort for DISTINCT */
|
||||
Index *pIndex; /* Index used, or NULL */
|
||||
} btree;
|
||||
struct { /* Information for virtual tables */
|
||||
@@ -279,10 +281,10 @@ struct WhereTerm {
|
||||
#define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */
|
||||
#define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */
|
||||
#define TERM_OR_OK 0x40 /* Used during OR-clause processing */
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
# define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */
|
||||
#else
|
||||
# define TERM_VNULL 0x00 /* Disabled if not using stat3 */
|
||||
# define TERM_VNULL 0x00 /* Disabled if not using stat4 */
|
||||
#endif
|
||||
#define TERM_LIKEOPT 0x100 /* Virtual terms from the LIKE optimization */
|
||||
#define TERM_LIKECOND 0x200 /* Conditionally this LIKE operator term */
|
||||
@@ -399,7 +401,7 @@ struct WhereLoopBuilder {
|
||||
ExprList *pOrderBy; /* ORDER BY clause */
|
||||
WhereLoop *pNew; /* Template WhereLoop */
|
||||
WhereOrSet *pOrSet; /* Record best loops here, if not NULL */
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
UnpackedRecord *pRec; /* Probe for stat4 (if required) */
|
||||
int nRecValid; /* Number of valid fields currently in pRec */
|
||||
#endif
|
||||
@@ -586,5 +588,6 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);
|
||||
#define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/
|
||||
#define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */
|
||||
#define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */
|
||||
#define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */
|
||||
|
||||
#endif /* !defined(SQLITE_WHEREINT_H) */
|
||||
|
||||
+85
-33
@@ -318,9 +318,9 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
|
||||
** Code an OP_Affinity opcode to apply the column affinity string zAff
|
||||
** to the n registers starting at base.
|
||||
**
|
||||
** As an optimization, SQLITE_AFF_BLOB entries (which are no-ops) at the
|
||||
** beginning and end of zAff are ignored. If all entries in zAff are
|
||||
** SQLITE_AFF_BLOB, then no code gets generated.
|
||||
** As an optimization, SQLITE_AFF_BLOB and SQLITE_AFF_NONE entries (which
|
||||
** are no-ops) at the beginning and end of zAff are ignored. If all entries
|
||||
** in zAff are SQLITE_AFF_BLOB or SQLITE_AFF_NONE, then no code gets generated.
|
||||
**
|
||||
** This routine makes its own copy of zAff so that the caller is free
|
||||
** to modify zAff after this routine returns.
|
||||
@@ -333,15 +333,16 @@ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){
|
||||
}
|
||||
assert( v!=0 );
|
||||
|
||||
/* Adjust base and n to skip over SQLITE_AFF_BLOB entries at the beginning
|
||||
** and end of the affinity string.
|
||||
/* Adjust base and n to skip over SQLITE_AFF_BLOB and SQLITE_AFF_NONE
|
||||
** entries at the beginning and end of the affinity string.
|
||||
*/
|
||||
while( n>0 && zAff[0]==SQLITE_AFF_BLOB ){
|
||||
assert( SQLITE_AFF_NONE<SQLITE_AFF_BLOB );
|
||||
while( n>0 && zAff[0]<=SQLITE_AFF_BLOB ){
|
||||
n--;
|
||||
base++;
|
||||
zAff++;
|
||||
}
|
||||
while( n>1 && zAff[n-1]==SQLITE_AFF_BLOB ){
|
||||
while( n>1 && zAff[n-1]<=SQLITE_AFF_BLOB ){
|
||||
n--;
|
||||
}
|
||||
|
||||
@@ -1116,6 +1117,7 @@ typedef struct IdxExprTrans {
|
||||
static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
|
||||
IdxExprTrans *pX = p->u.pIdxTrans;
|
||||
if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){
|
||||
pExpr->affExpr = sqlite3ExprAffinity(pExpr);
|
||||
pExpr->op = TK_COLUMN;
|
||||
pExpr->iTable = pX->iIdxCur;
|
||||
pExpr->iColumn = pX->iIdxCol;
|
||||
@@ -1548,32 +1550,12 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
u8 bSeekPastNull = 0; /* True to seek past initial nulls */
|
||||
u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */
|
||||
int omitTable; /* True if we use the index only */
|
||||
|
||||
int regBignull = 0; /* big-null flag register */
|
||||
|
||||
pIdx = pLoop->u.btree.pIndex;
|
||||
iIdxCur = pLevel->iIdxCur;
|
||||
assert( nEq>=pLoop->nSkip );
|
||||
|
||||
/* If this loop satisfies a sort order (pOrderBy) request that
|
||||
** was passed to this function to implement a "SELECT min(x) ..."
|
||||
** query, then the caller will only allow the loop to run for
|
||||
** a single iteration. This means that the first row returned
|
||||
** should not have a NULL value stored in 'x'. If column 'x' is
|
||||
** the first one after the nEq equality constraints in the index,
|
||||
** this requires some special handling.
|
||||
*/
|
||||
assert( pWInfo->pOrderBy==0
|
||||
|| pWInfo->pOrderBy->nExpr==1
|
||||
|| (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 );
|
||||
if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0
|
||||
&& pWInfo->nOBSat>0
|
||||
&& (pIdx->nKeyCol>nEq)
|
||||
){
|
||||
assert( pLoop->nSkip==0 );
|
||||
bSeekPastNull = 1;
|
||||
nExtraReg = 1;
|
||||
}
|
||||
|
||||
/* Find any inequality constraint terms for the start and end
|
||||
** of the range.
|
||||
*/
|
||||
@@ -1614,6 +1596,25 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
}
|
||||
assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );
|
||||
|
||||
/* If the WHERE_BIGNULL_SORT flag is set, then index column nEq uses
|
||||
** a non-default "big-null" sort (either ASC NULLS LAST or DESC NULLS
|
||||
** FIRST). In both cases separate ordered scans are made of those
|
||||
** index entries for which the column is null and for those for which
|
||||
** it is not. For an ASC sort, the non-NULL entries are scanned first.
|
||||
** For DESC, NULL entries are scanned first.
|
||||
*/
|
||||
if( (pLoop->wsFlags & (WHERE_TOP_LIMIT|WHERE_BTM_LIMIT))==0
|
||||
&& (pLoop->wsFlags & WHERE_BIGNULL_SORT)!=0
|
||||
){
|
||||
assert( bSeekPastNull==0 && nExtraReg==0 && nBtm==0 && nTop==0 );
|
||||
assert( pRangeEnd==0 && pRangeStart==0 );
|
||||
assert( pLoop->nSkip==0 );
|
||||
nExtraReg = 1;
|
||||
bSeekPastNull = 1;
|
||||
pLevel->regBignull = regBignull = ++pParse->nMem;
|
||||
pLevel->addrBignull = sqlite3VdbeMakeLabel(pParse);
|
||||
}
|
||||
|
||||
/* If we are doing a reverse order scan on an ascending index, or
|
||||
** a forward order scan on a descending index, interchange the
|
||||
** start and end terms (pRangeStart and pRangeEnd).
|
||||
@@ -1636,7 +1637,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
if( zStartAff && nTop ){
|
||||
zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]);
|
||||
}
|
||||
addrNxt = pLevel->addrNxt;
|
||||
addrNxt = (regBignull ? pLevel->addrBignull : pLevel->addrNxt);
|
||||
|
||||
testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
|
||||
testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 );
|
||||
@@ -1670,10 +1671,14 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
}
|
||||
bSeekPastNull = 0;
|
||||
}else if( bSeekPastNull ){
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
|
||||
nConstraint++;
|
||||
startEq = 0;
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
|
||||
start_constraints = 1;
|
||||
nConstraint++;
|
||||
}else if( regBignull ){
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
|
||||
start_constraints = 1;
|
||||
nConstraint++;
|
||||
}
|
||||
codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff);
|
||||
if( pLoop->nSkip>0 && nConstraint==pLoop->nSkip ){
|
||||
@@ -1684,6 +1689,11 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){
|
||||
sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur);
|
||||
}
|
||||
if( regBignull ){
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull);
|
||||
VdbeComment((v, "NULL-scan pass ctr"));
|
||||
}
|
||||
|
||||
op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
|
||||
assert( op!=0 );
|
||||
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
|
||||
@@ -1694,6 +1704,23 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE );
|
||||
VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE );
|
||||
VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT );
|
||||
|
||||
assert( bSeekPastNull==0 || bStopAtNull==0 );
|
||||
if( regBignull ){
|
||||
assert( bSeekPastNull==1 || bStopAtNull==1 );
|
||||
assert( bSeekPastNull==!bStopAtNull );
|
||||
assert( bStopAtNull==startEq );
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2);
|
||||
op = aStartOp[(nConstraint>1)*4 + 2 + bRev];
|
||||
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase,
|
||||
nConstraint-startEq);
|
||||
VdbeCoverage(v);
|
||||
VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind );
|
||||
VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last );
|
||||
VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE );
|
||||
VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE );
|
||||
assert( op==OP_Rewind || op==OP_Last || op==OP_SeekGE || op==OP_SeekLE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Load the value for the inequality constraint at the end of the
|
||||
@@ -1725,8 +1752,10 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
endEq = 1;
|
||||
}
|
||||
}else if( bStopAtNull ){
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
|
||||
endEq = 0;
|
||||
if( regBignull==0 ){
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
|
||||
endEq = 0;
|
||||
}
|
||||
nConstraint++;
|
||||
}
|
||||
sqlite3DbFree(db, zStartAff);
|
||||
@@ -1737,6 +1766,12 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
|
||||
/* Check if the index cursor is past the end of the range. */
|
||||
if( nConstraint ){
|
||||
if( regBignull ){
|
||||
/* Except, skip the end-of-range check while doing the NULL-scan */
|
||||
sqlite3VdbeAddOp2(v, OP_IfNot, regBignull, sqlite3VdbeCurrentAddr(v)+3);
|
||||
VdbeComment((v, "If NULL-scan 2nd pass"));
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
op = aEndOp[bRev*2 + endEq];
|
||||
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
|
||||
testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT );
|
||||
@@ -1744,6 +1779,23 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT );
|
||||
testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE );
|
||||
}
|
||||
if( regBignull ){
|
||||
/* During a NULL-scan, check to see if we have reached the end of
|
||||
** the NULLs */
|
||||
assert( bSeekPastNull==!bStopAtNull );
|
||||
assert( bSeekPastNull+bStopAtNull==1 );
|
||||
assert( nConstraint+bSeekPastNull>0 );
|
||||
sqlite3VdbeAddOp2(v, OP_If, regBignull, sqlite3VdbeCurrentAddr(v)+2);
|
||||
VdbeComment((v, "If NULL-scan 1st pass"));
|
||||
VdbeCoverage(v);
|
||||
op = aEndOp[bRev*2 + bSeekPastNull];
|
||||
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase,
|
||||
nConstraint+bSeekPastNull);
|
||||
testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT );
|
||||
testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE );
|
||||
testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT );
|
||||
testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE );
|
||||
}
|
||||
|
||||
if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){
|
||||
sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1);
|
||||
|
||||
+6
-6
@@ -84,7 +84,7 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
|
||||
}else{
|
||||
pTerm->truthProb = 1;
|
||||
}
|
||||
pTerm->pExpr = sqlite3ExprSkipCollate(p);
|
||||
pTerm->pExpr = sqlite3ExprSkipCollateAndLikely(p);
|
||||
pTerm->wtFlags = wtFlags;
|
||||
pTerm->pWC = pWC;
|
||||
pTerm->iParent = -1;
|
||||
@@ -1381,8 +1381,8 @@ static void exprAnalyze(
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
/* When sqlite_stat3 histogram data is available an operator of the
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
/* When sqlite_stat4 histogram data is available an operator of the
|
||||
** form "x IS NOT NULL" can sometimes be evaluated more efficiently
|
||||
** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a
|
||||
** virtual term of that form.
|
||||
@@ -1393,7 +1393,7 @@ static void exprAnalyze(
|
||||
&& pExpr->pLeft->op==TK_COLUMN
|
||||
&& pExpr->pLeft->iColumn>=0
|
||||
&& !ExprHasProperty(pExpr, EP_FromJoin)
|
||||
&& OptimizationEnabled(db, SQLITE_Stat34)
|
||||
&& OptimizationEnabled(db, SQLITE_Stat4)
|
||||
){
|
||||
Expr *pNewExpr;
|
||||
Expr *pLeft = pExpr->pLeft;
|
||||
@@ -1418,7 +1418,7 @@ static void exprAnalyze(
|
||||
pNewTerm->prereqAll = pTerm->prereqAll;
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
|
||||
#endif /* SQLITE_ENABLE_STAT4 */
|
||||
|
||||
/* Prevent ON clause terms of a LEFT JOIN from being used to drive
|
||||
** an index for tables to the left of the join.
|
||||
@@ -1451,7 +1451,7 @@ static void exprAnalyze(
|
||||
** all terms of the WHERE clause.
|
||||
*/
|
||||
void sqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
|
||||
Expr *pE2 = sqlite3ExprSkipCollate(pExpr);
|
||||
Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pExpr);
|
||||
pWC->op = op;
|
||||
if( pE2==0 ) return;
|
||||
if( pE2->op!=op ){
|
||||
|
||||
+86
-20
@@ -748,6 +748,8 @@ struct WindowRewrite {
|
||||
static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
|
||||
struct WindowRewrite *p = pWalker->u.pRewrite;
|
||||
Parse *pParse = pWalker->pParse;
|
||||
assert( p!=0 );
|
||||
assert( p->pWin!=0 );
|
||||
|
||||
/* If this function is being called from within a scalar sub-select
|
||||
** that used by the SELECT statement being processed, only process
|
||||
@@ -847,6 +849,7 @@ static void selectWindowRewriteEList(
|
||||
Walker sWalker;
|
||||
WindowRewrite sRewrite;
|
||||
|
||||
assert( pWin!=0 );
|
||||
memset(&sWalker, 0, sizeof(Walker));
|
||||
memset(&sRewrite, 0, sizeof(WindowRewrite));
|
||||
|
||||
@@ -885,7 +888,7 @@ static ExprList *exprListAppendList(
|
||||
pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse);
|
||||
}
|
||||
pList = sqlite3ExprListAppend(pParse, pList, pDup);
|
||||
if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
|
||||
if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags;
|
||||
}
|
||||
}
|
||||
return pList;
|
||||
@@ -931,11 +934,14 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
|
||||
** redundant, remove the ORDER BY from the parent SELECT. */
|
||||
pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0);
|
||||
pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy, 1);
|
||||
if( pSort && p->pOrderBy ){
|
||||
if( pSort && p->pOrderBy && p->pOrderBy->nExpr<=pSort->nExpr ){
|
||||
int nSave = pSort->nExpr;
|
||||
pSort->nExpr = p->pOrderBy->nExpr;
|
||||
if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){
|
||||
sqlite3ExprListDelete(db, p->pOrderBy);
|
||||
p->pOrderBy = 0;
|
||||
}
|
||||
pSort->nExpr = nSave;
|
||||
}
|
||||
|
||||
/* Assign a cursor number for the ephemeral table used to buffer rows.
|
||||
@@ -991,7 +997,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
|
||||
p->pSrc->a[0].pSelect = pSub;
|
||||
sqlite3SrcListAssignCursors(pParse, p->pSrc);
|
||||
pSub->selFlags |= SF_Expanded;
|
||||
pTab2 = sqlite3ResultSetOfSelect(pParse, pSub);
|
||||
pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
|
||||
if( pTab2==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
@@ -1014,11 +1020,24 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Unlink the Window object from the Select to which it is attached,
|
||||
** if it is attached.
|
||||
*/
|
||||
void sqlite3WindowUnlinkFromSelect(Window *p){
|
||||
if( p->ppThis ){
|
||||
*p->ppThis = p->pNextWin;
|
||||
if( p->pNextWin ) p->pNextWin->ppThis = p->ppThis;
|
||||
p->ppThis = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Free the Window object passed as the second argument.
|
||||
*/
|
||||
void sqlite3WindowDelete(sqlite3 *db, Window *p){
|
||||
if( p ){
|
||||
sqlite3WindowUnlinkFromSelect(p);
|
||||
sqlite3ExprDelete(db, p->pFilter);
|
||||
sqlite3ExprListDelete(db, p->pPartition);
|
||||
sqlite3ExprListDelete(db, p->pOrderBy);
|
||||
@@ -1196,28 +1215,44 @@ void sqlite3WindowChain(Parse *pParse, Window *pWin, Window *pList){
|
||||
void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
|
||||
if( p ){
|
||||
assert( p->op==TK_FUNCTION );
|
||||
/* This routine is only called for the parser. If pWin was not
|
||||
** allocated due to an OOM, then the parser would fail before ever
|
||||
** invoking this routine */
|
||||
if( ALWAYS(pWin) ){
|
||||
p->y.pWin = pWin;
|
||||
ExprSetProperty(p, EP_WinFunc);
|
||||
pWin->pOwner = p;
|
||||
if( p->flags & EP_Distinct ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"DISTINCT is not supported for window functions");
|
||||
}
|
||||
assert( pWin );
|
||||
p->y.pWin = pWin;
|
||||
ExprSetProperty(p, EP_WinFunc);
|
||||
pWin->pOwner = p;
|
||||
if( (p->flags & EP_Distinct) && pWin->eFrmType!=TK_FILTER ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"DISTINCT is not supported for window functions"
|
||||
);
|
||||
}
|
||||
}else{
|
||||
sqlite3WindowDelete(pParse->db, pWin);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Possibly link window pWin into the list at pSel->pWin (window functions
|
||||
** to be processed as part of SELECT statement pSel). The window is linked
|
||||
** in if either (a) there are no other windows already linked to this
|
||||
** SELECT, or (b) the windows already linked use a compatible window frame.
|
||||
*/
|
||||
void sqlite3WindowLink(Select *pSel, Window *pWin){
|
||||
if( 0==pSel->pWin
|
||||
|| 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0)
|
||||
){
|
||||
pWin->pNextWin = pSel->pWin;
|
||||
if( pSel->pWin ){
|
||||
pSel->pWin->ppThis = &pWin->pNextWin;
|
||||
}
|
||||
pSel->pWin = pWin;
|
||||
pWin->ppThis = &pSel->pWin;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return 0 if the two window objects are identical, or non-zero otherwise.
|
||||
** Identical window objects can be processed in a single scan.
|
||||
*/
|
||||
int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){
|
||||
int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2, int bFilter){
|
||||
if( p1->eFrmType!=p2->eFrmType ) return 1;
|
||||
if( p1->eStart!=p2->eStart ) return 1;
|
||||
if( p1->eEnd!=p2->eEnd ) return 1;
|
||||
@@ -1226,6 +1261,9 @@ int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){
|
||||
if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1;
|
||||
if( sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1) ) return 1;
|
||||
if( sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1) ) return 1;
|
||||
if( bFilter ){
|
||||
if( sqlite3ExprCompare(pParse, p1->pFilter, p2->pFilter, -1) ) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1277,8 +1315,8 @@ void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
|
||||
pWin->regApp = pParse->nMem+1;
|
||||
pParse->nMem += 3;
|
||||
if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
|
||||
assert( pKeyInfo->aSortOrder[0]==0 );
|
||||
pKeyInfo->aSortOrder[0] = 1;
|
||||
assert( pKeyInfo->aSortFlags[0]==0 );
|
||||
pKeyInfo->aSortFlags[0] = KEYINFO_ORDER_DESC;
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
|
||||
sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
|
||||
@@ -1397,6 +1435,8 @@ static void windowAggStep(
|
||||
int nArg = windowArgCount(pWin);
|
||||
int i;
|
||||
|
||||
assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED );
|
||||
|
||||
for(i=0; i<nArg; i++){
|
||||
if( i!=1 || pFunc->zName!=nth_valueName ){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
|
||||
@@ -1567,8 +1607,10 @@ static void windowFullScan(WindowCodeArg *p){
|
||||
int lblNext;
|
||||
int lblBrk;
|
||||
int addrNext;
|
||||
int csr = pMWin->csrApp;
|
||||
int csr;
|
||||
|
||||
assert( pMWin!=0 );
|
||||
csr = pMWin->csrApp;
|
||||
nPeer = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
|
||||
|
||||
lblNext = sqlite3VdbeMakeLabel(pParse);
|
||||
@@ -1834,12 +1876,13 @@ static void windowCodeRangeTest(
|
||||
int reg2 = sqlite3GetTempReg(pParse);
|
||||
int arith = OP_Add;
|
||||
int addrGe;
|
||||
ExprList *pOrderBy = p->pMWin->pOrderBy;
|
||||
|
||||
int regString = ++pParse->nMem;
|
||||
|
||||
assert( op==OP_Ge || op==OP_Gt || op==OP_Le );
|
||||
assert( p->pMWin->pOrderBy && p->pMWin->pOrderBy->nExpr==1 );
|
||||
if( p->pMWin->pOrderBy->a[0].sortOrder ){
|
||||
assert( pOrderBy && pOrderBy->nExpr==1 );
|
||||
if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_DESC ){
|
||||
switch( op ){
|
||||
case OP_Ge: op = OP_Le; break;
|
||||
case OP_Gt: op = OP_Lt; break;
|
||||
@@ -1859,6 +1902,28 @@ static void windowCodeRangeTest(
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1);
|
||||
sqlite3VdbeJumpHere(v, addrGe);
|
||||
if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_BIGNULL ){
|
||||
int addr;
|
||||
addr = sqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v);
|
||||
switch( op ){
|
||||
case OP_Ge: sqlite3VdbeAddOp2(v, OP_Goto, 0, lbl); break;
|
||||
case OP_Gt:
|
||||
sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl);
|
||||
VdbeCoverage(v);
|
||||
break;
|
||||
case OP_Le:
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl);
|
||||
VdbeCoverage(v);
|
||||
break;
|
||||
default: assert( op==OP_Lt ); /* no-op */
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v);
|
||||
if( op==OP_Gt || op==OP_Ge ){
|
||||
sqlite3VdbeChangeP2(v, -1, sqlite3VdbeCurrentAddr(v)+1);
|
||||
}
|
||||
}
|
||||
sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v);
|
||||
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
|
||||
assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le );
|
||||
@@ -2017,6 +2082,7 @@ Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
|
||||
pNew->eEnd = p->eEnd;
|
||||
pNew->eStart = p->eStart;
|
||||
pNew->eExclude = p->eExclude;
|
||||
pNew->regResult = p->regResult;
|
||||
pNew->pStart = sqlite3ExprDup(db, p->pStart, 0);
|
||||
pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0);
|
||||
pNew->pOwner = pOwner;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix affinity2
|
||||
|
||||
do_execsql_test affinity2-100 {
|
||||
CREATE TABLE t1(
|
||||
@@ -58,4 +59,62 @@ do_execsql_test affinity2-300 {
|
||||
SELECT rowid, xt==+xi, xt==xi, xt==xb FROM t1 ORDER BY rowid;
|
||||
} {1 1 1 0 2 1 1 1 3 0 1 1}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
do_execsql_test 400 {
|
||||
CREATE TABLE ttt(c0, c1);
|
||||
CREATE INDEX ii ON ttt(CAST(c0 AS NUMERIC));
|
||||
INSERT INTO ttt VALUES('abc', '-1');
|
||||
}
|
||||
do_execsql_test 410 {
|
||||
SELECT * FROM ttt WHERE CAST(c0 AS NUMERIC) > c1 GROUP BY rowid;
|
||||
} {abc -1}
|
||||
do_execsql_test 420 {
|
||||
SELECT * FROM ttt INDEXED BY ii WHERE CAST(c0 AS NUMERIC) > c1 GROUP BY rowid;
|
||||
} {abc -1}
|
||||
|
||||
do_execsql_test 430 {
|
||||
CREATE TABLE t3(a, b, c INTEGER);
|
||||
CREATE INDEX t3ac ON t3(a, c-1);
|
||||
INSERT INTO t3 VALUES(1, 1, 1);
|
||||
INSERT INTO t3 VALUES(2, 1, 0);
|
||||
INSERT INTO t3 VALUES(3, 1, 1);
|
||||
INSERT INTO t3 VALUES(4, 1, 0);
|
||||
INSERT INTO t3 VALUES(5, 1, 1);
|
||||
}
|
||||
do_execsql_test 440 {
|
||||
SELECT * FROM t3 WHERE c='0' ORDER BY a;
|
||||
} {2 1 0 4 1 0}
|
||||
|
||||
# 2019-08-22 ticket https://sqlite.org/src/info/d99f1ffe836c591ac57f
|
||||
# False positive in sqlite3ExprNeedsNoAffinityChange()
|
||||
#
|
||||
do_execsql_test 500 {
|
||||
DROP TABLE IF EXISTS t0;
|
||||
CREATE TABLE t0(c0 TEXT UNIQUE, c1);
|
||||
INSERT INTO t0(c0) VALUES (-1);
|
||||
SELECT quote(- x'ce'), quote(t0.c0), quote(- x'ce' >= t0.c0) FROM t0;
|
||||
} {0 '-1' 1}
|
||||
do_execsql_test 501 {
|
||||
SELECT * FROM t0 WHERE - x'ce' >= t0.c0;
|
||||
} {-1 {}}
|
||||
do_execsql_test 502 {
|
||||
SELECT quote(+-+x'ce'), quote(t0.c0), quote(+-+x'ce' >= t0.c0) FROM t0;
|
||||
} {0 '-1' 1}
|
||||
do_execsql_test 503 {
|
||||
SELECT * FROM t0 WHERE +-+x'ce' >= t0.c0;
|
||||
} {-1 {}}
|
||||
do_execsql_test 504 {
|
||||
SELECT quote(- 'ce'), quote(t0.c0), quote(- 'ce' >= t0.c0) FROM t0;
|
||||
} {0 '-1' 1}
|
||||
do_execsql_test 505 {
|
||||
SELECT * FROM t0 WHERE - 'ce' >= t0.c0;
|
||||
} {-1 {}}
|
||||
do_execsql_test 506 {
|
||||
SELECT quote(+-+'ce'), quote(t0.c0), quote(+-+'ce' >= t0.c0) FROM t0;
|
||||
} {0 '-1' 1}
|
||||
do_execsql_test 507 {
|
||||
SELECT * FROM t0 WHERE +-+'ce' >= t0.c0;
|
||||
} {-1 {}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -856,7 +856,6 @@ do_test alter-14.2 {
|
||||
set system_table_list {1 sqlite_master}
|
||||
catchsql ANALYZE
|
||||
ifcapable analyze { lappend system_table_list 2 sqlite_stat1 }
|
||||
ifcapable stat3 { lappend system_table_list 3 sqlite_stat3 }
|
||||
ifcapable stat4 { lappend system_table_list 4 sqlite_stat4 }
|
||||
|
||||
foreach {tn tbl} $system_table_list {
|
||||
|
||||
@@ -594,4 +594,3 @@ do_execsql_test 18.2.2 {
|
||||
} {{CREATE TABLE t0 (c1 INTEGER, PRIMARY KEY(c1))}}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ ifcapable !altertable {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
ifcapable windowfunc {
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b);
|
||||
@@ -237,5 +238,148 @@ do_execsql_test 10.2 {
|
||||
) IN () OR t1.a=5}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 11.1 {
|
||||
CREATE TABLE t1(
|
||||
a,b,c,d,e,f,g,h,j,jj,jjb,k,aa,bb,cc,dd,ee DEFAULT 3.14,
|
||||
ff DEFAULT('hiccup'),Wg NOD NULL DEFAULT(false)
|
||||
);
|
||||
|
||||
CREATE TRIGGER b AFTER INSERT ON t1 WHEN new.a BEGIN
|
||||
SELECT a, sum() w3 FROM t1
|
||||
WINDOW b AS (ORDER BY NOT EXISTS(SELECT 1 FROM abc));
|
||||
END;
|
||||
}
|
||||
|
||||
do_catchsql_test 11.2 {
|
||||
ALTER TABLE t1 RENAME TO t1x;
|
||||
} {1 {error in trigger b: no such table: abc}}
|
||||
|
||||
do_execsql_test 11.3 {
|
||||
DROP TRIGGER b;
|
||||
CREATE TRIGGER b AFTER INSERT ON t1 WHEN new.a BEGIN
|
||||
SELECT a, sum() w3 FROM t1
|
||||
WINDOW b AS (ORDER BY NOT EXISTS(SELECT 1 FROM t1));
|
||||
END;
|
||||
} {}
|
||||
|
||||
do_execsql_test 11.4 {
|
||||
ALTER TABLE t1 RENAME TO t1x;
|
||||
SELECT sql FROM sqlite_master WHERE name = 'b';
|
||||
} {
|
||||
{CREATE TRIGGER b AFTER INSERT ON "t1x" WHEN new.a BEGIN
|
||||
SELECT a, sum() w3 FROM "t1x"
|
||||
WINDOW b AS (ORDER BY NOT EXISTS(SELECT 1 FROM "t1x"));
|
||||
END}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 12.1 {
|
||||
CREATE TABLE t1(a,b,c,d,e,f,g,h,j,jj,Zjj,k,aQ,bb,cc,dd,ee DEFAULT 3.14,
|
||||
ff DEFAULT('hiccup'),gg NOD NULL DEFAULT(false));
|
||||
CREATE TRIGGER AFTER INSERT ON t1 WHEN new.a NOT NULL BEGIN
|
||||
|
||||
SELECT b () OVER , dense_rank() OVER d, d () OVER w1
|
||||
FROM t1
|
||||
WINDOW
|
||||
w1 AS
|
||||
( w1 ORDER BY d
|
||||
ROWS BETWEEN 2 NOT IN(SELECT a, sum(d) w2,max(d)OVER FROM t1
|
||||
WINDOW
|
||||
w1 AS
|
||||
(PARTITION BY d
|
||||
ROWS BETWEEN '' PRECEDING AND false FOLLOWING),
|
||||
d AS
|
||||
(PARTITION BY b ORDER BY d
|
||||
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
|
||||
) PRECEDING AND 1 FOLLOWING),
|
||||
w2 AS
|
||||
(PARTITION BY b ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),
|
||||
w3 AS
|
||||
(PARTITION BY b ORDER BY d
|
||||
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
|
||||
;
|
||||
SELECT a, sum(d) w2,max(d)OVER FROM t1
|
||||
WINDOW
|
||||
w1 AS
|
||||
(PARTITION BY d
|
||||
ROWS BETWEEN '' PRECEDING AND false FOLLOWING),
|
||||
d AS
|
||||
(PARTITION BY b ORDER BY d
|
||||
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
|
||||
;
|
||||
|
||||
END;
|
||||
}
|
||||
|
||||
do_execsql_test 12.2 {
|
||||
ALTER TABLE t1 RENAME TO t1x;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 13.1 {
|
||||
CREATE TABLE t1(a);
|
||||
CREATE TRIGGER r1 INSERT ON t1 BEGIN
|
||||
SELECT a(*) OVER (ORDER BY (SELECT 1)) FROM t1;
|
||||
END;
|
||||
}
|
||||
|
||||
do_execsql_test 13.2 {
|
||||
ALTER TABLE t1 RENAME TO t1x;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 14.1 {
|
||||
CREATE TABLE t1(a);
|
||||
CREATE TABLE t2(b);
|
||||
CREATE TRIGGER AFTER INSERT ON t1 BEGIN
|
||||
SELECT sum() FILTER (WHERE (SELECT sum() FILTER (WHERE 0)) AND a);
|
||||
END;
|
||||
}
|
||||
|
||||
do_catchsql_test 14.2 {
|
||||
ALTER TABLE t1 RENAME TO t1x;
|
||||
} {1 {error in trigger AFTER: no such column: a}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
|
||||
do_execsql_test 16.1 {
|
||||
CREATE TABLE t1(x);
|
||||
CREATE TRIGGER AFTER INSERT ON t1 BEGIN
|
||||
SELECT (WITH t2 AS (WITH t3 AS (SELECT true)
|
||||
SELECT * FROM t3 ORDER BY true COLLATE nocase)
|
||||
SELECT 11);
|
||||
|
||||
WITH t4 AS (SELECT * FROM t1) SELECT 33;
|
||||
END;
|
||||
}
|
||||
do_execsql_test 16.2 {
|
||||
ALTER TABLE t1 RENAME TO t1x;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 17.1 {
|
||||
CREATE TABLE t1(a,b,c);
|
||||
CREATE TRIGGER AFTER INSERT ON t1 WHEN new.a NOT NULL BEGIN
|
||||
SELECT a () FILTER (WHERE a>0) FROM t1;
|
||||
END;
|
||||
}
|
||||
|
||||
do_execsql_test 17.2 {
|
||||
ALTER TABLE t1 RENAME TO t1x;
|
||||
ALTER TABLE t1x RENAME a TO aaa;
|
||||
SELECT sql FROM sqlite_master WHERE type='trigger';
|
||||
} {
|
||||
{CREATE TRIGGER AFTER INSERT ON "t1x" WHEN new.aaa NOT NULL BEGIN
|
||||
SELECT a () FILTER (WHERE aaa>0) FROM "t1x";
|
||||
END}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+16
-17
@@ -288,7 +288,7 @@ do_test analyze-4.3 {
|
||||
} {}
|
||||
|
||||
# Verify that DROP TABLE and DROP INDEX remove entries from the
|
||||
# sqlite_stat1, sqlite_stat3 and sqlite_stat4 tables.
|
||||
# sqlite_stat1 and sqlite_stat4 tables.
|
||||
#
|
||||
do_test analyze-5.0 {
|
||||
execsql {
|
||||
@@ -306,13 +306,12 @@ do_test analyze-5.0 {
|
||||
SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
|
||||
}
|
||||
} {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4}
|
||||
ifcapable stat4||stat3 {
|
||||
ifcapable stat4 {set stat sqlite_stat4} else {set stat sqlite_stat3}
|
||||
ifcapable stat4 {
|
||||
do_test analyze-5.1 {
|
||||
execsql "
|
||||
SELECT DISTINCT idx FROM $stat ORDER BY 1;
|
||||
SELECT DISTINCT tbl FROM $stat ORDER BY 1;
|
||||
"
|
||||
execsql {
|
||||
SELECT DISTINCT idx FROM sqlite_stat4 ORDER BY 1;
|
||||
SELECT DISTINCT tbl FROM sqlite_stat4 ORDER BY 1;
|
||||
}
|
||||
} {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4}
|
||||
}
|
||||
do_test analyze-5.2 {
|
||||
@@ -322,12 +321,12 @@ do_test analyze-5.2 {
|
||||
SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
|
||||
}
|
||||
} {t3i1 t3i3 t4i1 t4i2 t3 t4}
|
||||
ifcapable stat4||stat3 {
|
||||
ifcapable stat4 {
|
||||
do_test analyze-5.3 {
|
||||
execsql "
|
||||
SELECT DISTINCT idx FROM $stat ORDER BY 1;
|
||||
SELECT DISTINCT tbl FROM $stat ORDER BY 1;
|
||||
"
|
||||
execsql {
|
||||
SELECT DISTINCT idx FROM sqlite_stat4 ORDER BY 1;
|
||||
SELECT DISTINCT tbl FROM sqlite_stat4 ORDER BY 1;
|
||||
}
|
||||
} {t3i1 t3i3 t4i1 t4i2 t3 t4}
|
||||
}
|
||||
do_test analyze-5.4 {
|
||||
@@ -337,12 +336,12 @@ do_test analyze-5.4 {
|
||||
SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
|
||||
}
|
||||
} {t4i1 t4i2 t4}
|
||||
ifcapable stat4||stat3 {
|
||||
ifcapable stat4 {
|
||||
do_test analyze-5.5 {
|
||||
execsql "
|
||||
SELECT DISTINCT idx FROM $stat ORDER BY 1;
|
||||
SELECT DISTINCT tbl FROM $stat ORDER BY 1;
|
||||
"
|
||||
execsql {
|
||||
SELECT DISTINCT idx FROM sqlite_stat4 ORDER BY 1;
|
||||
SELECT DISTINCT tbl FROM sqlite_stat4 ORDER BY 1;
|
||||
}
|
||||
} {t4i1 t4i2 t4}
|
||||
}
|
||||
|
||||
|
||||
+2
-6
@@ -18,7 +18,7 @@ set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix analyze3
|
||||
|
||||
ifcapable !stat4&&!stat3 {
|
||||
ifcapable !stat4 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
@@ -100,11 +100,7 @@ do_test analyze3-1.1.1 {
|
||||
ANALYZE;
|
||||
}
|
||||
|
||||
ifcapable stat4 {
|
||||
execsql { SELECT count(*)>0 FROM sqlite_stat4; }
|
||||
} else {
|
||||
execsql { SELECT count(*)>0 FROM sqlite_stat3; }
|
||||
}
|
||||
execsql { SELECT count(*)>0 FROM sqlite_stat4; }
|
||||
} {1}
|
||||
|
||||
do_execsql_test analyze3-1.1.x {
|
||||
|
||||
+10
-28
@@ -17,7 +17,7 @@
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
ifcapable !stat4&&!stat3 {
|
||||
ifcapable !stat4 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
@@ -67,39 +67,21 @@ do_test analyze5-1.0 {
|
||||
CREATE INDEX t1z ON t1(z); -- integers 0, 1, 2, and 3
|
||||
ANALYZE;
|
||||
}
|
||||
ifcapable stat4 {
|
||||
db eval {
|
||||
SELECT DISTINCT lindex(test_decode(sample),0)
|
||||
FROM sqlite_stat4 WHERE idx='t1u' ORDER BY nlt;
|
||||
}
|
||||
} else {
|
||||
db eval {
|
||||
SELECT sample FROM sqlite_stat3 WHERE idx='t1u' ORDER BY nlt;
|
||||
}
|
||||
db eval {
|
||||
SELECT DISTINCT lindex(test_decode(sample),0)
|
||||
FROM sqlite_stat4 WHERE idx='t1u' ORDER BY nlt;
|
||||
}
|
||||
} {alpha bravo charlie delta}
|
||||
|
||||
do_test analyze5-1.1 {
|
||||
ifcapable stat4 {
|
||||
db eval {
|
||||
SELECT DISTINCT lower(lindex(test_decode(sample), 0))
|
||||
FROM sqlite_stat4 WHERE idx='t1v' ORDER BY 1
|
||||
}
|
||||
} else {
|
||||
db eval {
|
||||
SELECT lower(sample) FROM sqlite_stat3 WHERE idx='t1v' ORDER BY 1
|
||||
}
|
||||
db eval {
|
||||
SELECT DISTINCT lower(lindex(test_decode(sample), 0))
|
||||
FROM sqlite_stat4 WHERE idx='t1v' ORDER BY 1
|
||||
}
|
||||
} {alpha bravo charlie delta}
|
||||
ifcapable stat4 {
|
||||
do_test analyze5-1.2 {
|
||||
db eval {SELECT idx, count(*) FROM sqlite_stat4 GROUP BY 1 ORDER BY 1}
|
||||
} {t1t 8 t1u 8 t1v 8 t1w 8 t1x 8 t1y 9 t1z 8}
|
||||
} else {
|
||||
do_test analyze5-1.2 {
|
||||
db eval {SELECT idx, count(*) FROM sqlite_stat3 GROUP BY 1 ORDER BY 1}
|
||||
} {t1t 4 t1u 4 t1v 4 t1w 4 t1x 4 t1y 2 t1z 4}
|
||||
}
|
||||
do_test analyze5-1.2 {
|
||||
db eval {SELECT idx, count(*) FROM sqlite_stat4 GROUP BY 1 ORDER BY 1}
|
||||
} {t1t 8 t1u 8 t1v 8 t1w 8 t1x 8 t1y 9 t1z 8}
|
||||
|
||||
# Verify that range queries generate the correct row count estimates
|
||||
#
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
ifcapable !stat4&&!stat3 {
|
||||
ifcapable !stat4 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
+2
-2
@@ -82,7 +82,7 @@ do_test analyze7-3.1 {
|
||||
do_test analyze7-3.2.1 {
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=?;}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/}
|
||||
ifcapable stat4||stat3 {
|
||||
ifcapable stat4 {
|
||||
# If ENABLE_STAT4 is defined, SQLite comes up with a different estimated
|
||||
# row count for (c=2) than it does for (c=?).
|
||||
do_test analyze7-3.2.2 {
|
||||
@@ -99,7 +99,7 @@ do_test analyze7-3.3 {
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND b=123}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
|
||||
|
||||
ifcapable {!stat4 && !stat3} {
|
||||
ifcapable {!stat4} {
|
||||
do_test analyze7-3.4 {
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND b=123}
|
||||
} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/}
|
||||
|
||||
+2
-2
@@ -10,13 +10,13 @@
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file implements tests for SQLite library. The focus of the tests
|
||||
# in this file is testing the capabilities of sqlite_stat3.
|
||||
# in this file is testing the capabilities of sqlite_stat4.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
ifcapable !stat4&&!stat3 {
|
||||
ifcapable !stat4 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,186 +0,0 @@
|
||||
# 2013 August 3
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file contains automated tests used to verify that the current build
|
||||
# (which must be either ENABLE_STAT3 or ENABLE_STAT4) works with both stat3
|
||||
# and stat4 data.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix analyzeA
|
||||
|
||||
ifcapable !stat4&&!stat3 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
# Populate the stat3 table according to the current contents of the db
|
||||
#
|
||||
proc populate_stat3 {{bDropTable 1}} {
|
||||
# Open a second connection on database "test.db" and run ANALYZE. If this
|
||||
# is an ENABLE_STAT3 build, this is all that is required to create and
|
||||
# populate the sqlite_stat3 table.
|
||||
#
|
||||
sqlite3 db2 test.db
|
||||
execsql { ANALYZE }
|
||||
|
||||
# Now, if this is an ENABLE_STAT4 build, create and populate the
|
||||
# sqlite_stat3 table based on the stat4 data gathered by the ANALYZE
|
||||
# above. Then drop the sqlite_stat4 table.
|
||||
#
|
||||
ifcapable stat4 {
|
||||
db2 func lindex lindex
|
||||
execsql {
|
||||
PRAGMA writable_schema = on;
|
||||
CREATE TABLE sqlite_stat3(tbl,idx,neq,nlt,ndlt,sample);
|
||||
INSERT INTO sqlite_stat3
|
||||
SELECT DISTINCT tbl, idx,
|
||||
lindex(neq,0), lindex(nlt,0), lindex(ndlt,0), test_extract(sample, 0)
|
||||
FROM sqlite_stat4;
|
||||
} db2
|
||||
if {$bDropTable} { execsql {DROP TABLE sqlite_stat4} db2 }
|
||||
execsql { PRAGMA writable_schema = off }
|
||||
}
|
||||
|
||||
# Modify the database schema cookie to ensure that the other connection
|
||||
# reloads the schema.
|
||||
#
|
||||
execsql {
|
||||
CREATE TABLE obscure_tbl_nm(x);
|
||||
DROP TABLE obscure_tbl_nm;
|
||||
} db2
|
||||
db2 close
|
||||
}
|
||||
|
||||
# Populate the stat4 table according to the current contents of the db
|
||||
#
|
||||
proc populate_stat4 {{bDropTable 1}} {
|
||||
sqlite3 db2 test.db
|
||||
execsql { ANALYZE }
|
||||
|
||||
ifcapable stat3 {
|
||||
execsql {
|
||||
PRAGMA writable_schema = on;
|
||||
CREATE TABLE sqlite_stat4(tbl,idx,neq,nlt,ndlt,sample);
|
||||
INSERT INTO sqlite_stat4
|
||||
SELECT tbl, idx, neq, nlt, ndlt, sqlite_record(sample)
|
||||
FROM sqlite_stat3;
|
||||
} db2
|
||||
if {$bDropTable} { execsql {DROP TABLE sqlite_stat3} db2 }
|
||||
execsql { PRAGMA writable_schema = off }
|
||||
}
|
||||
|
||||
# Modify the database schema cookie to ensure that the other connection
|
||||
# reloads the schema.
|
||||
#
|
||||
execsql {
|
||||
CREATE TABLE obscure_tbl_nm(x);
|
||||
DROP TABLE obscure_tbl_nm;
|
||||
} db2
|
||||
db2 close
|
||||
}
|
||||
|
||||
# Populate the stat4 table according to the current contents of the db.
|
||||
# Leave deceptive data in the stat3 table. This data should be ignored
|
||||
# in favour of that from the stat4 table.
|
||||
#
|
||||
proc populate_both {} {
|
||||
ifcapable stat4 { populate_stat3 0 }
|
||||
ifcapable stat3 { populate_stat4 0 }
|
||||
|
||||
sqlite3 db2 test.db
|
||||
execsql {
|
||||
PRAGMA writable_schema = on;
|
||||
UPDATE sqlite_stat3 SET idx =
|
||||
CASE idx WHEN 't1b' THEN 't1c' ELSE 't1b'
|
||||
END;
|
||||
PRAGMA writable_schema = off;
|
||||
CREATE TABLE obscure_tbl_nm(x);
|
||||
DROP TABLE obscure_tbl_nm;
|
||||
} db2
|
||||
db2 close
|
||||
}
|
||||
|
||||
foreach {tn analyze_cmd} {
|
||||
1 populate_stat4
|
||||
2 populate_stat3
|
||||
3 populate_both
|
||||
} {
|
||||
reset_db
|
||||
do_test 1.$tn.1 {
|
||||
execsql { CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT, c INT) }
|
||||
for {set i 0} {$i < 100} {incr i} {
|
||||
set c [expr int(pow(1.1,$i)/100)]
|
||||
set b [expr 125 - int(pow(1.1,99-$i))/100]
|
||||
execsql {INSERT INTO t1 VALUES($i, $b, $c)}
|
||||
}
|
||||
} {}
|
||||
|
||||
execsql { CREATE INDEX t1b ON t1(b) }
|
||||
execsql { CREATE INDEX t1c ON t1(c) }
|
||||
$analyze_cmd
|
||||
|
||||
do_execsql_test 1.$tn.2.1 { SELECT count(*) FROM t1 WHERE b=31 } 1
|
||||
do_execsql_test 1.$tn.2.2 { SELECT count(*) FROM t1 WHERE c=0 } 49
|
||||
do_execsql_test 1.$tn.2.3 { SELECT count(*) FROM t1 WHERE b=125 } 49
|
||||
do_execsql_test 1.$tn.2.4 { SELECT count(*) FROM t1 WHERE c=16 } 1
|
||||
|
||||
do_eqp_test 1.$tn.2.5 {
|
||||
SELECT * FROM t1 WHERE b = 31 AND c = 0;
|
||||
} {SEARCH TABLE t1 USING INDEX t1b (b=?)}
|
||||
do_eqp_test 1.$tn.2.6 {
|
||||
SELECT * FROM t1 WHERE b = 125 AND c = 16;
|
||||
} {SEARCH TABLE t1 USING INDEX t1c (c=?)}
|
||||
|
||||
do_execsql_test 1.$tn.3.1 {
|
||||
SELECT count(*) FROM t1 WHERE b BETWEEN 0 AND 50
|
||||
} {6}
|
||||
do_execsql_test 1.$tn.3.2 {
|
||||
SELECT count(*) FROM t1 WHERE c BETWEEN 0 AND 50
|
||||
} {90}
|
||||
do_execsql_test 1.$tn.3.3 {
|
||||
SELECT count(*) FROM t1 WHERE b BETWEEN 75 AND 125
|
||||
} {90}
|
||||
do_execsql_test 1.$tn.3.4 {
|
||||
SELECT count(*) FROM t1 WHERE c BETWEEN 75 AND 125
|
||||
} {6}
|
||||
|
||||
do_eqp_test 1.$tn.3.5 {
|
||||
SELECT * FROM t1 WHERE b BETWEEN 0 AND 50 AND c BETWEEN 0 AND 50
|
||||
} {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}
|
||||
|
||||
do_eqp_test 1.$tn.3.6 {
|
||||
SELECT * FROM t1 WHERE b BETWEEN 75 AND 125 AND c BETWEEN 75 AND 125
|
||||
} {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}
|
||||
|
||||
do_eqp_test 1.$tn.3.7 {
|
||||
SELECT * FROM t1 WHERE b BETWEEN +0 AND +50 AND c BETWEEN +0 AND +50
|
||||
} {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}
|
||||
|
||||
do_eqp_test 1.$tn.3.8 {
|
||||
SELECT * FROM t1
|
||||
WHERE b BETWEEN cast('0' AS int) AND cast('50.0' AS real)
|
||||
AND c BETWEEN cast('0' AS numeric) AND cast('50.0' AS real)
|
||||
} {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}
|
||||
|
||||
do_eqp_test 1.$tn.3.9 {
|
||||
SELECT * FROM t1 WHERE b BETWEEN +75 AND +125 AND c BETWEEN +75 AND +125
|
||||
} {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}
|
||||
|
||||
do_eqp_test 1.$tn.3.10 {
|
||||
SELECT * FROM t1
|
||||
WHERE b BETWEEN cast('75' AS int) AND cast('125.0' AS real)
|
||||
AND c BETWEEN cast('75' AS numeric) AND cast('125.0' AS real)
|
||||
} {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}
|
||||
}
|
||||
|
||||
finish_test
|
||||
@@ -1,682 +0,0 @@
|
||||
# 2013 August 3
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file contains automated tests used to verify that the sqlite_stat3
|
||||
# functionality is working. The tests in this file are based on a subset
|
||||
# of the sqlite_stat4 tests in analyze9.test.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix analyzeB
|
||||
|
||||
ifcapable !stat3 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a TEXT, b TEXT);
|
||||
INSERT INTO t1 VALUES('(0)', '(0)');
|
||||
INSERT INTO t1 VALUES('(1)', '(1)');
|
||||
INSERT INTO t1 VALUES('(2)', '(2)');
|
||||
INSERT INTO t1 VALUES('(3)', '(3)');
|
||||
INSERT INTO t1 VALUES('(4)', '(4)');
|
||||
CREATE INDEX i1 ON t1(a, b);
|
||||
} {}
|
||||
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
ANALYZE;
|
||||
} {}
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
SELECT tbl,idx,nEq,nLt,nDLt,quote(sample) FROM sqlite_stat3;
|
||||
} {
|
||||
t1 i1 1 0 0 '(0)'
|
||||
t1 i1 1 1 1 '(1)'
|
||||
t1 i1 1 2 2 '(2)'
|
||||
t1 i1 1 3 3 '(3)'
|
||||
t1 i1 1 4 4 '(4)'
|
||||
}
|
||||
|
||||
if {[permutation] != "utf16"} {
|
||||
do_execsql_test 1.3 {
|
||||
SELECT tbl,idx,nEq,nLt,nDLt,quote(sample) FROM sqlite_stat3;
|
||||
} {
|
||||
t1 i1 1 0 0 '(0)'
|
||||
t1 i1 1 1 1 '(1)'
|
||||
t1 i1 1 2 2 '(2)'
|
||||
t1 i1 1 3 3 '(3)'
|
||||
t1 i1 1 4 4 '(4)'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# This is really just to test SQL user function "test_decode".
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 2.1 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
INSERT INTO t1(a) VALUES('some text');
|
||||
INSERT INTO t1(a) VALUES(14);
|
||||
INSERT INTO t1(a) VALUES(NULL);
|
||||
INSERT INTO t1(a) VALUES(22.0);
|
||||
INSERT INTO t1(a) VALUES(x'656667');
|
||||
CREATE INDEX i1 ON t1(a, b, c);
|
||||
ANALYZE;
|
||||
SELECT quote(sample) FROM sqlite_stat3;
|
||||
} {
|
||||
NULL 14 22.0 {'some text'} X'656667'
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 3.1 {
|
||||
CREATE TABLE t2(a, b);
|
||||
CREATE INDEX i2 ON t2(a, b);
|
||||
BEGIN;
|
||||
}
|
||||
|
||||
do_test 3.2 {
|
||||
for {set i 0} {$i < 1000} {incr i} {
|
||||
set a [expr $i / 10]
|
||||
set b [expr int(rand() * 15.0)]
|
||||
execsql { INSERT INTO t2 VALUES($a, $b) }
|
||||
}
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
db func lindex lindex
|
||||
|
||||
# Each value of "a" occurs exactly 10 times in the table.
|
||||
#
|
||||
do_execsql_test 3.3.1 {
|
||||
SELECT count(*) FROM t2 GROUP BY a;
|
||||
} [lrange [string repeat "10 " 100] 0 99]
|
||||
|
||||
# The first element in the "nEq" list of all samples should therefore be 10.
|
||||
#
|
||||
do_execsql_test 3.3.2 {
|
||||
ANALYZE;
|
||||
SELECT nEq FROM sqlite_stat3;
|
||||
} [lrange [string repeat "10 " 100] 0 23]
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
do_execsql_test 3.4 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
INSERT INTO t1 VALUES(1, 1, 'one-a');
|
||||
INSERT INTO t1 VALUES(11, 1, 'one-b');
|
||||
INSERT INTO t1 VALUES(21, 1, 'one-c');
|
||||
INSERT INTO t1 VALUES(31, 1, 'one-d');
|
||||
INSERT INTO t1 VALUES(41, 1, 'one-e');
|
||||
INSERT INTO t1 VALUES(51, 1, 'one-f');
|
||||
INSERT INTO t1 VALUES(61, 1, 'one-g');
|
||||
INSERT INTO t1 VALUES(71, 1, 'one-h');
|
||||
INSERT INTO t1 VALUES(81, 1, 'one-i');
|
||||
INSERT INTO t1 VALUES(91, 1, 'one-j');
|
||||
INSERT INTO t1 SELECT a+1,2,'two' || substr(c,4) FROM t1;
|
||||
INSERT INTO t1 SELECT a+2,3,'three'||substr(c,4) FROM t1 WHERE c GLOB 'one-*';
|
||||
INSERT INTO t1 SELECT a+3,4,'four'||substr(c,4) FROM t1 WHERE c GLOB 'one-*';
|
||||
INSERT INTO t1 SELECT a+4,5,'five'||substr(c,4) FROM t1 WHERE c GLOB 'one-*';
|
||||
INSERT INTO t1 SELECT a+5,6,'six'||substr(c,4) FROM t1 WHERE c GLOB 'one-*';
|
||||
CREATE INDEX t1b ON t1(b);
|
||||
ANALYZE;
|
||||
SELECT c FROM t1 WHERE b=3 AND a BETWEEN 30 AND 60;
|
||||
} {three-d three-e three-f}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# These tests verify that the sample selection for stat3 appears to be
|
||||
# working as designed.
|
||||
#
|
||||
|
||||
reset_db
|
||||
db func lindex lindex
|
||||
db func lrange lrange
|
||||
|
||||
do_execsql_test 4.0 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(a, b, c);
|
||||
CREATE INDEX i1 ON t1(c, b, a);
|
||||
}
|
||||
|
||||
|
||||
proc insert_filler_rows_n {iStart args} {
|
||||
set A(-ncopy) 1
|
||||
set A(-nval) 1
|
||||
|
||||
foreach {k v} $args {
|
||||
if {[info exists A($k)]==0} { error "no such option: $k" }
|
||||
set A($k) $v
|
||||
}
|
||||
if {[llength $args] % 2} {
|
||||
error "option requires an argument: [lindex $args end]"
|
||||
}
|
||||
|
||||
for {set i 0} {$i < $A(-nval)} {incr i} {
|
||||
set iVal [expr $iStart+$i]
|
||||
for {set j 0} {$j < $A(-ncopy)} {incr j} {
|
||||
execsql { INSERT INTO t1 VALUES($iVal, $iVal, $iVal) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do_test 4.1 {
|
||||
execsql { BEGIN }
|
||||
insert_filler_rows_n 0 -ncopy 10 -nval 19
|
||||
insert_filler_rows_n 20 -ncopy 1 -nval 100
|
||||
|
||||
execsql {
|
||||
INSERT INTO t1(c, b, a) VALUES(200, 1, 'a');
|
||||
INSERT INTO t1(c, b, a) VALUES(200, 1, 'b');
|
||||
INSERT INTO t1(c, b, a) VALUES(200, 1, 'c');
|
||||
|
||||
INSERT INTO t1(c, b, a) VALUES(200, 2, 'e');
|
||||
INSERT INTO t1(c, b, a) VALUES(200, 2, 'f');
|
||||
|
||||
INSERT INTO t1(c, b, a) VALUES(201, 3, 'g');
|
||||
INSERT INTO t1(c, b, a) VALUES(201, 4, 'h');
|
||||
|
||||
ANALYZE;
|
||||
SELECT count(*) FROM sqlite_stat3;
|
||||
SELECT count(*) FROM t1;
|
||||
}
|
||||
} {24 297}
|
||||
|
||||
do_execsql_test 4.2 {
|
||||
SELECT neq, nlt, ndlt, sample FROM sqlite_stat3 ORDER BY rowid LIMIT 16;
|
||||
} {
|
||||
10 0 0 0
|
||||
10 10 1 1
|
||||
10 20 2 2
|
||||
10 30 3 3
|
||||
10 40 4 4
|
||||
10 50 5 5
|
||||
10 60 6 6
|
||||
10 70 7 7
|
||||
10 80 8 8
|
||||
10 90 9 9
|
||||
10 100 10 10
|
||||
10 110 11 11
|
||||
10 120 12 12
|
||||
10 130 13 13
|
||||
10 140 14 14
|
||||
10 150 15 15
|
||||
}
|
||||
|
||||
do_execsql_test 4.3 {
|
||||
SELECT neq, nlt, ndlt, sample FROM sqlite_stat3
|
||||
ORDER BY rowid DESC LIMIT 2;
|
||||
} {
|
||||
2 295 120 201
|
||||
5 290 119 200
|
||||
}
|
||||
|
||||
do_execsql_test 4.4 { SELECT count(DISTINCT c) FROM t1 WHERE c<201 } 120
|
||||
do_execsql_test 4.5 { SELECT count(DISTINCT c) FROM t1 WHERE c<200 } 119
|
||||
|
||||
reset_db
|
||||
do_test 4.7 {
|
||||
execsql {
|
||||
BEGIN;
|
||||
CREATE TABLE t1(o,t INTEGER PRIMARY KEY);
|
||||
CREATE INDEX i1 ON t1(o);
|
||||
}
|
||||
for {set i 0} {$i<10000} {incr i [expr (($i<1000)?1:10)]} {
|
||||
execsql { INSERT INTO t1 VALUES('x', $i) }
|
||||
}
|
||||
execsql {
|
||||
COMMIT;
|
||||
ANALYZE;
|
||||
SELECT count(*) FROM sqlite_stat3;
|
||||
}
|
||||
} {1}
|
||||
do_execsql_test 4.8 {
|
||||
SELECT sample FROM sqlite_stat3;
|
||||
} {x}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# The following would cause a crash at one point.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 5.1 {
|
||||
PRAGMA encoding = 'utf-16';
|
||||
CREATE TABLE t0(v);
|
||||
ANALYZE;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# This was also crashing (corrupt sqlite_stat3 table).
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 6.1 {
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE INDEX i1 ON t1(a);
|
||||
CREATE INDEX i2 ON t1(b);
|
||||
INSERT INTO t1 VALUES(1, 1);
|
||||
INSERT INTO t1 VALUES(2, 2);
|
||||
INSERT INTO t1 VALUES(3, 3);
|
||||
INSERT INTO t1 VALUES(4, 4);
|
||||
INSERT INTO t1 VALUES(5, 5);
|
||||
ANALYZE;
|
||||
PRAGMA writable_schema = 1;
|
||||
CREATE TEMP TABLE x1 AS
|
||||
SELECT tbl,idx,neq,nlt,ndlt,sample FROM sqlite_stat3
|
||||
ORDER BY (rowid%5), rowid;
|
||||
DELETE FROM sqlite_stat3;
|
||||
INSERT INTO sqlite_stat3 SELECT * FROM x1;
|
||||
PRAGMA writable_schema = 0;
|
||||
ANALYZE sqlite_master;
|
||||
}
|
||||
do_execsql_test 6.2 {
|
||||
SELECT * FROM t1 WHERE a = 'abc';
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# The following tests experiment with adding corrupted records to the
|
||||
# 'sample' column of the sqlite_stat3 table.
|
||||
#
|
||||
reset_db
|
||||
sqlite3_db_config_lookaside db 0 0 0
|
||||
|
||||
do_execsql_test 7.1 {
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE INDEX i1 ON t1(a, b);
|
||||
INSERT INTO t1 VALUES(1, 1);
|
||||
INSERT INTO t1 VALUES(2, 2);
|
||||
INSERT INTO t1 VALUES(3, 3);
|
||||
INSERT INTO t1 VALUES(4, 4);
|
||||
INSERT INTO t1 VALUES(5, 5);
|
||||
ANALYZE;
|
||||
UPDATE sqlite_stat3 SET sample = X'' WHERE rowid = 1;
|
||||
ANALYZE sqlite_master;
|
||||
}
|
||||
|
||||
do_execsql_test 7.2 {
|
||||
UPDATE sqlite_stat3 SET sample = X'FFFF';
|
||||
ANALYZE sqlite_master;
|
||||
SELECT * FROM t1 WHERE a = 1;
|
||||
} {1 1}
|
||||
|
||||
do_execsql_test 7.3 {
|
||||
ANALYZE;
|
||||
UPDATE sqlite_stat3 SET neq = '0 0 0';
|
||||
ANALYZE sqlite_master;
|
||||
SELECT * FROM t1 WHERE a = 1;
|
||||
} {1 1}
|
||||
|
||||
do_execsql_test 7.4 {
|
||||
ANALYZE;
|
||||
UPDATE sqlite_stat3 SET ndlt = '0 0 0';
|
||||
ANALYZE sqlite_master;
|
||||
SELECT * FROM t1 WHERE a = 3;
|
||||
} {3 3}
|
||||
|
||||
do_execsql_test 7.5 {
|
||||
ANALYZE;
|
||||
UPDATE sqlite_stat3 SET nlt = '0 0 0';
|
||||
ANALYZE sqlite_master;
|
||||
SELECT * FROM t1 WHERE a = 5;
|
||||
} {5 5}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 8.1 {
|
||||
CREATE TABLE t1(x TEXT);
|
||||
CREATE INDEX i1 ON t1(x);
|
||||
INSERT INTO t1 VALUES('1');
|
||||
INSERT INTO t1 VALUES('2');
|
||||
INSERT INTO t1 VALUES('3');
|
||||
INSERT INTO t1 VALUES('4');
|
||||
ANALYZE;
|
||||
}
|
||||
do_execsql_test 8.2 {
|
||||
SELECT * FROM t1 WHERE x = 3;
|
||||
} {3}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 9.1 {
|
||||
CREATE TABLE t1(a, b, c, d, e);
|
||||
CREATE INDEX i1 ON t1(a, b, c, d);
|
||||
CREATE INDEX i2 ON t1(e);
|
||||
}
|
||||
do_test 9.2 {
|
||||
execsql BEGIN;
|
||||
for {set i 0} {$i < 100} {incr i} {
|
||||
execsql "INSERT INTO t1 VALUES('x', 'y', 'z', $i, [expr $i/2])"
|
||||
}
|
||||
for {set i 0} {$i < 20} {incr i} {
|
||||
execsql "INSERT INTO t1 VALUES('x', 'y', 'z', 101, $i)"
|
||||
}
|
||||
for {set i 102} {$i < 200} {incr i} {
|
||||
execsql "INSERT INTO t1 VALUES('x', 'y', 'z', $i, [expr $i/2])"
|
||||
}
|
||||
execsql COMMIT
|
||||
execsql ANALYZE
|
||||
} {}
|
||||
|
||||
do_eqp_test 9.3.1 {
|
||||
SELECT * FROM t1 WHERE a='x' AND b='y' AND c='z' AND d=101 AND e=5;
|
||||
} {/t1 USING INDEX i1/}
|
||||
do_eqp_test 9.3.2 {
|
||||
SELECT * FROM t1 WHERE a='x' AND b='y' AND c='z' AND d=99 AND e=5;
|
||||
} {/t1 USING INDEX i1/}
|
||||
|
||||
set value_d [expr 101]
|
||||
do_eqp_test 9.4.1 {
|
||||
SELECT * FROM t1 WHERE a='x' AND b='y' AND c='z' AND d=$value_d AND e=5
|
||||
} {/t1 USING INDEX i1/}
|
||||
set value_d [expr 99]
|
||||
do_eqp_test 9.4.2 {
|
||||
SELECT * FROM t1 WHERE a='x' AND b='y' AND c='z' AND d=$value_d AND e=5
|
||||
} {/t1 USING INDEX i1/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that the planner takes stat3 data into account when considering
|
||||
# "IS NULL" and "IS NOT NULL" constraints.
|
||||
#
|
||||
do_execsql_test 10.1.1 {
|
||||
DROP TABLE IF EXISTS t3;
|
||||
CREATE TABLE t3(a, b);
|
||||
CREATE INDEX t3a ON t3(a);
|
||||
CREATE INDEX t3b ON t3(b);
|
||||
}
|
||||
do_test 10.1.2 {
|
||||
for {set i 1} {$i < 100} {incr i} {
|
||||
if {$i>90} { set a $i } else { set a NULL }
|
||||
set b [expr $i % 5]
|
||||
execsql "INSERT INTO t3 VALUES($a, $b)"
|
||||
}
|
||||
execsql ANALYZE
|
||||
} {}
|
||||
do_eqp_test 10.1.3 {
|
||||
SELECT * FROM t3 WHERE a IS NULL AND b = 2
|
||||
} {/t3 USING INDEX t3b/}
|
||||
do_eqp_test 10.1.4 {
|
||||
SELECT * FROM t3 WHERE a IS NOT NULL AND b = 2
|
||||
} {/t3 USING INDEX t3a/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that stat3 data is used correctly with non-default collation
|
||||
# sequences.
|
||||
#
|
||||
foreach {tn schema} {
|
||||
1 {
|
||||
CREATE TABLE t4(a COLLATE nocase, b);
|
||||
CREATE INDEX t4a ON t4(a);
|
||||
CREATE INDEX t4b ON t4(b);
|
||||
}
|
||||
2 {
|
||||
CREATE TABLE t4(a, b);
|
||||
CREATE INDEX t4a ON t4(a COLLATE nocase);
|
||||
CREATE INDEX t4b ON t4(b);
|
||||
}
|
||||
} {
|
||||
drop_all_tables
|
||||
do_test 11.$tn.1 { execsql $schema } {}
|
||||
|
||||
do_test 11.$tn.2 {
|
||||
for {set i 0} {$i < 100} {incr i} {
|
||||
if { ($i % 10)==0 } { set a ABC } else { set a DEF }
|
||||
set b [expr $i % 5]
|
||||
execsql { INSERT INTO t4 VALUES($a, $b) }
|
||||
}
|
||||
execsql ANALYZE
|
||||
} {}
|
||||
|
||||
do_eqp_test 11.$tn.3 {
|
||||
SELECT * FROM t4 WHERE a = 'def' AND b = 3;
|
||||
} {/t4 USING INDEX t4b/}
|
||||
|
||||
if {$tn==1} {
|
||||
set sql "SELECT * FROM t4 WHERE a = 'abc' AND b = 3;"
|
||||
do_eqp_test 11.$tn.4 $sql {/t4 USING INDEX t4a/}
|
||||
} else {
|
||||
|
||||
set sql "SELECT * FROM t4 WHERE a = 'abc' COLLATE nocase AND b = 3;"
|
||||
do_eqp_test 11.$tn.5 $sql {/t4 USING INDEX t4a/}
|
||||
|
||||
set sql "SELECT * FROM t4 WHERE a COLLATE nocase = 'abc' AND b = 3;"
|
||||
do_eqp_test 11.$tn.6 $sql {/t4 USING INDEX t4a/}
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that nothing untoward happens if the stat3 table contains entries
|
||||
# for indexes that do not exist. Or NULL values in the idx column.
|
||||
# Or NULL values in any of the other columns.
|
||||
#
|
||||
drop_all_tables
|
||||
do_execsql_test 15.1 {
|
||||
CREATE TABLE x1(a, b, UNIQUE(a, b));
|
||||
INSERT INTO x1 VALUES(1, 2);
|
||||
INSERT INTO x1 VALUES(3, 4);
|
||||
INSERT INTO x1 VALUES(5, 6);
|
||||
ANALYZE;
|
||||
INSERT INTO sqlite_stat3 VALUES(NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
do_execsql_test 15.2 { SELECT * FROM x1 } {1 2 3 4 5 6}
|
||||
|
||||
do_execsql_test 15.3 {
|
||||
INSERT INTO sqlite_stat3 VALUES(42, 42, 42, 42, 42, 42);
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
do_execsql_test 15.4 { SELECT * FROM x1 } {1 2 3 4 5 6}
|
||||
|
||||
do_execsql_test 15.5 {
|
||||
UPDATE sqlite_stat1 SET stat = NULL;
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
do_execsql_test 15.6 { SELECT * FROM x1 } {1 2 3 4 5 6}
|
||||
|
||||
do_execsql_test 15.7 {
|
||||
ANALYZE;
|
||||
UPDATE sqlite_stat1 SET tbl = 'no such tbl';
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
do_execsql_test 15.8 { SELECT * FROM x1 } {1 2 3 4 5 6}
|
||||
|
||||
do_execsql_test 15.9 {
|
||||
ANALYZE;
|
||||
UPDATE sqlite_stat3 SET neq = NULL, nlt=NULL, ndlt=NULL;
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
do_execsql_test 15.10 { SELECT * FROM x1 } {1 2 3 4 5 6}
|
||||
|
||||
# This is just for coverage....
|
||||
do_execsql_test 15.11 {
|
||||
ANALYZE;
|
||||
UPDATE sqlite_stat1 SET stat = stat || ' unordered';
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
do_execsql_test 15.12 { SELECT * FROM x1 } {1 2 3 4 5 6}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that allocations used for sqlite_stat3 samples are included in
|
||||
# the quantity returned by SQLITE_DBSTATUS_SCHEMA_USED.
|
||||
#
|
||||
set one [string repeat x 1000]
|
||||
set two [string repeat x 2000]
|
||||
do_test 16.1 {
|
||||
reset_db
|
||||
execsql {
|
||||
CREATE TABLE t1(a, UNIQUE(a));
|
||||
INSERT INTO t1 VALUES($one);
|
||||
ANALYZE;
|
||||
}
|
||||
set nByte [lindex [sqlite3_db_status db SCHEMA_USED 0] 1]
|
||||
|
||||
reset_db
|
||||
execsql {
|
||||
CREATE TABLE t1(a, UNIQUE(a));
|
||||
INSERT INTO t1 VALUES($two);
|
||||
ANALYZE;
|
||||
}
|
||||
set nByte2 [lindex [sqlite3_db_status db SCHEMA_USED 0] 1]
|
||||
|
||||
expr {$nByte2 > $nByte+950 && $nByte2 < $nByte+1050}
|
||||
} {1}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that stat3 data may be used with partial indexes.
|
||||
#
|
||||
do_test 17.1 {
|
||||
reset_db
|
||||
execsql {
|
||||
CREATE TABLE t1(a, b, c, d);
|
||||
CREATE INDEX i1 ON t1(a, b) WHERE d IS NOT NULL;
|
||||
INSERT INTO t1 VALUES(-1, -1, -1, NULL);
|
||||
INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
|
||||
INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
|
||||
INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
|
||||
INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
|
||||
INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
|
||||
INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
|
||||
}
|
||||
|
||||
for {set i 0} {$i < 32} {incr i} {
|
||||
execsql { INSERT INTO t1 VALUES($i%2, $b, $i/2, 'abc') }
|
||||
}
|
||||
execsql {ANALYZE main.t1}
|
||||
} {}
|
||||
|
||||
do_catchsql_test 17.1.2 {
|
||||
ANALYZE temp.t1;
|
||||
} {1 {no such table: temp.t1}}
|
||||
|
||||
do_eqp_test 17.2 {
|
||||
SELECT * FROM t1 WHERE d IS NOT NULL AND a=0;
|
||||
} {/USING INDEX i1/}
|
||||
do_eqp_test 17.3 {
|
||||
SELECT * FROM t1 WHERE d IS NOT NULL AND a=0;
|
||||
} {/USING INDEX i1/}
|
||||
|
||||
do_execsql_test 17.4 {
|
||||
CREATE INDEX i2 ON t1(c) WHERE d IS NOT NULL;
|
||||
ANALYZE main.i2;
|
||||
}
|
||||
do_eqp_test 17.5 {
|
||||
SELECT * FROM t1 WHERE d IS NOT NULL AND a=0;
|
||||
} {/USING INDEX i1/}
|
||||
do_eqp_test 17.6 {
|
||||
SELECT * FROM t1 WHERE d IS NOT NULL AND a=0 AND b=0 AND c=10;
|
||||
} {/USING INDEX i2/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
do_test 18.1 {
|
||||
reset_db
|
||||
execsql {
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE INDEX i1 ON t1(a, b);
|
||||
}
|
||||
for {set i 0} {$i < 9} {incr i} {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES($i, 0);
|
||||
INSERT INTO t1 VALUES($i, 0);
|
||||
INSERT INTO t1 VALUES($i, 0);
|
||||
INSERT INTO t1 VALUES($i, 0);
|
||||
INSERT INTO t1 VALUES($i, 0);
|
||||
INSERT INTO t1 VALUES($i, 0);
|
||||
INSERT INTO t1 VALUES($i, 0);
|
||||
INSERT INTO t1 VALUES($i, 0);
|
||||
INSERT INTO t1 VALUES($i, 0);
|
||||
INSERT INTO t1 VALUES($i, 0);
|
||||
INSERT INTO t1 VALUES($i, 0);
|
||||
INSERT INTO t1 VALUES($i, 0);
|
||||
INSERT INTO t1 VALUES($i, 0);
|
||||
INSERT INTO t1 VALUES($i, 0);
|
||||
INSERT INTO t1 VALUES($i, 0);
|
||||
}
|
||||
}
|
||||
execsql ANALYZE
|
||||
execsql { SELECT count(*) FROM sqlite_stat3 }
|
||||
} {9}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# For coverage.
|
||||
#
|
||||
ifcapable view {
|
||||
do_test 19.1 {
|
||||
reset_db
|
||||
execsql {
|
||||
CREATE TABLE t1(x, y);
|
||||
CREATE INDEX i1 ON t1(x, y);
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
ANALYZE;
|
||||
}
|
||||
} {}
|
||||
}
|
||||
ifcapable auth {
|
||||
proc authproc {op args} {
|
||||
if {$op == "SQLITE_ANALYZE"} { return "SQLITE_DENY" }
|
||||
return "SQLITE_OK"
|
||||
}
|
||||
do_test 19.2 {
|
||||
reset_db
|
||||
db auth authproc
|
||||
execsql {
|
||||
CREATE TABLE t1(x, y);
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
}
|
||||
catchsql ANALYZE
|
||||
} {1 {not authorized}}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
proc r {args} { expr rand() }
|
||||
db func r r
|
||||
db func lrange lrange
|
||||
do_test 20.1 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a,b,c,d);
|
||||
CREATE INDEX i1 ON t1(a,b,c,d);
|
||||
}
|
||||
for {set i 0} {$i < 16} {incr i} {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES($i, r(), r(), r());
|
||||
INSERT INTO t1 VALUES($i, $i, r(), r());
|
||||
INSERT INTO t1 VALUES($i, $i, $i, r());
|
||||
INSERT INTO t1 VALUES($i, $i, $i, $i);
|
||||
INSERT INTO t1 VALUES($i, $i, $i, $i);
|
||||
INSERT INTO t1 VALUES($i, $i, $i, r());
|
||||
INSERT INTO t1 VALUES($i, $i, r(), r());
|
||||
INSERT INTO t1 VALUES($i, r(), r(), r());
|
||||
}
|
||||
}
|
||||
} {}
|
||||
do_execsql_test 20.2 { ANALYZE }
|
||||
for {set i 0} {$i<16} {incr i} {
|
||||
set val $i
|
||||
do_execsql_test 20.3.$i {
|
||||
SELECT count(*) FROM sqlite_stat3 WHERE sample=$val
|
||||
} {1}
|
||||
}
|
||||
|
||||
finish_test
|
||||
@@ -132,6 +132,20 @@ do_execsql_test 4.3 {
|
||||
SELECT count(a) FROM t1;
|
||||
} {/.*INDEX t1ca.*/}
|
||||
|
||||
# 2019-08-15.
|
||||
# Ticket https://www.sqlite.org/src/tktview/e4598ecbdd18bd82945f602901
|
||||
# The sz=N parameter in the sqlite_stat1 table needs to have a value of
|
||||
# 2 or more to avoid a division by zero in the query planner.
|
||||
#
|
||||
do_execsql_test 4.4 {
|
||||
DROP TABLE IF EXISTS t44;
|
||||
CREATE TABLE t44(a PRIMARY KEY);
|
||||
INSERT INTO sqlite_stat1 VALUES('t44',null,'sz=0');
|
||||
ANALYZE sqlite_master;
|
||||
SELECT 0 FROM t44 WHERE a IN(1,2,3);
|
||||
} {}
|
||||
|
||||
|
||||
|
||||
# The sz=NNN parameter works even if there is other extraneous text
|
||||
# in the sqlite_stat1.stat column.
|
||||
|
||||
+1
-5
@@ -2450,11 +2450,7 @@ ifcapable compound&&subquery {
|
||||
ifcapable stat4 {
|
||||
set stat4 "sqlite_stat4 "
|
||||
} else {
|
||||
ifcapable stat3 {
|
||||
set stat4 "sqlite_stat3 "
|
||||
} else {
|
||||
set stat4 ""
|
||||
}
|
||||
set stat4 ""
|
||||
}
|
||||
do_test auth-5.2 {
|
||||
execsql {
|
||||
|
||||
@@ -495,4 +495,34 @@ do_execsql_test 10.1 {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 11.0 {
|
||||
CREATE TABLE t1 (Col0 CHECK(1 COLLATE BINARY BETWEEN 1 AND 1) ) ;
|
||||
}
|
||||
do_execsql_test 11.1 {
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
}
|
||||
do_execsql_test 11.2 {
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
}
|
||||
|
||||
do_execsql_test 11.3 {
|
||||
CREATE TABLE t2(b, a CHECK(
|
||||
CASE 'abc' COLLATE nocase WHEN a THEN 1 ELSE 0 END)
|
||||
);
|
||||
}
|
||||
do_execsql_test 11.4 {
|
||||
INSERT INTO t2(a) VALUES('abc');
|
||||
}
|
||||
do_execsql_test 11.5 {
|
||||
INSERT INTO t2(b, a) VALUES(1, 'abc'||'');
|
||||
}
|
||||
do_execsql_test 11.6 {
|
||||
INSERT INTO t2(b, a) VALUES(2, 'abc');
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# 2019 July 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 contains fault-injection test cases for the
|
||||
# sqlite3_db_cacheflush API.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix cffault
|
||||
source $testdir/malloc_common.tcl
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1 (Col0 CHECK(1 COLLATE BINARY BETWEEN 1 AND 1) ) ;
|
||||
CREATE TABLE t2(b, a CHECK(
|
||||
CASE 'abc' COLLATE nocase WHEN a THEN 1 ELSE 0 END)
|
||||
);
|
||||
}
|
||||
|
||||
do_faultsim_test 1.1 -faults oom* -body {
|
||||
execsql { INSERT INTO t1 VALUES ('ABCDEFG') }
|
||||
} -test {
|
||||
faultsim_test_result {0 {}}
|
||||
}
|
||||
|
||||
do_faultsim_test 1.2 -faults oom* -body {
|
||||
execsql { INSERT INTO t2(a) VALUES('abc') }
|
||||
} -test {
|
||||
faultsim_test_result {0 {}}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user