Compare commits

..

43 Commits

Author SHA1 Message Date
drh c0359f0490 If a subquery is used to drive an index, this change avoids making an extra
copy of the result of that subquery.  But, such situations are probably
sufficiently unusual that the added complexity of this enhancement is not
worth the performance gain.  So I'm going to park this check-in on a branch.
If we later find a use case to justify it, we can merge it to trunk then.
This is the "further change" that was promised by the prior check-in comment.

FossilOrigin-Name: 4488cb883e155a7466946d25569ab2816c4a8de9d4c7d540f5053ea5334e7ae5
2021-05-28 14:28:54 +00:00
drh e9de65201c Make a deep copy of the result of a subquery in case the subquery is
reused.  Fix for the problem reported by
[forum:/forumpost/28216b36ac|forum post 28216b36ac] and introduced by
check-in [f30fb19ff763a7cb].  Further changes to try to optimize the new
OP_Copy opcode back into either OP_SCopy or OP_Move will be attempted
separately.  A test case will be in TH3.

FossilOrigin-Name: c9f0b9cb0aef107265435e22c164dd3c974eadfd00abf7cfd4fc7ec95c0dd7d0
2021-05-28 12:48:31 +00:00
drh d2f55773f1 Fix a potential memory leak in json_group_object() following an error.
dbsqlfuzz cd32630de3ff039d97089592b63cb3616f8ec9dd

FossilOrigin-Name: 21676731cedae27d1ab9fe62b269001ae6e3eeb3caa87b4f5536f777631a8bbc
2021-05-28 12:15:19 +00:00
drh 48a296c589 Add the merge-test.tcl script to ease verification of LTS branches.
FossilOrigin-Name: f958ffbc61c693b71538cc3aa5f95ce0f0b5d4906efbb0c075f543e19883a669
2021-05-27 16:31:04 +00:00
drh 342cb33b23 Improved comment on the prpagateConstants() routine. No changes to executable
code.

FossilOrigin-Name: d61a875df48d8baab3ada0174c8e0312a9268bbd11bf104b4385eff9e2744266
2021-05-27 14:09:01 +00:00
drh 48f4f27cfb Remove a NEVER that is reachable following OOM in writable_schema=ON mode
with a corrupt schema.

FossilOrigin-Name: 4eb80b0cc61526c1ff7478b1b855b29fa4326daee61facd1d85e4297bb32ac9d
2021-05-27 10:23:16 +00:00
drh 7d11e647ad Improvements to the constant-propagation optimization in order to better
deal with unusual affinities.  See
[forum:/forumpost/6a06202608|forum post 6a06202608] for more detail.

FossilOrigin-Name: 9be208a6d70582c6808abe6e016ab9cd8d10f0deefb8c7a8c0543372cca15b12
2021-05-26 23:10:19 +00:00
drh a8ed515400 Minor optimization to opcode comparison logic in the fixes to
the constant-propagation optimization on this branch.

FossilOrigin-Name: f17dec40a0ccc044bd32e035fc10797552329af242408a45f36125ed8d2ef088
2021-05-26 19:52:21 +00:00
dan c3b48848b3 Add new test file whereM.test. Containing tests for the change on this branch.
FossilOrigin-Name: c4c76b824c41afb5b4d7b397c4d3142698aa303ea3a368c0cc7af4884e3a10bd
2021-05-26 19:37:27 +00:00
dan 40b82f9dc6 Avoid assuming that an expression like "x=10" in a WHERE clause implies that CASE(x AS TEXT)=='10'.
FossilOrigin-Name: 389ec669f416c74d651e25572f6e007c2a62ddd4027524f553107b06db5c55eb
2021-05-26 18:51:57 +00:00
drh 14c4d42874 Take care that the code is not generated for the same Select object more
than once, as transformations that apply during the first pass might
cause problems for the second pass.
dbsqlfuzz 836b625cd8a41809ef80fc7ebaa6554357bcb463.

