Incorporate the SQLITE_CHECKPOINT_TRUNCATE enhancement and a couple of
obscure bug fixes from trunk. FossilOrigin-Name: 34ffa3b3c002b0e87d8382ad76e87dbaec0b2bc6
This commit is contained in:
commit
34794c3d0c
@ -183,7 +183,7 @@ static int isVowel(const char *z){
|
||||
** by a consonant.
|
||||
**
|
||||
** In this routine z[] is in reverse order. So we are really looking
|
||||
** for an instance of of a consonant followed by a vowel.
|
||||
** for an instance of a consonant followed by a vowel.
|
||||
*/
|
||||
static int m_gt_0(const char *z){
|
||||
while( isVowel(z) ){ z++; }
|
||||
|
44
manifest
44
manifest
@ -1,5 +1,5 @@
|
||||
C Merge\sall\srecent\sfixes\sand\senhancements\sfrom\strunk\sinto\ssessions.
|
||||
D 2014-12-02T16:31:01.447
|
||||
C Incorporate\sthe\sSQLITE_CHECKPOINT_TRUNCATE\senhancement\sand\sa\scouple\sof\nobscure\sbug\sfixes\sfrom\strunk.
|
||||
D 2014-12-04T23:35:08.510
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in e2007fafb7b679a39800a1d636dcc6662a840530
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -86,7 +86,7 @@ F ext/fts3/fts3_expr.c 40123785eaa3ebd4c45c9b23407cc44ac0c49905
|
||||
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
|
||||
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
|
||||
F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5
|
||||
F ext/fts3/fts3_porter.c 7f8b4bf5af7c0f20f73b8e87e14fa9298f52e290
|
||||
F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
|
||||
F ext/fts3/fts3_snippet.c 51beb5c1498176fd9caccaf1c75b55cb803a985a
|
||||
F ext/fts3/fts3_term.c a521f75132f9a495bdca1bdd45949b3191c52763
|
||||
F ext/fts3/fts3_test.c 8a3a78c4458b2d7c631fcf4b152a5cd656fa7038
|
||||
@ -199,7 +199,7 @@ F src/complete.c c4ba6e0626bb94bc77a0861735f3382fcf7cc818
|
||||
F src/ctime.c df19848891c8a553c80e6f5a035e768280952d1a
|
||||
F src/date.c 93594514aae68de117ca4a2a0d6cc63eddf26744
|
||||
F src/delete.c 20a360262b62051afacb44122b3593a8bd9be131
|
||||
F src/expr.c 73de4c0da2eed6b149d40a05c589dfeb2c4a87a1
|
||||
F src/expr.c 00da3072f362b06f39ce4052baa1d4ce2bb36d1c
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7
|
||||
F src/func.c 6d3c4ebd72aa7923ce9b110a7dc15f9b8c548430
|
||||
@ -212,7 +212,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
|
||||
F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
|
||||
F src/loadext.c de741e66e5ddc1598d904d7289239696e40ed994
|
||||
F src/main.c e8d76c9dc47ae7aac2bb1b3d65b55cea4fdc900f
|
||||
F src/main.c 962eac230ec5c619ebccafa498bcfb617af0cc79
|
||||
F src/malloc.c 740db54387204c9a2eb67c6d98e68b08e9ef4eab
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c faf615aafd8be74a71494dfa027c113ea5c6615f
|
||||
@ -233,29 +233,29 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||
F src/os_unix.c fb587121840f690101336879adfa6d0b2cd0e8c7
|
||||
F src/os_win.c a9e500dd963fb1f67d7860e58b5772abe6123862
|
||||
F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21
|
||||
F src/pager.c b8764f90c135482988268eec93d7f5cdb89d687a
|
||||
F src/pager.c 7a5c5bc0e29b9b16834f5558a9d5d22bbae59a08
|
||||
F src/pager.h d1eee3c3f741be247ce6d82752a178515fc8578b
|
||||
F src/parse.y 5dfead8aed90cb0c7c1115898ee2266804daff45
|
||||
F src/pcache.c ace1b67632deeaa84859b4c16c27711dfb7db3d4
|
||||
F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
|
||||
F src/pcache1.c facbdd3ecc09c8f750089d941305694301328e98
|
||||
F src/pragma.c 3f3e959390a10c0131676f0e307acce372777e0f
|
||||
F src/pragma.c d54cdd40b63d608f2d95b7482c710690e3593a73
|
||||
F src/prepare.c b7b7bf020bd4c962f7c8aed5a3c542c7dfe9f9c7
|
||||
F src/printf.c 9e75a6a0b55bf61cfff7d7e19d89834a1b938236
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c 4965007d6497b6a4d7a6d98751cc39712885f952
|
||||
F src/resolve.c f6c46d3434439ab2084618d603e6d6dbeb0d6ada
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c 428165951748151e87a15295b7357221433e311b
|
||||
F src/select.c f377fb8a5c73c10678ea74f3400f7913943e3d75
|
||||
F src/shell.c 81e4f2b57396db0714bc73d1f95cf3970f5dcc10
|
||||
F src/sqlite.h.in 76626596dabd96d98b3bb88495386b1bb5fa7f44
|
||||
F src/sqlite.h.in 9e505658e72a84604b7571b6bc78d8a9bde0a9b7
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
||||
F src/sqliteInt.h 4ad823ef8e31448ca333eafa1892ab35759ae6c1
|
||||
F src/sqliteInt.h aff67183ad2b5d29f71a3084e15d16cae96f622c
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/status.c 81712116e826b0089bb221b018929536b2b5406f
|
||||
F src/table.c f142bba7903e93ca8d113a5b8877a108ad1a27dc
|
||||
F src/tclsqlite.c 05be57620509060e85064b9495256c05d56e76b0
|
||||
F src/test1.c a0bce4f47da65b76c80e5f8bf9a5ef174603866a
|
||||
F src/test1.c f5d7ecd3dd663b11f35269fd91f7090db0570903
|
||||
F src/test2.c 98049e51a17dc62606a99a9eb95ee477f9996712
|
||||
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
|
||||
F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
|
||||
@ -308,7 +308,7 @@ F src/update.c d207deb7a031f698104bee879de0632b611e72dd
|
||||
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
|
||||
F src/util.c 3b627daa45c7308c1e36e3dbaa3f9ce7e5c7fa73
|
||||
F src/vacuum.c 9b30ec729337dd012ed88d4c292922c8ef9cf00c
|
||||
F src/vdbe.c 24e590213c0b5b4432db922fcc2981d918b6607d
|
||||
F src/vdbe.c c02217423a807dc97c743f5fff493cd55dffa77d
|
||||
F src/vdbe.h b434bb75fbec973d18d49225a59833ae39ee2afc
|
||||
F src/vdbeInt.h dc69f0351bef56456fdba3e09d3387ba4f1b1520
|
||||
F src/vdbeapi.c 3d4d2a2b24055ce2cb029fa73067c56616264b51
|
||||
@ -318,10 +318,10 @@ F src/vdbemem.c 96e41193b4affd9ebc0eea2fa628879dac88c744
|
||||
F src/vdbesort.c 42c166f7ca78cb643c7f4e4bdfa83c59d363d1a6
|
||||
F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
|
||||
F src/vtab.c c08ec66f45919eaa726bf88aa53eb08379d607f9
|
||||
F src/wal.c 486e644b3b8aa5ad066f625bc428aa8ff7001405
|
||||
F src/wal.c 847692349eb6e1fb8543dbc97e69ddbfa4cc7ea7
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
|
||||
F src/where.c a0b16f9d78321cb340a977287d19f826555c7d3b
|
||||
F src/where.c d67fe69dd1bb32ad3d488a8c5bc803a29814f357
|
||||
F src/whereInt.h d3633e9b592103241b74b0ec76185f3e5b8b62e0
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
@ -471,7 +471,7 @@ F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240
|
||||
F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
|
||||
F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
|
||||
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
|
||||
F test/distinct.test 086e70c765f172e8974e9f83b9ac5ca03c154e77
|
||||
F test/distinct.test 175d49ee783febaf368192dfe7f5afbc68910230
|
||||
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
|
||||
F test/e_blobbytes.test 9bea1d3e2b20f3010b04abba58f6ba172301f49f
|
||||
F test/e_blobclose.test df756753f571bc30e42e3a6cba2807576e49e716
|
||||
@ -687,7 +687,7 @@ F test/join.test 52d4d49f86d0cf46926672878c4eaf0da399104a
|
||||
F test/join2.test f2171c265e57ee298a27e57e7051d22962f9f324
|
||||
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
|
||||
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
|
||||
F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe
|
||||
F test/join5.test 5df23eba184f159ed9705a954957e765a10c141d
|
||||
F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
|
||||
F test/journal1.test 69abc726c51b4a0409189f9a85191205297c0577
|
||||
F test/journal2.test ae06f566c28552c313ded3fee79a6c69e6d049b1
|
||||
@ -1131,7 +1131,7 @@ F test/wal.test 885f32b2b390b30b4aa3dbb0e568f8f78d40f5cc
|
||||
F test/wal2.test 1f841d2048080d32f552942e333fd99ce541dada
|
||||
F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0
|
||||
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
|
||||
F test/wal5.test 8f888b50f66b78821e61ed0e233ded5de378224b
|
||||
F test/wal5.test 174cc1512e304a7dfa28ac30527e28ea02fc37df
|
||||
F test/wal6.test 527581f5527bf9c24394991e2be83000aace5f9e
|
||||
F test/wal64k.test 163655ecd2cb8afef4737cac2a40fdd2eeaf20b8
|
||||
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
|
||||
@ -1172,7 +1172,7 @@ F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7
|
||||
F test/whereG.test 69f5ec4b15760a8c860f80e2d55525669390aab3
|
||||
F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
|
||||
F test/whereI.test 1d89199697919d4930be05a71e7fe620f114e622
|
||||
F test/whereJ.test 63599653dfefe4e74ebb358db753417fe0aa8a49
|
||||
F test/whereJ.test 55a3221706a7ab706293f17cc8f96da563bf0767
|
||||
F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
|
||||
F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
|
||||
F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c
|
||||
@ -1241,7 +1241,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P f09055f3c4348264c7336f90646375f0d98b061e 61b31e771430f490fc2c4cef55046debc4a5f4f5
|
||||
R 4cb97995ea5a95cf1669fe4c63af9fe5
|
||||
P 2617d93713d9f4cf907ab2e7baef6a0f74f7198e 0d3aef97ebddf422b8bdcbc5878970c6129e3f54
|
||||
R 6c3870353869dc63de6b6e7262754990
|
||||
U drh
|
||||
Z 1bc55c89abd689844735dcd7c551f20d
|
||||
Z 0421768e128ea5c34e2d7a186ce23ac0
|
||||
|
@ -1 +1 @@
|
||||
2617d93713d9f4cf907ab2e7baef6a0f74f7198e
|
||||
34ffa3b3c002b0e87d8382ad76e87dbaec0b2bc6
|
@ -1414,7 +1414,8 @@ int sqlite3ExprCanBeNull(const Expr *p){
|
||||
return 0;
|
||||
case TK_COLUMN:
|
||||
assert( p->pTab!=0 );
|
||||
return p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0;
|
||||
return ExprHasProperty(p, EP_CanBeNull) ||
|
||||
(p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
15
src/main.c
15
src/main.c
@ -1957,10 +1957,13 @@ int sqlite3_wal_checkpoint_v2(
|
||||
if( pnLog ) *pnLog = -1;
|
||||
if( pnCkpt ) *pnCkpt = -1;
|
||||
|
||||
assert( SQLITE_CHECKPOINT_FULL>SQLITE_CHECKPOINT_PASSIVE );
|
||||
assert( SQLITE_CHECKPOINT_FULL<SQLITE_CHECKPOINT_RESTART );
|
||||
assert( SQLITE_CHECKPOINT_PASSIVE+2==SQLITE_CHECKPOINT_RESTART );
|
||||
if( eMode<SQLITE_CHECKPOINT_PASSIVE || eMode>SQLITE_CHECKPOINT_RESTART ){
|
||||
assert( SQLITE_CHECKPOINT_PASSIVE==0 );
|
||||
assert( SQLITE_CHECKPOINT_FULL==1 );
|
||||
assert( SQLITE_CHECKPOINT_RESTART==2 );
|
||||
assert( SQLITE_CHECKPOINT_TRUNCATE==3 );
|
||||
if( eMode<SQLITE_CHECKPOINT_PASSIVE || eMode>SQLITE_CHECKPOINT_TRUNCATE ){
|
||||
/* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint
|
||||
** mode: */
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
|
||||
@ -1988,7 +1991,9 @@ int sqlite3_wal_checkpoint_v2(
|
||||
** checkpointed.
|
||||
*/
|
||||
int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
|
||||
return sqlite3_wal_checkpoint_v2(db, zDb, SQLITE_CHECKPOINT_PASSIVE, 0, 0);
|
||||
/* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to
|
||||
** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */
|
||||
return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0);
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
|
@ -7075,7 +7075,8 @@ int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
|
||||
int rc = SQLITE_OK;
|
||||
if( pPager->pWal ){
|
||||
rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
|
||||
pPager->xBusyHandler, pPager->pBusyHandlerArg,
|
||||
(eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
|
||||
pPager->pBusyHandlerArg,
|
||||
pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
|
||||
pnLog, pnCkpt
|
||||
);
|
||||
|
@ -2195,7 +2195,7 @@ void sqlite3Pragma(
|
||||
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
/*
|
||||
** PRAGMA [database.]wal_checkpoint = passive|full|restart
|
||||
** PRAGMA [database.]wal_checkpoint = passive|full|restart|truncate
|
||||
**
|
||||
** Checkpoint the database.
|
||||
*/
|
||||
@ -2207,6 +2207,8 @@ void sqlite3Pragma(
|
||||
eMode = SQLITE_CHECKPOINT_FULL;
|
||||
}else if( sqlite3StrICmp(zRight, "restart")==0 ){
|
||||
eMode = SQLITE_CHECKPOINT_RESTART;
|
||||
}else if( sqlite3StrICmp(zRight, "truncate")==0 ){
|
||||
eMode = SQLITE_CHECKPOINT_TRUNCATE;
|
||||
}
|
||||
}
|
||||
sqlite3VdbeSetNumCols(v, 3);
|
||||
|
@ -320,6 +320,10 @@ static int lookupName(
|
||||
if( pMatch ){
|
||||
pExpr->iTable = pMatch->iCursor;
|
||||
pExpr->pTab = pMatch->pTab;
|
||||
assert( (pMatch->jointype & JT_RIGHT)==0 ); /* RIGHT JOIN not (yet) supported */
|
||||
if( (pMatch->jointype & JT_LEFT)!=0 ){
|
||||
ExprSetProperty(pExpr, EP_CanBeNull);
|
||||
}
|
||||
pSchema = pExpr->pTab->pSchema;
|
||||
}
|
||||
} /* if( pSrcList ) */
|
||||
|
@ -4829,7 +4829,7 @@ int sqlite3Select(
|
||||
**
|
||||
** is transformed to:
|
||||
**
|
||||
** SELECT xyz FROM ... GROUP BY xyz
|
||||
** SELECT xyz FROM ... GROUP BY xyz ORDER BY xyz
|
||||
**
|
||||
** The second form is preferred as a single index (or temp-table) may be
|
||||
** used for both the ORDER BY and DISTINCT processing. As originally
|
||||
@ -4842,7 +4842,6 @@ int sqlite3Select(
|
||||
p->selFlags &= ~SF_Distinct;
|
||||
p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
|
||||
pGroupBy = p->pGroupBy;
|
||||
sSort.pOrderBy = 0;
|
||||
/* Notice that even thought SF_Distinct has been cleared from p->selFlags,
|
||||
** the sDistinct.isTnct is still set. Hence, isTnct represents the
|
||||
** original setting of the SF_Distinct flag, not the current setting */
|
||||
|
212
src/sqlite.h.in
212
src/sqlite.h.in
@ -1216,7 +1216,7 @@ struct sqlite3_vfs {
|
||||
** </ul>
|
||||
**
|
||||
** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as
|
||||
** was given no the corresponding lock.
|
||||
** was given on the corresponding lock.
|
||||
**
|
||||
** The xShmLock method can transition between unlocked and SHARED or
|
||||
** between unlocked and EXCLUSIVE. It cannot transition between SHARED
|
||||
@ -1519,8 +1519,8 @@ struct sqlite3_mem_methods {
|
||||
** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
|
||||
** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int,
|
||||
** interpreted as a boolean, which enables or disables the collection of
|
||||
** memory allocation statistics. ^(When memory allocation statistics are disabled, the
|
||||
** following SQLite interfaces become non-operational:
|
||||
** memory allocation statistics. ^(When memory allocation statistics are
|
||||
** disabled, the following SQLite interfaces become non-operational:
|
||||
** <ul>
|
||||
** <li> [sqlite3_memory_used()]
|
||||
** <li> [sqlite3_memory_highwater()]
|
||||
@ -1561,7 +1561,8 @@ struct sqlite3_mem_methods {
|
||||
** This configuration should not be used if an application-define page
|
||||
** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2]
|
||||
** configuration option.
|
||||
** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned
|
||||
** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to
|
||||
** 8-byte aligned
|
||||
** memory, the size of each page buffer (sz), and the number of pages (N).
|
||||
** The sz argument should be the size of the largest database page
|
||||
** (a power of two between 512 and 32768) plus some extra bytes for each
|
||||
@ -1581,7 +1582,8 @@ struct sqlite3_mem_methods {
|
||||
** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
|
||||
** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer
|
||||
** that SQLite will use for all of its dynamic memory allocation needs
|
||||
** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].
|
||||
** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and
|
||||
** [SQLITE_CONFIG_PAGECACHE].
|
||||
** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled
|
||||
** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns
|
||||
** [SQLITE_ERROR] if invoked otherwise.
|
||||
@ -1601,9 +1603,9 @@ struct sqlite3_mem_methods {
|
||||
** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
|
||||
** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a
|
||||
** pointer to an instance of the [sqlite3_mutex_methods] structure.
|
||||
** The argument specifies alternative low-level mutex routines to be used in place
|
||||
** the mutex routines built into SQLite.)^ ^SQLite makes a copy of the
|
||||
** content of the [sqlite3_mutex_methods] structure before the call to
|
||||
** The argument specifies alternative low-level mutex routines to be used
|
||||
** in place the mutex routines built into SQLite.)^ ^SQLite makes a copy of
|
||||
** the content of the [sqlite3_mutex_methods] structure before the call to
|
||||
** [sqlite3_config()] returns. ^If SQLite is compiled with
|
||||
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
|
||||
** the entire mutexing subsystem is omitted from the build and hence calls to
|
||||
@ -1641,8 +1643,8 @@ struct sqlite3_mem_methods {
|
||||
**
|
||||
** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt>
|
||||
** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which
|
||||
** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies of the current
|
||||
** page cache implementation into that object.)^ </dd>
|
||||
** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies of
|
||||
** the current page cache implementation into that object.)^ </dd>
|
||||
**
|
||||
** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt>
|
||||
** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite
|
||||
@ -1667,8 +1669,9 @@ struct sqlite3_mem_methods {
|
||||
** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
|
||||
** <dd>^(The SQLITE_CONFIG_URI option takes a single argument of type int.
|
||||
** If non-zero, then URI handling is globally enabled. If the parameter is zero,
|
||||
** then URI handling is globally disabled.)^ ^If URI handling is globally enabled,
|
||||
** all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or
|
||||
** then URI handling is globally disabled.)^ ^If URI handling is globally
|
||||
** enabled, all filenames passed to [sqlite3_open()], [sqlite3_open_v2()],
|
||||
** [sqlite3_open16()] or
|
||||
** specified as part of [ATTACH] commands are interpreted as URIs, regardless
|
||||
** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
|
||||
** connection is opened. ^If it is globally disabled, filenames are
|
||||
@ -1730,8 +1733,8 @@ struct sqlite3_mem_methods {
|
||||
** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
|
||||
** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE
|
||||
** <dd>^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is
|
||||
** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro defined.
|
||||
** ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
|
||||
** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro
|
||||
** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
|
||||
** that specifies the maximum size of the created heap.
|
||||
** </dl>
|
||||
**
|
||||
@ -1739,8 +1742,8 @@ struct sqlite3_mem_methods {
|
||||
** <dt>SQLITE_CONFIG_PCACHE_HDRSZ
|
||||
** <dd>^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which
|
||||
** is a pointer to an integer and writes into that integer the number of extra
|
||||
** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE]. The amount of
|
||||
** extra space required can change depending on the compiler,
|
||||
** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE].
|
||||
** The amount of extra space required can change depending on the compiler,
|
||||
** target platform, and SQLite version.
|
||||
** </dl>
|
||||
*/
|
||||
@ -2044,6 +2047,7 @@ int sqlite3_complete16(const void *sql);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
|
||||
** KEYWORDS: {busy-handler callback} {busy handler}
|
||||
**
|
||||
** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
|
||||
** that might be invoked with argument P whenever
|
||||
@ -2060,7 +2064,7 @@ int sqlite3_complete16(const void *sql);
|
||||
** ^The first argument to the busy handler is a copy of the void* pointer which
|
||||
** is the third argument to sqlite3_busy_handler(). ^The second argument to
|
||||
** the busy handler callback is the number of times that the busy handler has
|
||||
** been invoked for the same locking event. ^If the
|
||||
** been invoked previously for the same locking event. ^If the
|
||||
** busy callback returns 0, then no additional attempts are made to
|
||||
** access the database and [SQLITE_BUSY] is returned
|
||||
** to the application.
|
||||
@ -4515,7 +4519,8 @@ typedef void (*sqlite3_destructor_type)(void*);
|
||||
** the [sqlite3_context] pointer, the results are undefined.
|
||||
*/
|
||||
void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
|
||||
void sqlite3_result_blob64(sqlite3_context*,const void*,sqlite3_uint64,void(*)(void*));
|
||||
void sqlite3_result_blob64(sqlite3_context*,const void*,
|
||||
sqlite3_uint64,void(*)(void*));
|
||||
void sqlite3_result_double(sqlite3_context*, double);
|
||||
void sqlite3_result_error(sqlite3_context*, const char*, int);
|
||||
void sqlite3_result_error16(sqlite3_context*, const void*, int);
|
||||
@ -7241,97 +7246,114 @@ int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
|
||||
/*
|
||||
** CAPI3REF: Checkpoint a database
|
||||
**
|
||||
** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X
|
||||
** on [database connection] D to be [checkpointed]. ^If X is NULL or an
|
||||
** empty string, then a checkpoint is run on all databases of
|
||||
** connection D. ^If the database connection D is not in
|
||||
** [WAL | write-ahead log mode] then this interface is a harmless no-op.
|
||||
** ^The [sqlite3_wal_checkpoint(D,X)] interface initiates a
|
||||
** [sqlite3_wal_checkpoint_v2|PASSIVE] checkpoint.
|
||||
** Use the [sqlite3_wal_checkpoint_v2()] interface to get a FULL
|
||||
** or RESET checkpoint.
|
||||
** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to
|
||||
** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^
|
||||
**
|
||||
** ^The [wal_checkpoint pragma] can be used to invoke this interface
|
||||
** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the
|
||||
** [wal_autocheckpoint pragma] can be used to cause this interface to be
|
||||
** run whenever the WAL reaches a certain size threshold.
|
||||
** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the
|
||||
** [write-ahead log] for database X on [database connection] D to be
|
||||
** transferred into the database file and for the write-ahead log to
|
||||
** be reset. See the [checkpointing] documentation for addition
|
||||
** information.
|
||||
**
|
||||
** See also: [sqlite3_wal_checkpoint_v2()]
|
||||
** This interface used to be the only way to cause a checkpoint to
|
||||
** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()]
|
||||
** interface was added. This interface is retained for backwards
|
||||
** compatibility and as a convenience for applications that need to manually
|
||||
** start a callback but which do not need the full power (and corresponding
|
||||
** complication) of [sqlite3_wal_checkpoint_v2()].
|
||||
*/
|
||||
int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Checkpoint a database
|
||||
**
|
||||
** Run a checkpoint operation on WAL database zDb attached to database
|
||||
** handle db. The specific operation is determined by the value of the
|
||||
** eMode parameter:
|
||||
** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint
|
||||
** operation on database X of [database connection] D in mode M. Status
|
||||
** information is written back into integers pointed to by L and C.)^
|
||||
** ^(The M parameter must be a valid [checkpoint mode]:)^
|
||||
**
|
||||
** <dl>
|
||||
** <dt>SQLITE_CHECKPOINT_PASSIVE<dd>
|
||||
** Checkpoint as many frames as possible without waiting for any database
|
||||
** readers or writers to finish. Sync the db file if all frames in the log
|
||||
** are checkpointed. This mode is the same as calling
|
||||
** sqlite3_wal_checkpoint(). The [sqlite3_busy_handler|busy-handler callback]
|
||||
** is never invoked.
|
||||
** ^Checkpoint as many frames as possible without waiting for any database
|
||||
** readers or writers to finish, then sync the database file if all frames
|
||||
** in the log were checkpointed. ^The [busy-handler callback]
|
||||
** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode.
|
||||
** ^On the other hand, passive mode might leave the checkpoint unfinished
|
||||
** if there are concurrent readers or writers.
|
||||
**
|
||||
** <dt>SQLITE_CHECKPOINT_FULL<dd>
|
||||
** This mode blocks (it invokes the
|
||||
** ^This mode blocks (it invokes the
|
||||
** [sqlite3_busy_handler|busy-handler callback]) until there is no
|
||||
** database writer and all readers are reading from the most recent database
|
||||
** snapshot. It then checkpoints all frames in the log file and syncs the
|
||||
** database file. This call blocks database writers while it is running,
|
||||
** but not database readers.
|
||||
** snapshot. ^It then checkpoints all frames in the log file and syncs the
|
||||
** database file. ^This mode blocks new database writers while it is pending,
|
||||
** but new database readers are allowed to continue unimpeded.
|
||||
**
|
||||
** <dt>SQLITE_CHECKPOINT_RESTART<dd>
|
||||
** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after
|
||||
** checkpointing the log file it blocks (calls the
|
||||
** [sqlite3_busy_handler|busy-handler callback])
|
||||
** until all readers are reading from the database file only. This ensures
|
||||
** that the next client to write to the database file restarts the log file
|
||||
** from the beginning. This call blocks database writers while it is running,
|
||||
** but not database readers.
|
||||
** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition
|
||||
** that after checkpointing the log file it blocks (calls the
|
||||
** [busy-handler callback])
|
||||
** until all readers are reading from the database file only. ^This ensures
|
||||
** that the next writer will restart the log file from the beginning.
|
||||
** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new
|
||||
** database writer attempts while it is pending, but does not impede readers.
|
||||
**
|
||||
** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd>
|
||||
** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the
|
||||
** addition that it also truncates the log file to zero bytes just prior
|
||||
** to a successful return.
|
||||
** </dl>
|
||||
**
|
||||
** If pnLog is not NULL, then *pnLog is set to the total number of frames in
|
||||
** the log file before returning. If pnCkpt is not NULL, then *pnCkpt is set to
|
||||
** the total number of checkpointed frames (including any that were already
|
||||
** checkpointed when this function is called). *pnLog and *pnCkpt may be
|
||||
** populated even if sqlite3_wal_checkpoint_v2() returns other than SQLITE_OK.
|
||||
** If no values are available because of an error, they are both set to -1
|
||||
** before returning to communicate this to the caller.
|
||||
** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in
|
||||
** the log file or to -1 if the checkpoint could not run because
|
||||
** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not
|
||||
** NULL,then *pnCkpt is set to the total number of checkpointed frames in the
|
||||
** log file (including any that were already checkpointed before the function
|
||||
** was called) or to -1 if the checkpoint could not run due to an error or
|
||||
** because the database is not in WAL mode. ^Note that upon successful
|
||||
** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been
|
||||
** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero.
|
||||
**
|
||||
** All calls obtain an exclusive "checkpoint" lock on the database file. If
|
||||
** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If
|
||||
** any other process is running a checkpoint operation at the same time, the
|
||||
** lock cannot be obtained and SQLITE_BUSY is returned. Even if there is a
|
||||
** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a
|
||||
** busy-handler configured, it will not be invoked in this case.
|
||||
**
|
||||
** The SQLITE_CHECKPOINT_FULL and RESTART modes also obtain the exclusive
|
||||
** "writer" lock on the database file. If the writer lock cannot be obtained
|
||||
** immediately, and a busy-handler is configured, it is invoked and the writer
|
||||
** lock retried until either the busy-handler returns 0 or the lock is
|
||||
** successfully obtained. The busy-handler is also invoked while waiting for
|
||||
** database readers as described above. If the busy-handler returns 0 before
|
||||
** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the
|
||||
** exclusive "writer" lock on the database file. ^If the writer lock cannot be
|
||||
** obtained immediately, and a busy-handler is configured, it is invoked and
|
||||
** the writer lock retried until either the busy-handler returns 0 or the lock
|
||||
** is successfully obtained. ^The busy-handler is also invoked while waiting for
|
||||
** database readers as described above. ^If the busy-handler returns 0 before
|
||||
** the writer lock is obtained or while waiting for database readers, the
|
||||
** checkpoint operation proceeds from that point in the same way as
|
||||
** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible
|
||||
** without blocking any further. SQLITE_BUSY is returned in this case.
|
||||
** without blocking any further. ^SQLITE_BUSY is returned in this case.
|
||||
**
|
||||
** If parameter zDb is NULL or points to a zero length string, then the
|
||||
** specified operation is attempted on all WAL databases. In this case the
|
||||
** values written to output parameters *pnLog and *pnCkpt are undefined. If
|
||||
** ^If parameter zDb is NULL or points to a zero length string, then the
|
||||
** specified operation is attempted on all WAL databases [attached] to
|
||||
** [database connection] db. In this case the
|
||||
** values written to output parameters *pnLog and *pnCkpt are undefined. ^If
|
||||
** an SQLITE_BUSY error is encountered when processing one or more of the
|
||||
** attached WAL databases, the operation is still attempted on any remaining
|
||||
** attached databases and SQLITE_BUSY is returned to the caller. If any other
|
||||
** attached databases and SQLITE_BUSY is returned at the end. ^If any other
|
||||
** error occurs while processing an attached database, processing is abandoned
|
||||
** and the error code returned to the caller immediately. If no error
|
||||
** and the error code is returned to the caller immediately. ^If no error
|
||||
** (SQLITE_BUSY or otherwise) is encountered while processing the attached
|
||||
** databases, SQLITE_OK is returned.
|
||||
**
|
||||
** If database zDb is the name of an attached database that is not in WAL
|
||||
** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. If
|
||||
** ^If database zDb is the name of an attached database that is not in WAL
|
||||
** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If
|
||||
** zDb is not NULL (or a zero length string) and is not the name of any
|
||||
** attached database, SQLITE_ERROR is returned to the caller.
|
||||
**
|
||||
** ^Unless it returns SQLITE_MISUSE,
|
||||
** the sqlite3_wal_checkpoint_v2() interface
|
||||
** sets the error information that is queried by
|
||||
** [sqlite3_errcode()] and [sqlite3_errmsg()].
|
||||
**
|
||||
** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
|
||||
** from SQL.
|
||||
*/
|
||||
int sqlite3_wal_checkpoint_v2(
|
||||
sqlite3 *db, /* Database handle */
|
||||
@ -7342,16 +7364,18 @@ int sqlite3_wal_checkpoint_v2(
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Checkpoint operation parameters
|
||||
** CAPI3REF: Checkpoint Mode Values
|
||||
** KEYWORDS: {checkpoint mode}
|
||||
**
|
||||
** These constants can be used as the 3rd parameter to
|
||||
** [sqlite3_wal_checkpoint_v2()]. See the [sqlite3_wal_checkpoint_v2()]
|
||||
** documentation for additional information about the meaning and use of
|
||||
** each of these values.
|
||||
** These constants define all valid values for the "checkpoint mode" passed
|
||||
** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface.
|
||||
** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the
|
||||
** meaning of each of these checkpoint modes.
|
||||
*/
|
||||
#define SQLITE_CHECKPOINT_PASSIVE 0
|
||||
#define SQLITE_CHECKPOINT_FULL 1
|
||||
#define SQLITE_CHECKPOINT_RESTART 2
|
||||
#define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */
|
||||
#define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */
|
||||
#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */
|
||||
#define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Virtual Table Interface Configuration
|
||||
@ -7450,12 +7474,12 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
|
||||
**
|
||||
** <dl>
|
||||
** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
|
||||
** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set to the
|
||||
** total number of times that the X-th loop has run.</dd>
|
||||
** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be
|
||||
** set to the total number of times that the X-th loop has run.</dd>
|
||||
**
|
||||
** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt>
|
||||
** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set to the
|
||||
** total number of rows examined by all iterations of the X-th loop.</dd>
|
||||
** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set
|
||||
** to the total number of rows examined by all iterations of the X-th loop.</dd>
|
||||
**
|
||||
** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt>
|
||||
** <dd>^The "double" variable pointed to by the T parameter will be set to the
|
||||
@ -7466,14 +7490,14 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
|
||||
** be the NLOOP value for the current loop.
|
||||
**
|
||||
** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt>
|
||||
** <dd>^The "const char *" variable pointed to by the T parameter will be set to
|
||||
** a zero-terminated UTF-8 string containing the name of the index or table used
|
||||
** for the X-th loop.
|
||||
** <dd>^The "const char *" variable pointed to by the T parameter will be set
|
||||
** to a zero-terminated UTF-8 string containing the name of the index or table
|
||||
** used for the X-th loop.
|
||||
**
|
||||
** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt>
|
||||
** <dd>^The "const char *" variable pointed to by the T parameter will be set to
|
||||
** a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] description
|
||||
** for the X-th loop.
|
||||
** <dd>^The "const char *" variable pointed to by the T parameter will be set
|
||||
** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN]
|
||||
** description for the X-th loop.
|
||||
**
|
||||
** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
|
||||
** <dd>^The "int" variable pointed to by the T parameter will be set to the
|
||||
@ -7496,8 +7520,8 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
|
||||
** Return status data for a single loop within query pStmt.
|
||||
**
|
||||
** The "iScanStatusOp" parameter determines which status information to return.
|
||||
** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior of
|
||||
** this interface is undefined.
|
||||
** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
|
||||
** of this interface is undefined.
|
||||
** ^The requested measurement is written into a variable pointed to by
|
||||
** the "pOut" parameter.
|
||||
** Parameter "idx" identifies the specific loop to retrieve statistics for.
|
||||
|
@ -2023,7 +2023,7 @@ struct Expr {
|
||||
/*
|
||||
** The following are the meanings of bits in the Expr.flags field.
|
||||
*/
|
||||
#define EP_FromJoin 0x000001 /* Originated in ON or USING clause of a join */
|
||||
#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
|
||||
#define EP_Agg 0x000002 /* Contains one or more aggregate functions */
|
||||
#define EP_Resolved 0x000004 /* IDs have been resolved to COLUMNs */
|
||||
#define EP_Error 0x000008 /* Expression contains one or more errors */
|
||||
@ -2043,6 +2043,7 @@ struct Expr {
|
||||
#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
|
||||
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
|
||||
#define EP_Constant 0x080000 /* Node is a constant */
|
||||
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
|
||||
|
||||
/*
|
||||
** These macros can be used to test, set, or clear bits in the
|
||||
|
@ -5690,10 +5690,11 @@ static int test_wal_checkpoint_v2(
|
||||
int nCkpt = -555;
|
||||
Tcl_Obj *pRet;
|
||||
|
||||
const char * aMode[] = { "passive", "full", "restart", 0 };
|
||||
const char * aMode[] = { "passive", "full", "restart", "truncate", 0 };
|
||||
assert( SQLITE_CHECKPOINT_PASSIVE==0 );
|
||||
assert( SQLITE_CHECKPOINT_FULL==1 );
|
||||
assert( SQLITE_CHECKPOINT_RESTART==2 );
|
||||
assert( SQLITE_CHECKPOINT_TRUNCATE==3 );
|
||||
|
||||
if( objc!=3 && objc!=4 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB MODE ?NAME?");
|
||||
|
@ -5765,8 +5765,8 @@ case OP_AggFinal: {
|
||||
/* Opcode: Checkpoint P1 P2 P3 * *
|
||||
**
|
||||
** Checkpoint database P1. This is a no-op if P1 is not currently in
|
||||
** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL
|
||||
** or RESTART. Write 1 or 0 into mem[P3] if the checkpoint returns
|
||||
** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL,
|
||||
** RESTART, or TRUNCATE. Write 1 or 0 into mem[P3] if the checkpoint returns
|
||||
** SQLITE_BUSY or not, respectively. Write the number of pages in the
|
||||
** WAL after the checkpoint into mem[P3+1] and the number of pages
|
||||
** in the WAL that have been checkpointed after the checkpoint
|
||||
@ -5784,6 +5784,7 @@ case OP_Checkpoint: {
|
||||
assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
|
||||
|| pOp->p2==SQLITE_CHECKPOINT_FULL
|
||||
|| pOp->p2==SQLITE_CHECKPOINT_RESTART
|
||||
|| pOp->p2==SQLITE_CHECKPOINT_TRUNCATE
|
||||
);
|
||||
rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]);
|
||||
if( rc==SQLITE_BUSY ){
|
||||
|
123
src/wal.c
123
src/wal.c
@ -1623,6 +1623,38 @@ static int walPagesize(Wal *pWal){
|
||||
return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
|
||||
}
|
||||
|
||||
/*
|
||||
** The following is guaranteed when this function is called:
|
||||
**
|
||||
** a) the WRITER lock is held,
|
||||
** b) the entire log file has been checkpointed, and
|
||||
** c) any existing readers are reading exclusively from the database
|
||||
** file - there are no readers that may attempt to read a frame from
|
||||
** the log file.
|
||||
**
|
||||
** This function updates the shared-memory structures so that the next
|
||||
** client to write to the database (which may be this one) does so by
|
||||
** writing frames into the start of the log file.
|
||||
**
|
||||
** The value of parameter salt1 is used as the aSalt[1] value in the
|
||||
** new wal-index header. It should be passed a pseudo-random value (i.e.
|
||||
** one obtained from sqlite3_randomness()).
|
||||
*/
|
||||
static void walRestartHdr(Wal *pWal, u32 salt1){
|
||||
volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
|
||||
int i; /* Loop counter */
|
||||
u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */
|
||||
pWal->nCkpt++;
|
||||
pWal->hdr.mxFrame = 0;
|
||||
sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
|
||||
memcpy(&pWal->hdr.aSalt[1], &salt1, 4);
|
||||
walIndexWriteHdr(pWal);
|
||||
pInfo->nBackfill = 0;
|
||||
pInfo->aReadMark[1] = 0;
|
||||
for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
|
||||
assert( pInfo->aReadMark[0]==0 );
|
||||
}
|
||||
|
||||
/*
|
||||
** Copy as much content as we can from the WAL back into the database file
|
||||
** in response to an sqlite3_wal_checkpoint() request or the equivalent.
|
||||
@ -1657,7 +1689,7 @@ static int walPagesize(Wal *pWal){
|
||||
static int walCheckpoint(
|
||||
Wal *pWal, /* Wal connection */
|
||||
int eMode, /* One of PASSIVE, FULL or RESTART */
|
||||
int (*xBusyCall)(void*), /* Function to call when busy */
|
||||
int (*xBusy)(void*), /* Function to call when busy */
|
||||
void *pBusyArg, /* Context argument for xBusyHandler */
|
||||
int sync_flags, /* Flags for OsSync() (or 0) */
|
||||
u8 *zBuf /* Temporary buffer to use */
|
||||
@ -1671,7 +1703,6 @@ static int walCheckpoint(
|
||||
u32 mxPage; /* Max database page to write */
|
||||
int i; /* Loop counter */
|
||||
volatile WalCkptInfo *pInfo; /* The checkpoint status information */
|
||||
int (*xBusy)(void*) = 0; /* Function to call when waiting for locks */
|
||||
|
||||
szPage = walPagesize(pWal);
|
||||
testcase( szPage<=32768 );
|
||||
@ -1686,7 +1717,9 @@ static int walCheckpoint(
|
||||
}
|
||||
assert( pIter );
|
||||
|
||||
if( eMode!=SQLITE_CHECKPOINT_PASSIVE ) xBusy = xBusyCall;
|
||||
/* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
|
||||
** in the SQLITE_CHECKPOINT_PASSIVE mode. */
|
||||
assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
|
||||
|
||||
/* Compute in mxSafeFrame the index of the last frame of the WAL that is
|
||||
** safe to write into the database. Frames beyond mxSafeFrame might
|
||||
@ -1775,19 +1808,38 @@ static int walCheckpoint(
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
|
||||
/* If this is an SQLITE_CHECKPOINT_RESTART operation, and the entire wal
|
||||
** file has been copied into the database file, then block until all
|
||||
** readers have finished using the wal file. This ensures that the next
|
||||
** process to write to the database restarts the wal file.
|
||||
/* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the
|
||||
** entire wal file has been copied into the database file, then block
|
||||
** until all readers have finished using the wal file. This ensures that
|
||||
** the next process to write to the database restarts the wal file.
|
||||
*/
|
||||
if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){
|
||||
assert( pWal->writeLock );
|
||||
if( pInfo->nBackfill<pWal->hdr.mxFrame ){
|
||||
rc = SQLITE_BUSY;
|
||||
}else if( eMode==SQLITE_CHECKPOINT_RESTART ){
|
||||
}else if( eMode>=SQLITE_CHECKPOINT_RESTART ){
|
||||
u32 salt1;
|
||||
sqlite3_randomness(4, &salt1);
|
||||
assert( mxSafeFrame==pWal->hdr.mxFrame );
|
||||
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){
|
||||
/* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as
|
||||
** SQLITE_CHECKPOINT_RESTART with the addition that it also
|
||||
** truncates the log file to zero bytes just prior to a
|
||||
** successful return.
|
||||
**
|
||||
** In theory, it might be safe to do this without updating the
|
||||
** wal-index header in shared memory, as all subsequent reader or
|
||||
** writer clients should see that the entire log file has been
|
||||
** checkpointed and behave accordingly. This seems unsafe though,
|
||||
** as it would leave the system in a state where the contents of
|
||||
** the wal-index header do not match the contents of the
|
||||
** file-system. To avoid this, update the wal-index header to
|
||||
** indicate that the log file contains zero valid frames. */
|
||||
walRestartHdr(pWal, salt1);
|
||||
rc = sqlite3OsTruncate(pWal->pWalFd, 0);
|
||||
}
|
||||
walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
|
||||
}
|
||||
}
|
||||
@ -2573,7 +2625,6 @@ int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** This function is called just before writing a set of frames to the log
|
||||
** file (see sqlite3WalFrames()). It checks to see if, instead of appending
|
||||
@ -2606,20 +2657,8 @@ static int walRestartLog(Wal *pWal){
|
||||
** In theory it would be Ok to update the cache of the header only
|
||||
** at this point. But updating the actual wal-index header is also
|
||||
** safe and means there is no special case for sqlite3WalUndo()
|
||||
** to handle if this transaction is rolled back.
|
||||
*/
|
||||
int i; /* Loop counter */
|
||||
u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */
|
||||
|
||||
pWal->nCkpt++;
|
||||
pWal->hdr.mxFrame = 0;
|
||||
sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
|
||||
aSalt[1] = salt1;
|
||||
walIndexWriteHdr(pWal);
|
||||
pInfo->nBackfill = 0;
|
||||
pInfo->aReadMark[1] = 0;
|
||||
for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
|
||||
assert( pInfo->aReadMark[0]==0 );
|
||||
** to handle if this transaction is rolled back. */
|
||||
walRestartHdr(pWal, salt1);
|
||||
walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
|
||||
}else if( rc!=SQLITE_BUSY ){
|
||||
return rc;
|
||||
@ -2907,7 +2946,7 @@ int sqlite3WalFrames(
|
||||
*/
|
||||
int sqlite3WalCheckpoint(
|
||||
Wal *pWal, /* Wal connection */
|
||||
int eMode, /* PASSIVE, FULL or RESTART */
|
||||
int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */
|
||||
int (*xBusy)(void*), /* Function to call when busy */
|
||||
void *pBusyArg, /* Context argument for xBusyHandler */
|
||||
int sync_flags, /* Flags to sync db file with (or 0) */
|
||||
@ -2919,29 +2958,42 @@ int sqlite3WalCheckpoint(
|
||||
int rc; /* Return code */
|
||||
int isChanged = 0; /* True if a new wal-index header is loaded */
|
||||
int eMode2 = eMode; /* Mode to pass to walCheckpoint() */
|
||||
int (*xBusy2)(void*) = xBusy; /* Busy handler for eMode2 */
|
||||
|
||||
assert( pWal->ckptLock==0 );
|
||||
assert( pWal->writeLock==0 );
|
||||
|
||||
/* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
|
||||
** in the SQLITE_CHECKPOINT_PASSIVE mode. */
|
||||
assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
|
||||
|
||||
if( pWal->readOnly ) return SQLITE_READONLY;
|
||||
WALTRACE(("WAL%p: checkpoint begins\n", pWal));
|
||||
|
||||
/* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
|
||||
** "checkpoint" lock on the database file. */
|
||||
rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
|
||||
if( rc ){
|
||||
/* Usually this is SQLITE_BUSY meaning that another thread or process
|
||||
** is already running a checkpoint, or maybe a recovery. But it might
|
||||
** also be SQLITE_IOERR. */
|
||||
/* EVIDENCE-OF: R-10421-19736 If any other process is running a
|
||||
** checkpoint operation at the same time, the lock cannot be obtained and
|
||||
** SQLITE_BUSY is returned.
|
||||
** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
|
||||
** it will not be invoked in this case.
|
||||
*/
|
||||
testcase( rc==SQLITE_BUSY );
|
||||
testcase( xBusy!=0 );
|
||||
return rc;
|
||||
}
|
||||
pWal->ckptLock = 1;
|
||||
|
||||
/* If this is a blocking-checkpoint, then obtain the write-lock as well
|
||||
** to prevent any writers from running while the checkpoint is underway.
|
||||
** This has to be done before the call to walIndexReadHdr() below.
|
||||
/* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
|
||||
** TRUNCATE modes also obtain the exclusive "writer" lock on the database
|
||||
** file.
|
||||
**
|
||||
** If the writer lock cannot be obtained, then a passive checkpoint is
|
||||
** run instead. Since the checkpointer is not holding the writer lock,
|
||||
** there is no point in blocking waiting for any readers. Assuming no
|
||||
** other error occurs, this function will return SQLITE_BUSY to the caller.
|
||||
** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
|
||||
** immediately, and a busy-handler is configured, it is invoked and the
|
||||
** writer lock retried until either the busy-handler returns 0 or the
|
||||
** lock is successfully obtained.
|
||||
*/
|
||||
if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
|
||||
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
|
||||
@ -2949,6 +3001,7 @@ int sqlite3WalCheckpoint(
|
||||
pWal->writeLock = 1;
|
||||
}else if( rc==SQLITE_BUSY ){
|
||||
eMode2 = SQLITE_CHECKPOINT_PASSIVE;
|
||||
xBusy2 = 0;
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
}
|
||||
@ -2966,7 +3019,7 @@ int sqlite3WalCheckpoint(
|
||||
if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}else{
|
||||
rc = walCheckpoint(pWal, eMode2, xBusy, pBusyArg, sync_flags, zBuf);
|
||||
rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
|
||||
}
|
||||
|
||||
/* If no error occurred, set the output variables. */
|
||||
|
@ -3591,10 +3591,9 @@ static Bitmask codeOneLoopStart(
|
||||
Expr *pExpr = pWC->a[iTerm].pExpr;
|
||||
if( &pWC->a[iTerm] == pTerm ) continue;
|
||||
if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
|
||||
testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
|
||||
testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
|
||||
if( pWC->a[iTerm].wtFlags & (TERM_ORINFO|TERM_VIRTUAL) ) continue;
|
||||
if( (pWC->a[iTerm].wtFlags & TERM_VIRTUAL)!=0 ) continue;
|
||||
if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
|
||||
testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
|
||||
pExpr = sqlite3ExprDup(db, pExpr, 0);
|
||||
pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
|
||||
}
|
||||
|
@ -222,4 +222,34 @@ do_execsql_test 4.1 {
|
||||
SELECT quote(x) FROM t2 ORDER BY 1;
|
||||
} {'xyzzy' X'0000000000'}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Ticket [c5ea805691bfc4204b1cb9e9aa0103bd48bc7d34] (2014-12-04)
|
||||
# Make sure that DISTINCT works together with ORDER BY and descending
|
||||
# indexes.
|
||||
#
|
||||
do_execsql_test 5.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1(x) VALUES(3),(1),(5),(2),(6),(4),(5),(1),(3);
|
||||
CREATE INDEX t1x ON t1(x DESC);
|
||||
SELECT DISTINCT x FROM t1 ORDER BY x ASC;
|
||||
} {1 2 3 4 5 6}
|
||||
do_execsql_test 5.2 {
|
||||
SELECT DISTINCT x FROM t1 ORDER BY x DESC;
|
||||
} {6 5 4 3 2 1}
|
||||
do_execsql_test 5.3 {
|
||||
SELECT DISTINCT x FROM t1 ORDER BY x;
|
||||
} {1 2 3 4 5 6}
|
||||
do_execsql_test 5.4 {
|
||||
DROP INDEX t1x;
|
||||
CREATE INDEX t1x ON t1(x ASC);
|
||||
SELECT DISTINCT x FROM t1 ORDER BY x ASC;
|
||||
} {1 2 3 4 5 6}
|
||||
do_execsql_test 5.5 {
|
||||
SELECT DISTINCT x FROM t1 ORDER BY x DESC;
|
||||
} {6 5 4 3 2 1}
|
||||
do_execsql_test 5.6 {
|
||||
SELECT DISTINCT x FROM t1 ORDER BY x;
|
||||
} {1 2 3 4 5 6}
|
||||
|
||||
finish_test
|
||||
|
@ -106,5 +106,59 @@ do_test join5-2.12 {
|
||||
execsql {SELECT * FROM xy LEFT JOIN ab ON NULL WHERE NULL}
|
||||
} {}
|
||||
|
||||
# Ticket https://www.sqlite.org/src/tktview/6f2222d550f5b0ee7ed37601
|
||||
# Incorrect output on a LEFT JOIN.
|
||||
#
|
||||
do_execsql_test join5-3.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
DROP TABLE IF EXISTS t3;
|
||||
CREATE TABLE x1(a);
|
||||
INSERT INTO x1 VALUES(1);
|
||||
CREATE TABLE x2(b NOT NULL);
|
||||
CREATE TABLE x3(c, d);
|
||||
INSERT INTO x3 VALUES('a', NULL);
|
||||
INSERT INTO x3 VALUES('b', NULL);
|
||||
INSERT INTO x3 VALUES('c', NULL);
|
||||
SELECT * FROM x1 LEFT JOIN x2 LEFT JOIN x3 ON x3.d = x2.b;
|
||||
} {1 {} {} {}}
|
||||
do_execsql_test join5-3.2 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
DROP TABLE IF EXISTS t3;
|
||||
DROP TABLE IF EXISTS t4;
|
||||
DROP TABLE IF EXISTS t5;
|
||||
CREATE TABLE t1(x text NOT NULL, y text);
|
||||
CREATE TABLE t2(u text NOT NULL, x text NOT NULL);
|
||||
CREATE TABLE t3(w text NOT NULL, v text);
|
||||
CREATE TABLE t4(w text NOT NULL, z text NOT NULL);
|
||||
CREATE TABLE t5(z text NOT NULL, m text);
|
||||
INSERT INTO t1 VALUES('f6d7661f-4efe-4c90-87b5-858e61cd178b',NULL);
|
||||
INSERT INTO t1 VALUES('f6ea82c3-2cad-45ce-ae8f-3ddca4fb2f48',NULL);
|
||||
INSERT INTO t1 VALUES('f6f47499-ecb4-474b-9a02-35be73c235e5',NULL);
|
||||
INSERT INTO t1 VALUES('56f47499-ecb4-474b-9a02-35be73c235e5',NULL);
|
||||
INSERT INTO t3 VALUES('007f2033-cb20-494c-b135-a1e4eb66130c',
|
||||
'f6d7661f-4efe-4c90-87b5-858e61cd178b');
|
||||
SELECT *
|
||||
FROM t3
|
||||
INNER JOIN t1 ON t1.x= t3.v AND t1.y IS NULL
|
||||
LEFT JOIN t4 ON t4.w = t3.w
|
||||
LEFT JOIN t5 ON t5.z = t4.z
|
||||
LEFT JOIN t2 ON t2.u = t5.m
|
||||
LEFT JOIN t1 xyz ON xyz.y = t2.x;
|
||||
} {007f2033-cb20-494c-b135-a1e4eb66130c f6d7661f-4efe-4c90-87b5-858e61cd178b f6d7661f-4efe-4c90-87b5-858e61cd178b {} {} {} {} {} {} {} {} {}}
|
||||
do_execsql_test join5-3.3 {
|
||||
DROP TABLE IF EXISTS x1;
|
||||
DROP TABLE IF EXISTS x2;
|
||||
DROP TABLE IF EXISTS x3;
|
||||
CREATE TABLE x1(a);
|
||||
INSERT INTO x1 VALUES(1);
|
||||
CREATE TABLE x2(b NOT NULL);
|
||||
CREATE TABLE x3(c, d);
|
||||
INSERT INTO x3 VALUES('a', NULL);
|
||||
INSERT INTO x3 VALUES('b', NULL);
|
||||
INSERT INTO x3 VALUES('c', NULL);
|
||||
SELECT * FROM x1 LEFT JOIN x2 JOIN x3 WHERE x3.d = x2.b;
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
@ -55,7 +55,8 @@ foreach {testprefix do_wal_checkpoint} {
|
||||
if {[lsearch {-mode -db} $key]<0} { error "unknown switch: $key" }
|
||||
}
|
||||
|
||||
if {$a(-mode)!="restart" && $a(-mode)!="full"} { set a(-mode) passive }
|
||||
set vals {restart full truncate}
|
||||
if {[lsearch -exact $vals $a(-mode)]<0} { set a(-mode) passive }
|
||||
|
||||
set cmd [list sqlite3_wal_checkpoint_v2 $dbhandle $a(-mode)]
|
||||
if {[info exists a(-db)]} { lappend sql $a(-db) }
|
||||
@ -278,6 +279,11 @@ foreach {testprefix do_wal_checkpoint} {
|
||||
9 RESTART 2 {1 4 3} 2
|
||||
10 RESTART 3 {1 4 4} 3
|
||||
|
||||
11 TRUNCATE - {0 0 0} 3
|
||||
12 TRUNCATE 1 {1 3 3} 1
|
||||
13 TRUNCATE 2 {1 4 3} 2
|
||||
14 TRUNCATE 3 {1 4 4} 3
|
||||
|
||||
} {
|
||||
do_multiclient_test tn {
|
||||
setup_and_attach_aux
|
||||
@ -348,6 +354,41 @@ foreach {testprefix do_wal_checkpoint} {
|
||||
|
||||
do_test 3.$tn.6 { code3 { do_wal_checkpoint db3 } } {0 0 0}
|
||||
}
|
||||
|
||||
# Test SQLITE_CHECKPOINT_TRUNCATE.
|
||||
#
|
||||
do_multiclient_test tn {
|
||||
|
||||
code1 $do_wal_checkpoint
|
||||
code2 $do_wal_checkpoint
|
||||
code3 $do_wal_checkpoint
|
||||
|
||||
do_test 3.$tn.1 {
|
||||
sql1 {
|
||||
PRAGMA page_size = 1024;
|
||||
PRAGMA journal_mode = WAL;
|
||||
PRAGMA synchronous = normal;
|
||||
CREATE TABLE t1(x, y);
|
||||
CREATE INDEX i1 ON t1(x, y);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
}
|
||||
file size test.db-wal
|
||||
} [wal_file_size 8 1024]
|
||||
|
||||
do_test 3.$tn.2 { do_wal_checkpoint db -mode truncate } {0 0 0}
|
||||
do_test 3.$tn.3 { file size test.db-wal } 0
|
||||
|
||||
do_test 3.$tn.4 {
|
||||
sql2 { SELECT * FROM t1 }
|
||||
} {1 2 3 4}
|
||||
|
||||
do_test 3.$tn.5 {
|
||||
sql2 { INSERT INTO t1 VALUES('a', 'b') }
|
||||
file size test.db-wal
|
||||
} [wal_file_size 2 1024]
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -640,4 +640,39 @@ do_execsql_test 4.2 {
|
||||
} {/.*SCAN TABLE cx.*SEARCH TABLE px.*SEARCH TABLE le.*/}
|
||||
|
||||
|
||||
# The following test is derived from a performance problem reported from
|
||||
# the field. Notice the multiple indexes with the same initial tables,
|
||||
# and the unusual WHERE clause terms.
|
||||
#
|
||||
do_test 5.1 {
|
||||
set res [db eval {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(a,b,c,d,e,f,g,h);
|
||||
CREATE INDEX t1abc ON t1(a,b,c);
|
||||
CREATE INDEX t1abe ON t1(a,b,e);
|
||||
CREATE INDEX t1abf ON t1(a,b,f);
|
||||
ANALYZE;
|
||||
DROP TABLE IF EXISTS sqlite_stat4;
|
||||
DROP TABLE IF EXISTS sqlite_stat3;
|
||||
DELETE FROM sqlite_stat1;
|
||||
INSERT INTO sqlite_stat1(tbl,idx,stat)
|
||||
VALUES('t1','t1abc','2000000 8000 1600 800'),
|
||||
('t1','t1abe','2000000 8000 1600 150'),
|
||||
('t1','t1abf','2000000 8000 1600 150');
|
||||
ANALYZE sqlite_master;
|
||||
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1
|
||||
WHERE (a=1 OR a=2)
|
||||
AND (b=3 OR b=4)
|
||||
AND (d>=5 AND d<=5)
|
||||
AND ((e>=7 AND e<=7) OR (f>=8 AND f<=8))
|
||||
AND g>0;
|
||||
}]
|
||||
} {~/ANY/}
|
||||
do_test 5.2 {set res} {/USING INDEX t1abe/}
|
||||
do_test 5.3 {set res} {/USING INDEX t1abf/}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
Loading…
Reference in New Issue
Block a user