From 7bec505e26ab86cc9663f9c384956a3df6e3dc54 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 6 Feb 2005 02:45:41 +0000 Subject: [PATCH] Add the (highly experimental) omit_readlock pragma that disables the use of readlocks on read-only databases that are connected using ATTACH. (CVS 2317) FossilOrigin-Name: 2155448d2128119f74241da0ea07d6713b71765c --- manifest | 30 +++++++++++++++--------------- manifest.uuid | 2 +- src/btree.c | 5 ++--- src/btree.h | 8 ++++++-- src/main.c | 5 ++++- src/pager.c | 22 ++++++++++++++-------- src/pager.h | 12 ++++++++++-- src/pragma.c | 3 ++- src/sqliteInt.h | 4 +++- src/test2.c | 4 ++-- tool/lempar.c | 12 ++++++++++++ 11 files changed, 71 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index 883e6f931a..8a1bf2f3ae 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sexpressions\s(including\svariables)\sin\sLIMIT\sand\sOFFSET\sclauses.\sTicket\s#1096.\s(CVS\s2316) -D 2005-02-05T12:48:48 +C Add\sthe\s(highly\sexperimental)\somit_readlock\spragma\sthat\sdisables\sthe\suse\r\nof\sreadlocks\son\sread-only\sdatabases\sthat\sare\sconnected\susing\sATTACH.\s(CVS\s2317) +D 2005-02-06T02:45:42 F Makefile.in d928187101fa3d78426cf48ca30e39d0fb714e57 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1 @@ -29,8 +29,8 @@ F sqlite3.def dbaeb20c153e1d366e8f421b55a573f5dfc00863 F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a F src/attach.c f78f76bc6a8e5e487ca53636e21ccba2484a9a61 F src/auth.c 18c5a0befe20f3a58a41e3ddd78f372faeeefe1f -F src/btree.c c3241d44d44e75b54a249bc7c9ed46c7295dfb2a -F src/btree.h 74d19cf40ab49fd69abe9e4e12a6c321ad86c497 +F src/btree.c d88766f8eb98241cd7af6aabf302ed322606057b +F src/btree.h 2e2cc923224649337d7217df0dd32b06673ca180 F src/build.c fcb437bcda09a57b3fe898dff5ff558e7536621b F src/date.c f3d1f5cd1503dabf426a198f3ebef5afbc122a7f F src/delete.c 4b94395b52a8f7785acd71135c2ce54f3f5550b3 @@ -41,7 +41,7 @@ F src/hash.c 2b1b13f7400e179631c83a1be0c664608c8f021f F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84 F src/insert.c 6ab596846d52bd63d6227f9128a29e4f5b2cf524 F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b -F src/main.c 75e70f15b4e22bf69f84c77fb80d6a8f0b0836eb +F src/main.c 981099f5f73a71e54b0858b01e03d29b83168f7b F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070 F src/os.h ae44064dc118b20d39450cb331409a775e8bb1c6 F src/os_common.h 0e7f428ba0a6c40a61bc56c4e96f493231301b73 @@ -51,20 +51,20 @@ F src/os_unix.c 68d3d32937eee90fe1f50d500d1a4ee826cbe790 F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13 F src/os_win.c bddeae1c3299be0fbe47077dd4e98b786a067f71 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b -F src/pager.c d21565d0e844712809140632062a7b72b768fdff -F src/pager.h 9eba8c53dd91eae7f3f90743b2ee242da02a9862 +F src/pager.c d0c1f41b41d2b56a6fd0e1308a66518872f68ed5 +F src/pager.h 70d496f372163abb6340f474288c4bb9ea962cf7 F src/parse.y ee046c1ea30425a817285e52fb1993c2f955e766 -F src/pragma.c 572d7dd4f9c9d020ca2967a1c3ec02c3126e9631 +F src/pragma.c 809b95acd9af67297a5f923a1a57d82179e0ad3a F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/select.c 6217e1f72cee7e173b21b252fd42a052f3b4decc F src/shell.c 3cb0ef124ed9cd582ce89aec59ff7c659bc6e61b F src/sqlite.h.in c85f6bad9ca7de29f505fe886646cfff7df4c55e -F src/sqliteInt.h 58e9365c0f575ef42973439caf3bbab450ad700b +F src/sqliteInt.h 5fa59fd8369ec403bbdf35a9b6fbf7f60bd77cdb F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9 F src/tclsqlite.c 101994a2c4c0eaa69f1de9bfe4a02167f6049e7d F src/test1.c feac8a742aca920c8ab18a43b3208ae3a834fe9d -F src/test2.c bbc2ecc58ceeab12d1e40970f831b1017524e40d +F src/test2.c 7f0ef466706ac01414e1136b96e5d8a65cb97545 F src/test3.c 683e1e3819152ffd35da2f201e507228921148d0 F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df F src/test5.c 64f08b2a50ef371a1bd68ff206829e7b1b9997f5 @@ -210,7 +210,7 @@ F test/view.test 306cc4342eb03c28de1a92c681836189e03e5af9 F test/where.test ffb790dfda75d977bae7a1f5830351623f76861b F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/lemon.c 4a3b5ccc76d959b8caa5f127d23a7e14d4470b4e -F tool/lempar.c 9bf2f402ab464d3ffb67e7de6154eb66f99d115c +F tool/lempar.c e8b0eb00a6b905ce2ebd55965ed243574482cd5f F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133 F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8 F tool/memleak3.tcl b8eb053190e95a55dc188896afb972e8108822d6 @@ -270,7 +270,7 @@ F www/tclsqlite.tcl e73f8f8e5f20e8277619433f7970060ab01088fc F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0 F www/whentouse.tcl 3e522a06ad41992023c80ca29a048ae2331ca5bd -P a9c33a804d572dd9df15be2029637b10e5a65cc4 -R 0ba525d8e5e37833bac3706da6208349 -U danielk1977 -Z 5a32f92efa7eeaf1966c77064b18ce7a +P 515e5033a5482f55e7edb66d69ff3da7e234ff2e +R 46e8e0ae6e4ce5a599c5b024b5c2e241 +U drh +Z dd83c9ab3e3ce7d0c16a2d058d1f0afb diff --git a/manifest.uuid b/manifest.uuid index 78c38d6c49..909087ae42 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -515e5033a5482f55e7edb66d69ff3da7e234ff2e \ No newline at end of file +2155448d2128119f74241da0ea07d6713b71765c \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 952e91ad87..4cb6bda99a 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.245 2005/02/04 04:07:17 danielk1977 Exp $ +** $Id: btree.c,v 1.246 2005/02/06 02:45:42 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -1223,8 +1223,7 @@ int sqlite3BtreeOpen( *ppBtree = 0; return SQLITE_NOMEM; } - rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE, - (flags & BTREE_OMIT_JOURNAL)==0); + rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE, flags); if( rc!=SQLITE_OK ){ if( pBt->pPager ) sqlite3pager_close(pBt->pPager); sqliteFree(pBt); diff --git a/src/btree.h b/src/btree.h index 8d78f5871b..7426673537 100644 --- a/src/btree.h +++ b/src/btree.h @@ -13,7 +13,7 @@ ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** -** @(#) $Id: btree.h,v 1.61 2005/01/12 07:15:05 danielk1977 Exp $ +** @(#) $Id: btree.h,v 1.62 2005/02/06 02:45:42 drh Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ @@ -46,9 +46,13 @@ int sqlite3BtreeOpen( /* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the ** following values. +** +** NOTE: These values must match the corresponding PAGER_ values in +** pager.h. */ #define BTREE_OMIT_JOURNAL 1 /* Do not use journal. No argument */ -#define BTREE_MEMORY 2 /* In-memory DB. No argument */ +#define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */ +#define BTREE_MEMORY 4 /* In-memory DB. No argument */ int sqlite3BtreeClose(Btree*); int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*); diff --git a/src/main.c b/src/main.c index 51608cc81e..d36777df9c 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.279 2005/02/05 07:33:34 danielk1977 Exp $ +** $Id: main.c,v 1.280 2005/02/06 02:45:42 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -858,6 +858,9 @@ int sqlite3BtreeFactory( if( omitJournal ){ btree_flags |= BTREE_OMIT_JOURNAL; } + if( db->flags & SQLITE_NoReadlock ){ + btree_flags |= BTREE_NO_READLOCK; + } if( zFilename==0 ){ #if TEMP_STORE==0 /* Do nothing */ diff --git a/src/pager.c b/src/pager.c index e8b5a14309..53c2b84143 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.187 2005/01/29 08:32:45 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.188 2005/02/06 02:45:42 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -250,6 +250,7 @@ struct Pager { u8 journalOpen; /* True if journal file descriptors is valid */ u8 journalStarted; /* True if header of journal is synced */ u8 useJournal; /* Use a rollback journal on this file */ + u8 noReadlock; /* Do not bother to obtain readlocks */ u8 stmtOpen; /* True if the statement subjournal is open */ u8 stmtInUse; /* True we are in a statement subtransaction */ u8 stmtAutoopen; /* Open stmt journal when main journal is opened*/ @@ -1483,7 +1484,7 @@ int sqlite3pager_open( Pager **ppPager, /* Return the Pager structure here */ const char *zFilename, /* Name of the database file to open */ int nExtra, /* Extra bytes append to each in-memory page */ - int useJournal /* TRUE to use a rollback journal on this file */ + int flags /* flags controlling this file */ ){ Pager *pPager; char *zFullPathname = 0; @@ -1494,6 +1495,8 @@ int sqlite3pager_open( int tempFile = 0; int memDb = 0; int readOnly = 0; + int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; + int noReadlock = (flags & PAGER_NO_READLOCK)!=0; char zTemp[SQLITE_TEMPNAME_SIZE]; *ppPager = 0; @@ -1556,6 +1559,7 @@ int sqlite3pager_open( #endif pPager->journalOpen = 0; pPager->useJournal = useJournal && !memDb; + pPager->noReadlock = noReadlock && readOnly; pPager->stmtOpen = 0; pPager->stmtInUse = 0; pPager->nRef = 0; @@ -2144,7 +2148,7 @@ static PgHdr *pager_get_all_dirty_pages(Pager *pPager){ */ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ PgHdr *pPg; - int rc; + int rc, n; /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page ** number greater than this, or zero, is requested. @@ -2165,9 +2169,11 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ ** on the database file. */ if( pPager->nRef==0 && !MEMDB ){ - rc = pager_wait_on_lock(pPager, SHARED_LOCK); - if( rc!=SQLITE_OK ){ - return rc; + if( !pPager->noReadlock ){ + rc = pager_wait_on_lock(pPager, SHARED_LOCK); + if( rc!=SQLITE_OK ){ + return rc; + } } /* If a journal file exists, and there is no RESERVED lock on the @@ -2354,13 +2360,13 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ if( pPager->nExtra>0 ){ memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra); } - sqlite3pager_pagecount(pPager); + n = sqlite3pager_pagecount(pPager); if( pPager->errMask!=0 ){ sqlite3pager_unref(PGHDR_TO_DATA(pPg)); rc = pager_errcode(pPager); return rc; } - if( pPager->dbSize<(int)pgno ){ + if( n<(int)pgno ){ memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize); }else{ int rc; diff --git a/src/pager.h b/src/pager.h index ef602d3b86..8e88c86eb2 100644 --- a/src/pager.h +++ b/src/pager.h @@ -13,7 +13,7 @@ ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** -** @(#) $Id: pager.h,v 1.40 2004/11/05 16:37:03 danielk1977 Exp $ +** @(#) $Id: pager.h,v 1.41 2005/02/06 02:45:42 drh Exp $ */ /* @@ -50,13 +50,21 @@ typedef unsigned int Pgno; */ typedef struct Pager Pager; +/* +** Allowed values for the flags parameter to sqlite3pager_open(). +** +** NOTE: This values must match the corresponding BTREE_ values in btree.h. +*/ +#define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */ +#define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */ + /* ** See source code comments for a detailed description of the following ** routines: */ int sqlite3pager_open(Pager **ppPager, const char *zFilename, - int nExtra, int useJournal); + int nExtra, int flags); void sqlite3pager_set_busyhandler(Pager*, BusyHandler *pBusyHandler); void sqlite3pager_set_destructor(Pager*, void(*)(void*,int)); void sqlite3pager_set_reiniter(Pager*, void(*)(void*,int)); diff --git a/src/pragma.c b/src/pragma.c index 10accbf916..49a66c12e5 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.87 2005/02/04 04:07:17 danielk1977 Exp $ +** $Id: pragma.c,v 1.88 2005/02/06 02:45:42 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -148,6 +148,7 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ { "empty_result_callbacks", SQLITE_NullCallback }, /* The following is VERY experimental */ { "writable_schema", SQLITE_WriteSchema }, + { "omit_readlock", SQLITE_NoReadlock }, }; int i; const struct sPragmaType *p; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index dc4369aae1..627aeae65d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.367 2005/02/05 12:48:48 danielk1977 Exp $ +** @(#) $Id: sqliteInt.h,v 1.368 2005/02/06 02:45:43 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -469,6 +469,8 @@ struct sqlite3 { #define SQLITE_SqlTrace 0x00000200 /* Debug print SQL as it executes */ #define SQLITE_VdbeListing 0x00000400 /* Debug listings of VDBE programs */ #define SQLITE_WriteSchema 0x00000800 /* OK to update SQLITE_MASTER */ +#define SQLITE_NoReadlock 0x00001000 /* Readlocks are omitted when + ** accessing read-only databases */ /* ** Possible values for the sqlite.magic field. diff --git a/src/test2.c b/src/test2.c index b7c83cf56e..e77f2f2576 100644 --- a/src/test2.c +++ b/src/test2.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test2.c,v 1.28 2005/01/13 11:07:54 danielk1977 Exp $ +** $Id: test2.c,v 1.29 2005/02/06 02:45:43 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -81,7 +81,7 @@ static int pager_open( return TCL_ERROR; } if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR; - rc = sqlite3pager_open(&pPager, argv[1], 0, 1); + rc = sqlite3pager_open(&pPager, argv[1], 0, 0); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; diff --git a/tool/lempar.c b/tool/lempar.c index f7e2471f05..685f952c5f 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -462,6 +462,18 @@ static void yy_reduce( } #endif /* NDEBUG */ +#ifndef NDEBUG + /* Silence complaints from purify about yygotominor being uninitialized + ** in some cases when it is copied into the stack after the following + ** switch. yygotominor is uninitialized when a rule reduces that does + ** not set the value of its left-hand side nonterminal. Leaving the + ** value of the nonterminal uninitialized is utterly harmless as long + ** as the value is never used. So really the only thing this code + ** accomplishes is to quieten purify. + */ + memset(&yygotominor, 0, sizeof(yygotominor)); +#endif + switch( yyruleno ){ /* Beginning here are the reduction cases. A typical example ** follows: