Compare commits

...

22 Commits

Author SHA1 Message Date
drh 2400eaa08c Bring all the latest trunk fixes and enhancements into the commit-and-continue branch.
FossilOrigin-Name: 19e47df37a1ab76625de4a9643e78d2ab8d1241c9fb58ca2f9e3708622050d10
2024-12-09 21:01:19 +00:00
drh cb591953e4 Enhance the ".import" command of the CLI so that it is able to insert into a
view that has an instead-of trigger.
[forum:/info/3e03c73150f8b9f8|Forum post 3e03c73150f8b9f8].

FossilOrigin-Name: c71acee1cf45abf0429e8b1668315c75b155d7c300d53833aeacd92c9bb3395d
2024-12-09 20:36:14 +00:00
drh 49e053f873 Use the P5 rather than the P3 parameter of OP_AutoCommit to avoid an
unnecessary conflict in the begin-concurrent branch.  Fix some comments.

FossilOrigin-Name: e6f63526189bdd081af4f3de81ef2ba5e78dd2e722f9796eff9662bfd125a8c8
2024-11-27 14:41:08 +00:00
drh 4bab0fdb37 Merge the latest trunk enhancements into the commit-and-continue branch.
FossilOrigin-Name: adaddf49485d5c1bf71e4a1aa116eaebd77fef88f5a0061d441c13e3e58c330f
2024-11-27 14:16:34 +00:00
drh 5f152d5794 Merge the latest trunk fixes and makefile enhancements into the commit-and-continue branch.
FossilOrigin-Name: 34cb6029cc79955b4e4790af2647d6db428b38757470f6990d8f8d8ed4979d8f
2024-11-20 20:24:28 +00:00
drh ada583f6e1 Disable commit-and-continue tests under the inmemory-journal and journaltest
permutations.

FossilOrigin-Name: 2f31c2b0a14e278c4bdb3ab19811b9a3cdfeb788e4fb2308408d9d11a11a7313
2024-11-18 14:54:34 +00:00
drh 6e81f2af83 The COMMIT AND CONTINUE TRANSACTION syntax is disabled by default. Enable it
using the SQLITE_DBCONFIG_CONTINUE_TRANSACTION configuration option.

FossilOrigin-Name: a2b784cb876f8c7e5b713a5ae5b7c8072e40d1fb48837bff085683bf1b71c68f
2024-11-18 11:49:47 +00:00
drh 1a9e667c81 Fix a typo in a variable name.
FossilOrigin-Name: 9c7f569acdc2fb829354cefda42389a554f5fd957a7ef47e6e093f30789bb28e
2024-11-18 11:14:58 +00:00
drh 7fbebfdddb Fix an uninitialized variable that appears to be the cause of the problems
with check-in [80b98446fc070d9a].

FossilOrigin-Name: 22393c3a08e9473eef23a3182720b0f908253d3c02ebaad77e120355326023be
2024-11-17 23:53:27 +00:00
drh e3c97544e1 Merge the latest trunk enhancements into the commit-and-continue branch.
FossilOrigin-Name: 1742af1215c37c83b84b072773ddaa2ec3bacc2f0baa29a49dfeb666e6f13e63
2024-11-17 11:46:47 +00:00
drh 30d5b2fd21 Add simple test cases. In doing so I found that the feature does not work
on a Linux ramdisk.

FossilOrigin-Name: 80b98446fc070d9a2ab5816dd941cb829f067b2fcf2a3db7a19bf73806fbcdcc
2024-11-16 23:32:56 +00:00
drh 71fb34f757 Merge all the latest trunk enhancements into the commit-and-continue branch.
FossilOrigin-Name: d217b4847ecc4b3ce3eb3d1dc5e4774758d1f1f93b0df02c11f3c5944557c799
2024-11-16 18:59:31 +00:00
drh d209bd2d64 Clean up the implementation now that it only has to deal with the
much simplier concept of COMMIT AND CONTINUE TRANSACTION.