FossilOrigin-Name: f30fb19ff763a7cbe768ea49954704e14d6400f69bb4257c9c890e1564e14835
2021-05-26 18:46:51 +00:00
dan 151446e793 Update an assert() in wherecode.c that might fail following an unrelated SQL error.
FossilOrigin-Name: 3e2c36a8272ab3c1777638c0ed8222e7ff04657fe1c40f74a63b99a5a90258cc
2021-05-26 14:32:33 +00:00
dan 137b8ebb2b Do not run sessionbig.test as part of the session_strm permutation. It is too slow.
FossilOrigin-Name: 708ce7ad8acee702d08d1987aa253b0bfc3fd97255d6e4153122b03eba337570
2021-05-25 16:10:12 +00:00
dan 4df68e0ae5 Update an allocation routine in the sessions module to allow it to allocate the maximum size permitted by sqlite3_realloc64().
FossilOrigin-Name: 0b45e821911e4a852edd6d9e9cfe5f9de33337edf76fb12b79adaf11a4b83e8a
2021-05-25 15:21:54 +00:00
dan 78a9d7551c Enhance the shell tool ".dump PATTERN" command so that it dumps the contents of shadow tables when a virtual table is identified by the PATTERN.
FossilOrigin-Name: b0bc5ab9ceec496ac260ccfd53b51a2b53a81576fbe04c97b99f6705b063c59f
2021-05-25 11:39:14 +00:00
dan c00727ab58 Fix a problem in the in-memory journal code that could occasionally lead to a segfault when a sub-transaction that modified zero pages was committed.
FossilOrigin-Name: 17960165f5840cab45b7a8bb02779ebfb321c68f33ec6da9ab14063ccd134fa4
2021-05-24 14:35:19 +00:00
drh 0fcf6f01e7 Minor comment improvements in fuzzcheck.c.
FossilOrigin-Name: 7aca8d52c16c2192d9c1ff03a976c482a60365cef8d2474b540ff4c84e8737b4
2021-05-24 12:28:13 +00:00
drh b6b06bb339 New dbsqlfuzz cases added to test/fuzzdata8.db.
FossilOrigin-Name: 5bb5c9ec049488f95e47bbd9f1db9038ffabad3cfafa613acdaa790ab4034eee
2021-05-24 12:13:10 +00:00
drh bf7f3a005e Fix the TreeView module so that it works with the TK_ERROR exprssion.
Also fix an assert() that was failing due to the recent TK_ERROR addition.

FossilOrigin-Name: dd56fbe0cfb0f7848190ce097b378321dd25ae509c7edf93682b091014824fc6
2021-05-24 11:35:16 +00:00
drh 0542812726 Additional defenses (above and beyond [b986600520696b0c]) to prevent an
invalid subquery from causing problems downstream.  If an error is found
while analyzing a subquery expression, change the expression to TK_ERROR
so inhibit further processing on that expression.
dbsqlfuzz cf624b8c0484c66e0f552bf6475e3e3f2c22b24e.

FossilOrigin-Name: 0be6b6c9f7c562e764792a4a5eb53ed11b230174b19361f7cd7778c743314bbd
2021-05-24 00:17:04 +00:00
drh 7cc73b399e Do not push a WITH clause onto the processing stack if prior errors have
occurred.  dbsqlfuzz 6b7a144674e215f06ddfeb9042c873d9ee956ac0.

FossilOrigin-Name: c2066dde53b9872dbb991e27419dd031791c942fe23826556f52efbd66c51662
2021-05-23 17:47:04 +00:00
drh 5e1a7ded4d Do not invoke sqlite3ExprAffinity() after a syntax error that might have
left the tree in an inconsistent state.  See also [e8a1515b44380cc5] and
[forum:/forumpost/7e484e225c|forum post 7e484e225c].

FossilOrigin-Name: b986600520696b0c91c4ccc6aff1b698391b4bcaf8a3ea436be1967883faa2fe
2021-05-22 11:23:20 +00:00
drh ff9186137d The fix in the previous check-in was only correct if the OOM occurs on
the initial allocation.  This changes should make it correct for a resize
as well.

