I have a small patch that adds "BEGIN SHARED" syntax in addition to IMMEDIATE and EXCLUSIVE. I have an application that requires a consistent view of the data across a number of individual statements. What is ideal is a way to simply lock the database with a SHARED lock for the duration, but the only way to do this is run a SELECT. Unfortunately, this means that I have a SELECT that does nothing other than hold a lock. This smacks of programming by side effect, so killed a bit of time on a recent flight by adding the SHARED keyword.
After digging about on the site, don't see the 'right' way to submit a patch - although I did find the requirements for surrendering copyright. Odd at first thought, but a damn fine idea. Therefore, as this code was written on personal time using personal hardware, I include the following as requested: /The author or authors of this code dedicate any and all copyright interest in this code to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights this code under copyright law. / Attached patch is against 3.2.8. Thoughts? -P
diff -urN sqlite-3.2.8/src/build.c sqlite-3.2.8-shared/src/build.c --- sqlite-3.2.8/src/build.c 2005-12-19 11:26:41.000000000 -0500 +++ sqlite-3.2.8-shared/src/build.c 2006-04-04 12:44:47.000000000 -0400 @@ -2673,8 +2673,19 @@ v = sqlite3GetVdbe(pParse); if( !v ) return; if( type!=TK_DEFERRED ){ + switch( type ) { + case TK_EXCLUSIVE: + type = 2; + break; + case TK_IMMEDIATE: + type = 1; + break; + case TK_SHARED: + type = 0; + break; + } for(i=0; i<db->nDb; i++){ - sqlite3VdbeAddOp(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1); + sqlite3VdbeAddOp(v, OP_Transaction, i, type); } } sqlite3VdbeAddOp(v, OP_AutoCommit, 0, 0); diff -urN sqlite-3.2.8/src/parse.y sqlite-3.2.8-shared/src/parse.y --- sqlite-3.2.8/src/parse.y 2005-12-19 11:25:45.000000000 -0500 +++ sqlite-3.2.8-shared/src/parse.y 2006-04-04 12:29:17.000000000 -0400 @@ -120,6 +120,7 @@ transtype(A) ::= DEFERRED(X). {A = @X;} transtype(A) ::= IMMEDIATE(X). {A = @X;} transtype(A) ::= EXCLUSIVE(X). {A = @X;} +transtype(A) ::= SHARED(X). {A = @X;} cmd ::= COMMIT trans_opt. {sqlite3CommitTransaction(pParse);} cmd ::= END trans_opt. {sqlite3CommitTransaction(pParse);} cmd ::= ROLLBACK trans_opt. {sqlite3RollbackTransaction(pParse);} @@ -174,7 +175,7 @@ ABORT AFTER ANALYZE ASC ATTACH BEFORE BEGIN CASCADE CAST CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH PLAN QUERY KEY - OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT + OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW SHARED STATEMENT TEMP TRIGGER VACUUM VIEW %ifdef SQLITE_OMIT_COMPOUND_SELECT EXCEPT INTERSECT UNION diff -urN sqlite-3.2.8/tool/mkkeywordhash.c sqlite-3.2.8-shared/tool/mkkeywordhash.c --- sqlite-3.2.8/tool/mkkeywordhash.c 2005-12-19 11:25:45.000000000 -0500 +++ sqlite-3.2.8-shared/tool/mkkeywordhash.c 2006-04-04 12:38:35.000000000 -0400 @@ -209,6 +209,7 @@ { "ROW", "TK_ROW", TRIGGER }, { "SELECT", "TK_SELECT", ALWAYS }, { "SET", "TK_SET", ALWAYS }, + { "SHARED", "TK_SHARED", ALWAYS }, { "STATEMENT", "TK_STATEMENT", TRIGGER }, { "TABLE", "TK_TABLE", ALWAYS }, { "TEMP", "TK_TEMP", ALWAYS },