merge from trunk

FossilOrigin-Name: 19ffe3cfe278a4046f32df56f75080c2377e4c44ad40a02d39db8e7701526204
This commit is contained in:
larrybr 2021-05-19 19:55:10 +00:00
commit 4f878f33a9
69 changed files with 1827 additions and 970 deletions

View File

@ -616,12 +616,10 @@ SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS3_PARENTHESIS
#FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS5
@ -695,7 +693,6 @@ dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h
DBFUZZ2_OPTS = \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_ENABLE_DESERIALIZE \
-DSQLITE_DEBUG \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_BYTECODE_VTAB \
@ -1235,7 +1232,6 @@ TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_BYTECODE_VTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DESERIALIZE
TESTFIXTURE_FLAGS += -DSQLITE_CKSUMVFS_STATIC
TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
@ -1431,6 +1427,9 @@ threadtest3$(TEXE): sqlite3.lo $(THREADTEST3_SRC)
threadtest: threadtest3$(TEXE)
./threadtest3$(TEXE)
threadtest5: sqlite3.c $(TOP)/test/threadtest5.c
$(LTLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(TLIBS)
releasetest:
$(TCLSH_CMD) $(TOP)/test/releasetest.tcl
@ -1484,6 +1483,7 @@ clean:
rm -f sqldiff sqldiff.exe
rm -f dbhash dbhash.exe
rm -f fts5.* fts5parse.*
rm -f threadtest5
distclean: clean
rm -f config.h config.log config.status libtool Makefile sqlite3.pc

View File

@ -367,7 +367,6 @@ 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_ENABLE_BYTECODE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF
@ -1689,7 +1688,6 @@ FUZZDATA = \
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
# <<mark>>
@ -1698,7 +1696,6 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DESERIALIZE=1
MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_GEOPOLY
@ -2392,7 +2389,6 @@ TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CKSUMVFS_STATIC=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)

View File

@ -290,7 +290,6 @@ 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_ENABLE_BYTECODE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF
@ -960,7 +959,6 @@ LIBRESOBJS =
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF

View File