FossilOrigin-Name: 57087ab2f297e4d96da5b9f3b89a26d8dd2bc4d22c2be8045b5d956d86282f39
2021-05-22 11:00:03 +00:00
drh d42dbd9dfe If an FTS5 Cursor fails to enlarge the space for the aInst array, set the
size of the aInst array to zero.
dbsqlfuzz 294254b8105cca409f27a711f1eb2e9e63cbcac5.

FossilOrigin-Name: 4ae5e5b5ecbce580d3f7f970076e828fc6fb5fbcdc3bbe8381ab38f52870a54f
2021-05-22 01:30:30 +00:00
drh 93c8139c1a If there are errors in a nested CTE, be sure to abandon processing. Do not
continue since the parse tree may have been left in a goofy state which could
cause use-after-free and segfaults.
See [forum:/forumpost/aa4a7a3980|forum post aa4a7a3980] for an example.

FossilOrigin-Name: 94225d693932eb0b5d7799d40513afbd31ed40e1e156675eb92ad7216f1ff20f
2021-05-21 21:49:07 +00:00
dan acef1abda2 Fix a problem with SQLITE_MAX_MEMORY in malloc.c.
FossilOrigin-Name: c18dbe2f389f4ba7b219b7995d4f7009d1bc249ef8f93a30b262c6d2c008319d
2021-05-21 16:41:22 +00:00
drh ec2f689b21 Fix a faulty assert() statement in sqlite3ExprListDup(). This is a continuation
of the fix at [59812e7ef705226c].

FossilOrigin-Name: 240f7494bfa3e0806ae2f971e78039c62a419de647cb9e807309f90e1d2a536d
2021-05-20 23:25:28 +00:00
drh a76b7f5296 Enhance one test case to use various alternative definitions of DUAL.
FossilOrigin-Name: 179dcb6ba771f0e94e06b5e3c5534d8005d27b2c9b4601be20fd68abfbc5dfd0
2021-05-20 18:11:45 +00:00
dan 90bc36fb30 Ensure that objects within view definitions are not incorrectly resolved to CTEs that are part of the statement using the view.
FossilOrigin-Name: f7dcc4b5197c6413be31384b390bb98a737d3f9edb7964433448c3b90b35a436
2021-05-20 17:15:06 +00:00
dan a8f249f1e7 Ensure the required b-tree mutexes are held for "CREATE TABLE IF NOT EXISTS" and "DROP TABLE IF EXISTS" statements on attached databases.
FossilOrigin-Name: 67bde01614edd944b769ab28488bac1dbbf17d88beee62ca7f1e45681aa3d402
2021-05-20 11:42:51 +00:00
drh cd1499f47b Replace [0f0959c6f95046e8] with a new and better solution that also fixes the
CTE name resolution problem described in
[forum:/forumpost/8590e3f6dc|forum post 8590e3f6dc].
Test cases for both problems added.

FossilOrigin-Name: 5614279daff5007d6e047c5c1b3cc82ba80a5c91c529525b0fe68b79ee82dd2c
2021-05-20 00:44:04 +00:00
drh 5da5b71435 Fixes and improvements to PRAGMA compile_options.
FossilOrigin-Name: 34579549a3bc1c2cfbf47a4770c1d7abc97869ba57bcd3ab1515765ca505ea05
2021-05-20 00:10:24 +00:00
drh 1168f81092 When constructing the synthensized SELECT statement that is used to choose
the rows in an UPDATE FROM, make sure the first table is really the table
being updated, and not some common-table expression that happens to have the
same name.  [forum:/forumpost/a274248080|forum post a274248080].  More
changes associated with CTE name resolution are pending.

FossilOrigin-Name: 0f0959c6f95046e8e7887716e0a7de95da18d1e926ab1f919527083a56541db5
2021-05-19 21:55:56 +00:00
larrybr 14e250ac16 Incorporate ..._DESERIALIZE revision.
FossilOrigin-Name: b70587cca9e4f0116621e27362186e9329bcea8016c6565cd3ec5a9bf4a99d46
2021-05-19 20:01:53 +00:00
larrybr 4f878f33a9 merge from trunk
FossilOrigin-Name: 19ffe3cfe278a4046f32df56f75080c2377e4c44ad40a02d39db8e7701526204
2021-05-19 19:55:10 +00:00
drh 1f4f7c7a41 Add a comment with useful information about SHM locking. No changes to
deliverable code.

