Compare commits
12 Commits
master
...
commit-and
Author | SHA1 | Date | |
---|---|---|---|
![]() |
30d5b2fd21 | ||
![]() |
71fb34f757 | ||
![]() |
d209bd2d64 | ||
![]() |
92c526e71b | ||
![]() |
06315a8c67 | ||
![]() |
85aded1952 | ||
![]() |
c367ef3593 | ||
![]() |
a8602768f4 | ||
![]() |
083aaa551c | ||
![]() |
361549342c | ||
![]() |
458ce5f8f5 | ||
![]() |
3e97909bc5 |
27
manifest
27
manifest
@ -1,5 +1,5 @@
|
||||
C Call\sfflush()\son\s".echo"\soutput\sfrom\sthe\sshell,\sso\sthat\sthe\soutput\sto\nstdout\sis\saligned\swith\soutput\sto\sstderr.
|
||||
D 2024-11-16T18:54:46.664
|
||||
C Add\ssimple\stest\scases.\s\sIn\sdoing\sso\sI\sfound\sthat\sthe\sfeature\sdoes\snot\swork\non\sa\sLinux\sramdisk.
|
||||
D 2024-11-16T23:32:56.155
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
|
||||
@ -716,7 +716,7 @@ F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522
|
||||
F src/btree.c 63ca6b647342e8cef643863cd0962a542f133e1069460725ba4461dcda92b03c
|
||||
F src/btree.h 18e5e7b2124c23426a283523e5f31a4bff029131b795bb82391f9d2f3136fc50
|
||||
F src/btreeInt.h 98aadb6dcb77b012cab2574d6a728fad56b337fc946839b9898c4b4c969e30b6
|
||||
F src/build.c c6b09342d870a509529244ed8e19b4175a261f2e3163c199241d69e1d8a57607
|
||||
F src/build.c 2966f47b7be312f602658ae50225bb9255264ac4d3df70332e00eea461216c98
|
||||
F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c d35723024b963edce9c0fad5b3303e8bb9266083784844baed10a6dedfe26f3b
|
||||
@ -761,9 +761,9 @@ F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d87210
|
||||
F src/os_unix.c d2edbd92b07a3f778c2defa8a2e9d75acceb6267bda56948c41e8cdda65224d6
|
||||
F src/os_win.c db4baa8f62bbfe3967c71b008cea31a8f2ff337c1667ff4d8a677e697315ff0d
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c 9656ad4e8331efb8a4f94f7a0c6440b98caea073950a367ea0c728a53b8e62c9
|
||||
F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a
|
||||
F src/parse.y 8ec56598aa0df92428627502267d0d1c9778cc27308f8ffd31dfb2d017a8755f
|
||||
F src/pager.c d29770208271df2adbd96bc5d353aba74f84bbd79926734e9d4d4a081556439a
|
||||
F src/pager.h 4637ae0c299215d7ed3b54e379123b518e101c0453faa2d0f7db29cb23525cee
|
||||
F src/parse.y 8e86f09a67481b842504704d2c9919dcd22bca13244461d5dade85b308a23af2
|
||||
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
|
||||
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
|
||||
F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319
|
||||
@ -779,7 +779,7 @@ F src/shell.c.in 469039a2a09603bf32f47b5c4ddc61e8b980139919db1f46000241357f5f358
|
||||
F src/sqlite.h.in 4d93768709c53b7c653a63817a82d5a8625264ca0d8cdf99967ba147bdcf2aa6
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
|
||||
F src/sqliteInt.h 77be043f8694f4a8702d0ee882022b2e5a6489a0493e77c5d9a73f1efc5a2cc1
|
||||
F src/sqliteInt.h 08735a5db1be299c3478ceb03d63729c1c7c4fe1ba82ac7b724535098c86bfa7
|
||||
F src/sqliteLimit.h 6993c9cfe3af5b8169ae0e5f15627fc15596726d4f1dc90a221309f79715ce88
|
||||
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
@ -843,7 +843,7 @@ F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
|
||||
F src/utf.c 8b29d9a5956569ea2700f869669b8ef67a9662ee5e724ff77ab3c387e27094ba
|
||||
F src/util.c ceebf912f673247e305f16f97f0bb7285fca1d37413b79680714a553a9021d33
|
||||
F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40
|
||||
F src/vdbe.c 8a6eb02823b424b273614bae41579392a5c495424592b60423dd2c443a583df0
|
||||
F src/vdbe.c 1782cffa53d4bce9d9f2694debadbec6bb1e736a7e2bfd3f33a8f3d813d4cdae
|
||||
F src/vdbe.h c2549a215898a390de6669cfa32adba56f0d7e17ba5a7f7b14506d6fd5f0c36a
|
||||
F src/vdbeInt.h 2da01c73e8e3736a9015d5b04aa04d209bc9023d279d237d4d409205e921ea1e
|
||||
F src/vdbeapi.c 6353de05e8e78e497ccb33381ba5662ccc11c0339e5b1455faff01b6dacc3075
|
||||
@ -855,8 +855,8 @@ F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf8
|
||||
F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
|
||||
F src/vtab.c 316cd48e9320660db3047cd306cd056e4361180cebb4d0f10a39244e10c11422
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 8b7e309a8012659ac9275ad8cdcc6acaf73fa04b1090e38a01335f230fd10681
|
||||
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
|
||||
F src/wal.c 7a4962ae1f7cff6fe83d6f23902a2d7f19975f120c718ef4aa91b7a6a9c64c7f
|
||||
F src/wal.h a1ec57934aa26c23805e00ddbc0cd5da5760028d3608d882647345de2e330a3e
|
||||
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
|
||||
F src/where.c 4de9e7ca5f49e4a21c1d733e2b2fbbc8b62b1a157a58a562c569da84cfcb005b
|
||||
F src/whereInt.h 1e36ec50392f7cc3d93d1152d4338064cd522b87156a0739388b7e273735f0ca
|
||||
@ -1888,6 +1888,7 @@ F test/trace3.test 4f418ed30d15d9d17dcf13a17f0bd99a92e3038e038798e35db7525f82f4c
|
||||
F test/trans.test 45f6f9ab6f66a7b5744f1caac06b558f95da62501916906cf55586a896f9f439
|
||||
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
|
||||
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
|
||||
F test/trans4.test 9f6b30b09e9475a0b0590db5a71c09596e1546a9ec508ed73cddd5d812e2aad3
|
||||
F test/transitive1.test f8ee983600b33d167da1885657f064aec404e1c0d0bc8765fdf163f4c749237a
|
||||
F test/trigger1.test 2834f8830a1ae338d95c2e3ea0c2a7bc4cda126cdeb715004cf0fd071892e44f
|
||||
F test/trigger2.test 30fcb3a6aa6782020d47968735ee6086ed795f73a7affa9406c8d5a36e7b5265
|
||||
@ -2198,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
|
||||
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
|
||||
F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P cd942dce148c9d8f5a94cee61923aad8d1b732b807e004005f78323be30c02e7
|
||||
R c6e3e7808022fc93197afc8ff5529a17
|
||||
P d217b4847ecc4b3ce3eb3d1dc5e4774758d1f1f93b0df02c11f3c5944557c799
|
||||
R 5909ae71df1633b40ad9d4a2b82a36e8
|
||||
U drh
|
||||
Z 8206467963ac0d5803b490ec391283d6
|
||||
Z 8146320975380736b73f05c691b3a25e
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
c38b9db3c4f71706a7d211424da64311e6e5daf64b224565a6d82d4b1a68e261
|
||||
80b98446fc070d9a2ab5816dd941cb829f067b2fcf2a3db7a19bf73806fbcdcc
|
||||
|
12
src/build.c
12
src/build.c
@ -5198,6 +5198,7 @@ void sqlite3BeginTransaction(Parse *pParse, int type){
|
||||
int i;
|
||||
|
||||
assert( pParse!=0 );
|
||||
assert( type==TK_DEFERRED || type==TK_IMMEDIATE || type==TK_EXCLUSIVE );
|
||||
db = pParse->db;
|
||||
assert( db!=0 );
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){
|
||||
@ -5227,14 +5228,20 @@ void sqlite3BeginTransaction(Parse *pParse, int type){
|
||||
** Generate VDBE code for a COMMIT or ROLLBACK statement.
|
||||
** Code for ROLLBACK is generated if eType==TK_ROLLBACK. Otherwise
|
||||
** code is generated for a COMMIT.
|
||||
**
|
||||
** If bContinueTrans is true, then do the COMMIT so that past changes are
|
||||
** made permanent and visible to readers, but hold on to the write lock
|
||||
** and start a new transaction, without allowing any other database
|
||||
** connections to do a write or checkpoint.
|
||||
*/
|
||||
void sqlite3EndTransaction(Parse *pParse, int eType){
|
||||
void sqlite3EndTransaction(Parse *pParse, int eType, int bContinueTrans){
|
||||
Vdbe *v;
|
||||
int isRollback;
|
||||
|
||||
assert( pParse!=0 );
|
||||
assert( pParse->db!=0 );
|
||||
assert( eType==TK_COMMIT || eType==TK_END || eType==TK_ROLLBACK );
|
||||
assert( bContinueTrans==0 || bContinueTrans==1 );
|
||||
isRollback = eType==TK_ROLLBACK;
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION,
|
||||
isRollback ? "ROLLBACK" : "COMMIT", 0, 0) ){
|
||||
@ -5242,7 +5249,8 @@ void sqlite3EndTransaction(Parse *pParse, int eType){
|
||||
}
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( v ){
|
||||
sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, isRollback);
|
||||
sqlite3VdbeAddOp3(v, OP_AutoCommit, 1, isRollback, bContinueTrans);
|
||||
if( bContinueTrans ) sqlite3BeginTransaction(pParse, TK_IMMEDIATE);
|
||||
}
|
||||
}
|
||||
|
||||
|
20
src/pager.c
20
src/pager.c
@ -643,6 +643,7 @@ struct Pager {
|
||||
*/
|
||||
u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */
|
||||
u8 eLock; /* Current lock held on database file */
|
||||
u8 bHoldWrLock; /* Do not release write locks while true */
|
||||
u8 changeCountDone; /* Set after incrementing the change-counter */
|
||||
u8 setSuper; /* Super-jrnl name is written into jrnl */
|
||||
u8 doNotSpill; /* Do not spill the cache when non-zero */
|
||||
@ -1145,15 +1146,16 @@ static int pagerUnlockDb(Pager *pPager, int eLock){
|
||||
assert( !pPager->exclusiveMode || pPager->eLock==eLock );
|
||||
assert( eLock==NO_LOCK || eLock==SHARED_LOCK );
|
||||
assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 );
|
||||
pPager->changeCountDone = pPager->tempFile; /* ticket fb3b3024ea238d5c */
|
||||
if( isOpen(pPager->fd) ){
|
||||
assert( pPager->eLock>=eLock );
|
||||
if( pPager->bHoldWrLock ) return SQLITE_OK;
|
||||
rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock);
|
||||
if( pPager->eLock!=UNKNOWN_LOCK ){
|
||||
pPager->eLock = (u8)eLock;
|
||||
}
|
||||
IOTRACE(("UNLOCK %p %d\n", pPager, eLock))
|
||||
}
|
||||
pPager->changeCountDone = pPager->tempFile; /* ticket fb3b3024ea238d5c */
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -5365,6 +5367,7 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
||||
assert( pPager->eState==PAGER_OPEN );
|
||||
assert( (pPager->eLock==SHARED_LOCK)
|
||||
|| (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK)
|
||||
|| (pPager->bHoldWrLock && pPager->eLock>=SHARED_LOCK)
|
||||
);
|
||||
}
|
||||
|
||||
@ -6887,6 +6890,21 @@ int sqlite3PagerIsMemdb(Pager *pPager){
|
||||
return pPager->tempFile || pPager->memVfs;
|
||||
}
|
||||
|
||||
/*
|
||||
** In all pagers associated with db, set or clear the bHoldWrLock
|
||||
** flag.
|
||||
*/
|
||||
void sqlite3PagerHoldWrLock(sqlite3 *db, u8 bOnOff){
|
||||
int iDb;
|
||||
Pager *pPager;
|
||||
for(iDb=0; iDb<db->nDb; iDb++){
|
||||
if( db->aDb[iDb].pBt==0 ) continue;
|
||||
pPager = sqlite3BtreePager(db->aDb[iDb].pBt);
|
||||
pPager->bHoldWrLock = bOnOff;
|
||||
if( pPager->pWal ) sqlite3WalHoldWrLock(pPager->pWal, bOnOff);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Check that there are at least nSavepoint savepoints open. If there are
|
||||
** currently less than nSavepoints open, then open one or more savepoints
|
||||
|
@ -218,6 +218,7 @@ void *sqlite3PagerTempSpace(Pager*);
|
||||
int sqlite3PagerIsMemdb(Pager*);
|
||||
void sqlite3PagerCacheStat(Pager *, int, int, u64*);
|
||||
void sqlite3PagerClearCache(Pager*);
|
||||
void sqlite3PagerHoldWrLock(sqlite3*,u8);
|
||||
int sqlite3SectorSize(sqlite3_file *);
|
||||
|
||||
/* Functions used to truncate the database file. */
|
||||
|
15
src/parse.y
15
src/parse.y
@ -169,8 +169,10 @@ transtype(A) ::= . {A = TK_DEFERRED;}
|
||||
transtype(A) ::= DEFERRED(X). {A = @X; /*A-overwrites-X*/}
|
||||
transtype(A) ::= IMMEDIATE(X). {A = @X; /*A-overwrites-X*/}
|
||||
transtype(A) ::= EXCLUSIVE(X). {A = @X; /*A-overwrites-X*/}
|
||||
cmd ::= COMMIT|END(X) trans_opt. {sqlite3EndTransaction(pParse,@X);}
|
||||
cmd ::= ROLLBACK(X) trans_opt. {sqlite3EndTransaction(pParse,@X);}
|
||||
cmd ::= ROLLBACK(X) trans_opt. {sqlite3EndTransaction(pParse,@X,0);}
|
||||
cmd ::= COMMIT(X) trans_opt. {sqlite3EndTransaction(pParse,@X,0);}
|
||||
cmd ::= END(X) trans_opt. {sqlite3EndTransaction(pParse,@X,0);}
|
||||
// See also the COMMIT AND CONTINUE TRANSACTION section below
|
||||
|
||||
savepoint_opt ::= SAVEPOINT.
|
||||
savepoint_opt ::= .
|
||||
@ -474,6 +476,15 @@ resolvetype(A) ::= raisetype(A).
|
||||
resolvetype(A) ::= IGNORE. {A = OE_Ignore;}
|
||||
resolvetype(A) ::= REPLACE. {A = OE_Replace;}
|
||||
|
||||
////////////////////////// COMMIT AND CONTINUE TRANSACTION ////////////////////
|
||||
//
|
||||
cmd ::= COMMIT(X) AND ID(Y) TRANSACTION. {
|
||||
if( Y.n!=8 || sqlite3_strnicmp(Y.z,"continue",8)!=0 ){
|
||||
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &Y);
|
||||
}
|
||||
sqlite3EndTransaction(pParse, @X, 1);
|
||||
}
|
||||
|
||||
////////////////////////// The DROP TABLE /////////////////////////////////////
|
||||
//
|
||||
cmd ::= DROP TABLE ifexists(E) fullname(X). {
|
||||
|
@ -5072,8 +5072,8 @@ void sqlite3PrngRestoreState(void);
|
||||
void sqlite3RollbackAll(sqlite3*,int);
|
||||
void sqlite3CodeVerifySchema(Parse*, int);
|
||||
void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
|
||||
void sqlite3BeginTransaction(Parse*, int);
|
||||
void sqlite3EndTransaction(Parse*,int);
|
||||
void sqlite3BeginTransaction(Parse*,int);
|
||||
void sqlite3EndTransaction(Parse*,int,int);
|
||||
void sqlite3Savepoint(Parse*, int, Token*);
|
||||
void sqlite3CloseSavepoints(sqlite3 *);
|
||||
void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
|
||||
|
32
src/vdbe.c
32
src/vdbe.c
@ -3934,14 +3934,22 @@ case OP_Savepoint: {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: AutoCommit P1 P2 * * *
|
||||
/* Opcode: AutoCommit P1 P2 P3 * *
|
||||
**
|
||||
** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll
|
||||
** back any currently active btree transactions. If there are any active
|
||||
** VMs (apart from this one), then a ROLLBACK fails. A COMMIT fails if
|
||||
** there are active writing VMs or active VMs that use shared cache.
|
||||
** Set the database auto-commit flag to P1 (1 or 0). The current trasaction
|
||||
** will commit when the VDBE halts if the auto-commit flag is 1. The
|
||||
** current transaction will stay in effect if the auto-commit flag is 0.
|
||||
** Thus, this opcode implements COMMIT when P1 is 0 and it implements
|
||||
** BEGIN when P1 is 1.
|
||||
**
|
||||
** This instruction causes the VM to halt.
|
||||
** If P2 is true, rollback any currently active btree transactions. If there
|
||||
** are any active VMs (apart from this one), then a ROLLBACK fails. A
|
||||
** COMMIT fails if there are active writing VMs or active VMs that use
|
||||
** shared cache.
|
||||
**
|
||||
** If P3 and P1 are both is 1, then COMMIT but also hang on to the write lock
|
||||
** for the transaction. The P3 flag is used to help implement
|
||||
** COMMIT AND CONTINUE TRANSACTION.
|
||||
*/
|
||||
case OP_AutoCommit: {
|
||||
int desiredAutoCommit;
|
||||
@ -3959,7 +3967,7 @@ case OP_AutoCommit: {
|
||||
assert( desiredAutoCommit==1 );
|
||||
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
|
||||
db->autoCommit = 1;
|
||||
}else if( desiredAutoCommit && db->nVdbeWrite>0 ){
|
||||
}else if( desiredAutoCommit && db->nVdbeWrite>pOp->p3 ){
|
||||
/* If this instruction implements a COMMIT and other VMs are writing
|
||||
** return an error indicating that the other VMs must complete first.
|
||||
*/
|
||||
@ -3972,6 +3980,8 @@ case OP_AutoCommit: {
|
||||
}else{
|
||||
db->autoCommit = (u8)desiredAutoCommit;
|
||||
}
|
||||
assert( pOp->p3==0 || pOp->p3==1 );
|
||||
sqlite3PagerHoldWrLock(db, pOp->p3);
|
||||
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
|
||||
p->pc = (int)(pOp - aOp);
|
||||
db->autoCommit = (u8)(1-desiredAutoCommit);
|
||||
@ -3980,6 +3990,13 @@ case OP_AutoCommit: {
|
||||
}
|
||||
sqlite3CloseSavepoints(db);
|
||||
if( p->rc==SQLITE_OK ){
|
||||
if( pOp->p3 ){
|
||||
db->nVdbeActive++;
|
||||
db->nVdbeRead++;
|
||||
db->nVdbeWrite++;
|
||||
p->eVdbeState = VDBE_RUN_STATE;
|
||||
break;
|
||||
}
|
||||
rc = SQLITE_DONE;
|
||||
}else{
|
||||
rc = SQLITE_ERROR;
|
||||
@ -9128,6 +9145,7 @@ abort_due_to_error:
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
assert( rc );
|
||||
sqlite3PagerHoldWrLock(db, 0);
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( db->flags & SQLITE_VdbeTrace ){
|
||||
const char *zTrace = p->zSql;
|
||||
|
28
src/wal.c
28
src/wal.c
@ -516,6 +516,7 @@ struct Wal {
|
||||
i16 readLock; /* Which read lock is being held. -1 for none */
|
||||
u8 syncFlags; /* Flags to use to sync header writes */
|
||||
u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */
|
||||
u8 bHoldWrLock; /* Do not release WAL_WRITE locks if true */
|
||||
u8 writeLock; /* True if in a write transaction */
|
||||
u8 ckptLock; /* True if holding a checkpoint lock */
|
||||
u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */
|
||||
@ -2064,7 +2065,7 @@ int sqlite3WalWriteLock(Wal *pWal, int bLock){
|
||||
}
|
||||
walDisableBlocking(pWal);
|
||||
}
|
||||
}else if( pWal->writeLock ){
|
||||
}else if( pWal->writeLock && !pWal->bHOldWrLock ){
|
||||
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
|
||||
pWal->writeLock = 0;
|
||||
}
|
||||
@ -2698,7 +2699,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
|
||||
*pChanged = 1;
|
||||
}
|
||||
}
|
||||
if( bWriteLock==0 ){
|
||||
if( bWriteLock==0 && !pWal->bHoldWrLock ){
|
||||
pWal->writeLock = 0;
|
||||
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
|
||||
}
|
||||
@ -3670,7 +3671,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
|
||||
/* Cannot start a write transaction without first holding a read
|
||||
** transaction. */
|
||||
assert( pWal->readLock>=0 );
|
||||
assert( pWal->writeLock==0 && pWal->iReCksum==0 );
|
||||
// assert( pWal->writeLock==0 && pWal->iReCksum==0 );
|
||||
|
||||
if( pWal->readOnly ){
|
||||
return SQLITE_READONLY;
|
||||
@ -3679,11 +3680,13 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
|
||||
/* Only one writer allowed at a time. Get the write lock. Return
|
||||
** SQLITE_BUSY if unable.
|
||||
*/
|
||||
rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
|
||||
if( rc ){
|
||||
return rc;
|
||||
if( pWal->writeLock==0 ){
|
||||
rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
|
||||
if( rc ){
|
||||
return rc;
|
||||
}
|
||||
pWal->writeLock = 1;
|
||||
}
|
||||
pWal->writeLock = 1;
|
||||
|
||||
/* If another connection has written to the database file since the
|
||||
** time the read transaction on this connection was started, then
|
||||
@ -3708,7 +3711,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
|
||||
** routine merely releases the lock.
|
||||
*/
|
||||
int sqlite3WalEndWriteTransaction(Wal *pWal){
|
||||
if( pWal->writeLock ){
|
||||
if( pWal->writeLock && !pWal->bHoldWrLock ){
|
||||
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
|
||||
pWal->writeLock = 0;
|
||||
pWal->iReCksum = 0;
|
||||
@ -4419,7 +4422,7 @@ int sqlite3WalCallback(Wal *pWal){
|
||||
*/
|
||||
int sqlite3WalExclusiveMode(Wal *pWal, int op){
|
||||
int rc;
|
||||
assert( pWal->writeLock==0 );
|
||||
// assert( pWal->writeLock==0 );
|
||||
assert( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE || op==-1 );
|
||||
|
||||
/* pWal->readLock is usually set, but might be -1 if there was a
|
||||
@ -4456,6 +4459,13 @@ int sqlite3WalExclusiveMode(Wal *pWal, int op){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the temporary minimum lock level for the WAL subsystem.
|
||||
*/
|
||||
void sqlite3WalHoldWrLock(Wal *pWal, int bOnOff){
|
||||
pWal->bHoldWrLock = bOnOff;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if the argument is non-NULL and the WAL module is using
|
||||
** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
|
||||
|
@ -129,6 +129,11 @@ int sqlite3WalExclusiveMode(Wal *pWal, int op);
|
||||
*/
|
||||
int sqlite3WalHeapMemory(Wal *pWal);
|
||||
|
||||
/* Set or clear the transient flag that prevents the WAL_WRITE lock
|
||||
** from being released.
|
||||
*/
|
||||
void sqlite3WalHoldWrLock(Wal *pWal, int bOnOff);
|
||||
|
||||
#ifdef SQLITE_ENABLE_SNAPSHOT
|
||||
int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot);
|
||||
void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot);
|
||||
|
95
test/trans4.test
Normal file
95
test/trans4.test
Normal file
@ -0,0 +1,95 @@
|
||||
# 2024-11-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.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Test cases for COMMIT AND CONTINUE TRANSACTION.
|
||||
#
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
unset -nocomplain ecode
|
||||
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
sqlite3 db2 test.db
|
||||
do_execsql_test -db db2 trans4-1.1 {
|
||||
CREATE TABLE t1(x);
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(1),(2),(3);
|
||||
SELECT * FROM t1;
|
||||
} {1 2 3}
|
||||
|
||||
do_catchsql_test trans4-1.2 {
|
||||
SELECT * FROM t1;
|
||||
} {0 {}}
|
||||
|
||||
do_execsql_test -db db2 trans4-1.3 {
|
||||
COMMIT AND CONTINUE TRANSACTION;
|
||||
}
|
||||
|
||||
do_catchsql_test trans4-1.4 {
|
||||
SELECT * FROM t1;
|
||||
} {1 {database is locked}}
|
||||
|
||||
do_execsql_test -db db2 trans4-1.5 {
|
||||
INSERT INTO t1 VALUES(4);
|
||||
INSERT INTO t1 VALUES(5);
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
do_catchsql_test trans4-1.6 {
|
||||
SELECT * FROM t1;
|
||||
} {0 {1 2 3 4 5}}
|
||||
|
||||
db2 close
|
||||
db eval {PRAGMA journal_mode=WAL; VACUUM;}
|
||||
sqlite3 db2 test.db
|
||||
|
||||
do_execsql_test -db db2 trans4-2.1 {
|
||||
DELETE FROM t1;
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(1),(2),(3);
|
||||
SELECT * FROM t1;
|
||||
} {1 2 3}
|
||||
|
||||
do_catchsql_test trans4-2.2 {
|
||||
SELECT * FROM t1;
|
||||
} {0 {}}
|
||||
|
||||
do_execsql_test -db db2 trans4-2.3 {
|
||||
COMMIT AND CONTINUE TRANSACTION;
|
||||
INSERT INTO t1 VALUES(4);
|
||||
}
|
||||
|
||||
do_catchsql_test trans4-2.4 {
|
||||
SELECT * FROM t1;
|
||||
} {0 {1 2 3}}
|
||||
|
||||
do_execsql_test -db db2 trans4-2.5 {
|
||||
INSERT INTO t1 VALUES(5);
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
do_catchsql_test trans4-2.6 {
|
||||
SELECT * FROM t1;
|
||||
} {0 {1 2 3 4 5}}
|
||||
|
||||
do_catchsql_test trans4-3.1 {
|
||||
BEGIN;
|
||||
COMMIT AND continuex TRANSACTION;
|
||||
} {1 {near "continuex": syntax error}}
|
||||
do_catchsql_test trans4-3.2 {
|
||||
COMMIT AND continue;
|
||||
} {1 {near ";": syntax error}}
|
||||
do_catchsql_test trans4-3.3 {
|
||||
COMMIT AND continue Transaction;
|
||||
} {0 {}}
|
||||
db2 close
|
||||
|
||||
finish_test
|
Loading…
x
Reference in New Issue
Block a user