FossilOrigin-Name: 17360660bbaf1b6009fc608f9687914789853f25ae38c1377a1ea5e5a621f34c
2024-11-16 18:37:56 +00:00
drh 92c526e71b Simplify the new syntax to be just "COMMIT AND CONTINUE TRANSACTION".
FossilOrigin-Name: 61797109a2f0fee84bc3e0a0c021544c87e4b985e7e7b549e387e396cf1f86ec
2024-11-16 14:40:11 +00:00
drh 06315a8c67 Load all the latest trunk enhancements, and especially the enhancements to
vfstrace, into the commit-and-begin branch.

FossilOrigin-Name: 605889b02122d98011e9a8d458ba01010423680dd69446458ffe7230a1d47937
2024-11-15 20:42:12 +00:00
drh 85aded1952 Another approach at implementing COMMIT AND BEGIN.
FossilOrigin-Name: a905bd5dd6ccb6f2e5671a5b691e61c853aa425e6a53e7e6b6dbc12e4020ef14
2024-11-15 17:28:57 +00:00
drh c367ef3593 Attempt to hold a lock across the COMMIT AND BEGIN boundary so that no other
process can start a new transaction in between the COMMIT and the BEGIN.

FossilOrigin-Name: bc8bcc53ff7a0cbe1c2e3a96e1bded055622b667c27284798433cc6d58c7f9fe
2024-11-14 22:59:16 +00:00
drh a8602768f4 Fix assertion faults in the COMMIT AND BEGIN path.
FossilOrigin-Name: a9a4ac17c2169fa7f97434177dfb01eaf4fae7f99b9203677d985d048eea4559
2024-11-14 19:59:02 +00:00
drh 083aaa551c Merge more makefile enhancements from trunk into the commit-and-begin branch.
FossilOrigin-Name: 098400d36140b90e1d6dab5f54b080568c633875916a1130b6627599b4f99469
2024-11-14 19:36:41 +00:00
drh 361549342c Merge makefile enhancements from trunk into the commit-and-begin branch.
FossilOrigin-Name: b5dd11e0ac059573c2cc14640f0cd127a9f4c3d629023b21745f5442cb2de28a
2024-11-14 19:08:15 +00:00
drh 458ce5f8f5 Merge the latest trunk enhancements and fixes into the commit-and-begin branch.
FossilOrigin-Name: 05fb5d30750d20db86bbee1c27bd5965f999116a05de6414ab2aef060b407ad2
2024-11-14 17:25:28 +00:00
drh 3e97909bc5 Early prototype code for COMMIT AND BEGIN. Does not currently work.
FossilOrigin-Name: ddac5973215478d0cacdd99c697345019018916453ec0657868a4e2c21601779
2024-11-14 12:03:13 +00:00
15 changed files with 247 additions and 45 deletions
+18 -17
View File
@@ -1,5 +1,5 @@
C Make\sthe\sTCL\sinterface\smore\srebust\sagainst\svery\slarge\sstrings\scoming\nout\sof\sTCL9.
D 2024-12-09T20:46:36.165
C Bring\sall\sthe\slatest\strunk\sfixes\sand\senhancements\sinto\sthe\scommit-and-continue\sbranch.
D 2024-12-09T21:01:19.036
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
@@ -719,7 +719,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 a933062f4bf848e67993adb20d587cc13de8e987fdb4e0e7191926ef3741278f
F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c d35723024b963edce9c0fad5b3303e8bb9266083784844baed10a6dedfe26f3b
@@ -740,7 +740,7 @@ F src/insert.c f8d1a0f8ee258411009c6b7f2d93170e351bd19f5ad89d57e1180644297cbe70
F src/json.c 68a98c020c22127f2d65f08855f7fc7460ff352a6ce0b543d8931dde83319c22
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
F src/main.c efacea3a809ba236233c4bc7648e623c28cb5fd1e1a343e74fe772005f142d8c
F src/main.c 9be9c058d0f0028230f2f06a45c1ff6edc6e6e2edc57e088296677c677dbf1bc
F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
@@ -764,9 +764,9 @@ F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d87210
F src/os_unix.c d2edbd92b07a3f778c2defa8a2e9d75acceb6267bda56948c41e8cdda65224d6
F src/os_win.c 49c7725b500f5867e8360e75eeb30f9d70b62fa1f05c8a101da627210578df32
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 9656ad4e8331efb8a4f94f7a0c6440b98caea073950a367ea0c728a53b8e62c9
F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a
F src/parse.y dcf45a81b61223ac93e61fdfe9b22d635dd371c446e8222634d90aa37e25e5f6
F src/pager.c d29770208271df2adbd96bc5d353aba74f84bbd79926734e9d4d4a081556439a
F src/pager.h 4637ae0c299215d7ed3b54e379123b518e101c0453faa2d0f7db29cb23525cee
F src/parse.y 2b2b7a96e46dff37b85b0476cc2f6c58e61f0ba007928c4121ac726adcae497b
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319
@@ -778,17 +778,17 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 1c2b2321e1658e02f96da96d3071abcaa6839a1d75edd960a75a0ab11b6041bb
F src/shell.c.in ee54de10e9bd5572f689a6bc0c8e6fa58a8870e1670978ded44412d2715fd908
F src/sqlite.h.in 6afbcaae44140216704a6c82e4c4ea4118c46d5f6573d6c5fa4fc901ed9d369e
F src/shell.c.in aefeced3bc11bc3d2e7b31f14435c7ebc36527f0e3289ed14c64cf0755ccb741
F src/sqlite.h.in 236595e722c256189cfba479dc7c45753665e6d4ae5c2281fb7731b045f92629
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
F src/sqliteInt.h 77be043f8694f4a8702d0ee882022b2e5a6489a0493e77c5d9a73f1efc5a2cc1
F src/sqliteInt.h 0e5e4a3cadda1a1dadedd990093ad33d0e898f5b9bcb756f7765a835887708e4
F src/sqliteLimit.h 6993c9cfe3af5b8169ae0e5f15627fc15596726d4f1dc90a221309f79715ce88
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/tclsqlite.c 90441d3cc16f966a23499d9096a3d2d971e5e8fddb4d1413b096b79c2b2cff07
F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395
F src/test1.c 2d507751bfb4aa254dc22588ef1e3c5c5cfcb2e636d0e6e1fa0bbd307669c2a8
F src/test1.c cbf1c6ca9df2755b86808a671e1b03a787dc18cde9f7f3bfffd03da236f1173b
F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3
F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b
F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d
@@ -846,7 +846,7 @@ F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
F src/utf.c 8b29d9a5956569ea2700f869669b8ef67a9662ee5e724ff77ab3c387e27094ba
F src/util.c e5f6a5eeaa26b69054a43bbd0048cfe3d2851f6961052b35aed8f695df922850
F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40
F src/vdbe.c 8a6eb02823b424b273614bae41579392a5c495424592b60423dd2c443a583df0
F src/vdbe.c 0bcfd21c45c6af8e51ecec9ca10df2a00f5662a1f646aa0874b0ab791e7da8f3
F src/vdbe.h 9676348d342bd04e21e384c63b57224171ce84fac77853357334ef94c4d33cf4
F src/vdbeInt.h 2da01c73e8e3736a9015d5b04aa04d209bc9023d279d237d4d409205e921ea1e
F src/vdbeapi.c 6353de05e8e78e497ccb33381ba5662ccc11c0339e5b1455faff01b6dacc3075
@@ -858,8 +858,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 73064f1e2d1776cdfb6f6d12943888d83d2f3ab63e76ff2f13a992311def9ca8
F src/wal.h a1ec57934aa26c23805e00ddbc0cd5da5760028d3608d882647345de2e330a3e
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
F src/where.c 377f3363983251ec6b23aad5a3963822199d9bff2ad4072a5e006959ee5a2abb
F src/whereInt.h 1e36ec50392f7cc3d93d1152d4338064cd522b87156a0739388b7e273735f0ca
@@ -1892,6 +1892,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 ad936cefc84775723976ca1acb3cfc16e07f7769468b74366299758e0c2ad317
F test/transitive1.test f8ee983600b33d167da1885657f064aec404e1c0d0bc8765fdf163f4c749237a
F test/trigger1.test 2834f8830a1ae338d95c2e3ea0c2a7bc4cda126cdeb715004cf0fd071892e44f
F test/trigger2.test 30fcb3a6aa6782020d47968735ee6086ed795f73a7affa9406c8d5a36e7b5265
@@ -2202,8 +2203,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 7dcc3731a9057a91f1b173fbab2841d8a666a945d9bc61d4c20f8a2a279d5ff1
R e19f4142a15244f80b542d1a07f443fa
P c71acee1cf45abf0429e8b1668315c75b155d7c300d53833aeacd92c9bb3395d e2bae4143afd07de1ae55a6d2606a3b541a5b94568aa41f6a96e5d1245471653
R 15bda62d46b0272a5326f52c641b86fe
U drh
Z 5bb7b8fb1e527b79d5e286156e101c7f
Z 03e29135673c9b0005ee6ad7dd6831df
# Remove this line to create a well-formed Fossil manifest.
+1 -1
View File
@@ -1 +1 @@
e2bae4143afd07de1ae55a6d2606a3b541a5b94568aa41f6a96e5d1245471653
19e47df37a1ab76625de4a9643e78d2ab8d1241c9fb58ca2f9e3708622050d10
+12 -1
View File
@@ -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) ){
@@ -5243,6 +5250,10 @@ void sqlite3EndTransaction(Parse *pParse, int eType){
v = sqlite3GetVdbe(pParse);
if( v ){
sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, isRollback);
if( bContinueTrans ){
sqlite3VdbeChangeP5(v, 0x01);
sqlite3BeginTransaction(pParse, TK_IMMEDIATE);
}
}
}
+1
View File
@@ -980,6 +980,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
{ SQLITE_DBCONFIG_TRUSTED_SCHEMA, SQLITE_TrustedSchema },
{ SQLITE_DBCONFIG_STMT_SCANSTATUS, SQLITE_StmtScanStatus },
{ SQLITE_DBCONFIG_REVERSE_SCANORDER, SQLITE_ReverseOrder },
{ SQLITE_DBCONFIG_CONTINUE_TRANSACTION, SQLITE_OkContTrans },
};
unsigned int i;
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
+19 -1
View File
@@ -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
+1
View File
@@ -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. */
+16 -2
View File
@@ -176,8 +176,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 ::= .
@@ -481,6 +483,18 @@ resolvetype(A) ::= raisetype(A).
resolvetype(A) ::= IGNORE. {A = OE_Ignore;}
resolvetype(A) ::= REPLACE. {A = OE_Replace;}
////////////////////////// COMMIT AND CONTINUE TRANSACTION ////////////////////
//
cmd ::= COMMIT(X) AND(A) ID(Y) TRANSACTION. {
if( (pParse->db->flags & SQLITE_OkContTrans)==0 ){
parserSyntaxError(pParse, &A);
}
if( Y.n!=8 || sqlite3_strnicmp(Y.z,"continue",8)!=0 ){
parserSyntaxError(pParse, &Y);
}
sqlite3EndTransaction(pParse, @X, 1);
}
////////////////////////// The DROP TABLE /////////////////////////////////////
//
cmd ::= DROP TABLE ifexists(E) fullname(X). {
+1 -1
View File
@@ -8719,12 +8719,12 @@ static int do_meta_command(char *zLine, ShellState *p){
}
sqlite3_free(azName);
}else
if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbconfig", n)==0 ){
static const struct DbConfigChoices {
const char *zName;
int op;
} aDbConfig[] = {
{ "continue_transaction",SQLITE_DBCONFIG_CONTINUE_TRANSACTION },
{ "defensive", SQLITE_DBCONFIG_DEFENSIVE },
{ "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL },
{ "dqs_dml", SQLITE_DBCONFIG_DQS_DML },
+13 -1
View File
@@ -2521,6 +2521,17 @@ struct sqlite3_mem_methods {
** then 0 or 1 is written into the integer that the second argument points to
** depending on if the reverse scan order flag is set after processing the
** first argument.
**
** [[SQLITE_DBCONFIG_CONTINUE_TRANSACTION]]
** <dt>SQLITE_DBCONFIG_CONTINUE_TRANSACTION</dt>
** <dd>The SQLITE_DBCONFIG_CONTINUE_TRANSACTION option enables or disables
** the COMMIT AND CONTINUE TRANSACTION syntax. That special syntax if off
** by default. This option takes two arguments which are an integer and a
** pointer to an integer. The first argument is 1, 0, or -1 to enable,
** disable, or leave unchanged the COMMIT AND CONTINUE TRANSACTION syntax,
** respectively. If the second argument is not NULL, then 0 or 1 is written
** into the integer that the second argument points to depending on whether
** or not the COMMIT AND CONTINUE TRANSACTION syntax is enabled.
** </dd>
**
** </dl>
@@ -2545,7 +2556,8 @@ struct sqlite3_mem_methods {
#define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */
#define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 /* int int* */
#define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 /* int int* */
#define SQLITE_DBCONFIG_MAX 1019 /* Largest DBCONFIG */
#define SQLITE_DBCONFIG_CONTINUE_TRANSACTION 1020 /* int int* */
#define SQLITE_DBCONFIG_MAX 1020 /* Largest DBCONFIG */
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
+5 -4
View File
@@ -1799,8 +1799,7 @@ struct sqlite3 {
#define SQLITE_ShortColNames 0x00000040 /* Show short columns names */
#define SQLITE_TrustedSchema 0x00000080 /* Allow unsafe functions and
** vtabs in the schema definition */
#define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */
/* result set is empty */
#define SQLITE_OkContTrans 0x00000100 /* Enable COMMIT AND CONTINUE syntax*/
#define SQLITE_IgnoreChecks 0x00000200 /* Do not enforce check constraints */
#define SQLITE_StmtScanStatus 0x00000400 /* Enable stmt_scanstats() counters */
#define SQLITE_NoCkptOnClose 0x00000800 /* No checkpoint on close()/DETACH */
@@ -1830,6 +1829,8 @@ struct sqlite3 {
#define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */
#define SQLITE_ReadUncommit HI(0x00004) /* READ UNCOMMITTED in shared-cache */
#define SQLITE_FkNoAction HI(0x00008) /* Treat all FK as NO ACTION */
#define SQLITE_NullCallback HI(0x00010) /* Invoke the callback once if the */
/* result set is empty */
/* Flags used only if debugging */
#ifdef SQLITE_DEBUG
@@ -5072,8 +5073,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*);
+1
View File
@@ -8389,6 +8389,7 @@ static int SQLITE_TCLAPI test_sqlite3_db_config(
{ "DQS_DDL", SQLITE_DBCONFIG_DQS_DDL },
{ "LEGACY_FILE_FORMAT", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT },
{ "STMT_SCANSTATUS", SQLITE_DBCONFIG_STMT_SCANSTATUS },
{ "CONTINUE_TRANSACTION",SQLITE_DBCONFIG_CONTINUE_TRANSACTION },
};
int i;
int v = 0;
+25 -7
View File
@@ -3934,14 +3934,22 @@ case OP_Savepoint: {
break;
}
/* Opcode: AutoCommit P1 P2 * * *
/* Opcode: AutoCommit P1 P2 * * P5
**
** 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 P5 and P1 are both is 1, then COMMIT but also hold 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->p5 ){
/* 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->p5==0 || pOp->p5==1 );
sqlite3PagerHoldWrLock(db, pOp->p5);
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->p5 ){
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;
+20 -10
View File
@@ -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);
}
@@ -3655,7 +3656,7 @@ Pgno sqlite3WalDbsize(Wal *pWal){
** There can only be a single writer active at a time.
*/
int sqlite3WalBeginWriteTransaction(Wal *pWal){
int rc;
int rc = SQLITE_OK;
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
/* If the write-lock is already held, then it was obtained before the
@@ -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 );
testcase( pWal->writeLock );
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 );
testcase( 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 or clear the transient Wal.bHoldWrFlag boolean that prevents
** the WAL_WRITE lock from being released.
*/
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
+5
View File
@@ -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);
+109
View File
@@ -0,0 +1,109 @@
# 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
if {[permutation]=="inmemory_journal" || [permutation]=="journaltest"} {
finish_test
return
}
db close
sqlite3 db test.db
sqlite3 db2 test.db
sqlite3_db_config db CONTINUE_TRANSACTION 1
sqlite3_db_config db2 CONTINUE_TRANSACTION 1
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
sqlite3_db_config db2 CONTINUE_TRANSACTION 1
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 {}}
sqlite3_db_config db CONTINUE_TRANSACTION 0
do_catchsql_test trans4-3.4 {
COMMIT AND CONTINUE TRANSACTION;
} {1 {near "AND": syntax error}}
db2 close
finish_test