merge from trunk
FossilOrigin-Name: 19ffe3cfe278a4046f32df56f75080c2377e4c44ad40a02d39db8e7701526204
This commit is contained in:
commit
4f878f33a9
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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];
|
||||
|
@ -132,6 +132,11 @@ foreach {tn3 create_vfs destroy_vfs} {
|
||||
} {
|
||||
sqlite3rbu_destroy_vfs myrbu
|
||||
}
|
||||
3 {
|
||||
sqlite3_register_cksumvfs
|
||||
} {
|
||||
sqlite3_unregister_cksumvfs
|
||||
}
|
||||
} {
|
||||
|
||||
eval $create_vfs
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
6
main.mk
6
main.mk
@ -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
141
manifest
@ -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
|
||||
|
@ -1 +1 @@
|
||||
3ff228249adf2da345d3e19e9af3e23d1354f6b9a35ddbe9864e1a07716d871c
|
||||
19ffe3cfe278a4046f32df56f75080c2377e4c44ad40a02d39db8e7701526204
|
@ -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++){
|
||||
|
@ -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)
|
||||
|
54
src/btree.c
54
src/btree.c
@ -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);
|
||||
|
42
src/build.c
42
src/build.c
@ -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;
|
||||
|
13
src/expr.c
13
src/expr.c
@ -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;
|
||||
|
@ -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
|
||||
|
10
src/main.c
10
src/main.c
@ -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);
|
||||
|
345
src/memdb.c
345
src/memdb.c
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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). {
|
||||
|
@ -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 ){
|
||||
|
23
src/select.c
23
src/select.c
@ -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)
|
||||
){
|
||||
|
@ -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 ){
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
98
src/vdbe.c
98
src/vdbe.c
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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. */
|
||||
|
26
src/where.c
26
src/where.c
@ -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);
|
||||
|
@ -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) */
|
||||
|
@ -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);
|
||||
|
284
src/whereexpr.c
284
src/whereexpr.c
@ -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.
|
||||
|
15
src/window.c
15
src/window.c
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
@ -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
|
@ -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.
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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" {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
339
test/threadtest5.c
Normal 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;
|
||||
}
|
@ -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
|
||||
|
@ -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');
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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 \
|
||||
|
Loading…
x
Reference in New Issue
Block a user