FossilOrigin-Name: 4e81ea3b15fb3fce5f31b77273639e748a735ab0970620e564e9a5c977b24a1a
2021-05-19 19:28:48 +00:00
larrybr 3ec4861c00 merge latest trunk
FossilOrigin-Name: 3ff228249adf2da345d3e19e9af3e23d1354f6b9a35ddbe9864e1a07716d871c
2021-04-27 04:47:27 +00:00
larrybr 7d0a2f3fe3 Merge trunk bug/test fixes
FossilOrigin-Name: 830b0b1c49aaca53a40e5a4ca9a11351d697a980c7bf80379e32f0646738d566
2021-04-17 20:13:35 +00:00
larrybr c7a409e78e Merge from trunk.
FossilOrigin-Name: 43894f0b5b4f000a929052bc32822d704d25d139375362fad77f8824b5aad456
2021-04-16 23:53:07 +00:00
larrybr 89eab376da Merge from trunk.
FossilOrigin-Name: d762784a46946c5a5d565d7ef8ae243703eb38eb71d6101a7f2ed6d22eff1c53
2021-04-16 15:44:32 +00:00
larrybr 5ae13144ef Dial back assumptions on compile option defaults to reflect actual conditionals.
FossilOrigin-Name: cb3127725dbb9490f9bb3a95d7fd52acd78390981ee8b7c6da35bdfb84ad0359
2021-04-16 10:25:54 +00:00
larrybr cf5ad4210e Merge from (forked) trunk. Handle compile options that differ from default by being 0.
FossilOrigin-Name: 6eb83f83d280f82bd225972f52c52922257303740a968457ff0be08d43993d59
2021-04-15 23:43:25 +00:00
larrybr f8fb27f4a9 Bring pragma compile_options up to date. And make mkctimec.tcl help do so.
FossilOrigin-Name: 63ea3e298c575a408e5c5e12368292c966db6dcffcb6e1c770734f28b8757635
2021-04-15 00:26:34 +00:00
35 changed files with 1050 additions and 209 deletions
+4 -2
View File
@@ -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;
}
+1 -1
View File
@@ -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);
+103
View File
@@ -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
+19 -3
View File
@@ -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 ){
+41 -33
View File
@@ -1,5 +1,5 @@
C Fix\sa\sformatting\serror\son\sthe\scomment.
D 2021-05-19T19:27:42.183
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
@@ -120,7 +120,7 @@ F ext/fts5/fts5_config.c 8336d0ff6db0933f63cfec8ae0ab76e68393259cbccc0b46e1f79f7
F ext/fts5/fts5_expr.c 9462249a3bb82d0e49b163500f9d2197c2e4cd95bf440a9bbfc3906b22ea1e1b
F ext/fts5/fts5_hash.c 1aa93c9b5f461afba66701ee226297dc78402b3bdde81e90a10de5fe3df14959
F ext/fts5/fts5_index.c 222b5e56f51139ca5400985e26ea9971165901c7a45a2c17499bd2be3695c697
F ext/fts5/fts5_main.c f497ca97cb2802311ec93733b595762dc5b044ce3c6c8ce5fb3e871dd3fccd5d
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
@@ -305,7 +305,7 @@ F ext/misc/fileio.c 9b69e25da3b51d4a1d905a464ccb96709792ad627a742ba09215bc0d1447
F ext/misc/fossildelta.c 1240b2d3e52eab1d50c160c7fe1902a9bd210e052dc209200a750bbf885402d5
F ext/misc/fuzzer.c eae560134f66333e9e1ca4c8ffea75df42056e2ce8456734565dbe1c2a92bf3d
F ext/misc/ieee754.c cd6ab89f85fda8a020559b3f4d03001a8a62dd856beda5af3f558621d12be913
F ext/misc/json1.c 2c5c0dbc7fa303f0213f008e5878db9f0e5875fe8ff59a7c2d9f235b18e323a7
F ext/misc/json1.c 76c5d9e0960fd15b4be79dacb76d872b4d0d983ce13e72ebfe9481d82cb9345d
F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d
F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b
F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567
@@ -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,7 +457,7 @@ 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.c af0cb1163e224b286a9cba3c1ad877d927821e6a0e317c29b289a16e5da378a8
F ext/session/sqlite3session.h 0907de79bc13a2e3af30a6dc29acc60792a3eaf7d33d44cf52500d0f3c2b2171
F ext/session/test_session.c f433f68a8a8c64b0f5bc74dc725078f12483301ad4ae8375205eef790274a787
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
@@ -477,9 +478,9 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c df53c39fd4f32528fc7ad8188b3bf2b506e1a8b3bb975b14f16a1bc6e901950f
F src/alter.c e2e0e6be8a53cc5c145d9ff4f82a2c8d6851468a366ac8b5bd7306c792e37619
F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c
F src/attach.c 42774f1f26f6970aef07a206f0afa5d73fea5d2bb84d5a8f687a7f56f00f2a3a
F src/attach.c a514e81758ba7b3a3a0501faf70af6cfc509de8810235db726cfc9f25165e929
F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853
F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
@@ -487,15 +488,15 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
F src/btree.c 51ba86095316fceb3e25bc61617d673d84627e79f4ace83f8722910f33eedef3
F src/btree.h 096cc53baa58be22b02c896d1cf933c38cfc6d65f9253c1367ece8cc88a24de5
F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0
F src/build.c 4e13b92f77d3f6dc1285c3636a2ba7c6af5cbb793e52075a762fbcebcd36e968
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 1d5171fe602cd56ab8b9c9ecbd48d9917e6020cafd6bd87ceac5949e8a1ed2d8
F src/expr.c 09f8ae1421d09802b4ac4b05c507761ecd142fa32cc0b1e33b9bd07fba10d34a
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4
F src/func.c 88fd711754a7241cb9f8eb1391370fd0c0cea756b3358efa274c5d1efd59af93
@@ -508,14 +509,14 @@ F src/insert.c 2189e0e596010a0dc5405d9f14f78db1ee2fa71138c931f5b6ea96610b95bfc1
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067
F src/main.c 2b2044221a10e7c5f49a98f50563ce9a944511241ba5946d1754dcc2a7437a07
F src/malloc.c c1af4ac5a463648cd2953fd4ac679b3ba9022ce5ec794a60806150ad69dfd33a
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 f6ce717b26cd51a24cda62fce611b4b72b3db367113374aa498e489a69470715
F src/memjournal.c 431c70a111223a8a6e2e7e9f014afc6c88d818d357d866afc563195f2277d50e
F src/memjournal.c a85f0dc5c02a42453d0bc3819ecfb5666cb6433e5deefcd93ccbe05c9f088b83
F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8
F src/mutex.c 5e3409715552348732e97b9194abe92fdfcd934cfb681df4ba0ab87ac6c18d25
F src/mutex.h a7b2293c48db5f27007c3bdb21d438873637d12658f5a0bf8ad025bb96803c4a
@@ -532,7 +533,7 @@ F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 95c255256b13827caf038c8f963d334784073f38ab6ef9d70371d9d04f3c43e0
F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f
F src/parse.y ac294bd2891c4310b0b23a67ea3bbca2d0bf5b7662c4444b6517c3986be4a437
F src/parse.y 8920f4444957d7827ca458029b2e41ffa32dd3b72917be0b52cae0aace3eadb5
F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
F src/pcache1.c 388304fd2d91c39591080b5e0f3c62cfba87db20370e7e0554062bfb29740e9f
@@ -543,12 +544,12 @@ F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c 40e216d9a72e52841a9c8e0aec7d367bade8e2df17b804653b539b20c1ab5660
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c 09acd5a12c4229238919e38816d0d5c90b24015ef495afb825dc1b3f2a8cf18a
F src/shell.c.in 1b32ba2918ede13b68df47c7b92b72ba0d06e68d384e78bb9d7456527271d400
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 16d132f4380f9f4ebf9db6b803ddde641aa2c917964b028404d09459cf83533f
F src/sqliteInt.h 6d0c49ed218f9f6ffabfdc8bed1a5de89f61e70c96a62156aeebeb20c1be9bf0
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -608,14 +609,14 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c bae853ad129d1129c063de8630a3e99e306283bc40146f359b1bb91be2c08f1e
F src/treeview.c e483aeedf6f207000db1f90eb6abd816350493314c30e8749d319bdb9ab3b08c
F src/treeview.c 21449a944d5abd3ac07b7eab76f7221e20c9480d06f01798f8dc66d9bc361769
F src/trigger.c e0fd347b2571a2d956318cdc6d011ccca7ce862d10a0ca04188a37920ef5440c
F src/update.c b3abdaf4a314bbed238da69a6ca54c0f21262119389b412ee5778fffe62dd3cc
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 74491791630743ef5215a90e6ec94c0965577b9b7086b2180d2c7fa0954317a8
F src/vdbe.c 73e5a8b64a77359f4287d76f168e89d12ba967cbb72a3d7619650568e9c1d66c
F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe
F src/vdbeInt.h 58980223a32495ad059d10581b83e133abdc77248b1bab85c080cab8a13bd819
F src/vdbeapi.c d9e99daf59fec928986838b3389a7337e82fec6b3b5de30206cb99fb4661b94e
@@ -632,9 +633,9 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
F src/walker.c 7342becedf3f8a26f9817f08436bdf8b56ad69af83705f6b9320a0ad3092c2ac
F src/where.c 32f41c3c93c6785e0077e3a2cdc669c3ccfe70173787847be77f294c18fc7dc3
F src/whereInt.h 9248161dd004f625ce5d3841ca9b99fed3fc8d61522cf76340fc5217dbe1375b
F src/wherecode.c 110ed13049e0f1dc27e9dd942eb870417b36480cb7819302f5804cbcf9330b0e
F src/wherecode.c bcfee3789a7d3da1f3f8a76c1b20c95d6c0fc4ea93c5d9b03206a432ac8b1cc4
F src/whereexpr.c 5a9c9f5d2dac4bcdcaae3035034b4667523f731df228e0bb1d4efc669efa9da5
F src/window.c ce5e73ab88a8527d268673906bf89cbe58c61bca8d54d38ed8c33c3220a276ee
F src/window.c a6d624d83b2d5b3cfb82bb437a2fbae759c928d47dc9ad1338a9419269181bb2
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
F test/affinity3.test eecb0dabee4b7765a8465439d5e99429279ffba23ca74a7eae270a452799f9e7
@@ -1047,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 c51cdb34e926d0a6551624aa1f04c456c29317b5457855d64391917d9b4c2aff
F test/fuzzcheck.c 37f09efcd982048694d8b06fa3ef817df17f2a82e90af85cb3fb8eddd0f57ec4
F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
@@ -1055,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 5e616432bbdd9b27014463545cae06797790645021fbc650d28c994b4f02a6f5
F test/fuzzdata8.db 29ca3c47821abb626309e0d182b0f00ad3b49638370daee855641b9abc36dfa2
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc
@@ -1190,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
@@ -1265,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
@@ -1313,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
@@ -1656,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
@@ -1681,6 +1683,7 @@ F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2
F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
F test/view.test ea88361d5e9bc8eabf9f573185a16aea73a885be9b6c6a95ae84908913416a80
F test/view2.test db32c8138b5b556f610b35dfddd38c5a58a292f07fda5281eedb0851b2672679
F test/vtab1.test 99c0c13b5336ca7f87f137459de144b2f396bb8563fbd602e46bfaa425e3d8cc
F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
@@ -1762,6 +1765,7 @@ F test/whereI.test c4bb7e2ca56d49bd8ab5c7bd085b8b83e353922b46904d68aefb3c7468643
F test/whereJ.test fc05e374cc9f2dc204148d6c06822c380ad388895fe97a6d335b94a26a08aecf
F test/whereK.test 0270ab7f04ba5436fb9156d31d642a1c82727f4c4bfe5ba90d435c78cf44684a
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
@@ -1770,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 7cb66f49d30d89ca9d28dc20f7f1d85229365651e8e6211f7da1448740866511
F test/window1.test 49eadb28b0bae0f916518c9983b1fb7450c198915664f323b2bfc480cc98c431
F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476
F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
@@ -1790,8 +1794,8 @@ 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
@@ -1838,9 +1842,10 @@ 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
@@ -1913,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 b480aacb3430a789d98ffd81a1886bbbc3cda5b0e736ec9a3e2b463db2a3b3ad
R 51a5c10eeb74e980a28bc317ddd05223
P c9f0b9cb0aef107265435e22c164dd3c974eadfd00abf7cfd4fc7ec95c0dd7d0
R c044497982752ba303617f7de106b59c
T *branch * copy-optimization
T *sym-copy-optimization *
T -sym-trunk *
U drh
Z 312f630c2639a44670ce7c2d40505de2
Z 0c06d6f1ffda88b03d3d1e66ad233058
+1 -1
View File
@@ -1 +1 @@
6f2fb60e499fc758bea6ffec030fef8ab5f97d08d31450f0b3ffafc20e652891
4488cb883e155a7466946d25569ab2816c4a8de9d4c7d540f5053ea5334e7ae5
+1 -1
View File
@@ -919,7 +919,7 @@ static RenameToken *renameTokenFind(
void *pPtr
){
RenameToken **pp;
if( NEVER(pPtr==0) ){
if( pPtr==0 ){
return 0;
}
for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){
+10 -7
View File
@@ -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;
}
+1
View File
@@ -1070,6 +1070,7 @@ static void sqlite3ForceNotReadOnly(Parse *pParse){
Vdbe *v = sqlite3GetVdbe(pParse);
if( v ){
sqlite3VdbeAddOp3(v, OP_JournalMode, 0, iReg, PAGER_JOURNALMODE_QUERY);
sqlite3VdbeUsesBtree(v, 0);
}
}
+41 -22
View File
@@ -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
+46 -32
View File
@@ -445,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 ){
@@ -561,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;
@@ -570,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;
}
/*
@@ -1508,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 );
@@ -2981,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 );
@@ -3092,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:
**
@@ -3109,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);
}
@@ -3173,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 */
@@ -4016,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;
}
@@ -4359,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
View File
@@ -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 ){
+20 -18
View File
@@ -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;
}
+1
View File
@@ -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
+103 -27
View File
@@ -4417,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 */
};
@@ -4455,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,
@@ -4496,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);
@@ -4527,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.
**
@@ -4562,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 */
@@ -4575,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));
@@ -5011,6 +5074,7 @@ static struct Cte *searchWith(
return &p->a[i];
}
}
if( p->bView ) break;
}
return 0;
}
@@ -5020,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,
@@ -5066,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;
@@ -5315,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
@@ -6396,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
@@ -6495,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;
+21 -6
View File
@@ -7739,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;
}
}
}
@@ -7765,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",
@@ -7775,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
+2
View File
@@ -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 */
@@ -3925,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.... */
};
+8
View File
@@ -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;
+1
View File
@@ -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;
+1
View File
@@ -7247,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
+8 -3
View File
@@ -752,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 ){
@@ -773,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;
}
@@ -1122,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);
}
}
+1 -1
View File
@@ -958,7 +958,7 @@ static int disallowAggregatesInOrderByCb(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 */
+8 -8
View File
@@ -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
BIN
View File
Binary file not shown.
+48
View File
@@ -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
+1
View File
@@ -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)]
+13
View File
@@ -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
+32
View File
@@ -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
+49
View File
@@ -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
+112
View File
@@ -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
+17
View File
@@ -2159,4 +2159,21 @@ do_catchsql_test 68.0 {
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
+44 -14
View File
@@ -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
+62
View File
@@ -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
+99
View File
@@ -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
View File
@@ -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