mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Add support for DEFERRED, IMMEDIATE, and EXCLUSIVE transactions. (CVS 2000)
FossilOrigin-Name: 81ff8107ad63113782cf5a9ba7a512496114ba08
This commit is contained in:
41
manifest
41
manifest
@@ -1,5 +1,5 @@
|
|||||||
C More\schanges\sto\stake\sadvantage\sof\sthe\sTK_\sand\sOP_\salignments\sto\savoid\nunnecessary\stranslations.\s(CVS\s1999)
|
C Add\ssupport\sfor\sDEFERRED,\sIMMEDIATE,\sand\sEXCLUSIVE\stransactions.\s(CVS\s2000)
|
||||||
D 2004-10-04T13:38:09
|
D 2004-10-05T02:41:42
|
||||||
F Makefile.in 78ddc9fca09ab6e3b75a79ecf8d490e34cd0519c
|
F Makefile.in 78ddc9fca09ab6e3b75a79ecf8d490e34cd0519c
|
||||||
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
||||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||||
@@ -29,16 +29,16 @@ F sqlite3.def dbaeb20c153e1d366e8f421b55a573f5dfc00863
|
|||||||
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
|
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
|
||||||
F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689
|
F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689
|
||||||
F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea
|
F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea
|
||||||
F src/btree.c 014d3c9d31136050f3b3294c0c5dc0c7615557bf
|
F src/btree.c bb3f8cadf65cc0752d07e219733a496c1aebe020
|
||||||
F src/btree.h 94dfec0a1722d33359b23e7e310f2b64ffedf029
|
F src/btree.h 94dfec0a1722d33359b23e7e310f2b64ffedf029
|
||||||
F src/build.c 2ed6d9c26ad736142012bc99898869db17337121
|
F src/build.c 73bd4219c1cb6fb09a05b7d4a6ed3ae1d0ecb8db
|
||||||
F src/date.c 93927e2d1ffbd833fc220644896cfdc8f8d4af34
|
F src/date.c 93927e2d1ffbd833fc220644896cfdc8f8d4af34
|
||||||
F src/delete.c d862b383a9abc0b79f4588783c2619fe52d74ea7
|
F src/delete.c 7a9543ed784bd51ded17c805ff6a4fe864c1676c
|
||||||
F src/expr.c 2f492bf532d700bd2c38e16caa49048535e8ed27
|
F src/expr.c 2f492bf532d700bd2c38e16caa49048535e8ed27
|
||||||
F src/func.c 1fbc5256639586573fd0e70814d6dcd8bc10afc1
|
F src/func.c 1fbc5256639586573fd0e70814d6dcd8bc10afc1
|
||||||
F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
|
F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
|
||||||
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
||||||
F src/insert.c 2c10c001f62cde92e9517ec7516b6584519754d1
|
F src/insert.c 7e8ce8834c3716a313694e5340dbf28ff828677a
|
||||||
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
|
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
|
||||||
F src/main.c 2a1b9623fde3fe5e22fe726cdae4e10f33671caa
|
F src/main.c 2a1b9623fde3fe5e22fe726cdae4e10f33671caa
|
||||||
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
|
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
|
||||||
@@ -52,16 +52,16 @@ F src/os_unix.c 5c1f362846afec4232c2291b9f1564f0487e91f4
|
|||||||
F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13
|
F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13
|
||||||
F src/os_win.c 9482dfc92f289b68205bb2c9315757c7e3946bfb
|
F src/os_win.c 9482dfc92f289b68205bb2c9315757c7e3946bfb
|
||||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||||
F src/pager.c d3688828d314135ef0cd87b4d892805136c4168f
|
F src/pager.c dc0ffab9941393b072e0b1f1f3de54830727cec9
|
||||||
F src/pager.h 67739fe649f33be55dba522ca8a9cc4e42d14f71
|
F src/pager.h 774d1973acbda341827d21b0da0150575d69f7d9
|
||||||
F src/parse.y 3616bdde17fd9be9c235e40cd732a831a3e8fa61
|
F src/parse.y e03d7d7f712ad2b5be61e9a024820c0a8ffdf36d
|
||||||
F src/pragma.c 45978cc82fdf91f00d024a8e875c2b679fbce488
|
F src/pragma.c ba7fdd19c1680bb9bfc8bc5230278f6ae6b1c8ff
|
||||||
F src/printf.c 40770e1f553612d13dfc86d236086e69baa62fe1
|
F src/printf.c 40770e1f553612d13dfc86d236086e69baa62fe1
|
||||||
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
||||||
F src/select.c 96b1489111abe9b584be2f2cce26ad6f2d425b4e
|
F src/select.c 96b1489111abe9b584be2f2cce26ad6f2d425b4e
|
||||||
F src/shell.c 0856973c2b94e22664bc43f398ba3fc22d5e080c
|
F src/shell.c 0856973c2b94e22664bc43f398ba3fc22d5e080c
|
||||||
F src/sqlite.h.in 9bb76ff9e79ee72e6d529ff6ab1c252d513c3864
|
F src/sqlite.h.in 9bb76ff9e79ee72e6d529ff6ab1c252d513c3864
|
||||||
F src/sqliteInt.h bfb12f1da75b2a8f5c88c9c3050343571def65b9
|
F src/sqliteInt.h 610f25a92c0ce5edf40d12087c643c310e1d7d05
|
||||||
F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
|
F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
|
||||||
F src/tclsqlite.c 0302e3f42f015d132d1291f3388c06e86c24a008
|
F src/tclsqlite.c 0302e3f42f015d132d1291f3388c06e86c24a008
|
||||||
F src/test1.c 3d78e5d827bf5d037f697c233c5934d45af46cb5
|
F src/test1.c 3d78e5d827bf5d037f697c233c5934d45af46cb5
|
||||||
@@ -69,13 +69,13 @@ F src/test2.c b11fa244fff02190707dd0879987c37c75e61fc8
|
|||||||
F src/test3.c 5b5b0f3d11b097399c1054fff73d8f3711092301
|
F src/test3.c 5b5b0f3d11b097399c1054fff73d8f3711092301
|
||||||
F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
|
F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
|
||||||
F src/test5.c b001fa7f1b9e2dc5c2331de62fc641b5ab2bd7a1
|
F src/test5.c b001fa7f1b9e2dc5c2331de62fc641b5ab2bd7a1
|
||||||
F src/tokenize.c d4619367d9ba17c6bd4e018fb7e91015ae8562aa
|
F src/tokenize.c 449843c85c8118b9718f3935f4b5d18586c8cee2
|
||||||
F src/trigger.c d1f770ee37a80391dd6d0948ee821b0272f99ae7
|
F src/trigger.c b983f8d763d2c253535947e543c3386dc1117ca1
|
||||||
F src/update.c 7157084216c4b02a23cdb23eb6d246aa9034fa4d
|
F src/update.c 174c3b593b8f4928e510a51ec309e8ce69d2371c
|
||||||
F src/utf.c f4f83acd73389090e32d6589d307fc55d794c7ed
|
F src/utf.c f4f83acd73389090e32d6589d307fc55d794c7ed
|
||||||
F src/util.c f4ab796b9def353feed2191d7ce8e39a0f5059cd
|
F src/util.c f4ab796b9def353feed2191d7ce8e39a0f5059cd
|
||||||
F src/vacuum.c 257de36230cb988842f66eb08dc6c0250b8e05f3
|
F src/vacuum.c 257de36230cb988842f66eb08dc6c0250b8e05f3
|
||||||
F src/vdbe.c 49d4bda66884b1017e11962c7fb7eaf15b436be8
|
F src/vdbe.c f7ebf1a20a5fdca27e80cb96e06e988da2426379
|
||||||
F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181
|
F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181
|
||||||
F src/vdbeInt.h 6017100adff362b8dfa37a69e3f1431f084bfa5b
|
F src/vdbeInt.h 6017100adff362b8dfa37a69e3f1431f084bfa5b
|
||||||
F src/vdbeapi.c 81ab9e84c55f5762f552904e6e5d309269b02017
|
F src/vdbeapi.c 81ab9e84c55f5762f552904e6e5d309269b02017
|
||||||
@@ -137,6 +137,7 @@ F test/laststmtchanges.test 417aa27eb2b5cdfafb46e390e2c9ddd0a20eba43
|
|||||||
F test/limit.test f7c06fccd76755e8d083b61c06bc31cf461b9c35
|
F test/limit.test f7c06fccd76755e8d083b61c06bc31cf461b9c35
|
||||||
F test/lock.test 7cb9395919a0986ee4dd08bd49d34df93c8fc4fe
|
F test/lock.test 7cb9395919a0986ee4dd08bd49d34df93c8fc4fe
|
||||||
F test/lock2.test 2213590d442147d09fd2334c905a755586c1c398
|
F test/lock2.test 2213590d442147d09fd2334c905a755586c1c398
|
||||||
|
F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
|
||||||
F test/main.test 1430a4b5bd3a6d5e0294966b742d80a551f87211
|
F test/main.test 1430a4b5bd3a6d5e0294966b742d80a551f87211
|
||||||
F test/malloc.test 769b240d89a7ef3320d88919fdb6765f9395a51f
|
F test/malloc.test 769b240d89a7ef3320d88919fdb6765f9395a51f
|
||||||
F test/memdb.test b8a13fa79f006bd087bbcf135ce8eb62056a6027
|
F test/memdb.test b8a13fa79f006bd087bbcf135ce8eb62056a6027
|
||||||
@@ -150,7 +151,7 @@ F test/misuse.test fcd9e7cec6ecccc34822584aec6b4e31f13629e1
|
|||||||
F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0
|
F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0
|
||||||
F test/null.test 642428b6a5408cc5b954b49e1b6e5025e4458b2b
|
F test/null.test 642428b6a5408cc5b954b49e1b6e5025e4458b2b
|
||||||
F test/pager.test 394455707a079804e8a4e431d12edce831a065f0
|
F test/pager.test 394455707a079804e8a4e431d12edce831a065f0
|
||||||
F test/pager2.test 2b505eca6bf214dfff412cf615678a835c83ca74
|
F test/pager2.test c7e731ac56a2984a605b032ffd19b9deee820377
|
||||||
F test/pager3.test 16f546293bb751b8151dc17df613fca938bbec8b
|
F test/pager3.test 16f546293bb751b8151dc17df613fca938bbec8b
|
||||||
F test/pagesize.test f8b46ec46b9fe9f708a8d757dda232588dfb7217
|
F test/pagesize.test f8b46ec46b9fe9f708a8d757dda232588dfb7217
|
||||||
F test/pragma.test 66a66b7f3b273b93325c9a5794acb418f52fdcbf
|
F test/pragma.test 66a66b7f3b273b93325c9a5794acb418f52fdcbf
|
||||||
@@ -234,7 +235,7 @@ F www/faq.tcl 8cf9f59fd93868c9954223a99db244c9975fa43b
|
|||||||
F www/fileformat.tcl f71a06a0d533c7df408539c64113b4adeaf29764
|
F www/fileformat.tcl f71a06a0d533c7df408539c64113b4adeaf29764
|
||||||
F www/formatchng.tcl d1dfecedfb25e122ab513a1e0948b15cb4f0be46
|
F www/formatchng.tcl d1dfecedfb25e122ab513a1e0948b15cb4f0be46
|
||||||
F www/index.tcl 3bf50fdac2f5df49cf4f6f76a7f312b5fd4725b8
|
F www/index.tcl 3bf50fdac2f5df49cf4f6f76a7f312b5fd4725b8
|
||||||
F www/lang.tcl 604683def6e987db1703faf580d9b2150905fda1
|
F www/lang.tcl dde78c1415ee2d19fc30360808ca6f0e2ea71c30
|
||||||
F www/lockingv3.tcl afcd22f0f063989cff2f4d57bbc38d719b4c6e75
|
F www/lockingv3.tcl afcd22f0f063989cff2f4d57bbc38d719b4c6e75
|
||||||
F www/mingw.tcl d96b451568c5d28545fefe0c80bee3431c73f69c
|
F www/mingw.tcl d96b451568c5d28545fefe0c80bee3431c73f69c
|
||||||
F www/nulls.tcl ede975a29def48838c606d4a0c0185d44f90a789
|
F www/nulls.tcl ede975a29def48838c606d4a0c0185d44f90a789
|
||||||
@@ -249,7 +250,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25
|
|||||||
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
||||||
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
||||||
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
||||||
P 4c817e3f293a9c1365e632f7dc13ae440263332a
|
P e8e972ba65fc36171f6b685e8a8f67f93452e031
|
||||||
R baa88e3ccdeca2bd21538a311420eedc
|
R d2fc50e21e7b6df513c30d8cad94f529
|
||||||
U drh
|
U drh
|
||||||
Z f63cffc592cc58b47f0dd722884db290
|
Z d7255f319d142e01096c8a1787a44a2e
|
||||||
|
@@ -1 +1 @@
|
|||||||
e8e972ba65fc36171f6b685e8a8f67f93452e031
|
81ff8107ad63113782cf5a9ba7a512496114ba08
|
12
src/btree.c
12
src/btree.c
@@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** $Id: btree.c,v 1.191 2004/09/27 13:19:52 drh Exp $
|
** $Id: btree.c,v 1.192 2004/10/05 02:41:42 drh Exp $
|
||||||
**
|
**
|
||||||
** This file implements a external (disk-based) database using BTrees.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** For a detailed discussion of BTrees, refer to
|
** For a detailed discussion of BTrees, refer to
|
||||||
@@ -1289,8 +1289,12 @@ static int newDatabase(Btree *pBt){
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** Attempt to start a new transaction. A write-transaction
|
** Attempt to start a new transaction. A write-transaction
|
||||||
** is started if the second argument is true, otherwise a read-
|
** is started if the second argument is nonzero, otherwise a read-
|
||||||
** transaction.
|
** transaction. If the second argument is 2 or more and exclusive
|
||||||
|
** transaction is started, meaning that no other process is allowed
|
||||||
|
** to access the database. A preexisting transaction may not be
|
||||||
|
** upgrade to exclusive by calling this routine a second time - the
|
||||||
|
** exclusivity flag only works for a new transaction.
|
||||||
**
|
**
|
||||||
** A write-transaction must be started before attempting any
|
** A write-transaction must be started before attempting any
|
||||||
** changes to the database. None of the following routines
|
** changes to the database. None of the following routines
|
||||||
@@ -1329,7 +1333,7 @@ int sqlite3BtreeBeginTrans(Btree *pBt, int wrflag){
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( rc==SQLITE_OK && wrflag ){
|
if( rc==SQLITE_OK && wrflag ){
|
||||||
rc = sqlite3pager_begin(pBt->pPage1->aData);
|
rc = sqlite3pager_begin(pBt->pPage1->aData, wrflag>1);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = newDatabase(pBt);
|
rc = newDatabase(pBt);
|
||||||
}
|
}
|
||||||
|
30
src/build.c
30
src/build.c
@@ -23,7 +23,7 @@
|
|||||||
** ROLLBACK
|
** ROLLBACK
|
||||||
** PRAGMA
|
** PRAGMA
|
||||||
**
|
**
|
||||||
** $Id: build.c,v 1.255 2004/09/30 14:22:47 drh Exp $
|
** $Id: build.c,v 1.256 2004/10/05 02:41:42 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -1376,8 +1376,6 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){
|
|||||||
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
||||||
sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0,
|
sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0,
|
||||||
sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC);
|
sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC);
|
||||||
|
|
||||||
sqlite3EndWriteOperation(pParse);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the table to the in-memory representation of the database.
|
/* Add the table to the in-memory representation of the database.
|
||||||
@@ -1663,7 +1661,6 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeOp3(v, OP_DropTable, pTab->iDb, 0, pTab->zName, 0);
|
sqlite3VdbeOp3(v, OP_DropTable, pTab->iDb, 0, pTab->zName, 0);
|
||||||
sqlite3EndWriteOperation(pParse);
|
|
||||||
}
|
}
|
||||||
sqliteViewResetAll(db, iDb);
|
sqliteViewResetAll(db, iDb);
|
||||||
|
|
||||||
@@ -2131,7 +2128,6 @@ void sqlite3CreateIndex(
|
|||||||
sqlite3VdbeAddOp(v, OP_Close, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Close, 1, 0);
|
||||||
sqlite3ChangeCookie(db, v, iDb);
|
sqlite3ChangeCookie(db, v, iDb);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
||||||
sqlite3EndWriteOperation(pParse);
|
|
||||||
sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0,
|
sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0,
|
||||||
sqlite3MPrintf("name='%q'", pIndex->zName), P3_DYNAMIC);
|
sqlite3MPrintf("name='%q'", pIndex->zName), P3_DYNAMIC);
|
||||||
}
|
}
|
||||||
@@ -2232,7 +2228,6 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName){
|
|||||||
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Destroy, pIndex->tnum, pIndex->iDb);
|
sqlite3VdbeAddOp(v, OP_Destroy, pIndex->tnum, pIndex->iDb);
|
||||||
sqlite3VdbeOp3(v, OP_DropIndex, pIndex->iDb, 0, pIndex->zName, 0);
|
sqlite3VdbeOp3(v, OP_DropIndex, pIndex->iDb, 0, pIndex->zName, 0);
|
||||||
sqlite3EndWriteOperation(pParse);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exit_drop_index:
|
exit_drop_index:
|
||||||
@@ -2398,9 +2393,10 @@ void sqlite3SrcListDelete(SrcList *pList){
|
|||||||
/*
|
/*
|
||||||
** Begin a transaction
|
** Begin a transaction
|
||||||
*/
|
*/
|
||||||
void sqlite3BeginTransaction(Parse *pParse){
|
void sqlite3BeginTransaction(Parse *pParse, int type){
|
||||||
sqlite3 *db;
|
sqlite3 *db;
|
||||||
Vdbe *v;
|
Vdbe *v;
|
||||||
|
int i;
|
||||||
|
|
||||||
if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
|
if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
|
||||||
if( pParse->nErr || sqlite3_malloc_failed ) return;
|
if( pParse->nErr || sqlite3_malloc_failed ) return;
|
||||||
@@ -2408,6 +2404,11 @@ void sqlite3BeginTransaction(Parse *pParse){
|
|||||||
|
|
||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
if( !v ) return;
|
if( !v ) return;
|
||||||
|
if( type!=TK_DEFERRED ){
|
||||||
|
for(i=0; i<db->nDb; i++){
|
||||||
|
sqlite3VdbeAddOp(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_AutoCommit, 0, 0);
|
sqlite3VdbeAddOp(v, OP_AutoCommit, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2551,21 +2552,6 @@ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** Generate code that concludes an operation that may have changed
|
|
||||||
** the database. If a statement transaction was started, then emit
|
|
||||||
** an OP_Commit that will cause the changes to be committed to disk.
|
|
||||||
**
|
|
||||||
** Note that checkpoints are automatically committed at the end of
|
|
||||||
** a statement. Note also that there can be multiple calls to
|
|
||||||
** sqlite3BeginWriteOperation() but there should only be a single
|
|
||||||
** call to sqlite3EndWriteOperation() at the conclusion of the statement.
|
|
||||||
*/
|
|
||||||
void sqlite3EndWriteOperation(Parse *pParse){
|
|
||||||
/* Delete me! */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return the transient sqlite3_value object used for encoding conversions
|
** Return the transient sqlite3_value object used for encoding conversions
|
||||||
** during SQL compilation.
|
** during SQL compilation.
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle DELETE FROM statements.
|
** to handle DELETE FROM statements.
|
||||||
**
|
**
|
||||||
** $Id: delete.c,v 1.81 2004/09/19 02:15:25 drh Exp $
|
** $Id: delete.c,v 1.82 2004/10/05 02:41:42 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -307,7 +307,6 @@ void sqlite3DeleteFrom(
|
|||||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3EndWriteOperation(pParse);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return the number of rows that were deleted.
|
** Return the number of rows that were deleted.
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle INSERT statements in SQLite.
|
** to handle INSERT statements in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: insert.c,v 1.118 2004/09/19 02:15:26 drh Exp $
|
** $Id: insert.c,v 1.119 2004/10/05 02:41:42 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -616,8 +616,6 @@ void sqlite3Insert(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3EndWriteOperation(pParse);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return the number of rows inserted.
|
** Return the number of rows inserted.
|
||||||
*/
|
*/
|
||||||
|
114
src/pager.c
114
src/pager.c
@@ -18,7 +18,7 @@
|
|||||||
** file simultaneously, or one process from reading the database while
|
** file simultaneously, or one process from reading the database while
|
||||||
** another is writing.
|
** another is writing.
|
||||||
**
|
**
|
||||||
** @(#) $Id: pager.c,v 1.166 2004/10/02 20:38:28 drh Exp $
|
** @(#) $Id: pager.c,v 1.167 2004/10/05 02:41:43 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -88,11 +88,27 @@
|
|||||||
** or sqlite_pager_commit(), the state goes back to PAGER_SHARED.
|
** or sqlite_pager_commit(), the state goes back to PAGER_SHARED.
|
||||||
*/
|
*/
|
||||||
#define PAGER_UNLOCK 0
|
#define PAGER_UNLOCK 0
|
||||||
#define PAGER_SHARED 1
|
#define PAGER_SHARED 1 /* same as SHARED_LOCK */
|
||||||
#define PAGER_RESERVED 2
|
#define PAGER_RESERVED 2 /* same as RESERVED_LOCK */
|
||||||
#define PAGER_EXCLUSIVE 3
|
#define PAGER_EXCLUSIVE 4 /* same as EXCLUSIVE_LOCK */
|
||||||
#define PAGER_SYNCED 4
|
#define PAGER_SYNCED 5
|
||||||
|
|
||||||
|
/*
|
||||||
|
** If the SQLITE_BUSY_RESERVED_LOCK macro is set to true at compile-time,
|
||||||
|
** then failed attempts to get a reserved lock will invoke the busy callback.
|
||||||
|
** This is off by default. To see why, consider the following scenario:
|
||||||
|
**
|
||||||
|
** Suppose thread A already has a shared lock and wants a reserved lock.
|
||||||
|
** Thread B already has a reserved lock and wants an exclusive lock. If
|
||||||
|
** both threads are using their busy callbacks, it might be a long time
|
||||||
|
** be for one of the threads give up and allows the other to proceed.
|
||||||
|
** But if the thread trying to get the reserved lock gives up quickly
|
||||||
|
** (if it never invokes its busy callback) then the contention will be
|
||||||
|
** resolved quickly.
|
||||||
|
*/
|
||||||
|
#ifndef SQLITE_BUSY_RESERVED_LOCK
|
||||||
|
# define SQLITE_BUSY_RESERVED_LOCK 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Each in-memory image of a page begins with the following header.
|
** Each in-memory image of a page begins with the following header.
|
||||||
@@ -1907,6 +1923,37 @@ static int syncJournal(Pager *pPager){
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Try to obtain a lock on a file. Invoke the busy callback if the lock
|
||||||
|
** is currently not available. Repeate until the busy callback returns
|
||||||
|
** false or until the lock succeeds.
|
||||||
|
**
|
||||||
|
** Return SQLITE_OK on success and an error code if we cannot obtain
|
||||||
|
** the lock.
|
||||||
|
*/
|
||||||
|
static int pager_wait_on_lock(Pager *pPager, int locktype){
|
||||||
|
int rc;
|
||||||
|
assert( PAGER_SHARED==SHARED_LOCK );
|
||||||
|
assert( PAGER_RESERVED==RESERVED_LOCK );
|
||||||
|
assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );
|
||||||
|
if( pPager->state>=locktype ){
|
||||||
|
rc = SQLITE_OK;
|
||||||
|
}else{
|
||||||
|
int busy = 1;
|
||||||
|
do {
|
||||||
|
rc = sqlite3OsLock(&pPager->fd, locktype);
|
||||||
|
}while( rc==SQLITE_BUSY &&
|
||||||
|
pPager->pBusyHandler &&
|
||||||
|
pPager->pBusyHandler->xFunc &&
|
||||||
|
pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, busy++)
|
||||||
|
);
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
pPager->state = locktype;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Given a list of pages (connected by the PgHdr.pDirty pointer) write
|
** Given a list of pages (connected by the PgHdr.pDirty pointer) write
|
||||||
** every one of those pages out to the database file and mark them all
|
** every one of those pages out to the database file and mark them all
|
||||||
@@ -1915,7 +1962,6 @@ static int syncJournal(Pager *pPager){
|
|||||||
static int pager_write_pagelist(PgHdr *pList){
|
static int pager_write_pagelist(PgHdr *pList){
|
||||||
Pager *pPager;
|
Pager *pPager;
|
||||||
int rc;
|
int rc;
|
||||||
int busy = 1;
|
|
||||||
|
|
||||||
if( pList==0 ) return SQLITE_OK;
|
if( pList==0 ) return SQLITE_OK;
|
||||||
pPager = pList->pPager;
|
pPager = pList->pPager;
|
||||||
@@ -1936,17 +1982,10 @@ static int pager_write_pagelist(PgHdr *pList){
|
|||||||
** EXCLUSIVE, it means the database file has been changed and any rollback
|
** EXCLUSIVE, it means the database file has been changed and any rollback
|
||||||
** will require a journal playback.
|
** will require a journal playback.
|
||||||
*/
|
*/
|
||||||
do {
|
rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
|
||||||
rc = sqlite3OsLock(&pPager->fd, EXCLUSIVE_LOCK);
|
|
||||||
}while( rc==SQLITE_BUSY &&
|
|
||||||
pPager->pBusyHandler &&
|
|
||||||
pPager->pBusyHandler->xFunc &&
|
|
||||||
pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, busy++)
|
|
||||||
);
|
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
pPager->state = PAGER_EXCLUSIVE;
|
|
||||||
|
|
||||||
while( pList ){
|
while( pList ){
|
||||||
assert( pList->dirty );
|
assert( pList->dirty );
|
||||||
@@ -2019,18 +2058,10 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
|||||||
** on the database file.
|
** on the database file.
|
||||||
*/
|
*/
|
||||||
if( pPager->nRef==0 && !pPager->memDb ){
|
if( pPager->nRef==0 && !pPager->memDb ){
|
||||||
int busy = 1;
|
rc = pager_wait_on_lock(pPager, SHARED_LOCK);
|
||||||
do {
|
|
||||||
rc = sqlite3OsLock(&pPager->fd, SHARED_LOCK);
|
|
||||||
}while( rc==SQLITE_BUSY &&
|
|
||||||
pPager->pBusyHandler &&
|
|
||||||
pPager->pBusyHandler->xFunc &&
|
|
||||||
pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, busy++)
|
|
||||||
);
|
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
pPager->state = PAGER_SHARED;
|
|
||||||
|
|
||||||
/* If a journal file exists, and there is no RESERVED lock on the
|
/* If a journal file exists, and there is no RESERVED lock on the
|
||||||
** database file, then it either needs to be played back or deleted.
|
** database file, then it either needs to be played back or deleted.
|
||||||
@@ -2408,8 +2439,12 @@ failed_to_open_journal:
|
|||||||
** actual need to write to the journal.
|
** actual need to write to the journal.
|
||||||
**
|
**
|
||||||
** If the database is already reserved for writing, this routine is a no-op.
|
** If the database is already reserved for writing, this routine is a no-op.
|
||||||
|
**
|
||||||
|
** If exFlag is true, go ahead and get an EXCLUSIVE lock on the file
|
||||||
|
** immediately instead of waiting until we try to flush the cache. The
|
||||||
|
** exFlag is ignored if a transaction is already active.
|
||||||
*/
|
*/
|
||||||
int sqlite3pager_begin(void *pData){
|
int sqlite3pager_begin(void *pData, int exFlag){
|
||||||
PgHdr *pPg = DATA_TO_PGHDR(pData);
|
PgHdr *pPg = DATA_TO_PGHDR(pData);
|
||||||
Pager *pPager = pPg->pPager;
|
Pager *pPager = pPg->pPager;
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
@@ -2421,29 +2456,20 @@ int sqlite3pager_begin(void *pData){
|
|||||||
pPager->state = PAGER_EXCLUSIVE;
|
pPager->state = PAGER_EXCLUSIVE;
|
||||||
pPager->origDbSize = pPager->dbSize;
|
pPager->origDbSize = pPager->dbSize;
|
||||||
}else{
|
}else{
|
||||||
#ifdef SQLITE_BUSY_RESERVED_LOCK
|
if( SQLITE_BUSY_RESERVED_LOCK || exFlag ){
|
||||||
int busy = 1;
|
rc = pager_wait_on_lock(pPager, RESERVED_LOCK);
|
||||||
do {
|
}else{
|
||||||
rc = sqlite3OsLock(&pPager->fd, RESERVED_LOCK);
|
rc = sqlite3OsLock(&pPager->fd, RESERVED_LOCK);
|
||||||
}while( rc==SQLITE_BUSY &&
|
}
|
||||||
pPager->pBusyHandler &&
|
if( rc==SQLITE_OK ){
|
||||||
pPager->pBusyHandler->xFunc &&
|
pPager->state = PAGER_RESERVED;
|
||||||
pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, busy++)
|
if( exFlag ){
|
||||||
);
|
rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
|
||||||
#else
|
}
|
||||||
rc = sqlite3OsLock(&pPager->fd, RESERVED_LOCK);
|
}
|
||||||
#endif
|
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
/* We do not call the busy handler when we fail to get a reserved lock.
|
|
||||||
** The only reason we might fail is because another process is holding
|
|
||||||
** the reserved lock. But the other process will not be able to
|
|
||||||
** release its reserved lock until this process releases its shared
|
|
||||||
** lock. So we might as well fail in this process, let it release
|
|
||||||
** its shared lock so that the other process can commit.
|
|
||||||
*/
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
pPager->state = PAGER_RESERVED;
|
|
||||||
pPager->dirtyCache = 0;
|
pPager->dirtyCache = 0;
|
||||||
TRACE2("TRANSACTION %d\n", pPager->fd.h);
|
TRACE2("TRANSACTION %d\n", pPager->fd.h);
|
||||||
if( pPager->useJournal && !pPager->tempFile ){
|
if( pPager->useJournal && !pPager->tempFile ){
|
||||||
@@ -2504,7 +2530,7 @@ int sqlite3pager_write(void *pData){
|
|||||||
** create it if it does not.
|
** create it if it does not.
|
||||||
*/
|
*/
|
||||||
assert( pPager->state!=PAGER_UNLOCK );
|
assert( pPager->state!=PAGER_UNLOCK );
|
||||||
rc = sqlite3pager_begin(pData);
|
rc = sqlite3pager_begin(pData, 0);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
** subsystem. The page cache subsystem reads and writes a file a page
|
** subsystem. The page cache subsystem reads and writes a file a page
|
||||||
** at a time and provides a journal for rollback.
|
** at a time and provides a journal for rollback.
|
||||||
**
|
**
|
||||||
** @(#) $Id: pager.h,v 1.37 2004/07/22 01:19:35 drh Exp $
|
** @(#) $Id: pager.h,v 1.38 2004/10/05 02:41:43 drh Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -74,7 +74,7 @@ int sqlite3pager_iswriteable(void*);
|
|||||||
int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void*);
|
int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void*);
|
||||||
int sqlite3pager_pagecount(Pager*);
|
int sqlite3pager_pagecount(Pager*);
|
||||||
int sqlite3pager_truncate(Pager*,Pgno);
|
int sqlite3pager_truncate(Pager*,Pgno);
|
||||||
int sqlite3pager_begin(void*);
|
int sqlite3pager_begin(void*, int exFlag);
|
||||||
int sqlite3pager_commit(Pager*);
|
int sqlite3pager_commit(Pager*);
|
||||||
int sqlite3pager_sync(Pager*,const char *zMaster);
|
int sqlite3pager_sync(Pager*,const char *zMaster);
|
||||||
int sqlite3pager_rollback(Pager*);
|
int sqlite3pager_rollback(Pager*);
|
||||||
|
11
src/parse.y
11
src/parse.y
@@ -14,7 +14,7 @@
|
|||||||
** the parser. Lemon will also generate a header file containing
|
** the parser. Lemon will also generate a header file containing
|
||||||
** numeric codes for all of the tokens.
|
** numeric codes for all of the tokens.
|
||||||
**
|
**
|
||||||
** @(#) $Id: parse.y,v 1.141 2004/10/04 13:38:09 drh Exp $
|
** @(#) $Id: parse.y,v 1.142 2004/10/05 02:41:43 drh Exp $
|
||||||
*/
|
*/
|
||||||
%token_prefix TK_
|
%token_prefix TK_
|
||||||
%token_type {Token}
|
%token_type {Token}
|
||||||
@@ -81,10 +81,15 @@ explain ::= . { sqlite3BeginParse(pParse, 0); }
|
|||||||
///////////////////// Begin and end transactions. ////////////////////////////
|
///////////////////// Begin and end transactions. ////////////////////////////
|
||||||
//
|
//
|
||||||
|
|
||||||
cmd ::= BEGIN trans_opt. {sqlite3BeginTransaction(pParse);}
|
cmd ::= BEGIN transtype(Y) trans_opt. {sqlite3BeginTransaction(pParse, Y);}
|
||||||
trans_opt ::= .
|
trans_opt ::= .
|
||||||
trans_opt ::= TRANSACTION.
|
trans_opt ::= TRANSACTION.
|
||||||
trans_opt ::= TRANSACTION nm.
|
trans_opt ::= TRANSACTION nm.
|
||||||
|
%type transtype {int}
|
||||||
|
transtype(A) ::= . {A = TK_DEFERRED;}
|
||||||
|
transtype(A) ::= DEFERRED(X). {A = @X;}
|
||||||
|
transtype(A) ::= IMMEDIATE(X). {A = @X;}
|
||||||
|
transtype(A) ::= EXCLUSIVE(X). {A = @X;}
|
||||||
cmd ::= COMMIT trans_opt. {sqlite3CommitTransaction(pParse);}
|
cmd ::= COMMIT trans_opt. {sqlite3CommitTransaction(pParse);}
|
||||||
cmd ::= END trans_opt. {sqlite3CommitTransaction(pParse);}
|
cmd ::= END trans_opt. {sqlite3CommitTransaction(pParse);}
|
||||||
cmd ::= ROLLBACK trans_opt. {sqlite3RollbackTransaction(pParse);}
|
cmd ::= ROLLBACK trans_opt. {sqlite3RollbackTransaction(pParse);}
|
||||||
@@ -127,7 +132,7 @@ id(A) ::= ID(X). {A = X;}
|
|||||||
//
|
//
|
||||||
%fallback ID
|
%fallback ID
|
||||||
ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CONFLICT
|
ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CONFLICT
|
||||||
DATABASE DEFERRED DESC DETACH EACH END EXPLAIN FAIL FOR
|
DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
|
||||||
GLOB IGNORE IMMEDIATE INITIALLY INSTEAD LIKE MATCH KEY
|
GLOB IGNORE IMMEDIATE INITIALLY INSTEAD LIKE MATCH KEY
|
||||||
OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT
|
OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT
|
||||||
TEMP TRIGGER VACUUM VIEW.
|
TEMP TRIGGER VACUUM VIEW.
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to implement the PRAGMA command.
|
** This file contains code used to implement the PRAGMA command.
|
||||||
**
|
**
|
||||||
** $Id: pragma.c,v 1.67 2004/09/25 14:39:19 drh Exp $
|
** $Id: pragma.c,v 1.68 2004/10/05 02:41:43 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -261,7 +261,6 @@ void sqlite3Pragma(
|
|||||||
sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3);
|
sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3);
|
||||||
sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2);
|
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2);
|
||||||
sqlite3EndWriteOperation(pParse);
|
|
||||||
pDb->cache_size = size;
|
pDb->cache_size = size;
|
||||||
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
|
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.326 2004/10/04 13:19:24 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.327 2004/10/05 02:41:43 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@@ -1310,7 +1310,7 @@ Vdbe *sqlite3GetVdbe(Parse*);
|
|||||||
void sqlite3Randomness(int, void*);
|
void sqlite3Randomness(int, void*);
|
||||||
void sqlite3RollbackAll(sqlite3*);
|
void sqlite3RollbackAll(sqlite3*);
|
||||||
void sqlite3CodeVerifySchema(Parse*, int);
|
void sqlite3CodeVerifySchema(Parse*, int);
|
||||||
void sqlite3BeginTransaction(Parse*);
|
void sqlite3BeginTransaction(Parse*, int);
|
||||||
void sqlite3CommitTransaction(Parse*);
|
void sqlite3CommitTransaction(Parse*);
|
||||||
void sqlite3RollbackTransaction(Parse*);
|
void sqlite3RollbackTransaction(Parse*);
|
||||||
int sqlite3ExprIsConstant(Expr*);
|
int sqlite3ExprIsConstant(Expr*);
|
||||||
@@ -1323,7 +1323,6 @@ void sqlite3GenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
|
|||||||
void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int);
|
void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int);
|
||||||
void sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
|
void sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
|
||||||
void sqlite3BeginWriteOperation(Parse*, int, int);
|
void sqlite3BeginWriteOperation(Parse*, int, int);
|
||||||
void sqlite3EndWriteOperation(Parse*);
|
|
||||||
Expr *sqlite3ExprDup(Expr*);
|
Expr *sqlite3ExprDup(Expr*);
|
||||||
void sqlite3TokenCopy(Token*, Token*);
|
void sqlite3TokenCopy(Token*, Token*);
|
||||||
ExprList *sqlite3ExprListDup(ExprList*);
|
ExprList *sqlite3ExprListDup(ExprList*);
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
** individual tokens and sends those tokens one-by-one over to the
|
** individual tokens and sends those tokens one-by-one over to the
|
||||||
** parser for analysis.
|
** parser for analysis.
|
||||||
**
|
**
|
||||||
** $Id: tokenize.c,v 1.89 2004/09/25 15:25:26 drh Exp $
|
** $Id: tokenize.c,v 1.90 2004/10/05 02:41:43 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -71,6 +71,7 @@ static Keyword aKeywordTable[] = {
|
|||||||
{ "EACH", TK_EACH, },
|
{ "EACH", TK_EACH, },
|
||||||
{ "ELSE", TK_ELSE, },
|
{ "ELSE", TK_ELSE, },
|
||||||
{ "EXCEPT", TK_EXCEPT, },
|
{ "EXCEPT", TK_EXCEPT, },
|
||||||
|
{ "EXCLUSIVE", TK_EXCLUSIVE, },
|
||||||
{ "EXPLAIN", TK_EXPLAIN, },
|
{ "EXPLAIN", TK_EXPLAIN, },
|
||||||
{ "FAIL", TK_FAIL, },
|
{ "FAIL", TK_FAIL, },
|
||||||
{ "FOR", TK_FOR, },
|
{ "FOR", TK_FOR, },
|
||||||
|
@@ -241,7 +241,6 @@ void sqlite3FinishTrigger(
|
|||||||
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
||||||
sqlite3VdbeOp3(v, OP_ParseSchema, nt->iDb, 0,
|
sqlite3VdbeOp3(v, OP_ParseSchema, nt->iDb, 0,
|
||||||
sqlite3MPrintf("type='trigger' AND name='%q'", nt->name), P3_DYNAMIC);
|
sqlite3MPrintf("type='trigger' AND name='%q'", nt->name), P3_DYNAMIC);
|
||||||
sqlite3EndWriteOperation(pParse);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( db->init.busy ){
|
if( db->init.busy ){
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle UPDATE statements.
|
** to handle UPDATE statements.
|
||||||
**
|
**
|
||||||
** $Id: update.c,v 1.89 2004/09/19 02:15:26 drh Exp $
|
** $Id: update.c,v 1.90 2004/10/05 02:41:43 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -430,8 +430,6 @@ void sqlite3Update(
|
|||||||
sqlite3VdbeAddOp(v, OP_Close, oldIdx, 0);
|
sqlite3VdbeAddOp(v, OP_Close, oldIdx, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3EndWriteOperation(pParse);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return the number of rows that were changed.
|
** Return the number of rows that were changed.
|
||||||
*/
|
*/
|
||||||
|
@@ -43,7 +43,7 @@
|
|||||||
** in this file for details. If in doubt, do not deviate from existing
|
** in this file for details. If in doubt, do not deviate from existing
|
||||||
** commenting and indentation practices when changing or adding code.
|
** commenting and indentation practices when changing or adding code.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.c,v 1.416 2004/10/04 13:19:24 drh Exp $
|
** $Id: vdbe.c,v 1.417 2004/10/05 02:41:43 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -2157,7 +2157,8 @@ case OP_AutoCommit: {
|
|||||||
** other process can start another write transaction while this transaction is
|
** other process can start another write transaction while this transaction is
|
||||||
** underway. Starting a write transaction also creates a rollback journal. A
|
** underway. Starting a write transaction also creates a rollback journal. A
|
||||||
** write transaction must be started before any changes can be made to the
|
** write transaction must be started before any changes can be made to the
|
||||||
** database.
|
** database. If P2 is 2 or greater then an EXCLUSIVE lock is also obtained
|
||||||
|
** on the file.
|
||||||
**
|
**
|
||||||
** If P2 is zero, then a read-lock is obtained on the database file.
|
** If P2 is zero, then a read-lock is obtained on the database file.
|
||||||
*/
|
*/
|
||||||
|
78
test/lock3.test
Normal file
78
test/lock3.test
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
# 2001 September 15
|
||||||
|
#
|
||||||
|
# The author disclaims copyright to this source code. In place of
|
||||||
|
# a legal notice, here is a blessing:
|
||||||
|
#
|
||||||
|
# May you do good and not evil.
|
||||||
|
# May you find forgiveness for yourself and forgive others.
|
||||||
|
# May you share freely, never taking more than you give.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
# This file implements regression tests for SQLite library. The
|
||||||
|
# focus of this script is database locks and the operation of the
|
||||||
|
# DEFERRED, IMMEDIATE, and EXCLUSIVE keywords as modifiers to the
|
||||||
|
# BEGIN command.
|
||||||
|
#
|
||||||
|
# $Id: lock3.test,v 1.1 2004/10/05 02:41:43 drh Exp $
|
||||||
|
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
|
||||||
|
# Establish two connections to the same database. Put some
|
||||||
|
# sample data into the database.
|
||||||
|
#
|
||||||
|
do_test lock3-1.1 {
|
||||||
|
sqlite3 db2 test.db
|
||||||
|
execsql {
|
||||||
|
CREATE TABLE t1(a);
|
||||||
|
INSERT INTO t1 VALUES(1);
|
||||||
|
}
|
||||||
|
execsql {
|
||||||
|
SELECT * FROM t1
|
||||||
|
} db2
|
||||||
|
} 1
|
||||||
|
|
||||||
|
# Get a deferred lock on the database using one connection. The
|
||||||
|
# other connection should still be able to write.
|
||||||
|
#
|
||||||
|
do_test lock3-2.1 {
|
||||||
|
execsql {BEGIN DEFERRED TRANSACTION}
|
||||||
|
execsql {INSERT INTO t1 VALUES(2)} db2
|
||||||
|
execsql {END TRANSACTION}
|
||||||
|
execsql {SELECT * FROM t1}
|
||||||
|
} {1 2}
|
||||||
|
|
||||||
|
# Get an immediate lock on the database using one connection. The
|
||||||
|
# other connection should be able to read the database but not write
|
||||||
|
# it.
|
||||||
|
#
|
||||||
|
do_test lock3-3.1 {
|
||||||
|
execsql {BEGIN IMMEDIATE TRANSACTION}
|
||||||
|
catchsql {SELECT * FROM t1} db2
|
||||||
|
} {0 {1 2}}
|
||||||
|
do_test lock3-3.2 {
|
||||||
|
catchsql {INSERT INTO t1 VALUES(3)} db2
|
||||||
|
} {1 {database is locked}}
|
||||||
|
do_test lock3-3.3 {
|
||||||
|
execsql {END TRANSACTION}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
|
||||||
|
# Get an exclusive lock on the database using one connection. The
|
||||||
|
# other connection should be unable to read or write the database.
|
||||||
|
#
|
||||||
|
do_test lock3-4.1 {
|
||||||
|
execsql {BEGIN EXCLUSIVE TRANSACTION}
|
||||||
|
catchsql {SELECT * FROM t1} db2
|
||||||
|
} {1 {database is locked}}
|
||||||
|
do_test lock3-4.2 {
|
||||||
|
catchsql {INSERT INTO t1 VALUES(3)} db2
|
||||||
|
} {1 {database is locked}}
|
||||||
|
do_test lock3-4.3 {
|
||||||
|
execsql {END TRANSACTION}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
catch {db2 close}
|
||||||
|
|
||||||
|
finish_test
|
@@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this script is page cache subsystem.
|
# focus of this script is page cache subsystem.
|
||||||
#
|
#
|
||||||
# $Id: pager2.test,v 1.3 2004/09/08 20:13:06 drh Exp $
|
# $Id: pager2.test,v 1.4 2004/10/05 02:41:43 drh Exp $
|
||||||
|
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
@@ -122,7 +122,7 @@ do_test pager2-2.14 {
|
|||||||
} {0 {}}
|
} {0 {}}
|
||||||
do_test pager2-2.15 {
|
do_test pager2-2.15 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 1 page 1 max 10 size 1 state 3 err 0 hit 1 miss 1 ovfl 0}
|
} {ref 1 page 1 max 10 size 1 state 4 err 0 hit 1 miss 1 ovfl 0}
|
||||||
do_test pager2-2.16 {
|
do_test pager2-2.16 {
|
||||||
page_read $::g1
|
page_read $::g1
|
||||||
} {Page-One}
|
} {Page-One}
|
||||||
@@ -295,7 +295,7 @@ for {set i 1} {$i<20} {incr i} {
|
|||||||
do_test pager2-4.5.$i.1 {
|
do_test pager2-4.5.$i.1 {
|
||||||
page_write $g1 "Page-1 v$i"
|
page_write $g1 "Page-1 v$i"
|
||||||
lrange [pager_stats $p1] 8 9
|
lrange [pager_stats $p1] 8 9
|
||||||
} {state 3}
|
} {state 4}
|
||||||
do_test pager2-4.5.$i.2 {
|
do_test pager2-4.5.$i.2 {
|
||||||
for {set j 2} {$j<=20} {incr j} {
|
for {set j 2} {$j<=20} {incr j} {
|
||||||
set gx [page_get $p1 $j]
|
set gx [page_get $p1 $j]
|
||||||
@@ -336,7 +336,7 @@ for {set i 1} {$i<20} {incr i} {
|
|||||||
do_test pager2-4.5.$i.5 {
|
do_test pager2-4.5.$i.5 {
|
||||||
page_write $g1 "Page-1 v$i"
|
page_write $g1 "Page-1 v$i"
|
||||||
lrange [pager_stats $p1] 8 9
|
lrange [pager_stats $p1] 8 9
|
||||||
} {state 3}
|
} {state 4}
|
||||||
do_test pager2-4.5.$i.6 {
|
do_test pager2-4.5.$i.6 {
|
||||||
for {set j 2} {$j<=20} {incr j} {
|
for {set j 2} {$j<=20} {incr j} {
|
||||||
set gx [page_get $p1 $j]
|
set gx [page_get $p1 $j]
|
||||||
|
40
www/lang.tcl
40
www/lang.tcl
@@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Run this Tcl script to generate the sqlite.html file.
|
# Run this Tcl script to generate the sqlite.html file.
|
||||||
#
|
#
|
||||||
set rcsid {$Id: lang.tcl,v 1.72 2004/09/08 13:06:21 drh Exp $}
|
set rcsid {$Id: lang.tcl,v 1.73 2004/10/05 02:41:43 drh Exp $}
|
||||||
source common.tcl
|
source common.tcl
|
||||||
header {Query Language Understood by SQLite}
|
header {Query Language Understood by SQLite}
|
||||||
puts {
|
puts {
|
||||||
@@ -169,7 +169,7 @@ the main database were ":memory:".
|
|||||||
Section {BEGIN TRANSACTION} transaction
|
Section {BEGIN TRANSACTION} transaction
|
||||||
|
|
||||||
Syntax {sql-statement} {
|
Syntax {sql-statement} {
|
||||||
BEGIN [TRANSACTION [<name>]]
|
BEGIN [ DEFERRED | IMMEDIATE | EXCLUSIVE ] [TRANSACTION [<name>]]
|
||||||
}
|
}
|
||||||
Syntax {sql-statement} {
|
Syntax {sql-statement} {
|
||||||
END [TRANSACTION [<name>]]
|
END [TRANSACTION [<name>]]
|
||||||
@@ -207,6 +207,42 @@ clause for additional information about the ROLLBACK
|
|||||||
conflict resolution algorithm.
|
conflict resolution algorithm.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In SQLite version 3.0.8 and later, transactions can be deferred,
|
||||||
|
immediate, or exclusive. Deferred means that no locks are acquired
|
||||||
|
on the database until the database is first accessed. Thus with a
|
||||||
|
deferred transaction, the BEGIN statement itself does nothing. Locks
|
||||||
|
are not acquired until the first read or write operation. The first read
|
||||||
|
operation against a database creates a SHARED lock and the first
|
||||||
|
write operation creates a RESERVED lock. Because the acquisition of
|
||||||
|
locks is deferred until they are needed, it is possible that another
|
||||||
|
thread or process could create a separate transaction and write to
|
||||||
|
the database after the BEGIN on the current thread has executed.
|
||||||
|
If the transation is immediate, then RESERVED locks
|
||||||
|
are acquired on all databases as soon as the BEGIN command is
|
||||||
|
executed, without waiting for the
|
||||||
|
database to be used. After a BEGIN IMMEDIATE, you are guaranteed that
|
||||||
|
no other thread or process will be able to write to the database or
|
||||||
|
do a BEGIN IMMEDIATE or BEGIN EXCLUSIVE. Other processes can continue
|
||||||
|
to read from the database, however. An exclusive transaction causes
|
||||||
|
EXCLUSIVE locks to be acquired on all databases. After a BEGIN
|
||||||
|
EXCLUSIVE, you are guaranteed that no other thread or process will
|
||||||
|
be able to read or write the database until the transaction is
|
||||||
|
complete.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A description of the meaning of SHARED, RESERVED, and EXCLUSIVE locks
|
||||||
|
is available <a href="lockingv3.html">separately</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The default behavior for SQLite version 3.0.8 is a
|
||||||
|
deferred transaction. For SQLite version 3.0.0 through 3.0.7,
|
||||||
|
deferred is the only kind of transaction available. For SQLite
|
||||||
|
version 2.8 and earlier, all transactions are exclusive.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The COMMIT command does not actually perform a commit until all
|
The COMMIT command does not actually perform a commit until all
|
||||||
pending SQL commands finish. Thus if two or more SELECT statements
|
pending SQL commands finish. Thus if two or more SELECT statements
|
||||||
|
Reference in New Issue
Block a user