@ -1899,7 +1899,7 @@ static int fts3ScanInteriorNode(
char *zBuffer = 0; /* Buffer to load terms into */
i64 nAlloc = 0; /* Size of allocated buffer */
int isFirstTerm = 1; /* True when processing first term on page */
sqlite3_int64 iChild; /* Block id of child node to descend to */
u64 iChild; /* Block id of child node to descend to */
int nBuffer = 0; /* Total term size */
/* Skip over the 'height' varint that occurs at the start of every
@ -1915,8 +1915,8 @@ static int fts3ScanInteriorNode(
** table, then there are always 20 bytes of zeroed padding following the
** nNode bytes of content (see sqlite3Fts3ReadBlock() for details).
*/
zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
zCsr += sqlite3Fts3GetVarintU(zCsr, &iChild);
zCsr += sqlite3Fts3GetVarintU(zCsr, &iChild);
if( zCsr>zEnd ){
return FTS_CORRUPT_VTAB;
}
@ -1969,20 +1969,20 @@ static int fts3ScanInteriorNode(
*/
cmp = memcmp(zTerm, zBuffer, (nBuffer>nTerm ? nTerm : nBuffer));
if( piFirst && (cmp<0 || (cmp==0 && nBuffer>nTerm)) ){
*piFirst = iChild;
*piFirst = (i64)iChild;
piFirst = 0;
}
if( piLast && cmp<0 ){
*piLast = iChild;
*piLast = (i64)iChild;
piLast = 0;
}
iChild++;
};
if( piFirst ) *piFirst = iChild;
if( piLast ) *piLast = iChild;
if( piFirst ) *piFirst = (i64)iChild;
if( piLast ) *piLast = (i64)iChild;
finish_scan:
sqlite3_free(zBuffer);

View File

@ -431,7 +431,7 @@ struct Fts5SegIter {
int iLeafPgno; /* Current leaf page number */
Fts5Data *pLeaf; /* Current leaf data */
Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */
int iLeafOffset; /* Byte offset within current leaf */
i64 iLeafOffset; /* Byte offset within current leaf */
/* Next method */
void (*xNext)(Fts5Index*, Fts5SegIter*, int*);
@ -1611,7 +1611,7 @@ static void fts5SegIterLoadNPos(Fts5Index *p, Fts5SegIter *pIter){
static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){
u8 *a = pIter->pLeaf->p; /* Buffer to read data from */
int iOff = pIter->iLeafOffset;
i64 iOff = pIter->iLeafOffset;
ASSERT_SZLEAF_OK(pIter->pLeaf);
if( iOff>=pIter->pLeaf->szLeaf ){
@ -1644,7 +1644,7 @@ static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){
*/
static void fts5SegIterLoadTerm(Fts5Index *p, Fts5SegIter *pIter, int nKeep){
u8 *a = pIter->pLeaf->p; /* Buffer to read data from */
int iOff = pIter->iLeafOffset; /* Offset to read at */
i64 iOff = pIter->iLeafOffset; /* Offset to read at */
int nNew; /* Bytes of new data */
iOff += fts5GetVarint32(&a[iOff], nNew);
@ -2072,7 +2072,6 @@ static void fts5SegIterNext(
** this block is particularly performance critical, so equivalent
** code is inlined. */
int nSz;
assert( p->rc==SQLITE_OK );
assert_nc( pIter->iLeafOffset<=pIter->pLeaf->nn );
fts5FastGetVarint32(pIter->pLeaf->p, pIter->iLeafOffset, nSz);
pIter->bDel = (nSz & 0x0001);

View File

@ -14793,6 +14793,135 @@ do_catchsql_test 75.1 {
SELECT rowid, quote(matchinfo(t1,'pcxybs')) FROM t1 WHERE t1 MATCH 'e*';
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_test 76.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 40960 pagesize 4096 filename crash-03b68c01d30713.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 0a .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 0d 00 00 00 04 ................
| 96: 00 00 00 00 0d 00 00 00 0d 0b 6e 00 0f a3 0f 4c ..........n....L
| 112: 0e e1 0e 81 0e 24 0d cc 0d 72 0d 1b 0c b0 0c 50 .....$...r.....P
| 128: 0b f8 0b b3 0b 6e 01 00 00 00 00 00 00 00 00 00 .....n..........
| 2912: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 43 0d ..............C.
| 2928: 06 17 11 11 08 75 74 61 62 6c 65 74 34 74 34 43 .....utablet4t4C
| 2944: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 REATE VIRTUAL TA
| 2960: 42 4c 45 20 74 34 20 55 53 49 4e 47 20 66 74 73 BLE t4 USING fts
| 2976: 35 76 6f 63 61 62 28 27 74 32 27 2c 20 27 72 6f 5vocab('t2', 'ro
| 2992: 77 27 29 43 0c 06 17 11 11 08 75 74 61 62 6c 65 w')C......utable
| 3008: 74 33 74 33 43 52 45 41 54 45 20 56 49 52 54 55 t3t3CREATE VIRTU
| 3024: 41 4c 20 54 41 42 4c 45 20 74 33 20 55 53 49 4e AL TABLE t3 USIN
| 3040: 47 20 66 74 73 35 76 6f 63 61 62 28 27 74 31 27 G fts5vocab('t1'
| 3056: 2c 20 27 72 6f 77 27 29 56 0b 06 17 1f 1f 01 7d , 'row')V.......
| 3072: 74 61 62 6c 65 74 32 5f 63 6f 6e 66 69 67 74 32 tablet2_configt2
| 3088: 5f 63 6f 6e 66 69 67 0a 43 52 45 41 54 45 20 54 _config.CREATE T
| 3104: 41 42 4c 45 20 27 74 32 5f 63 6f 6e 66 69 67 27 ABLE 't2_config'
| 3120: 28 6b 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 (k PRIMARY KEY,
| 3136: 76 29 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 v) WITHOUT ROWID
| 3152: 5e 0a 07 17 21 21 01 81 07 74 61 62 6c 65 74 32 ^...!!...tablet2
| 3168: 5f 63 6f 6e 74 65 6e 74 74 32 5f 63 6f 6e 74 65 _contentt2_conte
| 3184: 6e 74 09 43 52 45 41 54 45 20 54 41 42 4c 45 20 nt.CREATE TABLE
| 3200: 27 74 32 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20 't2_content'(id
| 3216: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INTEGER PRIMARY
| 3232: 4b 45 59 2c 20 63 30 2c 20 63 31 2c 20 63 32 29 KEY, c0, c1, c2)
| 3248: 69 09 07 17 19 19 01 81 2d 74 61 62 6c 65 74 32 i.......-tablet2
| 3264: 5f 69 64 78 74 32 5f 69 64 78 08 43 52 45 41 54 _idxt2_idx.CREAT
| 3280: 45 20 54 41 42 4c 45 20 27 74 32 5f 69 64 78 27 E TABLE 't2_idx'
| 3296: 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 67 (segid, term, pg
| 3312: 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 no, PRIMARY KEY(
| 3328: 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 segid, term)) WI
| 3344: 54 48 4f 55 54 20 52 4f 57 49 44 55 08 07 17 1b THOUT ROWIDU....
| 3360: 1b 01 81 01 74 61 62 6c 65 74 32 5f 64 61 74 61 ....tablet2_data
| 3376: 74 32 5f 64 61 74 61 07 43 52 45 41 54 45 20 54 t2_data.CREATE T
| 3392: 41 42 4c 45 20 27 74 32 5f 64 61 74 61 27 28 69 ABLE 't2_data'(i
| 3408: 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 d INTEGER PRIMAR
| 3424: 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f Y KEY, block BLO
| 3440: 42 29 58 07 07 17 11 11 08 81 1d 74 61 62 6c 65 B)X........table
| 3456: 74 32 74 32 43 52 45 41 54 45 20 56 49 52 54 55 t2t2CREATE VIRTU
| 3472: 41 4c 20 54 41 42 4c 45 20 74 32 20 55 53 49 4e AL TABLE t2 USIN
| 3488: 47 20 66 74 73 35 28 27 61 27 2c 5b 62 5d 2c 22 G fts5('a',[b],.
| 3504: 63 22 2c 64 65 74 61 69 6c 3d 6e 6f 6e 65 2c 63 c.,detail=none,c
| 3520: 6f 6c 75 6d 6e 73 69 7a 65 3d 30 29 56 06 06 17 olumnsize=0)V...
| 3536: 1f 1f 01 7d 74 61 62 6c 65 74 31 5f 63 6f 6e 66 ....tablet1_conf
| 3552: 69 67 74 31 5f 63 6f 6e 66 69 67 06 43 52 45 41 igt1_config.CREA
| 3568: 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f 6e TE TABLE 't1_con
| 3584: 66 69 67 27 28 6b 20 50 52 49 4d 41 52 59 20 4b fig'(k PRIMARY K
| 3600: 45 59 2c 20 76 29 20 57 49 54 48 4f 55 54 20 52 EY, v) WITHOUT R
| 3616: 4f 57 49 44 5b 05 07 17 21 21 01 81 01 74 61 62 OWID[...!!...tab
| 3632: 6c 65 74 31 5f 64 6f 63 73 69 7a 65 74 31 5f 64 let1_docsizet1_d
| 3648: 6f 63 73 69 7a 65 05 43 52 45 41 54 45 20 54 41 ocsize.CREATE TA
| 3664: 42 4c 45 20 27 74 31 5f 64 6f 63 73 69 7a 65 27 BLE 't1_docsize'
| 3680: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (id INTEGER PRIM
| 3696: 41 52 59 20 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 ARY KEY, sz BLOB
| 3712: 29 5e 04 07 17 21 21 01 81 07 74 61 62 6c 65 74 )^...!!...tablet
| 3728: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74 1_contentt1_cont
| 3744: 65 6e 74 04 43 52 45 41 54 45 20 54 41 42 4c 45 ent.CREATE TABLE
| 3760: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 69 64 't1_content'(id
| 3776: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 INTEGER PRIMARY
| 3792: 20 4b 45 59 2c 20 63 30 2c 20 63 31 2c 20 63 32 KEY, c0, c1, c2
| 3808: 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65 74 )i.......-tablet
| 3824: 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45 41 1_idxt1_idx.CREA
| 3840: 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64 78 TE TABLE 't1_idx
| 3856: 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 '(segid, term, p
| 3872: 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 gno, PRIMARY KEY
| 3888: 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 (segid, term)) W
| 3904: 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07 17 ITHOUT ROWIDU...
| 3920: 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61 74 .....tablet1_dat
| 3936: 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45 20 at1_data.CREATE
| 3952: 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27 28 TABLE 't1_data'(
| 3968: 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 id INTEGER PRIMA
| 3984: 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c RY KEY, block BL
| 4000: 4f 42 29 5b 01 07 17 11 11 08 81 23 74 61 62 6c OB)[.......#tabl
| 4016: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54 et1t1CREATE VIRT
| 4032: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49 UAL TABLE t1 USI
| 4048: 4e 47 20 66 74 73 35 28 61 2c 62 20 75 6e 69 65 NG fts5(a,b unie
| 4064: 24 65 78 65 64 2c 63 2c 74 6f 6b 65 6e 69 7a 65 $exed,c,tokenize
| 4080: 3d 22 70 6f 72 74 65 72 20 61 73 63 69 69 22 29 =.porter ascii.)
| page 2 offset 4096
| 0: 0d 0f 68 00 05 0f 13 00 0f e6 0f 13 0f a8 00 00 ..h.............
| 3856: 00 00 00 15 0a 03 00 30 00 00 00 00 01 03 03 00 .......0........
| 3872: 03 01 01 01 02 01 01 03 01 01 37 8c 80 80 80 80 ..........7.....
| 3888: 01 03 00 74 00 20 68 20 69 0d 00 00 00 03 0f e8 ...t. h i.......
| page 5 offset 16384
| 4064: 00 00 00 00 00 00 00 00 06 03 03 00 12 03 00 00 ................
| 4080: 60 20 30 d6 20 30 00 30 60 10 30 01 20 30 00 30 ` 0. 0.0`.0. 0.0
| page 6 offset 20480
| 0: a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
| page 7 offset 24576
| 0: 0d 00 00 00 03 0f 9e 00 0f e6 0f ef 0f 9e 00 00 ................
| 16: 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 3984: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 84 ..............A.
| 4000: 80 80 80 80 01 04 00 81 06 00 00 00 34 02 30 61 ............4.0a
| 4016: 01 00 ff ff ff ff ff ff ff ff ff 11 87 89 06 26 ...............&
| 4032: 01 64 01 01 01 65 01 01 01 66 01 01 01 66 01 01 .d...e...f...f..
| 4048: 01 01 01 68 01 01 01 01 01 69 01 01 01 04 01 56 ...h.....i.....V
| 4064: 06 04 44 00 06 06 07 01 03 00 14 03 09 09 09 0f ..D.............
| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
| page 8 offset 28672
| 0: 0a 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 1c 01 02 ................
| page 9 offset 32768
| 0: 0d 00 00 00 9d 0f be 00 0f ea 0f d4 0f be 00 00 ................
| 4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 14 03 ................
| 4032: 05 00 17 17 17 61 20 62 20 63 67 20 68 20 69 67 .....a b cg h ig
| 4048: 20 68 20 69 14 02 05 00 17 17 17 67 20 68 20 69 h i.......g h i
| 4064: 61 20 62 20 63 67 20 68 20 69 14 01 04 ff 17 17 a b cg h i......
| 4080: 17 61 20 62 20 63 64 20 65 20 66 67 20 68 20 69 .a b cd e fg h i
| page 10 offset 36864
| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 01 ................
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
| end crash-03b68c01d30713.db
}]} {}
do_catchsql_test 76.1 {
SELECT * FROM t4;
} {1 {database disk image is malformed}}
sqlite3_fts5_may_be_corrupt 0
finish_test

View File

@ -579,6 +579,18 @@ static int cksmFileControl(sqlite3_file *pFile, int op, void *pArg){
}else if( op==SQLITE_FCNTL_CKPT_START || op==SQLITE_FCNTL_CKPT_DONE ){
p->inCkpt = op==SQLITE_FCNTL_CKPT_START;
if( p->pPartner ) p->pPartner->inCkpt = p->inCkpt;
}else if( op==SQLITE_FCNTL_CKSM_FILE ){
/* This VFS needs to obtain a pointer to the corresponding database
** file handle from within xOpen() calls to open wal files. To do this,
** it uses the sqlite3_database_file_object() API to obtain a pointer
** to the file-handle used by SQLite to access the db file. This is
** fine if cksmvfs happens to be the top-level VFS, but not if there
** are one or more wrapper VFS. To handle this case, this file-control
** is used to extract the cksmvfs file-handle from any wrapper file
** handle. */
sqlite3_file **ppFile = (sqlite3_file**)pArg;
*ppFile = (sqlite3_file*)p;
return SQLITE_OK;
}
rc = pFile->pMethods->xFileControl(pFile, op, pArg);
if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
@ -688,6 +700,8 @@ static int cksmOpen(
if( rc ) goto cksm_open_done;
if( flags & SQLITE_OPEN_WAL ){
sqlite3_file *pDb = sqlite3_database_file_object(zName);
rc = pDb->pMethods->xFileControl(pDb, SQLITE_FCNTL_CKSM_FILE, (void*)&pDb);
assert( rc==SQLITE_OK );
p->pPartner = (CksmFile*)pDb;
assert( p->pPartner->pPartner==0 );
p->pPartner->pPartner = p;

View File

@ -459,10 +459,11 @@ static void decimalSubFunc(
Decimal *pA = decimal_new(context, argv[0], 0, 0);
Decimal *pB = decimal_new(context, argv[1], 0, 0);
UNUSED_PARAMETER(argc);
if( pB==0 ) return;
pB->sign = !pB->sign;
decimal_add(pA, pB);
decimal_result(context, pA);
if( pB ){
pB->sign = !pB->sign;
decimal_add(pA, pB);
decimal_result(context, pA);
}
decimal_free(pA);
decimal_free(pB);
}

View File

@ -299,7 +299,7 @@ static void jsonAppendSeparator(JsonString *p){
*/
static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
u32 i;
if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
if( zIn==0 || ((N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0) ) return;
p->zBuf[p->nUsed++] = '"';
for(i=0; i<N; i++){
unsigned char c = ((unsigned const char*)zIn)[i];

View File

@ -132,6 +132,11 @@ foreach {tn3 create_vfs destroy_vfs} {
} {
sqlite3rbu_destroy_vfs myrbu
}
3 {
sqlite3_register_cksumvfs
} {
sqlite3_unregister_cksumvfs
}
} {
eval $create_vfs

View File

@ -1620,7 +1620,9 @@ char *rbuVacuumIndexStart(
zSep = "";
for(iCol=0; iCol<pIter->nCol; iCol++){
const char *zQuoted = (const char*)sqlite3_column_text(pSel, iCol);
if( zQuoted[0]=='N' ){
if( zQuoted==0 ){
p->rc = SQLITE_NOMEM;
}else if( zQuoted[0]=='N' ){
bFailed = 1;
break;
}
@ -4992,28 +4994,14 @@ static int rbuVfsOpen(
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0);
if( pDb ){
if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
/* This call is to open a *-wal file. Intead, open the *-oal. This
** code ensures that the string passed to xOpen() is terminated by a
** pair of '\0' bytes in case the VFS attempts to extract a URI
** parameter from it. */
const char *zBase = zName;
size_t nCopy;
char *zCopy;
/* This call is to open a *-wal file. Intead, open the *-oal. */
size_t nOpen;
if( rbuIsVacuum(pDb->pRbu) ){
zBase = sqlite3_db_filename(pDb->pRbu->dbRbu, "main");
zBase = sqlite3_filename_wal(zBase);
}
nCopy = strlen(zBase);
zCopy = sqlite3_malloc64(nCopy+2);
if( zCopy ){
memcpy(zCopy, zBase, nCopy);
zCopy[nCopy-3] = 'o';
zCopy[nCopy] = '\0';
zCopy[nCopy+1] = '\0';
zOpen = (const char*)(pFd->zDel = zCopy);
}else{
rc = SQLITE_NOMEM;
zOpen = sqlite3_db_filename(pDb->pRbu->dbRbu, "main");
zOpen = sqlite3_filename_wal(zOpen);
}
nOpen = strlen(zOpen);
((char*)zOpen)[nOpen-3] = 'o';
pFd->pRbu = pDb->pRbu;
}
pDb->pWalFd = pFd;

View File

@ -86,14 +86,11 @@ void sqlite3session_delete(sqlite3_session *pSession);
** This method is used to configure a session object after it has been
** created. At present the only valid value for the second parameter is
** [SQLITE_SESSION_OBJCONFIG_SIZE].
*/
int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
/*
** CAPI3REF: Arguments for sqlite3session_object_config()
**
** Arguments for sqlite3session_object_config()
**
** The following values may passed as the the 4th parameter to
** [sqlite3session_object_config].
** sqlite3session_object_config().
**
** <dt>SQLITE_SESSION_OBJCONFIG_SIZE <dd>
** This option is used to set, clear or query the flag that enables
@ -109,6 +106,10 @@ int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
** It is an error (SQLITE_MISUSE) to attempt to modify this setting after
** the first table has been attached to the session object.
*/
int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
/*
*/
#define SQLITE_SESSION_OBJCONFIG_SIZE 1
/*
@ -356,11 +357,11 @@ int sqlite3session_changeset(
/*
** CAPI3REF: Return An Upper-limit For The Size Of The Changeset
** METHOD: sqlite3session_changeset_size()
** METHOD: sqlite3_session
**
** By default, this function always returns 0. For it to return
** a useful result, the sqlite3_session object must have been configured
** to enable this API using [sqlite3session_object_config()] with the
** to enable this API using sqlite3session_object_config() with the
** SQLITE_SESSION_OBJCONFIG_SIZE verb.
**
** When enabled, this function returns an upper limit, in bytes, for the size

View File

@ -539,7 +539,6 @@ FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPT += -DSQLITE_ENABLE_GEOPOLY
@ -592,7 +591,6 @@ dbfuzz$(EXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h
DBFUZZ2_OPTS = \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_ENABLE_DESERIALIZE \
-DSQLITE_DEBUG \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_BYTECODE_VTAB \
@ -1081,6 +1079,9 @@ rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o
loadfts: $(TOP)/tool/loadfts.c libsqlite3.a
$(TCC) $(TOP)/tool/loadfts.c libsqlite3.a -o loadfts $(THREADLIB)
threadtest5: $(TOP)/test/threadtest5.c libsqlite3.a
$(TCC) $(TOP)/test/threadtest5.c libsqlite3.a -o threadtest5 $(THREADLIB)
# This target will fail if the SQLite amalgamation contains any exported
# symbols that do not begin with "sqlite3_". It is run as part of the
# releasetest.tcl script.
@ -1143,3 +1144,4 @@ clean:
rm -f sqldiff sqldiff.exe
rm -f fts5.* fts5parse.*
rm -f lsm.h lsm1.c
rm -f threadtest5

141
manifest
View File

@ -1,11 +1,11 @@
C merge\slatest\strunk
D 2021-04-27T04:47:27.151
C merge\sfrom\strunk
D 2021-05-19T19:55:10.206
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F Makefile.in 3f76d8a9b0e78aa7b627ad56cab35908d99909de51dcb90b1e6a29eb4fd4394a
F Makefile.in 30c6d39386246695e951a676973e0bf57aabbd1e37024c07e657af89dd332555
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
F Makefile.msc 231cf3fbc7bab3cc1801b3bf6a006098e9dfeca00d4d0910aad74795d0f94d5f
F Makefile.msc 6443729ba6a013a0fea4f999b22e54760f36e73c2e691554f0c4bfa1dbe4d070
F README.md 2a71913f398ecac5f3e10945fcf438aed425c2e9ed9874de561156ba77fb7023
F VERSION 8c392f6d70d82e513a0eac622bdf23c43df3e084cb630288beba8cef3012c812
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
@ -15,7 +15,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
F autoconf/Makefile.am a8d1d24affe52ebf8d7ddcf91aa973fa0316618ab95bb68c87cabf8faf527dc8
F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac
F autoconf/Makefile.msc ebe7e66edbb2f453593cbde186d1a0fa0dcd8cae9977febcae27aef1dab5678d
F autoconf/Makefile.msc d146a08ebbdf7f881ba600a49cd8dce40c4c807addcdb4b9b6a507e4b40ce837
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1
F autoconf/configure.ac a8ba2a9e61216f5093d44f3b7d2cb8fe1890d6b7dc330a02f802d8efaa1fdc79
@ -84,7 +84,7 @@ F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c 1d80d0a1e53ce5e7316e1379969c842079c46237369e131fd378288e64ebbf5f
F ext/fts3/fts3.c 95f55e24550c01c2a325d09c9ea8fdff61e923a4675f8545b28bf3c470e57dfb
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h bde280294d56ff50ee29d03e5140f0b6953b44d1c969bb5831e8ae85e3e76715
F ext/fts3/fts3_aux.c 1af58af8f2b00a49f4fb1c2602f8da2054ad60076f46c8ebf85c5410eccccb65
@ -119,7 +119,7 @@ F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6
F ext/fts5/fts5_config.c 8336d0ff6db0933f63cfec8ae0ab76e68393259cbccc0b46e1f79f7fa1842ff3
F ext/fts5/fts5_expr.c 9462249a3bb82d0e49b163500f9d2197c2e4cd95bf440a9bbfc3906b22ea1e1b
F ext/fts5/fts5_hash.c 1aa93c9b5f461afba66701ee226297dc78402b3bdde81e90a10de5fe3df14959
F ext/fts5/fts5_index.c 345824b780672465f786a65f348321f1e100880961e682273230eba65b795b62
F ext/fts5/fts5_index.c 222b5e56f51139ca5400985e26ea9971165901c7a45a2c17499bd2be3695c697
F ext/fts5/fts5_main.c f497ca97cb2802311ec93733b595762dc5b044ce3c6c8ce5fb3e871dd3fccd5d
F ext/fts5/fts5_storage.c 58ba71e6cd3d43a5735815e7956ee167babb4d2cbfe206905174792af4d09d75
F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae
@ -160,7 +160,7 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0
F ext/fts5/test/fts5content.test 213506436fb2c87567b8e31f6d43ab30aab99354cec74ed679f22aad0cdbf283
F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe
F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f
F ext/fts5/test/fts5corrupt3.test 04dde67b3ecff4206a86e02d082b41a5706c88238f0bee139d950dc5c74bbba6
F ext/fts5/test/fts5corrupt3.test 7748c28d0a0c8f00e7741a097df7c76eed207b5443908621dd1ce1dd23b84a07
F ext/fts5/test/fts5corrupt4.test f4c08e2182a48d8b70975fd869ee5391855c06d8a0ff87b6a2529e7c5a88a1d3
F ext/fts5/test/fts5delete.test 619295b20dbc1d840b403ee07c878f52378849c3c02e44f2ee143b3e978a0aa7
F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e
@ -291,21 +291,21 @@ F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0e
F ext/misc/btreeinfo.c d28ce349b40054eaa9473e835837bad7a71deec33ba13e39f963d50933bfa0f9
F ext/misc/carray.c b75a0f207391038bf1540d3372f482a95c3613511c7c474db51ede1196321c7c
F ext/misc/carray.h de74ac70b2338f416723f7d538026e8ec0b7f1d388319f8f140c9a4d7677f02e
F ext/misc/cksumvfs.c 8dc4e1b718e374bed3a9b5c0a08da2922438002e33267311697768e06217b983
F ext/misc/cksumvfs.c 2c6b07714f3be6c1200671c53aa781a86d2c472c0fcb2fff520375362eb94303
F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243
F ext/misc/completion.c 6dafd7f4348eecc7be9e920d4b419d1fb2af75d938cd9c59a20cfe8beb2f22b9
F ext/misc/compress.c 3354c77a7c8e86e07d849916000cdac451ed96500bfb5bd83b20eb61eee012c9
F ext/misc/csv.c 53b3338d4fa812eda51a2637df30233a4dae16b964ee5666e2051b9672ed8bb4
F ext/misc/dbdata.c e316fba936571584e55abd5b974a32a191727a6b746053a0c9d439bd2cf93940
F ext/misc/dbdump.c b8592f6f2da292c62991a13864a60d6c573c47a9cc58362131b9e6a64f823e01
F ext/misc/decimal.c 3ddbf8162015be4d5ec2395dee4538f1e638bb517174bb148274b132df6e1d08
F ext/misc/decimal.c 09f967dcf4a1ee35a76309829308ec278d3648168733f4a1147820e11ebefd12
F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1
F ext/misc/explain.c 0086fab288d4352ea638cf40ac382aad3b0dc5e845a1ea829a694c015fd970fe
F ext/misc/fileio.c 9b69e25da3b51d4a1d905a464ccb96709792ad627a742ba09215bc0d1447e7bd
F ext/misc/fossildelta.c 1240b2d3e52eab1d50c160c7fe1902a9bd210e052dc209200a750bbf885402d5
F ext/misc/fuzzer.c eae560134f66333e9e1ca4c8ffea75df42056e2ce8456734565dbe1c2a92bf3d
F ext/misc/ieee754.c cd6ab89f85fda8a020559b3f4d03001a8a62dd856beda5af3f558621d12be913
F ext/misc/json1.c 332c285db81a3757c278d725e5dafd7afeab6232240c679fbdc087683923eb85
F ext/misc/json1.c 2c5c0dbc7fa303f0213f008e5878db9f0e5875fe8ff59a7c2d9f235b18e323a7
F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d
F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b
F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567
@ -340,7 +340,7 @@ F ext/misc/wholenumber.c a838d1bea913c514ff316c69695efbb49ea3b8cb37d22afc57f73b6
F ext/misc/zipfile.c acbad31bd9c9ec3540fa72b2e3fcd6f757eb33117d51528c0e13d0da5c836908
F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64
F ext/rbu/rbu.c b880ca5cb857d6d6f52e72eb7397813058ef48c78c5402cd04ff2b6b5437f622
F ext/rbu/rbu1.test 221d9c18a5e600ac9ac6b1810d99d9f99163a7909ba61597876ab6e4d4beb3d6
F ext/rbu/rbu1.test c62904bd9526dcdc3496a21199aaf14ae191bbadbf67f076bf16be6b3f2115c2
F ext/rbu/rbu10.test 0a201c32202143f23c81c0144503da339786fc20acb7a2fda11601b65659f314
F ext/rbu/rbu11.test 5c834cf491086b45e071eabf71f708febc143e86a384a92de69e0b1a4cace144
F ext/rbu/rbu12.test 29f8b2118f6c96fac3755bd6d2b55c2db24f878b1f11fbfbe294f3a230a3dcdc
@ -379,7 +379,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 e6531884442b72f9e0ba47036fb5c4641ea817ff659a642b3984c10b8535b0fd
F ext/rbu/sqlite3rbu.c badb52388467f58e67ef104c5276d1ac68b316a30f8ccb2f74eac733625ae236
F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812
F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
@ -457,7 +457,7 @@ F ext/session/sessionsize.test 6f644aff31c7f1e4871e9ff3542766e18da68fc7e587b83a3
F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5
F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc
F ext/session/sqlite3session.c 703634ca25b4b903ae8ec25045802a8c8deca36a65d2b993c4bc8888f6d6c7ee
F ext/session/sqlite3session.h 4c299467627cd27ac31fcbd062274da676d0c471be22f1255867f30f4f832b9a
F ext/session/sqlite3session.h 0907de79bc13a2e3af30a6dc29acc60792a3eaf7d33d44cf52500d0f3c2b2171
F ext/session/test_session.c f433f68a8a8c64b0f5bc74dc725078f12483301ad4ae8375205eef790274a787
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
@ -465,7 +465,7 @@ F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk 71abdbb39dbc530f436f7095d2c0504140d513142a6a552602fb55c8156fd854
F main.mk d1654e2923a7195603a7d6564dabe037a3a20ea5b3817002db534ffc4ad8cecf
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@ -477,17 +477,17 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 6c62a47364d4eb142de6b0aa8a21e83450ad115ca5c2100f031af171777af068
F src/alter.c df53c39fd4f32528fc7ad8188b3bf2b506e1a8b3bb975b14f16a1bc6e901950f
F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c
F src/attach.c a7d1a7df69f053951ec1665e5894c61184fda3f677323762f1c3679ebd27d5c7
F src/attach.c 42774f1f26f6970aef07a206f0afa5d73fea5d2bb84d5a8f687a7f56f00f2a3a
F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853
F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
F src/btree.c 0555f7e97ede886ac3d7aaec363b44498c9716dd45f3f0484de31eb90e30a37e
F src/btree.c 51ba86095316fceb3e25bc61617d673d84627e79f4ace83f8722910f33eedef3
F src/btree.h 096cc53baa58be22b02c896d1cf933c38cfc6d65f9253c1367ece8cc88a24de5
F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0
F src/build.c f4072218dacf42f45b733d1a9a98b3a4d7b8c676a7e5d8ff17d70b60aff687ae
F src/build.c 4e13b92f77d3f6dc1285c3636a2ba7c6af5cbb793e52075a762fbcebcd36e968
F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c fbc6243075128ddf187ec469a6d178ebd58bb6eae8e3ba191446fa18cffb17c3
@ -495,11 +495,11 @@ F src/date.c e0632f335952b32401482d099321bbf12716b29d6e72836b53ae49683ebae4bf
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c
F src/delete.c 73f57a9a183532c344a3135cf8f2a5589376e39183e0b5f562d6b61b2af0f4d8
F src/expr.c 70e2cf6e270bb97ab6602336c82060bee0720cd887483f85c645ac1df97d4a34
F src/expr.c 1d5171fe602cd56ab8b9c9ecbd48d9917e6020cafd6bd87ceac5949e8a1ed2d8
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4
F src/func.c 88fd711754a7241cb9f8eb1391370fd0c0cea756b3358efa274c5d1efd59af93
F src/global.c 56d6762a3a44495ab035e2d3185eeccbc98579e18c06038e1bb9af346105bc84
F src/global.c 25ba4d58476f6be29bba9d9d14f7f146b78476d3a4d75ebb8c3b736328afe0f9
F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
@ -507,14 +507,14 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c 2189e0e596010a0dc5405d9f14f78db1ee2fa71138c931f5b6ea96610b95bfc1
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067
F src/main.c 7db30c6293bb86c45c11638b1de38419e663623b549c74959be6981e7731eb5e
F src/main.c 2b2044221a10e7c5f49a98f50563ce9a944511241ba5946d1754dcc2a7437a07
F src/malloc.c c1af4ac5a463648cd2953fd4ac679b3ba9022ce5ec794a60806150ad69dfd33a
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
F src/mem2.c b93b8762ab999a29ae7751532dadf0a1ac78040308a5fb1d17fcc365171d67eb
F src/mem3.c 30301196cace2a085cbedee1326a49f4b26deff0af68774ca82c1f7c06fda4f6
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
F src/memdb.c eab3c87582a99de1589703e393b0238881c9a16511dc5a29009e84042a5e9f25
F src/memdb.c f6ce717b26cd51a24cda62fce611b4b72b3db367113374aa498e489a69470715
F src/memjournal.c 431c70a111223a8a6e2e7e9f014afc6c88d818d357d866afc563195f2277d50e
F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8
F src/mutex.c 5e3409715552348732e97b9194abe92fdfcd934cfb681df4ba0ab87ac6c18d25
@ -527,12 +527,12 @@ F src/os.c 6e94cd64b134c9317e52ad534117578e3df66ec180d70dbf4b1d7eb1db8e5a5d
F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
F src/os_unix.c b5b7475bd1a8f1b83b6173a81f4fe50f9e077ccbacb62ce2fe7a5cb89916bce1
F src/os_unix.c efa60c1cb54dba767abbba3c6dd67d3df5ef8aa26e2e499c37f055f56a374068
F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 0c84ba222cc58825098ae7d693db85c69f1700ba2a74d9d395033337a511b4e6
F src/pager.c 95c255256b13827caf038c8f963d334784073f38ab6ef9d70371d9d04f3c43e0
F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f
F src/parse.y 77039cf996d9cde8ee1e947ad9284566c30e48cc227766a7be1d475ec7aed9dd
F src/parse.y ac294bd2891c4310b0b23a67ea3bbca2d0bf5b7662c4444b6517c3986be4a437
F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
F src/pcache1.c 388304fd2d91c39591080b5e0f3c62cfba87db20370e7e0554062bfb29740e9f
@ -541,18 +541,18 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf
F src/prepare.c d778af9986f3b0107c5b255dcfe2696e8e99e00fb77c5115bbfea4e92c3302e7
F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c c38bbb89d7ba7a8673ec4f59b63e0980eb859c39ff2acc5df8b3d0f2dcd33115
F src/resolve.c 40e216d9a72e52841a9c8e0aec7d367bade8e2df17b804653b539b20c1ab5660
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c 57dbb27e0d0cb2438487c797365a4c17294d0df3c25c970ca87f123105f33ed0
F src/shell.c.in 9320b476fde0f7c46700e5695b69b435f1e46843a1513cdd187ac426cdbee016
F src/sqlite.h.in 372554fcd1e1ed25ba44a316e8abdaad712470b7dcfa185ece54f51b10fbde10
F src/select.c 09acd5a12c4229238919e38816d0d5c90b24015ef495afb825dc1b3f2a8cf18a
F src/shell.c.in 1b32ba2918ede13b68df47c7b92b72ba0d06e68d384e78bb9d7456527271d400
F src/sqlite.h.in 5c950066775ca9efdaa49077c05d38d0bef6418f3bd07d2dce0210f1d2f3c326
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e
F src/sqliteInt.h a00cc0642e2a4e26367313dc553781253e278a0e571e7211cc56245a8db3e0e7
F src/sqliteInt.h 16d132f4380f9f4ebf9db6b803ddde641aa2c917964b028404d09459cf83533f
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/tclsqlite.c 986b6391f02cd9b53c1d688be55899f6ffddeb8e8014cd83c1b73ff912579a71
F src/tclsqlite.c 97645e4a15dde6a6ad6de8d81057ff9869413b866015a89e208fedacd709493e
F src/test1.c 2100f4c28bae21ce83a9a0c5ec6827efd0e15d11b93b569b614daa5654b3fcf6
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
@ -560,7 +560,7 @@ F src/test4.c 7c4420e01c577b5c4add2cb03119743b1a357543d347773b9e717195ea967159
F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d
F src/test6.c ae73a3a42bbc982fb9e301b84d30bda65a307be48c6dff20aba1461e17a9b0ce
F src/test7.c 5612e9aecf934d6df7bba6ce861fdf5ba5456010
F src/test8.c 7fb971777c2c79c734bb52757191d68d4af659b8de9b4a071be3f527a9d19a02
F src/test8.c 0c856d6ff6b0d2ff6696addc467a15ed17c6910f14475302cd5b3b4e54406161
F src/test9.c 12e5ba554d2d1cbe0158f6ab3f7ffcd7a86ee4e5
F src/test_async.c 195ab49da082053fdb0f949c114b806a49ca770a
F src/test_autoext.c 915d245e736652a219a907909bb6710f0d587871
@ -568,7 +568,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 842ddde1f1d32c12f1651a77e51d6ccdb84697d5023be352c54683db930e9702
F src/test_config.c 9c8e12823c46082a01765addf43be9309889f4e9dfb5a512a6c974e1c4efb413
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
F src/test_demovfs.c 86142ba864d4297d54c5b2e972e74f3141ae4b30f05b3a95824184ed2d3d7f91
F src/test_devsym.c aff2255ea290d7718da08af30cdf18e470ff7325a5eff63e0057b1496ed66593
@ -609,32 +609,32 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c bae853ad129d1129c063de8630a3e99e306283bc40146f359b1bb91be2c08f1e
F src/treeview.c e483aeedf6f207000db1f90eb6abd816350493314c30e8749d319bdb9ab3b08c
F src/trigger.c f8493674f5c8f103c1a2cd0616af9dca85c7058450f9fe47cacd15cf5d512d52
F src/trigger.c e0fd347b2571a2d956318cdc6d011ccca7ce862d10a0ca04188a37920ef5440c
F src/update.c b3abdaf4a314bbed238da69a6ca54c0f21262119389b412ee5778fffe62dd3cc
F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048
F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286
F src/vdbe.c ff3ccdd969774e6ce821b54d076286c84137e2f0e6387b1133bafbaa7470f749
F src/vdbe.c 74491791630743ef5215a90e6ec94c0965577b9b7086b2180d2c7fa0954317a8
F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe
F src/vdbeInt.h 58980223a32495ad059d10581b83e133abdc77248b1bab85c080cab8a13bd819
F src/vdbeapi.c d9e99daf59fec928986838b3389a7337e82fec6b3b5de30206cb99fb4661b94e
F src/vdbeaux.c 065a10392378109f08435bd50d03dff315e384cde2831d6b8dbaec05f33b10af
F src/vdbeblob.c c6b8db50b227f66fb404215732068df76485b5b433e5f9d4d9ac27410b218193
F src/vdbemem.c 947f2a65910edb4014dc981d33e414a68c51f169f9df8c4c493a0ba840b6eb1f
F src/vdbemem.c 175c73ced03edbb0f6567a41c8032afaeb83372090fa7bddfc88a67e28da2b8a
F src/vdbesort.c f5b5e473a7cee44e47a94817b042fd7172cf3aa2c0a7928a8339d612bcfdec5a
F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb724
F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c
F src/vtab.c b928405ccb66040fc6c3a11eaa93ddb02cbf20f9ab6860b301b222b9b50dc089
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14
F src/wal.c c8ec20a1ca161d5635a4f19c2a4efec2e006e19a8a61f272bf6bce1c80ab7436
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
F src/walker.c 6e540867a30d81e00205995fa2dc0e3d25365a7402251c9fd5d19aa4ff5e60b6
F src/where.c 22705995adaa97f7fb9163f31b9277c457d6995dcb0c4fcf52d1b317d9594d1f
F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4
F src/wherecode.c 992bf0d7520bffd345472fb9bc83a1ca0134e46d9e904879bb21e1e77957fcc3
F src/whereexpr.c d8cafcf6781cf871082f04d7540862cf0fe30cb381dd1b2145a380376364fe8e
F src/window.c 35b14e7a53fe0472b42679919c474de3a5b5c1615fe90a2c41431f37e4ede1be
F src/walker.c 7342becedf3f8a26f9817f08436bdf8b56ad69af83705f6b9320a0ad3092c2ac
F src/where.c 32f41c3c93c6785e0077e3a2cdc669c3ccfe70173787847be77f294c18fc7dc3
F src/whereInt.h 9248161dd004f625ce5d3841ca9b99fed3fc8d61522cf76340fc5217dbe1375b
F src/wherecode.c 110ed13049e0f1dc27e9dd942eb870417b36480cb7819302f5804cbcf9330b0e
F src/whereexpr.c 5a9c9f5d2dac4bcdcaae3035034b4667523f731df228e0bb1d4efc669efa9da5
F src/window.c ce5e73ab88a8527d268673906bf89cbe58c61bca8d54d38ed8c33c3220a276ee
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
F test/affinity3.test eecb0dabee4b7765a8465439d5e99429279ffba23ca74a7eae270a452799f9e7
@ -645,7 +645,7 @@ F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13
F test/alter.test f53d8a4ecd35f051c07e54a36beec5d0a30d30a9d98bc723f6cde6afbfb3c5ca
F test/alter2.test a966ccfcddf9ce0a4e0e6ff1aca9e6e7948e0e242cd7e43fc091948521807687
F test/alter3.test e487958dec7932453e0b83baf21d6b1e71d5e7d9a55bc20eadfa62a51ddffc29
F test/alter4.test dfd6086faf461b27ca2d2999848dcd207edf23352fc1592d0005c0844f3f08cf
F test/alter4.test 716caa071dd8a3c6d57225778d15d3c3cbf5e34b2e84ae44199aeb2bbf50a707
F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959
F test/alterauth2.test 381b1ab603c9ef96314a3158528ea17f7964449385a28eeaf8191120b2e24a8d
F test/altercol.test b11fa1b131e80ab5b6ecfb3b725fb0419c14ca6efba5adb57aeabfc9baa0c8f3
@ -657,7 +657,7 @@ F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74
F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b
F test/altermalloc3.test 059841a3de6b6780efd9f0b30bf1d9b4443c555f68d39975cbcac2583167b239
F test/alterqf.test 67568ad152db8c1187b15633b801242cf960f1beafc51261a3d1725d910baeb2
F test/altertab.test 2591f93cc1c5ac1f1854b096ffdfe10caf0a8bcdfc8f830bdc9a554e08e6dd6d
F test/altertab.test c7966d92e4da535050b911e1e9972ecb3a5befb0b2d22026b132cf5003d43dec
F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b
F test/altertab3.test 2b82fa2236a3a91553d53ae5555d8e723c7eec174c41f1fa62ff497355398479
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
@ -782,7 +782,7 @@ F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4
F test/corrupt.test d7cb0300e4a297147b6a05e92a1684bc8973635c3bcaa3d66e983c9cbdbf47a3
F test/corrupt2.test bb50042cf9a1f1023d73af325d47eb02a6bb11e3c52f8812644b220c5d4bca35
F test/corrupt3.test 2520432b1fbf99994841e69804a3c59fb828183f4d09b85a1631bc7adca17e31
F test/corrupt4.test 04965221ecd005901923fdc57f26811fa07178074b0672e50ea424c21638c708
F test/corrupt4.test b5ae41607e8d17d9c1f3e94fdb572ce061ed3beeebdb46fb3a348181b8c8a097
F test/corrupt5.test 387be3250795e2a86e6234745558b80efb248a357d0cd8e53bce75c7463f545d
F test/corrupt6.test fc6a891716139665dae0073b6945e3670bf92568
F test/corrupt7.test b036f94bda4b0b23a2919bf717046ce9ecca4543
@ -801,7 +801,7 @@ F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af
F test/corruptL.test df132ba9ffd6fa15038380b4154998b9904ab8f1ea78400d7da53c920cb3b13d
F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067
F test/corruptN.test 7a8a8399f57cdc6a189f275230300ccbb2b31a5aea8399070251beeebe2cc02b
F test/corruptN.test f56e3417fe9a444efd765ae55acbe65595d7b8f747785fe0fd785dbdc424932a
F test/cost.test b11cdbf9f11ffe8ef99c9881bf390e61fe92baf2182bad1dbe6de59a7295c576
F test/count.test 5364003488249957750a5f15ee42ca1cd7b100b1131c2dc71fff266a1250bf55
F test/countofview.test e17d6e6688cf74f22783c9ec6e788c0790ee4fbbaee713affd00b1ac0bb39b86
@ -829,7 +829,7 @@ F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
F test/dbfuzz001.test 55e1a3504f8dea84155e09912fe3b1c3ad77e0b1a938ec42ca03b8e51b321e30
F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee
F test/dbfuzz2.c db2a1710c0d30d38e1352ee1b52b717fcb224c8caacc6f10909ef540f73cc9e8
F test/dbfuzz2.c 4b3c12de4d98b1b2d908ab03d217d4619e47c8b23d5e67f8a6f2b1bdee7cae23
F test/dbpage.test 650234ba683b9d82b899c6c51439819787e7609f17a0cc40e0080a7b6443bc38
F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759
F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef
@ -884,8 +884,6 @@ F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650
F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac
F test/exists2.test 92d563a97019a70f7adcbe3cbaab16f9fc696affbf0f9ede1796ea5f7cc5a3ac
F test/existsfault.test 72a0036c1424d9204d49f4d976c3277a1b8bb2eed3c67aa124ba2df2f1331c7c
F test/expr.test 26cd01e8485bc48c8aa6a1add598e9ce1e706b4eb4f3f554e0b0223022e8c2cf
F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8
F test/exprfault.test 497cc0b8fe6a677f49b55cb485e040f709ec2834b84f25912fe9c2dfeeda33db
@ -1049,7 +1047,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
F test/fuzzcheck.c 59bcbb5f5c6dcec4f6f5c4e4456b5dc7211ea893f2204c80ceb4277bba83fb9b
F test/fuzzcheck.c c51cdb34e926d0a6551624aa1f04c456c29317b5457855d64391917d9b4c2aff
F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
@ -1057,7 +1055,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4
F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5
F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7
F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2
F test/fuzzdata8.db 00e053a6a486be9edf2d6bae8f3911ca7e2cc27aa32291d1c8258130e9eb9eb3
F test/fuzzdata8.db 5e616432bbdd9b27014463545cae06797790645021fbc650d28c994b4f02a6f5
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc
@ -1077,7 +1075,7 @@ F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
F test/in4.test cd08375ba470b248c3dc4ab30fd5dbcb682deafe3862d8249ba0ad6a11dd25ea
F test/in5.test b32ce7f4a93f44c5dee94af16886d922cc16ebe33c8e1765c73d4049d0f4b40f
F test/in6.test 8562d0945195cab3cc4ab3794e9118e72cb44c43f785c2b04d48a9d06ca6b4ec
F test/in6.test f5f40d6816a8bb7c784424b58a10ac38efb76ab29127a2c17399e0cbeeda0e4b
F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822
F test/incrblob2.test a494c9e848560039a23974b9119cfc2cf3ad3bd15cc2694ee6367ae537ef8f1f
F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4
@ -1239,7 +1237,7 @@ F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2
F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
F test/optfuzz-db01.c 9f2fa80b8f84ebbf1f2e8b13421a4e0477fe300f6686fbd76cac1d2db66e0fdc
F test/optfuzz-db01.txt 21f6bdeadc701cf11528276e2a55c70bfcb846ba42df327f979bd9e7b6ce7041
F test/optfuzz.c 50e330304eb1992e15ddd11f3daaad9bcc0d9aaad09cb2bcc77f9515df2e88b1
F test/optfuzz.c 690430a0bf0ad047d5a168bf52b05b2ee97aedaad8c14337e9eb5050faa64994
F test/orderby1.test a4bba04b9c60a21e53486fbc173a596b29641a3b3a57a0f26a1cbef1360358e9
F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04
F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99
@ -1295,11 +1293,11 @@ F test/recover.test ccb8c2623902a92ebb76770edd075cb4f75a4760bb7afde38026572c6e79
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c
F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d
F test/releasetest.tcl 8dcfc21d6b4a4a1d9a8503de0a94800d129ec8f03ef53d6e68b79ef78a786acd x
F test/releasetest_data.tcl a864d27370e812c34a05224d6144ca082463906d5a4651782ad3b43712ab166a
F test/releasetest.tcl 6f803ef0b896f8f3f4c26eb072c0399963a5987a509a64d45f5dfbc1ebae2951 x
F test/releasetest_data.tcl f88ed29aa18366ed3956ace36c96ec6868ef5b9ee04cc05d32f4d81031e19e28
F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5eeb2b
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
F test/returning1.test 99012dc464860e1502153276d5e5c2bee32c53d3a866dcfc09b39932048e2276
F test/returning1.test 52b4ed60f104a4ce85b38417e5319b2078b2b908c71a768d539cee3c0ce8bdc9
F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
F test/rollback2.test 3f3a4e20401825017df7e7671e9f31b6de5fae5620c2b9b49917f52f8c160a8f
F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a
@ -1465,6 +1463,7 @@ F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
F test/threadtest2.c a70a8e94bef23339d34226eb9521015ef99f4df8
F test/threadtest3.c e63013af10cf236c7610eb06d33bde08c861806dc64be811940ff4d9ddd34a4f
F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925
F test/threadtest5.c 9b4d782c58d8915d7e955ff8051f3d03628bda0d33b82971ea8c0f2f2808c421
F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90
F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c
F test/tkt-18458b1a.test 6a62cb1ee50fa3c620da59e3a6f531eb38fceaf7e2166203816b724524e6f1d6
@ -1617,7 +1616,7 @@ F test/trace3.test ae2004df24b585fed9046cc0bae4601762bc6fc4aa321d475f1350bba5047
F test/trans.test 45f6f9ab6f66a7b5744f1caac06b558f95da62501916906cf55586a896f9f439
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
F test/transitive1.test 239eec5343388983f112c16d666aa89960cd85302b6af6cd8408ce8edb7b3316
F test/transitive1.test 06bcfeeb2ed719abf6ae582f9f65a6b07642dd1363fa648ae9a74a35e83a825c
F test/trigger1.test d30cd09ae8ac365a088f09daba583cc5c0b8fc7d4e1d70809d0b4be3bf6ae2ab
F test/trigger2.test 6e35bd7321c49e63d540aee980eb95dec63e1d1caca175224101045bcc80871f
F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945
@ -1682,7 +1681,7 @@ F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2
F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
F test/view.test ea88361d5e9bc8eabf9f573185a16aea73a885be9b6c6a95ae84908913416a80
F test/vtab1.test c5d9e90ed02bcacd776dcbb7360199d290f7f53c26b484ddece543060c54319f
F test/vtab1.test 99c0c13b5336ca7f87f137459de144b2f396bb8563fbd602e46bfaa425e3d8cc
F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3
@ -1750,7 +1749,7 @@ F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
F test/where7.test ab41d53ce8f2a6919ea3d5b13cd1153c1375a8e3ddaa129b81781f9033981383
F test/where8.test 461ca40265ed996a6305da99bb024b0e41602bb586acf544c08f95922358e49f
F test/where9.test b1942ed1d4c4632ea99e135691371f33803428ee4092a462280338ab3347f916
F test/where9.test 1ffb75edc50a8faa6e7bd77f8221d783febb00b44b0bdb32fb48cec6e38eca95
F test/whereA.test 9d1077b117f1b68d5f739d94f36956c36cf995eb87bb19b77b2e81af020edd20
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6
@ -1762,7 +1761,7 @@ F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
F test/whereI.test c4bb7e2ca56d49bd8ab5c7bd085b8b83e353922b46904d68aefb3c7468643581
F test/whereJ.test fc05e374cc9f2dc204148d6c06822c380ad388895fe97a6d335b94a26a08aecf
F test/whereK.test 0270ab7f04ba5436fb9156d31d642a1c82727f4c4bfe5ba90d435c78cf44684a
F test/whereL.test 7717caf61ff4b09d05ddd2978701c4cf5661408bd4dce31d38eff482f60f44f3
F test/whereL.test 50171e3ec00b4c8ad5ec773119a35d9e9642cec45154b44c366d628326479f4d
F test/wherefault.test 6cf2a9c5712952d463d3f45ebee7f6caf400984df51a195d884cfb7eb0e837a7
F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3
F test/wherelimit.test afb46397c6d7e964e6e294ba3569864a0c570fe3807afc634236c2b752372f31
@ -1771,7 +1770,7 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2
F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
F test/win32longpath.test 4baffc3acb2e5188a5e3a895b2b543ed09e62f7c72d713c1feebf76222fe9976
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
F test/window1.test 54e160bdeb8b06fb3b97993e0eec45ee4c3294f39ad63007c921c40961298815
F test/window1.test 7cb66f49d30d89ca9d28dc20f7f1d85229365651e8e6211f7da1448740866511
F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476
F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
@ -1782,8 +1781,8 @@ F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652
F test/window6.test f8d674254b23289cc17c84d79dec7eda7caa1dfb7836c43122cfdf3640d1df32
F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d76108f
F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd
F test/window8.tcl f2711aa3571e4e6b0dad98db8d95fd6cb8d9db0c92bbdf535f153b07606a1ce2
F test/window8.test c4331b27a6f66d69fa8f8bab10cc731db1a81d293ae108a68f7c3487fa94e65b
F test/window8.tcl 5e02e41d9d9a80f597063aed1a381eb19d1d0ef677a4f0df352c5365cf23f79c
F test/window8.test 4ab16817414af0c904abe2ebdf88eb6c2b00058b84f9748c6174ff11fc45f1ed
F test/window9.test 349c71eab4288a1ffc19e2f65872ec2c37e6cf8a1dda2ad300364b7450ae4836
F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be
F test/windowB.test 6e601f8178ba8ba28b2f19e74fe613815084bb4a8d2ad942defc7d42e191e521
@ -1798,7 +1797,7 @@ F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f1982
F test/with5.test 6248213c41fab36290b5b73aa3f937309dfba337004d9d8434c3fabc8c7d4be8
F test/with6.test 661d7e416bef6c0a2556b2c9f0c8178a5b15932bed65246abed99723a8d4e7c0
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
F test/without_rowid1.test e4034c0849ccc2e8bb749c69f15bd69bb9fcf8fe77e8d17ce02369604242fe83
F test/without_rowid1.test 6abc5d497f634520944dac0a89a6c240a48d2ee0f8353356a750eb70dc1db41a
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
F test/without_rowid3.test 39ab0dd773eaa62e59b17093f875327630f54c4145458f6d2b053d68d4b2f67b
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
@ -1845,7 +1844,7 @@ F tool/mkctimec.tcl 6469850ad5e9f9173046da7569a0a6f40c5b21316406b70aaa029b357bc8
F tool/mkkeywordhash.c 08b6e4d7a482a7f37a9a0032e7ba968e26624a027b6b2e9ba589be6f5e3d8c2c
F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a895ab33
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21
F tool/mkopcodeh.tcl acc798757e2c60e4b6e16745505b9595fca76c206815c8ada576a136cf3608ed
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
F tool/mkpragmatab.tcl ae5585ae76ca26e4d6ccd5ea9cdebaf5efefb318bf989497a0e846cd711d9ab1
F tool/mkshellc.tcl 70a9978e363b0f3280ca9ce1c46d72563ff479c1930a12a7375e3881b7325712
@ -1857,7 +1856,7 @@ F tool/mksqlite3h.tcl 1f5e4a1dbbbc43c83cc6e74fe32c6c620502240b66c7c0f33a51378e78
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845
F tool/omittest.tcl 38c3e409ae0070df177ca49164f5ed19ad4f3d5b574ee3272d521a94b59bdb84
F tool/omittest.tcl 3d222272b1d840b4e3d67bff0cb743ce3f633faddadb3702b2056b726775db8f
F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
F tool/replace.tcl 60f91e8dd06ab81f74d213ecbd9c9945f32ac048
@ -1914,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 830b0b1c49aaca53a40e5a4ca9a11351d697a980c7bf80379e32f0646738d566 7e18e114b245d17aa259ea9ab42752ccc9ad5303bbac8d8e46928dd10319f545
R 05bf1168d4e82946cb66360ad9e9f04a
P 3ff228249adf2da345d3e19e9af3e23d1354f6b9a35ddbe9864e1a07716d871c 4e81ea3b15fb3fce5f31b77273639e748a735ab0970620e564e9a5c977b24a1a
R ea5c2f2d0e31f28da39a2a85c2aa9d20
U larrybr
Z 638e936d637dceb5113ec52daa047f9b
Z aa5a2c613a1eb5b66660089c16f7322a

View File

@ -1 +1 @@
3ff228249adf2da345d3e19e9af3e23d1354f6b9a35ddbe9864e1a07716d871c
19ffe3cfe278a4046f32df56f75080c2377e4c44ad40a02d39db8e7701526204

View File

@ -835,7 +835,7 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){
Parse *pParse = pWalker->pParse;
int i;
if( pParse->nErr ) return WRC_Abort;
if( NEVER(p->selFlags & SF_View) ) return WRC_Prune;
if( p->selFlags & SF_View ) return WRC_Prune;
if( ALWAYS(p->pEList) ){
ExprList *pList = p->pEList;
for(i=0; i<pList->nExpr; i++){

View File

@ -95,7 +95,7 @@ static void attachFunc(
if( zFile==0 ) zFile = "";
if( zName==0 ) zName = "";
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
# define REOPEN_AS_MEMDB(db) (db->init.reopenMemdb)
#else
# define REOPEN_AS_MEMDB(db) (0)

View File

@ -547,7 +547,7 @@ static void invalidateIncrblobCursors(
int isClearTable /* True if all rows are being deleted */
){
BtCursor *p;
if( pBtree->hasIncrblobCur==0 ) return;
assert( pBtree->hasIncrblobCur );
assert( sqlite3BtreeHoldsMutex(pBtree) );
pBtree->hasIncrblobCur = 0;
for(p=pBtree->pBt->pCursor; p; p=p->pNext){
@ -6419,10 +6419,9 @@ static void freePage(MemPage *pPage, int *pRC){
}
/*
** Free any overflow pages associated with the given Cell. Store
** size information about the cell in pInfo.
** Free the overflow pages associated with the given Cell.
*/
static int clearCell(
static SQLITE_NOINLINE int clearCellOverflow(
MemPage *pPage, /* The page that contains the Cell */
unsigned char *pCell, /* First byte of the Cell */
CellInfo *pInfo /* Size information about the cell */
@ -6434,10 +6433,7 @@ static int clearCell(
u32 ovflPageSize;
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
pPage->xParseCell(pPage, pCell, pInfo);
if( pInfo->nLocal==pInfo->nPayload ){
return SQLITE_OK; /* No overflow pages. Return without doing anything */
}
assert( pInfo->nLocal!=pInfo->nPayload );
testcase( pCell + pInfo->nSize == pPage->aDataEnd );
testcase( pCell + (pInfo->nSize-1) == pPage->aDataEnd );
if( pCell + pInfo->nSize > pPage->aDataEnd ){
@ -6493,6 +6489,21 @@ static int clearCell(
return SQLITE_OK;
}
/* Call xParseCell to compute the size of a cell. If the cell contains
** overflow, then invoke cellClearOverflow to clear out that overflow.
** STore the result code (SQLITE_OK or some error code) in rc.
**
** Implemented as macro to force inlining for performance.
*/
#define BTREE_CLEAR_CELL(rc, pPage, pCell, sInfo) \
pPage->xParseCell(pPage, pCell, &sInfo); \
if( sInfo.nLocal!=sInfo.nPayload ){ \
rc = clearCellOverflow(pPage, pCell, &sInfo); \
}else{ \
rc = SQLITE_OK; \
}
/*
** Create the byte sequence used to represent a cell on page pPage
** and write that byte sequence into pCell[]. Overflow pages are
@ -7168,7 +7179,9 @@ static int pageFreeArray(
}
pFree = pCell;
szFree = sz;
if( pFree+sz>pEnd ) return 0;
if( pFree+sz>pEnd ){
return 0;
}
}else{
pFree = pCell;
szFree += sz;
@ -8144,6 +8157,7 @@ static int balance_nonroot(
u8 *pCell;
u8 *pTemp;
int sz;
u8 *pSrcEnd;
MemPage *pNew = apNew[i];
j = cntNew[i];
@ -8187,6 +8201,12 @@ static int balance_nonroot(
iOvflSpace += sz;
assert( sz<=pBt->maxLocal+23 );
assert( iOvflSpace <= (int)pBt->pageSize );
for(k=0; b.ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
pSrcEnd = b.apEnd[k];
if( SQLITE_WITHIN(pSrcEnd, pCell, pCell+sz) ){
rc = SQLITE_CORRUPT_BKPT;
goto balance_cleanup;
}
insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno, &rc);
if( rc!=SQLITE_OK ) goto balance_cleanup;
assert( sqlite3PagerIswriteable(pParent->pDbPage) );
@ -8743,7 +8763,9 @@ int sqlite3BtreeInsert(
assert( pX->pKey==0 );
/* If this is an insert into a table b-tree, invalidate any incrblob
** cursors open on the row being replaced */
invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0);
if( p->hasIncrblobCur ){
invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0);
}
/* If BTREE_SAVEPOSITION is set, the cursor must already be pointing
** to a row with the same key as the new entry being inserted.
@ -8877,7 +8899,7 @@ int sqlite3BtreeInsert(
if( !pPage->leaf ){
memcpy(newCell, oldCell, 4);
}
rc = clearCell(pPage, oldCell, &info);
BTREE_CLEAR_CELL(rc, pPage, oldCell, info);
testcase( pCur->curFlags & BTCF_ValidOvfl );
invalidateOverflowCache(pCur);
if( info.nSize==szNew && info.nLocal==info.nPayload
@ -9170,7 +9192,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
/* If this is a delete operation to remove a row from a table b-tree,
** invalidate any incrblob cursors open on the row being deleted. */
if( pCur->pKeyInfo==0 ){
if( pCur->pKeyInfo==0 && p->hasIncrblobCur ){
invalidateIncrblobCursors(p, pCur->pgnoRoot, pCur->info.nKey, 0);
}
@ -9179,7 +9201,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
** itself from within the page. */
rc = sqlite3PagerWrite(pPage->pDbPage);
if( rc ) return rc;
rc = clearCell(pPage, pCell, &info);
BTREE_CLEAR_CELL(rc, pPage, pCell, info);
dropCell(pPage, iCellIdx, info.nSize, &rc);
if( rc ) return rc;
@ -9466,7 +9488,7 @@ static int clearDatabasePage(
rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
if( rc ) goto cleardatabasepage_out;
}
rc = clearCell(pPage, pCell, &info);
BTREE_CLEAR_CELL(rc, pPage, pCell, info);
if( rc ) goto cleardatabasepage_out;
}
if( !pPage->leaf ){
@ -9514,7 +9536,9 @@ int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){
/* Invalidate all incrblob cursors open on table iTable (assuming iTable
** is the root of a table b-tree - if it is not, the following call is
** a no-op). */
invalidateIncrblobCursors(p, (Pgno)iTable, 0, 1);
if( p->hasIncrblobCur ){
invalidateIncrblobCursors(p, (Pgno)iTable, 0, 1);
}
rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange);
}
sqlite3BtreeLeave(p);

View File

@ -46,7 +46,7 @@ struct TableLock {
** code to make the lock occur is generated by a later call to
** codeTableLocks() which occurs during sqlite3FinishCoding().
*/
void sqlite3TableLock(
static SQLITE_NOINLINE void lockTable(
Parse *pParse, /* Parsing context */
int iDb, /* Index of the database containing the table to lock */
Pgno iTab, /* Root page number of the table to be locked */
@ -59,8 +59,6 @@ void sqlite3TableLock(
TableLock *p;
assert( iDb>=0 );
if( iDb==1 ) return;
if( !sqlite3BtreeSharable(pParse->db->aDb[iDb].pBt) ) return;
pToplevel = sqlite3ParseToplevel(pParse);
for(i=0; i<pToplevel->nTableLock; i++){
p = &pToplevel->aTableLock[i];
@ -84,6 +82,17 @@ void sqlite3TableLock(
sqlite3OomFault(pToplevel->db);
}
}
void sqlite3TableLock(
Parse *pParse, /* Parsing context */
int iDb, /* Index of the database containing the table to lock */
Pgno iTab, /* Root page number of the table to be locked */
u8 isWriteLock, /* True for a write lock */
const char *zName /* Name of the table to be locked */
){
if( iDb==1 ) return;
if( !sqlite3BtreeSharable(pParse->db->aDb[iDb].pBt) ) return;
lockTable(pParse, iDb, iTab, isWriteLock, zName);
}
/*
** Code an OP_TableLock instruction for each table locked by the
@ -1048,6 +1057,22 @@ i16 sqlite3TableColumnToStorage(Table *pTab, i16 iCol){
}
#endif
/*
** Insert a single OP_JournalMode query opcode in order to force the
** prepared statement to return false for sqlite3_stmt_readonly(). This
** is used by CREATE TABLE IF NOT EXISTS and similar if the table already
** exists, so that the prepared statement for CREATE TABLE IF NOT EXISTS
** will return false for sqlite3_stmt_readonly() even if that statement
** is a read-only no-op.
*/
static void sqlite3ForceNotReadOnly(Parse *pParse){
int iReg = ++pParse->nMem;
Vdbe *v = sqlite3GetVdbe(pParse);
if( v ){
sqlite3VdbeAddOp3(v, OP_JournalMode, 0, iReg, PAGER_JOURNALMODE_QUERY);
}
}
/*
** Begin constructing a new table representation in memory. This is
** the first of several action routines that get called in response
@ -1147,6 +1172,7 @@ void sqlite3StartTable(
}else{
assert( !db->init.busy || CORRUPT_DB );
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3ForceNotReadOnly(pParse);
}
goto begin_table_error;
}
@ -1323,6 +1349,7 @@ void sqlite3AddReturning(Parse *pParse, ExprList *pList){
pRet->retTrig.tr_tm = TRIGGER_AFTER;
pRet->retTrig.bReturning = 1;
pRet->retTrig.pSchema = db->aDb[1].pSchema;
pRet->retTrig.pTabSchema = db->aDb[1].pSchema;
pRet->retTrig.step_list = &pRet->retTStep;
pRet->retTStep.op = TK_RETURNING;
pRet->retTStep.pTrig = &pRet->retTrig;
@ -3196,7 +3223,10 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
if( noErr ) db->suppressErr--;
if( pTab==0 ){
if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
if( noErr ){
sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
sqlite3ForceNotReadOnly(pParse);
}
goto exit_drop_table;
}
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
@ -3766,6 +3796,7 @@ void sqlite3CreateIndex(
}else{
assert( !db->init.busy );
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3ForceNotReadOnly(pParse);
}
goto exit_create_index;
}
@ -4246,7 +4277,7 @@ void sqlite3DefaultRowEst(Index *pIdx){
if( x<99 ){
pIdx->pTable->nRowLogEst = x = 99;
}
if( pIdx->pPartIdxWhere!=0 ) x -= 10; assert( 10==sqlite3LogEst(2) );
if( pIdx->pPartIdxWhere!=0 ){ x -= 10; assert( 10==sqlite3LogEst(2) ); }
a[0] = x;
/* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is
@ -4284,6 +4315,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
sqlite3ErrorMsg(pParse, "no such index: %S", pName->a);
}else{
sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
sqlite3ForceNotReadOnly(pParse);
}
pParse->checkSchema = 1;
goto exit_drop_index;

View File

@ -95,18 +95,7 @@ Expr *sqlite3ExprAddCollateToken(
const Token *pCollName, /* Name of collating sequence */
int dequote /* True to dequote pCollName */
){
assert( pExpr!=0 || pParse->db->mallocFailed );
if( pExpr==0 ) return 0;
if( pExpr->op==TK_VECTOR ){
ExprList *pList = pExpr->x.pList;
if( ALWAYS(pList!=0) ){
int i;
for(i=0; i<pList->nExpr; i++){
pList->a[i].pExpr = sqlite3ExprAddCollateToken(pParse,pList->a[i].pExpr,
pCollName, dequote);
}
}
}else if( pCollName->n>0 ){
if( pCollName->n>0 ){
Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote);
if( pNew ){
pNew->pLeft = pExpr;

View File

@ -279,7 +279,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
0, /* xVdbeBranch */
0, /* pVbeBranchArg */
#endif
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
SQLITE_MEMDB_DEFAULT_MAXSIZE, /* mxMemdbSize */
#endif
#ifndef SQLITE_UNTESTABLE

View File

@ -305,7 +305,7 @@ int sqlite3_initialize(void){
sqlite3GlobalConfig.isPCacheInit = 1;
rc = sqlite3OsInit();
}
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
if( rc==SQLITE_OK ){
rc = sqlite3MemdbInit();
}
@ -720,12 +720,12 @@ int sqlite3_config(int op, ...){
}
#endif /* SQLITE_ENABLE_SORTER_REFERENCES */
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
case SQLITE_CONFIG_MEMDB_MAXSIZE: {
sqlite3GlobalConfig.mxMemdbSize = va_arg(ap, sqlite3_int64);
break;
}
#endif /* SQLITE_ENABLE_DESERIALIZE */
#endif /* SQLITE_OMIT_DESERIALIZE */
default: {
rc = SQLITE_ERROR;
@ -1884,6 +1884,10 @@ int sqlite3CreateFunc(
}else{
sqlite3ExpirePreparedStatements(db, 0);
}
}else if( xSFunc==0 && xFinal==0 ){
/* Trying to delete a function that does not exist. This is a no-op.
** https://sqlite.org/forum/forumpost/726219164b */
return SQLITE_OK;
}
p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 1);

View File

@ -17,31 +17,88 @@
** sqlite3_deserialize().
*/
#include "sqliteInt.h"
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
/*
** Forward declaration of objects used by this utility
*/
typedef struct sqlite3_vfs MemVfs;
typedef struct MemFile MemFile;
typedef struct MemStore MemStore;
/* Access to a lower-level VFS that (might) implement dynamic loading,
** access to randomness, etc.
*/
#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
/* An open file */
struct MemFile {
sqlite3_file base; /* IO methods */
/* Storage for a memdb file.
**
** An memdb object can be shared or separate. Shared memdb objects can be
** used by more than one database connection. Mutexes are used by shared
** memdb objects to coordinate access. Separate memdb objects are only
** connected to a single database connection and do not require additional
** mutexes.
**
** Shared memdb objects have .zFName!=0 and .pMutex!=0. They are created
** using "file:/name?vfs=memdb". The first character of the name must be
** "/" or else the object will be a separate memdb object. All shared
** memdb objects are stored in memdb_g.apMemStore[] in an arbitrary order.
**
** Separate memdb objects are created using a name that does not begin
** with "/" or using sqlite3_deserialize().
**
** Access rules for shared MemStore objects:
**
** * .zFName is initialized when the object is created and afterwards
** is unchanged until the object is destroyed. So it can be accessed
** at any time as long as we know the object is not being destroyed,
** which means while either the SQLITE_MUTEX_STATIC_VFS1 or
** .pMutex is held or the object is not part of memdb_g.apMemStore[].
**
** * Can .pMutex can only be changed while holding the
** SQLITE_MUTEX_STATIC_VFS1 mutex or while the object is not part
** of memdb_g.apMemStore[].
**
** * Other fields can only be changed while holding the .pMutex mutex
** or when the .nRef is less than zero and the object is not part of
** memdb_g.apMemStore[].
**
** * The .aData pointer has the added requirement that it can can only
** be changed (for resizing) when nMmap is zero.
**
*/
struct MemStore {
sqlite3_int64 sz; /* Size of the file */
sqlite3_int64 szAlloc; /* Space allocated to aData */
sqlite3_int64 szMax; /* Maximum allowed size of the file */
unsigned char *aData; /* content of the file */
sqlite3_mutex *pMutex; /* Used by shared stores only */
int nMmap; /* Number of memory mapped pages */
unsigned mFlags; /* Flags */
int nRdLock; /* Number of readers */
int nWrLock; /* Number of writers. (Always 0 or 1) */
int nRef; /* Number of users of this MemStore */
char *zFName; /* The filename for shared stores */
};
/* An open file */
struct MemFile {
sqlite3_file base; /* IO methods */
MemStore *pStore; /* The storage */
int eLock; /* Most recent lock against this file */
};
/*
** File-scope variables for holding the memdb files that are accessible
** to multiple database connections in separate threads.
**
** Must hold SQLITE_MUTEX_STATIC_VFS1 to access any part of this object.
*/
static struct MemFS {
int nMemStore; /* Number of shared MemStore objects */
MemStore **apMemStore; /* Array of all shared MemStore objects */
} memdb_g;
/*
** Methods for MemFile
*/
@ -95,7 +152,10 @@ static sqlite3_vfs memdb_vfs = {
memdbSleep, /* xSleep */
0, /* memdbCurrentTime, */ /* xCurrentTime */
memdbGetLastError, /* xGetLastError */
memdbCurrentTimeInt64 /* xCurrentTimeInt64 */
memdbCurrentTimeInt64, /* xCurrentTimeInt64 */
0, /* xSetSystemCall */
0, /* xGetSystemCall */
0, /* xNextSystemCall */
};
static const sqlite3_io_methods memdb_io_methods = {
@ -120,19 +180,67 @@ static const sqlite3_io_methods memdb_io_methods = {
memdbUnfetch /* xUnfetch */
};
/*
** Enter/leave the mutex on a MemStore
*/
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0
static void memdbEnter(MemStore *p){
UNUSED_PARAMETER(p);
}
static void memdbLeave(MemStore *p){
UNUSED_PARAMETER(p);
}
#else
static void memdbEnter(MemStore *p){
sqlite3_mutex_enter(p->pMutex);
}
static void memdbLeave(MemStore *p){
sqlite3_mutex_leave(p->pMutex);
}
#endif
/*
** Close an memdb-file.
**
** The pData pointer is owned by the application, so there is nothing
** to free. Unless the SQLITE_DESERIALIZE_FREEONCLOSE flag is set,
** in which case we own the pData pointer and need to free it.
** Free the underlying MemStore object when its refcount drops to zero
** or less.
*/
static int memdbClose(sqlite3_file *pFile){
MemFile *p = (MemFile *)pFile;
if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ){
sqlite3_free(p->aData);
MemStore *p = ((MemFile*)pFile)->pStore;
if( p->zFName ){
int i;
#ifndef SQLITE_MUTEX_OMIT
sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
#endif
sqlite3_mutex_enter(pVfsMutex);
for(i=0; ALWAYS(i<memdb_g.nMemStore); i++){
if( memdb_g.apMemStore[i]==p ){
memdbEnter(p);
if( p->nRef==1 ){
memdb_g.apMemStore[i] = memdb_g.apMemStore[--memdb_g.nMemStore];
if( memdb_g.nMemStore==0 ){
sqlite3_free(memdb_g.apMemStore);
memdb_g.apMemStore = 0;
}
}
break;
}
}
sqlite3_mutex_leave(pVfsMutex);
}else{
memdbEnter(p);
}
p->nRef--;
if( p->nRef<=0 ){
if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ){
sqlite3_free(p->aData);
}
memdbLeave(p);
sqlite3_mutex_free(p->pMutex);
sqlite3_free(p);
}else{
memdbLeave(p);
}
return SQLITE_OK;
}
@ -146,20 +254,23 @@ static int memdbRead(
int iAmt,
sqlite_int64 iOfst
){
MemFile *p = (MemFile *)pFile;
MemStore *p = ((MemFile*)pFile)->pStore;
memdbEnter(p);
if( iOfst+iAmt>p->sz ){
memset(zBuf, 0, iAmt);
if( iOfst<p->sz ) memcpy(zBuf, p->aData+iOfst, p->sz - iOfst);
memdbLeave(p);
return SQLITE_IOERR_SHORT_READ;
}
memcpy(zBuf, p->aData+iOfst, iAmt);
memdbLeave(p);
return SQLITE_OK;
}
/*
** Try to enlarge the memory allocation to hold at least sz bytes
*/
static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){
static int memdbEnlarge(MemStore *p, sqlite3_int64 newSz){
unsigned char *pNew;
if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){
return SQLITE_FULL;
@ -185,19 +296,27 @@ static int memdbWrite(
int iAmt,
sqlite_int64 iOfst
){
MemFile *p = (MemFile *)pFile;
if( NEVER(p->mFlags & SQLITE_DESERIALIZE_READONLY) ) return SQLITE_READONLY;
MemStore *p = ((MemFile*)pFile)->pStore;
memdbEnter(p);
if( NEVER(p->mFlags & SQLITE_DESERIALIZE_READONLY) ){
/* Can't happen: memdbLock() will return SQLITE_READONLY before
** reaching this point */
memdbLeave(p);
return SQLITE_IOERR_WRITE;
}
if( iOfst+iAmt>p->sz ){
int rc;
if( iOfst+iAmt>p->szAlloc
&& (rc = memdbEnlarge(p, iOfst+iAmt))!=SQLITE_OK
){
memdbLeave(p);
return rc;
}
if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz);
p->sz = iOfst+iAmt;
}
memcpy(p->aData+iOfst, z, iAmt);
memdbLeave(p);
return SQLITE_OK;
}
@ -209,16 +328,24 @@ static int memdbWrite(
** the size of a file, never to increase the size.
*/
static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
MemFile *p = (MemFile *)pFile;
if( NEVER(size>p->sz) ) return SQLITE_FULL;
p->sz = size;
return SQLITE_OK;
MemStore *p = ((MemFile*)pFile)->pStore;
int rc = SQLITE_OK;
memdbEnter(p);
if( NEVER(size>p->sz) ){
rc = SQLITE_FULL;
}else{
p->sz = size;
}
memdbLeave(p);
return rc;
}
/*
** Sync an memdb-file.
*/
static int memdbSync(sqlite3_file *pFile, int flags){
UNUSED_PARAMETER(pFile);
UNUSED_PARAMETER(flags);
return SQLITE_OK;
}
@ -226,8 +353,10 @@ static int memdbSync(sqlite3_file *pFile, int flags){
** Return the current file-size of an memdb-file.
*/
static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
MemFile *p = (MemFile *)pFile;
MemStore *p = ((MemFile*)pFile)->pStore;
memdbEnter(p);
*pSize = p->sz;
memdbLeave(p);
return SQLITE_OK;
}
@ -235,19 +364,48 @@ static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
** Lock an memdb-file.
*/
static int memdbLock(sqlite3_file *pFile, int eLock){
MemFile *p = (MemFile *)pFile;
if( eLock>SQLITE_LOCK_SHARED
&& (p->mFlags & SQLITE_DESERIALIZE_READONLY)!=0
){
return SQLITE_READONLY;
MemFile *pThis = (MemFile*)pFile;
MemStore *p = pThis->pStore;
int rc = SQLITE_OK;
if( eLock==pThis->eLock ) return SQLITE_OK;
memdbEnter(p);
if( eLock>SQLITE_LOCK_SHARED ){
if( p->mFlags & SQLITE_DESERIALIZE_READONLY ){
rc = SQLITE_READONLY;
}else if( pThis->eLock<=SQLITE_LOCK_SHARED ){
if( p->nWrLock ){
rc = SQLITE_BUSY;
}else{
p->nWrLock = 1;
}
}
}else if( eLock==SQLITE_LOCK_SHARED ){
if( pThis->eLock > SQLITE_LOCK_SHARED ){
assert( p->nWrLock==1 );
p->nWrLock = 0;
}else if( p->nWrLock ){
rc = SQLITE_BUSY;
}else{
p->nRdLock++;
}
}else{
assert( eLock==SQLITE_LOCK_NONE );
if( pThis->eLock>SQLITE_LOCK_SHARED ){
assert( p->nWrLock==1 );
p->nWrLock = 0;
}
assert( p->nRdLock>0 );
p->nRdLock--;
}
p->eLock = eLock;
return SQLITE_OK;
if( rc==SQLITE_OK ) pThis->eLock = eLock;
memdbLeave(p);
return rc;
}
#if 0 /* Never used because memdbAccess() always returns false */
#if 0
/*
** Check if another file-handle holds a RESERVED lock on an memdb-file.
** This interface is only used for crash recovery, which does not
** occur on an in-memory database.
*/
static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){
*pResOut = 0;
@ -255,12 +413,14 @@ static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){
}
#endif
/*
** File control method. For custom operations on an memdb-file.
*/
static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){
MemFile *p = (MemFile *)pFile;
MemStore *p = ((MemFile*)pFile)->pStore;
int rc = SQLITE_NOTFOUND;
memdbEnter(p);
if( op==SQLITE_FCNTL_VFSNAME ){
*(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz);
rc = SQLITE_OK;
@ -278,6 +438,7 @@ static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){
*(sqlite3_int64*)pArg = iLimit;
rc = SQLITE_OK;
}
memdbLeave(p);
return rc;
}
@ -294,6 +455,7 @@ static int memdbSectorSize(sqlite3_file *pFile){
** Return the device characteristic flags supported by an memdb-file.
*/
static int memdbDeviceCharacteristics(sqlite3_file *pFile){
UNUSED_PARAMETER(pFile);
return SQLITE_IOCAP_ATOMIC |
SQLITE_IOCAP_POWERSAFE_OVERWRITE |
SQLITE_IOCAP_SAFE_APPEND |
@ -307,20 +469,26 @@ static int memdbFetch(
int iAmt,
void **pp
){
MemFile *p = (MemFile *)pFile;
MemStore *p = ((MemFile*)pFile)->pStore;
memdbEnter(p);
if( iOfst+iAmt>p->sz ){
*pp = 0;
}else{
p->nMmap++;
*pp = (void*)(p->aData + iOfst);
}
memdbLeave(p);
return SQLITE_OK;
}
/* Release a memory-mapped page */
static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
MemFile *p = (MemFile *)pFile;
MemStore *p = ((MemFile*)pFile)->pStore;
UNUSED_PARAMETER(iOfst);
UNUSED_PARAMETER(pPage);
memdbEnter(p);
p->nMmap--;
memdbLeave(p);
return SQLITE_OK;
}
@ -330,20 +498,79 @@ static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
static int memdbOpen(
sqlite3_vfs *pVfs,
const char *zName,
sqlite3_file *pFile,
sqlite3_file *pFd,
int flags,
int *pOutFlags
){
MemFile *p = (MemFile*)pFile;
MemFile *pFile = (MemFile*)pFd;
MemStore *p = 0;
int szName;
if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFile, flags, pOutFlags);
return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFd, flags, pOutFlags);
}
memset(p, 0, sizeof(*p));
p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
memset(pFile, 0, sizeof(*p));
szName = sqlite3Strlen30(zName);
if( szName>1 && zName[0]=='/' ){
int i;
#ifndef SQLITE_MUTEX_OMIT
sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
#endif
sqlite3_mutex_enter(pVfsMutex);
for(i=0; i<memdb_g.nMemStore; i++){
if( strcmp(memdb_g.apMemStore[i]->zFName,zName)==0 ){
p = memdb_g.apMemStore[i];
break;
}
}
if( p==0 ){
MemStore **apNew;
p = sqlite3Malloc( sizeof(*p) + szName + 3 );
if( p==0 ){
sqlite3_mutex_leave(pVfsMutex);
return SQLITE_NOMEM;
}
apNew = sqlite3Realloc(memdb_g.apMemStore,
sizeof(apNew[0])*(memdb_g.nMemStore+1) );
if( apNew==0 ){
sqlite3_free(p);
sqlite3_mutex_leave(pVfsMutex);
return SQLITE_NOMEM;
}
apNew[memdb_g.nMemStore++] = p;
memdb_g.apMemStore = apNew;
memset(p, 0, sizeof(*p));
p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE|SQLITE_DESERIALIZE_FREEONCLOSE;
p->szMax = sqlite3GlobalConfig.mxMemdbSize;
p->zFName = (char*)&p[1];
memcpy(p->zFName, zName, szName+1);
p->pMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
if( p->pMutex==0 ){
memdb_g.nMemStore--;
sqlite3_free(p);
sqlite3_mutex_leave(pVfsMutex);
return SQLITE_NOMEM;
}
p->nRef = 1;
memdbEnter(p);
}else{
memdbEnter(p);
p->nRef++;
}
sqlite3_mutex_leave(pVfsMutex);
}else{
p = sqlite3Malloc( sizeof(*p) );
if( p==0 ){
return SQLITE_NOMEM;
}
memset(p, 0, sizeof(*p));
p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
p->szMax = sqlite3GlobalConfig.mxMemdbSize;
}
pFile->pStore = p;
assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */
*pOutFlags = flags | SQLITE_OPEN_MEMORY;
pFile->pMethods = &memdb_io_methods;
p->szMax = sqlite3GlobalConfig.mxMemdbSize;
pFd->pMethods = &memdb_io_methods;
memdbLeave(p);
return SQLITE_OK;
}
@ -371,6 +598,9 @@ static int memdbAccess(
int flags,
int *pResOut
){
UNUSED_PARAMETER(pVfs);
UNUSED_PARAMETER(zPath);
UNUSED_PARAMETER(flags);
*pResOut = 0;
return SQLITE_OK;
}
@ -386,6 +616,7 @@ static int memdbFullPathname(
int nOut,
char *zOut
){
UNUSED_PARAMETER(pVfs);
sqlite3_snprintf(nOut, zOut, "%s", zPath);
return SQLITE_OK;
}
@ -458,9 +689,14 @@ static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
*/
static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){
MemFile *p = 0;
MemStore *pStore;
int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p);
if( rc ) return 0;
if( p->base.pMethods!=&memdb_io_methods ) return 0;
pStore = p->pStore;
memdbEnter(pStore);
if( pStore->zFName!=0 ) p = 0;
memdbLeave(pStore);
return p;
}
@ -496,12 +732,14 @@ unsigned char *sqlite3_serialize(
if( piSize ) *piSize = -1;
if( iDb<0 ) return 0;
if( p ){
if( piSize ) *piSize = p->sz;
MemStore *pStore = p->pStore;
assert( pStore->pMutex==0 );
if( piSize ) *piSize = pStore->sz;
if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
pOut = p->aData;
pOut = pStore->aData;
}else{
pOut = sqlite3_malloc64( p->sz );
if( pOut ) memcpy(pOut, p->aData, p->sz);
pOut = sqlite3_malloc64( pStore->sz );
if( pOut ) memcpy(pOut, pStore->aData, pStore->sz);
}
return pOut;
}
@ -595,15 +833,16 @@ int sqlite3_deserialize(
if( p==0 ){
rc = SQLITE_ERROR;
}else{
p->aData = pData;
MemStore *pStore = p->pStore;
pStore->aData = pData;
pData = 0;
p->sz = szDb;
p->szAlloc = szBuf;
p->szMax = szBuf;
if( p->szMax<sqlite3GlobalConfig.mxMemdbSize ){
p->szMax = sqlite3GlobalConfig.mxMemdbSize;
pStore->sz = szDb;
pStore->szAlloc = szBuf;
pStore->szMax = szBuf;
if( pStore->szMax<sqlite3GlobalConfig.mxMemdbSize ){
pStore->szMax = sqlite3GlobalConfig.mxMemdbSize;
}
p->mFlags = mFlags;
pStore->mFlags = mFlags;
rc = SQLITE_OK;
}
@ -622,7 +861,7 @@ end_deserialize:
*/
int sqlite3MemdbInit(void){
sqlite3_vfs *pLower = sqlite3_vfs_find(0);
int sz = pLower->szOsFile;
unsigned int sz = pLower->szOsFile;
memdb_vfs.pAppData = pLower;
/* The following conditional can only be true when compiled for
** Windows x86 and SQLITE_MAX_MMAP_SIZE=0. We always leave
@ -632,4 +871,4 @@ int sqlite3MemdbInit(void){
memdb_vfs.szOsFile = sz;
return sqlite3_vfs_register(&memdb_vfs, 0);
}
#endif /* SQLITE_ENABLE_DESERIALIZE */
#endif /* SQLITE_OMIT_DESERIALIZE */

View File

@ -8067,6 +8067,22 @@ int sqlite3_os_init(void){
sqlite3_vfs_register(&aVfs[i], i==0);
}
unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
/* Validate lock assumptions */
assert( SQLITE_SHM_NLOCK==8 ); /* Number of available locks */
assert( UNIX_SHM_BASE==120 ); /* Start of locking area */
/* Locks:
** WRITE UNIX_SHM_BASE 120
** CKPT UNIX_SHM_BASE+1 121
** RECOVER UNIX_SHM_BASE+2 122
** READ-0 UNIX_SHM_BASE+3 123
** READ-1 UNIX_SHM_BASE+4 124
** READ-2 UNIX_SHM_BASE+5 125
** READ-3 UNIX_SHM_BASE+6 126
** READ-4 UNIX_SHM_BASE+7 127
** DMS UNIX_SHM_BASE+8 128
*/
assert( UNIX_SHM_DMS==128 ); /* Byte offset of the deadman-switch */
return SQLITE_OK;
}

View File

@ -4665,7 +4665,7 @@ int sqlite3PagerOpen(
int rc = SQLITE_OK; /* Return code */
int tempFile = 0; /* True for temp files (incl. in-memory files) */
int memDb = 0; /* True if this is an in-memory file */
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
int memJM = 0; /* Memory journal mode */
#else
# define memJM 0
@ -4869,7 +4869,7 @@ int sqlite3PagerOpen(
int fout = 0; /* VFS flags returned by xOpen() */
rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
assert( !memDb );
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
memJM = (fout&SQLITE_OPEN_MEMORY)!=0;
#endif
readOnly = (fout&SQLITE_OPEN_READONLY)!=0;

View File

@ -193,7 +193,7 @@ ifnotexists(A) ::= . {A = 0;}
ifnotexists(A) ::= IF NOT EXISTS. {A = 1;}
%type temp {int}
%ifndef SQLITE_OMIT_TEMPDB
temp(A) ::= TEMP. {A = 1;}
temp(A) ::= TEMP. {A = pParse->db->init.busy==0;}
%endif SQLITE_OMIT_TEMPDB
temp(A) ::= . {A = 0;}
create_table_args ::= LP columnlist conslist_opt(X) RP(E) table_options(F). {

View File

@ -1715,6 +1715,19 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
}
}
#ifndef SQLITE_OMIT_WINDOWFUNC
if( IN_RENAME_OBJECT ){
Window *pWin;
for(pWin=p->pWinDefn; pWin; pWin=pWin->pNextWin){
if( sqlite3ResolveExprListNames(&sNC, pWin->pOrderBy)
|| sqlite3ResolveExprListNames(&sNC, pWin->pPartition)
){
return WRC_Abort;
}
}
}
#endif
/* The ORDER BY and GROUP BY clauses may not refer to terms in
** outer queries
*/
@ -1771,19 +1784,6 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
}
}
#ifndef SQLITE_OMIT_WINDOWFUNC
if( IN_RENAME_OBJECT ){
Window *pWin;
for(pWin=p->pWinDefn; pWin; pWin=pWin->pNextWin){
if( sqlite3ResolveExprListNames(&sNC, pWin->pOrderBy)
|| sqlite3ResolveExprListNames(&sNC, pWin->pPartition)
){
return WRC_Abort;
}
}
}
#endif
/* If this is part of a compound SELECT, check that it has the right
** number of expressions in the select list. */
if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){

View File

@ -1955,7 +1955,7 @@ static void generateColumnTypes(
** then the result column name with the table name
** prefix, ex: TABLE.COLUMN. Otherwise use zSpan.
*/
static void generateColumnNames(
void sqlite3GenerateColumnNames(
Parse *pParse, /* Parser context */
Select *pSelect /* Generate column names for this SELECT statement */
){
@ -2045,7 +2045,7 @@ static void generateColumnNames(
** and will break if those assumptions changes. Hence, use extreme caution
** when modifying this routine to avoid breaking legacy.
**
** See Also: generateColumnNames()
** See Also: sqlite3GenerateColumnNames()
*/
int sqlite3ColumnsFromExprList(
Parse *pParse, /* Parsing context */
@ -2748,6 +2748,7 @@ static int multiSelect(
pPrior->iLimit = p->iLimit;
pPrior->iOffset = p->iOffset;
pPrior->pLimit = p->pLimit;
SELECTTRACE(1, pParse, p, ("multiSelect UNION ALL left...\n"));
rc = sqlite3Select(pParse, pPrior, &dest);
pPrior->pLimit = 0;
if( rc ){
@ -2765,6 +2766,7 @@ static int multiSelect(
}
}
ExplainQueryPlan((pParse, 1, "UNION ALL"));
SELECTTRACE(1, pParse, p, ("multiSelect UNION ALL right...\n"));
rc = sqlite3Select(pParse, p, &dest);
testcase( rc!=SQLITE_OK );
pDelete = p->pPrior;
@ -2817,6 +2819,7 @@ static int multiSelect(
*/
assert( !pPrior->pOrderBy );
sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
SELECTTRACE(1, pParse, p, ("multiSelect EXCEPT/UNION left...\n"));
rc = sqlite3Select(pParse, pPrior, &uniondest);
if( rc ){
goto multi_select_end;
@ -2836,6 +2839,7 @@ static int multiSelect(
uniondest.eDest = op;
ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
sqlite3SelectOpName(p->op)));
SELECTTRACE(1, pParse, p, ("multiSelect EXCEPT/UNION right...\n"));
rc = sqlite3Select(pParse, p, &uniondest);
testcase( rc!=SQLITE_OK );
assert( p->pOrderBy==0 );
@ -2896,6 +2900,7 @@ static int multiSelect(
/* Code the SELECTs to our left into temporary table "tab1".
*/
sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
SELECTTRACE(1, pParse, p, ("multiSelect INTERSECT left...\n"));
rc = sqlite3Select(pParse, pPrior, &intersectdest);
if( rc ){
goto multi_select_end;
@ -2912,6 +2917,7 @@ static int multiSelect(
intersectdest.iSDParm = tab2;
ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
sqlite3SelectOpName(p->op)));
SELECTTRACE(1, pParse, p, ("multiSelect INTERSECT right...\n"));
rc = sqlite3Select(pParse, p, &intersectdest);
testcase( rc!=SQLITE_OK );
pDelete = p->pPrior;
@ -4469,7 +4475,7 @@ static void constInsert(
*/
static void findConstInWhere(WhereConst *pConst, Expr *pExpr){
Expr *pRight, *pLeft;
if( pExpr==0 ) return;
if( NEVER(pExpr==0) ) return;
if( ExprHasProperty(pExpr, EP_FromJoin) ) return;
if( pExpr->op==TK_AND ){
findConstInWhere(pConst, pExpr->pRight);
@ -5213,7 +5219,7 @@ static int resolveFromTermToCte(
** sqlite3SelectExpand() when walking a SELECT tree to resolve table
** names and other FROM clause elements.
*/
static void selectPopWith(Walker *pWalker, Select *p){
void sqlite3SelectPopWith(Walker *pWalker, Select *p){
Parse *pParse = pWalker->pParse;
if( OK_IF_ALWAYS_TRUE(pParse->pWith) && p->pPrior==0 ){
With *pWith = findRightmost(p)->pWith;
@ -5223,8 +5229,6 @@ static void selectPopWith(Walker *pWalker, Select *p){
}
}
}
#else
#define selectPopWith 0
#endif
/*
@ -5611,7 +5615,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
sqlite3WalkSelect(&w, pSelect);
}
w.xSelectCallback = selectExpander;
w.xSelectCallback2 = selectPopWith;
w.xSelectCallback2 = sqlite3SelectPopWith;
w.eCode = 0;
sqlite3WalkSelect(&w, pSelect);
}
@ -6198,7 +6202,7 @@ int sqlite3Select(
}
if( pDest->eDest==SRT_Output ){
generateColumnNames(pParse, p);
sqlite3GenerateColumnNames(pParse, p);
}
#ifndef SQLITE_OMIT_WINDOWFUNC
@ -6328,7 +6332,8 @@ int sqlite3Select(
** as the equivalent optimization will be handled by query planner in
** sqlite3WhereBegin().
*/
if( pTabList->nSrc>1
if( p->pWhere!=0
&& p->pWhere->op==TK_AND
&& OptimizationEnabled(db, SQLITE_PropagateConst)
&& propagateConstants(pParse, p)
){

View File

@ -3978,8 +3978,8 @@ static const char *(azHelp[]) = {
".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
" Options:",
" --append Use appendvfs to append database to the end of FILE",
#ifdef SQLITE_ENABLE_DESERIALIZE
" --deserialize Load into memory useing sqlite3_deserialize()",
#ifndef SQLITE_OMIT_DESERIALIZE
" --deserialize Load into memory using sqlite3_deserialize()",
" --hexdb Load the output of \"dbtotxt\" as an in-memory db",
" --maxsize N Maximum size for --hexdb or --deserialized database",
#endif
@ -4300,7 +4300,7 @@ int deduceDatabaseType(const char *zName, int dfltZip){
return rc;
}
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
/*
** Reconstruct an in-memory database using the output from the "dbtotxt"
** program. Read content from the file in p->zDbFilename. If p->zDbFilename
@ -4389,7 +4389,7 @@ readHexDb_error:
utf8_printf(stderr,"Error on line %d of --hexdb input\n", nLine);
return 0;
}
#endif /* SQLITE_ENABLE_DESERIALIZE */
#endif /* SQLITE_OMIT_DESERIALIZE */
/*
** Scalar function "shell_int32". The first argument to this function
@ -4650,7 +4650,7 @@ static void open_db(ShellState *p, int openFlags){
sqlite3_exec(p->db, zSql, 0, 0, 0);
sqlite3_free(zSql);
}
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
else
if( p->openMode==SHELL_OPEN_DESERIALIZE || p->openMode==SHELL_OPEN_HEXDB ){
int rc;
@ -6717,6 +6717,7 @@ static void shellExec(sqlite3 *db, int *pRc, const char *zSql){
if( rc!=SQLITE_OK ){
raw_printf(stderr, "SQL error: %s\n", zErr);
}
sqlite3_free(zErr);
*pRc = rc;
}
}
@ -8021,7 +8022,6 @@ static int do_meta_command(char *zLine, ShellState *p){
if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
ShellState data;
char *zErrMsg = 0;
int doStats = 0;
memcpy(&data, p, sizeof(data));
data.showHeader = 0;
@ -8043,7 +8043,7 @@ static int do_meta_command(char *zLine, ShellState *p){
" SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_schema) "
"WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
"ORDER BY rowid",
callback, &data, &zErrMsg
callback, &data, 0
);
if( rc==SQLITE_OK ){
sqlite3_stmt *pStmt;
@ -8059,12 +8059,12 @@ static int do_meta_command(char *zLine, ShellState *p){
}else{
raw_printf(p->out, "ANALYZE sqlite_schema;\n");
sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_schema'",
callback, &data, &zErrMsg);
callback, &data, 0);
data.cMode = data.mode = MODE_Insert;
data.zDestTable = "sqlite_stat1";
shell_exec(&data, "SELECT * FROM sqlite_stat1", &zErrMsg);
shell_exec(&data, "SELECT * FROM sqlite_stat1", 0);
data.zDestTable = "sqlite_stat4";
shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg);
shell_exec(&data, "SELECT * FROM sqlite_stat4", 0);
raw_printf(p->out, "ANALYZE sqlite_schema;\n");
}
}else
@ -8712,14 +8712,14 @@ static int do_meta_command(char *zLine, ShellState *p){
p->openMode = SHELL_OPEN_READONLY;
}else if( optionMatch(z, "nofollow") ){
p->openFlags |= SQLITE_OPEN_NOFOLLOW;
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
}else if( optionMatch(z, "deserialize") ){
p->openMode = SHELL_OPEN_DESERIALIZE;
}else if( optionMatch(z, "hexdb") ){
p->openMode = SHELL_OPEN_HEXDB;
}else if( optionMatch(z, "maxsize") && iName+1<nArg ){
p->szMax = integerValue(azArg[++iName]);
#endif /* SQLITE_ENABLE_DESERIALIZE */
#endif /* SQLITE_OMIT_DESERIALIZE */
}else if( z[0]=='-' ){
utf8_printf(stderr, "unknown option: %s\n", z);
rc = 1;
@ -10703,7 +10703,7 @@ static const char zOptions[] =
" -column set output mode to 'column'\n"
" -cmd COMMAND run \"COMMAND\" before reading stdin\n"
" -csv set output mode to 'csv'\n"
#if defined(SQLITE_ENABLE_DESERIALIZE)
#if !defined(SQLITE_OMIT_DESERIALIZE)
" -deserialize open the database using sqlite3_deserialize()\n"
#endif
" -echo print commands before execution\n"
@ -10720,7 +10720,7 @@ static const char zOptions[] =
" -list set output mode to 'list'\n"
" -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
" -markdown set output mode to 'markdown'\n"
#if defined(SQLITE_ENABLE_DESERIALIZE)
#if !defined(SQLITE_OMIT_DESERIALIZE)
" -maxsize N maximum size for a --deserialize database\n"
#endif
" -memtrace trace all memory allocations and deallocations\n"
@ -11050,7 +11050,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
#endif
}else if( strcmp(z,"-append")==0 ){
data.openMode = SHELL_OPEN_APPENDVFS;
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
}else if( strcmp(z,"-deserialize")==0 ){
data.openMode = SHELL_OPEN_DESERIALIZE;
}else if( strcmp(z,"-maxsize")==0 && i+1<argc ){
@ -11167,7 +11167,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
#endif
}else if( strcmp(z,"-append")==0 ){
data.openMode = SHELL_OPEN_APPENDVFS;
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
}else if( strcmp(z,"-deserialize")==0 ){
data.openMode = SHELL_OPEN_DESERIALIZE;
}else if( strcmp(z,"-maxsize")==0 && i+1<argc ){

View File

@ -1141,6 +1141,10 @@ struct sqlite3_io_methods {
** other process. This opcode cannot be used to detect transactions opened
** by clients within the current process, only within other processes.
** </ul>
**
** <li>[[SQLITE_FCNTL_CKSM_FILE]]
** Used by the cksmvfs VFS module only.
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
@ -1180,8 +1184,8 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_CKPT_DONE 37
#define SQLITE_FCNTL_RESERVE_BYTES 38
#define SQLITE_FCNTL_CKPT_START 39
#define SQLITE_FCNTL_EXTERNAL_READER 40
#define SQLITE_FCNTL_CKSM_FILE 41
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@ -4194,6 +4198,15 @@ const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and
** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so
** sqlite3_stmt_readonly() returns false for those commands.
**
** ^This routine returns false if there is any possibility that the
** statement might change the database file. ^A false return does
** not guarantee that the statement will change the database file.
** ^For example, an UPDATE statement might have a WHERE clause that
** makes it a no-op, but the sqlite3_stmt_readonly() result would still
** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
** read-only no-op if the table already exists, but
** sqlite3_stmt_readonly() still returns false for such a statement.
*/
int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
@ -4363,18 +4376,22 @@ typedef struct sqlite3_context sqlite3_context;
** contain embedded NULs. The result of expressions involving strings
** with embedded NULs is undefined.
**
** ^The fifth argument to the BLOB and string binding interfaces
** is a destructor used to dispose of the BLOB or
** string after SQLite has finished with it. ^The destructor is called
** to dispose of the BLOB or string even if the call to the bind API fails,
** except the destructor is not called if the third parameter is a NULL
** pointer or the fourth parameter is negative.
** ^If the fifth argument is
** the special value [SQLITE_STATIC], then SQLite assumes that the
** information is in static, unmanaged space and does not need to be freed.
** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
** SQLite makes its own private copy of the data immediately, before
** the sqlite3_bind_*() routine returns.
** ^The fifth argument to the BLOB and string binding interfaces controls
** or indicates the lifetime of the object referenced by the third parameter.
** ^These three options exist:
** ^(1) A destructor to dispose of the BLOB or string after SQLite has finished
** with it may be passed. ^It is called to dispose of the BLOB or string even
** if the call to the bind API fails, except the destructor is not called if
** the third parameter is a NULL pointer or the fourth parameter is negative.
** ^(2) The special constant, [SQLITE_STATIC], may be passsed to indicate that
** the application remains responsible for disposing of the object. ^In this
** case, the object and the provided pointer to it must remain valid until
** either the prepared statement is finalized or the same SQL parameter is
** bound to something else, whichever occurs sooner.
** ^(3) The constant, [SQLITE_TRANSIENT], may be passed to indicate that the
** object is to be copied prior to the return from sqlite3_bind_*(). ^The
** object and pointer to it must remain valid until then. ^SQLite will then
** manage the lifetime of its private copy.
**
** ^The sixth argument to sqlite3_bind_text64() must be one of
** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
@ -9814,8 +9831,8 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory
** allocation error occurs.
**
** This interface is only available if SQLite is compiled with the
** [SQLITE_ENABLE_DESERIALIZE] option.
** This interface is omitted if SQLite is compiled with the
** [SQLITE_OMIT_DESERIALIZE] option.
*/
unsigned char *sqlite3_serialize(
sqlite3 *db, /* The database connection */
@ -9866,8 +9883,8 @@ unsigned char *sqlite3_serialize(
** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then
** [sqlite3_free()] is invoked on argument P prior to returning.
**
** This interface is only available if SQLite is compiled with the
** [SQLITE_ENABLE_DESERIALIZE] option.
** This interface is omitted if SQLite is compiled with the
** [SQLITE_OMIT_DESERIALIZE] option.
*/
int sqlite3_deserialize(
sqlite3 *db, /* The database connection */

View File

@ -1731,7 +1731,6 @@ struct sqlite3 {
#define SQLITE_SkipScan 0x00004000 /* Skip-scans */
#define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */
#define SQLITE_MinMaxOpt 0x00010000 /* The min/max optimization */
#define SQLITE_ExistsToIN 0x00020000 /* The EXISTS-to-IN optimization */
#define SQLITE_AllOpts 0xffffffff /* All optimizations */
/*
@ -3794,7 +3793,7 @@ struct Sqlite3Config {
void (*xVdbeBranch)(void*,unsigned iSrcLine,u8 eThis,u8 eMx); /* Callback */
void *pVdbeBranchArg; /* 1st argument */
#endif
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
sqlite3_int64 mxMemdbSize; /* Default max memdb size */
#endif
#ifndef SQLITE_UNTESTABLE
@ -3887,6 +3886,12 @@ void sqlite3WalkWinDefnDummyCallback(Walker*,Select*);
void sqlite3SelectWalkAssert2(Walker*, Select*);
#endif
#ifndef SQLITE_OMIT_CTE
void sqlite3SelectPopWith(Walker*, Select*);
#else
# define sqlite3SelectPopWith 0
#endif
/*
** Return code from the parse-tree walking primitives and their
** callbacks.
@ -4312,6 +4317,7 @@ void sqlite3ResetOneSchema(sqlite3*,int);
void sqlite3CollapseDatabaseArray(sqlite3*);
void sqlite3CommitInternalChanges(sqlite3*);
void sqlite3DeleteColumnNames(sqlite3*,Table*);
void sqlite3GenerateColumnNames(Parse *pParse, Select *pSelect);
int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char);
Table *sqlite3ResultSetOfSelect(Parse*,Select*,char);
@ -4690,7 +4696,7 @@ int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
const char *sqlite3ErrName(int);
#endif
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
int sqlite3MemdbInit(void);
#endif

View File

@ -2600,7 +2600,7 @@ static int SQLITE_TCLAPI DbObjCmd(
** Reopen DATABASE (default "main") using the content in $VALUE
*/
case DB_DESERIALIZE: {
#ifndef SQLITE_ENABLE_DESERIALIZE
#ifdef SQLITE_OMIT_DESERIALIZE
Tcl_AppendResult(interp, "MEMDB not available in this build",
(char*)0);
rc = TCL_ERROR;
@ -3167,7 +3167,7 @@ deserialize_error:
** Return a serialization of a database.
*/
case DB_SERIALIZE: {
#ifndef SQLITE_ENABLE_DESERIALIZE
#ifdef SQLITE_OMIT_DESERIALIZE
Tcl_AppendResult(interp, "MEMDB not available in this build",
(char*)0);
rc = TCL_ERROR;

View File

@ -389,6 +389,7 @@ static int echoDestructor(sqlite3_vtab *pVtab){
typedef struct EchoModule EchoModule;
struct EchoModule {
Tcl_Interp *interp;
sqlite3 *db;
};
/*
@ -1352,6 +1353,9 @@ extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
extern const char *sqlite3ErrName(int);
static void moduleDestroy(void *p){
EchoModule *pMod = (EchoModule*)p;
sqlite3_create_function(pMod->db, "function_that_does_not_exist_0982ma98",
SQLITE_ANY, 1, 0, 0, 0, 0);
sqlite3_free(p);
}
@ -1376,6 +1380,7 @@ static int SQLITE_TCLAPI register_echo_module(
/* Virtual table module "echo" */
pMod = sqlite3_malloc(sizeof(EchoModule));
pMod->interp = interp;
pMod->db = db;
rc = sqlite3_create_module_v2(
db, "echo", &echoModule, (void*)pMod, moduleDestroy
);
@ -1384,6 +1389,7 @@ static int SQLITE_TCLAPI register_echo_module(
if( rc==SQLITE_OK ){
pMod = sqlite3_malloc(sizeof(EchoModule));
pMod->interp = interp;
pMod->db = db;
rc = sqlite3_create_module_v2(db, "echo_v2",
&echoModuleV2, (void*)pMod, moduleDestroy
);

View File

@ -155,7 +155,7 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "hiddencolumns", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
Tcl_SetVar2(interp, "sqlite_options", "deserialize", "1", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "deserialize", "0", TCL_GLOBAL_ONLY);

View File

@ -57,33 +57,41 @@ Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
}
pTmpSchema = pParse->db->aDb[1].pSchema;
p = sqliteHashFirst(&pTmpSchema->trigHash);
if( p==0 ){
return pTab->pTrigger;
}
pList = pTab->pTrigger;
if( pTmpSchema!=pTab->pSchema ){
while( p ){
Trigger *pTrig = (Trigger *)sqliteHashData(p);
if( pTrig->pTabSchema==pTab->pSchema
&& 0==sqlite3StrICmp(pTrig->table, pTab->zName)
){
pTrig->pNext = pList;
pList = pTrig;
}else if( pTrig->op==TK_RETURNING
while( p ){
Trigger *pTrig = (Trigger *)sqliteHashData(p);
if( pTrig->pTabSchema==pTab->pSchema
&& pTrig->table
&& 0==sqlite3StrICmp(pTrig->table, pTab->zName)
&& pTrig->pTabSchema!=pTmpSchema
){
pTrig->pNext = pList;
pList = pTrig;
}else if( pTrig->op==TK_RETURNING
#ifndef SQLITE_OMIT_VIRTUALTABLE
&& pParse->db->pVtabCtx==0
&& pParse->db->pVtabCtx==0
#endif
){
assert( pParse->bReturning );
assert( &(pParse->u1.pReturning->retTrig) == pTrig );
pTrig->table = pTab->zName;
pTrig->pTabSchema = pTab->pSchema;
pTrig->pNext = pList;
pList = pTrig;
}
p = sqliteHashNext(p);
}
){
assert( pParse->bReturning );
assert( &(pParse->u1.pReturning->retTrig) == pTrig );
pTrig->table = pTab->zName;
pTrig->pTabSchema = pTab->pSchema;
pTrig->pNext = pList;
pList = pTrig;
}
p = sqliteHashNext(p);
}
#if 0
if( pList ){
Trigger *pX;
printf("Triggers for %s:", pTab->zName);
for(pX=pList; pX; pX=pX->pNext){
printf(" %s", pX->zName);
}
printf("\n");
fflush(stdout);
}
#endif
return pList;
}
@ -887,15 +895,6 @@ static ExprList *sqlite3ExpandReturning(
}
}
}
if( !db->mallocFailed ){
Vdbe *v = pParse->pVdbe;
assert( v!=0 );
sqlite3VdbeSetNumCols(v, pNew->nExpr);
for(i=0; i<pNew->nExpr; i++){
sqlite3VdbeSetColName(v, i, COLNAME_NAME, pNew->a[i].zEName,
SQLITE_TRANSIENT);
}
}
return pNew;
}
@ -911,13 +910,27 @@ static void codeReturningTrigger(
int regIn /* The first in an array of registers */
){
Vdbe *v = pParse->pVdbe;
sqlite3 *db = pParse->db;
ExprList *pNew;
Returning *pReturning;
Select sSelect;
SrcList sFrom;
assert( v!=0 );
assert( pParse->bReturning );
pReturning = pParse->u1.pReturning;
assert( pTrigger == &(pReturning->retTrig) );
memset(&sSelect, 0, sizeof(sSelect));
memset(&sFrom, 0, sizeof(sFrom));
sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0);
sSelect.pSrc = &sFrom;
sFrom.nSrc = 1;
sFrom.a[0].pTab = pTab;
sqlite3SelectPrep(pParse, &sSelect, 0);
if( db->mallocFailed==0 && pParse->nErr==0 ){
sqlite3GenerateColumnNames(pParse, &sSelect);
}
sqlite3ExprListDelete(db, sSelect.pEList);
pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab);
if( pNew ){
NameContext sNC;
@ -938,13 +951,14 @@ static void codeReturningTrigger(
pParse->nMem += nCol+2;
pReturning->iRetReg = reg;
for(i=0; i<nCol; i++){
sqlite3ExprCodeFactorable(pParse, pNew->a[i].pExpr, reg+i);
Expr *pCol = pNew->a[i].pExpr;
sqlite3ExprCodeFactorable(pParse, pCol, reg+i);
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, i, reg+i);
sqlite3VdbeAddOp2(v, OP_NewRowid, pReturning->iRetCur, reg+i+1);
sqlite3VdbeAddOp3(v, OP_Insert, pReturning->iRetCur, reg+i, reg+i+1);
}
sqlite3ExprListDelete(pParse->db, pNew);
sqlite3ExprListDelete(db, pNew);
pParse->eTriggerOp = 0;
pParse->pTriggerTab = 0;
}

View File

@ -275,18 +275,36 @@ static VdbeCursor *allocateCursor(
sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
p->apCsr[iCur] = 0;
}
if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
memset(pCx, 0, offsetof(VdbeCursor,pAltCursor));
pCx->eCurType = eCurType;
pCx->iDb = iDb;
pCx->nField = nField;
pCx->aOffset = &pCx->aType[nField];
if( eCurType==CURTYPE_BTREE ){
pCx->uc.pCursor = (BtCursor*)
&pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
sqlite3BtreeCursorZero(pCx->uc.pCursor);
/* There used to be a call to sqlite3VdbeMemClearAndResize() to make sure
** the pMem used to hold space for the cursor has enough storage available
** in pMem->zMalloc. But for the special case of the aMem[] entries used
** to hold cursors, it is faster to in-line the logic. */
assert( pMem->flags==MEM_Undefined );
assert( (pMem->flags & MEM_Dyn)==0 );
assert( pMem->szMalloc==0 || pMem->z==pMem->zMalloc );
if( pMem->szMalloc<nByte ){
if( pMem->szMalloc>0 ){
sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
}
pMem->z = pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, nByte);
if( pMem->zMalloc==0 ){
pMem->szMalloc = 0;
return 0;
}
pMem->szMalloc = nByte;
}
p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->zMalloc;
memset(pCx, 0, offsetof(VdbeCursor,pAltCursor));
pCx->eCurType = eCurType;
pCx->iDb = iDb;
pCx->nField = nField;
pCx->aOffset = &pCx->aType[nField];
if( eCurType==CURTYPE_BTREE ){
pCx->uc.pCursor = (BtCursor*)
&pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
sqlite3BtreeCursorZero(pCx->uc.pCursor);
}
return pCx;
}
@ -574,6 +592,11 @@ static void registerTrace(int iReg, Mem *p){
printf("\n");
sqlite3VdbeCheckMemInvariants(p);
}
/**/ void sqlite3PrintMem(Mem *pMem){
memTracePrint(pMem);
printf("\n");
fflush(stdout);
}
#endif
#ifdef SQLITE_DEBUG
@ -2021,6 +2044,31 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
pIn3 = &aMem[pOp->p3];
flags1 = pIn1->flags;
flags3 = pIn3->flags;
if( (flags1 & flags3 & MEM_Int)!=0 ){
assert( (pOp->p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_TEXT || CORRUPT_DB );
/* Common case of comparison of two integers */
if( pIn3->u.i > pIn1->u.i ){
iCompare = +1;
if( sqlite3aGTb[pOp->opcode] ){
VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
goto jump_to_p2;
}
}else if( pIn3->u.i < pIn1->u.i ){
iCompare = -1;
if( sqlite3aLTb[pOp->opcode] ){
VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
goto jump_to_p2;
}
}else{
iCompare = 0;
if( sqlite3aEQb[pOp->opcode] ){
VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
goto jump_to_p2;
}
}
VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
break;
}
if( (flags1 | flags3)&MEM_Null ){
/* One or both operands are NULL */
if( pOp->p5 & SQLITE_NULLEQ ){
@ -2051,7 +2099,8 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
break;
}
}else{
/* Neither operand is NULL. Do a comparison. */
/* Neither operand is NULL and we couldn't do the special high-speed
** integer comparison case. So do a general-case comparison. */
affinity = pOp->p5 & SQLITE_AFF_MASK;
if( affinity>=SQLITE_AFF_NUMERIC ){
if( (flags1 | flags3)&MEM_Str ){
@ -2064,14 +2113,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
applyNumericAffinity(pIn3,0);
}
}
/* Handle the common case of integer comparison here, as an
** optimization, to avoid a call to sqlite3MemCompare() */
if( (pIn1->flags & pIn3->flags & MEM_Int)!=0 ){
if( pIn3->u.i > pIn1->u.i ){ res = +1; goto compare_op; }
if( pIn3->u.i < pIn1->u.i ){ res = -1; goto compare_op; }
res = 0;
goto compare_op;
}
}else if( affinity==SQLITE_AFF_TEXT ){
if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
testcase( pIn1->flags & MEM_Int );
@ -2094,7 +2135,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
}
compare_op:
/* At this point, res is negative, zero, or positive if reg[P1] is
** less than, equal to, or greater than reg[P3], respectively. Compute
** the answer to this operator in res2, depending on what the comparison
@ -4535,8 +4576,18 @@ case OP_SeekHit: {
assert( pC!=0 );
assert( pOp->p3>=pOp->p2 );
if( pC->seekHit<pOp->p2 ){
#ifdef SQLITE_DEBUG
if( db->flags&SQLITE_VdbeTrace ){
printf("seekHit changes from %d to %d\n", pC->seekHit, pOp->p2);
}
#endif
pC->seekHit = pOp->p2;
}else if( pC->seekHit>pOp->p3 ){
#ifdef SQLITE_DEBUG
if( db->flags&SQLITE_VdbeTrace ){
printf("seekHit changes from %d to %d\n", pC->seekHit, pOp->p3);
}
#endif
pC->seekHit = pOp->p3;
}
break;
@ -4651,6 +4702,11 @@ case OP_IfNoHope: { /* jump, in3 */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
#ifdef SQLITE_DEBUG
if( db->flags&SQLITE_VdbeTrace ){
printf("seekHit is %d\n", pC->seekHit);
}
#endif
if( pC->seekHit>=pOp->p4.i ) break;
/* Fall through into OP_NotFound */
/* no break */ deliberate_fall_through

View File

@ -75,7 +75,9 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
/* The szMalloc field holds the correct memory allocation size */
assert( p->szMalloc==0
|| p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc) );
|| (p->flags==MEM_Undefined
&& p->szMalloc<=sqlite3DbMallocSize(p->db,p->zMalloc))
|| p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc));
/* If p holds a string or blob, the Mem.z must point to exactly
** one of the following:
@ -239,7 +241,9 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
testcase( bPreserve && pMem->z==0 );
assert( pMem->szMalloc==0
|| pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
|| (pMem->flags==MEM_Undefined
&& pMem->szMalloc<=sqlite3DbMallocSize(pMem->db,pMem->zMalloc))
|| pMem->szMalloc==sqlite3DbMallocSize(pMem->db,pMem->zMalloc));
if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){
if( pMem->db ){
pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);

View File

@ -999,7 +999,6 @@ static void walCleanupHash(Wal *pWal){
int iLimit = 0; /* Zero values greater than this */
int nByte; /* Number of bytes to zero in aPgno[] */
int i; /* Used to iterate through aHash[] */
int rc; /* Return code form walHashGet() */
assert( pWal->writeLock );
testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE-1 );
@ -1014,8 +1013,8 @@ static void walCleanupHash(Wal *pWal){
*/
assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) );
assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] );
rc = walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc);
if( NEVER(rc) ) return; /* Defense-in-depth, in case (1) above is wrong */
i = walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc);
if( NEVER(i) ) return; /* Defense-in-depth, in case (1) above is wrong */
/* Zero all hash-table entries that correspond to frame numbers greater
** than pWal->hdr.mxFrame.

View File

@ -140,6 +140,9 @@ int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){
Parse *pParse;
if( pWalker->xSelectCallback2==sqlite3WalkWinDefnDummyCallback
|| ((pParse = pWalker->pParse)!=0 && IN_RENAME_OBJECT)
#ifndef SQLITE_OMIT_CTE
|| pWalker->xSelectCallback2==sqlite3SelectPopWith
#endif
){
/* The following may return WRC_Abort if there are unresolvable
** symbols (e.g. a table that does not exist) in a window definition. */

View File

@ -338,6 +338,18 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
}
pScan->pWC = pWC;
pScan->k = k+1;
#ifdef WHERETRACE_ENABLED
if( sqlite3WhereTrace & 0x20000 ){
int ii;
sqlite3DebugPrintf("SCAN-TERM %p: nEquiv=%d",
pTerm, pScan->nEquiv);
for(ii=0; ii<pScan->nEquiv; ii++){
sqlite3DebugPrintf(" {%d:%d}",
pScan->aiCur[ii], pScan->aiColumn[ii]);
}
sqlite3DebugPrintf("\n");
}
#endif
return pTerm;
}
}
@ -2501,6 +2513,8 @@ static int whereLoopAddBtreeIndex(
if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
assert( pNew->u.btree.nEq<pProbe->nColumn );
assert( pNew->u.btree.nEq<pProbe->nKeyCol
|| pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY );
saved_nEq = pNew->u.btree.nEq;
saved_nBtm = pNew->u.btree.nBtm;
@ -2634,6 +2648,7 @@ static int whereLoopAddBtreeIndex(
pNew->wsFlags |= WHERE_UNQ_WANTED;
}
}
if( scan.iEquiv>1 ) pNew->wsFlags |= WHERE_TRANSCONS;
}else if( eOp & WO_ISNULL ){
pNew->wsFlags |= WHERE_COLUMN_NULL;
}else if( eOp & (WO_GT|WO_GE) ){
@ -2777,6 +2792,8 @@ static int whereLoopAddBtreeIndex(
if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0
&& pNew->u.btree.nEq<pProbe->nColumn
&& (pNew->u.btree.nEq<pProbe->nKeyCol ||
pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY)
){
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
}
@ -4145,7 +4162,7 @@ static LogEst whereSortingCost(
}else if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT) ){
/* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT
** reduces the number of output rows by a factor of 2 */
if( nRow>10 ) nRow -= 10; assert( 10==sqlite3LogEst(2) );
if( nRow>10 ){ nRow -= 10; assert( 10==sqlite3LogEst(2) ); }
}
rSortCost += estLog(nRow);
return rSortCost;
@ -5435,6 +5452,8 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
int j;
sqlite3VdbeResolveLabel(v, pLevel->addrNxt);
for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
assert( sqlite3VdbeGetOp(v, pIn->addrInTop+1)->opcode==OP_IsNull
|| pParse->db->mallocFailed );
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
if( pIn->eEndLoopOp!=OP_Noop ){
if( pIn->nPrefix ){
@ -5459,6 +5478,11 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3VdbeCurrentAddr(v)+2,
pIn->iBase, pIn->nPrefix);
VdbeCoverage(v);
/* Retarget the OP_IsNull against the left operand of IN so
** it jumps past the OP_IfNoHope. This is because the
** OP_IsNull also bypasses the OP_Affinity opcode that is
** required by OP_IfNoHope. */
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
}
}
sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);

View File

@ -293,8 +293,8 @@ struct WhereScan {
const char *zCollName; /* Required collating sequence, if not NULL */
Expr *pIdxExpr; /* Search for this index expression */
char idxaff; /* Must match this affinity, if zCollName!=NULL */
unsigned char nEquiv; /* Number of entries in aEquiv[] */
unsigned char iEquiv; /* Next unused slot in aEquiv[] */
unsigned char nEquiv; /* Number of entries in aiCur[] and aiColumn[] */
unsigned char iEquiv; /* Next unused slot in aiCur[] and aiColumn[] */
u32 opMask; /* Acceptable operators */
int k; /* Resume scanning at this->pWC->a[this->k] */
int aiCur[11]; /* Cursors in the equivalence class */
@ -603,5 +603,6 @@ void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
#define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */
#define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */
#define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */
#define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */
#endif /* !defined(SQLITE_WHEREINT_H) */

View File

@ -297,6 +297,12 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
}else{
pTerm->wtFlags |= TERM_CODED;
}
#ifdef WHERETRACE_ENABLED
if( sqlite3WhereTrace & 0x20000 ){
sqlite3DebugPrintf("DISABLE-");
sqlite3WhereTermPrint(pTerm, (int)(pTerm - (pTerm->pWC->a)));
}
#endif
if( pTerm->iParent<0 ) break;
pTerm = &pTerm->pWC->a[pTerm->iParent];
assert( pTerm!=0 );
@ -614,7 +620,22 @@ static int codeEqualityTerm(
sqlite3DbFree(pParse->db, aiMap);
#endif
}
disableTerm(pLevel, pTerm);
/* As an optimization, try to disable the WHERE clause term that is
** driving the index as it will always be true. The correct answer is
** obtained regardless, but we might get the answer with fewer CPU cycles
** by omitting the term.
**
** But do not disable the term unless we are certain that the term is
** not a transitive constraint. For an example of where that does not
** work, see https://sqlite.org/forum/forumpost/eb8613976a (2021-05-04)
*/
if( (pLevel->pWLoop->wsFlags & WHERE_TRANSCONS)==0
|| (pTerm->eOperator & WO_EQUIV)==0
){
disableTerm(pLevel, pTerm);
}
return iReg;
}
@ -1728,9 +1749,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
** a forward order scan on a descending index, interchange the
** start and end terms (pRangeStart and pRangeEnd).
*/
if( (nEq<pIdx->nKeyCol && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
|| (bRev && pIdx->nKeyCol==nEq)
){
if( (nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC)) ){
SWAP(WhereTerm *, pRangeEnd, pRangeStart);
SWAP(u8, bSeekPastNull, bStopAtNull);
SWAP(u8, nBtm, nTop);
@ -2151,7 +2170,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
/* The extra 0x10000 bit on the opcode is masked off and does not
** become part of the new Expr.op. However, it does make the
** op==TK_AND comparison inside of sqlite3PExpr() false, and this
** prevents sqlite3PExpr() from implementing AND short-circuit
** prevents sqlite3PExpr() from applying the AND short-circuit
** optimization, which we do not want here. */
pAndExpr = sqlite3PExpr(pParse, TK_AND|0x10000, 0, pAndExpr);
}
@ -2167,10 +2186,16 @@ Bitmask sqlite3WhereCodeOneLoopStart(
if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
WhereInfo *pSubWInfo; /* Info for single OR-term scan */
Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
Expr *pDelete; /* Local copy of OR clause term */
int jmp1 = 0; /* Address of jump operation */
testcase( (pTabItem[0].fg.jointype & JT_LEFT)!=0
&& !ExprHasProperty(pOrExpr, EP_FromJoin)
); /* See TH3 vtab25.400 and ticket 614b25314c766238 */
pDelete = pOrExpr = sqlite3ExprDup(db, pOrExpr, 0);
if( db->mallocFailed ){
sqlite3ExprDelete(db, pDelete);
continue;
}
if( pAndExpr ){
pAndExpr->pLeft = pOrExpr;
pOrExpr = pAndExpr;
@ -2285,6 +2310,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3WhereEnd(pSubWInfo);
ExplainQueryPlanPop(pParse);
}
sqlite3ExprDelete(db, pDelete);
}
}
ExplainQueryPlanPop(pParse);

View File

@ -872,7 +872,7 @@ static void exprAnalyzeOrTerm(
idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
exprAnalyze(pSrc, pWC, idxNew);
/* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where used again */
/* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where reused */
markTermAsChild(pWC, idxNew, idxTerm);
}else{
sqlite3ExprListDelete(db, pList);
@ -996,6 +996,7 @@ static int exprMightBeIndexed(
assert( op<=TK_GE );
if( pExpr->op==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){
pExpr = pExpr->x.pList->a[0].pExpr;
}
if( pExpr->op==TK_COLUMN ){
@ -1008,276 +1009,6 @@ static int exprMightBeIndexed(
return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr);
}
/*
** Expression callback for exprUsesSrclist().
*/
static int exprUsesSrclistCb(Walker *p, Expr *pExpr){
if( pExpr->op==TK_COLUMN ){
SrcList *pSrc = p->u.pSrcList;
int iCsr = pExpr->iTable;
int ii;
for(ii=0; ii<pSrc->nSrc; ii++){
if( pSrc->a[ii].iCursor==iCsr ){
return p->eCode ? WRC_Abort : WRC_Continue;
}
}
return p->eCode ? WRC_Continue : WRC_Abort;
}
return WRC_Continue;
}
/*
** Select callback for exprUsesSrclist().
*/
static int exprUsesSrclistSelectCb(Walker *NotUsed1, Select *NotUsed2){
UNUSED_PARAMETER(NotUsed1);
UNUSED_PARAMETER(NotUsed2);
return WRC_Abort;
}
/*
** This function always returns true if expression pExpr contains
** a sub-select.
**
** If there is no sub-select in pExpr, then return true if pExpr
** contains a TK_COLUMN node for a table that is (bUses==1)
** or is not (bUses==0) in pSrc.
**
** Said another way:
**
** bUses Return Meaning
** -------- ------ ------------------------------------------------
**
** bUses==1 true pExpr contains either a sub-select or a
** TK_COLUMN referencing pSrc.
**
** bUses==1 false pExpr contains no sub-selects and all TK_COLUMN
** nodes reference tables not found in pSrc
**
** bUses==0 true pExpr contains either a sub-select or a TK_COLUMN
** that references a table not in pSrc.
**
** bUses==0 false pExpr contains no sub-selects and all TK_COLUMN
** nodes reference pSrc
*/
static int exprUsesSrclist(SrcList *pSrc, Expr *pExpr, int bUses){
Walker sWalker;
memset(&sWalker, 0, sizeof(Walker));
sWalker.eCode = bUses;
sWalker.u.pSrcList = pSrc;
sWalker.xExprCallback = exprUsesSrclistCb;
sWalker.xSelectCallback = exprUsesSrclistSelectCb;
return (sqlite3WalkExpr(&sWalker, pExpr)==WRC_Abort);
}
/*
** Context object used by exprExistsToInIter() as it iterates through an
** expression tree.
*/
struct ExistsToInCtx {
SrcList *pSrc; /* The tables in an EXISTS(SELECT ... FROM <here> ...) */
Expr *pInLhs; /* OUT: Use this as the LHS of the IN operator */
Expr *pEq; /* OUT: The == term that include pInLhs */
Expr **ppAnd; /* OUT: The AND operator that includes pEq as a child */
Expr **ppParent; /* The AND operator currently being examined */
};
/*
** Iterate through all AND connected nodes in the expression tree
** headed by (*ppExpr), populating the structure passed as the first
** argument with the values required by exprAnalyzeExistsFindEq().
**
** This function returns non-zero if the expression tree does not meet
** the two conditions described by the header comment for
** exprAnalyzeExistsFindEq(), or zero if it does.
*/
static int exprExistsToInIter(struct ExistsToInCtx *p, Expr **ppExpr){
Expr *pExpr = *ppExpr;
switch( pExpr->op ){
case TK_AND:
p->ppParent = ppExpr;
if( exprExistsToInIter(p, &pExpr->pLeft) ) return 1;
p->ppParent = ppExpr;
if( exprExistsToInIter(p, &pExpr->pRight) ) return 1;
break;
case TK_EQ: {
int bLeft = exprUsesSrclist(p->pSrc, pExpr->pLeft, 0);
int bRight = exprUsesSrclist(p->pSrc, pExpr->pRight, 0);
if( bLeft || bRight ){
if( (bLeft && bRight) || p->pInLhs ) return 1;
p->pInLhs = bLeft ? pExpr->pLeft : pExpr->pRight;
if( exprUsesSrclist(p->pSrc, p->pInLhs, 1) ) return 1;
p->pEq = pExpr;
p->ppAnd = p->ppParent;
}
break;
}
default:
if( exprUsesSrclist(p->pSrc, pExpr, 0) ){
return 1;
}
break;
}
return 0;
}
/*
** This function is used by exprAnalyzeExists() when creating virtual IN(...)
** terms equivalent to user-supplied EXIST(...) clauses. It splits the WHERE
** clause of the Select object passed as the first argument into one or more
** expressions joined by AND operators, and then tests if the following are
** true:
**
** 1. Exactly one of the AND separated terms refers to the outer
** query, and it is an == (TK_EQ) expression.
**
** 2. Only one side of the == expression refers to the outer query, and
** it does not refer to any columns from the inner query.
**
** If both these conditions are true, then a pointer to the side of the ==
** expression that refers to the outer query is returned. The caller will
** use this expression as the LHS of the IN(...) virtual term. Or, if one
** or both of the above conditions are not true, NULL is returned.
**
** If non-NULL is returned and ppEq is non-NULL, *ppEq is set to point
** to the == expression node before returning. If pppAnd is non-NULL and
** the == node is not the root of the WHERE clause, then *pppAnd is set
** to point to the pointer to the AND node that is the parent of the ==
** node within the WHERE expression tree.
*/
static Expr *exprAnalyzeExistsFindEq(
Select *pSel, /* The SELECT of the EXISTS */
Expr **ppEq, /* OUT: == node from WHERE clause */
Expr ***pppAnd /* OUT: Pointer to parent of ==, if any */
){
struct ExistsToInCtx ctx;
memset(&ctx, 0, sizeof(ctx));
ctx.pSrc = pSel->pSrc;
if( exprExistsToInIter(&ctx, &pSel->pWhere) ){
return 0;
}
if( ppEq ) *ppEq = ctx.pEq;
if( pppAnd ) *pppAnd = ctx.ppAnd;
return ctx.pInLhs;
}
/*
** Term idxTerm of the WHERE clause passed as the second argument is an
** EXISTS expression with a correlated SELECT statement on the RHS.
** This function analyzes the SELECT statement, and if possible adds an
** equivalent "? IN(SELECT...)" virtual term to the WHERE clause.
**
** For an EXISTS term such as the following:
**
** EXISTS (SELECT ... FROM <srclist> WHERE <e1> = <e2> AND <e3>)
**
** The virtual IN() term added is:
**
** <e1> IN (SELECT <e2> FROM <srclist> WHERE <e3>)
**
** The virtual term is only added if the following conditions are met:
**
** 1. The sub-select must not be an aggregate or use window functions,
**
** 2. The sub-select must not be a compound SELECT,
**
** 3. Expression <e1> must refer to at least one column from the outer
** query, and must not refer to any column from the inner query
** (i.e. from <srclist>).
**
** 4. <e2> and <e3> must not refer to any values from the outer query.
** In other words, once <e1> has been removed, the inner query
** must not be correlated.
**
*/
static void exprAnalyzeExists(
SrcList *pSrc, /* the FROM clause */
WhereClause *pWC, /* the WHERE clause */
int idxTerm /* Index of the term to be analyzed */
){
Parse *pParse = pWC->pWInfo->pParse;
WhereTerm *pTerm = &pWC->a[idxTerm];
Expr *pExpr = pTerm->pExpr;
Select *pSel = pExpr->x.pSelect;
Expr *pDup = 0;
Expr *pEq = 0;
Expr *pRet = 0;
Expr *pInLhs = 0;
Expr **ppAnd = 0;
int idxNew;
sqlite3 *db = pParse->db;
assert( pExpr->op==TK_EXISTS );
assert( (pExpr->flags & EP_VarSelect) && (pExpr->flags & EP_xIsSelect) );
if( pSel->selFlags & SF_Aggregate ) return;
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pSel->pWin ) return;
#endif
if( pSel->pPrior ) return;
if( pSel->pWhere==0 ) return;
if( pSel->pLimit ) return;
if( 0==exprAnalyzeExistsFindEq(pSel, 0, 0) ) return;
pDup = sqlite3ExprDup(db, pExpr, 0);
if( db->mallocFailed ){
sqlite3ExprDelete(db, pDup);
return;
}
pSel = pDup->x.pSelect;
sqlite3ExprListDelete(db, pSel->pEList);
pSel->pEList = 0;
pInLhs = exprAnalyzeExistsFindEq(pSel, &pEq, &ppAnd);
assert( pInLhs && pEq );
assert( pEq==pSel->pWhere || ppAnd );
if( pInLhs==pEq->pLeft ){
pRet = pEq->pRight;
}else{
CollSeq *p = sqlite3ExprCompareCollSeq(pParse, pEq);
pInLhs = sqlite3ExprAddCollateString(pParse, pInLhs, p?p->zName:"BINARY");
pRet = pEq->pLeft;
}
assert( pDup->pLeft==0 );
pDup->op = TK_IN;
pDup->pLeft = pInLhs;
pDup->flags &= ~EP_VarSelect;
if( pRet->op==TK_VECTOR ){
pSel->pEList = pRet->x.pList;
pRet->x.pList = 0;
sqlite3ExprDelete(db, pRet);
}else{
pSel->pEList = sqlite3ExprListAppend(pParse, 0, pRet);
}
pEq->pLeft = 0;
pEq->pRight = 0;
if( ppAnd ){
Expr *pAnd = *ppAnd;
Expr *pOther = (pAnd->pLeft==pEq) ? pAnd->pRight : pAnd->pLeft;
pAnd->pLeft = pAnd->pRight = 0;
sqlite3ExprDelete(db, pAnd);
*ppAnd = pOther;
}else{
assert( pSel->pWhere==pEq );
pSel->pWhere = 0;
}
sqlite3ExprDelete(db, pEq);
#ifdef WHERETRACE_ENABLED /* 0x20 */
if( sqlite3WhereTrace & 0x20 ){
sqlite3DebugPrintf("Convert EXISTS:\n");
sqlite3TreeViewExpr(0, pExpr, 0);
sqlite3DebugPrintf("into IN:\n");
sqlite3TreeViewExpr(0, pDup, 0);
}
#endif
idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
exprAnalyze(pSrc, pWC, idxNew);
markTermAsChild(pWC, idxNew, idxTerm);
pWC->a[idxTerm].wtFlags |= TERM_COPIED;
}
/*
** The input to this routine is an WhereTerm structure with only the
@ -1377,6 +1108,7 @@ static void exprAnalyze(
if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
if( pRight
&& exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op)
&& !ExprHasProperty(pRight, EP_FixedCol)
){
WhereTerm *pNew;
Expr *pDup;
@ -1469,16 +1201,6 @@ static void exprAnalyze(
pTerm = &pWC->a[idxTerm];
}
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
else if( pExpr->op==TK_EXISTS ){
/* Perhaps treat an EXISTS operator as an IN operator */
if( (pExpr->flags & EP_VarSelect)!=0
&& OptimizationEnabled(db, SQLITE_ExistsToIN)
){
exprAnalyzeExists(pSrc, pWC, idxTerm);
}
}
/* 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.

View File

@ -941,6 +941,14 @@ static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){
return WRC_Continue;
}
static int disallowAggregatesInOrderByCb(Walker *pWalker, Expr *pExpr){
if( pExpr->op==TK_AGG_FUNCTION && pExpr->pAggInfo==0 ){
sqlite3ErrorMsg(pWalker->pParse,
"misuse of aggregate: %s()", pExpr->u.zToken);
}
return WRC_Continue;
}
/*
** If the SELECT statement passed as the second argument does not invoke
** any SQL window functions, this function is a no-op. Otherwise, it
@ -974,6 +982,11 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
}
sqlite3AggInfoPersistWalkerInit(&w, pParse);
sqlite3WalkSelect(&w, p);
if( (p->selFlags & SF_Aggregate)==0 ){
w.xExprCallback = disallowAggregatesInOrderByCb;
w.xSelectCallback = 0;
sqlite3WalkExprList(&w, p->pOrderBy);
}
p->pSrc = 0;
p->pWhere = 0;
@ -2263,7 +2276,7 @@ static int windowCodeOp(
}else if( p->regRowid ){
sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid1);
sqlite3VdbeAddOp3(v, OP_Ge, p->regRowid, lblDone, regRowid1);
VdbeCoverage(v);
VdbeCoverageNeverNull(v);
}
sqlite3ReleaseTempReg(pParse, regRowid1);
sqlite3ReleaseTempReg(pParse, regRowid2);

View File

@ -318,16 +318,16 @@ ifcapable trigger&&tempdb {
END;
INSERT INTO t1 VALUES(1, 2);
SELECT * FROM log;
SELECT * FROM log ORDER BY trig, a, b;
}
} {b 1 2 a 1 2}
} {a 1 2 b 1 2}
do_test alter4-6.2 {
execsql {
ALTER TABLE t1 ADD COLUMN c DEFAULT 'c';
INSERT INTO t1(a, b) VALUES(3, 4);
SELECT * FROM log;
SELECT * FROM log ORDER BY trig, a, b;
}
} {b 1 2 a 1 2 b 3 4 a 3 4}
} {a 1 2 a 3 4 b 1 2 b 3 4}
}
# Ticket #1183 - Make sure adding columns to large tables does not cause

View File

@ -750,4 +750,53 @@ ifcapable json1&&vtab {
} {1 {table json_each may not be altered}}
}
# 2021-05-01 dbsqlfuzz bc17a306a09329bba0ecc61547077f6178bcf321
# Remove a NEVER() inserted on 2019-12-09 that is reachable after all.
#
reset_db
do_execsql_test 26.1 {
CREATE TABLE t1(k,v);
CREATE TABLE t2_a(k,v);
CREATE VIEW t2 AS SELECT * FROM t2_a;
CREATE TRIGGER r2 AFTER INSERT ON t1 BEGIN
UPDATE t1
SET (k,v)=((WITH cte1(a) AS (SELECT 1 FROM t2) SELECT t2.k FROM t2, cte1),1);
END;
ALTER TABLE t1 RENAME TO t1x;
INSERT INTO t2_a VALUES(2,3);
INSERT INTO t1x VALUES(98,99);
SELECT * FROM t1x;
} {2 1}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 27.1 {
create table t_sa (
c_muyat INTEGER NOT NULL,
c_d4u TEXT
);
create table t2 ( abc );
CREATE TRIGGER trig AFTER DELETE ON t_sa
BEGIN
DELETE FROM t_sa WHERE (
SELECT 123 FROM t2
WINDOW oamat7fzf AS ( PARTITION BY t_sa.c_d4u )
);
END;
}
breakpoint
do_execsql_test 27.2 {
alter table t_sa rename column c_muyat to c_dg;
}
finish_test

View File

@ -129,19 +129,21 @@ set pgnoChild [get4byte $fd $offChild]
put4byte $fd $offChild 1
close $fd
sqlite3 db test.db
do_catchsql_test 2.2 {
PRAGMA writable_schema = 1;
SELECT * FROM sqlite_schema;
} {1 {database disk image is malformed}}
if {![info exists ::G(perm:presql)]} {
sqlite3 db test.db
do_test 2.3 {
list [catch {
for {set ii $nView} {$ii<$nView*2} {incr ii} {
execsql "INSERT INTO sqlite_master VALUES(1, 2, 3, 4, 5)"
}
} msg] $msg
} {1 {database disk image is malformed}}
do_catchsql_test 2.2 {
PRAGMA writable_schema = 1;
SELECT * FROM sqlite_schema;
} {1 {database disk image is malformed}}
do_test 2.3 {
list [catch {
for {set ii $nView} {$ii<$nView*2} {incr ii} {
execsql "INSERT INTO sqlite_master VALUES(1, 2, 3, 4, 5)"
}
} msg] $msg
} {1 {database disk image is malformed}}
}
finish_test

View File

@ -149,69 +149,74 @@ INSERT INTO t1(a) SELECT randomblob(null) FROM c;
} {1 {database disk image is malformed}}
reset_db
do_execsql_test 3.0 {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
PRAGMA writable_schema = 1;
UPDATE sqlite_schema
SET sql = 'CREATE TABLE sqlite_sequence(name-seq)'
WHERE name = 'sqlite_sequence';
if {![info exists ::G(perm:presql)]} {
do_execsql_test 3.0 {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
PRAGMA writable_schema = 1;
UPDATE sqlite_schema
SET sql = 'CREATE TABLE sqlite_sequence(name-seq)'
WHERE name = 'sqlite_sequence';
}
db close
sqlite3 db test.db
do_catchsql_test 3.1 {
PRAGMA writable_schema = 1;
INSERT INTO t1(y) VALUES('abc');
} {1 {database disk image is malformed}}
reset_db
do_execsql_test 4.1 {
CREATE TABLE x1(a INTEGER PRIMARY KEY, b UNIQUE, c UNIQUE);
INSERT INTO x1 VALUES(1, 1, 2);
INSERT INTO x1 VALUES(2, 2, 3);
INSERT INTO x1 VALUES(3, 3, 4);
INSERT INTO x1 VALUES(4, 5, 6);
PRAGMA writable_schema = 1;
UPDATE sqlite_schema SET rootpage = (
SELECT rootpage FROM sqlite_schema WHERE name = 'sqlite_autoindex_x1_2'
) WHERE name = 'sqlite_autoindex_x1_1';
}
db close
sqlite3 db test.db
breakpoint
do_catchsql_test 4.2 {
PRAGMA writable_schema = 1;
REPLACE INTO x1 VALUES(5, 2, 3);
} {1 {database disk image is malformed}}
}
db close
sqlite3 db test.db
do_catchsql_test 3.1 {
PRAGMA writable_schema = 1;
INSERT INTO t1(y) VALUES('abc');
} {1 {database disk image is malformed}}
reset_db
do_execsql_test 4.1 {
CREATE TABLE x1(a INTEGER PRIMARY KEY, b UNIQUE, c UNIQUE);
INSERT INTO x1 VALUES(1, 1, 2);
INSERT INTO x1 VALUES(2, 2, 3);
INSERT INTO x1 VALUES(3, 3, 4);
INSERT INTO x1 VALUES(4, 5, 6);
PRAGMA writable_schema = 1;
UPDATE sqlite_schema SET rootpage = (
SELECT rootpage FROM sqlite_schema WHERE name = 'sqlite_autoindex_x1_2'
) WHERE name = 'sqlite_autoindex_x1_1';
}
db close
sqlite3 db test.db
breakpoint
do_catchsql_test 3.1 {
PRAGMA writable_schema = 1;
REPLACE INTO x1 VALUES(5, 2, 3);
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
db func strreplace strreplace
proc strreplace {orig a b} {
string map [list $a $b] $orig
}
do_execsql_test 4.0 {
CREATE TABLE t1(a, b);
CREATE INDEX t1a ON t1(a);
CREATE INDEX t1b ON t1(b);
ifcapable json1&&vtab {
db func strreplace strreplace
proc strreplace {orig a b} {
string map [list $a $b] $orig
}
PRAGMA writable_schema = 1;
UPDATE sqlite_schema
SET sql = strreplace(sql, 't1', 'json_each')
WHERE type='index';
}
do_execsql_test 5.0 {
CREATE TABLE t1(a, b);
CREATE INDEX t1a ON t1(a);
CREATE INDEX t1b ON t1(b);
db close
sqlite3 db test.db
PRAGMA writable_schema = 1;
UPDATE sqlite_schema
SET sql = strreplace(sql, 't1', 'json_each')
WHERE type='index';
}
do_execsql_test 4.1 {
PRAGMA writable_schema = 1;
SELECT * FROM t1
}
db close
sqlite3 db test.db
do_execsql_test 5.1 {
PRAGMA writable_schema = 1;
SELECT * FROM t1
}
}; # ifcapable json1&&vtab
finish_test

View File

@ -31,8 +31,7 @@
**
** mkdir dir
** cp dbfuzz2-seed*.db dir
** clang-6.0 -I. -g -O1 -fsanitize=fuzzer \
** -DTHREADSAFE=0 -DSQLITE_ENABLE_DESERIALIZE \
** clang-6.0 -I. -g -O1 -fsanitize=fuzzer -DTHREADSAFE=0 \
** -DSQLITE_ENABLE_DBSTAT_VTAB dbfuzz2.c sqlite3.c -ldl
** ./a.out dir
*/

View File

@ -1,194 +0,0 @@
# 2021 January 15
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing cases where EXISTS expressions are
# transformed to IN() expressions by where.c
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix exists2
do_execsql_test 1.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
INSERT INTO t1 VALUES(1, 'one');
INSERT INTO t1 VALUES(2, 'two');
INSERT INTO t1 VALUES(3, 'three');
INSERT INTO t1 VALUES(4, 'four');
INSERT INTO t1 VALUES(5, 'five');
INSERT INTO t1 VALUES(6, 'six');
INSERT INTO t1 VALUES(7, 'seven');
CREATE TABLE t2(c INTEGER, d INTEGER);
INSERT INTO t2 VALUES(1, 1);
INSERT INTO t2 VALUES(3, 2);
INSERT INTO t2 VALUES(5, 3);
INSERT INTO t2 VALUES(7, 4);
}
proc do_execsql_eqp_test {tn sql eqp res} {
uplevel [list do_eqp_test $tn.1 $sql [string trim $eqp]]
uplevel [list do_execsql_test $tn.2 $sql $res]
}
do_execsql_eqp_test 1.1 {
SELECT t1.* FROM t1 WHERE EXISTS(SELECT * FROM t2 WHERE t1.a=t2.c);
} {
USING INTEGER PRIMARY KEY
} {
1 one 3 three 5 five 7 seven
}
do_execsql_eqp_test 1.2 {
SELECT t1.* FROM t1 WHERE EXISTS(SELECT * FROM t2 WHERE t2.c=t1.a);
} {
SEARCH t1 USING INTEGER PRIMARY KEY
} {
1 one 3 three 5 five 7 seven
}
do_execsql_eqp_test 1.3 {
SELECT t1.* FROM t1 WHERE EXISTS(SELECT * FROM t2 WHERE t2.c+1=t1.a);
} {
SEARCH t1 USING INTEGER PRIMARY KEY
} {
2 two 4 four 6 six
}
do_execsql_eqp_test 1.4 {
SELECT t1.* FROM t1 WHERE EXISTS(SELECT * FROM t2 WHERE t2.c+1=t1.a+1);
} {
SCAN t1
} {
1 one 3 three 5 five 7 seven
}
do_execsql_eqp_test 1.5 {
SELECT t1.* FROM t1 WHERE EXISTS(
SELECT * FROM t2 WHERE t1.a=t2.c AND d IN (1, 2, 3)
);
} {
SEARCH t1 USING INTEGER PRIMARY KEY
} {
1 one 3 three 5 five
}
do_execsql_eqp_test 1.6 {
SELECT t1.* FROM t1 WHERE EXISTS(
SELECT * FROM t2 WHERE d IN (1, 2, 3)AND t1.a=t2.c
);
} {
SEARCH t1 USING INTEGER PRIMARY KEY
} {
1 one 3 three 5 five
}
do_execsql_eqp_test 1.7 {
SELECT t1.* FROM t1 WHERE EXISTS(
SELECT * FROM t2 WHERE d IN (1, 2, 3)AND t1.a=t2.c
);
} {
SEARCH t1 USING INTEGER PRIMARY KEY
} {
1 one 3 three 5 five
}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 2.0 {
CREATE TABLE t3(a TEXT PRIMARY KEY, b TEXT, x INT) WITHOUT ROWID;
CREATE TABLE t4(c TEXT COLLATE nocase, y INT);
INSERT INTO t3 VALUES('one', 'i', 1);
INSERT INTO t3 VALUES('two', 'ii', 2);
INSERT INTO t3 VALUES('three', 'iii', 3);
INSERT INTO t3 VALUES('four', 'iv', 4);
INSERT INTO t3 VALUES('five', 'v', 5);
INSERT INTO t4 VALUES('FIVE',5), ('four',4), ('TWO',2), ('one',1);
}
do_execsql_test 2.1 { SELECT a FROM t3, t4 WHERE a=c } {four one}
do_execsql_test 2.2 { SELECT a FROM t3, t4 WHERE c=a } {five four one two}
do_execsql_eqp_test 2.3 {
SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE a=c)
} {
SEARCH t3 USING PRIMARY KEY
} {
four one
}
do_execsql_eqp_test 2.4 {
SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE c=a)
} {
SCAN t3
} {
five four one two
}
do_execsql_test 2.5 {
CREATE INDEX t3anc ON t3(a COLLATE nocase, x);
}
do_execsql_eqp_test 2.6 {
SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE c=a)
} {
SEARCH t3 USING COVERING INDEX t3anc
} {
five four one two
}
do_execsql_test 2.6a {
SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE (c,y)=(a,x))
} {five four one two}
do_execsql_eqp_test 2.7 {
SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE a=c)
} {
SEARCH t3 USING PRIMARY KEY
} {
four one
}
do_execsql_test 2.7a {
SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE (a,x)=(c,y))
} {
four one
}
do_execsql_test 2.7b {
SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE (a,x)=(c,y) LIMIT 1)
} {
four one
}
# EXISTS clauses using vector expressions in the WHERE clause.
#
reset_db
do_execsql_test 3.0 {
CREATE TABLE t1(a,b);
INSERT INTO t1(a,b) VALUES(1,111),(2,222),(8,888);
CREATE TABLE t2(x INTEGER PRIMARY KEY, y);
INSERT INTO t2(x,y) VALUES(2,222),(3,333),(7,333);
SELECT y FROM t2 WHERE EXISTS(SELECT 1 FROM t1 WHERE (x,y)=(a,b));
} {222}
do_execsql_test 3.1 {
SELECT y FROM t2 WHERE EXISTS(SELECT 1 FROM t1 WHERE (a,b)=(x,y));
} {222}
do_execsql_test 3.2 {
SELECT y FROM t2 WHERE EXISTS(SELECT 1 FROM t1 WHERE (x,b)=(a,y));
} {222}
finish_test

View File

@ -1,51 +0,0 @@
# 2021 January 15
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing cases where EXISTS expressions are
# transformed to IN() expressions by where.c
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix existsfault
do_execsql_test 1 {
CREATE TABLE t1(a PRIMARY KEY, b);
INSERT INTO t1 VALUES(1, 'one');
INSERT INTO t1 VALUES(2, 'two');
INSERT INTO t1 VALUES(3, 'three');
INSERT INTO t1 VALUES(4, 'four');
INSERT INTO t1 VALUES(5, 'five');
INSERT INTO t1 VALUES(6, 'six');
INSERT INTO t1 VALUES(7, 'seven');
CREATE TABLE t2(c INTEGER, d INTEGER);
INSERT INTO t2 VALUES(1, 1);
INSERT INTO t2 VALUES(3, 2);
INSERT INTO t2 VALUES(5, 3);
INSERT INTO t2 VALUES(7, 4);
}
faultsim_save_and_close
do_faultsim_test 1 -prep {
faultsim_restore_and_reopen
} -body {
execsql {
SELECT t1.* FROM t1 WHERE EXISTS(
SELECT * FROM t2 WHERE t2.c=t1.a AND d IN (1, 2, 3)
)
}
} -test {
faultsim_test_result {0 {1 one 3 three 5 five}}
}
finish_test

View File

@ -1784,14 +1784,16 @@ int main(int argc, char **argv){
char zLine[2000];
while( rc==0 && fgets(zLine,sizeof(zLine),stdin)!=0 ){
size_t kk = strlen(zLine);
while( kk>0 && (zLine[kk]=='\n' || zLine[kk]=='\r')) kk--;
while( kk>0 && zLine[kk-1]<=' ' ) kk--;
sqlite3_bind_text(pStmt, 1, zLine, kk, SQLITE_STATIC);
if( verboseFlag ) printf("loading %.*s\n", (int)kk, zLine);
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
if( rc ) fatalError("insert failed for %s", zLine);
}
}else{
sqlite3_bind_text(pStmt, 1, argv[i], -1, SQLITE_STATIC);
if( verboseFlag ) printf("loading %s\n", argv[i]);
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
if( rc ) fatalError("insert failed for %s", argv[i]);

Binary file not shown.

View File

@ -97,4 +97,23 @@ do_execsql_test in6-3.110 {
SELECT quote(v5) FROM v0 LEFT JOIN v3 ON v4 = NULL AND v5 IN(0);
} {NULL}
# 2021-04-29 forum https://sqlite.org/forum/forumpost/6a3ec138e9
# An early OP_IsNull bypass might skip over the OP_Affinity and
# cause the OP_IfNoHope to jump on a false-positive, resulting in
# incomplete output.
#
reset_db
do_execsql_test in6-3.120 {
CREATE TABLE t1(a TEXT, b TEXT);
INSERT INTO t1 VALUES(null,10),(0,10),(10,10);
CREATE INDEX t1ab ON t1(a,b);
SELECT quote(a), quote(b), '|' FROM t1 WHERE b in (SELECT a FROM t1) AND a=0;
} {'0' '10' |}
do_execsql_test in6-3.130 {
CREATE TABLE t2(x TEXT);
INSERT INTO t2(x) VALUES(NULL),(0),(10);
SELECT quote(x), quote(a), quote(b), 'x'
FROM t2 LEFT JOIN t1 ON a=x AND b in (null,0,10);
} {NULL NULL NULL x '0' '0' '10' x '10' '10' '10' x}
finish_test

View File

@ -26,7 +26,6 @@
*/
#define SQLITE_THREADSAFE 0
#define SQLITE_OMIT_LOAD_EXTENSION 1
#define SQLITE_ENABLE_DESERIALIZE 1
#include "sqlite3.c"
/* Content of the read-only test database */

View File

@ -50,7 +50,6 @@ array set ::Configs [strip_comments {
-O2
--disable-amalgamation --disable-shared
--enable-session
-DSQLITE_ENABLE_DESERIALIZE
}
"Sanitize" {
CC=clang -fsanitize=undefined
@ -180,7 +179,6 @@ array set ::Configs [strip_comments {
-DSQLITE_OMIT_TRACE=1
-DSQLITE_TEMP_STORE=3
-DSQLITE_THREADSAFE=2
-DSQLITE_ENABLE_DESERIALIZE=1
--enable-json1 --enable-fts5 --enable-session
}
"Locking-Style" {

View File

@ -51,7 +51,6 @@ array set ::Configs [strip_comments {
-O2
--disable-amalgamation --disable-shared
--enable-session
-DSQLITE_ENABLE_DESERIALIZE
}
"Sanitize" {
CC=clang -fsanitize=address,undefined
@ -188,7 +187,6 @@ array set ::Configs [strip_comments {
-DSQLITE_OMIT_TRACE=1
-DSQLITE_TEMP_STORE=3
-DSQLITE_THREADSAFE=2
-DSQLITE_ENABLE_DESERIALIZE=1
--enable-json1 --enable-fts5 --enable-session
}
"Locking-Style" {
@ -629,5 +627,3 @@ if {[string match ${cmd}* configurations] && $n==0} {
} else {
usage
}

View File

@ -224,4 +224,98 @@ do_execsql_test 10.4 {
SELECT * FROM log;
} {}
# 2021-04-27 dbsqlfuzz 78b9400770ef8cc7d9427dfba26f4fcf46ea7dc2
# Returning clauses on TEMP tables with triggers.
#
reset_db
do_execsql_test 11.1 {
CREATE TEMP TABLE t1(a,b);
CREATE TEMP TABLE t2(c,d);
CREATE TEMP TABLE t3(e,f);
CREATE TEMP TABLE log(op,x,y);
CREATE TEMP TRIGGER t1r1 AFTER INSERT ON t1 BEGIN
INSERT INTO log(op,x,y) VALUES('I1',new.a,new.b);
END;
CREATE TEMP TRIGGER t1r2 BEFORE DELETE ON t1 BEGIN
INSERT INTO log(op,x,y) VALUES('D1',old.a,old.b);
END;
CREATE TEMP TRIGGER t2r3 AFTER UPDATE ON t1 BEGIN
INSERT INTO log(op,x,y) VALUES('U1',new.a,new.b);
END;
CREATE TEMP TRIGGER t2r1 BEFORE INSERT ON t2 BEGIN
INSERT INTO log(op,x,y) VALUES('I2',new.c,new.d);
END;
CREATE TEMP TRIGGER t3r1 AFTER DELETE ON t3 BEGIN
INSERT INTO log(op,x,y) VALUES('D3',old.e,old.f);
END;
CREATE TEMP TRIGGER t3r2 BEFORE UPDATE ON t3 BEGIN
INSERT INTO log(op,x,y) VALUES('U3',new.e,new.f);
END;
INSERT INTO t1(a,b) VALUES(1,2),('happy','glad') RETURNING a, b, '|';
} {1 2 | happy glad |}
do_execsql_test 11.2 {
UPDATE t1 SET b=9 WHERE a=1 RETURNING a, b, 'x';
} {1 9 x}
do_execsql_test 11.3 {
DELETE FROM t1 WHERE a<>'xray' RETURNING a, b, '@';
} {1 9 @ happy glad @}
do_execsql_test 11.4 {
SELECT * FROM log;
DELETE FROM log;
} {I1 1 2 I1 happy glad U1 1 9 D1 1 9 D1 happy glad}
do_execsql_test 11.5 {
INSERT INTO t2 VALUES('bravo','charlie') RETURNING d, c, 'z';
} {charlie bravo z}
do_execsql_test 11.6 {
SELECT * FROM log;
DELETE FROM log;
} {I2 bravo charlie}
do_execsql_test 11.7 {
INSERT INTO t3(e) VALUES(1),(2),(3) RETURNING 'I', e;
UPDATE t3 SET f=e+100 RETURNING 'U', e, f;
DELETE FROM t3 WHERE f>100 RETURNING 'D', e, f;
} {I 1 I 2 I 3 U 1 101 U 2 102 U 3 103 D 1 101 D 2 102 D 3 103}
do_execsql_test 11.6 {
SELECT * FROM log;
DELETE FROM log;
} {U3 1 101 U3 2 102 U3 3 103 D3 1 101 D3 2 102 D3 3 103}
reset_db
do_execsql_test 11.11 {
CREATE TEMP TABLE t1(a,b);
CREATE TRIGGER r1 BEFORE INSERT ON t1 BEGIN SELECT 1; END;
DELETE FROM t1 RETURNING *;
DROP TRIGGER r1;
INSERT INTO t1 VALUES(5,30);
} {}
do_execsql_test 11.12 {
SELECT * FROM t1;
} {5 30}
# RETURNING column names are dequoted.
# https://sqlite.org/forum/forumpost/033daf0b32
#
reset_db
do_test 12.1 {
db eval {CREATE TABLE t1(x INT, y INT)}
unset -nocomplain cname
db eval {INSERT INTO t1(x) VALUES(1) RETURNING "x";} cname {}
lsort [array names cname]
} {* x}
do_test 12.2 {
unset -nocomplain cname
db eval {INSERT INTO t1(x) VALUES(2) RETURNING [x];} cname {}
lsort [array names cname]
} {* x}
do_test 12.3 {
unset -nocomplain cname
db eval {INSERT INTO t1(x) VALUES(3) RETURNING x AS [xyz];} cname {}
lsort [array names cname]
} {* xyz}
do_test 12.4 {
unset -nocomplain cname
db eval {INSERT INTO t1(x,y) VALUES(4,5) RETURNING "x"+"y";} cname {}
lsort [array names cname]
} {{"x"+"y"} *}
finish_test

339
test/threadtest5.c Normal file
View File

@ -0,0 +1,339 @@
/*
** 2021-05-12
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** Testing threading behavior when multiple database connections in separate
** threads of the same process are all talking to the same database file.
**
** For best results, ensure that SQLite is compiled with HAVE_USLEEP=1
**
** Only works on unix platforms.
**
** Usage:
**
** ./threadtest5 ?DATABASE?
**
** If DATABASE is omitted, it defaults to using file:/mem?vfs=memdb.
*/
#include "sqlite3.h"
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
/* Name of the in-memory database */
static char *zDbName = 0;
/* True for debugging */
static int eVerbose = 0;
/* If rc is not SQLITE_OK, then print an error message and stop
** the test.
*/
static void error_out(int rc, const char *zCtx, int lineno){
if( rc!=SQLITE_OK ){
fprintf(stderr, "error %d at %d in \"%s\"\n", rc, lineno, zCtx);
exit(-1);
}
}
#if 0
/* Return the number of milliseconds since the Julian epoch (-4714-11-24).
*/
static sqlite3_int64 gettime(void){
sqlite3_int64 tm;
sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
pVfs->xCurrentTimeInt64(pVfs, &tm);
return tm;
}
#endif
/* Run the SQL in the second argument.
*/
static int exec(
sqlite3 *db,
const char *zId,
int lineno,
const char *zFormat,
...
){
int rc;
va_list ap;
char *zSql;
va_start(ap, zFormat);
zSql = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
if( eVerbose){
printf("%s:%d: [%s]\n", zId, lineno, zSql);
fflush(stdout);
}
rc = sqlite3_exec(db, zSql, 0, 0, 0);
if( rc && eVerbose ){
printf("%s:%d: return-code %d\n", zId, lineno, rc);
fflush(stdout);
}
sqlite3_free(zSql);
return rc;
}
/* Generate a perpared statement from the input SQL
*/
static sqlite3_stmt *prepare(
sqlite3 *db,
const char *zId,
int lineno,
const char *zFormat,
...
){
int rc;
va_list ap;
char *zSql;
sqlite3_stmt *pStmt = 0;
va_start(ap, zFormat);
zSql = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
if( eVerbose){
printf("%s:%d: [%s]\n", zId, lineno, zSql);
fflush(stdout);
}
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
if( rc ){
printf("%s:%d: ERROR - %s\n", zId, lineno, sqlite3_errmsg(db));
exit(-1);
}
sqlite3_free(zSql);
return pStmt;
}
/*
** Wait for table zTable to exist in the schema.
*/
static void waitOnTable(sqlite3 *db, const char *zWorker, const char *zTable){
while(1){
int eFound = 0;
sqlite3_stmt *q = prepare(db, zWorker, __LINE__,
"SELECT 1 FROM sqlite_schema WHERE name=%Q", zTable);
if( sqlite3_step(q)==SQLITE_ROW && sqlite3_column_int(q,0)!=0 ){
eFound = 1;
}
sqlite3_finalize(q);
if( eFound ) return;
sqlite3_sleep(1);
}
}
/*
** Return true if x is a prime number
*/
static int isPrime(int x){
int i;
if( x<2 ) return 1;
for(i=2; i*i<=x; i++){
if( (x%i)==0 ) return 0;
}
return 1;
}
/* Each worker thread runs an instance of the following */
static void *worker(void *pArg){
int rc;
const char *zName = (const char*)pArg;
sqlite3 *db = 0;
if( eVerbose ){
printf("%s: startup\n", zName);
fflush(stdout);
}
rc = sqlite3_open(zDbName, &db);
error_out(rc, "sqlite3_open", __LINE__);
sqlite3_busy_timeout(db, 2000);
while( 1 ){
sqlite3_stmt *q1;
int tid = -1;
q1 = prepare(db, zName, __LINE__,
"UPDATE task SET doneby=%Q"
" WHERE tid=(SELECT tid FROM task WHERE doneby IS NULL LIMIT 1)"
"RETURNING tid", zName
);
if( sqlite3_step(q1)==SQLITE_ROW ){
tid = sqlite3_column_int(q1,0);
}
sqlite3_finalize(q1);
if( tid<0 ) break;
if( eVerbose ){
printf("%s: starting task %d\n", zName, tid);
fflush(stdout);
}
if( tid==1 ){
exec(db, zName, __LINE__,
"CREATE TABLE IF NOT EXISTS p1(x INTEGER PRIMARY KEY);"
);
}else if( tid>=2 && tid<=51 ){
int a, b, i;
waitOnTable(db, zName, "p1");
a = (tid-2)*200 + 1;
b = a+200;
for(i=a; i<b; i++){
if( isPrime(i) ){
exec(db, zName, __LINE__,
"INSERT INTO p1(x) VALUES(%d)", i);
}
}
}else if( tid==52 ){
exec(db, zName, __LINE__,
"CREATE TABLE IF NOT EXISTS p2(x INTEGER PRIMARY KEY);"
"WITH RECURSIVE"
" c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10000)"
"INSERT INTO p2(x) SELECT x FROM c;"
);
}else if( tid>=53 && tid<=62 ){
int a, b, i;
waitOnTable(db, zName, "p2");
a = (tid-53)*10 + 2;
b = a+9;
for(i=a; i<=b; i++){
exec(db, zName, __LINE__,
"DELETE FROM p2 WHERE x>%d AND (x %% %d)==0", i, i);
}
}
if( eVerbose ){
printf("%s: completed task %d\n", zName, tid);
fflush(stdout);
}
sqlite3_sleep(1);
}
sqlite3_close(db);
if( eVerbose ){
printf("%s: exit\n", zName);
fflush(stdout);
}
return 0;
}
/* Print a usage comment and die */
static void usage(const char *argv0){
printf("Usage: %s [options]\n", argv0);
printf(
" -num-workers N Run N worker threads\n"
" -v Debugging output\n"
);
exit(1);
}
/* Maximum number of threads */
#define MX_WORKER 100
/*
** Main routine
*/
int main(int argc, char **argv){
int i;
int nWorker = 4;
int rc;
sqlite3 *db = 0;
sqlite3_stmt *q;
pthread_t aWorker[MX_WORKER];
char aWorkerName[MX_WORKER][8];
for(i=1; i<argc; i++){
const char *zArg = argv[i];
if( zArg[0]!='-' ){
if( zDbName==0 ){
zDbName = argv[i];
continue;
}
printf("unknown argument: %s\n", zArg);
usage(argv[0]);
}
if( zArg[1]=='-' ) zArg++;
if( strcmp(zArg, "-v")==0 ){
eVerbose = 1;
continue;
}
if( strcmp(zArg, "-num-workers")==0 && i+1<argc ){
nWorker = atoi(argv[++i]);
if( nWorker<1 || nWorker>MX_WORKER ){
printf("number of threads must be between 1 and %d\n", MX_WORKER);
exit(1);
}
continue;
}
printf("unknown option: %s\n", argv[i]);
usage(argv[0]);
}
if( zDbName==0 ) zDbName = "file:/mem?vfs=memdb";
sqlite3_config(SQLITE_CONFIG_URI, (int)1);
rc = sqlite3_open(zDbName, &db);
error_out(rc, "sqlite3_open", __LINE__);
rc = exec(db, "SETUP", __LINE__,
"DROP TABLE IF EXISTS task;\n"
"DROP TABLE IF EXISTS p1;\n"
"DROP TABLE IF EXISTS p2;\n"
"DROP TABLE IF EXISTS verify;\n"
"CREATE TABLE IF NOT EXISTS task(\n"
" tid INTEGER PRIMARY KEY,\n"
" doneby TEXT\n"
");\n"
"WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)"
"INSERT INTO task(tid) SELECT x FROM c;\n"
);
error_out(rc, "sqlite3_exec", __LINE__);
for(i=0; i<nWorker; i++){
sqlite3_snprintf(sizeof(aWorkerName[i]), aWorkerName[i],
"W%02d", i);
pthread_create(&aWorker[i], 0, worker, aWorkerName[i]);
}
for(i=0; i<nWorker; i++){
pthread_join(aWorker[i], 0);
}
for(i=0; i<nWorker; i++){
q = prepare(db, "MAIN", __LINE__,
"SELECT group_concat(tid,',') FROM task WHERE doneby=%Q",
aWorkerName[i]);
if( sqlite3_step(q)==SQLITE_ROW ){
printf("%s: %s\n", aWorkerName[i], sqlite3_column_text(q,0));
}
sqlite3_finalize(q);
}
q = prepare(db, "MAIN", __LINE__, "SELECT count(*) FROM p2");
if( sqlite3_step(q)!=SQLITE_ROW || sqlite3_column_int(q,0)<10 ){
printf("incorrect result\n");
exit(-1);
}
sqlite3_finalize(q);
q = prepare(db, "MAIN", __LINE__, "SELECT x FROM p1 EXCEPT SELECT x FROM p2");
if( sqlite3_step(q)==SQLITE_ROW ){
printf("incorrect result\n");
exit(-1);
}
sqlite3_finalize(q);
q = prepare(db, "MAIN", __LINE__, "SELECT x FROM p2 EXCEPT SELECT x FROM p1");
if( sqlite3_step(q)==SQLITE_ROW ){
printf("incorrect result\n");
exit(-1);
}
sqlite3_finalize(q);
printf("OK\n");
sqlite3_close(db);
return 0;
}

View File

@ -353,4 +353,31 @@ do_execsql_test transitive1-570eqp {
SELECT * FROM c1 WHERE x=y AND z=y AND z='abc';
} {/SEARCH c1 USING INDEX c1x/}
# 2021-05-04 forum https://sqlite.org/forum/forumpost/eb8613976a
reset_db
do_execsql_test transitive1-600 {
CREATE TABLE t0(a0 INT, b1 INT);
CREATE INDEX t0b1 ON t0(b1);
CREATE TABLE t1(w,x,y,z3 INT);
INSERT INTO t0(a0, b1) VALUES (0,1);
INSERT INTO t1(w,x,y,z3) VALUES (7,8,9,1);
} {}
do_execsql_test transitive1-610 {
SELECT ALL * FROM t0,t1 WHERE b1=z3 AND a0=z3;
} {}
do_execsql_test transitive1-620 {
SELECT ALL * FROM t0,t1 WHERE likely(b1=z3) AND a0=z3;
} {}
do_execsql_test transitive1-630 {
DROP TABLE t0;
DROP TABLE t1;
CREATE TABLE t0(c0 INT, c1 INT UNIQUE);
CREATE TABLE t1(c0 INT);
INSERT INTO t0(c0, c1) VALUES (0, 1);
INSERT INTO t1(c0) VALUES (1);
SELECT ALL * FROM t1 NATURAL JOIN t0 WHERE (t1.c0=t0.c1);
SELECT ALL * FROM t1 NATURAL JOIN t0 WHERE (likely(t1.c0=t0.c1));
SELECT ALL * FROM t1,t0 WHERE (likely(t1.c0=t0.c1) AND t1.c0=t0.c0);
} {}
finish_test

View File

@ -983,6 +983,7 @@ do_test vtab1.10-5 {
proc match_func {args} {return ""}
do_test vtab1.10-6 {
set echo_module ""
sqlite_delete_function db match
db function match match_func
execsql {
SELECT * FROM e WHERE match('pattern', rowid, 'pattern2');

View File

@ -982,6 +982,23 @@ do_test where9-10.2 {
}
} {1 {} 1}
# dbsqlfuzz 9df1d53c24c4c96af0dae15ee764897af415ac76
# The MULTI-INDEX OR processing evaluates the same WHERE-clause sub-expression
# twice. But if that sub-expression contains a UNION ALL SELECT statement
# subject to query flattening, the sub-expression might be transformed in a
# way that it can only be code-generated once. An assert() will fail on
# the second attempt to generate code from the same sub-expression.
# The solution is to make a copy of sub-expressions used by MULTI-INDEX OR
#
reset_db
do_execsql_test where9-11.1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT);
CREATE TABLE t2_a(k INTEGER PRIMARY KEY, v TEXT);
CREATE TABLE t2_b(k INTEGER PRIMARY KEY, v TEXT);
CREATE VIEW t2 AS SELECT * FROM t2_a UNION ALL SELECT * FROM t2_b;
SELECT 1 FROM t1 JOIN t1 USING(a)
WHERE (a=1)
OR (a=2 AND (SELECT 4 FROM t2,(SELECT 5 FROM t1 ORDER BY a) WHERE a));
} {}
finish_test

View File

@ -28,11 +28,11 @@ do_eqp_test 110 {
QUERY PLAN
`--COMPOUND QUERY
|--LEFT-MOST SUBQUERY
| |--SEARCH t2 USING INDEX sqlite_autoindex_t2_1 (a=?)
| `--SEARCH t1 USING INDEX sqlite_autoindex_t1_1 (a=?)
| |--SEARCH t1 USING INDEX sqlite_autoindex_t1_1 (a=?)
| `--SEARCH t2 USING INDEX sqlite_autoindex_t2_1 (a=?)
`--UNION ALL
|--SEARCH t3 USING INDEX sqlite_autoindex_t3_1 (a=?)
`--SEARCH t1 USING INDEX sqlite_autoindex_t1_1 (a=?)
|--SEARCH t1 USING INDEX sqlite_autoindex_t1_1 (a=?)
`--SEARCH t3 USING INDEX sqlite_autoindex_t3_1 (a=?)
}
# The scan of the t1 table goes first since that enables the ORDER BY

View File

@ -1915,11 +1915,59 @@ do_execsql_test 60.1 {
# the Parse object is destroyed.
#
reset_db
do_execsql_test 61.1 {
do_catchsql_test 61.1 {
CREATE TABLE t1(a);
INSERT INTO t1 VALUES(5),(NULL),('seventeen');
SELECT (SELECT max(x)OVER(ORDER BY x) % min(x)OVER(ORDER BY CASE x WHEN 889 THEN x WHEN x THEN x END)) FROM (SELECT (SELECT sum(CAST(a IN(SELECT (SELECT max(x)OVER(ORDER BY CASE x WHEN 889 THEN 299 WHEN 863 THEN 863 END)) FROM (SELECT (SELECT sum(CAST((SELECT (SELECT max(x)OVER(ORDER BY x) / min(x)OVER(ORDER BY CASE x WHEN 889 THEN 299 WHEN -true THEN 863 END)) FROM (SELECT (SELECT sum(CAST(a IN(SELECT (SELECT max(x) & sum ( a )OVER(ORDER BY CASE x WHEN -8 THEN 299 WHEN 863 THEN 863 END)) FROM (SELECT (SELECT sum(CAST(a AS )) FROM t1) AS x FROM t1)) AS t1 )) FROM t1) AS x FROM t1)) AS x )) FROM t1) AS x FROM t1)) AS real)) FROM t1) AS x FROM t1);
} {{} {} {}}
} {0 {{} {} {}}}
foreach tn {1 2} {
if {$tn==2} { optimization_control db query-flattener 0 }
do_catchsql_test 61.2.$tn {
SELECT
(SELECT max(x)OVER(ORDER BY x) / min(x) OVER() )
FROM (
SELECT (SELECT sum(a) FROM t1 ) AS x FROM t1
)
} {0 {1.0 1.0 1.0}}
}
reset_db
optimization_control db all 0
do_execsql_test 61.3.0 {
CREATE TABLE t1(a);
CREATE TABLE t2(y);
}
do_execsql_test 61.3.1 {
SELECT (
SELECT count(a) OVER ( ORDER BY (SELECT sum(y) FROM t2) )
+ total(a) OVER()
)
FROM t1
} {}
do_execsql_test 61.4.2 {
SELECT (
SELECT count(a) OVER ( ORDER BY sum(a) )
+ total(a) OVER()
)
FROM t1
} {0.0}
do_catchsql_test 61.4.3 {
SELECT
sum(a) OVER ( ORDER BY a )
FROM t1
ORDER BY (SELECT sum(a) FROM t2)
} {1 {misuse of aggregate: sum()}}
do_execsql_test 61.4.4 {
SELECT
sum(a) OVER ( ORDER BY a )
FROM t1
ORDER BY (SELECT sum(y) FROM t2)
}
#-------------------------------------------------------------------------
reset_db
@ -2090,6 +2138,25 @@ do_catchsql_test 67.1 {
SELECT nth_value(a,2) OVER w1
WINDOW w1 AS ( ORDER BY ((SELECT 1 FROM v1)) )
)
} {1 {no such table: v1}}
do_catchsql_test 67.2 {
SELECT a,c,b FROM t1 INTERSECT SELECT a,b,c FROM t1 ORDER BY (
SELECT nth_value(a,2) OVER w1
WINDOW w1 AS ( ORDER BY ((SELECT 1 FROM t2)) )
)
} {1 {1st ORDER BY term does not match any column in the result set}}
# 2021-05-07
# Do not allow aggregate functions in the ORDER BY clause even if
# there are window functions in the result set.
# Forum: /forumpost/540fdfef77
#
reset_db
do_catchsql_test 68.0 {
CREATE TABLE t1(a,b);
INSERT INTO t1(a,b) VALUES(0,0),(1,1),(2,4),(3,9),(4,99);
SELECT rowid, a, b, sum(a)OVER() FROM t1 ORDER BY count(b);
} {1 {misuse of aggregate: count()}}
finish_test

View File

@ -418,6 +418,76 @@ execsql_test 7.$tn.9 "
"
}
==========
execsql_test 8.0 {
DROP TABLE IF EXISTS tx;
CREATE TABLE tx(a INTEGER PRIMARY KEY);
INSERT INTO tx VALUES(1), (2), (3), (4), (5), (6);
DROP TABLE IF EXISTS map;
CREATE TABLE map(v INTEGER PRIMARY KEY, t TEXT);
INSERT INTO map VALUES
(1, 'odd'), (2, 'even'), (3, 'odd'),
(4, 'even'), (5, 'odd'), (6, 'even');
}
execsql_test 8.1 {
SELECT sum(a) OVER (
PARTITION BY (
SELECT t FROM map WHERE v=a
) ORDER BY a
) FROM tx;
}
execsql_test 8.2 {
SELECT sum(a) OVER win FROM tx
WINDOW win AS (
PARTITION BY (
SELECT t FROM map WHERE v=a
) ORDER BY a
);
}
execsql_test 8.3 {
WITH map2 AS (
SELECT * FROM map
)
SELECT sum(a) OVER (
PARTITION BY (
SELECT t FROM map2 WHERE v=a
) ORDER BY a
) FROM tx;
}
execsql_test 8.4 {
WITH map2 AS (
SELECT * FROM map
)
SELECT sum(a) OVER win FROM tx
WINDOW win AS (
PARTITION BY (
SELECT t FROM map2 WHERE v=a
) ORDER BY a
);
}
==========
execsql_test 9.1 {
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1(a INTEGER);
CREATE TABLE t2(y INTEGER);
}
execsql_test 9.2 {
SELECT (
SELECT max(a) OVER ( ORDER BY (SELECT sum(a) FROM t1) )
+ min(a) OVER()
)
FROM t1
}
finish_test

View File

@ -6469,4 +6469,75 @@ do_execsql_test 7.4.9 {
);
} {4 4 4 {} {} {}}
#==========================================================================
do_execsql_test 8.0 {
DROP TABLE IF EXISTS tx;
CREATE TABLE tx(a INTEGER PRIMARY KEY);
INSERT INTO tx VALUES(1), (2), (3), (4), (5), (6);
DROP TABLE IF EXISTS map;
CREATE TABLE map(v INTEGER PRIMARY KEY, t TEXT);
INSERT INTO map VALUES
(1, 'odd'), (2, 'even'), (3, 'odd'),
(4, 'even'), (5, 'odd'), (6, 'even');
} {}
do_execsql_test 8.1 {
SELECT sum(a) OVER (
PARTITION BY (
SELECT t FROM map WHERE v=a
) ORDER BY a
) FROM tx;
} {2 6 12 1 4 9}
do_execsql_test 8.2 {
SELECT sum(a) OVER win FROM tx
WINDOW win AS (
PARTITION BY (
SELECT t FROM map WHERE v=a
) ORDER BY a
);
} {2 6 12 1 4 9}
do_execsql_test 8.3 {
WITH map2 AS (
SELECT * FROM map
)
SELECT sum(a) OVER (
PARTITION BY (
SELECT t FROM map2 WHERE v=a
) ORDER BY a
) FROM tx;
} {2 6 12 1 4 9}
do_execsql_test 8.4 {
WITH map2 AS (
SELECT * FROM map
)
SELECT sum(a) OVER win FROM tx
WINDOW win AS (
PARTITION BY (
SELECT t FROM map2 WHERE v=a
) ORDER BY a
);
} {2 6 12 1 4 9}
#==========================================================================
do_execsql_test 9.1 {
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1(a INTEGER);
CREATE TABLE t2(y INTEGER);
} {}
do_execsql_test 9.2 {
SELECT (
SELECT max(a) OVER ( ORDER BY (SELECT sum(a) FROM t1) )
+ min(a) OVER()
)
FROM t1
} {}
finish_test

View File

@ -452,5 +452,18 @@ do_execsql_test 13.10 {
PRAGMA integrity_check;
SELECT * FROM t0, t1;
} {ok abc xyz abc xyz}
# 2021-05-13 https://sqlite.org/forum/forumpost/6c8960f545
reset_db
do_execsql_test 14.1 {
CREATE TABLE t1(a INT PRIMARY KEY) WITHOUT ROWID;
INSERT INTO t1(a) VALUES(10);
ALTER TABLE t1 ADD COLUMN b INT;
SELECT * FROM t1 WHERE a=20 OR (a=10 AND b=10);
} {}
do_execsql_test 14.2 {
CREATE TABLE dual AS SELECT 'X' AS dummy;
EXPLAIN QUERY PLAN SELECT * FROM dual, t1 WHERE a=10 AND b=10;
} {~/b=/}
finish_test

View File

@ -145,7 +145,9 @@ foreach name {OP_Noop OP_Explain OP_Abortable} {
incr nOp
}
# The following are the opcodes that are processed by resolveP2Values()
# The following are the opcodes that receive special processing in the
# resolveP2Values() routine. Update this list whenever new cases are
# added to the pOp->opcode switch within resolveP2Values().
#
set rp2v_ops {
OP_Transaction
@ -157,13 +159,11 @@ set rp2v_ops {
OP_VUpdate
OP_VFilter
OP_Next
OP_NextIfOpen
OP_SorterNext
OP_Prev
OP_PrevIfOpen
}
# Assign small values to opcodes that are processed by resolveP2Values()
# Assign the smallest values to opcodes that are processed by resolveP2Values()
# to make code generation for the switch() statement smaller and faster.
#
set cnt -1
@ -177,6 +177,7 @@ for {set i 0} {$i<$nOp} {incr i} {
set def($cnt) $name
}
}
set mxCase1 $cnt
# Assign the next group of values to JUMP opcodes
#
@ -311,7 +312,7 @@ for {set i 0} {$i<=$max} {incr i} {
}
puts "\175"
puts ""
puts "/* The sqlite3P2Values() routine is able to run faster if it knows"
puts "/* The resolve3P2Values() routine is able to run faster if it knows"
puts "** the value of the largest JUMP opcode. The smaller the maximum"
puts "** JUMP opcode the better, so the mkopcodeh.tcl script that"
puts "** generated this include file strives to group all JUMP opcodes"

View File

@ -206,6 +206,7 @@ proc main {argv} {
SQLITE_OMIT_DATETIME_FUNCS \
SQLITE_OMIT_DECLTYPE \
SQLITE_OMIT_DEPRECATED \
SQLITE_OMIT_DESERIALIZE \
SQLITE_OMIT_DISKIO \
SQLITE_OMIT_EXPLAIN \
SQLITE_OMIT_FLAG_PRAGMAS \