From 4edc6bf3eed92fc5a5547406dec6760c9b062fcf Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 10 May 2011 17:31:29 +0000 Subject: [PATCH 01/30] Add experimental support for read-only connections to WAL databases. FossilOrigin-Name: bb59f9862da45d25fb51d7821130854828c91c98 --- manifest | 26 ++++++---- manifest.uuid | 2 +- src/os_unix.c | 51 +++++++++++++----- src/sqlite.h.in | 4 ++ src/test1.c | 3 ++ src/wal.c | 59 +++++++++++++++------ test/lock_common.tcl | 4 +- test/walro.test | 121 +++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 227 insertions(+), 43 deletions(-) create mode 100644 test/walro.test diff --git a/manifest b/manifest index daee9754e7..50889411e1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Return\sa\ssuitable\serror\smessage\sif\sthe\smode=\sargument\sto\sa\sURI\sspecifies\na\shigher\smode\sthan\swhat\sis\sallowed\sby\scontext.\s\sOther\sminor\scleanups\sfor\nthe\sURI\sparsing\slogic. -D 2011-05-09T19:20:17.775 +C Add\sexperimental\ssupport\sfor\sread-only\sconnections\sto\sWAL\sdatabases. +D 2011-05-10T17:31:29.338 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -163,7 +163,7 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c 2c67d126874b78eb427371db4793f0e8fbc7448b +F src/os_unix.c 03630dd062c3d1fb9f25e2a227048b709c5babff F src/os_win.c ff0e14615a5086fa5ba6926e4ec0dc9cfb5a1a84 F src/pager.c 24b689bc3639d534f5fb292d2c68038b1e720527 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 @@ -179,14 +179,14 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d9d440809025a58547e39f4f268c2a296bfb56ff F src/shell.c 72e7e176bf46d5c6518d15ac4ad6847c4bb5df79 -F src/sqlite.h.in 41a0e4bc842917226e170273f64b95717a63270a +F src/sqlite.h.in e7bbcb330ced6b5e25c9db8089c2c77aaefadf7d F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 F src/sqliteInt.h b34bd64a7ade4808fcc301e0bb67ef5051ea49c6 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c 501c9a200fd998a268be475be5858febc90b725b -F src/test1.c f506164085bc4cbbb4b5c14b9c6de153f1aeafc5 +F src/test1.c 6ae026cd9d2b1b1e95a372a7460d091705db645d F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7 @@ -245,7 +245,7 @@ F src/vdbeblob.c c3ccb7c8732858c680f442932e66ad06bb036562 F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 F src/vtab.c 48dcef8bc757c2e7b488f68b5ddebb1650da2450 -F src/wal.c 7334009b396285b658a95a3b6bc6d2b016a1f794 +F src/wal.c 2574b16ee88b1934e97f63ae38025dc48ef45327 F src/wal.h 7a5fbb00114b7f2cd40c7e1003d4c41ce9d26840 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c 55403ce19c506be6a321c7f129aff693d6103db5 @@ -547,7 +547,7 @@ F test/lock4.test c82268c031d39345d05efa672f80b025481b3ae5 F test/lock5.test b2abb5e711bc59b0eae00f6c97a36ec9f458fada F test/lock6.test ad5b387a3a8096afd3c68a55b9535056431b0cf5 F test/lock7.test 64006c84c1c616657e237c7ad6532b765611cf64 -F test/lock_common.tcl d279887a0ab16cdb6d935c1203e64113c5a000e9 +F test/lock_common.tcl 0c270b121d40959fa2f3add382200c27045b3d95 F test/lookaside.test 93f07bac140c5bb1d49f3892d2684decafdc7af2 F test/main.test 9d7bbfcc1b52c88ba7b2ba6554068ecf9939f252 F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9 @@ -883,6 +883,7 @@ F test/walfault.test 58fce626359c9376fe35101b5c0f2df8040aa839 F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walmode.test 22ddccd073c817ac9ead62b88ac446e8dedc7d2c F test/walnoshm.test a074428046408f4eb5c6a00e09df8cc97ff93317 +F test/walro.test 0fb4c79a9dfa1d14f46859e469d3b4844480cd9d F test/walshared.test 6dda2293880c300baf5d791c307f653094585761 F test/walslow.test d21625e2e99e11c032ce949e8a94661576548933 F test/walthread.test a25a393c068a2b42b44333fa3fdaae9072f1617c @@ -935,7 +936,10 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P ca3797d4967361e31a8a5ce1ce8190b095f3ed4c -R fbfaa47316ae48b91e92f26cbe2f2742 -U drh -Z 82e3dc394cc5052bfb9a5a6a21e4f298 +P d9bc1c7fe0ca5f6973a85827330958f4d09f8171 +R 864e9c4ee7a6cf5f8240415fb38d1af8 +T *branch * wal-readonly +T *sym-wal-readonly * +T -sym-trunk * +U dan +Z 321776a9f8d852e48652ad186c3a479b diff --git a/manifest.uuid b/manifest.uuid index 2b8787f1e2..e39ce5418f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d9bc1c7fe0ca5f6973a85827330958f4d09f8171 \ No newline at end of file +bb59f9862da45d25fb51d7821130854828c91c98 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index a760e2c147..d463e5917f 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -212,6 +212,7 @@ struct unixFile { UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ + int readOnlyShm; /* True to open shared-memory read-only */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ #if SQLITE_ENABLE_LOCKING_STYLE int openFlags; /* The flags specified at open() */ @@ -3452,6 +3453,10 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ case SQLITE_FCNTL_SIZE_HINT: { return fcntlSizeHint((unixFile *)id, *(i64 *)pArg); } + case SQLITE_FCNTL_READONLY_SHM: { + ((unixFile*)id)->readOnlyShm = (pArg!=0); + return SQLITE_OK; + } #ifndef NDEBUG /* The pager calls this method to signal that it has done ** a rollback and that the database is therefore unchanged and @@ -3541,6 +3546,7 @@ struct unixShmNode { char **apRegion; /* Array of mapped shared-memory regions */ int nRef; /* Number of unixShm objects pointing to this */ unixShm *pFirst; /* All unixShm objects pointing to this */ + u8 readOnly; /* True if this is a read-only mapping */ #ifdef SQLITE_DEBUG u8 exclMask; /* Mask of exclusive locks held */ u8 sharedMask; /* Mask of shared locks held */ @@ -3780,29 +3786,48 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ } if( pInode->bProcessLock==0 ){ - pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT, - (sStat.st_mode & 0777)); + int flags = (pDbFd->readOnlyShm ? O_RDONLY : O_RDWR|O_CREAT); + pShmNode->h = robust_open(zShmFilename, flags, (sStat.st_mode & 0777)); if( pShmNode->h<0 ){ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); goto shm_open_err; } + pShmNode->readOnly = pDbFd->readOnlyShm; /* Check to see if another process is holding the dead-man switch. - ** If not, truncate the file to zero length. - */ - rc = SQLITE_OK; - if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ - if( robust_ftruncate(pShmNode->h, 0) ){ - rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); + ** If not, zero the first few bytes of the shared-memory file to make + ** sure it is not mistaken for valid by code in wal.c. Except, if this + ** is a read-only connection to the shared-memory then it is not possible + ** to check check if another process is holding a read-lock on the DMS + ** byte, as we cannot attempt a write-lock via a read-only file + ** descriptor. So in this case, we just assume the shared-memory + ** contents are Ok and proceed. */ + if( pShmNode->readOnly==0 ){ + rc = SQLITE_OK; + if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ + if( pDbFd->readOnlyShm ){ + rc = SQLITE_IOERR_SHMOPEN; + }else if( 4!=osWrite(pShmNode->h, "\00\00\00\00", 4) ){ + rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); + } } + if( rc==SQLITE_OK ){ + rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); + } + if( rc ) goto shm_open_err; } - if( rc==SQLITE_OK ){ - rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); - } - if( rc ) goto shm_open_err; } } + /* If the unixShmNode is read-only, but SQLITE_FCNTL_READONLY_SHM has not + ** been set for file-descriptor pDbFd, return an error. The wal.c module + ** will then call this function again with SQLITE_FCNTL_READONLY_SHM set. + */ + else if( pShmNode->readOnly && !pDbFd->readOnlyShm ){ + rc = SQLITE_IOERR_SHMOPEN; + goto shm_open_err; + } + /* Make the new connection a child of the unixShmNode */ p->pShmNode = pShmNode; #ifdef SQLITE_DEBUG @@ -3923,7 +3948,7 @@ static int unixShmMap( while(pShmNode->nRegion<=iRegion){ void *pMem; if( pShmNode->h>=0 ){ - pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, + pMem = mmap(0, szRegion, PROT_READ|(!pShmNode->readOnly?PROT_WRITE:0), MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion ); if( pMem==MAP_FAILED ){ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d78daa7672..af88e4e726 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -454,6 +454,9 @@ int sqlite3_exec( #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) +#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) +#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) + /* ** CAPI3REF: Flags For File Open Operations ** @@ -742,6 +745,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_CHUNK_SIZE 6 #define SQLITE_FCNTL_FILE_POINTER 7 #define SQLITE_FCNTL_SYNC_OMITTED 8 +#define SQLITE_FCNTL_READONLY_SHM 9 /* diff --git a/src/test1.c b/src/test1.c index 8e30123433..c25fd2289d 100644 --- a/src/test1.c +++ b/src/test1.c @@ -163,6 +163,9 @@ const char *sqlite3TestErrorName(int rc){ case SQLITE_IOERR_CHECKRESERVEDLOCK: zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break; + + case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break; + case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break; default: zName = "SQLITE_Unknown"; break; } return zName; diff --git a/src/wal.c b/src/wal.c index 51ea18fb21..707fe12976 100644 --- a/src/wal.c +++ b/src/wal.c @@ -420,6 +420,7 @@ struct Wal { u8 writeLock; /* True if in a write transaction */ u8 ckptLock; /* True if holding a checkpoint lock */ u8 readOnly; /* True if the WAL file is open read-only */ + u8 readOnlyShm; /* True if the SHM file is open read-only */ WalIndexHdr hdr; /* Wal-index header for current transaction */ const char *zWalName; /* Name of WAL file */ u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ @@ -528,6 +529,16 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){ rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] ); + if( rc==SQLITE_CANTOPEN && iPage==0 ){ + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_READONLY_SHM, (void*)1); + rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, + pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] + ); + if( rc==SQLITE_OK ){ + pWal->readOnly = pWal->readOnlyShm = 1; + } + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_READONLY_SHM, (void*)0); + } } } @@ -772,6 +783,7 @@ static void walUnlockShared(Wal *pWal, int lockIdx){ } static int walLockExclusive(Wal *pWal, int lockIdx, int n){ int rc; + assert( pWal->readOnlyShm==0 ); if( pWal->exclusiveMode ) return SQLITE_OK; rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE); @@ -781,6 +793,7 @@ static int walLockExclusive(Wal *pWal, int lockIdx, int n){ return rc; } static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){ + assert( pWal->readOnlyShm==0 ); if( pWal->exclusiveMode ) return; (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE); @@ -1056,6 +1069,7 @@ static int walIndexRecover(Wal *pWal){ assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 ); assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE ); assert( pWal->writeLock ); + assert( pWal->readOnlyShm==0 ); iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock; nLock = SQLITE_SHM_NLOCK - iLock; rc = walLockExclusive(pWal, iLock, nLock); @@ -1904,24 +1918,31 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1); /* If the first attempt failed, it might have been due to a race - ** with a writer. So get a WRITE lock and try again. + ** with a writer. So lock the WAL_WRITE_LOCK byte and try again. */ assert( badHdr==0 || pWal->writeLock==0 ); - if( badHdr && SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ - pWal->writeLock = 1; - if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ - badHdr = walIndexTryHdr(pWal, pChanged); - if( badHdr ){ - /* If the wal-index header is still malformed even while holding - ** a WRITE lock, it can only mean that the header is corrupted and - ** needs to be reconstructed. So run recovery to do exactly that. - */ - rc = walIndexRecover(pWal); - *pChanged = 1; + if( badHdr ){ + if( pWal->readOnlyShm ){ + if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){ + walUnlockShared(pWal, WAL_WRITE_LOCK); + rc = SQLITE_READONLY_RECOVERY; } + }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ + pWal->writeLock = 1; + if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ + badHdr = walIndexTryHdr(pWal, pChanged); + if( badHdr ){ + /* If the wal-index header is still malformed even while holding + ** a WRITE lock, it can only mean that the header is corrupted and + ** needs to be reconstructed. So run recovery to do exactly that. + */ + rc = walIndexRecover(pWal); + *pChanged = 1; + } + } + pWal->writeLock = 0; + walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); } - pWal->writeLock = 0; - walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); } /* If the header is read successfully, check the version number to make @@ -2108,7 +2129,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ } /* There was once an "if" here. The extra "{" is to preserve indentation. */ { - if( mxReadMark < pWal->hdr.mxFrame || mxI==0 ){ + if( pWal->readOnlyShm==0 && (mxReadMark < pWal->hdr.mxFrame || mxI==0) ){ for(i=1; ireadOnlyShm && rc==SQLITE_OK) ); + return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK; } rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); @@ -2359,6 +2381,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){ if( pWal->readOnly ){ return SQLITE_READONLY; } + assert( pWal->readOnlyShm==0 ); /* Only one writer allowed at a time. Get the write lock. Return ** SQLITE_BUSY if unable. @@ -2748,6 +2771,10 @@ int sqlite3WalCheckpoint( assert( pWal->writeLock==0 ); WALTRACE(("WAL%p: checkpoint begins\n", pWal)); + if( pWal->readOnlyShm ){ + return SQLITE_READONLY; + } + rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); if( rc ){ /* Usually this is SQLITE_BUSY meaning that another thread or process diff --git a/test/lock_common.tcl b/test/lock_common.tcl index 21f584264a..bc1eb86bdc 100644 --- a/test/lock_common.tcl +++ b/test/lock_common.tcl @@ -55,8 +55,8 @@ proc do_multiclient_test {varname script} { uplevel set $varname $tn uplevel $script - code2 { db2 close } - code3 { db3 close } + catch { code2 { db2 close } } + catch { code3 { db3 close } } catch { close $::code2_chan } catch { close $::code3_chan } catch { db close } diff --git a/test/walro.test b/test/walro.test new file mode 100644 index 0000000000..b558622cad --- /dev/null +++ b/test/walro.test @@ -0,0 +1,121 @@ +# 2011 May 09 +# +# 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 contains tests for using WAL databases in read-only mode. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/lock_common.tcl +set ::testprefix walro + + +do_multiclient_test tn { + # These tests are only going to work on unix. + # + if {$tcl_platform(platform) != "unix"} continue + + # Do not run tests with the connections in the same process. + # + if {$tn==2} continue + + # Close all connections and delete the database. + # + code1 { db close } + code2 { db2 close } + code3 { db3 close } + forcedelete test.db + forcedelete walro + + file mkdir walro + + do_test 1.1.1 { + code2 { sqlite3 db2 test.db } + sql2 { + PRAGMA journal_mode = WAL; + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES('a', 'b'); + } + file exists test.db-shm + } {1} + + do_test 1.1.2 { + file attributes test.db-shm -permissions r--r--r-- + code1 { sqlite3 db test.db } + } {} + + do_test 1.1.3 { sql1 "SELECT * FROM t1" } {a b} + do_test 1.1.4 { sql2 "INSERT INTO t1 VALUES('c', 'd')" } {} + do_test 1.1.5 { sql1 "SELECT * FROM t1" } {a b c d} + + # Check that the read-only connection cannot write or checkpoint the db. + # + do_test 1.1.6 { + csql1 "INSERT INTO t1 VALUES('e', 'f')" + } {1 {attempt to write a readonly database}} + do_test 1.1.7 { + csql1 "PRAGMA wal_checkpoint" + } {1 {attempt to write a readonly database}} + + do_test 1.1.9 { sql2 "INSERT INTO t1 VALUES('e', 'f')" } {} + do_test 1.1.10 { sql1 "SELECT * FROM t1" } {a b c d e f} + + do_test 1.1.11 { + sql2 { + INSERT INTO t1 VALUES('g', 'h'); + PRAGMA wal_checkpoint; + } + set {} {} + } {} + do_test 1.1.12 { sql1 "SELECT * FROM t1" } {a b c d e f g h} + do_test 1.1.13 { sql2 "INSERT INTO t1 VALUES('i', 'j')" } {} + + do_test 1.2.1 { + code2 { db2 close } + code1 { db close } + list [file exists test.db-wal] [file exists test.db-shm] + } {1 1} + do_test 1.2.2 { + code1 { sqlite3 db test.db } + sql1 { SELECT * FROM t1 } + } {a b c d e f g h i j} + + do_test 1.2.3 { + code1 { db close } + file attributes test.db-shm -permissions rw-r--r-- + hexio_write test.db-shm 0 01020304 + file attributes test.db-shm -permissions r--r--r-- + code1 { sqlite3 db test.db } + csql1 { SELECT * FROM t1 } + } {1 {attempt to write a readonly database}} + do_test 1.2.4 { + code1 { sqlite3_extended_errcode db } + } {SQLITE_READONLY_RECOVERY} + + do_test 1.2.5 { + file attributes test.db-shm -permissions rw-r--r-- + code2 { sqlite3 db2 test.db } + sql2 "SELECT * FROM t1" + } {a b c d e f g h i j} + file attributes test.db-shm -permissions r--r--r-- + do_test 1.2.6 { sql1 "SELECT * FROM t1" } {a b c d e f g h i j} + + do_test 1.2.7 { + sql2 { + PRAGMA wal_checkpoint; + INSERT INTO t1 VALUES('k', 'l'); + } + set {} {} + } {} + do_test 1.2.8 { sql1 "SELECT * FROM t1" } {a b c d e f g h i j k l} +} + +finish_test From b6d2f9c5ef0d6fa71b744bf5ccfb8ac83b5ed060 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 11 May 2011 14:57:33 +0000 Subject: [PATCH 02/30] Only open a read-only connection to shared-memory if the "readonly_shm=1" option is specified as part of the database file URI (and if a read-write connection fails). FossilOrigin-Name: 671ba5fc59f7a958e5a4138d2425b1173a442ad7 --- manifest | 31 ++++++++++++++----------------- manifest.uuid | 2 +- src/attach.c | 6 ++++-- src/btree.h | 1 + src/main.c | 13 +++++++++++-- src/pager.c | 7 +++++-- src/pager.h | 1 + src/sqliteInt.h | 2 +- src/wal.c | 14 +++++++++++--- src/wal.h | 4 ++-- test/walro.test | 13 ++++++++++--- 11 files changed, 61 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index 50889411e1..3d33b8171b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sexperimental\ssupport\sfor\sread-only\sconnections\sto\sWAL\sdatabases. -D 2011-05-10T17:31:29.338 +C Only\sopen\sa\sread-only\sconnection\sto\sshared-memory\sif\sthe\s"readonly_shm=1"\soption\sis\sspecified\sas\spart\sof\sthe\sdatabase\sfile\sURI\s(and\sif\sa\sread-write\sconnection\sfails). +D 2011-05-11T14:57:33.029 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -117,13 +117,13 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c 280f5c04b11b492703a342222b3de0a999445280 F src/analyze.c a425d62e8fa9ebcb4359ab84ff0c62c6563d2e2a -F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f +F src/attach.c a87bfb77a720f7aa02791434aacfd9bc8feb50cc F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 26f8a9d6169413c5682b89b5397d20437b653154 -F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce +F src/btree.h d796dc4030b3cce7f5a0cc4f2f986d2befa6b8ac F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 F src/build.c 0132bc6631fa617a1d28ef805921f6dbac18a514 F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a @@ -144,7 +144,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e F src/loadext.c 3ae0d52da013a6326310655be6473fd472347b85 -F src/main.c f00cee5a27f5df5ed536e7043cb451b3c85ce65c +F src/main.c 167fb3285720917e4d1a5c633f558c81b751eca3 F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206 @@ -165,8 +165,8 @@ F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 03630dd062c3d1fb9f25e2a227048b709c5babff F src/os_win.c ff0e14615a5086fa5ba6926e4ec0dc9cfb5a1a84 -F src/pager.c 24b689bc3639d534f5fb292d2c68038b1e720527 -F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 +F src/pager.c 4056376f83f85cea9922a11161087c529e39f7dc +F src/pager.h 34c6b029446f06f40847746d22faac0d354dd909 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 F src/pcache.c 09d38c44ab275db581f7a2f6ff8b9bc7f8c0faaa F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 @@ -181,7 +181,7 @@ F src/select.c d9d440809025a58547e39f4f268c2a296bfb56ff F src/shell.c 72e7e176bf46d5c6518d15ac4ad6847c4bb5df79 F src/sqlite.h.in e7bbcb330ced6b5e25c9db8089c2c77aaefadf7d F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 -F src/sqliteInt.h b34bd64a7ade4808fcc301e0bb67ef5051ea49c6 +F src/sqliteInt.h 798fb09648cefc159ac9b3ce5e00f5ada1377ed1 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -245,8 +245,8 @@ F src/vdbeblob.c c3ccb7c8732858c680f442932e66ad06bb036562 F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 F src/vtab.c 48dcef8bc757c2e7b488f68b5ddebb1650da2450 -F src/wal.c 2574b16ee88b1934e97f63ae38025dc48ef45327 -F src/wal.h 7a5fbb00114b7f2cd40c7e1003d4c41ce9d26840 +F src/wal.c adc6c83b650e67e32159e11d557a46594834853e +F src/wal.h c1e05cdf3d42ed7c9263739ca8f5cdd8761e7de3 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c 55403ce19c506be6a321c7f129aff693d6103db5 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -883,7 +883,7 @@ F test/walfault.test 58fce626359c9376fe35101b5c0f2df8040aa839 F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walmode.test 22ddccd073c817ac9ead62b88ac446e8dedc7d2c F test/walnoshm.test a074428046408f4eb5c6a00e09df8cc97ff93317 -F test/walro.test 0fb4c79a9dfa1d14f46859e469d3b4844480cd9d +F test/walro.test c204f62fb6a77839bc6ce5adbdcc9df2aac877ca F test/walshared.test 6dda2293880c300baf5d791c307f653094585761 F test/walslow.test d21625e2e99e11c032ce949e8a94661576548933 F test/walthread.test a25a393c068a2b42b44333fa3fdaae9072f1617c @@ -936,10 +936,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P d9bc1c7fe0ca5f6973a85827330958f4d09f8171 -R 864e9c4ee7a6cf5f8240415fb38d1af8 -T *branch * wal-readonly -T *sym-wal-readonly * -T -sym-trunk * +P bb59f9862da45d25fb51d7821130854828c91c98 +R 04ad06f1f1eb20213db6e513d8bb75aa U dan -Z 321776a9f8d852e48652ad186c3a479b +Z 112f0ce43ba9dc957c26d5146ee2fe50 diff --git a/manifest.uuid b/manifest.uuid index e39ce5418f..e0664d4e86 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bb59f9862da45d25fb51d7821130854828c91c98 \ No newline at end of file +671ba5fc59f7a958e5a4138d2425b1173a442ad7 \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 18f8823b31..4b8ea77917 100644 --- a/src/attach.c +++ b/src/attach.c @@ -76,6 +76,8 @@ static void attachFunc( Db *aNew; char *zErrDyn = 0; sqlite3_vfs *pVfs; + const char *zVfs = db->pVfs->zName; /* Name of default (main) VFS */ + int btflags = 0; UNUSED_PARAMETER(NotUsed); @@ -129,7 +131,7 @@ static void attachFunc( ** or may not be initialised. */ flags = db->openFlags; - rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); + rc = sqlite3ParseUri(zVfs, zFile, &flags, &btflags, &pVfs, &zPath, &zErr); if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; sqlite3_result_error(context, zErr, -1); @@ -138,7 +140,7 @@ static void attachFunc( } assert( pVfs ); flags |= SQLITE_OPEN_MAIN_DB; - rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, 0, flags); + rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, btflags, flags); sqlite3_free( zPath ); db->nDb++; if( rc==SQLITE_CONSTRAINT ){ diff --git a/src/btree.h b/src/btree.h index 9e3a73b3b6..c5abc9c865 100644 --- a/src/btree.h +++ b/src/btree.h @@ -61,6 +61,7 @@ int sqlite3BtreeOpen( #define BTREE_MEMORY 4 /* This is an in-memory DB */ #define BTREE_SINGLE 8 /* The file contains at most 1 b-tree */ #define BTREE_UNORDERED 16 /* Use of a hash implementation is OK */ +#define BTREE_READONLYSHM 32 /* Read-only SHM access is acceptable */ int sqlite3BtreeClose(Btree*); int sqlite3BtreeSetCacheSize(Btree*,int); diff --git a/src/main.c b/src/main.c index 5b46f4b736..e986f83225 100644 --- a/src/main.c +++ b/src/main.c @@ -1818,6 +1818,7 @@ int sqlite3ParseUri( const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */ const char *zUri, /* Nul-terminated URI to parse */ unsigned int *pFlags, /* IN/OUT: SQLITE_OPEN_XXX flags */ + int *pBtflags, /* IN/OUT: BTREE_XXX flags */ sqlite3_vfs **ppVfs, /* OUT: VFS to use */ char **pzFile, /* OUT: Filename component of URI */ char **pzErrMsg /* OUT: Error message (if rc!=SQLITE_OK) */ @@ -1933,6 +1934,12 @@ int sqlite3ParseUri( if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){ zVfs = zVal; + }else if( nOpt==12 && memcmp("readonly_shm", zOpt, 12)==0 ){ + if( sqlite3Atoi(zVal) ){ + *pBtflags |= BTREE_READONLYSHM; + }else{ + *pBtflags &= ~BTREE_READONLYSHM; + } }else{ struct OpenMode { const char *z; @@ -2036,6 +2043,7 @@ static int openDatabase( int isThreadsafe; /* True for threadsafe connections */ char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */ char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */ + int btflags = 0; /* Mask of BTREE_XXX flags */ *ppDb = 0; #ifndef SQLITE_OMIT_AUTOINIT @@ -2163,7 +2171,8 @@ static int openDatabase( nocaseCollatingFunc, 0); /* Parse the filename/URI argument. */ - rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); + rc = sqlite3ParseUri( + zVfs, zFilename, &flags, &btflags, &db->pVfs, &zOpen, &zErrMsg); if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; sqlite3Error(db, rc, zErrMsg ? "%s" : 0, zErrMsg); @@ -2173,7 +2182,7 @@ static int openDatabase( /* Open the backend database driver */ db->openFlags = flags; - rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0, + rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, btflags, flags | SQLITE_OPEN_MAIN_DB); if( rc!=SQLITE_OK ){ if( rc==SQLITE_IOERR_NOMEM ){ diff --git a/src/pager.c b/src/pager.c index 8ad6984f8a..56dae06040 100644 --- a/src/pager.c +++ b/src/pager.c @@ -620,6 +620,7 @@ struct Pager { u8 tempFile; /* zFilename is a temporary file */ u8 readOnly; /* True for a read-only database */ u8 memDb; /* True to inhibit all file I/O */ + u8 readOnlyShm; /* True if read-only shm access is Ok */ /************************************************************************** ** The following block contains those class members that change during @@ -3017,6 +3018,7 @@ static int pagerWalFrames( static int pagerBeginReadTransaction(Pager *pPager){ int rc; /* Return code */ int changed = 0; /* True if cache must be reset */ + Wal *pWal = pPager->pWal; assert( pagerUseWal(pPager) ); assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); @@ -3026,9 +3028,9 @@ static int pagerBeginReadTransaction(Pager *pPager){ ** are in locking_mode=NORMAL and EndRead() was previously called, ** the duplicate call is harmless. */ - sqlite3WalEndReadTransaction(pPager->pWal); + sqlite3WalEndReadTransaction(pWal); - rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed); + rc = sqlite3WalBeginReadTransaction(pWal, pPager->readOnlyShm, &changed); if( rc!=SQLITE_OK || changed ){ pager_reset(pPager); } @@ -4414,6 +4416,7 @@ int sqlite3PagerOpen( } pPager->pVfs = pVfs; pPager->vfsFlags = vfsFlags; + pPager->readOnlyShm = (flags & PAGER_READONLYSHM)!=0; /* Open the pager file. */ diff --git a/src/pager.h b/src/pager.h index eab7ddaf80..c6cb8bcb55 100644 --- a/src/pager.h +++ b/src/pager.h @@ -60,6 +60,7 @@ typedef struct PgHdr DbPage; #define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */ #define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */ #define PAGER_MEMORY 0x0004 /* In-memory database */ +#define PAGER_READONLYSHM 0x0020 /* Read-only SHM access is acceptable */ /* ** Valid values for the second argument to sqlite3PagerLockingMode(). diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4a3e45d7c0..cedd780779 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2673,7 +2673,7 @@ void sqlite3AddColumnType(Parse*,Token*); void sqlite3AddDefaultValue(Parse*,ExprSpan*); void sqlite3AddCollateType(Parse*, Token*); void sqlite3EndTable(Parse*,Token*,Token*,Select*); -int sqlite3ParseUri(const char*,const char*,unsigned int*, +int sqlite3ParseUri(const char*,const char*,unsigned int*,int*, sqlite3_vfs**,char**,char **); Bitvec *sqlite3BitvecCreate(u32); diff --git a/src/wal.c b/src/wal.c index 707fe12976..3d6baf21c8 100644 --- a/src/wal.c +++ b/src/wal.c @@ -529,7 +529,8 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){ rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] ); - if( rc==SQLITE_CANTOPEN && iPage==0 ){ + if( rc==SQLITE_CANTOPEN && pWal->readOnlyShm>1 ){ + assert( iPage==0 ); sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_READONLY_SHM, (void*)1); rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] @@ -541,9 +542,10 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){ } } } - *ppPage = pWal->apWiData[iPage]; + assert( iPage==0 || *ppPage || rc!=SQLITE_OK ); + if( pWal->readOnlyShm>1 ) pWal->readOnlyShm = 0; return rc; } @@ -1909,6 +1911,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ return rc; }; assert( page0 || pWal->writeLock==0 ); + assert( pWal->readOnlyShm==0 || pWal->readOnlyShm==1 ); /* If the first page of the wal-index has been mapped, try to read the ** wal-index header immediately, without holding any lock. This usually @@ -2200,13 +2203,18 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ ** Pager layer will use this to know that is cache is stale and ** needs to be flushed. */ -int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ +int sqlite3WalBeginReadTransaction(Wal *pWal, int readOnlyShm, int *pChanged){ int rc; /* Return code */ int cnt = 0; /* Number of TryBeginRead attempts */ + if( pWal->nWiData==0 || pWal->apWiData[0]==0 ){ + assert( readOnlyShm==0 || readOnlyShm==1 ); + pWal->readOnlyShm = readOnlyShm*2; + } do{ rc = walTryBeginRead(pWal, pChanged, 0, ++cnt); }while( rc==WAL_RETRY ); + assert( rc || pWal->readOnlyShm==0 || (readOnlyShm && pWal->readOnlyShm==1) ); testcase( (rc&0xff)==SQLITE_BUSY ); testcase( (rc&0xff)==SQLITE_IOERR ); testcase( rc==SQLITE_PROTOCOL ); diff --git a/src/wal.h b/src/wal.h index 2039c701cf..aca5a56a56 100644 --- a/src/wal.h +++ b/src/wal.h @@ -22,7 +22,7 @@ #ifdef SQLITE_OMIT_WAL # define sqlite3WalOpen(x,y,z) 0 # define sqlite3WalClose(w,x,y,z) 0 -# define sqlite3WalBeginReadTransaction(y,z) 0 +# define sqlite3WalBeginReadTransaction(x,y,z) 0 # define sqlite3WalEndReadTransaction(z) # define sqlite3WalRead(v,w,x,y,z) 0 # define sqlite3WalDbsize(y) 0 @@ -56,7 +56,7 @@ int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *); ** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the ** transaction and releases the lock. */ -int sqlite3WalBeginReadTransaction(Wal *pWal, int *); +int sqlite3WalBeginReadTransaction(Wal *pWal, int, int *); void sqlite3WalEndReadTransaction(Wal *pWal); /* Read a page from the write-ahead log, if it is present. */ diff --git a/test/walro.test b/test/walro.test index b558622cad..1025f00e33 100644 --- a/test/walro.test +++ b/test/walro.test @@ -35,6 +35,13 @@ do_multiclient_test tn { forcedelete test.db forcedelete walro + foreach c {code1 code2 code3} { + $c { + sqlite3_shutdown + sqlite3_config_uri 1 + } + } + file mkdir walro do_test 1.1.1 { @@ -49,7 +56,7 @@ do_multiclient_test tn { do_test 1.1.2 { file attributes test.db-shm -permissions r--r--r-- - code1 { sqlite3 db test.db } + code1 { sqlite3 db file:test.db?readonly_shm=1 } } {} do_test 1.1.3 { sql1 "SELECT * FROM t1" } {a b} @@ -84,7 +91,7 @@ do_multiclient_test tn { list [file exists test.db-wal] [file exists test.db-shm] } {1 1} do_test 1.2.2 { - code1 { sqlite3 db test.db } + code1 { sqlite3 db file:test.db?readonly_shm=1 } sql1 { SELECT * FROM t1 } } {a b c d e f g h i j} @@ -93,7 +100,7 @@ do_multiclient_test tn { file attributes test.db-shm -permissions rw-r--r-- hexio_write test.db-shm 0 01020304 file attributes test.db-shm -permissions r--r--r-- - code1 { sqlite3 db test.db } + code1 { sqlite3 db file:test.db?readonly_shm=1 } csql1 { SELECT * FROM t1 } } {1 {attempt to write a readonly database}} do_test 1.2.4 { From a96a399ec95667f268c135e74a16bef517b1fca2 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 11 May 2011 17:36:17 +0000 Subject: [PATCH 03/30] Add missing comments associated with readonly shm changes. FossilOrigin-Name: 6a2ea52e6c09a570428161090c2f087c66f714ec --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/main.c | 5 +++++ src/sqlite.h.in | 39 ++++++++++++++++++++++++++++++++++++++- src/wal.c | 8 ++++++++ 5 files changed, 60 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index d15e2a3497..15dda4253a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\strunk\schanges.\sAdd\sa\scouple\sof\sreadonly\sshm\stests. -D 2011-05-11T15:53:16.929 +C Add\smissing\scomments\sassociated\swith\sreadonly\sshm\schanges. +D 2011-05-11T17:36:17.276 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -144,7 +144,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e F src/loadext.c 3ae0d52da013a6326310655be6473fd472347b85 -F src/main.c 951a1af49d13083da09be9d2464052e49fc25830 +F src/main.c a145cea130adfe945ab1fa7e9543c492e3f2f419 F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206 @@ -179,7 +179,7 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d9d440809025a58547e39f4f268c2a296bfb56ff F src/shell.c 72e7e176bf46d5c6518d15ac4ad6847c4bb5df79 -F src/sqlite.h.in 059514ec27c8f9e11c73695aa57e55d354973e1e +F src/sqlite.h.in adeb2c8019a3851a10e3872f44b34c95c6e409f2 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 F src/sqliteInt.h 798fb09648cefc159ac9b3ce5e00f5ada1377ed1 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -245,7 +245,7 @@ F src/vdbeblob.c c3ccb7c8732858c680f442932e66ad06bb036562 F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 F src/vtab.c 48dcef8bc757c2e7b488f68b5ddebb1650da2450 -F src/wal.c adc6c83b650e67e32159e11d557a46594834853e +F src/wal.c 6d8ee757f62bca9b0b713724677878dff5bf7e79 F src/wal.h c1e05cdf3d42ed7c9263739ca8f5cdd8761e7de3 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c 55403ce19c506be6a321c7f129aff693d6103db5 @@ -936,7 +936,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 671ba5fc59f7a958e5a4138d2425b1173a442ad7 3e490915301216e242a5cdeb0febaff12ed53cb9 -R 1feba9025b47c541dc5cefaffc74e97e +P cde45a033ee6834900f5f5c272c383408883a74c +R 77f3671cb0a1ec2771484489a2a100be U dan -Z af31082504210cb42f7a67f58917a8ef +Z 826df29e354d14eb64673fd89c39c62e diff --git a/manifest.uuid b/manifest.uuid index 8bb70d0669..68e3f5666d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cde45a033ee6834900f5f5c272c383408883a74c \ No newline at end of file +6a2ea52e6c09a570428161090c2f087c66f714ec \ No newline at end of file diff --git a/src/main.c b/src/main.c index 45ee8fbd5b..f4cf735e3c 100644 --- a/src/main.c +++ b/src/main.c @@ -1803,6 +1803,11 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ ** *pFlags may be updated before returning if the URI filename contains ** "cache=xxx" or "mode=xxx" query parameters. ** +** The third argument, pBtflags, points to an integer containing the flags +** that will be passed as the 5th argument to sqlite3BtreeOpen (BTREE_XXX +** flags). This value will be edited if the URI filename contains a +** "readonly_shm=1" or "readonly_shm=0" query parameter. +** ** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to ** the VFS that should be used to open the database file. *pzFile is set to ** point to a buffer containing the name of the file to open. It is the diff --git a/src/sqlite.h.in b/src/sqlite.h.in index bafd322264..a002a8b4ea 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -736,6 +736,27 @@ struct sqlite3_io_methods { ** Applications should not call [sqlite3_file_control()] with this ** opcode as doing so may disrupt the operation of the specialized VFSes ** that do require it. +** +** The [SQLITE_FCNTL_READONLY_SHM] may be generated internally by SQLite if +** the "readonly_shm=1" URI option is specified when the database is opened. +** The fourth argument passed to the VFS xFileControl methods is a pointer +** to a variable of type "int" containing the value 1 or 0. If the variable +** contains the value 1, then this indicates to the VFS that a read-only +** mapping of the shared-memory region is acceptable. If it is set to 0, then +** this indicates that a read-write mapping is required (as normal). If +** a read-only mapping is returned, then the VFS may also return read-only +** mappings for any subsequent requests via the same file-descriptor - +** regardless of the value most recently configured using +** SQLITE_FCNTL_READONLY_SHM. +** +** In practice, if "readonly_shm=1" is specified and the first attempt to +** map a shared-memory region fails, then this file-control is invoked with +** the argument variable set to 1 and a second attempt to map the shared-memory +** region is made. If this mapping succeeds, then the connection continues +** with the read-only mapping. Otherwise, if it fails, SQLITE_CANTOPEN is +** returned to the caller. Whether or not the second (read-only) mapping +** attempt succeeds, the file-control is invoked again with the argument +** variable set to 0. */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_GET_LOCKPROXYFILE 2 @@ -2444,7 +2465,7 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** ** The query component of a URI may contain parameters that are interpreted ** either by SQLite itself, or by a [sqlite3_vfs | custom VFS implementation]. -** SQLite interprets the following three query parameters: +** SQLite interprets the following four query parameters: ** **
    **
  • vfs: ^The "vfs" parameter may be used to specify the name of @@ -2476,6 +2497,22 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in ** a URI filename, its value overrides any behaviour requested by setting ** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. +** +**
  • readonly_shm: ^The readonly_shm parameter may be set to +** either "1" or "0". Setting it to "1" indicates that if the database +** is in WAL mode and read-write access to the associated shared +** memory region cannot be obtained, then an attempt should be made to open +** the shared-memory in read-only mode instead. If there exist one or +** more other database clients that have read-write connections to the +** database shared-memory, then a read-only shared-memory connection works +** fine. However, if there exist no clients with read-write connections +** to the shared-memory and the most recent such crashed or was interrupted +** by a power failure, then it is possible for a database client using a +** read-only connection to return incorrect data, incorrectly report +** database corruption, or return an SQLITE_READONLY error. Or if the +** most recent read-write connection shut down cleanly, it may not be +** possible to open the shared-memory in read-only mode at all, and SQLite +** will return SQLITE_CANTOPEN. **
** ** ^Specifying an unknown parameter in the query component of a URI is not an diff --git a/src/wal.c b/src/wal.c index 3d6baf21c8..2ee7f59e89 100644 --- a/src/wal.c +++ b/src/wal.c @@ -406,6 +406,14 @@ struct WalCkptInfo { /* ** An open write-ahead log file is represented by an instance of the ** following object. +** +** The readOnlyShm variable is normally set to 0. If it is set to 1, then +** the connection to shared-memory is read-only. This means it cannot +** be written at all (even when read-locking the database). If it is set +** to 2, then the shared-memory region is not yet open, but a read-only +** connection is acceptable. In this case when the shared-memory is opened +** (see function walIndexPage()), readOnlyShm is set to either 0 or 1 as +** appropriate. */ struct Wal { sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ From ef05c39d12cf13bdad52c9f63f3154a588aaeb74 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 25 May 2011 20:25:10 +0000 Subject: [PATCH 04/30] Ignore malloc failures within the WAL file truncation attempt for journal_size_limit. FossilOrigin-Name: dd19105aa9521ffc0edcf16b84c064d5ebad55d7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wal.c | 2 ++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 1074285b3f..bd65c3d5e3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scase\swhere\sa\smalloc()\serror\scould\slead\sto\smismatched\svirtual-table\sxBegin/xCommit/xRollback\scallbacks. -D 2011-05-25T18:46:22.024 +C Ignore\smalloc\sfailures\swithin\sthe\sWAL\sfile\struncation\sattempt\sfor\njournal_size_limit. +D 2011-05-25T20:25:10.559 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -245,7 +245,7 @@ F src/vdbeblob.c c3ccb7c8732858c680f442932e66ad06bb036562 F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 F src/vtab.c 9ba8c7fdb7d39260c033a402f6032d3e7bc5d336 -F src/wal.c de27c34c8016c00be348fc6bed588816557ceb66 +F src/wal.c ab1d8c5abf904fd6396f90499cbd8c54b8d6961b F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c 55403ce19c506be6a321c7f129aff693d6103db5 @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 6df99e52dabf2a243ad635529649b86c21735e91 -R 02c26b8fd230a540c57276590c974e79 -U dan -Z e2a23225f8e5abceac6a8fe1d14982ec +P d807304a695fc85402b86e1cd32a6e3bbb2823c8 +R 40f4c0754c95b7a51c08aa03886ff26c +U drh +Z c74bad4333e073e26c4db5e166f8f584 diff --git a/manifest.uuid b/manifest.uuid index 5b49fb4d2d..f139bfb8f7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d807304a695fc85402b86e1cd32a6e3bbb2823c8 \ No newline at end of file +dd19105aa9521ffc0edcf16b84c064d5ebad55d7 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 1222660985..d90fb05d8b 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2539,10 +2539,12 @@ static int walRestartLog(Wal *pWal){ if( pWal->mxWalSize>=0 ){ i64 sz; int rx; + sqlite3BeginBenignMalloc(); rx = sqlite3OsFileSize(pWal->pWalFd, &sz); if( rx==SQLITE_OK && (sz > pWal->mxWalSize) ){ rx = sqlite3OsTruncate(pWal->pWalFd, pWal->mxWalSize); } + sqlite3EndBenignMalloc(); if( rx ){ sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName); } From 7ee4fdd7ba0366a929adb5c94297f9debcf4a4b3 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 25 May 2011 23:18:02 +0000 Subject: [PATCH 05/30] Fix some minor and harmless compiler warnings. FossilOrigin-Name: a4755e7088c3cc7c5ea191ce37f3950472f523ec --- ext/fts3/fts3.c | 4 ++++ ext/fts3/fts3_aux.c | 6 +++++- ext/rtree/rtree.c | 7 +++++-- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 5e2472753e..0aba0546c3 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -3665,6 +3665,7 @@ static int fts3RenameMethod( static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts3Table *p = (Fts3Table*)pVtab; + UNUSED_PARAMETER(iSavepoint); assert( p->inTransaction ); assert( p->mxSavepoint < iSavepoint ); TESTONLY( p->mxSavepoint = iSavepoint ); @@ -3672,6 +3673,8 @@ static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ } static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); + UNUSED_PARAMETER(iSavepoint); + UNUSED_PARAMETER(pVtab); assert( p->inTransaction ); assert( p->mxSavepoint >= iSavepoint ); TESTONLY( p->mxSavepoint = iSavepoint-1 ); @@ -3679,6 +3682,7 @@ static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ } static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts3Table *p = (Fts3Table*)pVtab; + UNUSED_PARAMETER(iSavepoint); assert( p->inTransaction ); assert( p->mxSavepoint >= iSavepoint ); TESTONLY( p->mxSavepoint = iSavepoint ); diff --git a/ext/fts3/fts3_aux.c b/ext/fts3/fts3_aux.c index 6108689ae1..cd035d2a30 100644 --- a/ext/fts3/fts3_aux.c +++ b/ext/fts3/fts3_aux.c @@ -342,6 +342,7 @@ static int fts3auxFilterMethod( int isScan; UNUSED_PARAMETER(nVal); + UNUSED_PARAMETER(idxStr); assert( idxStr==0 ); assert( idxNum==FTS4AUX_EQ_CONSTRAINT || idxNum==0 @@ -459,7 +460,10 @@ int sqlite3Fts3InitAux(sqlite3 *db){ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindFunction */ - 0 /* xRename */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0 /* xRollbackTo */ }; int rc; /* Return code */ diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 6e00827b46..66a10df1c3 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -2849,7 +2849,7 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){ } static sqlite3_module rtreeModule = { - 0, /* iVersion */ + 0, /* iVersion */ rtreeCreate, /* xCreate - create a table */ rtreeConnect, /* xConnect - connect to an existing table */ rtreeBestIndex, /* xBestIndex - Determine search strategy */ @@ -2868,7 +2868,10 @@ static sqlite3_module rtreeModule = { 0, /* xCommit - commit transaction */ 0, /* xRollback - rollback transaction */ 0, /* xFindFunction - function overloading */ - rtreeRename /* xRename - rename the table */ + rtreeRename, /* xRename - rename the table */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0 /* xRollbackTo */ }; static int rtreeSqlInit( diff --git a/manifest b/manifest index bd65c3d5e3..bd8d6e5ef2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ignore\smalloc\sfailures\swithin\sthe\sWAL\sfile\struncation\sattempt\sfor\njournal_size_limit. -D 2011-05-25T20:25:10.559 +C Fix\ssome\sminor\sand\sharmless\scompiler\swarnings. +D 2011-05-25T23:18:02.794 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -61,10 +61,10 @@ F ext/fts2/mkfts2amal.tcl 974d5d438cb3f7c4a652639262f82418c1e4cff0 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers 998756696647400de63d5ba60e9655036cb966e9 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 0a2ae110f2d1806687ee0de837ac1eff106843b4 +F ext/fts3/fts3.c b3a10a1a320aaeb56a1dd6710bf09eb5c2370839 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h c8c0011c5e5b3a7703376ea6cd7deb91cfb96a06 -F ext/fts3/fts3_aux.c 9e931f55eed8498dafe7bc1160f10cbb1a652fdf +F ext/fts3/fts3_aux.c 97c960b1b0d371c08eae6b8565dfac619eb9d979 F ext/fts3/fts3_expr.c 5f49e0deaf723724b08100bb3ff40aab02ad0c93 F ext/fts3/fts3_hash.c 3c8f6387a4a7f5305588b203fa7c887d753e1f1c F ext/fts3/fts3_hash.h 8331fb2206c609f9fc4c4735b9ab5ad6137c88ec @@ -82,7 +82,7 @@ F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9 F ext/icu/icu.c eb9ae1d79046bd7871aa97ee6da51eb770134b5a F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 2445bec932f58f8f4fe9de49a63bd6bf24db82d6 +F ext/rtree/rtree.c 4b8438444927191b55de18e00df43b2e02aacbda F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 28e1b8da4da98093ce3210187434dd760a8d89d8 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P d807304a695fc85402b86e1cd32a6e3bbb2823c8 -R 40f4c0754c95b7a51c08aa03886ff26c +P dd19105aa9521ffc0edcf16b84c064d5ebad55d7 +R 008aea5da6bfc4eb7e4a2c09eb3620eb U drh -Z c74bad4333e073e26c4db5e166f8f584 +Z e8c2f21e52caf9d88919dc2348e8bfe9 diff --git a/manifest.uuid b/manifest.uuid index f139bfb8f7..310e58b317 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dd19105aa9521ffc0edcf16b84c064d5ebad55d7 \ No newline at end of file +a4755e7088c3cc7c5ea191ce37f3950472f523ec \ No newline at end of file From 305ebab7cc7b12e17a502865a01c9d20658495fe Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 26 May 2011 14:19:14 +0000 Subject: [PATCH 06/30] Changes to work with SQLITE_OMIT_VIRTUAL_TABLE. FossilOrigin-Name: 03f7d36a8a24825b7542b5fed651af1622ae4eb5 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 2 ++ test/tkt-2d1a5c67d.test | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index bd8d6e5ef2..3f4e379ddd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\sminor\sand\sharmless\scompiler\swarnings. -D 2011-05-25T23:18:02.794 +C Changes\sto\swork\swith\sSQLITE_OMIT_VIRTUAL_TABLE. +D 2011-05-26T14:19:14.865 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -236,7 +236,7 @@ F src/update.c 5bcb56e5c7380a2eecb0e71891dbd4ad7437748f F src/utf.c d83650c3ea08f7407bd9d0839d9885241c209c60 F src/util.c 0f33bbbdfcc4a2d8cf20c3b2a16ffc3b57c58a70 F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e -F src/vdbe.c 4812f0e5813b3969307ec466d26d9b32b7b814e9 +F src/vdbe.c a8ff6724d4f1ca8c45ef778d67633d1fb4d9bdbf F src/vdbe.h 8a675fefdf7119441fe817c800a9a52440c2e797 F src/vdbeInt.h fe8f58d305e629fff02f61f655aca1d299f1f6ae F src/vdbeapi.c e0e2672e0a96ae3f8575c8ecd02912a3e8a554a1 @@ -705,7 +705,7 @@ F test/threadtest2.c ace893054fa134af3fc8d6e7cfecddb8e3acefb9 F test/threadtest3.c 0ed13e09690f6204d7455fac3b0e8ece490f6eef F test/tkt-02a8e81d44.test 58494de77be2cf249228ada3f313fa399821c6ab F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660 -F test/tkt-2d1a5c67d.test 450b3cf86ca9a3b1fd0a9e136978142be3bff7e0 +F test/tkt-2d1a5c67d.test 73574c758502bf23260c17f97fcd9316dfb5a060 F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28 F test/tkt-31338dca7e.test 5741cd48de500347a437ba1be58c8335e83c5a5e F test/tkt-313723c356.test c47f8a9330523e6f35698bf4489bcb29609b53ac @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P dd19105aa9521ffc0edcf16b84c064d5ebad55d7 -R 008aea5da6bfc4eb7e4a2c09eb3620eb +P a4755e7088c3cc7c5ea191ce37f3950472f523ec +R 730ee7bc721983cbb8520125b21bb17e U drh -Z e8c2f21e52caf9d88919dc2348e8bfe9 +Z d447764bdbeb7397b78d42ae4b389d7c diff --git a/manifest.uuid b/manifest.uuid index 310e58b317..ff053854df 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a4755e7088c3cc7c5ea191ce37f3950472f523ec \ No newline at end of file +03f7d36a8a24825b7542b5fed651af1622ae4eb5 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index add643f176..c55927e663 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2584,6 +2584,7 @@ case OP_Savepoint: { }else{ nName = sqlite3Strlen30(zName); +#ifdef SQLITE_OMIT_VIRTUAL_TABLE /* This call is Ok even if this savepoint is actually a transaction ** savepoint (and therefore should not prompt xSavepoint()) callbacks. ** If this is a transaction savepoint being opened, it is guaranteed @@ -2592,6 +2593,7 @@ case OP_Savepoint: { rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, db->nStatement+db->nSavepoint); if( rc!=SQLITE_OK ) goto abort_due_to_error; +#endif /* Create a new savepoint structure. */ pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+nName+1); diff --git a/test/tkt-2d1a5c67d.test b/test/tkt-2d1a5c67d.test index 5db364bd79..278e1d38bc 100644 --- a/test/tkt-2d1a5c67d.test +++ b/test/tkt-2d1a5c67d.test @@ -19,7 +19,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix tkt-2d1a5c67d -ifcapable !wal {finish_test; return} +ifcapable {!wal || !vtab} {finish_test; return} for {set ii 1} {$ii<=10} {incr ii} { do_test tkt-2d1a5c67d.1.$ii { From c97125eb72437be15c8499782bb00c786671cd4a Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 28 May 2011 15:53:07 +0000 Subject: [PATCH 07/30] Print a log message on each cache spill if compiled with SQLITE_LOG_CACHE_SPILL. FossilOrigin-Name: 5f15579f8ca747f0fa0a7867ceffc8c7b8f904e6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pcache.c | 7 +++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 3f4e379ddd..ef773de94f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\swork\swith\sSQLITE_OMIT_VIRTUAL_TABLE. -D 2011-05-26T14:19:14.865 +C Print\sa\slog\smessage\son\seach\scache\sspill\sif\scompiled\swith\nSQLITE_LOG_CACHE_SPILL. +D 2011-05-28T15:53:07.056 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -168,7 +168,7 @@ F src/os_win.c 218b899469e570d46eb8147c2383075f7c026230 F src/pager.c 120550e7ef01dafaa2cbb4a0528c0d87c8f12b41 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 -F src/pcache.c 09d38c44ab275db581f7a2f6ff8b9bc7f8c0faaa +F src/pcache.c 49e718c095810c6b3334e3a6d89970aceaddefce F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 F src/pcache1.c d548e31beafa792d1994b663a29a5303569efc4e F src/pragma.c 9e778decc3ee9bcaf88904b4a3b0a4360aaf0eab @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P a4755e7088c3cc7c5ea191ce37f3950472f523ec -R 730ee7bc721983cbb8520125b21bb17e +P 03f7d36a8a24825b7542b5fed651af1622ae4eb5 +R ecca10c4aa82cb4b740a494236bdb180 U drh -Z d447764bdbeb7397b78d42ae4b389d7c +Z 7233c15025f0530a32ecee3359d1f724 diff --git a/manifest.uuid b/manifest.uuid index ff053854df..42def11d4f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -03f7d36a8a24825b7542b5fed651af1622ae4eb5 \ No newline at end of file +5f15579f8ca747f0fa0a7867ceffc8c7b8f904e6 \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index 242f3071d9..f37511e9e4 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -253,6 +253,13 @@ int sqlite3PcacheFetch( } if( pPg ){ int rc; +#ifdef SQLITE_LOG_CACHE_SPILL + sqlite3_log(SQLITE_FULL, + "spill page %d making room for %d - cache used: %d/%d", + pPg->pgno, pgno, + sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), + pCache->nMax); +#endif rc = pCache->xStress(pCache->pStress, pPg); if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ return rc; From 21f80f0478ae4570dfd9f803fecd15a05abc5b54 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 28 May 2011 19:24:15 +0000 Subject: [PATCH 08/30] Fix a "#ifdef" from check-in [03f7d36a8a] that should have been "#ifndef". FossilOrigin-Name: edb865c35415f9553f8279028120f7b8de2bf7e2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ef773de94f..701dc47e95 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Print\sa\slog\smessage\son\seach\scache\sspill\sif\scompiled\swith\nSQLITE_LOG_CACHE_SPILL. -D 2011-05-28T15:53:07.056 +C Fix\sa\s"#ifdef"\sfrom\scheck-in\s[03f7d36a8a]\sthat\sshould\shave\sbeen\s"#ifndef". +D 2011-05-28T19:24:15.852 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -236,7 +236,7 @@ F src/update.c 5bcb56e5c7380a2eecb0e71891dbd4ad7437748f F src/utf.c d83650c3ea08f7407bd9d0839d9885241c209c60 F src/util.c 0f33bbbdfcc4a2d8cf20c3b2a16ffc3b57c58a70 F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e -F src/vdbe.c a8ff6724d4f1ca8c45ef778d67633d1fb4d9bdbf +F src/vdbe.c 380dddc404c1e4a9260a4194daa728b94ed102d7 F src/vdbe.h 8a675fefdf7119441fe817c800a9a52440c2e797 F src/vdbeInt.h fe8f58d305e629fff02f61f655aca1d299f1f6ae F src/vdbeapi.c e0e2672e0a96ae3f8575c8ecd02912a3e8a554a1 @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 03f7d36a8a24825b7542b5fed651af1622ae4eb5 -R ecca10c4aa82cb4b740a494236bdb180 +P 5f15579f8ca747f0fa0a7867ceffc8c7b8f904e6 +R a63903941bea8f77658823b8763468e2 U drh -Z 7233c15025f0530a32ecee3359d1f724 +Z 62e9bfe1cc7669e25feec8cecb39066d diff --git a/manifest.uuid b/manifest.uuid index 42def11d4f..60ef9e438e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5f15579f8ca747f0fa0a7867ceffc8c7b8f904e6 \ No newline at end of file +edb865c35415f9553f8279028120f7b8de2bf7e2 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index c55927e663..d28f73d1b1 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2584,7 +2584,7 @@ case OP_Savepoint: { }else{ nName = sqlite3Strlen30(zName); -#ifdef SQLITE_OMIT_VIRTUAL_TABLE +#ifndef SQLITE_OMIT_VIRTUAL_TABLE /* This call is Ok even if this savepoint is actually a transaction ** savepoint (and therefore should not prompt xSavepoint()) callbacks. ** If this is a transaction savepoint being opened, it is guaranteed From 1fbb230f90e150c3c42c294afc06eb32901193e5 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 30 May 2011 14:35:48 +0000 Subject: [PATCH 09/30] Make sure the P5 argument to the OP_VUpdate opcode is always set to a valid conflict resolution code. FossilOrigin-Name: e3350dbd9f472c27ea6bc872d85098ac89d874c7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/delete.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 701dc47e95..f9e0a1ae94 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\s"#ifdef"\sfrom\scheck-in\s[03f7d36a8a]\sthat\sshould\shave\sbeen\s"#ifndef". -D 2011-05-28T19:24:15.852 +C Make\ssure\sthe\sP5\sargument\sto\sthe\sOP_VUpdate\sopcode\sis\salways\sset\sto\sa\nvalid\sconflict\sresolution\scode. +D 2011-05-30T14:35:48.783 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -130,7 +130,7 @@ F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 7deec4534f3b5a0c3b4a4cbadf809d321f64f9c4 F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b -F src/delete.c 7a24fcc9a31664d145acb97ce56b6d9f249a25e4 +F src/delete.c cecc926c70783452f3e8eb452c728291ce1a0b21 F src/expr.c e3cf0957c6b8faaaf7386a3bc69e53c0dc9705be F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c a43ba8a005fb5efd1deeee06853e3a6120d46a91 @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 5f15579f8ca747f0fa0a7867ceffc8c7b8f904e6 -R a63903941bea8f77658823b8763468e2 +P edb865c35415f9553f8279028120f7b8de2bf7e2 +R 3b765e3c18f9b2a8d8763c389176a0b5 U drh -Z 62e9bfe1cc7669e25feec8cecb39066d +Z 3e70f15cebd9551500dd66c2327a7d64 diff --git a/manifest.uuid b/manifest.uuid index 60ef9e438e..f3911243ba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -edb865c35415f9553f8279028120f7b8de2bf7e2 \ No newline at end of file +e3350dbd9f472c27ea6bc872d85098ac89d874c7 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index e5389e2b6a..a2df773af8 100644 --- a/src/delete.c +++ b/src/delete.c @@ -401,6 +401,7 @@ void sqlite3DeleteFrom( const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); sqlite3VtabMakeWritable(pParse, pTab); sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB); + sqlite3VdbeChangeP5(v, OE_Abort); sqlite3MayAbort(pParse); }else #endif From f4b595b929449c03383f8c20d1929f284c960cc9 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 30 May 2011 15:06:48 +0000 Subject: [PATCH 10/30] Update evidence marks on the URI filename tests to conform to the latest documentation. FossilOrigin-Name: 1bab03c4811b5e5b3d15632bc2a3844891f9fad7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/e_uri.test | 18 ++++++++++-------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index f9e0a1ae94..207bb8d5bf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\sP5\sargument\sto\sthe\sOP_VUpdate\sopcode\sis\salways\sset\sto\sa\nvalid\sconflict\sresolution\scode. -D 2011-05-30T14:35:48.783 +C Update\sevidence\smarks\son\sthe\sURI\sfilename\stests\sto\sconform\sto\sthe\slatest\ndocumentation. +D 2011-05-30T15:06:48.453 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -380,7 +380,7 @@ F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6 F test/e_select.test bf385ae3aa0f014c4933ae66fd3e1302138493eb F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92 F test/e_update.test 963d6876064e65f318d1c93aaed36a02b9b389bf -F test/e_uri.test 9ce11319fb9b271bf7392027f913f7830e93e7a7 +F test/e_uri.test b6da43a10f44d9aa0aff5ffa3c2f3de668361255 F test/e_vacuum.test 6c09c2af7f2f140518f371c5342100118f779dcf F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398 @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P edb865c35415f9553f8279028120f7b8de2bf7e2 -R 3b765e3c18f9b2a8d8763c389176a0b5 +P e3350dbd9f472c27ea6bc872d85098ac89d874c7 +R 31eb4302622f868d251135572f646bae U drh -Z 3e70f15cebd9551500dd66c2327a7d64 +Z 47e43c01cd8d7b7136f7bc52a005ac53 diff --git a/manifest.uuid b/manifest.uuid index f3911243ba..45419984ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e3350dbd9f472c27ea6bc872d85098ac89d874c7 \ No newline at end of file +1bab03c4811b5e5b3d15632bc2a3844891f9fad7 \ No newline at end of file diff --git a/test/e_uri.test b/test/e_uri.test index b0e2f876de..3e47427941 100644 --- a/test/e_uri.test +++ b/test/e_uri.test @@ -48,10 +48,11 @@ proc open_uri_error {uri} { # and the filename argument begins with "file:", then the filename is # interpreted as a URI. # -# EVIDENCE-OF: R-00067-59538 URI filename interpretation is enabled if +# EVIDENCE-OF: R-32637-34037 URI filename interpretation is enabled if # the SQLITE_OPEN_URI flag is is set in the fourth argument to # sqlite3_open_v2(), or if it has been enabled globally using the -# SQLITE_CONFIG_URI option with the sqlite3_config() method. +# SQLITE_CONFIG_URI option with the sqlite3_config() method or by the +# SQLITE_USE_URI compile-time option. # if {$tcl_platform(platform) == "unix"} { set flags [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE] @@ -140,8 +141,8 @@ if {$tcl_platform(platform) == "unix"} { } } -# EVIDENCE-OF: R-43804-65312 The 'fragment' component of a URI, if -# present, is always ignored. +# EVIDENCE-OF: R-45981-25528 The fragment component of a URI, if +# present, is ignored. # # It is difficult to test that something is ignore correctly. So these tests # just show that adding a fragment does not interfere with the pathname or @@ -157,14 +158,15 @@ if {$tcl_platform(platform) == "unix"} { } } -# EVIDENCE-OF: R-00273-20588 SQLite uses the 'path' component of the URI -# as the path to the database file to open. +# EVIDENCE-OF: R-62557-09390 SQLite uses the path component of the URI +# as the name of the disk file which contains the database. # # EVIDENCE-OF: R-28659-11035 If the path begins with a '/' character, # then it is interpreted as an absolute path. # -# EVIDENCE-OF: R-39349-47203 If it does not begin with a '/', it is -# interpreted as a relative path. +# EVIDENCE-OF: R-46234-61323 If the path does not begin with a '/' +# (meaning that the authority section is omitted from the URI) then the +# path is interpreted as a relative path. # if {$tcl_platform(platform) == "unix"} { foreach {tn uri parse} " From c3f1d5f0958df10afadc10cd24ea1fb1d7003dfb Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 30 May 2011 23:42:16 +0000 Subject: [PATCH 11/30] Minor performance improvements. FossilOrigin-Name: f9950c6af1813f724dacd7455f472acec921b06a --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/btree.c | 6 ++++-- src/vdbe.c | 28 ++++++++++++++-------------- src/vdbeaux.c | 4 +++- 5 files changed, 30 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index 207bb8d5bf..b9205ae2bb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sevidence\smarks\son\sthe\sURI\sfilename\stests\sto\sconform\sto\sthe\slatest\ndocumentation. -D 2011-05-30T15:06:48.453 +C Minor\sperformance\simprovements. +D 2011-05-30T23:42:16.233 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -122,7 +122,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 975ad691a57eb1fb60f1ec76ad0b6571eace62f9 +F src/btree.c 0d3b39dcb79565c053e35fc12713f12d8a74d6a9 F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 F src/build.c 0132bc6631fa617a1d28ef805921f6dbac18a514 @@ -236,11 +236,11 @@ F src/update.c 5bcb56e5c7380a2eecb0e71891dbd4ad7437748f F src/utf.c d83650c3ea08f7407bd9d0839d9885241c209c60 F src/util.c 0f33bbbdfcc4a2d8cf20c3b2a16ffc3b57c58a70 F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e -F src/vdbe.c 380dddc404c1e4a9260a4194daa728b94ed102d7 +F src/vdbe.c 103827f560cdc48b1d455ce4d4b3573dd88f9ab4 F src/vdbe.h 8a675fefdf7119441fe817c800a9a52440c2e797 F src/vdbeInt.h fe8f58d305e629fff02f61f655aca1d299f1f6ae F src/vdbeapi.c e0e2672e0a96ae3f8575c8ecd02912a3e8a554a1 -F src/vdbeaux.c 07a5226ae6e9c6e54b5fcd3c395b86e7ffdba3a4 +F src/vdbeaux.c 99900868d18618a07ffaf780ecc41fd807834bde F src/vdbeblob.c c3ccb7c8732858c680f442932e66ad06bb036562 F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P e3350dbd9f472c27ea6bc872d85098ac89d874c7 -R 31eb4302622f868d251135572f646bae +P 1bab03c4811b5e5b3d15632bc2a3844891f9fad7 +R 7acb04adb38e3c88e3b1f83ed6f40a4e U drh -Z 47e43c01cd8d7b7136f7bc52a005ac53 +Z 9e474b54141fcb6c3097a32384090f3c diff --git a/manifest.uuid b/manifest.uuid index 45419984ac..58a05fb539 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1bab03c4811b5e5b3d15632bc2a3844891f9fad7 \ No newline at end of file +f9950c6af1813f724dacd7455f472acec921b06a \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index df75053743..972a2f608c 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5390,10 +5390,10 @@ static int fillInCell( ** "sz" must be the number of bytes in the cell. */ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ - int i; /* Loop counter */ u32 pc; /* Offset to cell content of cell being deleted */ u8 *data; /* pPage->aData */ u8 *ptr; /* Used to move bytes around within data[] */ + u8 *endPtr; /* End of loop */ int rc; /* The return code */ int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ @@ -5418,9 +5418,11 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ *pRC = rc; return; } - for(i=idx+1; inCell; i++, ptr+=2){ + endPtr = &data[pPage->cellOffset + 2*pPage->nCell - 2]; + while( ptrnCell--; put2byte(&data[hdr+3], pPage->nCell); diff --git a/src/vdbe.c b/src/vdbe.c index d28f73d1b1..eea6aba70e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1766,7 +1766,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ pIn3 = &aMem[pOp->p3]; flags1 = pIn1->flags; flags3 = pIn3->flags; - if( (pIn1->flags | pIn3->flags)&MEM_Null ){ + if( (flags1 | flags3)&MEM_Null ){ /* One or both operands are NULL */ if( pOp->p5 & SQLITE_NULLEQ ){ /* If SQLITE_NULLEQ is set (which will only happen if the operator is @@ -1774,7 +1774,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ ** or not both operands are null. */ assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); - res = (pIn1->flags & pIn3->flags & MEM_Null)==0; + res = (flags1 & flags3 & MEM_Null)==0; }else{ /* SQLITE_NULLEQ is clear and at least one operand is NULL, ** then the result is always NULL. @@ -5882,20 +5882,20 @@ case OP_MaxPgcnt: { /* out2-prerelease */ */ case OP_Trace: { char *zTrace; + char *z; - zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); - if( zTrace ){ - if( db->xTrace ){ - char *z = sqlite3VdbeExpandSql(p, zTrace); - db->xTrace(db->pTraceArg, z); - sqlite3DbFree(db, z); - } -#ifdef SQLITE_DEBUG - if( (db->flags & SQLITE_SqlTrace)!=0 ){ - sqlite3DebugPrintf("SQL-trace: %s\n", zTrace); - } -#endif /* SQLITE_DEBUG */ + if( db->xTrace && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ + z = sqlite3VdbeExpandSql(p, zTrace); + db->xTrace(db->pTraceArg, z); + sqlite3DbFree(db, z); } +#ifdef SQLITE_DEBUG + if( (db->flags & SQLITE_SqlTrace)!=0 + && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 + ){ + sqlite3DebugPrintf("SQL-trace: %s\n", zTrace); + } +#endif /* SQLITE_DEBUG */ break; } #endif diff --git a/src/vdbeaux.c b/src/vdbeaux.c index e9764a5096..0322b04c21 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2852,7 +2852,7 @@ UnpackedRecord *sqlite3VdbeRecordUnpack( idx += getVarint32(&aKey[idx], serial_type); pMem->enc = pKeyInfo->enc; pMem->db = pKeyInfo->db; - pMem->flags = 0; + /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */ pMem->zMalloc = 0; d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); pMem++; @@ -2867,6 +2867,7 @@ UnpackedRecord *sqlite3VdbeRecordUnpack( ** This routine destroys a UnpackedRecord object. */ void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){ +#ifdef SQLITE_DEBUG int i; Mem *pMem; @@ -2880,6 +2881,7 @@ void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){ */ if( NEVER(pMem->zMalloc) ) sqlite3VdbeMemRelease(pMem); } +#endif if( p->flags & UNPACKED_NEED_FREE ){ sqlite3DbFree(p->pKeyInfo->db, p); } From a80a141247a233e71d0adc29244096eebf3204f0 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 31 May 2011 11:56:15 +0000 Subject: [PATCH 12/30] Update the documentation to state that any parameter that is optimized out of a prepared statement becomes an anonymous parameter for which sqlite3_bind_parameter_name() returns NULL. FossilOrigin-Name: 701b8a23e3ea2c94454af5d9bd1e72acb66d0fe2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index b9205ae2bb..f7cee8fa4c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sperformance\simprovements. -D 2011-05-30T23:42:16.233 +C Update\sthe\sdocumentation\sto\sstate\sthat\sany\sparameter\sthat\sis\soptimized\sout\nof\sa\sprepared\sstatement\sbecomes\san\sanonymous\sparameter\sfor\swhich\nsqlite3_bind_parameter_name()\sreturns\sNULL. +D 2011-05-31T11:56:15.040 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -179,7 +179,7 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d9d440809025a58547e39f4f268c2a296bfb56ff F src/shell.c decd04236a7ef26be5ef46d4ea963044bfad9a48 -F src/sqlite.h.in 91c63a69eeddbd62182ec00dbfee390016972bdb +F src/sqlite.h.in c095996e68e0082f674f32e68ca909fc24196a2a F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 F src/sqliteInt.h d9ff5f198b5bac7ee0c6e1ea55f76897ba4dda87 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 1bab03c4811b5e5b3d15632bc2a3844891f9fad7 -R 7acb04adb38e3c88e3b1f83ed6f40a4e +P f9950c6af1813f724dacd7455f472acec921b06a +R f6b845f51167252cf7d20999b01d5085 U drh -Z 9e474b54141fcb6c3097a32384090f3c +Z 659dc0a03ae6f4d76444e7107181eaaf diff --git a/manifest.uuid b/manifest.uuid index 58a05fb539..6374f63920 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f9950c6af1813f724dacd7455f472acec921b06a \ No newline at end of file +701b8a23e3ea2c94454af5d9bd1e72acb66d0fe2 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 445a247a19..a9d60e8a2d 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3068,6 +3068,8 @@ int sqlite3_bind_parameter_count(sqlite3_stmt*); ** is included as part of the name.)^ ** ^Parameters of the form "?" without a following integer have no name ** and are referred to as "nameless" or "anonymous parameters". +** ^Any parameter that is optimized out of the prepared statement by the +** query planner becomes a nameless or anonymous parameter. ** ** ^The first host parameter has an index of 1, not 0. ** From ed9624187d89a96e591353a7bdee53b292e6f849 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 31 May 2011 16:50:23 +0000 Subject: [PATCH 13/30] Fix a problem in the sqlite3TestErrorName() function (used only for testing) that appears to have originated from a bad merge. FossilOrigin-Name: a0ae314c7f41d0146a9ee1adc576cd977219a378 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test1.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f7cee8fa4c..9323cd6b55 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sdocumentation\sto\sstate\sthat\sany\sparameter\sthat\sis\soptimized\sout\nof\sa\sprepared\sstatement\sbecomes\san\sanonymous\sparameter\sfor\swhich\nsqlite3_bind_parameter_name()\sreturns\sNULL. -D 2011-05-31T11:56:15.040 +C Fix\sa\sproblem\sin\sthe\ssqlite3TestErrorName()\sfunction\s(used\sonly\sfor\stesting)\nthat\sappears\sto\shave\soriginated\sfrom\sa\sbad\smerge. +D 2011-05-31T16:50:23.129 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -186,7 +186,7 @@ F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c 501c9a200fd998a268be475be5858febc90b725b -F src/test1.c 4a1171af201be90c21d64a872e686b1333d9a2cf +F src/test1.c 9f61b9d23938bc5dd165ec7b95a91c30ce6e66db F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7 @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P f9950c6af1813f724dacd7455f472acec921b06a -R f6b845f51167252cf7d20999b01d5085 +P 701b8a23e3ea2c94454af5d9bd1e72acb66d0fe2 +R 0252c62ef68072dedfcd687577c244b5 U drh -Z 659dc0a03ae6f4d76444e7107181eaaf +Z 32d78009c9e58634b2f842adf352a1be diff --git a/manifest.uuid b/manifest.uuid index 6374f63920..55d88bed1a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -701b8a23e3ea2c94454af5d9bd1e72acb66d0fe2 \ No newline at end of file +a0ae314c7f41d0146a9ee1adc576cd977219a378 \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index 50575afbbc..7d31c6d02a 100644 --- a/src/test1.c +++ b/src/test1.c @@ -164,7 +164,6 @@ const char *sqlite3TestErrorName(int rc){ zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break; case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break; - zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; default: zName = "SQLITE_Unknown"; break; } return zName; From 124c0b49a19ce24302c6594e60c80c7ba4df6c98 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 1 Jun 2011 18:15:55 +0000 Subject: [PATCH 14/30] Refactor the SQL parameter processing so that parameter names for values that are optimized out of the prepare statement are not forgotten. FossilOrigin-Name: b3aaf715b60b8a338cc6c92dad1ead4a3f7146a3 --- manifest | 30 +++---- manifest.uuid | 2 +- src/build.c | 4 +- src/expr.c | 86 +++++++++--------- src/sqlite.h.in | 2 - src/sqliteInt.h | 5 +- src/tokenize.c | 8 +- src/vdbe.h | 3 +- src/vdbeInt.h | 2 +- src/vdbeapi.c | 34 +------ src/vdbeaux.c | 229 ++++++++++++++++++++++++++---------------------- src/vdbeblob.c | 5 +- 12 files changed, 202 insertions(+), 208 deletions(-) diff --git a/manifest b/manifest index 9323cd6b55..b747a1409f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sthe\ssqlite3TestErrorName()\sfunction\s(used\sonly\sfor\stesting)\nthat\sappears\sto\shave\soriginated\sfrom\sa\sbad\smerge. -D 2011-05-31T16:50:23.129 +C Refactor\sthe\sSQL\sparameter\sprocessing\sso\sthat\sparameter\snames\sfor\svalues\nthat\sare\soptimized\sout\sof\sthe\sprepare\sstatement\sare\snot\sforgotten. +D 2011-06-01T18:15:55.858 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -125,13 +125,13 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 0d3b39dcb79565c053e35fc12713f12d8a74d6a9 F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 -F src/build.c 0132bc6631fa617a1d28ef805921f6dbac18a514 +F src/build.c c10ab9e2c77ade99dee23554787f8acfc0c231fc F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 7deec4534f3b5a0c3b4a4cbadf809d321f64f9c4 F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b F src/delete.c cecc926c70783452f3e8eb452c728291ce1a0b21 -F src/expr.c e3cf0957c6b8faaaf7386a3bc69e53c0dc9705be +F src/expr.c c33584bcf4ee011e28ff74e4dcef02da1dc09dd6 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c a43ba8a005fb5efd1deeee06853e3a6120d46a91 F src/func.c b9117e40975245b8504cf3625d7e321d8d4b63dc @@ -179,9 +179,9 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d9d440809025a58547e39f4f268c2a296bfb56ff F src/shell.c decd04236a7ef26be5ef46d4ea963044bfad9a48 -F src/sqlite.h.in c095996e68e0082f674f32e68ca909fc24196a2a +F src/sqlite.h.in 91c63a69eeddbd62182ec00dbfee390016972bdb F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 -F src/sqliteInt.h d9ff5f198b5bac7ee0c6e1ea55f76897ba4dda87 +F src/sqliteInt.h 6e58c558c57c8f44011736d5fa5295eb3130f9de F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -230,18 +230,18 @@ F src/test_vfs.c e7855568dfa1e0ba73668d273b65605d9f8b77e8 F src/test_vfstrace.c 0b884e06094a746da729119a2cabdc7aa790063d F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 -F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 +F src/tokenize.c 7b0c9281b2368dc69135e7a50bd271de9af1b467 F src/trigger.c 144cc18bb701f3286484aae4292a9531f09278c8 F src/update.c 5bcb56e5c7380a2eecb0e71891dbd4ad7437748f F src/utf.c d83650c3ea08f7407bd9d0839d9885241c209c60 F src/util.c 0f33bbbdfcc4a2d8cf20c3b2a16ffc3b57c58a70 F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e F src/vdbe.c 103827f560cdc48b1d455ce4d4b3573dd88f9ab4 -F src/vdbe.h 8a675fefdf7119441fe817c800a9a52440c2e797 -F src/vdbeInt.h fe8f58d305e629fff02f61f655aca1d299f1f6ae -F src/vdbeapi.c e0e2672e0a96ae3f8575c8ecd02912a3e8a554a1 -F src/vdbeaux.c 99900868d18618a07ffaf780ecc41fd807834bde -F src/vdbeblob.c c3ccb7c8732858c680f442932e66ad06bb036562 +F src/vdbe.h d9c6123384189dc37d27beac1bf44688aa75b6cb +F src/vdbeInt.h ad84226cc0adcb1185c22b70696b235a1678bb45 +F src/vdbeapi.c 0eeadc75e44a30efd996d6af6e7c5a2488e35be8 +F src/vdbeaux.c 0505dc4f7ff3cf35e219fe0a20ab798a42772b8b +F src/vdbeblob.c f024f0bf420f36b070143c32b15cc7287341ffd3 F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 F src/vtab.c 9ba8c7fdb7d39260c033a402f6032d3e7bc5d336 @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 701b8a23e3ea2c94454af5d9bd1e72acb66d0fe2 -R 0252c62ef68072dedfcd687577c244b5 +P a0ae314c7f41d0146a9ee1adc576cd977219a378 +R d99e1065a540709b7ea760de89dbcfd0 U drh -Z 32d78009c9e58634b2f842adf352a1be +Z ce5ce2791f47aa05a4daaafded206f56 diff --git a/manifest.uuid b/manifest.uuid index 55d88bed1a..4597483a7e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a0ae314c7f41d0146a9ee1adc576cd977219a378 \ No newline at end of file +b3aaf715b60b8a338cc6c92dad1ead4a3f7146a3 \ No newline at end of file diff --git a/src/build.c b/src/build.c index fa2d53a14b..afe2089325 100644 --- a/src/build.c +++ b/src/build.c @@ -200,9 +200,7 @@ void sqlite3FinishCoding(Parse *pParse){ /* A minimum of one cursor is required if autoincrement is used * See ticket [a696379c1f08866] */ if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; - sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem, - pParse->nTab, pParse->nMaxArg, pParse->explain, - pParse->isMultiWrite && pParse->mayAbort); + sqlite3VdbeMakeReady(v, pParse); pParse->rc = SQLITE_DONE; pParse->colNamesSet = 0; }else{ diff --git a/src/expr.c b/src/expr.c index c0e9ba6fd5..4cd2f24551 100644 --- a/src/expr.c +++ b/src/expr.c @@ -555,53 +555,53 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ /* Wildcard of the form "?". Assign the next variable number */ assert( z[0]=='?' ); pExpr->iColumn = (ynVar)(++pParse->nVar); - }else if( z[0]=='?' ){ - /* Wildcard of the form "?nnn". Convert "nnn" to an integer and - ** use it as the variable number */ - i64 i; - int bOk = 0==sqlite3Atoi64(&z[1], &i, sqlite3Strlen30(&z[1]), SQLITE_UTF8); - pExpr->iColumn = (ynVar)i; - testcase( i==0 ); - testcase( i==1 ); - testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); - testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); - if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ - sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", - db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); - } - if( i>pParse->nVar ){ - pParse->nVar = (int)i; - } }else{ - /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable - ** number as the prior appearance of the same name, or if the name - ** has never appeared before, reuse the same variable number - */ - int i; - u32 n; - n = sqlite3Strlen30(z); - for(i=0; inVarExpr; i++){ - Expr *pE = pParse->apVarExpr[i]; - assert( pE!=0 ); - if( memcmp(pE->u.zToken, z, n)==0 && pE->u.zToken[n]==0 ){ - pExpr->iColumn = pE->iColumn; - break; + ynVar x = 0; + u32 n = sqlite3Strlen30(z); + if( z[0]=='?' ){ + /* Wildcard of the form "?nnn". Convert "nnn" to an integer and + ** use it as the variable number */ + i64 i; + int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); + pExpr->iColumn = x = (ynVar)i; + testcase( i==0 ); + testcase( i==1 ); + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); + if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ + sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", + db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); + x = 0; } + if( i>pParse->nVar ){ + pParse->nVar = (int)i; + } + }else{ + /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable + ** number as the prior appearance of the same name, or if the name + ** has never appeared before, reuse the same variable number + */ + ynVar i; + for(i=0; inzVar; i++){ + if( pParse->azVar[i] && memcmp(pParse->azVar[i],z,n+1)==0 ){ + pExpr->iColumn = x = (ynVar)i+1; + break; + } + } + if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar); } - if( i>=pParse->nVarExpr ){ - pExpr->iColumn = (ynVar)(++pParse->nVar); - if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){ - pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10; - pParse->apVarExpr = - sqlite3DbReallocOrFree( - db, - pParse->apVarExpr, - pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) - ); + if( x>0 ){ + if( x>pParse->nzVar ){ + char **a; + a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0])); + if( a==0 ) return; /* Error reported through db->mallocFailed */ + pParse->azVar = a; + memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0])); + pParse->nzVar = x; } - if( !db->mallocFailed ){ - assert( pParse->apVarExpr!=0 ); - pParse->apVarExpr[pParse->nVarExpr++] = pExpr; + if( z[0]!='?' || pParse->azVar[x-1]==0 ){ + sqlite3DbFree(db, pParse->azVar[x-1]); + pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n); } } } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index a9d60e8a2d..445a247a19 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3068,8 +3068,6 @@ int sqlite3_bind_parameter_count(sqlite3_stmt*); ** is included as part of the name.)^ ** ^Parameters of the form "?" without a following integer have no name ** and are referred to as "nameless" or "anonymous parameters". -** ^Any parameter that is optimized out of the prepared statement by the -** query planner becomes a nameless or anonymous parameter. ** ** ^The first host parameter has an index of 1, not 0. ** diff --git a/src/sqliteInt.h b/src/sqliteInt.h index bba0b3c441..fd86158e00 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2230,9 +2230,8 @@ struct Parse { ** each recursion */ int nVar; /* Number of '?' variables seen in the SQL so far */ - int nVarExpr; /* Number of used slots in apVarExpr[] */ - int nVarExprAlloc; /* Number of allocated slots in apVarExpr[] */ - Expr **apVarExpr; /* Pointers to :aaa and $aaaa wildcard expressions */ + int nzVar; /* Number of available slots in azVar[] */ + char **azVar; /* Pointers to names of parameters */ Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ int nAlias; /* Number of aliased result set columns */ int nAliasAlloc; /* Number of allocated slots for aAlias[] */ diff --git a/src/tokenize.c b/src/tokenize.c index c624efdcc7..016a218262 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -412,9 +412,8 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ assert( pParse->pNewTable==0 ); assert( pParse->pNewTrigger==0 ); assert( pParse->nVar==0 ); - assert( pParse->nVarExpr==0 ); - assert( pParse->nVarExprAlloc==0 ); - assert( pParse->apVarExpr==0 ); + assert( pParse->nzVar==0 ); + assert( pParse->azVar==0 ); enableLookaside = db->lookaside.bEnabled; if( db->lookaside.pStart ) db->lookaside.bEnabled = 1; while( !db->mallocFailed && zSql[i]!=0 ){ @@ -508,7 +507,8 @@ abort_parse: } sqlite3DeleteTrigger(db, pParse->pNewTrigger); - sqlite3DbFree(db, pParse->apVarExpr); + for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]); + sqlite3DbFree(db, pParse->azVar); sqlite3DbFree(db, pParse->aAlias); while( pParse->pAinc ){ AutoincInfo *p = pParse->pAinc; diff --git a/src/vdbe.h b/src/vdbe.h index 43044533f3..56f9eb51ca 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -185,7 +185,7 @@ int sqlite3VdbeMakeLabel(Vdbe*); void sqlite3VdbeRunOnlyOnce(Vdbe*); void sqlite3VdbeDelete(Vdbe*); void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*); -void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int,int,int); +void sqlite3VdbeMakeReady(Vdbe*,Parse*); int sqlite3VdbeFinalize(Vdbe*); void sqlite3VdbeResolveLabel(Vdbe*, int); int sqlite3VdbeCurrentAddr(Vdbe*); @@ -194,6 +194,7 @@ int sqlite3VdbeCurrentAddr(Vdbe*); void sqlite3VdbeTrace(Vdbe*,FILE*); #endif void sqlite3VdbeResetStepResult(Vdbe*); +void sqlite3VdbeRewind(Vdbe*); int sqlite3VdbeReset(Vdbe*); void sqlite3VdbeSetNumCols(Vdbe*,int); int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 5e96c6f9ff..0aeb3af7a9 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -287,11 +287,11 @@ struct Vdbe { Mem *aVar; /* Values for the OP_Variable opcode. */ char **azVar; /* Name of variables */ ynVar nVar; /* Number of entries in aVar[] */ + ynVar nzVar; /* Number of entries in azVar[] */ u32 cacheCtr; /* VdbeCursor row cache generation counter */ int pc; /* The program counter */ int rc; /* Value to return */ u8 errorAction; /* Recovery action to do in case of an error */ - u8 okVar; /* True if azVar[] has been initialized */ u8 explain; /* True if EXPLAIN present on SQL command */ u8 changeCntOn; /* True to update the change-counter */ u8 expired; /* True if the VM needs to be recompiled */ diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 90baaccc68..5923a4c01f 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -102,7 +102,7 @@ int sqlite3_reset(sqlite3_stmt *pStmt){ Vdbe *v = (Vdbe*)pStmt; sqlite3_mutex_enter(v->db->mutex); rc = sqlite3VdbeReset(v); - sqlite3VdbeMakeReady(v, -1, 0, 0, 0, 0, 0); + sqlite3VdbeRewind(v); assert( (rc & (v->db->errMask))==rc ); rc = sqlite3ApiExit(v->db, rc); sqlite3_mutex_leave(v->db->mutex); @@ -1167,32 +1167,6 @@ int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ return p ? p->nVar : 0; } -/* -** Create a mapping from variable numbers to variable names -** in the Vdbe.azVar[] array, if such a mapping does not already -** exist. -*/ -static void createVarMap(Vdbe *p){ - if( !p->okVar ){ - int j; - Op *pOp; - sqlite3_mutex_enter(p->db->mutex); - /* The race condition here is harmless. If two threads call this - ** routine on the same Vdbe at the same time, they both might end - ** up initializing the Vdbe.azVar[] array. That is a little extra - ** work but it results in the same answer. - */ - for(j=0, pOp=p->aOp; jnOp; j++, pOp++){ - if( pOp->opcode==OP_Variable ){ - assert( pOp->p1>0 && pOp->p1<=p->nVar ); - p->azVar[pOp->p1-1] = pOp->p4.z; - } - } - p->okVar = 1; - sqlite3_mutex_leave(p->db->mutex); - } -} - /* ** Return the name of a wildcard parameter. Return NULL if the index ** is out of range or if the wildcard is unnamed. @@ -1201,10 +1175,9 @@ static void createVarMap(Vdbe *p){ */ const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ Vdbe *p = (Vdbe*)pStmt; - if( p==0 || i<1 || i>p->nVar ){ + if( p==0 || i<1 || i>p->nzVar ){ return 0; } - createVarMap(p); return p->azVar[i-1]; } @@ -1218,9 +1191,8 @@ int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){ if( p==0 ){ return 0; } - createVarMap(p); if( zName ){ - for(i=0; inVar; i++){ + for(i=0; inzVar; i++){ const char *z = p->azVar[i]; if( z && memcmp(z,zName,nName)==0 && z[nName]==0 ){ return i+1; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 0322b04c21..8181f01aa3 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1391,34 +1391,13 @@ static void *allocSpace( } /* -** Prepare a virtual machine for execution. This involves things such -** as allocating stack space and initializing the program counter. -** After the VDBE has be prepped, it can be executed by one or more -** calls to sqlite3VdbeExec(). -** -** This is the only way to move a VDBE from VDBE_MAGIC_INIT to -** VDBE_MAGIC_RUN. -** -** This function may be called more than once on a single virtual machine. -** The first call is made while compiling the SQL statement. Subsequent -** calls are made as part of the process of resetting a statement to be -** re-executed (from a call to sqlite3_reset()). The nVar, nMem, nCursor -** and isExplain parameters are only passed correct values the first time -** the function is called. On subsequent calls, from sqlite3_reset(), nVar -** is passed -1 and nMem, nCursor and isExplain are all passed zero. +** Rewind the VDBE back to the beginning in preparation for +** running it. */ -void sqlite3VdbeMakeReady( - Vdbe *p, /* The VDBE */ - int nVar, /* Number of '?' see in the SQL statement */ - int nMem, /* Number of memory cells to allocate */ - int nCursor, /* Number of cursors to allocate */ - int nArg, /* Maximum number of args in SubPrograms */ - int isExplain, /* True if the EXPLAIN keywords is present */ - int usesStmtJournal /* True to set Vdbe.usesStmtJournal */ -){ - int n; - sqlite3 *db = p->db; - +void sqlite3VdbeRewind(Vdbe *p){ +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) + int i; +#endif assert( p!=0 ); assert( p->magic==VDBE_MAGIC_INIT ); @@ -1429,6 +1408,71 @@ void sqlite3VdbeMakeReady( /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */ p->magic = VDBE_MAGIC_RUN; +#ifdef SQLITE_DEBUG + for(i=1; inMem; i++){ + assert( p->aMem[i].db==p->db ); + } +#endif + p->pc = -1; + p->rc = SQLITE_OK; + p->errorAction = OE_Abort; + p->magic = VDBE_MAGIC_RUN; + p->nChange = 0; + p->cacheCtr = 1; + p->minWriteFileFormat = 255; + p->iStatement = 0; + p->nFkConstraint = 0; +#ifdef VDBE_PROFILE + for(i=0; inOp; i++){ + p->aOp[i].cnt = 0; + p->aOp[i].cycles = 0; + } +#endif +} + +/* +** Prepare a virtual machine for execution for the first time after +** creating the virtual machine. This involves things such +** as allocating stack space and initializing the program counter. +** After the VDBE has be prepped, it can be executed by one or more +** calls to sqlite3VdbeExec(). +** +** This function may be called exact once on a each virtual machine. +** After this routine is called the VM has been "packaged" and is ready +** to run. After this routine is called, futher calls to +** sqlite3VdbeAddOp() functions are prohibited. This routine disconnects +** the Vdbe from the Parse object that helped generate it so that the +** the Vdbe becomes an independent entity and the Parse object can be +** destroyed. +** +** Use the sqlite3VdbeRewind() procedure to restore a virtual machine back +** to its initial state after it has been run. +*/ +void sqlite3VdbeMakeReady( + Vdbe *p, /* The VDBE */ + Parse *pParse /* Parsing context */ +){ + sqlite3 *db; /* The database connection */ + int nVar; /* Number of parameters */ + int nMem; /* Number of VM memory registers */ + int nCursor; /* Number of cursors required */ + int nArg; /* Number of arguments in subprograms */ + int n; /* Loop counter */ + u8 *zCsr; /* Memory available for allocation */ + u8 *zEnd; /* First byte past allocated memory */ + int nByte; /* How much extra memory is needed */ + + assert( p!=0 ); + assert( p->nOp>0 ); + assert( pParse!=0 ); + assert( p->magic==VDBE_MAGIC_INIT ); + db = p->db; + assert( db->mallocFailed==0 ); + nVar = pParse->nVar; + nMem = pParse->nMem; + nCursor = pParse->nTab; + nArg = pParse->nMaxArg; + /* For each cursor required, also allocate a memory cell. Memory ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by ** the vdbe program. Instead they are used to allocate space for @@ -1441,91 +1485,68 @@ void sqlite3VdbeMakeReady( nMem += nCursor; /* Allocate space for memory registers, SQL variables, VDBE cursors and - ** an array to marshal SQL function arguments in. This is only done the - ** first time this function is called for a given VDBE, not when it is - ** being called from sqlite3_reset() to reset the virtual machine. + ** an array to marshal SQL function arguments in. */ - if( nVar>=0 && ALWAYS(db->mallocFailed==0) ){ - u8 *zCsr = (u8 *)&p->aOp[p->nOp]; /* Memory avaliable for alloation */ - u8 *zEnd = (u8 *)&p->aOp[p->nOpAlloc]; /* First byte past available mem */ - int nByte; /* How much extra memory needed */ + zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */ + zEnd = (u8*)&p->aOp[p->nOpAlloc]; /* First byte past end of zCsr[] */ - resolveP2Values(p, &nArg); - p->usesStmtJournal = (u8)usesStmtJournal; - if( isExplain && nMem<10 ){ - nMem = 10; + resolveP2Values(p, &nArg); + p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); + if( pParse->explain && nMem<10 ){ + nMem = 10; + } + memset(zCsr, 0, zEnd-zCsr); + zCsr += (zCsr - (u8*)0)&7; + assert( EIGHT_BYTE_ALIGNMENT(zCsr) ); + + /* Memory for registers, parameters, cursor, etc, is allocated in two + ** passes. On the first pass, we try to reuse unused space at the + ** end of the opcode array. If we are unable to satisfy all memory + ** requirements by reusing the opcode array tail, then the second + ** pass will fill in the rest using a fresh allocation. + ** + ** This two-pass approach that reuses as much memory as possible from + ** the leftover space at the end of the opcode array can significantly + ** reduce the amount of memory held by a prepared statement. + */ + do { + nByte = 0; + p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte); + p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte); + p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte); + p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte); + p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), + &zCsr, zEnd, &nByte); + if( nByte ){ + p->pFree = sqlite3DbMallocZero(db, nByte); } - memset(zCsr, 0, zEnd-zCsr); - zCsr += (zCsr - (u8*)0)&7; - assert( EIGHT_BYTE_ALIGNMENT(zCsr) ); + zCsr = p->pFree; + zEnd = &zCsr[nByte]; + }while( nByte && !db->mallocFailed ); - /* Memory for registers, parameters, cursor, etc, is allocated in two - ** passes. On the first pass, we try to reuse unused space at the - ** end of the opcode array. If we are unable to satisfy all memory - ** requirements by reusing the opcode array tail, then the second - ** pass will fill in the rest using a fresh allocation. - ** - ** This two-pass approach that reuses as much memory as possible from - ** the leftover space at the end of the opcode array can significantly - ** reduce the amount of memory held by a prepared statement. - */ - do { - nByte = 0; - p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte); - p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte); - p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte); - p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte); - p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), - &zCsr, zEnd, &nByte); - if( nByte ){ - p->pFree = sqlite3DbMallocZero(db, nByte); - } - zCsr = p->pFree; - zEnd = &zCsr[nByte]; - }while( nByte && !db->mallocFailed ); - - p->nCursor = (u16)nCursor; - if( p->aVar ){ - p->nVar = (ynVar)nVar; - for(n=0; naVar[n].flags = MEM_Null; - p->aVar[n].db = db; - } - } - if( p->aMem ){ - p->aMem--; /* aMem[] goes from 1..nMem */ - p->nMem = nMem; /* not from 0..nMem-1 */ - for(n=1; n<=nMem; n++){ - p->aMem[n].flags = MEM_Null; - p->aMem[n].db = db; - } + p->nCursor = (u16)nCursor; + if( p->aVar ){ + p->nVar = (ynVar)nVar; + for(n=0; naVar[n].flags = MEM_Null; + p->aVar[n].db = db; } } -#ifdef SQLITE_DEBUG - for(n=1; nnMem; n++){ - assert( p->aMem[n].db==db ); + if( p->azVar ){ + p->nzVar = pParse->nzVar; + memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0])); + memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0])); } -#endif - - p->pc = -1; - p->rc = SQLITE_OK; - p->errorAction = OE_Abort; - p->explain |= isExplain; - p->magic = VDBE_MAGIC_RUN; - p->nChange = 0; - p->cacheCtr = 1; - p->minWriteFileFormat = 255; - p->iStatement = 0; - p->nFkConstraint = 0; -#ifdef VDBE_PROFILE - { - int i; - for(i=0; inOp; i++){ - p->aOp[i].cnt = 0; - p->aOp[i].cycles = 0; + if( p->aMem ){ + p->aMem--; /* aMem[] goes from 1..nMem */ + p->nMem = nMem; /* not from 0..nMem-1 */ + for(n=1; n<=nMem; n++){ + p->aMem[n].flags = MEM_Null; + p->aMem[n].db = db; } } -#endif + p->explain = pParse->explain; + sqlite3VdbeRewind(p); } /* @@ -2399,6 +2420,7 @@ void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){ */ void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){ SubProgram *pSub, *pNext; + int i; assert( p->db==0 || p->db==db ); releaseMemArray(p->aVar, p->nVar); releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); @@ -2407,6 +2429,7 @@ void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){ vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); sqlite3DbFree(db, pSub); } + for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]); vdbeFreeOpArray(db, p->aOp, p->nOp); sqlite3DbFree(db, p->aLabel); sqlite3DbFree(db, p->aColName); diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 18fdd465ae..a8728e6d25 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -297,7 +297,10 @@ int sqlite3_blob_open( sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32); sqlite3VdbeChangeP2(v, 7, pTab->nCol); if( !db->mallocFailed ){ - sqlite3VdbeMakeReady(v, 1, 1, 1, 0, 0, 0); + pParse->nVar = 1; + pParse->nMem = 1; + pParse->nTab = 1; + sqlite3VdbeMakeReady(v, pParse); } } From 04e9eeadc63bb651a658150e0529cd3463914690 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 1 Jun 2011 19:16:06 +0000 Subject: [PATCH 15/30] Avoid unnecessary duplication of SQL parameter names. FossilOrigin-Name: e704e8690ae35decc9769a45cf8d519ccad8b79d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 4 +++- src/vdbe.c | 1 + 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index b747a1409f..9e6489e647 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sthe\sSQL\sparameter\sprocessing\sso\sthat\sparameter\snames\sfor\svalues\nthat\sare\soptimized\sout\sof\sthe\sprepare\sstatement\sare\snot\sforgotten. -D 2011-06-01T18:15:55.858 +C Avoid\sunnecessary\sduplication\sof\sSQL\sparameter\snames. +D 2011-06-01T19:16:06.364 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -131,7 +131,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 7deec4534f3b5a0c3b4a4cbadf809d321f64f9c4 F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b F src/delete.c cecc926c70783452f3e8eb452c728291ce1a0b21 -F src/expr.c c33584bcf4ee011e28ff74e4dcef02da1dc09dd6 +F src/expr.c ab46ab0f0c44979a8164ca31728d7d10ae5e8106 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c a43ba8a005fb5efd1deeee06853e3a6120d46a91 F src/func.c b9117e40975245b8504cf3625d7e321d8d4b63dc @@ -236,7 +236,7 @@ F src/update.c 5bcb56e5c7380a2eecb0e71891dbd4ad7437748f F src/utf.c d83650c3ea08f7407bd9d0839d9885241c209c60 F src/util.c 0f33bbbdfcc4a2d8cf20c3b2a16ffc3b57c58a70 F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e -F src/vdbe.c 103827f560cdc48b1d455ce4d4b3573dd88f9ab4 +F src/vdbe.c 2ec37637fa70ab0c694d8327ee5dcedbc0621524 F src/vdbe.h d9c6123384189dc37d27beac1bf44688aa75b6cb F src/vdbeInt.h ad84226cc0adcb1185c22b70696b235a1678bb45 F src/vdbeapi.c 0eeadc75e44a30efd996d6af6e7c5a2488e35be8 @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P a0ae314c7f41d0146a9ee1adc576cd977219a378 -R d99e1065a540709b7ea760de89dbcfd0 +P b3aaf715b60b8a338cc6c92dad1ead4a3f7146a3 +R 018490a374b5cf414074a5a4bbd3de70 U drh -Z ce5ce2791f47aa05a4daaafded206f56 +Z dcf10ad87997753baf45956f9011da61 diff --git a/manifest.uuid b/manifest.uuid index 4597483a7e..de373954a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b3aaf715b60b8a338cc6c92dad1ead4a3f7146a3 \ No newline at end of file +e704e8690ae35decc9769a45cf8d519ccad8b79d \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 4cd2f24551..be2f4d7c66 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2345,7 +2345,9 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ assert( pExpr->u.zToken[0]!=0 ); sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); if( pExpr->u.zToken[1]!=0 ){ - sqlite3VdbeChangeP4(v, -1, pExpr->u.zToken, P4_TRANSIENT); + assert( pExpr->u.zToken[0]=='?' + || strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 ); + sqlite3VdbeChangeP4(v, -1, pParse->azVar[pExpr->iColumn-1], P4_STATIC); } break; } diff --git a/src/vdbe.c b/src/vdbe.c index eea6aba70e..439fe72540 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -988,6 +988,7 @@ case OP_Variable: { /* out2-prerelease */ Mem *pVar; /* Value being transferred */ assert( pOp->p1>0 && pOp->p1<=p->nVar ); + assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] ); pVar = &p->aVar[pOp->p1 - 1]; if( sqlite3VdbeMemTooBig(pVar) ){ goto too_big; From 66dfec8b7a6052d4b639e5ab1910249aebb8828d Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 1 Jun 2011 20:01:49 +0000 Subject: [PATCH 16/30] Simplify the wal-readonly branch so that it does not require changes to anything other than os_unix.c and wal.c and a couple of new error codes. FossilOrigin-Name: d6b4709de4d1f8af001f58938247f00a652a616e --- manifest | 30 ++++++++++----------- manifest.uuid | 2 +- src/attach.c | 6 ++--- src/btree.h | 1 - src/main.c | 18 ++----------- src/os_unix.c | 69 ++++++++++++++++++++----------------------------- src/pager.c | 7 ++--- src/pager.h | 1 - src/sqlite.h.in | 41 +---------------------------- src/sqliteInt.h | 2 +- src/wal.c | 62 ++++++++++++++------------------------------ src/wal.h | 4 +-- 12 files changed, 74 insertions(+), 169 deletions(-) diff --git a/manifest b/manifest index b3a84d3a3f..8b6e11236e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Pull\sthe\slatest\strunk\schanges\sinto\sthe\swal-readonly\sbranch. -D 2011-06-01T19:44:57.308 +C Simplify\sthe\swal-readonly\sbranch\sso\sthat\sit\sdoes\snot\srequire\schanges\sto\nanything\sother\sthan\sos_unix.c\sand\swal.c\sand\sa\scouple\sof\snew\serror\scodes. +D 2011-06-01T20:01:49.650 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -117,13 +117,13 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c 280f5c04b11b492703a342222b3de0a999445280 F src/analyze.c a425d62e8fa9ebcb4359ab84ff0c62c6563d2e2a -F src/attach.c a87bfb77a720f7aa02791434aacfd9bc8feb50cc +F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 0d3b39dcb79565c053e35fc12713f12d8a74d6a9 -F src/btree.h d796dc4030b3cce7f5a0cc4f2f986d2befa6b8ac +F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 F src/build.c c10ab9e2c77ade99dee23554787f8acfc0c231fc F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a @@ -144,7 +144,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e F src/loadext.c 3ae0d52da013a6326310655be6473fd472347b85 -F src/main.c 4e55ff4800181e3ad063492740f54ce406de5deb +F src/main.c 059daeed5876b3604f0192f838faf5f4db138901 F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206 @@ -163,10 +163,10 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c af3c3f6a0fc6dbde802e55848f1cad7fb2121ff3 +F src/os_unix.c a59c0718021934157f235468788c793cbc0d53de F src/os_win.c 218b899469e570d46eb8147c2383075f7c026230 -F src/pager.c 2cf3bad86e6fbac42d9dbd3b89799185a343b17b -F src/pager.h 34c6b029446f06f40847746d22faac0d354dd909 +F src/pager.c 120550e7ef01dafaa2cbb4a0528c0d87c8f12b41 +F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 F src/pcache.c 49e718c095810c6b3334e3a6d89970aceaddefce F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 @@ -179,9 +179,9 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d9d440809025a58547e39f4f268c2a296bfb56ff F src/shell.c decd04236a7ef26be5ef46d4ea963044bfad9a48 -F src/sqlite.h.in dbe88418628302c0a93671a216346acb5746211a +F src/sqlite.h.in 2f51e4f58b2b4626fcbd9938580e730cb5fb4985 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 -F src/sqliteInt.h 219b21e80f46eef7cc7bb7477c12de61d00f5607 +F src/sqliteInt.h 6e58c558c57c8f44011736d5fa5295eb3130f9de F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -245,8 +245,8 @@ F src/vdbeblob.c f024f0bf420f36b070143c32b15cc7287341ffd3 F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 F src/vtab.c 9ba8c7fdb7d39260c033a402f6032d3e7bc5d336 -F src/wal.c 861ea98779dac3867e5f97d13e61cbbb39b310b0 -F src/wal.h 0835021ae243c2f1119e997e8af5d8cc3b991de1 +F src/wal.c fd63d07233203dd3bd29cbe1ae5c8bb2c34e08fc +F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c 55403ce19c506be6a321c7f129aff693d6103db5 F test/8_3_names.test b93687beebd17f6ebf812405a6833bae5d1f4199 @@ -939,7 +939,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 2c6b5a28e3f6b7cb96b944d0a254f3707885f1ce e704e8690ae35decc9769a45cf8d519ccad8b79d -R 5f4edf2ff77d011b562e3dc234f8f21d +P 0b63b71357a65e26ecd3f3bb34a5f14feee322f4 +R 20a045d8e6470f5f17b67b2f15ff8859 U drh -Z 99212444a62258034d706d358ee0a50e +Z f7b3b70c555e3fb5f3360ed8e60c2877 diff --git a/manifest.uuid b/manifest.uuid index 70ad59250f..6f393899aa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0b63b71357a65e26ecd3f3bb34a5f14feee322f4 \ No newline at end of file +d6b4709de4d1f8af001f58938247f00a652a616e \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 4b8ea77917..18f8823b31 100644 --- a/src/attach.c +++ b/src/attach.c @@ -76,8 +76,6 @@ static void attachFunc( Db *aNew; char *zErrDyn = 0; sqlite3_vfs *pVfs; - const char *zVfs = db->pVfs->zName; /* Name of default (main) VFS */ - int btflags = 0; UNUSED_PARAMETER(NotUsed); @@ -131,7 +129,7 @@ static void attachFunc( ** or may not be initialised. */ flags = db->openFlags; - rc = sqlite3ParseUri(zVfs, zFile, &flags, &btflags, &pVfs, &zPath, &zErr); + rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; sqlite3_result_error(context, zErr, -1); @@ -140,7 +138,7 @@ static void attachFunc( } assert( pVfs ); flags |= SQLITE_OPEN_MAIN_DB; - rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, btflags, flags); + rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, 0, flags); sqlite3_free( zPath ); db->nDb++; if( rc==SQLITE_CONSTRAINT ){ diff --git a/src/btree.h b/src/btree.h index c5abc9c865..9e3a73b3b6 100644 --- a/src/btree.h +++ b/src/btree.h @@ -61,7 +61,6 @@ int sqlite3BtreeOpen( #define BTREE_MEMORY 4 /* This is an in-memory DB */ #define BTREE_SINGLE 8 /* The file contains at most 1 b-tree */ #define BTREE_UNORDERED 16 /* Use of a hash implementation is OK */ -#define BTREE_READONLYSHM 32 /* Read-only SHM access is acceptable */ int sqlite3BtreeClose(Btree*); int sqlite3BtreeSetCacheSize(Btree*,int); diff --git a/src/main.c b/src/main.c index cdd54b659d..c99d396546 100644 --- a/src/main.c +++ b/src/main.c @@ -1803,11 +1803,6 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ ** *pFlags may be updated before returning if the URI filename contains ** "cache=xxx" or "mode=xxx" query parameters. ** -** The third argument, pBtflags, points to an integer containing the flags -** that will be passed as the 5th argument to sqlite3BtreeOpen (BTREE_XXX -** flags). This value will be edited if the URI filename contains a -** "readonly_shm=1" or "readonly_shm=0" query parameter. -** ** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to ** the VFS that should be used to open the database file. *pzFile is set to ** point to a buffer containing the name of the file to open. It is the @@ -1823,7 +1818,6 @@ int sqlite3ParseUri( const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */ const char *zUri, /* Nul-terminated URI to parse */ unsigned int *pFlags, /* IN/OUT: SQLITE_OPEN_XXX flags */ - int *pBtflags, /* IN/OUT: BTREE_XXX flags */ sqlite3_vfs **ppVfs, /* OUT: VFS to use */ char **pzFile, /* OUT: Filename component of URI */ char **pzErrMsg /* OUT: Error message (if rc!=SQLITE_OK) */ @@ -1939,12 +1933,6 @@ int sqlite3ParseUri( if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){ zVfs = zVal; - }else if( nOpt==12 && memcmp("readonly_shm", zOpt, 12)==0 ){ - if( sqlite3Atoi(zVal) ){ - *pBtflags |= BTREE_READONLYSHM; - }else{ - *pBtflags &= ~BTREE_READONLYSHM; - } }else{ struct OpenMode { const char *z; @@ -2048,7 +2036,6 @@ static int openDatabase( int isThreadsafe; /* True for threadsafe connections */ char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */ char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */ - int btflags = 0; /* Mask of BTREE_XXX flags */ *ppDb = 0; #ifndef SQLITE_OMIT_AUTOINIT @@ -2177,8 +2164,7 @@ static int openDatabase( /* Parse the filename/URI argument. */ db->openFlags = flags; - rc = sqlite3ParseUri( - zVfs, zFilename, &flags, &btflags, &db->pVfs, &zOpen, &zErrMsg); + rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; sqlite3Error(db, rc, zErrMsg ? "%s" : 0, zErrMsg); @@ -2187,7 +2173,7 @@ static int openDatabase( } /* Open the backend database driver */ - rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, btflags, + rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0, flags | SQLITE_OPEN_MAIN_DB); if( rc!=SQLITE_OK ){ if( rc==SQLITE_IOERR_NOMEM ){ diff --git a/src/os_unix.c b/src/os_unix.c index 947f431aeb..e6d1774a49 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -212,7 +212,6 @@ struct unixFile { UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ - int readOnlyShm; /* True to open shared-memory read-only */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ #if SQLITE_ENABLE_LOCKING_STYLE int openFlags; /* The flags specified at open() */ @@ -3453,10 +3452,6 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ case SQLITE_FCNTL_SIZE_HINT: { return fcntlSizeHint((unixFile *)id, *(i64 *)pArg); } - case SQLITE_FCNTL_READONLY_SHM: { - ((unixFile*)id)->readOnlyShm = (pArg!=0); - return SQLITE_OK; - } #ifndef NDEBUG /* The pager calls this method to signal that it has done ** a rollback and that the database is therefore unchanged and @@ -3542,11 +3537,11 @@ struct unixShmNode { char *zFilename; /* Name of the mmapped file */ int h; /* Open file descriptor */ int szRegion; /* Size of shared-memory regions */ - int nRegion; /* Size of array apRegion */ + u16 nRegion; /* Size of array apRegion */ + u8 isReadonly; /* True if read-only */ char **apRegion; /* Array of mapped shared-memory regions */ int nRef; /* Number of unixShm objects pointing to this */ unixShm *pFirst; /* All unixShm objects pointing to this */ - u8 readOnly; /* True if this is a read-only mapping */ #ifdef SQLITE_DEBUG u8 exclMask; /* Mask of exclusive locks held */ u8 sharedMask; /* Mask of shared locks held */ @@ -3787,48 +3782,38 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ } if( pInode->bProcessLock==0 ){ - int flags = (pDbFd->readOnlyShm ? O_RDONLY : O_RDWR|O_CREAT); - pShmNode->h = robust_open(zShmFilename, flags, (sStat.st_mode & 0777)); + pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT, + (sStat.st_mode & 0777)); if( pShmNode->h<0 ){ - rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); - goto shm_open_err; + const char *zRO; + zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm"); + if( zRO && (zRO[0]!='0' || zRO[1]!=0) ){ + pShmNode->h = robust_open(zShmFilename, O_RDONLY, + (sStat.st_mode & 0777)); + pShmNode->isReadonly = 1; + } + if( pShmNode->h<0 ){ + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); + goto shm_open_err; + } } - pShmNode->readOnly = pDbFd->readOnlyShm; /* Check to see if another process is holding the dead-man switch. - ** If not, zero the first few bytes of the shared-memory file to make - ** sure it is not mistaken for valid by code in wal.c. Except, if this - ** is a read-only connection to the shared-memory then it is not possible - ** to check check if another process is holding a read-lock on the DMS - ** byte, as we cannot attempt a write-lock via a read-only file - ** descriptor. So in this case, we just assume the shared-memory - ** contents are Ok and proceed. */ - if( pShmNode->readOnly==0 ){ - rc = SQLITE_OK; - if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ - if( pDbFd->readOnlyShm ){ - rc = SQLITE_IOERR_SHMOPEN; - }else if( 4!=osWrite(pShmNode->h, "\00\00\00\00", 4) ){ - rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); - } + ** If not, truncate the file to zero length. + */ + rc = SQLITE_OK; + if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ + if( robust_ftruncate(pShmNode->h, 0) ){ + rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); } - if( rc==SQLITE_OK ){ - rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); - } - if( rc ) goto shm_open_err; } + if( rc==SQLITE_OK ){ + rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); + } + if( rc ) goto shm_open_err; } } - /* If the unixShmNode is read-only, but SQLITE_FCNTL_READONLY_SHM has not - ** been set for file-descriptor pDbFd, return an error. The wal.c module - ** will then call this function again with SQLITE_FCNTL_READONLY_SHM set. - */ - else if( pShmNode->readOnly && !pDbFd->readOnlyShm ){ - rc = SQLITE_IOERR_SHMOPEN; - goto shm_open_err; - } - /* Make the new connection a child of the unixShmNode */ p->pShmNode = pShmNode; #ifdef SQLITE_DEBUG @@ -3949,7 +3934,8 @@ static int unixShmMap( while(pShmNode->nRegion<=iRegion){ void *pMem; if( pShmNode->h>=0 ){ - pMem = mmap(0, szRegion, PROT_READ|(!pShmNode->readOnly?PROT_WRITE:0), + pMem = mmap(0, szRegion, + pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion ); if( pMem==MAP_FAILED ){ @@ -3975,6 +3961,7 @@ shmpage_out: }else{ *pp = 0; } + if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; sqlite3_mutex_leave(pShmNode->mutex); return rc; } diff --git a/src/pager.c b/src/pager.c index 461c735432..7ff9a9a000 100644 --- a/src/pager.c +++ b/src/pager.c @@ -620,7 +620,6 @@ struct Pager { u8 tempFile; /* zFilename is a temporary file */ u8 readOnly; /* True for a read-only database */ u8 memDb; /* True to inhibit all file I/O */ - u8 readOnlyShm; /* True if read-only shm access is Ok */ /************************************************************************** ** The following block contains those class members that change during @@ -3018,7 +3017,6 @@ static int pagerWalFrames( static int pagerBeginReadTransaction(Pager *pPager){ int rc; /* Return code */ int changed = 0; /* True if cache must be reset */ - Wal *pWal = pPager->pWal; assert( pagerUseWal(pPager) ); assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); @@ -3028,9 +3026,9 @@ static int pagerBeginReadTransaction(Pager *pPager){ ** are in locking_mode=NORMAL and EndRead() was previously called, ** the duplicate call is harmless. */ - sqlite3WalEndReadTransaction(pWal); + sqlite3WalEndReadTransaction(pPager->pWal); - rc = sqlite3WalBeginReadTransaction(pWal, pPager->readOnlyShm, &changed); + rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed); if( rc!=SQLITE_OK || changed ){ pager_reset(pPager); } @@ -4418,7 +4416,6 @@ int sqlite3PagerOpen( } pPager->pVfs = pVfs; pPager->vfsFlags = vfsFlags; - pPager->readOnlyShm = (flags & PAGER_READONLYSHM)!=0; /* Open the pager file. */ diff --git a/src/pager.h b/src/pager.h index c6cb8bcb55..eab7ddaf80 100644 --- a/src/pager.h +++ b/src/pager.h @@ -60,7 +60,6 @@ typedef struct PgHdr DbPage; #define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */ #define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */ #define PAGER_MEMORY 0x0004 /* In-memory database */ -#define PAGER_READONLYSHM 0x0020 /* Read-only SHM access is acceptable */ /* ** Valid values for the second argument to sqlite3PagerLockingMode(). diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 45aec0e1c2..593e9148fe 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -454,7 +454,6 @@ int sqlite3_exec( #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) - #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) @@ -737,27 +736,6 @@ struct sqlite3_io_methods { ** Applications should not call [sqlite3_file_control()] with this ** opcode as doing so may disrupt the operation of the specialized VFSes ** that do require it. -** -** The [SQLITE_FCNTL_READONLY_SHM] may be generated internally by SQLite if -** the "readonly_shm=1" URI option is specified when the database is opened. -** The fourth argument passed to the VFS xFileControl methods is a pointer -** to a variable of type "int" containing the value 1 or 0. If the variable -** contains the value 1, then this indicates to the VFS that a read-only -** mapping of the shared-memory region is acceptable. If it is set to 0, then -** this indicates that a read-write mapping is required (as normal). If -** a read-only mapping is returned, then the VFS may also return read-only -** mappings for any subsequent requests via the same file-descriptor - -** regardless of the value most recently configured using -** SQLITE_FCNTL_READONLY_SHM. -** -** In practice, if "readonly_shm=1" is specified and the first attempt to -** map a shared-memory region fails, then this file-control is invoked with -** the argument variable set to 1 and a second attempt to map the shared-memory -** region is made. If this mapping succeeds, then the connection continues -** with the read-only mapping. Otherwise, if it fails, SQLITE_CANTOPEN is -** returned to the caller. Whether or not the second (read-only) mapping -** attempt succeeds, the file-control is invoked again with the argument -** variable set to 0. */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_GET_LOCKPROXYFILE 2 @@ -767,7 +745,6 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_CHUNK_SIZE 6 #define SQLITE_FCNTL_FILE_POINTER 7 #define SQLITE_FCNTL_SYNC_OMITTED 8 -#define SQLITE_FCNTL_READONLY_SHM 9 /* @@ -2481,7 +2458,7 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** [[core URI query parameters]] ** The query component of a URI may contain parameters that are interpreted ** either by SQLite itself, or by a [VFS | custom VFS implementation]. -** SQLite interprets the following four query parameters: +** SQLite interprets the following three query parameters: ** **
    **
  • vfs: ^The "vfs" parameter may be used to specify the name of @@ -2513,22 +2490,6 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in ** a URI filename, its value overrides any behaviour requested by setting ** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. -** -**
  • readonly_shm: ^The readonly_shm parameter may be set to -** either "1" or "0". Setting it to "1" indicates that if the database -** is in WAL mode and read-write access to the associated shared -** memory region cannot be obtained, then an attempt should be made to open -** the shared-memory in read-only mode instead. If there exist one or -** more other database clients that have read-write connections to the -** database shared-memory, then a read-only shared-memory connection works -** fine. However, if there exist no clients with read-write connections -** to the shared-memory and the most recent such crashed or was interrupted -** by a power failure, then it is possible for a database client using a -** read-only connection to return incorrect data, incorrectly report -** database corruption, or return an SQLITE_READONLY error. Or if the -** most recent read-write connection shut down cleanly, it may not be -** possible to open the shared-memory in read-only mode at all, and SQLite -** will return SQLITE_CANTOPEN. **
** ** ^Specifying an unknown parameter in the query component of a URI is not an diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8b0aa855d8..fd86158e00 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2673,7 +2673,7 @@ void sqlite3AddColumnType(Parse*,Token*); void sqlite3AddDefaultValue(Parse*,ExprSpan*); void sqlite3AddCollateType(Parse*, Token*); void sqlite3EndTable(Parse*,Token*,Token*,Select*); -int sqlite3ParseUri(const char*,const char*,unsigned int*,int*, +int sqlite3ParseUri(const char*,const char*,unsigned int*, sqlite3_vfs**,char**,char **); Bitvec *sqlite3BitvecCreate(u32); diff --git a/src/wal.c b/src/wal.c index 87d3fcc968..9f9e1115fa 100644 --- a/src/wal.c +++ b/src/wal.c @@ -406,14 +406,6 @@ struct WalCkptInfo { /* ** An open write-ahead log file is represented by an instance of the ** following object. -** -** The readOnlyShm variable is normally set to 0. If it is set to 1, then -** the connection to shared-memory is read-only. This means it cannot -** be written at all (even when read-locking the database). If it is set -** to 2, then the shared-memory region is not yet open, but a read-only -** connection is acceptable. In this case when the shared-memory is opened -** (see function walIndexPage()), readOnlyShm is set to either 0 or 1 as -** appropriate. */ struct Wal { sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ @@ -428,8 +420,7 @@ struct Wal { u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ u8 writeLock; /* True if in a write transaction */ u8 ckptLock; /* True if holding a checkpoint lock */ - u8 readOnly; /* True if the WAL file is open read-only */ - u8 readOnlyShm; /* True if the SHM file is open read-only */ + u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ WalIndexHdr hdr; /* Wal-index header for current transaction */ const char *zWalName; /* Name of WAL file */ u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ @@ -445,6 +436,13 @@ struct Wal { #define WAL_EXCLUSIVE_MODE 1 #define WAL_HEAPMEMORY_MODE 2 +/* +** Possible values for WAL.readOnly +*/ +#define WAL_RDWR 0 /* Normal read/write connection */ +#define WAL_RDONLY 1 /* The WAL file is readonly */ +#define WAL_SHM_RDONLY 2 /* The SHM file is readonly */ + /* ** Each page of the wal-index mapping contains a hash-table made up of ** an array of HASHTABLE_NSLOT elements of the following type. @@ -538,23 +536,15 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){ rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] ); - if( rc==SQLITE_CANTOPEN && pWal->readOnlyShm>1 ){ - assert( iPage==0 ); - sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_READONLY_SHM, (void*)1); - rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, - pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] - ); - if( rc==SQLITE_OK ){ - pWal->readOnly = pWal->readOnlyShm = 1; - } - sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_READONLY_SHM, (void*)0); + if( rc==SQLITE_READONLY ){ + pWal->readOnly |= WAL_SHM_RDONLY; + rc = SQLITE_OK; } } } - *ppPage = pWal->apWiData[iPage]; + *ppPage = pWal->apWiData[iPage]; assert( iPage==0 || *ppPage || rc!=SQLITE_OK ); - if( pWal->readOnlyShm>1 ) pWal->readOnlyShm = 0; return rc; } @@ -794,7 +784,6 @@ static void walUnlockShared(Wal *pWal, int lockIdx){ } static int walLockExclusive(Wal *pWal, int lockIdx, int n){ int rc; - assert( pWal->readOnlyShm==0 ); if( pWal->exclusiveMode ) return SQLITE_OK; rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE); @@ -804,7 +793,6 @@ static int walLockExclusive(Wal *pWal, int lockIdx, int n){ return rc; } static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){ - assert( pWal->readOnlyShm==0 ); if( pWal->exclusiveMode ) return; (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE); @@ -1080,7 +1068,6 @@ static int walIndexRecover(Wal *pWal){ assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 ); assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE ); assert( pWal->writeLock ); - assert( pWal->readOnlyShm==0 ); iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock; nLock = SQLITE_SHM_NLOCK - iLock; rc = walLockExclusive(pWal, iLock, nLock); @@ -1300,7 +1287,7 @@ int sqlite3WalOpen( flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL); rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags); if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){ - pRet->readOnly = 1; + pRet->readOnly = WAL_RDONLY; } if( rc!=SQLITE_OK ){ @@ -1929,7 +1916,6 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ return rc; }; assert( page0 || pWal->writeLock==0 ); - assert( pWal->readOnlyShm==0 || pWal->readOnlyShm==1 ); /* If the first page of the wal-index has been mapped, try to read the ** wal-index header immediately, without holding any lock. This usually @@ -1939,11 +1925,11 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1); /* If the first attempt failed, it might have been due to a race - ** with a writer. So lock the WAL_WRITE_LOCK byte and try again. + ** with a writer. So get a WRITE lock and try again. */ assert( badHdr==0 || pWal->writeLock==0 ); if( badHdr ){ - if( pWal->readOnlyShm ){ + if( pWal->readOnly & WAL_SHM_RDONLY ){ if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){ walUnlockShared(pWal, WAL_WRITE_LOCK); rc = SQLITE_READONLY_RECOVERY; @@ -2150,7 +2136,9 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ } /* There was once an "if" here. The extra "{" is to preserve indentation. */ { - if( pWal->readOnlyShm==0 && (mxReadMark < pWal->hdr.mxFrame || mxI==0) ){ + if( (pWal->readOnly & WAL_SHM_RDONLY)==0 + && (mxReadMarkhdr.mxFrame || mxI==0) + ){ for(i=1; ireadOnlyShm && rc==SQLITE_OK) ); return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK; } @@ -2221,18 +2208,13 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ ** Pager layer will use this to know that is cache is stale and ** needs to be flushed. */ -int sqlite3WalBeginReadTransaction(Wal *pWal, int readOnlyShm, int *pChanged){ +int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ int rc; /* Return code */ int cnt = 0; /* Number of TryBeginRead attempts */ - if( pWal->nWiData==0 || pWal->apWiData[0]==0 ){ - assert( readOnlyShm==0 || readOnlyShm==1 ); - pWal->readOnlyShm = readOnlyShm*2; - } do{ rc = walTryBeginRead(pWal, pChanged, 0, ++cnt); }while( rc==WAL_RETRY ); - assert( rc || pWal->readOnlyShm==0 || (readOnlyShm && pWal->readOnlyShm==1) ); testcase( (rc&0xff)==SQLITE_BUSY ); testcase( (rc&0xff)==SQLITE_IOERR ); testcase( rc==SQLITE_PROTOCOL ); @@ -2407,7 +2389,6 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){ if( pWal->readOnly ){ return SQLITE_READONLY; } - assert( pWal->readOnlyShm==0 ); /* Only one writer allowed at a time. Get the write lock. Return ** SQLITE_BUSY if unable. @@ -2814,11 +2795,8 @@ int sqlite3WalCheckpoint( assert( pWal->ckptLock==0 ); assert( pWal->writeLock==0 ); + if( pWal->readOnly ) return SQLITE_READONLY; WALTRACE(("WAL%p: checkpoint begins\n", pWal)); - if( pWal->readOnlyShm ){ - return SQLITE_READONLY; - } - rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); if( rc ){ /* Usually this is SQLITE_BUSY meaning that another thread or process diff --git a/src/wal.h b/src/wal.h index df09beffe7..a62b23bbdc 100644 --- a/src/wal.h +++ b/src/wal.h @@ -23,7 +23,7 @@ # define sqlite3WalOpen(x,y,z) 0 # define sqlite3WalLimit(x,y) # define sqlite3WalClose(w,x,y,z) 0 -# define sqlite3WalBeginReadTransaction(x,y,z) 0 +# define sqlite3WalBeginReadTransaction(y,z) 0 # define sqlite3WalEndReadTransaction(z) # define sqlite3WalRead(v,w,x,y,z) 0 # define sqlite3WalDbsize(y) 0 @@ -60,7 +60,7 @@ void sqlite3WalLimit(Wal*, i64); ** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the ** transaction and releases the lock. */ -int sqlite3WalBeginReadTransaction(Wal *pWal, int, int *); +int sqlite3WalBeginReadTransaction(Wal *pWal, int *); void sqlite3WalEndReadTransaction(Wal *pWal); /* Read a page from the write-ahead log, if it is present. */ From fd019ef7ceaf17d41a47c3be1ef7309deb9be7eb Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 1 Jun 2011 20:13:36 +0000 Subject: [PATCH 17/30] Make use of the sqlite3GetBoolean() interface for more robust processing of the readonly_shm query parameter inside of unixShmMap(). FossilOrigin-Name: 1f930d7e04cd4a5ff3d91a0e9f1b62114f1cebd2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8b6e11236e..b9fd02df11 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\swal-readonly\sbranch\sso\sthat\sit\sdoes\snot\srequire\schanges\sto\nanything\sother\sthan\sos_unix.c\sand\swal.c\sand\sa\scouple\sof\snew\serror\scodes. -D 2011-06-01T20:01:49.650 +C Make\suse\sof\sthe\ssqlite3GetBoolean()\sinterface\sfor\smore\srobust\sprocessing\nof\sthe\sreadonly_shm\squery\sparameter\sinside\sof\sunixShmMap(). +D 2011-06-01T20:13:36.269 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -163,7 +163,7 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c a59c0718021934157f235468788c793cbc0d53de +F src/os_unix.c fd4e9588ff0ce09720721ce739ab2682202875ae F src/os_win.c 218b899469e570d46eb8147c2383075f7c026230 F src/pager.c 120550e7ef01dafaa2cbb4a0528c0d87c8f12b41 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 @@ -939,7 +939,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 0b63b71357a65e26ecd3f3bb34a5f14feee322f4 -R 20a045d8e6470f5f17b67b2f15ff8859 +P d6b4709de4d1f8af001f58938247f00a652a616e +R fdd310892b7cea51b352170f4a152593 U drh -Z f7b3b70c555e3fb5f3360ed8e60c2877 +Z cc8ff93f2b92f997226013b652879169 diff --git a/manifest.uuid b/manifest.uuid index 6f393899aa..203442f1d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d6b4709de4d1f8af001f58938247f00a652a616e \ No newline at end of file +1f930d7e04cd4a5ff3d91a0e9f1b62114f1cebd2 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index e6d1774a49..5860ae71a9 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3787,7 +3787,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ if( pShmNode->h<0 ){ const char *zRO; zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm"); - if( zRO && (zRO[0]!='0' || zRO[1]!=0) ){ + if( zRO && sqlite3GetBoolean(zRO) ){ pShmNode->h = robust_open(zShmFilename, O_RDONLY, (sStat.st_mode & 0777)); pShmNode->isReadonly = 1; From 070d422d31cec08996630f03622afed9b1d2407a Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 Jun 2011 15:48:51 +0000 Subject: [PATCH 18/30] Add a missing check for out-of-memory in the lemon code generator. FossilOrigin-Name: efb20b9da6c7cb310a449cc818eaccd3d5bb4ab3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lemon.c | 6 +++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f2e67cf931..355ba1eb5b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sread-only\sshared\smemory\sbranch\sinto\strunk.\s\sAfter\sthis\smerge,\san\nunprivileged\sprocess\scan\sopen\sWAL-mode\sdatabases\sowned\sby\sanother\suser\sas\nlong\sas\sa\sdatabase\sconnection\swith\swrite\spermission\sexists\son\sthe\sdatabase\nfile\sand\sif\sthe\sreadonly_shm=1\sURI\squery\sparameter\sis\ssupplied. -D 2011-06-02T13:04:33.467 +C Add\sa\smissing\scheck\sfor\sout-of-memory\sin\sthe\slemon\scode\sgenerator. +D 2011-06-02T15:48:51.684 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -909,7 +909,7 @@ F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -F tool/lemon.c dfd81a51b6e27e469ba21d01a75ddf092d429027 +F tool/lemon.c 2f182cf58a44a29107ad0027e4e696c79cbb9ad6 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e @@ -939,7 +939,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P e704e8690ae35decc9769a45cf8d519ccad8b79d 1f930d7e04cd4a5ff3d91a0e9f1b62114f1cebd2 -R fdd310892b7cea51b352170f4a152593 +P 19084a6641f77a62110b04ea50e298fe132ea784 +R 35b0b86c3f244adcf3711ae5d8007435 U drh -Z c21bc600f09ce2bc60c48c66dd9bd252 +Z df920ad923d5c14dce2ff7d7b1f2c419 diff --git a/manifest.uuid b/manifest.uuid index 2a33332676..2ce7958fe9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -19084a6641f77a62110b04ea50e298fe132ea784 \ No newline at end of file +efb20b9da6c7cb310a449cc818eaccd3d5bb4ab3 \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index 898022e28c..0a50524854 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -3434,6 +3434,10 @@ void print_stack_union( /* Allocate and initialize types[] and allocate stddt[] */ arraysize = lemp->nsymbol * 2; types = (char**)calloc( arraysize, sizeof(char*) ); + if( types==0 ){ + fprintf(stderr,"Out of memory.\n"); + exit(1); + } for(i=0; ivartype ){ @@ -3447,7 +3451,7 @@ void print_stack_union( if( len>maxdtlength ) maxdtlength = len; } stddt = (char*)malloc( maxdtlength*2 + 1 ); - if( types==0 || stddt==0 ){ + if( stddt==0 ){ fprintf(stderr,"Out of memory.\n"); exit(1); } From 5bf3934652568cdef29ca24ab9585004e11d0ce3 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 Jun 2011 17:24:49 +0000 Subject: [PATCH 19/30] Fix a faulty assert() in the WAL-mode logic for read-only shared memory. FossilOrigin-Name: a13cfe616284f4ee86f0406e7b8fe8f9ba6e6990 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wal.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 355ba1eb5b..f04e836195 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\smissing\scheck\sfor\sout-of-memory\sin\sthe\slemon\scode\sgenerator. -D 2011-06-02T15:48:51.684 +C Fix\sa\sfaulty\sassert()\sin\sthe\sWAL-mode\slogic\sfor\sread-only\sshared\smemory. +D 2011-06-02T17:24:49.997 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -245,7 +245,7 @@ F src/vdbeblob.c f024f0bf420f36b070143c32b15cc7287341ffd3 F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 F src/vtab.c 9ba8c7fdb7d39260c033a402f6032d3e7bc5d336 -F src/wal.c fd63d07233203dd3bd29cbe1ae5c8bb2c34e08fc +F src/wal.c 0c70ad7b1cac6005fa5e2cbefd23ee05e391c290 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c 55403ce19c506be6a321c7f129aff693d6103db5 @@ -939,7 +939,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 19084a6641f77a62110b04ea50e298fe132ea784 -R 35b0b86c3f244adcf3711ae5d8007435 +P efb20b9da6c7cb310a449cc818eaccd3d5bb4ab3 +R 7af7e431287e95dc91be1106acfd740b U drh -Z df920ad923d5c14dce2ff7d7b1f2c419 +Z e77c10de1c037b59f0516366918c7ba0 diff --git a/manifest.uuid b/manifest.uuid index 2ce7958fe9..b636e3ed7d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -efb20b9da6c7cb310a449cc818eaccd3d5bb4ab3 \ No newline at end of file +a13cfe616284f4ee86f0406e7b8fe8f9ba6e6990 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 9f9e1115fa..b9a03dff23 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2152,7 +2152,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ } } if( mxI==0 ){ - assert( rc==SQLITE_BUSY ); + assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK; } From be07ec582e358da8a7864d882a20596d6cb69dda Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 Jun 2011 12:15:26 +0000 Subject: [PATCH 20/30] Fix an #ifdef of SQLITE_OMIT_VIRTUALTABLE that had an extra "_" character. FossilOrigin-Name: 93e0be2bbf16d66d97ea7344187139d254b11cc3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f04e836195..62c45edfca 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sfaulty\sassert()\sin\sthe\sWAL-mode\slogic\sfor\sread-only\sshared\smemory. -D 2011-06-02T17:24:49.997 +C Fix\san\s#ifdef\sof\sSQLITE_OMIT_VIRTUALTABLE\sthat\shad\san\sextra\s"_"\scharacter. +D 2011-06-03T12:15:26.459 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -236,7 +236,7 @@ F src/update.c 5bcb56e5c7380a2eecb0e71891dbd4ad7437748f F src/utf.c d83650c3ea08f7407bd9d0839d9885241c209c60 F src/util.c 0f33bbbdfcc4a2d8cf20c3b2a16ffc3b57c58a70 F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e -F src/vdbe.c 2ec37637fa70ab0c694d8327ee5dcedbc0621524 +F src/vdbe.c edfa3827d7a6fac2425bc10c0eb6e54342d2fa56 F src/vdbe.h d9c6123384189dc37d27beac1bf44688aa75b6cb F src/vdbeInt.h ad84226cc0adcb1185c22b70696b235a1678bb45 F src/vdbeapi.c 0eeadc75e44a30efd996d6af6e7c5a2488e35be8 @@ -939,7 +939,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P efb20b9da6c7cb310a449cc818eaccd3d5bb4ab3 -R 7af7e431287e95dc91be1106acfd740b +P a13cfe616284f4ee86f0406e7b8fe8f9ba6e6990 +R 560ca19206a2de258e4ac41eb28208c5 U drh -Z e77c10de1c037b59f0516366918c7ba0 +Z 105c7f13fbfb0b81256f08e0207c0eef diff --git a/manifest.uuid b/manifest.uuid index b636e3ed7d..8cec759819 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a13cfe616284f4ee86f0406e7b8fe8f9ba6e6990 \ No newline at end of file +93e0be2bbf16d66d97ea7344187139d254b11cc3 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 439fe72540..97a0a6a555 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2585,7 +2585,7 @@ case OP_Savepoint: { }else{ nName = sqlite3Strlen30(zName); -#ifndef SQLITE_OMIT_VIRTUAL_TABLE +#ifndef SQLITE_OMIT_VIRTUALTABLE /* This call is Ok even if this savepoint is actually a transaction ** savepoint (and therefore should not prompt xSavepoint()) callbacks. ** If this is a transaction savepoint being opened, it is guaranteed From c7dc9bf88ed33e1676dd8e53b57eb330f8bf78fa Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 Jun 2011 13:02:57 +0000 Subject: [PATCH 21/30] Fix the build when using SQLITE_OMIT_PRAGMA. FossilOrigin-Name: 051f4635bf1e9618b108c4177b8ecc5762ed08e7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pragma.c | 10 ++++++---- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 62c45edfca..e99630aa85 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\s#ifdef\sof\sSQLITE_OMIT_VIRTUALTABLE\sthat\shad\san\sextra\s"_"\scharacter. -D 2011-06-03T12:15:26.459 +C Fix\sthe\sbuild\swhen\susing\sSQLITE_OMIT_PRAGMA. +D 2011-06-03T13:02:57.441 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -171,7 +171,7 @@ F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 F src/pcache.c 49e718c095810c6b3334e3a6d89970aceaddefce F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 F src/pcache1.c d548e31beafa792d1994b663a29a5303569efc4e -F src/pragma.c 9e778decc3ee9bcaf88904b4a3b0a4360aaf0eab +F src/pragma.c ebcd20f1e654f5cb3aeef864ed69c4697719fbaa F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4 F src/printf.c 585a36b6a963df832cfb69505afa3a34ed5ef8a1 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 @@ -939,7 +939,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P a13cfe616284f4ee86f0406e7b8fe8f9ba6e6990 -R 560ca19206a2de258e4ac41eb28208c5 +P 93e0be2bbf16d66d97ea7344187139d254b11cc3 +R 4ed98f1ed7ddc5d80458937702f664db U drh -Z 105c7f13fbfb0b81256f08e0207c0eef +Z 234b0b60ed4ca4872a72109fff862187 diff --git a/manifest.uuid b/manifest.uuid index 8cec759819..ae169702be 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -93e0be2bbf16d66d97ea7344187139d254b11cc3 \ No newline at end of file +051f4635bf1e9618b108c4177b8ecc5762ed08e7 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 799805c40b..cd2aab223c 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -13,10 +13,6 @@ */ #include "sqliteInt.h" -/* Ignore this whole file if pragmas are disabled -*/ -#if !defined(SQLITE_OMIT_PRAGMA) - /* ** Interpret the given string as a safety level. Return 0 for OFF, ** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or @@ -53,6 +49,12 @@ u8 sqlite3GetBoolean(const char *z){ return getSafetyLevel(z)&1; } +/* The sqlite3GetBoolean() function is used by other modules but the +** remainder of this file is specific to PRAGMA processing. So omit +** the rest of the file if PRAGMAs are omitted from the build. +*/ +#if !defined(SQLITE_OMIT_PRAGMA) + /* ** Interpret the given string as a locking mode value. */ From 3043ac70c44024b0f0cab143392805dcf02e095f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 Jun 2011 13:06:50 +0000 Subject: [PATCH 22/30] Add shell scripts used for testing compiler warnings (tool/warnings.sh), for verifying that the library exports the correct symbols (tool/symbols.sh), and to demonstrate building a full-featured command-line shell (tool/build-shell.sh). FossilOrigin-Name: 3aca9a92c8b29bb43f65f93593ba4defd65139dc --- manifest | 13 ++++++++----- manifest.uuid | 2 +- tool/build-shell.sh | 21 +++++++++++++++++++++ tool/symbols.sh | 34 ++++++++++++++++++++++++++++++++++ tool/warnings.sh | 14 ++++++++++++++ 5 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 tool/build-shell.sh create mode 100644 tool/symbols.sh create mode 100644 tool/warnings.sh diff --git a/manifest b/manifest index e99630aa85..c7ac33de9e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sbuild\swhen\susing\sSQLITE_OMIT_PRAGMA. -D 2011-06-03T13:02:57.441 +C Add\sshell\sscripts\sused\sfor\stesting\scompiler\swarnings\s(tool/warnings.sh),\nfor\sverifying\sthat\sthe\slibrary\sexports\sthe\scorrect\ssymbols\s(tool/symbols.sh),\nand\sto\sdemonstrate\sbuilding\sa\sfull-featured\scommand-line\sshell\n(tool/build-shell.sh). +D 2011-06-03T13:06:50.043 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -904,6 +904,7 @@ F test/whereA.test 24c234263c8fe358f079d5e57d884fb569d2da0a F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 +F tool/build-shell.sh 12aa4391073a777fcb6dcc490b219a018ae98bac F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 @@ -938,8 +939,10 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c +F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 93e0be2bbf16d66d97ea7344187139d254b11cc3 -R 4ed98f1ed7ddc5d80458937702f664db +F tool/warnings.sh 347d974d143cf132f953b565fbc03026f19fcb4d +P 051f4635bf1e9618b108c4177b8ecc5762ed08e7 +R 9da6c706bda9f5ba334ec4313d0142ea U drh -Z 234b0b60ed4ca4872a72109fff862187 +Z a1ce6be566aa33f6b6cc12b210f2a7c9 diff --git a/manifest.uuid b/manifest.uuid index ae169702be..face1e362d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -051f4635bf1e9618b108c4177b8ecc5762ed08e7 \ No newline at end of file +3aca9a92c8b29bb43f65f93593ba4defd65139dc \ No newline at end of file diff --git a/tool/build-shell.sh b/tool/build-shell.sh new file mode 100644 index 0000000000..54e8308095 --- /dev/null +++ b/tool/build-shell.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# +# This script demonstrates how to do a full-featured build of the sqlite3 +# command-line shell on Linux. +# +# SQLite source code should be in a sibling directory named "sqlite". For +# example, put SQLite sources in ~/sqlite/sqlite and run this script from +# ~/sqlite/bld. There should be an appropriate Makefile in the current +# directory as well. +# +make sqlite3.c +gcc -o sqlite3 -g -Os -I. \ + -DSQLITE_THREADSAFE=0 \ + -DSQLITE_ENABLE_VFSTRACE \ + -DSQLITE_ENABLE_STAT2 \ + -DSQLITE_ENABLE_FTS3 \ + -DSQLITE_ENABLE_RTREE \ + -DHAVE_READLINE \ + -DHAVE_USLEEP=1 \ + ../sqlite/src/shell.c ../sqlite/src/test_vfstrace.c \ + sqlite3.c -ldl -lreadline -lncurses diff --git a/tool/symbols.sh b/tool/symbols.sh new file mode 100644 index 0000000000..8aec00569a --- /dev/null +++ b/tool/symbols.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# +# Run this script in a directory that contains a valid SQLite makefile in +# order to verify that unintentionally exported symbols. +# +make sqlite3.c + +echo '****** Exported symbols from a build including RTREE, FTS4 & ICU ******' +gcc -c -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE \ + -DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_STAT2 \ + -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_ENABLE_UNLOCK_NOTIFY \ + -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_ATOMIC_WRITE \ + -DSQLITE_ENABLE_ICU \ + sqlite3.c +nm sqlite3.o | grep ' T ' | sort -k 3 + +echo '****** Surplus symbols from a build including RTREE, FTS4 & ICU ******' +nm sqlite3.o | grep ' T ' | grep -v ' sqlite3_' + +echo '****** Dependencies of the core. No extensions. No OS interface *******' +gcc -c -DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_STAT2 \ + -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_ENABLE_UNLOCK_NOTIFY \ + -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_ATOMIC_WRITE \ + -DSQLITE_OS_OTHER -DSQLITE_THREADSAFE=0 \ + sqlite3.c +nm sqlite3.o | grep ' U ' | sort -k 3 + +echo '****** Dependencies including RTREE & FTS4 *******' +gcc -c -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE \ + -DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_STAT2 \ + -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_ENABLE_UNLOCK_NOTIFY \ + -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_ATOMIC_WRITE \ + sqlite3.c +nm sqlite3.o | grep ' U ' | sort -k 3 diff --git a/tool/warnings.sh b/tool/warnings.sh new file mode 100644 index 0000000000..e1fa2b2d91 --- /dev/null +++ b/tool/warnings.sh @@ -0,0 +1,14 @@ +#/bin/sh +# +# Run this script in a directory with a working makefile to check for +# compiler warnings in SQLite. +# +make sqlite3.c +echo '********** No optimizations. Includes FTS4 and RTREE *********' +gcc -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \ + -ansi -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE \ + sqlite3.c +echo '********** Optimized -O3. Includes FTS4 and RTREE *********' +gcc -O3 -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \ + -ansi -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE \ + sqlite3.c From 9fd301bb6ac5e9d7e017fff079d9034716ae1a09 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 Jun 2011 13:28:22 +0000 Subject: [PATCH 23/30] Include more detailed version information in the command-line shell output. FossilOrigin-Name: 049c3c42fdefea8de7ec7008871963e37ce2d7bc --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 11 ++++++++--- tool/shell1.test | 5 +++-- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index c7ac33de9e..bcc31ebfb3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sshell\sscripts\sused\sfor\stesting\scompiler\swarnings\s(tool/warnings.sh),\nfor\sverifying\sthat\sthe\slibrary\sexports\sthe\scorrect\ssymbols\s(tool/symbols.sh),\nand\sto\sdemonstrate\sbuilding\sa\sfull-featured\scommand-line\sshell\n(tool/build-shell.sh). -D 2011-06-03T13:06:50.043 +C Include\smore\sdetailed\sversion\sinformation\sin\sthe\scommand-line\sshell\soutput. +D 2011-06-03T13:28:22.119 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -178,7 +178,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d9d440809025a58547e39f4f268c2a296bfb56ff -F src/shell.c decd04236a7ef26be5ef46d4ea963044bfad9a48 +F src/shell.c 0e0173b3e79d956368013e759f084caa7995ecb1 F src/sqlite.h.in 2f51e4f58b2b4626fcbd9938580e730cb5fb4985 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 F src/sqliteInt.h 6e58c558c57c8f44011736d5fa5295eb3130f9de @@ -922,7 +922,7 @@ F tool/omittest.tcl b1dd290c1596e0f31fd335160a74ec5dfea3df4a F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5 -F tool/shell1.test 5542ecdc952f91121a835ed817e6feaf8988b333 +F tool/shell1.test 20dfe7099cf2afe37aecd69afb7678d14f7a0abf F tool/shell2.test 5dc76b8005b465f420fed8241621da7513060ff3 F tool/shell3.test 4fad469e8003938426355afdf34155f08c587836 F tool/shell4.test 35f9c3d452b4e76d5013c63e1fd07478a62f14ce @@ -942,7 +942,7 @@ F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 347d974d143cf132f953b565fbc03026f19fcb4d -P 051f4635bf1e9618b108c4177b8ecc5762ed08e7 -R 9da6c706bda9f5ba334ec4313d0142ea +P 3aca9a92c8b29bb43f65f93593ba4defd65139dc +R 1eb21a9d7ed9685f625d6c1573544e8b U drh -Z a1ce6be566aa33f6b6cc12b210f2a7c9 +Z 70d86fceaffca6cead41b36e31773fcc diff --git a/manifest.uuid b/manifest.uuid index face1e362d..13a02e0d29 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3aca9a92c8b29bb43f65f93593ba4defd65139dc \ No newline at end of file +049c3c42fdefea8de7ec7008871963e37ce2d7bc \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 8e9870a5a8..a54c922e87 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2302,6 +2302,11 @@ static int do_meta_command(char *zLine, struct callback_data *p){ enableTimer = booleanValue(azArg[1]); }else + if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ + printf("SQLite %s %s\n", + sqlite3_libversion(), sqlite3_sourceid()); + }else + if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){ int j; assert( nArg<=ArraySize(azArg) ); @@ -2836,7 +2841,7 @@ int main(int argc, char **argv){ }else if( strcmp(z,"-bail")==0 ){ bail_on_error = 1; }else if( strcmp(z,"-version")==0 ){ - printf("%s\n", sqlite3_libversion()); + printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid()); return 0; }else if( strcmp(z,"-interactive")==0 ){ stdin_is_interactive = 1; @@ -2881,10 +2886,10 @@ int main(int argc, char **argv){ char *zHistory = 0; int nHistory; printf( - "SQLite version %s\n" + "SQLite version %s %.19s\n" "Enter \".help\" for instructions\n" "Enter SQL statements terminated with a \";\"\n", - sqlite3_libversion() + sqlite3_libversion(), sqlite3_sourceid() ); zHome = find_home_dir(); if( zHome ){ diff --git a/tool/shell1.test b/tool/shell1.test index 068f8ea25c..9dd9df5555 100644 --- a/tool/shell1.test +++ b/tool/shell1.test @@ -199,8 +199,9 @@ do_test shell1-1.15.3 { # -version show SQLite version do_test shell1-1.16.1 { - catchcmd "-version test.db" "" -} {0 3.7.7} + set x [catchcmd "-version test.db" ""] + regexp {0 \{3.\d.\d+ 20\d\d-[01]\d-\d\d \d\d:\d\d:\d\d [0-9a-f]+\}} $x +} 1 #---------------------------------------------------------------------------- # Test cases shell1-2.*: Basic "dot" command token parsing. From 45caededba6bd24dcbd31c5db1bb0d423fb8be9e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 Jun 2011 14:19:10 +0000 Subject: [PATCH 24/30] Hush some harmless compiler warnings in the URI parsing logic. FossilOrigin-Name: 0206bc6f87bb9393218a380fc5b18039d334a8d8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/main.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index bcc31ebfb3..1099d5534a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Include\smore\sdetailed\sversion\sinformation\sin\sthe\scommand-line\sshell\soutput. -D 2011-06-03T13:28:22.119 +C Hush\ssome\sharmless\scompiler\swarnings\sin\sthe\sURI\sparsing\slogic. +D 2011-06-03T14:19:10.707 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -144,7 +144,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e F src/loadext.c 3ae0d52da013a6326310655be6473fd472347b85 -F src/main.c 059daeed5876b3604f0192f838faf5f4db138901 +F src/main.c d67ea48933e4d63abba00578224a3319e6fbcbe1 F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206 @@ -942,7 +942,7 @@ F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 347d974d143cf132f953b565fbc03026f19fcb4d -P 3aca9a92c8b29bb43f65f93593ba4defd65139dc -R 1eb21a9d7ed9685f625d6c1573544e8b +P 049c3c42fdefea8de7ec7008871963e37ce2d7bc +R 06582f4582a8157c228d4b288a346794 U drh -Z 70d86fceaffca6cead41b36e31773fcc +Z 0eb02a6eb0f61a953a539b049b2322b5 diff --git a/manifest.uuid b/manifest.uuid index 13a02e0d29..a5c8a3d8b3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -049c3c42fdefea8de7ec7008871963e37ce2d7bc \ No newline at end of file +0206bc6f87bb9393218a380fc5b18039d334a8d8 \ No newline at end of file diff --git a/src/main.c b/src/main.c index c99d396546..d3386eb0cd 100644 --- a/src/main.c +++ b/src/main.c @@ -1938,9 +1938,9 @@ int sqlite3ParseUri( const char *z; int mode; } *aMode = 0; - char *zModeType; - int mask; - int limit; + char *zModeType = 0; + int mask = 0; + int limit = 0; if( nOpt==5 && memcmp("cache", zOpt, 5)==0 ){ static struct OpenMode aCacheMode[] = { From 68f2a57698780de49312cdb0f11732c521955d60 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 Jun 2011 17:50:49 +0000 Subject: [PATCH 25/30] Factor an "if" out of a loop in balance_nonroot() for about a 1% performance increase. FossilOrigin-Name: 1bd72d0c616e20fdb395c72ecd96579090ae26cb --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 26 ++++++++++++++++++++------ 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 1099d5534a..b636720757 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Hush\ssome\sharmless\scompiler\swarnings\sin\sthe\sURI\sparsing\slogic. -D 2011-06-03T14:19:10.707 +C Factor\san\s"if"\sout\sof\sa\sloop\sin\sbalance_nonroot()\sfor\sabout\sa\s1%\sperformance\nincrease. +D 2011-06-03T17:50:49.782 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -122,7 +122,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 0d3b39dcb79565c053e35fc12713f12d8a74d6a9 +F src/btree.c 12aa3b71359c888984223cb2bcf691cf2d7753ae F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 F src/build.c c10ab9e2c77ade99dee23554787f8acfc0c231fc @@ -942,7 +942,7 @@ F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 347d974d143cf132f953b565fbc03026f19fcb4d -P 049c3c42fdefea8de7ec7008871963e37ce2d7bc -R 06582f4582a8157c228d4b288a346794 +P 0206bc6f87bb9393218a380fc5b18039d334a8d8 +R 9437f6a8af920a11b9b18fbeccb53c6b U drh -Z 0eb02a6eb0f61a953a539b049b2322b5 +Z d6270d9f0f6d36a33c5a8dae47c51fc0 diff --git a/manifest.uuid b/manifest.uuid index a5c8a3d8b3..a78d2a2cc4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0206bc6f87bb9393218a380fc5b18039d334a8d8 \ No newline at end of file +1bd72d0c616e20fdb395c72ecd96579090ae26cb \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 972a2f608c..9e9677cc42 100644 --- a/src/btree.c +++ b/src/btree.c @@ -857,6 +857,8 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ */ #define findCell(P,I) \ ((P)->aData + ((P)->maskPage & get2byte(&(P)->aData[(P)->cellOffset+2*(I)]))) +#define findCellv2(D,M,O,I) (D+(M&get2byte(D+(O+2*(I))))) + /* ** This a more complex version of findCell() that works for @@ -6016,12 +6018,24 @@ static int balance_nonroot( memcpy(pOld->aData, apOld[i]->aData, pBt->pageSize); limit = pOld->nCell+pOld->nOverflow; - for(j=0; jnOverflow>0 ){ + for(j=0; jaData; + u16 maskPage = pOld->maskPage; + u16 cellOffset = pOld->cellOffset; + for(j=0; j Date: Fri, 3 Jun 2011 20:11:17 +0000 Subject: [PATCH 26/30] Create and use a function especially for adding the ParseSchema opcode. This gives a small reduction in code and a small performance increase. FossilOrigin-Name: 957b2ab67c6185f0e1062593d237de5c434a38bf --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/alter.c | 4 ++-- src/build.c | 9 ++++----- src/trigger.c | 5 ++--- src/vdbe.h | 1 + src/vdbeaux.c | 21 ++++++++++++++------- src/vtab.c | 2 +- 8 files changed, 36 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index b636720757..c00993097b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Factor\san\s"if"\sout\sof\sa\sloop\sin\sbalance_nonroot()\sfor\sabout\sa\s1%\sperformance\nincrease. -D 2011-06-03T17:50:49.782 +C Create\sand\suse\sa\sfunction\sespecially\sfor\sadding\sthe\sParseSchema\sopcode.\nThis\sgives\sa\ssmall\sreduction\sin\scode\sand\sa\ssmall\sperformance\sincrease. +D 2011-06-03T20:11:17.958 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -115,7 +115,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad -F src/alter.c 280f5c04b11b492703a342222b3de0a999445280 +F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 F src/analyze.c a425d62e8fa9ebcb4359ab84ff0c62c6563d2e2a F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 @@ -125,7 +125,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 12aa3b71359c888984223cb2bcf691cf2d7753ae F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 -F src/build.c c10ab9e2c77ade99dee23554787f8acfc0c231fc +F src/build.c 5a428625d21ad409514afb40ad083bee25dd957a F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 7deec4534f3b5a0c3b4a4cbadf809d321f64f9c4 @@ -231,20 +231,20 @@ F src/test_vfstrace.c 0b884e06094a746da729119a2cabdc7aa790063d F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 7b0c9281b2368dc69135e7a50bd271de9af1b467 -F src/trigger.c 144cc18bb701f3286484aae4292a9531f09278c8 +F src/trigger.c c836a6caac16ba96611558922106858f6ca3d6bf F src/update.c 5bcb56e5c7380a2eecb0e71891dbd4ad7437748f F src/utf.c d83650c3ea08f7407bd9d0839d9885241c209c60 F src/util.c 0f33bbbdfcc4a2d8cf20c3b2a16ffc3b57c58a70 F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e F src/vdbe.c edfa3827d7a6fac2425bc10c0eb6e54342d2fa56 -F src/vdbe.h d9c6123384189dc37d27beac1bf44688aa75b6cb +F src/vdbe.h 5cf09e7ee8a3f7d93bc51f196a96550786afe7a1 F src/vdbeInt.h ad84226cc0adcb1185c22b70696b235a1678bb45 F src/vdbeapi.c 0eeadc75e44a30efd996d6af6e7c5a2488e35be8 -F src/vdbeaux.c 0505dc4f7ff3cf35e219fe0a20ab798a42772b8b +F src/vdbeaux.c 0b2e2880f13af400a27c92a7673287c3eaec8b21 F src/vdbeblob.c f024f0bf420f36b070143c32b15cc7287341ffd3 F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 -F src/vtab.c 9ba8c7fdb7d39260c033a402f6032d3e7bc5d336 +F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582 F src/wal.c 0c70ad7b1cac6005fa5e2cbefd23ee05e391c290 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f @@ -942,7 +942,7 @@ F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 347d974d143cf132f953b565fbc03026f19fcb4d -P 0206bc6f87bb9393218a380fc5b18039d334a8d8 -R 9437f6a8af920a11b9b18fbeccb53c6b +P 1bd72d0c616e20fdb395c72ecd96579090ae26cb +R 80ecde493cfcd0f0a571171fe6ad9164 U drh -Z d6270d9f0f6d36a33c5a8dae47c51fc0 +Z 08497a0228f24f1156217359e2dbd164 diff --git a/manifest.uuid b/manifest.uuid index a78d2a2cc4..67c1f2f89d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1bd72d0c616e20fdb395c72ecd96579090ae26cb \ No newline at end of file +957b2ab67c6185f0e1062593d237de5c434a38bf \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index aa3fa929f8..fb6d89de6f 100644 --- a/src/alter.c +++ b/src/alter.c @@ -358,14 +358,14 @@ static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){ /* Reload the table, index and permanent trigger schemas. */ zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName); if( !zWhere ) return; - sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC); + sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); #ifndef SQLITE_OMIT_TRIGGER /* Now, if the table is not stored in the temp database, reload any temp ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. */ if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ - sqlite3VdbeAddOp4(v, OP_ParseSchema, 1, 0, 0, zWhere, P4_DYNAMIC); + sqlite3VdbeAddParseSchemaOp(v, 1, zWhere); } #endif } diff --git a/src/build.c b/src/build.c index afe2089325..97758cbcbd 100644 --- a/src/build.c +++ b/src/build.c @@ -1619,8 +1619,8 @@ void sqlite3EndTable( #endif /* Reparse everything to update our internal data structures */ - sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, - sqlite3MPrintf(db, "tbl_name='%q'",p->zName), P4_DYNAMIC); + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "tbl_name='%q'", p->zName)); } @@ -2817,9 +2817,8 @@ Index *sqlite3CreateIndex( if( pTblName ){ sqlite3RefillIndex(pParse, pIndex, iMem); sqlite3ChangeCookie(pParse, iDb); - sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, - sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName), - P4_DYNAMIC); + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName)); sqlite3VdbeAddOp1(v, OP_Expire, 0); } } diff --git a/src/trigger.c b/src/trigger.c index 0f3f5bad39..6242de5e6c 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -301,9 +301,8 @@ void sqlite3FinishTrigger( pTrig->table, z); sqlite3DbFree(db, z); sqlite3ChangeCookie(pParse, iDb); - sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, sqlite3MPrintf( - db, "type='trigger' AND name='%q'", zName), P4_DYNAMIC - ); + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName)); } if( db->init.busy ){ diff --git a/src/vdbe.h b/src/vdbe.h index 56f9eb51ca..e66ee3024d 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -172,6 +172,7 @@ int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp); +void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1); void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2); void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8181f01aa3..447ba57a1e 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -156,13 +156,6 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ pOp->p3 = p3; pOp->p4.p = 0; pOp->p4type = P4_NOTUSED; - p->expired = 0; - if( op==OP_ParseSchema ){ - /* Any program that uses the OP_ParseSchema opcode needs to lock - ** all btrees. */ - int j; - for(j=0; jdb->nDb; j++) sqlite3VdbeUsesBtree(p, j); - } #ifdef SQLITE_DEBUG pOp->zComment = 0; if( sqlite3VdbeAddopTrace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]); @@ -201,6 +194,20 @@ int sqlite3VdbeAddOp4( return addr; } +/* +** Add an OP_ParseSchema opcode. This routine is broken out from +** sqlite3VdbeAddOp4() since it needs to also local all btrees. +** +** The zWhere string must have been obtained from sqlite3_malloc(). +** This routine will take ownership of the allocated memory. +*/ +void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){ + int j; + int addr = sqlite3VdbeAddOp3(p, OP_ParseSchema, iDb, 0, 0); + sqlite3VdbeChangeP4(p, addr, zWhere, P4_DYNAMIC); + for(j=0; jdb->nDb; j++) sqlite3VdbeUsesBtree(p, j); +} + /* ** Add an opcode that includes the p4 value as an integer. */ diff --git a/src/vtab.c b/src/vtab.c index dffd6a2664..223ef4e7bd 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -383,7 +383,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ sqlite3VdbeAddOp2(v, OP_Expire, 0, 0); zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName); - sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC); + sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); sqlite3VdbeAddOp4(v, OP_VCreate, iDb, 0, 0, pTab->zName, sqlite3Strlen30(pTab->zName) + 1); } From 3a61a5a2b534f357822851d7859a683212aaab72 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 Jun 2011 21:34:45 +0000 Subject: [PATCH 27/30] Performance enhancement to the blob-literal tokenizer. FossilOrigin-Name: 61aa2031f1c5ae05e31077588a55194a9546262a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tokenize.c | 11 +++++------ 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index c00993097b..014b8a5783 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Create\sand\suse\sa\sfunction\sespecially\sfor\sadding\sthe\sParseSchema\sopcode.\nThis\sgives\sa\ssmall\sreduction\sin\scode\sand\sa\ssmall\sperformance\sincrease. -D 2011-06-03T20:11:17.958 +C Performance\senhancement\sto\sthe\sblob-literal\stokenizer. +D 2011-06-03T21:34:45.326 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -230,7 +230,7 @@ F src/test_vfs.c e7855568dfa1e0ba73668d273b65605d9f8b77e8 F src/test_vfstrace.c 0b884e06094a746da729119a2cabdc7aa790063d F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 -F src/tokenize.c 7b0c9281b2368dc69135e7a50bd271de9af1b467 +F src/tokenize.c c819d9f72168a035d545a5bdafe9b085b20df705 F src/trigger.c c836a6caac16ba96611558922106858f6ca3d6bf F src/update.c 5bcb56e5c7380a2eecb0e71891dbd4ad7437748f F src/utf.c d83650c3ea08f7407bd9d0839d9885241c209c60 @@ -942,7 +942,7 @@ F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 347d974d143cf132f953b565fbc03026f19fcb4d -P 1bd72d0c616e20fdb395c72ecd96579090ae26cb -R 80ecde493cfcd0f0a571171fe6ad9164 +P 957b2ab67c6185f0e1062593d237de5c434a38bf +R bd36ddd3c30f1348cf18f2599b20bbca U drh -Z 08497a0228f24f1156217359e2dbd164 +Z fe6a860af7a1658c61a1531782a69559 diff --git a/manifest.uuid b/manifest.uuid index 67c1f2f89d..01e044ed3e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -957b2ab67c6185f0e1062593d237de5c434a38bf \ No newline at end of file +61aa2031f1c5ae05e31077588a55194a9546262a \ No newline at end of file diff --git a/src/tokenize.c b/src/tokenize.c index 016a218262..b32989277e 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -353,13 +353,12 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ testcase( z[0]=='x' ); testcase( z[0]=='X' ); if( z[1]=='\'' ){ *tokenType = TK_BLOB; - for(i=2; (c=z[i])!=0 && c!='\''; i++){ - if( !sqlite3Isxdigit(c) ){ - *tokenType = TK_ILLEGAL; - } + for(i=2; sqlite3Isxdigit(z[i]); i++){} + if( z[i]!='\'' || i%2 ){ + *tokenType = TK_ILLEGAL; + while( z[i] && z[i]!='\'' ){ i++; } } - if( i%2 || !c ) *tokenType = TK_ILLEGAL; - if( c ) i++; + if( z[i] ) i++; return i; } /* Otherwise fall through to the next case */ From 61d2fe955c2af8a24ab3829d143c8f9fd6324319 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 Jun 2011 23:28:33 +0000 Subject: [PATCH 28/30] Performance improvements on memory copies inside of btree by moving 2 bytes at a time instead of just 1 byte at a time. FossilOrigin-Name: 897f56a158ebe62758c9998e4941ae046c75fb99 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 17 ++++++++++------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 014b8a5783..7f9a970797 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\senhancement\sto\sthe\sblob-literal\stokenizer. -D 2011-06-03T21:34:45.326 +C Performance\simprovements\son\smemory\scopies\sinside\sof\sbtree\sby\smoving\s2\sbytes\nat\sa\stime\sinstead\sof\sjust\s1\sbyte\sat\sa\stime. +D 2011-06-03T23:28:33.011 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -122,7 +122,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 12aa3b71359c888984223cb2bcf691cf2d7753ae +F src/btree.c 9f214af284fae1e96f12989dcc4d26f247b502fc F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 F src/build.c 5a428625d21ad409514afb40ad083bee25dd957a @@ -942,7 +942,7 @@ F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 347d974d143cf132f953b565fbc03026f19fcb4d -P 957b2ab67c6185f0e1062593d237de5c434a38bf -R bd36ddd3c30f1348cf18f2599b20bbca +P 61aa2031f1c5ae05e31077588a55194a9546262a +R ee8453a74951d0e43529f6f62862f77e U drh -Z fe6a860af7a1658c61a1531782a69559 +Z eb5472e3af1761c7727508ef6d936f22 diff --git a/manifest.uuid b/manifest.uuid index 01e044ed3e..246d28ad64 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -61aa2031f1c5ae05e31077588a55194a9546262a \ No newline at end of file +897f56a158ebe62758c9998e4941ae046c75fb99 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 9e9677cc42..ece4602159 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5422,8 +5422,7 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ } endPtr = &data[pPage->cellOffset + 2*pPage->nCell - 2]; while( ptrnCell--; @@ -5464,6 +5463,7 @@ static void insertCell( int cellOffset; /* Address of first cell pointer in data[] */ u8 *data; /* The content of the whole page */ u8 *ptr; /* Used for moving information around in data[] */ + u8 *endPtr; /* End of the loop */ int nSkip = (iChild ? 4 : 0); @@ -5514,9 +5514,11 @@ static void insertCell( if( iChild ){ put4byte(&data[idx], iChild); } - for(j=end, ptr=&data[j]; j>ins; j-=2, ptr-=2){ - ptr[0] = ptr[-2]; - ptr[1] = ptr[-1]; + ptr = &data[end]; + endPtr = &data[ins]; + while( ptr>endPtr ){ + *(u16*)ptr = *(u16*)&ptr[-2]; + ptr -= 2; } put2byte(&data[ins], idx); put2byte(&data[pPage->hdrOffset+3], pPage->nCell); @@ -5561,10 +5563,11 @@ static void assemblePage( pCellptr = &data[pPage->cellOffset + nCell*2]; cellbody = nUsable; for(i=nCell-1; i>=0; i--){ + u16 sz = aSize[i]; pCellptr -= 2; - cellbody -= aSize[i]; + cellbody -= sz; put2byte(pCellptr, cellbody); - memcpy(&data[cellbody], apCell[i], aSize[i]); + memcpy(&data[cellbody], apCell[i], sz); } put2byte(&data[hdr+3], nCell); put2byte(&data[hdr+5], cellbody); From afb9817f8c85b9a3e43edabfc84e079c8dd384ab Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 Jun 2011 01:43:53 +0000 Subject: [PATCH 29/30] Performance improvement to the btree search routine. FossilOrigin-Name: 65db822f200bafe9abe59b33b17b2c643c17c5e8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 7f9a970797..acedbbc719 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovements\son\smemory\scopies\sinside\sof\sbtree\sby\smoving\s2\sbytes\nat\sa\stime\sinstead\sof\sjust\s1\sbyte\sat\sa\stime. -D 2011-06-03T23:28:33.011 +C Performance\simprovement\sto\sthe\sbtree\ssearch\sroutine. +D 2011-06-04T01:43:53.858 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -122,7 +122,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 9f214af284fae1e96f12989dcc4d26f247b502fc +F src/btree.c c19d7b35c8325b302d88d73e834642a7a96ee003 F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 F src/build.c 5a428625d21ad409514afb40ad083bee25dd957a @@ -942,7 +942,7 @@ F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 347d974d143cf132f953b565fbc03026f19fcb4d -P 61aa2031f1c5ae05e31077588a55194a9546262a -R ee8453a74951d0e43529f6f62862f77e +P 897f56a158ebe62758c9998e4941ae046c75fb99 +R 84139bde7a129a9544042a4a85d415c4 U drh -Z eb5472e3af1761c7727508ef6d936f22 +Z 4316427fea8d5aeb84c01ffb6d821ecd diff --git a/manifest.uuid b/manifest.uuid index 246d28ad64..e0e3846b64 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -897f56a158ebe62758c9998e4941ae046c75fb99 \ No newline at end of file +65db822f200bafe9abe59b33b17b2c643c17c5e8 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index ece4602159..640d48b452 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4453,7 +4453,7 @@ int sqlite3BtreeMovetoUnpacked( } assert( pCur->apPage[0]->intKey || pIdxKey ); for(;;){ - int lwr, upr; + int lwr, upr, idx; Pgno chldPg; MemPage *pPage = pCur->apPage[pCur->iPage]; int c; @@ -4469,14 +4469,14 @@ int sqlite3BtreeMovetoUnpacked( lwr = 0; upr = pPage->nCell-1; if( biasRight ){ - pCur->aiIdx[pCur->iPage] = (u16)upr; + pCur->aiIdx[pCur->iPage] = (u16)(idx = upr); }else{ - pCur->aiIdx[pCur->iPage] = (u16)((upr+lwr)/2); + pCur->aiIdx[pCur->iPage] = (u16)(idx = (upr+lwr)/2); } for(;;){ - int idx = pCur->aiIdx[pCur->iPage]; /* Index of current cell in pPage */ u8 *pCell; /* Pointer to current cell in pPage */ + assert( idx==pCur->aiIdx[pCur->iPage] ); pCur->info.nSize = 0; pCell = findCell(pPage, idx) + pPage->childPtrSize; if( pPage->intKey ){ @@ -4559,7 +4559,7 @@ int sqlite3BtreeMovetoUnpacked( if( lwr>upr ){ break; } - pCur->aiIdx[pCur->iPage] = (u16)((lwr+upr)/2); + pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2); } assert( lwr==upr+1 ); assert( pPage->isInit ); From 2ce71b4e7a11d23d9267f4c3e2714adde454ddcd Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 6 Jun 2011 13:38:11 +0000 Subject: [PATCH 30/30] Add assert() statements to verify that u16 pointers associated with the enhancement in [897f56a158] are always 2-byte aligned. FossilOrigin-Name: 98ccfa930e8e5f10808a518e3e22e85e8a8a65c2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index acedbbc719..9f7ebae4ea 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovement\sto\sthe\sbtree\ssearch\sroutine. -D 2011-06-04T01:43:53.858 +C Add\sassert()\sstatements\sto\sverify\sthat\su16\spointers\sassociated\swith\nthe\senhancement\sin\s[897f56a158]\sare\salways\s2-byte\saligned. +D 2011-06-06T13:38:11.704 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -122,7 +122,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c c19d7b35c8325b302d88d73e834642a7a96ee003 +F src/btree.c 8c46f0ab69ad9549c75a3a91fed87abdaa743e2f F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 F src/build.c 5a428625d21ad409514afb40ad083bee25dd957a @@ -942,7 +942,7 @@ F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 347d974d143cf132f953b565fbc03026f19fcb4d -P 897f56a158ebe62758c9998e4941ae046c75fb99 -R 84139bde7a129a9544042a4a85d415c4 +P 65db822f200bafe9abe59b33b17b2c643c17c5e8 +R 6f20bbc84376df4d202ff7744a749f24 U drh -Z 4316427fea8d5aeb84c01ffb6d821ecd +Z b952c48c970134cec62f175ed76931db diff --git a/manifest.uuid b/manifest.uuid index e0e3846b64..4a6c7d51ec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -65db822f200bafe9abe59b33b17b2c643c17c5e8 \ No newline at end of file +98ccfa930e8e5f10808a518e3e22e85e8a8a65c2 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 640d48b452..3d7162dbb3 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5421,6 +5421,7 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ return; } endPtr = &data[pPage->cellOffset + 2*pPage->nCell - 2]; + assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */ while( ptrendPtr ){ *(u16*)ptr = *(u16*)&ptr[-2]; ptr -= 2;