Compare commits
133 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c0359f0490 | |||
| e9de65201c | |||
| d2f55773f1 | |||
| 48a296c589 | |||
| 342cb33b23 | |||
| 48f4f27cfb | |||
| 7d11e647ad | |||
| a8ed515400 | |||
| c3b48848b3 | |||
| 40b82f9dc6 | |||
| 14c4d42874 | |||
| 151446e793 | |||
| 137b8ebb2b | |||
| 4df68e0ae5 | |||
| 78a9d7551c | |||
| c00727ab58 | |||
| 0fcf6f01e7 | |||
| b6b06bb339 | |||
| bf7f3a005e | |||
| 0542812726 | |||
| 7cc73b399e | |||
| 5e1a7ded4d | |||
| ff9186137d | |||
| d42dbd9dfe | |||
| 93c8139c1a | |||
| acef1abda2 | |||
| ec2f689b21 | |||
| a76b7f5296 | |||
| 90bc36fb30 | |||
| a8f249f1e7 | |||
| cd1499f47b | |||
| 5da5b71435 | |||
| 1168f81092 | |||
| 14e250ac16 | |||
| 4f878f33a9 | |||
| 1f4f7c7a41 | |||
| 04f4b6836b | |||
| 187e2e48a8 | |||
| 3d691fd9ff | |||
| 9088186bfb | |||
| 99bd552503 | |||
| 93ffb50fcd | |||
| e74ca517b4 | |||
| 8ed1da195a | |||
| 904e48eb89 | |||
| 8546497383 | |||
| be12083bc7 | |||
| ba39ca4058 | |||
| 9430506df0 | |||
| 2454e4a901 | |||
| 86c779fe42 | |||
| 49bb56e9b0 | |||
| 6a9595a76b | |||
| b775c97682 | |||
| 11c87895e0 | |||
| 31da7be9f2 | |||
| 756748ea86 | |||
| 7ffb16b495 | |||
| 0564cc2601 | |||
| 52d1407891 | |||
| 85ffcae177 | |||
| 277ae64103 | |||
| 2d344f944e | |||
| 483051c9b6 | |||
| f71d6fa9db | |||
| ccb897c70a | |||
| 2f4d0ec392 | |||
| 8d889afc0d | |||
| d10c3ca3f7 | |||
| 4752bbd872 | |||
| 01ec691979 | |||
| e31cba5675 | |||
| c3c23f346c | |||
| 59df3e92db | |||
| 4fd82a2a78 | |||
| 67656ac78a | |||
| 23634898c5 | |||
| 6068b6b451 | |||
| 433a3e935d | |||
| f83d501c6d | |||
| e103a8de2d | |||
| 736d11ed21 | |||
| 76baad95f4 | |||
| 0449f6561f | |||
| 5f5719bd07 | |||
| 5960724789 | |||
| 81f5ef05a9 | |||
| 7bfccfe73c | |||
| 5f086ddee0 | |||
| 5e26d07d62 | |||
| c645871123 | |||
| 79f313f13c | |||
| 3765c03243 | |||
| a476768340 | |||
| a4cd0bbcb3 | |||
| 3ec4861c00 | |||
| 2f40dc9884 | |||
| 19a7f72ce2 | |||
| d8bc250b91 | |||
| c7f5077e88 | |||
| feef447271 | |||
| ada2323d95 | |||
| f0ac29090b | |||
| 3c6edc8a11 | |||
| 8ed8ddf759 | |||
| bb0eec438d | |||
| 3ff6a5edd9 | |||
| 113a33c539 | |||
| ba9ebc2d12 | |||
| 971ae9f66a | |||
| 1521270010 | |||
| ba6619d7be | |||
| 292ed6decf | |||
| d84f10ed13 | |||
| f3d5a68461 | |||
| 7a04e296f3 | |||
| eca3c67b1c | |||
| 214b50314a | |||
| 743b5fd589 | |||
| 9ad39a33ff | |||
| 3d8c92d041 | |||
| a5b51b8715 | |||
| 65b930553d | |||
| 68b63c0195 | |||
| 1da9c97bc0 | |||
| 824043150f | |||
| 31536304a5 | |||
| 7d0a2f3fe3 | |||
| c7a409e78e | |||
| 89eab376da | |||
| 5ae13144ef | |||
| cf5ad4210e | |||
| f8fb27f4a9 |
+4
-4
@@ -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
|
||||
|
||||
|
||||
|
||||
+7
-7
@@ -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);
|
||||
|
||||
@@ -2806,6 +2806,7 @@ int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
|
||||
}
|
||||
#else
|
||||
int rc = SQLITE_OK;
|
||||
UNUSED_PARAM2(pGlobal,db);
|
||||
#endif
|
||||
|
||||
/* Avoid warnings indicating that sqlite3Fts5ParserTrace() and
|
||||
|
||||
@@ -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);
|
||||
@@ -5079,7 +5078,8 @@ static void fts5MergePrefixLists(
|
||||
nTail = pHead->iter.nPoslist - pHead->iOff;
|
||||
|
||||
/* WRITEPOSLISTSIZE */
|
||||
assert( tmp.n+nTail<=nTmp );
|
||||
assert_nc( tmp.n+nTail<=nTmp );
|
||||
assert( tmp.n+nTail<=nTmp+nMerge*10 );
|
||||
if( tmp.n+nTail>nTmp-FTS5_DATA_ZERO_PADDING ){
|
||||
if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT;
|
||||
break;
|
||||
@@ -6720,6 +6720,7 @@ int sqlite3Fts5IndexInit(sqlite3 *db){
|
||||
return rc;
|
||||
#else
|
||||
return SQLITE_OK;
|
||||
UNUSED_PARAM(db);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1949,13 +1949,15 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){
|
||||
|
||||
nInst++;
|
||||
if( nInst>=pCsr->nInstAlloc ){
|
||||
pCsr->nInstAlloc = pCsr->nInstAlloc ? pCsr->nInstAlloc*2 : 32;
|
||||
int nNewSize = pCsr->nInstAlloc ? pCsr->nInstAlloc*2 : 32;
|
||||
aInst = (int*)sqlite3_realloc64(
|
||||
pCsr->aInst, pCsr->nInstAlloc*sizeof(int)*3
|
||||
pCsr->aInst, nNewSize*sizeof(int)*3
|
||||
);
|
||||
if( aInst ){
|
||||
pCsr->aInst = aInst;
|
||||
pCsr->nInstAlloc = nNewSize;
|
||||
}else{
|
||||
nInst--;
|
||||
rc = SQLITE_NOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -14591,6 +14591,336 @@ do_catchsql_test 74.1 {
|
||||
SELECT rowid, quote(matchinfo(t1,'p�xyb<s')) FROM t1 WHERE t1 MATCH 'e*';
|
||||
} {1 {unable to use function matchinfo in the requested context}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_test 75.0 {
|
||||
sqlite3 db {}
|
||||
db deserialize [decode_hexdb {
|
||||
| size 32768 pagesize 4096 filename crash-033d665d5caa8d.db
|
||||
| page 1 offset 0
|
||||
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
|
||||
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
|
||||
| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6
|
||||
| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 00 00 00 00 00 00 ...k............
|
||||
| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet
|
||||
| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE
|
||||
| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta
|
||||
| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
|
||||
| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
|
||||
| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
|
||||
| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
|
||||
| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[.
|
||||
| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
|
||||
| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
|
||||
| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
|
||||
| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
|
||||
| 3664: 54 45 47 45 52 20 50 52 49 4d 54 52 59 20 4b 45 TEGER PRIMTRY KE
|
||||
| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...!
|
||||
| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont
|
||||
| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR
|
||||
| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c
|
||||
| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG
|
||||
| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
|
||||
| 3776: 63 30 2c 20 63 31 2c d6 63 32 29 69 04 07 17 19 c0, c1,.c2)i....
|
||||
| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt
|
||||
| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB
|
||||
| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi
|
||||
| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P
|
||||
| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid
|
||||
| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT
|
||||
| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t
|
||||
| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da
|
||||
| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE
|
||||
| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT
|
||||
| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
|
||||
| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8..
|
||||
| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR
|
||||
| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
|
||||
| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5
|
||||
| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c).........
|
||||
| page 3 offset 8192
|
||||
| 0: 0d 00 00 00 03 0c 93 ff 0f e6 0f ef 0c 94 00 00 ................
|
||||
| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J..........
|
||||
| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00.........
|
||||
| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 31 31 36 30 ...........21160
|
||||
| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 33 f1 609...........3.
|
||||
| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 03 01 02 ..........5.....
|
||||
| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 3d ......0000000..=
|
||||
| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary..
|
||||
| 3328: 01 02 02 03 06 01 01 f2 03 06 4e 02 02 03 06 01 ..........N.....
|
||||
| 3344: 02 02 03 05 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
|
||||
| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp
|
||||
| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d
|
||||
| 3408: 62 73 74 61 74 07 02 03 01 02 13 01 02 03 02 04 bstat...........
|
||||
| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 07 65 ebug...........e
|
||||
| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable...........
|
||||
| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
|
||||
| 3472: 01 02 02 01 02 02 01 02 01 f1 02 02 01 02 02 01 ................
|
||||
| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
|
||||
| 3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02 ......xtension..
|
||||
| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4...
|
||||
| 3536: 01 02 03 01 02 03 04 01 25 0d 02 03 01 02 03 01 ........%.......
|
||||
| 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc.........
|
||||
| 3568: 02 06 65 6f 70 6f 6c 79 0f f2 03 01 02 03 01 02 ..eopoly........
|
||||
| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........
|
||||
| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load.........
|
||||
| 3616: 00 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05 ..max...........
|
||||
| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory...........
|
||||
| 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n
|
||||
| 3664: 6f 63 61 73 65 02 06 01 02 02 13 06 00 f2 02 03 ocase...........
|
||||
| 3680: 06 01 02 02 13 06 01 02 02 03 06 01 02 02 03 06 ................
|
||||
| 3696: 01 02 02 03 06 01 02 02 03 06 02 02 02 03 06 01 ................
|
||||
| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 b2 ...omit.........
|
||||
| 3744: 01 0a 22 74 72 65 65 19 02 03 01 02 03 01 02 03 ...tree.........
|
||||
| 3760: 04 02 69 6c f1 06 01 02 02 03 06 01 02 02 03 06 ..il............
|
||||
| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
|
||||
| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
|
||||
| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe....
|
||||
| 3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab.....
|
||||
| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x.........
|
||||
| 3872: 02 01 06 01 01 02 04 36 01 01 02 01 06 01 01 02 .......6........
|
||||
| 3888: 01 06 01 11 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
|
||||
| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
|
||||
| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
|
||||
| 3952: 02 01 06 01 01 01 f1 06 01 01 02 ad 06 01 01 02 ................
|
||||
| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 3984: 06 01 01 01 01 06 01 01 02 01 06 01 01 02 01 06 ................
|
||||
| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
|
||||
| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
|
||||
| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................
|
||||
| 4048: 12 44 13 11 0f 47 13 0e fc 0e 11 10 0f 0e 10 0f .D...G..........
|
||||
| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$.
|
||||
| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
|
||||
| page 4 offset 12288
|
||||
| 0: 0a 00 00 00 00 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 0c 01 02 ................
|
||||
| page 5 offset 16384
|
||||
| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%.
|
||||
| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI
|
||||
| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA
|
||||
| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 8f DSAFE=0XNOCASE..
|
||||
| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d ..%..THREADSAFE=
|
||||
| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 45 ed 0XRTRIM.!..3..E.
|
||||
| 3168: 49 54 20 4c 4f 41 44 21 45 58 54 45 4e 53 49 4f IT LOAD!EXTENSIO
|
||||
| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O
|
||||
| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 5a 29 MIT LOAD EXTENZ)
|
||||
| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3..
|
||||
| 3232: 4f 4d 59 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMYT LOAD EXTENS
|
||||
| 3248: 49 4f 4e 58 52 54 56 a9 4d 1f 1e 05 00 33 0f 19 IONXRTV.M....3..
|
||||
| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 25 30 30 30 30 MAX MEMORY=%0000
|
||||
| 3280: 30 30 30 57 42 49 4e 31 52 59 1f 1d 05 00 33 0f 000WBIN1RY....3.
|
||||
| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000
|
||||
| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 32 0000XNOCASE....2
|
||||
| 3328: 0e 17 4e 41 58 20 4d 45 4d 4f 52 59 2d 35 30 30 ..NAX MEMORY-500
|
||||
| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....%
|
||||
| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB
|
||||
| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
|
||||
| 3392: 4c 45 20 52 54 52 45 45 59 4e 4f 43 41 53 45 17 LE RTREEYNOCASE.
|
||||
| 3408: 19 66 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 .f.%..ENABLE RTR
|
||||
| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E
|
||||
| 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 NABLE MEMSYS5XBI
|
||||
| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL
|
||||
| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE
|
||||
| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME
|
||||
| 3504: 4d 53 59 76 35 58 52 54 52 49 4d 18 15 05 10 25 MSYv5XRTRIM....%
|
||||
| 3520: 0f 19 45 4e 40 42 4c 45 20 4a 53 4f 4e 31 58 42 ..EN@BLE JSON1XB
|
||||
| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
|
||||
| 3552: 4c 45 20 4a 53 4f 4e 32 58 4e 4f 43 41 53 45 17 LE JSON2XNOCASE.
|
||||
| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO
|
||||
| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E
|
||||
| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 NABLE GEOPOLYXBI
|
||||
| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 5f 81 42 4c NARY....)..E_.BL
|
||||
| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 51 53 45 E GEOPOLYXNOCQSE
|
||||
| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE
|
||||
| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....#
|
||||
| 3680: 0f 1a 45 4e 41 42 4c 45 20 56 54 43 35 58 42 49 ..ENABLE VTC5XBI
|
||||
| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL
|
||||
| 3712: 45 20 46 54 53 35 48 4e 4f 43 41 53 45 16 1d 05 E FTS5HNOCASE...
|
||||
| 3728: 00 23 0f a4 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X
|
||||
| 3744: 52 54 52 49 4d b7 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB
|
||||
| 3760: 4c 45 20 46 55 53 34 58 42 49 4e 41 52 59 17 0b LE FUS4XBINARY..
|
||||
| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4
|
||||
| 3792: 57 4e 4f 43 41 53 45 16 0a 05 00 21 7f 17 45 4e WNOCASE....!..EN
|
||||
| 3808: 41 42 4c 45 20 46 54 53 34 05 52 54 52 49 4d 1e ABLE FTS4.RTRIM.
|
||||
| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
|
||||
| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY.
|
||||
| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
|
||||
| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE.
|
||||
| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
|
||||
| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 TAT VTABXRTRIM..
|
||||
| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52 .....DEBUGXBINAR
|
||||
| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO
|
||||
| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG
|
||||
| 3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XRTRIM'...C..COM
|
||||
| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0
|
||||
| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY'
|
||||
| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3f 87 ...C..COMPILER?.
|
||||
| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060
|
||||
| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 00 9XNOCASE&...C...
|
||||
| page 6 offset 20480
|
||||
| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#......
|
||||
| 3824: 06 22 03 01 12 02 01 01 06 21 03 00 12 03 01 01 .........!......
|
||||
| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 02 01 . ..............
|
||||
| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................
|
||||
| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................
|
||||
| 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................
|
||||
| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................
|
||||
| 3920: 06 16 03 00 12 02 01 01 06 15 03 00 12 02 01 01 ................
|
||||
| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................
|
||||
| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................
|
||||
| 3968: 06 00 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................
|
||||
| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................
|
||||
| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 10 12 02 01 01 ................
|
||||
| 4016: 06 0a 03 00 12 02 01 01 06 09 03 01 12 03 01 01 ................
|
||||
| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................
|
||||
| 4048: 07 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01 ................
|
||||
| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................
|
||||
| 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................
|
||||
| page 7 offset 24576
|
||||
| 0: 0a 00 00 00 01 0f f4 00 0f f4 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 8 offset 28672
|
||||
| 4048: 00 00 00 00 00 00 5d 03 02 2b 69 6e 74 00 00 00 ......]..+int...
|
||||
| end crash-033d665d5caa8d.db
|
||||
}]} {}
|
||||
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
|
||||
+5
-4
@@ -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);
|
||||
}
|
||||
|
||||
+2
-2
@@ -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];
|
||||
@@ -2003,8 +2003,8 @@ static void jsonObjectStep(
|
||||
jsonAppendChar(pStr, '{');
|
||||
}else if( pStr->nUsed>1 ){
|
||||
jsonAppendChar(pStr, ',');
|
||||
pStr->pCtx = ctx;
|
||||
}
|
||||
pStr->pCtx = ctx;
|
||||
z = (const char*)sqlite3_value_text(argv[0]);
|
||||
n = (u32)sqlite3_value_bytes(argv[0]);
|
||||
jsonAppendString(pStr, z, n);
|
||||
|
||||
+37
-29
@@ -36,10 +36,24 @@ SQLITE_EXTENSION_INIT1
|
||||
|
||||
#ifndef SQLITE_AMALGAMATION
|
||||
|
||||
#ifndef UINT32_TYPE
|
||||
# ifdef HAVE_UINT32_T
|
||||
# define UINT32_TYPE uint32_t
|
||||
# else
|
||||
# define UINT32_TYPE unsigned int
|
||||
# endif
|
||||
#endif
|
||||
#ifndef UINT16_TYPE
|
||||
# ifdef HAVE_UINT16_T
|
||||
# define UINT16_TYPE uint16_t
|
||||
# else
|
||||
# define UINT16_TYPE unsigned short int
|
||||
# endif
|
||||
#endif
|
||||
typedef sqlite3_int64 i64;
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned long u32;
|
||||
typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
|
||||
typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
|
||||
#define MIN(a,b) ((a)<(b) ? (a) : (b))
|
||||
|
||||
#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
|
||||
@@ -706,34 +720,24 @@ static int zipfileScanExtra(u8 *aExtra, int nExtra, u32 *pmTime){
|
||||
** https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx
|
||||
*/
|
||||
static u32 zipfileMtime(ZipfileCDS *pCDS){
|
||||
int Y = (1980 + ((pCDS->mDate >> 9) & 0x7F));
|
||||
int M = ((pCDS->mDate >> 5) & 0x0F);
|
||||
int D = (pCDS->mDate & 0x1F);
|
||||
int B = -13;
|
||||
|
||||
int sec = (pCDS->mTime & 0x1F)*2;
|
||||
int min = (pCDS->mTime >> 5) & 0x3F;
|
||||
int hr = (pCDS->mTime >> 11) & 0x1F;
|
||||
i64 JD;
|
||||
|
||||
/* JD = INT(365.25 * (Y+4716)) + INT(30.6001 * (M+1)) + D + B - 1524.5 */
|
||||
|
||||
/* Calculate the JD in seconds for noon on the day in question */
|
||||
if( M<3 ){
|
||||
Y = Y-1;
|
||||
M = M+12;
|
||||
int Y,M,D,X1,X2,A,B,sec,min,hr;
|
||||
i64 JDsec;
|
||||
Y = (1980 + ((pCDS->mDate >> 9) & 0x7F));
|
||||
M = ((pCDS->mDate >> 5) & 0x0F);
|
||||
D = (pCDS->mDate & 0x1F);
|
||||
sec = (pCDS->mTime & 0x1F)*2;
|
||||
min = (pCDS->mTime >> 5) & 0x3F;
|
||||
hr = (pCDS->mTime >> 11) & 0x1F;
|
||||
if( M<=2 ){
|
||||
Y--;
|
||||
M += 12;
|
||||
}
|
||||
JD = (i64)(24*60*60) * (
|
||||
(int)(365.25 * (Y + 4716))
|
||||
+ (int)(30.6001 * (M + 1))
|
||||
+ D + B - 1524
|
||||
);
|
||||
|
||||
/* Correct the JD for the time within the day */
|
||||
JD += (hr-12) * 3600 + min * 60 + sec;
|
||||
|
||||
/* Convert JD to unix timestamp (the JD epoch is 2440587.5) */
|
||||
return (u32)(JD - (i64)(24405875) * 24*60*6);
|
||||
X1 = 36525*(Y+4716)/100;
|
||||
X2 = 306001*(M+1)/10000;
|
||||
A = Y/100;
|
||||
B = 2 - A + (A/4);
|
||||
JDsec = (i64)((X1 + X2 + D + B - 1524.5)*86400) + hr*3600 + min*60 + sec;
|
||||
return (u32)(JDsec - (i64)24405875*(i64)8640);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2170,6 +2174,10 @@ static int zipfileRegister(sqlite3 *db){
|
||||
zipfileStep, zipfileFinal
|
||||
);
|
||||
}
|
||||
assert( sizeof(i64)==8 );
|
||||
assert( sizeof(u32)==4 );
|
||||
assert( sizeof(u16)==2 );
|
||||
assert( sizeof(u8)==1 );
|
||||
return rc;
|
||||
}
|
||||
#else /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
||||
@@ -132,6 +132,11 @@ foreach {tn3 create_vfs destroy_vfs} {
|
||||
} {
|
||||
sqlite3rbu_destroy_vfs myrbu
|
||||
}
|
||||
3 {
|
||||
sqlite3_register_cksumvfs
|
||||
} {
|
||||
sqlite3_unregister_cksumvfs
|
||||
}
|
||||
} {
|
||||
|
||||
eval $create_vfs
|
||||
|
||||
+9
-21
@@ -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;
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
# 2014 August 16
|
||||
#
|
||||
# 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 sessions SQLite extension.
|
||||
# Specifically, this file contains tests for "patchset" changes.
|
||||
#
|
||||
|
||||
if {![info exists testdir]} {
|
||||
set testdir [file join [file dirname [info script]] .. .. test]
|
||||
}
|
||||
source [file join [file dirname [info script]] session_common.tcl]
|
||||
source $testdir/tester.tcl
|
||||
ifcapable !session {finish_test; return}
|
||||
|
||||
if {[permutation]=="session_strm" || [permutation]=="session_eec"} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
set testprefix sessionbig
|
||||
|
||||
forcedelete test.db2
|
||||
sqlite3 db2 test.db2
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
}
|
||||
do_execsql_test -db db2 1.1 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
}
|
||||
|
||||
do_test 1.2 {
|
||||
do_then_apply_sql {
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
}
|
||||
} {}
|
||||
|
||||
do_test 1.3 {
|
||||
execsql { DELETE FROM t1 }
|
||||
execsql2 { DELETE FROM t1 }
|
||||
} {}
|
||||
|
||||
do_test 1.4 {
|
||||
set rc [catch {
|
||||
do_then_apply_sql {
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
|
||||
}
|
||||
} msg]
|
||||
list $rc $msg
|
||||
} {1 SQLITE_NOMEM}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -1974,13 +1974,29 @@ int sqlite3session_attach(
|
||||
** If successful, return zero. Otherwise, if an OOM condition is encountered,
|
||||
** set *pRc to SQLITE_NOMEM and return non-zero.
|
||||
*/
|
||||
static int sessionBufferGrow(SessionBuffer *p, size_t nByte, int *pRc){
|
||||
if( *pRc==SQLITE_OK && (size_t)(p->nAlloc-p->nBuf)<nByte ){
|
||||
static int sessionBufferGrow(SessionBuffer *p, i64 nByte, int *pRc){
|
||||
#define SESSION_MAX_BUFFER_SZ (0x7FFFFF00 - 1)
|
||||
i64 nReq = p->nBuf + nByte;
|
||||
if( *pRc==SQLITE_OK && nReq>p->nAlloc ){
|
||||
u8 *aNew;
|
||||
i64 nNew = p->nAlloc ? p->nAlloc : 128;
|
||||
|
||||
do {
|
||||
nNew = nNew*2;
|
||||
}while( (size_t)(nNew-p->nBuf)<nByte );
|
||||
}while( nNew<nReq );
|
||||
|
||||
/* The value of SESSION_MAX_BUFFER_SZ is copied from the implementation
|
||||
** of sqlite3_realloc64(). Allocations greater than this size in bytes
|
||||
** always fail. It is used here to ensure that this routine can always
|
||||
** allocate up to this limit - instead of up to the largest power of
|
||||
** two smaller than the limit. */
|
||||
if( nNew>SESSION_MAX_BUFFER_SZ ){
|
||||
nNew = SESSION_MAX_BUFFER_SZ;
|
||||
if( nNew<nReq ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew);
|
||||
if( 0==aNew ){
|
||||
|
||||
@@ -82,14 +82,15 @@ void sqlite3session_delete(sqlite3_session *pSession);
|
||||
/*
|
||||
** CAPIREF: Conigure a Session Object
|
||||
** METHOD: sqlite3_session
|
||||
*/
|
||||
int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Arguments for sqlite3session_object_config()
|
||||
**
|
||||
** 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].
|
||||
**
|
||||
** 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
|
||||
@@ -105,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
|
||||
|
||||
/*
|
||||
@@ -351,13 +356,18 @@ int sqlite3session_changeset(
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Load The Difference Between Tables Into A Session
|
||||
** METHOD: sqlite3session_changeset_size()
|
||||
** CAPI3REF: Return An Upper-limit For The Size Of The Changeset
|
||||
** METHOD: sqlite3_session
|
||||
**
|
||||
** This function returns an upper limit, in bytes, of the size of the
|
||||
** changeset that might be produced if sqlite3session_changeset() were
|
||||
** called. The final changeset size might be equal to or smaller than
|
||||
** the size in bytes returned by this function.
|
||||
** 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
|
||||
** SQLITE_SESSION_OBJCONFIG_SIZE verb.
|
||||
**
|
||||
** When enabled, this function returns an upper limit, in bytes, for the size
|
||||
** of the changeset that might be produced if sqlite3session_changeset() were
|
||||
** called. The final changeset size might be equal to or smaller than the
|
||||
** size in bytes returned by this function.
|
||||
*/
|
||||
sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
C Add\sthe\ssqlite3session_object_config()\sAPI.\sCurrent\sused\sto\senable/disable\scollecting\sdata\sfor\ssqlite3session_changeset_size().
|
||||
D 2021-04-22T17:40:28.167
|
||||
C If\sa\ssubquery\sis\sused\sto\sdrive\san\sindex,\sthis\schange\savoids\smaking\san\sextra\ncopy\sof\sthe\sresult\sof\sthat\ssubquery.\s\sBut,\ssuch\ssituations\sare\sprobably\nsufficiently\sunusual\sthat\sthe\sadded\scomplexity\sof\sthis\senhancement\sis\snot\nworth\sthe\sperformance\sgain.\s\sSo\sI'm\sgoing\sto\spark\sthis\scheck-in\son\sa\sbranch.\nIf\swe\slater\sfind\sa\suse\scase\sto\sjustify\sit,\swe\scan\smerge\sit\sto\strunk\sthen.\nThis\sis\sthe\s"further\schange"\sthat\swas\spromised\sby\sthe\sprior\scheck-in\scomment.
|
||||
D 2021-05-28T14:28:54.261
|
||||
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
|
||||
@@ -117,10 +117,10 @@ F ext/fts5/fts5Int.h 26c74dd5776f798436fbf604a0bf0e8de263b35b5060b05c15f9085845d
|
||||
F ext/fts5/fts5_aux.c f558e1fb9f0f86a4f7489e258c162e1f947de5ff2709087fbb465fddb7092f98
|
||||
F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70
|
||||
F ext/fts5/fts5_config.c 8336d0ff6db0933f63cfec8ae0ab76e68393259cbccc0b46e1f79f7fa1842ff3
|
||||
F ext/fts5/fts5_expr.c 5d0ab73f08af31837b1a4cbcaf571e74d7bb87f4f15bf79709de1b67ff4bfc05
|
||||
F ext/fts5/fts5_expr.c 9462249a3bb82d0e49b163500f9d2197c2e4cd95bf440a9bbfc3906b22ea1e1b
|
||||
F ext/fts5/fts5_hash.c 1aa93c9b5f461afba66701ee226297dc78402b3bdde81e90a10de5fe3df14959
|
||||
F ext/fts5/fts5_index.c a2ee22478318ad2c176fb06b0a7a752b770056cde6a0a8d8a50968f3afcc306e
|
||||
F ext/fts5/fts5_main.c f497ca97cb2802311ec93733b595762dc5b044ce3c6c8ce5fb3e871dd3fccd5d
|
||||
F ext/fts5/fts5_index.c 222b5e56f51139ca5400985e26ea9971165901c7a45a2c17499bd2be3695c697
|
||||
F ext/fts5/fts5_main.c 35ebbcae681a4a40027c47bc2e94d7e7c81e331dc406bb9b23c546454ee8f98a
|
||||
F ext/fts5/fts5_storage.c 58ba71e6cd3d43a5735815e7956ee167babb4d2cbfe206905174792af4d09d75
|
||||
F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae
|
||||
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
|
||||
@@ -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 1cad09897fc69084a904c921dee7f777e1c866964ee2ec2cc7a8a69cc3f1ab68
|
||||
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 76c5d9e0960fd15b4be79dacb76d872b4d0d983ce13e72ebfe9481d82cb9345d
|
||||
F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d
|
||||
F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b
|
||||
F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567
|
||||
@@ -337,10 +337,10 @@ F ext/misc/vfsstat.c 389ea13983d3af926504c314f06a83cc858d5adc24b40af74aaed1fece0
|
||||
F ext/misc/vtablog.c 5538acd0c8ddaae372331bee11608d76973436b77d6a91e8635cfc9432fba5ae
|
||||
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
|
||||
F ext/misc/wholenumber.c a838d1bea913c514ff316c69695efbb49ea3b8cb37d22afc57f73b6b010b4546
|
||||
F ext/misc/zipfile.c e35e035bc2765b1ccdcb15f9815c2112843fcbc8f36aa071f0e5935df7072228
|
||||
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
|
||||
@@ -446,6 +446,7 @@ F ext/session/sessionH.test b17afdbd3b8f17e9bab91e235acf167cf35485db2ab2df0ea889
|
||||
F ext/session/session_common.tcl f613174665456b2d916ae8df3e5735092a1c1712f36f46840172e9a01e8cc53e
|
||||
F ext/session/session_speed_test.c dcf0ef58d76b70c8fbd9eab3be77cf9deb8bc1638fed8be518b62d6cbdef88b3
|
||||
F ext/session/sessionat.test efe88965e74ff1bc2af9c310b28358c02d420c1fb2705cc7a28f0c1cc142c3ec
|
||||
F ext/session/sessionbig.test 5851fc7f9981e2ccf1c7d9e7cb239dc530db07d5e878ebbb2f6d993d27872a43
|
||||
F ext/session/sessiondiff.test ad13dd65664bae26744e1f18eb3cbd5588349b7e9118851d8f9364248d67bcec
|
||||
F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7
|
||||
F ext/session/sessionfault2.test dd593f80b6b4786f7adfe83c5939620bc505559770cc181332da26f29cddd7bb
|
||||
@@ -456,8 +457,8 @@ F ext/session/sessionrebase.test ccfa716b23bd1d3b03217ee58cfd90c78d4b99f53e6a9a2
|
||||
F ext/session/sessionsize.test 6f644aff31c7f1e4871e9ff3542766e18da68fc7e587b83a347ea9820a002dd8
|
||||
F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5
|
||||
F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc
|
||||
F ext/session/sqlite3session.c 703634ca25b4b903ae8ec25045802a8c8deca36a65d2b993c4bc8888f6d6c7ee
|
||||
F ext/session/sqlite3session.h 874b084ea97252a57ff1b79bb5da172ab4156f6302a8d3e3f5c88ce2748480d8
|
||||
F ext/session/sqlite3session.c af0cb1163e224b286a9cba3c1ad877d927821e6a0e317c29b289a16e5da378a8
|
||||
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 +466,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,29 +478,29 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c e7caf3eefce268250dc1d10322eec637319de486aa1bae7f48c606259455537e
|
||||
F src/alter.c e2e0e6be8a53cc5c145d9ff4f82a2c8d6851468a366ac8b5bd7306c792e37619
|
||||
F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c
|
||||
F src/attach.c a7d1a7df69f053951ec1665e5894c61184fda3f677323762f1c3679ebd27d5c7
|
||||
F src/attach.c a514e81758ba7b3a3a0501faf70af6cfc509de8810235db726cfc9f25165e929
|
||||
F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853
|
||||
F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
|
||||
F src/btree.c c747dca6b20dbc6f4de8aad99ac6deae153a099af95718de366c602bb9121a63
|
||||
F src/btree.c 51ba86095316fceb3e25bc61617d673d84627e79f4ace83f8722910f33eedef3
|
||||
F src/btree.h 096cc53baa58be22b02c896d1cf933c38cfc6d65f9253c1367ece8cc88a24de5
|
||||
F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0
|
||||
F src/build.c 45889a1ac425eb7d60113ce65a519c55c5d5d01f2a9e978ab1467f8653bb57eb
|
||||
F src/build.c daeb1beb04e3729456f095686bc26bb0cde026263fc281257d431ba22c2e7f21
|
||||
F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410
|
||||
F src/ctime.c 3052b6b05ed9ef547a3dd66b8e01bfa9d582e78752ad6ed327da84652641e038
|
||||
F src/date.c e0632f335952b32401482d099321bbf12716b29d6e72836b53ae49683ebae4bf
|
||||
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
|
||||
F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c
|
||||
F src/delete.c 73f57a9a183532c344a3135cf8f2a5589376e39183e0b5f562d6b61b2af0f4d8
|
||||
F src/expr.c 2b79c16f167b7ec74dfbd325b6f9cd9ff026908017f6804a5af6ba451c13b5b1
|
||||
F src/expr.c 09f8ae1421d09802b4ac4b05c507761ecd142fa32cc0b1e33b9bd07fba10d34a
|
||||
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,15 +508,15 @@ 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/malloc.c c1af4ac5a463648cd2953fd4ac679b3ba9022ce5ec794a60806150ad69dfd33a
|
||||
F src/main.c 2b2044221a10e7c5f49a98f50563ce9a944511241ba5946d1754dcc2a7437a07
|
||||
F src/malloc.c cbc93cdd429c4594912017d92ab656e2579aca64dbd1c6888551275bed46f25b
|
||||
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/memjournal.c 431c70a111223a8a6e2e7e9f014afc6c88d818d357d866afc563195f2277d50e
|
||||
F src/memdb.c f6ce717b26cd51a24cda62fce611b4b72b3db367113374aa498e489a69470715
|
||||
F src/memjournal.c a85f0dc5c02a42453d0bc3819ecfb5666cb6433e5deefcd93ccbe05c9f088b83
|
||||
F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8
|
||||
F src/mutex.c 5e3409715552348732e97b9194abe92fdfcd934cfb681df4ba0ab87ac6c18d25
|
||||
F src/mutex.h a7b2293c48db5f27007c3bdb21d438873637d12658f5a0bf8ad025bb96803c4a
|
||||
@@ -527,12 +528,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 8920f4444957d7827ca458029b2e41ffa32dd3b72917be0b52cae0aace3eadb5
|
||||
F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
|
||||
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
|
||||
F src/pcache1.c 388304fd2d91c39591080b5e0f3c62cfba87db20370e7e0554062bfb29740e9f
|
||||
@@ -541,18 +542,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 e299d53c4077fc32bc63741b5b27fdf8a1328cb8e812b9fafb55441c4c73a80a
|
||||
F src/resolve.c 40e216d9a72e52841a9c8e0aec7d367bade8e2df17b804653b539b20c1ab5660
|
||||
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
||||
F src/select.c bc08a79364ad2056b1b3b83142b1cc4eacabf850603166f3a72581d56c320d9c
|
||||
F src/shell.c.in 9320b476fde0f7c46700e5695b69b435f1e46843a1513cdd187ac426cdbee016
|
||||
F src/sqlite.h.in 372554fcd1e1ed25ba44a316e8abdaad712470b7dcfa185ece54f51b10fbde10
|
||||
F src/select.c 2f4429e0b0ca031e360489c45dca5dfa06cd85480e12c0d1360b91e1c8e7f7a2
|
||||
F src/shell.c.in 2a2b06d463933ee3a5bb0242d5d2200ca36769493fd6f4d939a0574113f3d6d8
|
||||
F src/sqlite.h.in 5c950066775ca9efdaa49077c05d38d0bef6418f3bd07d2dce0210f1d2f3c326
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e
|
||||
F src/sqliteInt.h 234ab17b1797cbc2adb7741a15786edf72bc96d40b4de68795e91926cfd46eba
|
||||
F src/sqliteInt.h 6d0c49ed218f9f6ffabfdc8bed1a5de89f61e70c96a62156aeebeb20c1be9bf0
|
||||
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 +561,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 +569,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
|
||||
@@ -607,34 +608,34 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9
|
||||
F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c 0b9c82fa628b5adce93e2bcaf935a24d43eb83344fb51551f7835526d0693fc4
|
||||
F src/treeview.c e483aeedf6f207000db1f90eb6abd816350493314c30e8749d319bdb9ab3b08c
|
||||
F src/trigger.c f8493674f5c8f103c1a2cd0616af9dca85c7058450f9fe47cacd15cf5d512d52
|
||||
F src/update.c b3abdaf4a314bbed238da69a6ca54c0f21262119389b412ee5778fffe62dd3cc
|
||||
F src/tokenize.c bae853ad129d1129c063de8630a3e99e306283bc40146f359b1bb91be2c08f1e
|
||||
F src/treeview.c 21449a944d5abd3ac07b7eab76f7221e20c9480d06f01798f8dc66d9bc361769
|
||||
F src/trigger.c e0fd347b2571a2d956318cdc6d011ccca7ce862d10a0ca04188a37920ef5440c
|
||||
F src/update.c 56fa0458b1ffc1042629f926443e8ed44203983df3ab2b0db2ba556e6ceed68c
|
||||
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 73e5a8b64a77359f4287d76f168e89d12ba967cbb72a3d7619650568e9c1d66c
|
||||
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 032a0165c147fda16927e6a3230e90c068d4af93f887ce94e26f678fe48e5e4c
|
||||
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 1c305bab0996a63219a6cb3d4718587f3a5dc5608120c4448985aa2bef88b7f5
|
||||
F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4
|
||||
F src/wherecode.c b4f24544fbaf5ecf0d060d9581e14df7c0de51b5e6c37af5b98048a9ba551b72
|
||||
F src/whereexpr.c d8cafcf6781cf871082f04d7540862cf0fe30cb381dd1b2145a380376364fe8e
|
||||
F src/window.c ae9fbd0cbaa39e1b384c13289ed769f9981383bde7b2f262c70ad6c42e5ab226
|
||||
F src/walker.c 7342becedf3f8a26f9817f08436bdf8b56ad69af83705f6b9320a0ad3092c2ac
|
||||
F src/where.c 32f41c3c93c6785e0077e3a2cdc669c3ccfe70173787847be77f294c18fc7dc3
|
||||
F src/whereInt.h 9248161dd004f625ce5d3841ca9b99fed3fc8d61522cf76340fc5217dbe1375b
|
||||
F src/wherecode.c bcfee3789a7d3da1f3f8a76c1b20c95d6c0fc4ea93c5d9b03206a432ac8b1cc4
|
||||
F src/whereexpr.c 5a9c9f5d2dac4bcdcaae3035034b4667523f731df228e0bb1d4efc669efa9da5
|
||||
F src/window.c a6d624d83b2d5b3cfb82bb437a2fbae759c928d47dc9ad1338a9419269181bb2
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
|
||||
F test/affinity3.test eecb0dabee4b7765a8465439d5e99429279ffba23ca74a7eae270a452799f9e7
|
||||
@@ -645,7 +646,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 +658,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 d15362de3d487368e1f64d600fdfc1976033aecf8394c0a88454a5c63b357209
|
||||
F test/altertab.test c7966d92e4da535050b911e1e9972ecb3a5befb0b2d22026b132cf5003d43dec
|
||||
F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b
|
||||
F test/altertab3.test 2b82fa2236a3a91553d53ae5555d8e723c7eec174c41f1fa62ff497355398479
|
||||
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
|
||||
@@ -782,7 +783,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 +802,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 352c8f006b46130c27c06d4894c0919123308440473d699ec796b9c04f828ad8
|
||||
F test/corruptN.test f56e3417fe9a444efd765ae55acbe65595d7b8f747785fe0fd785dbdc424932a
|
||||
F test/cost.test b11cdbf9f11ffe8ef99c9881bf390e61fe92baf2182bad1dbe6de59a7295c576
|
||||
F test/count.test 5364003488249957750a5f15ee42ca1cd7b100b1131c2dc71fff266a1250bf55
|
||||
F test/countofview.test e17d6e6688cf74f22783c9ec6e788c0790ee4fbbaee713affd00b1ac0bb39b86
|
||||
@@ -829,7 +830,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 +885,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 +1048,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 74a457891ba166e7f4121eaaae81f4dbceb053b65ddee47db3eccd2ba59cd67d
|
||||
F test/fuzzcheck.c 37f09efcd982048694d8b06fa3ef817df17f2a82e90af85cb3fb8eddd0f57ec4
|
||||
F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f
|
||||
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
|
||||
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||
@@ -1057,7 +1056,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 a5f04edee03f0446759272e976f7e68568201077b8adf5c769f5b2a8ddc3e10d
|
||||
F test/fuzzdata8.db 29ca3c47821abb626309e0d182b0f00ad3b49638370daee855641b9abc36dfa2
|
||||
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
|
||||
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
|
||||
F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc
|
||||
@@ -1077,7 +1076,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
|
||||
@@ -1192,6 +1191,7 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
|
||||
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
|
||||
F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7
|
||||
F test/memdb1.test 7b76c3262d63c46dd6b408d18f5721071776f2df4ffeb11e668824e427127594
|
||||
F test/memjournal.test 70f3a00c7f84ee2978ad14e831231caa1e7f23915a2c54b4f775a021d5740c6c
|
||||
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
|
||||
F test/memsubsys1.test 9e7555a22173b8f1c96c281ce289b338fcba2abe8b157f8798ca195bbf1d347e
|
||||
F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08
|
||||
@@ -1239,7 +1239,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
|
||||
@@ -1267,7 +1267,7 @@ F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035c
|
||||
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
F test/permutations.test 9bb03106a024e9938d329a33380ea7fd91b6e45516881db68663505c444b3242
|
||||
F test/permutations.test 63da39a4234eed2ccd10bf7872de58e24d53a50d11014dc8a8ab9f252368e880
|
||||
F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f
|
||||
F test/pragma.test 50b91bedea9324d3ab48e793f908ee7d2c7dcf84bfa2281e792838be59641ec8
|
||||
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
|
||||
@@ -1295,11 +1295,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
|
||||
@@ -1315,7 +1315,7 @@ F test/rowvalue5.test c81c7d8cf36711ab37675ad7376084ae2a359cb6
|
||||
F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087
|
||||
F test/rowvalue7.test c1cbdbf407029db01f87764097c6ac02a1c5a37efd2776eff32a9cdfdf6f2dba
|
||||
F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0
|
||||
F test/rowvalue9.test d8dd2c6ecac432dadaa79e41dc2434f007be1b6b
|
||||
F test/rowvalue9.test cb5380df82dca9db463081e26952c1e097b34fc2c2ac87453970c048d97df687
|
||||
F test/rowvaluefault.test 7cd9ccc6c2fbdd881672984087aad0491bb75504
|
||||
F test/rowvaluevtab.test cd9747bb3f308086944c07968f547ad6b05022e698d80b9ffbdfe09ce0b8da6f
|
||||
F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798
|
||||
@@ -1341,7 +1341,7 @@ F test/select1.test 3d23f66bf9ba77570acfe2ca5f1540ece17037cc64ab1a00efec9758ac29
|
||||
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
|
||||
F test/select3.test c49fbb758903f3718e2de5aa4655eda4838131cbea24a86db908f8b6889aa68c
|
||||
F test/select4.test f0684d3da3bccacbe2a1ebadf6fb49d9df6f53acb4c6ebc228a88d0d6054cc7b
|
||||
F test/select5.test df9ec0d218cedceb4fe7b63262025b547b50a55e59148c6f40b60ca25f1d4546
|
||||
F test/select5.test 8afc5e5dcdebc2be54472e73ebd9cd1adef1225fd15d37a1c62f969159f390ae
|
||||
F test/select6.test 319d45e414cdd321bf17cfacedaf19e3935ad64dac357c53f1492338c6e9b801
|
||||
F test/select7.test f659f231489349e8c5734e610803d7654207318f
|
||||
F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d
|
||||
@@ -1440,7 +1440,7 @@ F test/sync.test 89539f4973c010eda5638407e71ca7fddbcd8e0594f4c9980229f804d433309
|
||||
F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef2039
|
||||
F test/syscall.test a39d9a36f852ae6e4800f861bc2f2e83f68bbc2112d9399931ecfadeabd2d69d
|
||||
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
|
||||
F test/tabfunc01.test 5ca6d004157a3e886a55a9387b960cc0db41acd88753eb597ff409ec6cfb1be0
|
||||
F test/tabfunc01.test acb5be558868c65d8cf3495539fff23093d77139eb1e4e8c4580568099f98645
|
||||
F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132
|
||||
F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4
|
||||
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
||||
@@ -1465,6 +1465,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 +1618,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
|
||||
@@ -1645,7 +1646,7 @@ F test/tt3_vacuum.c 1753f45917699c9c1f66b64c717a717c9379f776
|
||||
F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
|
||||
F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac
|
||||
F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a
|
||||
F test/unionall.test 369dac51f4e7b94442b054d3d7f2e6755cd6994274718228878e3bd47c425f6d
|
||||
F test/unionall.test fee6e6adebe5446938475432ae8b042835a286c7e2efdc1b186d2182dfb93ffb
|
||||
F test/unionall2.test 71e8fa08d5699d50dc9f9dc0c9799c2e7a6bb7931a330d369307a4df7f157fa1
|
||||
F test/unionallfault.test 652bfbb630e6c43135965dc1e8f0a9a791da83aec885d626a632fe1909c56f73
|
||||
F test/unionvtab.test e1704ab1b4c1bb3ffc9da4681f8e85a0b909fd80b937984fc94b27415ac8e5a4
|
||||
@@ -1657,7 +1658,7 @@ F test/unordered.test 0edaf3411d300693bca595897c5201421c6c5ec787990a1dfe2f7f60ae
|
||||
F test/update.test e906ca7cb1dc6f52af1ea243e08f727edfa79f924c2691f2f9e72481f847310d
|
||||
F test/update2.test 67455bc61fcbcf96923c45b3bc4f87bc72be7d67575ad35f134906148c7b06d3
|
||||
F test/upfrom1.tcl 8859d9d437f03b44174c4524a7a734a391fd4526fcff65be08285dafc9dc9041
|
||||
F test/upfrom1.test d18f69f7c691bc791e7f31bf0e354eeff04cf2f44edc32d6b1928bad71697073
|
||||
F test/upfrom1.test 8cb06689e99cd707d884faa16da0e8eb26ff658bb01c47ddf72fadade666e6e1
|
||||
F test/upfrom2.test f92e47bfc35e9410d3e8716ee626384e89ad026c55fd6148508ca9d707521673
|
||||
F test/upfrom3.test 6130f24ebf97f5ea865e5d2a14a2d543fe5428a62e87cc60f62d875e45c1f5f0
|
||||
F test/upfromfault.test 3a10075a0043f0c4fad6614b2c371f88a8ba5a4acab68b907438413865d6a8d6
|
||||
@@ -1682,7 +1683,8 @@ 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/view2.test db32c8138b5b556f610b35dfddd38c5a58a292f07fda5281eedb0851b2672679
|
||||
F test/vtab1.test 99c0c13b5336ca7f87f137459de144b2f396bb8563fbd602e46bfaa425e3d8cc
|
||||
F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082
|
||||
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
|
||||
F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3
|
||||
@@ -1750,7 +1752,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 +1764,8 @@ 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/whereM.test 0dbc9998783458ddcf3cc078ca7c2951d8b2677d472ecf0028f449ed327c0250
|
||||
F test/wherefault.test 6cf2a9c5712952d463d3f45ebee7f6caf400984df51a195d884cfb7eb0e837a7
|
||||
F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3
|
||||
F test/wherelimit.test afb46397c6d7e964e6e294ba3569864a0c570fe3807afc634236c2b752372f31
|
||||
@@ -1771,7 +1774,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 49eadb28b0bae0f916518c9983b1fb7450c198915664f323b2bfc480cc98c431
|
||||
F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476
|
||||
F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c
|
||||
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
|
||||
@@ -1782,8 +1785,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
|
||||
@@ -1791,14 +1794,14 @@ F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387
|
||||
F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b
|
||||
F test/windowfault.test 21919e601f20b976ea2a73aa401220c89ed0e8d203c4f69476ea55bce3726496
|
||||
F test/windowpushd.test d8895d08870b7226f7693665bd292eb177e62ca06799184957b3ca7dc03067df
|
||||
F test/with1.test b231edbf0f7c1d94bc14365cd9f33e197b2f0aa16add927ee121649fce014c15
|
||||
F test/with2.test 000fb95f1f29dae868cea0f41505eb5126077d49eb967ff88f9ee46212ad8863
|
||||
F test/with1.test 7bc5abfe4c80c0cef8a90f5a66d60b9982e8ccd7350c8eb70611323a3b8e07ba
|
||||
F test/with2.test bbf82609bbacc0a7a01d822022aed7b2fa702436dd3d0ecf942023564d2bba13
|
||||
F test/with3.test ad32d13ad50661e6fa305f62a0717649c348792e7b658bf2644976227a9e0373
|
||||
F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
|
||||
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
|
||||
@@ -1809,7 +1812,7 @@ F test/wordcount.c d721a4b6fae93e6e33449700bce1686bc23257c27425bc3ef1599dc912ade
|
||||
F test/writecrash.test f1da7f7adfe8d7f09ea79b42e5ca6dcc41102f27f8e334ad71539501ddd910cc
|
||||
F test/zeroblob.test 07a5b11ab591d1f26c626945fb7f228f68b993533b2ada77273edf6ee29db174
|
||||
F test/zerodamage.test 9c41628db7e8d9e8a0181e59ea5f189df311a9f6ce99cc376dc461f66db6f8dc
|
||||
F test/zipfile.test 429cb81c518487fa1b644b6b04b6e9af704a4fa767bd1a110204c5f03b2e8616
|
||||
F test/zipfile.test 0d8758d8c0d63f16644f959689f78969d223789d998964276554039f067b4548
|
||||
F test/zipfile2.test 9903388a602a3834189857a985106ff95c3bba6a3969e0134127df991889db5d
|
||||
F test/zipfilefault.test 44d4d7a7f7cca7521d569d7f71026b241d65a6b1757aa409c1a168827edbbc2c
|
||||
F tool/GetFile.cs 47852aa0d806fe47ed1ac5138bdce7f000fe87aaa7f28107d0cb1e26682aeb44
|
||||
@@ -1839,13 +1842,14 @@ F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
|
||||
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
||||
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
|
||||
F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
|
||||
F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176
|
||||
F tool/mkautoconfamal.sh f62353eb6c06ab264da027fd4507d09914433dbdcab9cb011cdc18016f1ab3b8
|
||||
F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x
|
||||
F tool/mkctimec.tcl dd183b73ae1c28249669741c250525f0407e579a70482371668fd5f130d9feb3
|
||||
F tool/mkctimec.tcl 06b0d503ee0e6c2d4abe83563b43d4925a12e31ec9fb3249ce39661f53fbd1ce
|
||||
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,14 +1861,14 @@ 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
|
||||
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
|
||||
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
|
||||
F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076
|
||||
F tool/showdb.c 49e810f5c414c792b5bf38cd5557ca9639713ebfef32aaff32faf7cb7ccce513
|
||||
F tool/showdb.c 8c6b1cbb86ee25ca2173497183f8fcd444d4e26923e4cf57ddabe66c633b4dab
|
||||
F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818
|
||||
F tool/showlocks.c 9cc5e66d4ebbf2d194f39db2527ece92077e86ae627ddd233ee48e16e8142564
|
||||
F tool/showshm.c a0ab6ec32dd1f11218ca2a4018f8fb875b59414801ab8ceed8b2e69b7b45a809
|
||||
@@ -1914,7 +1918,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P b5564a6fd54875db1de884fdc0e5eeabcd6aa5595ad03a8a60843503e830a2d8
|
||||
R fa53b8d1cc3def8dc3ef8249968de9f0
|
||||
U dan
|
||||
Z 5eb2943cb766ada953003dbe5c9f5486
|
||||
P c9f0b9cb0aef107265435e22c164dd3c974eadfd00abf7cfd4fc7ec95c0dd7d0
|
||||
R c044497982752ba303617f7de106b59c
|
||||
T *branch * copy-optimization
|
||||
T *sym-copy-optimization *
|
||||
T -sym-trunk *
|
||||
U drh
|
||||
Z 0c06d6f1ffda88b03d3d1e66ad233058
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
4d5fd2151e024d11289b6c4fbce2996d8d07b2b5a1c953ef895c237e79d3aa55
|
||||
4488cb883e155a7466946d25569ab2816c4a8de9d4c7d540f5053ea5334e7ae5
|
||||
+6
-3
@@ -29,8 +29,9 @@
|
||||
** Or, if zName is not a system table, zero is returned.
|
||||
*/
|
||||
static int isAlterableTable(Parse *pParse, Table *pTab){
|
||||
if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7)
|
||||
if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7)
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
|| (pTab->tabFlags & TF_Eponymous)!=0
|
||||
|| ( (pTab->tabFlags & TF_Shadow)!=0
|
||||
&& sqlite3ReadOnlyShadowTables(pParse->db)
|
||||
)
|
||||
@@ -834,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++){
|
||||
@@ -918,7 +919,9 @@ static RenameToken *renameTokenFind(
|
||||
void *pPtr
|
||||
){
|
||||
RenameToken **pp;
|
||||
assert( pPtr!=0 );
|
||||
if( pPtr==0 ){
|
||||
return 0;
|
||||
}
|
||||
for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){
|
||||
if( (*pp)->p==pPtr ){
|
||||
RenameToken *pToken = *pp;
|
||||
|
||||
+11
-8
@@ -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)
|
||||
@@ -464,14 +464,17 @@ static int fixSelectCb(Walker *p, Select *pSelect){
|
||||
if( NEVER(pList==0) ) return WRC_Continue;
|
||||
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
|
||||
if( pFix->bTemp==0 ){
|
||||
if( pItem->zDatabase && iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){
|
||||
sqlite3ErrorMsg(pFix->pParse,
|
||||
"%s %T cannot reference objects in database %s",
|
||||
pFix->zType, pFix->pName, pItem->zDatabase);
|
||||
return WRC_Abort;
|
||||
if( pItem->zDatabase ){
|
||||
if( iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){
|
||||
sqlite3ErrorMsg(pFix->pParse,
|
||||
"%s %T cannot reference objects in database %s",
|
||||
pFix->zType, pFix->pName, pItem->zDatabase);
|
||||
return WRC_Abort;
|
||||
}
|
||||
sqlite3DbFree(db, pItem->zDatabase);
|
||||
pItem->zDatabase = 0;
|
||||
pItem->fg.notCte = 1;
|
||||
}
|
||||
sqlite3DbFree(db, pItem->zDatabase);
|
||||
pItem->zDatabase = 0;
|
||||
pItem->pSchema = pFix->pSchema;
|
||||
pItem->fg.fromDDL = 1;
|
||||
}
|
||||
|
||||
+42
-17
@@ -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
|
||||
@@ -7028,7 +7039,7 @@ static int rebuildPage(
|
||||
put2byte(pCellptr, (pData - aData));
|
||||
pCellptr += 2;
|
||||
if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT;
|
||||
memcpy(pData, pCell, sz);
|
||||
memmove(pData, pCell, sz);
|
||||
assert( sz==pPg->xCellSize(pPg, pCell) || CORRUPT_DB );
|
||||
i++;
|
||||
if( i>=iEnd ) break;
|
||||
@@ -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
|
||||
@@ -9114,7 +9136,8 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
|
||||
assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
|
||||
if( pCur->eState==CURSOR_REQUIRESEEK ){
|
||||
rc = btreeRestoreCursorPosition(pCur);
|
||||
if( rc ) return rc;
|
||||
assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID );
|
||||
if( rc || pCur->eState!=CURSOR_VALID ) return rc;
|
||||
}
|
||||
assert( CORRUPT_DB || pCur->eState==CURSOR_VALID );
|
||||
|
||||
@@ -9169,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);
|
||||
}
|
||||
|
||||
@@ -9178,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;
|
||||
|
||||
@@ -9465,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 ){
|
||||
@@ -9513,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);
|
||||
|
||||
+39
-6
@@ -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
|
||||
@@ -438,7 +447,7 @@ Table *sqlite3LocateTable(
|
||||
/* If zName is the not the name of a table in the schema created using
|
||||
** CREATE, then check to see if it is the name of an virtual table that
|
||||
** can be an eponymous virtual table. */
|
||||
if( pParse->disableVtab==0 ){
|
||||
if( pParse->disableVtab==0 && db->init.busy==0 ){
|
||||
Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
|
||||
if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
|
||||
pMod = sqlite3PragmaVtabRegister(db, zName);
|
||||
@@ -1048,6 +1057,23 @@ 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);
|
||||
sqlite3VdbeUsesBtree(v, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Begin constructing a new table representation in memory. This is
|
||||
** the first of several action routines that get called in response
|
||||
@@ -1147,6 +1173,7 @@ void sqlite3StartTable(
|
||||
}else{
|
||||
assert( !db->init.busy || CORRUPT_DB );
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
sqlite3ForceNotReadOnly(pParse);
|
||||
}
|
||||
goto begin_table_error;
|
||||
}
|
||||
@@ -1323,6 +1350,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 +3224,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 +3797,7 @@ void sqlite3CreateIndex(
|
||||
}else{
|
||||
assert( !db->init.busy );
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
sqlite3ForceNotReadOnly(pParse);
|
||||
}
|
||||
goto exit_create_index;
|
||||
}
|
||||
@@ -4246,7 +4278,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 +4316,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;
|
||||
|
||||
+41
-22
@@ -58,8 +58,10 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_64BIT_STATS
|
||||
"64BIT_STATS",
|
||||
#endif
|
||||
#if SQLITE_ALLOW_COVERING_INDEX_SCAN
|
||||
"ALLOW_COVERING_INDEX_SCAN",
|
||||
#ifdef SQLITE_ALLOW_COVERING_INDEX_SCAN
|
||||
# if SQLITE_ALLOW_COVERING_INDEX_SCAN != 1
|
||||
"ALLOW_COVERING_INDEX_SCAN=" CTIMEOPT_VAL(SQLITE_ALLOW_COVERING_INDEX_SCAN),
|
||||
# endif
|
||||
#endif
|
||||
#if SQLITE_ALLOW_URI_AUTHORITY
|
||||
"ALLOW_URI_AUTHORITY",
|
||||
@@ -121,8 +123,10 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#ifdef SQLITE_DEFAULT_LOOKASIDE
|
||||
"DEFAULT_LOOKASIDE=" CTIMEOPT_VAL2(SQLITE_DEFAULT_LOOKASIDE),
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_MEMSTATUS
|
||||
"DEFAULT_MEMSTATUS",
|
||||
#ifdef SQLITE_DEFAULT_MEMSTATUS
|
||||
# if SQLITE_DEFAULT_MEMSTATUS != 1
|
||||
"DEFAULT_MEMSTATUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_MEMSTATUS),
|
||||
# endif
|
||||
#endif
|
||||
#ifdef SQLITE_DEFAULT_MMAP_SIZE
|
||||
"DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
|
||||
@@ -196,7 +200,7 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_ENABLE_BYTECODE_VTAB
|
||||
"ENABLE_BYTECODE_VTAB",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_CEROD
|
||||
#ifdef SQLITE_ENABLE_CEROD
|
||||
"ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD),
|
||||
#endif
|
||||
#if SQLITE_ENABLE_COLUMN_METADATA
|
||||
@@ -211,17 +215,17 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_ENABLE_CURSOR_HINTS
|
||||
"ENABLE_CURSOR_HINTS",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_DBPAGE_VTAB
|
||||
"ENABLE_DBPAGE_VTAB",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_DBSTAT_VTAB
|
||||
"ENABLE_DBSTAT_VTAB",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_EXPENSIVE_ASSERT
|
||||
"ENABLE_EXPENSIVE_ASSERT",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_FTS1
|
||||
"ENABLE_FTS1",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_FTS2
|
||||
"ENABLE_FTS2",
|
||||
#if SQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
"ENABLE_EXPLAIN_COMMENTS",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_FTS3
|
||||
"ENABLE_FTS3",
|
||||
@@ -280,6 +284,9 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_ENABLE_NULL_TRIM
|
||||
"ENABLE_NULL_TRIM",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
"ENABLE_OFFSET_SQL_FUNC",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
|
||||
"ENABLE_OVERSIZE_CELL_CHECK",
|
||||
#endif
|
||||
@@ -310,7 +317,7 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_ENABLE_SQLLOG
|
||||
"ENABLE_SQLLOG",
|
||||
#endif
|
||||
#if defined(SQLITE_ENABLE_STAT4)
|
||||
#if SQLITE_ENABLE_STAT4
|
||||
"ENABLE_STAT4",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_STMTVTAB
|
||||
@@ -364,8 +371,10 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
|
||||
"HAVE_ISNAN",
|
||||
#endif
|
||||
#if SQLITE_HOMEGROWN_RECURSIVE_MUTEX
|
||||
"HOMEGROWN_RECURSIVE_MUTEX",
|
||||
#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
|
||||
# if SQLITE_HOMEGROWN_RECURSIVE_MUTEX != 1
|
||||
"HOMEGROWN_RECURSIVE_MUTEX=" CTIMEOPT_VAL(SQLITE_HOMEGROWN_RECURSIVE_MUTEX),
|
||||
# endif
|
||||
#endif
|
||||
#if SQLITE_IGNORE_AFP_LOCK_ERRORS
|
||||
"IGNORE_AFP_LOCK_ERRORS",
|
||||
@@ -463,9 +472,6 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_MUTEX_NOOP
|
||||
"MUTEX_NOOP",
|
||||
#endif
|
||||
#if SQLITE_MUTEX_NREF
|
||||
"MUTEX_NREF",
|
||||
#endif
|
||||
#if SQLITE_MUTEX_OMIT
|
||||
"MUTEX_OMIT",
|
||||
#endif
|
||||
@@ -535,7 +541,7 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_OMIT_CTE
|
||||
"OMIT_CTE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_DATETIME_FUNCS
|
||||
#if defined(SQLITE_OMIT_DATETIME_FUNCS) || defined(SQLITE_OMIT_FLOATING_POINT)
|
||||
"OMIT_DATETIME_FUNCS",
|
||||
#endif
|
||||
#if SQLITE_OMIT_DECLTYPE
|
||||
@@ -544,6 +550,9 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_OMIT_DEPRECATED
|
||||
"OMIT_DEPRECATED",
|
||||
#endif
|
||||
#if SQLITE_OMIT_DESERIALIZE
|
||||
"OMIT_DESERIALIZE",
|
||||
#endif
|
||||
#if SQLITE_OMIT_DISKIO
|
||||
"OMIT_DISKIO",
|
||||
#endif
|
||||
@@ -571,6 +580,9 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_OMIT_INTEGRITY_CHECK
|
||||
"OMIT_INTEGRITY_CHECK",
|
||||
#endif
|
||||
#if SQLITE_OMIT_INTROSPECTION_PRAGMAS
|
||||
"OMIT_INTROSPECTION_PRAGMAS",
|
||||
#endif
|
||||
#if SQLITE_OMIT_LIKE_OPTIMIZATION
|
||||
"OMIT_LIKE_OPTIMIZATION",
|
||||
#endif
|
||||
@@ -634,8 +646,10 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_OMIT_TEST_CONTROL
|
||||
"OMIT_TEST_CONTROL",
|
||||
#endif
|
||||
#if SQLITE_OMIT_TRACE
|
||||
"OMIT_TRACE",
|
||||
#ifdef SQLITE_OMIT_TRACE
|
||||
# if SQLITE_OMIT_TRACE != 1
|
||||
"OMIT_TRACE=" CTIMEOPT_VAL(SQLITE_OMIT_TRACE),
|
||||
# endif
|
||||
#endif
|
||||
#if SQLITE_OMIT_TRIGGER
|
||||
"OMIT_TRIGGER",
|
||||
@@ -670,8 +684,10 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_PERFORMANCE_TRACE
|
||||
"PERFORMANCE_TRACE",
|
||||
#endif
|
||||
#if SQLITE_POWERSAFE_OVERWRITE
|
||||
"POWERSAFE_OVERWRITE",
|
||||
#ifdef SQLITE_POWERSAFE_OVERWRITE
|
||||
# if SQLITE_POWERSAFE_OVERWRITE != 1
|
||||
"POWERSAFE_OVERWRITE=" CTIMEOPT_VAL(SQLITE_POWERSAFE_OVERWRITE),
|
||||
# endif
|
||||
#endif
|
||||
#if SQLITE_PREFER_PROXY_LOCKING
|
||||
"PREFER_PROXY_LOCKING",
|
||||
@@ -706,7 +722,10 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_SUBSTR_COMPATIBILITY
|
||||
"SUBSTR_COMPATIBILITY",
|
||||
#endif
|
||||
#if SQLITE_SYSTEM_MALLOC
|
||||
#if (!defined(SQLITE_WIN32_MALLOC) \
|
||||
&& !defined(SQLITE_ZERO_MALLOC) \
|
||||
&& !defined(SQLITE_MEMDEBUG) \
|
||||
) || defined(SQLITE_SYSTEM_MALLOC)
|
||||
"SYSTEM_MALLOC",
|
||||
#endif
|
||||
#if SQLITE_TCL
|
||||
|
||||
+51
-45
@@ -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( 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;
|
||||
@@ -456,7 +445,7 @@ int sqlite3ExprVectorSize(Expr *pExpr){
|
||||
** been positioned.
|
||||
*/
|
||||
Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){
|
||||
assert( i<sqlite3ExprVectorSize(pVector) );
|
||||
assert( i<sqlite3ExprVectorSize(pVector) || pVector->op==TK_ERROR );
|
||||
if( sqlite3ExprIsVector(pVector) ){
|
||||
assert( pVector->op2==0 || pVector->op==TK_REGISTER );
|
||||
if( pVector->op==TK_SELECT || pVector->op2==TK_SELECT ){
|
||||
@@ -572,7 +561,7 @@ static int exprVectorRegister(
|
||||
int *pRegFree /* OUT: Temp register to free */
|
||||
){
|
||||
u8 op = pVector->op;
|
||||
assert( op==TK_VECTOR || op==TK_REGISTER || op==TK_SELECT );
|
||||
assert( op==TK_VECTOR || op==TK_REGISTER || op==TK_SELECT || op==TK_ERROR );
|
||||
if( op==TK_REGISTER ){
|
||||
*ppExpr = sqlite3VectorFieldSubexpr(pVector, iField);
|
||||
return pVector->iTable+iField;
|
||||
@@ -581,8 +570,11 @@ static int exprVectorRegister(
|
||||
*ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr;
|
||||
return regSelect+iField;
|
||||
}
|
||||
*ppExpr = pVector->x.pList->a[iField].pExpr;
|
||||
return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree);
|
||||
if( op==TK_VECTOR ){
|
||||
*ppExpr = pVector->x.pList->a[iField].pExpr;
|
||||
return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1324,6 +1316,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
|
||||
if( pzBuffer ){
|
||||
zAlloc = *pzBuffer;
|
||||
staticFlag = EP_Static;
|
||||
assert( zAlloc!=0 );
|
||||
}else{
|
||||
zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags));
|
||||
staticFlag = 0;
|
||||
@@ -1518,7 +1511,8 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
|
||||
){
|
||||
assert( pNewExpr->iColumn==0 || i>0 );
|
||||
if( pNewExpr->iColumn==0 ){
|
||||
assert( pOldExpr->pLeft==pOldExpr->pRight );
|
||||
assert( pOldExpr->pLeft==pOldExpr->pRight
|
||||
|| ExprHasProperty(pOldExpr->pLeft, EP_Subquery) );
|
||||
pPriorSelectCol = pNewExpr->pLeft = pNewExpr->pRight;
|
||||
}else{
|
||||
assert( i>0 );
|
||||
@@ -2356,8 +2350,10 @@ int sqlite3ExprIsInteger(Expr *p, int *pValue){
|
||||
*/
|
||||
int sqlite3ExprCanBeNull(const Expr *p){
|
||||
u8 op;
|
||||
assert( p!=0 );
|
||||
while( p->op==TK_UPLUS || p->op==TK_UMINUS ){
|
||||
p = p->pLeft;
|
||||
assert( p!=0 );
|
||||
}
|
||||
op = p->op;
|
||||
if( op==TK_REGISTER ) op = p->op2;
|
||||
@@ -2989,19 +2985,23 @@ void sqlite3CodeRhsOfIN(
|
||||
/* If the LHS and RHS of the IN operator do not match, that
|
||||
** error will have been caught long before we reach this point. */
|
||||
if( ALWAYS(pEList->nExpr==nVal) ){
|
||||
Select *pCopy;
|
||||
SelectDest dest;
|
||||
int i;
|
||||
int rc;
|
||||
sqlite3SelectDestInit(&dest, SRT_Set, iTab);
|
||||
dest.zAffSdst = exprINAffinity(pParse, pExpr);
|
||||
pSelect->iLimit = 0;
|
||||
testcase( pSelect->selFlags & SF_Distinct );
|
||||
testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
|
||||
if( sqlite3Select(pParse, pSelect, &dest) ){
|
||||
sqlite3DbFree(pParse->db, dest.zAffSdst);
|
||||
pCopy = sqlite3SelectDup(pParse->db, pSelect, 0);
|
||||
rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest);
|
||||
sqlite3SelectDelete(pParse->db, pCopy);
|
||||
sqlite3DbFree(pParse->db, dest.zAffSdst);
|
||||
if( rc ){
|
||||
sqlite3KeyInfoUnref(pKeyInfo);
|
||||
return;
|
||||
}
|
||||
sqlite3DbFree(pParse->db, dest.zAffSdst);
|
||||
}
|
||||
assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
|
||||
assert( pEList!=0 );
|
||||
assert( pEList->nExpr>0 );
|
||||
@@ -3100,12 +3100,30 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
assert( v!=0 );
|
||||
if( pParse->nErr ) return 0;
|
||||
testcase( pExpr->op==TK_EXISTS );
|
||||
testcase( pExpr->op==TK_SELECT );
|
||||
assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
|
||||
assert( ExprHasProperty(pExpr, EP_xIsSelect) );
|
||||
pSel = pExpr->x.pSelect;
|
||||
|
||||
/* If this routine has already been coded, then invoke it as a
|
||||
** subroutine. */
|
||||
if( ExprHasProperty(pExpr, EP_Subrtn) ){
|
||||
ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId));
|
||||
sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
|
||||
pExpr->y.sub.iAddr);
|
||||
return pExpr->iTable;
|
||||
}
|
||||
|
||||
/* Begin coding the subroutine */
|
||||
ExprSetProperty(pExpr, EP_Subrtn);
|
||||
pExpr->y.sub.regReturn = ++pParse->nMem;
|
||||
pExpr->y.sub.iAddr =
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
|
||||
VdbeComment((v, "return address"));
|
||||
|
||||
|
||||
/* The evaluation of the EXISTS/SELECT must be repeated every time it
|
||||
** is encountered if any of the following is true:
|
||||
**
|
||||
@@ -3117,22 +3135,6 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
** save the results, and reuse the same result on subsequent invocations.
|
||||
*/
|
||||
if( !ExprHasProperty(pExpr, EP_VarSelect) ){
|
||||
/* If this routine has already been coded, then invoke it as a
|
||||
** subroutine. */
|
||||
if( ExprHasProperty(pExpr, EP_Subrtn) ){
|
||||
ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId));
|
||||
sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
|
||||
pExpr->y.sub.iAddr);
|
||||
return pExpr->iTable;
|
||||
}
|
||||
|
||||
/* Begin coding the subroutine */
|
||||
ExprSetProperty(pExpr, EP_Subrtn);
|
||||
pExpr->y.sub.regReturn = ++pParse->nMem;
|
||||
pExpr->y.sub.iAddr =
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
|
||||
VdbeComment((v, "return address"));
|
||||
|
||||
addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
|
||||
}
|
||||
|
||||
@@ -3181,19 +3183,22 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
}
|
||||
pSel->iLimit = 0;
|
||||
if( sqlite3Select(pParse, pSel, &dest) ){
|
||||
if( pParse->nErr ){
|
||||
pExpr->op2 = pExpr->op;
|
||||
pExpr->op = TK_ERROR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
pExpr->iTable = rReg = dest.iSDParm;
|
||||
ExprSetVVAProperty(pExpr, EP_NoReduce);
|
||||
if( addrOnce ){
|
||||
sqlite3VdbeJumpHere(v, addrOnce);
|
||||
|
||||
/* Subroutine return */
|
||||
sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
|
||||
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
|
||||
sqlite3ClearTempRegCache(pParse);
|
||||
}
|
||||
|
||||
/* Subroutine return */
|
||||
sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
|
||||
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
|
||||
sqlite3ClearTempRegCache(pParse);
|
||||
return rReg;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_SUBQUERY */
|
||||
@@ -3207,7 +3212,7 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
*/
|
||||
int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){
|
||||
int nVector = sqlite3ExprVectorSize(pIn->pLeft);
|
||||
if( (pIn->flags & EP_xIsSelect) ){
|
||||
if( (pIn->flags & EP_xIsSelect)!=0 && !pParse->db->mallocFailed ){
|
||||
if( nVector!=pIn->x.pSelect->pEList->nExpr ){
|
||||
sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector);
|
||||
return 1;
|
||||
@@ -4024,7 +4029,7 @@ expr_code_doover:
|
||||
** Expr node to be passed into this function, it will be handled
|
||||
** sanely and not crash. But keep the assert() to bring the problem
|
||||
** to the attention of the developers. */
|
||||
assert( op==TK_NULL || pParse->db->mallocFailed );
|
||||
assert( op==TK_NULL || op==TK_ERROR || pParse->db->mallocFailed );
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
|
||||
return target;
|
||||
}
|
||||
@@ -4367,7 +4372,8 @@ expr_code_doover:
|
||||
if( pExpr->pLeft->iTable==0 ){
|
||||
pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft);
|
||||
}
|
||||
assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT );
|
||||
assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT
|
||||
|| pExpr->pLeft->op==TK_ERROR );
|
||||
if( pExpr->iTable!=0
|
||||
&& pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft))
|
||||
){
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+7
-3
@@ -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);
|
||||
|
||||
@@ -161,7 +161,6 @@ int sqlite3MallocInit(void){
|
||||
if( sqlite3GlobalConfig.m.xMalloc==0 ){
|
||||
sqlite3MemSetDefault();
|
||||
}
|
||||
memset(&mem0, 0, sizeof(mem0));
|
||||
mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
|
||||
if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512
|
||||
|| sqlite3GlobalConfig.nPage<=0 ){
|
||||
|
||||
+292
-53
@@ -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 */
|
||||
|
||||
+20
-18
@@ -257,26 +257,28 @@ static int memjrnlWrite(
|
||||
*/
|
||||
static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
|
||||
MemJournal *p = (MemJournal *)pJfd;
|
||||
FileChunk *pIter = 0;
|
||||
assert( p->endpoint.pChunk==0 || p->endpoint.pChunk->pNext==0 );
|
||||
if( size<p->endpoint.iOffset ){
|
||||
FileChunk *pIter = 0;
|
||||
if( size==0 ){
|
||||
memjrnlFreeChunks(p->pFirst);
|
||||
p->pFirst = 0;
|
||||
}else{
|
||||
i64 iOff = p->nChunkSize;
|
||||
for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){
|
||||
iOff += p->nChunkSize;
|
||||
}
|
||||
if( ALWAYS(pIter) ){
|
||||
memjrnlFreeChunks(pIter->pNext);
|
||||
pIter->pNext = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( size==0 ){
|
||||
memjrnlFreeChunks(p->pFirst);
|
||||
p->pFirst = 0;
|
||||
}else{
|
||||
i64 iOff = p->nChunkSize;
|
||||
for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){
|
||||
iOff += p->nChunkSize;
|
||||
}
|
||||
if( ALWAYS(pIter) ){
|
||||
memjrnlFreeChunks(pIter->pNext);
|
||||
pIter->pNext = 0;
|
||||
}
|
||||
p->endpoint.pChunk = pIter;
|
||||
p->endpoint.iOffset = size;
|
||||
p->readpoint.pChunk = 0;
|
||||
p->readpoint.iOffset = 0;
|
||||
}
|
||||
|
||||
p->endpoint.pChunk = pIter;
|
||||
p->endpoint.iOffset = size;
|
||||
p->readpoint.pChunk = 0;
|
||||
p->readpoint.iOffset = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
+2
-1
@@ -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). {
|
||||
@@ -1855,6 +1855,7 @@ filter_clause(A) ::= FILTER LP WHERE expr(X) RP. { A = X; }
|
||||
IF_NULL_ROW /* the if-null-row operator */
|
||||
ASTERISK /* The "*" in count(*) and similar */
|
||||
SPAN /* The span operator */
|
||||
ERROR /* An expression containing an error */
|
||||
.
|
||||
/* There must be no more than 255 tokens defined above. If this grammar
|
||||
** is extended with new rules and tokens, they must either be so few in
|
||||
|
||||
+18
-17
@@ -81,7 +81,10 @@ static void resolveAlias(
|
||||
assert( pOrig!=0 );
|
||||
db = pParse->db;
|
||||
pDup = sqlite3ExprDup(db, pOrig, 0);
|
||||
if( pDup!=0 ){
|
||||
if( db->mallocFailed ){
|
||||
sqlite3ExprDelete(db, pDup);
|
||||
pDup = 0;
|
||||
}else{
|
||||
incrAggFunctionDepth(pDup, nSubquery);
|
||||
if( pExpr->op==TK_COLLATE ){
|
||||
pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
|
||||
@@ -103,10 +106,8 @@ static void resolveAlias(
|
||||
pExpr->flags |= EP_MemToken;
|
||||
}
|
||||
if( ExprHasProperty(pExpr, EP_WinFunc) ){
|
||||
if( pExpr->y.pWin!=0 ){
|
||||
if( ALWAYS(pExpr->y.pWin!=0) ){
|
||||
pExpr->y.pWin->pOwner = pExpr;
|
||||
}else{
|
||||
assert( db->mallocFailed );
|
||||
}
|
||||
}
|
||||
sqlite3DbFree(db, pDup);
|
||||
@@ -1714,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
|
||||
*/
|
||||
@@ -1770,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 ){
|
||||
|
||||
+121
-37
@@ -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;
|
||||
@@ -3767,7 +3773,10 @@ static void srclistRenumberCursors(
|
||||
for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){
|
||||
if( i!=iExcept ){
|
||||
Select *p;
|
||||
pItem->iCursor = aCsrMap[pItem->iCursor] = pParse->nTab++;
|
||||
if( !pItem->fg.isRecursive || aCsrMap[pItem->iCursor]==0 ){
|
||||
aCsrMap[pItem->iCursor] = pParse->nTab++;
|
||||
}
|
||||
pItem->iCursor = aCsrMap[pItem->iCursor];
|
||||
for(p=pItem->pSelect; p; p=p->pPrior){
|
||||
srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1);
|
||||
}
|
||||
@@ -4408,6 +4417,7 @@ struct WhereConst {
|
||||
Parse *pParse; /* Parsing context */
|
||||
int nConst; /* Number for COLUMN=CONSTANT terms */
|
||||
int nChng; /* Number of times a constant is propagated */
|
||||
int bHasAffBlob; /* At least one column in apExpr[] as affinity BLOB */
|
||||
Expr **apExpr; /* [i*2] is COLUMN and [i*2+1] is VALUE */
|
||||
};
|
||||
|
||||
@@ -4446,6 +4456,9 @@ static void constInsert(
|
||||
return; /* Already present. Return without doing anything. */
|
||||
}
|
||||
}
|
||||
if( sqlite3ExprAffinity(pColumn)==SQLITE_AFF_BLOB ){
|
||||
pConst->bHasAffBlob = 1;
|
||||
}
|
||||
|
||||
pConst->nConst++;
|
||||
pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr,
|
||||
@@ -4466,7 +4479,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);
|
||||
@@ -4487,26 +4500,34 @@ static void findConstInWhere(WhereConst *pConst, Expr *pExpr){
|
||||
}
|
||||
|
||||
/*
|
||||
** This is a Walker expression callback. pExpr is a candidate expression
|
||||
** to be replaced by a value. If pExpr is equivalent to one of the
|
||||
** columns named in pWalker->u.pConst, then overwrite it with its
|
||||
** corresponding value.
|
||||
** This is a helper function for Walker callback propagateConstantExprRewrite().
|
||||
**
|
||||
** Argument pExpr is a candidate expression to be replaced by a value. If
|
||||
** pExpr is equivalent to one of the columns named in pWalker->u.pConst,
|
||||
** then overwrite it with the corresponding value. Except, do not do so
|
||||
** if argument bIgnoreAffBlob is non-zero and the affinity of pExpr
|
||||
** is SQLITE_AFF_BLOB.
|
||||
*/
|
||||
static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){
|
||||
static int propagateConstantExprRewriteOne(
|
||||
WhereConst *pConst,
|
||||
Expr *pExpr,
|
||||
int bIgnoreAffBlob
|
||||
){
|
||||
int i;
|
||||
WhereConst *pConst;
|
||||
if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
|
||||
if( ExprHasProperty(pExpr, EP_FixedCol|EP_FromJoin) ){
|
||||
testcase( ExprHasProperty(pExpr, EP_FixedCol) );
|
||||
testcase( ExprHasProperty(pExpr, EP_FromJoin) );
|
||||
return WRC_Continue;
|
||||
}
|
||||
pConst = pWalker->u.pConst;
|
||||
for(i=0; i<pConst->nConst; i++){
|
||||
Expr *pColumn = pConst->apExpr[i*2];
|
||||
if( pColumn==pExpr ) continue;
|
||||
if( pColumn->iTable!=pExpr->iTable ) continue;
|
||||
if( pColumn->iColumn!=pExpr->iColumn ) continue;
|
||||
if( bIgnoreAffBlob && sqlite3ExprAffinity(pColumn)==SQLITE_AFF_BLOB ){
|
||||
break;
|
||||
}
|
||||
/* A match is found. Add the EP_FixedCol property */
|
||||
pConst->nChng++;
|
||||
ExprClearProperty(pExpr, EP_Leaf);
|
||||
@@ -4518,6 +4539,41 @@ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){
|
||||
return WRC_Prune;
|
||||
}
|
||||
|
||||
/*
|
||||
** This is a Walker expression callback. pExpr is a node from the WHERE
|
||||
** clause of a SELECT statement. This function examines pExpr to see if
|
||||
** any substitutions based on the contents of pWalker->u.pConst should
|
||||
** be made to pExpr or its immediate children.
|
||||
**
|
||||
** A substitution is made if:
|
||||
**
|
||||
** + pExpr is a column with an affinity other than BLOB that matches
|
||||
** one of the columns in pWalker->u.pConst, or
|
||||
**
|
||||
** + pExpr is a binary comparison operator (=, <=, >=, <, >) that
|
||||
** uses an affinity other than TEXT and one of its immediate
|
||||
** children is a column that matches one of the columns in
|
||||
** pWalker->u.pConst.
|
||||
*/
|
||||
static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){
|
||||
WhereConst *pConst = pWalker->u.pConst;
|
||||
assert( TK_GT==TK_EQ+1 );
|
||||
assert( TK_LE==TK_EQ+2 );
|
||||
assert( TK_LT==TK_EQ+3 );
|
||||
assert( TK_GE==TK_EQ+4 );
|
||||
if( pConst->bHasAffBlob ){
|
||||
if( (pExpr->op>=TK_EQ && pExpr->op<=TK_GE)
|
||||
|| pExpr->op==TK_IS
|
||||
){
|
||||
propagateConstantExprRewriteOne(pConst, pExpr->pLeft, 0);
|
||||
if( sqlite3ExprAffinity(pExpr->pLeft)!=SQLITE_AFF_TEXT ){
|
||||
propagateConstantExprRewriteOne(pConst, pExpr->pRight, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return propagateConstantExprRewriteOne(pConst, pExpr, pConst->bHasAffBlob);
|
||||
}
|
||||
|
||||
/*
|
||||
** The WHERE-clause constant propagation optimization.
|
||||
**
|
||||
@@ -4553,6 +4609,21 @@ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){
|
||||
** routines know to generate the constant "123" instead of looking up the
|
||||
** column value. Also, to avoid collation problems, this optimization is
|
||||
** only attempted if the "a=123" term uses the default BINARY collation.
|
||||
**
|
||||
** 2021-05-25 forum post 6a06202608: Another troublesome case is...
|
||||
**
|
||||
** CREATE TABLE t1(x);
|
||||
** INSERT INTO t1 VALUES(10.0);
|
||||
** SELECT 1 FROM t1 WHERE x=10 AND x LIKE 10;
|
||||
**
|
||||
** The query should return no rows, because the t1.x value is '10.0' not '10'
|
||||
** and '10.0' is not LIKE '10'. But if we are not careful, the first WHERE
|
||||
** term "x=10" will cause the second WHERE term to become "10 LIKE 10",
|
||||
** resulting in a false positive. To avoid this, constant propagation for
|
||||
** columns with BLOB affinity is only allowed if the constant is used with
|
||||
** operators ==, <=, <, >=, >, or IS in a way that will cause the correct
|
||||
** type conversions to occur. See logic associated with the bHasAffBlob flag
|
||||
** for details.
|
||||
*/
|
||||
static int propagateConstants(
|
||||
Parse *pParse, /* The parsing context */
|
||||
@@ -4566,6 +4637,7 @@ static int propagateConstants(
|
||||
x.nConst = 0;
|
||||
x.nChng = 0;
|
||||
x.apExpr = 0;
|
||||
x.bHasAffBlob = 0;
|
||||
findConstInWhere(&x, p->pWhere);
|
||||
if( x.nConst ){
|
||||
memset(&w, 0, sizeof(w));
|
||||
@@ -5002,6 +5074,7 @@ static struct Cte *searchWith(
|
||||
return &p->a[i];
|
||||
}
|
||||
}
|
||||
if( p->bView ) break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -5011,16 +5084,18 @@ static struct Cte *searchWith(
|
||||
**
|
||||
** This routine pushes the WITH clause passed as the second argument
|
||||
** onto the top of the stack. If argument bFree is true, then this
|
||||
** WITH clause will never be popped from the stack. In this case it
|
||||
** should be freed along with the Parse object. In other cases, when
|
||||
** WITH clause will never be popped from the stack but should instead
|
||||
** be freed along with the Parse object. In other cases, when
|
||||
** bFree==0, the With object will be freed along with the SELECT
|
||||
** statement with which it is associated.
|
||||
*/
|
||||
void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){
|
||||
if( pWith ){
|
||||
assert( pParse->pWith!=pWith );
|
||||
pWith->pOuter = pParse->pWith;
|
||||
pParse->pWith = pWith;
|
||||
if( pParse->nErr==0 ){
|
||||
assert( pParse->pWith!=pWith );
|
||||
pWith->pOuter = pParse->pWith;
|
||||
pParse->pWith = pWith;
|
||||
}
|
||||
if( bFree ){
|
||||
sqlite3ParserAddCleanup(pParse,
|
||||
(void(*)(sqlite3*,void*))sqlite3WithDelete,
|
||||
@@ -5057,11 +5132,24 @@ static int resolveFromTermToCte(
|
||||
/* There are no WITH clauses in the stack. No match is possible */
|
||||
return 0;
|
||||
}
|
||||
if( pParse->nErr ){
|
||||
/* Prior errors might have left pParse->pWith in a goofy state, so
|
||||
** go no further. */
|
||||
return 0;
|
||||
}
|
||||
if( pFrom->zDatabase!=0 ){
|
||||
/* The FROM term contains a schema qualifier (ex: main.t1) and so
|
||||
** it cannot possibly be a CTE reference. */
|
||||
return 0;
|
||||
}
|
||||
if( pFrom->fg.notCte ){
|
||||
/* The FROM term is specifically excluded from matching a CTE.
|
||||
** (1) It is part of a trigger that used to have zDatabase but had
|
||||
** zDatabase removed by sqlite3FixTriggerStep().
|
||||
** (2) This is the first term in the FROM clause of an UPDATE.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
pCte = searchWith(pParse->pWith, pFrom, &pWith);
|
||||
if( pCte ){
|
||||
sqlite3 *db = pParse->db;
|
||||
@@ -5210,7 +5298,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;
|
||||
@@ -5220,8 +5308,6 @@ static void selectPopWith(Walker *pWalker, Select *p){
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define selectPopWith 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -5308,6 +5394,15 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
}
|
||||
pTabList = p->pSrc;
|
||||
pEList = p->pEList;
|
||||
if( pParse->pWith && (p->selFlags & SF_View) ){
|
||||
if( p->pWith==0 ){
|
||||
p->pWith = (With*)sqlite3DbMallocZero(db, sizeof(With));
|
||||
if( p->pWith==0 ){
|
||||
return WRC_Abort;
|
||||
}
|
||||
}
|
||||
p->pWith->bView = 1;
|
||||
}
|
||||
sqlite3WithPush(pParse, p->pWith, 0);
|
||||
|
||||
/* Make sure cursor numbers have been assigned to all entries in
|
||||
@@ -5608,7 +5703,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);
|
||||
}
|
||||
@@ -6195,7 +6290,7 @@ int sqlite3Select(
|
||||
}
|
||||
|
||||
if( pDest->eDest==SRT_Output ){
|
||||
generateColumnNames(pParse, p);
|
||||
sqlite3GenerateColumnNames(pParse, p);
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
@@ -6325,7 +6420,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)
|
||||
){
|
||||
@@ -6388,19 +6484,8 @@ int sqlite3Select(
|
||||
pSub = pItem->pSelect;
|
||||
if( pSub==0 ) continue;
|
||||
|
||||
/* The code for a subquery should only be generated once, though it is
|
||||
** technically harmless for it to be generated multiple times. The
|
||||
** following assert() will detect if something changes to cause
|
||||
** the same subquery to be coded multiple times, as a signal to the
|
||||
** developers to try to optimize the situation.
|
||||
**
|
||||
** Update 2019-07-24:
|
||||
** See ticket https://sqlite.org/src/tktview/c52b09c7f38903b1311cec40.
|
||||
** The dbsqlfuzz fuzzer found a case where the same subquery gets
|
||||
** coded twice. So this assert() now becomes a testcase(). It should
|
||||
** be very rare, though.
|
||||
*/
|
||||
testcase( pItem->addrFillSub!=0 );
|
||||
/* The code for a subquery should only be generated once. */
|
||||
assert( pItem->addrFillSub==0 );
|
||||
|
||||
/* Increment Parse.nHeight by the height of the largest expression
|
||||
** tree referred to by this, the parent select. The child select
|
||||
@@ -6487,14 +6572,13 @@ int sqlite3Select(
|
||||
sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor);
|
||||
pSub->nSelectRow = pPrior->pSelect->nSelectRow;
|
||||
}else{
|
||||
/* Materalize the view. If the view is not correlated, generate a
|
||||
/* Materialize the view. If the view is not correlated, generate a
|
||||
** subroutine to do the materialization so that subsequent uses of
|
||||
** the same view can reuse the materialization. */
|
||||
int topAddr;
|
||||
int onceAddr = 0;
|
||||
int retAddr;
|
||||
|
||||
testcase( pItem->addrFillSub==0 ); /* Ticket c52b09c7f38903b1311 */
|
||||
pItem->regReturn = ++pParse->nMem;
|
||||
topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
|
||||
pItem->addrFillSub = topAddr+1;
|
||||
|
||||
+37
-22
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -7738,11 +7739,26 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sqlite3_free(zLike);
|
||||
goto meta_command_exit;
|
||||
}
|
||||
}else if( zLike ){
|
||||
zLike = sqlite3_mprintf("%z OR name LIKE %Q ESCAPE '\\'",
|
||||
zLike, azArg[i]);
|
||||
}else{
|
||||
zLike = sqlite3_mprintf("name LIKE %Q ESCAPE '\\'", azArg[i]);
|
||||
/* azArg[i] contains a LIKE pattern. This ".dump" request should
|
||||
** only dump data for tables for which either the table name matches
|
||||
** the LIKE pattern, or the table appears to be a shadow table of
|
||||
** a virtual table for which the name matches the LIKE pattern.
|
||||
*/
|
||||
char *zExpr = sqlite3_mprintf(
|
||||
"name LIKE %Q ESCAPE '\\' OR EXISTS ("
|
||||
" SELECT 1 FROM sqlite_schema WHERE "
|
||||
" name LIKE %Q ESCAPE '\\' AND"
|
||||
" sql LIKE 'CREATE VIRTUAL TABLE%%' AND"
|
||||
" substr(o.name, 1, length(name)+1) == (name||'_')"
|
||||
")", azArg[i], azArg[i]
|
||||
);
|
||||
|
||||
if( zLike ){
|
||||
zLike = sqlite3_mprintf("%z OR %z", zLike, zExpr);
|
||||
}else{
|
||||
zLike = zExpr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7764,7 +7780,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
p->nErr = 0;
|
||||
if( zLike==0 ) zLike = sqlite3_mprintf("true");
|
||||
zSql = sqlite3_mprintf(
|
||||
"SELECT name, type, sql FROM sqlite_schema "
|
||||
"SELECT name, type, sql FROM sqlite_schema AS o "
|
||||
"WHERE (%s) AND type=='table'"
|
||||
" AND sql NOT NULL"
|
||||
" ORDER BY tbl_name='sqlite_sequence', rowid",
|
||||
@@ -7774,7 +7790,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sqlite3_free(zSql);
|
||||
if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
|
||||
zSql = sqlite3_mprintf(
|
||||
"SELECT sql FROM sqlite_schema "
|
||||
"SELECT sql FROM sqlite_schema AS o "
|
||||
"WHERE (%s) AND sql NOT NULL"
|
||||
" AND type IN ('index','trigger','view')",
|
||||
zLike
|
||||
@@ -8021,7 +8037,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 +8058,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 +8074,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 +8727,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 +10718,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 +10735,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 +11065,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 +11182,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 ){
|
||||
|
||||
+34
-17
@@ -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 */
|
||||
|
||||
+12
-3
@@ -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 */
|
||||
|
||||
/*
|
||||
@@ -2236,6 +2235,7 @@ struct Table {
|
||||
#define TF_Shadow 0x1000 /* True for a shadow table */
|
||||
#define TF_HasStat4 0x2000 /* STAT4 info available for this table */
|
||||
#define TF_Ephemeral 0x4000 /* An ephemeral table */
|
||||
#define TF_Eponymous 0x8000 /* An eponymous virtual table */
|
||||
|
||||
/*
|
||||
** Test to see whether or not a table is a virtual table. This is
|
||||
@@ -2948,6 +2948,7 @@ struct SrcItem {
|
||||
unsigned isRecursive :1; /* True for recursive reference in WITH */
|
||||
unsigned fromDDL :1; /* Comes from sqlite_schema */
|
||||
unsigned isCte :1; /* This is a CTE */
|
||||
unsigned notCte :1; /* This item may not match a CTE */
|
||||
} fg;
|
||||
int iCursor; /* The VDBE cursor number used to access this table */
|
||||
Expr *pOn; /* The ON clause of a join */
|
||||
@@ -3793,7 +3794,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
|
||||
@@ -3886,6 +3887,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.
|
||||
@@ -3919,6 +3926,7 @@ struct Cte {
|
||||
*/
|
||||
struct With {
|
||||
int nCte; /* Number of CTEs in the WITH clause */
|
||||
int bView; /* Belongs to the outermost Select of a view */
|
||||
With *pOuter; /* Containing WITH clause, or NULL */
|
||||
Cte a[1]; /* For each CTE in the WITH clause.... */
|
||||
};
|
||||
@@ -4311,6 +4319,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);
|
||||
@@ -4689,7 +4698,7 @@ int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
|
||||
const char *sqlite3ErrName(int);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_DESERIALIZE
|
||||
#ifndef SQLITE_OMIT_DESERIALIZE
|
||||
int sqlite3MemdbInit(void);
|
||||
#endif
|
||||
|
||||
|
||||
+2
-2
@@ -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
|
||||
);
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+17
-8
@@ -56,6 +56,7 @@
|
||||
#define CC_ID 27 /* unicode characters usable in IDs */
|
||||
#define CC_ILLEGAL 28 /* Illegal character */
|
||||
#define CC_NUL 29 /* 0x00 */
|
||||
#define CC_BOM 30 /* First byte of UTF8 BOM: 0xEF 0xBB 0xBF */
|
||||
|
||||
static const unsigned char aiClass[] = {
|
||||
#ifdef SQLITE_ASCII
|
||||
@@ -68,14 +69,14 @@ static const unsigned char aiClass[] = {
|
||||
/* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 9, 28, 28, 28, 2,
|
||||
/* 6x */ 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 28, 10, 28, 25, 28,
|
||||
/* 8x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
/* 9x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
/* Ax */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
/* Bx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
/* Cx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
/* Dx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
/* Ex */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
/* Fx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
|
||||
/* 8x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
|
||||
/* 9x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
|
||||
/* Ax */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
|
||||
/* Bx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
|
||||
/* Cx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
|
||||
/* Dx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
|
||||
/* Ex */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 30,
|
||||
/* Fx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27
|
||||
#endif
|
||||
#ifdef SQLITE_EBCDIC
|
||||
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */
|
||||
@@ -535,6 +536,14 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
|
||||
i = 1;
|
||||
break;
|
||||
}
|
||||
case CC_BOM: {
|
||||
if( z[1]==0xbb && z[2]==0xbf ){
|
||||
*tokenType = TK_SPACE;
|
||||
return 3;
|
||||
}
|
||||
i = 1;
|
||||
break;
|
||||
}
|
||||
case CC_NUL: {
|
||||
*tokenType = TK_ILLEGAL;
|
||||
return 0;
|
||||
|
||||
@@ -706,6 +706,14 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
|
||||
break;
|
||||
}
|
||||
case TK_ERROR: {
|
||||
Expr tmp;
|
||||
sqlite3TreeViewLine(pView, "ERROR");
|
||||
tmp = *pExpr;
|
||||
tmp.op = pExpr->op2;
|
||||
sqlite3TreeViewExpr(pView, &tmp, 0);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sqlite3TreeViewLine(pView, "op=%d", pExpr->op);
|
||||
break;
|
||||
|
||||
+48
-34
@@ -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;
|
||||
}
|
||||
|
||||
@@ -220,6 +220,7 @@ static void updateFromSelect(
|
||||
|
||||
assert( pTabList->nSrc>1 );
|
||||
if( pSrc ){
|
||||
pSrc->a[0].fg.notCte = 1;
|
||||
pSrc->a[0].iCursor = -1;
|
||||
pSrc->a[0].pTab->nTabRef--;
|
||||
pSrc->a[0].pTab = 0;
|
||||
|
||||
+78
-21
@@ -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
|
||||
@@ -7191,6 +7247,7 @@ case OP_JournalMode: { /* out2 */
|
||||
pPager = sqlite3BtreePager(pBt);
|
||||
eOld = sqlite3PagerGetJournalMode(pPager);
|
||||
if( eNew==PAGER_JOURNALMODE_QUERY ) eNew = eOld;
|
||||
assert( sqlite3BtreeHoldsMutex(pBt) );
|
||||
if( !sqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld;
|
||||
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
|
||||
+6
-2
@@ -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);
|
||||
|
||||
@@ -1221,6 +1221,7 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
|
||||
pTab->pSchema = db->aDb[0].pSchema;
|
||||
assert( pTab->nModuleArg==0 );
|
||||
pTab->iPKey = -1;
|
||||
pTab->tabFlags |= TF_Eponymous;
|
||||
addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
|
||||
addModuleArgument(pParse, pTab, 0);
|
||||
addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
|
||||
|
||||
@@ -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. */
|
||||
|
||||
+42
-10
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1942,7 +1954,7 @@ static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){
|
||||
static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){
|
||||
whereLoopClearUnion(db, pTo);
|
||||
if( whereLoopResize(db, pTo, pFrom->nLTerm) ){
|
||||
memset(&pTo->u, 0, sizeof(pTo->u));
|
||||
memset(pTo, 0, WHERE_LOOP_XFER_SZ);
|
||||
return SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ);
|
||||
@@ -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);
|
||||
}
|
||||
@@ -3879,6 +3896,10 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) );
|
||||
assert( pIndex->aiColumn[nColumn-1]==XN_ROWID
|
||||
|| !HasRowid(pIndex->pTable));
|
||||
/* All relevant terms of the index must also be non-NULL in order
|
||||
** for isOrderDistinct to be true. So the isOrderDistint value
|
||||
** computed here might be a false positive. Corrections will be
|
||||
** made at tag-20210426-1 below */
|
||||
isOrderDistinct = IsUniqueIndex(pIndex)
|
||||
&& (pLoop->wsFlags & WHERE_SKIPSCAN)==0;
|
||||
}
|
||||
@@ -3946,15 +3967,19 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
}
|
||||
|
||||
/* An unconstrained column that might be NULL means that this
|
||||
** WhereLoop is not well-ordered
|
||||
** WhereLoop is not well-ordered. tag-20210426-1
|
||||
*/
|
||||
if( isOrderDistinct
|
||||
&& iColumn>=0
|
||||
&& j>=pLoop->u.btree.nEq
|
||||
&& pIndex->pTable->aCol[iColumn].notNull==0
|
||||
){
|
||||
isOrderDistinct = 0;
|
||||
}
|
||||
if( isOrderDistinct ){
|
||||
if( iColumn>=0
|
||||
&& j>=pLoop->u.btree.nEq
|
||||
&& pIndex->pTable->aCol[iColumn].notNull==0
|
||||
){
|
||||
isOrderDistinct = 0;
|
||||
}
|
||||
if( iColumn==XN_EXPR ){
|
||||
isOrderDistinct = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the ORDER BY term that corresponds to the j-th column
|
||||
** of the index and mark that ORDER BY term off
|
||||
@@ -4137,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;
|
||||
@@ -5427,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 ){
|
||||
@@ -5451,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);
|
||||
|
||||
+3
-2
@@ -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) */
|
||||
|
||||
+40
-9
@@ -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;
|
||||
}
|
||||
|
||||
@@ -700,7 +721,7 @@ static int codeAllEqualityTerms(
|
||||
|
||||
if( nSkip ){
|
||||
int iIdxCur = pLevel->iIdxCur;
|
||||
sqlite3VdbeAddOp3(v, OP_Null, 0, regBase, nSkip);
|
||||
sqlite3VdbeAddOp3(v, OP_Null, 0, regBase, regBase+nSkip-1);
|
||||
sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
|
||||
VdbeCoverageIf(v, bRev==0);
|
||||
VdbeCoverageIf(v, bRev!=0);
|
||||
@@ -731,11 +752,16 @@ static int codeAllEqualityTerms(
|
||||
testcase( pTerm->wtFlags & TERM_VIRTUAL );
|
||||
r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
|
||||
if( r1!=regBase+j ){
|
||||
assert( pTerm->pExpr->op==TK_EQ || pTerm->pExpr->op==TK_IS );
|
||||
if( nReg==1 ){
|
||||
sqlite3ReleaseTempReg(pParse, regBase);
|
||||
regBase = r1;
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
|
||||
if( ExprHasProperty(pTerm->pExpr->pRight, EP_VarSelect) ){
|
||||
sqlite3VdbeAddOp3(v, OP_Move, r1, regBase+j, 1);
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
|
||||
}
|
||||
}
|
||||
}
|
||||
if( pTerm->eOperator & WO_IN ){
|
||||
@@ -752,7 +778,7 @@ static int codeAllEqualityTerms(
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
if( pParse->db->mallocFailed==0 ){
|
||||
if( pParse->db->mallocFailed==0 && pParse->nErr==0 ){
|
||||
if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){
|
||||
zAff[j] = SQLITE_AFF_BLOB;
|
||||
}
|
||||
@@ -1101,7 +1127,7 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
|
||||
}
|
||||
}
|
||||
}else{
|
||||
assert( nReg==1 );
|
||||
assert( nReg==1 || pParse->nErr );
|
||||
sqlite3ExprCode(pParse, p, iReg);
|
||||
}
|
||||
}
|
||||
@@ -1728,9 +1754,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 +2175,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 +2191,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 +2315,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
sqlite3WhereEnd(pSubWInfo);
|
||||
ExplainQueryPlanPop(pParse);
|
||||
}
|
||||
sqlite3ExprDelete(db, pDelete);
|
||||
}
|
||||
}
|
||||
ExplainQueryPlanPop(pParse);
|
||||
|
||||
+3
-281
@@ -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.
|
||||
|
||||
+34
-12
@@ -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
|
||||
@@ -950,7 +958,7 @@ static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){
|
||||
*/
|
||||
int sqlite3WindowRewrite(Parse *pParse, Select *p){
|
||||
int rc = SQLITE_OK;
|
||||
if( p->pWin && p->pPrior==0 && (p->selFlags & SF_WinRewrite)==0 ){
|
||||
if( p->pWin && p->pPrior==0 && ALWAYS((p->selFlags & SF_WinRewrite)==0) ){
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
sqlite3 *db = pParse->db;
|
||||
Select *pSub = 0; /* The subquery */
|
||||
@@ -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;
|
||||
@@ -1570,6 +1583,7 @@ struct WindowCodeArg {
|
||||
int regGosub; /* Register used with OP_Gosub(addrGosub) */
|
||||
int regArg; /* First in array of accumulator registers */
|
||||
int eDelete; /* See above */
|
||||
int regRowid;
|
||||
|
||||
WindowCsrAndReg start;
|
||||
WindowCsrAndReg current;
|
||||
@@ -2246,16 +2260,24 @@ static int windowCodeOp(
|
||||
/* If this is a (RANGE BETWEEN a FOLLOWING AND b FOLLOWING) or
|
||||
** (RANGE BETWEEN b PRECEDING AND a PRECEDING) frame, ensure the
|
||||
** start cursor does not advance past the end cursor within the
|
||||
** temporary table. It otherwise might, if (a>b). */
|
||||
** temporary table. It otherwise might, if (a>b). Also ensure that,
|
||||
** if the input cursor is still finding new rows, that the end
|
||||
** cursor does not go past it to EOF. */
|
||||
if( pMWin->eStart==pMWin->eEnd && regCountdown
|
||||
&& pMWin->eFrmType==TK_RANGE && op==WINDOW_AGGINVERSE
|
||||
&& pMWin->eFrmType==TK_RANGE
|
||||
){
|
||||
int regRowid1 = sqlite3GetTempReg(pParse);
|
||||
int regRowid2 = sqlite3GetTempReg(pParse);
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1);
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2);
|
||||
sqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1);
|
||||
VdbeCoverage(v);
|
||||
if( op==WINDOW_AGGINVERSE ){
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1);
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2);
|
||||
sqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1);
|
||||
VdbeCoverage(v);
|
||||
}else if( p->regRowid ){
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid1);
|
||||
sqlite3VdbeAddOp3(v, OP_Ge, p->regRowid, lblDone, regRowid1);
|
||||
VdbeCoverageNeverNull(v);
|
||||
}
|
||||
sqlite3ReleaseTempReg(pParse, regRowid1);
|
||||
sqlite3ReleaseTempReg(pParse, regRowid2);
|
||||
assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING );
|
||||
@@ -2752,7 +2774,6 @@ void sqlite3WindowCodeStep(
|
||||
int addrEmpty; /* Address of OP_Rewind in flush: */
|
||||
int regNew; /* Array of registers holding new input row */
|
||||
int regRecord; /* regNew array in record form */
|
||||
int regRowid; /* Rowid for regRecord in eph table */
|
||||
int regNewPeer = 0; /* Peer values for new row (part of regNew) */
|
||||
int regPeer = 0; /* Peer values for current row */
|
||||
int regFlushPart = 0; /* Register for "Gosub flush_partition" */
|
||||
@@ -2824,7 +2845,7 @@ void sqlite3WindowCodeStep(
|
||||
regNew = pParse->nMem+1;
|
||||
pParse->nMem += nInput;
|
||||
regRecord = ++pParse->nMem;
|
||||
regRowid = ++pParse->nMem;
|
||||
s.regRowid = ++pParse->nMem;
|
||||
|
||||
/* If the window frame contains an "<expr> PRECEDING" or "<expr> FOLLOWING"
|
||||
** clause, allocate registers to store the results of evaluating each
|
||||
@@ -2880,9 +2901,9 @@ void sqlite3WindowCodeStep(
|
||||
}
|
||||
|
||||
/* Insert the new row into the ephemeral table */
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, regRowid);
|
||||
sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, regRowid);
|
||||
addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, regRowid);
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, s.regRowid);
|
||||
sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, s.regRowid);
|
||||
addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, s.regRowid);
|
||||
VdbeCoverageNeverNull(v);
|
||||
|
||||
/* This block is run for the first row of each partition */
|
||||
@@ -3000,6 +3021,7 @@ void sqlite3WindowCodeStep(
|
||||
sqlite3VdbeJumpHere(v, addrGosubFlush);
|
||||
}
|
||||
|
||||
s.regRowid = 0;
|
||||
addrEmpty = sqlite3VdbeAddOp1(v, OP_Rewind, csrWrite);
|
||||
VdbeCoverage(v);
|
||||
if( pMWin->eEnd==TK_PRECEDING ){
|
||||
|
||||
+4
-4
@@ -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
|
||||
|
||||
@@ -736,5 +736,67 @@ do_catchsql_test 24.2.1 {
|
||||
ALTER TABLE t1 RENAME TO t2;
|
||||
} {1 {error in trigger AFTER: no such table: main.nosuchtable}}
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 25.1 {
|
||||
CREATE TABLE xx(x);
|
||||
CREATE VIEW v3(b) AS WITH b AS (SELECT b FROM (SELECT * FROM t2)) VALUES(1);
|
||||
}
|
||||
|
||||
ifcapable json1&&vtab {
|
||||
do_catchsql_test 25.2 {
|
||||
ALTER TABLE json_each RENAME TO t4;
|
||||
} {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
|
||||
|
||||
+14
-12
@@ -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
|
||||
|
||||
+64
-37
@@ -149,47 +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';
|
||||
}
|
||||
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}}
|
||||
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
|
||||
|
||||
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;
|
||||
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;
|
||||
PRAGMA vdbe_trace = 1;
|
||||
REPLACE INTO x1 VALUES(5, 2, 3);
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
explain_i {
|
||||
REPLACE INTO x1 VALUES(5, 2, 3);
|
||||
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}}
|
||||
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
reset_db
|
||||
|
||||
ifcapable json1&&vtab {
|
||||
db func strreplace strreplace
|
||||
proc strreplace {orig a b} {
|
||||
string map [list $a $b] $orig
|
||||
}
|
||||
|
||||
do_execsql_test 5.0 {
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE INDEX t1a ON t1(a);
|
||||
CREATE INDEX t1b ON t1(b);
|
||||
|
||||
PRAGMA writable_schema = 1;
|
||||
UPDATE sqlite_schema
|
||||
SET sql = strreplace(sql, 't1', 'json_each')
|
||||
WHERE type='index';
|
||||
}
|
||||
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
|
||||
do_execsql_test 5.1 {
|
||||
PRAGMA writable_schema = 1;
|
||||
SELECT * FROM t1
|
||||
}
|
||||
}; # ifcapable json1&&vtab
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-2
@@ -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
|
||||
+33
-16
@@ -63,7 +63,7 @@
|
||||
** of the global variable g.zTextName[] will identify the specific XSQL and
|
||||
** DB values that were running when the crash occurred.
|
||||
**
|
||||
** DBSQLFUZZ:
|
||||
** DBSQLFUZZ: (Added 2020-02-25)
|
||||
**
|
||||
** The dbsqlfuzz fuzzer includes both a database file and SQL to run against
|
||||
** that database in its input. This utility can now process dbsqlfuzz
|
||||
@@ -108,10 +108,10 @@ typedef unsigned char uint8_t;
|
||||
*/
|
||||
typedef struct VFile VFile;
|
||||
struct VFile {
|
||||
char *zFilename; /* Filename. NULL for delete-on-close. From malloc() */
|
||||
int sz; /* Size of the file in bytes */
|
||||
int nRef; /* Number of references to this file */
|
||||
unsigned char *a; /* Content of the file. From malloc() */
|
||||
char *zFilename; /* Filename. NULL for delete-on-close. From malloc() */
|
||||
int sz; /* Size of the file in bytes */
|
||||
int nRef; /* Number of references to this file */
|
||||
unsigned char *a; /* Content of the file. From malloc() */
|
||||
};
|
||||
typedef struct VHandle VHandle;
|
||||
struct VHandle {
|
||||
@@ -219,7 +219,7 @@ static int progressHandler(void *pVdbeLimitFlag){
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Reallocate memory. Show and error and quit if unable.
|
||||
** Reallocate memory. Show an error and quit if unable.
|
||||
*/
|
||||
static void *safe_realloc(void *pOld, int szNew){
|
||||
void *pNew = realloc(pOld, szNew<=0 ? 1 : szNew);
|
||||
@@ -617,8 +617,8 @@ static int isOffset(
|
||||
|
||||
/*
|
||||
** Decode the text starting at zIn into a binary database file.
|
||||
** The maximum length of zIn is nIn bytes. Compute the binary database
|
||||
** file contain in space obtained from sqlite3_malloc().
|
||||
** The maximum length of zIn is nIn bytes. Store the binary database
|
||||
** file in space obtained from sqlite3_malloc().
|
||||
**
|
||||
** Return the number of bytes of zIn consumed. Or return -1 if there
|
||||
** is an error. One potential error is that the recipe specifies a
|
||||
@@ -1435,9 +1435,10 @@ static void showHelp(void){
|
||||
" --limit-heap N Limit heap memory to N. Default: 100M\n"
|
||||
" --limit-mem N Limit memory used by test SQLite instance to N bytes\n"
|
||||
" --limit-vdbe Panic if any test runs for more than 100,000 cycles\n"
|
||||
" --load-sql ARGS... Load SQL scripts fron files into SOURCE-DB\n"
|
||||
" --load-db ARGS... Load template databases from files into SOURCE_DB\n"
|
||||
" --load-dbsql ARGS.. Load dbsqlfuzz outputs into the xsql table\n"
|
||||
" --load-sql FILE.. Load SQL scripts fron files into SOURCE-DB\n"
|
||||
" --load-db FILE.. Load template databases from files into SOURCE_DB\n"
|
||||
" --load-dbsql FILE.. Load dbsqlfuzz outputs into the xsql table\n"
|
||||
" ^^^^------ Use \"-\" for FILE to read filenames from stdin\n"
|
||||
" -m TEXT Add a description to the database\n"
|
||||
" --native-vfs Use the native VFS for initially empty database files\n"
|
||||
" --native-malloc Turn off MEMSYS3/5 and Lookaside\n"
|
||||
@@ -1778,10 +1779,25 @@ int main(int argc, char **argv){
|
||||
rc = sqlite3_exec(db, "BEGIN", 0, 0, 0);
|
||||
if( rc ) fatalError("cannot start a transaction");
|
||||
for(i=iFirstInsArg; i<argc; i++){
|
||||
sqlite3_bind_text(pStmt, 1, argv[i], -1, SQLITE_STATIC);
|
||||
sqlite3_step(pStmt);
|
||||
rc = sqlite3_reset(pStmt);
|
||||
if( rc ) fatalError("insert failed for %s", argv[i]);
|
||||
if( strcmp(argv[i],"-")==0 ){
|
||||
/* A filename of "-" means read multiple filenames from stdin */
|
||||
char zLine[2000];
|
||||
while( rc==0 && fgets(zLine,sizeof(zLine),stdin)!=0 ){
|
||||
size_t kk = strlen(zLine);
|
||||
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]);
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
rc = sqlite3_exec(db, "COMMIT", 0, 0, 0);
|
||||
@@ -2050,7 +2066,8 @@ int main(int argc, char **argv){
|
||||
}
|
||||
}
|
||||
if( bSpinner ){
|
||||
printf("\n");
|
||||
int nTotal = g.nDb*g.nSql;
|
||||
printf("\r%s: %d/%d \n", zDbName, nTotal, nTotal);
|
||||
}else if( !quietFlag && !verboseFlag ){
|
||||
printf(" 100%% - %d tests\n", g.nDb*g.nSql);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# 2021 May 24
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# Tests focused on the in-memory journal.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
set testprefix memjournal
|
||||
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
PRAGMA journal_mode = memory;
|
||||
CREATE TABLE t1(a);
|
||||
} {memory}
|
||||
|
||||
set nRow [expr 1]
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES( randomblob(500) );
|
||||
} {}
|
||||
|
||||
do_test 1.2 {
|
||||
for {set i 1} {$i <= 500} {incr i} {
|
||||
execsql {
|
||||
SAVEPOINT one;
|
||||
UPDATE t1 SET a=randomblob(500);
|
||||
}
|
||||
execsql { SAVEPOINT abc }
|
||||
execsql { UPDATE t1 SET a=randomblob(500) WHERE rowid<=$i AND 0 }
|
||||
execsql { RELEASE abc }
|
||||
}
|
||||
} {}
|
||||
|
||||
do_execsql_test 1.3 {
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
@@ -131,6 +131,7 @@ set allquicktests [test_set $alltests -exclude {
|
||||
fts3defer.test fts4langid.test fts3sort.test fts5unicode.test
|
||||
|
||||
rtree4.test
|
||||
sessionbig.test
|
||||
}]
|
||||
if {[info exists ::env(QUICKTEST_INCLUDE)]} {
|
||||
set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -297,5 +297,18 @@ do_execsql_test 7.3 {
|
||||
);
|
||||
} { 1 4 1 5 }
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
do_execsql_test 8.1 {
|
||||
CREATE TABLE t1(a ,b FLOAT);
|
||||
CREATE INDEX t1x1 ON t1(a,b,a,a,a,a,a,a,a,a,a,b);
|
||||
}
|
||||
|
||||
do_catchsql_test 8.2 {
|
||||
SELECT a FROM t1 NATURAL JOIN t1 WHERE (a,b)> (SELECT 2 IN (SELECT 2,2), 2);
|
||||
} {1 {sub-select returns 2 columns - expected 1}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
|
||||
+8
-3
@@ -12,7 +12,6 @@
|
||||
# focus of this file is testing aggregate functions and the
|
||||
# GROUP BY and HAVING clauses of SELECT statements.
|
||||
#
|
||||
# $Id: select5.test,v 1.20 2008/08/21 14:15:59 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@@ -251,7 +250,13 @@ do_test select5-8.8 {
|
||||
}
|
||||
} {two 3 one 9}
|
||||
|
||||
# 2021-04-26 forum https://sqlite.org/forum/forumpost/74330094d8
|
||||
reset_db
|
||||
do_execsql_test select5-9.1 {
|
||||
CREATE TABLE t1(a INT, b INT);
|
||||
INSERT INTO t1(a,b) VALUES(1,null),(null,null),(1,null);
|
||||
CREATE UNIQUE INDEX t1b ON t1(abs(b));
|
||||
SELECT quote(a), quote(b), '|' FROM t1 GROUP BY a, abs(b);
|
||||
} {NULL NULL | 1 NULL |}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -227,6 +227,50 @@ do_test tabfunc01-751 {
|
||||
}
|
||||
} {5.0 x5 | 7.0 x7 | 13.0 x13 | 17.0 x17 | 23.0 x23 |}
|
||||
|
||||
ifcapable altertable {
|
||||
do_test tabfunc01-800 {
|
||||
catchsql {
|
||||
ALTER TABLE generate_series ADD COLUMN col2;
|
||||
}
|
||||
} {1 {virtual tables may not be altered}}
|
||||
do_test tabfunc01-810 {
|
||||
catchsql {
|
||||
ALTER TABLE generate_series RENAME TO flubber;
|
||||
}
|
||||
} {1 {table generate_series may not be altered}}
|
||||
do_test tabfunc01-820 {
|
||||
catchsql {
|
||||
ALTER TABLE generate_series RENAME start TO flubber;
|
||||
}
|
||||
} {1 {table generate_series may not be altered}}
|
||||
do_test tabfunc01-830 {
|
||||
catchsql {
|
||||
ALTER TABLE generate_series DROP COLUMN start;
|
||||
}
|
||||
} {1 {table generate_series may not be altered}}
|
||||
do_test tabfunc01-900 {
|
||||
catchsql {
|
||||
ALTER TABLE pragma_compile_options ADD COLUMN col2;
|
||||
}
|
||||
} {1 {virtual tables may not be altered}}
|
||||
do_test tabfunc01-910 {
|
||||
catchsql {
|
||||
ALTER TABLE pragma_compile_options RENAME TO flubber;
|
||||
}
|
||||
} {1 {table pragma_compile_options may not be altered}}
|
||||
do_test tabfunc01-920 {
|
||||
catchsql {
|
||||
ALTER TABLE pragma_compile_options RENAME start TO flubber;
|
||||
}
|
||||
} {1 {table pragma_compile_options may not be altered}}
|
||||
do_test tabfunc01-930 {
|
||||
catchsql {
|
||||
ALTER TABLE pragma_compile_options DROP COLUMN start;
|
||||
}
|
||||
} {1 {table pragma_compile_options may not be altered}}
|
||||
}
|
||||
|
||||
|
||||
# Free up memory allocations
|
||||
intarray_addr
|
||||
int64array_addr
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -355,4 +355,13 @@ do_execsql_test 6.1 {
|
||||
9 10 800 100 9 10 800 400
|
||||
}
|
||||
|
||||
# 2021-04-26 dbsqlfuzz 88ed5c66789fced139d148aed823cba7c0926dd7
|
||||
reset_db
|
||||
do_execsql_test 7.1 {
|
||||
WITH c1(x) AS (VALUES(0) UNION ALL SELECT 100+x FROM c1 WHERE x<100 UNION ALL SELECT 1+x FROM c1 WHERE x<1)
|
||||
SELECT x, y, '|'
|
||||
FROM c1 AS x1, (SELECT x+1 AS y FROM c1 WHERE x<1 UNION ALL SELECT 1+x FROM c1 WHERE 1<x) AS x2
|
||||
ORDER BY x, y;
|
||||
} {0 1 | 0 101 | 0 102 | 1 1 | 1 101 | 1 102 | 100 1 | 100 101 | 100 102 | 101 1 | 101 101 | 101 102 |}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -175,4 +175,36 @@ do_execsql_test 3.1 {
|
||||
SELECT * FROM t0, t1;
|
||||
} {}
|
||||
|
||||
# Problem described by forum post https://sqlite.org/forum/forumpost/a274248080
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 4.1 {
|
||||
CREATE TABLE t1(x INT); INSERT INTO t1 VALUES(1);
|
||||
CREATE TABLE t2(y INT); INSERT INTO t2 VALUES(2);
|
||||
WITH t1 AS (SELECT y+100 AS x FROM t2)
|
||||
UPDATE t1 SET x=(SELECT x FROM t1);
|
||||
SELECT x, y FROM t1, t2;
|
||||
} {102 2}
|
||||
do_execsql_test 4.2 {
|
||||
WITH t1 AS (SELECT y+100 AS x FROM t2)
|
||||
UPDATE t1 SET x=x+y FROM t2;
|
||||
SELECT x, y FROM t1, t2;
|
||||
} {104 2}
|
||||
|
||||
# 2021-05-20
|
||||
# Forum https://sqlite.org/forum/forumpost/339f487de5 by Yu Liang
|
||||
# A bad assert()
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 5.1 {
|
||||
CREATE TABLE t1(a);
|
||||
INSERT INTO t1(a) VALUES(5);
|
||||
CREATE VIEW t2 AS SELECT a FROM t1 UNION ALL SELECT a FROM t1;
|
||||
CREATE TABLE t3(b,c);
|
||||
INSERT INTO t3(b,c) VALUES(1,2);
|
||||
UPDATE t3 SET (c,b) = (SELECT 3,4) FROM t1, t2;
|
||||
SELECT * FROM t3;
|
||||
} {4 3}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
# 2021 May 20
|
||||
#
|
||||
# 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 VIEW statements.
|
||||
#
|
||||
# $Id: view.test,v 1.39 2008/12/14 14:45:21 danielk1977 Exp $
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# Omit this entire file if the library is not configured with views enabled.
|
||||
ifcapable !view {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
set testprefix view2
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(x, y);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
CREATE VIEW v1 AS SELECT * FROM (
|
||||
WITH x1 AS (SELECT y, x FROM t1)
|
||||
SELECT * FROM x1
|
||||
);
|
||||
}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
SELECT * FROM v1
|
||||
} {2 1}
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
CREATE VIEW v3 AS SELECT * FROM main.t1;
|
||||
WITH t1(a, b) AS ( SELECT 3, 4 ) SELECT * FROM v3;
|
||||
} {1 2}
|
||||
|
||||
breakpoint
|
||||
do_execsql_test 1.3 {
|
||||
CREATE VIEW v2 AS SELECT * FROM t1;
|
||||
WITH t1(a, b) AS ( SELECT 3, 4 ) SELECT * FROM v2;
|
||||
} {1 2}
|
||||
|
||||
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');
|
||||
|
||||
+18
-1
@@ -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
|
||||
|
||||
+4
-4
@@ -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
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
# 2021 May 27
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# Tests focused on the "constant propagation" that occurs within the
|
||||
# WHERE clause of a SELECT statemente.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
set testprefix whereM
|
||||
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b INTEGER, c TEXT, d REAL, e BLOB);
|
||||
INSERT INTO t1 VALUES(10.0, 10.0, 10.0, 10.0, 10.0);
|
||||
SELECT * FROM t1;
|
||||
} {
|
||||
10.0 10 10.0 10.0 10.0
|
||||
}
|
||||
|
||||
do_execsql_test 1.1.1 {
|
||||
SELECT a=10, a = '10.0', a LIKE '10.0' FROM t1;
|
||||
} {1 0 1}
|
||||
do_execsql_test 1.1.2 {
|
||||
SELECT count(*) FROM t1 WHERE a=10 AND a = '10.0'
|
||||
} {0}
|
||||
do_execsql_test 1.1.3 {
|
||||
SELECT count(*) FROM t1 WHERE a=10 AND a LIKE '10.0'
|
||||
} {1}
|
||||
do_execsql_test 1.1.4 {
|
||||
SELECT count(*) FROM t1 WHERE a='10.0' AND a LIKE '10.0'
|
||||
} {0}
|
||||
|
||||
do_execsql_test 1.2.1 {
|
||||
SELECT b=10, b = '10.0', b LIKE '10.0', b LIKE '10' FROM t1;
|
||||
} {1 1 0 1}
|
||||
do_execsql_test 1.2.2 {
|
||||
SELECT count(*) FROM t1 WHERE b=10 AND b = '10.0'
|
||||
} {1}
|
||||
do_execsql_test 1.2.3 {
|
||||
SELECT count(*) FROM t1 WHERE b=10 AND b LIKE '10.0'
|
||||
} {0}
|
||||
do_execsql_test 1.2.4 {
|
||||
SELECT count(*) FROM t1 WHERE b='10.0' AND b LIKE '10.0'
|
||||
} {0}
|
||||
do_execsql_test 1.2.3 {
|
||||
SELECT count(*) FROM t1 WHERE b=10 AND b LIKE '10'
|
||||
} {1}
|
||||
do_execsql_test 1.2.4 {
|
||||
SELECT count(*) FROM t1 WHERE b='10.0' AND b LIKE '10'
|
||||
} {1}
|
||||
|
||||
do_execsql_test 1.3.1 {
|
||||
SELECT c=10, c = 10.0, c = '10.0', c LIKE '10.0' FROM t1;
|
||||
} {0 1 1 1}
|
||||
do_execsql_test 1.3.2 {
|
||||
SELECT count(*) FROM t1 WHERE c=10 AND c = '10.0'
|
||||
} {0}
|
||||
do_execsql_test 1.3.3 {
|
||||
SELECT count(*) FROM t1 WHERE c=10 AND c LIKE '10.0'
|
||||
} {0}
|
||||
do_execsql_test 1.3.4 {
|
||||
SELECT count(*) FROM t1 WHERE c='10.0' AND c LIKE '10.0'
|
||||
} {1}
|
||||
do_execsql_test 1.3.5 {
|
||||
SELECT count(*) FROM t1 WHERE c=10.0 AND c = '10.0'
|
||||
} {1}
|
||||
do_execsql_test 1.3.6 {
|
||||
SELECT count(*) FROM t1 WHERE c=10.0 AND c LIKE '10.0'
|
||||
} {1}
|
||||
|
||||
do_execsql_test 1.4.1 {
|
||||
SELECT d=10, d = 10.0, d = '10.0', d LIKE '10.0', d LIKE '10' FROM t1;
|
||||
} {1 1 1 1 0}
|
||||
do_execsql_test 1.4.2 {
|
||||
SELECT count(*) FROM t1 WHERE d=10 AND d = '10.0'
|
||||
} {1}
|
||||
do_execsql_test 1.4.3 {
|
||||
SELECT count(*) FROM t1 WHERE d=10 AND d LIKE '10.0'
|
||||
} {1}
|
||||
do_execsql_test 1.4.4 {
|
||||
SELECT count(*) FROM t1 WHERE d='10.0' AND d LIKE '10.0'
|
||||
} {1}
|
||||
do_execsql_test 1.4.5 {
|
||||
SELECT count(*) FROM t1 WHERE d='10' AND d LIKE '10.0'
|
||||
} {1}
|
||||
|
||||
do_execsql_test 1.5.1 {
|
||||
SELECT e=10, e = '10.0', e LIKE '10.0', e LIKE '10' FROM t1;
|
||||
} {1 0 1 0}
|
||||
do_execsql_test 1.5.2 {
|
||||
SELECT count(*) FROM t1 WHERE e=10 AND e = '10.0'
|
||||
} {0}
|
||||
do_execsql_test 1.5.3 {
|
||||
SELECT count(*) FROM t1 WHERE e=10 AND e LIKE '10.0'
|
||||
} {1}
|
||||
do_execsql_test 1.5.4 {
|
||||
SELECT count(*) FROM t1 WHERE e='10.0' AND e LIKE '10.0'
|
||||
} {0}
|
||||
do_execsql_test 1.5.5 {
|
||||
SELECT count(*) FROM t1 WHERE e=10.0 AND e LIKE '10.0'
|
||||
} {1}
|
||||
|
||||
finish_test
|
||||
+86
-2
@@ -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,42 @@ 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()}}
|
||||
|
||||
# 2021-05-22
|
||||
# Forum https://sqlite.org/forum/forumpost/7e484e225c
|
||||
#
|
||||
reset_db
|
||||
do_catchsql_test 69.0 {
|
||||
CREATE TABLE t1(a,b);
|
||||
CREATE INDEX t1ba ON t1(b,a);
|
||||
SELECT * FROM t1 WHERE b = (SELECT b FROM t1 ORDER BY lead(b) OVER () AND sum(a));
|
||||
} {1 {misuse of aggregate: sum()}}
|
||||
do_catchsql_test 69.1 {
|
||||
SELECT * FROM t1 WHERE b >= (SELECT b FROM t1 ORDER BY lead(b) OVER () AND sum(a));
|
||||
} {1 {misuse of aggregate: sum()}}
|
||||
do_catchsql_test 69.2 {
|
||||
SELECT * FROM t1 WHERE b <= (SELECT b FROM t1 ORDER BY lead(b) OVER () AND sum(a));
|
||||
} {1 {misuse of aggregate: sum()}}
|
||||
|
||||
|
||||
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
|
||||
|
||||
+44
-14
@@ -1149,20 +1149,26 @@ do_execsql_test 24.2 {
|
||||
# had to continue to recognize "true" and "false" as identifiers for
|
||||
# backwards compatibility.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 25.1 {
|
||||
CREATE TABLE dual(dummy);
|
||||
INSERT INTO dual(dummy) VALUES('X');
|
||||
WITH cte1 AS (
|
||||
SELECT TRUE, (
|
||||
WITH cte2 AS (SELECT avg(DISTINCT TRUE) FROM dual)
|
||||
SELECT 2571 FROM cte2
|
||||
) AS subquery1
|
||||
FROM dual
|
||||
GROUP BY 1
|
||||
)
|
||||
SELECT (SELECT 1324 FROM cte1) FROM cte1;
|
||||
} {1324}
|
||||
foreach {id dual} {
|
||||
1 {CREATE TABLE dual AS SELECT 'X' AS dummy}
|
||||
2 {CREATE TEMP TABLE dual AS SELECT 'X' AS dummy}
|
||||
3 {CREATE VIEW dual(dummy) AS VALUES('X')}
|
||||
4 {CREATE TEMP VIEW dual(dummy) AS VALUES('X')}
|
||||
} {
|
||||
reset_db
|
||||
db eval $dual
|
||||
do_execsql_test 25.$id {
|
||||
WITH cte1 AS (
|
||||
SELECT TRUE, (
|
||||
WITH cte2 AS (SELECT avg(DISTINCT TRUE) FROM dual)
|
||||
SELECT 2571 FROM cte2
|
||||
) AS subquery1
|
||||
FROM dual
|
||||
GROUP BY 1
|
||||
)
|
||||
SELECT (SELECT 1324 FROM cte1) FROM cte1;
|
||||
} {1324}
|
||||
}
|
||||
|
||||
do_catchsql_test 26.0 {
|
||||
WITH i(x) AS (
|
||||
@@ -1207,4 +1213,28 @@ do_execsql_test 26.3 {
|
||||
SELECT * FROM cte ORDER BY +label, +step;
|
||||
} {a 1 a 2 a 3 b 1 b 2 b 3}
|
||||
|
||||
# 2021-05-20
|
||||
# forum post https://sqlite.org/forum/forumpost/8590e3f6dc
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 27.1 {
|
||||
CREATE TABLE t1(k);
|
||||
CREATE TABLE log(k, cte_map, main_map);
|
||||
CREATE TABLE map(k, v);
|
||||
INSERT INTO map VALUES(1, 'main1'), (2, 'main2');
|
||||
|
||||
CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
|
||||
INSERT INTO log
|
||||
WITH map(k,v) AS (VALUES(1,'cte1'),(2,'cte2'))
|
||||
SELECT
|
||||
new.k,
|
||||
(SELECT v FROM map WHERE k=new.k),
|
||||
(SELECT v FROM main.map WHERE k=new.k);
|
||||
END;
|
||||
|
||||
INSERT INTO t1 VALUES(1);
|
||||
INSERT INTO t1 VALUES(2);
|
||||
SELECT k, cte_map, main_map, '|' FROM log ORDER BY k;
|
||||
} {1 cte1 main1 | 2 cte2 main2 |}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -549,4 +549,66 @@ do_execsql_test 10.1 {
|
||||
)
|
||||
} {1}
|
||||
|
||||
# 2021-05-21
|
||||
# Forum post https://sqlite.org/forum/forumpost/aa4a7a3980
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 11.1 {
|
||||
CREATE TABLE t1(a);
|
||||
CREATE VIEW v2(c) AS
|
||||
WITH x AS (
|
||||
WITH y AS (
|
||||
WITH z AS(SELECT * FROM t1)
|
||||
SELECT * FROM v2
|
||||
) SELECT a
|
||||
) SELECT * from t1;
|
||||
ALTER TABLE t1 RENAME COLUMN a TO b;
|
||||
SELECT sql FROM sqlite_schema WHERE name='t1';
|
||||
} {{CREATE TABLE t1(b)}}
|
||||
do_catchsql_test 11.2 {
|
||||
INSERT INTO t1 VALUES(55);
|
||||
SELECT * FROM v2;
|
||||
} {0 55}
|
||||
do_catchsql_test 11.3 {
|
||||
DROP VIEW v2;
|
||||
CREATE VIEW v2(c) AS
|
||||
WITH x AS (
|
||||
WITH y AS (
|
||||
WITH z AS(SELECT * FROM t1)
|
||||
SELECT * FROM v2
|
||||
) SELECT a
|
||||
) SELECT * from t1, x;
|
||||
SELECT * FROM v2;
|
||||
} {1 {no such column: a}}
|
||||
do_catchsql_test 11.4 {
|
||||
DROP VIEW v2;
|
||||
CREATE VIEW v2(c) AS
|
||||
WITH x AS (
|
||||
WITH y AS (
|
||||
WITH z AS(SELECT * FROM t1)
|
||||
SELECT * FROM v2
|
||||
) SELECT *
|
||||
) SELECT * from t1, x;
|
||||
SELECT * FROM v2;
|
||||
} {1 {no tables specified}}
|
||||
do_catchsql_test 11.5 {
|
||||
WITH x AS (
|
||||
WITH y AS (
|
||||
WITH z AS(SELECT * FROM t1)
|
||||
SELECT * FROM no_such_table
|
||||
) SELECT a
|
||||
) SELECT * from t1;
|
||||
} {0 55}
|
||||
|
||||
# 2021-05-23 dbsqlfuzz 6b7a144674e215f06ddfeb9042c873d9ee956ac0 */
|
||||
reset_db
|
||||
do_execsql_test 12.1 {
|
||||
CREATE TABLE t1(a);
|
||||
INSERT INTO t1 VALUES(1),('hello'),(4.25),(NULL),(x'3c626c6f623e');
|
||||
CREATE VIEW v2(c) AS WITH x AS (WITH y AS (WITH z AS(SELECT * FROM t1) SELECT * FROM v2) SELECT a) SELECT * from t1;
|
||||
CREATE VIEW v3(c) AS WITH x AS (WITH y AS (WITH z AS(SELECT * FROM v2) SELECT * FROM v3) SELECT a) SELECT * from t1;
|
||||
ALTER TABLE t1 RENAME TO t1x;
|
||||
SELECT quote(c) FROM v3;
|
||||
} {1 'hello' 4.25 NULL X'3C626C6F623E'}
|
||||
|
||||
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
|
||||
|
||||
@@ -843,4 +843,16 @@ do_catchsql_test 16.20 {
|
||||
REPLACE INTO zipfile VALUES(null,null,null,null,null,123,null);
|
||||
} {1 {zipfile: missing filename}}
|
||||
|
||||
# 2021-04-22 forum https://sqlite.org/forum/forumpost/d82289d69f
|
||||
do_execsql_test 17.1 {
|
||||
WITH vlist(x) AS (
|
||||
VALUES(9223372036854775807),
|
||||
(-9223372036854775808),
|
||||
(9223372036854775806),
|
||||
(-9223372036854775807)
|
||||
)
|
||||
SELECT DISTINCT typeof(zipfile(0,0,x,0)) FROM vlist;
|
||||
} {blob}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/tcl
|
||||
#
|
||||
# Run this script to test to see that the latest trunk changes can be
|
||||
# merged into LTS branches without breaking anything.
|
||||
#
|
||||
# To Use:
|
||||
#
|
||||
# * Copy this script into a directory above the sqlite checkout
|
||||
# * Run "fossil update trunk" and "fossil revert"
|
||||
# * Run "tclsh ../merge-test.tcl" (in other words run this script)
|
||||
#
|
||||
# Operation:
|
||||
#
|
||||
# This script changes to each LTS branch to be tested, merges the latest
|
||||
# trunk changes into the branch (without committing them) and then
|
||||
# runs "make test". Any errors are stored in local files.
|
||||
#
|
||||
# Limitations:
|
||||
#
|
||||
# Some LTS branches are not synced directly from trunk but rather from
|
||||
# other LTS branches. These other branches cannot be tested because
|
||||
# there is no good way to generate the intermediate merges.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# Run a shell command contained in arguments. Put the return code in
|
||||
# global variable ::res and the output string in global variable ::result
|
||||
#
|
||||
proc safeexec {args} {
|
||||
global res result
|
||||
set res [catch "exec $args" result]
|
||||
}
|
||||
|
||||
# Run the shell command contained in arguments. Print an error and exit
|
||||
# if anything goes wrong.
|
||||
#
|
||||
proc mustbeok {args} {
|
||||
global res result
|
||||
set res [catch "exec $args" result]
|
||||
if {$res} {
|
||||
puts "FAILED: $args"
|
||||
puts $result
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# Write $content into a file named $filename. The file is overwritten if it
|
||||
# already exist. The file is create if it does not already exist.
|
||||
#
|
||||
proc writefile {filename content} {
|
||||
set fd [open $filename wb]
|
||||
puts $fd $content
|
||||
close $fd
|
||||
}
|
||||
|
||||
# Run the merge-test
|
||||
#
|
||||
foreach {branch configopts} {
|
||||
begin-concurrent {--enable-json1}
|
||||
begin-concurrent-pnu {--enable-json1}
|
||||
wal2 {--enable-all}
|
||||
reuse-schema {--enable-all}
|
||||
} {
|
||||
puts $branch
|
||||
set errorfile ${branch}-error.txt
|
||||
mustbeok fossil revert
|
||||
mustbeok fossil up $branch
|
||||
safeexec fossil merge trunk
|
||||
if {$res} {
|
||||
puts " merge failed - see $errorfile"
|
||||
writefile $errorfile $result
|
||||
} else {
|
||||
puts " merge ok"
|
||||
safeexec ./configure --enable-debug {*}$configopts
|
||||
if {$res} {
|
||||
puts " configure failed - see $errorfile"
|
||||
writefile $errorfile $result
|
||||
} else {
|
||||
puts " configure ok"
|
||||
safeexec make fuzzcheck sqlite3 testfixture
|
||||
if {$res} {
|
||||
puts " build failed - see $errorfile"
|
||||
writefile $errorfile $result
|
||||
} else {
|
||||
puts " build ok"
|
||||
safeexec make test
|
||||
if {$res} {
|
||||
puts " test failed - see $errorfile"
|
||||
writefile $errorfile $result
|
||||
} else {
|
||||
puts " test ok"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mustbeok fossil revert
|
||||
mustbeok fossil up trunk
|
||||
puts "reset back to trunk"
|
||||
+131
-29
@@ -4,16 +4,28 @@
|
||||
#
|
||||
# const char **azCompileOpt[]
|
||||
#
|
||||
# declaration used in src/ctime.c, run this script.
|
||||
# definition used in src/ctime.c, run this script from
|
||||
# the checkout root. It alters src/ctime.c in-place.
|
||||
#
|
||||
|
||||
# All Boolean compile time options.
|
||||
# All Boolean compile time options which default to something
|
||||
# other than 0 or empty. The default is paired with the PP
|
||||
# symbol so that a differing define can be detected.
|
||||
#
|
||||
set boolean_options {
|
||||
set boolean_defnnz_options {
|
||||
{SQLITE_HOMEGROWN_RECURSIVE_MUTEX 1}
|
||||
{SQLITE_POWERSAFE_OVERWRITE 1}
|
||||
{SQLITE_DEFAULT_MEMSTATUS 1}
|
||||
{SQLITE_OMIT_TRACE 1}
|
||||
{SQLITE_ALLOW_COVERING_INDEX_SCAN 1}
|
||||
}
|
||||
|
||||
# All Boolean compile time options which default to 0 or empty.
|
||||
#
|
||||
set boolean_defnil_options {
|
||||
SQLITE_32BIT_ROWID
|
||||
SQLITE_4_BYTE_ALIGNED_MALLOC
|
||||
SQLITE_64BIT_STATS
|
||||
SQLITE_ALLOW_COVERING_INDEX_SCAN
|
||||
SQLITE_ALLOW_URI_AUTHORITY
|
||||
SQLITE_BUG_COMPATIBLE_20160819
|
||||
SQLITE_CASE_SENSITIVE_LIKE
|
||||
@@ -25,7 +37,6 @@ set boolean_options {
|
||||
SQLITE_DEFAULT_CKPTFULLFSYNC
|
||||
SQLITE_DEFAULT_FOREIGN_KEYS
|
||||
SQLITE_DEFAULT_LOCKING_MODE
|
||||
SQLITE_DEFAULT_MEMSTATUS
|
||||
SQLITE_DEFAULT_RECURSIVE_TRIGGERS
|
||||
SQLITE_DEFAULT_SYNCHRONOUS
|
||||
SQLITE_DEFAULT_WAL_SYNCHRONOUS
|
||||
@@ -40,40 +51,49 @@ set boolean_options {
|
||||
SQLITE_ENABLE_8_3_NAMES
|
||||
SQLITE_ENABLE_API_ARMOR
|
||||
SQLITE_ENABLE_ATOMIC_WRITE
|
||||
SQLITE_ENABLE_CEROD
|
||||
SQLITE_ENABLE_BATCH_ATOMIC_WRITE
|
||||
SQLITE_ENABLE_BYTECODE_VTAB
|
||||
SQLITE_ENABLE_COLUMN_METADATA
|
||||
SQLITE_ENABLE_COLUMN_USED_MASK
|
||||
SQLITE_ENABLE_COSTMULT
|
||||
SQLITE_ENABLE_CURSOR_HINTS
|
||||
SQLITE_ENABLE_DBPAGE_VTAB
|
||||
SQLITE_ENABLE_DBSTAT_VTAB
|
||||
SQLITE_ENABLE_EXPENSIVE_ASSERT
|
||||
SQLITE_ENABLE_FTS1
|
||||
SQLITE_ENABLE_FTS2
|
||||
SQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
SQLITE_ENABLE_FTS3
|
||||
SQLITE_ENABLE_FTS3_PARENTHESIS
|
||||
SQLITE_ENABLE_FTS3_TOKENIZER
|
||||
SQLITE_ENABLE_FTS4
|
||||
SQLITE_ENABLE_FTS5
|
||||
SQLITE_ENABLE_GEOPOLY
|
||||
SQLITE_ENABLE_HIDDEN_COLUMNS
|
||||
SQLITE_ENABLE_ICU
|
||||
SQLITE_ENABLE_IOTRACE
|
||||
SQLITE_ENABLE_JSON1
|
||||
SQLITE_ENABLE_LOAD_EXTENSION
|
||||
SQLITE_ENABLE_LOCKING_STYLE
|
||||
SQLITE_ENABLE_MATH_FUNCTIONS
|
||||
SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
SQLITE_ENABLE_MEMSYS3
|
||||
SQLITE_ENABLE_MEMSYS5
|
||||
SQLITE_ENABLE_MULTIPLEX
|
||||
SQLITE_ENABLE_NORMALIZE
|
||||
SQLITE_ENABLE_NULL_TRIM
|
||||
SQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
SQLITE_ENABLE_OVERSIZE_CELL_CHECK
|
||||
SQLITE_ENABLE_PREUPDATE_HOOK
|
||||
SQLITE_ENABLE_QPSG
|
||||
SQLITE_ENABLE_RBU
|
||||
SQLITE_ENABLE_RTREE
|
||||
SQLITE_ENABLE_SELECTTRACE
|
||||
SQLITE_ENABLE_SESSION
|
||||
SQLITE_ENABLE_SNAPSHOT
|
||||
SQLITE_ENABLE_SORTER_REFERENCES
|
||||
SQLITE_ENABLE_SQLLOG
|
||||
SQLITE_ENABLE_STAT4
|
||||
SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
SQLITE_ENABLE_STMTVTAB
|
||||
SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
SQLITE_ENABLE_UNLOCK_NOTIFY
|
||||
SQLITE_ENABLE_UPDATE_DELETE_LIMIT
|
||||
@@ -85,8 +105,6 @@ set boolean_options {
|
||||
SQLITE_EXTRA_IFNULLROW
|
||||
SQLITE_FTS5_ENABLE_TEST_MI
|
||||
SQLITE_FTS5_NO_WITHOUT_ROWID
|
||||
SQLITE_HAS_CODEC
|
||||
SQLITE_HOMEGROWN_RECURSIVE_MUTEX
|
||||
SQLITE_IGNORE_AFP_LOCK_ERRORS
|
||||
SQLITE_IGNORE_FLOCK_LOCK_ERRORS
|
||||
SQLITE_INLINE_MEMCPY
|
||||
@@ -98,7 +116,6 @@ set boolean_options {
|
||||
SQLITE_MIXED_ENDIAN_64BIT_FLOAT
|
||||
SQLITE_MMAP_READWRITE
|
||||
SQLITE_MUTEX_NOOP
|
||||
SQLITE_MUTEX_NREF
|
||||
SQLITE_MUTEX_OMIT
|
||||
SQLITE_MUTEX_PTHREADS
|
||||
SQLITE_MUTEX_W32
|
||||
@@ -116,16 +133,15 @@ set boolean_options {
|
||||
SQLITE_OMIT_AUTOVACUUM
|
||||
SQLITE_OMIT_BETWEEN_OPTIMIZATION
|
||||
SQLITE_OMIT_BLOB_LITERAL
|
||||
SQLITE_OMIT_BTREECOUNT
|
||||
SQLITE_OMIT_CAST
|
||||
SQLITE_OMIT_CHECK
|
||||
SQLITE_OMIT_COMPLETE
|
||||
SQLITE_OMIT_COMPOUND_SELECT
|
||||
SQLITE_OMIT_CONFLICT_CLAUSE
|
||||
SQLITE_OMIT_CTE
|
||||
SQLITE_OMIT_DATETIME_FUNCS
|
||||
SQLITE_OMIT_DECLTYPE
|
||||
SQLITE_OMIT_DEPRECATED
|
||||
SQLITE_OMIT_DESERIALIZE
|
||||
SQLITE_OMIT_DISKIO
|
||||
SQLITE_OMIT_EXPLAIN
|
||||
SQLITE_OMIT_FLAG_PRAGMAS
|
||||
@@ -135,6 +151,7 @@ set boolean_options {
|
||||
SQLITE_OMIT_HEX_INTEGER
|
||||
SQLITE_OMIT_INCRBLOB
|
||||
SQLITE_OMIT_INTEGRITY_CHECK
|
||||
SQLITE_OMIT_INTROSPECTION_PRAGMAS
|
||||
SQLITE_OMIT_LIKE_OPTIMIZATION
|
||||
SQLITE_OMIT_LOAD_EXTENSION
|
||||
SQLITE_OMIT_LOCALTIME
|
||||
@@ -156,7 +173,6 @@ set boolean_options {
|
||||
SQLITE_OMIT_TCL_VARIABLE
|
||||
SQLITE_OMIT_TEMPDB
|
||||
SQLITE_OMIT_TEST_CONTROL
|
||||
SQLITE_OMIT_TRACE
|
||||
SQLITE_OMIT_TRIGGER
|
||||
SQLITE_OMIT_TRUNCATE_OPTIMIZATION
|
||||
SQLITE_OMIT_UTF16
|
||||
@@ -168,7 +184,6 @@ set boolean_options {
|
||||
SQLITE_OMIT_XFER_OPT
|
||||
SQLITE_PCACHE_SEPARATE_HEADER
|
||||
SQLITE_PERFORMANCE_TRACE
|
||||
SQLITE_POWERSAFE_OVERWRITE
|
||||
SQLITE_PREFER_PROXY_LOCKING
|
||||
SQLITE_PROXY_DEBUG
|
||||
SQLITE_REVERSE_UNORDERED_SELECTS
|
||||
@@ -177,7 +192,6 @@ set boolean_options {
|
||||
SQLITE_SMALL_STACK
|
||||
SQLITE_SOUNDEX
|
||||
SQLITE_SUBSTR_COMPATIBILITY
|
||||
SQLITE_SYSTEM_MALLOC
|
||||
SQLITE_TCL
|
||||
SQLITE_TEST
|
||||
SQLITE_UNLINK_AFTER_CLOSE
|
||||
@@ -191,7 +205,15 @@ set boolean_options {
|
||||
SQLITE_ZERO_MALLOC
|
||||
}
|
||||
|
||||
# All compile time options for which the assigned value is other than boolean.
|
||||
# All compile time options for which the assigned value is other than boolean
|
||||
# and is a comma-separated scalar pair.
|
||||
#
|
||||
set value2_options {
|
||||
SQLITE_DEFAULT_LOOKASIDE
|
||||
}
|
||||
|
||||
# All compile time options for which the assigned value is other than boolean
|
||||
# and is a single scalar.
|
||||
#
|
||||
set value_options {
|
||||
SQLITE_BITMASK_TYPE
|
||||
@@ -200,7 +222,6 @@ set value_options {
|
||||
SQLITE_DEFAULT_FILE_PERMISSIONS
|
||||
SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT
|
||||
SQLITE_DEFAULT_LOCKING_MODE
|
||||
SQLITE_DEFAULT_LOOKASIDE
|
||||
SQLITE_DEFAULT_MMAP_SIZE
|
||||
SQLITE_DEFAULT_PAGE_SIZE
|
||||
SQLITE_DEFAULT_PCACHE_INITSZ
|
||||
@@ -212,6 +233,7 @@ set value_options {
|
||||
SQLITE_DEFAULT_WAL_SYNCHRONOUS
|
||||
SQLITE_DEFAULT_WORKER_THREADS
|
||||
SQLITE_ENABLE_8_3_NAMES
|
||||
SQLITE_ENABLE_CEROD
|
||||
SQLITE_ENABLE_LOCKING_STYLE
|
||||
SQLITE_EXTRA_INIT
|
||||
SQLITE_EXTRA_SHUTDOWN
|
||||
@@ -245,13 +267,6 @@ set value_options {
|
||||
|
||||
# Options that require custom code.
|
||||
#
|
||||
set options(ENABLE_STAT3) {
|
||||
#if defined(SQLITE_ENABLE_STAT4)
|
||||
"ENABLE_STAT4",
|
||||
#elif defined(SQLITE_ENABLE_STAT3)
|
||||
"ENABLE_STAT3",
|
||||
#endif
|
||||
}
|
||||
set options(COMPILER) {
|
||||
#if defined(__clang__) && defined(__clang_major__)
|
||||
"COMPILER=clang-" CTIMEOPT_VAL(__clang_major__) "."
|
||||
@@ -268,13 +283,26 @@ set options(HAVE_ISNAN) {
|
||||
"HAVE_ISNAN",
|
||||
#endif
|
||||
}
|
||||
set options(OMIT_DATETIME_FUNCS) {
|
||||
#if defined(SQLITE_OMIT_DATETIME_FUNCS) || defined(SQLITE_OMIT_FLOATING_POINT)
|
||||
"OMIT_DATETIME_FUNCS",
|
||||
#endif
|
||||
}
|
||||
set options(SYSTEM_MALLOC) "\
|
||||
#if (!defined(SQLITE_WIN32_MALLOC) \\
|
||||
&& !defined(SQLITE_ZERO_MALLOC) \\
|
||||
&& !defined(SQLITE_MEMDEBUG) \\
|
||||
) || defined(SQLITE_SYSTEM_MALLOC)
|
||||
\"SYSTEM_MALLOC\",
|
||||
#endif
|
||||
"
|
||||
set options(THREADSAFE) {
|
||||
#if defined(SQLITE_THREADSAFE)
|
||||
"THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
|
||||
#elif defined(THREADSAFE)
|
||||
"THREADSAFE=" CTIMEOPT_VAL(THREADSAFE),
|
||||
#else
|
||||
"THREADSAFE=1"
|
||||
"THREADSAFE=1",
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -286,7 +314,20 @@ proc trim_name {in} {
|
||||
return $ret
|
||||
}
|
||||
|
||||
foreach b $boolean_options {
|
||||
foreach name_defval $boolean_defnnz_options {
|
||||
set b [lindex $name_defval 0]
|
||||
set defval [lindex $name_defval 1]
|
||||
set name [trim_name $b]
|
||||
set options($name) [subst {
|
||||
#ifdef $b
|
||||
# if $b != $defval
|
||||
"$name=" CTIMEOPT_VAL($b),
|
||||
# endif
|
||||
#endif
|
||||
}]
|
||||
}
|
||||
|
||||
foreach b $boolean_defnil_options {
|
||||
set name [trim_name $b]
|
||||
set options($name) [subst {
|
||||
#if $b
|
||||
@@ -303,9 +344,70 @@ foreach v $value_options {
|
||||
#endif
|
||||
}]
|
||||
}
|
||||
|
||||
foreach v $value2_options {
|
||||
set name [trim_name $v]
|
||||
set options($name) [subst {
|
||||
#ifdef $v
|
||||
"$name=" CTIMEOPT_VAL2($v),
|
||||
#endif
|
||||
}]
|
||||
}
|
||||
|
||||
foreach o [lsort [array names options]] {
|
||||
puts [string trim $options($o)]
|
||||
# Split a string on a regex, return all parts in order.
|
||||
# Any elements with an even index may be empty.
|
||||
# Elements with odd indices will match the regex.
|
||||
proc split_on_re {re str {nrepps 1}} {
|
||||
set chunks {}
|
||||
set cix 0
|
||||
set resm [regexp -all -inline -indices $re $str]
|
||||
if {[llength $resm]==0} {
|
||||
return $str
|
||||
}
|
||||
set rix 0
|
||||
while {$rix < [llength $resm]} {
|
||||
set mre [lindex $resm $rix]
|
||||
incr rix $nrepps
|
||||
set mbx [lindex $mre 0]
|
||||
set mex [lindex $mre 1]
|
||||
lappend chunks [string range $str $cix [expr $mbx - 1]]
|
||||
lappend chunks [string range $str $mbx $mex]
|
||||
set cix [expr $mex + 1]
|
||||
}
|
||||
lappend chunks [string range $str $cix end]
|
||||
return $chunks
|
||||
}
|
||||
|
||||
|
||||
set ctime_c "src/ctime.c"
|
||||
if {[catch {set cfd [open $ctime_c r]}]!=0} {
|
||||
puts stderr "File '$ctime_c' unreadable. Run this script from checkout root."
|
||||
exit 1;
|
||||
}
|
||||
|
||||
set ctfc [read $cfd]
|
||||
close $cfd
|
||||
|
||||
set re {/\*\s+\*+\s*((BEGIN)|(END)) CODE GENERATED BY (\S+)\s+\*/\s+}
|
||||
set renpp 5
|
||||
|
||||
set ctfcChunks [split_on_re $re $ctfc $renpp]
|
||||
if {[llength $ctfcChunks] != 5} {
|
||||
puts stderr "File '$ctime_c' has too few generated code markers."
|
||||
exit 1;
|
||||
}
|
||||
|
||||
if {[catch {set cfd [open $ctime_c w]}]!=0} {
|
||||
puts stderr "File '$ctime_c' unwritable."
|
||||
exit 1;
|
||||
}
|
||||
|
||||
puts -nonewline $cfd [lindex $ctfcChunks 0]
|
||||
puts -nonewline $cfd [lindex $ctfcChunks 1]
|
||||
foreach o [lsort [array names options]] {
|
||||
puts $cfd [string trim $options($o)]
|
||||
}
|
||||
puts -nonewline $cfd [lindex $ctfcChunks 3]
|
||||
puts -nonewline $cfd [lindex $ctfcChunks 4]
|
||||
|
||||
close $cfd
|
||||
|
||||
+6
-5
@@ -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 \
|
||||
|
||||
+11
-2
@@ -912,10 +912,19 @@ static void page_usage_btree(
|
||||
int cellstart = hdr+12;
|
||||
u32 child;
|
||||
for(i=0; i<nCell; i++){
|
||||
u32 cellidx;
|
||||
u32 ofst;
|
||||
|
||||
ofst = cellstart + i*2;
|
||||
ofst = a[ofst]*256 + a[ofst+1];
|
||||
cellidx = cellstart + i*2;
|
||||
if( cellidx+1 >= g.pagesize ){
|
||||
printf("ERROR: page %d too many cells (%d)\n", pgno, nCell);
|
||||
break;
|
||||
}
|
||||
ofst = a[cellidx]*256 + a[cellidx+1];
|
||||
if( ofst<cellidx+2 || ofst+4>=g.pagesize ){
|
||||
printf("ERROR: page %d cell %d out of bounds\n", pgno, i);
|
||||
continue;
|
||||
}
|
||||
child = decodeInt32(a+ofst);
|
||||
page_usage_btree(child, pgno, i, zName);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user