From 75e700c100f429c544e12b35d2ab2b13457807b5 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 1 Nov 2011 00:52:41 +0000 Subject: [PATCH 001/161] Version 3.7.9 FossilOrigin-Name: c7c6050ef060877ebe77b41d959e9df13f8c9b5e --- manifest | 9 +++++---- manifest.uuid | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/manifest b/manifest index 1a5584b29b..307b0c39c8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sa\scomment.\s\sNo\scode\schanges. -D 2011-10-31T12:25:01.056 +C Version\s3.7.9 +D 2011-11-01T00:52:41.132 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -974,7 +974,8 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 13a9d085e1a5654a97b8d26bae7182ca6c0c237b +P 6635cd9a7714b681dd8aa96e90be462a40d10178 R b059ff356abfc5b4524a9b548916f43e +T +sym-version-3.7.9 * U drh -Z 96e807ea22060094cd672e7fd9baae6e +Z a9ecbb5c487c786a176874d979505217 diff --git a/manifest.uuid b/manifest.uuid index 445a58c5ee..ce12ac8420 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6635cd9a7714b681dd8aa96e90be462a40d10178 \ No newline at end of file +c7c6050ef060877ebe77b41d959e9df13f8c9b5e \ No newline at end of file From e7224a011bd2ee28ceab126b6d867ba7963260e7 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 4 Nov 2011 00:23:53 +0000 Subject: [PATCH 002/161] Make sure the INSERT INTO ... SELECT statement works correctly even when the destination table contains an INTEGER PRIMARY KEY ON CONFLICT... column. Ticket [676bc02b87176125]. FossilOrigin-Name: 6f9898db7ff0730cc03f561f9c32ef3dee7e5d81 --- manifest | 15 +++--- manifest.uuid | 2 +- src/insert.c | 3 +- test/insert4.test | 119 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 307b0c39c8..178b6147a5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.7.9 -D 2011-11-01T00:52:41.132 +C Make\ssure\sthe\sINSERT\sINTO\s...\sSELECT\sstatement\sworks\scorrectly\seven\swhen\nthe\sdestination\stable\scontains\san\sINTEGER\sPRIMARY\sKEY\sON\sCONFLICT...\scolumn.\nTicket\s[676bc02b87176125]. +D 2011-11-04T00:23:53.875 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -142,7 +142,7 @@ F src/global.c e230227de13601714b29f9363028514aada5ae2f F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c ca18783512323f74aaf4ee74b46ffd75ec80d031 +F src/insert.c bfe25a1d333658bd6f79fded6581d8a6962ce272 F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 @@ -525,7 +525,7 @@ F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/insert.test aef273dd1cee84cc92407469e6bd1b3cdcb76908 F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435 F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30 -F test/insert4.test 63ea672b0fc6d3a9a0ccee774a771510b1e684c4 +F test/insert4.test 03f1644c4f2393e26e6b12d105ce375811178ace F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4 F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1 @@ -974,8 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 6635cd9a7714b681dd8aa96e90be462a40d10178 -R b059ff356abfc5b4524a9b548916f43e -T +sym-version-3.7.9 * +P c7c6050ef060877ebe77b41d959e9df13f8c9b5e +R 86847a1d583226c862e98772b444bf54 U drh -Z a9ecbb5c487c786a176874d979505217 +Z a5a032e1b2e9278ae9ce6bac983d1037 diff --git a/manifest.uuid b/manifest.uuid index ce12ac8420..27b9032fb9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c7c6050ef060877ebe77b41d959e9df13f8c9b5e \ No newline at end of file +6f9898db7ff0730cc03f561f9c32ef3dee7e5d81 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 277a852cc7..72fba06efd 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1639,7 +1639,8 @@ static int xferOptimization( } #endif if( onError==OE_Default ){ - onError = OE_Abort; + if( pDest->iPKey>=0 ) onError = pDest->keyConf; + if( onError==OE_Default ) onError = OE_Abort; } if( onError!=OE_Abort && onError!=OE_Rollback ){ return 0; /* Cannot do OR REPLACE or OR IGNORE or OR FAIL */ diff --git a/test/insert4.test b/test/insert4.test index cb02b9dccb..8e316448c1 100644 --- a/test/insert4.test +++ b/test/insert4.test @@ -386,4 +386,123 @@ ifcapable foreignkey { } {1} } +# Ticket [676bc02b87176125635cb174d110b431581912bb] +# Make sure INTEGER PRIMARY KEY ON CONFLICT ... works with the xfer +# optimization. +# +do_test insert4-8.1 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT REPLACE, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 3} +do_test insert4-8.2 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b); + CREATE TABLE t2(x, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 3} +do_test insert4-8.3 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT IGNORE, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT IGNORE, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 2} +do_test insert4-8.4 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT IGNORE, b); + CREATE TABLE t2(x, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 2} +do_test insert4-8.5 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT FAIL, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT FAIL, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(-99,100); + INSERT INTO t2 VALUES(1,3); + SELECT * FROM t1; + } + catchsql { + INSERT INTO t1 SELECT * FROM t2; + } +} {1 {PRIMARY KEY must be unique}} +do_test insert4-8.6 { + execsql { + SELECT * FROM t1; + } +} {-99 100 1 2} +do_test insert4-8.7 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ABORT, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ABORT, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(-99,100); + INSERT INTO t2 VALUES(1,3); + SELECT * FROM t1; + } + catchsql { + INSERT INTO t1 SELECT * FROM t2; + } +} {1 {PRIMARY KEY must be unique}} +do_test insert4-8.8 { + execsql { + SELECT * FROM t1; + } +} {1 2} +do_test insert4-8.9 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(-99,100); + INSERT INTO t2 VALUES(1,3); + SELECT * FROM t1; + } + catchsql { + BEGIN; + INSERT INTO t1 VALUES(2,3); + INSERT INTO t1 SELECT * FROM t2; + } +} {1 {PRIMARY KEY must be unique}} +do_test insert4-8.10 { + catchsql {COMMIT} +} {1 {cannot commit - no transaction is active}} +do_test insert4-8.11 { + execsql { + SELECT * FROM t1; + } +} {1 2} + + finish_test From 6ac7a58b144906b70f184c6731668c2b0a1dec3d Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 4 Nov 2011 00:35:56 +0000 Subject: [PATCH 003/161] Enhance the shell so that the ".schema" command works with case insensitive LIKE patterns even with PRAGMA cache_sensitive_like=ON. FossilOrigin-Name: b06bf3b3605a3c39cdfbb76c9a9f6b5202bb95ec --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 178b6147a5..7821e33a9a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\sINSERT\sINTO\s...\sSELECT\sstatement\sworks\scorrectly\seven\swhen\nthe\sdestination\stable\scontains\san\sINTEGER\sPRIMARY\sKEY\sON\sCONFLICT...\scolumn.\nTicket\s[676bc02b87176125]. -D 2011-11-04T00:23:53.875 +C Enhance\sthe\sshell\sso\sthat\sthe\s".schema"\scommand\sworks\swith\scase\sinsensitive\nLIKE\spatterns\seven\swith\sPRAGMA\scache_sensitive_like=ON. +D 2011-11-04T00:35:56.173 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -181,7 +181,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 -F src/shell.c f0ab793261ab045a0b8c47fa2707e8a894d2898f +F src/shell.c 6d2ad7f80adc9c8c3195412879af36eb3196c1b6 F src/sqlite.h.in ff950aef7b378963c67add42dda5d446a0b7330e F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h c74457cd2c4bd77683bac76e698bf2ec2d3e13f9 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P c7c6050ef060877ebe77b41d959e9df13f8c9b5e -R 86847a1d583226c862e98772b444bf54 +P 6f9898db7ff0730cc03f561f9c32ef3dee7e5d81 +R d2ce493b65686d96618972d4df6ad36c U drh -Z a5a032e1b2e9278ae9ce6bac983d1037 +Z 773ddc7cfde2cddd1397075b47c1fbba diff --git a/manifest.uuid b/manifest.uuid index 27b9032fb9..943b13cc7b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6f9898db7ff0730cc03f561f9c32ef3dee7e5d81 \ No newline at end of file +b06bf3b3605a3c39cdfbb76c9a9f6b5202bb95ec \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 07623e52a0..11da32aa8f 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2085,7 +2085,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){ " (SELECT sql sql, type type, tbl_name tbl_name, name name" " FROM sqlite_master UNION ALL" " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) " - "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL " + "WHERE lower(tbl_name) LIKE shellstatic()" + " AND type!='meta' AND sql NOTNULL " "ORDER BY substr(type,2,1), name", callback, &data, &zErrMsg); zShellStatic = 0; From 9ef6bc427a4c31266a9282b8cc7df894ad933a6e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 4 Nov 2011 02:24:02 +0000 Subject: [PATCH 004/161] Use mkdir() and rmdir() rather than open() and unlink() to create the lock files with the unix-dotlock VFS. The change is backwards compatible and, we are told, works better on some network filesystems. FossilOrigin-Name: e2f08426d7a84a2ac6148f485b7af377201a175b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_unix.c | 37 ++++++++++++++++++++++--------------- test/syscall.test | 2 +- 4 files changed, 31 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 7821e33a9a..619f91a7e0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sshell\sso\sthat\sthe\s".schema"\scommand\sworks\swith\scase\sinsensitive\nLIKE\spatterns\seven\swith\sPRAGMA\scache_sensitive_like=ON. -D 2011-11-04T00:35:56.173 +C Use\smkdir()\sand\srmdir()\srather\sthan\sopen()\sand\sunlink()\sto\screate\sthe\slock\nfiles\swith\sthe\sunix-dotlock\sVFS.\s\sThe\schange\sis\sbackwards\scompatible\sand,\nwe\sare\stold,\sworks\sbetter\son\ssome\snetwork\sfilesystems. +D 2011-11-04T02:24:02.845 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/os.c 5d9b02782ed36345348d6fe21d7762ed3a9cfd2a F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c ddda0b1c5ae536669634d7bff31b3f8f4d654866 +F src/os_unix.c 32f2ac2adbbba6acb649915a6953524ecf4cf9d5 F src/os_win.c 49d418916428a59d773f39993db0ecde56ab4c37 F src/pager.c ad62daa0c21e27ae332b3ceb4f579a2a97046ddc F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d @@ -699,7 +699,7 @@ F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/superlock.test 7b1167925e9d30a5d1f0701d24812fdda42c3a86 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 -F test/syscall.test 966addf703faee6a5d509abe6d8885e393e552fd +F test/syscall.test 2a922050dbee032f587249b070fb42692f5e1e22 F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f F test/table.test a59d985ca366e39b17b175f387f9d5db5a18d4e2 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 6f9898db7ff0730cc03f561f9c32ef3dee7e5d81 -R d2ce493b65686d96618972d4df6ad36c +P b06bf3b3605a3c39cdfbb76c9a9f6b5202bb95ec +R 044a4088718b0a84e4c3090a9efafe25 U drh -Z 773ddc7cfde2cddd1397075b47c1fbba +Z 61f6de61b36ef0e121c72533e9e5fa9c diff --git a/manifest.uuid b/manifest.uuid index 943b13cc7b..313b234dee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b06bf3b3605a3c39cdfbb76c9a9f6b5202bb95ec \ No newline at end of file +e2f08426d7a84a2ac6148f485b7af377201a175b \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 0ea6daf27f..5ca3415a53 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -407,6 +407,12 @@ static struct unix_syscall { { "openDirectory", (sqlite3_syscall_ptr)openDirectory, 0 }, #define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent) + { "mkdir", (sqlite3_syscall_ptr)mkdir, 0 }, +#define osMkdir ((int(*)(const char*,mode_t))aSyscall[18].pCurrent) + + { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 }, +#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) + }; /* End of the overrideable system calls */ /* @@ -1845,8 +1851,8 @@ static int nolockClose(sqlite3_file *id) { ************************* Begin dot-file Locking ****************************** ** ** The dotfile locking implementation uses the existance of separate lock -** files in order to control access to the database. This works on just -** about every filesystem imaginable. But there are serious downsides: +** files (really a directory) to control access to the database. This works +** on just about every filesystem imaginable. But there are serious downsides: ** ** (1) There is zero concurrency. A single reader blocks all other ** connections from reading or writing the database. @@ -1857,15 +1863,15 @@ static int nolockClose(sqlite3_file *id) { ** Nevertheless, a dotlock is an appropriate locking mode for use if no ** other locking strategy is available. ** -** Dotfile locking works by creating a file in the same directory as the -** database and with the same name but with a ".lock" extension added. -** The existance of a lock file implies an EXCLUSIVE lock. All other lock -** types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE. +** Dotfile locking works by creating a subdirectory in the same directory as +** the database and with the same name but with a ".lock" extension added. +** The existance of a lock directory implies an EXCLUSIVE lock. All other +** lock types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE. */ /* ** The file suffix added to the data base filename in order to create the -** lock file. +** lock directory. */ #define DOTLOCK_SUFFIX ".lock" @@ -1932,7 +1938,6 @@ static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { */ static int dotlockLock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; - int fd; char *zLockFile = (char *)pFile->lockingContext; int rc = SQLITE_OK; @@ -1952,9 +1957,9 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) { } /* grab an exclusive lock */ - fd = robust_open(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600); - if( fd<0 ){ - /* failed to open/create the file, someone else may have stolen the lock */ + rc = osMkdir(zLockFile, 0777); + if( rc<0 ){ + /* failed to open/create the lock directory */ int tErrno = errno; if( EEXIST == tErrno ){ rc = SQLITE_BUSY; @@ -1966,7 +1971,6 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) { } return rc; } - robust_close(pFile, fd, __LINE__); /* got it, set the type and return ok */ pFile->eFileLock = eFileLock; @@ -1985,6 +1989,7 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) { static int dotlockUnlock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; char *zLockFile = (char *)pFile->lockingContext; + int rc; assert( pFile ); OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock, @@ -2006,7 +2011,9 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) { /* To fully unlock the database, delete the lock file */ assert( eFileLock==NO_LOCK ); - if( osUnlink(zLockFile) ){ + rc = osRmdir(zLockFile); + if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile); + if( rc<0 ){ int rc = 0; int tErrno = errno; if( ENOENT != tErrno ){ @@ -5715,7 +5722,7 @@ static int proxyCreateLockPath(const char *lockPath){ if( i-start>2 || (i-start==1 && buf[start] != '.' && buf[start] != '/') || (i-start==2 && buf[start] != '.' && buf[start+1] != '.') ){ buf[i]='\0'; - if( mkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){ + if( osMkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){ int err=errno; if( err!=EEXIST ) { OSTRACE(("CREATELOCKPATH FAILED creating %s, " @@ -6751,7 +6758,7 @@ int sqlite3_os_init(void){ /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ - assert( ArraySize(aSyscall)==18 ); + assert( ArraySize(aSyscall)==20 ); /* Register all VFSes defined in the aVfs[] array */ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ diff --git a/test/syscall.test b/test/syscall.test index 201bd63647..b67bead7da 100644 --- a/test/syscall.test +++ b/test/syscall.test @@ -59,7 +59,7 @@ do_test 2.1.2 { test_syscall exists nosuchcall } 0 foreach s { open close access getcwd stat fstat ftruncate fcntl read pread write pwrite fchmod fallocate - pread64 pwrite64 unlink openDirectory + pread64 pwrite64 unlink openDirectory mkdir rmdir } { if {[test_syscall exists $s]} {lappend syscall_list $s} } From 689e38f7cfd8515155157df242f361853a7ec04e Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 4 Nov 2011 10:37:21 +0000 Subject: [PATCH 005/161] Add a missing va_end() macro to fts3.c. FossilOrigin-Name: e6f825748a1d510c8f5529c79656bb5db9216231 --- ext/fts3/fts3.c | 1 + manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 12013f2b72..88a4148acb 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -712,6 +712,7 @@ static void fts3Appendf( char *z; va_start(ap, zFormat); z = sqlite3_vmprintf(zFormat, ap); + va_end(ap); if( z && *pz ){ char *z2 = sqlite3_mprintf("%s%s", *pz, z); sqlite3_free(z); diff --git a/manifest b/manifest index 619f91a7e0..c196c22622 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\smkdir()\sand\srmdir()\srather\sthan\sopen()\sand\sunlink()\sto\screate\sthe\slock\nfiles\swith\sthe\sunix-dotlock\sVFS.\s\sThe\schange\sis\sbackwards\scompatible\sand,\nwe\sare\stold,\sworks\sbetter\son\ssome\snetwork\sfilesystems. -D 2011-11-04T02:24:02.845 +C Add\sa\smissing\sva_end()\smacro\sto\sfts3.c. +D 2011-11-04T10:37:21.486 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -63,7 +63,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers 998756696647400de63d5ba60e9655036cb966e9 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 246ef2d0cef67517d156d39c9247cd6c432f0d79 +F ext/fts3/fts3.c bd570b99f1f65b17d587361a421d7f2f28082aa0 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h def7a900f98c5ab5fa4772e922bfa219d5097f05 F ext/fts3/fts3_aux.c 0ebfa7b86cf8ff6a0861605fcc63b83ec1b70691 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P b06bf3b3605a3c39cdfbb76c9a9f6b5202bb95ec -R 044a4088718b0a84e4c3090a9efafe25 -U drh -Z 61f6de61b36ef0e121c72533e9e5fa9c +P e2f08426d7a84a2ac6148f485b7af377201a175b +R 19c57c219de81f8809cf2fb3735a6990 +U dan +Z 0b59c1e4adcdd28152b0ec79ab89340f diff --git a/manifest.uuid b/manifest.uuid index 313b234dee..c2a1699c25 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2f08426d7a84a2ac6148f485b7af377201a175b \ No newline at end of file +e6f825748a1d510c8f5529c79656bb5db9216231 \ No newline at end of file From d28286181d3b739e0c177323f021107b7756793a Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 4 Nov 2011 12:05:52 +0000 Subject: [PATCH 006/161] Change a memcpy() in sqlite3FileSuffix() to memmove() on the grounds that the source and destination may overlap. FossilOrigin-Name: 5e1d247e5b3b5dcf6763f01002e996786db48152 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/util.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index c196c22622..9d5ac1b65e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\smissing\sva_end()\smacro\sto\sfts3.c. -D 2011-11-04T10:37:21.486 +C Change\sa\smemcpy()\sin\ssqlite3FileSuffix()\sto\smemmove()\son\sthe\sgrounds\sthat\sthe\ssource\sand\sdestination\smay\soverlap. +D 2011-11-04T12:05:52.920 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -237,7 +237,7 @@ F src/tokenize.c c819d9f72168a035d545a5bdafe9b085b20df705 F src/trigger.c 1cfb80e2290ef66ea89cb4e821caae65a02c0d56 F src/update.c 25e046a8f69d5e557aabde2000487b8545509d8d F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 -F src/util.c df83983bd57057df4951516880066b42b7055269 +F src/util.c 01238e2b0f24a14779181dbf991fe02620a80e31 F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa F src/vdbe.c 326994a64a9a08853122200dc9f62cb96b8f0831 F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P e2f08426d7a84a2ac6148f485b7af377201a175b -R 19c57c219de81f8809cf2fb3735a6990 +P e6f825748a1d510c8f5529c79656bb5db9216231 +R 68c2a70c630ede591afbf936bbf79f75 U dan -Z 0b59c1e4adcdd28152b0ec79ab89340f +Z 793b5014c789d9668df6d06bf87edd80 diff --git a/manifest.uuid b/manifest.uuid index c2a1699c25..569c8aea30 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e6f825748a1d510c8f5529c79656bb5db9216231 \ No newline at end of file +5e1d247e5b3b5dcf6763f01002e996786db48152 \ No newline at end of file diff --git a/src/util.c b/src/util.c index 3356417e0c..ffbf7daadf 100644 --- a/src/util.c +++ b/src/util.c @@ -1180,7 +1180,7 @@ void sqlite3FileSuffix3(const char *zBaseFilename, char *z){ int i, sz; sz = sqlite3Strlen30(z); for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} - if( z[i]=='.' && ALWAYS(sz>i+4) ) memcpy(&z[i+1], &z[sz-3], 4); + if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4); } } #endif From ccdf1baebfc468672c9214c48245825f8fc65d4e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 4 Nov 2011 14:36:02 +0000 Subject: [PATCH 007/161] Update the xfer optimization code so that the xfer optimization can be used with INTEGER PRIMARY KEY ON CONFLICT ... as long as the destination table is initially empty. Improvements to the comments on the xfer optimization. New test cases added. FossilOrigin-Name: e3f368cd5ef66a56fd4bd05a77276039e26b9e0e --- manifest | 16 +++++----- manifest.uuid | 2 +- src/insert.c | 78 ++++++++++++++++++++++------------------------- test/insert4.test | 56 ++++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 51 deletions(-) diff --git a/manifest b/manifest index 9d5ac1b65e..293e80acf9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sa\smemcpy()\sin\ssqlite3FileSuffix()\sto\smemmove()\son\sthe\sgrounds\sthat\sthe\ssource\sand\sdestination\smay\soverlap. -D 2011-11-04T12:05:52.920 +C Update\sthe\sxfer\soptimization\scode\sso\sthat\sthe\sxfer\soptimization\scan\sbe\sused\nwith\sINTEGER\sPRIMARY\sKEY\sON\sCONFLICT\s...\sas\slong\sas\sthe\sdestination\stable\nis\sinitially\sempty.\s\sImprovements\sto\sthe\scomments\son\sthe\sxfer\soptimization.\nNew\stest\scases\sadded. +D 2011-11-04T14:36:02.150 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -142,7 +142,7 @@ F src/global.c e230227de13601714b29f9363028514aada5ae2f F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c bfe25a1d333658bd6f79fded6581d8a6962ce272 +F src/insert.c 9794a963911da8157ad0dc39726c9c695b1c4692 F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 @@ -525,7 +525,7 @@ F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/insert.test aef273dd1cee84cc92407469e6bd1b3cdcb76908 F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435 F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30 -F test/insert4.test 03f1644c4f2393e26e6b12d105ce375811178ace +F test/insert4.test 87f6798f31d60c4e177622fcc3663367e6ecbd90 F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4 F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P e6f825748a1d510c8f5529c79656bb5db9216231 -R 68c2a70c630ede591afbf936bbf79f75 -U dan -Z 793b5014c789d9668df6d06bf87edd80 +P 5e1d247e5b3b5dcf6763f01002e996786db48152 +R 97a1f3cbe9769d6539f852a4f755f4f2 +U drh +Z c28f9972b18a5ec408f3c191a9ff9538 diff --git a/manifest.uuid b/manifest.uuid index 569c8aea30..9171da14c6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5e1d247e5b3b5dcf6763f01002e996786db48152 \ No newline at end of file +e3f368cd5ef66a56fd4bd05a77276039e26b9e0e \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 72fba06efd..bfcd2c2536 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1578,31 +1578,25 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){ ** ** INSERT INTO tab1 SELECT * FROM tab2; ** -** This optimization is only attempted if +** The xfer optimization transfers raw records from tab2 over to tab1. +** Columns are not decoded and reassemblied, which greatly improves +** performance. Raw index records are transferred in the same way. ** -** (1) tab1 and tab2 have identical schemas including all the -** same indices and constraints +** The xfer optimization is only attempted if tab1 and tab2 are compatible. +** There are lots of rules for determining compatibility - see comments +** embedded in the code for details. ** -** (2) tab1 and tab2 are different tables +** This routine returns TRUE if the optimization is guaranteed to be used. +** Sometimes the xfer optimization will only work if the destination table +** is empty - a factor that can only be determined at run-time. In that +** case, this routine generates code for the xfer optimization but also +** does a test to see if the destination table is empty and jumps over the +** xfer optimization code if the test fails. In that case, this routine +** returns FALSE so that the caller will know to go ahead and generate +** an unoptimized transfer. This routine also returns FALSE if there +** is no chance that the xfer optimization can be applied. ** -** (3) There must be no triggers on tab1 -** -** (4) The result set of the SELECT statement is "*" -** -** (5) The SELECT statement has no WHERE, HAVING, ORDER BY, GROUP BY, -** or LIMIT clause. -** -** (6) The SELECT statement is a simple (not a compound) select that -** contains only tab2 in its FROM clause -** -** This method for implementing the INSERT transfers raw records from -** tab2 over to tab1. The columns are not decoded. Raw records from -** the indices of tab2 are transfered to tab1 as well. In so doing, -** the resulting tab1 has much less fragmentation. -** -** This routine returns TRUE if the optimization is attempted. If any -** of the conditions above fail so that the optimization should not -** be attempted, then this routine returns FALSE. +** This optimization is particularly useful at making VACUUM run faster. */ static int xferOptimization( Parse *pParse, /* Parser context */ @@ -1642,9 +1636,6 @@ static int xferOptimization( if( pDest->iPKey>=0 ) onError = pDest->keyConf; if( onError==OE_Default ) onError = OE_Abort; } - if( onError!=OE_Abort && onError!=OE_Rollback ){ - return 0; /* Cannot do OR REPLACE or OR IGNORE or OR FAIL */ - } assert(pSelect->pSrc); /* allocated even if there is no FROM clause */ if( pSelect->pSrc->nSrc!=1 ){ return 0; /* FROM clause must have exactly one term */ @@ -1749,16 +1740,12 @@ static int xferOptimization( } #endif if( (pParse->db->flags & SQLITE_CountRows)!=0 ){ - return 0; + return 0; /* xfer opt does not play well with PRAGMA count_changes */ } - /* If we get this far, it means either: - ** - ** * We can always do the transfer if the table contains an - ** an integer primary key - ** - ** * We can conditionally do the transfer if the destination - ** table is empty. + /* If we get this far, it means that the xfer optimization is at + ** least a possibility, though it might only work if the destination + ** table (tab1) is initially empty. */ #ifdef SQLITE_TEST sqlite3_xferopt_count++; @@ -1770,16 +1757,23 @@ static int xferOptimization( iDest = pParse->nTab++; regAutoinc = autoIncBegin(pParse, iDbDest, pDest); sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); - if( (pDest->iPKey<0 && pDest->pIndex!=0) || destHasUniqueIdx ){ - /* If tables do not have an INTEGER PRIMARY KEY and there - ** are indices to be copied and the destination is not empty, - ** we have to disallow the transfer optimization because the - ** the rowids might change which will mess up indexing. + if( (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */ + || destHasUniqueIdx /* (2) */ + || (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */ + ){ + /* In some circumstances, we are able to run the xfer optimization + ** only if the destination table is initially empty. This code makes + ** that determination. Conditions under which the destination must + ** be empty: ** - ** Or if the destination has a UNIQUE index and is not empty, - ** we also disallow the transfer optimization because we cannot - ** insure that all entries in the union of DEST and SRC will be - ** unique. + ** (1) There is no INTEGER PRIMARY KEY but there are indices. + ** (If the destination is not initially empty, the rowid fields + ** of index entries might need to change.) + ** + ** (2) The destination has a unique index. (The xfer optimization + ** is unable to test uniqueness.) + ** + ** (3) onError is something other than OE_Abort and OE_Rollback. */ addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); diff --git a/test/insert4.test b/test/insert4.test index 8e316448c1..f4a45c182c 100644 --- a/test/insert4.test +++ b/test/insert4.test @@ -504,5 +504,61 @@ do_test insert4-8.11 { } } {1 2} +do_test insert4-8.21 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT REPLACE, y); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 3} +do_test insert4-8.22 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT IGNORE, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT IGNORE, y); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 3} +do_test insert4-8.23 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ABORT, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ABORT, y); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 3} +do_test insert4-8.24 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT FAIL, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT FAIL, y); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 3} +do_test insert4-8.25 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, y); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 3} + finish_test From f673e09ef5b4898e65901a78217df652c459a930 Mon Sep 17 00:00:00 2001 From: dan Date: Sun, 6 Nov 2011 05:06:13 +0000 Subject: [PATCH 008/161] Move function sqlite3PagerClearCache() out of the "ifndef SQLITE_OMIT_WAL" block and into an "ifndef SQLITE_OMIT_VACUUM" block. FossilOrigin-Name: 5dbfaed8c3e09ea35033dacf6faa3d6a0202cc68 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pager.c | 16 +++++++++------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 293e80acf9..170c7e2fa6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sxfer\soptimization\scode\sso\sthat\sthe\sxfer\soptimization\scan\sbe\sused\nwith\sINTEGER\sPRIMARY\sKEY\sON\sCONFLICT\s...\sas\slong\sas\sthe\sdestination\stable\nis\sinitially\sempty.\s\sImprovements\sto\sthe\scomments\son\sthe\sxfer\soptimization.\nNew\stest\scases\sadded. -D 2011-11-04T14:36:02.150 +C Move\sfunction\ssqlite3PagerClearCache()\sout\sof\sthe\s"ifndef\sSQLITE_OMIT_WAL"\sblock\sand\sinto\san\s"ifndef\sSQLITE_OMIT_VACUUM"\sblock. +D 2011-11-06T05:06:13.597 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -168,7 +168,7 @@ F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 32f2ac2adbbba6acb649915a6953524ecf4cf9d5 F src/os_win.c 49d418916428a59d773f39993db0ecde56ab4c37 -F src/pager.c ad62daa0c21e27ae332b3ceb4f579a2a97046ddc +F src/pager.c db33d4bf1e3e019c34c220971cc6c3aa07c30f54 F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 F src/pcache.c 49e718c095810c6b3334e3a6d89970aceaddefce @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 5e1d247e5b3b5dcf6763f01002e996786db48152 -R 97a1f3cbe9769d6539f852a4f755f4f2 -U drh -Z c28f9972b18a5ec408f3c191a9ff9538 +P e3f368cd5ef66a56fd4bd05a77276039e26b9e0e +R 5c39124f3d2f2639b32de1100072ae22 +U dan +Z 40b32dc92ad17e089c0e0585e705b0ef diff --git a/manifest.uuid b/manifest.uuid index 9171da14c6..7d99104f38 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e3f368cd5ef66a56fd4bd05a77276039e26b9e0e \ No newline at end of file +5dbfaed8c3e09ea35033dacf6faa3d6a0202cc68 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 63dda3ddff..6900610b20 100644 --- a/src/pager.c +++ b/src/pager.c @@ -6660,6 +6660,15 @@ sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ return &pPager->pBackup; } +#ifndef SQLITE_OMIT_VACUUM +/* +** Unless this is an in-memory or temporary database, clear the pager cache. +*/ +void sqlite3PagerClearCache(Pager *pPager){ + if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager); +} +#endif + #ifndef SQLITE_OMIT_WAL /* ** This function is called when the user invokes "PRAGMA wal_checkpoint", @@ -6836,13 +6845,6 @@ int sqlite3PagerCloseWal(Pager *pPager){ return rc; } -/* -** Unless this is an in-memory or temporary database, clear the pager cache. -*/ -void sqlite3PagerClearCache(Pager *pPager){ - if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager); -} - #ifdef SQLITE_HAS_CODEC /* ** This function is called by the wal module when writing page content From bf3f5f8d5c12357c3253a44265b7c459fdc63943 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 7 Nov 2011 13:05:23 +0000 Subject: [PATCH 009/161] Change the default file format from 1 to 4. This means that, unless PRAGMA legacy_file_format=ON is used first, new databases will not be readable by versions prior to 3.3.0 (2006-01-10). FossilOrigin-Name: a35f52b1ad22c2ad49fb1083f892b92c72da348c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 170c7e2fa6..d002e948e8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\sfunction\ssqlite3PagerClearCache()\sout\sof\sthe\s"ifndef\sSQLITE_OMIT_WAL"\sblock\sand\sinto\san\s"ifndef\sSQLITE_OMIT_VACUUM"\sblock. -D 2011-11-06T05:06:13.597 +C Change\sthe\sdefault\sfile\sformat\sfrom\s1\sto\s4.\s\sThis\smeans\sthat,\sunless\nPRAGMA\slegacy_file_format=ON\sis\sused\sfirst,\nnew\sdatabases\swill\snot\sbe\sreadable\sby\sversions\sprior\sto\s3.3.0\s(2006-01-10). +D 2011-11-07T13:05:23.752 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -184,7 +184,7 @@ F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 F src/shell.c 6d2ad7f80adc9c8c3195412879af36eb3196c1b6 F src/sqlite.h.in ff950aef7b378963c67add42dda5d446a0b7330e F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h c74457cd2c4bd77683bac76e698bf2ec2d3e13f9 +F src/sqliteInt.h b0b6df8f7fe739e3cd718debb60f58853666d13e F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P e3f368cd5ef66a56fd4bd05a77276039e26b9e0e -R 5c39124f3d2f2639b32de1100072ae22 -U dan -Z 40b32dc92ad17e089c0e0585e705b0ef +P 5dbfaed8c3e09ea35033dacf6faa3d6a0202cc68 +R 91210a7cb330216247f576d63b7cb22e +U drh +Z ee567ee7aeddc37d4ee7c9054a23b5ee diff --git a/manifest.uuid b/manifest.uuid index 7d99104f38..b28f6e03e9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5dbfaed8c3e09ea35033dacf6faa3d6a0202cc68 \ No newline at end of file +a35f52b1ad22c2ad49fb1083f892b92c72da348c \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9e276541c6..2171c15749 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -346,7 +346,7 @@ */ #define SQLITE_MAX_FILE_FORMAT 4 #ifndef SQLITE_DEFAULT_FILE_FORMAT -# define SQLITE_DEFAULT_FILE_FORMAT 1 +# define SQLITE_DEFAULT_FILE_FORMAT 4 #endif /* From f4fd9ed3cd852dc1645a1588b766fdb94d3301c9 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 7 Nov 2011 16:46:43 +0000 Subject: [PATCH 010/161] Add a makefile target for tclsqlite3.c to Makefile.in. FossilOrigin-Name: f521b6b7e42c82f09a91df5a5acf4e46c860e72a --- Makefile.in | 6 ++++++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Makefile.in b/Makefile.in index cbcf8eca43..14ceb38cbc 100644 --- a/Makefile.in +++ b/Makefile.in @@ -518,6 +518,12 @@ sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl +tclsqlite3.c: sqlite3.c + echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c + cat sqlite3.c >>tclsqlite3.c + echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c + cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c + sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl $(TCLSH_CMD) $(TOP)/tool/split-sqlite3c.tcl diff --git a/manifest b/manifest index d002e948e8..f9985f32f0 100644 --- a/manifest +++ b/manifest @@ -1,7 +1,7 @@ -C Change\sthe\sdefault\sfile\sformat\sfrom\s1\sto\s4.\s\sThis\smeans\sthat,\sunless\nPRAGMA\slegacy_file_format=ON\sis\sused\sfirst,\nnew\sdatabases\swill\snot\sbe\sreadable\sby\sversions\sprior\sto\s3.3.0\s(2006-01-10). -D 2011-11-07T13:05:23.752 +C Add\sa\smakefile\starget\sfor\stclsqlite3.c\sto\sMakefile.in. +D 2011-11-07T16:46:43.166 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 +F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.msc dcad80fa69f17d46fe6778ba873fc108ca16298d F Makefile.vxworks 1deb39c8bb047296c30161ffa10c1b5423e632f9 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 5dbfaed8c3e09ea35033dacf6faa3d6a0202cc68 -R 91210a7cb330216247f576d63b7cb22e +P a35f52b1ad22c2ad49fb1083f892b92c72da348c +R f257df2fa7b8aed0523718d037ef131f U drh -Z ee567ee7aeddc37d4ee7c9054a23b5ee +Z 0907ff28d067a85c58af2436afc0a409 diff --git a/manifest.uuid b/manifest.uuid index b28f6e03e9..e2691f54e9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a35f52b1ad22c2ad49fb1083f892b92c72da348c \ No newline at end of file +f521b6b7e42c82f09a91df5a5acf4e46c860e72a \ No newline at end of file From a46739eae0b16a4cef596f12853621b14625f1c4 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 7 Nov 2011 17:54:26 +0000 Subject: [PATCH 011/161] Amplify the restriction on commit-hooks that they cannot recursively run SQL on the same database connection. FossilOrigin-Name: 4fe5b73115a8b44950767f1b528107261d7312c9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f9985f32f0..fddf3bd484 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\smakefile\starget\sfor\stclsqlite3.c\sto\sMakefile.in. -D 2011-11-07T16:46:43.166 +C Amplify\sthe\srestriction\son\scommit-hooks\sthat\sthey\scannot\srecursively\nrun\sSQL\son\sthe\ssame\sdatabase\sconnection. +D 2011-11-07T17:54:26.821 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -182,7 +182,7 @@ F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 F src/shell.c 6d2ad7f80adc9c8c3195412879af36eb3196c1b6 -F src/sqlite.h.in ff950aef7b378963c67add42dda5d446a0b7330e +F src/sqlite.h.in b7a4e8d428e467d820cbb4c1d275fdda88b4d7ab F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h b0b6df8f7fe739e3cd718debb60f58853666d13e F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P a35f52b1ad22c2ad49fb1083f892b92c72da348c -R f257df2fa7b8aed0523718d037ef131f +P f521b6b7e42c82f09a91df5a5acf4e46c860e72a +R 55cca41ab47514d8db108b3f26e18c32 U drh -Z 0907ff28d067a85c58af2436afc0a409 +Z a1378b40deb34e0ef30ad969852d18f3 diff --git a/manifest.uuid b/manifest.uuid index e2691f54e9..46bd34afcc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f521b6b7e42c82f09a91df5a5acf4e46c860e72a \ No newline at end of file +4fe5b73115a8b44950767f1b528107261d7312c9 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index ed18330748..9679965ce2 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4401,13 +4401,15 @@ sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); ** on the same [database connection] D, or NULL for ** the first call for each function on D. ** +** The commit and rollback hook callbacks are not reentrant. ** The callback implementation must not do anything that will modify ** the database connection that invoked the callback. Any actions ** to modify the database connection must be deferred until after the ** completion of the [sqlite3_step()] call that triggered the commit ** or rollback hook in the first place. -** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their -** database connections for the meaning of "modify" in this paragraph. +** Note that running any other SQL statements, including SELECT statements, +** or merely calling [sqlite3_prepare_v2()] and [sqlite3_step()] will modify +** the database connections for the meaning of "modify" in this paragraph. ** ** ^Registering a NULL function disables the callback. ** From 5802464316abd24623bdd62e028bf4ad6ed1c184 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 7 Nov 2011 18:16:00 +0000 Subject: [PATCH 012/161] Make the unix VFS tolerant of read() calls that return less than the requested number of bytes. FossilOrigin-Name: a210695abcfa5cb04279edfd04824d881b7c4ada --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 51 ++++++++++++++++++++++++++++++++------------------- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index fddf3bd484..4ac21d9d50 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Amplify\sthe\srestriction\son\scommit-hooks\sthat\sthey\scannot\srecursively\nrun\sSQL\son\sthe\ssame\sdatabase\sconnection. -D 2011-11-07T17:54:26.821 +C Make\sthe\sunix\sVFS\stolerant\sof\sread()\scalls\sthat\sreturn\sless\sthan\sthe\nrequested\snumber\sof\sbytes. +D 2011-11-07T18:16:00.449 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/os.c 5d9b02782ed36345348d6fe21d7762ed3a9cfd2a F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c 32f2ac2adbbba6acb649915a6953524ecf4cf9d5 +F src/os_unix.c 4fbb91726165e105c1679a2660f49a3f4c376e4f F src/os_win.c 49d418916428a59d773f39993db0ecde56ab4c37 F src/pager.c db33d4bf1e3e019c34c220971cc6c3aa07c30f54 F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P f521b6b7e42c82f09a91df5a5acf4e46c860e72a -R 55cca41ab47514d8db108b3f26e18c32 +P 4fe5b73115a8b44950767f1b528107261d7312c9 +R 235506ff1af96e54491bff797f85e25a U drh -Z a1378b40deb34e0ef30ad969852d18f3 +Z b43cdd5d2255740ef7ed4b6994dd0923 diff --git a/manifest.uuid b/manifest.uuid index 46bd34afcc..26a5869430 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4fe5b73115a8b44950767f1b528107261d7312c9 \ No newline at end of file +a210695abcfa5cb04279edfd04824d881b7c4ada \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 5ca3415a53..51d144906a 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -2951,35 +2951,48 @@ static int nfsUnlock(sqlite3_file *id, int eFileLock){ */ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ int got; + int prior = 0; #if (!defined(USE_PREAD) && !defined(USE_PREAD64)) i64 newOffset; #endif TIMER_START; + do{ #if defined(USE_PREAD) - do{ got = osPread(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR ); - SimulateIOError( got = -1 ); + got = osPread(id->h, pBuf, cnt, offset); + SimulateIOError( got = -1 ); #elif defined(USE_PREAD64) - do{ got = osPread64(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR); - SimulateIOError( got = -1 ); + got = osPread64(id->h, pBuf, cnt, offset); + SimulateIOError( got = -1 ); #else - newOffset = lseek(id->h, offset, SEEK_SET); - SimulateIOError( newOffset-- ); - if( newOffset!=offset ){ - if( newOffset == -1 ){ - ((unixFile*)id)->lastErrno = errno; - }else{ - ((unixFile*)id)->lastErrno = 0; + newOffset = lseek(id->h, offset, SEEK_SET); + SimulateIOError( newOffset-- ); + if( newOffset!=offset ){ + if( newOffset == -1 ){ + ((unixFile*)id)->lastErrno = errno; + }else{ + ((unixFile*)id)->lastErrno = 0; + } + return -1; } - return -1; - } - do{ got = osRead(id->h, pBuf, cnt); }while( got<0 && errno==EINTR ); + got = osRead(id->h, pBuf, cnt); #endif + if( got==cnt ) break; + if( got<0 ){ + if( errno==EINTR ){ got = 1; continue; } + prior = 0; + ((unixFile*)id)->lastErrno = errno; + break; + }else if( got>0 ){ + cnt -= got; + offset += got; + prior += got; + pBuf = (void*)(got + (char*)pBuf); + } + }while( got>0 ); TIMER_END; - if( got<0 ){ - ((unixFile*)id)->lastErrno = errno; - } - OSTRACE(("READ %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED)); - return got; + OSTRACE(("READ %-3d %5d %7lld %llu\n", + id->h, got+prior, offset-prior, TIMER_ELAPSED)); + return got+prior; } /* From 22e21ff4fc04b67f176060f5f3471a9b4a8afa70 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 8 Nov 2011 20:08:44 +0000 Subject: [PATCH 013/161] Experimental change to the pcache interface to allow page buffers to be allocated separately from their associated container structures. FossilOrigin-Name: c275c9d323cb1dccb031b199d413ac3a0b244fea --- manifest | 35 +++++++++-------- manifest.uuid | 2 +- src/global.c | 2 +- src/main.c | 19 ++++++--- src/pcache.c | 76 +++++++++++++++++++----------------- src/pcache.h | 3 +- src/pcache1.c | 92 +++++++++++++++++++++++++------------------- src/sqlite.h.in | 23 +++++++++++ src/sqliteInt.h | 2 +- src/test_init.c | 29 ++++++++------ src/test_pcache.c | 49 +++++++++++++---------- test/memsubsys1.test | 2 +- 12 files changed, 201 insertions(+), 133 deletions(-) diff --git a/manifest b/manifest index 4ac21d9d50..e2c1f41759 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\sunix\sVFS\stolerant\sof\sread()\scalls\sthat\sreturn\sless\sthan\sthe\nrequested\snumber\sof\sbytes. -D 2011-11-07T18:16:00.449 +C Experimental\schange\sto\sthe\spcache\sinterface\sto\sallow\spage\sbuffers\sto\sbe\sallocated\sseparately\sfrom\stheir\sassociated\scontainer\sstructures. +D 2011-11-08T20:08:44.098 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -138,7 +138,7 @@ F src/expr.c fbf116f90cabc917ae50bba24a73a0b55519a0c8 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5 F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9 -F src/global.c e230227de13601714b29f9363028514aada5ae2f +F src/global.c 107ccaacb4b30895cf3a3a39decf417c804acfa1 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 @@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f -F src/main.c df06f5229b8046f85dde253dfd7fe35ae9e4902e +F src/main.c 93d49bc6abf4ccea97721d016b9f45228cff7057 F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206 @@ -171,9 +171,9 @@ F src/os_win.c 49d418916428a59d773f39993db0ecde56ab4c37 F src/pager.c db33d4bf1e3e019c34c220971cc6c3aa07c30f54 F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 -F src/pcache.c 49e718c095810c6b3334e3a6d89970aceaddefce -F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 -F src/pcache1.c 24f5e85a78514584b46190260ba7ab0a66312197 +F src/pcache.c fad8646667e074d06e29028029a0440d852497e5 +F src/pcache.h c770382f9fae4ca5025c5523bd0aa13cd6ddc6f8 +F src/pcache1.c 54fc4ed623157b6f706da961c1d3776a40aa131d F src/pragma.c da8ef96b3eec351e81e0061c39810e548bcc96d7 F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4 F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869 @@ -182,9 +182,9 @@ F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 F src/shell.c 6d2ad7f80adc9c8c3195412879af36eb3196c1b6 -F src/sqlite.h.in b7a4e8d428e467d820cbb4c1d275fdda88b4d7ab +F src/sqlite.h.in c436f15dd27782e83d532651394c41fe4b96d1b0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h b0b6df8f7fe739e3cd718debb60f58853666d13e +F src/sqliteInt.h f87f241b9821a9d466c2711b7345d30ef3624249 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -208,7 +208,7 @@ F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 F src/test_fuzzer.c f884f6f32e8513d34248d6e1ac8a32047fead254 F src/test_hexio.c c4773049603151704a6ab25ac5e936b5109caf5a -F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c +F src/test_init.c 1ff3a696ca45e3c4cd7639217ded5d9c41428fed F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99 F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff @@ -219,7 +219,7 @@ F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32 -F src/test_pcache.c 7bf828972ac0d2403f5cfa4cd14da41f8ebe73d8 +F src/test_pcache.c 708147942470815963efa7a58fe63470a1943a5e F src/test_quota.c a391c866217e92986c6f523f05b08aa6956c8419 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 @@ -592,7 +592,7 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f F test/memdb.test 708a028d6d373e5b3842e4bdc8ba80998c9a4da6 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 -F test/memsubsys1.test 16ce163ac1ace3d71bf0eaa6a821ed153addd91f +F test/memsubsys1.test c0db8a1e99f4fa07cb858900c55bad9547899aa8 F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9 F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0 @@ -974,7 +974,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 4fe5b73115a8b44950767f1b528107261d7312c9 -R 235506ff1af96e54491bff797f85e25a -U drh -Z b43cdd5d2255740ef7ed4b6994dd0923 +P a210695abcfa5cb04279edfd04824d881b7c4ada +R 753cd5b3a540b0935d5201e586350091 +T *branch * experimental-pcache +T *sym-experimental-pcache * +T -sym-trunk * +U dan +Z 65dd88e6b6c81cfeaddd0d87f1e89623 diff --git a/manifest.uuid b/manifest.uuid index 26a5869430..9631c1e9b1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a210695abcfa5cb04279edfd04824d881b7c4ada \ No newline at end of file +c275c9d323cb1dccb031b199d413ac3a0b244fea \ No newline at end of file diff --git a/src/global.c b/src/global.c index 1e691c4494..b8a8a49d3d 100644 --- a/src/global.c +++ b/src/global.c @@ -147,7 +147,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = { 500, /* nLookaside */ {0,0,0,0,0,0,0,0}, /* m */ {0,0,0,0,0,0,0,0,0}, /* mutex */ - {0,0,0,0,0,0,0,0,0,0,0}, /* pcache */ + {0,0,0,0,0,0,0,0,0,0,0}, /* pcache2 */ (void*)0, /* pHeap */ 0, /* nHeap */ 0, 0, /* mnHeap, mxHeap */ diff --git a/src/main.c b/src/main.c index 42bbba5d01..6e6af78c7a 100644 --- a/src/main.c +++ b/src/main.c @@ -365,16 +365,25 @@ int sqlite3_config(int op, ...){ } case SQLITE_CONFIG_PCACHE: { - /* Specify an alternative page cache implementation */ - sqlite3GlobalConfig.pcache = *va_arg(ap, sqlite3_pcache_methods*); + /* no-op */ + break; + } + case SQLITE_CONFIG_GETPCACHE: { + /* now an error */ + rc = SQLITE_ERROR; break; } - case SQLITE_CONFIG_GETPCACHE: { - if( sqlite3GlobalConfig.pcache.xInit==0 ){ + case SQLITE_CONFIG_PCACHE2: { + /* Specify an alternative page cache implementation */ + sqlite3GlobalConfig.pcache2 = *va_arg(ap, sqlite3_pcache_methods2*); + break; + } + case SQLITE_CONFIG_GETPCACHE2: { + if( sqlite3GlobalConfig.pcache2.xInit==0 ){ sqlite3PCacheSetDefault(); } - *va_arg(ap, sqlite3_pcache_methods*) = sqlite3GlobalConfig.pcache; + *va_arg(ap, sqlite3_pcache_methods2*) = sqlite3GlobalConfig.pcache2; break; } diff --git a/src/pcache.c b/src/pcache.c index f37511e9e4..f689aaa77f 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -131,7 +131,7 @@ static void pcacheUnpin(PgHdr *p){ if( p->pgno==1 ){ pCache->pPage1 = 0; } - sqlite3GlobalConfig.pcache.xUnpin(pCache->pCache, p, 0); + sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 0); } } @@ -141,18 +141,18 @@ static void pcacheUnpin(PgHdr *p){ ** functions are threadsafe. */ int sqlite3PcacheInitialize(void){ - if( sqlite3GlobalConfig.pcache.xInit==0 ){ + if( sqlite3GlobalConfig.pcache2.xInit==0 ){ /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the ** built-in default page cache is used instead of the application defined ** page cache. */ sqlite3PCacheSetDefault(); } - return sqlite3GlobalConfig.pcache.xInit(sqlite3GlobalConfig.pcache.pArg); + return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg); } void sqlite3PcacheShutdown(void){ - if( sqlite3GlobalConfig.pcache.xShutdown ){ + if( sqlite3GlobalConfig.pcache2.xShutdown ){ /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */ - sqlite3GlobalConfig.pcache.xShutdown(sqlite3GlobalConfig.pcache.pArg); + sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg); } } @@ -191,7 +191,7 @@ void sqlite3PcacheOpen( void sqlite3PcacheSetPageSize(PCache *pCache, int szPage){ assert( pCache->nRef==0 && pCache->pDirty==0 ); if( pCache->pCache ){ - sqlite3GlobalConfig.pcache.xDestroy(pCache->pCache); + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); pCache->pCache = 0; pCache->pPage1 = 0; } @@ -207,7 +207,8 @@ int sqlite3PcacheFetch( int createFlag, /* If true, create page if it does not exist already */ PgHdr **ppPage /* Write the page here */ ){ - PgHdr *pPage = 0; + sqlite3_pcache_page *pPage = 0; + PgHdr *pPgHdr = 0; int eCreate; assert( pCache!=0 ); @@ -219,19 +220,19 @@ int sqlite3PcacheFetch( */ if( !pCache->pCache && createFlag ){ sqlite3_pcache *p; - int nByte; - nByte = pCache->szPage + pCache->szExtra + sizeof(PgHdr); - p = sqlite3GlobalConfig.pcache.xCreate(nByte, pCache->bPurgeable); + p = sqlite3GlobalConfig.pcache2.xCreate( + pCache->szExtra + sizeof(PgHdr), pCache->szPage, pCache->bPurgeable + ); if( !p ){ return SQLITE_NOMEM; } - sqlite3GlobalConfig.pcache.xCachesize(p, pCache->nMax); + sqlite3GlobalConfig.pcache2.xCachesize(p, pCache->nMax); pCache->pCache = p; } eCreate = createFlag * (1 + (!pCache->bPurgeable || !pCache->pDirty)); if( pCache->pCache ){ - pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, eCreate); + pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); } if( !pPage && eCreate==1 ){ @@ -266,33 +267,36 @@ int sqlite3PcacheFetch( } } - pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, 2); + pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2); } if( pPage ){ - if( !pPage->pData ){ - memset(pPage, 0, sizeof(PgHdr)); - pPage->pData = (void *)&pPage[1]; - pPage->pExtra = (void*)&((char *)pPage->pData)[pCache->szPage]; - memset(pPage->pExtra, 0, pCache->szExtra); - pPage->pCache = pCache; - pPage->pgno = pgno; - } - assert( pPage->pCache==pCache ); - assert( pPage->pgno==pgno ); - assert( pPage->pData==(void *)&pPage[1] ); - assert( pPage->pExtra==(void *)&((char *)&pPage[1])[pCache->szPage] ); + pPgHdr = (PgHdr *)pPage->pExtra; - if( 0==pPage->nRef ){ + if( !pPgHdr->pPage ){ + memset(pPgHdr, 0, sizeof(PgHdr)); + pPgHdr->pPage = pPage; + pPgHdr->pData = pPage->pBuf; + pPgHdr->pExtra = (void *)&pPgHdr[1]; + memset(pPgHdr->pExtra, 0, pCache->szExtra); + pPgHdr->pCache = pCache; + pPgHdr->pgno = pgno; + } + assert( pPgHdr->pCache==pCache ); + assert( pPgHdr->pgno==pgno ); + assert( pPgHdr->pData==pPage->pBuf ); + assert( pPgHdr->pExtra==(void *)&pPgHdr[1] ); + + if( 0==pPgHdr->nRef ){ pCache->nRef++; } - pPage->nRef++; + pPgHdr->nRef++; if( pgno==1 ){ - pCache->pPage1 = pPage; + pCache->pPage1 = pPgHdr; } } - *ppPage = pPage; - return (pPage==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK; + *ppPage = pPgHdr; + return (pPgHdr==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK; } /* @@ -339,7 +343,7 @@ void sqlite3PcacheDrop(PgHdr *p){ if( p->pgno==1 ){ pCache->pPage1 = 0; } - sqlite3GlobalConfig.pcache.xUnpin(pCache->pCache, p, 1); + sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 1); } /* @@ -397,7 +401,7 @@ void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ PCache *pCache = p->pCache; assert( p->nRef>0 ); assert( newPgno>0 ); - sqlite3GlobalConfig.pcache.xRekey(pCache->pCache, p, p->pgno, newPgno); + sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); p->pgno = newPgno; if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){ pcacheRemoveFromDirtyList(p); @@ -434,7 +438,7 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ memset(pCache->pPage1->pData, 0, pCache->szPage); pgno = 1; } - sqlite3GlobalConfig.pcache.xTruncate(pCache->pCache, pgno+1); + sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1); } } @@ -443,7 +447,7 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ */ void sqlite3PcacheClose(PCache *pCache){ if( pCache->pCache ){ - sqlite3GlobalConfig.pcache.xDestroy(pCache->pCache); + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); } } @@ -555,7 +559,7 @@ int sqlite3PcachePageRefcount(PgHdr *p){ int sqlite3PcachePagecount(PCache *pCache){ int nPage = 0; if( pCache->pCache ){ - nPage = sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache); + nPage = sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache); } return nPage; } @@ -575,7 +579,7 @@ int sqlite3PcacheGetCachesize(PCache *pCache){ void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ pCache->nMax = mxPage; if( pCache->pCache ){ - sqlite3GlobalConfig.pcache.xCachesize(pCache->pCache, mxPage); + sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, mxPage); } } diff --git a/src/pcache.h b/src/pcache.h index 33735d2cbb..c4a25b251f 100644 --- a/src/pcache.h +++ b/src/pcache.h @@ -23,7 +23,8 @@ typedef struct PCache PCache; ** structure. */ struct PgHdr { - void *pData; /* Content of this page */ + sqlite3_pcache_page *pPage; /* Pcache object page handle */ + void *pData; /* Page data */ void *pExtra; /* Extra content */ PgHdr *pDirty; /* Transient list of dirty pages */ Pgno pgno; /* Page number for this page */ diff --git a/src/pcache1.c b/src/pcache1.c index 077a7b2168..f94241f5ee 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -72,6 +72,7 @@ struct PCache1 { */ PGroup *pGroup; /* PGroup this cache belongs to */ int szPage; /* Size of allocated pages in bytes */ + int szExtra; /* Size of extra space in bytes */ int bPurgeable; /* True if cache is purgeable */ unsigned int nMin; /* Minimum number of pages reserved */ unsigned int nMax; /* Configured "cache_size" value */ @@ -90,11 +91,12 @@ struct PCache1 { /* ** Each cache entry is represented by an instance of the following -** structure. A buffer of PgHdr1.pCache->szPage bytes is allocated -** directly before this structure in memory (see the PGHDR1_TO_PAGE() -** macro below). +** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of +** PgHdr1.pCache->szPage bytes is allocated directly before this structure +** in memory. */ struct PgHdr1 { + sqlite3_pcache_page page; unsigned int iKey; /* Key value (page number) */ PgHdr1 *pNext; /* Next in hash table chain */ PCache1 *pCache; /* Cache that currently owns this page */ @@ -144,21 +146,6 @@ static SQLITE_WSD struct PCacheGlobal { */ #define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g)) -/* -** When a PgHdr1 structure is allocated, the associated PCache1.szPage -** bytes of data are located directly before it in memory (i.e. the total -** size of the allocation is sizeof(PgHdr1)+PCache1.szPage byte). The -** PGHDR1_TO_PAGE() macro takes a pointer to a PgHdr1 structure as -** an argument and returns a pointer to the associated block of szPage -** bytes. The PAGE_TO_PGHDR1() macro does the opposite: its argument is -** a pointer to a block of szPage bytes of data and the return value is -** a pointer to the associated PgHdr1 structure. -** -** assert( PGHDR1_TO_PAGE(PAGE_TO_PGHDR1(pCache, X))==X ); -*/ -#define PGHDR1_TO_PAGE(p) (void*)(((char*)p) - p->pCache->szPage) -#define PAGE_TO_PGHDR1(c, p) (PgHdr1*)(((char*)p) + c->szPage) - /* ** Macros to enter and leave the PCache LRU mutex. */ @@ -288,7 +275,6 @@ static int pcache1MemSize(void *p){ ** Allocate a new page object initially associated with cache pCache. */ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){ - int nByte = sizeof(PgHdr1) + pCache->szPage; PgHdr1 *p = 0; void *pPg; @@ -297,16 +283,29 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){ ** this mutex is not held. */ assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); pcache1LeaveMutex(pCache->pGroup); - pPg = pcache1Alloc(nByte); +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + pPg = pcache1Alloc(pCache->szPage); + p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra); + if( !pPg || !p ){ + pcache1Free(pPg); + sqlite3_free(p); + pPg = 0; + } +#else + pPg = pcache1Alloc(sizeof(PgHdr1) + pCache->szPage + pCache->szExtra); + p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; +#endif pcache1EnterMutex(pCache->pGroup); if( pPg ){ - p = PAGE_TO_PGHDR1(pCache, pPg); + p->page.pBuf = pPg; + p->page.pExtra = &p[1]; if( pCache->bPurgeable ){ pCache->pGroup->nCurrentPage++; } + return p; } - return p; + return 0; } /* @@ -320,7 +319,10 @@ static void pcache1FreePage(PgHdr1 *p){ if( ALWAYS(p) ){ PCache1 *pCache = p->pCache; assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) ); - pcache1Free(PGHDR1_TO_PAGE(p)); + pcache1Free(p->page.pBuf); +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + sqlite3_free(p); +#endif if( pCache->bPurgeable ){ pCache->pGroup->nCurrentPage--; } @@ -361,7 +363,7 @@ void sqlite3PageFree(void *p){ ** the heap even further. */ static int pcache1UnderMemoryPressure(PCache1 *pCache){ - if( pcache1.nSlot && pCache->szPage<=pcache1.szSlot ){ + if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){ return pcache1.bUnderPressure; }else{ return sqlite3HeapNearlyFull(); @@ -552,7 +554,7 @@ static void pcache1Shutdown(void *NotUsed){ ** ** Allocate a new cache. */ -static sqlite3_pcache *pcache1Create(int szPage, int bPurgeable){ +static sqlite3_pcache *pcache1Create(int szExtra, int szPage, int bPurgeable){ PCache1 *pCache; /* The newly created page cache */ PGroup *pGroup; /* The group the new page cache will belong to */ int sz; /* Bytes of memory required to allocate the new cache */ @@ -587,6 +589,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int bPurgeable){ } pCache->pGroup = pGroup; pCache->szPage = szPage; + pCache->szExtra = szExtra; pCache->bPurgeable = (bPurgeable ? 1 : 0); if( bPurgeable ){ pCache->nMin = 10; @@ -684,7 +687,11 @@ static int pcache1Pagecount(sqlite3_pcache *p){ ** ** 5. Otherwise, allocate and return a new page buffer. */ -static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){ +static sqlite3_pcache_page *pcache1Fetch( + sqlite3_pcache *p, + unsigned int iKey, + int createFlag +){ int nPinned; PCache1 *pCache = (PCache1 *)p; PGroup *pGroup; @@ -719,7 +726,6 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){ pGroup = pCache->pGroup; #endif - /* Step 3: Abort if createFlag is 1 but the cache is nearly full */ nPinned = pCache->nPage - pCache->nRecyclable; assert( nPinned>=0 ); @@ -747,12 +753,13 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){ pPage = pGroup->pLruTail; pcache1RemoveFromHash(pPage); pcache1PinPage(pPage); - if( (pOtherCache = pPage->pCache)->szPage!=pCache->szPage ){ + if( (pOtherCache = pPage->pCache)->szPage!=pCache->szPage + || pOtherCache->szExtra!=pCache->szExtra + ){ pcache1FreePage(pPage); pPage = 0; }else{ - pGroup->nCurrentPage -= - (pOtherCache->bPurgeable - pCache->bPurgeable); + pGroup->nCurrentPage -= (pOtherCache->bPurgeable - pCache->bPurgeable); } } @@ -773,7 +780,7 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){ pPage->pCache = pCache; pPage->pLruPrev = 0; pPage->pLruNext = 0; - *(void **)(PGHDR1_TO_PAGE(pPage)) = 0; + *(void **)pPage->page.pExtra = 0; pCache->apHash[h] = pPage; } @@ -782,7 +789,7 @@ fetch_out: pCache->iMaxKey = iKey; } pcache1LeaveMutex(pGroup); - return (pPage ? PGHDR1_TO_PAGE(pPage) : 0); + return &pPage->page; } @@ -791,9 +798,13 @@ fetch_out: ** ** Mark a page as unpinned (eligible for asynchronous recycling). */ -static void pcache1Unpin(sqlite3_pcache *p, void *pPg, int reuseUnlikely){ +static void pcache1Unpin( + sqlite3_pcache *p, + sqlite3_pcache_page *pPg, + int reuseUnlikely +){ PCache1 *pCache = (PCache1 *)p; - PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg); + PgHdr1 *pPage = (PgHdr1 *)pPg; PGroup *pGroup = pCache->pGroup; assert( pPage->pCache==pCache ); @@ -829,12 +840,12 @@ static void pcache1Unpin(sqlite3_pcache *p, void *pPg, int reuseUnlikely){ */ static void pcache1Rekey( sqlite3_pcache *p, - void *pPg, + sqlite3_pcache_page *pPg, unsigned int iOld, unsigned int iNew ){ PCache1 *pCache = (PCache1 *)p; - PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg); + PgHdr1 *pPage = (PgHdr1 *)pPg; PgHdr1 **pp; unsigned int h; assert( pPage->iKey==iOld ); @@ -903,7 +914,7 @@ static void pcache1Destroy(sqlite3_pcache *p){ ** already provided an alternative. */ void sqlite3PCacheSetDefault(void){ - static const sqlite3_pcache_methods defaultMethods = { + static const sqlite3_pcache_methods2 defaultMethods = { 0, /* pArg */ pcache1Init, /* xInit */ pcache1Shutdown, /* xShutdown */ @@ -916,7 +927,7 @@ void sqlite3PCacheSetDefault(void){ pcache1Truncate, /* xTruncate */ pcache1Destroy /* xDestroy */ }; - sqlite3_config(SQLITE_CONFIG_PCACHE, &defaultMethods); + sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods); } #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT @@ -937,7 +948,10 @@ int sqlite3PcacheReleaseMemory(int nReq){ PgHdr1 *p; pcache1EnterMutex(&pcache1.grp); while( (nReq<0 || nFreepage.pBuf); +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + nFree += sqlite3MemSize(p); +#endif pcache1PinPage(p); pcache1RemoveFromHash(p); pcache1FreePage(p); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 9679965ce2..d3dc86120b 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1497,6 +1497,8 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_GETPCACHE 15 /* sqlite3_pcache_methods* */ #define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ #define SQLITE_CONFIG_URI 17 /* int */ +#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ /* ** CAPI3REF: Database Connection Configuration Options @@ -6097,6 +6099,27 @@ struct sqlite3_pcache_methods { void (*xDestroy)(sqlite3_pcache*); }; +typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; +typedef struct sqlite3_pcache_page sqlite3_pcache_page; +struct sqlite3_pcache_page { + void *pBuf; + void *pExtra; +}; +struct sqlite3_pcache_methods2 { + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szExtra, int szPage, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); + void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, + unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); +}; + /* ** CAPI3REF: Online Backup Object ** diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 2171c15749..46bec6a309 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2459,7 +2459,7 @@ struct Sqlite3Config { int nLookaside; /* Default lookaside buffer count */ sqlite3_mem_methods m; /* Low-level memory allocation interface */ sqlite3_mutex_methods mutex; /* Low-level mutex interface */ - sqlite3_pcache_methods pcache; /* Low-level page-cache interface */ + sqlite3_pcache_methods2 pcache2; /* Low-level page-cache interface */ void *pHeap; /* Heap storage space */ int nHeap; /* Size of pHeap[] */ int mnReq, mxReq; /* Min and max heap requests sizes */ diff --git a/src/test_init.c b/src/test_init.c index a67b6788ab..7741cd19e7 100644 --- a/src/test_init.c +++ b/src/test_init.c @@ -30,9 +30,9 @@ #include static struct Wrapped { - sqlite3_pcache_methods pcache; - sqlite3_mem_methods mem; - sqlite3_mutex_methods mutex; + sqlite3_pcache_methods2 pcache; + sqlite3_mem_methods mem; + sqlite3_mutex_methods mutex; int mem_init; /* True if mem subsystem is initalized */ int mem_fail; /* True to fail mem subsystem inialization */ @@ -123,8 +123,8 @@ static void wrPCacheShutdown(void *pArg){ wrapped.pcache_init = 0; } -static sqlite3_pcache *wrPCacheCreate(int a, int b){ - return wrapped.pcache.xCreate(a, b); +static sqlite3_pcache *wrPCacheCreate(int a, int b, int c){ + return wrapped.pcache.xCreate(a, b, c); } static void wrPCacheCachesize(sqlite3_pcache *p, int n){ wrapped.pcache.xCachesize(p, n); @@ -132,13 +132,18 @@ static void wrPCacheCachesize(sqlite3_pcache *p, int n){ static int wrPCachePagecount(sqlite3_pcache *p){ return wrapped.pcache.xPagecount(p); } -static void *wrPCacheFetch(sqlite3_pcache *p, unsigned a, int b){ +static sqlite3_pcache_page *wrPCacheFetch(sqlite3_pcache *p, unsigned a, int b){ return wrapped.pcache.xFetch(p, a, b); } -static void wrPCacheUnpin(sqlite3_pcache *p, void *a, int b){ +static void wrPCacheUnpin(sqlite3_pcache *p, sqlite3_pcache_page *a, int b){ wrapped.pcache.xUnpin(p, a, b); } -static void wrPCacheRekey(sqlite3_pcache *p, void *a, unsigned b, unsigned c){ +static void wrPCacheRekey( + sqlite3_pcache *p, + sqlite3_pcache_page *a, + unsigned b, + unsigned c +){ wrapped.pcache.xRekey(p, a, b, c); } static void wrPCacheTruncate(sqlite3_pcache *p, unsigned a){ @@ -154,7 +159,7 @@ static void installInitWrappers(void){ wrMutexFree, wrMutexEnter, wrMutexTry, wrMutexLeave, wrMutexHeld, wrMutexNotheld }; - sqlite3_pcache_methods pcachemethods = { + sqlite3_pcache_methods2 pcachemethods = { 0, wrPCacheInit, wrPCacheShutdown, wrPCacheCreate, wrPCacheCachesize, wrPCachePagecount, wrPCacheFetch, @@ -173,10 +178,10 @@ static void installInitWrappers(void){ sqlite3_shutdown(); sqlite3_config(SQLITE_CONFIG_GETMUTEX, &wrapped.mutex); sqlite3_config(SQLITE_CONFIG_GETMALLOC, &wrapped.mem); - sqlite3_config(SQLITE_CONFIG_GETPCACHE, &wrapped.pcache); + sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &wrapped.pcache); sqlite3_config(SQLITE_CONFIG_MUTEX, &mutexmethods); sqlite3_config(SQLITE_CONFIG_MALLOC, &memmethods); - sqlite3_config(SQLITE_CONFIG_PCACHE, &pcachemethods); + sqlite3_config(SQLITE_CONFIG_PCACHE2, &pcachemethods); } static int init_wrapper_install( @@ -218,7 +223,7 @@ static int init_wrapper_uninstall( sqlite3_shutdown(); sqlite3_config(SQLITE_CONFIG_MUTEX, &wrapped.mutex); sqlite3_config(SQLITE_CONFIG_MALLOC, &wrapped.mem); - sqlite3_config(SQLITE_CONFIG_PCACHE, &wrapped.pcache); + sqlite3_config(SQLITE_CONFIG_PCACHE2, &wrapped.pcache); return TCL_OK; } diff --git a/src/test_pcache.c b/src/test_pcache.c index 98aa1367aa..1b8424d10f 100644 --- a/src/test_pcache.c +++ b/src/test_pcache.c @@ -100,15 +100,16 @@ static void testpcacheShutdown(void *pArg){ typedef struct testpcache testpcache; struct testpcache { int szPage; /* Size of each page. Multiple of 8. */ + int szExtra; /* Size of extra data that accompanies each page */ int bPurgeable; /* True if the page cache is purgeable */ int nFree; /* Number of unused slots in a[] */ int nPinned; /* Number of pinned slots in a[] */ unsigned iRand; /* State of the PRNG */ unsigned iMagic; /* Magic number for sanity checking */ struct testpcachePage { + sqlite3_pcache_page page; /* Base class */ unsigned key; /* The key for this page. 0 means unallocated */ int isPinned; /* True if the page is pinned */ - void *pData; /* Data for this page */ } a[TESTPCACHE_NPAGE]; /* All pages in the cache */ }; @@ -129,27 +130,33 @@ static unsigned testpcacheRandom(testpcache *p){ /* ** Allocate a new page cache instance. */ -static sqlite3_pcache *testpcacheCreate(int szPage, int bPurgeable){ +static sqlite3_pcache *testpcacheCreate( + int szExtra, + int szPage, + int bPurgeable +){ int nMem; char *x; testpcache *p; int i; assert( testpcacheGlobal.pDummy!=0 ); szPage = (szPage+7)&~7; - nMem = sizeof(testpcache) + TESTPCACHE_NPAGE*szPage; + nMem = sizeof(testpcache) + TESTPCACHE_NPAGE*(szPage+szExtra); p = sqlite3_malloc( nMem ); if( p==0 ) return 0; x = (char*)&p[1]; p->szPage = szPage; + p->szExtra = szExtra; p->nFree = TESTPCACHE_NPAGE; p->nPinned = 0; p->iRand = testpcacheGlobal.prngSeed; p->bPurgeable = bPurgeable; p->iMagic = TESTPCACHE_VALID; - for(i=0; ia[i].key = 0; p->a[i].isPinned = 0; - p->a[i].pData = (void*)x; + p->a[i].page.pBuf = (void*)x; + p->a[i].page.pExtra = (void*)&x[szPage]; } testpcacheGlobal.nInstance++; return (sqlite3_pcache*)p; @@ -181,7 +188,7 @@ static int testpcachePagecount(sqlite3_pcache *pCache){ /* ** Fetch a page. */ -static void *testpcacheFetch( +static sqlite3_pcache_page *testpcacheFetch( sqlite3_pcache *pCache, unsigned key, int createFlag @@ -200,7 +207,7 @@ static void *testpcacheFetch( assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree ); p->a[i].isPinned = 1; } - return p->a[i].pData; + return &p->a[i].page; } } @@ -237,11 +244,12 @@ static void *testpcacheFetch( if( p->a[j].key==0 ){ p->a[j].key = key; p->a[j].isPinned = 1; - memset(p->a[j].pData, 0, p->szPage); + memset(p->a[j].page.pBuf, 0, p->szPage); + memset(p->a[j].page.pExtra, 0, p->szExtra); p->nPinned++; p->nFree--; assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree ); - return p->a[j].pData; + return &p->a[j].page; } } @@ -263,10 +271,11 @@ static void *testpcacheFetch( if( p->a[j].key>0 && p->a[j].isPinned==0 ){ p->a[j].key = key; p->a[j].isPinned = 1; - memset(p->a[j].pData, 0, p->szPage); + memset(p->a[j].page.pBuf, 0, p->szPage); + memset(p->a[j].page.pExtra, 0, p->szExtra); p->nPinned++; assert( p->nPinned <= TESTPCACHE_NPAGE - p->nFree ); - return p->a[j].pData; + return &p->a[j].page; } } @@ -280,7 +289,7 @@ static void *testpcacheFetch( */ static void testpcacheUnpin( sqlite3_pcache *pCache, - void *pOldPage, + sqlite3_pcache_page *pOldPage, int discard ){ testpcache *p = (testpcache*)pCache; @@ -300,7 +309,7 @@ static void testpcacheUnpin( } for(i=0; ia[i].pData==pOldPage ){ + if( &p->a[i].page==pOldPage ){ /* The pOldPage pointer always points to a pinned page */ assert( p->a[i].isPinned ); p->a[i].isPinned = 0; @@ -325,7 +334,7 @@ static void testpcacheUnpin( */ static void testpcacheRekey( sqlite3_pcache *pCache, - void *pOldPage, + sqlite3_pcache_page *pOldPage, unsigned oldKey, unsigned newKey ){ @@ -354,7 +363,7 @@ static void testpcacheRekey( for(i=0; ia[i].key==oldKey ){ /* The oldKey and pOldPage parameters match */ - assert( p->a[i].pData==pOldPage ); + assert( &p->a[i].page==pOldPage ); /* Page to be rekeyed must be pinned */ assert( p->a[i].isPinned ); p->a[i].key = newKey; @@ -422,7 +431,7 @@ void installTestPCache( unsigned prngSeed, /* Seed for the PRNG */ unsigned highStress /* Call xStress agressively */ ){ - static const sqlite3_pcache_methods testPcache = { + static const sqlite3_pcache_methods2 testPcache = { (void*)&testpcacheGlobal, testpcacheInit, testpcacheShutdown, @@ -435,7 +444,7 @@ void installTestPCache( testpcacheTruncate, testpcacheDestroy, }; - static sqlite3_pcache_methods defaultPcache; + static sqlite3_pcache_methods2 defaultPcache; static int isInstalled = 0; assert( testpcacheGlobal.nInstance==0 ); @@ -446,12 +455,12 @@ void installTestPCache( testpcacheGlobal.highStress = highStress; if( installFlag!=isInstalled ){ if( installFlag ){ - sqlite3_config(SQLITE_CONFIG_GETPCACHE, &defaultPcache); + sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &defaultPcache); assert( defaultPcache.xCreate!=testpcacheCreate ); - sqlite3_config(SQLITE_CONFIG_PCACHE, &testPcache); + sqlite3_config(SQLITE_CONFIG_PCACHE2, &testPcache); }else{ assert( defaultPcache.xCreate!=0 ); - sqlite3_config(SQLITE_CONFIG_PCACHE, &defaultPcache); + sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultPcache); } isInstalled = installFlag; } diff --git a/test/memsubsys1.test b/test/memsubsys1.test index 7eecf083a7..894a554789 100644 --- a/test/memsubsys1.test +++ b/test/memsubsys1.test @@ -68,7 +68,7 @@ proc reset_highwater_marks {} { sqlite3_status SQLITE_STATUS_PARSER_STACK 1 } -set xtra_size 256 +set xtra_size 272 # Test 1: Both PAGECACHE and SCRATCH are shut down. # From e5c40b18e34f22c7e553d738e9065801e2178694 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 9 Nov 2011 00:06:05 +0000 Subject: [PATCH 014/161] Update the API documentation for the new pcache2 interface. Change the order of parameters on the xCreate method of pcache2. FossilOrigin-Name: 4da7095683ec821414e255419d63a24dbd9d726d --- manifest | 23 +++++----- manifest.uuid | 2 +- src/pcache.c | 2 +- src/pcache1.c | 3 +- src/sqlite.h.in | 108 ++++++++++++++++++++++++++-------------------- src/test_pcache.c | 2 +- 6 files changed, 75 insertions(+), 65 deletions(-) diff --git a/manifest b/manifest index e2c1f41759..a9eaa6df48 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimental\schange\sto\sthe\spcache\sinterface\sto\sallow\spage\sbuffers\sto\sbe\sallocated\sseparately\sfrom\stheir\sassociated\scontainer\sstructures. -D 2011-11-08T20:08:44.098 +C Update\sthe\sAPI\sdocumentation\sfor\sthe\snew\spcache2\sinterface.\s\sChange\sthe\norder\sof\sparameters\son\sthe\sxCreate\smethod\sof\spcache2. +D 2011-11-09T00:06:05.887 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -171,9 +171,9 @@ F src/os_win.c 49d418916428a59d773f39993db0ecde56ab4c37 F src/pager.c db33d4bf1e3e019c34c220971cc6c3aa07c30f54 F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 -F src/pcache.c fad8646667e074d06e29028029a0440d852497e5 +F src/pcache.c 8820564f6e32842190f06df545d964a5491ddae4 F src/pcache.h c770382f9fae4ca5025c5523bd0aa13cd6ddc6f8 -F src/pcache1.c 54fc4ed623157b6f706da961c1d3776a40aa131d +F src/pcache1.c 9a42ace8022b3d38175c3b41802aa9bccd9c6a3a F src/pragma.c da8ef96b3eec351e81e0061c39810e548bcc96d7 F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4 F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869 @@ -182,7 +182,7 @@ F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 F src/shell.c 6d2ad7f80adc9c8c3195412879af36eb3196c1b6 -F src/sqlite.h.in c436f15dd27782e83d532651394c41fe4b96d1b0 +F src/sqlite.h.in 51b40e104b9d11b3d3a72a4d1399cb0b0ef45b19 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h f87f241b9821a9d466c2711b7345d30ef3624249 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -219,7 +219,7 @@ F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32 -F src/test_pcache.c 708147942470815963efa7a58fe63470a1943a5e +F src/test_pcache.c 96f5ba93a34d844de596bebdfe1c09bab438a8bd F src/test_quota.c a391c866217e92986c6f523f05b08aa6956c8419 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 @@ -974,10 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P a210695abcfa5cb04279edfd04824d881b7c4ada -R 753cd5b3a540b0935d5201e586350091 -T *branch * experimental-pcache -T *sym-experimental-pcache * -T -sym-trunk * -U dan -Z 65dd88e6b6c81cfeaddd0d87f1e89623 +P c275c9d323cb1dccb031b199d413ac3a0b244fea +R 4fb01fb575d63e4a5f19c0220660f3b1 +U drh +Z afa7f9c0cc886adac8a55835b7a79aea diff --git a/manifest.uuid b/manifest.uuid index 9631c1e9b1..6e280dee1d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c275c9d323cb1dccb031b199d413ac3a0b244fea \ No newline at end of file +4da7095683ec821414e255419d63a24dbd9d726d \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index f689aaa77f..6c68ddee61 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -221,7 +221,7 @@ int sqlite3PcacheFetch( if( !pCache->pCache && createFlag ){ sqlite3_pcache *p; p = sqlite3GlobalConfig.pcache2.xCreate( - pCache->szExtra + sizeof(PgHdr), pCache->szPage, pCache->bPurgeable + pCache->szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable ); if( !p ){ return SQLITE_NOMEM; diff --git a/src/pcache1.c b/src/pcache1.c index f94241f5ee..c4bebe548d 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -24,7 +24,6 @@ typedef struct PgHdr1 PgHdr1; typedef struct PgFreeslot PgFreeslot; typedef struct PGroup PGroup; - /* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set ** of one or more PCaches that are able to recycle each others unpinned ** pages when they are under memory pressure. A PGroup is an instance of @@ -554,7 +553,7 @@ static void pcache1Shutdown(void *NotUsed){ ** ** Allocate a new cache. */ -static sqlite3_pcache *pcache1Create(int szExtra, int szPage, int bPurgeable){ +static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ PCache1 *pCache; /* The newly created page cache */ PGroup *pGroup; /* The group the new page cache will belong to */ int sz; /* Bytes of memory required to allocate the new cache */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d3dc86120b..316d4231b2 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1368,7 +1368,7 @@ struct sqlite3_mem_methods { **
^This option specifies a static memory buffer that SQLite can use for ** the database page cache with the default page cache implementation. ** This configuration should not be used if an application-define page -** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option. +** cache implementation is loaded using the SQLITE_CONFIG_PCACHE2 option. ** There are three arguments to this option: A pointer to 8-byte aligned ** memory, the size of each page buffer (sz), and the number of pages (N). ** The sz argument should be the size of the largest database page @@ -1437,15 +1437,15 @@ struct sqlite3_mem_methods { ** verb to [sqlite3_db_config()] can be used to change the lookaside ** configuration on individual connections.)^
** -** [[SQLITE_CONFIG_PCACHE]]
SQLITE_CONFIG_PCACHE
+** [[SQLITE_CONFIG_PCACHE2]]
SQLITE_CONFIG_PCACHE2
**
^(This option takes a single argument which is a pointer to -** an [sqlite3_pcache_methods] object. This object specifies the interface +** an [sqlite3_pcache_methods2] object. This object specifies the interface ** to a custom page cache implementation.)^ ^SQLite makes a copy of the ** object and uses it for page cache memory allocations.
** -** [[SQLITE_CONFIG_GETPCACHE]]
SQLITE_CONFIG_GETPCACHE
+** [[SQLITE_CONFIG_GETPCACHE2]]
SQLITE_CONFIG_GETPCACHE2
**
^(This option takes a single argument which is a pointer to an -** [sqlite3_pcache_methods] object. SQLite copies of the current +** [sqlite3_pcache_methods2] object. SQLite copies of the current ** page cache implementation into that object.)^
** ** [[SQLITE_CONFIG_LOG]]
SQLITE_CONFIG_LOG
@@ -1478,6 +1478,11 @@ struct sqlite3_mem_methods { ** database connection is opened. By default, URI handling is globally ** disabled. The default value may be changed by compiling with the ** [SQLITE_USE_URI] symbol defined. +** +** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] +**
SQLITE_CONFIG_PCACHE and SQLITE_CONFNIG_GETPCACHE +**
These options are obsolete and should not be used by new code. +** They are retained for backwards compatibility but are now no-ops. ** */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ @@ -1493,8 +1498,8 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ /* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ #define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ -#define SQLITE_CONFIG_PCACHE 14 /* sqlite3_pcache_methods* */ -#define SQLITE_CONFIG_GETPCACHE 15 /* sqlite3_pcache_methods* */ +#define SQLITE_CONFIG_PCACHE 14 /* no-op */ +#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ #define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ #define SQLITE_CONFIG_URI 17 /* int */ #define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ @@ -4557,7 +4562,7 @@ int sqlite3_release_memory(int); ** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and ** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option. **
  • An alternative page cache implementation is specified using -** [sqlite3_config]([SQLITE_CONFIG_PCACHE],...). +** [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...). **
  • The page cache allocates from its own memory pool supplied ** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than ** from the heap. @@ -5938,9 +5943,9 @@ typedef struct sqlite3_pcache sqlite3_pcache; ** CAPI3REF: Application Defined Page Cache. ** KEYWORDS: {page cache} ** -** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can +** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can ** register an alternative page cache implementation by passing in an -** instance of the sqlite3_pcache_methods structure.)^ +** instance of the sqlite3_pcache_methods2 structure.)^ ** In many applications, most of the heap memory allocated by ** SQLite is used for the page cache. ** By implementing a @@ -5954,7 +5959,7 @@ typedef struct sqlite3_pcache sqlite3_pcache; ** extreme measure that is only needed by the most demanding applications. ** The built-in page cache is recommended for most uses. ** -** ^(The contents of the sqlite3_pcache_methods structure are copied to an +** ^(The contents of the sqlite3_pcache_methods2 structure are copied to an ** internal buffer by SQLite within the call to [sqlite3_config]. Hence ** the application may discard the parameter after the call to ** [sqlite3_config()] returns.)^ @@ -5989,18 +5994,16 @@ typedef struct sqlite3_pcache sqlite3_pcache; ** ^SQLite invokes the xCreate() method to construct a new cache instance. ** SQLite will typically create one cache instance for each open database file, ** though this is not guaranteed. ^The -** first parameter, szPage, is the size in bytes of the pages that must -** be allocated by the cache. ^szPage will not be a power of two. ^szPage -** will the page size of the database file that is to be cached plus an -** increment (here called "R") of less than 250. SQLite will use the -** extra R bytes on each page to store metadata about the underlying -** database page on disk. The value of R depends +** parameter parameter, szPage, is the size in bytes of the pages that must +** be allocated by the cache. ^szPage will always a power of two. ^The +** second parameter szExtra is a number of bytes of extra storage +** associated with each page cache entry. ^The szExtra parameter will +** a number less than 250. SQLite will use the +** extra szExtra bytes on each page to store metadata about the underlying +** database page on disk. The value passed into szExtra depends ** on the SQLite version, the target platform, and how SQLite was compiled. -** ^(R is constant for a particular build of SQLite. Except, there are two -** distinct values of R when SQLite is compiled with the proprietary -** ZIPVFS extension.)^ ^The second argument to -** xCreate(), bPurgeable, is true if the cache being created will -** be used to cache database pages of a file stored on disk, or +** ^The third argument to xCreate(), bPurgeable, is true if the cache being +** created will be used to cache database pages of a file stored on disk, or ** false if it is used for an in-memory database. The cache implementation ** does not have to do anything special based with the value of bPurgeable; ** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will @@ -6024,11 +6027,16 @@ typedef struct sqlite3_pcache sqlite3_pcache; ** ** [[the xFetch() page cache methods]] ** The xFetch() method locates a page in the cache and returns a pointer to -** the page, or a NULL pointer. -** A "page", in this context, means a buffer of szPage bytes aligned at an -** 8-byte boundary. The page to be fetched is determined by the key. ^The -** minimum key value is 1. After it has been retrieved using xFetch, the page -** is considered to be "pinned". +** an sqlite3_pcache_page object associated with that page, or a NULL pointer. +** The pBuf element of the returned sqlite3_pcache_page object will be a +** pointer to a buffer of szPage bytes used to store the content of a +** single database page. The pExtra element of sqlite3_pcache_page will be +** a pointer to the szExtra bytes of extra storage that SQLite has requested +** for each entry in the page cache. +** +** The page to be fetched is determined by the key. ^The minimum key value +** is 1. After it has been retrieved using xFetch, the page is considered +** to be "pinned". ** ** If the requested page is already in the page cache, then the page cache ** implementation must return a pointer to the page buffer with its content @@ -6084,6 +6092,32 @@ typedef struct sqlite3_pcache sqlite3_pcache; ** handle invalid, and will not use it with any other sqlite3_pcache_methods ** functions. */ +typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; +typedef struct sqlite3_pcache_page sqlite3_pcache_page; +struct sqlite3_pcache_page { + void *pBuf; + void *pExtra; +}; +struct sqlite3_pcache_methods2 { + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); + void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, + unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); +}; + +/* +** This is the obsolete pcache_methods object that has now been replaced +** by sqlite3_pcache_methods2. This object is not used by SQLite. It is +** retained in the header file for backwards compatibility only. +*/ typedef struct sqlite3_pcache_methods sqlite3_pcache_methods; struct sqlite3_pcache_methods { void *pArg; @@ -6099,26 +6133,6 @@ struct sqlite3_pcache_methods { void (*xDestroy)(sqlite3_pcache*); }; -typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; -typedef struct sqlite3_pcache_page sqlite3_pcache_page; -struct sqlite3_pcache_page { - void *pBuf; - void *pExtra; -}; -struct sqlite3_pcache_methods2 { - void *pArg; - int (*xInit)(void*); - void (*xShutdown)(void*); - sqlite3_pcache *(*xCreate)(int szExtra, int szPage, int bPurgeable); - void (*xCachesize)(sqlite3_pcache*, int nCachesize); - int (*xPagecount)(sqlite3_pcache*); - sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); - void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); - void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, - unsigned oldKey, unsigned newKey); - void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); - void (*xDestroy)(sqlite3_pcache*); -}; /* ** CAPI3REF: Online Backup Object diff --git a/src/test_pcache.c b/src/test_pcache.c index 1b8424d10f..d2890a1660 100644 --- a/src/test_pcache.c +++ b/src/test_pcache.c @@ -131,8 +131,8 @@ static unsigned testpcacheRandom(testpcache *p){ ** Allocate a new page cache instance. */ static sqlite3_pcache *testpcacheCreate( - int szExtra, int szPage, + int szExtra, int bPurgeable ){ int nMem; From 6a8ab6d9cb0614224b569c9e065d934e7b65a743 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 9 Nov 2011 01:53:25 +0000 Subject: [PATCH 015/161] For the mem1.c system malloc implementation, use the malloc_usable_size() function if the HAVE_MALLOC_USABLE_SIZE macro is defined. Update autoconf to look for that function when configuring. FossilOrigin-Name: 2e8ab3cedfebc33a831837792b523d1aa7cdc6b7 --- config.h.in | 3 + configure | 387 +++++++++++++++++++++++-------------------- configure.ac | 2 +- manifest | 24 +-- manifest.uuid | 2 +- src/mem1.c | 32 ++++ src/test_config.c | 8 + test/dbstatus.test | 5 + test/memsubsys1.test | 8 +- 9 files changed, 272 insertions(+), 199 deletions(-) diff --git a/config.h.in b/config.h.in index 11f22803f4..5e087dc3fd 100644 --- a/config.h.in +++ b/config.h.in @@ -33,6 +33,9 @@ /* Define to 1 if you have the `localtime_s' function. */ #undef HAVE_LOCALTIME_S +/* Define to 1 if you have the `malloc_usable_size' function. */ +#undef HAVE_MALLOC_USABLE_SIZE + /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H diff --git a/configure b/configure index 79cd72de34..14ff675064 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.67 for sqlite 3.7.9. +# Generated by GNU Autoconf 2.68 for sqlite 3.7.9. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -89,6 +89,7 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. +as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -214,11 +215,18 @@ IFS=$as_save_IFS # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL - exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : @@ -1294,7 +1302,7 @@ Try \`$0 --help' for more information" $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac @@ -1615,7 +1623,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF sqlite configure 3.7.9 -generated by GNU Autoconf 2.67 +generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation @@ -1661,7 +1669,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile @@ -1707,7 +1715,7 @@ fi # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link @@ -1721,7 +1729,7 @@ ac_fn_c_check_header_compile () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -1739,7 +1747,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile @@ -1775,7 +1783,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp @@ -1817,7 +1825,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run @@ -1830,7 +1838,7 @@ ac_fn_c_check_func () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -1885,7 +1893,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func @@ -1898,7 +1906,7 @@ ac_fn_c_check_type () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" @@ -1939,7 +1947,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type @@ -1951,10 +1959,10 @@ $as_echo "$ac_res" >&6; } ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval "test \"\${$3+set}\"" = set; then : + if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 @@ -2017,7 +2025,7 @@ $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" @@ -2026,7 +2034,7 @@ eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel cat >config.log <<_ACEOF @@ -2034,7 +2042,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by sqlite $as_me 3.7.9, which was -generated by GNU Autoconf 2.67. Invocation command line was +generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2292,7 +2300,7 @@ $as_echo "$as_me: loading site script $ac_site_file" >&6;} || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi done @@ -2456,7 +2464,7 @@ $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } -if test "${ac_cv_build+set}" = set; then : +if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias @@ -2472,7 +2480,7 @@ fi $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' @@ -2490,7 +2498,7 @@ case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } -if test "${ac_cv_host+set}" = set; then : +if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then @@ -2505,7 +2513,7 @@ fi $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' @@ -2531,7 +2539,7 @@ if test -n "$ac_tool_prefix"; then set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -2571,7 +2579,7 @@ if test -z "$ac_cv_prog_CC"; then set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : +if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then @@ -2624,7 +2632,7 @@ if test -z "$CC"; then set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -2664,7 +2672,7 @@ if test -z "$CC"; then set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -2723,7 +2731,7 @@ if test -z "$CC"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -2767,7 +2775,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : +if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then @@ -2822,7 +2830,7 @@ fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 @@ -2937,7 +2945,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -2980,7 +2988,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 @@ -3039,7 +3047,7 @@ $as_echo "$ac_try_echo"; } >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi fi fi @@ -3050,7 +3058,7 @@ rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } -if test "${ac_cv_objext+set}" = set; then : +if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -3091,7 +3099,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi @@ -3101,7 +3109,7 @@ OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if test "${ac_cv_c_compiler_gnu+set}" = set; then : +if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -3138,7 +3146,7 @@ ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then : +if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag @@ -3216,7 +3224,7 @@ else fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then : +if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no @@ -3313,7 +3321,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } -if test "${ac_cv_path_SED+set}" = set; then : +if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ @@ -3395,7 +3403,7 @@ Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if test "${ac_cv_path_GREP+set}" = set; then : +if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then @@ -3458,7 +3466,7 @@ $as_echo "$ac_cv_path_GREP" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } -if test "${ac_cv_path_EGREP+set}" = set; then : +if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 @@ -3525,7 +3533,7 @@ $as_echo "$ac_cv_path_EGREP" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } -if test "${ac_cv_path_FGREP+set}" = set; then : +if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 @@ -3656,7 +3664,7 @@ else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi -if test "${lt_cv_path_LD+set}" = set; then : +if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then @@ -3696,7 +3704,7 @@ fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } -if test "${lt_cv_prog_gnu_ld+set}" = set; then : +if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. @@ -3723,7 +3731,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } -if test "${lt_cv_path_NM+set}" = set; then : +if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then @@ -3783,7 +3791,7 @@ else set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_DUMPBIN+set}" = set; then : +if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then @@ -3827,7 +3835,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then : +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then @@ -3890,18 +3898,18 @@ test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } -if test "${lt_cv_nm_interface+set}" = set; then : +if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3898: $ac_compile\"" >&5) + (eval echo "\"\$as_me:3906: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:3901: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:3909: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:3904: output\"" >&5) + (eval echo "\"\$as_me:3912: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -3925,7 +3933,7 @@ fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } -if test "${lt_cv_sys_max_cmd_len+set}" = set; then : +if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 @@ -4117,7 +4125,7 @@ esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } -if test "${lt_cv_ld_reload_flag+set}" = set; then : +if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' @@ -4153,7 +4161,7 @@ if test -n "$ac_tool_prefix"; then set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_OBJDUMP+set}" = set; then : +if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then @@ -4193,7 +4201,7 @@ if test -z "$ac_cv_prog_OBJDUMP"; then set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then @@ -4252,7 +4260,7 @@ test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } -if test "${lt_cv_deplibs_check_method+set}" = set; then : +if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' @@ -4468,7 +4476,7 @@ if test -n "$ac_tool_prefix"; then set dummy ${ac_tool_prefix}ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_AR+set}" = set; then : +if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then @@ -4508,7 +4516,7 @@ if test -z "$ac_cv_prog_AR"; then set dummy ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : +if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then @@ -4573,7 +4581,7 @@ if test -n "$ac_tool_prefix"; then set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_STRIP+set}" = set; then : +if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then @@ -4613,7 +4621,7 @@ if test -z "$ac_cv_prog_STRIP"; then set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then @@ -4672,7 +4680,7 @@ if test -n "$ac_tool_prefix"; then set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_RANLIB+set}" = set; then : +if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then @@ -4712,7 +4720,7 @@ if test -z "$ac_cv_prog_RANLIB"; then set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then @@ -4829,7 +4837,7 @@ compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } -if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then : +if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else @@ -5107,7 +5115,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5110 "configure"' > conftest.$ac_ext + echo '#line 5118 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -5201,7 +5209,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } -if test "${lt_cv_cc_needs_belf+set}" = set; then : +if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c @@ -5277,7 +5285,7 @@ need_locks="$enable_libtool_lock" set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_DSYMUTIL+set}" = set; then : +if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then @@ -5317,7 +5325,7 @@ if test -z "$ac_cv_prog_DSYMUTIL"; then set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then : +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then @@ -5369,7 +5377,7 @@ fi set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_NMEDIT+set}" = set; then : +if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then @@ -5409,7 +5417,7 @@ if test -z "$ac_cv_prog_NMEDIT"; then set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then : +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then @@ -5461,7 +5469,7 @@ fi set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_LIPO+set}" = set; then : +if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then @@ -5501,7 +5509,7 @@ if test -z "$ac_cv_prog_LIPO"; then set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then : +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then @@ -5553,7 +5561,7 @@ fi set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_OTOOL+set}" = set; then : +if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then @@ -5593,7 +5601,7 @@ if test -z "$ac_cv_prog_OTOOL"; then set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then : +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then @@ -5645,7 +5653,7 @@ fi set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_OTOOL64+set}" = set; then : +if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then @@ -5685,7 +5693,7 @@ if test -z "$ac_cv_prog_OTOOL64"; then set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then : +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then @@ -5760,7 +5768,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } -if test "${lt_cv_apple_cc_single_mod+set}" = set; then : +if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no @@ -5789,7 +5797,7 @@ fi $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } -if test "${lt_cv_ld_exported_symbols_list+set}" = set; then : +if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no @@ -5866,7 +5874,7 @@ if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then : + if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded @@ -5982,7 +5990,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c @@ -5994,7 +6002,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } -if test "${ac_cv_header_stdc+set}" = set; then : +if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -6125,7 +6133,7 @@ for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " -if test "x$ac_cv_header_dlfcn_h" = x""yes; then : +if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF @@ -6309,7 +6317,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } -if test "${lt_cv_objdir+set}" = set; then : +if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null @@ -6417,7 +6425,7 @@ file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } -if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : +if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in @@ -6483,7 +6491,7 @@ if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } -if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : +if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in @@ -6616,7 +6624,7 @@ if test "$GCC" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } -if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then : +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no @@ -6632,11 +6640,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6635: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6643: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6639: \$? = $ac_status" >&5 + echo "$as_me:6647: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -6955,7 +6963,7 @@ $as_echo "$lt_prog_compiler_pic" >&6; } if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } -if test "${lt_cv_prog_compiler_pic_works+set}" = set; then : +if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no @@ -6971,11 +6979,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6974: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6982: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6978: \$? = $ac_status" >&5 + echo "$as_me:6986: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7014,7 +7022,7 @@ fi wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } -if test "${lt_cv_prog_compiler_static_works+set}" = set; then : +if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no @@ -7057,7 +7065,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if test "${lt_cv_prog_compiler_c_o+set}" = set; then : +if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no @@ -7076,11 +7084,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7079: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7087: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7083: \$? = $ac_status" >&5 + echo "$as_me:7091: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7112,7 +7120,7 @@ $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if test "${lt_cv_prog_compiler_c_o+set}" = set; then : +if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no @@ -7131,11 +7139,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7134: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7142: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7138: \$? = $ac_status" >&5 + echo "$as_me:7146: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9253,7 +9261,7 @@ else # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } -if test "${ac_cv_lib_dl_dlopen+set}" = set; then : +if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -9287,7 +9295,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else @@ -9301,12 +9309,12 @@ fi *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" -if test "x$ac_cv_func_shl_load" = x""yes; then : +if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } -if test "${ac_cv_lib_dld_shl_load+set}" = set; then : +if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -9340,16 +9348,16 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } -if test "x$ac_cv_lib_dld_shl_load" = x""yes; then : +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" -if test "x$ac_cv_func_dlopen" = x""yes; then : +if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } -if test "${ac_cv_lib_dl_dlopen+set}" = set; then : +if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -9383,12 +9391,12 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } -if test "${ac_cv_lib_svld_dlopen+set}" = set; then : +if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -9422,12 +9430,12 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } -if test "x$ac_cv_lib_svld_dlopen" = x""yes; then : +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } -if test "${ac_cv_lib_dld_dld_link+set}" = set; then : +if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -9461,7 +9469,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } -if test "x$ac_cv_lib_dld_dld_link" = x""yes; then : +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi @@ -9502,7 +9510,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } -if test "${lt_cv_dlopen_self+set}" = set; then : +if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : @@ -9511,7 +9519,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9514 "configure" +#line 9522 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9598,7 +9606,7 @@ $as_echo "$lt_cv_dlopen_self" >&6; } wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } -if test "${lt_cv_dlopen_self_static+set}" = set; then : +if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : @@ -9607,7 +9615,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9610 "configure" +#line 9618 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9851,7 +9859,7 @@ CC="$lt_save_CC" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then -if test "${ac_cv_path_install+set}" = set; then : +if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -9933,7 +9941,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_AWK+set}" = set; then : +if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then @@ -9982,7 +9990,7 @@ if test "$enable_largefile" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 $as_echo_n "checking for special C compiler options needed for large files... " >&6; } -if test "${ac_cv_sys_largefile_CC+set}" = set; then : +if ${ac_cv_sys_largefile_CC+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_sys_largefile_CC=no @@ -10033,7 +10041,7 @@ $as_echo "$ac_cv_sys_largefile_CC" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 $as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } -if test "${ac_cv_sys_file_offset_bits+set}" = set; then : +if ${ac_cv_sys_file_offset_bits+:} false; then : $as_echo_n "(cached) " >&6 else while :; do @@ -10102,7 +10110,7 @@ rm -rf conftest* if test $ac_cv_sys_file_offset_bits = unknown; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 $as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } -if test "${ac_cv_sys_large_files+set}" = set; then : +if ${ac_cv_sys_large_files+:} false; then : $as_echo_n "(cached) " >&6 else while :; do @@ -10175,7 +10183,7 @@ fi ######### # Check for needed/wanted data types ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "$ac_includes_default" -if test "x$ac_cv_type_int8_t" = x""yes; then : +if test "x$ac_cv_type_int8_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INT8_T 1 @@ -10184,7 +10192,7 @@ _ACEOF fi ac_fn_c_check_type "$LINENO" "int16_t" "ac_cv_type_int16_t" "$ac_includes_default" -if test "x$ac_cv_type_int16_t" = x""yes; then : +if test "x$ac_cv_type_int16_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INT16_T 1 @@ -10193,7 +10201,7 @@ _ACEOF fi ac_fn_c_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "$ac_includes_default" -if test "x$ac_cv_type_int32_t" = x""yes; then : +if test "x$ac_cv_type_int32_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INT32_T 1 @@ -10202,7 +10210,7 @@ _ACEOF fi ac_fn_c_check_type "$LINENO" "int64_t" "ac_cv_type_int64_t" "$ac_includes_default" -if test "x$ac_cv_type_int64_t" = x""yes; then : +if test "x$ac_cv_type_int64_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INT64_T 1 @@ -10211,7 +10219,7 @@ _ACEOF fi ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default" -if test "x$ac_cv_type_intptr_t" = x""yes; then : +if test "x$ac_cv_type_intptr_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INTPTR_T 1 @@ -10220,7 +10228,7 @@ _ACEOF fi ac_fn_c_check_type "$LINENO" "uint8_t" "ac_cv_type_uint8_t" "$ac_includes_default" -if test "x$ac_cv_type_uint8_t" = x""yes; then : +if test "x$ac_cv_type_uint8_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UINT8_T 1 @@ -10229,7 +10237,7 @@ _ACEOF fi ac_fn_c_check_type "$LINENO" "uint16_t" "ac_cv_type_uint16_t" "$ac_includes_default" -if test "x$ac_cv_type_uint16_t" = x""yes; then : +if test "x$ac_cv_type_uint16_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UINT16_T 1 @@ -10238,7 +10246,7 @@ _ACEOF fi ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "$ac_includes_default" -if test "x$ac_cv_type_uint32_t" = x""yes; then : +if test "x$ac_cv_type_uint32_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UINT32_T 1 @@ -10247,7 +10255,7 @@ _ACEOF fi ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "$ac_includes_default" -if test "x$ac_cv_type_uint64_t" = x""yes; then : +if test "x$ac_cv_type_uint64_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UINT64_T 1 @@ -10256,7 +10264,7 @@ _ACEOF fi ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" -if test "x$ac_cv_type_uintptr_t" = x""yes; then : +if test "x$ac_cv_type_uintptr_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UINTPTR_T 1 @@ -10285,7 +10293,7 @@ done ######### # Figure out whether or not we have these functions # -for ac_func in usleep fdatasync localtime_r gmtime_r localtime_s utime +for ac_func in usleep fdatasync localtime_r gmtime_r localtime_s utime malloc_usable_size do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -10314,7 +10322,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_TCLSH_CMD+set}" = set; then : +if ${ac_cv_prog_TCLSH_CMD+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$TCLSH_CMD"; then @@ -10448,7 +10456,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_BUILD_CC+set}" = set; then : +if ${ac_cv_prog_BUILD_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$BUILD_CC"; then @@ -10517,7 +10525,7 @@ fi if test "$SQLITE_THREADSAFE" = "1"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create" >&5 $as_echo_n "checking for library containing pthread_create... " >&6; } -if test "${ac_cv_search_pthread_create+set}" = set; then : +if ${ac_cv_search_pthread_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS @@ -10551,11 +10559,11 @@ for ac_lib in '' pthread; do fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext - if test "${ac_cv_search_pthread_create+set}" = set; then : + if ${ac_cv_search_pthread_create+:} false; then : break fi done -if test "${ac_cv_search_pthread_create+set}" = set; then : +if ${ac_cv_search_pthread_create+:} false; then : else ac_cv_search_pthread_create=no @@ -10745,7 +10753,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5 $as_echo_n "checking for Tcl configuration... " >&6; } - if test "${ac_cv_c_tclconfig+set}" = set; then : + if ${ac_cv_c_tclconfig+:} false; then : $as_echo_n "(cached) " >&6 else @@ -10929,7 +10937,7 @@ fi LIBS="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing tgetent" >&5 $as_echo_n "checking for library containing tgetent... " >&6; } -if test "${ac_cv_search_tgetent+set}" = set; then : +if ${ac_cv_search_tgetent+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS @@ -10963,11 +10971,11 @@ for ac_lib in '' readline ncurses curses termcap; do fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext - if test "${ac_cv_search_tgetent+set}" = set; then : + if ${ac_cv_search_tgetent+:} false; then : break fi done -if test "${ac_cv_search_tgetent+set}" = set; then : +if ${ac_cv_search_tgetent+:} false; then : else ac_cv_search_tgetent=no @@ -10987,7 +10995,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 $as_echo_n "checking for readline in -lreadline... " >&6; } -if test "${ac_cv_lib_readline_readline+set}" = set; then : +if ${ac_cv_lib_readline_readline+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -11021,7 +11029,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 $as_echo "$ac_cv_lib_readline_readline" >&6; } -if test "x$ac_cv_lib_readline_readline" = x""yes; then : +if test "x$ac_cv_lib_readline_readline" = xyes; then : TARGET_READLINE_LIBS="-lreadline" else found="no" @@ -11043,7 +11051,7 @@ fi if test "x$with_readline_inc" = xauto; then ac_fn_c_check_header_mongrel "$LINENO" "readline.h" "ac_cv_header_readline_h" "$ac_includes_default" -if test "x$ac_cv_header_readline_h" = x""yes; then : +if test "x$ac_cv_header_readline_h" = xyes; then : found="yes" else @@ -11054,7 +11062,7 @@ else as_ac_File=`$as_echo "ac_cv_file_$dir/$subdir/readline.h" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $dir/$subdir/readline.h" >&5 $as_echo_n "checking for $dir/$subdir/readline.h... " >&6; } -if eval "test \"\${$as_ac_File+set}\"" = set; then : +if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && @@ -11107,7 +11115,7 @@ fi # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fdatasync" >&5 $as_echo_n "checking for library containing fdatasync... " >&6; } -if test "${ac_cv_search_fdatasync+set}" = set; then : +if ${ac_cv_search_fdatasync+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS @@ -11141,11 +11149,11 @@ for ac_lib in '' rt; do fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext - if test "${ac_cv_search_fdatasync+set}" = set; then : + if ${ac_cv_search_fdatasync+:} false; then : break fi done -if test "${ac_cv_search_fdatasync+set}" = set; then : +if ${ac_cv_search_fdatasync+:} false; then : else ac_cv_search_fdatasync=no @@ -11205,7 +11213,7 @@ if test "${use_loadextension}" = "yes" ; then OPT_FEATURE_FLAGS="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 $as_echo_n "checking for library containing dlopen... " >&6; } -if test "${ac_cv_search_dlopen+set}" = set; then : +if ${ac_cv_search_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS @@ -11239,11 +11247,11 @@ for ac_lib in '' dl; do fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext - if test "${ac_cv_search_dlopen+set}" = set; then : + if ${ac_cv_search_dlopen+:} false; then : break fi done -if test "${ac_cv_search_dlopen+set}" = set; then : +if ${ac_cv_search_dlopen+:} false; then : else ac_cv_search_dlopen=no @@ -11406,10 +11414,21 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then - test "x$cache_file" != "x/dev/null" && + if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} - cat confcache >$cache_file + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} @@ -11441,7 +11460,7 @@ LTLIBOBJS=$ac_ltlibobjs -: ${CONFIG_STATUS=./config.status} +: "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" @@ -11542,6 +11561,7 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. +as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -11849,7 +11869,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # values after options handling. ac_log=" This file was extended by sqlite $as_me 3.7.9, which was -generated by GNU Autoconf 2.67. Invocation command line was +generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -11915,7 +11935,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ sqlite config.status 3.7.9 -configured by $0, generated by GNU Autoconf 2.67, +configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. @@ -12301,7 +12321,7 @@ do "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "sqlite3.pc") CONFIG_FILES="$CONFIG_FILES sqlite3.pc" ;; - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done @@ -12324,9 +12344,10 @@ fi # after its creation but before its name has been assigned to `$tmp'. $debug || { - tmp= + tmp= ac_tmp= trap 'exit_status=$? - { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } @@ -12334,12 +12355,13 @@ $debug || { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" + test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. @@ -12361,7 +12383,7 @@ else ac_cs_awk_cr=$ac_cr fi -echo 'BEGIN {' >"$tmp/subs1.awk" && +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF @@ -12389,7 +12411,7 @@ done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h @@ -12437,7 +12459,7 @@ t delim rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK -cat >>"\$tmp/subs1.awk" <<_ACAWK && +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" @@ -12469,7 +12491,7 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat -fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF @@ -12503,7 +12525,7 @@ fi # test -n "$CONFIG_FILES" # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then -cat >"$tmp/defines.awk" <<\_ACAWK || +cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF @@ -12515,8 +12537,8 @@ _ACEOF # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do - ac_t=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_t"; then + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 @@ -12617,7 +12639,7 @@ do esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac @@ -12636,7 +12658,7 @@ do for ac_f do case $ac_f in - -) ac_f="$tmp/stdin";; + -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. @@ -12645,7 +12667,7 @@ do [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" @@ -12671,8 +12693,8 @@ $as_echo "$as_me: creating $ac_file" >&6;} esac case $ac_tag in - *:-:* | *:-) cat >"$tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac @@ -12802,21 +12824,22 @@ s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} - rm -f "$tmp/stdin" + rm -f "$ac_tmp/stdin" case $ac_file in - -) cat "$tmp/out" && rm -f "$tmp/out";; - *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; @@ -12827,20 +12850,20 @@ which seems to be undefined. Please make sure it is defined" >&2;} if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" - } >"$tmp/config.h" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" - mv "$tmp/config.h" "$ac_file" \ + mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; diff --git a/configure.ac b/configure.ac index 46afeb7527..a772e03b5e 100644 --- a/configure.ac +++ b/configure.ac @@ -127,7 +127,7 @@ AC_CHECK_HEADERS([sys/types.h stdlib.h stdint.h inttypes.h]) ######### # Figure out whether or not we have these functions # -AC_CHECK_FUNCS([usleep fdatasync localtime_r gmtime_r localtime_s utime]) +AC_CHECK_FUNCS([usleep fdatasync localtime_r gmtime_r localtime_s utime malloc_usable_size]) ######### # By default, we use the amalgamation (this may be changed below...) diff --git a/manifest b/manifest index a9eaa6df48..fc92f8fff3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sAPI\sdocumentation\sfor\sthe\snew\spcache2\sinterface.\s\sChange\sthe\norder\sof\sparameters\son\sthe\sxCreate\smethod\sof\spcache2. -D 2011-11-09T00:06:05.887 +C For\sthe\smem1.c\ssystem\smalloc\simplementation,\suse\sthe\smalloc_usable_size()\nfunction\sif\sthe\sHAVE_MALLOC_USABLE_SIZE\smacro\sis\sdefined.\s\sUpdate\sautoconf\nto\slook\sfor\sthat\sfunction\swhen\sconfiguring. +D 2011-11-09T01:53:25.593 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -21,10 +21,10 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F art/src_logo.gif 9341ef09f0e53cd44c0c9b6fc3c16f7f3d6c2ad9 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 -F config.h.in 405a958bdb3af382a809dccb08a44694923ddd61 +F config.h.in 31cc8c4943f56e60c4aa4fba929c9d4c70e418b4 F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure 806c06aef5895860da49600ce098dbe4d5a8435c x -F configure.ac 298a759c086e72c013da459c2aec02a104f4224f +F configure 194ed7797c67c24ebbeb001fcfc557116fe5eba9 x +F configure.ac 75323bdac56fb0e69f6a3fc5b23f24359550b9d9 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html 3091574143dd3415669b6745843ff8d011d33549 F doc/pager-invariants.txt 870107036470d7c419e93768676fae2f8749cf9e @@ -150,7 +150,7 @@ F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f F src/main.c 93d49bc6abf4ccea97721d016b9f45228cff7057 F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 -F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206 +F src/mem1.c 7456e2ca0524609ebc06a9befeda5289d4575ad4 F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534 F src/mem5.c c2c63b7067570b00bf33d751c39af24182316f7f @@ -202,7 +202,7 @@ F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2 -F src/test_config.c bc8826296a7b3a86eeaba1ac2af5551d1c20c35b +F src/test_config.c a036a69b550ebc477ab9ca2b37269201f888436e F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 @@ -361,7 +361,7 @@ F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/date.test a18a2ce81add84b17b06559e82ad7bb91bc6ddff -F test/dbstatus.test 9eb484ba837c6f3f9bbcaecc29e6060a8c3ba6d2 +F test/dbstatus.test 179575499759241bf92ca2fb86bd3ccc8a562aac F test/dbstatus2.test dc57b0d9610851c0ff58a8e1b5b191678398b72a F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc F test/delete.test a065b05d2ebf60fd16639c579a4adfb7c381c701 @@ -592,7 +592,7 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f F test/memdb.test 708a028d6d373e5b3842e4bdc8ba80998c9a4da6 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 -F test/memsubsys1.test c0db8a1e99f4fa07cb858900c55bad9547899aa8 +F test/memsubsys1.test 5b3f39b452f4c0b3cd884fc2fd2246f8f960d313 F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9 F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P c275c9d323cb1dccb031b199d413ac3a0b244fea -R 4fb01fb575d63e4a5f19c0220660f3b1 +P 4da7095683ec821414e255419d63a24dbd9d726d +R c213b277008496abb081e494c07b96f8 U drh -Z afa7f9c0cc886adac8a55835b7a79aea +Z adde38f0bee72bcf55d83cbeb4f89a8f diff --git a/manifest.uuid b/manifest.uuid index 6e280dee1d..88ba491fc8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4da7095683ec821414e255419d63a24dbd9d726d \ No newline at end of file +2e8ab3cedfebc33a831837792b523d1aa7cdc6b7 \ No newline at end of file diff --git a/src/mem1.c b/src/mem1.c index 61fbf4bdba..e0d1dd6e8f 100644 --- a/src/mem1.c +++ b/src/mem1.c @@ -26,6 +26,10 @@ */ #ifdef SQLITE_SYSTEM_MALLOC +#ifdef HAVE_MALLOC_USABLE_SIZE +#include +#endif + /* ** Like malloc(), but remember the size of the allocation ** so that we can find it later using sqlite3MemSize(). @@ -35,6 +39,14 @@ ** routines. */ static void *sqlite3MemMalloc(int nByte){ +#ifdef HAVE_MALLOC_USABLE_SIZE + void *p = malloc( nByte ); + if( p==0 ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); + } + return p; +#else sqlite3_int64 *p; assert( nByte>0 ); nByte = ROUND8(nByte); @@ -47,6 +59,7 @@ static void *sqlite3MemMalloc(int nByte){ sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); } return (void *)p; +#endif } /* @@ -58,10 +71,14 @@ static void *sqlite3MemMalloc(int nByte){ ** by higher-level routines. */ static void sqlite3MemFree(void *pPrior){ +#if HAVE_MALLOC_USABLE_SIZE + free(pPrior); +#else sqlite3_int64 *p = (sqlite3_int64*)pPrior; assert( pPrior!=0 ); p--; free(p); +#endif } /* @@ -69,11 +86,15 @@ static void sqlite3MemFree(void *pPrior){ ** or xRealloc(). */ static int sqlite3MemSize(void *pPrior){ +#if HAVE_MALLOC_USABLE_SIZE + return pPrior ? (int)malloc_usable_size(pPrior) : 0; +#else sqlite3_int64 *p; if( pPrior==0 ) return 0; p = (sqlite3_int64*)pPrior; p--; return (int)p[0]; +#endif } /* @@ -87,6 +108,16 @@ static int sqlite3MemSize(void *pPrior){ ** routines and redirected to xFree. */ static void *sqlite3MemRealloc(void *pPrior, int nByte){ +#if HAVE_MALLOC_USABLE_SIZE + void *p = realloc(pPrior, nByte); + if( p==0 ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, + "failed memory resize %u to %u bytes", + malloc_usable_size(pPrior), nByte); + } + return p; +#else sqlite3_int64 *p = (sqlite3_int64*)pPrior; assert( pPrior!=0 && nByte>0 ); assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */ @@ -102,6 +133,7 @@ static void *sqlite3MemRealloc(void *pPrior, int nByte){ sqlite3MemSize(pPrior), nByte); } return (void*)p; +#endif } /* diff --git a/src/test_config.c b/src/test_config.c index ce72f87376..18442a49e0 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -37,6 +37,14 @@ ** procedures use this to determine when tests should be omitted. */ static void set_options(Tcl_Interp *interp){ +#ifdef HAVE_MALLOC_USABLE_SIZE + Tcl_SetVar2(interp, "sqlite_options", "malloc_usable_size", "1", + TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "malloc_usable_size", "0", + TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_32BIT_ROWID Tcl_SetVar2(interp, "sqlite_options", "rowid32", "1", TCL_GLOBAL_ONLY); #else diff --git a/test/dbstatus.test b/test/dbstatus.test index e1c8f3ebbf..182f4ddbcd 100644 --- a/test/dbstatus.test +++ b/test/dbstatus.test @@ -62,6 +62,11 @@ ifcapable stat3 { set STAT3 0 } +ifcapable malloc_usable_size { + finish_test + return +} + #--------------------------------------------------------------------------- # Run the dbstatus-2 and dbstatus-3 tests with several of different # lookaside buffer sizes. diff --git a/test/memsubsys1.test b/test/memsubsys1.test index 894a554789..e58ef7df26 100644 --- a/test/memsubsys1.test +++ b/test/memsubsys1.test @@ -97,9 +97,11 @@ reset_highwater_marks build_test_db memsubsys1-2 {PRAGMA page_size=1024} #show_memstats set MEMORY_MANAGEMENT $sqlite_options(memorymanage) -do_test memsubsys1-2.3 { - set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2] -} [expr ($TEMP_STORE>1 || $MEMORY_MANAGEMENT==0)*1024] +ifcapable !malloc_usable_size { + do_test memsubsys1-2.3 { + set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2] + } [expr ($TEMP_STORE>1 || $MEMORY_MANAGEMENT==0)*1024] +} do_test memsubsys1-2.4 { set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2] } 20 From 3b42abb35b19df09b5f37877161a8eed8ee1e118 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 9 Nov 2011 14:23:04 +0000 Subject: [PATCH 016/161] A negative value N for the cache_size pragma adjusts the number of cache pages to use approximately N kibibytes of memory. FossilOrigin-Name: b3faa680aedc94ed8aa2819228c0d304b181cc51 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/pcache.c | 26 +++++++++++++++++++------- src/pragma.c | 15 ++++++--------- test/pragma.test | 4 ++-- 5 files changed, 36 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index fc92f8fff3..9fb4c8839b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\sthe\smem1.c\ssystem\smalloc\simplementation,\suse\sthe\smalloc_usable_size()\nfunction\sif\sthe\sHAVE_MALLOC_USABLE_SIZE\smacro\sis\sdefined.\s\sUpdate\sautoconf\nto\slook\sfor\sthat\sfunction\swhen\sconfiguring. -D 2011-11-09T01:53:25.593 +C A\snegative\svalue\sN\sfor\sthe\scache_size\spragma\sadjusts\sthe\snumber\sof\scache\npages\sto\suse\sapproximately\sN\skibibytes\sof\smemory. +D 2011-11-09T14:23:04.394 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -171,10 +171,10 @@ F src/os_win.c 49d418916428a59d773f39993db0ecde56ab4c37 F src/pager.c db33d4bf1e3e019c34c220971cc6c3aa07c30f54 F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 -F src/pcache.c 8820564f6e32842190f06df545d964a5491ddae4 +F src/pcache.c b9d52e9f844d91c27c161279234f273fc02abc71 F src/pcache.h c770382f9fae4ca5025c5523bd0aa13cd6ddc6f8 F src/pcache1.c 9a42ace8022b3d38175c3b41802aa9bccd9c6a3a -F src/pragma.c da8ef96b3eec351e81e0061c39810e548bcc96d7 +F src/pragma.c c5ba7627fbdedc02c7b8f52e77a3bceb030cf5ed F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4 F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 @@ -627,7 +627,7 @@ F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0 F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16 F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 F test/permutations.test 522823b47238cb1754198f80817fe9f9158ede55 -F test/pragma.test 1ea0c85be853135bb7468e6eed48ee12b04794d4 +F test/pragma.test 7fa35e53085812dac94c2bfcbb02c2a4ad35df5e F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 4da7095683ec821414e255419d63a24dbd9d726d -R c213b277008496abb081e494c07b96f8 +P 2e8ab3cedfebc33a831837792b523d1aa7cdc6b7 +R f79cb2e5e3c648503ef136bcf9a7e813 U drh -Z adde38f0bee72bcf55d83cbeb4f89a8f +Z ee913c4e43d90078be9388d453dfd115 diff --git a/manifest.uuid b/manifest.uuid index 88ba491fc8..a97b46c07b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2e8ab3cedfebc33a831837792b523d1aa7cdc6b7 \ No newline at end of file +b3faa680aedc94ed8aa2819228c0d304b181cc51 \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index 6c68ddee61..a504633919 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -20,7 +20,7 @@ struct PCache { PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */ PgHdr *pSynced; /* Last synced page in dirty page list */ int nRef; /* Number of referenced pages */ - int nMax; /* Configured cache size */ + int szCache; /* Configured cache size */ int szPage; /* Size of every page in this cache */ int szExtra; /* Size of extra space for each page */ int bPurgeable; /* True if pages are on backing store */ @@ -181,7 +181,7 @@ void sqlite3PcacheOpen( p->bPurgeable = bPurgeable; p->xStress = xStress; p->pStress = pStress; - p->nMax = 100; + p->szCache = 100; } /* @@ -198,6 +198,17 @@ void sqlite3PcacheSetPageSize(PCache *pCache, int szPage){ pCache->szPage = szPage; } +/* +** Compute the number of pages of cache requested. +*/ +static int numberOfCachePages(PCache *p){ + if( p->szCache>=0 ){ + return p->szCache; + }else{ + return (-1024*p->szCache)/(p->szPage+p->szExtra); + } +} + /* ** Try to obtain a page from the cache. */ @@ -226,7 +237,7 @@ int sqlite3PcacheFetch( if( !p ){ return SQLITE_NOMEM; } - sqlite3GlobalConfig.pcache2.xCachesize(p, pCache->nMax); + sqlite3GlobalConfig.pcache2.xCachesize(p, numberOfCachePages(pCache)); pCache->pCache = p; } @@ -259,7 +270,7 @@ int sqlite3PcacheFetch( "spill page %d making room for %d - cache used: %d/%d", pPg->pgno, pgno, sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), - pCache->nMax); + numberOfCachePages(pCache)); #endif rc = pCache->xStress(pCache->pStress, pPg); if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ @@ -569,7 +580,7 @@ int sqlite3PcachePagecount(PCache *pCache){ ** Get the suggested cache-size value. */ int sqlite3PcacheGetCachesize(PCache *pCache){ - return pCache->nMax; + return numberOfCachePages(pCache); } #endif @@ -577,9 +588,10 @@ int sqlite3PcacheGetCachesize(PCache *pCache){ ** Set the suggested cache-size value. */ void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ - pCache->nMax = mxPage; + pCache->szCache = mxPage; if( pCache->pCache ){ - sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, mxPage); + sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, + numberOfCachePages(pCache)); } } diff --git a/src/pragma.c b/src/pragma.c index 13a973347b..5f33ee99d7 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -684,14 +684,11 @@ void sqlite3Pragma( ** PRAGMA [database.]cache_size=N ** ** The first form reports the current local setting for the - ** page cache size. The local setting can be different from - ** the persistent cache size value that is stored in the database - ** file itself. The value returned is the maximum number of - ** pages in the page cache. The second form sets the local - ** page cache size value. It does not change the persistent - ** cache size stored on the disk so the cache size will revert - ** to its default value when the database is closed and reopened. - ** N should be a positive integer. + ** page cache size. The second form sets the local + ** page cache size value. If N is positive then that is the + ** number of pages in the cache. If N is negative, then the + ** number of pages is adjusted so that the cache uses -N kibibytes + ** of memory. */ if( sqlite3StrICmp(zLeft,"cache_size")==0 ){ if( sqlite3ReadSchema(pParse) ) goto pragma_out; @@ -699,7 +696,7 @@ void sqlite3Pragma( if( !zRight ){ returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size); }else{ - int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); + int size = sqlite3Atoi(zRight); pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } diff --git a/test/pragma.test b/test/pragma.test index 0cad25a37d..cbe35ea806 100644 --- a/test/pragma.test +++ b/test/pragma.test @@ -99,7 +99,7 @@ do_test pragma-1.5 { PRAGMA default_cache_size; PRAGMA synchronous; } -} [list 4321 $DFLT_CACHE_SZ 0] +} [list -4321 $DFLT_CACHE_SZ 0] do_test pragma-1.6 { execsql { PRAGMA synchronous=ON; @@ -107,7 +107,7 @@ do_test pragma-1.6 { PRAGMA default_cache_size; PRAGMA synchronous; } -} [list 4321 $DFLT_CACHE_SZ 1] +} [list -4321 $DFLT_CACHE_SZ 1] do_test pragma-1.7 { db close sqlite3 db test.db From e73c91496fc921f3f6803a1f1a3ac0e1d6d2043d Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 9 Nov 2011 16:12:24 +0000 Subject: [PATCH 017/161] Minor changes needed to restore full branch test coverage. FossilOrigin-Name: bc10a753579b65ba4604867204b7b3d8383f3ac7 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/main.c | 9 --------- src/pcache1.c | 20 +++++++++++++++----- src/pragma.c | 13 ++++++++++--- src/prepare.c | 4 ++++ src/shell.c | 2 -- src/sqlite.h.in | 7 +++---- 8 files changed, 44 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 9fb4c8839b..d2fca0f81f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C A\snegative\svalue\sN\sfor\sthe\scache_size\spragma\sadjusts\sthe\snumber\sof\scache\npages\sto\suse\sapproximately\sN\skibibytes\sof\smemory. -D 2011-11-09T14:23:04.394 +C Minor\schanges\sneeded\sto\srestore\sfull\sbranch\stest\scoverage. +D 2011-11-09T16:12:24.434 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f -F src/main.c 93d49bc6abf4ccea97721d016b9f45228cff7057 +F src/main.c 8d75abfbb6f9518da984fcb83e7deb986e5fad1a F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 7456e2ca0524609ebc06a9befeda5289d4575ad4 @@ -173,16 +173,16 @@ F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 F src/pcache.c b9d52e9f844d91c27c161279234f273fc02abc71 F src/pcache.h c770382f9fae4ca5025c5523bd0aa13cd6ddc6f8 -F src/pcache1.c 9a42ace8022b3d38175c3b41802aa9bccd9c6a3a -F src/pragma.c c5ba7627fbdedc02c7b8f52e77a3bceb030cf5ed -F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4 +F src/pcache1.c 7a3ce2dca0ef889be94b9cb0a2dfc7917ec83eba +F src/pragma.c 65d1d63d64f8b7350f28d5ee6d40f7985deccdfe +F src/prepare.c ec4989f7f480544bdc4192fe663470d2a2d7d61e F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 -F src/shell.c 6d2ad7f80adc9c8c3195412879af36eb3196c1b6 -F src/sqlite.h.in 51b40e104b9d11b3d3a72a4d1399cb0b0ef45b19 +F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8 +F src/sqlite.h.in fa162d2a068b6c1c25896e8614be3c4f01897a95 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h f87f241b9821a9d466c2711b7345d30ef3624249 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 2e8ab3cedfebc33a831837792b523d1aa7cdc6b7 -R f79cb2e5e3c648503ef136bcf9a7e813 +P b3faa680aedc94ed8aa2819228c0d304b181cc51 +R b23b4af5ccb8f4c997cdcda51776df0c U drh -Z ee913c4e43d90078be9388d453dfd115 +Z d923662f887715e80eb341a5d52f178f diff --git a/manifest.uuid b/manifest.uuid index a97b46c07b..574c5c2aab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b3faa680aedc94ed8aa2819228c0d304b181cc51 \ No newline at end of file +bc10a753579b65ba4604867204b7b3d8383f3ac7 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 6e6af78c7a..eb40dcd7f1 100644 --- a/src/main.c +++ b/src/main.c @@ -2898,15 +2898,6 @@ int sqlite3_test_control(int op, ...){ } #endif - /* sqlite3_test_control(SQLITE_TESTCTRL_PGHDRSZ) - ** - ** Return the size of a pcache header in bytes. - */ - case SQLITE_TESTCTRL_PGHDRSZ: { - rc = sizeof(PgHdr); - break; - } - /* sqlite3_test_control(SQLITE_TESTCTRL_SCRATCHMALLOC, sz, &pNew, pFree); ** ** Pass pFree into sqlite3ScratchFree(). diff --git a/src/pcache1.c b/src/pcache1.c index c4bebe548d..a026ed2fb5 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -576,6 +576,9 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ int separateCache = sqlite3GlobalConfig.bCoreMutex>0; #endif + assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 ); + assert( szExtra < 300 ); + sz = sizeof(PCache1) + sizeof(PGroup)*separateCache; pCache = (PCache1 *)sqlite3_malloc(sz); if( pCache ){ @@ -748,17 +751,24 @@ static sqlite3_pcache_page *pcache1Fetch( || pGroup->nCurrentPage>=pGroup->nMaxPage || pcache1UnderMemoryPressure(pCache) )){ - PCache1 *pOtherCache; + PCache1 *pOther; pPage = pGroup->pLruTail; pcache1RemoveFromHash(pPage); pcache1PinPage(pPage); - if( (pOtherCache = pPage->pCache)->szPage!=pCache->szPage - || pOtherCache->szExtra!=pCache->szExtra - ){ + pOther = pPage->pCache; + + /* We want to verify that szPage and szExtra are the same for pOther + ** and pCache. Assert that we can verify this by comparing sums. */ + assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 ); + assert( pCache->szExtra<512 ); + assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 ); + assert( pOther->szExtra<512 ); + + if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){ pcache1FreePage(pPage); pPage = 0; }else{ - pGroup->nCurrentPage -= (pOtherCache->bPurgeable - pCache->bPurgeable); + pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable); } } diff --git a/src/pragma.c b/src/pragma.c index 5f33ee99d7..538aa61083 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -346,7 +346,7 @@ void sqlite3Pragma( goto pragma_out; } -#ifndef SQLITE_OMIT_PAGER_PRAGMAS +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) /* ** PRAGMA [database.]default_cache_size ** PRAGMA [database.]default_cache_size=N @@ -395,7 +395,9 @@ void sqlite3Pragma( sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } }else +#endif /* !SQLITE_OMIT_PAGER_PRAGMAS && !SQLITE_OMIT_DEPRECATED */ +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) /* ** PRAGMA [database.]page_size ** PRAGMA [database.]page_size=N @@ -416,7 +418,7 @@ void sqlite3Pragma( ** buffer that the pager module resizes using sqlite3_realloc(). */ db->nextPagesize = sqlite3Atoi(zRight); - if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){ + if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){ db->mallocFailed = 1; } } @@ -456,6 +458,10 @@ void sqlite3Pragma( ** second form attempts to change this setting. Both ** forms return the current setting. ** + ** The absolute value of N is used. This is undocumented and might + ** change. The only purpose is to provide an easy way to test + ** the sqlite3AbsInt32() function. + ** ** PRAGMA [database.]page_count ** ** Return the number of pages in the specified database. @@ -470,7 +476,8 @@ void sqlite3Pragma( if( sqlite3Tolower(zLeft[0])=='p' ){ sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg); }else{ - sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, sqlite3Atoi(zRight)); + sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, + sqlite3AbsInt32(sqlite3Atoi(zRight))); } sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1); sqlite3VdbeSetNumCols(v, 1); diff --git a/src/prepare.c b/src/prepare.c index fc45b8e6aa..faeefa894f 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -278,9 +278,13 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ pDb->pSchema->enc = ENC(db); if( pDb->pSchema->cache_size==0 ){ +#ifndef SQLITE_OMIT_DEPRECATED size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]); if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } pDb->pSchema->cache_size = size; +#else + pDb->pSchema->cache_size = SQLITE_DEFAULT_CACHE_SIZE; +#endif sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } diff --git a/src/shell.c b/src/shell.c index 11da32aa8f..e33a0687b4 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2220,7 +2220,6 @@ static int do_meta_command(char *zLine, struct callback_data *p){ { "reserve", SQLITE_TESTCTRL_RESERVE }, { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, - { "pghdrsz", SQLITE_TESTCTRL_PGHDRSZ }, { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, }; int testctrl = -1; @@ -2265,7 +2264,6 @@ static int do_meta_command(char *zLine, struct callback_data *p){ case SQLITE_TESTCTRL_PRNG_SAVE: case SQLITE_TESTCTRL_PRNG_RESTORE: case SQLITE_TESTCTRL_PRNG_RESET: - case SQLITE_TESTCTRL_PGHDRSZ: if( nArg==2 ){ rc = sqlite3_test_control(testctrl); printf("%d (0x%08x)\n", rc, rc); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 316d4231b2..50e95efe2c 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5630,10 +5630,9 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_RESERVE 14 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 -#define SQLITE_TESTCTRL_PGHDRSZ 17 -#define SQLITE_TESTCTRL_SCRATCHMALLOC 18 -#define SQLITE_TESTCTRL_LOCALTIME_FAULT 19 -#define SQLITE_TESTCTRL_LAST 19 +#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 +#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 +#define SQLITE_TESTCTRL_LAST 18 /* ** CAPI3REF: SQLite Runtime Status From 32121199be5e64c99d060476c6531fe43521e57a Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 9 Nov 2011 17:01:40 +0000 Subject: [PATCH 018/161] When compiling with MSVC, use the _msize function. FossilOrigin-Name: 797a147934743a565c6f1f9dd4d41574690b4c2b --- Makefile.msc | 3 +++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index f40936d915..ea7efa7580 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -49,6 +49,9 @@ BCC = cl.exe # TCC = cl.exe -W3 -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src -fp:precise +# We always have the _msize function available when using MSVC. +TCC = $(TCC) -DHAVE_MALLOC_USABLE_SIZE -Dmalloc_usable_size=_msize + # The mksqlite3c.tcl and mksqlite3h.tcl scripts will pull in # any extension header files by default. For non-amalgamation # builds, we need to make sure the compiler can find these. diff --git a/manifest b/manifest index d2fca0f81f..e2b45c4c60 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Minor\schanges\sneeded\sto\srestore\sfull\sbranch\stest\scoverage. -D 2011-11-09T16:12:24.434 +C When\scompiling\swith\sMSVC,\suse\sthe\s_msize\sfunction. +D 2011-11-09T17:01:40.187 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc dcad80fa69f17d46fe6778ba873fc108ca16298d +F Makefile.msc 3bd3641a345d488a9601c0cc7f9d35aeede5d12b F Makefile.vxworks 1deb39c8bb047296c30161ffa10c1b5423e632f9 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION bb37c274b503bbe73f00ea4f374eb817cba4b171 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P b3faa680aedc94ed8aa2819228c0d304b181cc51 -R b23b4af5ccb8f4c997cdcda51776df0c -U drh -Z d923662f887715e80eb341a5d52f178f +P bc10a753579b65ba4604867204b7b3d8383f3ac7 +R b4ab2e16a52b2d4a4a1aafe11f524dda +U mistachkin +Z 36fa820f8cb337e79d0b9d411145a7d3 diff --git a/manifest.uuid b/manifest.uuid index 574c5c2aab..48433751d7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bc10a753579b65ba4604867204b7b3d8383f3ac7 \ No newline at end of file +797a147934743a565c6f1f9dd4d41574690b4c2b \ No newline at end of file From d6ca4b9fe1a7bbf2b1c00e8d29d969dd623c1652 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 9 Nov 2011 18:07:34 +0000 Subject: [PATCH 019/161] Omit an unnecessary Sleep() call in windows pending-lock retry logic. Enhance the comment on that logic to discourage people from copying it into other VFSes. FossilOrigin-Name: 0c951a970436725b6bbd64568de500f7a4e6460b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_win.c | 8 +++++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 4ac21d9d50..53857bdc28 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\sunix\sVFS\stolerant\sof\sread()\scalls\sthat\sreturn\sless\sthan\sthe\nrequested\snumber\sof\sbytes. -D 2011-11-07T18:16:00.449 +C Omit\san\sunnecessary\sSleep()\scall\sin\swindows\spending-lock\sretry\nlogic.\s\sEnhance\sthe\scomment\son\sthat\slogic\sto\sdiscourage\speople\nfrom\scopying\sit\sinto\sother\sVFSes. +D 2011-11-09T18:07:34.181 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -167,7 +167,7 @@ F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 4fbb91726165e105c1679a2660f49a3f4c376e4f -F src/os_win.c 49d418916428a59d773f39993db0ecde56ab4c37 +F src/os_win.c 6749a95cfe4bf00b71716515ca1c2601aa212ef8 F src/pager.c db33d4bf1e3e019c34c220971cc6c3aa07c30f54 F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 4fe5b73115a8b44950767f1b528107261d7312c9 -R 235506ff1af96e54491bff797f85e25a +P a210695abcfa5cb04279edfd04824d881b7c4ada +R e1dcb4cfde514f4d6d711be7740004c1 U drh -Z b43cdd5d2255740ef7ed4b6994dd0923 +Z 8231b98b427b17224b8ab6c5f9a53e24 diff --git a/manifest.uuid b/manifest.uuid index 26a5869430..06b8ed2350 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a210695abcfa5cb04279edfd04824d881b7c4ada \ No newline at end of file +0c951a970436725b6bbd64568de500f7a4e6460b \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 4518030483..71c5248f70 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -1445,11 +1445,13 @@ static int winLock(sqlite3_file *id, int locktype){ ){ int cnt = 3; while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){ - /* Try 3 times to get the pending lock. The pending lock might be - ** held by another reader process who will release it momentarily. + /* Try 3 times to get the pending lock. This is needed to work + ** around problems caused by anti-virus software on windows system. + ** If you are using this code as a model for alternative VFSes, do not + ** copy this retry logic. It is a hack intended for windows only. */ OSTRACE(("could not get a PENDING lock. cnt=%d\n", cnt)); - Sleep(1); + if( cnt ) Sleep(1); } gotPendingLock = res; if( !res ){ From 8225d66be651e542dc990ecf9fe8a84b7ff01e42 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 10 Nov 2011 02:24:11 +0000 Subject: [PATCH 020/161] Use sqlite3MallocSize() to get the actual size of the memory allocation used for lookaside cache and increase the size of the cache to use the full allocation. FossilOrigin-Name: 0e53ecad9468d0a13d155a4462551d4c234a7d5c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/main.c | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index e2b45c4c60..2d01a44018 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\scompiling\swith\sMSVC,\suse\sthe\s_msize\sfunction. -D 2011-11-09T17:01:40.187 +C Use\ssqlite3MallocSize()\sto\sget\sthe\sactual\ssize\sof\sthe\smemory\sallocation\nused\sfor\slookaside\scache\sand\sincrease\sthe\ssize\sof\sthe\scache\sto\suse\sthe\nfull\sallocation. +D 2011-11-10T02:24:11.076 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f -F src/main.c 8d75abfbb6f9518da984fcb83e7deb986e5fad1a +F src/main.c 666a78ff3495e6b598dfdf95470d94cdc7026b3e F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 7456e2ca0524609ebc06a9befeda5289d4575ad4 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P bc10a753579b65ba4604867204b7b3d8383f3ac7 -R b4ab2e16a52b2d4a4a1aafe11f524dda -U mistachkin -Z 36fa820f8cb337e79d0b9d411145a7d3 +P 797a147934743a565c6f1f9dd4d41574690b4c2b +R 18d8d9d953fa089dbbd8eb3a1a1977dd +U drh +Z 2aff7dca442feb19b2932365e48ed79f diff --git a/manifest.uuid b/manifest.uuid index 48433751d7..f0fb8356c2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -797a147934743a565c6f1f9dd4d41574690b4c2b \ No newline at end of file +0e53ecad9468d0a13d155a4462551d4c234a7d5c \ No newline at end of file diff --git a/src/main.c b/src/main.c index eb40dcd7f1..04110ce14e 100644 --- a/src/main.c +++ b/src/main.c @@ -495,6 +495,7 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ sqlite3BeginBenignMalloc(); pStart = sqlite3Malloc( sz*cnt ); /* IMP: R-61949-35727 */ sqlite3EndBenignMalloc(); + if( pStart ) cnt = sqlite3MallocSize(pStart)/sz; }else{ sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ pStart = pBuf; From 61a4bd5c6cfc2d196dad5a5ab2929fec48f03e89 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 10 Nov 2011 02:39:28 +0000 Subject: [PATCH 021/161] Follow-on to the previous check-in to prevent a division by zero if the lookahead slot size is something goofy like 6 on a 32-bit machine. FossilOrigin-Name: 6bda711f93e753dd0be8d896a007b3f7b5064787 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/main.c | 7 +++---- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 2d01a44018..51265bf5ec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\ssqlite3MallocSize()\sto\sget\sthe\sactual\ssize\sof\sthe\smemory\sallocation\nused\sfor\slookaside\scache\sand\sincrease\sthe\ssize\sof\sthe\scache\sto\suse\sthe\nfull\sallocation. -D 2011-11-10T02:24:11.076 +C Follow-on\sto\sthe\sprevious\scheck-in\sto\sprevent\sa\sdivision\sby\szero\sif\sthe\nlookahead\sslot\ssize\sis\ssomething\sgoofy\slike\s6\son\sa\s32-bit\smachine. +D 2011-11-10T02:39:28.949 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f -F src/main.c 666a78ff3495e6b598dfdf95470d94cdc7026b3e +F src/main.c 87dd4f6ee9b1700d54164ab4e14f2f7abc75486f F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 7456e2ca0524609ebc06a9befeda5289d4575ad4 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 797a147934743a565c6f1f9dd4d41574690b4c2b -R 18d8d9d953fa089dbbd8eb3a1a1977dd +P 0e53ecad9468d0a13d155a4462551d4c234a7d5c +R fbf272ab03502c9559fd474b247cbcd0 U drh -Z 2aff7dca442feb19b2932365e48ed79f +Z f89d3293b31cf240feb4175eb6a1bbd3 diff --git a/manifest.uuid b/manifest.uuid index f0fb8356c2..6018b07c43 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0e53ecad9468d0a13d155a4462551d4c234a7d5c \ No newline at end of file +6bda711f93e753dd0be8d896a007b3f7b5064787 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 04110ce14e..27dacac1b2 100644 --- a/src/main.c +++ b/src/main.c @@ -482,22 +482,21 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ if( db->lookaside.bMalloced ){ sqlite3_free(db->lookaside.pStart); } - /* The size of a lookaside slot needs to be larger than a pointer - ** to be useful. + /* The size of a lookaside slot after ROUNDDOWN8 needs to be larger + ** than a pointer to be useful. */ + sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0; if( cnt<0 ) cnt = 0; if( sz==0 || cnt==0 ){ sz = 0; pStart = 0; }else if( pBuf==0 ){ - sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ sqlite3BeginBenignMalloc(); pStart = sqlite3Malloc( sz*cnt ); /* IMP: R-61949-35727 */ sqlite3EndBenignMalloc(); if( pStart ) cnt = sqlite3MallocSize(pStart)/sz; }else{ - sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ pStart = pBuf; } db->lookaside.pStart = pStart; From 2aef997cbdc535def641a4918dd0ca287ca72d9b Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 10 Nov 2011 20:21:20 +0000 Subject: [PATCH 022/161] In winAccess, save the Win32 last error value prior to invoking user logging callback. Also, explicitly pass the Win32 last error value to winLogError in order to keep it accurate. Fixes a problem reported on the mailing list. FossilOrigin-Name: 32ab365715e2c50f30aa2f92a323857b9d917bf6 --- manifest | 14 ++++++------ manifest.uuid | 2 +- src/os_win.c | 63 ++++++++++++++++++++++++++++++++------------------- 3 files changed, 48 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 53857bdc28..69f18e241a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Omit\san\sunnecessary\sSleep()\scall\sin\swindows\spending-lock\sretry\nlogic.\s\sEnhance\sthe\scomment\son\sthat\slogic\sto\sdiscourage\speople\nfrom\scopying\sit\sinto\sother\sVFSes. -D 2011-11-09T18:07:34.181 +C In\swinAccess,\ssave\sthe\sWin32\slast\serror\svalue\sprior\sto\sinvoking\suser\slogging\scallback.\s\sAlso,\sexplicitly\spass\sthe\sWin32\slast\serror\svalue\sto\swinLogError\sin\sorder\sto\skeep\sit\saccurate.\s\sFixes\sa\sproblem\sreported\son\sthe\smailing\slist. +D 2011-11-10T20:21:20.308 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -167,7 +167,7 @@ F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 4fbb91726165e105c1679a2660f49a3f4c376e4f -F src/os_win.c 6749a95cfe4bf00b71716515ca1c2601aa212ef8 +F src/os_win.c a9190cb70e5071776e0064f7a04778c594c2afad F src/pager.c db33d4bf1e3e019c34c220971cc6c3aa07c30f54 F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P a210695abcfa5cb04279edfd04824d881b7c4ada -R e1dcb4cfde514f4d6d711be7740004c1 -U drh -Z 8231b98b427b17224b8ab6c5f9a53e24 +P 0c951a970436725b6bbd64568de500f7a4e6460b +R 07fcb0ebb49fcaa5a3b1285d87c90ade +U mistachkin +Z 984e599e94c8add22fe67965d6d580c6 diff --git a/manifest.uuid b/manifest.uuid index 06b8ed2350..cee874f887 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0c951a970436725b6bbd64568de500f7a4e6460b \ No newline at end of file +32ab365715e2c50f30aa2f92a323857b9d917bf6 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 71c5248f70..e8ea45583f 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -630,16 +630,16 @@ static int getLastErrorMsg(int nBuf, char *zBuf){ ** The two subsequent arguments should be the name of the OS function that ** failed and the the associated file-system path, if any. */ -#define winLogError(a,b,c) winLogErrorAtLine(a,b,c,__LINE__) +#define winLogError(a,b,c,d) winLogErrorAtLine(a,b,c,d,__LINE__) static int winLogErrorAtLine( int errcode, /* SQLite error code */ + DWORD lastErrno, /* Win32 last error */ const char *zFunc, /* Name of OS function that failed */ const char *zPath, /* File path associated with error */ int iLine /* Source line number where error occurred */ ){ char zMsg[500]; /* Human readable error text */ int i; /* Loop counter */ - DWORD iErrno = GetLastError(); /* Error code */ zMsg[0] = 0; getLastErrorMsg(sizeof(zMsg), zMsg); @@ -649,7 +649,7 @@ static int winLogErrorAtLine( zMsg[i] = 0; sqlite3_log(errcode, "os_win.c:%d: (%d) %s(%s) - %s", - iLine, iErrno, zFunc, zPath, zMsg + iLine, lastErrno, zFunc, zPath, zMsg ); return errcode; @@ -780,7 +780,7 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ pFile->hMutex = CreateMutexW(NULL, FALSE, zName); if (!pFile->hMutex){ pFile->lastErrno = GetLastError(); - winLogError(SQLITE_ERROR, "winceCreateLock1", zFilename); + winLogError(SQLITE_ERROR, pFile->lastErrno, "winceCreateLock1", zFilename); free(zName); return FALSE; } @@ -812,7 +812,8 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ /* If mapping failed, close the shared memory handle and erase it */ if (!pFile->shared){ pFile->lastErrno = GetLastError(); - winLogError(SQLITE_ERROR, "winceCreateLock2", zFilename); + winLogError(SQLITE_ERROR, pFile->lastErrno, + "winceCreateLock2", zFilename); CloseHandle(pFile->hShared); pFile->hShared = NULL; } @@ -1058,7 +1059,8 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){ dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); if( (dwRet==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR) ){ pFile->lastErrno = GetLastError(); - winLogError(SQLITE_IOERR_SEEK, "seekWinFile", pFile->zPath); + winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, + "seekWinFile", pFile->zPath); return 1; } @@ -1105,7 +1107,8 @@ static int winClose(sqlite3_file *id){ OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed")); OpenCounter(-1); return rc ? SQLITE_OK - : winLogError(SQLITE_IOERR_CLOSE, "winClose", pFile->zPath); + : winLogError(SQLITE_IOERR_CLOSE, GetLastError(), + "winClose", pFile->zPath); } /* @@ -1133,7 +1136,8 @@ static int winRead( while( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ if( retryIoerr(&nRetry) ) continue; pFile->lastErrno = GetLastError(); - return winLogError(SQLITE_IOERR_READ, "winRead", pFile->zPath); + return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, + "winRead", pFile->zPath); } logIoerr(nRetry); if( nRead<(DWORD)amt ){ @@ -1192,7 +1196,8 @@ static int winWrite( || ( pFile->lastErrno==ERROR_DISK_FULL )){ return SQLITE_FULL; } - return winLogError(SQLITE_IOERR_WRITE, "winWrite", pFile->zPath); + return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, + "winWrite", pFile->zPath); }else{ logIoerr(nRetry); } @@ -1222,10 +1227,12 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ if( seekWinFile(pFile, nByte) ){ - rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate1", pFile->zPath); + rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, + "winTruncate1", pFile->zPath); }else if( 0==SetEndOfFile(pFile->h) ){ pFile->lastErrno = GetLastError(); - rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate2", pFile->zPath); + rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, + "winTruncate2", pFile->zPath); } OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok")); @@ -1296,7 +1303,8 @@ static int winSync(sqlite3_file *id, int flags){ return SQLITE_OK; }else{ pFile->lastErrno = GetLastError(); - return winLogError(SQLITE_IOERR_FSYNC, "winSync", pFile->zPath); + return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, + "winSync", pFile->zPath); } #endif } @@ -1317,7 +1325,8 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ && ((error = GetLastError()) != NO_ERROR) ) { pFile->lastErrno = error; - return winLogError(SQLITE_IOERR_FSTAT, "winFileSize", pFile->zPath); + return winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, + "winFileSize", pFile->zPath); } *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; return SQLITE_OK; @@ -1377,7 +1386,8 @@ static int unlockReadLock(winFile *pFile){ } if( res==0 && GetLastError()!=ERROR_NOT_LOCKED ){ pFile->lastErrno = GetLastError(); - winLogError(SQLITE_IOERR_UNLOCK, "unlockReadLock", pFile->zPath); + winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, + "unlockReadLock", pFile->zPath); } return res; } @@ -1580,7 +1590,8 @@ static int winUnlock(sqlite3_file *id, int locktype){ if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ /* This should never happen. We should always be able to ** reacquire the read lock */ - rc = winLogError(SQLITE_IOERR_UNLOCK, "winUnlock", pFile->zPath); + rc = winLogError(SQLITE_IOERR_UNLOCK, GetLastError(), + "winUnlock", pFile->zPath); } } if( type>=RESERVED_LOCK ){ @@ -1971,7 +1982,8 @@ static int winOpenSharedMemory(winFile *pDbFd){ if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); if( rc!=SQLITE_OK ){ - rc = winLogError(SQLITE_IOERR_SHMOPEN, "winOpenShm", pDbFd->zPath); + rc = winLogError(SQLITE_IOERR_SHMOPEN, GetLastError(), + "winOpenShm", pDbFd->zPath); } } if( rc==SQLITE_OK ){ @@ -2230,7 +2242,8 @@ static int winShmMap( */ rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); if( rc!=SQLITE_OK ){ - rc = winLogError(SQLITE_IOERR_SHMSIZE, "winShmMap1", pDbFd->zPath); + rc = winLogError(SQLITE_IOERR_SHMSIZE, GetLastError(), + "winShmMap1", pDbFd->zPath); goto shmpage_out; } @@ -2244,7 +2257,8 @@ static int winShmMap( if( !isWrite ) goto shmpage_out; rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte); if( rc!=SQLITE_OK ){ - rc = winLogError(SQLITE_IOERR_SHMSIZE, "winShmMap2", pDbFd->zPath); + rc = winLogError(SQLITE_IOERR_SHMSIZE, GetLastError(), + "winShmMap2", pDbFd->zPath); goto shmpage_out; } } @@ -2281,7 +2295,8 @@ static int winShmMap( } if( !pMap ){ pShmNode->lastErrno = GetLastError(); - rc = winLogError(SQLITE_IOERR_SHMMAP, "winShmMap3", pDbFd->zPath); + rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, + "winShmMap3", pDbFd->zPath); if( hMap ) CloseHandle(hMap); goto shmpage_out; } @@ -2615,7 +2630,7 @@ static int winOpen( if( h==INVALID_HANDLE_VALUE ){ pFile->lastErrno = GetLastError(); - winLogError(SQLITE_CANTOPEN, "winOpen", zUtf8Name); + winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); free(zConverted); if( isReadWrite && !isExclusive ){ return winOpen(pVfs, zName, id, @@ -2708,7 +2723,8 @@ static int winDelete( #endif } if( rc ){ - rc = winLogError(SQLITE_IOERR_DELETE, "winDelete", zFilename); + rc = winLogError(SQLITE_IOERR_DELETE, GetLastError(), + "winDelete", zFilename); }else{ logIoerr(cnt); } @@ -2755,9 +2771,10 @@ static int winAccess( attr = sAttrData.dwFileAttributes; } }else{ + DWORD lastErrno = GetLastError(); logIoerr(cnt); - if( GetLastError()!=ERROR_FILE_NOT_FOUND ){ - winLogError(SQLITE_IOERR_ACCESS, "winAccess", zFilename); + if( lastErrno!=ERROR_FILE_NOT_FOUND ){ + winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename); free(zConverted); return SQLITE_IOERR_ACCESS; }else{ From a9664a14ea7e16d1e3031c5f8e53347375838005 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 10 Nov 2011 21:45:06 +0000 Subject: [PATCH 023/161] Expand passing of a last error argument to the getLastErrorMsg function. Also, remove unused SQLITE_W32_THREADS define. FossilOrigin-Name: 8f28797984c1d4700357a75815ca4b324c3ebf5c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_win.c | 30 +++++++++++++----------------- 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 69f18e241a..1e9639f02b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\swinAccess,\ssave\sthe\sWin32\slast\serror\svalue\sprior\sto\sinvoking\suser\slogging\scallback.\s\sAlso,\sexplicitly\spass\sthe\sWin32\slast\serror\svalue\sto\swinLogError\sin\sorder\sto\skeep\sit\saccurate.\s\sFixes\sa\sproblem\sreported\son\sthe\smailing\slist. -D 2011-11-10T20:21:20.308 +C Expand\spassing\sof\sa\slast\serror\sargument\sto\sthe\sgetLastErrorMsg\sfunction.\s\sAlso,\sremove\sunused\sSQLITE_W32_THREADS\sdefine. +D 2011-11-10T21:45:06.907 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -167,7 +167,7 @@ F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 4fbb91726165e105c1679a2660f49a3f4c376e4f -F src/os_win.c a9190cb70e5071776e0064f7a04778c594c2afad +F src/os_win.c d6cf718667c4d89d930f30caa6cdc7f7753e259a F src/pager.c db33d4bf1e3e019c34c220971cc6c3aa07c30f54 F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 0c951a970436725b6bbd64568de500f7a4e6460b -R 07fcb0ebb49fcaa5a3b1285d87c90ade +P 32ab365715e2c50f30aa2f92a323857b9d917bf6 +R d5d8a9a49f50a40940976e300037af02 U mistachkin -Z 984e599e94c8add22fe67965d6d580c6 +Z a0f426067c598247950f7d47f9af3362 diff --git a/manifest.uuid b/manifest.uuid index cee874f887..b053265d1f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -32ab365715e2c50f30aa2f92a323857b9d917bf6 \ No newline at end of file +8f28797984c1d4700357a75815ca4b324c3ebf5c \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index e8ea45583f..8032b04bdd 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -48,13 +48,6 @@ # include #endif -/* -** Macros used to determine whether or not to use threads. -*/ -#if defined(THREADSAFE) && THREADSAFE -# define SQLITE_W32_THREADS 1 -#endif - /* ** Include code that is common to all os_*.c files */ @@ -558,20 +551,21 @@ char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ ** is zero if the error message fits in the buffer, or non-zero ** otherwise (if the message was truncated). */ -static int getLastErrorMsg(int nBuf, char *zBuf){ +static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ /* FormatMessage returns 0 on failure. Otherwise it ** returns the number of TCHARs written to the output ** buffer, excluding the terminating null char. */ - DWORD error = GetLastError(); DWORD dwLen = 0; char *zOut = 0; if( isNT() ){ WCHAR *zTempWide = NULL; - dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, - error, + lastErrno, 0, (LPWSTR) &zTempWide, 0, @@ -589,9 +583,11 @@ static int getLastErrorMsg(int nBuf, char *zBuf){ #if SQLITE_OS_WINCE==0 }else{ char *zTemp = NULL; - dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, - error, + lastErrno, 0, (LPSTR) &zTemp, 0, @@ -605,7 +601,7 @@ static int getLastErrorMsg(int nBuf, char *zBuf){ #endif } if( 0 == dwLen ){ - sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error); + sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", lastErrno, lastErrno); }else{ /* copy a maximum of nBuf chars to output buffer */ sqlite3_snprintf(nBuf, zBuf, "%s", zOut); @@ -642,7 +638,7 @@ static int winLogErrorAtLine( int i; /* Loop counter */ zMsg[0] = 0; - getLastErrorMsg(sizeof(zMsg), zMsg); + getLastErrorMsg(lastErrno, sizeof(zMsg), zMsg); assert( errcode!=SQLITE_OK ); if( zPath==0 ) zPath = ""; for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} @@ -2998,7 +2994,7 @@ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ } static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ UNUSED_PARAMETER(pVfs); - getLastErrorMsg(nBuf, zBufOut); + getLastErrorMsg(GetLastError(), nBuf, zBufOut); } static void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){ UNUSED_PARAMETER(pVfs); @@ -3172,7 +3168,7 @@ static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ */ static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ UNUSED_PARAMETER(pVfs); - return getLastErrorMsg(nBuf, zBuf); + return getLastErrorMsg(GetLastError(), nBuf, zBuf); } From 3def2357e6c0e7d72e195e52f780e5d78d9913d7 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 11 Nov 2011 00:27:15 +0000 Subject: [PATCH 024/161] Make sure a corrupt index does not cause a buffer overread in sqlite3VdbeRecordCompare(). FossilOrigin-Name: 471cf0d8e7857110e525e029c2d535cb518dba6a --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/btree.c | 20 +++++++++++++++----- src/btreeInt.h | 2 ++ 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 1e9639f02b..1d56a640de 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Expand\spassing\sof\sa\slast\serror\sargument\sto\sthe\sgetLastErrorMsg\sfunction.\s\sAlso,\sremove\sunused\sSQLITE_W32_THREADS\sdefine. -D 2011-11-10T21:45:06.907 +C Make\ssure\sa\scorrupt\sindex\sdoes\snot\scause\sa\sbuffer\soverread\sin\s\nsqlite3VdbeRecordCompare(). +D 2011-11-11T00:27:15.786 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -125,9 +125,9 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 4368158da74d4711888e03264105c5c527d76caf F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 32199e2d939233ade25340eaba450f818b37c079 +F src/btree.c 2521a74f04cf288497af3b318fa3a31efb272ef6 F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce -F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 +F src/btreeInt.h ea863a819224d3e6845ad1e39954d41558b8cd8b F src/build.c 8af67a08a852ff4c63701963cb1ab7166f577814 F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 32ab365715e2c50f30aa2f92a323857b9d917bf6 -R d5d8a9a49f50a40940976e300037af02 -U mistachkin -Z a0f426067c598247950f7d47f9af3362 +P 8f28797984c1d4700357a75815ca4b324c3ebf5c +R 0b7ae5ff536a087fdb2c3479a3ed3d3f +U drh +Z 717b87433a48f5a306459509a02bb49f diff --git a/manifest.uuid b/manifest.uuid index b053265d1f..8f58ddd640 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8f28797984c1d4700357a75815ca4b324c3ebf5c \ No newline at end of file +471cf0d8e7857110e525e029c2d535cb518dba6a \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index d64e172f74..a1b05e1f3e 100644 --- a/src/btree.c +++ b/src/btree.c @@ -859,7 +859,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ ** This routine works only for pages that do not contain overflow cells. */ #define findCell(P,I) \ - ((P)->aData + ((P)->maskPage & get2byte(&(P)->aData[(P)->cellOffset+2*(I)]))) + ((P)->aData + ((P)->maskPage & get2byte(&(P)->aCellIdx[2*(I)]))) #define findCellv2(D,M,O,I) (D+(M&get2byte(D+(O+2*(I))))) @@ -1409,6 +1409,8 @@ static int btreeInitPage(MemPage *pPage){ pPage->nOverflow = 0; usableSize = pBt->usableSize; pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf; + pPage->aDataEnd = &data[usableSize]; + pPage->aCellIdx = &data[cellOffset]; top = get2byteNotZero(&data[hdr+5]); pPage->nCell = get2byte(&data[hdr+3]); if( pPage->nCell>MX_CELL(pBt) ){ @@ -1512,6 +1514,8 @@ static void zeroPage(MemPage *pPage, int flags){ decodeFlags(pPage, flags); pPage->hdrOffset = hdr; pPage->cellOffset = first; + pPage->aDataEnd = &data[pBt->usableSize]; + pPage->aCellIdx = &data[first]; pPage->nOverflow = 0; assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); pPage->maskPage = (u16)(pBt->pageSize - 1); @@ -4550,16 +4554,22 @@ int sqlite3BtreeMovetoUnpacked( ** 2 bytes of the cell. */ int nCell = pCell[0]; - if( !(nCell & 0x80) && nCell<=pPage->maxLocal ){ + if( !(nCell & 0x80) + && nCell<=pPage->maxLocal + && (pCell+nCell+1)<=pPage->aDataEnd + ){ /* This branch runs if the record-size field of the cell is a ** single byte varint and the record fits entirely on the main ** b-tree page. */ + testcase( pCell+nCell+1==pPage->aDataEnd ); c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[1], pIdxKey); }else if( !(pCell[1] & 0x80) && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal + && (pCell+nCell+2)<=pPage->aDataEnd ){ /* The record-size field is a 2 byte varint and the record ** fits entirely on the main b-tree page. */ + testcase( pCell+nCell+2==pPage->aDataEnd ); c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[2], pIdxKey); }else{ /* The record flows over onto one or more overflow pages. In @@ -5454,7 +5464,7 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); data = pPage->aData; - ptr = &data[pPage->cellOffset + 2*idx]; + ptr = &pPage->aCellIdx[2*idx]; pc = get2byte(ptr); hdr = pPage->hdrOffset; testcase( pc==get2byte(&data[hdr+5]) ); @@ -5468,7 +5478,7 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ *pRC = rc; return; } - endPtr = &data[pPage->cellOffset + 2*pPage->nCell - 2]; + endPtr = &pPage->aCellIdx[2*pPage->nCell - 2]; assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */ while( ptrnCell==0 ); assert( get2byteNotZero(&data[hdr+5])==nUsable ); - pCellptr = &data[pPage->cellOffset + nCell*2]; + pCellptr = &pPage->aCellIdx[nCell*2]; cellbody = nUsable; for(i=nCell-1; i>=0; i--){ u16 sz = aSize[i]; diff --git a/src/btreeInt.h b/src/btreeInt.h index 55469cff90..d3117ad9fa 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -289,6 +289,8 @@ struct MemPage { } aOvfl[5]; BtShared *pBt; /* Pointer to BtShared that this page is part of */ u8 *aData; /* Pointer to disk image of the page data */ + u8 *aDataEnd; /* One byte past the end of usable data */ + u8 *aCellIdx; /* The cell index area */ DbPage *pDbPage; /* Pager page handle */ Pgno pgno; /* Page number for this page */ }; From 318507b74fe668f2b147e5c1d03f211860226428 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 11 Nov 2011 22:08:54 +0000 Subject: [PATCH 025/161] Work in progress to implement the 'syscall' functionality for Windows. FossilOrigin-Name: ed88fb00240de75457c0da19e87c12082622ca17 --- manifest | 15 +- manifest.uuid | 2 +- src/os_win.c | 1025 +++++++++++++++++++++++++++++++++++++------------ 3 files changed, 779 insertions(+), 263 deletions(-) diff --git a/manifest b/manifest index 1e9639f02b..455829f1fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Expand\spassing\sof\sa\slast\serror\sargument\sto\sthe\sgetLastErrorMsg\sfunction.\s\sAlso,\sremove\sunused\sSQLITE_W32_THREADS\sdefine. -D 2011-11-10T21:45:06.907 +C Work\sin\sprogress\sto\simplement\sthe\s'syscall'\sfunctionality\sfor\sWindows. +D 2011-11-11T22:08:54.567 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -167,7 +167,7 @@ F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 4fbb91726165e105c1679a2660f49a3f4c376e4f -F src/os_win.c d6cf718667c4d89d930f30caa6cdc7f7753e259a +F src/os_win.c 1d8fe13d456ef2df6576af55a8b15937244e1e26 F src/pager.c db33d4bf1e3e019c34c220971cc6c3aa07c30f54 F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 @@ -974,7 +974,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 32ab365715e2c50f30aa2f92a323857b9d917bf6 -R d5d8a9a49f50a40940976e300037af02 +P 8f28797984c1d4700357a75815ca4b324c3ebf5c +R 0ef79000409253332bbd2b77a41d7f05 +T *branch * winSyscall +T *sym-winSyscall * +T -sym-trunk * U mistachkin -Z a0f426067c598247950f7d47f9af3362 +Z 57ebd7677acce4cb8f4dee76b646710f diff --git a/manifest.uuid b/manifest.uuid index b053265d1f..3546fa2265 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8f28797984c1d4700357a75815ca4b324c3ebf5c \ No newline at end of file +ed88fb00240de75457c0da19e87c12082622ca17 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 8032b04bdd..bc86e98588 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -10,10 +10,10 @@ ** ****************************************************************************** ** -** This file contains code that is specific to windows. +** This file contains code that is specific to Windows. */ #include "sqliteInt.h" -#if SQLITE_OS_WIN /* This file is used for windows only */ +#if SQLITE_OS_WIN /* This file is used for Windows only */ /* @@ -38,12 +38,10 @@ ** ** The point of this discussion is as follows: When creating a new ** OS layer for an embedded system, if you use this file as an example, -** avoid the use of malloc()/free(). Those routines work ok on windows +** avoid the use of malloc()/free(). Those routines work ok on Windows ** desktops but not so well in embedded systems. */ -#include - #ifdef __CYGWIN__ # include #endif @@ -54,21 +52,12 @@ #include "os_common.h" /* -** Some microsoft compilers lack this definition. +** Some Microsoft compilers lack this definition. */ #ifndef INVALID_FILE_ATTRIBUTES # define INVALID_FILE_ATTRIBUTES ((DWORD)-1) #endif -/* -** Determine if we are dealing with WindowsCE - which has a much -** reduced API. -*/ -#if SQLITE_OS_WINCE -# define AreFileApisANSI() 1 -# define FormatMessageW(a,b,c,d,e,f,g) 0 -#endif - /* Forward references */ typedef struct winShm winShm; /* A connection to shared-memory */ typedef struct winShmNode winShmNode; /* A region of shared-memory */ @@ -104,7 +93,7 @@ struct winFile { const char *zPath; /* Full pathname of this file */ int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */ #if SQLITE_OS_WINCE - WCHAR *zDeleteOnClose; /* Name of file to delete when closing */ + LPWSTR zDeleteOnClose; /* Name of file to delete when closing */ HANDLE hMutex; /* Mutex used to control access to shared lock */ HANDLE hShared; /* Shared memory segment used for locking */ winceLock local; /* Locks obtained by this instance of winFile */ @@ -209,6 +198,536 @@ int sqlite3_os_type = 0; static int sqlite3_os_type = 0; #endif +/* +** Many system calls are accessed through pointer-to-functions so that +** they may be overridden at runtime to facilitate fault injection during +** testing and sandboxing. The following array holds the names and pointers +** to all overrideable system calls. +*/ +#if !SQLITE_OS_WINCE +# define SQLITE_WIN32_HAS_ANSI +#endif + +#if SQLITE_OS_WINCE || defined(_WIN32_WINNT) +# define SQLITE_WIN32_HAS_WIDE +#endif + +#ifndef SYSCALL +# define SYSCALL sqlite3_syscall_ptr +#endif + +#if SQLITE_OS_WINCE +/* +** These macros are necessary because Windows CE does not natively support the +** Win32 APIs LockFile, UnlockFile, and LockFileEx. + */ + +# define LockFile(a,b,c,d,e) winceLockFile(&a, b, c, d, e) +# define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e) +# define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f) + +/* +** These are the special syscall hacks for Windows CE. The locking related +** defines here refer to the macros defined just above. + */ + +# define osAreFileApisANSI() 1 +# define osLockFile LockFile +# define osUnlockFile UnlockFile +# define osLockFileEx LockFileEx +#endif + +static struct win_syscall { + const char *zName; /* Name of the sytem call */ + sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ + sqlite3_syscall_ptr pDefault; /* Default value */ +} aSyscall[] = { +#if !SQLITE_OS_WINCE + { "AreFileApisANSI", (SYSCALL)AreFileApisANSI, 0 }, + +#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent) +#else + { "AreFileApisANSI", (SYSCALL)0, 0 }, +#endif + +#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "CharLowerW", (SYSCALL)CharLowerW, 0 }, +#else + { "CharLowerW", (SYSCALL)0, 0 }, +#endif + +#define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent) + +#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "CharUpperW", (SYSCALL)CharUpperW, 0 }, +#else + { "CharUpperW", (SYSCALL)0, 0 }, +#endif + +#define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent) + + { "CloseHandle", (SYSCALL)CloseHandle, 0 }, + +#define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "CreateFileA", (SYSCALL)CreateFileA, 0 }, +#else + { "CreateFileA", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \ + LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "CreateFileW", (SYSCALL)CreateFileW, 0 }, +#else + { "CreateFileW", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ + LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) + + { "CreateFileMapping", (SYSCALL)CreateFileMapping, 0 }, + +#define osCreateFileMapping ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ + DWORD,DWORD,DWORD,LPCTSTR))aSyscall[6].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 }, +#else + { "CreateFileMappingW", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ + DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "CreateMutexW", (SYSCALL)CreateMutexW, 0 }, +#else + { "CreateMutexW", (SYSCALL)0, 0 }, +#endif + +#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \ + LPCWSTR))aSyscall[8].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "DeleteFileA", (SYSCALL)DeleteFileA, 0 }, +#else + { "DeleteFileA", (SYSCALL)0, 0 }, +#endif + +#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "DeleteFileW", (SYSCALL)DeleteFileW, 0 }, +#else + { "DeleteFileW", (SYSCALL)0, 0 }, +#endif + +#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent) + +#if SQLITE_OS_WINCE + { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 }, +#else + { "FileTimeToLocalFileTime", (SYSCALL)0, 0 }, +#endif + +#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \ + LPFILETIME))aSyscall[11].pCurrent) + +#if SQLITE_OS_WINCE + { "FileTimeToSystemTime", (SYSCALL)FileTimeToSystemTime, 0 }, +#else + { "FileTimeToSystemTime", (SYSCALL)0, 0 }, +#endif + +#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \ + LPSYSTEMTIME))aSyscall[12].pCurrent) + + { "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 }, + +#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "FormatMessageA", (SYSCALL)FormatMessageA, 0 }, +#else + { "FormatMessageA", (SYSCALL)0, 0 }, +#endif + +#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \ + DWORD,va_list*))aSyscall[14].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "FormatMessageW", (SYSCALL)FormatMessageW, 0 }, +#else + { "FormatMessageW", (SYSCALL)0, 0 }, +#endif + +#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \ + DWORD,va_list*))aSyscall[15].pCurrent) + + { "FreeLibrary", (SYSCALL)FreeLibrary, 0 }, + +#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent) + + { "GetCurrentProcessId", (SYSCALL)GetCurrentProcessId, 0 }, + +#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) + { "GetDiskFreeSpaceA", (SYSCALL)GetDiskFreeSpaceA, 0 }, +#else + { "GetDiskFreeSpaceA", (SYSCALL)0, 0 }, +#endif + +#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \ + LPDWORD))aSyscall[18].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "GetDiskFreeSpaceW", (SYSCALL)GetDiskFreeSpaceW, 0 }, +#else + { "GetDiskFreeSpaceW", (SYSCALL)0, 0 }, +#endif + +#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \ + LPDWORD))aSyscall[19].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "GetFileAttributesA", (SYSCALL)GetFileAttributesA, 0 }, +#else + { "GetFileAttributesA", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "GetFileAttributesW", (SYSCALL)GetFileAttributesW, 0 }, +#else + { "GetFileAttributesW", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "GetFileAttributesExW", (SYSCALL)GetFileAttributesExW, 0 }, +#else + { "GetFileAttributesExW", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \ + LPVOID))aSyscall[22].pCurrent) + + { "GetFileSize", (SYSCALL)GetFileSize, 0 }, + +#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) + { "GetFullPathNameA", (SYSCALL)GetFullPathNameA, 0 }, +#else + { "GetFullPathNameA", (SYSCALL)0, 0 }, +#endif + +#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \ + LPSTR*))aSyscall[24].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "GetFullPathNameW", (SYSCALL)GetFullPathNameW, 0 }, +#else + { "GetFullPathNameW", (SYSCALL)0, 0 }, +#endif + +#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \ + LPWSTR*))aSyscall[25].pCurrent) + + { "GetLastError", (SYSCALL)GetLastError, 0 }, + +#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent) + +#if SQLITE_OS_WINCE + /* The GetProcAddressA() routine is only available on Windows CE. */ + { "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 }, +#else + /* All other Windows platforms expect GetProcAddress() to take + ** an ANSI string regardless of the _UNICODE setting */ + { "GetProcAddressA", (SYSCALL)GetProcAddress, 0 }, +#endif + +#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \ + LPCSTR))aSyscall[27].pCurrent) + + { "GetSystemInfo", (SYSCALL)GetSystemInfo, 0 }, + +#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent) + + { "GetSystemTime", (SYSCALL)GetSystemTime, 0 }, + +#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent) + +#if !SQLITE_OS_WINCE + { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 }, +#else + { "GetSystemTimeAsFileTime", (SYSCALL)0, 0 }, +#endif + +#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \ + LPFILETIME))aSyscall[30].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "GetTempPathA", (SYSCALL)GetTempPathA, 0 }, +#else + { "GetTempPathA", (SYSCALL)0, 0 }, +#endif + +#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "GetTempPathW", (SYSCALL)GetTempPathW, 0 }, +#else + { "GetTempPathW", (SYSCALL)0, 0 }, +#endif + +#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent) + + { "GetTickCount", (SYSCALL)GetTickCount, 0 }, + +#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "GetVersionExA", (SYSCALL)GetVersionExA, 0 }, +#else + { "GetVersionExA", (SYSCALL)0, 0 }, +#endif + +#define osGetVersionExA ((BOOL(WINAPI*)( \ + LPOSVERSIONINFOA))aSyscall[34].pCurrent) + + { "HeapAlloc", (SYSCALL)HeapAlloc, 0 }, + +#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \ + SIZE_T))aSyscall[35].pCurrent) + + { "HeapCreate", (SYSCALL)HeapCreate, 0 }, + +#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \ + SIZE_T))aSyscall[36].pCurrent) + + { "HeapDestroy", (SYSCALL)HeapDestroy, 0 }, + +#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[37].pCurrent) + + { "HeapFree", (SYSCALL)HeapFree, 0 }, + +#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[38].pCurrent) + + { "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 }, + +#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \ + SIZE_T))aSyscall[39].pCurrent) + + { "HeapSize", (SYSCALL)HeapSize, 0 }, + +#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \ + LPCVOID))aSyscall[40].pCurrent) + + { "HeapValidate", (SYSCALL)HeapValidate, 0 }, + +#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \ + LPCVOID))aSyscall[41].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 }, +#else + { "LoadLibraryA", (SYSCALL)0, 0 }, +#endif + +#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 }, +#else + { "LoadLibraryW", (SYSCALL)0, 0 }, +#endif + +#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent) + + { "LocalFree", (SYSCALL)LocalFree, 0 }, + +#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[44].pCurrent) + +#if !SQLITE_OS_WINCE + { "LockFile", (SYSCALL)LockFile, 0 }, + +#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + DWORD))aSyscall[45].pCurrent) +#else + { "LockFile", (SYSCALL)0, 0 }, +#endif + +#if !SQLITE_OS_WINCE + { "LockFileEx", (SYSCALL)LockFileEx, 0 }, + +#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \ + LPOVERLAPPED))aSyscall[46].pCurrent) +#else + { "LockFileEx", (SYSCALL)0, 0 }, +#endif + + { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 }, + +#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + SIZE_T))aSyscall[47].pCurrent) + + { "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 }, + +#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \ + int))aSyscall[48].pCurrent) + + { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 }, + +#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \ + LARGE_INTEGER*))aSyscall[49].pCurrent) + + { "ReadFile", (SYSCALL)ReadFile, 0 }, + +#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \ + LPOVERLAPPED))aSyscall[50].pCurrent) + + { "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 }, + +#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent) + + { "SetFilePointer", (SYSCALL)SetFilePointer, 0 }, + +#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \ + DWORD))aSyscall[52].pCurrent) + + { "Sleep", (SYSCALL)Sleep, 0 }, + +#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[53].pCurrent) + + { "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 }, + +#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \ + LPFILETIME))aSyscall[54].pCurrent) + +#if !SQLITE_OS_WINCE + { "UnlockFile", (SYSCALL)UnlockFile, 0 }, + +#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + DWORD))aSyscall[55].pCurrent) +#else + { "UnlockFile", (SYSCALL)0, 0 }, +#endif + +#if !SQLITE_OS_WINCE + { "UnlockFileEx", (SYSCALL)UnlockFileEx, 0 }, + +#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + LPOVERLAPPED))aSyscall[56].pCurrent) +#else + { "UnlockFileEx", (SYSCALL)0, 0 }, +#endif + + { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 }, + +#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[57].pCurrent) + + { "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 }, + +#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \ + LPCSTR,LPBOOL))aSyscall[58].pCurrent) + + { "WriteFile", (SYSCALL)WriteFile, 0 }, + +#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \ + LPOVERLAPPED))aSyscall[59].pCurrent) + +}; /* End of the overrideable system calls */ + +/* +** This is the xSetSystemCall() method of sqlite3_vfs for all of the +** "win32" VFSes. Return SQLITE_OK opon successfully updating the +** system call pointer, or SQLITE_NOTFOUND if there is no configurable +** system call named zName. +*/ +static int winSetSystemCall( + sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ + const char *zName, /* Name of system call to override */ + sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ +){ + unsigned int i; + int rc = SQLITE_NOTFOUND; + + UNUSED_PARAMETER(pNotUsed); + if( zName==0 ){ + /* If no zName is given, restore all system calls to their default + ** settings and return NULL + */ + rc = SQLITE_OK; + for(i=0; i=0 ); - p = HeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); + p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); if( !p ){ sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%d), heap=%p", - nBytes, GetLastError(), (void*)hHeap); + nBytes, osGetLastError(), (void*)hHeap); } return p; } @@ -269,12 +788,12 @@ static void winMemFree(void *pPrior){ assert( hHeap!=0 ); assert( hHeap!=INVALID_HANDLE_VALUE ); #ifdef SQLITE_WIN32_MALLOC_VALIDATE - assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); + assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); #endif if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */ - if( !HeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){ + if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){ sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%d), heap=%p", - pPrior, GetLastError(), (void*)hHeap); + pPrior, osGetLastError(), (void*)hHeap); } } @@ -290,18 +809,18 @@ static void *winMemRealloc(void *pPrior, int nBytes){ assert( hHeap!=0 ); assert( hHeap!=INVALID_HANDLE_VALUE ); #ifdef SQLITE_WIN32_MALLOC_VALIDATE - assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); + assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); #endif assert( nBytes>=0 ); if( !pPrior ){ - p = HeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); + p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); }else{ - p = HeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes); + p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes); } if( !p ){ sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%d), heap=%p", - pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, GetLastError(), - (void*)hHeap); + pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(), + (void*)hHeap); } return p; } @@ -318,13 +837,13 @@ static int winMemSize(void *p){ assert( hHeap!=0 ); assert( hHeap!=INVALID_HANDLE_VALUE ); #ifdef SQLITE_WIN32_MALLOC_VALIDATE - assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); + assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); #endif if( !p ) return 0; - n = HeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p); + n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p); if( n==(SIZE_T)-1 ){ sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%d), heap=%p", - p, GetLastError(), (void*)hHeap); + p, osGetLastError(), (void*)hHeap); return 0; } return (int)n; @@ -346,14 +865,14 @@ static int winMemInit(void *pAppData){ if( !pWinMemData ) return SQLITE_ERROR; assert( pWinMemData->magic==WINMEM_MAGIC ); if( !pWinMemData->hHeap ){ - pWinMemData->hHeap = HeapCreate(SQLITE_WIN32_HEAP_FLAGS, - SQLITE_WIN32_HEAP_INIT_SIZE, - SQLITE_WIN32_HEAP_MAX_SIZE); + pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS, + SQLITE_WIN32_HEAP_INIT_SIZE, + SQLITE_WIN32_HEAP_MAX_SIZE); if( !pWinMemData->hHeap ){ sqlite3_log(SQLITE_NOMEM, "failed to HeapCreate (%d), flags=%u, initSize=%u, maxSize=%u", - GetLastError(), SQLITE_WIN32_HEAP_FLAGS, SQLITE_WIN32_HEAP_INIT_SIZE, - SQLITE_WIN32_HEAP_MAX_SIZE); + osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, + SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE); return SQLITE_NOMEM; } pWinMemData->bOwned = TRUE; @@ -361,7 +880,7 @@ static int winMemInit(void *pAppData){ assert( pWinMemData->hHeap!=0 ); assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); #ifdef SQLITE_WIN32_MALLOC_VALIDATE - assert( HeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); + assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); #endif return SQLITE_OK; } @@ -376,12 +895,12 @@ static void winMemShutdown(void *pAppData){ if( pWinMemData->hHeap ){ assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); #ifdef SQLITE_WIN32_MALLOC_VALIDATE - assert( HeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); + assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); #endif if( pWinMemData->bOwned ){ - if( !HeapDestroy(pWinMemData->hHeap) ){ + if( !osHeapDestroy(pWinMemData->hHeap) ){ sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), heap=%p", - GetLastError(), (void*)pWinMemData->hHeap); + osGetLastError(), (void*)pWinMemData->hHeap); } pWinMemData->bOwned = FALSE; } @@ -417,20 +936,21 @@ void sqlite3MemSetDefault(void){ #endif /* SQLITE_WIN32_MALLOC */ /* -** Convert a UTF-8 string to microsoft unicode (UTF-16?). +** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). ** ** Space to hold the returned string is obtained from malloc. */ -static WCHAR *utf8ToUnicode(const char *zFilename){ +static LPWSTR utf8ToUnicode(const char *zFilename){ int nChar; - WCHAR *zWideFilename; + LPWSTR zWideFilename; - nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); zWideFilename = malloc( nChar*sizeof(zWideFilename[0]) ); if( zWideFilename==0 ){ return 0; } - nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar); + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, + nChar); if( nChar==0 ){ free(zWideFilename); zWideFilename = 0; @@ -439,20 +959,20 @@ static WCHAR *utf8ToUnicode(const char *zFilename){ } /* -** Convert microsoft unicode to UTF-8. Space to hold the returned string is +** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is ** obtained from malloc(). */ -static char *unicodeToUtf8(const WCHAR *zWideFilename){ +static char *unicodeToUtf8(LPCWSTR zWideFilename){ int nByte; char *zFilename; - nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); + nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); zFilename = malloc( nByte ); if( zFilename==0 ){ return 0; } - nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte, - 0, 0); + nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte, + 0, 0); if( nByte == 0 ){ free(zFilename); zFilename = 0; @@ -461,23 +981,25 @@ static char *unicodeToUtf8(const WCHAR *zWideFilename){ } /* -** Convert an ansi string to microsoft unicode, based on the +** Convert an ansi string to Microsoft Unicode, based on the ** current codepage settings for file apis. ** ** Space to hold the returned string is obtained ** from malloc. */ -static WCHAR *mbcsToUnicode(const char *zFilename){ +static LPWSTR mbcsToUnicode(const char *zFilename){ int nByte; - WCHAR *zMbcsFilename; - int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; + LPWSTR zMbcsFilename; + int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; - nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR); + nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL, + 0)*sizeof(WCHAR); zMbcsFilename = malloc( nByte*sizeof(zMbcsFilename[0]) ); if( zMbcsFilename==0 ){ return 0; } - nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte); + nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, + nByte); if( nByte==0 ){ free(zMbcsFilename); zMbcsFilename = 0; @@ -486,24 +1008,24 @@ static WCHAR *mbcsToUnicode(const char *zFilename){ } /* -** Convert microsoft unicode to multibyte character string, based on the -** user's Ansi codepage. +** Convert Microsoft Unicode to multi-byte character string, based on the +** user's ANSI codepage. ** ** Space to hold the returned string is obtained from ** malloc(). */ -static char *unicodeToMbcs(const WCHAR *zWideFilename){ +static char *unicodeToMbcs(LPCWSTR zWideFilename){ int nByte; char *zFilename; - int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; + int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; - nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); + nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); zFilename = malloc( nByte ); if( zFilename==0 ){ return 0; } - nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte, - 0, 0); + nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, + nByte, 0, 0); if( nByte == 0 ){ free(zFilename); zFilename = 0; @@ -517,7 +1039,7 @@ static char *unicodeToMbcs(const WCHAR *zWideFilename){ */ char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){ char *zFilenameUtf8; - WCHAR *zTmpWide; + LPWSTR zTmpWide; zTmpWide = mbcsToUnicode(zFilename); if( zTmpWide==0 ){ @@ -534,7 +1056,7 @@ char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){ */ char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ char *zFilenameMbcs; - WCHAR *zTmpWide; + LPWSTR zTmpWide; zTmpWide = utf8ToUnicode(zFilename); if( zTmpWide==0 ){ @@ -560,21 +1082,21 @@ static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ char *zOut = 0; if( isNT() ){ - WCHAR *zTempWide = NULL; - dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - lastErrno, - 0, - (LPWSTR) &zTempWide, - 0, - 0); + LPWSTR zTempWide = NULL; + dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + lastErrno, + 0, + (LPWSTR) &zTempWide, + 0, + 0); if( dwLen > 0 ){ /* allocate a buffer and convert to UTF8 */ zOut = unicodeToUtf8(zTempWide); /* free the system buffer allocated by FormatMessage */ - LocalFree(zTempWide); + osLocalFree(zTempWide); } /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ASCII version of these Windows API do not exist for WINCE, @@ -583,20 +1105,20 @@ static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ #if SQLITE_OS_WINCE==0 }else{ char *zTemp = NULL; - dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - lastErrno, - 0, - (LPSTR) &zTemp, - 0, - 0); + dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + lastErrno, + 0, + (LPSTR) &zTemp, + 0, + 0); if( dwLen > 0 ){ /* allocate a buffer and convert to UTF8 */ zOut = sqlite3_win32_mbcs_to_utf8(zTemp); /* free the system buffer allocated by FormatMessage */ - LocalFree(zTemp); + osLocalFree(zTemp); } #endif } @@ -676,11 +1198,11 @@ static int retryIoerr(int *pnRetry){ if( *pnRetry>=win32IoerrRetry ){ return 0; } - e = GetLastError(); + e = osGetLastError(); if( e==ERROR_ACCESS_DENIED || e==ERROR_LOCK_VIOLATION || e==ERROR_SHARING_VIOLATION ){ - Sleep(win32IoerrRetryDelay*(1+*pnRetry)); + osSleep(win32IoerrRetryDelay*(1+*pnRetry)); ++*pnRetry; return 1; } @@ -704,7 +1226,7 @@ static void logIoerr(int nRetry){ ** This section contains code for WinCE only. */ /* -** WindowsCE does not have a localtime() function. So create a +** Windows CE does not have a localtime() function. So create a ** substitute. */ #include @@ -718,8 +1240,8 @@ struct tm *__cdecl localtime(const time_t *t) t64 = (t64 + 11644473600)*10000000; uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF); uTm.dwHighDateTime= (DWORD)(t64 >> 32); - FileTimeToLocalFileTime(&uTm,&lTm); - FileTimeToSystemTime(&lTm,&pTm); + osFileTimeToLocalFileTime(&uTm,&lTm); + osFileTimeToSystemTime(&lTm,&pTm); y.tm_year = pTm.wYear - 1900; y.tm_mon = pTm.wMonth - 1; y.tm_wday = pTm.wDayOfWeek; @@ -730,13 +1252,6 @@ struct tm *__cdecl localtime(const time_t *t) return &y; } -/* This will never be called, but defined to make the code compile */ -#define GetTempPathA(a,b) - -#define LockFile(a,b,c,d,e) winceLockFile(&a, b, c, d, e) -#define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e) -#define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f) - #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)] /* @@ -758,24 +1273,24 @@ static void winceMutexAcquire(HANDLE h){ ** descriptor pFile */ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ - WCHAR *zTok; - WCHAR *zName = utf8ToUnicode(zFilename); + LPWSTR zTok; + LPWSTR zName = utf8ToUnicode(zFilename); BOOL bInit = TRUE; /* Initialize the local lockdata */ - ZeroMemory(&pFile->local, sizeof(pFile->local)); + memset(&pFile->local, 0, sizeof(pFile->local)); /* Replace the backslashes from the filename and lowercase it ** to derive a mutex name. */ - zTok = CharLowerW(zName); + zTok = osCharLowerW(zName); for (;*zTok;zTok++){ if (*zTok == '\\') *zTok = '_'; } /* Create/open the named mutex */ - pFile->hMutex = CreateMutexW(NULL, FALSE, zName); + pFile->hMutex = osCreateMutexW(NULL, FALSE, zName); if (!pFile->hMutex){ - pFile->lastErrno = GetLastError(); + pFile->lastErrno = osGetLastError(); winLogError(SQLITE_ERROR, pFile->lastErrno, "winceCreateLock1", zFilename); free(zName); return FALSE; @@ -788,14 +1303,14 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ ** case-sensitive, take advantage of that by uppercasing the mutex name ** and using that as the shared filemapping name. */ - CharUpperW(zName); - pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, - PAGE_READWRITE, 0, sizeof(winceLock), - zName); + osCharUpperW(zName); + pFile->hShared = osCreateFileMappingW(INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE, 0, sizeof(winceLock), + zName); /* Set a flag that indicates we're the first to create the memory so it ** must be zero-initialized */ - if (GetLastError() == ERROR_ALREADY_EXISTS){ + if (osGetLastError() == ERROR_ALREADY_EXISTS){ bInit = FALSE; } @@ -803,14 +1318,14 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ /* If we succeeded in making the shared memory handle, map it. */ if (pFile->hShared){ - pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared, + pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock)); /* If mapping failed, close the shared memory handle and erase it */ if (!pFile->shared){ - pFile->lastErrno = GetLastError(); + pFile->lastErrno = osGetLastError(); winLogError(SQLITE_ERROR, pFile->lastErrno, "winceCreateLock2", zFilename); - CloseHandle(pFile->hShared); + osCloseHandle(pFile->hShared); pFile->hShared = NULL; } } @@ -818,14 +1333,14 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ /* If shared memory could not be created, then close the mutex and fail */ if (pFile->hShared == NULL){ winceMutexRelease(pFile->hMutex); - CloseHandle(pFile->hMutex); + osCloseHandle(pFile->hMutex); pFile->hMutex = NULL; return FALSE; } /* Initialize the shared memory if we're supposed to */ if (bInit) { - ZeroMemory(pFile->shared, sizeof(winceLock)); + memset(pFile->shared, 0, sizeof(winceLock)); } winceMutexRelease(pFile->hMutex); @@ -856,18 +1371,18 @@ static void winceDestroyLock(winFile *pFile){ } /* De-reference and close our copy of the shared memory handle */ - UnmapViewOfFile(pFile->shared); - CloseHandle(pFile->hShared); + osUnmapViewOfFile(pFile->shared); + osCloseHandle(pFile->hShared); /* Done with the mutex */ winceMutexRelease(pFile->hMutex); - CloseHandle(pFile->hMutex); + osCloseHandle(pFile->hMutex); pFile->hMutex = NULL; } } /* -** An implementation of the LockFile() API of windows for wince +** An implementation of the LockFile() API of Windows for CE */ static BOOL winceLockFile( HANDLE *phFile, @@ -931,7 +1446,7 @@ static BOOL winceLockFile( } /* -** An implementation of the UnlockFile API of windows for wince +** An implementation of the UnlockFile API of Windows for CE */ static BOOL winceUnlockFile( HANDLE *phFile, @@ -993,7 +1508,7 @@ static BOOL winceUnlockFile( } /* -** An implementation of the LockFileEx() API of windows for wince +** An implementation of the LockFileEx() API of Windows for CE */ static BOOL winceLockFileEx( HANDLE *phFile, @@ -1026,7 +1541,7 @@ static BOOL winceLockFileEx( ******************************************************************************/ /* -** Some microsoft compilers lack this definition. +** Some Microsoft compilers lack this definition. */ #ifndef INVALID_SET_FILE_POINTER # define INVALID_SET_FILE_POINTER ((DWORD)-1) @@ -1052,9 +1567,9 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){ ** whether an error has actually occured, it is also necessary to call ** GetLastError(). */ - dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); - if( (dwRet==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR) ){ - pFile->lastErrno = GetLastError(); + dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); + if( (dwRet==INVALID_SET_FILE_POINTER && osGetLastError()!=NO_ERROR) ){ + pFile->lastErrno = osGetLastError(); winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, "seekWinFile", pFile->zPath); return 1; @@ -1067,7 +1582,7 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){ ** Close a file. ** ** It is reported that an attempt to close a handle might sometimes -** fail. This is a very unreasonable result, but windows is notorious +** fail. This is a very unreasonable result, but Windows is notorious ** for being unreasonable so I do not doubt that it might happen. If ** the close fails, we pause for 100 milliseconds and try again. As ** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before @@ -1082,20 +1597,20 @@ static int winClose(sqlite3_file *id){ assert( pFile->pShm==0 ); OSTRACE(("CLOSE %d\n", pFile->h)); do{ - rc = CloseHandle(pFile->h); + rc = osCloseHandle(pFile->h); /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */ - }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (Sleep(100), 1) ); + }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (osSleep(100), 1) ); #if SQLITE_OS_WINCE #define WINCE_DELETION_ATTEMPTS 3 winceDestroyLock(pFile); if( pFile->zDeleteOnClose ){ int cnt = 0; while( - DeleteFileW(pFile->zDeleteOnClose)==0 - && GetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff + osDeleteFileW(pFile->zDeleteOnClose)==0 + && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff && cnt++ < WINCE_DELETION_ATTEMPTS ){ - Sleep(100); /* Wait a little before trying again */ + osSleep(100); /* Wait a little before trying again */ } free(pFile->zDeleteOnClose); } @@ -1103,7 +1618,7 @@ static int winClose(sqlite3_file *id){ OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed")); OpenCounter(-1); return rc ? SQLITE_OK - : winLogError(SQLITE_IOERR_CLOSE, GetLastError(), + : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(), "winClose", pFile->zPath); } @@ -1129,9 +1644,9 @@ static int winRead( if( seekWinFile(pFile, offset) ){ return SQLITE_FULL; } - while( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ + while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ if( retryIoerr(&nRetry) ) continue; - pFile->lastErrno = GetLastError(); + pFile->lastErrno = osGetLastError(); return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, "winRead", pFile->zPath); } @@ -1173,7 +1688,7 @@ static int winWrite( DWORD nWrite; /* Bytes written by each WriteFile() call */ while( nRem>0 ){ - if( !WriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ + if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ if( retryIoerr(&nRetry) ) continue; break; } @@ -1182,7 +1697,7 @@ static int winWrite( nRem -= nWrite; } if( nRem>0 ){ - pFile->lastErrno = GetLastError(); + pFile->lastErrno = osGetLastError(); rc = 1; } } @@ -1225,8 +1740,8 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ if( seekWinFile(pFile, nByte) ){ rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, "winTruncate1", pFile->zPath); - }else if( 0==SetEndOfFile(pFile->h) ){ - pFile->lastErrno = GetLastError(); + }else if( 0==osSetEndOfFile(pFile->h) ){ + pFile->lastErrno = osGetLastError(); rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, "winTruncate2", pFile->zPath); } @@ -1293,12 +1808,12 @@ static int winSync(sqlite3_file *id, int flags){ #ifdef SQLITE_NO_SYNC return SQLITE_OK; #else - rc = FlushFileBuffers(pFile->h); + rc = osFlushFileBuffers(pFile->h); SimulateIOError( rc=FALSE ); if( rc ){ return SQLITE_OK; }else{ - pFile->lastErrno = GetLastError(); + pFile->lastErrno = osGetLastError(); return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, "winSync", pFile->zPath); } @@ -1316,9 +1831,9 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ assert( id!=0 ); SimulateIOError(return SQLITE_IOERR_FSTAT); - lowerBits = GetFileSize(pFile->h, &upperBits); + lowerBits = osGetFileSize(pFile->h, &upperBits); if( (lowerBits == INVALID_FILE_SIZE) - && ((error = GetLastError()) != NO_ERROR) ) + && ((error = osGetLastError()) != NO_ERROR) ) { pFile->lastErrno = error; return winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, @@ -1347,8 +1862,8 @@ static int getReadLock(winFile *pFile){ ovlp.Offset = SHARED_FIRST; ovlp.OffsetHigh = 0; ovlp.hEvent = 0; - res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY, - 0, SHARED_SIZE, 0, &ovlp); + res = osLockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY, + 0, SHARED_SIZE, 0, &ovlp); /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. */ #if SQLITE_OS_WINCE==0 @@ -1356,11 +1871,11 @@ static int getReadLock(winFile *pFile){ int lk; sqlite3_randomness(sizeof(lk), &lk); pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1)); - res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); + res = osLockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); #endif } if( res == 0 ){ - pFile->lastErrno = GetLastError(); + pFile->lastErrno = osGetLastError(); /* No need to log a failure to lock */ } return res; @@ -1372,16 +1887,16 @@ static int getReadLock(winFile *pFile){ static int unlockReadLock(winFile *pFile){ int res; if( isNT() ){ - res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); + res = osUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. */ #if SQLITE_OS_WINCE==0 }else{ - res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0); + res = osUnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0); #endif } - if( res==0 && GetLastError()!=ERROR_NOT_LOCKED ){ - pFile->lastErrno = GetLastError(); + if( res==0 && osGetLastError()!=ERROR_NOT_LOCKED ){ + pFile->lastErrno = osGetLastError(); winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, "unlockReadLock", pFile->zPath); } @@ -1416,7 +1931,7 @@ static int unlockReadLock(winFile *pFile){ */ static int winLock(sqlite3_file *id, int locktype){ int rc = SQLITE_OK; /* Return code from subroutines */ - int res = 1; /* Result of a windows lock call */ + int res = 1; /* Result of a Windows lock call */ int newLocktype; /* Set pFile->locktype to this value before exiting */ int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ winFile *pFile = (winFile*)id; @@ -1450,18 +1965,19 @@ static int winLock(sqlite3_file *id, int locktype){ && (pFile->locktype==RESERVED_LOCK)) ){ int cnt = 3; - while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){ + while( cnt-->0 && (res = osLockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){ /* Try 3 times to get the pending lock. This is needed to work - ** around problems caused by anti-virus software on windows system. + ** around problems caused by indexing and/or anti-virus software on + ** Windows systems. ** If you are using this code as a model for alternative VFSes, do not - ** copy this retry logic. It is a hack intended for windows only. + ** copy this retry logic. It is a hack intended for Windows only. */ OSTRACE(("could not get a PENDING lock. cnt=%d\n", cnt)); - if( cnt ) Sleep(1); + if( cnt ) osSleep(1); } gotPendingLock = res; if( !res ){ - error = GetLastError(); + error = osGetLastError(); } } @@ -1473,7 +1989,7 @@ static int winLock(sqlite3_file *id, int locktype){ if( res ){ newLocktype = SHARED_LOCK; }else{ - error = GetLastError(); + error = osGetLastError(); } } @@ -1481,11 +1997,11 @@ static int winLock(sqlite3_file *id, int locktype){ */ if( locktype==RESERVED_LOCK && res ){ assert( pFile->locktype==SHARED_LOCK ); - res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); + res = osLockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); if( res ){ newLocktype = RESERVED_LOCK; }else{ - error = GetLastError(); + error = osGetLastError(); } } @@ -1502,11 +2018,11 @@ static int winLock(sqlite3_file *id, int locktype){ assert( pFile->locktype>=SHARED_LOCK ); res = unlockReadLock(pFile); OSTRACE(("unreadlock = %d\n", res)); - res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); + res = osLockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); if( res ){ newLocktype = EXCLUSIVE_LOCK; }else{ - error = GetLastError(); + error = osGetLastError(); OSTRACE(("error-code = %d\n", error)); getReadLock(pFile); } @@ -1516,7 +2032,7 @@ static int winLock(sqlite3_file *id, int locktype){ ** release it now. */ if( gotPendingLock && locktype==SHARED_LOCK ){ - UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); + osUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); } /* Update the state of the lock has held in the file descriptor then @@ -1550,9 +2066,9 @@ static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ rc = 1; OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc)); }else{ - rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); + rc = osLockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); if( rc ){ - UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); + osUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); } rc = !rc; OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc)); @@ -1582,22 +2098,22 @@ static int winUnlock(sqlite3_file *id, int locktype){ pFile->locktype, pFile->sharedLockByte)); type = pFile->locktype; if( type>=EXCLUSIVE_LOCK ){ - UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); + osUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ /* This should never happen. We should always be able to ** reacquire the read lock */ - rc = winLogError(SQLITE_IOERR_UNLOCK, GetLastError(), + rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), "winUnlock", pFile->zPath); } } if( type>=RESERVED_LOCK ){ - UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); + osUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); } if( locktype==NO_LOCK && type>=SHARED_LOCK ){ unlockReadLock(pFile); } if( type>=PENDING_LOCK ){ - UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); + osUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); } pFile->locktype = (u8)locktype; return rc; @@ -1834,15 +2350,15 @@ static int winShmSystemLock( /* Release/Acquire the system-level lock */ if( lockType==_SHM_UNLCK ){ - rc = UnlockFileEx(pFile->hFile.h, 0, nByte, 0, &ovlp); + rc = osUnlockFileEx(pFile->hFile.h, 0, nByte, 0, &ovlp); }else{ - rc = LockFileEx(pFile->hFile.h, dwFlags, 0, nByte, 0, &ovlp); + rc = osLockFileEx(pFile->hFile.h, dwFlags, 0, nByte, 0, &ovlp); } if( rc!= 0 ){ rc = SQLITE_OK; }else{ - pFile->lastErrno = GetLastError(); + pFile->lastErrno = osGetLastError(); rc = SQLITE_BUSY; } @@ -1876,13 +2392,13 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ int i; if( p->mutex ) sqlite3_mutex_free(p->mutex); for(i=0; inRegion; i++){ - bRc = UnmapViewOfFile(p->aRegion[i].pMap); + bRc = osUnmapViewOfFile(p->aRegion[i].pMap); OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n", - (int)GetCurrentProcessId(), i, + (int)osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); - bRc = CloseHandle(p->aRegion[i].hMap); + bRc = osCloseHandle(p->aRegion[i].hMap); OSTRACE(("SHM-PURGE pid-%d close region=%d %s\n", - (int)GetCurrentProcessId(), i, + (int)osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); } if( p->hFile.h != INVALID_HANDLE_VALUE ){ @@ -1978,7 +2494,7 @@ static int winOpenSharedMemory(winFile *pDbFd){ if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); if( rc!=SQLITE_OK ){ - rc = winLogError(SQLITE_IOERR_SHMOPEN, GetLastError(), + rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), "winOpenShm", pDbFd->zPath); } } @@ -2164,7 +2680,7 @@ static int winShmLock( } sqlite3_mutex_leave(pShmNode->mutex); OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n", - p->id, (int)GetCurrentProcessId(), p->sharedMask, p->exclMask, + p->id, (int)osGetCurrentProcessId(), p->sharedMask, p->exclMask, rc ? "failed" : "ok")); return rc; } @@ -2238,7 +2754,7 @@ static int winShmMap( */ rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); if( rc!=SQLITE_OK ){ - rc = winLogError(SQLITE_IOERR_SHMSIZE, GetLastError(), + rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), "winShmMap1", pDbFd->zPath); goto shmpage_out; } @@ -2253,7 +2769,7 @@ static int winShmMap( if( !isWrite ) goto shmpage_out; rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte); if( rc!=SQLITE_OK ){ - rc = winLogError(SQLITE_IOERR_SHMSIZE, GetLastError(), + rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), "winShmMap2", pDbFd->zPath); goto shmpage_out; } @@ -2273,27 +2789,27 @@ static int winShmMap( HANDLE hMap; /* file-mapping handle */ void *pMap = 0; /* Mapped memory region */ - hMap = CreateFileMapping(pShmNode->hFile.h, + hMap = osCreateFileMapping(pShmNode->hFile.h, NULL, PAGE_READWRITE, 0, nByte, NULL ); OSTRACE(("SHM-MAP pid-%d create region=%d nbyte=%d %s\n", - (int)GetCurrentProcessId(), pShmNode->nRegion, nByte, + (int)osGetCurrentProcessId(), pShmNode->nRegion, nByte, hMap ? "ok" : "failed")); if( hMap ){ int iOffset = pShmNode->nRegion*szRegion; int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; - pMap = MapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, + pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, 0, iOffset - iOffsetShift, szRegion + iOffsetShift ); OSTRACE(("SHM-MAP pid-%d map region=%d offset=%d size=%d %s\n", - (int)GetCurrentProcessId(), pShmNode->nRegion, iOffset, szRegion, - pMap ? "ok" : "failed")); + (int)osGetCurrentProcessId(), pShmNode->nRegion, iOffset, + szRegion, pMap ? "ok" : "failed")); } if( !pMap ){ - pShmNode->lastErrno = GetLastError(); + pShmNode->lastErrno = osGetLastError(); rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, "winShmMap3", pDbFd->zPath); - if( hMap ) CloseHandle(hMap); + if( hMap ) osCloseHandle(hMap); goto shmpage_out; } @@ -2404,7 +2920,7 @@ static int getTempname(int nBuf, char *zBuf){ }else if( isNT() ){ char *zMulti; WCHAR zWidePath[MAX_PATH]; - GetTempPathW(MAX_PATH-30, zWidePath); + osGetTempPathW(MAX_PATH-30, zWidePath); zMulti = unicodeToUtf8(zWidePath); if( zMulti ){ sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti); @@ -2420,7 +2936,7 @@ static int getTempname(int nBuf, char *zBuf){ }else{ char *zUtf8; char zMbcsPath[MAX_PATH]; - GetTempPathA(MAX_PATH-30, zMbcsPath); + osGetTempPathA(MAX_PATH-30, zMbcsPath); zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); if( zUtf8 ){ sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8); @@ -2595,26 +3111,26 @@ static int winOpen( #endif if( isNT() ){ - while( (h = CreateFileW((WCHAR*)zConverted, - dwDesiredAccess, - dwShareMode, NULL, - dwCreationDisposition, - dwFlagsAndAttributes, - NULL))==INVALID_HANDLE_VALUE && - retryIoerr(&cnt) ){} + while( (h = osCreateFileW((LPCWSTR)zConverted, + dwDesiredAccess, + dwShareMode, NULL, + dwCreationDisposition, + dwFlagsAndAttributes, + NULL))==INVALID_HANDLE_VALUE && + retryIoerr(&cnt) ){} /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ASCII version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 }else{ - while( (h = CreateFileA((char*)zConverted, - dwDesiredAccess, - dwShareMode, NULL, - dwCreationDisposition, - dwFlagsAndAttributes, - NULL))==INVALID_HANDLE_VALUE && - retryIoerr(&cnt) ){} + while( (h = osCreateFileA((LPCSTR)zConverted, + dwDesiredAccess, + dwShareMode, NULL, + dwCreationDisposition, + dwFlagsAndAttributes, + NULL))==INVALID_HANDLE_VALUE && + retryIoerr(&cnt) ){} #endif } @@ -2625,7 +3141,7 @@ static int winOpen( h==INVALID_HANDLE_VALUE ? "failed" : "ok")); if( h==INVALID_HANDLE_VALUE ){ - pFile->lastErrno = GetLastError(); + pFile->lastErrno = osGetLastError(); winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); free(zConverted); if( isReadWrite && !isExclusive ){ @@ -2657,7 +3173,7 @@ static int winOpen( if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB && !winceCreateLock(zName, pFile) ){ - CloseHandle(h); + osCloseHandle(h); free(zConverted); return SQLITE_CANTOPEN_BKPT; } @@ -2676,7 +3192,7 @@ static int winOpen( /* ** Delete the named file. ** -** Note that windows does not allow a file to be deleted if some other +** Note that Windows does not allow a file to be deleted if some other ** process has it open. Sometimes a virus scanner or indexing program ** will open a journal file shortly after it is created in order to do ** whatever it does. While this other process is holding the @@ -2703,8 +3219,8 @@ static int winDelete( } if( isNT() ){ rc = 1; - while( GetFileAttributesW(zConverted)!=INVALID_FILE_ATTRIBUTES && - (rc = DeleteFileW(zConverted))==0 && retryIoerr(&cnt) ){} + while( osGetFileAttributesW(zConverted)!=INVALID_FILE_ATTRIBUTES && + (rc = osDeleteFileW(zConverted))==0 && retryIoerr(&cnt) ){} rc = rc ? SQLITE_OK : SQLITE_ERROR; /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ASCII version of these Windows API do not exist for WINCE, @@ -2713,13 +3229,13 @@ static int winDelete( #if SQLITE_OS_WINCE==0 }else{ rc = 1; - while( GetFileAttributesA(zConverted)!=INVALID_FILE_ATTRIBUTES && - (rc = DeleteFileA(zConverted))==0 && retryIoerr(&cnt) ){} + while( osGetFileAttributesA(zConverted)!=INVALID_FILE_ATTRIBUTES && + (rc = osDeleteFileA(zConverted))==0 && retryIoerr(&cnt) ){} rc = rc ? SQLITE_OK : SQLITE_ERROR; #endif } if( rc ){ - rc = winLogError(SQLITE_IOERR_DELETE, GetLastError(), + rc = winLogError(SQLITE_IOERR_DELETE, osGetLastError(), "winDelete", zFilename); }else{ logIoerr(cnt); @@ -2752,7 +3268,7 @@ static int winAccess( int cnt = 0; WIN32_FILE_ATTRIBUTE_DATA sAttrData; memset(&sAttrData, 0, sizeof(sAttrData)); - while( !(rc = GetFileAttributesExW((WCHAR*)zConverted, + while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, GetFileExInfoStandard, &sAttrData)) && retryIoerr(&cnt) ){} if( rc ){ @@ -2767,7 +3283,7 @@ static int winAccess( attr = sAttrData.dwFileAttributes; } }else{ - DWORD lastErrno = GetLastError(); + DWORD lastErrno = osGetLastError(); logIoerr(cnt); if( lastErrno!=ERROR_FILE_NOT_FOUND ){ winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename); @@ -2783,7 +3299,7 @@ static int winAccess( */ #if SQLITE_OS_WINCE==0 }else{ - attr = GetFileAttributesA((char*)zConverted); + attr = osGetFileAttributesA((char*)zConverted); #endif } free(zConverted); @@ -2852,14 +3368,14 @@ static int winFullPathname( UNUSED_PARAMETER(nFull); zConverted = convertUtf8Filename(zRelative); if( isNT() ){ - WCHAR *zTemp; - nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3; + LPWSTR zTemp; + nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0) + 3; zTemp = malloc( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ free(zConverted); return SQLITE_NOMEM; } - GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0); + osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); free(zConverted); zOut = unicodeToUtf8(zTemp); free(zTemp); @@ -2870,13 +3386,13 @@ static int winFullPathname( #if SQLITE_OS_WINCE==0 }else{ char *zTemp; - nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3; + nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0) + 3; zTemp = malloc( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ free(zConverted); return SQLITE_NOMEM; } - GetFullPathNameA((char*)zConverted, nByte, zTemp, 0); + osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); free(zConverted); zOut = sqlite3_win32_mbcs_to_utf8(zTemp); free(zTemp); @@ -2925,18 +3441,18 @@ static int getSectorSize( if( zConverted ){ if( isNT() ){ /* trim path to just drive reference */ - WCHAR *p = zConverted; + LPWSTR p = zConverted; for(;*p;p++){ if( *p == '\\' ){ *p = '\0'; break; } } - dwRet = GetDiskFreeSpaceW((WCHAR*)zConverted, - &dwDummy, - &bytesPerSector, - &dwDummy, - &dwDummy); + dwRet = osGetDiskFreeSpaceW((LPCWSTR)zConverted, + &dwDummy, + &bytesPerSector, + &dwDummy, + &dwDummy); }else{ /* trim path to just drive reference */ char *p = (char *)zConverted; @@ -2946,11 +3462,11 @@ static int getSectorSize( break; } } - dwRet = GetDiskFreeSpaceA((char*)zConverted, - &dwDummy, - &bytesPerSector, - &dwDummy, - &dwDummy); + dwRet = osGetDiskFreeSpaceA((char*)zConverted, + &dwDummy, + &bytesPerSector, + &dwDummy, + &dwDummy); } free(zConverted); } @@ -2979,14 +3495,14 @@ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ return 0; } if( isNT() ){ - h = LoadLibraryW((WCHAR*)zConverted); + h = osLoadLibraryW((LPCWSTR)zConverted); /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ASCII version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 }else{ - h = LoadLibraryA((char*)zConverted); + h = osLoadLibraryA((char*)zConverted); #endif } free(zConverted); @@ -2994,22 +3510,15 @@ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ } static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ UNUSED_PARAMETER(pVfs); - getLastErrorMsg(GetLastError(), nBuf, zBufOut); + getLastErrorMsg(osGetLastError(), nBuf, zBufOut); } static void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){ UNUSED_PARAMETER(pVfs); -#if SQLITE_OS_WINCE - /* The GetProcAddressA() routine is only available on wince. */ - return (void(*)(void))GetProcAddressA((HANDLE)pHandle, zSymbol); -#else - /* All other windows platforms expect GetProcAddress() to take - ** an Ansi string regardless of the _UNICODE setting */ - return (void(*)(void))GetProcAddress((HANDLE)pHandle, zSymbol); -#endif + return (void(*)(void))osGetProcAddressA((HANDLE)pHandle, zSymbol); } static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ UNUSED_PARAMETER(pVfs); - FreeLibrary((HANDLE)pHandle); + osFreeLibrary((HANDLE)pHandle); } #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ #define winDlOpen 0 @@ -3031,23 +3540,23 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ #else if( sizeof(SYSTEMTIME)<=nBuf-n ){ SYSTEMTIME x; - GetSystemTime(&x); + osGetSystemTime(&x); memcpy(&zBuf[n], &x, sizeof(x)); n += sizeof(x); } if( sizeof(DWORD)<=nBuf-n ){ - DWORD pid = GetCurrentProcessId(); + DWORD pid = osGetCurrentProcessId(); memcpy(&zBuf[n], &pid, sizeof(pid)); n += sizeof(pid); } if( sizeof(DWORD)<=nBuf-n ){ - DWORD cnt = GetTickCount(); + DWORD cnt = osGetTickCount(); memcpy(&zBuf[n], &cnt, sizeof(cnt)); n += sizeof(cnt); } if( sizeof(LARGE_INTEGER)<=nBuf-n ){ LARGE_INTEGER i; - QueryPerformanceCounter(&i); + osQueryPerformanceCounter(&i); memcpy(&zBuf[n], &i, sizeof(i)); n += sizeof(i); } @@ -3060,7 +3569,7 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ ** Sleep for a little while. Return the amount of time slept. */ static int winSleep(sqlite3_vfs *pVfs, int microsec){ - Sleep((microsec+999)/1000); + osSleep((microsec+999)/1000); UNUSED_PARAMETER(pVfs); return ((microsec+999)/1000)*1000; } @@ -3099,13 +3608,13 @@ static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ #if SQLITE_OS_WINCE SYSTEMTIME time; - GetSystemTime(&time); + osGetSystemTime(&time); /* if SystemTimeToFileTime() fails, it returns zero. */ - if (!SystemTimeToFileTime(&time,&ft)){ + if (!osSystemTimeToFileTime(&time,&ft)){ return SQLITE_ERROR; } #else - GetSystemTimeAsFileTime( &ft ); + osGetSystemTimeAsFileTime( &ft ); #endif *piNow = winFiletimeEpoch + @@ -3138,8 +3647,8 @@ static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ /* ** The idea is that this function works like a combination of -** GetLastError() and FormatMessage() on windows (or errno and -** strerror_r() on unix). After an error is returned by an OS +** GetLastError() and FormatMessage() on Windows (or errno and +** strerror_r() on Unix). After an error is returned by an OS ** function, SQLite calls this function with zBuf pointing to ** a buffer of nBuf bytes. The OS layer should populate the ** buffer with a nul-terminated UTF-8 encoded error message @@ -3168,7 +3677,7 @@ static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ */ static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ UNUSED_PARAMETER(pVfs); - return getLastErrorMsg(GetLastError(), nBuf, zBuf); + return getLastErrorMsg(osGetLastError(), nBuf, zBuf); } @@ -3197,15 +3706,19 @@ int sqlite3_os_init(void){ winCurrentTime, /* xCurrentTime */ winGetLastError, /* xGetLastError */ winCurrentTimeInt64, /* xCurrentTimeInt64 */ - 0, /* xSetSystemCall */ - 0, /* xGetSystemCall */ - 0, /* xNextSystemCall */ + winSetSystemCall, /* xSetSystemCall */ + winGetSystemCall, /* xGetSystemCall */ + winNextSystemCall, /* xNextSystemCall */ }; + /* Double-check that the aSyscall[] array has been constructed + ** correctly. See ticket [bb3a86e890c8e96ab] */ + assert( ArraySize(aSyscall)==60 ); + #ifndef SQLITE_OMIT_WAL /* get memory map allocation granularity */ memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); - GetSystemInfo(&winSysInfo); + osGetSystemInfo(&winSysInfo); assert(winSysInfo.dwAllocationGranularity > 0); #endif From 5f075388deea7375909c73621bcfeef75ded9be5 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 11 Nov 2011 23:31:04 +0000 Subject: [PATCH 026/161] Remove use of malloc and free from the Windows VFS. Also, prevent sqlite3BtreeOpen from assuming that sqlite3OsFullPathname cannot fail. FossilOrigin-Name: 8966ec1797be63d1305628d459bdad5be08cf3ca --- manifest | 17 +++---- manifest.uuid | 2 +- src/btree.c | 7 ++- src/os_win.c | 136 ++++++++++++++++++++++---------------------------- 4 files changed, 73 insertions(+), 89 deletions(-) diff --git a/manifest b/manifest index 455829f1fb..0c8720d589 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Work\sin\sprogress\sto\simplement\sthe\s'syscall'\sfunctionality\sfor\sWindows. -D 2011-11-11T22:08:54.567 +C Remove\suse\sof\smalloc\sand\sfree\sfrom\sthe\sWindows\sVFS.\s\sAlso,\sprevent\ssqlite3BtreeOpen\sfrom\sassuming\sthat\ssqlite3OsFullPathname\scannot\sfail. +D 2011-11-11T23:31:04.676 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -125,7 +125,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 4368158da74d4711888e03264105c5c527d76caf F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 32199e2d939233ade25340eaba450f818b37c079 +F src/btree.c 60e0151ccc9d1d09a3fd2d0e609689ab8544e93f F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 F src/build.c 8af67a08a852ff4c63701963cb1ab7166f577814 @@ -167,7 +167,7 @@ F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 4fbb91726165e105c1679a2660f49a3f4c376e4f -F src/os_win.c 1d8fe13d456ef2df6576af55a8b15937244e1e26 +F src/os_win.c ee8ba0846294f154e0822095512a665cdb197c8a F src/pager.c db33d4bf1e3e019c34c220971cc6c3aa07c30f54 F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 @@ -974,10 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 8f28797984c1d4700357a75815ca4b324c3ebf5c -R 0ef79000409253332bbd2b77a41d7f05 -T *branch * winSyscall -T *sym-winSyscall * -T -sym-trunk * +P ed88fb00240de75457c0da19e87c12082622ca17 +R a35825c17aca6258f92039304b464c67 U mistachkin -Z 57ebd7677acce4cb8f4dee76b646710f +Z 93813e17596e2d1608777ccc9fc54b6a diff --git a/manifest.uuid b/manifest.uuid index 3546fa2265..68895f5c98 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ed88fb00240de75457c0da19e87c12082622ca17 \ No newline at end of file +8966ec1797be63d1305628d459bdad5be08cf3ca \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index d64e172f74..e28ad0f7fa 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1772,7 +1772,12 @@ int sqlite3BtreeOpen( sqlite3_free(p); return SQLITE_NOMEM; } - sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); + rc = sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); + if( rc!=SQLITE_OK ){ + sqlite3_free(zFullPathname); + sqlite3_free(p); + return rc; + } #if SQLITE_THREADSAFE mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN); sqlite3_mutex_enter(mutexOpen); diff --git a/src/os_win.c b/src/os_win.c index bc86e98588..8550c628f6 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -15,33 +15,6 @@ #include "sqliteInt.h" #if SQLITE_OS_WIN /* This file is used for Windows only */ - -/* -** A Note About Memory Allocation: -** -** This driver uses malloc()/free() directly rather than going through -** the SQLite-wrappers sqlite3_malloc()/sqlite3_free(). Those wrappers -** are designed for use on embedded systems where memory is scarce and -** malloc failures happen frequently. Win32 does not typically run on -** embedded systems, and when it does the developers normally have bigger -** problems to worry about than running out of memory. So there is not -** a compelling need to use the wrappers. -** -** But there is a good reason to not use the wrappers. If we use the -** wrappers then we will get simulated malloc() failures within this -** driver. And that causes all kinds of problems for our tests. We -** could enhance SQLite to deal with simulated malloc failures within -** the OS driver, but the code to deal with those failure would not -** be exercised on Linux (which does not need to malloc() in the driver) -** and so we would have difficulty writing coverage tests for that -** code. Better to leave the code out, we think. -** -** The point of this discussion is as follows: When creating a new -** OS layer for an embedded system, if you use this file as an example, -** avoid the use of malloc()/free(). Those routines work ok on Windows -** desktops but not so well in embedded systems. -*/ - #ifdef __CYGWIN__ # include #endif @@ -945,14 +918,14 @@ static LPWSTR utf8ToUnicode(const char *zFilename){ LPWSTR zWideFilename; nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); - zWideFilename = malloc( nChar*sizeof(zWideFilename[0]) ); + zWideFilename = sqlite3_malloc( nChar*sizeof(zWideFilename[0]) ); if( zWideFilename==0 ){ return 0; } nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar); if( nChar==0 ){ - free(zWideFilename); + sqlite3_free(zWideFilename); zWideFilename = 0; } return zWideFilename; @@ -960,21 +933,21 @@ static LPWSTR utf8ToUnicode(const char *zFilename){ /* ** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is -** obtained from malloc(). +** obtained from sqlite3_malloc(). */ static char *unicodeToUtf8(LPCWSTR zWideFilename){ int nByte; char *zFilename; nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); - zFilename = malloc( nByte ); + zFilename = sqlite3_malloc( nByte ); if( zFilename==0 ){ return 0; } nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte, 0, 0); if( nByte == 0 ){ - free(zFilename); + sqlite3_free(zFilename); zFilename = 0; } return zFilename; @@ -985,7 +958,7 @@ static char *unicodeToUtf8(LPCWSTR zWideFilename){ ** current codepage settings for file apis. ** ** Space to hold the returned string is obtained -** from malloc. +** from sqlite3_malloc. */ static LPWSTR mbcsToUnicode(const char *zFilename){ int nByte; @@ -994,14 +967,14 @@ static LPWSTR mbcsToUnicode(const char *zFilename){ nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL, 0)*sizeof(WCHAR); - zMbcsFilename = malloc( nByte*sizeof(zMbcsFilename[0]) ); + zMbcsFilename = sqlite3_malloc( nByte*sizeof(zMbcsFilename[0]) ); if( zMbcsFilename==0 ){ return 0; } nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte); if( nByte==0 ){ - free(zMbcsFilename); + sqlite3_free(zMbcsFilename); zMbcsFilename = 0; } return zMbcsFilename; @@ -1012,7 +985,7 @@ static LPWSTR mbcsToUnicode(const char *zFilename){ ** user's ANSI codepage. ** ** Space to hold the returned string is obtained from -** malloc(). +** sqlite3_malloc(). */ static char *unicodeToMbcs(LPCWSTR zWideFilename){ int nByte; @@ -1020,14 +993,14 @@ static char *unicodeToMbcs(LPCWSTR zWideFilename){ int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); - zFilename = malloc( nByte ); + zFilename = sqlite3_malloc( nByte ); if( zFilename==0 ){ return 0; } nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte, 0, 0); if( nByte == 0 ){ - free(zFilename); + sqlite3_free(zFilename); zFilename = 0; } return zFilename; @@ -1035,7 +1008,7 @@ static char *unicodeToMbcs(LPCWSTR zWideFilename){ /* ** Convert multibyte character string to UTF-8. Space to hold the -** returned string is obtained from malloc(). +** returned string is obtained from sqlite3_malloc(). */ char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){ char *zFilenameUtf8; @@ -1046,13 +1019,13 @@ char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){ return 0; } zFilenameUtf8 = unicodeToUtf8(zTmpWide); - free(zTmpWide); + sqlite3_free(zTmpWide); return zFilenameUtf8; } /* ** Convert UTF-8 to multibyte character string. Space to hold the -** returned string is obtained from malloc(). +** returned string is obtained from sqlite3_malloc(). */ char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ char *zFilenameMbcs; @@ -1063,7 +1036,7 @@ char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ return 0; } zFilenameMbcs = unicodeToMbcs(zTmpWide); - free(zTmpWide); + sqlite3_free(zTmpWide); return zFilenameMbcs; } @@ -1128,7 +1101,7 @@ static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ /* copy a maximum of nBuf chars to output buffer */ sqlite3_snprintf(nBuf, zBuf, "%s", zOut); /* free the UTF8 buffer */ - free(zOut); + sqlite3_free(zOut); } return 0; } @@ -1274,9 +1247,15 @@ static void winceMutexAcquire(HANDLE h){ */ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ LPWSTR zTok; - LPWSTR zName = utf8ToUnicode(zFilename); + LPWSTR zName; BOOL bInit = TRUE; + zName = utf8ToUnicode(zFilename); + if( zName==0 ){ + /* out of memory */ + return FALSE; + } + /* Initialize the local lockdata */ memset(&pFile->local, 0, sizeof(pFile->local)); @@ -1292,7 +1271,7 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ if (!pFile->hMutex){ pFile->lastErrno = osGetLastError(); winLogError(SQLITE_ERROR, pFile->lastErrno, "winceCreateLock1", zFilename); - free(zName); + sqlite3_free(zName); return FALSE; } @@ -1314,7 +1293,7 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ bInit = FALSE; } - free(zName); + sqlite3_free(zName); /* If we succeeded in making the shared memory handle, map it. */ if (pFile->hShared){ @@ -1612,7 +1591,7 @@ static int winClose(sqlite3_file *id){ ){ osSleep(100); /* Wait a little before trying again */ } - free(pFile->zDeleteOnClose); + sqlite3_free(pFile->zDeleteOnClose); } #endif OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed")); @@ -2440,13 +2419,13 @@ static int winOpenSharedMemory(winFile *pDbFd){ ** allocate space for a new winShmNode and filename. */ p = sqlite3_malloc( sizeof(*p) ); - if( p==0 ) return SQLITE_NOMEM; + if( p==0 ) return SQLITE_IOERR_NOMEM; memset(p, 0, sizeof(*p)); nName = sqlite3Strlen30(pDbFd->zPath); pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 15 ); if( pNew==0 ){ sqlite3_free(p); - return SQLITE_NOMEM; + return SQLITE_IOERR_NOMEM; } memset(pNew, 0, sizeof(*pNew)); pNew->zFilename = (char*)&pNew[1]; @@ -2474,7 +2453,7 @@ static int winOpenSharedMemory(winFile *pDbFd){ pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); if( pShmNode->mutex==0 ){ - rc = SQLITE_NOMEM; + rc = SQLITE_IOERR_NOMEM; goto shm_open_err; } @@ -2924,9 +2903,9 @@ static int getTempname(int nBuf, char *zBuf){ zMulti = unicodeToUtf8(zWidePath); if( zMulti ){ sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti); - free(zMulti); + sqlite3_free(zMulti); }else{ - return SQLITE_NOMEM; + return SQLITE_IOERR_NOMEM; } /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ASCII version of these Windows API do not exist for WINCE, @@ -2940,9 +2919,9 @@ static int getTempname(int nBuf, char *zBuf){ zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); if( zUtf8 ){ sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8); - free(zUtf8); + sqlite3_free(zUtf8); }else{ - return SQLITE_NOMEM; + return SQLITE_IOERR_NOMEM; } #endif } @@ -3065,7 +3044,7 @@ static int winOpen( /* Convert the filename to the system encoding. */ zConverted = convertUtf8Filename(zUtf8Name); if( zConverted==0 ){ - return SQLITE_NOMEM; + return SQLITE_IOERR_NOMEM; } if( isReadWrite ){ @@ -3143,7 +3122,7 @@ static int winOpen( if( h==INVALID_HANDLE_VALUE ){ pFile->lastErrno = osGetLastError(); winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); - free(zConverted); + sqlite3_free(zConverted); if( isReadWrite && !isExclusive ){ return winOpen(pVfs, zName, id, ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags); @@ -3174,7 +3153,7 @@ static int winOpen( && !winceCreateLock(zName, pFile) ){ osCloseHandle(h); - free(zConverted); + sqlite3_free(zConverted); return SQLITE_CANTOPEN_BKPT; } if( isTemp ){ @@ -3182,7 +3161,7 @@ static int winOpen( }else #endif { - free(zConverted); + sqlite3_free(zConverted); } OpenCounter(+1); @@ -3215,7 +3194,7 @@ static int winDelete( SimulateIOError(return SQLITE_IOERR_DELETE); zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ - return SQLITE_NOMEM; + return SQLITE_IOERR_NOMEM; } if( isNT() ){ rc = 1; @@ -3240,7 +3219,7 @@ static int winDelete( }else{ logIoerr(cnt); } - free(zConverted); + sqlite3_free(zConverted); OSTRACE(("DELETE \"%s\" %s\n", zFilename, (rc ? "failed" : "ok" ))); return rc; } @@ -3262,7 +3241,7 @@ static int winAccess( SimulateIOError( return SQLITE_IOERR_ACCESS; ); zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ - return SQLITE_NOMEM; + return SQLITE_IOERR_NOMEM; } if( isNT() ){ int cnt = 0; @@ -3287,7 +3266,7 @@ static int winAccess( logIoerr(cnt); if( lastErrno!=ERROR_FILE_NOT_FOUND ){ winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename); - free(zConverted); + sqlite3_free(zConverted); return SQLITE_IOERR_ACCESS; }else{ attr = INVALID_FILE_ATTRIBUTES; @@ -3302,7 +3281,7 @@ static int winAccess( attr = osGetFileAttributesA((char*)zConverted); #endif } - free(zConverted); + sqlite3_free(zConverted); switch( flags ){ case SQLITE_ACCESS_READ: case SQLITE_ACCESS_EXISTS: @@ -3367,18 +3346,21 @@ static int winFullPathname( SimulateIOError( return SQLITE_ERROR ); UNUSED_PARAMETER(nFull); zConverted = convertUtf8Filename(zRelative); + if( zConverted==0 ){ + return SQLITE_IOERR_NOMEM; + } if( isNT() ){ LPWSTR zTemp; nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0) + 3; - zTemp = malloc( nByte*sizeof(zTemp[0]) ); + zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ - free(zConverted); - return SQLITE_NOMEM; + sqlite3_free(zConverted); + return SQLITE_IOERR_NOMEM; } osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); - free(zConverted); + sqlite3_free(zConverted); zOut = unicodeToUtf8(zTemp); - free(zTemp); + sqlite3_free(zTemp); /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ASCII version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. @@ -3387,23 +3369,23 @@ static int winFullPathname( }else{ char *zTemp; nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0) + 3; - zTemp = malloc( nByte*sizeof(zTemp[0]) ); + zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ - free(zConverted); - return SQLITE_NOMEM; + sqlite3_free(zConverted); + return SQLITE_IOERR_NOMEM; } osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); - free(zConverted); + sqlite3_free(zConverted); zOut = sqlite3_win32_mbcs_to_utf8(zTemp); - free(zTemp); + sqlite3_free(zTemp); #endif } if( zOut ){ sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut); - free(zOut); + sqlite3_free(zOut); return SQLITE_OK; }else{ - return SQLITE_NOMEM; + return SQLITE_IOERR_NOMEM; } #endif } @@ -3468,7 +3450,7 @@ static int getSectorSize( &dwDummy, &dwDummy); } - free(zConverted); + sqlite3_free(zConverted); } if( !dwRet ){ bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE; @@ -3505,7 +3487,7 @@ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ h = osLoadLibraryA((char*)zConverted); #endif } - free(zConverted); + sqlite3_free(zConverted); return (void*)h; } static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ From 4cb5f436cba31df86076b949b0968d77fa8a0092 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 11 Nov 2011 23:51:15 +0000 Subject: [PATCH 027/161] Catch and report errors from sqlite3OsFullPathname(). FossilOrigin-Name: 77119785c84ac7f416ed72c38c532399b6093d7a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 7 ++++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 1d56a640de..2df6569372 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sa\scorrupt\sindex\sdoes\snot\scause\sa\sbuffer\soverread\sin\s\nsqlite3VdbeRecordCompare(). -D 2011-11-11T00:27:15.786 +C Catch\sand\sreport\serrors\sfrom\ssqlite3OsFullPathname(). +D 2011-11-11T23:51:15.820 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -125,7 +125,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 4368158da74d4711888e03264105c5c527d76caf F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 2521a74f04cf288497af3b318fa3a31efb272ef6 +F src/btree.c 80ea65224512884bb72976c93810d2dcaecc1353 F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h ea863a819224d3e6845ad1e39954d41558b8cd8b F src/build.c 8af67a08a852ff4c63701963cb1ab7166f577814 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 8f28797984c1d4700357a75815ca4b324c3ebf5c -R 0b7ae5ff536a087fdb2c3479a3ed3d3f +P 471cf0d8e7857110e525e029c2d535cb518dba6a +R 65b07c80cc955ef693a9df9b61c2f7e6 U drh -Z 717b87433a48f5a306459509a02bb49f +Z 2bcb48737ffc2ef5d0789f9c5e08f674 diff --git a/manifest.uuid b/manifest.uuid index 8f58ddd640..d5d2731377 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -471cf0d8e7857110e525e029c2d535cb518dba6a \ No newline at end of file +77119785c84ac7f416ed72c38c532399b6093d7a \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a1b05e1f3e..713016e756 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1776,7 +1776,12 @@ int sqlite3BtreeOpen( sqlite3_free(p); return SQLITE_NOMEM; } - sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); + rc = sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); + if( rc ){ + sqlite3_free(zFullPathname); + sqlite3_free(p); + return rc; + } #if SQLITE_THREADSAFE mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN); sqlite3_mutex_enter(mutexOpen); From 6c3c1a0951c0d071ab377ff1ef81a6a6358e3e6d Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sat, 12 Nov 2011 03:17:40 +0000 Subject: [PATCH 028/161] Make sure to flag benign malloc failures in the Windows VFS as such. Expand use of the DO_OS_MALLOC_TEST to cover the VFS functions that can now return an out of memory error. Support an experimental --match option to the test suite that will run only those tests matching the specified pattern. FossilOrigin-Name: 76dec8aa9dbbc39e0a7c3b358b58ce7f7a477a2b --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/os.c | 13 ++++++++++++- src/os_win.c | 36 ++++++++++++++++++++++-------------- src/test_vfs.c | 10 ++++++++-- test/tester.tcl | 38 +++++++++++++++++++++++++++----------- 6 files changed, 79 insertions(+), 38 deletions(-) diff --git a/manifest b/manifest index 0c8720d589..82f3c653e6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\suse\sof\smalloc\sand\sfree\sfrom\sthe\sWindows\sVFS.\s\sAlso,\sprevent\ssqlite3BtreeOpen\sfrom\sassuming\sthat\ssqlite3OsFullPathname\scannot\sfail. -D 2011-11-11T23:31:04.676 +C Make\ssure\sto\sflag\sbenign\smalloc\sfailures\sin\sthe\sWindows\sVFS\sas\ssuch.\s\sExpand\suse\sof\sthe\sDO_OS_MALLOC_TEST\sto\scover\sthe\sVFS\sfunctions\sthat\scan\snow\sreturn\san\sout\sof\smemory\serror.\s\sSupport\san\sexperimental\s--match\soption\sto\sthe\stest\ssuite\sthat\swill\srun\sonly\sthose\stests\smatching\sthe\sspecified\spattern. +D 2011-11-12T03:17:40.954 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -162,12 +162,12 @@ F src/mutex_os2.c 882d735098c07c8c6a5472b8dd66e19675fe117f F src/mutex_unix.c b4f4e923bb8de93ec3f251fadb50855f23df9579 F src/mutex_w32.c 5e54f3ba275bcb5d00248b8c23107df2e2f73e33 F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 -F src/os.c 5d9b02782ed36345348d6fe21d7762ed3a9cfd2a +F src/os.c 28bbdab2170dfce84d86c45456a18eab1d0f99a9 F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 4fbb91726165e105c1679a2660f49a3f4c376e4f -F src/os_win.c ee8ba0846294f154e0822095512a665cdb197c8a +F src/os_win.c a22b88d2c088c09a678a471abafa8d60dbf56803 F src/pager.c db33d4bf1e3e019c34c220971cc6c3aa07c30f54 F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 @@ -229,7 +229,7 @@ F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_thread.c 35022393dd54d147b998b6b7f7e945b01114d666 -F src/test_vfs.c b0baec983bd6f872715a4b44c8f39104fec333af +F src/test_vfs.c 27b7d9de40630f603b9e2cf9ef2a7c81d31c4515 F src/test_vfstrace.c 0b884e06094a746da729119a2cabdc7aa790063d F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 @@ -707,7 +707,7 @@ F test/tclsqlite.test 5ebcbb0dccc3fbc1edc3bba84c38e2c2d574c5aa F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2 F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d -F test/tester.tcl 0b2999b578964297663de4870babbbee29225622 +F test/tester.tcl 001051eaf28c1040800f588a64c63e0bd0e1f36b F test/thread001.test 7cc2ce08f9cde95964736d11e91f9ab610f82f91 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P ed88fb00240de75457c0da19e87c12082622ca17 -R a35825c17aca6258f92039304b464c67 +P 8966ec1797be63d1305628d459bdad5be08cf3ca +R b05037fbfa7e2180ed81bf446e380e48 U mistachkin -Z 93813e17596e2d1608777ccc9fc54b6a +Z 1660438f613633eeb0e91d69e2a176bd diff --git a/manifest.uuid b/manifest.uuid index 68895f5c98..6a03a23564 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8966ec1797be63d1305628d459bdad5be08cf3ca \ No newline at end of file +76dec8aa9dbbc39e0a7c3b358b58ce7f7a477a2b \ No newline at end of file diff --git a/src/os.c b/src/os.c index 0b13c86e9e..a347ec1d02 100644 --- a/src/os.c +++ b/src/os.c @@ -27,11 +27,18 @@ ** The following functions are instrumented for malloc() failure ** testing: ** -** sqlite3OsOpen() ** sqlite3OsRead() ** sqlite3OsWrite() ** sqlite3OsSync() +** sqlite3OsFileSize() ** sqlite3OsLock() +** sqlite3OsCheckReservedLock() +** sqlite3OsFileControl() +** sqlite3OsShmMap() +** sqlite3OsOpen() +** sqlite3OsDelete() +** sqlite3OsAccess() +** sqlite3OsFullPathname() ** */ #if defined(SQLITE_TEST) @@ -91,6 +98,7 @@ int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ return id->pMethods->xCheckReservedLock(id, pResOut); } int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ + DO_OS_MALLOC_TEST(id); return id->pMethods->xFileControl(id, op, pArg); } int sqlite3OsSectorSize(sqlite3_file *id){ @@ -116,6 +124,7 @@ int sqlite3OsShmMap( int bExtend, /* True to extend file if necessary */ void volatile **pp /* OUT: Pointer to mapping */ ){ + DO_OS_MALLOC_TEST(id); return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp); } @@ -141,6 +150,7 @@ int sqlite3OsOpen( return rc; } int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + DO_OS_MALLOC_TEST(0); return pVfs->xDelete(pVfs, zPath, dirSync); } int sqlite3OsAccess( @@ -158,6 +168,7 @@ int sqlite3OsFullPathname( int nPathOut, char *zPathOut ){ + DO_OS_MALLOC_TEST(0); zPathOut[0] = 0; return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); } diff --git a/src/os_win.c b/src/os_win.c index 8550c628f6..62868ba504 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -155,11 +155,11 @@ static int getSectorSize( /* ** The following variable is (normally) set once and never changes -** thereafter. It records whether the operating system is Win95 +** thereafter. It records whether the operating system is Win9x ** or WinNT. ** ** 0: Operating system unknown. -** 1: Operating system is Win95. +** 1: Operating system is Win9x. ** 2: Operating system is WinNT. ** ** In order to facilitate testing on a WinNT system, the test fixture @@ -954,7 +954,7 @@ static char *unicodeToUtf8(LPCWSTR zWideFilename){ } /* -** Convert an ansi string to Microsoft Unicode, based on the +** Convert an ANSI string to Microsoft Unicode, based on the ** current codepage settings for file apis. ** ** Space to hold the returned string is obtained @@ -1067,12 +1067,14 @@ static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ 0); if( dwLen > 0 ){ /* allocate a buffer and convert to UTF8 */ + sqlite3BeginBenignMalloc(); zOut = unicodeToUtf8(zTempWide); + sqlite3EndBenignMalloc(); /* free the system buffer allocated by FormatMessage */ osLocalFree(zTempWide); } /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. -** Since the ASCII version of these Windows API do not exist for WINCE, +** Since the ANSI version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 @@ -1089,7 +1091,9 @@ static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ 0); if( dwLen > 0 ){ /* allocate a buffer and convert to UTF8 */ + sqlite3BeginBenignMalloc(); zOut = sqlite3_win32_mbcs_to_utf8(zTemp); + sqlite3EndBenignMalloc(); /* free the system buffer allocated by FormatMessage */ osLocalFree(zTemp); } @@ -1832,7 +1836,7 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ /* ** Acquire a reader lock. ** Different API routines are called depending on whether or not this -** is Win95 or WinNT. +** is Win9x or WinNT. */ static int getReadLock(winFile *pFile){ int res; @@ -2908,7 +2912,7 @@ static int getTempname(int nBuf, char *zBuf){ return SQLITE_IOERR_NOMEM; } /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. -** Since the ASCII version of these Windows API do not exist for WINCE, +** Since the ANSI version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 @@ -3098,7 +3102,7 @@ static int winOpen( NULL))==INVALID_HANDLE_VALUE && retryIoerr(&cnt) ){} /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. -** Since the ASCII version of these Windows API do not exist for WINCE, +** Since the ANSI version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 @@ -3202,7 +3206,7 @@ static int winDelete( (rc = osDeleteFileW(zConverted))==0 && retryIoerr(&cnt) ){} rc = rc ? SQLITE_OK : SQLITE_ERROR; /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. -** Since the ASCII version of these Windows API do not exist for WINCE, +** Since the ANSI version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 @@ -3273,7 +3277,7 @@ static int winAccess( } } /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. -** Since the ASCII version of these Windows API do not exist for WINCE, +** Since the ANSI version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 @@ -3362,7 +3366,7 @@ static int winFullPathname( zOut = unicodeToUtf8(zTemp); sqlite3_free(zTemp); /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. -** Since the ASCII version of these Windows API do not exist for WINCE, +** Since the ANSI version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 @@ -3415,11 +3419,16 @@ static int getSectorSize( ** size. */ SimulateIOErrorBenign(1); + sqlite3BeginBenignMalloc(); rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath); + sqlite3EndBenignMalloc(); SimulateIOErrorBenign(0); if( rc == SQLITE_OK ) { - void *zConverted = convertUtf8Filename(zFullpath); + void *zConverted; + sqlite3BeginBenignMalloc(); + zConverted = convertUtf8Filename(zFullpath); + sqlite3EndBenignMalloc(); if( zConverted ){ if( isNT() ){ /* trim path to just drive reference */ @@ -3479,7 +3488,7 @@ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ if( isNT() ){ h = osLoadLibraryW((LPCWSTR)zConverted); /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. -** Since the ASCII version of these Windows API do not exist for WINCE, +** Since the ANSI version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 @@ -3662,8 +3671,6 @@ static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ return getLastErrorMsg(osGetLastError(), nBuf, zBuf); } - - /* ** Initialize and deinitialize the operating system interface. */ @@ -3707,6 +3714,7 @@ int sqlite3_os_init(void){ sqlite3_vfs_register(&winVfs, 1); return SQLITE_OK; } + int sqlite3_os_end(void){ return SQLITE_OK; } diff --git a/src/test_vfs.c b/src/test_vfs.c index 546cb7cf49..a59aa40a48 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -988,7 +988,7 @@ static int testvfs_obj_cmd( switch( aSubcmd[i].eCmd ){ case CMD_SHM: { Tcl_Obj *pObj; - int i; + int i, rc; TestvfsBuffer *pBuffer; char *zName; if( objc!=3 && objc!=4 ){ @@ -996,10 +996,16 @@ static int testvfs_obj_cmd( return TCL_ERROR; } zName = ckalloc(p->pParent->mxPathname); - p->pParent->xFullPathname( + rc = p->pParent->xFullPathname( p->pParent, Tcl_GetString(objv[2]), p->pParent->mxPathname, zName ); + if( rc!=SQLITE_OK ){ + Tcl_AppendResult(interp, "failed to get full path: ", + Tcl_GetString(objv[2]), 0); + ckfree(zName); + return TCL_ERROR; + } for(pBuffer=p->pBuffer; pBuffer; pBuffer=pBuffer->pNext){ if( 0==strcmp(pBuffer->zFile, zName) ) break; } diff --git a/test/tester.tcl b/test/tester.tcl index 3c34b45d4e..e27a483f41 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -57,7 +57,7 @@ # Commands providing a lower level interface to the global test counters: # # set_test_counter COUNTER ?VALUE? -# omit_test TESTNAME REASON +# omit_test TESTNAME REASON ?APPEND? # fail_test TESTNAME # incr_ntest # @@ -274,6 +274,7 @@ if {[info exists cmdlinearg]==0} { # --file-retries=N # --file-retry-delay=N # --start=[$permutation:]$testfile + # --match=$pattern # set cmdlinearg(soft-heap-limit) 0 set cmdlinearg(maxerror) 1000 @@ -283,7 +284,8 @@ if {[info exists cmdlinearg]==0} { set cmdlinearg(soak) 0 set cmdlinearg(file-retries) 0 set cmdlinearg(file-retry-delay) 0 - set cmdlinearg(start) "" + set cmdlinearg(start) "" + set cmdlinearg(match) "" set leftover [list] foreach a $argv { @@ -336,6 +338,12 @@ if {[info exists cmdlinearg]==0} { } if {$::G(start:file) == ""} {unset ::G(start:file)} } + {^-+match=.+$} { + foreach {dummy cmdlinearg(match)} [split $a =] break + + set ::G(match) $cmdlinearg(match) + if {$::G(match) == ""} {unset ::G(match)} + } default { lappend leftover $a } @@ -414,9 +422,11 @@ if {0==[info exists ::SLAVE]} { # Record the fact that a sequence of tests were omitted. # -proc omit_test {name reason} { +proc omit_test {name reason {append 1}} { set omitList [set_test_counter omit_list] - lappend omitList [list $name $reason] + if {$append} { + lappend omitList [list $name $reason] + } set_test_counter omit_list $omitList } @@ -471,14 +481,20 @@ proc do_test {name cmd expected} { incr_ntest puts -nonewline $name... flush stdout - if {[catch {uplevel #0 "$cmd;\n"} result]} { - puts "\nError: $result" - fail_test $name - } elseif {[string compare $result $expected]} { - puts "\nExpected: \[$expected\]\n Got: \[$result\]" - fail_test $name + + if {![info exists ::G(match)] || [string match $::G(match) $name]} { + if {[catch {uplevel #0 "$cmd;\n"} result]} { + puts "\nError: $result" + fail_test $name + } elseif {[string compare $result $expected]} { + puts "\nExpected: \[$expected\]\n Got: \[$result\]" + fail_test $name + } else { + puts " Ok" + } } else { - puts " Ok" + puts " Omitted" + omit_test $name "pattern mismatch" 0 } flush stdout } From d5156605231bd81e6338fc8dce5966d6710b14d1 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 12 Nov 2011 16:46:55 +0000 Subject: [PATCH 029/161] Remove a couple of incorrect assert statements so that the test suite will run with -DSQLITE_DEFAULT_CACHE_SIZE=0. FossilOrigin-Name: 87614b62ace530761e0e1170ec5840b212735ec6 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/test_pcache.c | 1 - src/wal.c | 2 +- test/wal.test | 2 ++ 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index cdc683141c..61a9274c37 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\swindows\sxSyscall\senhancements\sinto\strunk. -D 2011-11-12T15:41:52.950 +C Remove\sa\scouple\sof\sincorrect\sassert\sstatements\sso\sthat\sthe\stest\ssuite\swill\nrun\swith\s-DSQLITE_DEFAULT_CACHE_SIZE=0. +D 2011-11-12T16:46:55.610 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,7 +219,7 @@ F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32 -F src/test_pcache.c 7bf828972ac0d2403f5cfa4cd14da41f8ebe73d8 +F src/test_pcache.c 335285416eb7a5c3a0f4daffb796912011ebbf6e F src/test_quota.c a391c866217e92986c6f523f05b08aa6956c8419 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 @@ -249,7 +249,7 @@ F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a -F src/wal.c 9658df8d404b82e6b2d40fd05944463214e2d935 +F src/wal.c 5fe1ba55b8fab9d3936bc9093af61ab9f1c580a1 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c 7c85f4c93058e27100d404f0777aaeb0d1b296ae @@ -893,7 +893,7 @@ F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d -F test/wal.test e11da8d5ea8a38a247339455098357e9adf63d76 +F test/wal.test c743be787e60c1242fa6cdf73b410e64b2977e25 F test/wal2.test ad6412596815f553cd30f271d291ab003092bc7e F test/wal3.test 18da4e65c30c43c646ad40e145e9a074e4062fc9 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 77119785c84ac7f416ed72c38c532399b6093d7a 76dec8aa9dbbc39e0a7c3b358b58ce7f7a477a2b -R ed313c65fa66f4a0f305ec8176ce8f6d +P c1fab9aca1fe1dda2b4c7e4fdc0a406998847bdb +R 9f74f7e0555602e5901be80ed362f860 U drh -Z 011c8308c57c9b72d1c6dd7078495814 +Z 60452ea200640726cdeacf2996a4fa41 diff --git a/manifest.uuid b/manifest.uuid index 4f5951bb69..d0c247ea6f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c1fab9aca1fe1dda2b4c7e4fdc0a406998847bdb \ No newline at end of file +87614b62ace530761e0e1170ec5840b212735ec6 \ No newline at end of file diff --git a/src/test_pcache.c b/src/test_pcache.c index 98aa1367aa..8e66b4b025 100644 --- a/src/test_pcache.c +++ b/src/test_pcache.c @@ -161,7 +161,6 @@ static sqlite3_pcache *testpcacheCreate(int szPage, int bPurgeable){ static void testpcacheCachesize(sqlite3_pcache *pCache, int newSize){ testpcache *p = (testpcache*)pCache; assert( p->iMagic==TESTPCACHE_VALID ); - assert( newSize>=1 ); assert( testpcacheGlobal.pDummy!=0 ); assert( testpcacheGlobal.nInstance>0 ); } diff --git a/src/wal.c b/src/wal.c index f2b3187147..2c905a29e9 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2310,7 +2310,7 @@ int sqlite3WalRead( for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){ u32 iFrame = aHash[iKey] + iZero; if( iFrame<=iLast && aPgno[aHash[iKey]]==pgno ){ - assert( iFrame>iRead ); + /* assert( iFrame>iRead ); -- not true if there is corruption */ iRead = iFrame; } if( (nCollide--)==0 ){ diff --git a/test/wal.test b/test/wal.test index 056becf7db..1c63ddc00f 100644 --- a/test/wal.test +++ b/test/wal.test @@ -416,6 +416,7 @@ do_test wal-8.3 { do_test wal-9.1 { reopen_db execsql { + PRAGMA cache_size=2000; CREATE TABLE t1(x PRIMARY KEY); INSERT INTO t1 VALUES(blob(900)); INSERT INTO t1 VALUES(blob(900)); @@ -1124,6 +1125,7 @@ foreach {tn sectorsize logsize} " execsql { PRAGMA auto_vacuum = 0; PRAGMA page_size = 512; + PRAGMA cache_size = -2000; PRAGMA journal_mode = WAL; PRAGMA synchronous = FULL; } From f923f8211831a7dc09d85efad5f948103e4cd51d Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 12 Nov 2011 23:10:13 +0000 Subject: [PATCH 030/161] Attempt to modify btree.c so that it assumes that calls to sqlite3PagerWrite() will reallocate the page buffer. As there is not good way to test this assumption yet, probably a few spots were missed. FossilOrigin-Name: ceee03c79a55ea39866758aa76b78b10e5f4246d --- manifest | 12 +++++----- manifest.uuid | 2 +- src/btree.c | 66 +++++++++++++++++++++------------------------------ 3 files changed, 34 insertions(+), 46 deletions(-) diff --git a/manifest b/manifest index 8d620e85e9..f7e1882466 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Pull\sover\sall\sthe\slatest\schanges\sfrom\strunk. -D 2011-11-11T14:12:36.001 +C Attempt\sto\smodify\sbtree.c\sso\sthat\sit\sassumes\sthat\scalls\sto\ssqlite3PagerWrite()\nwill\sreallocate\sthe\spage\sbuffer.\s\sAs\sthere\sis\snot\sgood\sway\sto\stest\sthis\nassumption\syet,\sprobably\sa\sfew\sspots\swere\smissed. +D 2011-11-12T23:10:13.436 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -125,7 +125,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 4368158da74d4711888e03264105c5c527d76caf F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 2521a74f04cf288497af3b318fa3a31efb272ef6 +F src/btree.c 149cccf2134f555583d0825e47b17104aa06cb84 F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h ea863a819224d3e6845ad1e39954d41558b8cd8b F src/build.c 8af67a08a852ff4c63701963cb1ab7166f577814 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 6bda711f93e753dd0be8d896a007b3f7b5064787 471cf0d8e7857110e525e029c2d535cb518dba6a -R 50394ddf6c21b3d5be10b1579addf880 +P 1bbbf8574a820c5f787a937f02a8e2a91264ace0 +R 8fe5168196d72d713cb64bacae73a939 U drh -Z 183f0080d0ed04f08eff14296686e20c +Z db5deb4d4c1ff85ac518999d30605134 diff --git a/manifest.uuid b/manifest.uuid index cee1bf9447..a6ee8619eb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1bbbf8574a820c5f787a937f02a8e2a91264ace0 \ No newline at end of file +ceee03c79a55ea39866758aa76b78b10e5f4246d \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a1b05e1f3e..43933fa27d 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1776,7 +1776,12 @@ int sqlite3BtreeOpen( sqlite3_free(p); return SQLITE_NOMEM; } - sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); + rc = sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); + if( rc ){ + sqlite3_free(zFullPathname); + sqlite3_free(p); + return rc; + } #if SQLITE_THREADSAFE mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN); sqlite3_mutex_enter(mutexOpen); @@ -2477,9 +2482,9 @@ static int newDatabase(BtShared *pBt){ } pP1 = pBt->pPage1; assert( pP1!=0 ); - data = pP1->aData; rc = sqlite3PagerWrite(pP1->pDbPage); if( rc ) return rc; + data = pP1->aData; memcpy(data, zMagicHeader, sizeof(zMagicHeader)); assert( sizeof(zMagicHeader)==16 ); data[16] = (u8)((pBt->pageSize>>8)&0xff); @@ -3777,38 +3782,6 @@ static int getOverflowPage( return (rc==SQLITE_DONE ? SQLITE_OK : rc); } -/* -** Copy data from a buffer to a page, or from a page to a buffer. -** -** pPayload is a pointer to data stored on database page pDbPage. -** If argument eOp is false, then nByte bytes of data are copied -** from pPayload to the buffer pointed at by pBuf. If eOp is true, -** then sqlite3PagerWrite() is called on pDbPage and nByte bytes -** of data are copied from the buffer pBuf to pPayload. -** -** SQLITE_OK is returned on success, otherwise an error code. -*/ -static int copyPayload( - void *pPayload, /* Pointer to page data */ - void *pBuf, /* Pointer to buffer */ - int nByte, /* Number of bytes to copy */ - int eOp, /* 0 -> copy from page, 1 -> copy to page */ - DbPage *pDbPage /* Page containing pPayload */ -){ - if( eOp ){ - /* Copy data from buffer to page (a write operation) */ - int rc = sqlite3PagerWrite(pDbPage); - if( rc!=SQLITE_OK ){ - return rc; - } - memcpy(pPayload, pBuf, nByte); - }else{ - /* Copy data from page to buffer (a read operation) */ - memcpy(pBuf, pPayload, nByte); - } - return SQLITE_OK; -} - /* ** This function is used to read or overwrite payload information ** for the entry that the pCur cursor is pointing to. If the eOp @@ -3856,6 +3829,7 @@ static int accessPayload( assert( pCur->aiIdx[pCur->iPage]nCell ); assert( cursorHoldsMutex(pCur) ); + getCellInfo(pCur); aPayload = pCur->info.pCell + pCur->info.nHeader; nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey); @@ -3873,7 +3847,14 @@ static int accessPayload( if( a+offset>pCur->info.nLocal ){ a = pCur->info.nLocal - offset; } - rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage); + if( eOp ){ + if( (rc = sqlite3PagerWrite(pPage->pDbPage))!=SQLITE_OK ) return rc; + getCellInfo(pCur); + aPayload = pCur->info.pCell + pCur->info.nHeader; + memcpy(aPayload+offset, pBuf, a); + }else{ + memcpy(pBuf, aPayload+offset, a); + } offset = 0; pBuf += a; amt -= a; @@ -3984,9 +3965,17 @@ static int accessPayload( DbPage *pDbPage; rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage); if( rc==SQLITE_OK ){ + if( eOp && (rc = sqlite3PagerWrite(pDbPage))!=SQLITE_OK ){ + sqlite3PagerUnref(pDbPage); + return rc; + } aPayload = sqlite3PagerGetData(pDbPage); nextPage = get4byte(aPayload); - rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); + if( eOp ){ + memcpy(&aPayload[offset+4], pBuf, a); + }else{ + memcpy(pBuf, &aPayload[offset+4], a); + } sqlite3PagerUnref(pDbPage); offset = 0; } @@ -7385,16 +7374,14 @@ void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){ */ int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){ BtShared *pBt = p->pBt; - unsigned char *pP1; int rc; assert( idx>=1 && idx<=15 ); sqlite3BtreeEnter(p); assert( p->inTrans==TRANS_WRITE ); assert( pBt->pPage1!=0 ); - pP1 = pBt->pPage1->aData; rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); if( rc==SQLITE_OK ){ - put4byte(&pP1[36 + idx*4], iMeta); + put4byte(&pBt->pPage1->aData[36 + idx*4], iMeta); #ifndef SQLITE_OMIT_AUTOVACUUM if( idx==BTREE_INCR_VACUUM ){ assert( pBt->autoVacuum || iMeta==0 ); @@ -8223,6 +8210,7 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ if( rc==SQLITE_OK ){ rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); if( rc==SQLITE_OK ){ + aData = pBt->pPage1->aData; aData[18] = (u8)iVersion; aData[19] = (u8)iVersion; } From 81ef0f97ef421c36852a3a7fd103e675fb706f52 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 13 Nov 2011 21:44:03 +0000 Subject: [PATCH 031/161] Add a version number to the sqlite3_pcache_methods2 object. Other PCACHE2 documentation improvements. FossilOrigin-Name: 9f839ac05a9f3cfe587d2ccdccd50dac41baedbe --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/pcache1.c | 1 + src/sqlite.h.in | 24 ++++++++++++++++++------ src/test_init.c | 2 +- src/test_pcache.c | 1 + 6 files changed, 31 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index f7e1882466..2988a3c3a3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Attempt\sto\smodify\sbtree.c\sso\sthat\sit\sassumes\sthat\scalls\sto\ssqlite3PagerWrite()\nwill\sreallocate\sthe\spage\sbuffer.\s\sAs\sthere\sis\snot\sgood\sway\sto\stest\sthis\nassumption\syet,\sprobably\sa\sfew\sspots\swere\smissed. -D 2011-11-12T23:10:13.436 +C Add\sa\sversion\snumber\sto\sthe\ssqlite3_pcache_methods2\sobject.\s\sOther\sPCACHE2\ndocumentation\simprovements. +D 2011-11-13T21:44:03.995 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -173,7 +173,7 @@ F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 F src/pcache.c b9d52e9f844d91c27c161279234f273fc02abc71 F src/pcache.h c770382f9fae4ca5025c5523bd0aa13cd6ddc6f8 -F src/pcache1.c 7a3ce2dca0ef889be94b9cb0a2dfc7917ec83eba +F src/pcache1.c 0ac7b63db83a705787f4ababf1e4cff27b5f8064 F src/pragma.c 65d1d63d64f8b7350f28d5ee6d40f7985deccdfe F src/prepare.c ec4989f7f480544bdc4192fe663470d2a2d7d61e F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869 @@ -182,7 +182,7 @@ F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8 -F src/sqlite.h.in fa162d2a068b6c1c25896e8614be3c4f01897a95 +F src/sqlite.h.in 557f4113a649f15d13e566aaa85820509b4daa52 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h f87f241b9821a9d466c2711b7345d30ef3624249 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -208,7 +208,7 @@ F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 F src/test_fuzzer.c f884f6f32e8513d34248d6e1ac8a32047fead254 F src/test_hexio.c c4773049603151704a6ab25ac5e936b5109caf5a -F src/test_init.c 1ff3a696ca45e3c4cd7639217ded5d9c41428fed +F src/test_init.c 3cbad7ce525aec925f8fda2192d576d47f0d478a F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99 F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff @@ -219,7 +219,7 @@ F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32 -F src/test_pcache.c 96f5ba93a34d844de596bebdfe1c09bab438a8bd +F src/test_pcache.c a07e9c1222e964ea20d49e6e0b6e23aa6ae8b6da F src/test_quota.c a391c866217e92986c6f523f05b08aa6956c8419 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 1bbbf8574a820c5f787a937f02a8e2a91264ace0 -R 8fe5168196d72d713cb64bacae73a939 +P ceee03c79a55ea39866758aa76b78b10e5f4246d +R d08ae8acf53f2cb149aeb898f50b49c8 U drh -Z db5deb4d4c1ff85ac518999d30605134 +Z af6f24cf5b51e20dd59385851602a05e diff --git a/manifest.uuid b/manifest.uuid index a6ee8619eb..140730cf5c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ceee03c79a55ea39866758aa76b78b10e5f4246d \ No newline at end of file +9f839ac05a9f3cfe587d2ccdccd50dac41baedbe \ No newline at end of file diff --git a/src/pcache1.c b/src/pcache1.c index a026ed2fb5..35bdda8a9a 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -924,6 +924,7 @@ static void pcache1Destroy(sqlite3_pcache *p){ */ void sqlite3PCacheSetDefault(void){ static const sqlite3_pcache_methods2 defaultMethods = { + 1, /* iVersion */ 0, /* pArg */ pcache1Init, /* xInit */ pcache1Shutdown, /* xShutdown */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 50e95efe2c..27c2b75db3 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5934,10 +5934,26 @@ int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** sqlite3_pcache object except by holding and passing pointers ** to the object. ** -** See [sqlite3_pcache_methods] for additional information. +** See [sqlite3_pcache_methods2] for additional information. */ typedef struct sqlite3_pcache sqlite3_pcache; +/* +** CAPI3REF: Custom Page Cache Object +** +** The sqlite3_pcache_page object represents a single page in the +** page cache. The page cache will allocate instances of this +** object. Various methods of the page cache use pointers to instances +** of this object as parameters or as their return value. +** +** See [sqlite3_pcache_methods2] for additional information. +*/ +typedef struct sqlite3_pcache_page sqlite3_pcache_page; +struct sqlite3_pcache_page { + void *pBuf; /* The content of the page */ + void *pExtra; /* Extra information associated with the page */ +}; + /* ** CAPI3REF: Application Defined Page Cache. ** KEYWORDS: {page cache} @@ -6092,12 +6108,8 @@ typedef struct sqlite3_pcache sqlite3_pcache; ** functions. */ typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; -typedef struct sqlite3_pcache_page sqlite3_pcache_page; -struct sqlite3_pcache_page { - void *pBuf; - void *pExtra; -}; struct sqlite3_pcache_methods2 { + int iVersion; void *pArg; int (*xInit)(void*); void (*xShutdown)(void*); diff --git a/src/test_init.c b/src/test_init.c index 7741cd19e7..e3724d8be3 100644 --- a/src/test_init.c +++ b/src/test_init.c @@ -160,7 +160,7 @@ static void installInitWrappers(void){ wrMutexLeave, wrMutexHeld, wrMutexNotheld }; sqlite3_pcache_methods2 pcachemethods = { - 0, + 1, 0, wrPCacheInit, wrPCacheShutdown, wrPCacheCreate, wrPCacheCachesize, wrPCachePagecount, wrPCacheFetch, wrPCacheUnpin, wrPCacheRekey, wrPCacheTruncate, diff --git a/src/test_pcache.c b/src/test_pcache.c index d2890a1660..2f25de14bf 100644 --- a/src/test_pcache.c +++ b/src/test_pcache.c @@ -432,6 +432,7 @@ void installTestPCache( unsigned highStress /* Call xStress agressively */ ){ static const sqlite3_pcache_methods2 testPcache = { + 1, (void*)&testpcacheGlobal, testpcacheInit, testpcacheShutdown, From e09b84c558d09956e29467a3ed70018b4c6f7aca Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 14 Nov 2011 02:53:54 +0000 Subject: [PATCH 032/161] Fix a 8-byte alignment problem that causes a SIGBUS on Sparc. FossilOrigin-Name: 54cc11981127b52145e39f551d958580b1d45169 --- manifest | 16 +++++++++------- manifest.uuid | 2 +- src/build.c | 19 +++++++++++-------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 307b0c39c8..0127e99098 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.7.9 -D 2011-11-01T00:52:41.132 +C Fix\sa\s8-byte\salignment\sproblem\sthat\scauses\sa\sSIGBUS\son\sSparc. +D 2011-11-14T02:53:54.950 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -128,7 +128,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 32199e2d939233ade25340eaba450f818b37c079 F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 -F src/build.c 8af67a08a852ff4c63701963cb1ab7166f577814 +F src/build.c 8915bb6d72ead998f94c2756ea8d143c77709b70 F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33 @@ -974,8 +974,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 6635cd9a7714b681dd8aa96e90be462a40d10178 -R b059ff356abfc5b4524a9b548916f43e -T +sym-version-3.7.9 * +P c7c6050ef060877ebe77b41d959e9df13f8c9b5e +R ff6342b74061a33cbd4fa1292ca6bba4 +T *branch * branch-3.7.9 +T *sym-branch-3.7.9 * +T -sym-trunk * U drh -Z a9ecbb5c487c786a176874d979505217 +Z d03af58daca88e6314e5ea39548757b9 diff --git a/manifest.uuid b/manifest.uuid index ce12ac8420..2723e4eb4e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c7c6050ef060877ebe77b41d959e9df13f8c9b5e \ No newline at end of file +54cc11981127b52145e39f551d958580b1d45169 \ No newline at end of file diff --git a/src/build.c b/src/build.c index e23aab6b19..46512f8e38 100644 --- a/src/build.c +++ b/src/build.c @@ -2661,19 +2661,22 @@ Index *sqlite3CreateIndex( nName = sqlite3Strlen30(zName); nCol = pList->nExpr; pIndex = sqlite3DbMallocZero(db, - sizeof(Index) + /* Index structure */ - sizeof(tRowcnt)*(nCol+1) + /* Index.aiRowEst */ - sizeof(int)*nCol + /* Index.aiColumn */ - sizeof(char *)*nCol + /* Index.azColl */ - sizeof(u8)*nCol + /* Index.aSortOrder */ - nName + 1 + /* Index.zName */ - nExtra /* Collation sequence names */ + sizeof(Index) + /* Index structure */ + ROUND8(sizeof(tRowcnt)*(nCol+1)) + /* Index.aiRowEst */ + sizeof(char *)*nCol + /* Index.azColl */ + sizeof(int)*nCol + /* Index.aiColumn */ + sizeof(u8)*nCol + /* Index.aSortOrder */ + nName + 1 + /* Index.zName */ + nExtra /* Collation sequence names */ ); if( db->mallocFailed ){ goto exit_create_index; } pIndex->aiRowEst = (tRowcnt*)(&pIndex[1]); - pIndex->azColl = (char**)(&pIndex->aiRowEst[nCol+1]); + pIndex->azColl = (char**) + ((char*)pIndex->aiRowEst + ROUND8(sizeof(tRowcnt)*nCol+1)); + assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) ); + assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) ); pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]); pIndex->aSortOrder = (u8 *)(&pIndex->aiColumn[nCol]); pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]); From bf567db91d5f74eba63fdb7e97dea65c2773424d Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 16 Nov 2011 08:18:20 +0000 Subject: [PATCH 033/161] Update memsubsys1.test to account for the recently increased size of the MemPage structure in btreeInt.h. FossilOrigin-Name: 4fb3ca756a3a7c66baa4745a9b2c1e246a67c699 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/memsubsys1.test | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e602249bda..cd931ca42a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Forward\sport\sthe\s8-byte\salignment\sfix\sfrom\sbranch-3.7.9. -D 2011-11-14T03:00:28.076 +C Update\smemsubsys1.test\sto\saccount\sfor\sthe\srecently\sincreased\ssize\sof\sthe\sMemPage\sstructure\sin\sbtreeInt.h. +D 2011-11-16T08:18:20.698 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -592,7 +592,7 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f F test/memdb.test 708a028d6d373e5b3842e4bdc8ba80998c9a4da6 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 -F test/memsubsys1.test 16ce163ac1ace3d71bf0eaa6a821ed153addd91f +F test/memsubsys1.test c0db8a1e99f4fa07cb858900c55bad9547899aa8 F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9 F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0 @@ -974,7 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 87614b62ace530761e0e1170ec5840b212735ec6 54cc11981127b52145e39f551d958580b1d45169 -R d0f4fbb7a87678b75d0d31293b56ed61 -U drh -Z 9316f0b6f55795050abf35dbc6e7bbba +P ebf6eb6ed756c0a3158b4cb5fb4b460c79d93c29 +R caea05edce79a54f0d9a19e01ae7581d +U dan +Z 63891b2b7447d3ac397ed0d8ca697472 diff --git a/manifest.uuid b/manifest.uuid index c1553fe64a..1c039625bc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ebf6eb6ed756c0a3158b4cb5fb4b460c79d93c29 \ No newline at end of file +4fb3ca756a3a7c66baa4745a9b2c1e246a67c699 \ No newline at end of file diff --git a/test/memsubsys1.test b/test/memsubsys1.test index 7eecf083a7..894a554789 100644 --- a/test/memsubsys1.test +++ b/test/memsubsys1.test @@ -68,7 +68,7 @@ proc reset_highwater_marks {} { sqlite3_status SQLITE_STATUS_PARSER_STACK 1 } -set xtra_size 256 +set xtra_size 272 # Test 1: Both PAGECACHE and SCRATCH are shut down. # From 0c733f67d806e96138a923ce3f6c29e3c7edff19 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 16 Nov 2011 15:27:09 +0000 Subject: [PATCH 034/161] Where possible, take advantage of the rowid at the end of index records to optimize range constraints (<, >, <=, >=) on the rowid column. FossilOrigin-Name: 3b58f5f06648205a47e5cace0201269c406e476a --- manifest | 19 ++++++------- manifest.uuid | 2 +- src/insert.c | 4 +-- src/vdbe.c | 4 +-- src/vdbeaux.c | 2 +- src/where.c | 42 ++++++++++++++++++----------- test/whereC.test | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 113 insertions(+), 30 deletions(-) create mode 100644 test/whereC.test diff --git a/manifest b/manifest index cd931ca42a..ce4d2b370f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\smemsubsys1.test\sto\saccount\sfor\sthe\srecently\sincreased\ssize\sof\sthe\sMemPage\sstructure\sin\sbtreeInt.h. -D 2011-11-16T08:18:20.698 +C Where\spossible,\stake\sadvantage\sof\sthe\srowid\sat\sthe\send\sof\sindex\srecords\sto\soptimize\srange\sconstraints\s(<,\s>,\s<=,\s>=)\son\sthe\srowid\scolumn. +D 2011-11-16T15:27:09.116 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -142,7 +142,7 @@ F src/global.c e230227de13601714b29f9363028514aada5ae2f F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 9794a963911da8157ad0dc39726c9c695b1c4692 +F src/insert.c 8f283d6734dd837ed7531b26d7622fda70874390 F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 @@ -239,11 +239,11 @@ F src/update.c 25e046a8f69d5e557aabde2000487b8545509d8d F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 F src/util.c 01238e2b0f24a14779181dbf991fe02620a80e31 F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa -F src/vdbe.c 326994a64a9a08853122200dc9f62cb96b8f0831 +F src/vdbe.c a7ab9993ec5a4d9479dc99671faec061fbf9b889 F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755 F src/vdbeInt.h 9498fc98a2c9e349a4ef13455ff5a3e898f40176 F src/vdbeapi.c 4dbba7f94f127f6ea8d2d0505ee1f98e5ffbf546 -F src/vdbeaux.c a950e34449a508d48d90475acc287943a4094f3a +F src/vdbeaux.c 17bee21d513b8567f2e010aea287e81e9e6e273f F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 @@ -252,7 +252,7 @@ F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a F src/wal.c 5fe1ba55b8fab9d3936bc9093af61ab9f1c580a1 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c 7c85f4c93058e27100d404f0777aaeb0d1b296ae +F src/where.c f73752ca85c0ed221753fda98aeaf6b9d4616e0e F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 @@ -927,6 +927,7 @@ F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739 F test/where9.test bed66dcfc69a54a99661c0c9906189cb5e58f4e2 F test/whereA.test 24c234263c8fe358f079d5e57d884fb569d2da0a F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5 +F test/whereC.test 13ff5ec0dba407c0e0c075980c75b3275a6774e5 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 @@ -974,7 +975,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P ebf6eb6ed756c0a3158b4cb5fb4b460c79d93c29 -R caea05edce79a54f0d9a19e01ae7581d +P 4fb3ca756a3a7c66baa4745a9b2c1e246a67c699 +R 131e1406052949b0c9af0dcdeb54bce6 U dan -Z 63891b2b7447d3ac397ed0d8ca697472 +Z 4ed1ee25329fe5dbd728820234ee8619 diff --git a/manifest.uuid b/manifest.uuid index 1c039625bc..c2ae2e6bb3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4fb3ca756a3a7c66baa4745a9b2c1e246a67c699 \ No newline at end of file +3b58f5f06648205a47e5cace0201269c406e476a \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index bfcd2c2536..eca3c12ddc 100644 --- a/src/insert.c +++ b/src/insert.c @@ -47,7 +47,7 @@ void sqlite3OpenTable( ** 'd' INTEGER ** 'e' REAL ** -** An extra 'b' is appended to the end of the string to cover the +** An extra 'd' is appended to the end of the string to cover the ** rowid that appears as the last column in every index. ** ** Memory for the buffer containing the column index affinity string @@ -75,7 +75,7 @@ const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ for(n=0; nnColumn; n++){ pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity; } - pIdx->zColAff[n++] = SQLITE_AFF_NONE; + pIdx->zColAff[n++] = SQLITE_AFF_INTEGER; pIdx->zColAff[n] = 0; } diff --git a/src/vdbe.c b/src/vdbe.c index 22e6d9c5b6..e7fa05037d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4616,9 +4616,9 @@ case OP_IdxGE: { /* jump */ r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)pOp->p4.i; if( pOp->p5 ){ - r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; + r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH; }else{ - r.flags = UNPACKED_IGNORE_ROWID; + r.flags = UNPACKED_PREFIX_MATCH; } r.aMem = &aMem[pOp->p3]; #ifdef SQLITE_DEBUG diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 75250238ec..67b4ec7593 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3166,7 +3166,7 @@ int sqlite3VdbeIdxKeyCompare( if( rc ){ return rc; } - assert( pUnpacked->flags & UNPACKED_IGNORE_ROWID ); + assert( pUnpacked->flags & UNPACKED_PREFIX_SEARCH ); *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked); sqlite3VdbeMemRelease(&m); return SQLITE_OK; diff --git a/src/where.c b/src/where.c index 05414da58b..a604d788c4 100644 --- a/src/where.c +++ b/src/where.c @@ -604,7 +604,7 @@ static WhereTerm *findTerm( && pTerm->u.leftColumn==iColumn && (pTerm->eOperator & op)!=0 ){ - if( pIdx && pTerm->eOperator!=WO_ISNULL ){ + if( iColumn>=0 && pIdx && pTerm->eOperator!=WO_ISNULL ){ Expr *pX = pTerm->pExpr; CollSeq *pColl; char idxaff; @@ -3052,10 +3052,24 @@ static void bestBtreeIndex( #endif used |= pTerm->prereqRight; } - - /* Determine the value of rangeDiv */ - if( nEqnColumn && pProbe->bUnordered==0 ){ - int j = pProbe->aiColumn[nEq]; + + /* If the index being considered is UNIQUE, and there is an equality + ** constraint for all columns in the index, then this search will find + ** at most a single row. In this case set the WHERE_UNIQUE flag to + ** indicate this to the caller. + ** + ** Otherwise, if the search may find more than one row, test to see if + ** there is a range constraint on indexed column (nEq+1) that can be + ** optimized using the index. + */ + if( nEq==pProbe->nColumn && pProbe->onError!=OE_None ){ + testcase( wsFlags & WHERE_COLUMN_IN ); + testcase( wsFlags & WHERE_COLUMN_NULL ); + if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){ + wsFlags |= WHERE_UNIQUE; + } + }else if( pProbe->bUnordered==0 ){ + int j = (nEq==pProbe->nColumn ? -1 : pProbe->aiColumn[nEq]); if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){ WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx); WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx); @@ -3074,12 +3088,6 @@ static void bestBtreeIndex( } wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE); } - }else if( pProbe->onError!=OE_None ){ - testcase( wsFlags & WHERE_COLUMN_IN ); - testcase( wsFlags & WHERE_COLUMN_NULL ); - if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){ - wsFlags |= WHERE_UNIQUE; - } } /* If there is an ORDER BY clause and the index being considered will @@ -3690,10 +3698,12 @@ static char *explainIndexRange(sqlite3 *db, WhereLevel *pLevel, Table *pTab){ j = i; if( pPlan->wsFlags&WHERE_BTM_LIMIT ){ - explainAppendTerm(&txt, i++, aCol[aiColumn[j]].zName, ">"); + char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName; + explainAppendTerm(&txt, i++, z, ">"); } if( pPlan->wsFlags&WHERE_TOP_LIMIT ){ - explainAppendTerm(&txt, i, aCol[aiColumn[j]].zName, "<"); + char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName; + explainAppendTerm(&txt, i, z, "<"); } sqlite3StrAccumAppend(&txt, ")", 1); return sqlite3StrAccumFinish(&txt); @@ -4051,7 +4061,7 @@ static Bitmask codeOneLoopStart( pIdx = pLevel->plan.u.pIdx; iIdxCur = pLevel->iIdxCur; - k = pIdx->aiColumn[nEq]; /* Column for inequality constraints */ + k = (nEq==pIdx->nColumn ? -1 : pIdx->aiColumn[nEq]); /* If this loop satisfies a sort order (pOrderBy) request that ** was passed to this function to implement a "SELECT min(x) ..." @@ -4097,7 +4107,9 @@ static Bitmask codeOneLoopStart( ** a forward order scan on a descending index, interchange the ** start and end terms (pRangeStart and pRangeEnd). */ - if( nEqnColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC) ){ + if( (nEqnColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC)) + || (bRev && pIdx->nColumn==nEq) + ){ SWAP(WhereTerm *, pRangeEnd, pRangeStart); } diff --git a/test/whereC.test b/test/whereC.test new file mode 100644 index 0000000000..9fa1bbaf95 --- /dev/null +++ b/test/whereC.test @@ -0,0 +1,70 @@ +# 2011 November 16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix whereC + +do_execsql_test 1.0 { + CREATE TABLE t1(i INTEGER PRIMARY KEY, a, b INTEGER); + + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 1, 1); + INSERT INTO t1 VALUES(3, 1, 2); + INSERT INTO t1 VALUES(4, 1, 2); + INSERT INTO t1 VALUES(5, 1, 2); + INSERT INTO t1 VALUES(6, 1, 3); + INSERT INTO t1 VALUES(7, 1, 3); + + INSERT INTO t1 VALUES(8, 2, 1); + INSERT INTO t1 VALUES(9, 2, 1); + INSERT INTO t1 VALUES(10, 2, 2); + INSERT INTO t1 VALUES(11, 2, 2); + INSERT INTO t1 VALUES(12, 2, 2); + INSERT INTO t1 VALUES(13, 2, 3); + INSERT INTO t1 VALUES(14, 2, 3); + + INSERT INTO t1 VALUES(15, 2, 1); + INSERT INTO t1 VALUES(16, 2, 1); + INSERT INTO t1 VALUES(17, 2, 2); + INSERT INTO t1 VALUES(18, 2, 2); + INSERT INTO t1 VALUES(19, 2, 2); + INSERT INTO t1 VALUES(20, 2, 3); + INSERT INTO t1 VALUES(21, 2, 3); + + CREATE INDEX i1 ON t1(a, b); +} + +foreach {tn sql res} { + 1 "SELECT i FROM t1 WHERE a=1 AND b=2 AND i>3" {4 5} + 2 "SELECT i FROM t1 WHERE rowid='12'" {12} + 3 "SELECT i FROM t1 WHERE a=1 AND b='2'" {3 4 5} + 4 "SELECT i FROM t1 WHERE a=1 AND b='2' AND i>'3'" {4 5} + 5 "SELECT i FROM t1 WHERE a=1 AND b='2' AND i<5" {3 4} + 6 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i<12" {10 11} + 7 "SELECT i FROM t1 WHERE a IN(1, 2) AND b=2 AND i<11" {3 4 5 10} + 8 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i BETWEEN 10 AND 12" {10 11 12} + 9 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i BETWEEN 11 AND 12" {11 12} + 10 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i BETWEEN 10 AND 11" {10 11} + 11 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i BETWEEN 12 AND 10" {} + 12 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i=NULL" {} + 14 "SELECT i FROM t1 WHERE a=1 AND b='2' AND i<4.5" {3 4} +} { + do_execsql_test 1.$tn.1 $sql $res + do_execsql_test 1.$tn.2 "$sql ORDER BY i ASC" [lsort -integer -inc $res] + do_execsql_test 1.$tn.3 "$sql ORDER BY i DESC" [lsort -integer -dec $res] +} + + +finish_test + From 6f13323118bde3c7180466da6bb5963121901360 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 16 Nov 2011 15:41:29 +0000 Subject: [PATCH 035/161] Fix an invalid assert() statement added by [3b58f5f066]. FossilOrigin-Name: 888b09dd8fc0a31b69852a2c10eebb5f31fe35de --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ce4d2b370f..6463dd6b39 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Where\spossible,\stake\sadvantage\sof\sthe\srowid\sat\sthe\send\sof\sindex\srecords\sto\soptimize\srange\sconstraints\s(<,\s>,\s<=,\s>=)\son\sthe\srowid\scolumn. -D 2011-11-16T15:27:09.116 +C Fix\san\sinvalid\sassert()\sstatement\sadded\sby\s[3b58f5f066]. +D 2011-11-16T15:41:29.973 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -243,7 +243,7 @@ F src/vdbe.c a7ab9993ec5a4d9479dc99671faec061fbf9b889 F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755 F src/vdbeInt.h 9498fc98a2c9e349a4ef13455ff5a3e898f40176 F src/vdbeapi.c 4dbba7f94f127f6ea8d2d0505ee1f98e5ffbf546 -F src/vdbeaux.c 17bee21d513b8567f2e010aea287e81e9e6e273f +F src/vdbeaux.c 3ff5f59d4fdbe94eafd97483e7ceee6045364d02 F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 @@ -975,7 +975,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 4fb3ca756a3a7c66baa4745a9b2c1e246a67c699 -R 131e1406052949b0c9af0dcdeb54bce6 +P 3b58f5f06648205a47e5cace0201269c406e476a +R c8ea7107e3daef31b122bbcd288f4e49 U dan -Z 4ed1ee25329fe5dbd728820234ee8619 +Z 2cec893a5743ba3152a50038626b1c85 diff --git a/manifest.uuid b/manifest.uuid index c2ae2e6bb3..6d305be0df 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3b58f5f06648205a47e5cace0201269c406e476a \ No newline at end of file +888b09dd8fc0a31b69852a2c10eebb5f31fe35de \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 67b4ec7593..983ac2cde7 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3166,7 +3166,7 @@ int sqlite3VdbeIdxKeyCompare( if( rc ){ return rc; } - assert( pUnpacked->flags & UNPACKED_PREFIX_SEARCH ); + assert( pUnpacked->flags & UNPACKED_PREFIX_MATCH ); *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked); sqlite3VdbeMemRelease(&m); return SQLITE_OK; From 8f10acdb5bb3ebf64cdf7a57d1d25b167fe4c87e Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Nov 2011 16:23:15 +0000 Subject: [PATCH 036/161] Remove code made obsolete by the changes to index processing that allow range search on the rowid. FossilOrigin-Name: a5418c7fc216a30abf7b2fa8c579aee586393a91 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/sqliteInt.h | 1 - src/vdbeaux.c | 12 ------------ 4 files changed, 9 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 6463dd6b39..fc9815ffc5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sinvalid\sassert()\sstatement\sadded\sby\s[3b58f5f066]. -D 2011-11-16T15:41:29.973 +C Remove\scode\smade\sobsolete\sby\sthe\schanges\sto\sindex\sprocessing\sthat\sallow\nrange\ssearch\son\sthe\srowid. +D 2011-11-16T16:23:15.780 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -184,7 +184,7 @@ F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 F src/shell.c 6d2ad7f80adc9c8c3195412879af36eb3196c1b6 F src/sqlite.h.in b7a4e8d428e467d820cbb4c1d275fdda88b4d7ab F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h b0b6df8f7fe739e3cd718debb60f58853666d13e +F src/sqliteInt.h ce631f204a67ae35b817928e3931484bda0963bc F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -243,7 +243,7 @@ F src/vdbe.c a7ab9993ec5a4d9479dc99671faec061fbf9b889 F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755 F src/vdbeInt.h 9498fc98a2c9e349a4ef13455ff5a3e898f40176 F src/vdbeapi.c 4dbba7f94f127f6ea8d2d0505ee1f98e5ffbf546 -F src/vdbeaux.c 3ff5f59d4fdbe94eafd97483e7ceee6045364d02 +F src/vdbeaux.c 45713a5f8f4f36195f503b30153ddef292323f88 F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 @@ -975,7 +975,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 3b58f5f06648205a47e5cace0201269c406e476a -R c8ea7107e3daef31b122bbcd288f4e49 -U dan -Z 2cec893a5743ba3152a50038626b1c85 +P 888b09dd8fc0a31b69852a2c10eebb5f31fe35de +R e9cdc1916fc67db6e66156ee2c102eee +U drh +Z 65f4e24eecf20b0f9a407d4be4414918 diff --git a/manifest.uuid b/manifest.uuid index 6d305be0df..426ffad767 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -888b09dd8fc0a31b69852a2c10eebb5f31fe35de \ No newline at end of file +a5418c7fc216a30abf7b2fa8c579aee586393a91 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 2171c15749..b4b2128898 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1453,7 +1453,6 @@ struct UnpackedRecord { */ #define UNPACKED_NEED_FREE 0x0001 /* Memory is from sqlite3Malloc() */ #define UNPACKED_NEED_DESTROY 0x0002 /* apMem[]s should all be destroyed */ -#define UNPACKED_IGNORE_ROWID 0x0004 /* Ignore trailing rowid on key1 */ #define UNPACKED_INCRKEY 0x0008 /* Make this key an epsilon larger */ #define UNPACKED_PREFIX_MATCH 0x0010 /* A prefix match is considered OK */ #define UNPACKED_PREFIX_SEARCH 0x0020 /* A prefix match is considered OK */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 983ac2cde7..7c69d28cf6 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2943,15 +2943,6 @@ void sqlite3VdbeRecordUnpack( ** Or if the UNPACKED_MATCH_PREFIX flag is set and the prefixes are ** equal, then the keys are considered to be equal and ** the parts beyond the common prefix are ignored. -** -** If the UNPACKED_IGNORE_ROWID flag is set, then the last byte of -** the header of pKey1 is ignored. It is assumed that pKey1 is -** an index key, and thus ends with a rowid value. The last byte -** of the header will therefore be the serial type of the rowid: -** one of 1, 2, 3, 4, 5, 6, 8, or 9 - the integer serial types. -** The serial type of the final rowid will always be a single byte. -** By ignoring this last byte of the header, we force the comparison -** to ignore the rowid at the end of key1. */ int sqlite3VdbeRecordCompare( int nKey1, const void *pKey1, /* Left key */ @@ -2984,9 +2975,6 @@ int sqlite3VdbeRecordCompare( idx1 = getVarint32(aKey1, szHdr1); d1 = szHdr1; - if( pPKey2->flags & UNPACKED_IGNORE_ROWID ){ - szHdr1--; - } nField = pKeyInfo->nField; while( idx1nField ){ u32 serial_type1; From d236b16412aa7f2e6b01798eaa80782705ded691 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Nov 2011 17:32:28 +0000 Subject: [PATCH 037/161] Change the multiplexor suffix from 2 to 3 digits. FossilOrigin-Name: 06e0cdaf9112f722c23692e25c5b1f99b61c2d78 --- manifest | 17 ++++++++++------- manifest.uuid | 2 +- src/test_multiplex.c | 28 +++++++--------------------- test/multiplex.test | 2 +- 4 files changed, 19 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index fc9815ffc5..3a42d47788 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\scode\smade\sobsolete\sby\sthe\schanges\sto\sindex\sprocessing\sthat\sallow\nrange\ssearch\son\sthe\srowid. -D 2011-11-16T16:23:15.780 +C Change\sthe\smultiplexor\ssuffix\sfrom\s2\sto\s3\sdigits. +D 2011-11-16T17:32:28.704 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c 3fc368022c46fe44ec22c5e1ed727223a54a6a1d +F src/test_multiplex.c 6a65dd5006117d26718110a8e00b0118aa5c98a1 F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -605,7 +605,7 @@ F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5 F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test eafaa41b9133d7a2ded4641bbe5f340731d35a52 F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054 -F test/multiplex.test 9df8bf738b3b97c718fceb3fadb30900ba494418 +F test/multiplex.test 770f0295dd6673e60458cb93abd033ed2f253291 F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test e9648b9d007c7045242af35e11a984d4b169443a @@ -975,7 +975,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 888b09dd8fc0a31b69852a2c10eebb5f31fe35de -R e9cdc1916fc67db6e66156ee2c102eee +P a5418c7fc216a30abf7b2fa8c579aee586393a91 +R 6f660080d5c293528a113cc8cdb20026 +T *branch * 3-digit-multiplex-suffix +T *sym-3-digit-multiplex-suffix * +T -sym-trunk * U drh -Z 65f4e24eecf20b0f9a407d4be4414918 +Z 8b5e0625a534e1e664db241b7f45d292 diff --git a/manifest.uuid b/manifest.uuid index 426ffad767..71507368b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a5418c7fc216a30abf7b2fa8c579aee586393a91 \ No newline at end of file +06e0cdaf9112f722c23692e25c5b1f99b61c2d78 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 5d29607acb..334024fc1e 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -96,26 +96,14 @@ # define SQLITE_MULTIPLEX_CHUNK_SIZE 2147418112 #endif -/* Default limit on number of chunks. Care should be taken -** so that values for chunks numbers fit in the SQLITE_MULTIPLEX_EXT_FMT -** format specifier. It may be changed by calling +/* Default limit on number of chunks. +** May be changed by calling ** the xFileControl() interface. */ #ifndef SQLITE_MULTIPLEX_MAX_CHUNKS # define SQLITE_MULTIPLEX_MAX_CHUNKS 32 #endif -/* If SQLITE_MULTIPLEX_EXT_OVWR is defined, the -** last SQLITE_MULTIPLEX_EXT_SZ characters of the -** filename will be overwritten, otherwise, the -** multiplex extension is simply appended to the filename. -** Ex. (undefined) test.db -> test.db01 -** (defined) test.db -> test.01 -** Chunk 0 does not have a modified extension. -*/ -#define SQLITE_MULTIPLEX_EXT_FMT "%02d" -#define SQLITE_MULTIPLEX_EXT_SZ 2 - /************************ Object Definitions ******************************/ /* Forward declaration of all object types */ @@ -304,20 +292,18 @@ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){ if( pGroup->aReal[iChunk].z==0 ){ char *z; int n = pGroup->nName; - pGroup->aReal[iChunk].z = z = sqlite3_malloc( n+3 ); + pGroup->aReal[iChunk].z = z = sqlite3_malloc( n+4 ); if( z==0 ){ return SQLITE_NOMEM; } memcpy(z, pGroup->zName, n+1); if( iChunk>0 ){ #ifdef SQLITE_ENABLE_8_3_NAMES - if( n>3 && z[n-3]=='.' ){ - n--; - }else if( n>4 && z[n-4]=='.' ){ - n -= 2; - } + int i; + for(i=n-1; i>0 && i>=n-4 && z[i]!='.'; i--){} + if( i>=n-4 ) n = i+1; #endif - sqlite3_snprintf(3,&z[n],"%02d",iChunk); + sqlite3_snprintf(4,&z[n],"%03d",iChunk); } } return SQLITE_OK; diff --git a/test/multiplex.test b/test/multiplex.test index 3abdcf4507..cb6c8a0b63 100644 --- a/test/multiplex.test +++ b/test/multiplex.test @@ -24,7 +24,7 @@ set g_max_chunks 32 # file name with the chunk number. proc multiplex_name {name chunk} { if {$chunk==0} { return $name } - set num [format "%02d" $chunk] + set num [format "%03d" $chunk] ifcapable {multiplex_ext_overwrite} { set name [string range $name 0 [expr [string length $name]-2-1]] } From 09419b4bae13024d9bfc011e0a108eb3dfc6296f Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Nov 2011 19:29:17 +0000 Subject: [PATCH 038/161] Add the sqlite3_db_release_memory() interface and the shrink_memory pragma. FossilOrigin-Name: 3f58e7c8895d1252eff56282c08b1a6f1194452c --- manifest | 29 +++++++++++++++-------------- manifest.uuid | 2 +- src/main.c | 18 ++++++++++++++++++ src/pager.c | 7 +++++++ src/pager.h | 1 + src/pcache.c | 9 +++++++++ src/pcache.h | 3 +++ src/pcache1.c | 33 +++++++++++++++++++++++++++------ src/pragma.c | 10 ++++++++++ src/sqlite.h.in | 22 ++++++++++++++++++++++ src/test1.c | 26 ++++++++++++++++++++++++++ test/shrink.test | 42 ++++++++++++++++++++++++++++++++++++++++++ 12 files changed, 181 insertions(+), 21 deletions(-) create mode 100644 test/shrink.test diff --git a/manifest b/manifest index 18ce75562b..32a5baf41b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sPCACHE2\schanges\sinto\strunk. -D 2011-11-16T18:08:07.023 +C Add\sthe\ssqlite3_db_release_memory()\sinterface\sand\sthe\sshrink_memory\spragma. +D 2011-11-16T19:29:17.253 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f -F src/main.c 87dd4f6ee9b1700d54164ab4e14f2f7abc75486f +F src/main.c 3acbdf6f8b93093bd7f96bdfd7f88bab95a5cd7a F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 7456e2ca0524609ebc06a9befeda5289d4575ad4 @@ -168,13 +168,13 @@ F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 4fbb91726165e105c1679a2660f49a3f4c376e4f F src/os_win.c a22b88d2c088c09a678a471abafa8d60dbf56803 -F src/pager.c db33d4bf1e3e019c34c220971cc6c3aa07c30f54 -F src/pager.h 9f81b08efb06db4ba8be69446e10b005c351373d +F src/pager.c d981f3bfcc0e4460537d983899620700ccf8f539 +F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 -F src/pcache.c b9d52e9f844d91c27c161279234f273fc02abc71 -F src/pcache.h c770382f9fae4ca5025c5523bd0aa13cd6ddc6f8 -F src/pcache1.c 0ac7b63db83a705787f4ababf1e4cff27b5f8064 -F src/pragma.c 65d1d63d64f8b7350f28d5ee6d40f7985deccdfe +F src/pcache.c 1fdd77978c1525d1ca4b9ef48eb80abca710cb4c +F src/pcache.h b1d8775a9bddf44e65edb0d20bfc57a4982f840f +F src/pcache1.c 9d735349ac87ef08076c6b1230f04cd83b15c6da +F src/pragma.c dd66f21fafe7be40e1a48ad4195764cc191cf583 F src/prepare.c ec4989f7f480544bdc4192fe663470d2a2d7d61e F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 @@ -182,14 +182,14 @@ F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8 -F src/sqlite.h.in 557f4113a649f15d13e566aaa85820509b4daa52 +F src/sqlite.h.in a9d9b247a5e1a203bc24154fdfe8fad49978faa1 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h f412e020e1009163c74be56eaac1bf7f6c0a4515 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c de581e2e71f5e7f98366156afad83b4742ac6fe0 -F src/test1.c 0f41b7c67719207a5de24b009e172c4dcf189827 +F src/test1.c 348de9657e874bff49b99dcd7307074b6feaf456 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7 @@ -678,6 +678,7 @@ F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 +F test/shrink.test 28165922bfea5c003c51a2d02bce69c4141ef013 F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329 F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test c16709a16ad79fa43b32929b2e623d1d117ccf53 @@ -975,7 +976,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P a5418c7fc216a30abf7b2fa8c579aee586393a91 9f839ac05a9f3cfe587d2ccdccd50dac41baedbe -R e41a73511b92616ee76fa30eb271c907 +P 457513f21f2438c61b1a214716e338a4e3eeaafa +R 2aefebff3180a54a438215134f3a783d U drh -Z e97a12a6137cafdd18edeb6857a80579 +Z 6faa593abe3d90439929fe507a12385d diff --git a/manifest.uuid b/manifest.uuid index eb4dd66704..f09b57bd77 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -457513f21f2438c61b1a214716e338a4e3eeaafa \ No newline at end of file +3f58e7c8895d1252eff56282c08b1a6f1194452c \ No newline at end of file diff --git a/src/main.c b/src/main.c index 27dacac1b2..edca152903 100644 --- a/src/main.c +++ b/src/main.c @@ -530,6 +530,24 @@ sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){ return db->mutex; } +/* +** Free up as much memory as we can from the given database +** connection. +*/ +int sqlite3_db_release_memory(sqlite3 *db){ + int i; + sqlite3BtreeEnterAll(db); + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + Pager *pPager = sqlite3BtreePager(pBt); + sqlite3PagerShrink(pPager); + } + } + sqlite3BtreeLeaveAll(db); + return SQLITE_OK; +} + /* ** Configuration settings for an individual database connection */ diff --git a/src/pager.c b/src/pager.c index 6900610b20..f3069e52ba 100644 --- a/src/pager.c +++ b/src/pager.c @@ -3294,6 +3294,13 @@ void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){ sqlite3PcacheSetCachesize(pPager->pPCache, mxPage); } +/* +** Free as much memory as possible from the pager. +*/ +void sqlite3PagerShrink(Pager *pPager){ + sqlite3PcacheShrink(pPager->pPCache); +} + /* ** Adjust the robustness of the database to damage due to OS crashes ** or power failures by changing the number of syncs()s when writing diff --git a/src/pager.h b/src/pager.h index e36e6c2e86..f68b19f6eb 100644 --- a/src/pager.h +++ b/src/pager.h @@ -103,6 +103,7 @@ void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *); int sqlite3PagerSetPagesize(Pager*, u32*, int); int sqlite3PagerMaxPageCount(Pager*, int); void sqlite3PagerSetCachesize(Pager*, int); +void sqlite3PagerShrink(Pager*); void sqlite3PagerSetSafetyLevel(Pager*,int,int,int); int sqlite3PagerLockingMode(Pager *, int); int sqlite3PagerSetJournalMode(Pager *, int); diff --git a/src/pcache.c b/src/pcache.c index a504633919..0c3e9ee0a2 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -595,6 +595,15 @@ void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ } } +/* +** Free up as much memory as possible from the page cache. +*/ +void sqlite3PcacheShrink(PCache *pCache){ + if( pCache->pCache ){ + sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache); + } +} + #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) /* ** For all dirty pages currently in the cache, invoke the specified diff --git a/src/pcache.h b/src/pcache.h index c4a25b251f..82543dbc30 100644 --- a/src/pcache.h +++ b/src/pcache.h @@ -142,6 +142,9 @@ void sqlite3PcacheSetCachesize(PCache *, int); int sqlite3PcacheGetCachesize(PCache *); #endif +/* Free up as much memory as possible from the page cache */ +void sqlite3PcacheShrink(PCache*); + #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* Try to return memory used by the pcache module to the main memory heap */ int sqlite3PcacheReleaseMemory(int); diff --git a/src/pcache1.c b/src/pcache1.c index 35bdda8a9a..505941a3a7 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -227,8 +227,9 @@ static void *pcache1Alloc(int nByte){ /* ** Free an allocated buffer obtained from pcache1Alloc(). */ -static void pcache1Free(void *p){ - if( p==0 ) return; +static int pcache1Free(void *p){ + int nFreed = 0; + if( p==0 ) return 0; if( p>=pcache1.pStart && pbPurgeable ){ + PGroup *pGroup = pCache->pGroup; + int savedMaxPage; + pcache1EnterMutex(pGroup); + savedMaxPage = pGroup->nMaxPage; + pGroup->nMaxPage = 0; + pcache1EnforceMaxPage(pGroup); + pGroup->nMaxPage = savedMaxPage; + pcache1LeaveMutex(pGroup); + } +} + /* ** Implementation of the sqlite3_pcache.xPagecount method. */ @@ -935,7 +955,8 @@ void sqlite3PCacheSetDefault(void){ pcache1Unpin, /* xUnpin */ pcache1Rekey, /* xRekey */ pcache1Truncate, /* xTruncate */ - pcache1Destroy /* xDestroy */ + pcache1Destroy, /* xDestroy */ + pcache1Shrink /* xShrink */ }; sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods); } diff --git a/src/pragma.c b/src/pragma.c index 538aa61083..bfdcb2370a 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1438,6 +1438,16 @@ void sqlite3Pragma( }else #endif + /* + ** PRAGMA shrink_memory + ** + ** This pragma attempts to free as much memory as possible from the + ** current database connection. + */ + if( sqlite3StrICmp(zLeft, "shrink_memory")==0 ){ + sqlite3_db_release_memory(db); + }else + #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) /* ** Report the current state of file logs for all databases diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 27c2b75db3..dc193c6daf 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4529,9 +4529,24 @@ int sqlite3_enable_shared_cache(int); ** which might be more or less than the amount requested. ** ^The sqlite3_release_memory() routine is a no-op returning zero ** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT]. +** +** See also: [sqlite3_db_release_memory()] */ int sqlite3_release_memory(int); +/* +** CAPI3REF: Free Memory Used By A Database Connection +** +** ^The sqlite3_db_shrink(D) interface attempts to free as much heap +** memory as possible from database connection D. Unlike the +** [sqlite3_release_memory()] interface, this interface is effect even +** when then [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is +** omitted. +** +** See also: [sqlite3_release_memory()] +*/ +int sqlite3_db_release_memory(sqlite3*); + /* ** CAPI3REF: Impose A Limit On Heap Size ** @@ -6106,6 +6121,12 @@ struct sqlite3_pcache_page { ** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*] ** handle invalid, and will not use it with any other sqlite3_pcache_methods ** functions. +** +** [[the xShrink() page cache method]] +** ^SQLite invokes the xShrink() method when it wants the page cache to +** free up as much of heap memory as possible. The page cache implementation +** is not obligated to free any memory, but well-behaved implementions should +** do their best. */ typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; struct sqlite3_pcache_methods2 { @@ -6122,6 +6143,7 @@ struct sqlite3_pcache_methods2 { unsigned oldKey, unsigned newKey); void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); void (*xDestroy)(sqlite3_pcache*); + void (*xShrink)(sqlite3_pcache*); }; /* diff --git a/src/test1.c b/src/test1.c index 26342522c5..9cd54e4561 100644 --- a/src/test1.c +++ b/src/test1.c @@ -4593,6 +4593,31 @@ static int test_release_memory( return TCL_OK; } + +/* +** Usage: sqlite3_db_release_memory DB +** +** Attempt to release memory currently held by database DB. Return the +** result code (which in the current implementation is always zero). +*/ +static int test_db_release_memory( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3 *db; + int rc; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + rc = sqlite3_db_release_memory(db); + Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); + return TCL_OK; +} + /* ** Usage: sqlite3_soft_heap_limit ?N? ** @@ -5915,6 +5940,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "uses_stmt_journal", uses_stmt_journal ,0 }, { "sqlite3_release_memory", test_release_memory, 0}, + { "sqlite3_db_release_memory", test_db_release_memory, 0}, { "sqlite3_soft_heap_limit", test_soft_heap_limit, 0}, { "sqlite3_thread_cleanup", test_thread_cleanup, 0}, { "sqlite3_pager_refcounts", test_pager_refcounts, 0}, diff --git a/test/shrink.test b/test/shrink.test new file mode 100644 index 0000000000..cc055c63b5 --- /dev/null +++ b/test/shrink.test @@ -0,0 +1,42 @@ +# 2011 November 16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains test cases for sqlite3_db_release_memory and +# the PRAGMA shrink_memory statement. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +unset -nocomplain baseline +do_test shrink-1.1 { + db eval { + CREATE TABLE t1(x,y); + INSERT INTO t1 VALUES(randomblob(1000000),1); + } + set ::baseline sqlite3_memory_used + sqlite3_db_release_memory db + expr {$::baseline > [sqlite3_memory_used]+500000} +} {1} +do_test shrink-1.2 { + set baseline [sqlite3_memory_used] + db eval { + UPDATE t1 SET y=y+1; + } + expr {$::baseline+500000 < [sqlite3_memory_used]} +} {1} +do_test shrink-1.3 { + set baseline [sqlite3_memory_used] + db eval {PRAGMA shrink_memory} + expr {$::baseline > [sqlite3_memory_used]+500000} +} {1} + +finish_test From 283829cb2022d2a0c0e193b9b1d574f374f0948b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Nov 2011 00:56:20 +0000 Subject: [PATCH 039/161] Add the sqlite3_db_filename() interface. FossilOrigin-Name: 93a947989b57959aacc37007a143fdf3921793ab --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/main.c | 14 ++++++++++++++ src/sqlite.h.in | 11 +++++++++++ src/test1.c | 24 ++++++++++++++++++++++++ test/attach.test | 19 +++++++++++++++++++ 6 files changed, 78 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 67fa8c4f42..cb7ea23d33 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Back\sout\sthe\s[ceee03c79a]\schange. -D 2011-11-16T23:29:37.606 +C Add\sthe\ssqlite3_db_filename()\sinterface. +D 2011-11-17T00:56:20.474 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f -F src/main.c 3acbdf6f8b93093bd7f96bdfd7f88bab95a5cd7a +F src/main.c 55cbc40465fb58708cb82d4a285a6ea8cf1e4581 F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 7456e2ca0524609ebc06a9befeda5289d4575ad4 @@ -182,14 +182,14 @@ F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8 -F src/sqlite.h.in a9d9b247a5e1a203bc24154fdfe8fad49978faa1 +F src/sqlite.h.in acd5715227b060010729b86c11c9a3882f818ec9 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h f412e020e1009163c74be56eaac1bf7f6c0a4515 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c de581e2e71f5e7f98366156afad83b4742ac6fe0 -F src/test1.c 348de9657e874bff49b99dcd7307074b6feaf456 +F src/test1.c a445a5d09f63ca66a704720dbec240c65806bcd1 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7 @@ -274,7 +274,7 @@ F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7 F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a F test/async5.test 0dd8701bd588bf6e70c2557a22ae3f22b2567b4c -F test/attach.test 0e6f8de2589f11a5f474ef57fe5af2877e61c0e8 +F test/attach.test 0d112b7713611fdf0340260192749737135fda5f F test/attach2.test e54436ed956d3d88bdee61221da59bf3935a0966 F test/attach3.test d89ccfe4fe6e2b5e368d480fcdfe4b496c54cf4e F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c @@ -976,7 +976,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 3f58e7c8895d1252eff56282c08b1a6f1194452c 1bbbf8574a820c5f787a937f02a8e2a91264ace0 -R 8e7cbea058ef7fa5fd72b3406095ff67 +P 69ec53fc1c60b07bf4aaa983dcd5bf3164fb1ea5 +R 99f71d23f57bbcc6e05ddde9985c021b U drh -Z e301581f8f88dd3a374b15753c08fc01 +Z aa529bb687e7c2c3b8e94ee609022d00 diff --git a/manifest.uuid b/manifest.uuid index 485d59ac9c..3f50082423 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -69ec53fc1c60b07bf4aaa983dcd5bf3164fb1ea5 \ No newline at end of file +93a947989b57959aacc37007a143fdf3921793ab \ No newline at end of file diff --git a/src/main.c b/src/main.c index edca152903..43cd82eaa6 100644 --- a/src/main.c +++ b/src/main.c @@ -2970,3 +2970,17 @@ const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){ } return 0; } + +/* +** Return the filename of the database associated with a database +** connection. +*/ +const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){ + int i; + for(i=0; inDb; i++){ + if( db->aDb[i].pBt && sqlite3StrICmp(zDbName, db->aDb[i].zName)==0 ){ + return sqlite3BtreeGetFilename(db->aDb[i].pBt); + } + } + return 0; +} diff --git a/src/sqlite.h.in b/src/sqlite.h.in index dc193c6daf..f70893a3db 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4373,6 +4373,17 @@ int sqlite3_get_autocommit(sqlite3*); */ sqlite3 *sqlite3_db_handle(sqlite3_stmt*); +/* +** CAPI3REF: Return The Filename For A Database Connection +** +** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename +** associated with database N of connection D. ^The main database file +** has the name "main". If there is no attached database N on the database +** connection D, or if database N is a temporary or in-memory database, then +** a NULL pointer is returned. +*/ +const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); + /* ** CAPI3REF: Find the next prepared statement ** diff --git a/src/test1.c b/src/test1.c index 9cd54e4561..3cf9b1375e 100644 --- a/src/test1.c +++ b/src/test1.c @@ -4618,6 +4618,29 @@ static int test_db_release_memory( return TCL_OK; } +/* +** Usage: sqlite3_db_filename DB DBNAME +** +** Return the name of a file associated with a database. +*/ +static int test_db_filename( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3 *db; + const char *zDbName; + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + zDbName = Tcl_GetString(objv[2]); + Tcl_AppendResult(interp, sqlite3_db_filename(db, zDbName), (void*)0); + return TCL_OK; +} + /* ** Usage: sqlite3_soft_heap_limit ?N? ** @@ -5941,6 +5964,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_release_memory", test_release_memory, 0}, { "sqlite3_db_release_memory", test_db_release_memory, 0}, + { "sqlite3_db_filename", test_db_filename, 0}, { "sqlite3_soft_heap_limit", test_soft_heap_limit, 0}, { "sqlite3_thread_cleanup", test_thread_cleanup, 0}, { "sqlite3_pager_refcounts", test_pager_refcounts, 0}, diff --git a/test/attach.test b/test/attach.test index d57f5bfb52..be5f9881c3 100644 --- a/test/attach.test +++ b/test/attach.test @@ -51,6 +51,25 @@ do_test attach-1.3 { SELECT * FROM two.t2; } } {1 x 2 y} + +# Tests for the sqlite3_db_filename interface +# +do_test attach-1.3.1 { + file tail [sqlite3_db_filename db main] +} {test.db} +do_test attach-1.3.2 { + file tail [sqlite3_db_filename db MAIN] +} {test.db} +do_test attach-1.3.3 { + file tail [sqlite3_db_filename db temp] +} {} +do_test attach-1.3.4 { + file tail [sqlite3_db_filename db two] +} {test2.db} +do_test attach-1.3.5 { + file tail [sqlite3_db_filename db three] +} {} + do_test attach-1.4 { execsql { SELECT * FROM t2; From 070ad6b6fee996e639fd31e5189c8319407e343f Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Nov 2011 11:43:19 +0000 Subject: [PATCH 040/161] Restore the test for sqlite3OsFullPathname() failure that was mistakenly removed when [ceee03c79a] was backed out by [69ec53fc1c]. FossilOrigin-Name: 4d3cf9e1d8ac356db5a708913f614e42a6a56b94 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 7 ++++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index cb7ea23d33..59cb7955f8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3_db_filename()\sinterface. -D 2011-11-17T00:56:20.474 +C Restore\sthe\stest\sfor\ssqlite3OsFullPathname()\sfailure\sthat\swas\smistakenly\s\nremoved\swhen\s[ceee03c79a]\swas\sbacked\sout\sby\s[69ec53fc1c]. +D 2011-11-17T11:43:19.664 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -125,7 +125,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 4368158da74d4711888e03264105c5c527d76caf F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 2521a74f04cf288497af3b318fa3a31efb272ef6 +F src/btree.c 80ea65224512884bb72976c93810d2dcaecc1353 F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h ea863a819224d3e6845ad1e39954d41558b8cd8b F src/build.c 8915bb6d72ead998f94c2756ea8d143c77709b70 @@ -976,7 +976,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 69ec53fc1c60b07bf4aaa983dcd5bf3164fb1ea5 -R 99f71d23f57bbcc6e05ddde9985c021b +P 93a947989b57959aacc37007a143fdf3921793ab +R 332ce6cc33326de9806334bfc2a7be92 U drh -Z aa529bb687e7c2c3b8e94ee609022d00 +Z 85dd2759b5a8c1b6d06bef9bf12e7a1b diff --git a/manifest.uuid b/manifest.uuid index 3f50082423..20c7bfea32 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -93a947989b57959aacc37007a143fdf3921793ab \ No newline at end of file +4d3cf9e1d8ac356db5a708913f614e42a6a56b94 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a1b05e1f3e..713016e756 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1776,7 +1776,12 @@ int sqlite3BtreeOpen( sqlite3_free(p); return SQLITE_NOMEM; } - sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); + rc = sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); + if( rc ){ + sqlite3_free(zFullPathname); + sqlite3_free(p); + return rc; + } #if SQLITE_THREADSAFE mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN); sqlite3_mutex_enter(mutexOpen); From 21495ba8a3d6079f55379eefbf8ed0567c51187c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Nov 2011 11:49:58 +0000 Subject: [PATCH 041/161] Improvements to the documentation of the sqlite3_db_filename() interface. FossilOrigin-Name: 1c45b2a0c055f6fc5da9d00ae2e9171099d904d4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 5 +++++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 59cb7955f8..aa26307489 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Restore\sthe\stest\sfor\ssqlite3OsFullPathname()\sfailure\sthat\swas\smistakenly\s\nremoved\swhen\s[ceee03c79a]\swas\sbacked\sout\sby\s[69ec53fc1c]. -D 2011-11-17T11:43:19.664 +C Improvements\sto\sthe\sdocumentation\sof\sthe\ssqlite3_db_filename()\sinterface. +D 2011-11-17T11:49:58.484 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -182,7 +182,7 @@ F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8 -F src/sqlite.h.in acd5715227b060010729b86c11c9a3882f818ec9 +F src/sqlite.h.in 19706a000717456c4963bb0f96262581436ffb5a F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h f412e020e1009163c74be56eaac1bf7f6c0a4515 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -976,7 +976,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 93a947989b57959aacc37007a143fdf3921793ab -R 332ce6cc33326de9806334bfc2a7be92 +P 4d3cf9e1d8ac356db5a708913f614e42a6a56b94 +R daa1b38027d3a49fc0c491c85b1f5a39 U drh -Z 85dd2759b5a8c1b6d06bef9bf12e7a1b +Z f65f1ce31dbae92bc408999ba5cab4af diff --git a/manifest.uuid b/manifest.uuid index 20c7bfea32..261f1cf6ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4d3cf9e1d8ac356db5a708913f614e42a6a56b94 \ No newline at end of file +1c45b2a0c055f6fc5da9d00ae2e9171099d904d4 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index f70893a3db..75241da42d 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4381,6 +4381,11 @@ sqlite3 *sqlite3_db_handle(sqlite3_stmt*); ** has the name "main". If there is no attached database N on the database ** connection D, or if database N is a temporary or in-memory database, then ** a NULL pointer is returned. +** +** ^The filename returned by this function is the output of the +** xFullPathname method of the [VFS]. ^In other words, the filename +** will be an absolute pathname, even if the filename used +** to open the database originally was a URI or relative pathname. */ const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); From d1ef9b6da105a27d42a500beb3a44484bb58a85d Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 21 Nov 2011 00:54:37 +0000 Subject: [PATCH 042/161] Cleanup the semantics surrounding use of the GetLastError function on Windows. FossilOrigin-Name: 7e657bbb800107c992a6ee7a3b35bc0a073bf3e4 --- manifest | 17 +++++++----- manifest.uuid | 2 +- src/os_win.c | 71 ++++++++++++++++++++++++++++++--------------------- 3 files changed, 53 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index bf28f8bbf8..d104ec1889 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\smultiplexor\sto\suse\sa\s3-digit\ssuffix. -D 2011-11-18T13:10:51.946 +C Cleanup\sthe\ssemantics\ssurrounding\suse\sof\sthe\sGetLastError\sfunction\son\sWindows. +D 2011-11-21T00:54:37.897 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -167,7 +167,7 @@ F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 4fbb91726165e105c1679a2660f49a3f4c376e4f -F src/os_win.c a22b88d2c088c09a678a471abafa8d60dbf56803 +F src/os_win.c 6efe66a38215c38eaa7603ee5f76848159f8669d F src/pager.c d981f3bfcc0e4460537d983899620700ccf8f539 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 @@ -976,7 +976,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 1c45b2a0c055f6fc5da9d00ae2e9171099d904d4 06e0cdaf9112f722c23692e25c5b1f99b61c2d78 -R d62e550a3406a1fdeec14ac20b144781 -U drh -Z d184ad6817e342a5dbefa36cc13c5962 +P 0b7edc44757660c8a5ae3b91cbcc3e6afd419b28 +R 99aff9fc0229e676974ede97756eda75 +T *branch * winGetLastError +T *sym-winGetLastError * +T -sym-trunk * +U mistachkin +Z 7ff767419ae0d15068d14c36ad0bea1d diff --git a/manifest.uuid b/manifest.uuid index deaed3cb30..5343d856e0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0b7edc44757660c8a5ae3b91cbcc3e6afd419b28 \ No newline at end of file +7e657bbb800107c992a6ee7a3b35bc0a073bf3e4 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 62868ba504..7e89a8cc02 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -1170,12 +1170,14 @@ static int win32IoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; ** to see if it should be retried. Return TRUE to retry. Return FALSE ** to give up with an error. */ -static int retryIoerr(int *pnRetry){ - DWORD e; +static int retryIoerr(int *pnRetry, DWORD *pError){ + DWORD e = osGetLastError(); if( *pnRetry>=win32IoerrRetry ){ + if( pError ){ + *pError = e; + } return 0; } - e = osGetLastError(); if( e==ERROR_ACCESS_DENIED || e==ERROR_LOCK_VIOLATION || e==ERROR_SHARING_VIOLATION ){ @@ -1183,6 +1185,9 @@ static int retryIoerr(int *pnRetry){ ++*pnRetry; return 1; } + if( pError ){ + *pError = e; + } return 0; } @@ -1539,6 +1544,7 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){ LONG upperBits; /* Most sig. 32 bits of new offset */ LONG lowerBits; /* Least sig. 32 bits of new offset */ DWORD dwRet; /* Value returned by SetFilePointer() */ + DWORD lastErrno; /* Value returned by GetLastError() */ upperBits = (LONG)((iOffset>>32) & 0x7fffffff); lowerBits = (LONG)(iOffset & 0xffffffff); @@ -1551,8 +1557,10 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){ ** GetLastError(). */ dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); - if( (dwRet==INVALID_SET_FILE_POINTER && osGetLastError()!=NO_ERROR) ){ - pFile->lastErrno = osGetLastError(); + + if( (dwRet==INVALID_SET_FILE_POINTER + && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ + pFile->lastErrno = lastErrno; winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, "seekWinFile", pFile->zPath); return 1; @@ -1628,8 +1636,9 @@ static int winRead( return SQLITE_FULL; } while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ - if( retryIoerr(&nRetry) ) continue; - pFile->lastErrno = osGetLastError(); + DWORD lastErrno; + if( retryIoerr(&nRetry, &lastErrno) ) continue; + pFile->lastErrno = lastErrno; return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, "winRead", pFile->zPath); } @@ -1669,10 +1678,11 @@ static int winWrite( u8 *aRem = (u8 *)pBuf; /* Data yet to be written */ int nRem = amt; /* Number of bytes yet to be written */ DWORD nWrite; /* Bytes written by each WriteFile() call */ + DWORD lastErrno = NO_ERROR; /* Value returned by GetLastError() */ while( nRem>0 ){ if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ - if( retryIoerr(&nRetry) ) continue; + if( retryIoerr(&nRetry, &lastErrno) ) continue; break; } if( nWrite<=0 ) break; @@ -1680,7 +1690,7 @@ static int winWrite( nRem -= nWrite; } if( nRem>0 ){ - pFile->lastErrno = osGetLastError(); + pFile->lastErrno = lastErrno; rc = 1; } } @@ -1810,15 +1820,15 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ DWORD upperBits; DWORD lowerBits; winFile *pFile = (winFile*)id; - DWORD error; + DWORD lastErrno; assert( id!=0 ); SimulateIOError(return SQLITE_IOERR_FSTAT); lowerBits = osGetFileSize(pFile->h, &upperBits); if( (lowerBits == INVALID_FILE_SIZE) - && ((error = osGetLastError()) != NO_ERROR) ) + && ((lastErrno = osGetLastError())!=NO_ERROR) ) { - pFile->lastErrno = error; + pFile->lastErrno = lastErrno; return winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, "winFileSize", pFile->zPath); } @@ -1869,6 +1879,7 @@ static int getReadLock(winFile *pFile){ */ static int unlockReadLock(winFile *pFile){ int res; + DWORD lastErrno; if( isNT() ){ res = osUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. @@ -1878,8 +1889,8 @@ static int unlockReadLock(winFile *pFile){ res = osUnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0); #endif } - if( res==0 && osGetLastError()!=ERROR_NOT_LOCKED ){ - pFile->lastErrno = osGetLastError(); + if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ + pFile->lastErrno = lastErrno; winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, "unlockReadLock", pFile->zPath); } @@ -1918,7 +1929,7 @@ static int winLock(sqlite3_file *id, int locktype){ int newLocktype; /* Set pFile->locktype to this value before exiting */ int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ winFile *pFile = (winFile*)id; - DWORD error = NO_ERROR; + DWORD lastErrno = NO_ERROR; assert( id!=0 ); OSTRACE(("LOCK %d %d was %d(%d)\n", @@ -1960,7 +1971,7 @@ static int winLock(sqlite3_file *id, int locktype){ } gotPendingLock = res; if( !res ){ - error = osGetLastError(); + lastErrno = osGetLastError(); } } @@ -1972,7 +1983,7 @@ static int winLock(sqlite3_file *id, int locktype){ if( res ){ newLocktype = SHARED_LOCK; }else{ - error = osGetLastError(); + lastErrno = osGetLastError(); } } @@ -1984,7 +1995,7 @@ static int winLock(sqlite3_file *id, int locktype){ if( res ){ newLocktype = RESERVED_LOCK; }else{ - error = osGetLastError(); + lastErrno = osGetLastError(); } } @@ -2005,8 +2016,8 @@ static int winLock(sqlite3_file *id, int locktype){ if( res ){ newLocktype = EXCLUSIVE_LOCK; }else{ - error = osGetLastError(); - OSTRACE(("error-code = %d\n", error)); + lastErrno = osGetLastError(); + OSTRACE(("error-code = %d\n", lastErrno)); getReadLock(pFile); } } @@ -2026,7 +2037,7 @@ static int winLock(sqlite3_file *id, int locktype){ }else{ OSTRACE(("LOCK FAILED %d trying for %d but got %d\n", pFile->h, locktype, newLocktype)); - pFile->lastErrno = error; + pFile->lastErrno = lastErrno; rc = SQLITE_BUSY; } pFile->locktype = (u8)newLocktype; @@ -2964,6 +2975,7 @@ static int winOpen( int *pOutFlags /* Status return flags */ ){ HANDLE h; + DWORD lastErrno; DWORD dwDesiredAccess; DWORD dwShareMode; DWORD dwCreationDisposition; @@ -3100,7 +3112,7 @@ static int winOpen( dwCreationDisposition, dwFlagsAndAttributes, NULL))==INVALID_HANDLE_VALUE && - retryIoerr(&cnt) ){} + retryIoerr(&cnt, &lastErrno) ){} /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ANSI version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. @@ -3113,7 +3125,7 @@ static int winOpen( dwCreationDisposition, dwFlagsAndAttributes, NULL))==INVALID_HANDLE_VALUE && - retryIoerr(&cnt) ){} + retryIoerr(&cnt, &lastErrno) ){} #endif } @@ -3124,7 +3136,7 @@ static int winOpen( h==INVALID_HANDLE_VALUE ? "failed" : "ok")); if( h==INVALID_HANDLE_VALUE ){ - pFile->lastErrno = osGetLastError(); + pFile->lastErrno = lastErrno; winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); sqlite3_free(zConverted); if( isReadWrite && !isExclusive ){ @@ -3191,6 +3203,7 @@ static int winDelete( ){ int cnt = 0; int rc; + DWORD lastErrno; void *zConverted; UNUSED_PARAMETER(pVfs); UNUSED_PARAMETER(syncDir); @@ -3203,7 +3216,7 @@ static int winDelete( if( isNT() ){ rc = 1; while( osGetFileAttributesW(zConverted)!=INVALID_FILE_ATTRIBUTES && - (rc = osDeleteFileW(zConverted))==0 && retryIoerr(&cnt) ){} + (rc = osDeleteFileW(zConverted))==0 && retryIoerr(&cnt, &lastErrno) ){} rc = rc ? SQLITE_OK : SQLITE_ERROR; /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ANSI version of these Windows API do not exist for WINCE, @@ -3213,12 +3226,12 @@ static int winDelete( }else{ rc = 1; while( osGetFileAttributesA(zConverted)!=INVALID_FILE_ATTRIBUTES && - (rc = osDeleteFileA(zConverted))==0 && retryIoerr(&cnt) ){} + (rc = osDeleteFileA(zConverted))==0 && retryIoerr(&cnt, &lastErrno) ){} rc = rc ? SQLITE_OK : SQLITE_ERROR; #endif } if( rc ){ - rc = winLogError(SQLITE_IOERR_DELETE, osGetLastError(), + rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename); }else{ logIoerr(cnt); @@ -3239,6 +3252,7 @@ static int winAccess( ){ DWORD attr; int rc = 0; + DWORD lastErrno; void *zConverted; UNUSED_PARAMETER(pVfs); @@ -3253,7 +3267,7 @@ static int winAccess( memset(&sAttrData, 0, sizeof(sAttrData)); while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, GetFileExInfoStandard, - &sAttrData)) && retryIoerr(&cnt) ){} + &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){} if( rc ){ /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file ** as if it does not exist. @@ -3266,7 +3280,6 @@ static int winAccess( attr = sAttrData.dwFileAttributes; } }else{ - DWORD lastErrno = osGetLastError(); logIoerr(cnt); if( lastErrno!=ERROR_FILE_NOT_FOUND ){ winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename); From 2fb6693e02d4d029e4332fe631a08353a5f527d6 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Nov 2011 17:21:47 +0000 Subject: [PATCH 043/161] Add the sqlite3_stmt_busy() interface. FossilOrigin-Name: 95cc4af686dc9bf85cb7224aecde27c9ca14ad5c --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/sqlite.h.in | 19 +++++++++++++++++++ src/test1.c | 28 ++++++++++++++++++++++++++++ src/vdbeapi.c | 8 ++++++++ test/capi3d.test | 26 +++++++++++++++++++++++++- 6 files changed, 90 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index bf28f8bbf8..9b86d8f20e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\smultiplexor\sto\suse\sa\s3-digit\ssuffix. -D 2011-11-18T13:10:51.946 +C Add\sthe\ssqlite3_stmt_busy()\sinterface. +D 2011-11-25T17:21:47.094 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -182,14 +182,14 @@ F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8 -F src/sqlite.h.in 19706a000717456c4963bb0f96262581436ffb5a +F src/sqlite.h.in ef5e1d1e25e5f3512ebb659975bc53840fe6ebf2 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h f412e020e1009163c74be56eaac1bf7f6c0a4515 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c de581e2e71f5e7f98366156afad83b4742ac6fe0 -F src/test1.c a445a5d09f63ca66a704720dbec240c65806bcd1 +F src/test1.c fe455fc1be1b0dbf4ce45b11c255900e8ae18da3 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7 @@ -242,7 +242,7 @@ F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa F src/vdbe.c a7ab9993ec5a4d9479dc99671faec061fbf9b889 F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755 F src/vdbeInt.h 9498fc98a2c9e349a4ef13455ff5a3e898f40176 -F src/vdbeapi.c 4dbba7f94f127f6ea8d2d0505ee1f98e5ffbf546 +F src/vdbeapi.c 86189ebba2c49791d75eaa12929f3ce6527596bd F src/vdbeaux.c 45713a5f8f4f36195f503b30153ddef292323f88 F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 @@ -315,7 +315,7 @@ F test/capi2.test 835d4cee9f542ea50fa8d01f3fe6de80b0627360 F test/capi3.test 7200dff6acb17b9a4b6f9918f554eaae04968ddd F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 F test/capi3c.test ccf0acf045dbacd09f6229aa4efed670aaba76a9 -F test/capi3d.test cd36571f014f34bdc4421967f6453cbb597d5d16 +F test/capi3d.test 17b57ca28be3e37e14c2ba8f787d292d84b724a1 F test/capi3e.test f7408dda65c92b9056199fdc180f893015f83dde F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 F test/check.test db2b29d557544347d28e25b8406f5d5ecc3d1bc3 @@ -976,7 +976,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 1c45b2a0c055f6fc5da9d00ae2e9171099d904d4 06e0cdaf9112f722c23692e25c5b1f99b61c2d78 -R d62e550a3406a1fdeec14ac20b144781 +P 0b7edc44757660c8a5ae3b91cbcc3e6afd419b28 +R 45cf62e5f6b60da1dccab28df3542630 U drh -Z d184ad6817e342a5dbefa36cc13c5962 +Z 09847bc32a30bed5dba534d9bd527061 diff --git a/manifest.uuid b/manifest.uuid index deaed3cb30..b5dd2ef433 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0b7edc44757660c8a5ae3b91cbcc3e6afd419b28 \ No newline at end of file +95cc4af686dc9bf85cb7224aecde27c9ca14ad5c \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 75241da42d..f34fb438f8 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2932,6 +2932,25 @@ const char *sqlite3_sql(sqlite3_stmt *pStmt); */ int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); +/* +** CAPI3REF: Determine If A Prepared Statement Has Been Reset +** +** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the +** [prepared statement] S has been stepped at least once using +** [sqlite3_step(S)] but has not run to completion and/or has not +** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S) +** interface returns false if S is a NULL pointer. If S is not a +** NULL pointer and is not a pointer to a valid [prepared statement] +** object, then the behavior is undefined and probably undesirable. +** +** This interface can be used in combination [sqlite3_stmt_next()] +** to locate all prepared statements associated with a database +** connection that are in need of being reset. This can be used, +** for example, in diagnostic routines to search for prepared +** statements that are holding a transaction open. +*/ +int sqlite3_stmt_busy(sqlite3_stmt*); + /* ** CAPI3REF: Dynamically Typed Value Object ** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value} diff --git a/src/test1.c b/src/test1.c index 3cf9b1375e..cf388d244b 100644 --- a/src/test1.c +++ b/src/test1.c @@ -2330,6 +2330,33 @@ static int test_stmt_readonly( return TCL_OK; } +/* +** Usage: sqlite3_stmt_busy STMT +** +** Return true if STMT is a non-NULL pointer to a statement +** that has been stepped but not to completion. +*/ +static int test_stmt_busy( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3_stmt *pStmt; + int rc; + + if( objc!=2 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_GetStringFromObj(objv[0], 0), " STMT", 0); + return TCL_ERROR; + } + + if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; + rc = sqlite3_stmt_busy(pStmt); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc)); + return TCL_OK; +} + /* ** Usage: uses_stmt_journal STMT ** @@ -5960,6 +5987,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_sql", test_sql ,0 }, { "sqlite3_next_stmt", test_next_stmt ,0 }, { "sqlite3_stmt_readonly", test_stmt_readonly ,0 }, + { "sqlite3_stmt_busy", test_stmt_busy ,0 }, { "uses_stmt_journal", uses_stmt_journal ,0 }, { "sqlite3_release_memory", test_release_memory, 0}, diff --git a/src/vdbeapi.c b/src/vdbeapi.c index adc9dba2f1..c6c54854f3 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1277,6 +1277,14 @@ int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){ return pStmt ? ((Vdbe*)pStmt)->readOnly : 1; } +/* +** Return true if the prepared statement is in need of being reset. +*/ +int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ + Vdbe *v = (Vdbe*)pStmt; + return v!=0 && v->pc>0 && v->magic==VDBE_MAGIC_RUN; +} + /* ** Return a pointer to the next prepared statement after pStmt associated ** with database connection pDb. If pStmt is NULL, return the first diff --git a/test/capi3d.test b/test/capi3d.test index 49e64476eb..746ec20b25 100644 --- a/test/capi3d.test +++ b/test/capi3d.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. # # This file is devoted to testing the sqlite3_next_stmt and -# sqlite3_stmt_readonly interfaces. +# sqlite3_stmt_readonly and sqlite3_stmt_busy interfaces. # # $Id: capi3d.test,v 1.2 2008/07/14 15:11:20 drh Exp $ # @@ -112,5 +112,29 @@ do_test capi3-2.99 { sqlite3_stmt_readonly 0 } 1 +# Tests for sqlite3_stmt_busy +# +do_test capi3d-3.1 { + db eval {INSERT INTO t1 VALUES(6); INSERT INTO t1 VALUES(7);} + set STMT [sqlite3_prepare db {SELECT * FROM t1} -1 TAIL] + sqlite3_stmt_busy $STMT +} {0} +do_test capi3d-3.2 { + sqlite3_step $STMT + sqlite3_stmt_busy $STMT +} {1} +do_test capi3d-3.3 { + sqlite3_step $STMT + sqlite3_stmt_busy $STMT +} {1} +do_test capi3d-3.4 { + sqlite3_reset $STMT + sqlite3_stmt_busy $STMT +} {0} + +do_test capi3d-3.99 { + sqlite3_finalize $STMT + sqlite3_stmt_busy 0 +} {0} finish_test From 814d6a7ba720808f7e0882e99c22e0dee4bfe7d2 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Nov 2011 17:51:52 +0000 Subject: [PATCH 044/161] Fix a typo in the documentation for sqlite3_stmt_busy(). FossilOrigin-Name: 7812626d1da1e19f2fc54a045c9fe2741ce68699 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9b86d8f20e..339e401bfe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3_stmt_busy()\sinterface. -D 2011-11-25T17:21:47.094 +C Fix\sa\stypo\sin\sthe\sdocumentation\sfor\ssqlite3_stmt_busy(). +D 2011-11-25T17:51:52.008 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -182,7 +182,7 @@ F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8 -F src/sqlite.h.in ef5e1d1e25e5f3512ebb659975bc53840fe6ebf2 +F src/sqlite.h.in 57081d8e6b53ce29541d7437c93bce6087ac53b5 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h f412e020e1009163c74be56eaac1bf7f6c0a4515 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -976,7 +976,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 0b7edc44757660c8a5ae3b91cbcc3e6afd419b28 -R 45cf62e5f6b60da1dccab28df3542630 +P 95cc4af686dc9bf85cb7224aecde27c9ca14ad5c +R db79d71dc43fe99dbb583145bbcb11d9 U drh -Z 09847bc32a30bed5dba534d9bd527061 +Z 288334a5a07994861eca34b0137225ec diff --git a/manifest.uuid b/manifest.uuid index b5dd2ef433..6263e2df34 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -95cc4af686dc9bf85cb7224aecde27c9ca14ad5c \ No newline at end of file +7812626d1da1e19f2fc54a045c9fe2741ce68699 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index f34fb438f8..bd5b41f431 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2943,7 +2943,7 @@ int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); ** NULL pointer and is not a pointer to a valid [prepared statement] ** object, then the behavior is undefined and probably undesirable. ** -** This interface can be used in combination [sqlite3_stmt_next()] +** This interface can be used in combination [sqlite3_next_stmt()] ** to locate all prepared statements associated with a database ** connection that are in need of being reset. This can be used, ** for example, in diagnostic routines to search for prepared From 5c0c56b89cb3d6ef1f610bb182dd8ca7c82c763d Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Nov 2011 21:51:03 +0000 Subject: [PATCH 045/161] Update the version number to 3.7.10. FossilOrigin-Name: ed0151ba8379a6c95304c9a8f9fe47e741fb80a3 --- VERSION | 2 +- configure | 18 +++++++++--------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/VERSION b/VERSION index c77a7de85c..f06fb9e915 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.7.9 +3.7.10 diff --git a/configure b/configure index 14ff675064..87b6a84109 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for sqlite 3.7.9. +# Generated by GNU Autoconf 2.68 for sqlite 3.7.10. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -706,8 +706,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.7.9' -PACKAGE_STRING='sqlite 3.7.9' +PACKAGE_VERSION='3.7.10' +PACKAGE_STRING='sqlite 3.7.10' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1440,7 +1440,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sqlite 3.7.9 to adapt to many kinds of systems. +\`configure' configures sqlite 3.7.10 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1505,7 +1505,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.7.9:";; + short | recursive ) echo "Configuration of sqlite 3.7.10:";; esac cat <<\_ACEOF @@ -1622,7 +1622,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.7.9 +sqlite configure 3.7.10 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -2041,7 +2041,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sqlite $as_me 3.7.9, which was +It was created by sqlite $as_me 3.7.10, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -11868,7 +11868,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sqlite $as_me 3.7.9, which was +This file was extended by sqlite $as_me 3.7.10, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -11934,7 +11934,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sqlite config.status 3.7.9 +sqlite config.status 3.7.10 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/manifest b/manifest index 339e401bfe..03c902a004 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ -C Fix\sa\stypo\sin\sthe\sdocumentation\sfor\ssqlite3_stmt_busy(). -D 2011-11-25T17:51:52.008 +C Update\sthe\sversion\snumber\sto\s3.7.10. +D 2011-11-25T21:51:03.023 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.msc 3bd3641a345d488a9601c0cc7f9d35aeede5d12b F Makefile.vxworks 1deb39c8bb047296c30161ffa10c1b5423e632f9 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 -F VERSION bb37c274b503bbe73f00ea4f374eb817cba4b171 +F VERSION af03cd6400f9d71d38bdb7a9d66a1aefdc2f3e0d F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531 F art/2005osaward.gif 0d1851b2a7c1c9d0ccce545f3e14bca42d7fd248 @@ -23,7 +23,7 @@ F art/src_logo.gif 9341ef09f0e53cd44c0c9b6fc3c16f7f3d6c2ad9 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 31cc8c4943f56e60c4aa4fba929c9d4c70e418b4 F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure 194ed7797c67c24ebbeb001fcfc557116fe5eba9 x +F configure cdfb8a907ded1f8e75b6967e3e3bd35718884aff x F configure.ac 75323bdac56fb0e69f6a3fc5b23f24359550b9d9 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html 3091574143dd3415669b6745843ff8d011d33549 @@ -976,7 +976,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 95cc4af686dc9bf85cb7224aecde27c9ca14ad5c -R db79d71dc43fe99dbb583145bbcb11d9 +P 7812626d1da1e19f2fc54a045c9fe2741ce68699 +R 00de12829df3386707d38924a0593a4d U drh -Z 288334a5a07994861eca34b0137225ec +Z e0beeb659ff8b012da42c86c4be4154a diff --git a/manifest.uuid b/manifest.uuid index 6263e2df34..5c71f750ee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7812626d1da1e19f2fc54a045c9fe2741ce68699 \ No newline at end of file +ed0151ba8379a6c95304c9a8f9fe47e741fb80a3 \ No newline at end of file From 4dd65e0f0cdde2ff2ea3f8eea71c1f91e2c189e7 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 29 Nov 2011 14:46:56 +0000 Subject: [PATCH 046/161] Removed the unused "type" field from the CollSeq (collating sequence) object. FossilOrigin-Name: ab89b047e82efdf59ed91a38b5195341a3743cbf --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/main.c | 23 ++++++++--------------- src/sqliteInt.h | 9 --------- 4 files changed, 16 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index 03c902a004..57f6d38fc4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sversion\snumber\sto\s3.7.10. -D 2011-11-25T21:51:03.023 +C Removed\sthe\sunused\s"type"\sfield\sfrom\sthe\sCollSeq\s(collating\ssequence)\sobject. +D 2011-11-29T14:46:56.791 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f -F src/main.c 55cbc40465fb58708cb82d4a285a6ea8cf1e4581 +F src/main.c 8be1ee70dd90ef7562c801dbe946a4f9f93bb128 F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 7456e2ca0524609ebc06a9befeda5289d4575ad4 @@ -184,7 +184,7 @@ F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8 F src/sqlite.h.in 57081d8e6b53ce29541d7437c93bce6087ac53b5 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h f412e020e1009163c74be56eaac1bf7f6c0a4515 +F src/sqliteInt.h f49fb4fdcbb771f0b20b0b19f5590bab1dcfbf0d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -976,7 +976,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 7812626d1da1e19f2fc54a045c9fe2741ce68699 -R 00de12829df3386707d38924a0593a4d +P ed0151ba8379a6c95304c9a8f9fe47e741fb80a3 +R 13b41fa72e4f9a2a4e116535aca5d91c U drh -Z e0beeb659ff8b012da42c86c4be4154a +Z 68de038f6dc2b2eb4d0dfd2d0418c9e2 diff --git a/manifest.uuid b/manifest.uuid index 5c71f750ee..33713fc17c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ed0151ba8379a6c95304c9a8f9fe47e741fb80a3 \ No newline at end of file +ab89b047e82efdf59ed91a38b5195341a3743cbf \ No newline at end of file diff --git a/src/main.c b/src/main.c index 43cd82eaa6..8562a90727 100644 --- a/src/main.c +++ b/src/main.c @@ -1655,7 +1655,6 @@ static int createCollation( sqlite3* db, const char *zName, u8 enc, - u8 collType, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*), void(*xDel)(void*) @@ -1720,7 +1719,6 @@ static int createCollation( pColl->pUser = pCtx; pColl->xDel = xDel; pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED)); - pColl->type = collType; sqlite3Error(db, SQLITE_OK, 0); return SQLITE_OK; } @@ -2181,14 +2179,10 @@ static int openDatabase( ** and UTF-16, so add a version for each to avoid any unnecessary ** conversions. The only error that can occur here is a malloc() failure. */ - createCollation(db, "BINARY", SQLITE_UTF8, SQLITE_COLL_BINARY, 0, - binCollFunc, 0); - createCollation(db, "BINARY", SQLITE_UTF16BE, SQLITE_COLL_BINARY, 0, - binCollFunc, 0); - createCollation(db, "BINARY", SQLITE_UTF16LE, SQLITE_COLL_BINARY, 0, - binCollFunc, 0); - createCollation(db, "RTRIM", SQLITE_UTF8, SQLITE_COLL_USER, (void*)1, - binCollFunc, 0); + createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0); + createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0); + createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0); + createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0); if( db->mallocFailed ){ goto opendb_out; } @@ -2196,8 +2190,7 @@ static int openDatabase( assert( db->pDfltColl!=0 ); /* Also add a UTF-8 case-insensitive collation sequence. */ - createCollation(db, "NOCASE", SQLITE_UTF8, SQLITE_COLL_NOCASE, 0, - nocaseCollatingFunc, 0); + createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0); /* Parse the filename/URI argument. */ db->openFlags = flags; @@ -2390,7 +2383,7 @@ int sqlite3_create_collation( int rc; sqlite3_mutex_enter(db->mutex); assert( !db->mallocFailed ); - rc = createCollation(db, zName, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0); + rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, 0); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; @@ -2410,7 +2403,7 @@ int sqlite3_create_collation_v2( int rc; sqlite3_mutex_enter(db->mutex); assert( !db->mallocFailed ); - rc = createCollation(db, zName, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, xDel); + rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xDel); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; @@ -2433,7 +2426,7 @@ int sqlite3_create_collation16( assert( !db->mallocFailed ); zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE); if( zName8 ){ - rc = createCollation(db, zName8, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0); + rc = createCollation(db, zName8, (u8)enc, pCtx, xCompare, 0); sqlite3DbFree(db, zName8); } rc = sqlite3ApiExit(db, rc); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 663b805b04..48884aa85f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1144,20 +1144,11 @@ struct Column { struct CollSeq { char *zName; /* Name of the collating sequence, UTF-8 encoded */ u8 enc; /* Text encoding handled by xCmp() */ - u8 type; /* One of the SQLITE_COLL_... values below */ void *pUser; /* First argument to xCmp() */ int (*xCmp)(void*,int, const void*, int, const void*); void (*xDel)(void*); /* Destructor for pUser */ }; -/* -** Allowed values of CollSeq.type: -*/ -#define SQLITE_COLL_BINARY 1 /* The default memcmp() collating sequence */ -#define SQLITE_COLL_NOCASE 2 /* The built-in NOCASE collating sequence */ -#define SQLITE_COLL_REVERSE 3 /* The built-in REVERSE collating sequence */ -#define SQLITE_COLL_USER 0 /* Any other user-defined collating sequence */ - /* ** A sort order can be either ASC or DESC. */ From 76a3acaceabe44df8a403fc4ae1e1cfd62a108f0 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 29 Nov 2011 15:04:12 +0000 Subject: [PATCH 047/161] Remove unused boolean fields from the UnpackedRecord object. FossilOrigin-Name: b10d091ec02e94643e865743129e2a21147b3136 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 10 ++++------ 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 57f6d38fc4..ebb20702cf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Removed\sthe\sunused\s"type"\sfield\sfrom\sthe\sCollSeq\s(collating\ssequence)\sobject. -D 2011-11-29T14:46:56.791 +C Remove\sunused\sboolean\sfields\sfrom\sthe\sUnpackedRecord\sobject. +D 2011-11-29T15:04:12.252 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -184,7 +184,7 @@ F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8 F src/sqlite.h.in 57081d8e6b53ce29541d7437c93bce6087ac53b5 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h f49fb4fdcbb771f0b20b0b19f5590bab1dcfbf0d +F src/sqliteInt.h bbc4c0b01e3499a9d30750c91718217c26688afb F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -976,7 +976,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P ed0151ba8379a6c95304c9a8f9fe47e741fb80a3 -R 13b41fa72e4f9a2a4e116535aca5d91c +P ab89b047e82efdf59ed91a38b5195341a3743cbf +R beca209612bf2507bfd744deef578dc8 U drh -Z 68de038f6dc2b2eb4d0dfd2d0418c9e2 +Z 97f245e9e22cbbc849b128b1b8b18545 diff --git a/manifest.uuid b/manifest.uuid index 33713fc17c..269eaa8b60 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ab89b047e82efdf59ed91a38b5195341a3743cbf \ No newline at end of file +b10d091ec02e94643e865743129e2a21147b3136 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 48884aa85f..856e878628 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1434,7 +1434,7 @@ struct KeyInfo { struct UnpackedRecord { KeyInfo *pKeyInfo; /* Collation and sort-order information */ u16 nField; /* Number of entries in apMem[] */ - u16 flags; /* Boolean settings. UNPACKED_... below */ + u8 flags; /* Boolean settings. UNPACKED_... below */ i64 rowid; /* Used by UNPACKED_PREFIX_SEARCH */ Mem *aMem; /* Values */ }; @@ -1442,11 +1442,9 @@ struct UnpackedRecord { /* ** Allowed values of UnpackedRecord.flags */ -#define UNPACKED_NEED_FREE 0x0001 /* Memory is from sqlite3Malloc() */ -#define UNPACKED_NEED_DESTROY 0x0002 /* apMem[]s should all be destroyed */ -#define UNPACKED_INCRKEY 0x0008 /* Make this key an epsilon larger */ -#define UNPACKED_PREFIX_MATCH 0x0010 /* A prefix match is considered OK */ -#define UNPACKED_PREFIX_SEARCH 0x0020 /* A prefix match is considered OK */ +#define UNPACKED_INCRKEY 0x01 /* Make this key an epsilon larger */ +#define UNPACKED_PREFIX_MATCH 0x02 /* A prefix match is considered OK */ +#define UNPACKED_PREFIX_SEARCH 0x04 /* Ignore final (rowid) field */ /* ** Each SQL index is represented in memory by an From d4e244ad5676359d33e657bc7b6910ba357db6c8 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 29 Nov 2011 15:40:32 +0000 Subject: [PATCH 048/161] Remove unused fields from the Parse object. Documentation and formatting improvements on data structure definitions. FossilOrigin-Name: 431556cac0b2c86d7f6a60412ff1023feeaafedf --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/delete.c | 1 - src/parse.y | 2 -- src/sqliteInt.h | 21 +++++++++------------ 5 files changed, 18 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index ebb20702cf..ef7ae4ea60 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunused\sboolean\sfields\sfrom\sthe\sUnpackedRecord\sobject. -D 2011-11-29T15:04:12.252 +C Remove\sunused\sfields\sfrom\sthe\sParse\sobject.\s\sDocumentation\sand\sformatting\nimprovements\son\sdata\sstructure\sdefinitions. +D 2011-11-29T15:40:32.491 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -133,7 +133,7 @@ F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 -F src/delete.c ff68e5ef23aee08c0ff528f699a19397ed8bbed8 +F src/delete.c 51d32f0a9c880663e54ce309f52e40c325d5e112 F src/expr.c fbf116f90cabc917ae50bba24a73a0b55519a0c8 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5 @@ -170,7 +170,7 @@ F src/os_unix.c 4fbb91726165e105c1679a2660f49a3f4c376e4f F src/os_win.c a22b88d2c088c09a678a471abafa8d60dbf56803 F src/pager.c d981f3bfcc0e4460537d983899620700ccf8f539 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 -F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 +F src/parse.y d02cc7bdb9ba11fb7aa212f55f99e59e4ee55439 F src/pcache.c 1fdd77978c1525d1ca4b9ef48eb80abca710cb4c F src/pcache.h b1d8775a9bddf44e65edb0d20bfc57a4982f840f F src/pcache1.c 9d735349ac87ef08076c6b1230f04cd83b15c6da @@ -184,7 +184,7 @@ F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8 F src/sqlite.h.in 57081d8e6b53ce29541d7437c93bce6087ac53b5 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h bbc4c0b01e3499a9d30750c91718217c26688afb +F src/sqliteInt.h 6f28b69d77356b1e45c024a6c103a1e0f0ec9f62 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -976,7 +976,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P ab89b047e82efdf59ed91a38b5195341a3743cbf -R beca209612bf2507bfd744deef578dc8 +P b10d091ec02e94643e865743129e2a21147b3136 +R 7d0a9d11e01c28eaf1d831b1553005fb U drh -Z 97f245e9e22cbbc849b128b1b8b18545 +Z fa710425b85d2a4b5e2c971fb970b087 diff --git a/manifest.uuid b/manifest.uuid index 269eaa8b60..b014af186d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b10d091ec02e94643e865743129e2a21147b3136 \ No newline at end of file +431556cac0b2c86d7f6a60412ff1023feeaafedf \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 147a5ca898..f666b90c83 100644 --- a/src/delete.c +++ b/src/delete.c @@ -148,7 +148,6 @@ Expr *sqlite3LimitWhere( */ if( pOrderBy && (pLimit == 0) ) { sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType); - pParse->parseError = 1; goto limit_where_cleanup_2; } diff --git a/src/parse.y b/src/parse.y index 92abd5ce58..b838215d42 100644 --- a/src/parse.y +++ b/src/parse.y @@ -33,12 +33,10 @@ UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */ assert( TOKEN.z[0] ); /* The tokenizer always gives us a token */ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); - pParse->parseError = 1; } %stack_overflow { UNUSED_PARAMETER(yypMinor); /* Silence some compiler warnings */ sqlite3ErrorMsg(pParse, "parser stack overflow"); - pParse->parseError = 1; } // The name of the generated procedure that implements the parser diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 856e878628..4e00ad03c1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2072,13 +2072,13 @@ struct Select { ** Allowed values for Select.selFlags. The "SF" prefix stands for ** "Select Flag". */ -#define SF_Distinct 0x0001 /* Output should be DISTINCT */ -#define SF_Resolved 0x0002 /* Identifiers have been resolved */ -#define SF_Aggregate 0x0004 /* Contains aggregate functions */ -#define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ -#define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ -#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ -#define SF_UseSorter 0x0040 /* Sort using a sorter */ +#define SF_Distinct 0x01 /* Output should be DISTINCT */ +#define SF_Resolved 0x02 /* Identifiers have been resolved */ +#define SF_Aggregate 0x04 /* Contains aggregate functions */ +#define SF_UsesEphemeral 0x08 /* Uses the OpenEphemeral opcode */ +#define SF_Expanded 0x10 /* sqlite3SelectExpand() called on this */ +#define SF_HasTypeInfo 0x20 /* FROM subqueries have Table metadata */ +#define SF_UseSorter 0x40 /* Sort using a sorter */ /* @@ -2193,10 +2193,8 @@ struct Parse { char *zErrMsg; /* An error message */ Vdbe *pVdbe; /* An engine for executing database bytecode */ u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */ - u8 nameClash; /* A permanent table name clashes with temp table name */ u8 checkSchema; /* Causes schema cookie check after an error */ u8 nested; /* Number of nested calls to the parser/code generator */ - u8 parseError; /* True after a parsing error. Ticket #1794 */ u8 nTempReg; /* Number of temporary registers in aTempReg[] */ u8 nTempInUse; /* Number of aTempReg[] currently checked out */ int aTempReg[8]; /* Holding area for temporary registers */ @@ -2209,8 +2207,8 @@ struct Parse { int ckBase; /* Base register of data during check constraints */ int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */ int iCacheCnt; /* Counter used to generate aColCache[].lru values */ - u8 nColCache; /* Number of entries in the column cache */ - u8 iColCache; /* Next entry of the cache to replace */ + u8 nColCache; /* Number of entries in aColCache[] */ + u8 iColCache; /* Next entry in aColCache[] to replace */ struct yColCache { int iTable; /* Table cursor number */ int iColumn; /* Table column number */ @@ -2252,7 +2250,6 @@ struct Parse { 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[] */ int *aAlias; /* Register used to hold aliased result */ u8 explain; /* True if the EXPLAIN flag is found on the query */ Token sNameToken; /* Token with unqualified schema object name */ From 60f21e4b6ee9964bd08ff65b4896adf6e39b36f9 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Dec 2011 18:44:21 +0000 Subject: [PATCH 049/161] Add stdio-like I/O interfaces to the test_quota VFS. This is a prototype change for discussion and is mostly untested. This is an alternative to adding stdio-like I/O interfaces in the core. There is no guarantee that this code will make it into the trunk. If it does get to trunk, there could be many changes to the interface first. FossilOrigin-Name: bd3ce723f1b5be52be46ede8614ca316f56e7e6f --- manifest | 16 ++-- manifest.uuid | 2 +- src/test_quota.c | 206 ++++++++++++++++++++++++++++++++++++++++++----- src/test_quota.h | 158 ++++++++++++++++++++++++++++++++++++ 4 files changed, 354 insertions(+), 28 deletions(-) create mode 100644 src/test_quota.h diff --git a/manifest b/manifest index ef7ae4ea60..cade689e9a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunused\sfields\sfrom\sthe\sParse\sobject.\s\sDocumentation\sand\sformatting\nimprovements\son\sdata\sstructure\sdefinitions. -D 2011-11-29T15:40:32.491 +C Add\sstdio-like\sI/O\sinterfaces\sto\sthe\stest_quota\sVFS.\s\sThis\sis\sa\sprototype\nchange\sfor\sdiscussion\sand\sis\smostly\suntested.\s\sThis\sis\san\salternative\sto\nadding\sstdio-like\sI/O\sinterfaces\sin\sthe\score.\s\sThere\sis\sno\sguarantee\sthat\nthis\scode\swill\smake\sit\sinto\sthe\strunk.\s\sIf\sit\sdoes\sget\sto\strunk,\sthere\ncould\sbe\smany\schanges\sto\sthe\sinterface\sfirst. +D 2011-12-01T18:44:21.630 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,8 @@ F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 -F src/test_quota.c a391c866217e92986c6f523f05b08aa6956c8419 +F src/test_quota.c f3ed8e130fff8e824a320a80668cfaffd6cb55ff +F src/test_quota.h 118dba604ae5b6903acdd40d2b94a1f319047612 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f @@ -976,7 +977,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P b10d091ec02e94643e865743129e2a21147b3136 -R 7d0a9d11e01c28eaf1d831b1553005fb +P 431556cac0b2c86d7f6a60412ff1023feeaafedf +R e31672c1519f90c43111109b685a8ffb +T *branch * quota-stdio +T *sym-quota-stdio * +T -sym-trunk * U drh -Z fa710425b85d2a4b5e2c971fb970b087 +Z 0283eb6e7b14cfb0e1559cbc303ec8df diff --git a/manifest.uuid b/manifest.uuid index b014af186d..f43d772bdb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -431556cac0b2c86d7f6a60412ff1023feeaafedf \ No newline at end of file +bd3ce723f1b5be52be46ede8614ca316f56e7e6f \ No newline at end of file diff --git a/src/test_quota.c b/src/test_quota.c index 74d1a6d3ba..1866e79986 100644 --- a/src/test_quota.c +++ b/src/test_quota.c @@ -27,7 +27,7 @@ ** files within the group is less than the new quota, then the write ** continues as if nothing had happened. */ -#include "sqlite3.h" +#include "test_quota.h" #include #include @@ -111,6 +111,18 @@ struct quotaConn { /* The underlying VFS sqlite3_file is appended to this object */ }; +/* +** An instance of the following object records the state of an +** open file. This object is opaque to all users - the internal +** structure is only visible to the functions below. +*/ +struct quota_FILE { + FILE *f; /* Open stdio file pointer */ + sqlite3_int64 iOfst; /* Current offset into the file */ + quotaFile *pFile; /* The file record in the quota system */ +}; + + /************************* Global Variables **********************************/ /* ** All global variables used by this file are containing within the following @@ -313,11 +325,29 @@ static sqlite3_file *quotaSubOpen(sqlite3_file *pConn){ /* Find a file in a quota group and return a pointer to that file. ** Return NULL if the file is not in the group. */ -static quotaFile *quotaFindFile(quotaGroup *pGroup, const char *zName){ +static quotaFile *quotaFindFile( + quotaGroup *pGroup, /* Group in which to look for the file */ + const char *zName, /* Full pathname of the file */ + int createFlag /* Try to create the file if not found */ +){ quotaFile *pFile = pGroup->pFiles; while( pFile && strcmp(pFile->zFilename, zName)!=0 ){ pFile = pFile->pNext; } + if( pFile==0 && createFlag ){ + int nName = strlen(zName); + pFile = (quotaFile *)sqlite3_malloc( sizeof(*pFile) + nName + 1 ); + if( pFile ){ + memset(pFile, 0, sizeof(*pFile)); + pFile->zFilename = (char*)&pFile[1]; + memcpy(pFile->zFilename, zName, nName+1); + pFile->pNext = pGroup->pFiles; + if( pGroup->pFiles ) pGroup->pFiles->ppPrev = &pFile->pNext; + pFile->ppPrev = &pGroup->pFiles; + pGroup->pFiles = pFile; + pFile->pGroup = pGroup; + } + } return pFile; } @@ -364,25 +394,13 @@ static int quotaOpen( pSubOpen = quotaSubOpen(pConn); rc = pOrigVfs->xOpen(pOrigVfs, zName, pSubOpen, flags, pOutFlags); if( rc==SQLITE_OK ){ - pFile = quotaFindFile(pGroup, zName); + pFile = quotaFindFile(pGroup, zName, 1); if( pFile==0 ){ - int nName = strlen(zName); - pFile = (quotaFile *)sqlite3_malloc( sizeof(*pFile) + nName + 1 ); - if( pFile==0 ){ - quotaLeave(); - pSubOpen->pMethods->xClose(pSubOpen); - return SQLITE_NOMEM; - } - memset(pFile, 0, sizeof(*pFile)); - pFile->zFilename = (char*)&pFile[1]; - memcpy(pFile->zFilename, zName, nName+1); - pFile->pNext = pGroup->pFiles; - if( pGroup->pFiles ) pGroup->pFiles->ppPrev = &pFile->pNext; - pFile->ppPrev = &pGroup->pFiles; - pGroup->pFiles = pFile; - pFile->pGroup = pGroup; - pFile->deleteOnClose = (flags & SQLITE_OPEN_DELETEONCLOSE)!=0; + quotaLeave(); + pSubOpen->pMethods->xClose(pSubOpen); + return SQLITE_NOMEM; } + pFile->deleteOnClose = (flags & SQLITE_OPEN_DELETEONCLOSE)!=0; pFile->nRef++; pQuotaOpen->pFile = pFile; if( pSubOpen->pMethods->iVersion==1 ){ @@ -423,7 +441,7 @@ static int quotaDelete( quotaEnter(); pGroup = quotaGroupFind(zName); if( pGroup ){ - pFile = quotaFindFile(pGroup, zName); + pFile = quotaFindFile(pGroup, zName, 0); if( pFile ){ if( pFile->nRef ){ pFile->deleteOnClose = 1; @@ -823,7 +841,7 @@ int sqlite3_quota_file(const char *zFilename){ quotaEnter(); pGroup = quotaGroupFind(zFull); if( pGroup ){ - pFile = quotaFindFile(pGroup, zFull); + pFile = quotaFindFile(pGroup, zFull, 0); if( pFile ) quotaRemoveFile(pFile); } quotaLeave(); @@ -832,6 +850,152 @@ int sqlite3_quota_file(const char *zFilename){ return rc; } +/* +** Open a potentially quotaed file for I/O. +*/ +quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode){ + quota_FILE *p = 0; + char *zFull = 0; + int rc; + quotaGroup *pGroup; + quotaFile *pFile; + + p = sqlite3_malloc(gQuota.sThisVfs.mxPathname + 1); + if( p==0 ) return 0; + zFull = (char*)&p[1]; + rc = gQuota.pOrigVfs->xFullPathname(gQuota.pOrigVfs, zFilename, + gQuota.sThisVfs.mxPathname+1, zFull); + if( rc ) goto quota_fopen_error; + p = sqlite3_malloc(sizeof(*p)); + if( p==0 ) goto quota_fopen_error; + memset(p, 0, sizeof(*p)); + p->f = fopen(zFull, zMode); + if( p->f==0 ) goto quota_fopen_error; + quotaEnter(); + pGroup = quotaGroupFind(zFull); + if( pGroup ){ + pFile = quotaFindFile(pGroup, zFull, 1); + if( pFile==0 ){ + quotaLeave(); + goto quota_fopen_error; + } + pFile->nRef++; + p->pFile = pFile; + } + quotaLeave(); + sqlite3_free(zFull); + return p; + +quota_fopen_error: + sqlite3_free(zFull); + if( p && p->f ) fclose(p->f); + sqlite3_free(p); + return 0; +} + +/* +** Read content from a quota_FILE +*/ +size_t sqlite3_quota_fread( + void *pBuf, /* Store the content here */ + size_t size, /* Size of each element */ + size_t nmemb, /* Number of elements to read */ + quota_FILE *p /* Read from this quota_FILE object */ +){ + return fread(pBuf, size, nmemb, p->f); +} + +/* +** Write content into a quota_FILE. Invoke the quota callback and block +** the write if we exceed quota. +*/ +size_t sqlite3_quota_fwrite( + void *pBuf, /* Take content to write from here */ + size_t size, /* Size of each element */ + size_t nmemb, /* Number of elements */ + quota_FILE *p /* Write to this quota_FILE objecct */ +){ + sqlite3_int64 iOfst; + sqlite3_int64 iEnd; + sqlite3_int64 szNew; + quotaFile *pFile; + + iOfst = ftell(p->f); + iEnd = iOfst + size*nmemb; + pFile = p->pFile; + if( pFile->iSizepGroup; + quotaEnter(); + szNew = pGroup->iSize - pFile->iSize + iEnd; + if( szNew>pGroup->iLimit && pGroup->iLimit>0 ){ + if( pGroup->xCallback ){ + pGroup->xCallback(pFile->zFilename, &pGroup->iLimit, szNew, + pGroup->pArg); + } + if( szNew>pGroup->iLimit && pGroup->iLimit>0 ){ + iEnd = pGroup->iLimit - pGroup->iSize + pFile->iSize; + nmemb = (iEnd - iOfst)/size; + iEnd = iOfst + size*nmemb; + szNew = pGroup->iSize - pFile->iSize + iEnd; + } + } + pGroup->iSize = szNew; + pFile->iSize = iEnd; + quotaLeave(); + } + return fwrite(pBuf, size, nmemb, p->f); +} + +/* +** Close an open quota_FILE stream. +*/ +int sqlite3_quota_fclose(quota_FILE *p){ + int rc; + quotaFile *pFile; + rc = fclose(p->f); + pFile = p->pFile; + quotaEnter(); + pFile->nRef--; + if( pFile->nRef==0 ){ + quotaGroup *pGroup = pFile->pGroup; + if( pFile->deleteOnClose ) quotaRemoveFile(pFile); + quotaGroupDeref(pGroup); + } + quotaLeave(); + sqlite3_free(p); + return rc; +} + +/* +** Seek on a quota_FILE stream. +*/ +int sqlite3_quota_fseek(quota_FILE *p, long offset, int whence){ + return fseek(p->f, offset, whence); +} + +/* +** rewind a quota_FILE stream. +*/ +void sqlite3_quota_rewind(quota_FILE *p){ + rewind(p->f); +} + +/* +** Tell the current location of a quota_FILE stream. +*/ +long sqlite3_quota_ftell(quota_FILE *p){ + return ftell(p->f); +} + +/* +** Remove a file. Update quotas accordingly. +*/ +int sqlite3_quota_remove(const char *zFilename){ + int rc = remove(zFilename); + sqlite3_quota_file(zFilename); + return rc; +} + /***************************** Test Code ***********************************/ #ifdef SQLITE_TEST diff --git a/src/test_quota.h b/src/test_quota.h new file mode 100644 index 0000000000..df78e7eb71 --- /dev/null +++ b/src/test_quota.h @@ -0,0 +1,158 @@ +/* +** 2011 December 1 +** +** 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 the interface definition for the quota a VFS shim. +** +** This particular shim enforces a quota system on files. One or more +** database files are in a "quota group" that is defined by a GLOB +** pattern. A quota is set for the combined size of all files in the +** the group. A quota of zero means "no limit". If the total size +** of all files in the quota group is greater than the limit, then +** write requests that attempt to enlarge a file fail with SQLITE_FULL. +** +** However, before returning SQLITE_FULL, the write requests invoke +** a callback function that is configurable for each quota group. +** This callback has the opportunity to enlarge the quota. If the +** callback does enlarge the quota such that the total size of all +** files within the group is less than the new quota, then the write +** continues as if nothing had happened. +*/ +#ifndef _QUOTA_H_ +#include "sqlite3.h" +#include + +/* +** Initialize the quota VFS shim. Use the VFS named zOrigVfsName +** as the VFS that does the actual work. Use the default if +** zOrigVfsName==NULL. +** +** The quota VFS shim is named "quota". It will become the default +** VFS if makeDefault is non-zero. +** +** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once +** during start-up. +*/ +int sqlite3_quota_initialize(const char *zOrigVfsName, int makeDefault); + +/* +** Shutdown the quota system. +** +** All SQLite database connections must be closed before calling this +** routine. +** +** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once while +** shutting down in order to free all remaining quota groups. +*/ +int sqlite3_quota_shutdown(void); + +/* +** Create or destroy a quota group. +** +** The quota group is defined by the zPattern. When calling this routine +** with a zPattern for a quota group that already exists, this routine +** merely updates the iLimit, xCallback, and pArg values for that quota +** group. If zPattern is new, then a new quota group is created. +** +** The zPattern is always compared against the full pathname of the file. +** Even if APIs are called with relative pathnames, SQLite converts the +** name to a full pathname before comparing it against zPattern. zPattern +** is a standard glob pattern with the following matching rules: +** +** '*' Matches any sequence of zero or more characters. +** +** '?' Matches exactly one character. +** +** [...] Matches one character from the enclosed list of +** characters. +** +** [^...] Matches one character not in the enclosed list. +** +** Note that, unlike unix shell globbing, the directory separator "/" +** can match a wildcard. So, for example, the pattern "/abc/xyz/" "*" +** matches any files anywhere in the directory hierarchy beneath +** /abc/xyz +** +** If the iLimit for a quota group is set to zero, then the quota group +** is disabled and will be deleted when the last database connection using +** the quota group is closed. +** +** Calling this routine on a zPattern that does not exist and with a +** zero iLimit is a no-op. +** +** A quota group must exist with a non-zero iLimit prior to opening +** database connections if those connections are to participate in the +** quota group. Creating a quota group does not affect database connections +** that are already open. +*/ +int sqlite3_quota_set( + const char *zPattern, /* The filename pattern */ + sqlite3_int64 iLimit, /* New quota to set for this quota group */ + void (*xCallback)( /* Callback invoked when going over quota */ + const char *zFilename, /* Name of file whose size increases */ + sqlite3_int64 *piLimit, /* IN/OUT: The current limit */ + sqlite3_int64 iSize, /* Total size of all files in the group */ + void *pArg /* Client data */ + ), + void *pArg, /* client data passed thru to callback */ + void (*xDestroy)(void*) /* Optional destructor for pArg */ +); + +/* +** Bring the named file under quota management. Or if it is already under +** management, update its size. +*/ +int sqlite3_quota_file(const char *zFilename); + +/* +** The following object serves the same role as FILE in the standard C +** library. It represents an open connection to a file on disk for I/O. +*/ +typedef struct quota_FILE quota_FILE; + +/* +** Create a new quota_FILE object used to read and/or write to the +** file zFilename. The zMode parameter is as with standard library zMode. +*/ +quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode); + +/* +** Perform I/O against a quota_FILE object. When doing writes, the +** quota mechanism may result in a short write, in order to prevent +** the sum of sizes of all files from going over quota. +*/ +size_t sqlite3_quota_fread(void*, size_t, size_t, quota_FILE*); +size_t sqlite3_quota_fwrite(void*, size_t, size_t, quota_FILE*); + +/* +** Close a quota_FILE object and free all associated resources. The +** file remains under quota management. +*/ +int sqlite3_quota_fclose(quota_FILE*); + +/* +** Move the read/write pointer for a quota_FILE object. Or tell the +** current location of the read/write pointer. +*/ +int sqlite3_quota_fseek(quota_FILE*, long, int); +void sqlite3_quota_rewind(quota_FILE*); +long sqlite3_quota_ftell(quota_FILE*); + +/* +** Delete a file from the disk. If that file is under quota management, +** then adjust quotas accordingly. +** +** The file being deleted must not be open for reading or writing or as +** a database when it is deleted. +*/ +int sqlite3_quota_remove(const char *zFilename); + +#endif /* _QUOTA_H_ */ From a76e85891777d1ff9b76103b1aa5ffc324e5d30c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Dec 2011 20:48:15 +0000 Subject: [PATCH 050/161] Add test logic and some test cases. FossilOrigin-Name: a4730586cc1f686ead956ccd1cc218b5931942c9 --- manifest | 18 ++- manifest.uuid | 2 +- src/test_quota.c | 319 +++++++++++++++++++++++++++++++++++++++++++++-- test/quota.test | 1 + test/quota2.test | 114 +++++++++++++++++ 5 files changed, 435 insertions(+), 19 deletions(-) create mode 100644 test/quota2.test diff --git a/manifest b/manifest index cade689e9a..f025539657 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sstdio-like\sI/O\sinterfaces\sto\sthe\stest_quota\sVFS.\s\sThis\sis\sa\sprototype\nchange\sfor\sdiscussion\sand\sis\smostly\suntested.\s\sThis\sis\san\salternative\sto\nadding\sstdio-like\sI/O\sinterfaces\sin\sthe\score.\s\sThere\sis\sno\sguarantee\sthat\nthis\scode\swill\smake\sit\sinto\sthe\strunk.\s\sIf\sit\sdoes\sget\sto\strunk,\sthere\ncould\sbe\smany\schanges\sto\sthe\sinterface\sfirst. -D 2011-12-01T18:44:21.630 +C Add\stest\slogic\sand\ssome\stest\scases. +D 2011-12-01T20:48:15.803 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 -F src/test_quota.c f3ed8e130fff8e824a320a80668cfaffd6cb55ff +F src/test_quota.c ed68398661b398f0ce213349eb1cac6b5c39f62e F src/test_quota.h 118dba604ae5b6903acdd40d2b94a1f319047612 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 @@ -634,7 +634,8 @@ F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 -F test/quota.test 1c59a396e8f7b5d8466fa74b59f2aeb778d74f7a +F test/quota.test 46e6571b45c3c58ac131cc38f7d600aa9f75974d +F test/quota2.test 1372a399adcecc423396f51faec5de44ae236019 F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6 F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test 1084050991e9ba22c1c10edd8d84673b501cc25a @@ -977,10 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 431556cac0b2c86d7f6a60412ff1023feeaafedf -R e31672c1519f90c43111109b685a8ffb -T *branch * quota-stdio -T *sym-quota-stdio * -T -sym-trunk * +P bd3ce723f1b5be52be46ede8614ca316f56e7e6f +R 137abcb878bf12767e2fb107dd20a728 U drh -Z 0283eb6e7b14cfb0e1559cbc303ec8df +Z 363de760bad75051e8a4f47a97fcd11d diff --git a/manifest.uuid b/manifest.uuid index f43d772bdb..c735789a39 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd3ce723f1b5be52be46ede8614ca316f56e7e6f \ No newline at end of file +a4730586cc1f686ead956ccd1cc218b5931942c9 \ No newline at end of file diff --git a/src/test_quota.c b/src/test_quota.c index 1866e79986..d435f88558 100644 --- a/src/test_quota.c +++ b/src/test_quota.c @@ -237,6 +237,8 @@ static void quotaGroupDeref(quotaGroup *pGroup){ ** ** [^...] Matches one character not in the enclosed list. ** +** / Matches "/" or "\\" +** */ static int quotaStrglob(const char *zGlob, const char *z){ int c, c2; @@ -295,6 +297,9 @@ static int quotaStrglob(const char *zGlob, const char *z){ c2 = *(zGlob++); } if( c2==0 || (seen ^ invert)==0 ) return 0; + }else if( c=='/' ){ + if( z[0]!='/' && z[0]!='\\' ) return 0; + z++; }else{ if( c!=(*(z++)) ) return 0; } @@ -351,6 +356,79 @@ static quotaFile *quotaFindFile( return pFile; } +/* +** Figure out if we are dealing with Unix, Windows, or some other +** operating system. After the following block of preprocess macros, +** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_OS2, and SQLITE_OS_OTHER +** will defined to either 1 or 0. One of the four will be 1. The other +** three will be 0. +*/ +#if defined(SQLITE_OS_OTHER) +# if SQLITE_OS_OTHER==1 +# undef SQLITE_OS_UNIX +# define SQLITE_OS_UNIX 0 +# undef SQLITE_OS_WIN +# define SQLITE_OS_WIN 0 +# undef SQLITE_OS_OS2 +# define SQLITE_OS_OS2 0 +# else +# undef SQLITE_OS_OTHER +# endif +#endif +#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER) +# define SQLITE_OS_OTHER 0 +# ifndef SQLITE_OS_WIN +# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) \ + || defined(__MINGW32__) || defined(__BORLANDC__) +# define SQLITE_OS_WIN 1 +# define SQLITE_OS_UNIX 0 +# define SQLITE_OS_OS2 0 +# elif defined(__EMX__) || defined(_OS2) || defined(OS2) \ + || defined(_OS2_) || defined(__OS2__) +# define SQLITE_OS_WIN 0 +# define SQLITE_OS_UNIX 0 +# define SQLITE_OS_OS2 1 +# else +# define SQLITE_OS_WIN 0 +# define SQLITE_OS_UNIX 1 +# define SQLITE_OS_OS2 0 +# endif +# else +# define SQLITE_OS_UNIX 0 +# define SQLITE_OS_OS2 0 +# endif +#else +# ifndef SQLITE_OS_WIN +# define SQLITE_OS_WIN 0 +# endif +#endif + + +/* +** Translate UTF8 to MBCS for use in fopen() calls. Return a pointer to the +** translated text.. Call quota_mbcs_free() to deallocate any memory +** used to store the returned pointer when done. +*/ +static char *quota_utf8_to_mbcs(const char *zUtf8){ +#if SQLITE_OS_WIN + extern char *sqlite3_win32_utf8_to_mbcs(const char*); + return sqlite3_win32_utf8_to_mbcs(zUtf8); +#else + return (char*)zUtf8; /* No-op on unix */ +#endif +} + +/* +** Deallocate any memory allocated by quota_utf8_to_mbcs(). +*/ +static void quota_mbcs_free(char *zOld){ +#if SQLITE_OS_WIN + free(zOld); +#else + /* No-op on unix */ +#endif +} + /************************* VFS Method Wrappers *****************************/ /* ** This is the xOpen method used for the "quota" VFS. @@ -856,20 +934,23 @@ int sqlite3_quota_file(const char *zFilename){ quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode){ quota_FILE *p = 0; char *zFull = 0; + char *zFullTranslated; int rc; quotaGroup *pGroup; quotaFile *pFile; - p = sqlite3_malloc(gQuota.sThisVfs.mxPathname + 1); - if( p==0 ) return 0; - zFull = (char*)&p[1]; + zFull = sqlite3_malloc(gQuota.sThisVfs.mxPathname + 1); + if( zFull==0 ) return 0; rc = gQuota.pOrigVfs->xFullPathname(gQuota.pOrigVfs, zFilename, gQuota.sThisVfs.mxPathname+1, zFull); if( rc ) goto quota_fopen_error; p = sqlite3_malloc(sizeof(*p)); if( p==0 ) goto quota_fopen_error; memset(p, 0, sizeof(*p)); - p->f = fopen(zFull, zMode); + zFullTranslated = quota_utf8_to_mbcs(zFull); + if( zFullTranslated==0 ) goto quota_fopen_error; + p->f = fopen(zFullTranslated, zMode); + quota_mbcs_free(zFullTranslated); if( p->f==0 ) goto quota_fopen_error; quotaEnter(); pGroup = quotaGroupFind(zFull); @@ -1242,6 +1323,220 @@ static int test_quota_dump( return TCL_OK; } +/* +** tclcmd: sqlite3_quota_fopen FILENAME MODE +*/ +static int test_quota_fopen( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + const char *zFilename; /* File pattern to configure */ + const char *zMode; /* Mode string */ + quota_FILE *p; /* Open string object */ + char zReturn[50]; /* Name of pointer to return */ + + /* Process arguments */ + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "FILENAME MODE"); + return TCL_ERROR; + } + zFilename = Tcl_GetString(objv[1]); + zMode = Tcl_GetString(objv[2]); + p = sqlite3_quota_fopen(zFilename, zMode); + sqlite3_snprintf(sizeof(zReturn), zReturn, "%p", p); + Tcl_SetResult(interp, zReturn, TCL_VOLATILE); + return TCL_OK; +} + +/* Defined in test1.c */ +extern void *sqlite3TestTextToPtr(const char*); + +/* +** tclcmd: sqlite3_quota_fread HANDLE SIZE NELEM +*/ +static int test_quota_fread( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + quota_FILE *p; + char *zBuf; + int sz; + int nElem; + int got; + + if( objc!=4 ){ + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE SIZE NELEM"); + return TCL_ERROR; + } + p = sqlite3TestTextToPtr(Tcl_GetString(objv[1])); + if( Tcl_GetIntFromObj(interp, objv[2], &sz) ) return TCL_ERROR; + if( Tcl_GetIntFromObj(interp, objv[3], &nElem) ) return TCL_ERROR; + zBuf = sqlite3_malloc( sz*nElem + 1 ); + if( zBuf==0 ){ + Tcl_SetResult(interp, "out of memory", TCL_STATIC); + return TCL_ERROR; + } + got = sqlite3_quota_fread(zBuf, sz, nElem, p); + if( got<0 ) got = 0; + zBuf[got*sz] = 0; + Tcl_SetResult(interp, zBuf, TCL_VOLATILE); + sqlite3_free(zBuf); + return TCL_OK; +} + +/* +** tclcmd: sqlite3_quota_fwrite HANDLE SIZE NELEM CONTENT +*/ +static int test_quota_fwrite( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + quota_FILE *p; + char *zBuf; + int sz; + int nElem; + int got; + + if( objc!=5 ){ + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE SIZE NELEM CONTENT"); + return TCL_ERROR; + } + p = sqlite3TestTextToPtr(Tcl_GetString(objv[1])); + if( Tcl_GetIntFromObj(interp, objv[2], &sz) ) return TCL_ERROR; + if( Tcl_GetIntFromObj(interp, objv[3], &nElem) ) return TCL_ERROR; + zBuf = Tcl_GetString(objv[4]); + got = sqlite3_quota_fwrite(zBuf, sz, nElem, p); + Tcl_SetObjResult(interp, Tcl_NewIntObj(got)); + return TCL_OK; +} + +/* +** tclcmd: sqlite3_quota_fclose HANDLE +*/ +static int test_quota_fclose( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + quota_FILE *p; + int rc; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE"); + return TCL_ERROR; + } + p = sqlite3TestTextToPtr(Tcl_GetString(objv[1])); + rc = sqlite3_quota_fclose(p); + Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); + return TCL_OK; +} + +/* +** tclcmd: sqlite3_quota_fseek HANDLE OFFSET WHENCE +*/ +static int test_quota_fseek( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + quota_FILE *p; + int ofst; + const char *zWhence; + int whence; + int rc; + + if( objc!=4 ){ + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE OFFSET WHENCE"); + return TCL_ERROR; + } + p = sqlite3TestTextToPtr(Tcl_GetString(objv[1])); + if( Tcl_GetIntFromObj(interp, objv[2], &ofst) ) return TCL_ERROR; + zWhence = Tcl_GetString(objv[3]); + if( strcmp(zWhence, "SEEK_SET")==0 ){ + whence = SEEK_SET; + }else if( strcmp(zWhence, "SEEK_CUR")==0 ){ + whence = SEEK_CUR; + }else if( strcmp(zWhence, "SEEK_END")==0 ){ + whence = SEEK_END; + }else{ + Tcl_AppendResult(interp, + "WHENCE should be SEEK_SET, SEEK_CUR, or SEEK_END", (char*)0); + return TCL_ERROR; + } + rc = sqlite3_quota_fseek(p, ofst, whence); + Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); + return TCL_OK; +} + +/* +** tclcmd: sqlite3_quota_rewind HANDLE +*/ +static int test_quota_rewind( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + quota_FILE *p; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE"); + return TCL_ERROR; + } + p = sqlite3TestTextToPtr(Tcl_GetString(objv[1])); + sqlite3_quota_rewind(p); + return TCL_OK; +} + +/* +** tclcmd: sqlite3_quota_ftell HANDLE +*/ +static int test_quota_ftell( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + quota_FILE *p; + sqlite3_int64 x; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE"); + return TCL_ERROR; + } + p = sqlite3TestTextToPtr(Tcl_GetString(objv[1])); + x = sqlite3_quota_ftell(p); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x)); + return TCL_OK; +} + +/* +** tclcmd: sqlite3_quota_remove FILENAME +*/ +static int test_quota_remove( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + const char *zFilename; /* File pattern to configure */ + int rc; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); + return TCL_ERROR; + } + zFilename = Tcl_GetString(objv[1]); + rc = sqlite3_quota_remove(zFilename); + Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); + return TCL_OK; +} + /* ** This routine registers the custom TCL commands defined in this ** module. This should be the only procedure visible from outside @@ -1253,10 +1548,18 @@ int Sqlitequota_Init(Tcl_Interp *interp){ Tcl_ObjCmdProc *xProc; } aCmd[] = { { "sqlite3_quota_initialize", test_quota_initialize }, - { "sqlite3_quota_shutdown", test_quota_shutdown }, - { "sqlite3_quota_set", test_quota_set }, - { "sqlite3_quota_file", test_quota_file }, - { "sqlite3_quota_dump", test_quota_dump }, + { "sqlite3_quota_shutdown", test_quota_shutdown }, + { "sqlite3_quota_set", test_quota_set }, + { "sqlite3_quota_file", test_quota_file }, + { "sqlite3_quota_dump", test_quota_dump }, + { "sqlite3_quota_fopen", test_quota_fopen }, + { "sqlite3_quota_fread", test_quota_fread }, + { "sqlite3_quota_fwrite", test_quota_fwrite }, + { "sqlite3_quota_fclose", test_quota_fclose }, + { "sqlite3_quota_fseek", test_quota_fseek }, + { "sqlite3_quota_rewind", test_quota_rewind }, + { "sqlite3_quota_ftell", test_quota_ftell }, + { "sqlite3_quota_remove", test_quota_remove }, }; int i; diff --git a/test/quota.test b/test/quota.test index 49b403f1eb..8f01c4fde5 100644 --- a/test/quota.test +++ b/test/quota.test @@ -48,6 +48,7 @@ do_test quota-1.8 { sqlite3_quota_shutdown } {SQLITE_OK} # sqlite3_quota_initialize "" 1 +unset -nocomplain quota_request_ok proc quota_check {filename limitvar size} { upvar $limitvar limit diff --git a/test/quota2.test b/test/quota2.test new file mode 100644 index 0000000000..33968082dd --- /dev/null +++ b/test/quota2.test @@ -0,0 +1,114 @@ +# 2011 December 1 +# +# 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. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl + +db close +sqlite3_quota_initialize "" 1 + +file delete -force quota2a +file delete -force quota2b +file mkdir quota2a +file mkdir quota2b + +# The quota_check procedure is a callback from the quota handler. +# It has three arguments which are (1) the full pathname of the file +# that has gone over quota, (2) the quota limit, (3) the requested +# new quota size to cover the last write. These three values are +# appended to the global variable $::quota. The filename is processed +# to convert every \ character into / and to change the name of the +# working directory to PWD. +# +# The quota is increased to the request if the ::quota_request_ok +# global variable is true. +# +set ::quota {} +set ::quota_request_ok 0 +proc quota_check {filename limitvar size} { + upvar $limitvar limit + set filename [string map [list [pwd] PWD \\ /] $filename] + lappend ::quota $filename [set limit] $size + if {$::quota_request_ok} {set limit $size} +} + +sqlite3_quota_set */quota2a/* 4000 quota_check +sqlite3_quota_set */quota2b/* 5000 quota_check + +unset -nocomplain bigtext +for {set i 1} {$i<=1000} {incr i} { + if {$i%10==0} { + append bigtext [format "%06d\n" $i] + } else { + append bigtext [format "%06d " $i] + } +} + +catch { unset h1 } +catch { unset x } +do_test quota2-1.1 { + set ::h1 [sqlite3_quota_fopen quota2a/xyz.txt w+] + sqlite3_quota_fwrite $::h1 1 7000 $bigtext +} {4000} +do_test quota2-1.2 { + set ::quota +} {PWD/quota2a/xyz.txt 4000 7000} +do_test quota2-1.3 { + sqlite3_quota_rewind $::h1 + set ::x [sqlite3_quota_fread $::h1 1001 7] + string length $::x +} {3003} +do_test quota2-1.4 { + string match $::x [string range $::bigtext 0 3002] +} {1} +do_test quota2-1.5 { + sqlite3_quota_fseek $::h1 0 SEEK_END + sqlite3_quota_ftell $::h1 +} {4000} +do_test quota2-1.6 { + sqlite3_quota_fseek $::h1 -100 SEEK_END + sqlite3_quota_ftell $::h1 +} {3900} +do_test quota2-1.7 { + sqlite3_quota_fseek $::h1 -100 SEEK_CUR + sqlite3_quota_ftell $::h1 +} {3800} +do_test quota2-1.8 { + sqlite3_quota_fseek $::h1 50 SEEK_CUR + sqlite3_quota_ftell $::h1 +} {3850} +do_test quota2-1.9 { + sqlite3_quota_fseek $::h1 50 SEEK_SET + sqlite3_quota_ftell $::h1 +} {50} +do_test quota2-1.10 { + sqlite3_quota_rewind $::h1 + sqlite3_quota_ftell $::h1 +} {0} +do_test quota2-1.11 { + string map [list [pwd] PWD \\ /] [sqlite3_quota_dump] +} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 1 0}}} +do_test quota1-1.12 { + sqlite3_quota_fclose $::h1 + string map [list [pwd] PWD \\ /] [sqlite3_quota_dump] +} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 0 0}}} +do_test quota1-1.13 { + sqlite3_quota_remove quota2a/xyz.txt + string map [list [pwd] PWD \\ /] [sqlite3_quota_dump] +} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}} + + + +catch { sqlite3_quota_shutdown } +catch { unset quota_request_ok } +finish_test From c8ccda60761ef2bd75cb122f04135cb938459cda Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Dec 2011 22:07:22 +0000 Subject: [PATCH 051/161] Progress toward getting things to work better on windows. FossilOrigin-Name: 253dd7072ef7f4e8742e5b6430658f8e5102e0bb --- manifest | 15 ++++++------ manifest.uuid | 2 +- src/test_quota.c | 58 +++++++++++++++++++++++++++++++++++--------- test/quota-glob.test | 50 ++++++++++++++++++++++++++++++++++++++ test/quota2.test | 21 ++++++++++++---- 5 files changed, 121 insertions(+), 25 deletions(-) create mode 100644 test/quota-glob.test diff --git a/manifest b/manifest index f025539657..66b7337e56 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\slogic\sand\ssome\stest\scases. -D 2011-12-01T20:48:15.803 +C Progress\stoward\sgetting\sthings\sto\swork\sbetter\son\swindows. +D 2011-12-01T22:07:22.034 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 -F src/test_quota.c ed68398661b398f0ce213349eb1cac6b5c39f62e +F src/test_quota.c 38c23c0fcbc92e0f8fe6fc0a76e66680cdb1b5cb F src/test_quota.h 118dba604ae5b6903acdd40d2b94a1f319047612 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 @@ -634,8 +634,9 @@ F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 +F test/quota-glob.test bb88e8da2f24f7f8413492967beb35d3222f52a4 F test/quota.test 46e6571b45c3c58ac131cc38f7d600aa9f75974d -F test/quota2.test 1372a399adcecc423396f51faec5de44ae236019 +F test/quota2.test 87b9c7a63e458706e528c661efa3955abc540fc5 F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6 F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test 1084050991e9ba22c1c10edd8d84673b501cc25a @@ -978,7 +979,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P bd3ce723f1b5be52be46ede8614ca316f56e7e6f -R 137abcb878bf12767e2fb107dd20a728 +P a4730586cc1f686ead956ccd1cc218b5931942c9 +R 2e2d8adc5259d2440bcb724fb4357d2b U drh -Z 363de760bad75051e8a4f47a97fcd11d +Z 0c07da994a8e7e81f42215da8ed506cb diff --git a/manifest.uuid b/manifest.uuid index c735789a39..64d966b624 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a4730586cc1f686ead956ccd1cc218b5931942c9 \ No newline at end of file +253dd7072ef7f4e8742e5b6430658f8e5102e0bb \ No newline at end of file diff --git a/src/test_quota.c b/src/test_quota.c index d435f88558..479cf0f0d8 100644 --- a/src/test_quota.c +++ b/src/test_quota.c @@ -241,7 +241,7 @@ static void quotaGroupDeref(quotaGroup *pGroup){ ** */ static int quotaStrglob(const char *zGlob, const char *z){ - int c, c2; + int c, c2, cx; int invert; int seen; @@ -258,8 +258,9 @@ static int quotaStrglob(const char *zGlob, const char *z){ } return (*z)!=0; } + cx = (c=='/') ? '\\' : c; while( (c2 = (*(z++)))!=0 ){ - while( c2!=c ){ + while( c2!=c && c2!=cx ){ c2 = *(z++); if( c2==0 ) return 0; } @@ -423,7 +424,7 @@ static char *quota_utf8_to_mbcs(const char *zUtf8){ */ static void quota_mbcs_free(char *zOld){ #if SQLITE_OS_WIN - free(zOld); + sqlite3_free(zOld); #else /* No-op on unix */ #endif @@ -1004,7 +1005,7 @@ size_t sqlite3_quota_fwrite( iOfst = ftell(p->f); iEnd = iOfst + size*nmemb; pFile = p->pFile; - if( pFile->iSizeiSizepGroup; quotaEnter(); szNew = pGroup->iSize - pFile->iSize + iEnd; @@ -1035,14 +1036,16 @@ int sqlite3_quota_fclose(quota_FILE *p){ quotaFile *pFile; rc = fclose(p->f); pFile = p->pFile; - quotaEnter(); - pFile->nRef--; - if( pFile->nRef==0 ){ - quotaGroup *pGroup = pFile->pGroup; - if( pFile->deleteOnClose ) quotaRemoveFile(pFile); - quotaGroupDeref(pGroup); + if( pFile ){ + quotaEnter(); + pFile->nRef--; + if( pFile->nRef==0 ){ + quotaGroup *pGroup = pFile->pGroup; + if( pFile->deleteOnClose ) quotaRemoveFile(pFile); + quotaGroupDeref(pGroup); + } + quotaLeave(); } - quotaLeave(); sqlite3_free(p); return rc; } @@ -1305,9 +1308,13 @@ static int test_quota_dump( Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewWideIntObj(pGroup->iSize)); for(pFile=pGroup->pFiles; pFile; pFile=pFile->pNext){ + int i; + char zTemp[1000]; pFileTerm = Tcl_NewObj(); + sqlite3_snprintf(sizeof(zTemp), zTemp, "%s", pFile->zFilename); + for(i=0; zTemp[i]; i++){ if( zTemp[i]=='\\' ) zTemp[i] = '/'; } Tcl_ListObjAppendElement(interp, pFileTerm, - Tcl_NewStringObj(pFile->zFilename, -1)); + Tcl_NewStringObj(zTemp, -1)); Tcl_ListObjAppendElement(interp, pFileTerm, Tcl_NewWideIntObj(pFile->iSize)); Tcl_ListObjAppendElement(interp, pFileTerm, @@ -1537,6 +1544,32 @@ static int test_quota_remove( return TCL_OK; } +/* +** tclcmd: sqlite3_quota_glob PATTERN TEXT +** +** Test the glob pattern matching. Return 1 if TEXT matches PATTERN +** and return 0 if it does not. +*/ +static int test_quota_glob( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + const char *zPattern; /* The glob pattern */ + const char *zText; /* Text to compare agains the pattern */ + int rc; + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "PATTERN TEXT"); + return TCL_ERROR; + } + zPattern = Tcl_GetString(objv[1]); + zText = Tcl_GetString(objv[2]); + rc = quotaStrglob(zPattern, zText); + Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); + return TCL_OK; +} + /* ** This routine registers the custom TCL commands defined in this ** module. This should be the only procedure visible from outside @@ -1560,6 +1593,7 @@ int Sqlitequota_Init(Tcl_Interp *interp){ { "sqlite3_quota_rewind", test_quota_rewind }, { "sqlite3_quota_ftell", test_quota_ftell }, { "sqlite3_quota_remove", test_quota_remove }, + { "sqlite3_quota_glob", test_quota_glob }, }; int i; diff --git a/test/quota-glob.test b/test/quota-glob.test new file mode 100644 index 0000000000..bacaa27c29 --- /dev/null +++ b/test/quota-glob.test @@ -0,0 +1,50 @@ +# 2011 December 1 +# +# 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. +# +#*********************************************************************** +# +# Tests for the glob-style string compare operator embedded in the +# quota shim. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +catch { unset testnum } +catch { unset pattern } +catch { unset text } +catch { unset ans } + +foreach {testnum pattern text ans} { + 1 abcdefg abcdefg 1 + 2 abcdefG abcdefg 0 + 3 abcdef abcdefg 0 + 4 abcdefgh abcdefg 0 + 5 abcdef? abcdefg 1 + 6 abcdef? abcdef 0 + 7 abcdef? abcdefgh 0 + 8 abcdefg abcdef? 0 + 9 abcdef? abcdef? 1 + 10 abc/def abc/def 1 + 11 abc/def abc\\def 1 + 12 */abc/* x/abc/y 1 + 13 */abc/* /abc/ 1 + 16 */abc/* x///a/ab/abc 0 + 17 */abc/* x//a/ab/abc/ 1 + 16 */abc/* x///a/ab/abc 0 + 17 */abc/* x//a/ab/abc/ 1 +} { + do_test quota-glob-$testnum.1 { + sqlite3_quota_glob $::pattern $::text + } $::ans + do_test quota-glob-$testnum.2 { + sqlite3_quota_glob $::pattern [string map {/ \\} $::text] + } $::ans +} +finish_test diff --git a/test/quota2.test b/test/quota2.test index 33968082dd..458c3069d7 100644 --- a/test/quota2.test +++ b/test/quota2.test @@ -22,6 +22,17 @@ file delete -force quota2b file mkdir quota2a file mkdir quota2b +# The standard_path procedure converts a pathname into a standard format +# that is the same across platforms. +# +unset -nocomplain ::quota_pwd ::quota_mapping +set ::quota_pwd [string map {\\ /} [pwd]] +set ::quota_mapping [list $::quota_pwd PWD] +proc standard_path {x} { + set x [string map {\\ /} $x] + return [string map $::quota_mapping $x] +} + # The quota_check procedure is a callback from the quota handler. # It has three arguments which are (1) the full pathname of the file # that has gone over quota, (2) the quota limit, (3) the requested @@ -35,10 +46,10 @@ file mkdir quota2b # set ::quota {} set ::quota_request_ok 0 + proc quota_check {filename limitvar size} { upvar $limitvar limit - set filename [string map [list [pwd] PWD \\ /] $filename] - lappend ::quota $filename [set limit] $size + lappend ::quota [standard_path $filename] [set limit] $size if {$::quota_request_ok} {set limit $size} } @@ -96,15 +107,15 @@ do_test quota2-1.10 { sqlite3_quota_ftell $::h1 } {0} do_test quota2-1.11 { - string map [list [pwd] PWD \\ /] [sqlite3_quota_dump] + standard_path [sqlite3_quota_dump] } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 1 0}}} do_test quota1-1.12 { sqlite3_quota_fclose $::h1 - string map [list [pwd] PWD \\ /] [sqlite3_quota_dump] + standard_path [sqlite3_quota_dump] } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 0 0}}} do_test quota1-1.13 { sqlite3_quota_remove quota2a/xyz.txt - string map [list [pwd] PWD \\ /] [sqlite3_quota_dump] + standard_path [sqlite3_quota_dump] } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}} From 0661ca6ce216ccabe0ede90a9556cc4da79f97f3 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Dec 2011 22:12:58 +0000 Subject: [PATCH 052/161] Run quota-stdio tests in binary mode so that they work on windows. FossilOrigin-Name: 71e4e97d9c883aa9f1d43d61543685924fc9339a --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/quota2.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 66b7337e56..8f0434f9ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Progress\stoward\sgetting\sthings\sto\swork\sbetter\son\swindows. -D 2011-12-01T22:07:22.034 +C Run\squota-stdio\stests\sin\sbinary\smode\sso\sthat\sthey\swork\son\swindows. +D 2011-12-01T22:12:58.579 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -636,7 +636,7 @@ F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota-glob.test bb88e8da2f24f7f8413492967beb35d3222f52a4 F test/quota.test 46e6571b45c3c58ac131cc38f7d600aa9f75974d -F test/quota2.test 87b9c7a63e458706e528c661efa3955abc540fc5 +F test/quota2.test eabde52ca2606f494be10aad87562b4dd2f4558a F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6 F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test 1084050991e9ba22c1c10edd8d84673b501cc25a @@ -979,7 +979,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P a4730586cc1f686ead956ccd1cc218b5931942c9 -R 2e2d8adc5259d2440bcb724fb4357d2b +P 253dd7072ef7f4e8742e5b6430658f8e5102e0bb +R 81841ea938699b5dac6d44310547d5e9 U drh -Z 0c07da994a8e7e81f42215da8ed506cb +Z 485f7e550a4a58d4cb24ca1e40fc9f7f diff --git a/manifest.uuid b/manifest.uuid index 64d966b624..f798ec3b64 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -253dd7072ef7f4e8742e5b6430658f8e5102e0bb \ No newline at end of file +71e4e97d9c883aa9f1d43d61543685924fc9339a \ No newline at end of file diff --git a/test/quota2.test b/test/quota2.test index 458c3069d7..57d54d056a 100644 --- a/test/quota2.test +++ b/test/quota2.test @@ -68,7 +68,7 @@ for {set i 1} {$i<=1000} {incr i} { catch { unset h1 } catch { unset x } do_test quota2-1.1 { - set ::h1 [sqlite3_quota_fopen quota2a/xyz.txt w+] + set ::h1 [sqlite3_quota_fopen quota2a/xyz.txt w+b] sqlite3_quota_fwrite $::h1 1 7000 $bigtext } {4000} do_test quota2-1.2 { From eff1433b6b7d1221034ba3c77687178537b413e9 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 2 Dec 2011 15:27:41 +0000 Subject: [PATCH 053/161] Documentation improvements and additional test cases. FossilOrigin-Name: fa71896089538589fb7015d6507e22961e72233b --- manifest | 16 ++++++------- manifest.uuid | 2 +- src/test_quota.h | 12 +++++++--- test/quota-glob.test | 39 ++++++++++++++++++++++++++++++- test/quota2.test | 55 ++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 107 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 8f0434f9ff..46f615874f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Run\squota-stdio\stests\sin\sbinary\smode\sso\sthat\sthey\swork\son\swindows. -D 2011-12-01T22:12:58.579 +C Documentation\simprovements\sand\sadditional\stest\scases. +D 2011-12-02T15:27:41.260 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -221,7 +221,7 @@ F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 F src/test_quota.c 38c23c0fcbc92e0f8fe6fc0a76e66680cdb1b5cb -F src/test_quota.h 118dba604ae5b6903acdd40d2b94a1f319047612 +F src/test_quota.h 64240c0f7505dc1d920ff908d63d12ff2bf9c7c0 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f @@ -634,9 +634,9 @@ F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 -F test/quota-glob.test bb88e8da2f24f7f8413492967beb35d3222f52a4 +F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26 F test/quota.test 46e6571b45c3c58ac131cc38f7d600aa9f75974d -F test/quota2.test eabde52ca2606f494be10aad87562b4dd2f4558a +F test/quota2.test b7169f613adf64c22a5336ca607d3b54d7b2ed5a F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6 F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test 1084050991e9ba22c1c10edd8d84673b501cc25a @@ -979,7 +979,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 253dd7072ef7f4e8742e5b6430658f8e5102e0bb -R 81841ea938699b5dac6d44310547d5e9 +P 71e4e97d9c883aa9f1d43d61543685924fc9339a +R 54a98987b22e40be43c533aef3d8d654 U drh -Z 485f7e550a4a58d4cb24ca1e40fc9f7f +Z 0fb6e66eea4239badfef5d9b0c5e6533 diff --git a/manifest.uuid b/manifest.uuid index f798ec3b64..f9f7f17f15 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -71e4e97d9c883aa9f1d43d61543685924fc9339a \ No newline at end of file +fa71896089538589fb7015d6507e22961e72233b \ No newline at end of file diff --git a/src/test_quota.h b/src/test_quota.h index df78e7eb71..d47f89bd78 100644 --- a/src/test_quota.h +++ b/src/test_quota.h @@ -65,21 +65,27 @@ int sqlite3_quota_shutdown(void); ** The zPattern is always compared against the full pathname of the file. ** Even if APIs are called with relative pathnames, SQLite converts the ** name to a full pathname before comparing it against zPattern. zPattern -** is a standard glob pattern with the following matching rules: +** is a glob pattern with the following matching rules: ** ** '*' Matches any sequence of zero or more characters. ** ** '?' Matches exactly one character. ** ** [...] Matches one character from the enclosed list of -** characters. +** characters. "]" can be part of the list if it is +** the first character. Within the list "X-Y" matches +** characters X or Y or any character in between the +** two. Ex: "[0-9]" matches any digit. ** ** [^...] Matches one character not in the enclosed list. ** +** / Matches either / or \. This allows glob patterns +** containing / to work on both unix and windows. +** ** Note that, unlike unix shell globbing, the directory separator "/" ** can match a wildcard. So, for example, the pattern "/abc/xyz/" "*" ** matches any files anywhere in the directory hierarchy beneath -** /abc/xyz +** /abc/xyz. ** ** If the iLimit for a quota group is set to zero, then the quota group ** is disabled and will be deleted when the last database connection using diff --git a/test/quota-glob.test b/test/quota-glob.test index bacaa27c29..28c813c30f 100644 --- a/test/quota-glob.test +++ b/test/quota-glob.test @@ -32,13 +32,50 @@ foreach {testnum pattern text ans} { 8 abcdefg abcdef? 0 9 abcdef? abcdef? 1 10 abc/def abc/def 1 - 11 abc/def abc\\def 1 + 11 abc//def abc/def 0 12 */abc/* x/abc/y 1 13 */abc/* /abc/ 1 16 */abc/* x///a/ab/abc 0 17 */abc/* x//a/ab/abc/ 1 16 */abc/* x///a/ab/abc 0 17 */abc/* x//a/ab/abc/ 1 + 18 **/abc/** x//a/ab/abc/ 1 + 19 *?/abc/*? x//a/ab/abc/y 1 + 20 ?*/abc/?* x//a/ab/abc/y 1 + 21 {abc[cde]efg} abcbefg 0 + 22 {abc[cde]efg} abccefg 1 + 23 {abc[cde]efg} abcdefg 1 + 24 {abc[cde]efg} abceefg 1 + 25 {abc[cde]efg} abcfefg 0 + 26 {abc[^cde]efg} abcbefg 1 + 27 {abc[^cde]efg} abccefg 0 + 28 {abc[^cde]efg} abcdefg 0 + 29 {abc[^cde]efg} abceefg 0 + 30 {abc[^cde]efg} abcfefg 1 + 31 {abc[c-e]efg} abcbefg 0 + 32 {abc[c-e]efg} abccefg 1 + 33 {abc[c-e]efg} abcdefg 1 + 34 {abc[c-e]efg} abceefg 1 + 35 {abc[c-e]efg} abcfefg 0 + 36 {abc[^c-e]efg} abcbefg 1 + 37 {abc[^c-e]efg} abccefg 0 + 38 {abc[^c-e]efg} abcdefg 0 + 39 {abc[^c-e]efg} abceefg 0 + 40 {abc[^c-e]efg} abcfefg 1 + 41 {abc[c-e]efg} abc-efg 0 + 42 {abc[-ce]efg} abc-efg 1 + 43 {abc[ce-]efg} abc-efg 1 + 44 {abc[][*?]efg} {abc]efg} 1 + 45 {abc[][*?]efg} {abc*efg} 1 + 46 {abc[][*?]efg} {abc?efg} 1 + 47 {abc[][*?]efg} {abc[efg} 1 + 48 {abc[^][*?]efg} {abc]efg} 0 + 49 {abc[^][*?]efg} {abc*efg} 0 + 50 {abc[^][*?]efg} {abc?efg} 0 + 51 {abc[^][*?]efg} {abc[efg} 0 + 52 {abc[^][*?]efg} {abcdefg} 1 + 53 {*[xyz]efg} {abcxefg} 1 + 54 {*[xyz]efg} {abcwefg} 0 } { do_test quota-glob-$testnum.1 { sqlite3_quota_glob $::pattern $::text diff --git a/test/quota2.test b/test/quota2.test index 57d54d056a..d408cda9ca 100644 --- a/test/quota2.test +++ b/test/quota2.test @@ -17,10 +17,10 @@ source $testdir/malloc_common.tcl db close sqlite3_quota_initialize "" 1 -file delete -force quota2a -file delete -force quota2b -file mkdir quota2a -file mkdir quota2b +foreach dir {quota2a quota2b quota2c} { + file delete -force $dir + file mkdir $dir +} # The standard_path procedure converts a pathname into a standard format # that is the same across platforms. @@ -119,6 +119,53 @@ do_test quota1-1.13 { } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}} +set quota {} +do_test quota2-2.1 { + set ::h1 [sqlite3_quota_fopen quota2c/xyz.txt w+b] + sqlite3_quota_fwrite $::h1 1 7000 $bigtext +} {7000} +do_test quota2-2.2 { + set ::quota +} {} +do_test quota2-2.3 { + sqlite3_quota_rewind $::h1 + set ::x [sqlite3_quota_fread $::h1 1001 7] + string length $::x +} {6006} +do_test quota2-2.4 { + string match $::x [string range $::bigtext 0 6005] +} {1} +do_test quota2-2.5 { + sqlite3_quota_fseek $::h1 0 SEEK_END + sqlite3_quota_ftell $::h1 +} {7000} +do_test quota2-2.6 { + sqlite3_quota_fseek $::h1 -100 SEEK_END + sqlite3_quota_ftell $::h1 +} {6900} +do_test quota2-2.7 { + sqlite3_quota_fseek $::h1 -100 SEEK_CUR + sqlite3_quota_ftell $::h1 +} {6800} +do_test quota2-2.8 { + sqlite3_quota_fseek $::h1 50 SEEK_CUR + sqlite3_quota_ftell $::h1 +} {6850} +do_test quota2-2.9 { + sqlite3_quota_fseek $::h1 50 SEEK_SET + sqlite3_quota_ftell $::h1 +} {50} +do_test quota2-2.10 { + sqlite3_quota_rewind $::h1 + sqlite3_quota_ftell $::h1 +} {0} +do_test quota2-2.11 { + standard_path [sqlite3_quota_dump] +} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}} +do_test quota1-2.12 { + sqlite3_quota_fclose $::h1 + standard_path [sqlite3_quota_dump] +} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}} catch { sqlite3_quota_shutdown } catch { unset quota_request_ok } From a0036917350bff6ca89bef8d135a6c8ad1770f48 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 2 Dec 2011 15:31:07 +0000 Subject: [PATCH 054/161] One minor documentation enhancement. FossilOrigin-Name: 8cfd3575c8d9f5361c5276d6b83aba47606975a3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test_quota.h | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 46f615874f..5de01fa78e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Documentation\simprovements\sand\sadditional\stest\scases. -D 2011-12-02T15:27:41.260 +C One\sminor\sdocumentation\senhancement. +D 2011-12-02T15:31:07.596 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -221,7 +221,7 @@ F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 F src/test_quota.c 38c23c0fcbc92e0f8fe6fc0a76e66680cdb1b5cb -F src/test_quota.h 64240c0f7505dc1d920ff908d63d12ff2bf9c7c0 +F src/test_quota.h c9e778a1ace38cd5be936e99a3d757477e2d1d4f F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f @@ -979,7 +979,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 71e4e97d9c883aa9f1d43d61543685924fc9339a -R 54a98987b22e40be43c533aef3d8d654 +P fa71896089538589fb7015d6507e22961e72233b +R a322cd5996330a42d9cdf5afaa24ab27 U drh -Z 0fb6e66eea4239badfef5d9b0c5e6533 +Z 9258d38c087b789fa674695734308523 diff --git a/manifest.uuid b/manifest.uuid index f9f7f17f15..b9b86d16df 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fa71896089538589fb7015d6507e22961e72233b \ No newline at end of file +8cfd3575c8d9f5361c5276d6b83aba47606975a3 \ No newline at end of file diff --git a/src/test_quota.h b/src/test_quota.h index d47f89bd78..6df423f5d1 100644 --- a/src/test_quota.h +++ b/src/test_quota.h @@ -87,6 +87,9 @@ int sqlite3_quota_shutdown(void); ** matches any files anywhere in the directory hierarchy beneath ** /abc/xyz. ** +** The glob algorithm works on bytes. Multi-byte UTF8 characters are +** matched as if each byte were a separate character. +** ** If the iLimit for a quota group is set to zero, then the quota group ** is disabled and will be deleted when the last database connection using ** the quota group is closed. From 69b2232d6e2cfe4a5d1cd25d48af015ee1faac7b Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 3 Dec 2011 00:13:06 +0000 Subject: [PATCH 055/161] Add the sqlite3_quota_fflush() interface. Enhance sqlite3_quota_remove() so that it can remove entire directories. FossilOrigin-Name: abcb65af4cdd192beaccdbc2109ad45b9e7f9d00 --- manifest | 16 ++++----- manifest.uuid | 2 +- src/test_quota.c | 91 ++++++++++++++++++++++++++++++++++++++++++++---- src/test_quota.h | 41 ++++++++++++++++++---- test/quota2.test | 64 +++++++++++++++++++++++++++++++--- 5 files changed, 189 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 5de01fa78e..e49d82bcc0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C One\sminor\sdocumentation\senhancement. -D 2011-12-02T15:31:07.596 +C Add\sthe\ssqlite3_quota_fflush()\sinterface.\s\sEnhance\ssqlite3_quota_remove()\nso\sthat\sit\scan\sremove\sentire\sdirectories. +D 2011-12-03T00:13:06.592 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,8 +220,8 @@ F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 -F src/test_quota.c 38c23c0fcbc92e0f8fe6fc0a76e66680cdb1b5cb -F src/test_quota.h c9e778a1ace38cd5be936e99a3d757477e2d1d4f +F src/test_quota.c 2e6191cbfc6ae978330a0d0ffcc3fb81b7059e68 +F src/test_quota.h 9b3c75a79e8c3c6a9d3846b73435bebcd550ba12 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f @@ -636,7 +636,7 @@ F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26 F test/quota.test 46e6571b45c3c58ac131cc38f7d600aa9f75974d -F test/quota2.test b7169f613adf64c22a5336ca607d3b54d7b2ed5a +F test/quota2.test 562b27570d1e0d0606c3769b648e23c72fa3859b F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6 F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test 1084050991e9ba22c1c10edd8d84673b501cc25a @@ -979,7 +979,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P fa71896089538589fb7015d6507e22961e72233b -R a322cd5996330a42d9cdf5afaa24ab27 +P 8cfd3575c8d9f5361c5276d6b83aba47606975a3 +R 28ca02cd727421756b639f8157eb6391 U drh -Z 9258d38c087b789fa674695734308523 +Z 84dc1ce8a56d57cb5251e17d63b686ff diff --git a/manifest.uuid b/manifest.uuid index b9b86d16df..83ef24af72 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8cfd3575c8d9f5361c5276d6b83aba47606975a3 \ No newline at end of file +abcb65af4cdd192beaccdbc2109ad45b9e7f9d00 \ No newline at end of file diff --git a/src/test_quota.c b/src/test_quota.c index 479cf0f0d8..c073b47d28 100644 --- a/src/test_quota.c +++ b/src/test_quota.c @@ -552,7 +552,10 @@ static int quotaClose(sqlite3_file *pConn){ pFile->nRef--; if( pFile->nRef==0 ){ quotaGroup *pGroup = pFile->pGroup; - if( pFile->deleteOnClose ) quotaRemoveFile(pFile); + if( pFile->deleteOnClose ){ + gQuota.pOrigVfs->xDelete(gQuota.pOrigVfs, pFile->zFilename, 0); + quotaRemoveFile(pFile); + } quotaGroupDeref(pGroup); } quotaLeave(); @@ -1041,7 +1044,10 @@ int sqlite3_quota_fclose(quota_FILE *p){ pFile->nRef--; if( pFile->nRef==0 ){ quotaGroup *pGroup = pFile->pGroup; - if( pFile->deleteOnClose ) quotaRemoveFile(pFile); + if( pFile->deleteOnClose ){ + gQuota.pOrigVfs->xDelete(gQuota.pOrigVfs, pFile->zFilename, 0); + quotaRemoveFile(pFile); + } quotaGroupDeref(pGroup); } quotaLeave(); @@ -1050,6 +1056,13 @@ int sqlite3_quota_fclose(quota_FILE *p){ return rc; } +/* +** Flush memory buffers for a quota_FILE to disk. +*/ +int sqlite3_quota_fflush(quota_FILE *p){ + return fflush(p->f); +} + /* ** Seek on a quota_FILE stream. */ @@ -1072,14 +1085,57 @@ long sqlite3_quota_ftell(quota_FILE *p){ } /* -** Remove a file. Update quotas accordingly. +** Remove a managed file. Update quotas accordingly. */ int sqlite3_quota_remove(const char *zFilename){ - int rc = remove(zFilename); - sqlite3_quota_file(zFilename); + char *zFull; /* Full pathname for zFilename */ + int nFull; /* Number of bytes in zFilename */ + int rc; /* Result code */ + quotaGroup *pGroup; /* Group containing zFilename */ + quotaFile *pFile; /* A file in the group */ + quotaFile *pNextFile; /* next file in the group */ + int diff; /* Difference between filenames */ + char c; /* First character past end of pattern */ + + zFull = sqlite3_malloc(gQuota.sThisVfs.mxPathname + 1); + if( zFull==0 ) return SQLITE_NOMEM; + rc = gQuota.pOrigVfs->xFullPathname(gQuota.pOrigVfs, zFilename, + gQuota.sThisVfs.mxPathname+1, zFull); + if( rc ){ + sqlite3_free(zFull); + return rc; + } + + /* Figure out the length of the full pathname. If the name ends with + ** / (or \ on windows) then remove the trailing /. + */ + nFull = strlen(zFull); + if( nFull>0 && (zFull[nFull-1]=='/' || zFull[nFull-1]=='\\') ){ + nFull--; + zFull[nFull] = 0; + } + + quotaEnter(); + pGroup = quotaGroupFind(zFull); + if( pGroup ){ + for(pFile=pGroup->pFiles; pFile && rc==SQLITE_OK; pFile=pNextFile){ + pNextFile = pFile->pNext; + diff = memcmp(zFull, pFile->zFilename, nFull); + if( diff==0 && ((c = pFile->zFilename[nFull])==0 || c=='/' || c=='\\') ){ + if( pFile->nRef ){ + pFile->deleteOnClose = 1; + }else{ + rc = gQuota.pOrigVfs->xDelete(gQuota.pOrigVfs, pFile->zFilename, 0); + quotaRemoveFile(pFile); + quotaGroupDeref(pGroup); + } + } + } + } + quotaLeave(); + sqlite3_free(zFull); return rc; } - /***************************** Test Code ***********************************/ #ifdef SQLITE_TEST @@ -1445,6 +1501,28 @@ static int test_quota_fclose( return TCL_OK; } +/* +** tclcmd: sqlite3_quota_fflush HANDLE +*/ +static int test_quota_fflush( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + quota_FILE *p; + int rc; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE"); + return TCL_ERROR; + } + p = sqlite3TestTextToPtr(Tcl_GetString(objv[1])); + rc = sqlite3_quota_fflush(p); + Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); + return TCL_OK; +} + /* ** tclcmd: sqlite3_quota_fseek HANDLE OFFSET WHENCE */ @@ -1589,6 +1667,7 @@ int Sqlitequota_Init(Tcl_Interp *interp){ { "sqlite3_quota_fread", test_quota_fread }, { "sqlite3_quota_fwrite", test_quota_fwrite }, { "sqlite3_quota_fclose", test_quota_fclose }, + { "sqlite3_quota_fflush", test_quota_fflush }, { "sqlite3_quota_fseek", test_quota_fseek }, { "sqlite3_quota_rewind", test_quota_rewind }, { "sqlite3_quota_ftell", test_quota_ftell }, diff --git a/src/test_quota.h b/src/test_quota.h index 6df423f5d1..dbcb2c185c 100644 --- a/src/test_quota.h +++ b/src/test_quota.h @@ -101,6 +101,10 @@ int sqlite3_quota_shutdown(void); ** database connections if those connections are to participate in the ** quota group. Creating a quota group does not affect database connections ** that are already open. +** +** The patterns that define the various quota groups should be distinct. +** If the same filename matches more than one quota group pattern, then +** the behavior of this package is undefined. */ int sqlite3_quota_set( const char *zPattern, /* The filename pattern */ @@ -116,14 +120,20 @@ int sqlite3_quota_set( ); /* -** Bring the named file under quota management. Or if it is already under -** management, update its size. +** Bring the named file under quota management, assuming its name matches +** the glob pattern of some quota group. Or if it is already under +** management, update its size. If zFilename does not match the glob +** pattern of any quota group, this routine is a no-op. */ int sqlite3_quota_file(const char *zFilename); /* ** The following object serves the same role as FILE in the standard C ** library. It represents an open connection to a file on disk for I/O. +** +** A single quota_FILE should not be used by two or more threads at the +** same time. Multiple threads can be using different quota_FILE objects +** simultaneously, but not the same quota_FILE object. */ typedef struct quota_FILE quota_FILE; @@ -141,6 +151,13 @@ quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode); size_t sqlite3_quota_fread(void*, size_t, size_t, quota_FILE*); size_t sqlite3_quota_fwrite(void*, size_t, size_t, quota_FILE*); +/* +** Flush all written content held in memory buffers out to disk. +** This is the equivalent of fflush() in the standard library - not +** an fsync(). +*/ +int sqlite3_quota_fflush(quota_FILE*); + /* ** Close a quota_FILE object and free all associated resources. The ** file remains under quota management. @@ -156,11 +173,23 @@ void sqlite3_quota_rewind(quota_FILE*); long sqlite3_quota_ftell(quota_FILE*); /* -** Delete a file from the disk. If that file is under quota management, -** then adjust quotas accordingly. +** Delete a file from the disk, if that file is under quota management. +** Adjust quotas accordingly. ** -** The file being deleted must not be open for reading or writing or as -** a database when it is deleted. +** If zFilename is the name of a directory that matches one of the +** quota glob patterns, then all files under quota management that +** are contained within that directory are deleted. +** +** A standard SQLite result code is returned (SQLITE_OK, SQLITE_NOMEM, etc.) +** When deleting a directory of files, if the deletion of any one +** file fails (for example due to an I/O error), then this routine +** returns immediately, with the error code, and does not try to +** delete any of the other files in the specified directory. +** +** All files are removed from quota management and deleted from disk. +** However, no attempt is made to remove empty directories. +** +** This routine is a no-op for files that are not under quota management. */ int sqlite3_quota_remove(const char *zFilename); diff --git a/test/quota2.test b/test/quota2.test index d408cda9ca..4b9daca2a2 100644 --- a/test/quota2.test +++ b/test/quota2.test @@ -17,8 +17,10 @@ source $testdir/malloc_common.tcl db close sqlite3_quota_initialize "" 1 -foreach dir {quota2a quota2b quota2c} { +foreach dir {quota2a/x1 quota2a/x2 quota2a quota2b quota2c} { file delete -force $dir +} +foreach dir {quota2a quota2a/x1 quota2a/x2 quota2b quota2c} { file mkdir $dir } @@ -109,11 +111,11 @@ do_test quota2-1.10 { do_test quota2-1.11 { standard_path [sqlite3_quota_dump] } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 1 0}}} -do_test quota1-1.12 { +do_test quota2-1.12 { sqlite3_quota_fclose $::h1 standard_path [sqlite3_quota_dump] } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 0 0}}} -do_test quota1-1.13 { +do_test quota2-1.13 { sqlite3_quota_remove quota2a/xyz.txt standard_path [sqlite3_quota_dump] } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}} @@ -162,11 +164,65 @@ do_test quota2-2.10 { do_test quota2-2.11 { standard_path [sqlite3_quota_dump] } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}} -do_test quota1-2.12 { +do_test quota2-2.12 { sqlite3_quota_fclose $::h1 standard_path [sqlite3_quota_dump] } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}} +do_test quota2-3.1 { + sqlite3_quota_set */quota2b/* 0 quota_check + set ::h1 [sqlite3_quota_fopen quota2a/x1/a.txt a] + sqlite3_quota_fwrite $::h1 10 10 $bigtext +} {10} +do_test quota2-3.2 { + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 100 {PWD/quota2a/x1/a.txt 100 1 0}}} +do_test quota2-3.3 { + sqlite3_quota_fflush $::h1 + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 100 {PWD/quota2a/x1/a.txt 100 1 0}}} +do_test quota2-3.4 { + sqlite3_quota_fclose $::h1 + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 100 {PWD/quota2a/x1/a.txt 100 0 0}}} +do_test quota2-3.5 { + set ::h2 [sqlite3_quota_fopen quota2a/x2/b.txt a] + sqlite3_quota_fwrite $::h2 10 20 $bigtext + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 300 {PWD/quota2a/x2/b.txt 200 1 0} {PWD/quota2a/x1/a.txt 100 0 0}}} +do_test quota2-3.6 { + set ::h3 [sqlite3_quota_fopen quota2a/x1/c.txt a] + sqlite3_quota_fwrite $::h3 10 50 $bigtext + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 800 {PWD/quota2a/x1/c.txt 500 1 0} {PWD/quota2a/x2/b.txt 200 1 0} {PWD/quota2a/x1/a.txt 100 0 0}}} +do_test quota2-3.7 { + file exists quota2a/x1/a.txt +} {1} +do_test quota2-3.8 { + file exists quota2a/x2/b.txt +} {1} +do_test quota2-3.9 { + file exists quota2a/x1/c.txt +} {1} +do_test quota2-3.10 { + sqlite3_quota_remove quota2a/x1 + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 700 {PWD/quota2a/x1/c.txt 500 1 1} {PWD/quota2a/x2/b.txt 200 1 0}}} +do_test quota2-3.11 { + sqlite3_quota_fclose $::h2 + sqlite3_quota_fclose $::h3 + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 200 {PWD/quota2a/x2/b.txt 200 0 0}}} +do_test quota2-3.12 { + file exists quota2a/x1/a.txt +} {0} +do_test quota2-3.13 { + file exists quota2a/x2/b.txt +} {1} +do_test quota2-3.14 { + file exists quota2a/x1/c.txt +} {0} + catch { sqlite3_quota_shutdown } catch { unset quota_request_ok } finish_test From cdc695571629850086a5d990c0026c5e69b32536 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 6 Dec 2011 13:24:59 +0000 Subject: [PATCH 056/161] Do not reuse temp registers originally allocated to a subroutine within the main body of the program logic, since if the subroutine is called while the reused temp registers are in use, their values will get clobbered. Candidate fix for ticket [3a77c9714e63330] FossilOrigin-Name: 092d53315e50be42b51ef7b3069c82c32a129b6a --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 8 ++++++++ src/select.c | 2 +- src/sqliteInt.h | 1 + 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index ef618fe69b..5fc0d1a877 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\swinGetLastError\sfixes\sinto\strunk. -D 2011-12-06T00:47:51.936 +C Do\snot\sreuse\stemp\sregisters\soriginally\sallocated\sto\sa\ssubroutine\swithin\nthe\smain\sbody\sof\sthe\sprogram\slogic,\ssince\sif\sthe\ssubroutine\sis\scalled\nwhile\sthe\sreused\stemp\sregisters\sare\sin\suse,\stheir\svalues\swill\sget\sclobbered.\nCandidate\sfix\sfor\sticket\s[3a77c9714e63330] +D 2011-12-06T13:24:59.067 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -134,7 +134,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 51d32f0a9c880663e54ce309f52e40c325d5e112 -F src/expr.c fbf116f90cabc917ae50bba24a73a0b55519a0c8 +F src/expr.c 319db0ad9f3c5d039d54bf5a65c98c08c7233924 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5 F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9 @@ -180,11 +180,11 @@ F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 -F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 +F src/select.c 538b5f096f6aacedf717bf982f9ad9a901008514 F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8 F src/sqlite.h.in 57081d8e6b53ce29541d7437c93bce6087ac53b5 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 6f28b69d77356b1e45c024a6c103a1e0f0ec9f62 +F src/sqliteInt.h 142ef5ed3fe0e6c662e99dbf92f38715b29a53b6 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -976,7 +976,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 431556cac0b2c86d7f6a60412ff1023feeaafedf 7e657bbb800107c992a6ee7a3b35bc0a073bf3e4 -R 543654dfa3532b18db5b62d6f330a3c2 +P 5b03ba9db0d23a8597b45e00ad5892c8065ce1cd +R 9fd2e18e31f5993e2a2417d0bd31fbb8 U drh -Z d9a349b5feef66c92d693305f283c870 +Z 6b588a9e7cf08c9f198f7cca1fb8c358 diff --git a/manifest.uuid b/manifest.uuid index fb1da87359..0f043b6cf3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5b03ba9db0d23a8597b45e00ad5892c8065ce1cd \ No newline at end of file +092d53315e50be42b51ef7b3069c82c32a129b6a \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index d506173771..e8a9d64108 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3762,3 +3762,11 @@ void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){ pParse->iRangeReg = iReg; } } + +/* +** Mark all temporary registers as being unavailable for reuse. +*/ +void sqlite3ClearTempRegCache(Parse *pParse){ + pParse->nTempReg = 0; + pParse->nRangeReg = 0; +} diff --git a/src/select.c b/src/select.c index 571a77822b..da75a51cd9 100644 --- a/src/select.c +++ b/src/select.c @@ -3860,7 +3860,7 @@ int sqlite3Select( retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); VdbeComment((v, "end %s", pItem->pTab->zName)); sqlite3VdbeChangeP1(v, topAddr, retAddr); - + sqlite3ClearTempRegCache(pParse); } if( /*pParse->nErr ||*/ db->mallocFailed ){ goto select_end; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4e00ad03c1..890f44f5e1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2660,6 +2660,7 @@ int sqlite3GetTempReg(Parse*); void sqlite3ReleaseTempReg(Parse*,int); int sqlite3GetTempRange(Parse*,int); void sqlite3ReleaseTempRange(Parse*,int,int); +void sqlite3ClearTempRegCache(Parse*); Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int); Expr *sqlite3Expr(sqlite3*,int,const char*); void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); From ed51f29774ca0581de17d7f4a066fea1b0459948 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 6 Dec 2011 13:46:54 +0000 Subject: [PATCH 057/161] Add file tkt-3a77c9714e.test, containing tests to verify that the problem documented by ticket [3a77c9714e] has been fixed. FossilOrigin-Name: 162421dadf93e9201c3290d800c597cbeeacdb40 --- manifest | 13 ++++---- manifest.uuid | 2 +- test/tkt-3a77c9714e.test | 68 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 test/tkt-3a77c9714e.test diff --git a/manifest b/manifest index 5fc0d1a877..1fd88a2a92 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sreuse\stemp\sregisters\soriginally\sallocated\sto\sa\ssubroutine\swithin\nthe\smain\sbody\sof\sthe\sprogram\slogic,\ssince\sif\sthe\ssubroutine\sis\scalled\nwhile\sthe\sreused\stemp\sregisters\sare\sin\suse,\stheir\svalues\swill\sget\sclobbered.\nCandidate\sfix\sfor\sticket\s[3a77c9714e63330] -D 2011-12-06T13:24:59.067 +C Add\sfile\stkt-3a77c9714e.test,\scontaining\stests\sto\sverify\sthat\sthe\sproblem\sdocumented\sby\sticket\s[3a77c9714e]\shas\sbeen\sfixed. +D 2011-12-06T13:46:54.313 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -728,6 +728,7 @@ F test/tkt-31338dca7e.test 1f714c14b6682c5db715e0bda347926a3456f7a9 F test/tkt-313723c356.test c47f8a9330523e6f35698bf4489bcb29609b53ac F test/tkt-38cb5df375.test 9e9b19857dba0896a8efdaf334d405ba423492f2 F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7 +F test/tkt-3a77c9714e.test 1675c22a5be71d7fa026e5db5daeeb4dd64f7824 F test/tkt-3fe897352e.test 10de1a67bd5c66b238a4c96abe55531b37bb4f00 F test/tkt-4a03edc4c8.test 2865e4edbc075b954daa82f8da7cc973033ec76e F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894 @@ -976,7 +977,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 5b03ba9db0d23a8597b45e00ad5892c8065ce1cd -R 9fd2e18e31f5993e2a2417d0bd31fbb8 -U drh -Z 6b588a9e7cf08c9f198f7cca1fb8c358 +P 092d53315e50be42b51ef7b3069c82c32a129b6a +R 8d2fc7565d4aa525192ff0541b1c9cf2 +U dan +Z d04d6b5cb95ec0b64c1e1542ea707494 diff --git a/manifest.uuid b/manifest.uuid index 0f043b6cf3..1ffea396bc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -092d53315e50be42b51ef7b3069c82c32a129b6a \ No newline at end of file +162421dadf93e9201c3290d800c597cbeeacdb40 \ No newline at end of file diff --git a/test/tkt-3a77c9714e.test b/test/tkt-3a77c9714e.test new file mode 100644 index 0000000000..d77ee42bb3 --- /dev/null +++ b/test/tkt-3a77c9714e.test @@ -0,0 +1,68 @@ +# 2011 December 06 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# +# This file implements tests to verify that ticket [3a77c9714e] has been +# fixed. + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +set testprefix "tkt-3a77c9714e" + +do_execsql_test 1.1 { + CREATE TABLE t1(t1_id INTEGER PRIMARY KEY, t1_title TEXT); + CREATE TABLE t2(t2_id INTEGER PRIMARY KEY, t2_title TEXT); + CREATE TABLE t3(t3_id INTEGER PRIMARY KEY, t3_title TEXT); + + INSERT INTO t1 (t1_id, t1_title) VALUES (888, 'ABCDEF'); + INSERT INTO t2 (t2_id, t2_title) VALUES (999, 'ABCDEF'); + INSERT INTO t3 (t3_id, t3_title) VALUES (999, 'ABCDEF'); +} + +do_execsql_test 1.2 { + SELECT t1_title, t2_title + FROM t1 LEFT JOIN t2 + WHERE + t2_id = (SELECT t3_id FROM + ( SELECT t3_id FROM t3 WHERE t3_title=t1_title LIMIT 500 ) + ) +} {ABCDEF ABCDEF} + +do_execsql_test 2.1 { + CREATE TABLE [Beginnings] ( + [Id] INTEGER PRIMARY KEY AUTOINCREMENT,[Title] TEXT, [EndingId] INTEGER + ); + CREATE TABLE [Endings] (Id INT,Title TEXT,EndingId INT); + INSERT INTO Beginnings (Id, Title, EndingId) VALUES (1, 'FACTOR', 18); + INSERT INTO Beginnings (Id, Title, EndingId) VALUES (2, 'SWIMM', 18); + INSERT INTO Endings (Id, Title, EndingId) VALUES (1, 'ING', 18); +} + +do_execsql_test 2.2 { + SELECT + SrcWord, Beginnings.Title + FROM + (SELECT 'FACTORING' AS SrcWord UNION SELECT 'SWIMMING' AS SrcWord ) + LEFT JOIN + Beginnings + WHERE Beginnings.Id= ( + SELECT BeginningId FROM ( + SELECT SrcWord, B.Id as BeginningId, B.Title || E.Title As Connected + FROM Beginnings B LEFT JOIN Endings E ON B.EndingId=E.EndingId + WHERE Connected=SrcWord LIMIT 1 + ) + ) +} {FACTORING FACTOR SWIMMING SWIMM} + + +finish_test + From 7e02e5e6b54ea4a6b58249210c0df67af80b11a1 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 6 Dec 2011 19:44:51 +0000 Subject: [PATCH 058/161] Begin adding the data-structure explaining subsystem. All is contained within FossilOrigin-Name: 79ae51c5b1b20ed0a425a87e65a32a096a80b7e1 --- manifest | 34 +++++++------- manifest.uuid | 2 +- src/expr.c | 50 +++++++++++++++++++++ src/main.c | 14 ++++++ src/parse.y | 3 ++ src/printf.c | 6 +-- src/select.c | 103 +++++++++++++++--------------------------- src/shell.c | 9 ++++ src/sqlite.h.in | 3 +- src/sqliteInt.h | 24 ++++++++++ src/vdbeInt.h | 17 +++++++ src/vdbeaux.c | 4 ++ src/vdbetrace.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 297 insertions(+), 89 deletions(-) diff --git a/manifest b/manifest index 1fd88a2a92..a93f5c0b29 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sfile\stkt-3a77c9714e.test,\scontaining\stests\sto\sverify\sthat\sthe\sproblem\sdocumented\sby\sticket\s[3a77c9714e]\shas\sbeen\sfixed. -D 2011-12-06T13:46:54.313 +C Begin\sadding\sthe\sdata-structure\sexplaining\ssubsystem.\s\sAll\sis\scontained\swithin +D 2011-12-06T19:44:51.212 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -134,7 +134,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 51d32f0a9c880663e54ce309f52e40c325d5e112 -F src/expr.c 319db0ad9f3c5d039d54bf5a65c98c08c7233924 +F src/expr.c 942171222a30af8cf4f9504a43ef6cadaf993dae F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5 F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9 @@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f -F src/main.c 8be1ee70dd90ef7562c801dbe946a4f9f93bb128 +F src/main.c 0e0b9dd5b054ed1aa3861b257035910aff9e1842 F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 7456e2ca0524609ebc06a9befeda5289d4575ad4 @@ -170,21 +170,21 @@ F src/os_unix.c 4fbb91726165e105c1679a2660f49a3f4c376e4f F src/os_win.c 6efe66a38215c38eaa7603ee5f76848159f8669d F src/pager.c d981f3bfcc0e4460537d983899620700ccf8f539 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 -F src/parse.y d02cc7bdb9ba11fb7aa212f55f99e59e4ee55439 +F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba F src/pcache.c 1fdd77978c1525d1ca4b9ef48eb80abca710cb4c F src/pcache.h b1d8775a9bddf44e65edb0d20bfc57a4982f840f F src/pcache1.c 9d735349ac87ef08076c6b1230f04cd83b15c6da F src/pragma.c dd66f21fafe7be40e1a48ad4195764cc191cf583 F src/prepare.c ec4989f7f480544bdc4192fe663470d2a2d7d61e -F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869 +F src/printf.c 7ffb4ebb8b341f67e049695ba031da717b3d2699 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 -F src/select.c 538b5f096f6aacedf717bf982f9ad9a901008514 -F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8 -F src/sqlite.h.in 57081d8e6b53ce29541d7437c93bce6087ac53b5 +F src/select.c 2923f3129afcddb8023971ab591b07cdc868c163 +F src/shell.c a1eadb2fdbfa45e54307263f0c8da8ee8cd61b8b +F src/sqlite.h.in 1dc07194eb1a2c69c8ef75f88022b170be08024a F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 142ef5ed3fe0e6c662e99dbf92f38715b29a53b6 +F src/sqliteInt.h 96041958f4508dbc588c82298f75559ac683fe75 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -241,13 +241,13 @@ F src/util.c 01238e2b0f24a14779181dbf991fe02620a80e31 F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa F src/vdbe.c a7ab9993ec5a4d9479dc99671faec061fbf9b889 F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755 -F src/vdbeInt.h 9498fc98a2c9e349a4ef13455ff5a3e898f40176 +F src/vdbeInt.h a2b8f17783c85995f64432d6cbd546a9183a56f3 F src/vdbeapi.c 86189ebba2c49791d75eaa12929f3ce6527596bd -F src/vdbeaux.c 45713a5f8f4f36195f503b30153ddef292323f88 +F src/vdbeaux.c ed7205125304fd8aab32ab0ea975f2c1088cace5 F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 -F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 +F src/vdbetrace.c 7e5946109138ff6f7f94e79fc702755bf79373a8 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a F src/wal.c 5fe1ba55b8fab9d3936bc9093af61ab9f1c580a1 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a @@ -977,7 +977,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 092d53315e50be42b51ef7b3069c82c32a129b6a -R 8d2fc7565d4aa525192ff0541b1c9cf2 -U dan -Z d04d6b5cb95ec0b64c1e1542ea707494 +P 162421dadf93e9201c3290d800c597cbeeacdb40 +R ddbfe0a87d25503aebbe5e810f678862 +U drh +Z ed29fdae1618daadbff0e860a54f25e4 diff --git a/manifest.uuid b/manifest.uuid index 1ffea396bc..12034d7e1a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -162421dadf93e9201c3290d800c597cbeeacdb40 \ No newline at end of file +79ae51c5b1b20ed0a425a87e65a32a096a80b7e1 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index e8a9d64108..d157743ab0 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2939,6 +2939,56 @@ int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){ return inReg; } +#if defined(SQLITE_DEBUG) +/* +** Generate a human-readable explanation of an expression tree. +*/ +void sqlite3ExplainExpr(Vdbe *pOut, Expr *p){ + if( p==0 ){ + sqlite3ExplainPrintf(pOut, "(C-null)"); + return; + } + if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + sqlite3ExplainPrintf(pOut, "(%s", p->u.zToken); + }else{ + sqlite3ExplainPrintf(pOut, "(op=%d", p->op); + } + if( p->pLeft ){ + sqlite3ExplainPrintf(pOut, " left="); + sqlite3ExplainExpr(pOut, p->pLeft); + } + if( p->pRight ){ + sqlite3ExplainPrintf(pOut, " right="); + sqlite3ExplainExpr(pOut, p->pRight); + } + sqlite3ExplainPrintf(pOut, ")"); +} +#endif /* defined(SQLITE_DEBUG) */ + +#if defined(SQLITE_DEBUG) +/* +** Generate a human-readable explanation of an expression list. +*/ +void sqlite3ExplainExprList(Vdbe *pOut, ExprList *pList){ + int i; + if( pList==0 ){ + sqlite3ExplainPrintf(pOut, "(empty-list)"); + return; + } + sqlite3ExplainPush(pOut); + for(i=0; inExpr; i++){ + sqlite3ExplainPrintf(pOut, "%02d: ", i); + sqlite3ExplainPush(pOut); + sqlite3ExplainExpr(pOut, pList->a[i].pExpr); + sqlite3ExplainPop(pOut); + if( inExpr-1 ){ + sqlite3ExplainNL(pOut); + } + } + sqlite3ExplainPop(pOut); +} +#endif /* SQLITE_DEBUG */ + /* ** Return TRUE if pExpr is an constant expression that is appropriate ** for factoring out of a loop. Appropriate expressions are: diff --git a/src/main.c b/src/main.c index 8562a90727..ca98d31402 100644 --- a/src/main.c +++ b/src/main.c @@ -2936,6 +2936,20 @@ int sqlite3_test_control(int op, ...){ break; } + /* sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, + ** sqlite3_stmt*,const char**); + ** + ** If compiled with SQLITE_DEBUG, each sqlite3_stmt holds a string that + ** describes the optimized parse tree. This test-control returns a + ** pointer to that string. + */ + case SQLITE_TESTCTRL_EXPLAIN_STMT: { + sqlite3_stmt *pStmt = va_arg(ap, sqlite3_stmt*); + const char **pzRet = va_arg(ap, const char**); + *pzRet = sqlite3VdbeExplanation((Vdbe*)pStmt); + break; + } + } va_end(ap); #endif /* SQLITE_OMIT_BUILTIN_TEST */ diff --git a/src/parse.y b/src/parse.y index b838215d42..2b8e9170f3 100644 --- a/src/parse.y +++ b/src/parse.y @@ -394,6 +394,9 @@ cmd ::= DROP VIEW ifexists(E) fullname(X). { cmd ::= select(X). { SelectDest dest = {SRT_Output, 0, 0, 0, 0}; sqlite3Select(pParse, X, &dest); + sqlite3ExplainBegin(pParse->pVdbe); + sqlite3ExplainSelect(pParse->pVdbe, X); + sqlite3ExplainFinish(pParse->pVdbe); sqlite3SelectDelete(pParse->db, X); } diff --git a/src/printf.c b/src/printf.c index 0babee5141..58cfd2bd41 100644 --- a/src/printf.c +++ b/src/printf.c @@ -136,7 +136,7 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){ /* ** Append N space characters to the given string buffer. */ -static void appendSpace(StrAccum *pAccum, int N){ +void sqlite3AppendSpace(StrAccum *pAccum, int N){ static const char zSpaces[] = " "; while( N>=(int)sizeof(zSpaces)-1 ){ sqlite3StrAccumAppend(pAccum, zSpaces, sizeof(zSpaces)-1); @@ -664,7 +664,7 @@ void sqlite3VXPrintf( register int nspace; nspace = width-length; if( nspace>0 ){ - appendSpace(pAccum, nspace); + sqlite3AppendSpace(pAccum, nspace); } } if( length>0 ){ @@ -674,7 +674,7 @@ void sqlite3VXPrintf( register int nspace; nspace = width-length; if( nspace>0 ){ - appendSpace(pAccum, nspace); + sqlite3AppendSpace(pAccum, nspace); } } sqlite3_free(zExtra); diff --git a/src/select.c b/src/select.c index da75a51cd9..75b6a60e05 100644 --- a/src/select.c +++ b/src/select.c @@ -4496,96 +4496,65 @@ select_end: #if defined(SQLITE_DEBUG) /* -******************************************************************************* -** The following code is used for testing and debugging only. The code -** that follows does not appear in normal builds. -** -** These routines are used to print out the content of all or part of a -** parse structures such as Select or Expr. Such printouts are useful -** for helping to understand what is happening inside the code generator -** during the execution of complex SELECT statements. -** -** These routine are not called anywhere from within the normal -** code base. Then are intended to be called from within the debugger -** or from temporary "printf" statements inserted for debugging. +** Generate a human-readable description of a the Select object. */ -void sqlite3PrintExpr(Expr *p){ - if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ - sqlite3DebugPrintf("(%s", p->u.zToken); - }else{ - sqlite3DebugPrintf("(%d", p->op); +void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){ + if( p==0 ){ + sqlite3ExplainPrintf(pVdbe, "(empty-select)"); + return; } - if( p->pLeft ){ - sqlite3DebugPrintf(" "); - sqlite3PrintExpr(p->pLeft); - } - if( p->pRight ){ - sqlite3DebugPrintf(" "); - sqlite3PrintExpr(p->pRight); - } - sqlite3DebugPrintf(")"); -} -void sqlite3PrintExprList(ExprList *pList){ - int i; - for(i=0; inExpr; i++){ - sqlite3PrintExpr(pList->a[i].pExpr); - if( inExpr-1 ){ - sqlite3DebugPrintf(", "); - } - } -} -void sqlite3PrintSelect(Select *p, int indent){ - sqlite3DebugPrintf("%*sSELECT(%p) ", indent, "", p); - sqlite3PrintExprList(p->pEList); - sqlite3DebugPrintf("\n"); - if( p->pSrc ){ - char *zPrefix; + sqlite3ExplainPrintf(pVdbe, "SELECT "); + sqlite3ExplainPush(pVdbe); + sqlite3ExplainExprList(pVdbe, p->pEList); + sqlite3ExplainNL(pVdbe); + sqlite3ExplainPop(pVdbe); + if( p->pSrc && p->pSrc->nSrc ){ int i; - zPrefix = "FROM"; + sqlite3ExplainPrintf(pVdbe, " FROM "); + sqlite3ExplainPush(pVdbe); for(i=0; ipSrc->nSrc; i++){ struct SrcList_item *pItem = &p->pSrc->a[i]; - sqlite3DebugPrintf("%*s ", indent+6, zPrefix); - zPrefix = ""; + sqlite3ExplainPrintf(pVdbe, "%02d: ", i); + sqlite3ExplainPush(pVdbe); if( pItem->pSelect ){ - sqlite3DebugPrintf("(\n"); - sqlite3PrintSelect(pItem->pSelect, indent+10); - sqlite3DebugPrintf("%*s)", indent+8, ""); + sqlite3ExplainSelect(pVdbe, pItem->pSelect); }else if( pItem->zName ){ - sqlite3DebugPrintf("%s", pItem->zName); + sqlite3ExplainPrintf(pVdbe, "%s", pItem->zName); } if( pItem->pTab ){ - sqlite3DebugPrintf("(table: %s)", pItem->pTab->zName); + sqlite3ExplainPrintf(pVdbe, " (table: %s)", pItem->pTab->zName); } if( pItem->zAlias ){ - sqlite3DebugPrintf(" AS %s", pItem->zAlias); + sqlite3ExplainPrintf(pVdbe, " (AS %s)", pItem->zAlias); } - if( ipSrc->nSrc-1 ){ - sqlite3DebugPrintf(","); - } - sqlite3DebugPrintf("\n"); + sqlite3ExplainNL(pVdbe); + sqlite3ExplainPop(pVdbe); } + sqlite3ExplainPop(pVdbe); } if( p->pWhere ){ - sqlite3DebugPrintf("%*s WHERE ", indent, ""); - sqlite3PrintExpr(p->pWhere); - sqlite3DebugPrintf("\n"); + sqlite3ExplainPrintf(pVdbe, " WHERE "); + sqlite3ExplainExpr(pVdbe, p->pWhere); + sqlite3ExplainNL(pVdbe); } if( p->pGroupBy ){ - sqlite3DebugPrintf("%*s GROUP BY ", indent, ""); - sqlite3PrintExprList(p->pGroupBy); - sqlite3DebugPrintf("\n"); + sqlite3ExplainPrintf(pVdbe, " GROUP BY "); + sqlite3ExplainExprList(pVdbe, p->pGroupBy); + sqlite3ExplainNL(pVdbe); } if( p->pHaving ){ - sqlite3DebugPrintf("%*s HAVING ", indent, ""); - sqlite3PrintExpr(p->pHaving); - sqlite3DebugPrintf("\n"); + sqlite3ExplainPrintf(pVdbe, "HAVING "); + sqlite3ExplainExpr(pVdbe, p->pHaving); + sqlite3ExplainNL(pVdbe); } if( p->pOrderBy ){ - sqlite3DebugPrintf("%*s ORDER BY ", indent, ""); - sqlite3PrintExprList(p->pOrderBy); - sqlite3DebugPrintf("\n"); + sqlite3ExplainPrintf(pVdbe, " ORDER BY "); + sqlite3ExplainExprList(pVdbe, p->pOrderBy); + sqlite3ExplainNL(pVdbe); } + sqlite3ExplainPrintf(pVdbe, " END"); } + /* End of the structure debug printing code *****************************************************************************/ #endif /* defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */ diff --git a/src/shell.c b/src/shell.c index e33a0687b4..93ed9a6db3 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1127,6 +1127,15 @@ static int shell_exec( fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql); } + /* Output TESTCTRL_EXPLAIN text of requested */ + if( pArg && pArg->mode==MODE_Explain ){ + const char *zExplain = 0; + sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain); + if( zExplain && zExplain[0] ){ + fprintf(pArg->out, "%s", zExplain); + } + } + /* perform the first step. this will tell us if we ** have a result set or not and how wide it is. */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index bd5b41f431..8c9e220e0e 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5682,7 +5682,8 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_ISKEYWORD 16 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 -#define SQLITE_TESTCTRL_LAST 18 +#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 +#define SQLITE_TESTCTRL_LAST 19 /* ** CAPI3REF: SQLite Runtime Status diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 890f44f5e1..1e7af8e342 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2650,6 +2650,29 @@ char *sqlite3MAppendf(sqlite3*,char*,const char*,...); #if defined(SQLITE_TEST) void *sqlite3TestTextToPtr(const char*); #endif + +/* Output formatting for SQLITE_TESTCTRL_EXPLAIN */ +#if defined(SQLITE_DEBUG) + void sqlite3ExplainBegin(Vdbe*); + void sqlite3ExplainPrintf(Vdbe*, const char*, ...); + void sqlite3ExplainNL(Vdbe*); + void sqlite3ExplainPush(Vdbe*); + void sqlite3ExplainPop(Vdbe*); + void sqlite3ExplainFinish(Vdbe*); + void sqlite3ExplainSelect(Vdbe*, Select*); + void sqlite3ExplainExpr(Vdbe*, Expr*); + void sqlite3ExplainExprList(Vdbe*, ExprList*); + const char *sqlite3VdbeExplanation(Vdbe*); +#else +# define sqlite3ExplainBegin(X) +# define sqlite3ExplainSelect(A,B) +# define sqlite3ExplainExpr(A,B) +# define sqlite3ExplainExprList(A,B) +# define sqlite3ExplainFinish(X) +# define sqlite3VdbeExplanation(X) 0 +#endif + + void sqlite3SetString(char **, sqlite3*, const char*, ...); void sqlite3ErrorMsg(Parse*, const char*, ...); int sqlite3Dequote(char*); @@ -3030,6 +3053,7 @@ int sqlite3OpenTempDatabase(Parse *); void sqlite3StrAccumInit(StrAccum*, char*, int, int); void sqlite3StrAccumAppend(StrAccum*,const char*,int); +void sqlite3AppendSpace(StrAccum*,int); char *sqlite3StrAccumFinish(StrAccum*); void sqlite3StrAccumReset(StrAccum*); void sqlite3SelectDestInit(SelectDest*,int,int); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 803ae1630e..44071e6851 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -33,6 +33,9 @@ typedef unsigned char Bool; /* Opaque type used by code in vdbesort.c */ typedef struct VdbeSorter VdbeSorter; +/* Opaque type used by the explainer */ +typedef struct Explain Explain; + /* ** A cursor is a pointer into a single BTree within a database file. ** The cursor can seek to a BTree entry with a particular key, or @@ -255,6 +258,18 @@ struct sqlite3_context { CollSeq *pColl; /* Collating sequence */ }; +/* +** An Explain object accumulates indented output which is helpful +** in describing recursive data structures. +*/ +struct Explain { + Vdbe *pVdbe; /* Attach the explanation to this Vdbe */ + StrAccum str; /* The string being accumulated */ + int nIndent; /* Number of elements in aIndent */ + u16 aIndent[100]; /* Levels of indentation */ + char zBase[100]; /* Initial space */ +}; + /* ** An instance of the virtual machine. This structure contains the complete ** state of the virtual machine. @@ -320,6 +335,8 @@ struct Vdbe { void *pFree; /* Free this when deleting the vdbe */ #ifdef SQLITE_DEBUG FILE *trace; /* Write an execution trace here, if not NULL */ + Explain *pExplain; /* The explainer */ + char *zExplain; /* Explanation of data structures */ #endif VdbeFrame *pFrame; /* Parent frame */ VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7c69d28cf6..510248a5f7 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2464,6 +2464,10 @@ void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){ sqlite3DbFree(db, p->aColName); sqlite3DbFree(db, p->zSql); sqlite3DbFree(db, p->pFree); +#if defined(SQLITE_DEBUG) + sqlite3_free(p->zExplain); + sqlite3_free(p->pExplain); +#endif sqlite3DbFree(db, p); } diff --git a/src/vdbetrace.c b/src/vdbetrace.c index de123b550f..bc05e5897a 100644 --- a/src/vdbetrace.c +++ b/src/vdbetrace.c @@ -12,6 +12,8 @@ ** ** This file contains code used to insert the values of host parameters ** (aka "wildcards") into the SQL text output by sqlite3_trace(). +** +** The Vdbe explainer is also found here. */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -152,3 +154,118 @@ char *sqlite3VdbeExpandSql( } #endif /* #ifndef SQLITE_OMIT_TRACE */ + +/***************************************************************************** +** The following code implements the data-structure explaining logic +** for the Vdbe. +*/ + +#if defined(SQLITE_DEBUG) + +/* +** Allocate a new Explain object +*/ +void sqlite3ExplainBegin(Vdbe *pVdbe){ + if( pVdbe ){ + sqlite3BeginBenignMalloc(); + Explain *p = sqlite3_malloc( sizeof(Explain) ); + if( p ){ + memset(p, 0, sizeof(*p)); + p->pVdbe = pVdbe; + sqlite3_free(pVdbe->pExplain); + pVdbe->pExplain = p; + sqlite3StrAccumInit(&p->str, p->zBase, sizeof(p->zBase), + SQLITE_MAX_LENGTH); + p->str.useMalloc = 2; + }else{ + sqlite3EndBenignMalloc(); + } + } +} + +/* +** Return true if the Explain ends with a new-line. +*/ +static int endsWithNL(Explain *p){ + return p && p->str.zText && p->str.nChar + && p->str.zText[p->str.nChar-1]=='\n'; +} + +/* +** Append text to the indentation +*/ +void sqlite3ExplainPrintf(Vdbe *pVdbe, const char *zFormat, ...){ + Explain *p; + if( pVdbe && (p = pVdbe->pExplain)!=0 ){ + va_list ap; + if( p->nIndent && endsWithNL(p) ){ + int n = p->nIndent; + if( n>ArraySize(p->aIndent) ) n = ArraySize(p->aIndent); + sqlite3AppendSpace(&p->str, p->aIndent[n-1]); + } + va_start(ap, zFormat); + sqlite3VXPrintf(&p->str, 1, zFormat, ap); + va_end(ap); + } +} + +/* +** Append a '\n' if there is not already one. +*/ +void sqlite3ExplainNL(Vdbe *pVdbe){ + Explain *p; + if( pVdbe && (p = pVdbe->pExplain)!=0 && !endsWithNL(p) ){ + sqlite3StrAccumAppend(&p->str, "\n", 1); + } +} + +/* +** Push a new indentation level. Subsequent lines will be indented +** so that they begin at the current cursor position. +*/ +void sqlite3ExplainPush(Vdbe *pVdbe){ + Explain *p; + if( pVdbe && (p = pVdbe->pExplain)!=0 ){ + if( p->str.zText && p->nIndentaIndent) ){ + const char *z = p->str.zText; + int i = p->str.nChar-1; + int x; + while( i>=0 && z[i]!='\n' ){ i--; } + x = (p->str.nChar - 1) - i; + if( p->nIndent && xaIndent[p->nIndent-1] ){ + x = p->aIndent[p->nIndent-1]; + } + p->aIndent[p->nIndent] = x; + } + p->nIndent++; + } +} + +/* +** Pop the indentation stack by one level. +*/ +void sqlite3ExplainPop(Vdbe *p){ + if( p && p->pExplain ) p->pExplain->nIndent--; +} + +/* +** Free the indentation structure +*/ +void sqlite3ExplainFinish(Vdbe *pVdbe){ + if( pVdbe && pVdbe->pExplain ){ + sqlite3_free(pVdbe->zExplain); + sqlite3ExplainNL(pVdbe); + pVdbe->zExplain = sqlite3StrAccumFinish(&pVdbe->pExplain->str); + sqlite3_free(pVdbe->pExplain); + pVdbe->pExplain = 0; + sqlite3EndBenignMalloc(); + } +} + +/* +** Return the explanation of a virtual machine. +*/ +const char *sqlite3VdbeExplanation(Vdbe *pVdbe){ + return (pVdbe && pVdbe->zExplain) ? pVdbe->zExplain : 0; +} +#endif /* defined(SQLITE_DEBUG) */ From a84203a0749e49cfff15fb99588a0158b6fd085e Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 7 Dec 2011 01:23:51 +0000 Subject: [PATCH 059/161] Improvements to the data-structure explain subsystem. Most queries now give a reasonably detailed graph of their parse tree. FossilOrigin-Name: 0aa7d3d2346bdddcc4e1e25ee26d13c8594885e5 --- manifest | 14 +-- manifest.uuid | 2 +- src/expr.c | 266 +++++++++++++++++++++++++++++++++++++++++++++----- src/select.c | 54 +++++++--- 4 files changed, 287 insertions(+), 49 deletions(-) diff --git a/manifest b/manifest index a93f5c0b29..e924999ec2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Begin\sadding\sthe\sdata-structure\sexplaining\ssubsystem.\s\sAll\sis\scontained\swithin -D 2011-12-06T19:44:51.212 +C Improvements\sto\sthe\sdata-structure\sexplain\ssubsystem.\s\sMost\squeries\snow\ngive\sa\sreasonably\sdetailed\sgraph\sof\stheir\sparse\stree. +D 2011-12-07T01:23:51.800 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -134,7 +134,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 51d32f0a9c880663e54ce309f52e40c325d5e112 -F src/expr.c 942171222a30af8cf4f9504a43ef6cadaf993dae +F src/expr.c 62f6ad2a1dcfbf684e6916c0662d5b4f28b98346 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5 F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9 @@ -180,7 +180,7 @@ F src/printf.c 7ffb4ebb8b341f67e049695ba031da717b3d2699 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 -F src/select.c 2923f3129afcddb8023971ab591b07cdc868c163 +F src/select.c 352ac58d6070f9a5564e9648bc2202b9d6339747 F src/shell.c a1eadb2fdbfa45e54307263f0c8da8ee8cd61b8b F src/sqlite.h.in 1dc07194eb1a2c69c8ef75f88022b170be08024a F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 @@ -977,7 +977,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 162421dadf93e9201c3290d800c597cbeeacdb40 -R ddbfe0a87d25503aebbe5e810f678862 +P 79ae51c5b1b20ed0a425a87e65a32a096a80b7e1 +R 33f29d39c143746ce94119c4aaec65fd U drh -Z ed29fdae1618daadbff0e860a54f25e4 +Z 8a3e65c823a12538f790d9d174308040 diff --git a/manifest.uuid b/manifest.uuid index 12034d7e1a..dbbd003458 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -79ae51c5b1b20ed0a425a87e65a32a096a80b7e1 \ No newline at end of file +0aa7d3d2346bdddcc4e1e25ee26d13c8594885e5 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index d157743ab0..0d217ed405 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2943,25 +2943,238 @@ int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){ /* ** Generate a human-readable explanation of an expression tree. */ -void sqlite3ExplainExpr(Vdbe *pOut, Expr *p){ - if( p==0 ){ - sqlite3ExplainPrintf(pOut, "(C-null)"); - return; - } - if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ - sqlite3ExplainPrintf(pOut, "(%s", p->u.zToken); +void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){ + int op; /* The opcode being coded */ + const char *zBinOp = 0; /* Binary operator */ + const char *zUniOp = 0; /* Unary operator */ + if( pExpr==0 ){ + op = TK_NULL; }else{ - sqlite3ExplainPrintf(pOut, "(op=%d", p->op); + op = pExpr->op; } - if( p->pLeft ){ - sqlite3ExplainPrintf(pOut, " left="); - sqlite3ExplainExpr(pOut, p->pLeft); + switch( op ){ + case TK_AGG_COLUMN: { + sqlite3ExplainPrintf(pOut, "AGG_COLUMN(%s:%d:%d)", + pExpr->pTab->zName, pExpr->iTable, pExpr->iColumn); + break; + } + case TK_COLUMN: { + if( pExpr->iTable<0 ){ + /* This only happens when coding check constraints */ + sqlite3ExplainPrintf(pOut, "COLUMN(%d)", pExpr->iColumn); + }else{ + sqlite3ExplainPrintf(pOut, "COLUMN(%s:%d:%d)", + pExpr->pTab->zName, pExpr->iTable, pExpr->iColumn); + } + break; + } + case TK_INTEGER: { + if( pExpr->flags & EP_IntValue ){ + sqlite3ExplainPrintf(pOut, "INTEGER(%d)", pExpr->u.iValue); + }else{ + sqlite3ExplainPrintf(pOut, "INTEGER(%s)", pExpr->u.zToken); + } + break; + } +#ifndef SQLITE_OMIT_FLOATING_POINT + case TK_FLOAT: { + sqlite3ExplainPrintf(pOut,"REAL(%s)", pExpr->u.zToken); + break; + } +#endif + case TK_STRING: { + sqlite3ExplainPrintf(pOut,"STRING(%s)", pExpr->u.zToken); + break; + } + case TK_NULL: { + sqlite3ExplainPrintf(pOut,"NULL"); + break; + } +#ifndef SQLITE_OMIT_BLOB_LITERAL + case TK_BLOB: { + int n; + const char *z; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); + assert( pExpr->u.zToken[1]=='\'' ); + z = &pExpr->u.zToken[2]; + n = sqlite3Strlen30(z) - 1; + assert( z[n]=='\'' ); + sqlite3ExplainPrintf(pOut,"BLOB(%.*s)", n, z); + break; + } +#endif + case TK_VARIABLE: { + sqlite3ExplainPrintf(pOut,"VARIABLE(%s,%d)", + pExpr->u.zToken, pExpr->iColumn); + break; + } + case TK_REGISTER: { + sqlite3ExplainPrintf(pOut,"REGISTER(%d)", pExpr->iTable); + break; + } + case TK_AS: { + sqlite3ExplainExpr(pOut, pExpr->pLeft); + break; + } +#ifndef SQLITE_OMIT_CAST + case TK_CAST: { + /* Expressions of the form: CAST(pLeft AS token) */ + const char *zAff = "unk"; + switch( sqlite3AffinityType(pExpr->u.zToken) ){ + case SQLITE_AFF_TEXT: zAff = "TEXT"; break; + case SQLITE_AFF_NONE: zAff = "NONE"; break; + case SQLITE_AFF_NUMERIC: zAff = "NUMERIC"; break; + case SQLITE_AFF_INTEGER: zAff = "INTEGER"; break; + case SQLITE_AFF_REAL: zAff = "REAL"; break; + } + sqlite3ExplainPrintf(pOut, "CAST-%s(", zAff); + sqlite3ExplainExpr(pOut, pExpr->pLeft); + sqlite3ExplainPrintf(pOut, ")"); + break; + } +#endif /* SQLITE_OMIT_CAST */ + case TK_LT: zBinOp = "LT"; break; + case TK_LE: zBinOp = "LE"; break; + case TK_GT: zBinOp = "GT"; break; + case TK_GE: zBinOp = "GE"; break; + case TK_NE: zBinOp = "NE"; break; + case TK_EQ: zBinOp = "EQ"; break; + case TK_IS: zBinOp = "IS"; break; + case TK_ISNOT: zBinOp = "ISNOT"; break; + case TK_AND: zBinOp = "AND"; break; + case TK_OR: zBinOp = "OR"; break; + case TK_PLUS: zBinOp = "ADD"; break; + case TK_STAR: zBinOp = "MUL"; break; + case TK_MINUS: zBinOp = "SUB"; break; + case TK_REM: zBinOp = "REM"; break; + case TK_BITAND: zBinOp = "BITAND"; break; + case TK_BITOR: zBinOp = "BITOR"; break; + case TK_SLASH: zBinOp = "DIV"; break; + case TK_LSHIFT: zBinOp = "LSHIFT"; break; + case TK_RSHIFT: zBinOp = "RSHIFT"; break; + case TK_CONCAT: zBinOp = "CONCAT"; break; + + case TK_UMINUS: zUniOp = "UMINUS"; break; + case TK_UPLUS: zUniOp = "UPLUS"; break; + case TK_BITNOT: zUniOp = "BITNOT"; break; + case TK_NOT: zUniOp = "NOT"; break; + case TK_ISNULL: zUniOp = "ISNULL"; break; + case TK_NOTNULL: zUniOp = "NOTNULL"; break; + + case TK_AGG_FUNCTION: + case TK_CONST_FUNC: + case TK_FUNCTION: { + ExprList *pFarg; /* List of function arguments */ + if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){ + pFarg = 0; + }else{ + pFarg = pExpr->x.pList; + } + sqlite3ExplainPrintf(pOut, "%sFUNCTION:%s(", + op==TK_AGG_FUNCTION ? "AGG_" : "", + pExpr->u.zToken); + if( pFarg ){ + sqlite3ExplainExprList(pOut, pFarg); + } + sqlite3ExplainPrintf(pOut, ")"); + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_EXISTS: { + sqlite3ExplainPrintf(pOut, "EXISTS("); + sqlite3ExplainSelect(pOut, pExpr->x.pSelect); + sqlite3ExplainPrintf(pOut,")"); + break; + } + case TK_SELECT: { + sqlite3ExplainPrintf(pOut, "("); + sqlite3ExplainSelect(pOut, pExpr->x.pSelect); + sqlite3ExplainPrintf(pOut, ")"); + break; + } + case TK_IN: { + sqlite3ExplainPrintf(pOut, "IN("); + sqlite3ExplainExpr(pOut, pExpr->pLeft); + sqlite3ExplainPrintf(pOut, ","); + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + sqlite3ExplainSelect(pOut, pExpr->x.pSelect); + }else{ + sqlite3ExplainExprList(pOut, pExpr->x.pList); + } + sqlite3ExplainPrintf(pOut, ")"); + break; + } +#endif /* SQLITE_OMIT_SUBQUERY */ + + /* + ** x BETWEEN y AND z + ** + ** This is equivalent to + ** + ** x>=y AND x<=z + ** + ** X is stored in pExpr->pLeft. + ** Y is stored in pExpr->pList->a[0].pExpr. + ** Z is stored in pExpr->pList->a[1].pExpr. + */ + case TK_BETWEEN: { + Expr *pX = pExpr->pLeft; + Expr *pY = pExpr->x.pList->a[0].pExpr; + Expr *pZ = pExpr->x.pList->a[1].pExpr; + sqlite3ExplainPrintf(pOut, "BETWEEN("); + sqlite3ExplainExpr(pOut, pX); + sqlite3ExplainPrintf(pOut, ","); + sqlite3ExplainExpr(pOut, pY); + sqlite3ExplainPrintf(pOut, ","); + sqlite3ExplainExpr(pOut, pZ); + sqlite3ExplainPrintf(pOut, ")"); + break; + } + case TK_TRIGGER: { + /* If the opcode is TK_TRIGGER, then the expression is a reference + ** to a column in the new.* or old.* pseudo-tables available to + ** trigger programs. In this case Expr.iTable is set to 1 for the + ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn + ** is set to the column of the pseudo-table to read, or to -1 to + ** read the rowid field. + */ + sqlite3ExplainPrintf(pOut, "%s(%d)", + pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn); + break; + } + case TK_CASE: { + sqlite3ExplainPrintf(pOut, "CASE("); + sqlite3ExplainExpr(pOut, pExpr->pLeft); + sqlite3ExplainPrintf(pOut, ","); + sqlite3ExplainExprList(pOut, pExpr->x.pList); + break; + } +#ifndef SQLITE_OMIT_TRIGGER + case TK_RAISE: { + const char *zType = "unk"; + switch( pExpr->affinity ){ + case OE_Rollback: zType = "rollback"; break; + case OE_Abort: zType = "abort"; break; + case OE_Fail: zType = "fail"; break; + case OE_Ignore: zType = "ignore"; break; + } + sqlite3ExplainPrintf(pOut, "RAISE-%s(%s)", zType, pExpr->u.zToken); + break; + } +#endif } - if( p->pRight ){ - sqlite3ExplainPrintf(pOut, " right="); - sqlite3ExplainExpr(pOut, p->pRight); + if( zBinOp ){ + sqlite3ExplainPrintf(pOut,"%s(", zBinOp); + sqlite3ExplainExpr(pOut, pExpr->pLeft); + sqlite3ExplainPrintf(pOut,","); + sqlite3ExplainExpr(pOut, pExpr->pRight); + sqlite3ExplainPrintf(pOut,")"); + }else if( zUniOp ){ + sqlite3ExplainPrintf(pOut,"%s(", zUniOp); + sqlite3ExplainExpr(pOut, pExpr->pLeft); + sqlite3ExplainPrintf(pOut,")"); } - sqlite3ExplainPrintf(pOut, ")"); } #endif /* defined(SQLITE_DEBUG) */ @@ -2971,21 +3184,24 @@ void sqlite3ExplainExpr(Vdbe *pOut, Expr *p){ */ void sqlite3ExplainExprList(Vdbe *pOut, ExprList *pList){ int i; - if( pList==0 ){ + if( pList==0 || pList->nExpr==0 ){ sqlite3ExplainPrintf(pOut, "(empty-list)"); return; - } - sqlite3ExplainPush(pOut); - for(i=0; inExpr; i++){ - sqlite3ExplainPrintf(pOut, "%02d: ", i); + }else if( pList->nExpr==1 ){ + sqlite3ExplainExpr(pOut, pList->a[0].pExpr); + }else{ sqlite3ExplainPush(pOut); - sqlite3ExplainExpr(pOut, pList->a[i].pExpr); - sqlite3ExplainPop(pOut); - if( inExpr-1 ){ - sqlite3ExplainNL(pOut); + for(i=0; inExpr; i++){ + sqlite3ExplainPrintf(pOut, "item[%d] = ", i); + sqlite3ExplainPush(pOut); + sqlite3ExplainExpr(pOut, pList->a[i].pExpr); + sqlite3ExplainPop(pOut); + if( inExpr-1 ){ + sqlite3ExplainNL(pOut); + } } + sqlite3ExplainPop(pOut); } - sqlite3ExplainPop(pOut); } #endif /* SQLITE_DEBUG */ diff --git a/src/select.c b/src/select.c index 75b6a60e05..539e4156a1 100644 --- a/src/select.c +++ b/src/select.c @@ -4498,47 +4498,43 @@ select_end: /* ** Generate a human-readable description of a the Select object. */ -void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){ - if( p==0 ){ - sqlite3ExplainPrintf(pVdbe, "(empty-select)"); - return; - } +static void explainOneSelect(Vdbe *pVdbe, Select *p){ sqlite3ExplainPrintf(pVdbe, "SELECT "); - sqlite3ExplainPush(pVdbe); sqlite3ExplainExprList(pVdbe, p->pEList); sqlite3ExplainNL(pVdbe); - sqlite3ExplainPop(pVdbe); if( p->pSrc && p->pSrc->nSrc ){ int i; - sqlite3ExplainPrintf(pVdbe, " FROM "); + sqlite3ExplainPrintf(pVdbe, "FROM "); sqlite3ExplainPush(pVdbe); for(i=0; ipSrc->nSrc; i++){ struct SrcList_item *pItem = &p->pSrc->a[i]; - sqlite3ExplainPrintf(pVdbe, "%02d: ", i); - sqlite3ExplainPush(pVdbe); + sqlite3ExplainPrintf(pVdbe, "src[%d] = ", i); if( pItem->pSelect ){ sqlite3ExplainSelect(pVdbe, pItem->pSelect); }else if( pItem->zName ){ sqlite3ExplainPrintf(pVdbe, "%s", pItem->zName); } if( pItem->pTab ){ - sqlite3ExplainPrintf(pVdbe, " (table: %s)", pItem->pTab->zName); + sqlite3ExplainPrintf(pVdbe, " (name=%s:%d)", + pItem->pTab->zName, pItem->iCursor); + } + if( pItem->jointype & JT_LEFT ){ + sqlite3ExplainPrintf(pVdbe, " LEFT-JOIN"); } if( pItem->zAlias ){ sqlite3ExplainPrintf(pVdbe, " (AS %s)", pItem->zAlias); } sqlite3ExplainNL(pVdbe); - sqlite3ExplainPop(pVdbe); } sqlite3ExplainPop(pVdbe); } if( p->pWhere ){ - sqlite3ExplainPrintf(pVdbe, " WHERE "); + sqlite3ExplainPrintf(pVdbe, "WHERE "); sqlite3ExplainExpr(pVdbe, p->pWhere); sqlite3ExplainNL(pVdbe); } if( p->pGroupBy ){ - sqlite3ExplainPrintf(pVdbe, " GROUP BY "); + sqlite3ExplainPrintf(pVdbe, "GROUPBY "); sqlite3ExplainExprList(pVdbe, p->pGroupBy); sqlite3ExplainNL(pVdbe); } @@ -4548,11 +4544,37 @@ void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){ sqlite3ExplainNL(pVdbe); } if( p->pOrderBy ){ - sqlite3ExplainPrintf(pVdbe, " ORDER BY "); + sqlite3ExplainPrintf(pVdbe, "ORDERBY "); sqlite3ExplainExprList(pVdbe, p->pOrderBy); sqlite3ExplainNL(pVdbe); } - sqlite3ExplainPrintf(pVdbe, " END"); + if( p->pLimit ){ + sqlite3ExplainPrintf(pVdbe, "LIMIT "); + sqlite3ExplainExpr(pVdbe, p->pLimit); + sqlite3ExplainNL(pVdbe); + } + if( p->pOffset ){ + sqlite3ExplainPrintf(pVdbe, "OFFSET "); + sqlite3ExplainExpr(pVdbe, p->pOffset); + sqlite3ExplainNL(pVdbe); + } +} +void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){ + if( p==0 ){ + sqlite3ExplainPrintf(pVdbe, "(null-select)"); + return; + } + while( p->pPrior ) p = p->pPrior; + sqlite3ExplainPush(pVdbe); + while( p ){ + explainOneSelect(pVdbe, p); + p = p->pNext; + if( p==0 ) break; + sqlite3ExplainNL(pVdbe); + sqlite3ExplainPrintf(pVdbe, "%s\n", selectOpName(p->op)); + } + sqlite3ExplainPrintf(pVdbe, "END"); + sqlite3ExplainPop(pVdbe); } /* End of the structure debug printing code From e7e6a54504d246345e79384a5d28f11f18878b84 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 7 Dec 2011 01:47:27 +0000 Subject: [PATCH 060/161] Bug fix in sqlite3SelectDup(). Make sure the pNext pointer is valid. FossilOrigin-Name: 7e5b56b1c602d4adfd4496a9c877f3b685b2d360 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e924999ec2..8900db8ee7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\sdata-structure\sexplain\ssubsystem.\s\sMost\squeries\snow\ngive\sa\sreasonably\sdetailed\sgraph\sof\stheir\sparse\stree. -D 2011-12-07T01:23:51.800 +C Bug\sfix\sin\ssqlite3SelectDup().\s\sMake\ssure\sthe\spNext\spointer\sis\svalid. +D 2011-12-07T01:47:27.299 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -134,7 +134,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 51d32f0a9c880663e54ce309f52e40c325d5e112 -F src/expr.c 62f6ad2a1dcfbf684e6916c0662d5b4f28b98346 +F src/expr.c 3d800a2280d1ea4eab33ab500af59ebb7b878e64 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5 F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9 @@ -977,7 +977,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 79ae51c5b1b20ed0a425a87e65a32a096a80b7e1 -R 33f29d39c143746ce94119c4aaec65fd +P 0aa7d3d2346bdddcc4e1e25ee26d13c8594885e5 +R 8f6a328e6230a075adb0590e80910ddf U drh -Z 8a3e65c823a12538f790d9d174308040 +Z 657cde2c7390fad792d576ed9952c864 diff --git a/manifest.uuid b/manifest.uuid index dbbd003458..e28fee5f60 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0aa7d3d2346bdddcc4e1e25ee26d13c8594885e5 \ No newline at end of file +7e5b56b1c602d4adfd4496a9c877f3b685b2d360 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 0d217ed405..09f07abf42 100644 --- a/src/expr.c +++ b/src/expr.c @@ -940,7 +940,7 @@ IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ return pNew; } Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ - Select *pNew; + Select *pNew, *pPrior; if( p==0 ) return 0; pNew = sqlite3DbMallocRaw(db, sizeof(*p) ); if( pNew==0 ) return 0; @@ -951,7 +951,9 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags); pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags); pNew->op = p->op; - pNew->pPrior = sqlite3SelectDup(db, p->pPrior, flags); + pNew->pPrior = pPrior = sqlite3SelectDup(db, p->pPrior, flags); + if( pPrior ) pPrior->pNext = pNew; + pNew->pNext = 0; pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags); pNew->iLimit = 0; From 23b1b37229b8f28c70d3711228ef58cb7a370b0b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 7 Dec 2011 01:55:51 +0000 Subject: [PATCH 061/161] Cherrypick the [7e5b56b1c6] fix for the sqlite3SelectDup() routine into trunk. FossilOrigin-Name: 7fc535090ca3416706dff4abce10ac2d7f775e02 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 6 ++++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 1fd88a2a92..e309ac01b1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sfile\stkt-3a77c9714e.test,\scontaining\stests\sto\sverify\sthat\sthe\sproblem\sdocumented\sby\sticket\s[3a77c9714e]\shas\sbeen\sfixed. -D 2011-12-06T13:46:54.313 +C Cherrypick\sthe\s[7e5b56b1c6]\sfix\sfor\sthe\ssqlite3SelectDup()\sroutine\s\ninto\strunk. +D 2011-12-07T01:55:51.485 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -134,7 +134,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 51d32f0a9c880663e54ce309f52e40c325d5e112 -F src/expr.c 319db0ad9f3c5d039d54bf5a65c98c08c7233924 +F src/expr.c 9ac5831769dddee6a55b07cdd439b21929bbe4e7 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5 F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9 @@ -977,7 +977,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 092d53315e50be42b51ef7b3069c82c32a129b6a -R 8d2fc7565d4aa525192ff0541b1c9cf2 -U dan -Z d04d6b5cb95ec0b64c1e1542ea707494 +P 162421dadf93e9201c3290d800c597cbeeacdb40 +R d17736709c9e1055d62b7d5dd5010549 +U drh +Z 01f1b62cbb252e00fe26739b3bf9a3e5 diff --git a/manifest.uuid b/manifest.uuid index 1ffea396bc..f9ed373759 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -162421dadf93e9201c3290d800c597cbeeacdb40 \ No newline at end of file +7fc535090ca3416706dff4abce10ac2d7f775e02 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index e8a9d64108..136f302f90 100644 --- a/src/expr.c +++ b/src/expr.c @@ -940,7 +940,7 @@ IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ return pNew; } Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ - Select *pNew; + Select *pNew, *pPrior; if( p==0 ) return 0; pNew = sqlite3DbMallocRaw(db, sizeof(*p) ); if( pNew==0 ) return 0; @@ -951,7 +951,9 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags); pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags); pNew->op = p->op; - pNew->pPrior = sqlite3SelectDup(db, p->pPrior, flags); + pNew->pPrior = pPrior = sqlite3SelectDup(db, p->pPrior, flags); + if( pPrior ) pPrior->pNext = pNew; + pNew->pNext = 0; pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags); pNew->iLimit = 0; From 04b8342b8313dc7fe57a93a2cc7a2e9e5a2afd26 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 7 Dec 2011 15:33:14 +0000 Subject: [PATCH 062/161] More compact notation for the parse-tree view. FossilOrigin-Name: 0eb3f8b1e3a196811fb54a5e2645debe6119610a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 26 +++++++++----------------- src/select.c | 13 ++++++------- 4 files changed, 23 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index 8900db8ee7..69c5847820 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Bug\sfix\sin\ssqlite3SelectDup().\s\sMake\ssure\sthe\spNext\spointer\sis\svalid. -D 2011-12-07T01:47:27.299 +C More\scompact\snotation\sfor\sthe\sparse-tree\sview. +D 2011-12-07T15:33:14.109 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -134,7 +134,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 51d32f0a9c880663e54ce309f52e40c325d5e112 -F src/expr.c 3d800a2280d1ea4eab33ab500af59ebb7b878e64 +F src/expr.c 59a530af612b95d4d29c066bf81f12def813d16d F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5 F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9 @@ -180,7 +180,7 @@ F src/printf.c 7ffb4ebb8b341f67e049695ba031da717b3d2699 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 -F src/select.c 352ac58d6070f9a5564e9648bc2202b9d6339747 +F src/select.c 984ff4d2865fbf13a0ddeedbf892a93094f2b9dd F src/shell.c a1eadb2fdbfa45e54307263f0c8da8ee8cd61b8b F src/sqlite.h.in 1dc07194eb1a2c69c8ef75f88022b170be08024a F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 @@ -977,7 +977,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 0aa7d3d2346bdddcc4e1e25ee26d13c8594885e5 -R 8f6a328e6230a075adb0590e80910ddf +P 7e5b56b1c602d4adfd4496a9c877f3b685b2d360 +R 7004d54e96eda502d15d7553ec65e84c U drh -Z 657cde2c7390fad792d576ed9952c864 +Z 6c7ae5dd374ffa9280bde6b5186b14b5 diff --git a/manifest.uuid b/manifest.uuid index e28fee5f60..870fbb8eb1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7e5b56b1c602d4adfd4496a9c877f3b685b2d360 \ No newline at end of file +0eb3f8b1e3a196811fb54a5e2645debe6119610a \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 09f07abf42..6af583ce0a 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2956,8 +2956,8 @@ void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){ } switch( op ){ case TK_AGG_COLUMN: { - sqlite3ExplainPrintf(pOut, "AGG_COLUMN(%s:%d:%d)", - pExpr->pTab->zName, pExpr->iTable, pExpr->iColumn); + sqlite3ExplainPrintf(pOut, "AGG{%d:%d}", + pExpr->iTable, pExpr->iColumn); break; } case TK_COLUMN: { @@ -2965,27 +2965,27 @@ void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){ /* This only happens when coding check constraints */ sqlite3ExplainPrintf(pOut, "COLUMN(%d)", pExpr->iColumn); }else{ - sqlite3ExplainPrintf(pOut, "COLUMN(%s:%d:%d)", - pExpr->pTab->zName, pExpr->iTable, pExpr->iColumn); + sqlite3ExplainPrintf(pOut, "{%d:%d}", + pExpr->iTable, pExpr->iColumn); } break; } case TK_INTEGER: { if( pExpr->flags & EP_IntValue ){ - sqlite3ExplainPrintf(pOut, "INTEGER(%d)", pExpr->u.iValue); + sqlite3ExplainPrintf(pOut, "%d", pExpr->u.iValue); }else{ - sqlite3ExplainPrintf(pOut, "INTEGER(%s)", pExpr->u.zToken); + sqlite3ExplainPrintf(pOut, "%s", pExpr->u.zToken); } break; } #ifndef SQLITE_OMIT_FLOATING_POINT case TK_FLOAT: { - sqlite3ExplainPrintf(pOut,"REAL(%s)", pExpr->u.zToken); + sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken); break; } #endif case TK_STRING: { - sqlite3ExplainPrintf(pOut,"STRING(%s)", pExpr->u.zToken); + sqlite3ExplainPrintf(pOut,"%Q", pExpr->u.zToken); break; } case TK_NULL: { @@ -2994,15 +2994,7 @@ void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){ } #ifndef SQLITE_OMIT_BLOB_LITERAL case TK_BLOB: { - int n; - const char *z; - assert( !ExprHasProperty(pExpr, EP_IntValue) ); - assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); - assert( pExpr->u.zToken[1]=='\'' ); - z = &pExpr->u.zToken[2]; - n = sqlite3Strlen30(z) - 1; - assert( z[n]=='\'' ); - sqlite3ExplainPrintf(pOut,"BLOB(%.*s)", n, z); + sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken); break; } #endif diff --git a/src/select.c b/src/select.c index 539e4156a1..d51ae103ee 100644 --- a/src/select.c +++ b/src/select.c @@ -4508,22 +4508,21 @@ static void explainOneSelect(Vdbe *pVdbe, Select *p){ sqlite3ExplainPush(pVdbe); for(i=0; ipSrc->nSrc; i++){ struct SrcList_item *pItem = &p->pSrc->a[i]; - sqlite3ExplainPrintf(pVdbe, "src[%d] = ", i); + sqlite3ExplainPrintf(pVdbe, "{%d,*} = ", pItem->iCursor); if( pItem->pSelect ){ sqlite3ExplainSelect(pVdbe, pItem->pSelect); + if( pItem->pTab ){ + sqlite3ExplainPrintf(pVdbe, " (tabname=%s)", pItem->pTab->zName); + } }else if( pItem->zName ){ sqlite3ExplainPrintf(pVdbe, "%s", pItem->zName); } - if( pItem->pTab ){ - sqlite3ExplainPrintf(pVdbe, " (name=%s:%d)", - pItem->pTab->zName, pItem->iCursor); + if( pItem->zAlias ){ + sqlite3ExplainPrintf(pVdbe, " (AS %s)", pItem->zAlias); } if( pItem->jointype & JT_LEFT ){ sqlite3ExplainPrintf(pVdbe, " LEFT-JOIN"); } - if( pItem->zAlias ){ - sqlite3ExplainPrintf(pVdbe, " (AS %s)", pItem->zAlias); - } sqlite3ExplainNL(pVdbe); } sqlite3ExplainPop(pVdbe); From 4e2a9c32721086d5f73f84c075c9883018038b89 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 7 Dec 2011 22:49:42 +0000 Subject: [PATCH 063/161] Additional detail added to the tree-explain output for SELECT statements. FossilOrigin-Name: 7b457ea4551ba411a4747d74fb78b795cc8d9ee6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 10 ++++++++++ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 69c5847820..3aac83707e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\scompact\snotation\sfor\sthe\sparse-tree\sview. -D 2011-12-07T15:33:14.109 +C Additional\sdetail\sadded\sto\sthe\stree-explain\soutput\sfor\sSELECT\sstatements. +D 2011-12-07T22:49:42.588 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -180,7 +180,7 @@ F src/printf.c 7ffb4ebb8b341f67e049695ba031da717b3d2699 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 -F src/select.c 984ff4d2865fbf13a0ddeedbf892a93094f2b9dd +F src/select.c 912bea602425df403c464c7da9a89a56281623a3 F src/shell.c a1eadb2fdbfa45e54307263f0c8da8ee8cd61b8b F src/sqlite.h.in 1dc07194eb1a2c69c8ef75f88022b170be08024a F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 @@ -977,7 +977,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 7e5b56b1c602d4adfd4496a9c877f3b685b2d360 -R 7004d54e96eda502d15d7553ec65e84c +P 0eb3f8b1e3a196811fb54a5e2645debe6119610a +R c8f99de136cf931e1dc991f6945ded2c U drh -Z 6c7ae5dd374ffa9280bde6b5186b14b5 +Z 90b0a98552fa9f4d4fff3f8a611f18ca diff --git a/manifest.uuid b/manifest.uuid index 870fbb8eb1..3c8a88f6d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0eb3f8b1e3a196811fb54a5e2645debe6119610a \ No newline at end of file +7b457ea4551ba411a4747d74fb78b795cc8d9ee6 \ No newline at end of file diff --git a/src/select.c b/src/select.c index d51ae103ee..f761a08977 100644 --- a/src/select.c +++ b/src/select.c @@ -4500,6 +4500,16 @@ select_end: */ static void explainOneSelect(Vdbe *pVdbe, Select *p){ sqlite3ExplainPrintf(pVdbe, "SELECT "); + if( p->selFlags & (SF_Distinct|SF_Aggregate) ){ + if( p->selFlags & SF_Distinct ){ + sqlite3ExplainPrintf(pVdbe, "DISTINCT "); + } + if( p->selFlags & SF_Aggregate ){ + sqlite3ExplainPrintf(pVdbe, "agg_flag "); + } + sqlite3ExplainNL(pVdbe); + sqlite3ExplainPrintf(pVdbe, " "); + } sqlite3ExplainExprList(pVdbe, p->pEList); sqlite3ExplainNL(pVdbe); if( p->pSrc && p->pSrc->nSrc ){ From c4eef45c14dd94e7f611b18d82ffcc9170d621fe Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 8 Dec 2011 03:51:12 +0000 Subject: [PATCH 064/161] Follow the previously established pattern for detecting preprocessor defines for specific flavors of Windows (for NT in this case). FossilOrigin-Name: a0d92193dd5ae97608748f354aa17eb188431546 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/os.h | 9 +++++++++ src/os_win.c | 2 +- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index e309ac01b1..349c059ce8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Cherrypick\sthe\s[7e5b56b1c6]\sfix\sfor\sthe\ssqlite3SelectDup()\sroutine\s\ninto\strunk. -D 2011-12-07T01:55:51.485 +C Follow\sthe\spreviously\sestablished\spattern\sfor\sdetecting\spreprocessor\sdefines\sfor\sspecific\sflavors\sof\sWindows\s(for\sNT\sin\sthis\scase). +D 2011-12-08T03:51:12.637 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -163,11 +163,11 @@ F src/mutex_unix.c b4f4e923bb8de93ec3f251fadb50855f23df9579 F src/mutex_w32.c 5e54f3ba275bcb5d00248b8c23107df2e2f73e33 F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 F src/os.c 28bbdab2170dfce84d86c45456a18eab1d0f99a9 -F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 +F src/os.h 5830d32c4dab94fa0373404a139ada670e800731 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 4fbb91726165e105c1679a2660f49a3f4c376e4f -F src/os_win.c 6efe66a38215c38eaa7603ee5f76848159f8669d +F src/os_win.c 8af100f78f157eb6185fd9153d7f35b829c4da04 F src/pager.c d981f3bfcc0e4460537d983899620700ccf8f539 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y d02cc7bdb9ba11fb7aa212f55f99e59e4ee55439 @@ -977,7 +977,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 162421dadf93e9201c3290d800c597cbeeacdb40 -R d17736709c9e1055d62b7d5dd5010549 -U drh -Z 01f1b62cbb252e00fe26739b3bf9a3e5 +P 7fc535090ca3416706dff4abce10ac2d7f775e02 +R 6482ffb35478eb08f1e552e0a44aef9d +U mistachkin +Z 72aea825d319aa78f5f6763f21c44870 diff --git a/manifest.uuid b/manifest.uuid index f9ed373759..f6b26e4b22 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7fc535090ca3416706dff4abce10ac2d7f775e02 \ No newline at end of file +a0d92193dd5ae97608748f354aa17eb188431546 \ No newline at end of file diff --git a/src/os.h b/src/os.h index 7f17c203ef..aa544697e1 100644 --- a/src/os.h +++ b/src/os.h @@ -65,6 +65,15 @@ # endif #endif +/* +** Determine if we are dealing with Windows NT. +*/ +#if defined(_WIN32_WINNT) +# define SQLITE_OS_WINNT 1 +#else +# define SQLITE_OS_WINNT 0 +#endif + /* ** Determine if we are dealing with WindowsCE - which has a much ** reduced API. diff --git a/src/os_win.c b/src/os_win.c index 7e89a8cc02..ae110c541c 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -181,7 +181,7 @@ static int sqlite3_os_type = 0; # define SQLITE_WIN32_HAS_ANSI #endif -#if SQLITE_OS_WINCE || defined(_WIN32_WINNT) +#if SQLITE_OS_WINCE || SQLITE_OS_WINNT # define SQLITE_WIN32_HAS_WIDE #endif From 8dd4afadd8a73c99cb8974dbb44c96e84cd5e4dc Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 8 Dec 2011 19:50:32 +0000 Subject: [PATCH 065/161] In persistent WAL mode, truncate the WAL file to the size specified by the journal_size_limit pragma when disconnecting from the WAL. FossilOrigin-Name: 9687b305c2320109a8649612181eecd2e0da7c7b --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/wal.c | 41 ++++++++++++++++++++++++----------------- test/walpersist.test | 22 ++++++++++++++++++++-- 4 files changed, 53 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index 349c059ce8..5a23b09df7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Follow\sthe\spreviously\sestablished\spattern\sfor\sdetecting\spreprocessor\sdefines\sfor\sspecific\sflavors\sof\sWindows\s(for\sNT\sin\sthis\scase). -D 2011-12-08T03:51:12.637 +C In\spersistent\sWAL\smode,\struncate\sthe\sWAL\sfile\sto\sthe\ssize\sspecified\sby\sthe\njournal_size_limit\spragma\swhen\sdisconnecting\sfrom\sthe\sWAL. +D 2011-12-08T19:50:32.953 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -249,7 +249,7 @@ F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a -F src/wal.c 5fe1ba55b8fab9d3936bc9093af61ab9f1c580a1 +F src/wal.c 7e6e7fe68ee649505dca38c8ab83eda0d0d96ae5 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c f73752ca85c0ed221753fda98aeaf6b9d4616e0e @@ -912,7 +912,7 @@ F test/walfault.test efb0d5724893133e71b8d9d90abdb781845a6bb0 F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496 -F test/walpersist.test fd40d33765b2693f721c90c66d97f99757559006 +F test/walpersist.test 710b1b6cf6f8333e984f437724d1fa9e0511c5aa F test/walro.test e6bb27762c9f22601cbb8bff6e0acfd124e74b63 F test/walshared.test 6dda2293880c300baf5d791c307f653094585761 F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a @@ -977,7 +977,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 7fc535090ca3416706dff4abce10ac2d7f775e02 -R 6482ffb35478eb08f1e552e0a44aef9d -U mistachkin -Z 72aea825d319aa78f5f6763f21c44870 +P a0d92193dd5ae97608748f354aa17eb188431546 +R 2af387da3b388b68a597840e0b4cefff +U drh +Z 15eed8d4acdafc18909017c3c88afe5e diff --git a/manifest.uuid b/manifest.uuid index f6b26e4b22..ca3c77e6c4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a0d92193dd5ae97608748f354aa17eb188431546 \ No newline at end of file +9687b305c2320109a8649612181eecd2e0da7c7b \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 2c905a29e9..209c909752 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1781,6 +1781,26 @@ static int walCheckpoint( return rc; } +/* +** Attempt to limit the WAL size to the size limit defined by +** PRAGMA journal_size_limit. +*/ +static void walLimitSize(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); + } + } +} + /* ** Close a connection to a log file. */ @@ -1814,6 +1834,8 @@ int sqlite3WalClose( sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersistWal); if( rc==SQLITE_OK && bPersistWal!=1 ){ isDelete = 1; + }else{ + walLimitSize(pWal); } } @@ -2518,6 +2540,7 @@ int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ return rc; } + /* ** This function is called just before writing a set of frames to the log ** file (see sqlite3WalFrames()). It checks to see if, instead of appending @@ -2555,23 +2578,7 @@ static int walRestartLog(Wal *pWal){ int i; /* Loop counter */ u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */ - /* Limit the size of WAL file if the journal_size_limit PRAGMA is - ** set to a non-negative value. Log errors encountered - ** during the truncation attempt. */ - 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); - } - } - + walLimitSize(pWal); pWal->nCkpt++; pWal->hdr.mxFrame = 0; sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0])); diff --git a/test/walpersist.test b/test/walpersist.test index 175dcbf896..bf65bd1e13 100644 --- a/test/walpersist.test +++ b/test/walpersist.test @@ -67,7 +67,25 @@ do_test walpersist-1.11 { list [file exists test.db] [file exists test.db-wal] [file exists test.db-shm] } {1 1 1} - - +# Make sure the journal_size_limit works to limit the size of the +# persisted wal file. +forcedelete test.db test.db-shm test.db-wal +do_test walpersist-2.1 { + sqlite3 db test.db + db eval { + PRAGMA journal_mode=WAL; + PRAGMA wal_autocheckpoint=OFF; + PRAGMA journal_size_limit=12000; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(randomblob(50000)); + UPDATE t1 SET x=randomblob(50000); + } + expr {[file size test.db-wal]>100000} +} {1} +do_test walpersist-2.2 { + file_control_persist_wal db 1 + db close + file size test.db-wal +} {12000} finish_test From f1c5726ef16772c6b6329edc65698575543d5163 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 8 Dec 2011 20:41:33 +0000 Subject: [PATCH 066/161] Hand merge the zone allocator for MacOS from the apple-osx branch. FossilOrigin-Name: 0d955c20c02da29582b5cd8df2b7124fb9d12ebb --- manifest | 12 ++++---- manifest.uuid | 2 +- src/mem1.c | 82 +++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 77 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 5a23b09df7..49900ac0be 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\spersistent\sWAL\smode,\struncate\sthe\sWAL\sfile\sto\sthe\ssize\sspecified\sby\sthe\njournal_size_limit\spragma\swhen\sdisconnecting\sfrom\sthe\sWAL. -D 2011-12-08T19:50:32.953 +C Hand\smerge\sthe\szone\sallocator\sfor\sMacOS\sfrom\sthe\sapple-osx\sbranch. +D 2011-12-08T20:41:33.299 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -150,7 +150,7 @@ F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f F src/main.c 8be1ee70dd90ef7562c801dbe946a4f9f93bb128 F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 -F src/mem1.c 7456e2ca0524609ebc06a9befeda5289d4575ad4 +F src/mem1.c f96706e354e5e540305ba4cfe315fe52173a9f9e F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534 F src/mem5.c c2c63b7067570b00bf33d751c39af24182316f7f @@ -977,7 +977,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P a0d92193dd5ae97608748f354aa17eb188431546 -R 2af387da3b388b68a597840e0b4cefff +P 9687b305c2320109a8649612181eecd2e0da7c7b +R 83ba2438b14dfac192d8fdfea2ba6d38 U drh -Z 15eed8d4acdafc18909017c3c88afe5e +Z a86d3022d423432c98b77483099e12da diff --git a/manifest.uuid b/manifest.uuid index ca3c77e6c4..199e8418f5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9687b305c2320109a8649612181eecd2e0da7c7b \ No newline at end of file +0d955c20c02da29582b5cd8df2b7124fb9d12ebb \ No newline at end of file diff --git a/src/mem1.c b/src/mem1.c index e0d1dd6e8f..3f786a4b55 100644 --- a/src/mem1.c +++ b/src/mem1.c @@ -26,10 +26,40 @@ */ #ifdef SQLITE_SYSTEM_MALLOC + +#if defined(__APPLE__) + +/* +** Use the zone allocator available on apple products +*/ +#include +#include +#include +static malloc_zone_t* _sqliteZone_; +#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x)) +#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x)); +#define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y)) +#define SQLITE_MALLOCSIZE(x) \ + (_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x)) + +#else /* if not __APPLE__ */ + +/* +** Use standard C library malloc and free on non-Apple systems. +*/ +#define SQLITE_MALLOC(x) malloc(x) +#define SQLITE_FREE(x) free(x) +#define SQLITE_REALLOC(x,y) realloc((x),(y)) + #ifdef HAVE_MALLOC_USABLE_SIZE #include +#define SQLITE_MALLOCSIZE(x) malloc_usable_size(x) +#else +#undef SQLITE_MALLOCSIZE #endif +#endif /* __APPLE__ or not __APPLE__ */ + /* ** Like malloc(), but remember the size of the allocation ** so that we can find it later using sqlite3MemSize(). @@ -39,8 +69,8 @@ ** routines. */ static void *sqlite3MemMalloc(int nByte){ -#ifdef HAVE_MALLOC_USABLE_SIZE - void *p = malloc( nByte ); +#ifdef SQLITE_MALLOCSIZE + void *p = SQLITE_MALLOC( nByte ); if( p==0 ){ testcase( sqlite3GlobalConfig.xLog!=0 ); sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); @@ -50,7 +80,7 @@ static void *sqlite3MemMalloc(int nByte){ sqlite3_int64 *p; assert( nByte>0 ); nByte = ROUND8(nByte); - p = malloc( nByte+8 ); + p = SQLITE_MALLOC( nByte+8 ); if( p ){ p[0] = nByte; p++; @@ -71,13 +101,13 @@ static void *sqlite3MemMalloc(int nByte){ ** by higher-level routines. */ static void sqlite3MemFree(void *pPrior){ -#if HAVE_MALLOC_USABLE_SIZE - free(pPrior); +#ifdef SQLITE_MALLOCSIZE + SQLITE_FREE(pPrior); #else sqlite3_int64 *p = (sqlite3_int64*)pPrior; assert( pPrior!=0 ); p--; - free(p); + SQLITE_FREE(p); #endif } @@ -86,8 +116,8 @@ static void sqlite3MemFree(void *pPrior){ ** or xRealloc(). */ static int sqlite3MemSize(void *pPrior){ -#if HAVE_MALLOC_USABLE_SIZE - return pPrior ? (int)malloc_usable_size(pPrior) : 0; +#ifdef SQLITE_MALLOCSIZE + return pPrior ? (int)SQLITE_MALLOCSIZE(pPrior) : 0; #else sqlite3_int64 *p; if( pPrior==0 ) return 0; @@ -108,13 +138,13 @@ static int sqlite3MemSize(void *pPrior){ ** routines and redirected to xFree. */ static void *sqlite3MemRealloc(void *pPrior, int nByte){ -#if HAVE_MALLOC_USABLE_SIZE - void *p = realloc(pPrior, nByte); +#ifdef SQLITE_MALLOCSIZE + void *p = SQLITE_REALLOC(pPrior, nByte); if( p==0 ){ testcase( sqlite3GlobalConfig.xLog!=0 ); sqlite3_log(SQLITE_NOMEM, "failed memory resize %u to %u bytes", - malloc_usable_size(pPrior), nByte); + SQLITE_MALLOCSIZE(pPrior), nByte); } return p; #else @@ -122,7 +152,7 @@ static void *sqlite3MemRealloc(void *pPrior, int nByte){ assert( pPrior!=0 && nByte>0 ); assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */ p--; - p = realloc(p, nByte+8 ); + p = SQLITE_REALLOC(p, nByte+8 ); if( p ){ p[0] = nByte; p++; @@ -147,6 +177,34 @@ static int sqlite3MemRoundup(int n){ ** Initialize this module. */ static int sqlite3MemInit(void *NotUsed){ +#if defined(__APPLE__) + int cpuCount; + size_t len; + if( _sqliteZone_ ){ + return SQLITE_OK; + } + len = sizeof(cpuCount); + /* One usually wants to use hw.acctivecpu for MT decisions, but not here */ + sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0); + if( cpuCount>1 ){ + /* defer MT decisions to system malloc */ + _sqliteZone_ = malloc_default_zone(); + }else{ + /* only 1 core, use our own zone to contention over global locks, + ** e.g. we have our own dedicated locks */ + bool success; + malloc_zone_t* newzone = malloc_create_zone(4096, 0); + malloc_set_zone_name(newzone, "Sqlite_Heap"); + do{ + success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, + (void * volatile *)&_sqliteZone_); + }while(!_sqliteZone_); + if( !success ){ + /* somebody registered a zone first */ + malloc_destroy_zone(newzone); + } + } +#endif UNUSED_PARAMETER(NotUsed); return SQLITE_OK; } From 254582f4c2211c4c7c7056512be0a1dee131fdda Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 9 Dec 2011 05:52:16 +0000 Subject: [PATCH 067/161] The Windows OS flavor #ifdefs must be performed after the 'windows.h' file has been included. FossilOrigin-Name: 3702a31e56fe02d14ce246109b318a124cad9f1a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os.h | 39 +++++++++++++++++++-------------------- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index 49900ac0be..9f0b01f8f2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Hand\smerge\sthe\szone\sallocator\sfor\sMacOS\sfrom\sthe\sapple-osx\sbranch. -D 2011-12-08T20:41:33.299 +C The\sWindows\sOS\sflavor\s#ifdefs\smust\sbe\sperformed\safter\sthe\s'windows.h'\sfile\shas\sbeen\sincluded. +D 2011-12-09T05:52:16.276 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -163,7 +163,7 @@ F src/mutex_unix.c b4f4e923bb8de93ec3f251fadb50855f23df9579 F src/mutex_w32.c 5e54f3ba275bcb5d00248b8c23107df2e2f73e33 F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 F src/os.c 28bbdab2170dfce84d86c45456a18eab1d0f99a9 -F src/os.h 5830d32c4dab94fa0373404a139ada670e800731 +F src/os.h 549b1a2e5e0ed1e1499f252dac126c4973e7379c F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 4fbb91726165e105c1679a2660f49a3f4c376e4f @@ -977,7 +977,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 9687b305c2320109a8649612181eecd2e0da7c7b -R 83ba2438b14dfac192d8fdfea2ba6d38 -U drh -Z a86d3022d423432c98b77483099e12da +P 0d955c20c02da29582b5cd8df2b7124fb9d12ebb +R cba6a22ba8dad5c2320a7a8f8ac118be +U mistachkin +Z 5127f14a32c508056103def7f6cd4a97 diff --git a/manifest.uuid b/manifest.uuid index 199e8418f5..65b2a7467d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0d955c20c02da29582b5cd8df2b7124fb9d12ebb \ No newline at end of file +3702a31e56fe02d14ce246109b318a124cad9f1a \ No newline at end of file diff --git a/src/os.h b/src/os.h index aa544697e1..80afc516ff 100644 --- a/src/os.h +++ b/src/os.h @@ -65,26 +65,6 @@ # endif #endif -/* -** Determine if we are dealing with Windows NT. -*/ -#if defined(_WIN32_WINNT) -# define SQLITE_OS_WINNT 1 -#else -# define SQLITE_OS_WINNT 0 -#endif - -/* -** Determine if we are dealing with WindowsCE - which has a much -** reduced API. -*/ -#if defined(_WIN32_WCE) -# define SQLITE_OS_WINCE 1 -#else -# define SQLITE_OS_WINCE 0 -#endif - - /* ** Define the maximum size of a temporary filename */ @@ -109,6 +89,25 @@ # define SQLITE_TEMPNAME_SIZE 200 #endif +/* +** Determine if we are dealing with Windows NT. +*/ +#if defined(_WIN32_WINNT) +# define SQLITE_OS_WINNT 1 +#else +# define SQLITE_OS_WINNT 0 +#endif + +/* +** Determine if we are dealing with WindowsCE - which has a much +** reduced API. +*/ +#if defined(_WIN32_WCE) +# define SQLITE_OS_WINCE 1 +#else +# define SQLITE_OS_WINCE 0 +#endif + /* If the SET_FULLSYNC macro is not defined above, then make it ** a no-op */ From 1d8cb21fdbd08180e65003df1ea015a8a16e6084 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 9 Dec 2011 13:24:16 +0000 Subject: [PATCH 068/161] Modify the OP_Once opcode so that it works correctly in trigger sub-programs. This is a candidate fix for [7bbfb7d442]. FossilOrigin-Name: 557c69055a300b4082830b5f4803091dca1c3140 --- manifest | 31 ++++---- manifest.uuid | 2 +- src/expr.c | 20 +++-- src/select.c | 5 +- src/sqliteInt.h | 2 + src/trigger.c | 1 + src/vdbe.c | 35 +++++---- src/vdbe.h | 1 + src/vdbeInt.h | 4 + src/vdbeaux.c | 8 ++ src/where.c | 4 +- test/tkt-7bbfb7d442.test | 154 +++++++++++++++++++++++++++++++++++++++ 12 files changed, 223 insertions(+), 44 deletions(-) create mode 100644 test/tkt-7bbfb7d442.test diff --git a/manifest b/manifest index 9f0b01f8f2..9b3f6a8700 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sWindows\sOS\sflavor\s#ifdefs\smust\sbe\sperformed\safter\sthe\s'windows.h'\sfile\shas\sbeen\sincluded. -D 2011-12-09T05:52:16.276 +C Modify\sthe\sOP_Once\sopcode\sso\sthat\sit\sworks\scorrectly\sin\strigger\ssub-programs.\sThis\sis\sa\scandidate\sfix\sfor\s[7bbfb7d442]. +D 2011-12-09T13:24:16.480 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -134,7 +134,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 51d32f0a9c880663e54ce309f52e40c325d5e112 -F src/expr.c 9ac5831769dddee6a55b07cdd439b21929bbe4e7 +F src/expr.c 672c6e5fa3ad2eae9ff2588eac2317d76fcdfaef F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5 F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9 @@ -180,11 +180,11 @@ F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 -F src/select.c 538b5f096f6aacedf717bf982f9ad9a901008514 +F src/select.c e16b188449a7841e9e801a3c45c973c24e345199 F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8 F src/sqlite.h.in 57081d8e6b53ce29541d7437c93bce6087ac53b5 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 142ef5ed3fe0e6c662e99dbf92f38715b29a53b6 +F src/sqliteInt.h de3db02a1e4762a6ec9e1ab604ebc02d77948030 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -234,16 +234,16 @@ F src/test_vfstrace.c 0b884e06094a746da729119a2cabdc7aa790063d F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c c819d9f72168a035d545a5bdafe9b085b20df705 -F src/trigger.c 1cfb80e2290ef66ea89cb4e821caae65a02c0d56 +F src/trigger.c ee7e178fb9188f44b532cebd449a7c1df90fb684 F src/update.c 25e046a8f69d5e557aabde2000487b8545509d8d F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 F src/util.c 01238e2b0f24a14779181dbf991fe02620a80e31 F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa -F src/vdbe.c a7ab9993ec5a4d9479dc99671faec061fbf9b889 -F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755 -F src/vdbeInt.h 9498fc98a2c9e349a4ef13455ff5a3e898f40176 +F src/vdbe.c f49816f99b853c6cbdec950eedd4434cb2452376 +F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb +F src/vdbeInt.h 23a9506c9ab31e7823d7257d1828d2d7843443a0 F src/vdbeapi.c 86189ebba2c49791d75eaa12929f3ce6527596bd -F src/vdbeaux.c 45713a5f8f4f36195f503b30153ddef292323f88 +F src/vdbeaux.c cdd74a86c6281b4393c5f94d8f5e40e160e44e19 F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 @@ -252,7 +252,7 @@ F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a F src/wal.c 7e6e7fe68ee649505dca38c8ab83eda0d0d96ae5 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c f73752ca85c0ed221753fda98aeaf6b9d4616e0e +F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 @@ -737,6 +737,7 @@ F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84 F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f F test/tkt-752e1646fc.test ea78d88d14fe9866bdd991c634483334639e13bf F test/tkt-78e04e52ea.test ab52f0c1e2de6e46c910f4cc16b086bba05952b7 +F test/tkt-7bbfb7d442.test 8e7658f77d1ccea9d88dc9e255d3ed7fb68f8bdf F test/tkt-80ba201079.test a09684db1a0bd55b8838f606adccee456a51ddbf F test/tkt-80e031a00f.test 9a154173461a4dbe2de49cda73963e04842d52f7 F test/tkt-8454a207b9.test c583a9f814a82a2b5ba95207f55001c9f0cd816c @@ -977,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 0d955c20c02da29582b5cd8df2b7124fb9d12ebb -R cba6a22ba8dad5c2320a7a8f8ac118be -U mistachkin -Z 5127f14a32c508056103def7f6cd4a97 +P 3702a31e56fe02d14ce246109b318a124cad9f1a +R 212172c6a4e482305cc0a6c8ccb724d1 +U dan +Z fd67074fb89c049640d6ea2f96341088 diff --git a/manifest.uuid b/manifest.uuid index 65b2a7467d..ae75c08960 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3702a31e56fe02d14ce246109b318a124cad9f1a \ No newline at end of file +557c69055a300b4082830b5f4803091dca1c3140 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 136f302f90..195e4627d0 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1375,6 +1375,15 @@ static int isCandidateForInOpt(Select *p){ } #endif /* SQLITE_OMIT_SUBQUERY */ +/* +** Code an OP_Once instruction and allocate space for its flag. Return the +** address of the new instruction. +*/ +int sqlite3CodeOnce(Parse *pParse){ + Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ + return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++); +} + /* ** This function is used by the implementation of the IN (...) operator. ** It's job is to find or create a b-tree structure that may be used @@ -1470,10 +1479,9 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ */ assert(v); if( iCol<0 ){ - int iMem = ++pParse->nMem; int iAddr; - iAddr = sqlite3VdbeAddOp1(v, OP_Once, iMem); + iAddr = sqlite3CodeOnce(pParse); sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); eType = IN_INDEX_ROWID; @@ -1499,12 +1507,11 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None)) ){ - int iMem = ++pParse->nMem; int iAddr; char *pKey; pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx); - iAddr = sqlite3VdbeAddOp1(v, OP_Once, iMem); + iAddr = sqlite3CodeOnce(pParse); sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb, pKey,P4_KEYINFO_HANDOFF); @@ -1601,9 +1608,8 @@ int sqlite3CodeSubselect( ** If all of the above are false, then we can run this code just once ** save the results, and reuse the same result on subsequent invocations. */ - if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->pTriggerTab ){ - int mem = ++pParse->nMem; - testAddr = sqlite3VdbeAddOp1(v, OP_Once, mem); + if( !ExprHasAnyProperty(pExpr, EP_VarSelect) ){ + testAddr = sqlite3CodeOnce(pParse); } #ifndef SQLITE_OMIT_EXPLAIN diff --git a/src/select.c b/src/select.c index da75a51cd9..a89ffe25c8 100644 --- a/src/select.c +++ b/src/select.c @@ -3845,12 +3845,11 @@ int sqlite3Select( topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn); pItem->addrFillSub = topAddr+1; VdbeNoopComment((v, "materialize %s", pItem->pTab->zName)); - if( pItem->isCorrelated==0 && pParse->pTriggerTab==0 ){ + if( pItem->isCorrelated==0 ){ /* If the subquery is no correlated and if we are not inside of ** a trigger, then we only need to compute the value of the subquery ** once. */ - int regOnce = ++pParse->nMem; - onceAddr = sqlite3VdbeAddOp1(v, OP_Once, regOnce); + onceAddr = sqlite3CodeOnce(pParse); } sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 890f44f5e1..bd4198c2f7 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2204,6 +2204,7 @@ struct Parse { int nTab; /* Number of previously allocated VDBE cursors */ int nMem; /* Number of memory cells used so far */ int nSet; /* Number of sets used so far */ + int nOnce; /* Number of OP_Once instructions so far */ int ckBase; /* Base register of data during check constraints */ int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */ int iCacheCnt; /* Counter used to generate aColCache[].lru values */ @@ -2692,6 +2693,7 @@ void sqlite3AddCollateType(Parse*, Token*); void sqlite3EndTable(Parse*,Token*,Token*,Select*); int sqlite3ParseUri(const char*,const char*,unsigned int*, sqlite3_vfs**,char**,char **); +int sqlite3CodeOnce(Parse *); Bitvec *sqlite3BitvecCreate(u32); int sqlite3BitvecTest(Bitvec*, u32); diff --git a/src/trigger.c b/src/trigger.c index 22c4877b6a..3c4bf62a18 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -904,6 +904,7 @@ static TriggerPrg *codeRowTrigger( } pProgram->nMem = pSubParse->nMem; pProgram->nCsr = pSubParse->nTab; + pProgram->nOnce = pSubParse->nOnce; pProgram->token = (void *)pTrigger; pPrg->aColmask[0] = pSubParse->oldmask; pPrg->aColmask[1] = pSubParse->newmask; diff --git a/src/vdbe.c b/src/vdbe.c index e7fa05037d..53cd4a2eff 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2023,14 +2023,19 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ /* Opcode: Once P1 P2 * * * ** -** Jump to P2 if the value in register P1 is a not null or zero. If -** the value is NULL or zero, fall through and change the P1 register -** to an integer 1. -** -** When P1 is not used otherwise in a program, this opcode falls through -** once and jumps on all subsequent invocations. It is the equivalent -** of "OP_If P1 P2", followed by "OP_Integer 1 P1". +** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise, +** set the flag and fall through to the next instruction. */ +case OP_Once: { /* jump */ + assert( pOp->p1nOnceFlag ); + if( p->aOnceFlag[pOp->p1] ){ + pc = pOp->p2-1; + }else{ + p->aOnceFlag[pOp->p1] = 1; + } + break; +} + /* Opcode: If P1 P2 P3 * * ** ** Jump to P2 if the value in register P1 is true. The value @@ -2043,7 +2048,6 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ ** is considered true if it has a numeric value of zero. If the value ** in P1 is NULL then take the jump if P3 is true. */ -case OP_Once: /* jump, in1 */ case OP_If: /* jump, in1 */ case OP_IfNot: { /* jump, in1 */ int c; @@ -2060,12 +2064,6 @@ case OP_IfNot: { /* jump, in1 */ } if( c ){ pc = pOp->p2-1; - }else if( pOp->opcode==OP_Once ){ - assert( (pIn1->flags & (MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))==0 ); - memAboutToChange(p, pIn1); - pIn1->flags = MEM_Int; - pIn1->u.i = 1; - REGISTER_TRACE(pOp->p1, pIn1); } break; } @@ -5110,7 +5108,8 @@ case OP_Program: { /* jump */ nMem = pProgram->nMem + pProgram->nCsr; nByte = ROUND8(sizeof(VdbeFrame)) + nMem * sizeof(Mem) - + pProgram->nCsr * sizeof(VdbeCursor *); + + pProgram->nCsr * sizeof(VdbeCursor *) + + pProgram->nOnce * sizeof(u8); pFrame = sqlite3DbMallocZero(db, nByte); if( !pFrame ){ goto no_mem; @@ -5130,6 +5129,8 @@ case OP_Program: { /* jump */ pFrame->aOp = p->aOp; pFrame->nOp = p->nOp; pFrame->token = pProgram->token; + pFrame->aOnceFlag = p->aOnceFlag; + pFrame->nOnceFlag = p->nOnceFlag; pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){ @@ -5155,7 +5156,11 @@ case OP_Program: { /* jump */ p->apCsr = (VdbeCursor **)&aMem[p->nMem+1]; p->aOp = aOp = pProgram->aOp; p->nOp = pProgram->nOp; + p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor]; + p->nOnceFlag = pProgram->nOnce; + p->nOp = pProgram->nOp; pc = -1; + memset(p->aOnceFlag, 0, p->nOnceFlag); break; } diff --git a/src/vdbe.h b/src/vdbe.h index 948c73bcab..90a43ce6ee 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -82,6 +82,7 @@ struct SubProgram { int nOp; /* Elements in aOp[] */ int nMem; /* Number of memory cells required */ int nCsr; /* Number of cursors required */ + int nOnce; /* Number of OP_Once instructions */ void *token; /* id that may be used to recursive triggers */ SubProgram *pNext; /* Next sub-program already visited */ }; diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 803ae1630e..5f75caaf09 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -117,6 +117,8 @@ struct VdbeFrame { int nOp; /* Size of aOp array */ Mem *aMem; /* Array of memory cells for parent frame */ int nMem; /* Number of entries in aMem */ + u8 *aOnceFlag; /* Array of OP_Once flags for parent frame */ + int nOnceFlag; /* Number of entries in aOnceFlag */ VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */ u16 nCursor; /* Number of entries in apCsr */ void *token; /* Copy of SubProgram.token */ @@ -326,6 +328,8 @@ struct Vdbe { int nFrame; /* Number of frames in pFrame list */ u32 expmask; /* Binding to these vars invalidates VM */ SubProgram *pProgram; /* Linked list of all sub-programs used by VM */ + int nOnceFlag; /* Size of array aOnceFlag[] */ + u8 *aOnceFlag; /* Flags for OP_Once */ }; /* diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7c69d28cf6..b6e13f1335 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1469,6 +1469,7 @@ void sqlite3VdbeMakeReady( int nMem; /* Number of VM memory registers */ int nCursor; /* Number of cursors required */ int nArg; /* Number of arguments in subprograms */ + int nOnce; /* Number of OP_Once instructions */ int n; /* Loop counter */ u8 *zCsr; /* Memory available for allocation */ u8 *zEnd; /* First byte past allocated memory */ @@ -1484,6 +1485,7 @@ void sqlite3VdbeMakeReady( nMem = pParse->nMem; nCursor = pParse->nTab; nArg = pParse->nMaxArg; + nOnce = pParse->nOnce; /* For each cursor required, also allocate a memory cell. Memory ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by @@ -1530,6 +1532,8 @@ void sqlite3VdbeMakeReady( p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte); p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), &zCsr, zEnd, &nByte); + p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce*sizeof(u8), + &zCsr, zEnd, &nByte); if( nByte ){ p->pFree = sqlite3DbMallocZero(db, nByte); } @@ -1538,6 +1542,7 @@ void sqlite3VdbeMakeReady( }while( nByte && !db->mallocFailed ); p->nCursor = (u16)nCursor; + p->nOnceFlag = nOnce; if( p->aVar ){ p->nVar = (ynVar)nVar; for(n=0; nv; + v->aOnceFlag = pFrame->aOnceFlag; + v->nOnceFlag = pFrame->nOnceFlag; v->aOp = pFrame->aOp; v->nOp = pFrame->nOp; v->aMem = pFrame->aMem; @@ -1642,6 +1649,7 @@ static void closeAllCursors(Vdbe *p){ p->pDelFrame = pDel->pParent; sqlite3VdbeFrameDelete(pDel); } + memset(p->aOnceFlag, 0, p->nOnceFlag); } /* diff --git a/src/where.c b/src/where.c index a604d788c4..78efbf9790 100644 --- a/src/where.c +++ b/src/where.c @@ -2005,7 +2005,6 @@ static void constructAutomaticIndex( int nByte; /* Byte of memory needed for pIdx */ Index *pIdx; /* Object describing the transient index */ Vdbe *v; /* Prepared statement under construction */ - int regIsInit; /* Register set by initialization */ int addrInit; /* Address of the initialization bypass jump */ Table *pTable; /* The table being indexed */ KeyInfo *pKeyinfo; /* Key information for the index */ @@ -2022,8 +2021,7 @@ static void constructAutomaticIndex( ** transient index on 2nd and subsequent iterations of the loop. */ v = pParse->pVdbe; assert( v!=0 ); - regIsInit = ++pParse->nMem; - addrInit = sqlite3VdbeAddOp1(v, OP_Once, regIsInit); + addrInit = sqlite3CodeOnce(pParse); /* Count the number of columns that will be added to the index ** and used to match WHERE clause constraints */ diff --git a/test/tkt-7bbfb7d442.test b/test/tkt-7bbfb7d442.test new file mode 100644 index 0000000000..e560a0d4d5 --- /dev/null +++ b/test/tkt-7bbfb7d442.test @@ -0,0 +1,154 @@ +# 2011 December 9 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# +# This file implements tests to verify that ticket [7bbfb7d442] has been +# fixed. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix tkt-7bbfb7d442 + +do_execsql_test 1.1 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + INSERT INTO t1 VALUES(3, 'three'); + + CREATE TABLE t2(c, d); + INSERT INTO t2 VALUES('one', 'I'); + INSERT INTO t2 VALUES('two', 'II'); + INSERT INTO t2 VALUES('three', 'III'); + + CREATE TABLE t3(t3_a PRIMARY KEY, t3_d); + CREATE TRIGGER t3t AFTER INSERT ON t3 WHEN new.t3_d IS NULL BEGIN + UPDATE t3 SET t3_d = ( + SELECT d FROM + (SELECT * FROM t2 WHERE (new.t3_a%2)=(rowid%2) LIMIT 10), + (SELECT * FROM t1 WHERE (new.t3_a%2)=(rowid%2) LIMIT 10) + WHERE a = new.t3_a AND b = c + ) WHERE t3_a = new.t3_a; + END; +} + +do_execsql_test 1.2 { + INSERT INTO t3(t3_a) VALUES(1); + INSERT INTO t3(t3_a) VALUES(2); + INSERT INTO t3(t3_a) VALUES(3); + SELECT * FROM t3; +} {1 I 2 II 3 III} + +do_execsql_test 1.3 { DELETE FROM t3 } + +do_execsql_test 1.4 { + INSERT INTO t3(t3_a) SELECT 1 UNION SELECT 2 UNION SELECT 3; + SELECT * FROM t3; +} {1 I 2 II 3 III} + + + +#------------------------------------------------------------------------- +# The following test case - 2.* - is from the original bug report as +# posted to the mailing list. +# +do_execsql_test 2.1 { + CREATE TABLE InventoryControl ( + InventoryControlId INTEGER PRIMARY KEY AUTOINCREMENT, + SKU INTEGER NOT NULL, + Variant INTEGER NOT NULL DEFAULT 0, + ControlDate DATE NOT NULL, + ControlState INTEGER NOT NULL DEFAULT -1, + DeliveredQty VARCHAR(30) + ); + + CREATE TRIGGER TGR_InventoryControl_AfterInsert + AFTER INSERT ON InventoryControl + FOR EACH ROW WHEN NEW.ControlState=-1 BEGIN + + INSERT OR REPLACE INTO InventoryControl( + InventoryControlId,SKU,Variant,ControlDate,ControlState,DeliveredQty + ) SELECT + T1.InventoryControlId AS InventoryControlId, + T1.SKU AS SKU, + T1.Variant AS Variant, + T1.ControlDate AS ControlDate, + 1 AS ControlState, + COALESCE(T2.DeliveredQty,0) AS DeliveredQty + FROM ( + SELECT + NEW.InventoryControlId AS InventoryControlId, + II.SKU AS SKU, + II.Variant AS Variant, + COALESCE(LastClosedIC.ControlDate,NEW.ControlDate) AS ControlDate + FROM + InventoryItem II + LEFT JOIN + InventoryControl LastClosedIC + ON LastClosedIC.InventoryControlId IN ( SELECT 99999 ) + WHERE + II.SKU=NEW.SKU AND + II.Variant=NEW.Variant + ) T1 + LEFT JOIN ( + SELECT + TD.SKU AS SKU, + TD.Variant AS Variant, + 10 AS DeliveredQty + FROM + TransactionDetail TD + WHERE + TD.SKU=NEW.SKU AND + TD.Variant=NEW.Variant + ) T2 + ON T2.SKU=T1.SKU AND + T2.Variant=T1.Variant; + END; + + CREATE TABLE InventoryItem ( + SKU INTEGER NOT NULL, + Variant INTEGER NOT NULL DEFAULT 0, + DeptCode INTEGER NOT NULL, + GroupCode INTEGER NOT NULL, + ItemDescription VARCHAR(120) NOT NULL, + PRIMARY KEY(SKU, Variant) + ); + + INSERT INTO InventoryItem VALUES(220,0,1,170,'Scoth Tampon Recurer'); + INSERT INTO InventoryItem VALUES(31,0,1,110,'Fromage'); + + CREATE TABLE TransactionDetail ( + TransactionId INTEGER NOT NULL, + SKU INTEGER NOT NULL, + Variant INTEGER NOT NULL DEFAULT 0, + PRIMARY KEY(TransactionId, SKU, Variant) + ); + INSERT INTO TransactionDetail(TransactionId, SKU, Variant) VALUES(44, 31, 0); + + + INSERT INTO InventoryControl(SKU, Variant, ControlDate) SELECT + II.SKU AS SKU, II.Variant AS Variant, '2011-08-30' AS ControlDate + FROM InventoryItem II; +} + +do_execsql_test 2.2 { + SELECT SKU, DeliveredQty FROM InventoryControl WHERE SKU=31 +} {31 10} + +do_execsql_test 2.3 { + SELECT CASE WHEN DeliveredQty=10 THEN "TEST PASSED!" ELSE "TEST FAILED!" END + FROM InventoryControl WHERE SKU=31; +} {{TEST PASSED!}} + + +finish_test + + From b8475df8093050de2eb79ad1e10067eea13a87a7 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 9 Dec 2011 16:21:19 +0000 Subject: [PATCH 069/161] Make no assumptions about the initial state of VDBE registers. FossilOrigin-Name: 521d72bdf67b4b1972331307345a18c231a6e1d6 --- manifest | 27 +++++++++++++++------------ manifest.uuid | 2 +- src/expr.c | 4 +++- src/insert.c | 1 + src/select.c | 4 ++-- src/update.c | 11 ++++++----- src/vdbe.c | 48 ++++++++++++++++++++++++++++++++++++++++-------- src/vdbeaux.c | 19 +++++++++++-------- 8 files changed, 79 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index 9b3f6a8700..97c32d2dc9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sthe\sOP_Once\sopcode\sso\sthat\sit\sworks\scorrectly\sin\strigger\ssub-programs.\sThis\sis\sa\scandidate\sfix\sfor\s[7bbfb7d442]. -D 2011-12-09T13:24:16.480 +C Make\sno\sassumptions\sabout\sthe\sinitial\sstate\sof\sVDBE\sregisters. +D 2011-12-09T16:21:19.224 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -134,7 +134,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 51d32f0a9c880663e54ce309f52e40c325d5e112 -F src/expr.c 672c6e5fa3ad2eae9ff2588eac2317d76fcdfaef +F src/expr.c b5920f108d6955b262f8db8e38f40f59b2bfcd7d F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5 F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9 @@ -142,7 +142,7 @@ F src/global.c 107ccaacb4b30895cf3a3a39decf417c804acfa1 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 8f283d6734dd837ed7531b26d7622fda70874390 +F src/insert.c 2d0162f70c45ccd0beb390661b63a85f303fc7e4 F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 @@ -180,7 +180,7 @@ F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 -F src/select.c e16b188449a7841e9e801a3c45c973c24e345199 +F src/select.c d1895ff59f2051ad55e9075bf093fd28bcd36a89 F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8 F src/sqlite.h.in 57081d8e6b53ce29541d7437c93bce6087ac53b5 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 @@ -235,15 +235,15 @@ F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c c819d9f72168a035d545a5bdafe9b085b20df705 F src/trigger.c ee7e178fb9188f44b532cebd449a7c1df90fb684 -F src/update.c 25e046a8f69d5e557aabde2000487b8545509d8d +F src/update.c d3076782c887c10e882996550345da9c4c9f9dea F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 F src/util.c 01238e2b0f24a14779181dbf991fe02620a80e31 F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa -F src/vdbe.c f49816f99b853c6cbdec950eedd4434cb2452376 +F src/vdbe.c 9fc8110b1f2c5285e53948ac59ab4d0e75f18d28 F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb F src/vdbeInt.h 23a9506c9ab31e7823d7257d1828d2d7843443a0 F src/vdbeapi.c 86189ebba2c49791d75eaa12929f3ce6527596bd -F src/vdbeaux.c cdd74a86c6281b4393c5f94d8f5e40e160e44e19 +F src/vdbeaux.c d9d406ae5963a4b0424f2f56415e3d4d330667b6 F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 @@ -978,7 +978,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 3702a31e56fe02d14ce246109b318a124cad9f1a -R 212172c6a4e482305cc0a6c8ccb724d1 -U dan -Z fd67074fb89c049640d6ea2f96341088 +P 557c69055a300b4082830b5f4803091dca1c3140 +R 3fc70f66913132be9fb89d0f0027fcb9 +T *branch * uninit-vdbe-mem +T *sym-uninit-vdbe-mem * +T -sym-trunk * +U drh +Z 6b717a43993e129981a6c5acd19a7014 diff --git a/manifest.uuid b/manifest.uuid index ae75c08960..7573408ffa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -557c69055a300b4082830b5f4803091dca1c3140 \ No newline at end of file +521d72bdf67b4b1972331307345a18c231a6e1d6 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 195e4627d0..3c69c564b5 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1444,6 +1444,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ int eType = 0; /* Type of RHS table. IN_INDEX_* */ int iTab = pParse->nTab++; /* Cursor of the RHS table */ int mustBeUnique = (prNotFound==0); /* True if RHS must be unique */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ assert( pX->op==TK_IN ); @@ -1454,7 +1455,6 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0); if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){ sqlite3 *db = pParse->db; /* Database connection */ - Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ Table *pTab; /* Table . */ Expr *pExpr; /* Expression */ int iCol; /* Index of column */ @@ -1521,6 +1521,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ sqlite3VdbeJumpHere(v, iAddr); if( prNotFound && !pTab->aCol[iCol].notNull ){ *prNotFound = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound); } } } @@ -1536,6 +1537,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ eType = IN_INDEX_EPH; if( prNotFound ){ *prNotFound = rMayHaveNull = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound); }else{ testcase( pParse->nQueryLoop>(double)1 ); pParse->nQueryLoop = (double)1; diff --git a/src/insert.c b/src/insert.c index eca3c12ddc..65a98a6f7a 100644 --- a/src/insert.c +++ b/src/insert.c @@ -240,6 +240,7 @@ void sqlite3AutoincrementBegin(Parse *pParse){ assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead); addr = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_Null, 0, memId+1); sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0); sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9); sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId); diff --git a/src/select.c b/src/select.c index a89ffe25c8..870db3f850 100644 --- a/src/select.c +++ b/src/select.c @@ -1947,13 +1947,12 @@ static int generateOutputSubroutine( */ if( regPrev ){ int j1, j2; - j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); + j1 = sqlite3VdbeAddOp1(v, OP_JumpOnce, pParse->nOnce++); j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem, (char*)pKeyInfo, p4type); sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); sqlite3VdbeJumpHere(v, j1); sqlite3ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem); - sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev); } if( pParse->db->mallocFailed ) return 0; @@ -4154,6 +4153,7 @@ int sqlite3Select( VdbeComment((v, "clear abort flag")); sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); VdbeComment((v, "indicate accumulator empty")); + sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1); /* Begin a loop that will extract all source rows in GROUP BY order. ** This might involve two separate loops with an OP_Sort in between, or diff --git a/src/update.c b/src/update.c index 1e3052218e..73d22690b5 100644 --- a/src/update.c +++ b/src/update.c @@ -126,8 +126,8 @@ void sqlite3Update( int regRowCount = 0; /* A count of rows changed */ int regOldRowid; /* The old rowid */ int regNewRowid; /* The new rowid */ - int regNew; - int regOld = 0; + int regNew; /* Content of the NEW.* table in triggers */ + int regOld = 0; /* Content of OLD.* table in triggers */ int regRowSet = 0; /* Rowset of rows to be updated */ memset(&sContext, 0, sizeof(sContext)); @@ -276,6 +276,7 @@ void sqlite3Update( #endif /* Allocate required registers. */ + regRowSet = ++pParse->nMem; regOldRowid = regNewRowid = ++pParse->nMem; if( pTrigger || hasFK ){ regOld = pParse->nMem + 1; @@ -310,7 +311,7 @@ void sqlite3Update( /* Begin the database scan */ - sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid); + sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid); pWInfo = sqlite3WhereBegin( pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED ); @@ -321,7 +322,6 @@ void sqlite3Update( */ sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regOldRowid); if( !okOnePass ){ - regRowSet = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid); } @@ -425,9 +425,10 @@ void sqlite3Update( newmask = sqlite3TriggerColmask( pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError ); + sqlite3VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1); for(i=0; inCol; i++){ if( i==pTab->iPKey ){ - sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i); + /*sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);*/ }else{ j = aXRef[i]; if( j>=0 ){ diff --git a/src/vdbe.c b/src/vdbe.c index 53cd4a2eff..7f763cfe69 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -764,7 +764,8 @@ case OP_Goto: { /* jump */ ** Write the current address onto register P1 ** and then jump to address P2. */ -case OP_Gosub: { /* jump, in1 */ +case OP_Gosub: { /* jump */ + assert( pOp->p1>0 && pOp->p1<=p->nMem ); pIn1 = &aMem[pOp->p1]; assert( (pIn1->flags & MEM_Dyn)==0 ); memAboutToChange(p, pIn1); @@ -961,12 +962,25 @@ case OP_String: { /* out2-prerelease */ break; } -/* Opcode: Null * P2 * * * +/* Opcode: Null * P2 P3 * * ** -** Write a NULL into register P2. +** Write a NULL into registers P2. If P3 greater than P2, then also write +** NULL into register P3 and ever register in between P2 and P3. If P3 +** is less than P2 (typically P3 is zero) then only register P2 is +** set to NULL */ case OP_Null: { /* out2-prerelease */ + int cnt; + cnt = pOp->p3-pOp->p2; + assert( pOp->p3<=p->nMem ); pOut->flags = MEM_Null; + while( cnt>0 ){ + pOut++; + memAboutToChange(p, pOut); + MemReleaseExt(pOut); + pOut->flags = MEM_Null; + cnt--; + } break; } @@ -2025,6 +2039,8 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ ** ** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise, ** set the flag and fall through to the next instruction. +** +** See also: JumpOnce */ case OP_Once: { /* jump */ assert( pOp->p1nOnceFlag ); @@ -2036,17 +2052,33 @@ case OP_Once: { /* jump */ break; } +/* Opcode: JumpOnce P1 P2 * * * +** +** Check if OP_Once flag P1 is clear. If so, set the flag and +** jump to instruction P2. Otherwise fall through. +** +** See also: Once +*/ +case OP_JumpOnce: { /* jump */ + assert( pOp->p1nOnceFlag ); + if( !p->aOnceFlag[pOp->p1] ){ + pc = pOp->p2-1; + p->aOnceFlag[pOp->p1] = 1; + } + break; +} + /* Opcode: If P1 P2 P3 * * ** ** Jump to P2 if the value in register P1 is true. The value ** is considered true if it is numeric and non-zero. If the value -** in P1 is NULL then take the jump if P3 is true. +** in P1 is NULL then take the jump if P3 is non-zero. */ /* Opcode: IfNot P1 P2 P3 * * ** ** Jump to P2 if the value in register P1 is False. The value -** is considered true if it has a numeric value of zero. If the value -** in P1 is NULL then take the jump if P3 is true. +** is considered false if it has a numeric value of zero. If the value +** in P1 is NULL then take the jump if P3 is zero. */ case OP_If: /* jump, in1 */ case OP_IfNot: { /* jump, in1 */ @@ -5069,7 +5101,7 @@ case OP_Program: { /* jump */ pProgram = pOp->p4.pProgram; pRt = &aMem[pOp->p3]; - assert( memIsValid(pRt) ); + /*assert( memIsValid(pRt) );*/ assert( pProgram->nOp>0 ); /* If the p5 flag is clear, then recursive invocation of triggers is @@ -5246,7 +5278,7 @@ case OP_MemMax: { /* in2 */ }else{ pIn1 = &aMem[pOp->p1]; } - assert( memIsValid(pIn1) ); + /*assert( memIsValid(pIn1) ); FIXME */ sqlite3VdbeMemIntegerify(pIn1); pIn2 = &aMem[pOp->p2]; sqlite3VdbeMemIntegerify(pIn2); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index b6e13f1335..a14447bada 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -913,13 +913,14 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ } case P4_MEM: { Mem *pMem = pOp->p4.pMem; - assert( (pMem->flags & MEM_Null)==0 ); if( pMem->flags & MEM_Str ){ zP4 = pMem->z; }else if( pMem->flags & MEM_Int ){ sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i); }else if( pMem->flags & MEM_Real ){ sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->r); + }else if( pMem->flags & MEM_Null ){ + sqlite3_snprintf(nTemp, zTemp, "NULL"); }else{ assert( pMem->flags & MEM_Blob ); zP4 = "(blob)"; @@ -1094,7 +1095,7 @@ static void releaseMemArray(Mem *p, int N){ p->zMalloc = 0; } - p->flags = MEM_Null; + p->flags = MEM_Invalid; } db->mallocFailed = malloc_failed; } @@ -1532,8 +1533,7 @@ void sqlite3VdbeMakeReady( p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte); p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), &zCsr, zEnd, &nByte); - p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce*sizeof(u8), - &zCsr, zEnd, &nByte); + p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, &zCsr, zEnd, &nByte); if( nByte ){ p->pFree = sqlite3DbMallocZero(db, nByte); } @@ -1559,10 +1559,11 @@ void sqlite3VdbeMakeReady( 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].flags = MEM_Invalid; p->aMem[n].db = db; } } + if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag); p->explain = pParse->explain; sqlite3VdbeRewind(p); } @@ -1649,7 +1650,6 @@ static void closeAllCursors(Vdbe *p){ p->pDelFrame = pDel->pParent; sqlite3VdbeFrameDelete(pDel); } - memset(p->aOnceFlag, 0, p->nOnceFlag); } /* @@ -1666,8 +1666,10 @@ static void Cleanup(Vdbe *p){ /* Execute assert() statements to ensure that the Vdbe.apCsr[] and ** Vdbe.aMem[] arrays have already been cleaned up. */ int i; - for(i=0; inCursor; i++) assert( p->apCsr==0 || p->apCsr[i]==0 ); - for(i=1; i<=p->nMem; i++) assert( p->aMem==0 || p->aMem[i].flags==MEM_Null ); + if( p->apCsr ) for(i=0; inCursor; i++) assert( p->apCsr[i]==0 ); + if( p->aMem ){ + for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Invalid ); + } #endif sqlite3DbFree(db, p->zErrMsg); @@ -2135,6 +2137,7 @@ int sqlite3VdbeHalt(Vdbe *p){ if( p->db->mallocFailed ){ p->rc = SQLITE_NOMEM; } + if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag); closeAllCursors(p); if( p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_OK; From f4d31bcb05b1b51f99c2c0bc9d10d3a0fce95cae Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 9 Dec 2011 16:59:19 +0000 Subject: [PATCH 070/161] Previous check-in broke auto-increment. This check-in appears to fix it. FossilOrigin-Name: 28ffd39c7162c8f7139711545122cffa257911dd --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/insert.c | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 97c32d2dc9..2814c2eb42 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sno\sassumptions\sabout\sthe\sinitial\sstate\sof\sVDBE\sregisters. -D 2011-12-09T16:21:19.224 +C Previous\scheck-in\sbroke\sauto-increment.\s\sThis\scheck-in\sappears\sto\sfix\sit. +D 2011-12-09T16:59:19.303 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -142,7 +142,7 @@ F src/global.c 107ccaacb4b30895cf3a3a39decf417c804acfa1 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 2d0162f70c45ccd0beb390661b63a85f303fc7e4 +F src/insert.c ea820fe9af748075b3b6827fb6f23f25079bf1f7 F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 @@ -978,10 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 557c69055a300b4082830b5f4803091dca1c3140 -R 3fc70f66913132be9fb89d0f0027fcb9 -T *branch * uninit-vdbe-mem -T *sym-uninit-vdbe-mem * -T -sym-trunk * +P 521d72bdf67b4b1972331307345a18c231a6e1d6 +R 28ec5920c638a4a7052dc1caf48390ef U drh -Z 6b717a43993e129981a6c5acd19a7014 +Z 3eb2c2f097e358392b3aefdceca7c178 diff --git a/manifest.uuid b/manifest.uuid index 7573408ffa..9695c697d7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -521d72bdf67b4b1972331307345a18c231a6e1d6 \ No newline at end of file +28ffd39c7162c8f7139711545122cffa257911dd \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 65a98a6f7a..dadb10acdb 100644 --- a/src/insert.c +++ b/src/insert.c @@ -239,8 +239,8 @@ void sqlite3AutoincrementBegin(Parse *pParse){ memId = p->regCtr; assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead); + sqlite3VdbeAddOp3(v, OP_Null, 0, memId, memId+1); addr = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_Null, 0, memId+1); sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0); sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9); sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId); From ec86c724ac430e33fb2d707afd59aab1dcb86790 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 9 Dec 2011 17:27:51 +0000 Subject: [PATCH 071/161] Take out the OP_JumpOnce opcode. Revert compound SELECT to use OP_IfNot, which is the correct behavior. Mark trigger registers as initially invalid. FossilOrigin-Name: 6a9fb47d5060fe641915f5f99cc9265409a4583b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 3 ++- src/vdbe.c | 21 ++------------------- 4 files changed, 12 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index 2814c2eb42..4cca45f7b7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Previous\scheck-in\sbroke\sauto-increment.\s\sThis\scheck-in\sappears\sto\sfix\sit. -D 2011-12-09T16:59:19.303 +C Take\sout\sthe\sOP_JumpOnce\sopcode.\s\sRevert\scompound\sSELECT\sto\suse\sOP_IfNot,\nwhich\sis\sthe\scorrect\sbehavior.\s\sMark\strigger\sregisters\sas\sinitially\ninvalid. +D 2011-12-09T17:27:51.519 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -180,7 +180,7 @@ F src/printf.c 03104cbff6959ff45df69dc9060ba6212f60a869 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 -F src/select.c d1895ff59f2051ad55e9075bf093fd28bcd36a89 +F src/select.c fd3046fb39a1de8dce269e9b5ecbf58fe7e7e480 F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8 F src/sqlite.h.in 57081d8e6b53ce29541d7437c93bce6087ac53b5 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 @@ -239,7 +239,7 @@ F src/update.c d3076782c887c10e882996550345da9c4c9f9dea F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 F src/util.c 01238e2b0f24a14779181dbf991fe02620a80e31 F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa -F src/vdbe.c 9fc8110b1f2c5285e53948ac59ab4d0e75f18d28 +F src/vdbe.c 029add0c5197a61db588824a58570547330b9d8f F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb F src/vdbeInt.h 23a9506c9ab31e7823d7257d1828d2d7843443a0 F src/vdbeapi.c 86189ebba2c49791d75eaa12929f3ce6527596bd @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 521d72bdf67b4b1972331307345a18c231a6e1d6 -R 28ec5920c638a4a7052dc1caf48390ef +P 28ffd39c7162c8f7139711545122cffa257911dd +R 121bb37be8c24842afbf4add96953aee U drh -Z 3eb2c2f097e358392b3aefdceca7c178 +Z 11be617eddaa1f2d6fdfc985cd0a65fa diff --git a/manifest.uuid b/manifest.uuid index 9695c697d7..c01915d14d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -28ffd39c7162c8f7139711545122cffa257911dd \ No newline at end of file +6a9fb47d5060fe641915f5f99cc9265409a4583b \ No newline at end of file diff --git a/src/select.c b/src/select.c index 870db3f850..793b849b79 100644 --- a/src/select.c +++ b/src/select.c @@ -1947,12 +1947,13 @@ static int generateOutputSubroutine( */ if( regPrev ){ int j1, j2; - j1 = sqlite3VdbeAddOp1(v, OP_JumpOnce, pParse->nOnce++); + j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem, (char*)pKeyInfo, p4type); sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); sqlite3VdbeJumpHere(v, j1); sqlite3ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem); + sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev); } if( pParse->db->mallocFailed ) return 0; diff --git a/src/vdbe.c b/src/vdbe.c index 7f763cfe69..64ae54e3db 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2052,22 +2052,6 @@ case OP_Once: { /* jump */ break; } -/* Opcode: JumpOnce P1 P2 * * * -** -** Check if OP_Once flag P1 is clear. If so, set the flag and -** jump to instruction P2. Otherwise fall through. -** -** See also: Once -*/ -case OP_JumpOnce: { /* jump */ - assert( pOp->p1nOnceFlag ); - if( !p->aOnceFlag[pOp->p1] ){ - pc = pOp->p2-1; - p->aOnceFlag[pOp->p1] = 1; - } - break; -} - /* Opcode: If P1 P2 P3 * * ** ** Jump to P2 if the value in register P1 is true. The value @@ -5101,7 +5085,6 @@ case OP_Program: { /* jump */ pProgram = pOp->p4.pProgram; pRt = &aMem[pOp->p3]; - /*assert( memIsValid(pRt) );*/ assert( pProgram->nOp>0 ); /* If the p5 flag is clear, then recursive invocation of triggers is @@ -5166,7 +5149,7 @@ case OP_Program: { /* jump */ pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){ - pMem->flags = MEM_Null; + pMem->flags = MEM_Invalid; pMem->db = db; } }else{ @@ -5278,7 +5261,7 @@ case OP_MemMax: { /* in2 */ }else{ pIn1 = &aMem[pOp->p1]; } - /*assert( memIsValid(pIn1) ); FIXME */ + assert( memIsValid(pIn1) ); sqlite3VdbeMemIntegerify(pIn1); pIn2 = &aMem[pOp->p2]; sqlite3VdbeMemIntegerify(pIn2); From 7fd3c07465576d44b292c85f4914e7f213dfde88 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 9 Dec 2011 17:38:23 +0000 Subject: [PATCH 072/161] Remove an unnecessary initialization of Vdbe.aOnceFlag. FossilOrigin-Name: 421714dad32f3460fa40a7f65e9fa276f5e37f58 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4cca45f7b7..838aa0e646 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Take\sout\sthe\sOP_JumpOnce\sopcode.\s\sRevert\scompound\sSELECT\sto\suse\sOP_IfNot,\nwhich\sis\sthe\scorrect\sbehavior.\s\sMark\strigger\sregisters\sas\sinitially\ninvalid. -D 2011-12-09T17:27:51.519 +C Remove\san\sunnecessary\sinitialization\sof\sVdbe.aOnceFlag. +D 2011-12-09T17:38:23.898 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -243,7 +243,7 @@ F src/vdbe.c 029add0c5197a61db588824a58570547330b9d8f F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb F src/vdbeInt.h 23a9506c9ab31e7823d7257d1828d2d7843443a0 F src/vdbeapi.c 86189ebba2c49791d75eaa12929f3ce6527596bd -F src/vdbeaux.c d9d406ae5963a4b0424f2f56415e3d4d330667b6 +F src/vdbeaux.c 71a0cd6ae14ddb2e2a6d6b97d5b54ae753272682 F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 28ffd39c7162c8f7139711545122cffa257911dd -R 121bb37be8c24842afbf4add96953aee +P 6a9fb47d5060fe641915f5f99cc9265409a4583b +R c86cf051b4407cf6125edf9f0e3046a6 U drh -Z 11be617eddaa1f2d6fdfc985cd0a65fa +Z 0944fb1b87cf72506193a8756f5ed350 diff --git a/manifest.uuid b/manifest.uuid index c01915d14d..997ba38d98 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6a9fb47d5060fe641915f5f99cc9265409a4583b \ No newline at end of file +421714dad32f3460fa40a7f65e9fa276f5e37f58 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index a14447bada..8b085ea6ce 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1563,7 +1563,6 @@ void sqlite3VdbeMakeReady( p->aMem[n].db = db; } } - if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag); p->explain = pParse->explain; sqlite3VdbeRewind(p); } From 61134508578cfdaa7be4bac22115a7f0b1924f52 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 9 Dec 2011 17:51:30 +0000 Subject: [PATCH 073/161] Remove an unnecessary condition. FossilOrigin-Name: d9ba023c608bce7768bc08478f9df9243f2e73ce --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 838aa0e646..84cc79d6f6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sinitialization\sof\sVdbe.aOnceFlag. -D 2011-12-09T17:38:23.898 +C Remove\san\sunnecessary\scondition. +D 2011-12-09T17:51:30.877 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -243,7 +243,7 @@ F src/vdbe.c 029add0c5197a61db588824a58570547330b9d8f F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb F src/vdbeInt.h 23a9506c9ab31e7823d7257d1828d2d7843443a0 F src/vdbeapi.c 86189ebba2c49791d75eaa12929f3ce6527596bd -F src/vdbeaux.c 71a0cd6ae14ddb2e2a6d6b97d5b54ae753272682 +F src/vdbeaux.c ff5eefb43647e1b1e60c1c23407523dbcfd0a86c F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 6a9fb47d5060fe641915f5f99cc9265409a4583b -R c86cf051b4407cf6125edf9f0e3046a6 +P 421714dad32f3460fa40a7f65e9fa276f5e37f58 +R d509edfce30feab29fb6f6730ef15f2e U drh -Z 0944fb1b87cf72506193a8756f5ed350 +Z 197b12cf9381c9c365def8e131bb26a7 diff --git a/manifest.uuid b/manifest.uuid index 997ba38d98..1c1bcc40a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -421714dad32f3460fa40a7f65e9fa276f5e37f58 \ No newline at end of file +d9ba023c608bce7768bc08478f9df9243f2e73ce \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8b085ea6ce..c8f6911ae1 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2136,7 +2136,7 @@ int sqlite3VdbeHalt(Vdbe *p){ if( p->db->mallocFailed ){ p->rc = SQLITE_NOMEM; } - if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag); + memset(p->aOnceFlag, 0, p->nOnceFlag); closeAllCursors(p); if( p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_OK; From 3a0c9c0298776f8a3ca842fe555979768fdabac7 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 10 Dec 2011 13:49:44 +0000 Subject: [PATCH 074/161] Always use _msize() to get memory allocation sizes on windows, without having to do anything special in the makefile. FossilOrigin-Name: 256e27bd118ed3ab6ecb19ad6a6494b71ac9bdd5 --- Makefile.msc | 3 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/mem1.c | 7 +++++++ 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index ea7efa7580..f40936d915 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -49,9 +49,6 @@ BCC = cl.exe # TCC = cl.exe -W3 -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src -fp:precise -# We always have the _msize function available when using MSVC. -TCC = $(TCC) -DHAVE_MALLOC_USABLE_SIZE -Dmalloc_usable_size=_msize - # The mksqlite3c.tcl and mksqlite3h.tcl scripts will pull in # any extension header files by default. For non-amalgamation # builds, we need to make sure the compiler can find these. diff --git a/manifest b/manifest index a364c55cdf..ec33d4e625 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Change\sthe\sVDBE\sso\sthat\sall\sregisters\sare\sinitialized\sto\s"Invalid"\sinstead\sof\nNULL\sand\sreport\serrors\son\sany\sattempted\sread\sof\san\sInvalid\sregister.\s\sThis\nwill\shelp\sprevent\sfuture\sbugs\ssimilar\sto\s[7bbfb7d442]. -D 2011-12-09T18:06:44.319 +C Always\suse\s_msize()\sto\sget\smemory\sallocation\ssizes\son\swindows,\swithout\shaving\nto\sdo\sanything\sspecial\sin\sthe\smakefile. +D 2011-12-10T13:49:44.752 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc 3bd3641a345d488a9601c0cc7f9d35aeede5d12b +F Makefile.msc dcad80fa69f17d46fe6778ba873fc108ca16298d F Makefile.vxworks 1deb39c8bb047296c30161ffa10c1b5423e632f9 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION af03cd6400f9d71d38bdb7a9d66a1aefdc2f3e0d @@ -150,7 +150,7 @@ F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f F src/main.c 8be1ee70dd90ef7562c801dbe946a4f9f93bb128 F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 -F src/mem1.c f96706e354e5e540305ba4cfe315fe52173a9f9e +F src/mem1.c 7998e7003a3047e323c849a26dda004debc04d03 F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534 F src/mem5.c c2c63b7067570b00bf33d751c39af24182316f7f @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 557c69055a300b4082830b5f4803091dca1c3140 d9ba023c608bce7768bc08478f9df9243f2e73ce -R c86cf051b4407cf6125edf9f0e3046a6 +P 0064bab77149768640d7758a3e271d5a1d63b256 +R 24b1670e7f54ceef1719656e8887fd23 U drh -Z b55d92759eb01feac738f44135c5de26 +Z 1195788bf6e0e867e75c58852af50db9 diff --git a/manifest.uuid b/manifest.uuid index 2ddca39cd5..77180fe99e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0064bab77149768640d7758a3e271d5a1d63b256 \ No newline at end of file +256e27bd118ed3ab6ecb19ad6a6494b71ac9bdd5 \ No newline at end of file diff --git a/src/mem1.c b/src/mem1.c index 3f786a4b55..bf84ce0909 100644 --- a/src/mem1.c +++ b/src/mem1.c @@ -26,6 +26,13 @@ */ #ifdef SQLITE_SYSTEM_MALLOC +/* +** Windows systems have malloc_usable_size() but it is called _msize() +*/ +#if !defined(HAVE_MALLOC_USABLE_SIZE) && SQLITE_OS_WIN +# define HAVE_MALLOC_USABLE_SIZE 1 +# define malloc_usable_size _msize +#endif #if defined(__APPLE__) From 1acc6cbe0078c40dd54d73800d874487b49a6dc5 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 10 Dec 2011 17:17:17 +0000 Subject: [PATCH 075/161] Allow UNION ALL compounds to be promoted up to replace a simple wrapper SELECT even if the compounds are joins. FossilOrigin-Name: 3d4b4f4fb7c1d9f1c742fef884383e9f50f8630e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 14ed07d1eb..def2ec37dc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Import\sthe\sexperimental\sparse-tree\sexplainer,\swith\sfixes,\sfrom\sthe\ntree-explain\sbranch. -D 2011-12-10T15:55:01.825 +C Allow\sUNION\sALL\scompounds\sto\sbe\spromoted\sup\sto\sreplace\sa\ssimple\swrapper\nSELECT\seven\sif\sthe\scompounds\sare\sjoins. +D 2011-12-10T17:17:17.131 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -180,7 +180,7 @@ F src/printf.c 7ffb4ebb8b341f67e049695ba031da717b3d2699 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 -F src/select.c 4d64e3ccccfd2b46e60e7a4cfd21175c3341e859 +F src/select.c 8c53ca04d6f6c06dd3bba5b53070572fd26ceaaa F src/shell.c a1eadb2fdbfa45e54307263f0c8da8ee8cd61b8b F src/sqlite.h.in 1dc07194eb1a2c69c8ef75f88022b170be08024a F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 256e27bd118ed3ab6ecb19ad6a6494b71ac9bdd5 1a360da0f8314f232c224c71829646bc7558892b -R 3dfa94d97a11ee2a078f9f1b12bd877f +P bcbc7152d49107afa926c8950360c61a6cf3d244 +R fdd2391ad6c97a200fa195ba2b7608fb U drh -Z 7f30df8f1f79a1cfbb2b882f754d8454 +Z 0fd477d0479c6495f79c3db569ff13d1 diff --git a/manifest.uuid b/manifest.uuid index a0c27bc5c9..f5b1a92778 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bcbc7152d49107afa926c8950360c61a6cf3d244 \ No newline at end of file +3d4b4f4fb7c1d9f1c742fef884383e9f50f8630e \ No newline at end of file diff --git a/src/select.c b/src/select.c index c41dc07f9e..02e71960f1 100644 --- a/src/select.c +++ b/src/select.c @@ -2812,7 +2812,7 @@ static int flattenSubquery( testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 || (pSub1->pPrior && pSub1->op!=TK_ALL) - || NEVER(pSub1->pSrc==0) || pSub1->pSrc->nSrc!=1 + || NEVER(pSub1->pSrc==0) || pSub1->pSrc->nSrc<1 ){ return 0; } From 4b3ac73c2ff20a5491b9e116502403b5657afeb1 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 10 Dec 2011 23:18:32 +0000 Subject: [PATCH 076/161] Minor cleanups of the compound-subquery flattening logic. New test cases added for joins the compound subquery. FossilOrigin-Name: 5061d85ff934db3c217c97acbbbed3286d9e02aa --- manifest | 20 ++++++------- manifest.uuid | 2 +- src/expr.c | 2 +- src/resolve.c | 14 +++++----- src/select.c | 16 ++++++----- src/sqliteInt.h | 2 +- test/selectB.test | 71 ++++++++++++++++++++++++++++++++++++++--------- 7 files changed, 87 insertions(+), 40 deletions(-) diff --git a/manifest b/manifest index def2ec37dc..1750fa12cb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sUNION\sALL\scompounds\sto\sbe\spromoted\sup\sto\sreplace\sa\ssimple\swrapper\nSELECT\seven\sif\sthe\scompounds\sare\sjoins. -D 2011-12-10T17:17:17.131 +C Minor\scleanups\sof\sthe\scompound-subquery\sflattening\slogic.\s\sNew\stest\scases\nadded\sfor\sjoins\sthe\scompound\ssubquery. +D 2011-12-10T23:18:32.554 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -134,7 +134,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 51d32f0a9c880663e54ce309f52e40c325d5e112 -F src/expr.c a68c194c7709388302266e9a5bd9de2243486835 +F src/expr.c 537591e95eac74af783e4eb033954fb218cf398e F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5 F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9 @@ -178,13 +178,13 @@ F src/pragma.c dd66f21fafe7be40e1a48ad4195764cc191cf583 F src/prepare.c ec4989f7f480544bdc4192fe663470d2a2d7d61e F src/printf.c 7ffb4ebb8b341f67e049695ba031da717b3d2699 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 -F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 +F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 -F src/select.c 8c53ca04d6f6c06dd3bba5b53070572fd26ceaaa +F src/select.c f38d6bb54dbe42409b66b038be24765f68b5d44b F src/shell.c a1eadb2fdbfa45e54307263f0c8da8ee8cd61b8b F src/sqlite.h.in 1dc07194eb1a2c69c8ef75f88022b170be08024a F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 7a64e24659e067f3882eeb75f31d59e7b3723b8b +F src/sqliteInt.h 165409fa8adc8701148830804febeded3f2e4448 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -666,7 +666,7 @@ F test/select7.test dad6f00f0d49728a879d6eb6451d4752db0b0abe F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d F test/select9.test 74c0fb2c6eecb0219cbed0cbe3df136f8fbf9343 F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532 -F test/selectB.test 0d072c5846071b569766e6cd7f923f646a8b2bfa +F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25 F test/selectC.test f9bf1bc4581b5b8158caa6e4e4f682acb379fb25 F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118 F test/shared.test 34945a516532b11182c3eb26e31247eee3c9ae48 @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P bcbc7152d49107afa926c8950360c61a6cf3d244 -R fdd2391ad6c97a200fa195ba2b7608fb +P 3d4b4f4fb7c1d9f1c742fef884383e9f50f8630e +R cd399db3e1d12898eb15c691830496b3 U drh -Z 0fd477d0479c6495f79c3db569ff13d1 +Z 6e0886d4861bd3870ceeed33fcdf7d2c diff --git a/manifest.uuid b/manifest.uuid index f5b1a92778..0e5bf24ff1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3d4b4f4fb7c1d9f1c742fef884383e9f50f8630e \ No newline at end of file +5061d85ff934db3c217c97acbbbed3286d9e02aa \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ede9c9d39c..22643ff331 100644 --- a/src/expr.c +++ b/src/expr.c @@ -870,7 +870,7 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); pItem->sortOrder = pOldItem->sortOrder; pItem->done = 0; - pItem->iCol = pOldItem->iCol; + pItem->iOrderByCol = pOldItem->iOrderByCol; pItem->iAlias = pOldItem->iAlias; } return pNew; diff --git a/src/resolve.c b/src/resolve.c index 6d857f0074..3da48136fd 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -799,7 +799,7 @@ static int resolveCompoundOrderBy( pE->pColl = pColl; pE->flags |= EP_IntValue | flags; pE->u.iValue = iCol; - pItem->iCol = (u16)iCol; + pItem->iOrderByCol = (u16)iCol; pItem->done = 1; }else{ moreToDo = 1; @@ -848,12 +848,12 @@ int sqlite3ResolveOrderGroupBy( pEList = pSelect->pEList; assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */ for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ - if( pItem->iCol ){ - if( pItem->iCol>pEList->nExpr ){ + if( pItem->iOrderByCol ){ + if( pItem->iOrderByCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); return 1; } - resolveAlias(pParse, pEList, pItem->iCol-1, pItem->pExpr, zType); + resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType); } } return 0; @@ -900,7 +900,7 @@ static int resolveOrderGroupBy( ** a copy of the iCol-th result-set column. The subsequent call to ** sqlite3ResolveOrderGroupBy() will convert the expression to a ** copy of the iCol-th result-set expression. */ - pItem->iCol = (u16)iCol; + pItem->iOrderByCol = (u16)iCol; continue; } if( sqlite3ExprIsInteger(pE, &iCol) ){ @@ -911,12 +911,12 @@ static int resolveOrderGroupBy( resolveOutOfRangeError(pParse, zType, i+1, nResult); return 1; } - pItem->iCol = (u16)iCol; + pItem->iOrderByCol = (u16)iCol; continue; } /* Otherwise, treat the ORDER BY term as an ordinary expression */ - pItem->iCol = 0; + pItem->iOrderByCol = 0; if( sqlite3ResolveExprNames(pNC, pE) ){ return 1; } diff --git a/src/select.c b/src/select.c index 02e71960f1..f0f4b6a5f2 100644 --- a/src/select.c +++ b/src/select.c @@ -2219,8 +2219,8 @@ static int multiSelectOrderBy( for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){ struct ExprList_item *pItem; for(j=0, pItem=pOrderBy->a; jiCol>0 ); - if( pItem->iCol==i ) break; + assert( pItem->iOrderByCol>0 ); + if( pItem->iOrderByCol==i ) break; } if( j==nOrderBy ){ Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); @@ -2228,7 +2228,7 @@ static int multiSelectOrderBy( pNew->flags |= EP_IntValue; pNew->u.iValue = i; pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew); - pOrderBy->a[nOrderBy++].iCol = (u16)i; + pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i; } } } @@ -2244,8 +2244,8 @@ static int multiSelectOrderBy( if( aPermute ){ struct ExprList_item *pItem; for(i=0, pItem=pOrderBy->a; iiCol>0 && pItem->iCol<=p->pEList->nExpr ); - aPermute[i] = pItem->iCol - 1; + assert( pItem->iOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr ); + aPermute[i] = pItem->iOrderByCol - 1; } pKeyMerge = sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1)); @@ -2810,19 +2810,21 @@ static int flattenSubquery( for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){ testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); + assert( pSub->pSrc!=0 ); if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 || (pSub1->pPrior && pSub1->op!=TK_ALL) - || NEVER(pSub1->pSrc==0) || pSub1->pSrc->nSrc<1 + || pSub1->pSrc->nSrc<1 ){ return 0; } + testcase( pSub1->pSrc->nSrc>1 ); } /* Restriction 18. */ if( p->pOrderBy ){ int ii; for(ii=0; iipOrderBy->nExpr; ii++){ - if( p->pOrderBy->a[ii].iCol==0 ) return 0; + if( p->pOrderBy->a[ii].iOrderByCol==0 ) return 0; } } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6266a9cb72..8613d865aa 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1772,7 +1772,7 @@ struct ExprList { char *zSpan; /* Original text of the expression */ u8 sortOrder; /* 1 for DESC or 0 for ASC */ u8 done; /* A flag to indicate when processing is finished */ - u16 iCol; /* For ORDER BY, column number in result set */ + u16 iOrderByCol; /* For ORDER BY, column number in result set */ u16 iAlias; /* Index into Parse.aAlias[] for zName */ } *a; /* One entry for each expression */ }; diff --git a/test/selectB.test b/test/selectB.test index b9d979acb7..05ec9c6bdb 100644 --- a/test/selectB.test +++ b/test/selectB.test @@ -194,19 +194,28 @@ do_test selectB-3.0 { } } {} -for {set ii 3} {$ii <= 4} {incr ii} { +for {set ii 3} {$ii <= 6} {incr ii} { - if {$ii == 4} { - do_test selectB-4.0 { - execsql { - CREATE INDEX i1 ON t1(a); - CREATE INDEX i2 ON t1(b); - CREATE INDEX i3 ON t1(c); - CREATE INDEX i4 ON t2(d); - CREATE INDEX i5 ON t2(e); - CREATE INDEX i6 ON t2(f); - } - } {} + switch $ii { + 4 { + optimization_control db query-flattener off + } + 5 { + optimization_control db query-flattener on + do_test selectB-5.0 { + execsql { + CREATE INDEX i1 ON t1(a); + CREATE INDEX i2 ON t1(b); + CREATE INDEX i3 ON t1(c); + CREATE INDEX i4 ON t2(d); + CREATE INDEX i5 ON t2(e); + CREATE INDEX i6 ON t2(f); + } + } {} + } + 6 { + optimization_control db query-flattener off + } } do_test selectB-$ii.1 { @@ -371,11 +380,47 @@ for {set ii 3} {$ii <= 4} {incr ii} { } } {2 4 6 3 6 9 8 10 12 12 15 18 14 16 18 21 24 27} - do_test selectB-$ii.21 { + do_test selectB-$ii.22 { execsql { SELECT * FROM (SELECT 345 UNION ALL SELECT d FROM t2) ORDER BY 1; } } {3 12 21 345} + + do_test selectB-$ii.23 { + execsql { + SELECT x, y FROM ( + SELECT a AS x, b AS y FROM t1 + UNION ALL + SELECT a*10 + 0.1, f*10 + 0.1 FROM t1 JOIN t2 ON (c=d) + UNION ALL + SELECT a*100, b*100 FROM t1 + ) ORDER BY 1; + } + } {2 4 8 10 14 16 80.1 180.1 200 400 800 1000 1400 1600} + + do_test selectB-$ii.24 { + execsql { + SELECT x, y FROM ( + SELECT a AS x, b AS y FROM t1 + UNION ALL + SELECT a*10 + 0.1, f*10 + 0.1 FROM t1 LEFT JOIN t2 ON (c=d) + UNION ALL + SELECT a*100, b*100 FROM t1 + ) ORDER BY 1; + } + } {2 4 8 10 14 16 20.1 {} 80.1 180.1 140.1 {} 200 400 800 1000 1400 1600} + + do_test selectB-$ii.25 { + execsql { + SELECT x+y FROM ( + SELECT a AS x, b AS y FROM t1 + UNION ALL + SELECT a*10 + 0.1, f*10 + 0.1 FROM t1 LEFT JOIN t2 ON (c=d) + UNION ALL + SELECT a*100, b*100 FROM t1 + ) WHERE y+x NOT NULL ORDER BY 1; + } + } {6 18 30 260.2 600 1800 3000} } finish_test From 13e0ea9923fab6921590efcc7b9a5905c2a56365 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 11 Dec 2011 02:29:25 +0000 Subject: [PATCH 077/161] Fix harmless compiler warnings. FossilOrigin-Name: 1e6a698aab9270637d3ea00fd6b0e94f4172e875 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/global.c | 2 +- src/os_unix.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 1750fa12cb..d2215a4238 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\scleanups\sof\sthe\scompound-subquery\sflattening\slogic.\s\sNew\stest\scases\nadded\sfor\sjoins\sthe\scompound\ssubquery. -D 2011-12-10T23:18:32.554 +C Fix\sharmless\scompiler\swarnings. +D 2011-12-11T02:29:25.100 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -138,7 +138,7 @@ F src/expr.c 537591e95eac74af783e4eb033954fb218cf398e F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5 F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9 -F src/global.c 107ccaacb4b30895cf3a3a39decf417c804acfa1 +F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 @@ -166,7 +166,7 @@ F src/os.c 28bbdab2170dfce84d86c45456a18eab1d0f99a9 F src/os.h 549b1a2e5e0ed1e1499f252dac126c4973e7379c F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c 4fbb91726165e105c1679a2660f49a3f4c376e4f +F src/os_unix.c 07dcae2de5f1aab27a16e6c6fc89fe1bb134026e F src/os_win.c 8af100f78f157eb6185fd9153d7f35b829c4da04 F src/pager.c d981f3bfcc0e4460537d983899620700ccf8f539 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 3d4b4f4fb7c1d9f1c742fef884383e9f50f8630e -R cd399db3e1d12898eb15c691830496b3 +P 5061d85ff934db3c217c97acbbbed3286d9e02aa +R 50fc7fd86c15521c2d33b9b65e5658d5 U drh -Z 6e0886d4861bd3870ceeed33fcdf7d2c +Z c0a452295d74b5e6062f8bf2ec7734da diff --git a/manifest.uuid b/manifest.uuid index 0e5bf24ff1..41ce00d86a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5061d85ff934db3c217c97acbbbed3286d9e02aa \ No newline at end of file +1e6a698aab9270637d3ea00fd6b0e94f4172e875 \ No newline at end of file diff --git a/src/global.c b/src/global.c index b8a8a49d3d..7de0668250 100644 --- a/src/global.c +++ b/src/global.c @@ -147,7 +147,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = { 500, /* nLookaside */ {0,0,0,0,0,0,0,0}, /* m */ {0,0,0,0,0,0,0,0,0}, /* mutex */ - {0,0,0,0,0,0,0,0,0,0,0}, /* pcache2 */ + {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */ (void*)0, /* pHeap */ 0, /* nHeap */ 0, 0, /* mnHeap, mxHeap */ diff --git a/src/os_unix.c b/src/os_unix.c index 51d144906a..0f003fc499 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -2014,8 +2014,8 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) { rc = osRmdir(zLockFile); if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile); if( rc<0 ){ - int rc = 0; int tErrno = errno; + rc = 0; if( ENOENT != tErrno ){ rc = SQLITE_IOERR_UNLOCK; } From e752cda8942f1fb0258e7d38bcdf3f23b55ffecf Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 11 Dec 2011 02:30:35 +0000 Subject: [PATCH 078/161] Fix STAT3 so that it works with the new uninitialized register logic of the VDBE. Ticket [7bbfb7d4422ff] FossilOrigin-Name: d11a57985c394772043c63d4c2b534944be0a664 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/analyze.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index d2215a4238..1969ac3e31 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings. -D 2011-12-11T02:29:25.100 +C Fix\sSTAT3\sso\sthat\sit\sworks\swith\sthe\snew\suninitialized\sregister\slogic\sof\nthe\sVDBE.\s\sTicket\s[7bbfb7d4422ff] +D 2011-12-11T02:30:35.672 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -119,7 +119,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 -F src/analyze.c 5a1db16a651ce6310c8b046b2cbb736e030e14b9 +F src/analyze.c f32ff304da413851eefa562b04e61ff6cb88248b F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 4368158da74d4711888e03264105c5c527d76caf @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 5061d85ff934db3c217c97acbbbed3286d9e02aa -R 50fc7fd86c15521c2d33b9b65e5658d5 +P 1e6a698aab9270637d3ea00fd6b0e94f4172e875 +R b14f97101207c69b3c216a1f2d4f412b U drh -Z c0a452295d74b5e6062f8bf2ec7734da +Z ed714f23f92d49472af328d21dd14bdc diff --git a/manifest.uuid b/manifest.uuid index 41ce00d86a..2526b92bc2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1e6a698aab9270637d3ea00fd6b0e94f4172e875 \ No newline at end of file +d11a57985c394772043c63d4c2b534944be0a664 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index b6a987ab85..cbfdc8587e 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -529,6 +529,7 @@ static void analyzeOneTable( sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumEq); sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumLt); sqlite3VdbeAddOp2(v, OP_Integer, -1, regNumDLt); + sqlite3VdbeAddOp3(v, OP_Null, 0, regSample, regAccum); sqlite3VdbeAddOp4(v, OP_Function, 1, regCount, regAccum, (char*)&stat3InitFuncdef, P4_FUNCDEF); sqlite3VdbeChangeP5(v, 2); From 630d296c57e9a94f0d209a9f4eb215c26132372d Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 11 Dec 2011 21:51:04 +0000 Subject: [PATCH 079/161] Update comments describing the flattening optimization in select.c. FossilOrigin-Name: dab4c137a852222f11179fa2ade52d17a4206dd2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 19 ++++++++++++------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 1969ac3e31..6a4599845f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sSTAT3\sso\sthat\sit\sworks\swith\sthe\snew\suninitialized\sregister\slogic\sof\nthe\sVDBE.\s\sTicket\s[7bbfb7d4422ff] -D 2011-12-11T02:30:35.672 +C Update\scomments\sdescribing\sthe\sflattening\soptimization\sin\sselect.c. +D 2011-12-11T21:51:04.519 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -180,7 +180,7 @@ F src/printf.c 7ffb4ebb8b341f67e049695ba031da717b3d2699 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 -F src/select.c f38d6bb54dbe42409b66b038be24765f68b5d44b +F src/select.c a1d075db66a0ea42807353501b62997969e5be79 F src/shell.c a1eadb2fdbfa45e54307263f0c8da8ee8cd61b8b F src/sqlite.h.in 1dc07194eb1a2c69c8ef75f88022b170be08024a F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 1e6a698aab9270637d3ea00fd6b0e94f4172e875 -R b14f97101207c69b3c216a1f2d4f412b +P d11a57985c394772043c63d4c2b534944be0a664 +R db74426b5ff988e285b71512d50b85b4 U drh -Z ed714f23f92d49472af328d21dd14bdc +Z fcdcb7d7647c15fa01d78b530015f5fb diff --git a/manifest.uuid b/manifest.uuid index 2526b92bc2..9f7b7a6208 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d11a57985c394772043c63d4c2b534944be0a664 \ No newline at end of file +dab4c137a852222f11179fa2ade52d17a4206dd2 \ No newline at end of file diff --git a/src/select.c b/src/select.c index f0f4b6a5f2..188050e8d1 100644 --- a/src/select.c +++ b/src/select.c @@ -2588,9 +2588,8 @@ static void substSelect( #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* -** This routine attempts to flatten subqueries in order to speed -** execution. It returns 1 if it makes changes and 0 if no flattening -** occurs. +** This routine attempts to flatten subqueries as a performance optimization. +** This routine returns 1 if it makes changes and 0 if no flattening occurs. ** ** To understand the concept of flattening, consider the following ** query: @@ -2632,7 +2631,10 @@ static void substSelect( ** (6) The subquery does not use aggregates or the outer query is not ** DISTINCT. ** -** (7) The subquery has a FROM clause. +** (7) The subquery has a FROM clause. TODO: For subqueries without +** A FROM clause, consider adding a FROM close with the special +** table sqlite_once that consists of a single row containing a +** single NULL. ** ** (8) The subquery does not use LIMIT or the outer query is not a join. ** @@ -2665,11 +2667,14 @@ static void substSelect( ** ** * is not itself part of a compound select, ** * is not an aggregate or DISTINCT query, and -** * has no other tables or sub-selects in the FROM clause. +** * is not a join ** ** The parent and sub-query may contain WHERE clauses. Subject to ** rules (11), (13) and (14), they may also contain ORDER BY, -** LIMIT and OFFSET clauses. +** LIMIT and OFFSET clauses. The subquery cannot use any compound +** operator other than UNION ALL because all the other compound +** operators have an implied DISTINCT which is disallowed by +** restriction (4). ** ** (18) If the sub-query is a compound select, then all terms of the ** ORDER by clause of the parent must be simple references to @@ -2681,7 +2686,7 @@ static void substSelect( ** (20) If the sub-query is a compound select, then it must not use ** an ORDER BY clause. Ticket #3773. We could relax this constraint ** somewhat by saying that the terms of the ORDER BY clause must -** appear as unmodified result columns in the outer query. But +** appear as unmodified result columns in the outer query. But we ** have other optimizations in mind to deal with that case. ** ** (21) The subquery does not use LIMIT or the outer query is not From 58cd3c61628d4b52301a8ca32e488bef64c75df8 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 11 Dec 2011 22:44:09 +0000 Subject: [PATCH 080/161] In the multiplexor shim, when using 8+3 filenames, begin numbering journal overflow files with 101 instead of 001 to avoid name collisions with the main database file. FossilOrigin-Name: 05bf8a0b17a13a581ac973dc84ceaf66532d7f92 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test_multiplex.c | 7 +++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 6a4599845f..74f3662800 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\scomments\sdescribing\sthe\sflattening\soptimization\sin\sselect.c. -D 2011-12-11T21:51:04.519 +C In\sthe\smultiplexor\sshim,\swhen\susing\s8+3\sfilenames,\sbegin\snumbering\sjournal\noverflow\sfiles\swith\s101\sinstead\sof\s001\sto\savoid\sname\scollisions\swith\sthe\nmain\sdatabase\sfile. +D 2011-12-11T22:44:09.610 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c 185378cade15fa9012bd17d9d5b04783d4478f79 +F src/test_multiplex.c 1bd9d0808771db7fec25dee46b78159e2aefeed2 F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P d11a57985c394772043c63d4c2b534944be0a664 -R db74426b5ff988e285b71512d50b85b4 +P dab4c137a852222f11179fa2ade52d17a4206dd2 +R 425d0660e438f7370e2c896a15db7167 U drh -Z fcdcb7d7647c15fa01d78b530015f5fb +Z 9892a9e7f3941ba5e32798c1f4a7624c diff --git a/manifest.uuid b/manifest.uuid index 9f7b7a6208..cf701affa3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dab4c137a852222f11179fa2ade52d17a4206dd2 \ No newline at end of file +05bf8a0b17a13a581ac973dc84ceaf66532d7f92 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 2ca8bf8d5d..84c14f7575 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -304,6 +304,13 @@ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){ int i; for(i=n-1; i>0 && i>=n-4 && z[i]!='.'; i--){} if( i>=n-4 ) n = i+1; + if( pGroup->flags & (SQLITE_OPEN_MAIN_JOURNAL|SQLITE_OPEN_TEMP_JOURNAL) ){ + /* The extensions on overflow files for main databases are 001, 002, + ** 003 and so forth. To avoid name collisions, add 100 to the + ** extensions of journal files so that they are 101, 102, 103, .... + */ + iChunk += 100; + } #endif sqlite3_snprintf(4,&z[n],"%03d",iChunk); } From 743e003c0ea57b252cc6a90bd4f1df79057fbc6b Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 12 Dec 2011 16:51:50 +0000 Subject: [PATCH 081/161] Add magic comments to shell.c to make it easier for scripts to insert additional version information displays for custom builds. FossilOrigin-Name: 9b2691aa911289d74bfe3edf45937a33fb7eaa8d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 74f3662800..292db80228 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\smultiplexor\sshim,\swhen\susing\s8+3\sfilenames,\sbegin\snumbering\sjournal\noverflow\sfiles\swith\s101\sinstead\sof\s001\sto\savoid\sname\scollisions\swith\sthe\nmain\sdatabase\sfile. -D 2011-12-11T22:44:09.610 +C Add\smagic\scomments\sto\sshell.c\sto\smake\sit\seasier\sfor\sscripts\sto\s\ninsert\sadditional\sversion\sinformation\sdisplays\sfor\scustom\sbuilds. +D 2011-12-12T16:51:50.465 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -181,7 +181,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c a1d075db66a0ea42807353501b62997969e5be79 -F src/shell.c a1eadb2fdbfa45e54307263f0c8da8ee8cd61b8b +F src/shell.c ea9c11ae5dbe32b9f0a779b96f6b351293b8e638 F src/sqlite.h.in 1dc07194eb1a2c69c8ef75f88022b170be08024a F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h 165409fa8adc8701148830804febeded3f2e4448 @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P dab4c137a852222f11179fa2ade52d17a4206dd2 -R 425d0660e438f7370e2c896a15db7167 +P 05bf8a0b17a13a581ac973dc84ceaf66532d7f92 +R dc7f4a3f6a59dd72fbcaff2a94f8f7f6 U drh -Z 9892a9e7f3941ba5e32798c1f4a7624c +Z fc8e968ece5f7a1fbfb50f6ab74c295e diff --git a/manifest.uuid b/manifest.uuid index cf701affa3..74d3ea9cbe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -05bf8a0b17a13a581ac973dc84ceaf66532d7f92 \ No newline at end of file +9b2691aa911289d74bfe3edf45937a33fb7eaa8d \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 93ed9a6db3..911f6fad9e 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2344,7 +2344,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ }else if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ - printf("SQLite %s %s\n", + printf("SQLite %s %s\n" /*extra-version-info*/, sqlite3_libversion(), sqlite3_sourceid()); }else @@ -2941,7 +2941,7 @@ int main(int argc, char **argv){ char *zHistory = 0; int nHistory; printf( - "SQLite version %s %.19s\n" + "SQLite version %s %.19s\n" /*extra-version-info*/ "Enter \".help\" for instructions\n" "Enter SQL statements terminated with a \";\"\n", sqlite3_libversion(), sqlite3_sourceid() From dc8ac1dd76d377ec8bc6ec271fd0bcbbf14573b5 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 12 Dec 2011 18:21:44 +0000 Subject: [PATCH 082/161] Fix for the xFileSize method of test_multiplex.c when used on a file opened with the DELETEONCLOSE flag set. FossilOrigin-Name: 713071c493e9937a20c436b07299df428249e378 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_multiplex.c | 9 +++++++-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 292db80228..11ca04ed64 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smagic\scomments\sto\sshell.c\sto\smake\sit\seasier\sfor\sscripts\sto\s\ninsert\sadditional\sversion\sinformation\sdisplays\sfor\scustom\sbuilds. -D 2011-12-12T16:51:50.465 +C Fix\sfor\sthe\sxFileSize\smethod\sof\stest_multiplex.c\swhen\sused\son\sa\sfile\sopened\swith\sthe\sDELETEONCLOSE\sflag\sset. +D 2011-12-12T18:21:44.814 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c 1bd9d0808771db7fec25dee46b78159e2aefeed2 +F src/test_multiplex.c affbe08d3c6f42d39490c022367ae3507b2fdf2f F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 05bf8a0b17a13a581ac973dc84ceaf66532d7f92 -R dc7f4a3f6a59dd72fbcaff2a94f8f7f6 -U drh -Z fc8e968ece5f7a1fbfb50f6ab74c295e +P 9b2691aa911289d74bfe3edf45937a33fb7eaa8d +R aecccf1f2de8d72e3aa2a9e170f720dc +U dan +Z 51500cb9c3cff96463190c290eed59f5 diff --git a/manifest.uuid b/manifest.uuid index 74d3ea9cbe..f48de61aec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b2691aa911289d74bfe3edf45937a33fb7eaa8d \ No newline at end of file +713071c493e9937a20c436b07299df428249e378 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 84c14f7575..675ed91028 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -814,8 +814,13 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ int exists = 0; rc = multiplexSubFilename(pGroup, i); if( rc ) break; - rc2 = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[i].z, - SQLITE_ACCESS_EXISTS, &exists); + if( pGroup->flags & SQLITE_OPEN_DELETEONCLOSE ){ + exists = pGroup->nReal>=i && pGroup->aReal[i].p!=0; + rc2 = SQLITE_OK; + }else{ + rc2 = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[i].z, + SQLITE_ACCESS_EXISTS, &exists); + } if( rc2==SQLITE_OK && exists){ /* if it exists, open it */ pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL); From 694592b247250ade001241356c8e785a84e11988 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 12 Dec 2011 18:55:44 +0000 Subject: [PATCH 083/161] Change the multiplexor VFS so that xTruncate is a no-op on database files. FossilOrigin-Name: ee1e012256ae8010b6b6c4895a74b6883f20e73c --- manifest | 13 ++++---- manifest.uuid | 2 +- src/test_multiplex.c | 2 +- test/multiplex2.test | 70 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 test/multiplex2.test diff --git a/manifest b/manifest index 11ca04ed64..79ab16d091 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sfor\sthe\sxFileSize\smethod\sof\stest_multiplex.c\swhen\sused\son\sa\sfile\sopened\swith\sthe\sDELETEONCLOSE\sflag\sset. -D 2011-12-12T18:21:44.814 +C Change\sthe\smultiplexor\sVFS\sso\sthat\sxTruncate\sis\sa\sno-op\son\sdatabase\sfiles. +D 2011-12-12T18:55:44.020 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c affbe08d3c6f42d39490c022367ae3507b2fdf2f +F src/test_multiplex.c 7dcf429b53f5f5ef22bba7987bea61234a0c7418 F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -606,6 +606,7 @@ F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test eafaa41b9133d7a2ded4641bbe5f340731d35a52 F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054 F test/multiplex.test 770f0295dd6673e60458cb93abd033ed2f253291 +F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test e9648b9d007c7045242af35e11a984d4b169443a @@ -978,7 +979,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 9b2691aa911289d74bfe3edf45937a33fb7eaa8d -R aecccf1f2de8d72e3aa2a9e170f720dc +P 713071c493e9937a20c436b07299df428249e378 +R a7073a245182348c2b23e6c1f035f042 U dan -Z 51500cb9c3cff96463190c290eed59f5 +Z 56d8f5d800b0598a435509f86c8ead65 diff --git a/manifest.uuid b/manifest.uuid index f48de61aec..88b7f467c1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -713071c493e9937a20c436b07299df428249e378 \ No newline at end of file +ee1e012256ae8010b6b6c4895a74b6883f20e73c \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 675ed91028..091f2395fd 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -749,7 +749,7 @@ static int multiplexTruncate(sqlite3_file *pConn, sqlite3_int64 size){ }else{ rc = pSubOpen->pMethods->xTruncate(pSubOpen, size); } - }else{ + }else if( (pGroup->flags & SQLITE_OPEN_MAIN_DB)==0 ){ int rc2; int i; sqlite3_file *pSubOpen; diff --git a/test/multiplex2.test b/test/multiplex2.test new file mode 100644 index 0000000000..bdfc05b82f --- /dev/null +++ b/test/multiplex2.test @@ -0,0 +1,70 @@ +# 2010 October 29 +# +# 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. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl +source $testdir/lock_common.tcl + + +do_multiclient_test tn { + code1 { catch { sqlite3_multiplex_initialize "" 0 } } + code2 { catch { sqlite3_multiplex_initialize "" 0 } } + + code1 { db close } + code2 { db2 close } + + code1 { sqlite3 db test.db -vfs multiplex } + code2 { sqlite3 db2 test.db -vfs multiplex } + + code1 { sqlite3_multiplex_control db main chunk_size [expr 1024*1024] } + code2 { sqlite3_multiplex_control db2 main chunk_size [expr 1024*1024] } + + sql1 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(randomblob(10), randomblob(4000)); -- 1 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 2 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 4 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 8 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 16 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 32 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 64 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 128 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 256 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 512 + SELECT count(*) FROM t1; + } + + do_test multiplex-1.$tn.1 { sql1 { SELECT count(*) FROM t1 } } 512 + do_test multiplex-1.$tn.2 { sql2 { SELECT count(*) FROM t1 } } 512 + sql2 { DELETE FROM t1 ; VACUUM } + do_test multiplex-1.$tn.3 { sql1 { SELECT count(*) FROM t1 } } 0 + + sql1 { + INSERT INTO t1 VALUES(randomblob(10), randomblob(4000)); -- 1 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 2 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 4 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 8 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 16 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 32 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 64 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 128 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 256 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 512 + SELECT count(*) FROM t1; + } + + do_test multiplex-1.$tn.4 { sql2 { SELECT count(*) FROM t1 } } 512 +} + +catch { sqlite3_multiplex_shutdown } +finish_test From 663cebfeaed8b365d69246ed5f4d843d53f9be24 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 12 Dec 2011 19:47:25 +0000 Subject: [PATCH 084/161] Make sure the quota logic is usable as C++. FossilOrigin-Name: f4534bd3023a599691018f35389a76045e49d831 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_quota.c | 11 ++++++----- src/test_quota.h | 8 ++++++++ 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index e49d82bcc0..af26387f87 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3_quota_fflush()\sinterface.\s\sEnhance\ssqlite3_quota_remove()\nso\sthat\sit\scan\sremove\sentire\sdirectories. -D 2011-12-03T00:13:06.592 +C Make\ssure\sthe\squota\slogic\sis\susable\sas\sC++. +D 2011-12-12T19:47:25.223 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,8 +220,8 @@ F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 -F src/test_quota.c 2e6191cbfc6ae978330a0d0ffcc3fb81b7059e68 -F src/test_quota.h 9b3c75a79e8c3c6a9d3846b73435bebcd550ba12 +F src/test_quota.c 5259eaa0c98b1f55cbce1f34ed7043ae9538911e +F src/test_quota.h 98cb0cdc4b4c0fa917f7f43734127f6d182e94fa F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f @@ -979,7 +979,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 8cfd3575c8d9f5361c5276d6b83aba47606975a3 -R 28ca02cd727421756b639f8157eb6391 +P abcb65af4cdd192beaccdbc2109ad45b9e7f9d00 +R 219a0e733f4a37c7491a23e5eb8ab5d1 U drh -Z 84dc1ce8a56d57cb5251e17d63b686ff +Z ccc24742bcaed950386a7bec659a920b diff --git a/manifest.uuid b/manifest.uuid index 83ef24af72..ecb5e3b1f6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -abcb65af4cdd192beaccdbc2109ad45b9e7f9d00 \ No newline at end of file +f4534bd3023a599691018f35389a76045e49d831 \ No newline at end of file diff --git a/src/test_quota.c b/src/test_quota.c index c073b47d28..3ea3af0643 100644 --- a/src/test_quota.c +++ b/src/test_quota.c @@ -905,7 +905,8 @@ int sqlite3_quota_file(const char *zFilename){ int rc; int outFlags = 0; sqlite3_int64 iSize; - fd = sqlite3_malloc(gQuota.sThisVfs.szOsFile + gQuota.sThisVfs.mxPathname+1); + fd = (sqlite3_file*)sqlite3_malloc(gQuota.sThisVfs.szOsFile + + gQuota.sThisVfs.mxPathname+1); if( fd==0 ) return SQLITE_NOMEM; zFull = gQuota.sThisVfs.szOsFile + (char*)fd; rc = gQuota.pOrigVfs->xFullPathname(gQuota.pOrigVfs, zFilename, @@ -943,12 +944,12 @@ quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode){ quotaGroup *pGroup; quotaFile *pFile; - zFull = sqlite3_malloc(gQuota.sThisVfs.mxPathname + 1); + zFull = (char*)sqlite3_malloc(gQuota.sThisVfs.mxPathname + 1); if( zFull==0 ) return 0; rc = gQuota.pOrigVfs->xFullPathname(gQuota.pOrigVfs, zFilename, gQuota.sThisVfs.mxPathname+1, zFull); if( rc ) goto quota_fopen_error; - p = sqlite3_malloc(sizeof(*p)); + p = (quota_FILE*)sqlite3_malloc(sizeof(*p)); if( p==0 ) goto quota_fopen_error; memset(p, 0, sizeof(*p)); zFullTranslated = quota_utf8_to_mbcs(zFull); @@ -1097,7 +1098,7 @@ int sqlite3_quota_remove(const char *zFilename){ int diff; /* Difference between filenames */ char c; /* First character past end of pattern */ - zFull = sqlite3_malloc(gQuota.sThisVfs.mxPathname + 1); + zFull = (char*)sqlite3_malloc(gQuota.sThisVfs.mxPathname + 1); if( zFull==0 ) return SQLITE_NOMEM; rc = gQuota.pOrigVfs->xFullPathname(gQuota.pOrigVfs, zFilename, gQuota.sThisVfs.mxPathname+1, zFull); @@ -1438,7 +1439,7 @@ static int test_quota_fread( p = sqlite3TestTextToPtr(Tcl_GetString(objv[1])); if( Tcl_GetIntFromObj(interp, objv[2], &sz) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[3], &nElem) ) return TCL_ERROR; - zBuf = sqlite3_malloc( sz*nElem + 1 ); + zBuf = (char*)sqlite3_malloc( sz*nElem + 1 ); if( zBuf==0 ){ Tcl_SetResult(interp, "out of memory", TCL_STATIC); return TCL_ERROR; diff --git a/src/test_quota.h b/src/test_quota.h index dbcb2c185c..5dab714176 100644 --- a/src/test_quota.h +++ b/src/test_quota.h @@ -30,6 +30,11 @@ #include "sqlite3.h" #include +/* Make this callable from C++ */ +#ifdef __cplusplus +extern "C" { +#endif + /* ** Initialize the quota VFS shim. Use the VFS named zOrigVfsName ** as the VFS that does the actual work. Use the default if @@ -193,4 +198,7 @@ long sqlite3_quota_ftell(quota_FILE*); */ int sqlite3_quota_remove(const char *zFilename); +#ifdef __cplusplus +} /* end of the 'extern "C"' block */ +#endif #endif /* _QUOTA_H_ */ From 28a67fd3f8d2868a6ce5fa5af92eadb53dfa4d39 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 12 Dec 2011 19:48:43 +0000 Subject: [PATCH 085/161] Fix os_unix.c so that, unless 8.3 filenames are actually in use, journal and wal file permissions are assigned correctly even if SQLITE_ENABLE_8_3_NAMES is defined. FossilOrigin-Name: 169e12295cca701443746b1209bd6a7714fd8988 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 79ab16d091..1b7bb9a180 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\smultiplexor\sVFS\sso\sthat\sxTruncate\sis\sa\sno-op\son\sdatabase\sfiles. -D 2011-12-12T18:55:44.020 +C Fix\sos_unix.c\sso\sthat,\sunless\s8.3\sfilenames\sare\sactually\sin\suse,\sjournal\sand\swal\sfile\spermissions\sare\sassigned\scorrectly\seven\sif\sSQLITE_ENABLE_8_3_NAMES\sis\sdefined. +D 2011-12-12T19:48:43.750 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/os.c 28bbdab2170dfce84d86c45456a18eab1d0f99a9 F src/os.h 549b1a2e5e0ed1e1499f252dac126c4973e7379c F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c 07dcae2de5f1aab27a16e6c6fc89fe1bb134026e +F src/os_unix.c dcb42d74044efcf760c3c03c668e9e7314aa2427 F src/os_win.c 8af100f78f157eb6185fd9153d7f35b829c4da04 F src/pager.c d981f3bfcc0e4460537d983899620700ccf8f539 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 @@ -979,7 +979,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 713071c493e9937a20c436b07299df428249e378 -R a7073a245182348c2b23e6c1f035f042 +P ee1e012256ae8010b6b6c4895a74b6883f20e73c +R 6f54deb234c6e01cb7083112d4738ce0 U dan -Z 56d8f5d800b0598a435509f86c8ead65 +Z 1fe68808d0e2249c5544c1978ff3d49d diff --git a/manifest.uuid b/manifest.uuid index 88b7f467c1..a794f24ca6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ee1e012256ae8010b6b6c4895a74b6883f20e73c \ No newline at end of file +169e12295cca701443746b1209bd6a7714fd8988 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 0f003fc499..51778c861f 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4899,7 +4899,7 @@ static int findCreateFileMode( */ nDb = sqlite3Strlen30(zPath) - 1; #ifdef SQLITE_ENABLE_8_3_NAMES - while( nDb>0 && !sqlite3Isalnum(zPath[nDb]) ) nDb--; + while( nDb>0 && sqlite3Isalnum(zPath[nDb]) ) nDb--; if( nDb==0 || zPath[nDb]!='-' ) return SQLITE_OK; #else while( zPath[nDb]!='-' ){ From 73795becfe6358659b482f4ebd9a7c0358161a29 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 12 Dec 2011 20:01:12 +0000 Subject: [PATCH 086/161] Backport a minimal set of changes needed to get 8+3 filenames and the multiplexor shim playing well together. FossilOrigin-Name: c4e2ce486217c96373836bfe641f46abf891799a --- manifest | 19 ++++++++++------- manifest.uuid | 2 +- src/os_unix.c | 2 +- src/shell.c | 4 ++-- src/test_multiplex.c | 50 ++++++++++++++++++++++---------------------- 5 files changed, 40 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index aa26307489..7bfa9b8297 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\sdocumentation\sof\sthe\ssqlite3_db_filename()\sinterface. -D 2011-11-17T11:49:58.484 +C Backport\sa\sminimal\sset\sof\schanges\sneeded\sto\sget\s8+3\sfilenames\sand\sthe\nmultiplexor\sshim\splaying\swell\stogether. +D 2011-12-12T20:01:12.623 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/os.c 28bbdab2170dfce84d86c45456a18eab1d0f99a9 F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c 4fbb91726165e105c1679a2660f49a3f4c376e4f +F src/os_unix.c 02b3794c008bab490689399cca9a8b81c1df6eaa F src/os_win.c a22b88d2c088c09a678a471abafa8d60dbf56803 F src/pager.c d981f3bfcc0e4460537d983899620700ccf8f539 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 @@ -181,7 +181,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 -F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8 +F src/shell.c 183c4b6a84e82c768fefcc554a1256e89fc8feba F src/sqlite.h.in 19706a000717456c4963bb0f96262581436ffb5a F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h f412e020e1009163c74be56eaac1bf7f6c0a4515 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c 3fc368022c46fe44ec22c5e1ed727223a54a6a1d +F src/test_multiplex.c 7dcf429b53f5f5ef22bba7987bea61234a0c7418 F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -976,7 +976,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 4d3cf9e1d8ac356db5a708913f614e42a6a56b94 -R daa1b38027d3a49fc0c491c85b1f5a39 +P 1c45b2a0c055f6fc5da9d00ae2e9171099d904d4 +R d417f9c46d07ddef314e54db481adadc +T *branch * nx-devkit +T *sym-nx-devkit * +T -sym-trunk * U drh -Z f65f1ce31dbae92bc408999ba5cab4af +Z 6224f10399d131c42f88b8ba9dbbfa5d diff --git a/manifest.uuid b/manifest.uuid index 261f1cf6ad..b0605ecc85 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1c45b2a0c055f6fc5da9d00ae2e9171099d904d4 \ No newline at end of file +c4e2ce486217c96373836bfe641f46abf891799a \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 51d144906a..ecd5bf2448 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4899,7 +4899,7 @@ static int findCreateFileMode( */ nDb = sqlite3Strlen30(zPath) - 1; #ifdef SQLITE_ENABLE_8_3_NAMES - while( nDb>0 && !sqlite3Isalnum(zPath[nDb]) ) nDb--; + while( nDb>0 && sqlite3Isalnum(zPath[nDb]) ) nDb--; if( nDb==0 || zPath[nDb]!='-' ) return SQLITE_OK; #else while( zPath[nDb]!='-' ){ diff --git a/src/shell.c b/src/shell.c index e33a0687b4..07b1b60b41 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2335,7 +2335,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ }else if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ - printf("SQLite %s %s\n", + printf("SQLite %s %s\n" /*extra-version-info*/, sqlite3_libversion(), sqlite3_sourceid()); }else @@ -2932,7 +2932,7 @@ int main(int argc, char **argv){ char *zHistory = 0; int nHistory; printf( - "SQLite version %s %.19s\n" + "SQLite version %s %.19s\n" /*extra-version-info*/ "Enter \".help\" for instructions\n" "Enter SQL statements terminated with a \";\"\n", sqlite3_libversion(), sqlite3_sourceid() diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 5d29607acb..091f2395fd 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -96,26 +96,16 @@ # define SQLITE_MULTIPLEX_CHUNK_SIZE 2147418112 #endif -/* Default limit on number of chunks. Care should be taken -** so that values for chunks numbers fit in the SQLITE_MULTIPLEX_EXT_FMT -** format specifier. It may be changed by calling -** the xFileControl() interface. +/* This used to be the default limit on number of chunks, but +** it is no longer enforced. There is currently no limit to the +** number of chunks. +** +** May be changed by calling the xFileControl() interface. */ #ifndef SQLITE_MULTIPLEX_MAX_CHUNKS -# define SQLITE_MULTIPLEX_MAX_CHUNKS 32 +# define SQLITE_MULTIPLEX_MAX_CHUNKS 12 #endif -/* If SQLITE_MULTIPLEX_EXT_OVWR is defined, the -** last SQLITE_MULTIPLEX_EXT_SZ characters of the -** filename will be overwritten, otherwise, the -** multiplex extension is simply appended to the filename. -** Ex. (undefined) test.db -> test.db01 -** (defined) test.db -> test.01 -** Chunk 0 does not have a modified extension. -*/ -#define SQLITE_MULTIPLEX_EXT_FMT "%02d" -#define SQLITE_MULTIPLEX_EXT_SZ 2 - /************************ Object Definitions ******************************/ /* Forward declaration of all object types */ @@ -304,20 +294,25 @@ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){ if( pGroup->aReal[iChunk].z==0 ){ char *z; int n = pGroup->nName; - pGroup->aReal[iChunk].z = z = sqlite3_malloc( n+3 ); + pGroup->aReal[iChunk].z = z = sqlite3_malloc( n+4 ); if( z==0 ){ return SQLITE_NOMEM; } memcpy(z, pGroup->zName, n+1); if( iChunk>0 ){ #ifdef SQLITE_ENABLE_8_3_NAMES - if( n>3 && z[n-3]=='.' ){ - n--; - }else if( n>4 && z[n-4]=='.' ){ - n -= 2; + int i; + for(i=n-1; i>0 && i>=n-4 && z[i]!='.'; i--){} + if( i>=n-4 ) n = i+1; + if( pGroup->flags & (SQLITE_OPEN_MAIN_JOURNAL|SQLITE_OPEN_TEMP_JOURNAL) ){ + /* The extensions on overflow files for main databases are 001, 002, + ** 003 and so forth. To avoid name collisions, add 100 to the + ** extensions of journal files so that they are 101, 102, 103, .... + */ + iChunk += 100; } #endif - sqlite3_snprintf(3,&z[n],"%02d",iChunk); + sqlite3_snprintf(4,&z[n],"%03d",iChunk); } } return SQLITE_OK; @@ -754,7 +749,7 @@ static int multiplexTruncate(sqlite3_file *pConn, sqlite3_int64 size){ }else{ rc = pSubOpen->pMethods->xTruncate(pSubOpen, size); } - }else{ + }else if( (pGroup->flags & SQLITE_OPEN_MAIN_DB)==0 ){ int rc2; int i; sqlite3_file *pSubOpen; @@ -819,8 +814,13 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ int exists = 0; rc = multiplexSubFilename(pGroup, i); if( rc ) break; - rc2 = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[i].z, - SQLITE_ACCESS_EXISTS, &exists); + if( pGroup->flags & SQLITE_OPEN_DELETEONCLOSE ){ + exists = pGroup->nReal>=i && pGroup->aReal[i].p!=0; + rc2 = SQLITE_OK; + }else{ + rc2 = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[i].z, + SQLITE_ACCESS_EXISTS, &exists); + } if( rc2==SQLITE_OK && exists){ /* if it exists, open it */ pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL); From 9797706c048e1051147272cb81a894ac5284de20 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 13 Dec 2011 01:34:21 +0000 Subject: [PATCH 087/161] Add a compile-time shutdown procedure to be called by sqlite3_shutdown() to undo the effects of the compile-time initialization procedure. FossilOrigin-Name: c2ed86f5945662a4ddcdc7b303df3f64fb3bf17d --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/main.c | 4 ++++ 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 7bfa9b8297..8d8dddccea 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Backport\sa\sminimal\sset\sof\schanges\sneeded\sto\sget\s8+3\sfilenames\sand\sthe\nmultiplexor\sshim\splaying\swell\stogether. -D 2011-12-12T20:01:12.623 +C Add\sa\scompile-time\sshutdown\sprocedure\sto\sbe\scalled\sby\ssqlite3_shutdown()\s\nto\sundo\sthe\seffects\sof\sthe\scompile-time\sinitialization\sprocedure. +D 2011-12-13T01:34:21.866 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f -F src/main.c 55cbc40465fb58708cb82d4a285a6ea8cf1e4581 +F src/main.c f6abb5b6e34cefce99e598a59da7f9282cb95476 F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 7456e2ca0524609ebc06a9befeda5289d4575ad4 @@ -976,10 +976,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 1c45b2a0c055f6fc5da9d00ae2e9171099d904d4 -R d417f9c46d07ddef314e54db481adadc -T *branch * nx-devkit -T *sym-nx-devkit * -T -sym-trunk * +P c4e2ce486217c96373836bfe641f46abf891799a +R d65c08a2f3d54828df6dbe84b5def66b U drh -Z 6224f10399d131c42f88b8ba9dbbfa5d +Z a5e8c7320fe29c2fddbea8503f1c5fe2 diff --git a/manifest.uuid b/manifest.uuid index b0605ecc85..087f5b1d8d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c4e2ce486217c96373836bfe641f46abf891799a \ No newline at end of file +c2ed86f5945662a4ddcdc7b303df3f64fb3bf17d \ No newline at end of file diff --git a/src/main.c b/src/main.c index 43cd82eaa6..95f2e96872 100644 --- a/src/main.c +++ b/src/main.c @@ -257,6 +257,10 @@ int sqlite3_initialize(void){ */ int sqlite3_shutdown(void){ if( sqlite3GlobalConfig.isInit ){ +#ifdef SQLITE_EXTRA_SHUTDOWN + void SQLITE_EXTRA_SHUTDOWN(void); + SQLITE_EXTRA_SHUTDOWN(); +#endif sqlite3_os_end(); sqlite3_reset_auto_extension(); sqlite3GlobalConfig.isInit = 0; From 43795e3b0b62ad9a1ab17ab4aca23950f3651be3 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 13 Dec 2011 02:41:13 +0000 Subject: [PATCH 088/161] When the multiplexor FileSize procedure fails to open the file, assume that the file is zero bytes in size. FossilOrigin-Name: dc8118cd89da71f2035c6ee07c0edb772bba2186 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test_multiplex.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 8d8dddccea..63d5302050 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\scompile-time\sshutdown\sprocedure\sto\sbe\scalled\sby\ssqlite3_shutdown()\s\nto\sundo\sthe\seffects\sof\sthe\scompile-time\sinitialization\sprocedure. -D 2011-12-13T01:34:21.866 +C When\sthe\smultiplexor\sFileSize\sprocedure\sfails\sto\sopen\sthe\sfile,\sassume\sthat\nthe\sfile\sis\szero\sbytes\sin\ssize. +D 2011-12-13T02:41:13.433 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c 7dcf429b53f5f5ef22bba7987bea61234a0c7418 +F src/test_multiplex.c 56f837b9cafb0efb641a4073226f2b05a2c4872d F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -976,7 +976,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P c4e2ce486217c96373836bfe641f46abf891799a -R d65c08a2f3d54828df6dbe84b5def66b +P c2ed86f5945662a4ddcdc7b303df3f64fb3bf17d +R 54dcfa200fabf4bee31d0ce1ef27bb67 U drh -Z a5e8c7320fe29c2fddbea8503f1c5fe2 +Z 12069cbcb91e3fccb976a5eab6a4fcac diff --git a/manifest.uuid b/manifest.uuid index 087f5b1d8d..216e947580 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c2ed86f5945662a4ddcdc7b303df3f64fb3bf17d \ No newline at end of file +dc8118cd89da71f2035c6ee07c0edb772bba2186 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 091f2395fd..1a3fbdef9f 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -798,11 +798,12 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ int rc = SQLITE_OK; int rc2; int i; + *pSize = 0; multiplexEnter(); if( !pGroup->bEnabled ){ sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL); if( pSubOpen==0 ){ - rc = SQLITE_IOERR_FSTAT; + rc = SQLITE_OK; /* If SubOpen failed, assume a size of zero */ }else{ rc = pSubOpen->pMethods->xFileSize(pSubOpen, pSize); } @@ -813,7 +814,7 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ sqlite3_file *pSubOpen = 0; int exists = 0; rc = multiplexSubFilename(pGroup, i); - if( rc ) break; + if( rc ){ rc = SQLITE_OK; /* Assume size of zero */ break; } if( pGroup->flags & SQLITE_OPEN_DELETEONCLOSE ){ exists = pGroup->nReal>=i && pGroup->aReal[i].p!=0; rc2 = SQLITE_OK; From e5077c1211eba1a30995fb5fac43353c54cfad43 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 13 Dec 2011 04:08:36 +0000 Subject: [PATCH 089/161] When an sqlite3_auto_extension() function fails, report back its actual error code, not the generic SQLITE_ERROR. FossilOrigin-Name: ce55f250f56fa3a1ca864f81e9e86f911b981490 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/loadext.c | 5 +++-- src/main.c | 9 ++++++--- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 63d5302050..5d96461685 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sthe\smultiplexor\sFileSize\sprocedure\sfails\sto\sopen\sthe\sfile,\sassume\sthat\nthe\sfile\sis\szero\sbytes\sin\ssize. -D 2011-12-13T02:41:13.433 +C When\san\ssqlite3_auto_extension()\sfunction\sfails,\sreport\sback\sits\sactual\nerror\scode,\snot\sthe\sgeneric\sSQLITE_ERROR. +D 2011-12-13T04:08:36.892 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -146,8 +146,8 @@ F src/insert.c 8f283d6734dd837ed7531b26d7622fda70874390 F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 -F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f -F src/main.c f6abb5b6e34cefce99e598a59da7f9282cb95476 +F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d +F src/main.c 8fc06b5ab42330f26d13fbd8f969eead1d214556 F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 7456e2ca0524609ebc06a9befeda5289d4575ad4 @@ -976,7 +976,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P c2ed86f5945662a4ddcdc7b303df3f64fb3bf17d -R 54dcfa200fabf4bee31d0ce1ef27bb67 +P dc8118cd89da71f2035c6ee07c0edb772bba2186 +R fcee0dd6fa555d5216e315a8c5784053 U drh -Z 12069cbcb91e3fccb976a5eab6a4fcac +Z 9d7ca46858b8a86804ab1862673e090c diff --git a/manifest.uuid b/manifest.uuid index 216e947580..1c74b293b8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dc8118cd89da71f2035c6ee07c0edb772bba2186 \ No newline at end of file +ce55f250f56fa3a1ca864f81e9e86f911b981490 \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index e9c97adff3..3fcf5008cf 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -625,6 +625,7 @@ void sqlite3_reset_auto_extension(void){ void sqlite3AutoLoadExtensions(sqlite3 *db){ int i; int go = 1; + int rc; int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); wsdAutoextInit; @@ -647,8 +648,8 @@ void sqlite3AutoLoadExtensions(sqlite3 *db){ } sqlite3_mutex_leave(mutex); zErrmsg = 0; - if( xInit && xInit(db, &zErrmsg, &sqlite3Apis) ){ - sqlite3Error(db, SQLITE_ERROR, + if( xInit && (rc = xInit(db, &zErrmsg, &sqlite3Apis))!=0 ){ + sqlite3Error(db, rc, "automatic extension loading failed: %s", zErrmsg); go = 0; } diff --git a/src/main.c b/src/main.c index 95f2e96872..229af8607c 100644 --- a/src/main.c +++ b/src/main.c @@ -2250,10 +2250,13 @@ static int openDatabase( /* Load automatic extensions - extensions that have been registered ** using the sqlite3_automatic_extension() API. */ - sqlite3AutoLoadExtensions(db); rc = sqlite3_errcode(db); - if( rc!=SQLITE_OK ){ - goto opendb_out; + if( rc==SQLITE_OK ){ + sqlite3AutoLoadExtensions(db); + rc = sqlite3_errcode(db); + if( rc!=SQLITE_OK ){ + goto opendb_out; + } } #ifdef SQLITE_ENABLE_FTS1 From 5b1626aa472c520e50f569766e7944cfdf7657d1 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 13 Dec 2011 15:02:54 +0000 Subject: [PATCH 090/161] Move the multiplexor changes in the experimental branch (check-ins [255d21499b] and [199f52bced]) into the nx-devkit branch. FossilOrigin-Name: eb95d2f72c625bcfd0f8e9db1db2cb8799854b57 --- manifest | 12 +-- manifest.uuid | 2 +- src/test_multiplex.c | 182 ++++++++++++------------------------------- 3 files changed, 58 insertions(+), 138 deletions(-) diff --git a/manifest b/manifest index 5d96461685..b1b9ea84ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\san\ssqlite3_auto_extension()\sfunction\sfails,\sreport\sback\sits\sactual\nerror\scode,\snot\sthe\sgeneric\sSQLITE_ERROR. -D 2011-12-13T04:08:36.892 +C Move\sthe\smultiplexor\schanges\sin\sthe\sexperimental\sbranch\n(check-ins\s[255d21499b]\sand\s[199f52bced])\sinto\sthe\snx-devkit\sbranch. +D 2011-12-13T15:02:54.819 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c 56f837b9cafb0efb641a4073226f2b05a2c4872d +F src/test_multiplex.c 10aaf8b7ebeb74f82d5c96e06c398b776917e457 F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -976,7 +976,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P dc8118cd89da71f2035c6ee07c0edb772bba2186 -R fcee0dd6fa555d5216e315a8c5784053 +P ce55f250f56fa3a1ca864f81e9e86f911b981490 +R cc774ebd7c088b6b617c7f855781c545 U drh -Z 9d7ca46858b8a86804ab1862673e090c +Z 1b3d8d40cb48e276ed9ae7077034a64e diff --git a/manifest.uuid b/manifest.uuid index 1c74b293b8..a4233b55c6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ce55f250f56fa3a1ca864f81e9e86f911b981490 \ No newline at end of file +eb95d2f72c625bcfd0f8e9db1db2cb8799854b57 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 1a3fbdef9f..ce55bad083 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -213,71 +213,6 @@ static int multiplexStrlen30(const char *z){ return 0x3fffffff & (int)(z2 - z); } -/* -** Create a temporary file name in zBuf. zBuf must be big enough to -** hold at pOrigVfs->mxPathname characters. This function departs -** from the traditional temporary name generation in the os_win -** and os_unix VFS in several ways, but is necessary so that -** the file name is known for temporary files (like those used -** during vacuum.) -** -** N.B. This routine assumes your underlying VFS is ok with using -** "/" as a directory seperator. This is the default for UNIXs -** and is allowed (even mixed) for most versions of Windows. -*/ -static int multiplexGetTempname(sqlite3_vfs *pOrigVfs, int nBuf, char *zBuf){ - static char zChars[] = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789"; - int i,j; - int attempts = 0; - int exists = 0; - int rc = SQLITE_ERROR; - - /* Check that the output buffer is large enough for - ** pVfs->mxPathname characters. - */ - if( pOrigVfs->mxPathname <= nBuf ){ - char *zTmp = sqlite3_malloc(pOrigVfs->mxPathname); - if( zTmp==0 ) return SQLITE_NOMEM; - - /* sqlite3_temp_directory should always be less than - ** pVfs->mxPathname characters. - */ - sqlite3_snprintf(pOrigVfs->mxPathname, - zTmp, - "%s/", - sqlite3_temp_directory ? sqlite3_temp_directory : "."); - rc = pOrigVfs->xFullPathname(pOrigVfs, zTmp, nBuf, zBuf); - sqlite3_free(zTmp); - if( rc ) return rc; - - /* Check that the output buffer is large enough for the temporary file - ** name. - */ - j = multiplexStrlen30(zBuf); - if( (j + 8 + 1 + 3 + 1) <= nBuf ){ - /* Make 3 attempts to generate a unique name. */ - do { - attempts++; - sqlite3_randomness(8, &zBuf[j]); - for(i=0; i<8; i++){ - unsigned char uc = (unsigned char)zBuf[j+i]; - zBuf[j+i] = (char)zChars[uc%(sizeof(zChars)-1)]; - } - memcpy(&zBuf[j+i], ".tmp", 5); - rc = pOrigVfs->xAccess(pOrigVfs, zBuf, SQLITE_ACCESS_EXISTS, &exists); - } while ( (rc==SQLITE_OK) && exists && (attempts<3) ); - if( rc==SQLITE_OK && exists ){ - rc = SQLITE_ERROR; - } - } - } - - return rc; -} - /* Compute the filename for the iChunk-th chunk */ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){ @@ -291,7 +226,7 @@ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){ pGroup->aReal = p; pGroup->nReal = iChunk+1; } - if( pGroup->aReal[iChunk].z==0 ){ + if( pGroup->zName && pGroup->aReal[iChunk].z==0 ){ char *z; int n = pGroup->nName; pGroup->aReal[iChunk].z = z = sqlite3_malloc( n+4 ); @@ -461,6 +396,7 @@ static int multiplexOpen( UNUSED_PARAMETER(pVfs); memset(pConn, 0, pVfs->szOsFile); + assert( zName || (flags & SQLITE_OPEN_DELETEONCLOSE) ); /* We need to create a group structure and manage ** access to this group of files. @@ -468,23 +404,9 @@ static int multiplexOpen( multiplexEnter(); pMultiplexOpen = (multiplexConn*)pConn; - /* If the second argument to this function is NULL, generate a - ** temporary file name to use. This will be handled by the - ** original xOpen method. We just need to allocate space for - ** it. - */ - if( !zName ){ - zName = zToFree = sqlite3_malloc( pOrigVfs->mxPathname + 10 ); - if( zName==0 ){ - rc = SQLITE_NOMEM; - }else{ - rc = multiplexGetTempname(pOrigVfs, pOrigVfs->mxPathname, zToFree); - } - } - if( rc==SQLITE_OK ){ /* allocate space for group */ - nName = multiplexStrlen30(zName); + nName = zName ? multiplexStrlen30(zName) : 0; sz = sizeof(multiplexGroup) /* multiplexGroup */ + nName + 1; /* zName */ pGroup = sqlite3_malloc( sz ); @@ -495,32 +417,34 @@ static int multiplexOpen( if( rc==SQLITE_OK ){ /* assign pointers to extra space allocated */ - char *p = (char *)&pGroup[1]; - pMultiplexOpen->pGroup = pGroup; memset(pGroup, 0, sz); + pMultiplexOpen->pGroup = pGroup; pGroup->bEnabled = -1; pGroup->szChunk = SQLITE_MULTIPLEX_CHUNK_SIZE; - if( flags & SQLITE_OPEN_URI ){ - const char *zChunkSize; - zChunkSize = sqlite3_uri_parameter(zName, "chunksize"); - if( zChunkSize ){ - unsigned int n = 0; - int i; - for(i=0; zChunkSize[i]>='0' && zChunkSize[i]<='9'; i++){ - n = n*10 + zChunkSize[i] - '0'; - } - if( n>0 ){ - pGroup->szChunk = (n+0xffff)&~0xffff; - }else{ - /* A zero or negative chunksize disabled the multiplexor */ - pGroup->bEnabled = 0; + + if( zName ){ + char *p = (char *)&pGroup[1]; + if( flags & SQLITE_OPEN_URI ){ + const char *zChunkSize; + zChunkSize = sqlite3_uri_parameter(zName, "chunksize"); + if( zChunkSize ){ + unsigned int n = 0; + int i; + for(i=0; zChunkSize[i]>='0' && zChunkSize[i]<='9'; i++){ + n = n*10 + zChunkSize[i] - '0'; + } + if( n>0 ){ + pGroup->szChunk = (n+0xffff)&~0xffff; + }else{ + /* A zero or negative chunksize disabled the multiplexor */ + pGroup->bEnabled = 0; + } } } + pGroup->zName = p; + memcpy(pGroup->zName, zName, nName+1); + pGroup->nName = nName; } - pGroup->zName = p; - /* save off base filename, name length, and original open flags */ - memcpy(pGroup->zName, zName, nName+1); - pGroup->nName = nName; pGroup->flags = flags; rc = multiplexSubFilename(pGroup, 1); if( rc==SQLITE_OK ){ @@ -796,52 +720,44 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ multiplexConn *p = (multiplexConn*)pConn; multiplexGroup *pGroup = p->pGroup; int rc = SQLITE_OK; - int rc2; int i; - *pSize = 0; multiplexEnter(); if( !pGroup->bEnabled ){ sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL); if( pSubOpen==0 ){ - rc = SQLITE_OK; /* If SubOpen failed, assume a size of zero */ + rc = SQLITE_IOERR_FSTAT; }else{ rc = pSubOpen->pMethods->xFileSize(pSubOpen, pSize); } }else{ sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; *pSize = 0; - for(i=0; 1; i++){ + for(i=0; rc==SQLITE_OK; i++){ sqlite3_file *pSubOpen = 0; int exists = 0; rc = multiplexSubFilename(pGroup, i); - if( rc ){ rc = SQLITE_OK; /* Assume size of zero */ break; } - if( pGroup->flags & SQLITE_OPEN_DELETEONCLOSE ){ - exists = pGroup->nReal>=i && pGroup->aReal[i].p!=0; - rc2 = SQLITE_OK; - }else{ - rc2 = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[i].z, - SQLITE_ACCESS_EXISTS, &exists); + if( rc!=SQLITE_OK ) break; + if( pGroup->nReal>i && pGroup->aReal[i].p!=0 ){ + exists = 1; + }else if( (pGroup->flags & SQLITE_OPEN_DELETEONCLOSE)==0 ){ + const char *zReal = pGroup->aReal[i].z; + rc = pOrigVfs->xAccess(pOrigVfs, zReal, SQLITE_ACCESS_EXISTS, &exists); } - if( rc2==SQLITE_OK && exists){ - /* if it exists, open it */ + if( exists==0 ){ + /* stop at first "gap" or IO error. */ + break; + } + if( rc==SQLITE_OK ){ pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL); - }else{ - /* stop at first "gap" */ - break; } - if( pSubOpen ){ - sqlite3_int64 sz; - rc2 = pSubOpen->pMethods->xFileSize(pSubOpen, &sz); - if( rc2!=SQLITE_OK ){ - rc = rc2; - }else{ - if( sz>pGroup->szChunk ){ - rc = SQLITE_IOERR_FSTAT; - } - *pSize += sz; + assert( pSubOpen || rc!=SQLITE_OK ); + if( rc==SQLITE_OK ){ + sqlite3_int64 sz = 0; + rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz); + if( rc==SQLITE_OK && sz>pGroup->szChunk ){ + rc = SQLITE_IOERR_FSTAT; } - }else{ - break; + *pSize += sz; } } } @@ -1192,9 +1108,13 @@ static int test_multiplex_dump( for(pGroup=gMultiplex.pGroups; pGroup; pGroup=pGroup->pNext){ pGroupTerm = Tcl_NewObj(); - pGroup->zName[pGroup->nName] = '\0'; - Tcl_ListObjAppendElement(interp, pGroupTerm, + if( pGroup->zName ){ + pGroup->zName[pGroup->nName] = '\0'; + Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewStringObj(pGroup->zName, -1)); + }else{ + Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewObj()); + } Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewIntObj(pGroup->nName)); Tcl_ListObjAppendElement(interp, pGroupTerm, From 658dd586ed49b5fa620c3b6b939716b51f738bac Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 13 Dec 2011 15:25:06 +0000 Subject: [PATCH 091/161] Update the multiplex.test script to conform to that found in the "experimental" branch off of trunk. FossilOrigin-Name: 2eb79efbff9cdab843b172e9fa9fb400c542fab1 --- manifest | 13 +++--- manifest.uuid | 2 +- test/multiplex.test | 12 +++++- test/multiplex3.test | 99 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 8 deletions(-) create mode 100644 test/multiplex3.test diff --git a/manifest b/manifest index b1b9ea84ff..53293465dd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\sthe\smultiplexor\schanges\sin\sthe\sexperimental\sbranch\n(check-ins\s[255d21499b]\sand\s[199f52bced])\sinto\sthe\snx-devkit\sbranch. -D 2011-12-13T15:02:54.819 +C Update\sthe\smultiplex.test\sscript\sto\sconform\sto\sthat\sfound\sin\sthe\s"experimental"\nbranch\soff\sof\strunk. +D 2011-12-13T15:25:06.872 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -605,7 +605,8 @@ F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5 F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test eafaa41b9133d7a2ded4641bbe5f340731d35a52 F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054 -F test/multiplex.test 9df8bf738b3b97c718fceb3fadb30900ba494418 +F test/multiplex.test 8bc3c71f73fe833bc8a659d454d320044a33b5da +F test/multiplex3.test 2860177d0ec8d494c538f2199b8812df1c09c7c5 F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test e9648b9d007c7045242af35e11a984d4b169443a @@ -976,7 +977,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P ce55f250f56fa3a1ca864f81e9e86f911b981490 -R cc774ebd7c088b6b617c7f855781c545 +P eb95d2f72c625bcfd0f8e9db1db2cb8799854b57 +R f11319d97c8d3b9123b61c079ca9c86c U drh -Z 1b3d8d40cb48e276ed9ae7077034a64e +Z b47be607cba7caec297cb5893d5ae313 diff --git a/manifest.uuid b/manifest.uuid index a4233b55c6..a66362662f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eb95d2f72c625bcfd0f8e9db1db2cb8799854b57 \ No newline at end of file +2eb79efbff9cdab843b172e9fa9fb400c542fab1 \ No newline at end of file diff --git a/test/multiplex.test b/test/multiplex.test index 3abdcf4507..7168e753ab 100644 --- a/test/multiplex.test +++ b/test/multiplex.test @@ -14,6 +14,16 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl +# The tests in this file assume that SQLite is compiled without +# ENABLE_8_3_NAMES. +# +ifcapable 8_3_names { + puts -nonewline "SQLite compiled with SQLITE_ENABLE_8_3_NAMES. " + puts "Skipping tests multiplex-*." + finish_test + return +} + set g_chunk_size [ expr ($::SQLITE_MAX_PAGE_SIZE*16384) ] set g_max_chunks 32 @@ -24,7 +34,7 @@ set g_max_chunks 32 # file name with the chunk number. proc multiplex_name {name chunk} { if {$chunk==0} { return $name } - set num [format "%02d" $chunk] + set num [format "%03d" $chunk] ifcapable {multiplex_ext_overwrite} { set name [string range $name 0 [expr [string length $name]-2-1]] } diff --git a/test/multiplex3.test b/test/multiplex3.test new file mode 100644 index 0000000000..b1fd4d1f84 --- /dev/null +++ b/test/multiplex3.test @@ -0,0 +1,99 @@ + +# 2011 December 13 +# +# 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 error (IO, OOM etc.) handling when using +# the multiplexor extension with 8.3 filenames. +# + +set testdir $env(SQLITE_TEST_DIR) +source $testdir/tester.tcl +source $testdir/malloc_common.tcl +set ::testprefix multiplex3 + +ifcapable !8_3_names { + puts -nonewline "SQLite compiled without SQLITE_ENABLE_8_3_NAMES. " + puts "Skipping tests zipvfsD-*." + finish_test + return +} + +db close +sqlite3_shutdown +sqlite3_config_uri 1 +autoinstall_test_functions + +sqlite3_multiplex_initialize "" 1 + +proc destroy_vfs_stack {} { + generic_unregister stack + sqlite3_multiplex_shutdown +} + +proc multiplex_delete_db {} { + forcedelete test.db + for {set i 1} {$i <= 1000} {incr i} { + forcedelete test.[format %03d $i] + } +} + +# Procs to save and restore the current muliplexed database. +# +proc multiplex_save_db {} { + foreach f [glob -nocomplain sv_test.*] { forcedelete $f } + foreach f [glob -nocomplain test.*] { forcecopy $f "sv_$f" } +} +proc multiplex_restore_db {} { + foreach f [glob -nocomplain test.*] {forcedelete $f} + foreach f [glob -nocomplain sv_test.*] {forcecopy $f [string range $f 3 end]} } + + +do_test 1.0 { + multiplex_delete_db + sqlite3 db file:test.db?8_3_names=1 + sqlite3_multiplex_control db main chunk_size [expr 256*1024] + execsql { + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES(randomblob(15), randomblob(2000)); + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 2 + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 4 + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 8 + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 16 + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 32 + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 64 + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 128 + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 256 + INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 512 + } + set ::cksum1 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a}] + db close + multiplex_save_db +} {} + +do_faultsim_test 1 -prep { + multiplex_restore_db + sqlite3 db file:test.db?8_3_names=1 + sqlite3_multiplex_control db main chunk_size [expr 256*1024] +} -body { + execsql "UPDATE t1 SET a=randomblob(12), b=randomblob(1500) WHERE (rowid%32)=0" +} -test { + faultsim_test_result {0 {}} + if {$testrc!=0} { + set cksum2 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a}] + if {$cksum2 != $::cksum1} { error "data mismatch" } + } +} + +catch { db close } + +sqlite3_multiplex_shutdown +finish_test + From add995cc25875a2b9ab0fbe49a7ba307d9be54df Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 13 Dec 2011 16:40:33 +0000 Subject: [PATCH 092/161] Add extra tests for the multiplexor VFS. No changes to code. FossilOrigin-Name: c7de6f683d0fec62bc138b4a53b5cccc80c736c3 --- manifest | 15 ++++----- manifest.uuid | 2 +- test/multiplex2.test | 72 ++++++++++++++++++++++++++++++++++++++++++++ test/multiplex3.test | 46 ++++++++++++++++++++++++---- 4 files changed, 121 insertions(+), 14 deletions(-) create mode 100644 test/multiplex2.test diff --git a/manifest b/manifest index 53293465dd..2927bef9ea 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\smultiplex.test\sscript\sto\sconform\sto\sthat\sfound\sin\sthe\s"experimental"\nbranch\soff\sof\strunk. -D 2011-12-13T15:25:06.872 +C Add\sextra\stests\sfor\sthe\smultiplexor\sVFS.\sNo\schanges\sto\scode. +D 2011-12-13T16:40:33.044 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -606,7 +606,8 @@ F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test eafaa41b9133d7a2ded4641bbe5f340731d35a52 F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054 F test/multiplex.test 8bc3c71f73fe833bc8a659d454d320044a33b5da -F test/multiplex3.test 2860177d0ec8d494c538f2199b8812df1c09c7c5 +F test/multiplex2.test 7e507a63f3981731556224b23646d29013b98c03 +F test/multiplex3.test 6772008fcaa754ae1b5ddc27c55aa813b12569b2 F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test e9648b9d007c7045242af35e11a984d4b169443a @@ -977,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P eb95d2f72c625bcfd0f8e9db1db2cb8799854b57 -R f11319d97c8d3b9123b61c079ca9c86c -U drh -Z b47be607cba7caec297cb5893d5ae313 +P 2eb79efbff9cdab843b172e9fa9fb400c542fab1 +R 77c5fb359ca24a528b4e0f7440c132da +U dan +Z 0e58dc3998254ef9753cd678e848dfd4 diff --git a/manifest.uuid b/manifest.uuid index a66362662f..fe6cb114ee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2eb79efbff9cdab843b172e9fa9fb400c542fab1 \ No newline at end of file +c7de6f683d0fec62bc138b4a53b5cccc80c736c3 \ No newline at end of file diff --git a/test/multiplex2.test b/test/multiplex2.test new file mode 100644 index 0000000000..b3a1656b02 --- /dev/null +++ b/test/multiplex2.test @@ -0,0 +1,72 @@ +# 2010 October 29 +# +# 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. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl +source $testdir/lock_common.tcl +db close + +do_multiclient_test tn { + foreach f [glob -nocomplain test.*] { forcedelete $f } + + code1 { catch { sqlite3_multiplex_initialize "" 0 } } + code2 { catch { sqlite3_multiplex_initialize "" 0 } } + + code1 { db close } + code2 { db2 close } + + code1 { sqlite3 db test.db -vfs multiplex } + code2 { sqlite3 db2 test.db -vfs multiplex } + + code1 { sqlite3_multiplex_control db main chunk_size [expr 1024*1024] } + code2 { sqlite3_multiplex_control db2 main chunk_size [expr 1024*1024] } + + sql1 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(randomblob(10), randomblob(4000)); -- 1 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 2 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 4 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 8 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 16 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 32 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 64 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 128 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 256 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 512 + SELECT count(*) FROM t1; + } + + do_test multiplex-1.$tn.1 { sql1 { SELECT count(*) FROM t1 } } 512 + do_test multiplex-1.$tn.2 { sql2 { SELECT count(*) FROM t1 } } 512 + sql2 { DELETE FROM t1 ; VACUUM } + do_test multiplex-1.$tn.3 { sql1 { SELECT count(*) FROM t1 } } 0 + + sql1 { + INSERT INTO t1 VALUES(randomblob(10), randomblob(4000)); -- 1 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 2 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 4 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 8 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 16 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 32 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 64 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 128 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 256 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 512 + SELECT count(*) FROM t1; + } + + do_test multiplex-1.$tn.4 { sql2 { SELECT count(*) FROM t1 } } 512 +} + +catch { sqlite3_multiplex_shutdown } +finish_test diff --git a/test/multiplex3.test b/test/multiplex3.test index b1fd4d1f84..9764ab4e60 100644 --- a/test/multiplex3.test +++ b/test/multiplex3.test @@ -55,8 +55,7 @@ proc multiplex_restore_db {} { foreach f [glob -nocomplain test.*] {forcedelete $f} foreach f [glob -nocomplain sv_test.*] {forcecopy $f [string range $f 3 end]} } - -do_test 1.0 { +proc setup_and_save_db {} { multiplex_delete_db sqlite3 db file:test.db?8_3_names=1 sqlite3_multiplex_control db main chunk_size [expr 256*1024] @@ -76,14 +75,17 @@ do_test 1.0 { set ::cksum1 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a}] db close multiplex_save_db -} {} +} +do_test 1.0 { setup_and_save_db } {} do_faultsim_test 1 -prep { multiplex_restore_db sqlite3 db file:test.db?8_3_names=1 sqlite3_multiplex_control db main chunk_size [expr 256*1024] } -body { - execsql "UPDATE t1 SET a=randomblob(12), b=randomblob(1500) WHERE (rowid%32)=0" + execsql { + UPDATE t1 SET a=randomblob(12), b=randomblob(1500) WHERE (rowid%32)=0 + } } -test { faultsim_test_result {0 {}} if {$testrc!=0} { @@ -92,8 +94,40 @@ do_faultsim_test 1 -prep { } } -catch { db close } +#------------------------------------------------------------------------- +# The following tests verify that hot-journal rollback works. As follows: +# +# 1. Create a large database. +# 2. Set the pager cache to be very small. +# 3. Open a transaction. +# 4. Run the following 100 times: +# a. Update a row. +# b. Copy all files on disk to a new db location, including the journal. +# c. Verify that the new db can be opened and that the content matches +# the database created in step 1 (proving the journal was rolled +# back). +do_test 2.0 { + setup_and_save_db + multiplex_restore_db + sqlite3 db file:test.db?8_3_names=1 + execsql { PRAGMA cache_size = 10 } + execsql { BEGIN } +} {} + +for {set iTest 1} {$iTest<=100} {incr iTest} { + do_test 2.$iTest { + execsql { + UPDATE t1 SET a=randomblob(12), b=randomblob(1400) WHERE rowid=5*$iTest + } + foreach f [glob -nocomplain test.*] {forcecopy $f "xx_$f"} + sqlite3 db2 file:xx_test.db?8_3_names=1 + execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a} db2 + } $::cksum1 + + db2 close +} + +catch { db close } sqlite3_multiplex_shutdown finish_test - From c7f946297a47319ac70b237a624a97495fc6b2ba Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 13 Dec 2011 18:22:38 +0000 Subject: [PATCH 093/161] Change the SQLITE_EXTRA_INIT routine to take a single argument which is a pointer to a string. Call SQLITE_EXTRA_INIT with a NULL argument. Fixes to multiplexor to treat the VFS properly in corner cases. Fix the initialization of multiplex3.test. FossilOrigin-Name: 8e65b9132530e46c62bd1352bfc2e9c29f57af5f --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/main.c | 4 ++-- src/test_multiplex.c | 4 ++-- test/multiplex3.test | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 2927bef9ea..3dc07e0bd5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sextra\stests\sfor\sthe\smultiplexor\sVFS.\sNo\schanges\sto\scode. -D 2011-12-13T16:40:33.044 +C Change\sthe\sSQLITE_EXTRA_INIT\sroutine\sto\stake\sa\ssingle\sargument\swhich\sis\sa\npointer\sto\sa\sstring.\s\sCall\sSQLITE_EXTRA_INIT\swith\sa\sNULL\sargument.\nFixes\sto\smultiplexor\sto\streat\sthe\sVFS\sproperly\sin\scorner\scases.\s\sFix\sthe\ninitialization\sof\smultiplex3.test. +D 2011-12-13T18:22:38.364 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d -F src/main.c 8fc06b5ab42330f26d13fbd8f969eead1d214556 +F src/main.c e7e6985365795ef6c500d05d766222222efbb0ac F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 7456e2ca0524609ebc06a9befeda5289d4575ad4 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c 10aaf8b7ebeb74f82d5c96e06c398b776917e457 +F src/test_multiplex.c c8cfaa7fa15494454a39c7e79241760d5fbe2c0c F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -607,7 +607,7 @@ F test/misc7.test eafaa41b9133d7a2ded4641bbe5f340731d35a52 F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054 F test/multiplex.test 8bc3c71f73fe833bc8a659d454d320044a33b5da F test/multiplex2.test 7e507a63f3981731556224b23646d29013b98c03 -F test/multiplex3.test 6772008fcaa754ae1b5ddc27c55aa813b12569b2 +F test/multiplex3.test e17b73e904dbd789de37192b6b94424e6f847bc3 F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test e9648b9d007c7045242af35e11a984d4b169443a @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 2eb79efbff9cdab843b172e9fa9fb400c542fab1 -R 77c5fb359ca24a528b4e0f7440c132da -U dan -Z 0e58dc3998254ef9753cd678e848dfd4 +P c7de6f683d0fec62bc138b4a53b5cccc80c736c3 +R c2c58817769bc21d103f97b44c17e047 +U drh +Z e8a8ea3bf562796b70179d1fa7b7b6fa diff --git a/manifest.uuid b/manifest.uuid index fe6cb114ee..8aab40e318 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c7de6f683d0fec62bc138b4a53b5cccc80c736c3 \ No newline at end of file +8e65b9132530e46c62bd1352bfc2e9c29f57af5f \ No newline at end of file diff --git a/src/main.c b/src/main.c index 229af8607c..7abde24e71 100644 --- a/src/main.c +++ b/src/main.c @@ -239,8 +239,8 @@ int sqlite3_initialize(void){ */ #ifdef SQLITE_EXTRA_INIT if( rc==SQLITE_OK && sqlite3GlobalConfig.isInit ){ - int SQLITE_EXTRA_INIT(void); - rc = SQLITE_EXTRA_INIT(); + int SQLITE_EXTRA_INIT(const char*); + rc = SQLITE_EXTRA_INIT(0); } #endif diff --git a/src/test_multiplex.c b/src/test_multiplex.c index ce55bad083..0208d2d98d 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -455,7 +455,7 @@ static int multiplexOpen( sqlite3_int64 sz; rc2 = pSubOpen->pMethods->xFileSize(pSubOpen, &sz); - if( rc2==SQLITE_OK ){ + if( rc2==SQLITE_OK && zName ){ /* If the first overflow file exists and if the size of the main file ** is different from the chunk size, that means the chunk size is set ** set incorrectly. So fix it. @@ -857,7 +857,7 @@ static int multiplexSectorSize(sqlite3_file *pConn){ multiplexConn *p = (multiplexConn*)pConn; int rc; sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); - if( pSubOpen ){ + if( pSubOpen && pSubOpen->pMethods->xSectorSize ){ return pSubOpen->pMethods->xSectorSize(pSubOpen); } return DEFAULT_SECTOR_SIZE; diff --git a/test/multiplex3.test b/test/multiplex3.test index 9764ab4e60..bdb264fdec 100644 --- a/test/multiplex3.test +++ b/test/multiplex3.test @@ -14,7 +14,7 @@ # the multiplexor extension with 8.3 filenames. # -set testdir $env(SQLITE_TEST_DIR) +set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl set ::testprefix multiplex3 From 27e69643cf81eb991dc5051c67857325c73220e2 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 13 Dec 2011 19:03:34 +0000 Subject: [PATCH 094/161] Add a hard limit to the number of chunks a multiplexed database may consist of if ENABLE_8_3_NAMES is defined. FossilOrigin-Name: 43a1264088c57bf598787b7a9f5d7a2536603d67 --- manifest | 16 ++++++------- manifest.uuid | 2 +- src/test_multiplex.c | 24 +++++++++++++------ test/multiplex2.test | 55 ++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 77 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 3dc07e0bd5..82b9fafa49 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sSQLITE_EXTRA_INIT\sroutine\sto\stake\sa\ssingle\sargument\swhich\sis\sa\npointer\sto\sa\sstring.\s\sCall\sSQLITE_EXTRA_INIT\swith\sa\sNULL\sargument.\nFixes\sto\smultiplexor\sto\streat\sthe\sVFS\sproperly\sin\scorner\scases.\s\sFix\sthe\ninitialization\sof\smultiplex3.test. -D 2011-12-13T18:22:38.364 +C Add\sa\shard\slimit\sto\sthe\snumber\sof\schunks\sa\smultiplexed\sdatabase\smay\sconsist\sof\sif\sENABLE_8_3_NAMES\sis\sdefined. +D 2011-12-13T19:03:34.498 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c c8cfaa7fa15494454a39c7e79241760d5fbe2c0c +F src/test_multiplex.c 10f881e4508976d970569fe0e7779bfec17907e5 F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -606,7 +606,7 @@ F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test eafaa41b9133d7a2ded4641bbe5f340731d35a52 F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054 F test/multiplex.test 8bc3c71f73fe833bc8a659d454d320044a33b5da -F test/multiplex2.test 7e507a63f3981731556224b23646d29013b98c03 +F test/multiplex2.test 896ff138d27688b68c894b8166606454ce915793 F test/multiplex3.test e17b73e904dbd789de37192b6b94424e6f847bc3 F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P c7de6f683d0fec62bc138b4a53b5cccc80c736c3 -R c2c58817769bc21d103f97b44c17e047 -U drh -Z e8a8ea3bf562796b70179d1fa7b7b6fa +P 8e65b9132530e46c62bd1352bfc2e9c29f57af5f +R 72e3acbb02cd24af246addd5a37e5bd0 +U dan +Z bb7ad67fc331d74f2be1df794e13fcc3 diff --git a/manifest.uuid b/manifest.uuid index 8aab40e318..97f853f6e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8e65b9132530e46c62bd1352bfc2e9c29f57af5f \ No newline at end of file +43a1264088c57bf598787b7a9f5d7a2536603d67 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 0208d2d98d..85b63b48f4 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -81,6 +81,8 @@ #define sqlite3_mutex_notheld(X) ((void)(X),1) #endif /* SQLITE_THREADSAFE==0 */ +#define SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET 400 + /************************ Shim Definitions ******************************/ @@ -97,7 +99,7 @@ #endif /* This used to be the default limit on number of chunks, but -** it is no longer enforced. There is currently no limit to the +** it is no longer enforced. There is currently no limit to the ** number of chunks. ** ** May be changed by calling the xFileControl() interface. @@ -244,7 +246,7 @@ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){ ** 003 and so forth. To avoid name collisions, add 100 to the ** extensions of journal files so that they are 101, 102, 103, .... */ - iChunk += 100; + iChunk += SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET; } #endif sqlite3_snprintf(4,&z[n],"%03d",iChunk); @@ -264,6 +266,18 @@ static sqlite3_file *multiplexSubOpen( ){ sqlite3_file *pSubOpen = 0; sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ + +#ifdef SQLITE_ENABLE_8_3_NAMES + /* If JOURNAL_8_3_OFFSET is set to (say) 500, then any overflow files are + ** part of a database journal are named db.501, db.502, and so on. A + ** database may therefore not grow to larger than 500 chunks. Attempting + ** to open chunk 501 indicates the database is full. */ + if( iChunk>=SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET ){ + *rc = SQLITE_FULL; + return 0; + } +#endif + *rc = multiplexSubFilename(pGroup, iChunk); if( (*rc)==SQLITE_OK && (pSubOpen = pGroup->aReal[iChunk].p)==0 ){ pSubOpen = sqlite3_malloc( pOrigVfs->szOsFile ); @@ -633,7 +647,7 @@ static int multiplexWrite( rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst); } }else{ - while( iAmt > 0 ){ + while( rc==SQLITE_OK && iAmt>0 ){ int i = (int)(iOfst / pGroup->szChunk); sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL); if( pSubOpen ){ @@ -643,13 +657,9 @@ static int multiplexWrite( iAmt -= extra; rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst % pGroup->szChunk); - if( rc!=SQLITE_OK ) break; pBuf = (char *)pBuf + iAmt; iOfst += iAmt; iAmt = extra; - }else{ - rc = SQLITE_IOERR_WRITE; - break; } } } diff --git a/test/multiplex2.test b/test/multiplex2.test index b3a1656b02..bf5791fe88 100644 --- a/test/multiplex2.test +++ b/test/multiplex2.test @@ -14,6 +14,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl source $testdir/lock_common.tcl +set testprefix multiplex2 db close do_multiclient_test tn { @@ -46,10 +47,10 @@ do_multiclient_test tn { SELECT count(*) FROM t1; } - do_test multiplex-1.$tn.1 { sql1 { SELECT count(*) FROM t1 } } 512 - do_test multiplex-1.$tn.2 { sql2 { SELECT count(*) FROM t1 } } 512 + do_test 1.$tn.1 { sql1 { SELECT count(*) FROM t1 } } 512 + do_test 1.$tn.2 { sql2 { SELECT count(*) FROM t1 } } 512 sql2 { DELETE FROM t1 ; VACUUM } - do_test multiplex-1.$tn.3 { sql1 { SELECT count(*) FROM t1 } } 0 + do_test 1.$tn.3 { sql1 { SELECT count(*) FROM t1 } } 0 sql1 { INSERT INTO t1 VALUES(randomblob(10), randomblob(4000)); -- 1 @@ -65,8 +66,54 @@ do_multiclient_test tn { SELECT count(*) FROM t1; } - do_test multiplex-1.$tn.4 { sql2 { SELECT count(*) FROM t1 } } 512 + do_test 1.$tn.4 { sql2 { SELECT count(*) FROM t1 } } 512 } +catch {db close} +foreach f [glob -nocomplain test.*] { forcedelete $f } + +ifcapable 8_3_names { + sqlite3 db test.db -vfs multiplex + sqlite3_multiplex_control db main chunk_size [expr 256*1024] + + # Insert 512 * 256K (128MB) of data. If each row is around 4K, this means + # we need 32768 rows. + do_catchsql_test 2.1 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(randomblob(10), randomblob(4000)); -- 1 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 2 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 4 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 8 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 16 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 32 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 64 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 128 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 256 + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 512 + + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 1K + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 2K + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 4K + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 8K + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 16K + INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1; -- 32K + + } {1 {database or disk is full}} + + do_execsql_test 2.2 { + UPDATE t1 SET a=randomblob(9), b=randomblob(3900); + PRAGMA integrity_check; + } ok + + db close + sqlite3 db test.db -vfs multiplex + sqlite3_multiplex_control db main chunk_size [expr 256*1024] + + do_execsql_test 2.3 { + PRAGMA integrity_check; + } ok +} + +catch { db close } catch { sqlite3_multiplex_shutdown } finish_test From 27cec37d8e8ad5493b2225ff707bcdb7c79a1bd6 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 13 Dec 2011 23:26:10 +0000 Subject: [PATCH 095/161] Enhancements to test_quota.c: Remove the external dependency on sqlite3_win32_utf8_to_msbc(). Add an extra parameter to quota_fflush() that will also do an fsync (or the equivalent). FossilOrigin-Name: 92f4188f90e3cdd71f1457a6e0eb22615e4a54f4 --- manifest | 16 +++++++------- manifest.uuid | 2 +- src/test_quota.c | 54 +++++++++++++++++++++++++++++++++++++++++------- src/test_quota.h | 11 +++++++--- test/quota2.test | 10 ++++++++- 5 files changed, 72 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index af26387f87..0a28bcdaa2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\squota\slogic\sis\susable\sas\sC++. -D 2011-12-12T19:47:25.223 +C Enhancements\sto\stest_quota.c:\s\sRemove\sthe\sexternal\sdependency\son\s\nsqlite3_win32_utf8_to_msbc().\s\sAdd\san\sextra\sparameter\sto\squota_fflush()\nthat\swill\salso\sdo\san\sfsync\s(or\sthe\sequivalent). +D 2011-12-13T23:26:10.637 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,8 +220,8 @@ F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 -F src/test_quota.c 5259eaa0c98b1f55cbce1f34ed7043ae9538911e -F src/test_quota.h 98cb0cdc4b4c0fa917f7f43734127f6d182e94fa +F src/test_quota.c fc7d4c4f8538396c1b0116efef695f9f33f984e7 +F src/test_quota.h 9ffa1d3ad6d0a6a24e8670ea64b909c717ec3358 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f @@ -636,7 +636,7 @@ F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26 F test/quota.test 46e6571b45c3c58ac131cc38f7d600aa9f75974d -F test/quota2.test 562b27570d1e0d0606c3769b648e23c72fa3859b +F test/quota2.test 1b8df088e604f2df573f96e726b5e518cb0cddaa F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6 F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test 1084050991e9ba22c1c10edd8d84673b501cc25a @@ -979,7 +979,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P abcb65af4cdd192beaccdbc2109ad45b9e7f9d00 -R 219a0e733f4a37c7491a23e5eb8ab5d1 +P f4534bd3023a599691018f35389a76045e49d831 +R 47ed3793a4d313cda8ae0615d4d258b5 U drh -Z ccc24742bcaed950386a7bec659a920b +Z a4d5e00fab55c6c4275b01f8f924030e diff --git a/manifest.uuid b/manifest.uuid index ecb5e3b1f6..76cee7109d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f4534bd3023a599691018f35389a76045e49d831 \ No newline at end of file +92f4188f90e3cdd71f1457a6e0eb22615e4a54f4 \ No newline at end of file diff --git a/src/test_quota.c b/src/test_quota.c index 3ea3af0643..e8eac19652 100644 --- a/src/test_quota.c +++ b/src/test_quota.c @@ -404,6 +404,12 @@ static quotaFile *quotaFindFile( # endif #endif +#if SQLITE_OS_UNIX +# include +#endif +#if SQLITE_OS_WIN +# include +#endif /* ** Translate UTF8 to MBCS for use in fopen() calls. Return a pointer to the @@ -412,8 +418,26 @@ static quotaFile *quotaFindFile( */ static char *quota_utf8_to_mbcs(const char *zUtf8){ #if SQLITE_OS_WIN - extern char *sqlite3_win32_utf8_to_mbcs(const char*); - return sqlite3_win32_utf8_to_mbcs(zUtf8); + int n; /* Bytes in zUtf8 */ + int nWide; /* number of UTF-16 characters */ + int nMbcs; /* Bytes of MBCS */ + LPWSTR zTmpWide; /* The UTF16 text */ + char *zMbcs; /* The MBCS text */ + int codepage; /* Code page used by fopen() */ + + n = strlen(zUtf8); + nWide = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, NULL, 0); + zTmpWide = sqlite3_malloc( nWide*sizeof(zTmpWide[0]) ); + if( zTmpWide==0 ) return 0; + MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zTmpWide, nWide); + codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; + nMbcs = WideCharToMultiByte(codepage, 0, zTmpWide, nWide, 0, 0, 0, 0); + zMbcs = sqlite3_malloc( nMbcs+1 ); + if( zMbcs ){ + WideCharToMultiByte(codepage, 0, zTmpWide, nWide, zMbcs, nMbcs, 0, 0); + } + sqlite3_free(zTmpWide); + return zMbcs; #else return (char*)zUtf8; /* No-op on unix */ #endif @@ -1060,8 +1084,18 @@ int sqlite3_quota_fclose(quota_FILE *p){ /* ** Flush memory buffers for a quota_FILE to disk. */ -int sqlite3_quota_fflush(quota_FILE *p){ - return fflush(p->f); +int sqlite3_quota_fflush(quota_FILE *p, int doFsync){ + int rc; + rc = fflush(p->f); + if( rc==0 && doFsync ){ +#if SQLITE_OS_UNIX + rc = fsync(fileno(p->f)); +#endif +#if SQLITE_OS_WIN + rc = 0==FlushFileBuffers((HANDLE)_fileno(p->f)); +#endif + } + return rc; } /* @@ -1503,7 +1537,7 @@ static int test_quota_fclose( } /* -** tclcmd: sqlite3_quota_fflush HANDLE +** tclcmd: sqlite3_quota_fflush HANDLE ?HARDSYNC? */ static int test_quota_fflush( void * clientData, @@ -1513,13 +1547,17 @@ static int test_quota_fflush( ){ quota_FILE *p; int rc; + int doSync = 0; - if( objc!=2 ){ - Tcl_WrongNumArgs(interp, 1, objv, "HANDLE"); + if( objc!=2 && objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE ?HARDSYNC?"); return TCL_ERROR; } p = sqlite3TestTextToPtr(Tcl_GetString(objv[1])); - rc = sqlite3_quota_fflush(p); + if( objc==3 ){ + if( Tcl_GetBooleanFromObj(interp, objv[2], &doSync) ) return TCL_ERROR; + } + rc = sqlite3_quota_fflush(p, doSync); Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_OK; } diff --git a/src/test_quota.h b/src/test_quota.h index 5dab714176..a2fddbbc43 100644 --- a/src/test_quota.h +++ b/src/test_quota.h @@ -158,10 +158,15 @@ size_t sqlite3_quota_fwrite(void*, size_t, size_t, quota_FILE*); /* ** Flush all written content held in memory buffers out to disk. -** This is the equivalent of fflush() in the standard library - not -** an fsync(). +** This is the equivalent of fflush() in the standard library. +** +** If the hardSync parameter is true (non-zero) then this routine +** also forces OS buffers to disk - the equivalent of fsync(). +** +** This routine return zero on success and non-zero if something goes +** wrong. */ -int sqlite3_quota_fflush(quota_FILE*); +int sqlite3_quota_fflush(quota_FILE*, int hardSync); /* ** Close a quota_FILE object and free all associated resources. The diff --git a/test/quota2.test b/test/quota2.test index 4b9daca2a2..cf3449dafc 100644 --- a/test/quota2.test +++ b/test/quota2.test @@ -177,7 +177,15 @@ do_test quota2-3.1 { do_test quota2-3.2 { standard_path [sqlite3_quota_dump] } {{*/quota2a/* 4000 100 {PWD/quota2a/x1/a.txt 100 1 0}}} -do_test quota2-3.3 { +do_test quota2-3.3a { + sqlite3_quota_fflush $::h1 0 + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 100 {PWD/quota2a/x1/a.txt 100 1 0}}} +do_test quota2-3.3b { + sqlite3_quota_fflush $::h1 1 + standard_path [sqlite3_quota_dump] +} {{*/quota2a/* 4000 100 {PWD/quota2a/x1/a.txt 100 1 0}}} +do_test quota2-3.3c { sqlite3_quota_fflush $::h1 standard_path [sqlite3_quota_dump] } {{*/quota2a/* 4000 100 {PWD/quota2a/x1/a.txt 100 1 0}}} From 49ed5c8562cbf9059d454c0ac68cd38ae2b38f66 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 14 Dec 2011 00:04:52 +0000 Subject: [PATCH 096/161] Harden the utf8-to-mbcs converter in the quota module against failures. FossilOrigin-Name: 1cda511deb625868395a23c95346e14d0c300670 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test_quota.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 0a28bcdaa2..eb499cd1b5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhancements\sto\stest_quota.c:\s\sRemove\sthe\sexternal\sdependency\son\s\nsqlite3_win32_utf8_to_msbc().\s\sAdd\san\sextra\sparameter\sto\squota_fflush()\nthat\swill\salso\sdo\san\sfsync\s(or\sthe\sequivalent). -D 2011-12-13T23:26:10.637 +C Harden\sthe\sutf8-to-mbcs\sconverter\sin\sthe\squota\smodule\sagainst\sfailures. +D 2011-12-14T00:04:52.373 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 -F src/test_quota.c fc7d4c4f8538396c1b0116efef695f9f33f984e7 +F src/test_quota.c 2552dfd897d2d74ecc368487fa5859e9a2b254ab F src/test_quota.h 9ffa1d3ad6d0a6a24e8670ea64b909c717ec3358 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 @@ -979,7 +979,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P f4534bd3023a599691018f35389a76045e49d831 -R 47ed3793a4d313cda8ae0615d4d258b5 +P 92f4188f90e3cdd71f1457a6e0eb22615e4a54f4 +R 628f1bcc3bb63f06518edb62745f94e5 U drh -Z a4d5e00fab55c6c4275b01f8f924030e +Z 2cf614ef38a2cb741ec717409dbd005d diff --git a/manifest.uuid b/manifest.uuid index 76cee7109d..1cd189003e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -92f4188f90e3cdd71f1457a6e0eb22615e4a54f4 \ No newline at end of file +1cda511deb625868395a23c95346e14d0c300670 \ No newline at end of file diff --git a/src/test_quota.c b/src/test_quota.c index e8eac19652..e2c0808969 100644 --- a/src/test_quota.c +++ b/src/test_quota.c @@ -427,12 +427,13 @@ static char *quota_utf8_to_mbcs(const char *zUtf8){ n = strlen(zUtf8); nWide = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, NULL, 0); - zTmpWide = sqlite3_malloc( nWide*sizeof(zTmpWide[0]) ); + if( nWide==0 ) return 0; + zTmpWide = sqlite3_malloc( (nWide+1)*sizeof(zTmpWide[0]) ); if( zTmpWide==0 ) return 0; MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zTmpWide, nWide); codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; nMbcs = WideCharToMultiByte(codepage, 0, zTmpWide, nWide, 0, 0, 0, 0); - zMbcs = sqlite3_malloc( nMbcs+1 ); + zMbcs = nMbcs ? sqlite3_malloc( nMbcs+1 ) : 0; if( zMbcs ){ WideCharToMultiByte(codepage, 0, zTmpWide, nWide, zMbcs, nMbcs, 0, 0); } From 6ca514b075afe07eee51dbeb6910ab4022e567eb Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 14 Dec 2011 00:37:45 +0000 Subject: [PATCH 097/161] Treat a zero return value from the Win32 APIs MultiByteToWideChar and WideCharToMultiByte as an error condition. FossilOrigin-Name: c65e5a36f1a1c91cb3415158ebe0f5759cbcdf96 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_win.c | 12 ++++++++++++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 296d435e22..7ebd8e4a88 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\snx-devkit\schanges\sinto\strunk. -D 2011-12-13T15:37:12.235 +C Treat\sa\szero\sreturn\svalue\sfrom\sthe\sWin32\sAPIs\sMultiByteToWideChar\sand\sWideCharToMultiByte\sas\san\serror\scondition. +D 2011-12-14T00:37:45.399 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -167,7 +167,7 @@ F src/os.h 549b1a2e5e0ed1e1499f252dac126c4973e7379c F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c dcb42d74044efcf760c3c03c668e9e7314aa2427 -F src/os_win.c 8af100f78f157eb6185fd9153d7f35b829c4da04 +F src/os_win.c 745cfae00e887ba90452f7ef2a245272c4ed7374 F src/pager.c d981f3bfcc0e4460537d983899620700ccf8f539 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba @@ -980,7 +980,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 169e12295cca701443746b1209bd6a7714fd8988 2eb79efbff9cdab843b172e9fa9fb400c542fab1 -R e5aa0bc552fbb5033b8311d030f5558d -U drh -Z afe5f3537b446035b4ee9315704cbe8b +P 03a70c3dae8d912fccd9d72c575dc372b198d238 +R 29870a4086be96ebc531e67fe7235bdd +U mistachkin +Z fc2bb105d27bbafb8656bcd186800dc4 diff --git a/manifest.uuid b/manifest.uuid index 2ba39b2ac4..5678b5737e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -03a70c3dae8d912fccd9d72c575dc372b198d238 \ No newline at end of file +c65e5a36f1a1c91cb3415158ebe0f5759cbcdf96 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index ae110c541c..bfde4b6f9f 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -918,6 +918,9 @@ static LPWSTR utf8ToUnicode(const char *zFilename){ LPWSTR zWideFilename; nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); + if( nChar==0 ){ + return 0; + } zWideFilename = sqlite3_malloc( nChar*sizeof(zWideFilename[0]) ); if( zWideFilename==0 ){ return 0; @@ -940,6 +943,9 @@ static char *unicodeToUtf8(LPCWSTR zWideFilename){ char *zFilename; nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); + if( nByte == 0 ){ + return 0; + } zFilename = sqlite3_malloc( nByte ); if( zFilename==0 ){ return 0; @@ -967,6 +973,9 @@ static LPWSTR mbcsToUnicode(const char *zFilename){ nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL, 0)*sizeof(WCHAR); + if( nByte==0 ){ + return 0; + } zMbcsFilename = sqlite3_malloc( nByte*sizeof(zMbcsFilename[0]) ); if( zMbcsFilename==0 ){ return 0; @@ -993,6 +1002,9 @@ static char *unicodeToMbcs(LPCWSTR zWideFilename){ int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); + if( nByte == 0 ){ + return 0; + } zFilename = sqlite3_malloc( nByte ); if( zFilename==0 ){ return 0; From 43a6d4bd4434ef62572c98264aaaf4d01b71c4ac Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 14 Dec 2011 01:38:12 +0000 Subject: [PATCH 098/161] Improvements to comments. No code changes. FossilOrigin-Name: 08bbbd8e38697908ab8ae0f6b512d01c32f7e4da --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_multiplex.c | 13 +++++++------ 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 82b9fafa49..03d497d4df 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\shard\slimit\sto\sthe\snumber\sof\schunks\sa\smultiplexed\sdatabase\smay\sconsist\sof\sif\sENABLE_8_3_NAMES\sis\sdefined. -D 2011-12-13T19:03:34.498 +C Improvements\sto\scomments.\s\sNo\scode\schanges. +D 2011-12-14T01:38:12.485 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c 10f881e4508976d970569fe0e7779bfec17907e5 +F src/test_multiplex.c a61af1bd64a78429c87c79d870bf681b66e7e025 F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 8e65b9132530e46c62bd1352bfc2e9c29f57af5f -R 72e3acbb02cd24af246addd5a37e5bd0 -U dan -Z bb7ad67fc331d74f2be1df794e13fcc3 +P 43a1264088c57bf598787b7a9f5d7a2536603d67 +R bccaf9dcf75a81906ae2a631899b3b9f +U drh +Z 311819ae6733da4a29af5f18337fa8de diff --git a/manifest.uuid b/manifest.uuid index 97f853f6e5..38fadc9ea8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -43a1264088c57bf598787b7a9f5d7a2536603d67 \ No newline at end of file +08bbbd8e38697908ab8ae0f6b512d01c32f7e4da \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 85b63b48f4..c4aeca81b5 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -81,6 +81,7 @@ #define sqlite3_mutex_notheld(X) ((void)(X),1) #endif /* SQLITE_THREADSAFE==0 */ +/* First chunk for rollback journal files */ #define SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET 400 @@ -243,8 +244,8 @@ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){ if( i>=n-4 ) n = i+1; if( pGroup->flags & (SQLITE_OPEN_MAIN_JOURNAL|SQLITE_OPEN_TEMP_JOURNAL) ){ /* The extensions on overflow files for main databases are 001, 002, - ** 003 and so forth. To avoid name collisions, add 100 to the - ** extensions of journal files so that they are 101, 102, 103, .... + ** 003 and so forth. To avoid name collisions, add 400 to the + ** extensions of journal files so that they are 401, 402, 403, .... */ iChunk += SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET; } @@ -268,10 +269,10 @@ static sqlite3_file *multiplexSubOpen( sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ #ifdef SQLITE_ENABLE_8_3_NAMES - /* If JOURNAL_8_3_OFFSET is set to (say) 500, then any overflow files are - ** part of a database journal are named db.501, db.502, and so on. A - ** database may therefore not grow to larger than 500 chunks. Attempting - ** to open chunk 501 indicates the database is full. */ + /* If JOURNAL_8_3_OFFSET is set to (say) 400, then any overflow files are + ** part of a database journal are named db.401, db.402, and so on. A + ** database may therefore not grow to larger than 400 chunks. Attempting + ** to open chunk 401 indicates the database is full. */ if( iChunk>=SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET ){ *rc = SQLITE_FULL; return 0; From de60fc2d87a9483cfc1e60ca04381dc07079920b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 14 Dec 2011 17:53:36 +0000 Subject: [PATCH 099/161] Add a file-control that will discover the name of the bottom-level VFS and all the shims in between. FossilOrigin-Name: cdbfb553af02d10767a905489d9dfc57fc6be54e --- manifest | 33 ++++++++++++++++++--------------- manifest.uuid | 2 +- src/os_unix.c | 6 ++++++ src/os_win.c | 4 ++++ src/shell.c | 13 +++++++++++++ src/sqlite.h.in | 12 ++++++++++++ src/test1.c | 34 ++++++++++++++++++++++++++++++++++ src/test_multiplex.c | 3 +++ src/test_osinst.c | 6 +++++- src/test_quota.c | 6 +++++- src/test_vfstrace.c | 8 ++++++++ test/quota.test | 5 +++++ 12 files changed, 114 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 03d497d4df..a798047867 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\scomments.\s\sNo\scode\schanges. -D 2011-12-14T01:38:12.485 +C Add\sa\sfile-control\sthat\swill\sdiscover\sthe\sname\sof\sthe\sbottom-level\sVFS\sand\nall\sthe\sshims\sin\sbetween. +D 2011-12-14T17:53:36.239 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,8 +166,8 @@ F src/os.c 28bbdab2170dfce84d86c45456a18eab1d0f99a9 F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c 02b3794c008bab490689399cca9a8b81c1df6eaa -F src/os_win.c a22b88d2c088c09a678a471abafa8d60dbf56803 +F src/os_unix.c baad28b27adc563579170b6d765af0b0cc1d98c8 +F src/os_win.c 823f55855ceb062d72231409b828d0486f09125f F src/pager.c d981f3bfcc0e4460537d983899620700ccf8f539 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 @@ -181,15 +181,15 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 365ab1c870e38596d6869e76fb544fe6e4ffc809 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6 -F src/shell.c 183c4b6a84e82c768fefcc554a1256e89fc8feba -F src/sqlite.h.in 19706a000717456c4963bb0f96262581436ffb5a +F src/shell.c 670644f7bd82073ce0c97c6bff94be04c326beb8 +F src/sqlite.h.in 84cd7be33f5bf39329e018f93eb34b4a345c9c23 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h f412e020e1009163c74be56eaac1bf7f6c0a4515 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c de581e2e71f5e7f98366156afad83b4742ac6fe0 -F src/test1.c a445a5d09f63ca66a704720dbec240c65806bcd1 +F src/test1.c d019682c4480d612e4eca73412011a120e1468db F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7 @@ -214,13 +214,13 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c a61af1bd64a78429c87c79d870bf681b66e7e025 +F src/test_multiplex.c 80677a47c75ca6a035d1ac66fb59186ffd4cdd19 F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec -F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32 +F src/test_osinst.c 6abf0a37ce831120c4ef1b913afdd813e7ac1a73 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 -F src/test_quota.c a391c866217e92986c6f523f05b08aa6956c8419 +F src/test_quota.c ec7d1056936f69be953c343bcb480305ce8928f3 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f @@ -230,7 +230,7 @@ F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_thread.c 35022393dd54d147b998b6b7f7e945b01114d666 F src/test_vfs.c 27b7d9de40630f603b9e2cf9ef2a7c81d31c4515 -F src/test_vfstrace.c 0b884e06094a746da729119a2cabdc7aa790063d +F src/test_vfstrace.c 065c7270a614254b2c68fbc7ba8d1fb1d5cbc823 F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c c819d9f72168a035d545a5bdafe9b085b20df705 @@ -635,7 +635,7 @@ F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 -F test/quota.test 1c59a396e8f7b5d8466fa74b59f2aeb778d74f7a +F test/quota.test e09a01ec974e04a2c4f1c7615005722725b5e131 F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6 F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test 1084050991e9ba22c1c10edd8d84673b501cc25a @@ -978,7 +978,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 43a1264088c57bf598787b7a9f5d7a2536603d67 -R bccaf9dcf75a81906ae2a631899b3b9f +P 08bbbd8e38697908ab8ae0f6b512d01c32f7e4da +R d213e3c5e90076919d50d6149e76976e +T *branch * vfsname-filectrl +T *sym-vfsname-filectrl * +T -sym-nx-devkit * U drh -Z 311819ae6733da4a29af5f18337fa8de +Z 739c7a11bf4ddcfa0aa24a6fb0f05205 diff --git a/manifest.uuid b/manifest.uuid index 38fadc9ea8..d2ab48f170 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -08bbbd8e38697908ab8ae0f6b512d01c32f7e4da \ No newline at end of file +cdbfb553af02d10767a905489d9dfc57fc6be54e \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index ecd5bf2448..3cb28b058d 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -206,6 +206,7 @@ struct UnixUnusedFd { typedef struct unixFile unixFile; struct unixFile { sqlite3_io_methods const *pMethod; /* Always the first entry */ + sqlite3_vfs *pVfs; /* The VFS that created this unixFile */ unixInodeInfo *pInode; /* Info about locks on this inode */ int h; /* The file descriptor */ unsigned char eFileLock; /* The type of lock held on this fd */ @@ -3533,6 +3534,10 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ } return SQLITE_OK; } + case SQLITE_FCNTL_VFSNAME: { + *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); + 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 @@ -4560,6 +4565,7 @@ static int fillInUnixFile( OSTRACE(("OPEN %-3d %s\n", h, zFilename)); pNew->h = h; + pNew->pVfs = pVfs; pNew->zPath = zFilename; if( memcmp(pVfs->zName,"unix-excl",10)==0 ){ pNew->ctrlFlags = UNIXFILE_EXCL; diff --git a/src/os_win.c b/src/os_win.c index 62868ba504..53cf523538 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -2145,6 +2145,10 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ } return SQLITE_OK; } + case SQLITE_FCNTL_VFSNAME: { + *(char**)pArg = sqlite3_mprintf("win32"); + return SQLITE_OK; + } case SQLITE_FCNTL_SYNC_OMITTED: { return SQLITE_OK; } diff --git a/src/shell.c b/src/shell.c index 07b1b60b41..503d8a6a8d 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1396,6 +1396,7 @@ static char zHelp[] = " If TABLE specified, only list tables matching\n" " LIKE pattern TABLE.\n" ".timeout MS Try opening locked tables for MS milliseconds\n" + ".vfsname ?AUX? Print the name of the VFS stack\n" ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n" ; @@ -2339,6 +2340,18 @@ static int do_meta_command(char *zLine, struct callback_data *p){ sqlite3_libversion(), sqlite3_sourceid()); }else + if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){ + const char *zDbName = nArg==2 ? azArg[1] : "main"; + char *zVfsName = 0; + if( p->db ){ + sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName); + if( zVfsName ){ + printf("%s\n", zVfsName); + sqlite3_free(zVfsName); + } + } + }else + if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){ int j; assert( nArg<=ArraySize(azArg) ); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 75241da42d..5533728038 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -771,6 +771,17 @@ struct sqlite3_io_methods { ** a write transaction to indicate that, unless it is rolled back for some ** reason, the entire database file will be overwritten by the current ** transaction. This is used by VACUUM operations. +** +** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of +** all [VFSes] in the VFS stack. The names are of all VFS shims and the +** final bottom-level VFS are written into memory obtained from +** [sqlite3_malloc()] and the result is stored in the char* variable +** that the fourth parameter of [sqlite3_file_control()] points to. +** The caller is responsible for freeing the memory when done. As with +** all file-control actions, there is no guarantee that this will actually +** do anything. Callers should initialize the char* variable to a NULL +** pointer in case this file-control is not implemented. This file-control +** is intended for diagnostic use only. */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_GET_LOCKPROXYFILE 2 @@ -783,6 +794,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_WIN32_AV_RETRY 9 #define SQLITE_FCNTL_PERSIST_WAL 10 #define SQLITE_FCNTL_OVERWRITE 11 +#define SQLITE_FCNTL_VFSNAME 12 /* ** CAPI3REF: Mutex Handle diff --git a/src/test1.c b/src/test1.c index 3cf9b1375e..3c68743680 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5209,6 +5209,39 @@ static int file_control_persist_wal( } +/* +** tclcmd: file_control_vfsname DB ?AUXDB? +** +** Return a string that describes the stack of VFSes. +*/ +static int file_control_vfsname( + ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + sqlite3 *db; + const char *zDbName = "main"; + char *zVfsName = 0; + + if( objc!=2 && objc!=3 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_GetStringFromObj(objv[0], 0), " DB ?AUXDB?", 0); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ + return TCL_ERROR; + } + if( objc==3 ){ + zDbName = Tcl_GetString(objv[2]); + } + sqlite3_file_control(db, zDbName, SQLITE_FCNTL_VFSNAME,(void*)&zVfsName); + Tcl_AppendResult(interp, zVfsName, (char*)0); + sqlite3_free(zVfsName); + return TCL_OK; +} + + /* ** tclcmd: sqlite3_vfs_list ** @@ -6032,6 +6065,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "file_control_sizehint_test", file_control_sizehint_test, 0 }, { "file_control_win32_av_retry", file_control_win32_av_retry, 0 }, { "file_control_persist_wal", file_control_persist_wal, 0 }, + { "file_control_vfsname", file_control_vfsname, 0 }, { "sqlite3_vfs_list", vfs_list, 0 }, { "sqlite3_create_function_v2", test_create_function_v2, 0 }, diff --git a/src/test_multiplex.c b/src/test_multiplex.c index c4aeca81b5..f6540d82dc 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -856,6 +856,9 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){ pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL); if( pSubOpen ){ rc = pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg); + if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){ + *(char**)pArg = sqlite3_mprintf("multiplex/%z", *(char**)pArg); + } } break; } diff --git a/src/test_osinst.c b/src/test_osinst.c index 50d6250e6c..b7f350577c 100644 --- a/src/test_osinst.c +++ b/src/test_osinst.c @@ -389,7 +389,11 @@ static int vfslogCheckReservedLock(sqlite3_file *pFile, int *pResOut){ */ static int vfslogFileControl(sqlite3_file *pFile, int op, void *pArg){ VfslogFile *p = (VfslogFile *)pFile; - return p->pReal->pMethods->xFileControl(p->pReal, op, pArg); + int rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg); + if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){ + *(char**)pArg = sqlite3_mprintf("vfslog/%z", *(char**)pArg); + } + return rc; } /* diff --git a/src/test_quota.c b/src/test_quota.c index 74d1a6d3ba..9aad4967b6 100644 --- a/src/test_quota.c +++ b/src/test_quota.c @@ -589,7 +589,11 @@ static int quotaCheckReservedLock(sqlite3_file *pConn, int *pResOut){ */ static int quotaFileControl(sqlite3_file *pConn, int op, void *pArg){ sqlite3_file *pSubOpen = quotaSubOpen(pConn); - return pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg); + int rc = pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg); + if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){ + *(char**)pArg = sqlite3_mprintf("quota/%z", *(char**)pArg); + } + return rc; } /* Pass xSectorSize requests through to the original VFS unchanged. diff --git a/src/test_vfstrace.c b/src/test_vfstrace.c index 5e94f5cf06..62577207b9 100644 --- a/src/test_vfstrace.c +++ b/src/test_vfstrace.c @@ -471,6 +471,10 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){ } case SQLITE_FCNTL_FILE_POINTER: zOp = "FILE_POINTER"; break; case SQLITE_FCNTL_SYNC_OMITTED: zOp = "SYNC_OMITTED"; break; + case SQLITE_FCNTL_WIN32_AV_RETRY: zOp = "WIN32_AV_RETRY"; break; + case SQLITE_FCNTL_PERSIST_WAL: zOp = "PERSIST_WAL"; break; + case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break; + case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break; case 0xca093fa0: zOp = "DB_UNCHANGED"; break; default: { sqlite3_snprintf(sizeof zBuf, zBuf, "%d", op); @@ -482,6 +486,10 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){ pInfo->zVfsName, p->zFName, zOp); rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg); vfstrace_print_errcode(pInfo, " -> %s\n", rc); + if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){ + *(char**)pArg = sqlite3_mprintf("vfstrace.%s/%z", + pInfo->zVfsName, *(char**)pArg); + } return rc; } diff --git a/test/quota.test b/test/quota.test index 49b403f1eb..29cb612fd4 100644 --- a/test/quota.test +++ b/test/quota.test @@ -14,6 +14,8 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl +unset -nocomplain defaultVfs +set defaultVfs [file_control_vfsname db] db close do_test quota-1.1 { sqlite3_quota_initialize nosuchvfs 1 } {SQLITE_ERROR} @@ -73,6 +75,9 @@ do_test quota-2.1.2 { } set ::quota } {} +do_test quota-2.1.2.1 { + file_control_vfsname db +} quota/$defaultVfs do_test quota-2.1.3 { file size test.db } {4096} do_test quota-2.1.4 { catchsql { INSERT INTO t1 VALUES(3, randomblob(1100)) } From 2be25bffcad4002b02a08a84eccb6bf72037721d Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Dec 2011 02:22:16 +0000 Subject: [PATCH 100/161] In the multiplexor, do not try to delete overflow files that do not exist. And assume all but the last overflow file is the size of the chunk size. FossilOrigin-Name: a822a80d3cfe42b2fca6f8c9ff11762993114a27 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test_multiplex.c | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e9459b2243..cd4f6d1738 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sVFSNAME\sfile-control\saddition\sinto\sthe\snx-devkit\sbranch. -D 2011-12-14T18:28:18.920 +C In\sthe\smultiplexor,\sdo\snot\stry\sto\sdelete\soverflow\sfiles\sthat\sdo\snot\sexist.\nAnd\sassume\sall\sbut\sthe\slast\soverflow\sfile\sis\sthe\ssize\sof\sthe\schunk\ssize. +D 2011-12-15T02:22:16.244 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c 80677a47c75ca6a035d1ac66fb59186ffd4cdd19 +F src/test_multiplex.c cee2474efe6ee92732e43184f62422bc17623d1f F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 08bbbd8e38697908ab8ae0f6b512d01c32f7e4da cdbfb553af02d10767a905489d9dfc57fc6be54e -R d213e3c5e90076919d50d6149e76976e +P 08c1dc517c1340737a55ad9012b7b06f72899c6f +R 05ea69e1c214c57dec4ba569476ada26 U drh -Z 8e788ffb68fb72b933914781f94a7874 +Z 5b0957f1b7fd94c5b03cf783382a1410 diff --git a/manifest.uuid b/manifest.uuid index d03e81ee9a..18315cb8d5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -08c1dc517c1340737a55ad9012b7b06f72899c6f \ No newline at end of file +a822a80d3cfe42b2fca6f8c9ff11762993114a27 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index f6540d82dc..b9688e34df 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -365,7 +365,9 @@ static void multiplexSubClose( sqlite3_file *pSubOpen = pGroup->aReal[iChunk].p; if( pSubOpen ){ pSubOpen->pMethods->xClose(pSubOpen); - if( pOrigVfs ) pOrigVfs->xDelete(pOrigVfs, pGroup->aReal[iChunk].z, 0); + if( pOrigVfs && pGroup->aReal[iChunk].z ){ + pOrigVfs->xDelete(pOrigVfs, pGroup->aReal[iChunk].z, 0); + } sqlite3_free(pGroup->aReal[iChunk].p); } sqlite3_free(pGroup->aReal[iChunk].z); @@ -768,7 +770,7 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ if( rc==SQLITE_OK && sz>pGroup->szChunk ){ rc = SQLITE_IOERR_FSTAT; } - *pSize += sz; + *pSize = i*(sqlite3_int64)pGroup->szChunk + sz; } } } From 31b21295b0f291b2e4f37442b687672e1feffac3 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 15 Dec 2011 11:45:19 +0000 Subject: [PATCH 101/161] Fix some problems with dropped error codes in multiplexOpen(). FossilOrigin-Name: 2d50f78188e3297e8cefdf73cff51fa0a3b36e65 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_multiplex.c | 18 +++++++++++------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index cd4f6d1738..33561aa1a4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\smultiplexor,\sdo\snot\stry\sto\sdelete\soverflow\sfiles\sthat\sdo\snot\sexist.\nAnd\sassume\sall\sbut\sthe\slast\soverflow\sfile\sis\sthe\ssize\sof\sthe\schunk\ssize. -D 2011-12-15T02:22:16.244 +C Fix\ssome\sproblems\swith\sdropped\serror\scodes\sin\smultiplexOpen(). +D 2011-12-15T11:45:19.350 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c cee2474efe6ee92732e43184f62422bc17623d1f +F src/test_multiplex.c 7e8d8303b8ba74ff50fbb40502522e576760266e F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 08c1dc517c1340737a55ad9012b7b06f72899c6f -R 05ea69e1c214c57dec4ba569476ada26 -U drh -Z 5b0957f1b7fd94c5b03cf783382a1410 +P a822a80d3cfe42b2fca6f8c9ff11762993114a27 +R 4637baef8720406f37351464996699d4 +U dan +Z a1536baba57190ddd9d59e1c01fe9761 diff --git a/manifest.uuid b/manifest.uuid index 18315cb8d5..b07b3ebcac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a822a80d3cfe42b2fca6f8c9ff11762993114a27 \ No newline at end of file +2d50f78188e3297e8cefdf73cff51fa0a3b36e65 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index b9688e34df..f0d495f491 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -466,13 +466,15 @@ static int multiplexOpen( rc = multiplexSubFilename(pGroup, 1); if( rc==SQLITE_OK ){ pSubOpen = multiplexSubOpen(pGroup, 0, &rc, pOutFlags); + assert( pSubOpen || rc!=SQLITE_OK ); } - if( pSubOpen ){ - int exists, rc2, rc3; + if( rc==SQLITE_OK ){ sqlite3_int64 sz; - rc2 = pSubOpen->pMethods->xFileSize(pSubOpen, &sz); - if( rc2==SQLITE_OK && zName ){ + rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz); + if( rc==SQLITE_OK && zName ){ + int exists; + /* If the first overflow file exists and if the size of the main file ** is different from the chunk size, that means the chunk size is set ** set incorrectly. So fix it. @@ -482,16 +484,18 @@ static int multiplexOpen( ** But we have no way of determining the intended chunk size, so ** just disable the multiplexor all togethre. */ - rc3 = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z, + rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z, SQLITE_ACCESS_EXISTS, &exists); - if( rc3==SQLITE_OK && exists && sz==(sz&0xffff0000) && sz>0 + if( rc==SQLITE_OK && exists && sz==(sz&0xffff0000) && sz>0 && sz!=pGroup->szChunk ){ pGroup->szChunk = sz; - }else if( rc3==SQLITE_OK && !exists && sz>pGroup->szChunk ){ + }else if( rc==SQLITE_OK && !exists && sz>pGroup->szChunk ){ pGroup->bEnabled = 0; } } + } + if( rc==SQLITE_OK ){ if( pSubOpen->pMethods->iVersion==1 ){ pMultiplexOpen->base.pMethods = &gMultiplex.sIoMethodsV1; }else{ From 78c0eafb3535fd70d74b9753b4e52f7a6225b5a2 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Dec 2011 13:29:12 +0000 Subject: [PATCH 102/161] Make sure the chunksize in test_multiplex does not cause the pending byte to fall near the end of a chunk. Adjust the chunksize upward as necessary to prevent this. FossilOrigin-Name: e05f8a2998f4f4cbdb65702baa65893c538b3d38 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_multiplex.c | 10 ++++++++++ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 33561aa1a4..21cbee27f3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\sproblems\swith\sdropped\serror\scodes\sin\smultiplexOpen(). -D 2011-12-15T11:45:19.350 +C Make\ssure\sthe\schunksize\sin\stest_multiplex\sdoes\snot\scause\sthe\spending\sbyte\nto\sfall\snear\sthe\send\sof\sa\schunk.\s\sAdjust\sthe\schunksize\supward\sas\snecessary\nto\sprevent\sthis. +D 2011-12-15T13:29:12.575 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c 7e8d8303b8ba74ff50fbb40502522e576760266e +F src/test_multiplex.c 7b65eea8b390dd223bd6e0ba9d7879389bd075c0 F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P a822a80d3cfe42b2fca6f8c9ff11762993114a27 -R 4637baef8720406f37351464996699d4 -U dan -Z a1536baba57190ddd9d59e1c01fe9761 +P 2d50f78188e3297e8cefdf73cff51fa0a3b36e65 +R db6d46332c6333123f8fa60ccb204a1d +U drh +Z f65d5d73aa828ce8ac2cca0eb8289aa5 diff --git a/manifest.uuid b/manifest.uuid index b07b3ebcac..ce1d054b8f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2d50f78188e3297e8cefdf73cff51fa0a3b36e65 \ No newline at end of file +e05f8a2998f4f4cbdb65702baa65893c538b3d38 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index f0d495f491..12e420fb5d 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -462,6 +462,16 @@ static int multiplexOpen( memcpy(pGroup->zName, zName, nName+1); pGroup->nName = nName; } + if( pGroup->bEnabled ){ + /* Make sure that the chunksize is not such that the pending byte + ** falls at the end of a chunk. A region of up to 64K following + ** the pending byte is never written, so if the pending byte occurs + ** near the end of a chunk, that chunk will be too small. */ + extern int sqlite3PendingByte; + while( (sqlite3PendingByte % pGroup->szChunk)>=(pGroup->szChunk-65536) ){ + pGroup->szChunk += 65536; + } + } pGroup->flags = flags; rc = multiplexSubFilename(pGroup, 1); if( rc==SQLITE_OK ){ From e712b5823e8c984491a8ac34e43fb5e50a995058 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 15 Dec 2011 17:00:10 +0000 Subject: [PATCH 103/161] When deleting a file with the multiplexor VFS, also delete any overflow files that exist. FossilOrigin-Name: 3af1feaa35d3fb2e7be550cd32a727001b874938 --- manifest | 14 ++--- manifest.uuid | 2 +- src/test_multiplex.c | 132 +++++++++++++++++++++++++++++++------------ 3 files changed, 105 insertions(+), 43 deletions(-) diff --git a/manifest b/manifest index 21cbee27f3..aec2b27521 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\schunksize\sin\stest_multiplex\sdoes\snot\scause\sthe\spending\sbyte\nto\sfall\snear\sthe\send\sof\sa\schunk.\s\sAdjust\sthe\schunksize\supward\sas\snecessary\nto\sprevent\sthis. -D 2011-12-15T13:29:12.575 +C When\sdeleting\sa\sfile\swith\sthe\smultiplexor\sVFS,\salso\sdelete\sany\soverflow\sfiles\sthat\sexist. +D 2011-12-15T17:00:10.854 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c 7b65eea8b390dd223bd6e0ba9d7879389bd075c0 +F src/test_multiplex.c c87d27283e2f578c17a8db7a8cac095f576f4323 F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 2d50f78188e3297e8cefdf73cff51fa0a3b36e65 -R db6d46332c6333123f8fa60ccb204a1d -U drh -Z f65d5d73aa828ce8ac2cca0eb8289aa5 +P e05f8a2998f4f4cbdb65702baa65893c538b3d38 +R 45b2cf463e6285a0d96697332c4d9aa9 +U dan +Z 16b7798bc9bd7dfe8e0e630d52e6558b diff --git a/manifest.uuid b/manifest.uuid index ce1d054b8f..e4ed76872d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e05f8a2998f4f4cbdb65702baa65893c538b3d38 \ No newline at end of file +3af1feaa35d3fb2e7be550cd32a727001b874938 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 12e420fb5d..d844604ab5 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -216,6 +216,39 @@ static int multiplexStrlen30(const char *z){ return 0x3fffffff & (int)(z2 - z); } +/* +** Generate the file-name for chunk iChunk of the group with base name +** zBase. The file-name is written to buffer zOut before returning. Buffer +** zOut must be allocated by the caller so that it is at least (nBase+4) +** bytes in size, where nBase is the length of zBase, not including the +** nul-terminator. +*/ +static void multiplexFilename( + const char *zBase, /* Filename for chunk 0 */ + int nBase, /* Size of zBase in bytes (without \0) */ + int flags, /* Flags used to open file */ + int iChunk, /* Chunk to generate filename for */ + char *zOut /* Buffer to write generated name to */ +){ + memcpy(zOut, zBase, nBase+1); + if( iChunk!=0 && iChunk!=SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET ){ + int n = nBase; +#ifdef SQLITE_ENABLE_8_3_NAMES + int i; + for(i=n-1; i>0 && i>=n-4 && zOut[i]!='.'; i--){} + if( i>=n-4 ) n = i+1; + if( flags & SQLITE_OPEN_MAIN_JOURNAL ){ + /* The extensions on overflow files for main databases are 001, 002, + ** 003 and so forth. To avoid name collisions, add 400 to the + ** extensions of journal files so that they are 401, 402, 403, .... + */ + iChunk += SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET; + } +#endif + sqlite3_snprintf(4,&zOut[n],"%03d",iChunk); + } +} + /* Compute the filename for the iChunk-th chunk */ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){ @@ -236,22 +269,7 @@ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){ if( z==0 ){ return SQLITE_NOMEM; } - memcpy(z, pGroup->zName, n+1); - if( iChunk>0 ){ -#ifdef SQLITE_ENABLE_8_3_NAMES - int i; - for(i=n-1; i>0 && i>=n-4 && z[i]!='.'; i--){} - if( i>=n-4 ) n = i+1; - if( pGroup->flags & (SQLITE_OPEN_MAIN_JOURNAL|SQLITE_OPEN_TEMP_JOURNAL) ){ - /* The extensions on overflow files for main databases are 001, 002, - ** 003 and so forth. To avoid name collisions, add 400 to the - ** extensions of journal files so that they are 401, 402, 403, .... - */ - iChunk += SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET; - } -#endif - sqlite3_snprintf(4,&z[n],"%03d",iChunk); - } + multiplexFilename(pGroup->zName, pGroup->nName, pGroup->flags, iChunk, z); } return SQLITE_OK; } @@ -483,24 +501,43 @@ static int multiplexOpen( rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz); if( rc==SQLITE_OK && zName ){ - int exists; - - /* If the first overflow file exists and if the size of the main file - ** is different from the chunk size, that means the chunk size is set - ** set incorrectly. So fix it. - ** - ** Or, if the first overflow file does not exist and the main file is - ** larger than the chunk size, that means the chunk size is too small. - ** But we have no way of determining the intended chunk size, so - ** just disable the multiplexor all togethre. - */ - rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z, - SQLITE_ACCESS_EXISTS, &exists); - if( rc==SQLITE_OK && exists && sz==(sz&0xffff0000) && sz>0 - && sz!=pGroup->szChunk ){ - pGroup->szChunk = sz; - }else if( rc==SQLITE_OK && !exists && sz>pGroup->szChunk ){ - pGroup->bEnabled = 0; + int bExists; + if( sz==0 ){ + if( flags & SQLITE_OPEN_MAIN_JOURNAL ){ + /* If opening a main journal file and the first chunk is zero + ** bytes in size, delete any subsequent chunks from the + ** file-system. */ + int iChunk = 1; + do { + rc = pOrigVfs->xAccess(pOrigVfs, + pGroup->aReal[iChunk].z, SQLITE_ACCESS_EXISTS, &bExists + ); + if( rc==SQLITE_OK && bExists ){ + rc = pOrigVfs->xDelete(pOrigVfs, pGroup->aReal[iChunk].z, 0); + if( rc==SQLITE_OK ){ + rc = multiplexSubFilename(pGroup, ++iChunk); + } + } + }while( rc==SQLITE_OK && bExists ); + } + }else{ + /* If the first overflow file exists and if the size of the main file + ** is different from the chunk size, that means the chunk size is set + ** set incorrectly. So fix it. + ** + ** Or, if the first overflow file does not exist and the main file is + ** larger than the chunk size, that means the chunk size is too small. + ** But we have no way of determining the intended chunk size, so + ** just disable the multiplexor all togethre. + */ + rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z, + SQLITE_ACCESS_EXISTS, &bExists); + if( rc==SQLITE_OK && bExists && sz==(sz&0xffff0000) && sz>0 + && sz!=pGroup->szChunk ){ + pGroup->szChunk = sz; + }else if( rc==SQLITE_OK && !bExists && sz>pGroup->szChunk ){ + pGroup->bEnabled = 0; + } } } } @@ -534,8 +571,33 @@ static int multiplexDelete( const char *zName, /* Name of file to delete */ int syncDir ){ + int rc; sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ - return pOrigVfs->xDelete(pOrigVfs, zName, syncDir); + rc = pOrigVfs->xDelete(pOrigVfs, zName, syncDir); + if( rc==SQLITE_OK ){ + /* If the main chunk was deleted successfully, also delete any subsequent + ** chunks - starting with the last (highest numbered). + */ + int nName = strlen(zName); + char *z; + z = sqlite3_malloc(nName + 4); + if( z==0 ){ + rc = SQLITE_IOERR_NOMEM; + }else{ + int iChunk = 0; + int bExists; + do{ + multiplexFilename(zName, nName, SQLITE_OPEN_MAIN_JOURNAL, ++iChunk, z); + rc = pOrigVfs->xAccess(pOrigVfs, z, SQLITE_ACCESS_EXISTS, &bExists); + }while( rc==SQLITE_OK && bExists ); + while( rc==SQLITE_OK && iChunk>1 ){ + multiplexFilename(zName, nName, SQLITE_OPEN_MAIN_JOURNAL, --iChunk, z); + rc = pOrigVfs->xDelete(pOrigVfs, z, syncDir); + } + } + sqlite3_free(z); + } + return rc; } static int multiplexAccess(sqlite3_vfs *a, const char *b, int c, int *d){ From c39f3e0085710806a3a19ac2eff8d5f099245893 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Dec 2011 17:42:35 +0000 Subject: [PATCH 104/161] Use _commit() rather than FlushFileBuffers() as a substitute for fsync() on windows. Also cast for C++ and add support for SQLITE_FCNTL_VFSNAME. FossilOrigin-Name: e85cfe9a17a2943ee0cf7915451ff6cc05908030 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test_quota.c | 17 ++++++++++++----- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index eb499cd1b5..90096462db 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Harden\sthe\sutf8-to-mbcs\sconverter\sin\sthe\squota\smodule\sagainst\sfailures. -D 2011-12-14T00:04:52.373 +C Use\s_commit()\srather\sthan\sFlushFileBuffers()\sas\sa\ssubstitute\sfor\sfsync()\non\swindows.\s\sAlso\scast\sfor\sC++\sand\sadd\ssupport\sfor\sSQLITE_FCNTL_VFSNAME. +D 2011-12-15T17:42:35.299 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_osinst.c 62b0b8ef21ce754cc94e17bb42377ed8795dba32 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 -F src/test_quota.c 2552dfd897d2d74ecc368487fa5859e9a2b254ab +F src/test_quota.c 1a5874e3ee9074426f43b37e8d7404948065b585 F src/test_quota.h 9ffa1d3ad6d0a6a24e8670ea64b909c717ec3358 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 @@ -979,7 +979,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 92f4188f90e3cdd71f1457a6e0eb22615e4a54f4 -R 628f1bcc3bb63f06518edb62745f94e5 +P 1cda511deb625868395a23c95346e14d0c300670 +R b97a14183d24f2ef8a473c4b8d89de75 U drh -Z 2cf614ef38a2cb741ec717409dbd005d +Z 78d66bb3da81c929977c8b164844aeef diff --git a/manifest.uuid b/manifest.uuid index 1cd189003e..39ac2ffec5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1cda511deb625868395a23c95346e14d0c300670 \ No newline at end of file +e85cfe9a17a2943ee0cf7915451ff6cc05908030 \ No newline at end of file diff --git a/src/test_quota.c b/src/test_quota.c index e2c0808969..4529bd3028 100644 --- a/src/test_quota.c +++ b/src/test_quota.c @@ -409,6 +409,7 @@ static quotaFile *quotaFindFile( #endif #if SQLITE_OS_WIN # include +# include #endif /* @@ -428,12 +429,12 @@ static char *quota_utf8_to_mbcs(const char *zUtf8){ n = strlen(zUtf8); nWide = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, NULL, 0); if( nWide==0 ) return 0; - zTmpWide = sqlite3_malloc( (nWide+1)*sizeof(zTmpWide[0]) ); + zTmpWide = (LPWSTR)sqlite3_malloc( (nWide+1)*sizeof(zTmpWide[0]) ); if( zTmpWide==0 ) return 0; MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zTmpWide, nWide); codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; nMbcs = WideCharToMultiByte(codepage, 0, zTmpWide, nWide, 0, 0, 0, 0); - zMbcs = nMbcs ? sqlite3_malloc( nMbcs+1 ) : 0; + zMbcs = nMbcs ? (char*)sqlite3_malloc( nMbcs+1 ) : 0; if( zMbcs ){ WideCharToMultiByte(codepage, 0, zTmpWide, nWide, zMbcs, nMbcs, 0, 0); } @@ -714,7 +715,13 @@ static int quotaCheckReservedLock(sqlite3_file *pConn, int *pResOut){ */ static int quotaFileControl(sqlite3_file *pConn, int op, void *pArg){ sqlite3_file *pSubOpen = quotaSubOpen(pConn); - return pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg); + int rc = pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg); +#if defined(SQLITE_FCNTL_VFSNAME) + if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){ + *(char**)pArg = sqlite3_mprintf("quota/%z", *(char**)pArg); + } +#endif + return rc; } /* Pass xSectorSize requests through to the original VFS unchanged. @@ -1093,10 +1100,10 @@ int sqlite3_quota_fflush(quota_FILE *p, int doFsync){ rc = fsync(fileno(p->f)); #endif #if SQLITE_OS_WIN - rc = 0==FlushFileBuffers((HANDLE)_fileno(p->f)); + rc = _commit(_fileno(p->f)); #endif } - return rc; + return rc!=0; } /* From f580860f5196fc51fd5d9b6f42fe89e5b0573adc Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Dec 2011 00:33:04 +0000 Subject: [PATCH 105/161] Make sure the antipenultimate character of master-journal filenames is a "9" in order to avoid collisions with other files in 8+3 filename mode. Also, limit the number of attempts at finding a unique master-journal filename. FossilOrigin-Name: 34a0483605d36e6cf03065ed0df33fb1f7c8a272 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/util.c | 1 + src/vdbeaux.c | 12 +++++++++++- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index aec2b27521..c6cfc989a6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sdeleting\sa\sfile\swith\sthe\smultiplexor\sVFS,\salso\sdelete\sany\soverflow\sfiles\sthat\sexist. -D 2011-12-15T17:00:10.854 +C Make\ssure\sthe\santipenultimate\scharacter\sof\smaster-journal\sfilenames\sis\sa\s"9"\nin\sorder\sto\savoid\scollisions\swith\sother\sfiles\sin\s8+3\sfilename\smode.\s\sAlso,\nlimit\sthe\snumber\sof\sattempts\sat\sfinding\sa\sunique\smaster-journal\sfilename. +D 2011-12-16T00:33:04.352 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -237,13 +237,13 @@ F src/tokenize.c c819d9f72168a035d545a5bdafe9b085b20df705 F src/trigger.c 1cfb80e2290ef66ea89cb4e821caae65a02c0d56 F src/update.c 25e046a8f69d5e557aabde2000487b8545509d8d F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 -F src/util.c 01238e2b0f24a14779181dbf991fe02620a80e31 +F src/util.c 343508d359df65685b62e63964a40e7af4cfbe05 F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa F src/vdbe.c a7ab9993ec5a4d9479dc99671faec061fbf9b889 F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755 F src/vdbeInt.h 9498fc98a2c9e349a4ef13455ff5a3e898f40176 F src/vdbeapi.c 4dbba7f94f127f6ea8d2d0505ee1f98e5ffbf546 -F src/vdbeaux.c 45713a5f8f4f36195f503b30153ddef292323f88 +F src/vdbeaux.c 896ce3c48bf1bf27a1330589a20daa2db0222381 F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P e05f8a2998f4f4cbdb65702baa65893c538b3d38 -R 45b2cf463e6285a0d96697332c4d9aa9 -U dan -Z 16b7798bc9bd7dfe8e0e630d52e6558b +P 3af1feaa35d3fb2e7be550cd32a727001b874938 +R 398b3e3805c532cf24ac8d99750e0da2 +U drh +Z ebbc2fb95389a75c4e570b61ca8c6d99 diff --git a/manifest.uuid b/manifest.uuid index e4ed76872d..b3c3bab442 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3af1feaa35d3fb2e7be550cd32a727001b874938 \ No newline at end of file +34a0483605d36e6cf03065ed0df33fb1f7c8a272 \ No newline at end of file diff --git a/src/util.c b/src/util.c index ffbf7daadf..d27f6fdf26 100644 --- a/src/util.c +++ b/src/util.c @@ -1169,6 +1169,7 @@ int sqlite3AbsInt32(int x){ ** test.db-journal => test.nal ** test.db-wal => test.wal ** test.db-shm => test.shm +** test.db-mj7f3319fa => test.9fa */ void sqlite3FileSuffix3(const char *zBaseFilename, char *z){ #if SQLITE_ENABLE_8_3_NAMES<2 diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7c69d28cf6..2e01c982e5 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1824,16 +1824,26 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ sqlite3_file *pMaster = 0; i64 offset = 0; int res; + int retryCount = 0; /* Select a master journal file name */ do { u32 iRandom; + if( retryCount++>100 ){ + sqlite3_log(SQLITE_FULL, "cannot create a master journal filename"); + rc = SQLITE_FULL; + break; + } sqlite3DbFree(db, zMaster); sqlite3_randomness(sizeof(iRandom), &iRandom); - zMaster = sqlite3MPrintf(db, "%s-mj%08X", zMainFile, iRandom&0x7fffffff); + zMaster = sqlite3MPrintf(db, "%s-mj%06X9%02X", zMainFile, + (iRandom>>8)&0xffffff, iRandom&0xff); if( !zMaster ){ return SQLITE_NOMEM; } + /* The antipenultimate character of the master journal name must + ** be "9" to avoid name collisions when using 8+3 filenames. */ + assert( zMaster[strlen(zMaster)-3]=='9' ); sqlite3FileSuffix3(zMainFile, zMaster); rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res); }while( rc==SQLITE_OK && res ); From 5c531a4aabce7f5a1f60ec87576f24092259a848 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Dec 2011 01:21:31 +0000 Subject: [PATCH 106/161] A better solution to being unable to find a unique master-journal filename: just delete an existing master-journal and reuse it. FossilOrigin-Name: 2685c2b949061f18bf6a4940eac8c8148873abb6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 15 +++++++-------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index c6cfc989a6..322d293528 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\santipenultimate\scharacter\sof\smaster-journal\sfilenames\sis\sa\s"9"\nin\sorder\sto\savoid\scollisions\swith\sother\sfiles\sin\s8+3\sfilename\smode.\s\sAlso,\nlimit\sthe\snumber\sof\sattempts\sat\sfinding\sa\sunique\smaster-journal\sfilename. -D 2011-12-16T00:33:04.352 +C A\sbetter\ssolution\sto\sbeing\sunable\sto\sfind\sa\sunique\smaster-journal\sfilename:\njust\sdelete\san\sexisting\smaster-journal\sand\sreuse\sit. +D 2011-12-16T01:21:31.882 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -243,7 +243,7 @@ F src/vdbe.c a7ab9993ec5a4d9479dc99671faec061fbf9b889 F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755 F src/vdbeInt.h 9498fc98a2c9e349a4ef13455ff5a3e898f40176 F src/vdbeapi.c 4dbba7f94f127f6ea8d2d0505ee1f98e5ffbf546 -F src/vdbeaux.c 896ce3c48bf1bf27a1330589a20daa2db0222381 +F src/vdbeaux.c 7bae4d94d7e41e8005824a6d1da54b73d47f52b1 F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 3af1feaa35d3fb2e7be550cd32a727001b874938 -R 398b3e3805c532cf24ac8d99750e0da2 +P 34a0483605d36e6cf03065ed0df33fb1f7c8a272 +R dac1ae186d64bf5089bb1df4a91a9793 U drh -Z ebbc2fb95389a75c4e570b61ca8c6d99 +Z cdecba57f424e5a33e7e2e3955b5bd95 diff --git a/manifest.uuid b/manifest.uuid index b3c3bab442..6fdf08c334 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -34a0483605d36e6cf03065ed0df33fb1f7c8a272 \ No newline at end of file +2685c2b949061f18bf6a4940eac8c8148873abb6 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 2e01c982e5..6e183d0b8c 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1825,25 +1825,24 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ i64 offset = 0; int res; int retryCount = 0; + int nMainFile; /* Select a master journal file name */ + nMainFile = sqlite3Strlen30(zMainFile); + zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XX", zMainFile); + if( zMaster==0 ) return SQLITE_NOMEM; do { u32 iRandom; if( retryCount++>100 ){ - sqlite3_log(SQLITE_FULL, "cannot create a master journal filename"); - rc = SQLITE_FULL; + sqlite3OsDelete(pVfs, zMaster, 0); break; } - sqlite3DbFree(db, zMaster); sqlite3_randomness(sizeof(iRandom), &iRandom); - zMaster = sqlite3MPrintf(db, "%s-mj%06X9%02X", zMainFile, + sqlite3_snprintf(13, &zMaster[nMainFile], "-mj%06X9%02X", (iRandom>>8)&0xffffff, iRandom&0xff); - if( !zMaster ){ - return SQLITE_NOMEM; - } /* The antipenultimate character of the master journal name must ** be "9" to avoid name collisions when using 8+3 filenames. */ - assert( zMaster[strlen(zMaster)-3]=='9' ); + assert( zMaster[sqlite3Strlen30(zMaster)-3]=='9' ); sqlite3FileSuffix3(zMainFile, zMaster); rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res); }while( rc==SQLITE_OK && res ); From 38deeb9763133eea8ffbf1d7c1d3843bb8f2fc9e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Dec 2011 01:30:15 +0000 Subject: [PATCH 107/161] Call sqlite3_log() with an appropriate message if unable to find a unique master-journal filename. FossilOrigin-Name: e9177f7d4ec19f0841d0613990d2fb5725700ba1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 322d293528..0d3df0583b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C A\sbetter\ssolution\sto\sbeing\sunable\sto\sfind\sa\sunique\smaster-journal\sfilename:\njust\sdelete\san\sexisting\smaster-journal\sand\sreuse\sit. -D 2011-12-16T01:21:31.882 +C Call\ssqlite3_log()\swith\san\sappropriate\smessage\sif\sunable\sto\sfind\sa\sunique\nmaster-journal\sfilename. +D 2011-12-16T01:30:15.388 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -243,7 +243,7 @@ F src/vdbe.c a7ab9993ec5a4d9479dc99671faec061fbf9b889 F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755 F src/vdbeInt.h 9498fc98a2c9e349a4ef13455ff5a3e898f40176 F src/vdbeapi.c 4dbba7f94f127f6ea8d2d0505ee1f98e5ffbf546 -F src/vdbeaux.c 7bae4d94d7e41e8005824a6d1da54b73d47f52b1 +F src/vdbeaux.c 52ebf2a62d6b66ded536d0a2745f2236771097c7 F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 34a0483605d36e6cf03065ed0df33fb1f7c8a272 -R dac1ae186d64bf5089bb1df4a91a9793 +P 2685c2b949061f18bf6a4940eac8c8148873abb6 +R 45a748a7c5e87682cd34056f04633da7 U drh -Z cdecba57f424e5a33e7e2e3955b5bd95 +Z 8c7f37ab067ed94fde60690f325712e2 diff --git a/manifest.uuid b/manifest.uuid index 6fdf08c334..57de583d49 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2685c2b949061f18bf6a4940eac8c8148873abb6 \ No newline at end of file +e9177f7d4ec19f0841d0613990d2fb5725700ba1 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 6e183d0b8c..bb1844dfb4 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1834,6 +1834,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ do { u32 iRandom; if( retryCount++>100 ){ + sqlite3_log(SQLITE_FULL, "cannot find unique master-journal"); sqlite3OsDelete(pVfs, zMaster, 0); break; } From e7d9f13d99667f89606a617eb9ffc01eb0fc8649 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Dec 2011 04:57:32 +0000 Subject: [PATCH 108/161] The xTruncate method for the multiplexor now changes surplus overflow files to zero-length by default. Or if the "truncate" query parameter is used, it actually deletes the surplus overflow files. This allows VACUUM to shrink the database again. FossilOrigin-Name: 5aefef04d6cc3b734c3f05e036b3869a52248f4d --- manifest | 12 ++-- manifest.uuid | 2 +- src/test_multiplex.c | 168 ++++++++++++++++++++++++------------------- 3 files changed, 103 insertions(+), 79 deletions(-) diff --git a/manifest b/manifest index 0d3df0583b..a12b10d33a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Call\ssqlite3_log()\swith\san\sappropriate\smessage\sif\sunable\sto\sfind\sa\sunique\nmaster-journal\sfilename. -D 2011-12-16T01:30:15.388 +C The\sxTruncate\smethod\sfor\sthe\smultiplexor\snow\schanges\ssurplus\soverflow\nfiles\sto\szero-length\sby\sdefault.\s\sOr\sif\sthe\s"truncate"\squery\sparameter\s\nis\sused,\sit\sactually\sdeletes\sthe\ssurplus\soverflow\sfiles.\s\sThis\sallows\nVACUUM\sto\sshrink\sthe\sdatabase\sagain. +D 2011-12-16T04:57:32.390 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c c87d27283e2f578c17a8db7a8cac095f576f4323 +F src/test_multiplex.c 993f930c9c8e1aa0f4fe7b5a74c9a60fbf3447e4 F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 2685c2b949061f18bf6a4940eac8c8148873abb6 -R 45a748a7c5e87682cd34056f04633da7 +P e9177f7d4ec19f0841d0613990d2fb5725700ba1 +R c09d355f93cdab856d4274295151320d U drh -Z 8c7f37ab067ed94fde60690f325712e2 +Z 4efbc5088c9568c2b7090122e09b39c8 diff --git a/manifest.uuid b/manifest.uuid index 57de583d49..4852f04967 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e9177f7d4ec19f0841d0613990d2fb5725700ba1 \ No newline at end of file +5aefef04d6cc3b734c3f05e036b3869a52248f4d \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index d844604ab5..f01a7f585b 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -133,7 +133,8 @@ struct multiplexGroup { int nName; /* Length of base filename */ int flags; /* Flags used for original opening */ unsigned int szChunk; /* Chunk size used for this group */ - int bEnabled; /* TRUE to use Multiplex VFS for this file */ + unsigned char bEnabled; /* TRUE to use Multiplex VFS for this file */ + unsigned char bTruncate; /* TRUE to enable truncation of databases */ multiplexGroup *pNext, *pPrev; /* Doubly linked list of all group objects */ }; @@ -276,12 +277,17 @@ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){ /* Translate an sqlite3_file* that is really a multiplexGroup* into ** the sqlite3_file* for the underlying original VFS. +** +** For chunk 0, the pGroup->flags determines whether or not a new file +** is created if it does not already exist. For chunks 1 and higher, the +** file is created only if createFlag is 1. */ static sqlite3_file *multiplexSubOpen( - multiplexGroup *pGroup, - int iChunk, - int *rc, - int *pOutFlags + multiplexGroup *pGroup, /* The multiplexor group */ + int iChunk, /* Which chunk to open. 0==original file */ + int *rc, /* Result code in and out */ + int *pOutFlags, /* Output flags */ + int createFlag /* True to create if iChunk>0 */ ){ sqlite3_file *pSubOpen = 0; sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ @@ -299,15 +305,28 @@ static sqlite3_file *multiplexSubOpen( *rc = multiplexSubFilename(pGroup, iChunk); if( (*rc)==SQLITE_OK && (pSubOpen = pGroup->aReal[iChunk].p)==0 ){ + int flags, rc2, bExists; + if( iChunk==0 ) createFlag = (pGroup->flags & SQLITE_OPEN_CREATE)!=0; + flags = pGroup->flags; + if( createFlag ){ + flags |= SQLITE_OPEN_CREATE; + }else if( pGroup->aReal[iChunk].z==0 ){ + return 0; + }else{ + *rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[iChunk].z, + SQLITE_ACCESS_EXISTS, &bExists); + if( *rc || !bExists ) return 0; + flags &= ~SQLITE_OPEN_CREATE; + } pSubOpen = sqlite3_malloc( pOrigVfs->szOsFile ); if( pSubOpen==0 ){ *rc = SQLITE_NOMEM; return 0; } pGroup->aReal[iChunk].p = pSubOpen; - *rc = pOrigVfs->xOpen(pOrigVfs, pGroup->aReal[iChunk].z, pSubOpen, - pGroup->flags, pOutFlags); - if( *rc!=SQLITE_OK ){ + rc2 = pOrigVfs->xOpen(pOrigVfs, pGroup->aReal[iChunk].z, pSubOpen, + flags, pOutFlags); + if( rc2!=SQLITE_OK ){ sqlite3_free(pSubOpen); pGroup->aReal[iChunk].p = 0; return 0; @@ -316,6 +335,25 @@ static sqlite3_file *multiplexSubOpen( return pSubOpen; } +/* +** Return the size, in bytes, of chunk number iChunk. If that chunk +** does not exist, then return 0. This function does not distingish between +** non-existant files and zero-length files. +*/ +static sqlite3_int64 multiplexSubSize( + multiplexGroup *pGroup, /* The multiplexor group */ + int iChunk, /* Which chunk to open. 0==original file */ + int *rc /* Result code in and out */ +){ + sqlite3_file *pSub; + sqlite3_int64 sz = 0; + + pSub = multiplexSubOpen(pGroup, iChunk, rc, NULL, 0); + if( pSub==0 ) return 0; + *rc = pSub->pMethods->xFileSize(pSub, &sz); + return sz; +} + /* ** This is the implementation of the multiplex_control() SQL function. */ @@ -455,6 +493,7 @@ static int multiplexOpen( memset(pGroup, 0, sz); pMultiplexOpen->pGroup = pGroup; pGroup->bEnabled = -1; + pGroup->bTruncate = (flags & SQLITE_OPEN_MAIN_DB)==0; pGroup->szChunk = SQLITE_MULTIPLEX_CHUNK_SIZE; if( zName ){ @@ -475,6 +514,7 @@ static int multiplexOpen( pGroup->bEnabled = 0; } } + if( sqlite3_uri_parameter(zName, "truncate") ) pGroup->bTruncate = 1; } pGroup->zName = p; memcpy(pGroup->zName, zName, nName+1); @@ -493,8 +533,8 @@ static int multiplexOpen( pGroup->flags = flags; rc = multiplexSubFilename(pGroup, 1); if( rc==SQLITE_OK ){ - pSubOpen = multiplexSubOpen(pGroup, 0, &rc, pOutFlags); - assert( pSubOpen || rc!=SQLITE_OK ); + pSubOpen = multiplexSubOpen(pGroup, 0, &rc, pOutFlags, 0); + if( pSubOpen==0 && rc==SQLITE_OK ) rc = SQLITE_CANTOPEN; } if( rc==SQLITE_OK ){ sqlite3_int64 sz; @@ -522,17 +562,18 @@ static int multiplexOpen( } }else{ /* If the first overflow file exists and if the size of the main file - ** is different from the chunk size, that means the chunk size is set - ** set incorrectly. So fix it. - ** - ** Or, if the first overflow file does not exist and the main file is - ** larger than the chunk size, that means the chunk size is too small. - ** But we have no way of determining the intended chunk size, so - ** just disable the multiplexor all togethre. - */ + ** is different from the chunk size, that means the chunk size is set + ** set incorrectly. So fix it. + ** + ** Or, if the first overflow file does not exist and the main file is + ** larger than the chunk size, that means the chunk size is too small. + ** But we have no way of determining the intended chunk size, so + ** just disable the multiplexor all togethre. + */ rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z, SQLITE_ACCESS_EXISTS, &bExists); - if( rc==SQLITE_OK && bExists && sz==(sz&0xffff0000) && sz>0 + bExists = multiplexSubSize(pGroup, 1, &rc)>0; + if( rc==SQLITE_OK && bExists && sz==(sz&0xffff0000) && sz>0 && sz!=pGroup->szChunk ){ pGroup->szChunk = sz; }else if( rc==SQLITE_OK && !bExists && sz>pGroup->szChunk ){ @@ -674,7 +715,7 @@ static int multiplexRead( int rc = SQLITE_OK; multiplexEnter(); if( !pGroup->bEnabled ){ - sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0); if( pSubOpen==0 ){ rc = SQLITE_IOERR_READ; }else{ @@ -683,7 +724,7 @@ static int multiplexRead( }else{ while( iAmt > 0 ){ int i = (int)(iOfst / pGroup->szChunk); - sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL, 1); if( pSubOpen ){ int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) - pGroup->szChunk; if( extra<0 ) extra = 0; @@ -719,7 +760,7 @@ static int multiplexWrite( int rc = SQLITE_OK; multiplexEnter(); if( !pGroup->bEnabled ){ - sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0); if( pSubOpen==0 ){ rc = SQLITE_IOERR_WRITE; }else{ @@ -728,7 +769,7 @@ static int multiplexWrite( }else{ while( rc==SQLITE_OK && iAmt>0 ){ int i = (int)(iOfst / pGroup->szChunk); - sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL, 1); if( pSubOpen ){ int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) - pGroup->szChunk; @@ -756,28 +797,35 @@ static int multiplexTruncate(sqlite3_file *pConn, sqlite3_int64 size){ int rc = SQLITE_OK; multiplexEnter(); if( !pGroup->bEnabled ){ - sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0); if( pSubOpen==0 ){ rc = SQLITE_IOERR_TRUNCATE; }else{ rc = pSubOpen->pMethods->xTruncate(pSubOpen, size); } - }else if( (pGroup->flags & SQLITE_OPEN_MAIN_DB)==0 ){ - int rc2; + }else{ int i; + int iBaseGroup = (int)(size / pGroup->szChunk); sqlite3_file *pSubOpen; sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ /* delete the chunks above the truncate limit */ - for(i=(int)(size / pGroup->szChunk)+1; inReal; i++){ - multiplexSubClose(pGroup, i, pOrigVfs); + for(i = pGroup->nReal-1; i>iBaseGroup && rc==SQLITE_OK; i--){ + if( pGroup->bTruncate ){ + multiplexSubClose(pGroup, i, pOrigVfs); + }else{ + pSubOpen = multiplexSubOpen(pGroup, i, &rc, 0, 0); + if( pSubOpen ){ + rc = pSubOpen->pMethods->xTruncate(pSubOpen, 0); + } + } } - pSubOpen = multiplexSubOpen(pGroup, (int)(size/pGroup->szChunk), &rc2,0); - if( pSubOpen ){ - rc2 = pSubOpen->pMethods->xTruncate(pSubOpen, size % pGroup->szChunk); - if( rc2!=SQLITE_OK ) rc = rc2; - }else{ - rc = SQLITE_IOERR_TRUNCATE; + if( rc==SQLITE_OK ){ + pSubOpen = multiplexSubOpen(pGroup, iBaseGroup, &rc, 0, 0); + if( pSubOpen ){ + rc = pSubOpen->pMethods->xTruncate(pSubOpen, size % pGroup->szChunk); + } } + if( rc ) rc = SQLITE_IOERR_TRUNCATE; } multiplexLeave(); return rc; @@ -812,42 +860,18 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ int i; multiplexEnter(); if( !pGroup->bEnabled ){ - sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0); if( pSubOpen==0 ){ rc = SQLITE_IOERR_FSTAT; }else{ rc = pSubOpen->pMethods->xFileSize(pSubOpen, pSize); } }else{ - sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; *pSize = 0; for(i=0; rc==SQLITE_OK; i++){ - sqlite3_file *pSubOpen = 0; - int exists = 0; - rc = multiplexSubFilename(pGroup, i); - if( rc!=SQLITE_OK ) break; - if( pGroup->nReal>i && pGroup->aReal[i].p!=0 ){ - exists = 1; - }else if( (pGroup->flags & SQLITE_OPEN_DELETEONCLOSE)==0 ){ - const char *zReal = pGroup->aReal[i].z; - rc = pOrigVfs->xAccess(pOrigVfs, zReal, SQLITE_ACCESS_EXISTS, &exists); - } - if( exists==0 ){ - /* stop at first "gap" or IO error. */ - break; - } - if( rc==SQLITE_OK ){ - pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL); - } - assert( pSubOpen || rc!=SQLITE_OK ); - if( rc==SQLITE_OK ){ - sqlite3_int64 sz = 0; - rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz); - if( rc==SQLITE_OK && sz>pGroup->szChunk ){ - rc = SQLITE_IOERR_FSTAT; - } - *pSize = i*(sqlite3_int64)pGroup->szChunk + sz; - } + sqlite3_int64 sz = multiplexSubSize(pGroup, i, &rc); + if( sz==0 ) break; + *pSize = i*(sqlite3_int64)pGroup->szChunk + sz; } } multiplexLeave(); @@ -859,7 +883,7 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ static int multiplexLock(sqlite3_file *pConn, int lock){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ return pSubOpen->pMethods->xLock(pSubOpen, lock); } @@ -871,7 +895,7 @@ static int multiplexLock(sqlite3_file *pConn, int lock){ static int multiplexUnlock(sqlite3_file *pConn, int lock){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ return pSubOpen->pMethods->xUnlock(pSubOpen, lock); } @@ -883,7 +907,7 @@ static int multiplexUnlock(sqlite3_file *pConn, int lock){ static int multiplexCheckReservedLock(sqlite3_file *pConn, int *pResOut){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ return pSubOpen->pMethods->xCheckReservedLock(pSubOpen, pResOut); } @@ -931,7 +955,7 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){ rc = SQLITE_OK; break; default: - pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL); + pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ rc = pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg); if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){ @@ -948,7 +972,7 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){ static int multiplexSectorSize(sqlite3_file *pConn){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); if( pSubOpen && pSubOpen->pMethods->xSectorSize ){ return pSubOpen->pMethods->xSectorSize(pSubOpen); } @@ -960,7 +984,7 @@ static int multiplexSectorSize(sqlite3_file *pConn){ static int multiplexDeviceCharacteristics(sqlite3_file *pConn){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ return pSubOpen->pMethods->xDeviceCharacteristics(pSubOpen); } @@ -978,7 +1002,7 @@ static int multiplexShmMap( ){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ return pSubOpen->pMethods->xShmMap(pSubOpen, iRegion, szRegion, bExtend,pp); } @@ -995,7 +1019,7 @@ static int multiplexShmLock( ){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ return pSubOpen->pMethods->xShmLock(pSubOpen, ofst, n, flags); } @@ -1007,7 +1031,7 @@ static int multiplexShmLock( static void multiplexShmBarrier(sqlite3_file *pConn){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ pSubOpen->pMethods->xShmBarrier(pSubOpen); } @@ -1018,7 +1042,7 @@ static void multiplexShmBarrier(sqlite3_file *pConn){ static int multiplexShmUnmap(sqlite3_file *pConn, int deleteFlag){ multiplexConn *p = (multiplexConn*)pConn; int rc; - sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL); + sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); if( pSubOpen ){ return pSubOpen->pMethods->xShmUnmap(pSubOpen, deleteFlag); } From 06999667980faaf686d7232e7d97bf1cf4907849 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Dec 2011 05:09:46 +0000 Subject: [PATCH 109/161] Fix a potential infinite loop (inserted by the previous check-in) on the multiplexWrite() method of the multiplexor. FossilOrigin-Name: 022bf427c2edfe494ec7c222f436953ff56574a6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test_multiplex.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index a12b10d33a..88df5c4fc4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sxTruncate\smethod\sfor\sthe\smultiplexor\snow\schanges\ssurplus\soverflow\nfiles\sto\szero-length\sby\sdefault.\s\sOr\sif\sthe\s"truncate"\squery\sparameter\s\nis\sused,\sit\sactually\sdeletes\sthe\ssurplus\soverflow\sfiles.\s\sThis\sallows\nVACUUM\sto\sshrink\sthe\sdatabase\sagain. -D 2011-12-16T04:57:32.390 +C Fix\sa\spotential\sinfinite\sloop\s(inserted\sby\sthe\sprevious\scheck-in)\non\sthe\smultiplexWrite()\smethod\sof\sthe\smultiplexor. +D 2011-12-16T05:09:46.415 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c 993f930c9c8e1aa0f4fe7b5a74c9a60fbf3447e4 +F src/test_multiplex.c ccc5f2feae52c4fbef1a88205667a6bcf2078844 F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P e9177f7d4ec19f0841d0613990d2fb5725700ba1 -R c09d355f93cdab856d4274295151320d +P 5aefef04d6cc3b734c3f05e036b3869a52248f4d +R 8d7b158bf3a519193898c5ead6ba7790 U drh -Z 4efbc5088c9568c2b7090122e09b39c8 +Z d8c8d1df41588adf9be8799f58ddd721 diff --git a/manifest.uuid b/manifest.uuid index 4852f04967..8cbc3f560c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5aefef04d6cc3b734c3f05e036b3869a52248f4d \ No newline at end of file +022bf427c2edfe494ec7c222f436953ff56574a6 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index f01a7f585b..47d553cc27 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -305,7 +305,7 @@ static sqlite3_file *multiplexSubOpen( *rc = multiplexSubFilename(pGroup, iChunk); if( (*rc)==SQLITE_OK && (pSubOpen = pGroup->aReal[iChunk].p)==0 ){ - int flags, rc2, bExists; + int flags, bExists; if( iChunk==0 ) createFlag = (pGroup->flags & SQLITE_OPEN_CREATE)!=0; flags = pGroup->flags; if( createFlag ){ @@ -324,9 +324,9 @@ static sqlite3_file *multiplexSubOpen( return 0; } pGroup->aReal[iChunk].p = pSubOpen; - rc2 = pOrigVfs->xOpen(pOrigVfs, pGroup->aReal[iChunk].z, pSubOpen, + *rc = pOrigVfs->xOpen(pOrigVfs, pGroup->aReal[iChunk].z, pSubOpen, flags, pOutFlags); - if( rc2!=SQLITE_OK ){ + if( (*rc)!=SQLITE_OK ){ sqlite3_free(pSubOpen); pGroup->aReal[iChunk].p = 0; return 0; From 8c24a369a5e5efab956a7dac56083ecd0fdd4e6b Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Dec 2011 05:50:39 +0000 Subject: [PATCH 110/161] Tweaks to the way multiplexSubOpen() works, for backwards compatibility. FossilOrigin-Name: bb40338887c912be70cb6fe3b760d87c14bb88a5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test_multiplex.c | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 88df5c4fc4..1257f0f4ca 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spotential\sinfinite\sloop\s(inserted\sby\sthe\sprevious\scheck-in)\non\sthe\smultiplexWrite()\smethod\sof\sthe\smultiplexor. -D 2011-12-16T05:09:46.415 +C Tweaks\sto\sthe\sway\smultiplexSubOpen()\sworks,\sfor\sbackwards\scompatibility. +D 2011-12-16T05:50:39.331 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c ccc5f2feae52c4fbef1a88205667a6bcf2078844 +F src/test_multiplex.c 6e07b94e2fe430f7f4f0d7d67b5e58f504dea655 F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -978,7 +978,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 5aefef04d6cc3b734c3f05e036b3869a52248f4d -R 8d7b158bf3a519193898c5ead6ba7790 +P 022bf427c2edfe494ec7c222f436953ff56574a6 +R 29ea54dcd671c93952fcbf93e86a1060 U drh -Z d8c8d1df41588adf9be8799f58ddd721 +Z b9fbbc1fe20301c015fc0588c12a3621 diff --git a/manifest.uuid b/manifest.uuid index 8cbc3f560c..6edf6058c3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -022bf427c2edfe494ec7c222f436953ff56574a6 \ No newline at end of file +bb40338887c912be70cb6fe3b760d87c14bb88a5 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 47d553cc27..25bfcdddd2 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -306,10 +306,12 @@ static sqlite3_file *multiplexSubOpen( *rc = multiplexSubFilename(pGroup, iChunk); if( (*rc)==SQLITE_OK && (pSubOpen = pGroup->aReal[iChunk].p)==0 ){ int flags, bExists; - if( iChunk==0 ) createFlag = (pGroup->flags & SQLITE_OPEN_CREATE)!=0; + createFlag = (pGroup->flags & SQLITE_OPEN_CREATE)!=0; flags = pGroup->flags; if( createFlag ){ flags |= SQLITE_OPEN_CREATE; + }else if( iChunk==0 ){ + /* Fall through */ }else if( pGroup->aReal[iChunk].z==0 ){ return 0; }else{ @@ -320,7 +322,7 @@ static sqlite3_file *multiplexSubOpen( } pSubOpen = sqlite3_malloc( pOrigVfs->szOsFile ); if( pSubOpen==0 ){ - *rc = SQLITE_NOMEM; + *rc = SQLITE_IOERR_NOMEM; return 0; } pGroup->aReal[iChunk].p = pSubOpen; From f60b7f36c1c83e9154aa8985162fb35bf9dcc984 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 16 Dec 2011 13:24:27 +0000 Subject: [PATCH 111/161] Experimental fix for [a1fa75cbdd]. FossilOrigin-Name: 6492af76ea6585a1b377d69751af930c0ccfe688 --- manifest | 18 ++++++----- manifest.uuid | 2 +- src/wal.c | 45 ++++++++++++++++----------- test/walcrash3.test | 75 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 26 deletions(-) create mode 100644 test/walcrash3.test diff --git a/manifest b/manifest index ba72d04b26..61d5f87ce3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sstdio\ssupport\sto\sthe\squota\sVFS. -D 2011-12-15T17:44:33.259 +C Experimental\sfix\sfor\s[a1fa75cbdd]. +D 2011-12-16T13:24:27.257 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -250,7 +250,7 @@ F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a -F src/wal.c 7e6e7fe68ee649505dca38c8ab83eda0d0d96ae5 +F src/wal.c dc5c0606db24a1c6b982de212bfbf6e56ac1c01c F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 @@ -914,6 +914,7 @@ F test/walbig.test 0ab8a430ef420a3114f7092e0f30fc9585ffa155 F test/walcksum.test f5447800a157c9e2234fbb8e80243f0813941bde F test/walcrash.test 4fcb661faf71db91214156d52d43ee327f52bde1 F test/walcrash2.test 019d60b89d96c1937adb2b30b850ac7e86e5a142 +F test/walcrash3.test 26d251a6dfaa1daae983268ccc6da0521d61e2e7 F test/walfault.test efb0d5724893133e71b8d9d90abdb781845a6bb0 F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c @@ -983,7 +984,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P da118e02c0576ce16f7a26663f59413316223d55 e85cfe9a17a2943ee0cf7915451ff6cc05908030 -R 4fb854e64d34a9b880548a23455e8f4d -U drh -Z 1f8384d1da732a66b49bdc6038214de7 +P 322bd15f97143d39b3a88d5f6cf7afb454e0666e +R c026e9599d51ae1a18c03cd1d5a83b3e +T *branch * experimental +T *sym-experimental * +T -sym-trunk * +U dan +Z 172fee4764ec1b8014a478816f19a037 diff --git a/manifest.uuid b/manifest.uuid index 07d7da1bd9..3218c8eac2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -322bd15f97143d39b3a88d5f6cf7afb454e0666e \ No newline at end of file +6492af76ea6585a1b377d69751af930c0ccfe688 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 209c909752..e3f9cd1149 100644 --- a/src/wal.c +++ b/src/wal.c @@ -421,6 +421,7 @@ struct Wal { u8 writeLock; /* True if in a write transaction */ u8 ckptLock; /* True if holding a checkpoint lock */ u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ + u8 truncateOnCommit; /* True to truncate WAL file on commit */ WalIndexHdr hdr; /* Wal-index header for current transaction */ const char *zWalName; /* Name of WAL file */ u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ @@ -1782,22 +1783,20 @@ static int walCheckpoint( } /* -** Attempt to limit the WAL size to the size limit defined by -** PRAGMA journal_size_limit. +** If the WAL file is currently larger than nMax bytes in size, truncate +** it to exactly nMax bytes. If an error occurs while doing so, ignore it. */ -static void walLimitSize(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); - } +static void walLimitSize(Wal *pWal, i64 nMax){ + i64 sz; + int rx; + sqlite3BeginBenignMalloc(); + rx = sqlite3OsFileSize(pWal->pWalFd, &sz); + if( rx==SQLITE_OK && (sz > nMax ) ){ + rx = sqlite3OsTruncate(pWal->pWalFd, nMax); + } + sqlite3EndBenignMalloc(); + if( rx ){ + sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName); } } @@ -1834,8 +1833,8 @@ int sqlite3WalClose( sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersistWal); if( rc==SQLITE_OK && bPersistWal!=1 ){ isDelete = 1; - }else{ - walLimitSize(pWal); + }else if( pWal->mxWalSize>=0 ){ + walLimitSize(pWal, pWal->mxWalSize); } } @@ -2444,6 +2443,7 @@ int sqlite3WalEndWriteTransaction(Wal *pWal){ if( pWal->writeLock ){ walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); pWal->writeLock = 0; + pWal->truncateOnCommit = 0; } return SQLITE_OK; } @@ -2578,7 +2578,6 @@ static int walRestartLog(Wal *pWal){ int i; /* Loop counter */ u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */ - walLimitSize(pWal); pWal->nCkpt++; pWal->hdr.mxFrame = 0; sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0])); @@ -2666,6 +2665,7 @@ int sqlite3WalFrames( pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN; pWal->hdr.aFrameCksum[0] = aCksum[0]; pWal->hdr.aFrameCksum[1] = aCksum[1]; + pWal->truncateOnCommit = 1; rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0); WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok")); @@ -2739,6 +2739,15 @@ int sqlite3WalFrames( rc = sqlite3OsSync(pWal->pWalFd, sync_flags); } + if( isCommit && pWal->truncateOnCommit && pWal->mxWalSize>=0 ){ + i64 sz = pWal->mxWalSize; + if( walFrameOffset(iFrame+nLast+1, szPage)>pWal->mxWalSize ){ + sz = walFrameOffset(iFrame+nLast+1, szPage); + } + walLimitSize(pWal, sz); + pWal->truncateOnCommit = 0; + } + /* Append data to the wal-index. It is not necessary to lock the ** wal-index to do this as the SQLITE_SHM_WRITE lock held on the wal-index ** guarantees that there are no other writers, and no data that may diff --git a/test/walcrash3.test b/test/walcrash3.test new file mode 100644 index 0000000000..156c2bd1c8 --- /dev/null +++ b/test/walcrash3.test @@ -0,0 +1,75 @@ +# 2011 December 16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This test simulates an application crash immediately following a +# system call to truncate a file. Specifically, the system call that +# truncates the WAL file if "PRAGMA journal_size_limit" is configured. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable !wal {finish_test ; return } +set testprefix walcrash3 + +db close +testvfs tvfs +tvfs filter {xTruncate xWrite} +tvfs script tvfs_callback +proc tvfs_callback {args} {} + +sqlite3 db test.db -vfs tvfs +do_execsql_test 1.1 { + PRAGMA page_size = 1024; + PRAGMA journal_mode = WAL; + PRAGMA wal_autocheckpoint = 128; + PRAGMA journal_size_limit = 16384; + + CREATE TABLE t1(a BLOB, b BLOB, UNIQUE(a, b)); + INSERT INTO t1 VALUES(randomblob(10), randomblob(1000)); +} {wal 128 16384} + +proc tvfs_callback {method file arglist} { + if {$::state==1} { + foreach f [glob -nocomplain xx_test.*] { forcedelete $f } + foreach f [glob -nocomplain test.*] { forcecopy $f "xx_$f" } + set ::state 2 + } + if {$::state==0 && $method=="xTruncate" && [file tail $file]=="test.db-wal"} { + set ::state 1 + } +} + +for {set i 2} {$i<1000} {incr i} { + + # If the WAL file is truncated within the following, within the following + # xWrite call the [tvfs_callback] makes a copy of the database and WAL + # files set sets $::state to 2. So that the copied files are in the same + # state as the real database and WAL files would be if an application crash + # occurred immediately following the xTruncate(). + # + set ::state 0 + do_execsql_test 1.$i.1 { + INSERT INTO t1 VALUES(randomblob(10), randomblob(1000)); + } + + # If a copy was made, open it and run the integrity-check. + # + if {$::state==2} { + sqlite3 db2 xx_test.db + do_test 1.$i.2 { execsql { PRAGMA integrity_check } db2 } "ok" + do_test 1.$i.3 { execsql { SELECT count(*) FROM t1 } db2 } [expr $i-1] + db2 close + } +} + +finish_test + From 84968c051d9d2630f103ce4e7886c1b894ed79eb Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Dec 2011 15:11:39 +0000 Subject: [PATCH 112/161] Improved logging of master-journal name conflicts. FossilOrigin-Name: b1005ef46cc2b46dd8e448ae1a9a9508bd5666ab --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 13 +++++++++---- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 9d87384e8d..cbedf29e4b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\snx-devkit\schanges\sinto\strunk. -D 2011-12-16T13:42:03.408 +C Improved\slogging\sof\smaster-journal\sname\sconflicts. +D 2011-12-16T15:11:39.468 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -244,7 +244,7 @@ F src/vdbe.c 029add0c5197a61db588824a58570547330b9d8f F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb F src/vdbeInt.h 48c158b2fceca9682d1577e61c62da3c58cf0748 F src/vdbeapi.c 86189ebba2c49791d75eaa12929f3ce6527596bd -F src/vdbeaux.c 4a96cddec7c8cc33f98da703c1baf2a654b50cab +F src/vdbeaux.c 3015179b27672cb773d014495023eaa4a8cd8f9c F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 @@ -983,7 +983,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 322bd15f97143d39b3a88d5f6cf7afb454e0666e bb40338887c912be70cb6fe3b760d87c14bb88a5 -R a70f90ef372516f64947505d1ba22869 +P cf3bccc2e944cd2dd3efb8554682994a06115f16 +R 9cdd098939326e460c36a0ff01e82e7f U drh -Z a2e5ef34107012b45c32946167d7851d +Z f579d2bc7a13e23fcc9e8ceaf02a267f diff --git a/manifest.uuid b/manifest.uuid index d3c7f87bf8..b02a3e69b1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cf3bccc2e944cd2dd3efb8554682994a06115f16 \ No newline at end of file +b1005ef46cc2b46dd8e448ae1a9a9508bd5666ab \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index aa024ca54e..c7d46a1bc1 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1842,11 +1842,16 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ if( zMaster==0 ) return SQLITE_NOMEM; do { u32 iRandom; - if( retryCount++>100 ){ - sqlite3_log(SQLITE_FULL, "cannot find unique master-journal"); - sqlite3OsDelete(pVfs, zMaster, 0); - break; + if( retryCount ){ + if( retryCount>100 ){ + sqlite3_log(SQLITE_FULL, "MJ delete: %s", zMaster); + sqlite3OsDelete(pVfs, zMaster, 0); + break; + }else if( retryCount==1 ){ + sqlite3_log(SQLITE_FULL, "MJ collide: %s", zMaster); + } } + retryCount++; sqlite3_randomness(sizeof(iRandom), &iRandom); sqlite3_snprintf(13, &zMaster[nMainFile], "-mj%06X9%02X", (iRandom>>8)&0xffffff, iRandom&0xff); From e98842f02d1f8fa6ace6296c609bf7c0c87c9fb8 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 16 Dec 2011 17:01:04 +0000 Subject: [PATCH 113/161] Add code for a test that was failing before the persistent-wal related changes of [9ccc4a1be]. FossilOrigin-Name: 49d21ce50fcf535e470d284ccbb9eb4d4bcfa3a6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/walpersist.test | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 66736fbb73..d0632ffbc3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sfix\sfor\s[a1fa75cbdd02]\sfrom\sthe\sexperimental\sbranch.\s\sAlso\nfix\sthe\spersistent-wal\smode\sfeature\sof\struncating\sthe\sWAL\son\sclose\sso\sthat\nit\salways\struncates\sthe\sWAL\sto\szero\sbytes. -D 2011-12-16T15:38:52.854 +C Add\scode\sfor\sa\stest\sthat\swas\sfailing\sbefore\sthe\spersistent-wal\srelated\schanges\sof\s[9ccc4a1be]. +D 2011-12-16T17:01:04.486 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -919,7 +919,7 @@ F test/walfault.test efb0d5724893133e71b8d9d90abdb781845a6bb0 F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496 -F test/walpersist.test 4d308b7f16470e85cb389636e59c455fe6b3a61a +F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6 F test/walro.test e6bb27762c9f22601cbb8bff6e0acfd124e74b63 F test/walshared.test 6dda2293880c300baf5d791c307f653094585761 F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a @@ -984,7 +984,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P b1005ef46cc2b46dd8e448ae1a9a9508bd5666ab 6492af76ea6585a1b377d69751af930c0ccfe688 -R 5e90bbe7156facb03e2de52b2217bc8c -U drh -Z 290df3a9d2eb83a09d72442af4b2f315 +P 09ccc4a1be7ba81890f10aac6623dd90dab4f990 +R 28af0dbcab33b710b481512f3ea16256 +U dan +Z ddd1a9a132526961a13184bc513a99bd diff --git a/manifest.uuid b/manifest.uuid index 689e39e8ad..b4b6e2437b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -09ccc4a1be7ba81890f10aac6623dd90dab4f990 \ No newline at end of file +49d21ce50fcf535e470d284ccbb9eb4d4bcfa3a6 \ No newline at end of file diff --git a/test/walpersist.test b/test/walpersist.test index ecb8f36408..692728dda4 100644 --- a/test/walpersist.test +++ b/test/walpersist.test @@ -90,5 +90,37 @@ do_test walpersist-2.2 { db close concat [file exists test.db-wal] [file size test.db-wal] } {1 0} +do_test walpersist-2.3 { + sqlite3 db test.db + execsql { PRAGMA integrity_check } +} {ok} + +do_test 3.1 { + catch {db close} + forcedelete test.db test.db-shm test.db-wal + sqlite3 db test.db + execsql { + PRAGMA page_size = 1024; + PRAGMA journal_mode = WAL; + PRAGMA wal_autocheckpoint=128; + PRAGMA journal_size_limit=16384; + CREATE TABLE t1(a, b, PRIMARY KEY(a, b)); + } +} {wal 128 16384} +do_test 3.2 { + for {set i 0} {$i<200} {incr i} { + execsql { INSERT INTO t1 VALUES(randomblob(500), randomblob(500)) } + } + file_control_persist_wal db 1 + db close +} {} +do_test walpersist-3.3 { + file size test.db-wal +} {0} +do_test walpersist-3.4 { + sqlite3 db test.db + execsql { PRAGMA integrity_check } +} {ok} + finish_test From 88f975a7a49dfd8786f0337add71d4841596a5f3 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Dec 2011 19:34:36 +0000 Subject: [PATCH 114/161] Proposed changes that ensure that the WAL header is written prior to the first commit mark. FossilOrigin-Name: 91d0437c0702904d27f0ef7b1b52d0797efe1826 --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/wal.c | 47 +++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 66736fbb73..8c212674db 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sfix\sfor\s[a1fa75cbdd02]\sfrom\sthe\sexperimental\sbranch.\s\sAlso\nfix\sthe\spersistent-wal\smode\sfeature\sof\struncating\sthe\sWAL\son\sclose\sso\sthat\nit\salways\struncates\sthe\sWAL\sto\szero\sbytes. -D 2011-12-16T15:38:52.854 +C Proposed\schanges\sthat\sensure\sthat\sthe\sWAL\sheader\sis\swritten\sprior\sto\sthe\nfirst\scommit\smark. +D 2011-12-16T19:34:36.384 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -250,7 +250,7 @@ F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a -F src/wal.c 8575f2bdaed48e7ffbea8608b614bb7abd382a54 +F src/wal.c a1157f289ef700ce9148d8448916799cb364c20f F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 @@ -984,7 +984,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P b1005ef46cc2b46dd8e448ae1a9a9508bd5666ab 6492af76ea6585a1b377d69751af930c0ccfe688 -R 5e90bbe7156facb03e2de52b2217bc8c +P 09ccc4a1be7ba81890f10aac6623dd90dab4f990 +R e39509fa33546fba87ec45fa63df451b +T *branch * wal-header-sync +T *sym-wal-header-sync * +T -sym-trunk * U drh -Z 290df3a9d2eb83a09d72442af4b2f315 +Z 6469301a128bde2c8fea4c5b47d61847 diff --git a/manifest.uuid b/manifest.uuid index 689e39e8ad..cf227b205f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -09ccc4a1be7ba81890f10aac6623dd90dab4f990 \ No newline at end of file +91d0437c0702904d27f0ef7b1b52d0797efe1826 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 0fae6cbc74..915e014aaa 100644 --- a/src/wal.c +++ b/src/wal.c @@ -414,6 +414,7 @@ struct Wal { u32 iCallback; /* Value to pass to log callback (or 0) */ i64 mxWalSize; /* Truncate WAL to this size upon reset */ int nWiData; /* Size of array apWiData */ + int szFirstBlock; /* Size of first block written to WAL file */ volatile u32 **apWiData; /* Pointer to wal-index content in memory */ u32 szPage; /* Database page size */ i16 readLock; /* Which read lock is being held. -1 for none */ @@ -2617,6 +2618,40 @@ static int walRestartLog(Wal *pWal){ return rc; } +/* +** Write iAmt bytes of content into the WAL file beginning at iOffset. +** +** When crossing the boundary between the first and second sectors of the +** file, first write all of the first sector content, then fsync(), then +** continue writing content for the second sector. This ensures that +** the WAL header is overwritten before the first commit mark. +*/ +static int walWriteToLog( + Wal *pWal, /* WAL to write to */ + void *pContent, /* Content to be written */ + int iAmt, /* Number of bytes to write */ + sqlite3_int64 iOffset /* Start writing at this offset */ +){ + int rc; + if( iOffset>=pWal->szFirstBlock || iOffset+iAmtszFirstBlock ){ + /* The common and fast case. Just write the data. */ + rc = sqlite3OsWrite(pWal->pWalFd, pContent, iAmt, iOffset); + }else{ + /* If this write will cross the first sector boundary, it has to + ** be split it two with a sync in between. */ + int iFirstAmt = pWal->szFirstBlock - iOffset; + assert( iFirstAmt>0 && iFirstAmtpWalFd, pContent, iFirstAmt, iOffset); + if( rc ) return rc; + rc = sqlite3OsSync(pWal->pWalFd, SQLITE_SYNC_NORMAL); + if( rc ) return rc; + pContent = (void*)(iFirstAmt + (char*)pContent); + rc = sqlite3OsWrite(pWal->pWalFd, pContent, + iAmt-iFirstAmt, iOffset+iFirstAmt); + } + return rc; +} + /* ** Write a set of frames to the log. The caller must hold the write-lock ** on the log file (obtained using sqlite3WalBeginWriteTransaction()). @@ -2686,6 +2721,10 @@ int sqlite3WalFrames( } assert( (int)pWal->szPage==szPage ); + /* The size of the block containing the WAL header */ + pWal->szFirstBlock = sqlite3OsSectorSize(pWal->pWalFd); + if( szPage>pWal->szFirstBlock ) pWal->szFirstBlock = szPage; + /* Write the log file. */ for(p=pList; p; p=p->pDirty){ u32 nDbsize; /* Db-size field for frame header */ @@ -2703,13 +2742,13 @@ int sqlite3WalFrames( pData = p->pData; #endif walEncodeFrame(pWal, p->pgno, nDbsize, pData, aFrame); - rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOffset); + rc = walWriteToLog(pWal, aFrame, sizeof(aFrame), iOffset); if( rc!=SQLITE_OK ){ return rc; } /* Write the page data */ - rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOffset+sizeof(aFrame)); + rc = walWriteToLog(pWal, pData, szPage, iOffset+sizeof(aFrame)); if( rc!=SQLITE_OK ){ return rc; } @@ -2734,12 +2773,12 @@ int sqlite3WalFrames( #endif walEncodeFrame(pWal, pLast->pgno, nTruncate, pData, aFrame); /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ - rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOffset); + rc = walWriteToLog(pWal, aFrame, sizeof(aFrame), iOffset); if( rc!=SQLITE_OK ){ return rc; } iOffset += WAL_FRAME_HDRSIZE; - rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOffset); + rc = walWriteToLog(pWal, pData, szPage, iOffset); if( rc!=SQLITE_OK ){ return rc; } From 4eb02a4556b41fe769a90085a87fe70d5c29d204 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Dec 2011 21:26:26 +0000 Subject: [PATCH 115/161] Enhance the WAL header sync so that it honors the various synchronous pragmas, settings, and device characteristics. FossilOrigin-Name: 9799241f7de952c4d1ea8bf6508b577d2b57a370 --- manifest | 23 ++++++++++------------- manifest.uuid | 2 +- src/pager.c | 32 +++++++++++++++++++++----------- src/wal.c | 29 +++++++++++++++++++++-------- src/wal.h | 6 ++++++ test/wal2.test | 50 +++++++++++++++++++++++++++++--------------------- test/wal3.test | 1 + 7 files changed, 89 insertions(+), 54 deletions(-) diff --git a/manifest b/manifest index 8c212674db..bc2dd4cdea 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Proposed\schanges\sthat\sensure\sthat\sthe\sWAL\sheader\sis\swritten\sprior\sto\sthe\nfirst\scommit\smark. -D 2011-12-16T19:34:36.384 +C Enhance\sthe\sWAL\sheader\ssync\sso\sthat\sit\shonors\sthe\svarious\ssynchronous\npragmas,\ssettings,\sand\sdevice\scharacteristics. +D 2011-12-16T21:26:26.087 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -168,7 +168,7 @@ F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 7dc7df10331942b139032328449a3723e051979e F src/os_win.c 197d23ce8a0dff748e766e034bf95ff756dd3884 -F src/pager.c d981f3bfcc0e4460537d983899620700ccf8f539 +F src/pager.c c7c32a1c279e0bbbde3578172985c41d4c5efc35 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba F src/pcache.c 1fdd77978c1525d1ca4b9ef48eb80abca710cb4c @@ -250,8 +250,8 @@ F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a -F src/wal.c a1157f289ef700ce9148d8448916799cb364c20f -F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a +F src/wal.c 20022b733ce06f77cc1d7f154da32987b57532ae +F src/wal.h 42f8313f7aaf8913e2d1fdf7b47025c23491ea1d F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 @@ -902,8 +902,8 @@ F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d F test/wal.test c743be787e60c1242fa6cdf73b410e64b2977e25 -F test/wal2.test ad6412596815f553cd30f271d291ab003092bc7e -F test/wal3.test 18da4e65c30c43c646ad40e145e9a074e4062fc9 +F test/wal2.test 29e2cbe840582fc6efd0487b4f6337caed4b3e80 +F test/wal3.test 29a6e8843e5f5fd13f33cb0407d2923107020d32 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c F test/wal5.test 1bbfaa316dc2a1d0d1fac3f4500c38a90055a41b F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3 @@ -984,10 +984,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 09ccc4a1be7ba81890f10aac6623dd90dab4f990 -R e39509fa33546fba87ec45fa63df451b -T *branch * wal-header-sync -T *sym-wal-header-sync * -T -sym-trunk * +P 91d0437c0702904d27f0ef7b1b52d0797efe1826 +R 5f78dbf89e78a567743daf43caa5df96 U drh -Z 6469301a128bde2c8fea4c5b47d61847 +Z da5e946383fd5dfe4d9a2957cf126f26 diff --git a/manifest.uuid b/manifest.uuid index cf227b205f..433b9f5a98 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -91d0437c0702904d27f0ef7b1b52d0797efe1826 \ No newline at end of file +9799241f7de952c4d1ea8bf6508b577d2b57a370 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index f3069e52ba..9db6ebd3f4 100644 --- a/src/pager.c +++ b/src/pager.c @@ -616,6 +616,7 @@ struct Pager { u8 noSync; /* Do not sync the journal if true */ u8 fullSync; /* Do extra syncs of the journal for robustness */ u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ + u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */ u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ u8 tempFile; /* zFilename is a temporary file */ u8 readOnly; /* True for a read-only database */ @@ -786,7 +787,7 @@ static int pagerUseWal(Pager *pPager){ #else # define pagerUseWal(x) 0 # define pagerRollbackWal(x) 0 -# define pagerWalFrames(v,w,x,y,z) 0 +# define pagerWalFrames(v,w,x,y) 0 # define pagerOpenWalIfPresent(z) SQLITE_OK # define pagerBeginReadTransaction(z) SQLITE_OK #endif @@ -2955,8 +2956,7 @@ static int pagerWalFrames( Pager *pPager, /* Pager object */ PgHdr *pList, /* List of frames to log */ Pgno nTruncate, /* Database size after this commit */ - int isCommit, /* True if this is a commit */ - int syncFlags /* Flags to pass to OsSync() (or 0) */ + int isCommit /* True if this is a commit */ ){ int rc; /* Return code */ #if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES) @@ -2987,7 +2987,7 @@ static int pagerWalFrames( if( pList->pgno==1 ) pager_write_changecounter(pList); rc = sqlite3WalFrames(pPager->pWal, - pPager->pageSize, pList, nTruncate, isCommit, syncFlags + pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags ); if( rc==SQLITE_OK && pPager->pBackup ){ PgHdr *p; @@ -3367,6 +3367,10 @@ void sqlite3PagerSetSafetyLevel( pPager->syncFlags = SQLITE_SYNC_NORMAL; pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; } + pPager->walSyncFlags = pPager->syncFlags; + if( pPager->fullSync ){ + pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS; + } } #endif @@ -4194,7 +4198,7 @@ static int pagerStress(void *p, PgHdr *pPg){ rc = subjournalPage(pPg); } if( rc==SQLITE_OK ){ - rc = pagerWalFrames(pPager, pPg, 0, 0, 0); + rc = pagerWalFrames(pPager, pPg, 0, 0); } }else{ @@ -4533,9 +4537,17 @@ int sqlite3PagerOpen( pPager->readOnly = (u8)readOnly; assert( useJournal || pPager->tempFile ); pPager->noSync = pPager->tempFile; - pPager->fullSync = pPager->noSync ?0:1; - pPager->syncFlags = pPager->noSync ? 0 : SQLITE_SYNC_NORMAL; - pPager->ckptSyncFlags = pPager->syncFlags; + if( pPager->noSync ){ + assert( pPager->fullSync==0 ); + assert( pPager->syncFlags==0 ); + assert( pPager->walSyncFlags==0 ); + assert( pPager->ckptSyncFlags==0 ); + }else{ + pPager->fullSync = 1; + pPager->syncFlags = SQLITE_SYNC_NORMAL; + pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS; + pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; + } /* pPager->pFirst = 0; */ /* pPager->pFirstSynced = 0; */ /* pPager->pLast = 0; */ @@ -5765,9 +5777,7 @@ int sqlite3PagerCommitPhaseOne( } assert( rc==SQLITE_OK ); if( ALWAYS(pList) ){ - rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1, - (pPager->fullSync ? pPager->syncFlags : 0) - ); + rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1); } sqlite3PagerUnref(pPageOne); if( rc==SQLITE_OK ){ diff --git a/src/wal.c b/src/wal.c index 915e014aaa..34ddb1b1e2 100644 --- a/src/wal.c +++ b/src/wal.c @@ -418,11 +418,13 @@ struct Wal { volatile u32 **apWiData; /* Pointer to wal-index content in memory */ u32 szPage; /* Database page size */ i16 readLock; /* Which read lock is being held. -1 for none */ + u8 syncFlags; /* Flags to use to sync header writes */ u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ u8 writeLock; /* True if in a write transaction */ u8 ckptLock; /* True if holding a checkpoint lock */ u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ u8 truncateOnCommit; /* True to truncate WAL file on commit */ + u8 noSyncHeader; /* Avoid WAL header fsyncs if true */ WalIndexHdr hdr; /* Wal-index header for current transaction */ const char *zWalName; /* Name of WAL file */ u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ @@ -1297,6 +1299,8 @@ int sqlite3WalOpen( sqlite3OsClose(pRet->pWalFd); sqlite3_free(pRet); }else{ + int iDC = sqlite3OsDeviceCharacteristics(pRet->pWalFd); + if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->noSyncHeader = 1; } *ppWal = pRet; WALTRACE(("WAL%d: opened\n", pRet)); } @@ -2633,7 +2637,10 @@ static int walWriteToLog( sqlite3_int64 iOffset /* Start writing at this offset */ ){ int rc; - if( iOffset>=pWal->szFirstBlock || iOffset+iAmtszFirstBlock ){ + if( iOffset>=pWal->szFirstBlock + || iOffset+iAmtszFirstBlock + || pWal->syncFlags==0 + ){ /* The common and fast case. Just write the data. */ rc = sqlite3OsWrite(pWal->pWalFd, pContent, iAmt, iOffset); }else{ @@ -2643,7 +2650,8 @@ static int walWriteToLog( assert( iFirstAmt>0 && iFirstAmtpWalFd, pContent, iFirstAmt, iOffset); if( rc ) return rc; - rc = sqlite3OsSync(pWal->pWalFd, SQLITE_SYNC_NORMAL); + assert( pWal->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) ); + rc = sqlite3OsSync(pWal->pWalFd, pWal->syncFlags); if( rc ) return rc; pContent = (void*)(iFirstAmt + (char*)pContent); rc = sqlite3OsWrite(pWal->pWalFd, pContent, @@ -2721,9 +2729,15 @@ int sqlite3WalFrames( } assert( (int)pWal->szPage==szPage ); - /* The size of the block containing the WAL header */ - pWal->szFirstBlock = sqlite3OsSectorSize(pWal->pWalFd); - if( szPage>pWal->szFirstBlock ) pWal->szFirstBlock = szPage; + /* Setup information needed to do the WAL header sync */ + if( pWal->noSyncHeader ){ + assert( pWal->szFirstBlock==0 ); + assert( pWal->syncFlags==0 ); + }else{ + pWal->szFirstBlock = sqlite3OsSectorSize(pWal->pWalFd); + if( szPage>pWal->szFirstBlock ) pWal->szFirstBlock = szPage; + pWal->syncFlags = sync_flags & SQLITE_SYNC_MASK; + } /* Write the log file. */ for(p=pList; p; p=p->pDirty){ @@ -2756,11 +2770,10 @@ int sqlite3WalFrames( } /* Sync the log file if the 'isSync' flag was specified. */ - if( sync_flags ){ + if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){ i64 iSegment = sqlite3OsSectorSize(pWal->pWalFd); i64 iOffset = walFrameOffset(iFrame+1, szPage); - assert( isCommit ); assert( iSegment>0 ); iSegment = (((iOffset+iSegment-1)/iSegment) * iSegment); @@ -2786,7 +2799,7 @@ int sqlite3WalFrames( iOffset += szPage; } - rc = sqlite3OsSync(pWal->pWalFd, sync_flags); + rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK); } if( isCommit && pWal->truncateOnCommit && pWal->mxWalSize>=0 ){ diff --git a/src/wal.h b/src/wal.h index a62b23bbdc..7cd84be997 100644 --- a/src/wal.h +++ b/src/wal.h @@ -87,6 +87,12 @@ int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData); /* Write a frame or frames to the log. */ int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int); +/* Additional values that can be added to the sync_flags argument of +** sqlite3WalFrames(): +*/ +#define WAL_SYNC_TRANSACTIONS 0x20 /* Sync at the end of each transaction */ +#define SQLITE_SYNC_MASK 0x13 /* Mask off the SQLITE_SYNC_* values */ + /* Copy pages from the log to the database file */ int sqlite3WalCheckpoint( Wal *pWal, /* Write-ahead log connection */ diff --git a/test/wal2.test b/test/wal2.test index f4887065a5..90ea9defed 100644 --- a/test/wal2.test +++ b/test/wal2.test @@ -1176,9 +1176,9 @@ if {$::tcl_platform(platform) == "unix"} { # Test that "PRAGMA checkpoint_fullsync" appears to be working. # foreach {tn sql reslist} { - 1 { } {8 0 3 0 5 0} - 2 { PRAGMA checkpoint_fullfsync = 1 } {8 4 3 2 5 2} - 3 { PRAGMA checkpoint_fullfsync = 0 } {8 0 3 0 5 0} + 1 { } {10 0 4 0 6 0} + 2 { PRAGMA checkpoint_fullfsync = 1 } {10 4 4 2 6 2} + 3 { PRAGMA checkpoint_fullfsync = 0 } {10 0 4 0 6 0} } { faultsim_delete_and_reopen @@ -1192,12 +1192,12 @@ foreach {tn sql reslist} { do_execsql_test wal2-14.$tn.2 { PRAGMA wal_autocheckpoint = 10; CREATE TABLE t1(a, b); -- 2 wal syncs - INSERT INTO t1 VALUES(1, 2); -- 1 wal sync + INSERT INTO t1 VALUES(1, 2); -- 2 wal sync PRAGMA wal_checkpoint; -- 1 wal sync, 1 db sync BEGIN; INSERT INTO t1 VALUES(3, 4); INSERT INTO t1 VALUES(5, 6); - COMMIT; -- 1 wal sync + COMMIT; -- 2 wal sync PRAGMA wal_checkpoint; -- 1 wal sync, 1 db sync } {10 0 5 5 0 2 2} @@ -1233,22 +1233,22 @@ catch { db close } # PRAGMA fullfsync # PRAGMA synchronous # -foreach {tn settings commit_sync ckpt_sync} { - 1 {0 0 off} {0 0} {0 0} - 2 {0 0 normal} {0 0} {2 0} - 3 {0 0 full} {1 0} {2 0} +foreach {tn settings restart_sync commit_sync ckpt_sync} { + 1 {0 0 off} {0 0} {0 0} {0 0} + 2 {0 0 normal} {1 0} {0 0} {2 0} + 3 {0 0 full} {2 0} {1 0} {2 0} - 4 {0 1 off} {0 0} {0 0} - 5 {0 1 normal} {0 0} {0 2} - 6 {0 1 full} {0 1} {0 2} + 4 {0 1 off} {0 0} {0 0} {0 0} + 5 {0 1 normal} {0 1} {0 0} {0 2} + 6 {0 1 full} {0 2} {0 1} {0 2} - 7 {1 0 off} {0 0} {0 0} - 8 {1 0 normal} {0 0} {0 2} - 9 {1 0 full} {1 0} {0 2} + 7 {1 0 off} {0 0} {0 0} {0 0} + 8 {1 0 normal} {1 0} {0 0} {0 2} + 9 {1 0 full} {2 0} {1 0} {0 2} - 10 {1 1 off} {0 0} {0 0} - 11 {1 1 normal} {0 0} {0 2} - 12 {1 1 full} {0 1} {0 2} + 10 {1 1 off} {0 0} {0 0} {0 0} + 11 {1 1 normal} {0 1} {0 0} {0 2} + 12 {1 1 full} {0 2} {0 1} {0 2} } { forcedelete test.db @@ -1262,27 +1262,35 @@ foreach {tn settings commit_sync ckpt_sync} { sqlite3 db test.db do_execsql_test 15.$tn.1 " CREATE TABLE t1(x); + PRAGMA wal_autocheckpoint = OFF; PRAGMA journal_mode = WAL; PRAGMA checkpoint_fullfsync = [lindex $settings 0]; PRAGMA fullfsync = [lindex $settings 1]; PRAGMA synchronous = [lindex $settings 2]; - " {wal} + " {0 wal} do_test 15.$tn.2 { set sync(normal) 0 set sync(full) 0 execsql { INSERT INTO t1 VALUES('abc') } list $::sync(normal) $::sync(full) - } $commit_sync + } $restart_sync do_test 15.$tn.3 { + set sync(normal) 0 + set sync(full) 0 + execsql { INSERT INTO t1 VALUES('abc') } + list $::sync(normal) $::sync(full) + } $commit_sync + + do_test 15.$tn.4 { set sync(normal) 0 set sync(full) 0 execsql { INSERT INTO t1 VALUES('def') } list $::sync(normal) $::sync(full) } $commit_sync - do_test 15.$tn.4 { + do_test 15.$tn.5 { set sync(normal) 0 set sync(full) 0 execsql { PRAGMA wal_checkpoint } diff --git a/test/wal3.test b/test/wal3.test index ea5e70571b..82f7d72a97 100644 --- a/test/wal3.test +++ b/test/wal3.test @@ -217,6 +217,7 @@ foreach {tn syncmode synccount} { execsql "PRAGMA synchronous = $syncmode" execsql { PRAGMA journal_mode = WAL } + execsql { CREATE TABLE filler(a,b,c); } set ::syncs [list] T filter xSync From d2980310d01601abd215e01a255b8dffcccada29 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Dec 2011 01:31:44 +0000 Subject: [PATCH 116/161] Make sure the Salt-1 value in the WAL file is sequentially numbered at each checkpoint, as it says it should be in the documentation. FossilOrigin-Name: 7b63b11b93396079131686abb36c4221354fa50e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wal.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d0632ffbc3..1bad8d9e21 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\scode\sfor\sa\stest\sthat\swas\sfailing\sbefore\sthe\spersistent-wal\srelated\schanges\sof\s[9ccc4a1be]. -D 2011-12-16T17:01:04.486 +C Make\ssure\sthe\sSalt-1\svalue\sin\sthe\sWAL\sfile\sis\ssequentially\snumbered\sat\neach\scheckpoint,\sas\sit\ssays\sit\sshould\sbe\sin\sthe\sdocumentation. +D 2011-12-17T01:31:44.448 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -250,7 +250,7 @@ F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a -F src/wal.c 8575f2bdaed48e7ffbea8608b614bb7abd382a54 +F src/wal.c 8f6fd4900934124f6c2701448c13038cbc02a4f4 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 @@ -984,7 +984,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 09ccc4a1be7ba81890f10aac6623dd90dab4f990 -R 28af0dbcab33b710b481512f3ea16256 -U dan -Z ddd1a9a132526961a13184bc513a99bd +P 49d21ce50fcf535e470d284ccbb9eb4d4bcfa3a6 +R 4fa928f2229c3510e15bdde794cf4c8f +U drh +Z 1119fcc0458452314585b8d9dc3542f8 diff --git a/manifest.uuid b/manifest.uuid index b4b6e2437b..25ecc50cf5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -49d21ce50fcf535e470d284ccbb9eb4d4bcfa3a6 \ No newline at end of file +7b63b11b93396079131686abb36c4221354fa50e \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 0fae6cbc74..047368406f 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2666,7 +2666,7 @@ int sqlite3WalFrames( sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION); sqlite3Put4byte(&aWalHdr[8], szPage); sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt); - sqlite3_randomness(8, pWal->hdr.aSalt); + if( pWal->nCkpt==0 ) sqlite3_randomness(8, pWal->hdr.aSalt); memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8); walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum); sqlite3Put4byte(&aWalHdr[24], aCksum[0]); From 533100d3a3aed47416b23e2e349282b9508e766b Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 17 Dec 2011 08:10:34 +0000 Subject: [PATCH 117/161] Add tests to walcrash3.test. FossilOrigin-Name: d76880428013ae2c5be00d87bb3e1695af6f706f --- manifest | 16 ++++++------- manifest.uuid | 2 +- test/permutations.test | 4 ++-- test/walcrash3.test | 54 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 1bad8d9e21..6676da8ac4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\sSalt-1\svalue\sin\sthe\sWAL\sfile\sis\ssequentially\snumbered\sat\neach\scheckpoint,\sas\sit\ssays\sit\sshould\sbe\sin\sthe\sdocumentation. -D 2011-12-17T01:31:44.448 +C Add\stests\sto\swalcrash3.test. +D 2011-12-17T08:10:34.481 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -629,7 +629,7 @@ F test/pageropt.test 9191867ed19a2b3db6c42d1b36b6fbc657cd1ab0 F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0 F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16 F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 -F test/permutations.test 522823b47238cb1754198f80817fe9f9158ede55 +F test/permutations.test 8db6d3b72e6ce423cfb94d87926e5edcb4b0078f F test/pragma.test 7fa35e53085812dac94c2bfcbb02c2a4ad35df5e F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 @@ -914,7 +914,7 @@ F test/walbig.test 0ab8a430ef420a3114f7092e0f30fc9585ffa155 F test/walcksum.test f5447800a157c9e2234fbb8e80243f0813941bde F test/walcrash.test 4fcb661faf71db91214156d52d43ee327f52bde1 F test/walcrash2.test 019d60b89d96c1937adb2b30b850ac7e86e5a142 -F test/walcrash3.test 26d251a6dfaa1daae983268ccc6da0521d61e2e7 +F test/walcrash3.test 595e44c6197f0d0aa509fc135be2fd0209d11a2c F test/walfault.test efb0d5724893133e71b8d9d90abdb781845a6bb0 F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c @@ -984,7 +984,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 49d21ce50fcf535e470d284ccbb9eb4d4bcfa3a6 -R 4fa928f2229c3510e15bdde794cf4c8f -U drh -Z 1119fcc0458452314585b8d9dc3542f8 +P 7b63b11b93396079131686abb36c4221354fa50e +R 177c457106f4a322f13cf8ef2b836d21 +U dan +Z c66e15671707eedc5457d2cd5fb751c5 diff --git a/manifest.uuid b/manifest.uuid index 25ecc50cf5..47932d748d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7b63b11b93396079131686abb36c4221354fa50e \ No newline at end of file +d76880428013ae2c5be00d87bb3e1695af6f706f \ No newline at end of file diff --git a/test/permutations.test b/test/permutations.test index 7c3b026c67..922e6e37ef 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -110,8 +110,8 @@ set allquicktests [test_set $alltests -exclude { speed4p.test sqllimits1.test tkt2686.test thread001.test thread002.test thread003.test thread004.test thread005.test trans2.test vacuum3.test incrvacuum_ioerr.test autovacuum_crash.test btree8.test shared_err.test - vtab_err.test walslow.test walcrash.test - walthread.test rtree3.test indexfault.test + vtab_err.test walslow.test walcrash.test walcrash3.test + walthread.test rtree3.test indexfault.test }] if {[info exists ::env(QUICKTEST_INCLUDE)]} { set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)] diff --git a/test/walcrash3.test b/test/walcrash3.test index 156c2bd1c8..c2c9a6d518 100644 --- a/test/walcrash3.test +++ b/test/walcrash3.test @@ -70,6 +70,60 @@ for {set i 2} {$i<1000} {incr i} { db2 close } } +catch { db close } +tvfs delete + +#-------------------------------------------------------------------------- +# +catch { db close } +forcedelete test.db + +do_test 2.1 { + sqlite3 db test.db + execsql { + PRAGMA page_size = 512; + PRAGMA journal_mode = WAL; + PRAGMA wal_autocheckpoint = 128; + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES(randomblob(25), randomblob(200)); + } + + for {set i 0} {$i < 1500} {incr i} { + execsql { INSERT INTO t1 VALUES(randomblob(25), randomblob(200)) } + } + + db_save + db close +} {} + +set nInitialErr [set_test_counter errors] +for {set i 2} {$i<10000 && [set_test_counter errors]==$nInitialErr} {incr i} { + + do_test 2.$i.1 { + catch { db close } + db_restore + crashsql -delay 2 -file test.db-wal -seed $i { + SELECT * FROM sqlite_master; + PRAGMA synchronous = full; + PRAGMA wal_checkpoint; + BEGIN; + INSERT INTO t1 VALUES(randomblob(26), randomblob(200)); + INSERT INTO t1 VALUES(randomblob(26), randomblob(200)); + INSERT INTO t1 VALUES(randomblob(26), randomblob(200)); + INSERT INTO t1 VALUES(randomblob(26), randomblob(200)); + INSERT INTO t1 VALUES(randomblob(26), randomblob(200)); + INSERT INTO t1 VALUES(randomblob(26), randomblob(200)); + INSERT INTO t1 VALUES(randomblob(26), randomblob(200)); + INSERT INTO t1 VALUES(randomblob(26), randomblob(200)); + COMMIT; + } + } {1 {child process exited abnormally}} + + do_test 2.$i.2 { + sqlite3 db test.db + execsql { PRAGMA integrity_check } + } {ok} +} finish_test From 1da88f025f3df80020872726071be8b0973901cb Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Dec 2011 16:09:16 +0000 Subject: [PATCH 118/161] Add support for statvfs() in os_unix.c, for determining the sector size. This causes many TCL test failures under Linux. FossilOrigin-Name: e0d44450b9bec8ea7b057c1ad0a2088cd3f1f221 --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/os_unix.c | 35 +++++++++++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index f48b9a0540..0382d0016a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sin\schanges\sthat\scause\sthe\sfirst\ssector\sof\sthe\sWAL\sfile\sto\sbe\ssynced\nwhen\sthe\sWAL\srestarts.\s\sThis\sis\sa\sfix\sfor\sthe\spower-loss\scorruption\nproblem\sdescribed\sin\sticket\s[ff5be73dee086] -D 2011-12-17T13:45:28.989 +C Add\ssupport\sfor\sstatvfs()\sin\sos_unix.c,\sfor\sdetermining\sthe\ssector\ssize.\nThis\scauses\smany\sTCL\stest\sfailures\sunder\sLinux. +D 2011-12-17T16:09:16.668 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/os.c 28bbdab2170dfce84d86c45456a18eab1d0f99a9 F src/os.h 549b1a2e5e0ed1e1499f252dac126c4973e7379c F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c 7dc7df10331942b139032328449a3723e051979e +F src/os_unix.c 987407fd031dda051cd1ce483e98cdd10c876406 F src/os_win.c 197d23ce8a0dff748e766e034bf95ff756dd3884 F src/pager.c c7c32a1c279e0bbbde3578172985c41d4c5efc35 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 @@ -984,7 +984,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P d76880428013ae2c5be00d87bb3e1695af6f706f 9799241f7de952c4d1ea8bf6508b577d2b57a370 -R a66c21780a9737a3739ef721dbd80b71 +P 44ca4d123385d759c11919865525c998c2e35bdb +R 7de59b5af451aa5e783f935f751fa23e +T *branch * statvfs +T *sym-statvfs * +T -sym-trunk * U drh -Z 8683a36598a7c916281a4627e543388f +Z 2ad2e7d7ae34e5854d882a8ab2c85c44 diff --git a/manifest.uuid b/manifest.uuid index 9c694594ad..3016870f55 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -44ca4d123385d759c11919865525c998c2e35bdb \ No newline at end of file +e0d44450b9bec8ea7b057c1ad0a2088cd3f1f221 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index ee5971f10e..9f88d24b45 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -122,6 +122,10 @@ #ifndef SQLITE_OMIT_WAL #include #endif +#ifndef MISSING_STATVFS +#include +#endif + #if SQLITE_ENABLE_LOCKING_STYLE # include @@ -217,6 +221,7 @@ struct unixFile { const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ + int szSector; /* Sector size */ #if SQLITE_ENABLE_LOCKING_STYLE int openFlags; /* The flags specified at open() */ #endif @@ -414,6 +419,14 @@ static struct unix_syscall { { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 }, #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) +#if defined(MISSING_STATVFS) + { "statvfs", (sqlite3_syscall_ptr)0, 0 }, +#define osStatvfs ((int(*)(const char*,void*))aSyscall[20].pCurrent) +#else + { "statvfs", (sqlite3_syscall_ptr)statvfs, 0 }, +#define osStatvfs ((int(*)(const char*,struct statvfs*))aSyscall[20].pCurrent) +#endif + }; /* End of the overrideable system calls */ /* @@ -3572,9 +3585,23 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ ** a database and its journal file) that the sector size will be the ** same for both. */ -static int unixSectorSize(sqlite3_file *NotUsed){ - UNUSED_PARAMETER(NotUsed); - return SQLITE_DEFAULT_SECTOR_SIZE; +static int unixSectorSize(sqlite3_file *pFile){ + unixFile *p = (unixFile*)pFile; + if( p->szSector==0 ){ +#ifdef MISSING_STATVFS + p->szSector = SQLITE_DEFAULT_SECTOR_SIZE; +#else + struct statvfs x; + int sz; + memset(&x, 0, sizeof(x)); + osStatvfs(p->zPath, &x); + p->szSector = sz = (int)x.f_frsize; + if( sz<512 || sz>65536 || (sz&(sz-1))!=0 ){ + p->szSector = SQLITE_DEFAULT_SECTOR_SIZE; + } + } +#endif + return p->szSector; } /* @@ -6777,7 +6804,7 @@ int sqlite3_os_init(void){ /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ - assert( ArraySize(aSyscall)==20 ); + assert( ArraySize(aSyscall)==21 ); /* Register all VFSes defined in the aVfs[] array */ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ From 9c0e29371e7d97ade110adbf61a250965f291390 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Dec 2011 16:25:17 +0000 Subject: [PATCH 119/161] Fix a bad #endif with the previous check-in on this branch. FossilOrigin-Name: 915713ffe4d02ddf1d09a82e39a47b88d3d95ea0 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/os_unix.c | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 0382d0016a..b54f93645f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\sstatvfs()\sin\sos_unix.c,\sfor\sdetermining\sthe\ssector\ssize.\nThis\scauses\smany\sTCL\stest\sfailures\sunder\sLinux. -D 2011-12-17T16:09:16.668 +C Fix\sa\sbad\s#endif\swith\sthe\sprevious\scheck-in\son\sthis\sbranch. +D 2011-12-17T16:25:17.970 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/os.c 28bbdab2170dfce84d86c45456a18eab1d0f99a9 F src/os.h 549b1a2e5e0ed1e1499f252dac126c4973e7379c F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c 987407fd031dda051cd1ce483e98cdd10c876406 +F src/os_unix.c a1d12b748d323cf88580ed4636526979438d2ced F src/os_win.c 197d23ce8a0dff748e766e034bf95ff756dd3884 F src/pager.c c7c32a1c279e0bbbde3578172985c41d4c5efc35 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 @@ -984,10 +984,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 44ca4d123385d759c11919865525c998c2e35bdb -R 7de59b5af451aa5e783f935f751fa23e -T *branch * statvfs -T *sym-statvfs * -T -sym-trunk * +P e0d44450b9bec8ea7b057c1ad0a2088cd3f1f221 +R b8a55204c658dabf0660ecc7d93188e9 U drh -Z 2ad2e7d7ae34e5854d882a8ab2c85c44 +Z 436c2db7515ae81b46726abca10da159 diff --git a/manifest.uuid b/manifest.uuid index 3016870f55..72300a33d9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e0d44450b9bec8ea7b057c1ad0a2088cd3f1f221 \ No newline at end of file +915713ffe4d02ddf1d09a82e39a47b88d3d95ea0 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 9f88d24b45..aa7002885c 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3599,8 +3599,8 @@ static int unixSectorSize(sqlite3_file *pFile){ if( sz<512 || sz>65536 || (sz&(sz-1))!=0 ){ p->szSector = SQLITE_DEFAULT_SECTOR_SIZE; } - } #endif + } return p->szSector; } From 8bbaa89d8d69761bf81b21d07d8eb7397ab9b6bb Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Dec 2011 19:49:02 +0000 Subject: [PATCH 120/161] Add SQLITE_IOCAP_ZERO_DAMAGE and enable it for both unix and windows. Use this device characteristic to reduce the required work in journaling. A side effect is that this changes the default page exists back to 1024 even with the use of statvfs(). FossilOrigin-Name: a0be6ea464695fdf1eaf2b7cf0652778617814f2 --- manifest | 24 ++++++++++++------------ manifest.uuid | 2 +- src/os_unix.c | 2 +- src/os_win.c | 3 ++- src/pager.c | 13 ++++++++++++- src/sqlite.h.in | 9 ++++++++- src/test6.c | 1 + src/test_vfs.c | 1 + src/wal.c | 50 ++++++++++++++++++++++++++----------------------- 9 files changed, 65 insertions(+), 40 deletions(-) diff --git a/manifest b/manifest index b54f93645f..d164fc5b9e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbad\s#endif\swith\sthe\sprevious\scheck-in\son\sthis\sbranch. -D 2011-12-17T16:25:17.970 +C Add\sSQLITE_IOCAP_ZERO_DAMAGE\sand\senable\sit\sfor\sboth\sunix\sand\swindows.\s\sUse\nthis\sdevice\scharacteristic\sto\sreduce\sthe\srequired\swork\sin\sjournaling.\nA\sside\seffect\sis\sthat\sthis\schanges\sthe\sdefault\spage\sexists\sback\sto\s1024\neven\swith\sthe\suse\sof\sstatvfs(). +D 2011-12-17T19:49:02.976 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,9 +166,9 @@ F src/os.c 28bbdab2170dfce84d86c45456a18eab1d0f99a9 F src/os.h 549b1a2e5e0ed1e1499f252dac126c4973e7379c F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c a1d12b748d323cf88580ed4636526979438d2ced -F src/os_win.c 197d23ce8a0dff748e766e034bf95ff756dd3884 -F src/pager.c c7c32a1c279e0bbbde3578172985c41d4c5efc35 +F src/os_unix.c e2b96f85eb91c962765005892014b014db3e6478 +F src/os_win.c 3cf34661f5ef47be81bb7be541582d6e14852159 +F src/pager.c 2fb503c73714eafb8bf82283c5c08e895124277b F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba F src/pcache.c 1fdd77978c1525d1ca4b9ef48eb80abca710cb4c @@ -182,7 +182,7 @@ F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c a1d075db66a0ea42807353501b62997969e5be79 F src/shell.c aa4183d4a5243d8110b1d3d77faa4aea7e9c9c2d -F src/sqlite.h.in e3e45b5c69ab3236c7ec4591a5858221863cecd4 +F src/sqlite.h.in d0e81fd4c72fbfdc786d3067e17a16a32f249428 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h 165409fa8adc8701148830804febeded3f2e4448 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -194,7 +194,7 @@ F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7 F src/test5.c e1a19845625144caf038031234a12185e40d315c -F src/test6.c 3191b4ab964a144230ff9ef96c093520375c7b2a +F src/test6.c ffcc25c9b32e08e40754d85adb0a5d289721974a F src/test7.c 2e0781754905c8adc3268d8f0967e7633af58843 F src/test8.c 99f70341d6ec480313775127f4cd14b4a47db557 F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60 @@ -230,7 +230,7 @@ F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_thread.c 35022393dd54d147b998b6b7f7e945b01114d666 -F src/test_vfs.c 27b7d9de40630f603b9e2cf9ef2a7c81d31c4515 +F src/test_vfs.c 01d5732a8dbdc3f6b75d4ec79aeb9455942243a0 F src/test_vfstrace.c 065c7270a614254b2c68fbc7ba8d1fb1d5cbc823 F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 @@ -250,7 +250,7 @@ F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a -F src/wal.c 89a60a8bf8daa805b819f97b2049a62ae5618707 +F src/wal.c dc06acfaa4f5ae90b06f6a960d0e45d1a1044843 F src/wal.h 42f8313f7aaf8913e2d1fdf7b47025c23491ea1d F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 @@ -984,7 +984,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P e0d44450b9bec8ea7b057c1ad0a2088cd3f1f221 -R b8a55204c658dabf0660ecc7d93188e9 +P 915713ffe4d02ddf1d09a82e39a47b88d3d95ea0 +R 93369b47da918caf4a8833cb9ab9735c U drh -Z 436c2db7515ae81b46726abca10da159 +Z 681bcd70ccdd44fe7553ce96599b2b2b diff --git a/manifest.uuid b/manifest.uuid index 72300a33d9..9b52eb7049 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -915713ffe4d02ddf1d09a82e39a47b88d3d95ea0 \ No newline at end of file +a0be6ea464695fdf1eaf2b7cf0652778617814f2 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index aa7002885c..a9d7de832d 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3609,7 +3609,7 @@ static int unixSectorSize(sqlite3_file *pFile){ */ static int unixDeviceCharacteristics(sqlite3_file *NotUsed){ UNUSED_PARAMETER(NotUsed); - return 0; + return SQLITE_IOCAP_ZERO_DAMAGE; } #ifndef SQLITE_OMIT_WAL diff --git a/src/os_win.c b/src/os_win.c index ab70eebbf7..5e0667d188 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -2213,7 +2213,8 @@ static int winSectorSize(sqlite3_file *id){ */ static int winDeviceCharacteristics(sqlite3_file *id){ UNUSED_PARAMETER(id); - return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN; + return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | + SQLITE_IOCAP_ZERO_DAMAGE; } #ifndef SQLITE_OMIT_WAL diff --git a/src/pager.c b/src/pager.c index 9db6ebd3f4..f90ece6448 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2515,11 +2515,22 @@ static int pager_truncate(Pager *pPager, Pgno nPage){ ** the value returned by the xSectorSize() method rounded up to 32 if ** it is less than 32, or rounded down to MAX_SECTOR_SIZE if it ** is greater than MAX_SECTOR_SIZE. +** +** If the file has the SQLITE_IOCAP_ZERO_DAMAGE property, then set the +** effective sector size to its minimum value (512). The purpose of +** pPager->sectorSize is to define the "blast radius" of bytes that +** might change if a crash occurs while writing to a single byte in +** that range. But with ZERO_DAMAGE, the blast radius is zero, so +** we minimize the sector size. For backwards compatibility of the +** rollback journal file format, we cannot reduce the effective sector +** size below 512. */ static void setSectorSize(Pager *pPager){ assert( isOpen(pPager->fd) || pPager->tempFile ); - if( !pPager->tempFile ){ + if( !pPager->tempFile + && (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_ZERO_DAMAGE)==0 + ){ /* Sector size doesn't matter for temporary files. Also, the file ** may not have been opened yet, in which case the OsSectorSize() ** call will segfault. diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 0e0e3af6b6..f7a2616baa 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -504,7 +504,13 @@ int sqlite3_exec( ** first then the size of the file is extended, never the other ** way around. The SQLITE_IOCAP_SEQUENTIAL property means that ** information is written to disk in the same order as calls -** to xWrite(). +** to xWrite(). The SQLITE_IOCAP_ZERO_DAMAGE property means that +** after reboot following a crash or power loss, the value of +** each byte in a file is a value that was actually written +** into that byte at some point. In other words, a crash will +** not introduce garbage or randomness into a file, and byte of +** a file that are never written will not change values due to +** writes to nearby bytes. */ #define SQLITE_IOCAP_ATOMIC 0x00000001 #define SQLITE_IOCAP_ATOMIC512 0x00000002 @@ -518,6 +524,7 @@ int sqlite3_exec( #define SQLITE_IOCAP_SAFE_APPEND 0x00000200 #define SQLITE_IOCAP_SEQUENTIAL 0x00000400 #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 +#define SQLITE_IOCAP_ZERO_DAMAGE 0x00001000 /* ** CAPI3REF: File Locking Levels diff --git a/src/test6.c b/src/test6.c index 23fb14c5b3..1bb9c65f05 100644 --- a/src/test6.c +++ b/src/test6.c @@ -716,6 +716,7 @@ static int processDevSymArgs( { "atomic64k", SQLITE_IOCAP_ATOMIC64K }, { "sequential", SQLITE_IOCAP_SEQUENTIAL }, { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, + { "zero_damage", SQLITE_IOCAP_ZERO_DAMAGE }, { 0, 0 } }; diff --git a/src/test_vfs.c b/src/test_vfs.c index a59aa40a48..33640c9c76 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -1174,6 +1174,7 @@ static int testvfs_obj_cmd( { "sequential", SQLITE_IOCAP_SEQUENTIAL }, { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, { "undeletable_when_open", SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN }, + { "zero_damage", SQLITE_IOCAP_ZERO_DAMAGE }, { 0, 0 } }; Tcl_Obj *pRet; diff --git a/src/wal.c b/src/wal.c index 03c482554e..a863b5b81f 100644 --- a/src/wal.c +++ b/src/wal.c @@ -425,6 +425,7 @@ struct Wal { u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ u8 truncateOnCommit; /* True to truncate WAL file on commit */ u8 noSyncHeader; /* Avoid WAL header fsyncs if true */ + u8 noPadding; /* No need to pad transactions to sector size */ WalIndexHdr hdr; /* Wal-index header for current transaction */ const char *zWalName; /* Name of WAL file */ u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ @@ -1310,6 +1311,7 @@ int sqlite3WalOpen( }else{ int iDC = sqlite3OsDeviceCharacteristics(pRet->pWalFd); if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->noSyncHeader = 1; } + if( iDC & SQLITE_IOCAP_ZERO_DAMAGE ){ pRet->noPadding = 1; } *ppWal = pRet; WALTRACE(("WAL%d: opened\n", pRet)); } @@ -2780,34 +2782,36 @@ int sqlite3WalFrames( /* Sync the log file if the 'isSync' flag was specified. */ if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){ - i64 iSegment = sqlite3OsSectorSize(pWal->pWalFd); - i64 iOffset = walFrameOffset(iFrame+1, szPage); - - assert( iSegment>0 ); - - iSegment = (((iOffset+iSegment-1)/iSegment) * iSegment); - while( iOffsetnoPadding ){ + i64 iSegment = sqlite3OsSectorSize(pWal->pWalFd); + i64 iOffset = walFrameOffset(iFrame+1, szPage); + + assert( iSegment>0 ); + + iSegment = (((iOffset+iSegment-1)/iSegment) * iSegment); + while( iOffsetpData; + pData = pLast->pData; #endif - walEncodeFrame(pWal, pLast->pgno, nTruncate, pData, aFrame); - /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ - rc = walWriteToLog(pWal, aFrame, sizeof(aFrame), iOffset); - if( rc!=SQLITE_OK ){ - return rc; + walEncodeFrame(pWal, pLast->pgno, nTruncate, pData, aFrame); + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ + rc = walWriteToLog(pWal, aFrame, sizeof(aFrame), iOffset); + if( rc!=SQLITE_OK ){ + return rc; + } + iOffset += WAL_FRAME_HDRSIZE; + rc = walWriteToLog(pWal, pData, szPage, iOffset); + if( rc!=SQLITE_OK ){ + return rc; + } + nLast++; + iOffset += szPage; } - iOffset += WAL_FRAME_HDRSIZE; - rc = walWriteToLog(pWal, pData, szPage, iOffset); - if( rc!=SQLITE_OK ){ - return rc; - } - nLast++; - iOffset += szPage; } - + rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK); } From 374f4a0447bdd75feca0d59555e374072e84fb4a Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Dec 2011 20:02:11 +0000 Subject: [PATCH 121/161] For improved clarity of presentation, refactor some of the code associated with ZERO_DAMAGE and sector-size. FossilOrigin-Name: 1dde96c9ee88af1c4e37c2e65acb7c0fe6a20e2a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pager.c | 23 ++++++++++++----------- src/wal.c | 7 ++++--- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index d164fc5b9e..34dcb99709 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sSQLITE_IOCAP_ZERO_DAMAGE\sand\senable\sit\sfor\sboth\sunix\sand\swindows.\s\sUse\nthis\sdevice\scharacteristic\sto\sreduce\sthe\srequired\swork\sin\sjournaling.\nA\sside\seffect\sis\sthat\sthis\schanges\sthe\sdefault\spage\sexists\sback\sto\s1024\neven\swith\sthe\suse\sof\sstatvfs(). -D 2011-12-17T19:49:02.976 +C For\simproved\sclarity\sof\spresentation,\s\nrefactor\ssome\sof\sthe\scode\sassociated\swith\sZERO_DAMAGE\sand\ssector-size. +D 2011-12-17T20:02:11.301 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -168,7 +168,7 @@ F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c e2b96f85eb91c962765005892014b014db3e6478 F src/os_win.c 3cf34661f5ef47be81bb7be541582d6e14852159 -F src/pager.c 2fb503c73714eafb8bf82283c5c08e895124277b +F src/pager.c c9bd2f7183edba480bea1dd49361a02d0c3d8f43 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba F src/pcache.c 1fdd77978c1525d1ca4b9ef48eb80abca710cb4c @@ -250,7 +250,7 @@ F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a -F src/wal.c dc06acfaa4f5ae90b06f6a960d0e45d1a1044843 +F src/wal.c 645fdf75d57f2a1b437241513f0ef0904233b8f2 F src/wal.h 42f8313f7aaf8913e2d1fdf7b47025c23491ea1d F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 @@ -984,7 +984,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 915713ffe4d02ddf1d09a82e39a47b88d3d95ea0 -R 93369b47da918caf4a8833cb9ab9735c +P a0be6ea464695fdf1eaf2b7cf0652778617814f2 +R a3ac9d3b46a9e1f98e50427074558d5c U drh -Z 681bcd70ccdd44fe7553ce96599b2b2b +Z c1eb985167dfc5f7ffec7a557d306f46 diff --git a/manifest.uuid b/manifest.uuid index 9b52eb7049..98a63cdd52 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a0be6ea464695fdf1eaf2b7cf0652778617814f2 \ No newline at end of file +1dde96c9ee88af1c4e37c2e65acb7c0fe6a20e2a \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index f90ece6448..ab944aa4f1 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2528,21 +2528,22 @@ static int pager_truncate(Pager *pPager, Pgno nPage){ static void setSectorSize(Pager *pPager){ assert( isOpen(pPager->fd) || pPager->tempFile ); - if( !pPager->tempFile - && (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_ZERO_DAMAGE)==0 + if( pPager->tempFile + || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_ZERO_DAMAGE)!=0 ){ /* Sector size doesn't matter for temporary files. Also, the file ** may not have been opened yet, in which case the OsSectorSize() - ** call will segfault. - */ - pPager->sectorSize = sqlite3OsSectorSize(pPager->fd); - } - if( pPager->sectorSize<32 ){ + ** call will segfault. */ pPager->sectorSize = 512; - } - if( pPager->sectorSize>MAX_SECTOR_SIZE ){ - assert( MAX_SECTOR_SIZE>=512 ); - pPager->sectorSize = MAX_SECTOR_SIZE; + }else{ + pPager->sectorSize = sqlite3OsSectorSize(pPager->fd); + if( pPager->sectorSize<32 ){ + pPager->sectorSize = 512; + } + if( pPager->sectorSize>MAX_SECTOR_SIZE ){ + assert( MAX_SECTOR_SIZE>=512 ); + pPager->sectorSize = MAX_SECTOR_SIZE; + } } } diff --git a/src/wal.c b/src/wal.c index a863b5b81f..b601d42ffb 100644 --- a/src/wal.c +++ b/src/wal.c @@ -425,7 +425,7 @@ struct Wal { u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ u8 truncateOnCommit; /* True to truncate WAL file on commit */ u8 noSyncHeader; /* Avoid WAL header fsyncs if true */ - u8 noPadding; /* No need to pad transactions to sector size */ + u8 padToSectorBoundary; /* Pad transactions out to the next sector */ WalIndexHdr hdr; /* Wal-index header for current transaction */ const char *zWalName; /* Name of WAL file */ u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ @@ -1295,6 +1295,7 @@ int sqlite3WalOpen( pRet->readLock = -1; pRet->mxWalSize = mxWalSize; pRet->zWalName = zWalName; + pRet->padToSectorBoundary = 1; pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE); /* Open file handle on the write-ahead log file. */ @@ -1311,7 +1312,7 @@ int sqlite3WalOpen( }else{ int iDC = sqlite3OsDeviceCharacteristics(pRet->pWalFd); if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->noSyncHeader = 1; } - if( iDC & SQLITE_IOCAP_ZERO_DAMAGE ){ pRet->noPadding = 1; } + if( iDC & SQLITE_IOCAP_ZERO_DAMAGE ){ pRet->padToSectorBoundary = 0; } *ppWal = pRet; WALTRACE(("WAL%d: opened\n", pRet)); } @@ -2782,7 +2783,7 @@ int sqlite3WalFrames( /* Sync the log file if the 'isSync' flag was specified. */ if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){ - if( !pWal->noPadding ){ + if( pWal->padToSectorBoundary ){ i64 iSegment = sqlite3OsSectorSize(pWal->pWalFd); i64 iOffset = walFrameOffset(iFrame+1, szPage); From 1eaaf93a83c198ad0d6fad3f625ca33f07dcc8db Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 19 Dec 2011 00:31:09 +0000 Subject: [PATCH 122/161] Some fixes to the test suite so that it works with ZERO_DAMAGE set to true. Still lots more problems remain. FossilOrigin-Name: 41891b231e20a1d32b1d7449e7863470eb38ca0a --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/test_vfs.c | 2 +- test/incrvacuum2.test | 4 ++-- test/journal2.test | 3 +-- test/pager1.test | 1 + test/syscall.test | 3 ++- test/wal.test | 20 ++++++++++---------- 8 files changed, 29 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index 34dcb99709..1f219bf3e6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\simproved\sclarity\sof\spresentation,\s\nrefactor\ssome\sof\sthe\scode\sassociated\swith\sZERO_DAMAGE\sand\ssector-size. -D 2011-12-17T20:02:11.301 +C Some\sfixes\sto\sthe\stest\ssuite\sso\sthat\sit\sworks\swith\sZERO_DAMAGE\sset\sto\strue.\nStill\slots\smore\sproblems\sremain. +D 2011-12-19T00:31:09.781 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -230,7 +230,7 @@ F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_thread.c 35022393dd54d147b998b6b7f7e945b01114d666 -F src/test_vfs.c 01d5732a8dbdc3f6b75d4ec79aeb9455942243a0 +F src/test_vfs.c b241a08b5fa5bfec22983eba323e0ca621d3cea6 F src/test_vfstrace.c 065c7270a614254b2c68fbc7ba8d1fb1d5cbc823 F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 @@ -514,7 +514,7 @@ F test/incrblob3.test aedbb35ea1b6450c33b98f2b6ed98e5020be8dc7 F test/incrblob_err.test d2562d2771ebffd4b3af89ef64c140dd44371597 F test/incrblobfault.test 917c0292224c64a56ef7215fd633a3a82f805be0 F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32 -F test/incrvacuum2.test 62fbeb85459fe4e501684d8fb5b6e98a23e3b0c0 +F test/incrvacuum2.test 379eeb8740b0ef60c372c439ad4cbea20b34bb9b F test/incrvacuum_ioerr.test 22f208d01c528403240e05beecc41dc98ed01637 F test/index.test b5429732b3b983fa810e3ac867d7ca85dae35097 F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 @@ -544,7 +544,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe F test/join6.test bf82cf3f979e9eade83ad0d056a66c5ed71d1901 F test/journal1.test 8b71ef1ed5798bdc0e6eb616d8694e2c2c188d4d -F test/journal2.test 29937bdbb253bbfd92057610120bdc0aa7e84a0a +F test/journal2.test 81f51a9f3e9b67c0efd4cdbb93752e064027ad96 F test/journal3.test 6fd28532c88b447db844186bc190523108b6dbb4 F test/jrnlmode.test 9ee3a78f53d52cca737db69293d15dc41c0cbd36 F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d @@ -619,7 +619,7 @@ F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394 F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3 -F test/pager1.test 1b630b3248c7d28862fe9e190cfe52234b502504 +F test/pager1.test 6fad92deb869a67197dd6afb8646375ecd57ca66 F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f F test/pagerfault.test 452f2cc23e3bfcfa935f4442aec1da4fe1dc0442 @@ -705,7 +705,7 @@ F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/superlock.test 7b1167925e9d30a5d1f0701d24812fdda42c3a86 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 -F test/syscall.test 2a922050dbee032f587249b070fb42692f5e1e22 +F test/syscall.test 265cda616f56a297406728ee1e74c9b4a93aa6dd F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f F test/table.test a59d985ca366e39b17b175f387f9d5db5a18d4e2 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 @@ -901,7 +901,7 @@ F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d -F test/wal.test c743be787e60c1242fa6cdf73b410e64b2977e25 +F test/wal.test 626ada15351fb27838f4a6e3047f34b1491286b1 F test/wal2.test 29e2cbe840582fc6efd0487b4f6337caed4b3e80 F test/wal3.test 29a6e8843e5f5fd13f33cb0407d2923107020d32 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c @@ -984,7 +984,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P a0be6ea464695fdf1eaf2b7cf0652778617814f2 -R a3ac9d3b46a9e1f98e50427074558d5c +P 1dde96c9ee88af1c4e37c2e65acb7c0fe6a20e2a +R 62e195e48920f4d65e051058065d4cbf U drh -Z c1eb985167dfc5f7ffec7a557d306f46 +Z 81e91113a96aa8ccbd0fc3b095654fd3 diff --git a/manifest.uuid b/manifest.uuid index 98a63cdd52..e5f49963fa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1dde96c9ee88af1c4e37c2e65acb7c0fe6a20e2a \ No newline at end of file +41891b231e20a1d32b1d7449e7863470eb38ca0a \ No newline at end of file diff --git a/src/test_vfs.c b/src/test_vfs.c index 33640c9c76..2c985a7db7 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -1208,7 +1208,7 @@ static int testvfs_obj_cmd( iNew |= aFlag[idx].iValue; } - p->iDevchar = iNew; + p->iDevchar = iNew| 0x10000000; } pRet = Tcl_NewObj(); diff --git a/test/incrvacuum2.test b/test/incrvacuum2.test index e67a086298..6e8e1bed5e 100644 --- a/test/incrvacuum2.test +++ b/test/incrvacuum2.test @@ -191,7 +191,7 @@ ifcapable wal { PRAGMA wal_checkpoint; } file size test.db-wal - } {1640} + } [expr {32+2*(512+24)}] do_test 4.3 { db close @@ -205,7 +205,7 @@ ifcapable wal { if {$newsz>$maxsz} {set maxsz $newsz} } set maxsz - } {2176} + } [expr {32+3*(512+24)}] } finish_test diff --git a/test/journal2.test b/test/journal2.test index 25ce941696..2272f139f4 100644 --- a/test/journal2.test +++ b/test/journal2.test @@ -34,7 +34,7 @@ proc a_string {n} { # characteristics flags to "SAFE_DELETE". # testvfs tvfs -default 1 -tvfs devchar undeletable_when_open +tvfs devchar {undeletable_when_open zero_damage} # Set up a hook so that each time a journal file is opened, closed or # deleted, the method name ("xOpen", "xClose" or "xDelete") and the final @@ -231,4 +231,3 @@ ifcapable wal { tvfs delete finish_test - diff --git a/test/pager1.test b/test/pager1.test index 0226fe49b2..3228d0a7e6 100644 --- a/test/pager1.test +++ b/test/pager1.test @@ -1312,6 +1312,7 @@ foreach sectorsize { 4096 8192 16384 32768 65536 131072 262144 } { tv sectorsize $sectorsize + tv devchar {} set eff $sectorsize if {$sectorsize < 512} { set eff 512 } if {$sectorsize > 65536} { set eff 65536 } diff --git a/test/syscall.test b/test/syscall.test index b67bead7da..dde4b467a2 100644 --- a/test/syscall.test +++ b/test/syscall.test @@ -59,7 +59,8 @@ do_test 2.1.2 { test_syscall exists nosuchcall } 0 foreach s { open close access getcwd stat fstat ftruncate fcntl read pread write pwrite fchmod fallocate - pread64 pwrite64 unlink openDirectory mkdir rmdir + pread64 pwrite64 unlink openDirectory mkdir rmdir + statvfs } { if {[test_syscall exists $s]} {lappend syscall_list $s} } diff --git a/test/wal.test b/test/wal.test index 1c63ddc00f..743e3a03ec 100644 --- a/test/wal.test +++ b/test/wal.test @@ -546,7 +546,7 @@ do_multiclient_test tn { } {1 2 3 4 5 6 7 8 9 10} do_test wal-10.$tn.12 { catchsql { PRAGMA wal_checkpoint } - } {0 {0 13 13}} ;# Reader no longer block checkpoints + } {0 {0 7 7}} ;# Reader no longer block checkpoints do_test wal-10.$tn.13 { execsql { INSERT INTO t1 VALUES(11, 12) } sql2 {SELECT * FROM t1} @@ -556,7 +556,7 @@ do_multiclient_test tn { # do_test wal-10.$tn.14 { catchsql { PRAGMA wal_checkpoint } - } {0 {0 15 13}} + } {0 {0 8 7}} # The following series of test cases used to verify another blocking # case in WAL - a case which no longer blocks. @@ -566,10 +566,10 @@ do_multiclient_test tn { } {1 2 3 4 5 6 7 8 9 10 11 12} do_test wal-10.$tn.16 { catchsql { PRAGMA wal_checkpoint } - } {0 {0 15 15}} + } {0 {0 8 8}} do_test wal-10.$tn.17 { execsql { PRAGMA wal_checkpoint } - } {0 15 15} + } {0 8 8} do_test wal-10.$tn.18 { sql3 { BEGIN; SELECT * FROM t1 } } {1 2 3 4 5 6 7 8 9 10 11 12} @@ -592,13 +592,13 @@ do_multiclient_test tn { # do_test wal-10.$tn.23 { execsql { PRAGMA wal_checkpoint } - } {0 17 17} + } {0 9 9} do_test wal-10.$tn.24 { sql2 { BEGIN; SELECT * FROM t1; } } {1 2 3 4 5 6 7 8 9 10 11 12 13 14} do_test wal-10.$tn.25 { execsql { PRAGMA wal_checkpoint } - } {0 17 17} + } {0 9 9} do_test wal-10.$tn.26 { catchsql { INSERT INTO t1 VALUES(15, 16) } } {0 {}} @@ -615,11 +615,11 @@ do_multiclient_test tn { do_test wal-10.$tn.29 { execsql { INSERT INTO t1 VALUES(19, 20) } catchsql { PRAGMA wal_checkpoint } - } {0 {0 6 0}} + } {0 {0 3 0}} do_test wal-10.$tn.30 { code3 { sqlite3_finalize $::STMT } execsql { PRAGMA wal_checkpoint } - } {0 6 0} + } {0 3 0} # At one point, if a reader failed to upgrade to a writer because it # was reading an old snapshot, the write-locks were not being released. @@ -658,7 +658,7 @@ do_multiclient_test tn { } {a b c d} do_test wal-10.$tn.36 { catchsql { PRAGMA wal_checkpoint } - } {0 {0 16 16}} + } {0 {0 8 8}} do_test wal-10.$tn.36 { sql3 { INSERT INTO t1 VALUES('e', 'f') } sql2 { SELECT * FROM t1 } @@ -666,7 +666,7 @@ do_multiclient_test tn { do_test wal-10.$tn.37 { sql2 COMMIT execsql { PRAGMA wal_checkpoint } - } {0 18 18} + } {0 9 9} } #------------------------------------------------------------------------- From 0774bb59c6beb2bd1fa388cae70a6da7bbd29390 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 19 Dec 2011 10:07:56 +0000 Subject: [PATCH 123/161] Modify test cases to account for the ZERO_DAMAGE change. FossilOrigin-Name: 68684495f1a62a41ad27934f3a6d3bc9d290a57d --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- test/superlock.test | 5 ++++- test/wal.test | 15 ++++++++++----- test/wal2.test | 13 +++++++++---- test/wal3.test | 10 +++++----- test/wal5.test | 40 ++++++++++++++++++++-------------------- 7 files changed, 60 insertions(+), 47 deletions(-) diff --git a/manifest b/manifest index 1f219bf3e6..16cd60ec35 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Some\sfixes\sto\sthe\stest\ssuite\sso\sthat\sit\sworks\swith\sZERO_DAMAGE\sset\sto\strue.\nStill\slots\smore\sproblems\sremain. -D 2011-12-19T00:31:09.781 +C Modify\stest\scases\sto\saccount\sfor\sthe\sZERO_DAMAGE\schange. +D 2011-12-19T10:07:56.428 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -703,7 +703,7 @@ F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796 F test/subquery2.test edcad5c118f0531c2e21bf16a09bbb105252d4cd F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a -F test/superlock.test 7b1167925e9d30a5d1f0701d24812fdda42c3a86 +F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/syscall.test 265cda616f56a297406728ee1e74c9b4a93aa6dd F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f @@ -901,11 +901,11 @@ F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d -F test/wal.test 626ada15351fb27838f4a6e3047f34b1491286b1 -F test/wal2.test 29e2cbe840582fc6efd0487b4f6337caed4b3e80 -F test/wal3.test 29a6e8843e5f5fd13f33cb0407d2923107020d32 +F test/wal.test edefe316b4125d7f68004ea53c5e73c398d436cc +F test/wal2.test f11883dd3cb7f647c5d2acfd7b5c6d4ba5770cc9 +F test/wal3.test 0f9bb79aa5712e9fa2343d1cdc9e2785adddcfc2 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c -F test/wal5.test 1bbfaa316dc2a1d0d1fac3f4500c38a90055a41b +F test/wal5.test f58ed4b8b542f71c7441da12fbd769d99b362437 F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3 F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe @@ -984,7 +984,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 1dde96c9ee88af1c4e37c2e65acb7c0fe6a20e2a -R 62e195e48920f4d65e051058065d4cbf -U drh -Z 81e91113a96aa8ccbd0fc3b095654fd3 +P 41891b231e20a1d32b1d7449e7863470eb38ca0a +R b6f691c6a328a432146fee6719bfa23f +U dan +Z d70b0c6ac6bdf4b36159c16417e96ac5 diff --git a/manifest.uuid b/manifest.uuid index e5f49963fa..2c217c71b4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -41891b231e20a1d32b1d7449e7863470eb38ca0a \ No newline at end of file +68684495f1a62a41ad27934f3a6d3bc9d290a57d \ No newline at end of file diff --git a/test/superlock.test b/test/superlock.test index 8155d929ce..8199d5218d 100644 --- a/test/superlock.test +++ b/test/superlock.test @@ -76,7 +76,10 @@ do_catchsql_test 3.4 { INSERT INTO t1 VALUES(5, 6)} {1 {database is locked}} do_catchsql_test 3.5 { PRAGMA wal_checkpoint } {0 {1 -1 -1}} do_test 3.6 { unlock } {} -do_execsql_test 4.1 { PRAGMA wal_checkpoint } {0 2 2} +# At this point the WAL file consists of a single frame only - written +# by test case 3.1. If the ZERO_DAMAGE flag were not set, it would consist +# of two frames - the frame written by 3.1 and a padding frame. +do_execsql_test 4.1 { PRAGMA wal_checkpoint } {0 1 1} do_test 4.2 { sqlite3demo_superlock unlock test.db } {unlock} do_catchsql_test 4.3 { SELECT * FROM t1 } {1 {database is locked}} diff --git a/test/wal.test b/test/wal.test index 743e3a03ec..3b63d3e792 100644 --- a/test/wal.test +++ b/test/wal.test @@ -1040,7 +1040,7 @@ foreach {tn ckpt_cmd ckpt_res ckpt_main ckpt_aux} { 5 {sqlite3_wal_checkpoint db aux} SQLITE_OK 0 1 6 {sqlite3_wal_checkpoint db temp} SQLITE_OK 0 0 7 {db eval "PRAGMA main.wal_checkpoint"} {0 10 10} 1 0 - 8 {db eval "PRAGMA aux.wal_checkpoint"} {0 16 16} 0 1 + 8 {db eval "PRAGMA aux.wal_checkpoint"} {0 13 13} 0 1 9 {db eval "PRAGMA temp.wal_checkpoint"} {0 -1 -1} 0 0 } { do_test wal-16.$tn.1 { @@ -1054,7 +1054,8 @@ foreach {tn ckpt_cmd ckpt_res ckpt_main ckpt_aux} { PRAGMA aux.auto_vacuum = 0; PRAGMA main.journal_mode = WAL; PRAGMA aux.journal_mode = WAL; - PRAGMA synchronous = NORMAL; + PRAGMA main.synchronous = NORMAL; + PRAGMA aux.synchronous = NORMAL; } } {wal wal} @@ -1072,7 +1073,7 @@ foreach {tn ckpt_cmd ckpt_res ckpt_main ckpt_aux} { } [list [expr 1*1024] [wal_file_size 10 1024]] do_test wal-16.$tn.3 { list [file size test2.db] [file size test2.db-wal] - } [list [expr 1*1024] [wal_file_size 16 1024]] + } [list [expr 1*1024] [wal_file_size 13 1024]] do_test wal-16.$tn.4 [list eval $ckpt_cmd] $ckpt_res @@ -1082,7 +1083,7 @@ foreach {tn ckpt_cmd ckpt_res ckpt_main ckpt_aux} { do_test wal-16.$tn.6 { list [file size test2.db] [file size test2.db-wal] - } [list [expr ($ckpt_aux ? 7 : 1)*1024] [wal_file_size 16 1024]] + } [list [expr ($ckpt_aux ? 7 : 1)*1024] [wal_file_size 13 1024]] catch { db close } } @@ -1552,9 +1553,13 @@ ifcapable autovacuum { } file size test.db } [expr 3 * 1024] + + # WAL file now contains a single frame - the new root page for table t1. + # It would be two frames (the new root page and a padding frame) if the + # ZERO_DAMAGE flag were not set. do_test 24.5 { file size test.db-wal - } 2128 + } [wal_file_size 1 1024] } db close diff --git a/test/wal2.test b/test/wal2.test index 90ea9defed..c7f00ea60f 100644 --- a/test/wal2.test +++ b/test/wal2.test @@ -361,7 +361,9 @@ do_test wal2-4.1 { INSERT INTO data VALUES('need xShmOpen to see this'); PRAGMA wal_checkpoint; } -} {wal 0 5 5} + # Three pages in the WAL file at this point: One copy of page 1 and two + # of the root page for table "data". +} {wal 0 3 3} do_test wal2-4.2 { db close testvfs tvfs -noshm 1 @@ -730,7 +732,7 @@ do_test wal2-6.5.1 { INSERT INTO t2 VALUES('I', 'II'); PRAGMA journal_mode; } -} {wal exclusive 0 3 3 wal} +} {wal exclusive 0 2 2 wal} do_test wal2-6.5.2 { execsql { PRAGMA locking_mode = normal; @@ -741,7 +743,7 @@ do_test wal2-6.5.2 { } {normal exclusive I II III IV} do_test wal2-6.5.3 { execsql { PRAGMA wal_checkpoint } -} {0 4 4} +} {0 2 2} db close proc lock_control {method filename handle spec} { @@ -1184,6 +1186,7 @@ foreach {tn sql reslist} { execsql {PRAGMA auto_vacuum = 0} execsql $sql + do_execsql_test wal2-14.$tn.0 { PRAGMA page_size = 4096 } {} do_execsql_test wal2-14.$tn.1 { PRAGMA journal_mode = WAL } {wal} set sqlite_sync_count 0 @@ -1199,7 +1202,7 @@ foreach {tn sql reslist} { INSERT INTO t1 VALUES(5, 6); COMMIT; -- 2 wal sync PRAGMA wal_checkpoint; -- 1 wal sync, 1 db sync - } {10 0 5 5 0 2 2} + } {10 0 3 3 0 1 1} do_test wal2-14.$tn.3 { cond_incr_sync_count 1 @@ -1261,6 +1264,7 @@ foreach {tn settings restart_sync commit_sync ckpt_sync} { sqlite3 db test.db do_execsql_test 15.$tn.1 " + PRAGMA page_size = 4096; CREATE TABLE t1(x); PRAGMA wal_autocheckpoint = OFF; PRAGMA journal_mode = WAL; @@ -1269,6 +1273,7 @@ foreach {tn settings restart_sync commit_sync ckpt_sync} { PRAGMA synchronous = [lindex $settings 2]; " {0 wal} +if { $tn==2} breakpoint do_test 15.$tn.2 { set sync(normal) 0 set sync(full) 0 diff --git a/test/wal3.test b/test/wal3.test index 82f7d72a97..839effedb4 100644 --- a/test/wal3.test +++ b/test/wal3.test @@ -198,9 +198,9 @@ foreach {tn syncmode synccount} { 1 off {} 2 normal - {test.db-wal normal test.db normal} + {test.db-wal normal test.db-wal normal test.db normal} 3 full - {test.db-wal normal test.db-wal normal test.db-wal normal test.db normal} + {test.db-wal normal test.db-wal normal test.db-wal normal test.db-wal normal test.db normal} } { proc sync_counter {args} { @@ -429,7 +429,7 @@ do_test wal3-6.1.2 { } {o t t f} do_test wal3-6.1.3 { execsql { PRAGMA wal_checkpoint } db2 -} {0 7 7} +} {0 4 4} # At this point the log file has been fully checkpointed. However, # connection [db3] holds a lock that prevents the log from being wrapped. @@ -518,7 +518,7 @@ proc lock_callback {method file handle spec} { } do_test wal3-6.2.2 { execsql { PRAGMA wal_checkpoint } -} {0 7 7} +} {0 4 4} do_test wal3-6.2.3 { set ::R } {h h l b} @@ -628,7 +628,7 @@ do_test wal3-8.1 { INSERT INTO b VALUES('Markazi'); PRAGMA wal_checkpoint; } -} {wal 0 9 9} +} {wal 0 5 5} do_test wal3-8.2 { execsql { SELECT * FROM b } } {Tehran Qom Markazi} diff --git a/test/wal5.test b/test/wal5.test index ad6bcfc7d8..6eceed5e59 100644 --- a/test/wal5.test +++ b/test/wal5.test @@ -197,9 +197,9 @@ foreach {testprefix do_wal_checkpoint} { INSERT INTO t2 VALUES(1, 2); } } {} - do_test 2.2.$tn.2 { file_page_counts } {1 5 1 5} - do_test 2.1.$tn.3 { code1 { do_wal_checkpoint db } } {0 5 5} - do_test 2.1.$tn.4 { file_page_counts } {2 5 2 5} + do_test 2.2.$tn.2 { file_page_counts } {1 3 1 3} + do_test 2.1.$tn.3 { code1 { do_wal_checkpoint db } } {0 3 3} + do_test 2.1.$tn.4 { file_page_counts } {2 3 2 3} } do_multiclient_test tn { @@ -213,10 +213,10 @@ foreach {testprefix do_wal_checkpoint} { INSERT INTO t2 VALUES(3, 4); } } {} - do_test 2.2.$tn.2 { file_page_counts } {1 5 1 7} + do_test 2.2.$tn.2 { file_page_counts } {1 3 1 4} do_test 2.2.$tn.3 { sql2 { BEGIN; SELECT * FROM t1 } } {1 2} - do_test 2.2.$tn.4 { code1 { do_wal_checkpoint db -mode restart } } {1 5 5} - do_test 2.2.$tn.5 { file_page_counts } {2 5 2 7} + do_test 2.2.$tn.4 { code1 { do_wal_checkpoint db -mode restart } } {1 3 3} + do_test 2.2.$tn.5 { file_page_counts } {2 3 2 4} } do_multiclient_test tn { @@ -229,13 +229,13 @@ foreach {testprefix do_wal_checkpoint} { INSERT INTO t2 VALUES(1, 2); } } {} - do_test 2.3.$tn.2 { file_page_counts } {1 5 1 5} + do_test 2.3.$tn.2 { file_page_counts } {1 3 1 3} do_test 2.3.$tn.3 { sql2 { BEGIN; SELECT * FROM t1 } } {1 2} do_test 2.3.$tn.4 { sql1 { INSERT INTO t1 VALUES(3, 4) } } {} do_test 2.3.$tn.5 { sql1 { INSERT INTO t2 VALUES(3, 4) } } {} - do_test 2.3.$tn.6 { file_page_counts } {1 7 1 7} - do_test 2.3.$tn.7 { code1 { do_wal_checkpoint db -mode full } } {1 7 5} - do_test 2.3.$tn.8 { file_page_counts } {1 7 2 7} + do_test 2.3.$tn.6 { file_page_counts } {1 4 1 4} + do_test 2.3.$tn.7 { code1 { do_wal_checkpoint db -mode full } } {1 4 3} + do_test 2.3.$tn.8 { file_page_counts } {1 4 2 4} } # Check that checkpoints block on the correct locks. And respond correctly @@ -256,18 +256,18 @@ foreach {testprefix do_wal_checkpoint} { # processes holding all three types of locks. # foreach {tn1 checkpoint busy_on ckpt_expected expected} { - 1 PASSIVE - {0 5 5} - - 2 TYPO - {0 5 5} - + 1 PASSIVE - {0 3 3} - + 2 TYPO - {0 3 3} - - 3 FULL - {0 7 7} 2 - 4 FULL 1 {1 5 5} 1 - 5 FULL 2 {1 7 5} 2 - 6 FULL 3 {0 7 7} 2 + 3 FULL - {0 4 4} 2 + 4 FULL 1 {1 3 3} 1 + 5 FULL 2 {1 4 3} 2 + 6 FULL 3 {0 4 4} 2 - 7 RESTART - {0 7 7} 3 - 8 RESTART 1 {1 5 5} 1 - 9 RESTART 2 {1 7 5} 2 - 10 RESTART 3 {1 7 7} 3 + 7 RESTART - {0 4 4} 3 + 8 RESTART 1 {1 3 3} 1 + 9 RESTART 2 {1 4 3} 2 + 10 RESTART 3 {1 4 4} 3 } { do_multiclient_test tn { From 7f9026dd942d06903427fbfbece68a743e9a2c74 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 19 Dec 2011 11:16:39 +0000 Subject: [PATCH 124/161] Fix a couple of test cases to account for the master-journal name related change in [cf3bccc2]. FossilOrigin-Name: 21b76af6edd48f665cdd3af5f99d477f030c7668 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/pager1.test | 27 +++++++++++++++++++++++---- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index f48b9a0540..4c700358b7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sin\schanges\sthat\scause\sthe\sfirst\ssector\sof\sthe\sWAL\sfile\sto\sbe\ssynced\nwhen\sthe\sWAL\srestarts.\s\sThis\sis\sa\sfix\sfor\sthe\spower-loss\scorruption\nproblem\sdescribed\sin\sticket\s[ff5be73dee086] -D 2011-12-17T13:45:28.989 +C Fix\sa\scouple\sof\stest\scases\sto\saccount\sfor\sthe\smaster-journal\sname\srelated\schange\sin\s[cf3bccc2]. +D 2011-12-19T11:16:39.956 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -619,7 +619,7 @@ F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394 F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3 -F test/pager1.test 1b630b3248c7d28862fe9e190cfe52234b502504 +F test/pager1.test b936e80553652002fc47d89bfde7018801d8257d F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f F test/pagerfault.test 452f2cc23e3bfcfa935f4442aec1da4fe1dc0442 @@ -984,7 +984,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P d76880428013ae2c5be00d87bb3e1695af6f706f 9799241f7de952c4d1ea8bf6508b577d2b57a370 -R a66c21780a9737a3739ef721dbd80b71 -U drh -Z 8683a36598a7c916281a4627e543388f +P 44ca4d123385d759c11919865525c998c2e35bdb +R 84fa60a337903d6e9b8a452659d1b330 +U dan +Z ebf66ca7938806efd839391c15a281c8 diff --git a/manifest.uuid b/manifest.uuid index 9c694594ad..9aef15622c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -44ca4d123385d759c11919865525c998c2e35bdb \ No newline at end of file +21b76af6edd48f665cdd3af5f99d477f030c7668 \ No newline at end of file diff --git a/test/pager1.test b/test/pager1.test index 0226fe49b2..7bf8643d1a 100644 --- a/test/pager1.test +++ b/test/pager1.test @@ -990,8 +990,19 @@ do_test pager1-5.4.1 { INSERT INTO t2 VALUES(85, 'Gorbachev'); COMMIT; } - set ::max_journal -} [expr 2615+[string length [pwd]]] + + # The size of the journal file is now: + # + # 1) 512 byte header + + # 2) 2 * (1024+8) byte records + + # 3) 20+N bytes of master-journal pointer, where N is the size of + # the master-journal name encoded as utf-8 with no nul term. + # + set mj_pointer [expr { + 20 + [string length [pwd]] + [string length "/test.db-mjXXXXXX9XX"] + }] + expr {$::max_journal==(512+2*(1024+8)+$mj_pointer)} +} 1 do_test pager1-5.4.2 { set ::max_journal 0 execsql { @@ -1001,8 +1012,16 @@ do_test pager1-5.4.2 { DELETE FROM t2 WHERE b = 'Lenin'; COMMIT; } - set ::max_journal -} [expr 3111+[string length [pwd]]] + + # In synchronous=full mode, the master-journal pointer is not written + # directly after the last record in the journal file. Instead, it is + # written starting at the next (in this case 512 byte) sector boundary. + # + set mj_pointer [expr { + 20 + [string length [pwd]] + [string length "/test.db-mjXXXXXX9XX"] + }] + expr {$::max_journal==(((512+2*(1024+8)+511)/512)*512 + $mj_pointer)} +} 1 db close tv delete From 19969d96ce107f6e9bbbd8af83288f151299b517 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 19 Dec 2011 15:46:51 +0000 Subject: [PATCH 125/161] Add test for WAL mode to unixexcl.test. FossilOrigin-Name: 4d518bd4801c31bb1e4fb0329ad057e549035237 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/unixexcl.test | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 4c700358b7..d896acd364 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scouple\sof\stest\scases\sto\saccount\sfor\sthe\smaster-journal\sname\srelated\schange\sin\s[cf3bccc2]. -D 2011-12-19T11:16:39.956 +C Add\stest\sfor\sWAL\smode\sto\sunixexcl.test. +D 2011-12-19T15:46:51.583 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -871,7 +871,7 @@ F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 3555aacf8ed8dc883356e59efc314707e6247a84 F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a F test/unique.test 083c7fff74695bcc27a71d75699deba3595bc9c2 -F test/unixexcl.test 9d80a54d86d2261f660758928959368ffc36151e +F test/unixexcl.test 892937c53d0c16e76631674e38a0fce052ae5e9c F test/unordered.test f53095cee37851bf30130fa1bf299a8845e837bb F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172 F test/uri.test 0d289d32396bdbc491e9dc845f1a52e13f861e0b @@ -984,7 +984,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 44ca4d123385d759c11919865525c998c2e35bdb -R 84fa60a337903d6e9b8a452659d1b330 +P 21b76af6edd48f665cdd3af5f99d477f030c7668 +R e3e501a911a193a6cca08b5fc467fda0 U dan -Z ebf66ca7938806efd839391c15a281c8 +Z 8da8eb99ffcc8591296a31b08a15f7c3 diff --git a/manifest.uuid b/manifest.uuid index 9aef15622c..a8926d69a1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -21b76af6edd48f665cdd3af5f99d477f030c7668 \ No newline at end of file +4d518bd4801c31bb1e4fb0329ad057e549035237 \ No newline at end of file diff --git a/test/unixexcl.test b/test/unixexcl.test index 057ae0af14..207078acde 100644 --- a/test/unixexcl.test +++ b/test/unixexcl.test @@ -80,4 +80,48 @@ do_multiclient_test tn { } {0 {hello world}} } +do_multiclient_test tn { + do_test unixexcl-3.$tn.1 { + code1 { db close; sqlite3 db test.db -vfs unix-excl } + code2 { db2 close; sqlite3 db2 test.db -vfs unix-excl } + sql1 { + PRAGMA journal_mode = WAL; + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); + } + } {wal} + + if {$tn==1} { + do_test unixexcl-3.$tn.1.multiproc { + csql2 { SELECT * FROM t1; } + } {1 {database is locked}} + } else { + do_test unixexcl-3.$tn.1.singleproc { + sql2 { SELECT * FROM t1; } + } {1 2} + + do_test unixexcl-3.$tn.2 { + sql2 { + BEGIN; + SELECT * FROM t1; + } + } {1 2} + do_test unixexcl-3.$tn.3 { + sql1 { PRAGMA wal_checkpoint; INSERT INTO t1 VALUES(3, 4); } + } {0 5 5} + do_test unixexcl-3.$tn.4 { + sql2 { SELECT * FROM t1; } + } {1 2} + do_test unixexcl-3.$tn.5 { + sql1 { SELECT * FROM t1; } + } {1 2 3 4} + do_test unixexcl-3.$tn.6 { + sql2 { COMMIT; SELECT * FROM t1; } + } {1 2 3 4} + do_test unixexcl-3.$tn.7 { + sql1 { PRAGMA wal_checkpoint; } + } {0 7 7} + } +} + finish_test From 4120994fdf0b646fda4768b68dda16f0799fd0ff Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 20 Dec 2011 13:13:09 +0000 Subject: [PATCH 126/161] Assert that the isCommit parameter to sqlite3WalFrames() is zero if and only if the nTruncate parameter is zero. FossilOrigin-Name: 979daf92e09305665d943e197b93b81139197c5b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wal.c | 4 ++++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d896acd364..e6573ae9e2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\sfor\sWAL\smode\sto\sunixexcl.test. -D 2011-12-19T15:46:51.583 +C Assert\sthat\sthe\sisCommit\sparameter\sto\ssqlite3WalFrames()\sis\szero\sif\sand\nonly\sif\sthe\snTruncate\sparameter\sis\szero. +D 2011-12-20T13:13:09.326 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -250,7 +250,7 @@ F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a -F src/wal.c 89a60a8bf8daa805b819f97b2049a62ae5618707 +F src/wal.c 5525f049dffd47ee860bf4ffbb8da4ebef78637d F src/wal.h 42f8313f7aaf8913e2d1fdf7b47025c23491ea1d F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 @@ -984,7 +984,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 21b76af6edd48f665cdd3af5f99d477f030c7668 -R e3e501a911a193a6cca08b5fc467fda0 -U dan -Z 8da8eb99ffcc8591296a31b08a15f7c3 +P 4d518bd4801c31bb1e4fb0329ad057e549035237 +R b6fa212f141f93e02b36860230812df1 +U drh +Z ec529eca7ddb3f43acff46ddca1c2443 diff --git a/manifest.uuid b/manifest.uuid index a8926d69a1..6ec54257b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4d518bd4801c31bb1e4fb0329ad057e549035237 \ No newline at end of file +979daf92e09305665d943e197b93b81139197c5b \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 03c482554e..fa44b66d32 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2691,6 +2691,10 @@ int sqlite3WalFrames( assert( pList ); assert( pWal->writeLock ); + /* If this frame set completes a transaction, then nTruncate>0. If + ** nTruncate==0 then this frame set does not complete the transaction. */ + assert( (isCommit!=0)==(nTruncate!=0) ); + #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){} WALTRACE(("WAL%p: frame write begin. %d frames. mxFrame=%d. %s\n", From d992b150c79b4b87419587aac218a40df879c963 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 20 Dec 2011 20:13:25 +0000 Subject: [PATCH 127/161] Refactor the sqlite3WalFrames() routine for clarity of presentation. Do the padded transaction sync as the write pointer crosses the final sector boundary instead of at the end, for efficiency. Always sync the WAL header immediately after it is written. FossilOrigin-Name: 92c73b421b6242b09247dfb759777a531a107523 --- manifest | 14 ++-- manifest.uuid | 2 +- src/wal.c | 215 ++++++++++++++++++++++++++++---------------------- 3 files changed, 129 insertions(+), 102 deletions(-) diff --git a/manifest b/manifest index 54fa8d4f5e..5a218072ca 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\s[21b76af6ed]\sinto\sstatvfs\sbranch. -D 2011-12-19T11:57:41.110 +C Refactor\sthe\ssqlite3WalFrames()\sroutine\sfor\sclarity\sof\spresentation.\nDo\sthe\spadded\stransaction\ssync\sas\sthe\swrite\spointer\scrosses\sthe\sfinal\nsector\sboundary\sinstead\sof\sat\sthe\send,\sfor\sefficiency.\s\sAlways\ssync\nthe\sWAL\sheader\simmediately\safter\sit\sis\swritten. +D 2011-12-20T20:13:25.386 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -250,7 +250,7 @@ F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a -F src/wal.c 645fdf75d57f2a1b437241513f0ef0904233b8f2 +F src/wal.c 311c36af11a721f8601371c1a5a9b15c84ec2dee F src/wal.h 42f8313f7aaf8913e2d1fdf7b47025c23491ea1d F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 @@ -984,7 +984,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 68684495f1a62a41ad27934f3a6d3bc9d290a57d 21b76af6edd48f665cdd3af5f99d477f030c7668 -R 13c6e9f68f2269f9e8e46485261d751c -U dan -Z 3609ee926071d362fe7af243818ae9ac +P e694f7b166144a0afba7846e1e18ad568b33a081 +R 5ba56fa16752a6d0272db759071cab34 +U drh +Z ae8908dc690fbf93e21d9e8cf0a20f23 diff --git a/manifest.uuid b/manifest.uuid index 84c4125952..f885437af4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e694f7b166144a0afba7846e1e18ad568b33a081 \ No newline at end of file +92c73b421b6242b09247dfb759777a531a107523 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index b601d42ffb..d61bfc069f 100644 --- a/src/wal.c +++ b/src/wal.c @@ -424,7 +424,7 @@ struct Wal { u8 ckptLock; /* True if holding a checkpoint lock */ u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ u8 truncateOnCommit; /* True to truncate WAL file on commit */ - u8 noSyncHeader; /* Avoid WAL header fsyncs if true */ + u8 syncHeader; /* Fsync the WAL header if true */ u8 padToSectorBoundary; /* Pad transactions out to the next sector */ WalIndexHdr hdr; /* Wal-index header for current transaction */ const char *zWalName; /* Name of WAL file */ @@ -1295,6 +1295,7 @@ int sqlite3WalOpen( pRet->readLock = -1; pRet->mxWalSize = mxWalSize; pRet->zWalName = zWalName; + pRet->syncHeader = 1; pRet->padToSectorBoundary = 1; pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE); @@ -1311,7 +1312,7 @@ int sqlite3WalOpen( sqlite3_free(pRet); }else{ int iDC = sqlite3OsDeviceCharacteristics(pRet->pWalFd); - if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->noSyncHeader = 1; } + if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; } if( iDC & SQLITE_IOCAP_ZERO_DAMAGE ){ pRet->padToSectorBoundary = 0; } *ppWal = pRet; WALTRACE(("WAL%d: opened\n", pRet)); @@ -2634,41 +2635,71 @@ static int walRestartLog(Wal *pWal){ return rc; } +/* +** Information about the current state of the WAL file and where +** the next fsync should occur - passed from sqlite3WalFrames() into +** walWriteToLog(). +*/ +typedef struct WalWriter { + Wal *pWal; /* The complete WAL information */ + sqlite3_file *pFd; /* The WAL file to which we write */ + sqlite3_int64 iSyncPoint; /* Fsync at this offset */ + int syncFlags; /* Flags for the fsync */ + int szPage; /* Size of one page */ +} WalWriter; + /* ** Write iAmt bytes of content into the WAL file beginning at iOffset. +** Do a sync when crossing the p->iSyncPoint boundary. ** -** When crossing the boundary between the first and second sectors of the -** file, first write all of the first sector content, then fsync(), then -** continue writing content for the second sector. This ensures that -** the WAL header is overwritten before the first commit mark. +** In other words, if iSyncPoint is in between iOffset and iOffset+iAmt, +** first write the part before iSyncPoint, then sync, then write the +** rest. */ static int walWriteToLog( - Wal *pWal, /* WAL to write to */ + WalWriter *p, /* WAL to write to */ void *pContent, /* Content to be written */ int iAmt, /* Number of bytes to write */ sqlite3_int64 iOffset /* Start writing at this offset */ ){ int rc; - if( iOffset>=pWal->szFirstBlock - || iOffset+iAmtszFirstBlock - || pWal->syncFlags==0 - ){ - /* The common and fast case. Just write the data. */ - rc = sqlite3OsWrite(pWal->pWalFd, pContent, iAmt, iOffset); - }else{ - /* If this write will cross the first sector boundary, it has to - ** be split it two with a sync in between. */ - int iFirstAmt = pWal->szFirstBlock - iOffset; - assert( iFirstAmt>0 && iFirstAmtpWalFd, pContent, iFirstAmt, iOffset); - if( rc ) return rc; - assert( pWal->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) ); - rc = sqlite3OsSync(pWal->pWalFd, pWal->syncFlags); + if( iOffsetiSyncPoint && iOffset+iAmt>=p->iSyncPoint ){ + int iFirstAmt = (int)(p->iSyncPoint - iOffset); + rc = sqlite3OsWrite(p->pFd, pContent, iFirstAmt, iOffset); if( rc ) return rc; + iOffset += iFirstAmt; + iAmt -= iFirstAmt; pContent = (void*)(iFirstAmt + (char*)pContent); - rc = sqlite3OsWrite(pWal->pWalFd, pContent, - iAmt-iFirstAmt, iOffset+iFirstAmt); + assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) ); + rc = sqlite3OsSync(p->pFd, p->syncFlags); + if( rc ) return rc; } + rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset); + return rc; +} + +/* +** Write out a single frame of the WAL +*/ +static int walWriteOneFrame( + WalWriter *p, /* Where to write the frame */ + PgHdr *pPage, /* The page of the frame to be written */ + int nTruncate, /* The commit flag. Usually 0. >0 for commit */ + sqlite3_int64 iOffset /* Byte offset at which to write */ +){ + int rc; /* Result code from subfunctions */ + void *pData; /* Data actually written */ + u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */ +#if defined(SQLITE_HAS_CODEC) + if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM; +#else + pData = pPage->pData; +#endif + walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame); + rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset); + if( rc ) return rc; + /* Write the page data */ + rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame)); return rc; } @@ -2686,14 +2717,20 @@ int sqlite3WalFrames( ){ int rc; /* Used to catch return codes */ u32 iFrame; /* Next frame address */ - u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */ PgHdr *p; /* Iterator to run through pList with. */ PgHdr *pLast = 0; /* Last frame in list */ - int nLast = 0; /* Number of extra copies of last page */ + int nExtra = 0; /* Number of extra copies of last page */ + int szFrame; /* The size of a single frame */ + i64 iOffset; /* Next byte to write in WAL file */ + WalWriter w; /* The writer */ assert( pList ); assert( pWal->writeLock ); + /* If this frame set completes a transaction, then nTruncate>0. If + ** nTruncate==0 then this frame set does not complete the transaction. */ + assert( (isCommit!=0)==(nTruncate!=0) ); + #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){} WALTRACE(("WAL%p: frame write begin. %d frames. mxFrame=%d. %s\n", @@ -2738,88 +2775,78 @@ int sqlite3WalFrames( if( rc!=SQLITE_OK ){ return rc; } + + /* Sync the header (unless SQLITE_IOCAP_SEQUENTIAL is true or unless + ** all syncing is turned off by PRAGMA synchronous=OFF). Otherwise + ** an out-of-order write following a WAL restart could result in + ** database corruption. See the ticket: + ** + ** http://localhost:591/sqlite/info/ff5be73dee + */ + if( pWal->syncHeader && sync_flags ){ + rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK); + if( rc ) return rc; + } } assert( (int)pWal->szPage==szPage ); - /* Setup information needed to do the WAL header sync */ - if( pWal->noSyncHeader ){ - assert( pWal->szFirstBlock==0 ); - assert( pWal->syncFlags==0 ); - }else{ - pWal->szFirstBlock = sqlite3OsSectorSize(pWal->pWalFd); - if( szPage>pWal->szFirstBlock ) pWal->szFirstBlock = szPage; - pWal->syncFlags = sync_flags & SQLITE_SYNC_MASK; - } + /* Setup information needed to write frames into the WAL */ + w.pWal = pWal; + w.pFd = pWal->pWalFd; + w.iSyncPoint = 0; + w.syncFlags = sync_flags; + w.szPage = szPage; + iOffset = walFrameOffset(iFrame+1, szPage); + szFrame = szPage + WAL_FRAME_HDRSIZE; - /* Write the log file. */ + /* Write all frames into the log file exactly once */ for(p=pList; p; p=p->pDirty){ - u32 nDbsize; /* Db-size field for frame header */ - i64 iOffset; /* Write offset in log file */ - void *pData; - - iOffset = walFrameOffset(++iFrame, szPage); - /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ - - /* Populate and write the frame header */ - nDbsize = (isCommit && p->pDirty==0) ? nTruncate : 0; -#if defined(SQLITE_HAS_CODEC) - if( (pData = sqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM; -#else - pData = p->pData; -#endif - walEncodeFrame(pWal, p->pgno, nDbsize, pData, aFrame); - rc = walWriteToLog(pWal, aFrame, sizeof(aFrame), iOffset); - if( rc!=SQLITE_OK ){ - return rc; - } - - /* Write the page data */ - rc = walWriteToLog(pWal, pData, szPage, iOffset+sizeof(aFrame)); - if( rc!=SQLITE_OK ){ - return rc; - } + int nDbSize; /* 0 normally. Positive == commit flag */ + iFrame++; + assert( iOffset==walFrameOffset(iFrame, szPage) ); + nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0; + rc = walWriteOneFrame(&w, p, nDbSize, iOffset); + if( rc ) return rc; pLast = p; + iOffset += szFrame; } - /* Sync the log file if the 'isSync' flag was specified. */ + /* If this is the end of a transaction, then we might need to pad + ** the transaction and/or sync the WAL file. + ** + ** Padding and syncing only occur if this set of frames complete a + ** transaction and if PRAGMA synchronous=FULL. If synchronous==NORMAL + ** or synchonous==OFF, then no padding or syncing are needed. + ** + ** If SQLITE_IOCAP_ZERO_DAMAGE is defined, then padding is not needed + ** and only the sync is done. If padding is needed, then the final + ** frame is repeated (with its commit mark) until the next sector + ** boundary is crossed. Only the part of the WAL prior to the last + ** sector boundary is synced; the part of the last frame that extends + ** past the sector boundary is written after the sync. + */ if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){ if( pWal->padToSectorBoundary ){ - i64 iSegment = sqlite3OsSectorSize(pWal->pWalFd); - i64 iOffset = walFrameOffset(iFrame+1, szPage); - - assert( iSegment>0 ); - - iSegment = (((iOffset+iSegment-1)/iSegment) * iSegment); - while( iOffsetpData; -#endif - walEncodeFrame(pWal, pLast->pgno, nTruncate, pData, aFrame); - /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ - rc = walWriteToLog(pWal, aFrame, sizeof(aFrame), iOffset); - if( rc!=SQLITE_OK ){ - return rc; - } - iOffset += WAL_FRAME_HDRSIZE; - rc = walWriteToLog(pWal, pData, szPage, iOffset); - if( rc!=SQLITE_OK ){ - return rc; - } - nLast++; - iOffset += szPage; + int sectorSize = sqlite3OsSectorSize(pWal->pWalFd); + w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize; + while( iOffsetpWalFd, sync_flags & SQLITE_SYNC_MASK); + rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK); } + /* If this frame set completes the first transaction in the WAL and + ** if PRAGMA journal_size_limit is set, then truncate the WAL to the + ** journal size limit, if possible. + */ if( isCommit && pWal->truncateOnCommit && pWal->mxWalSize>=0 ){ i64 sz = pWal->mxWalSize; - if( walFrameOffset(iFrame+nLast+1, szPage)>pWal->mxWalSize ){ - sz = walFrameOffset(iFrame+nLast+1, szPage); + if( walFrameOffset(iFrame+nExtra+1, szPage)>pWal->mxWalSize ){ + sz = walFrameOffset(iFrame+nExtra+1, szPage); } walLimitSize(pWal, sz); pWal->truncateOnCommit = 0; @@ -2835,9 +2862,9 @@ int sqlite3WalFrames( iFrame++; rc = walIndexAppend(pWal, iFrame, p->pgno); } - while( nLast>0 && rc==SQLITE_OK ){ + while( nExtra>0 && rc==SQLITE_OK ){ iFrame++; - nLast--; + nExtra--; rc = walIndexAppend(pWal, iFrame, pLast->pgno); } From f694aa6454630efdb04a7cb9f0d91c0fe5376770 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 20 Dec 2011 22:18:51 +0000 Subject: [PATCH 128/161] Remove the code that tries to detect OOO header writes on a WAL recovery. The code is made obsolete by syncing the WAL header. FossilOrigin-Name: 7ac713a14e24c48651c2a97acc9839850fa7f3c3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wal.c | 9 +-------- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 5a218072ca..f43cdd0272 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sthe\ssqlite3WalFrames()\sroutine\sfor\sclarity\sof\spresentation.\nDo\sthe\spadded\stransaction\ssync\sas\sthe\swrite\spointer\scrosses\sthe\sfinal\nsector\sboundary\sinstead\sof\sat\sthe\send,\sfor\sefficiency.\s\sAlways\ssync\nthe\sWAL\sheader\simmediately\safter\sit\sis\swritten. -D 2011-12-20T20:13:25.386 +C Remove\sthe\scode\sthat\stries\sto\sdetect\sOOO\sheader\swrites\son\sa\sWAL\srecovery.\nThe\scode\sis\smade\sobsolete\sby\ssyncing\sthe\sWAL\sheader. +D 2011-12-20T22:18:51.258 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -250,7 +250,7 @@ F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a -F src/wal.c 311c36af11a721f8601371c1a5a9b15c84ec2dee +F src/wal.c 86193db30a696ee46a0a0ee052e0cbb9aa6802cb F src/wal.h 42f8313f7aaf8913e2d1fdf7b47025c23491ea1d F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 @@ -984,7 +984,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P e694f7b166144a0afba7846e1e18ad568b33a081 -R 5ba56fa16752a6d0272db759071cab34 +P 92c73b421b6242b09247dfb759777a531a107523 +R 0e9b80c28c07203b08d85530f30aefdc U drh -Z ae8908dc690fbf93e21d9e8cf0a20f23 +Z 960abf57a2870882cf541fd88a471911 diff --git a/manifest.uuid b/manifest.uuid index f885437af4..e405f4958a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -92c73b421b6242b09247dfb759777a531a107523 \ No newline at end of file +7ac713a14e24c48651c2a97acc9839850fa7f3c3 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index d61bfc069f..ff33d5f30d 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1163,15 +1163,8 @@ static int walIndexRecover(Wal *pWal){ iFrame++; rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); if( rc!=SQLITE_OK ) break; - if( sqlite3Get4byte(&aFrame[8]) == - 1+sqlite3Get4byte((u8*)&pWal->hdr.aSalt[0]) ){ - pWal->hdr.mxFrame = 0; - pWal->hdr.nPage = 0; - break; - } - if( !isValid ) continue; isValid = walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame); - if( !isValid ) continue; + if( !isValid ) break; rc = walIndexAppend(pWal, iFrame, pgno); if( rc!=SQLITE_OK ) break; From f12b3f609f08e923833bc6c37863f11a82582c03 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 21 Dec 2011 14:42:29 +0000 Subject: [PATCH 129/161] Add the ability to enable or disable SQLITE_IOCAP_ZERO_DAMAGE using a URI parameter for both unix and windows. Add a file-control to query or disable the ZERO_DAMAGE setting. Add the -uri option to the "sqlite3" TCL command in tclsqlite3.c. Allow the sqlite3_uri_parameter() interface to accept a NULL pointer for its first parameter. FossilOrigin-Name: c83627b73285f883719845c1b9fe85f378f28dd2 --- manifest | 23 ++++----- manifest.uuid | 2 +- src/main.c | 1 + src/os_unix.c | 66 ++++++++++++++++++-------- src/os_win.c | 43 +++++++++++++---- src/sqlite.h.in | 10 ++++ src/tclsqlite.c | 8 ++++ src/test1.c | 33 +++++++++++++ test/zerodamage.test | 109 +++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 254 insertions(+), 41 deletions(-) create mode 100644 test/zerodamage.test diff --git a/manifest b/manifest index f43cdd0272..9b902fbbaf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\scode\sthat\stries\sto\sdetect\sOOO\sheader\swrites\son\sa\sWAL\srecovery.\nThe\scode\sis\smade\sobsolete\sby\ssyncing\sthe\sWAL\sheader. -D 2011-12-20T22:18:51.258 +C Add\sthe\sability\sto\senable\sor\sdisable\sSQLITE_IOCAP_ZERO_DAMAGE\susing\sa\sURI\nparameter\sfor\sboth\sunix\sand\swindows.\s\sAdd\sa\sfile-control\sto\squery\sor\sdisable\nthe\sZERO_DAMAGE\ssetting.\s\sAdd\sthe\s-uri\soption\sto\sthe\s"sqlite3"\sTCL\scommand\nin\stclsqlite3.c.\s\sAllow\sthe\ssqlite3_uri_parameter()\sinterface\sto\saccept\sa\nNULL\spointer\sfor\sits\sfirst\sparameter. +D 2011-12-21T14:42:29.520 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d -F src/main.c c837e24182e8ec7121c61e44f547b59cbe413e7f +F src/main.c 7f960366043b80c764de07e745d12b0705f56b30 F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 7998e7003a3047e323c849a26dda004debc04d03 @@ -166,8 +166,8 @@ F src/os.c 28bbdab2170dfce84d86c45456a18eab1d0f99a9 F src/os.h 549b1a2e5e0ed1e1499f252dac126c4973e7379c F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c e2b96f85eb91c962765005892014b014db3e6478 -F src/os_win.c 3cf34661f5ef47be81bb7be541582d6e14852159 +F src/os_unix.c 3e630701efd54ecbdba237c5a3cb3c55d83d8a2e +F src/os_win.c 4fc4aa8aecb334c64a250a4b36cff6a798704da4 F src/pager.c c9bd2f7183edba480bea1dd49361a02d0c3d8f43 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba @@ -182,14 +182,14 @@ F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c a1d075db66a0ea42807353501b62997969e5be79 F src/shell.c aa4183d4a5243d8110b1d3d77faa4aea7e9c9c2d -F src/sqlite.h.in d0e81fd4c72fbfdc786d3067e17a16a32f249428 +F src/sqlite.h.in 369e7597b7673e8bc490e2012bc00fb15cd55674 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h 165409fa8adc8701148830804febeded3f2e4448 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c de581e2e71f5e7f98366156afad83b4742ac6fe0 -F src/test1.c 33b9c49f728cf28937eea7b246c28e89e3cf5e9e +F src/tclsqlite.c bd86070f52ae3f77a2e6b3b065ff03adb9140bfa +F src/test1.c 4cbabeb8b2c487f67d724e2ea03841b69fa640c4 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7 @@ -940,6 +940,7 @@ F test/whereC.test 13ff5ec0dba407c0e0c075980c75b3275a6774e5 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 +F test/zerodamage.test 0e12b2d7343f1fbb015e56a4a2a6074336ff46cf F tool/build-shell.sh 12aa4391073a777fcb6dcc490b219a018ae98bac F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 @@ -984,7 +985,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 92c73b421b6242b09247dfb759777a531a107523 -R 0e9b80c28c07203b08d85530f30aefdc +P 7ac713a14e24c48651c2a97acc9839850fa7f3c3 +R 8d88cdfbb2218ba883425a8ad72e347f U drh -Z 960abf57a2870882cf541fd88a471911 +Z 6c0db6cbcd8026c224cda9667bf4cff6 diff --git a/manifest.uuid b/manifest.uuid index e405f4958a..074245c6ae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7ac713a14e24c48651c2a97acc9839850fa7f3c3 \ No newline at end of file +c83627b73285f883719845c1b9fe85f378f28dd2 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 690b73c2e7..ea64d8be9a 100644 --- a/src/main.c +++ b/src/main.c @@ -2977,6 +2977,7 @@ int sqlite3_test_control(int op, ...){ ** returns a NULL pointer. */ const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){ + if( zFilename==0 ) return 0; zFilename += sqlite3Strlen30(zFilename) + 1; while( zFilename[0] ){ int x = strcmp(zFilename, zParam); diff --git a/src/os_unix.c b/src/os_unix.c index a9d7de832d..4a31c8cdea 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -215,13 +215,13 @@ struct unixFile { int h; /* The file descriptor */ unsigned char eFileLock; /* The type of lock held on this fd */ unsigned char ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ + unsigned char szSector; /* Sectorsize/512 */ int lastErrno; /* The unix errno from last I/O error */ void *lockingContext; /* Locking style specific state */ UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ - int szSector; /* Sector size */ #if SQLITE_ENABLE_LOCKING_STYLE int openFlags; /* The flags specified at open() */ #endif @@ -263,6 +263,7 @@ struct unixFile { #else # define UNIXFILE_DIRSYNC 0x00 #endif +#define UNIXFILE_ZERO_DAMAGE 0x10 /* True if SQLITE_IOCAP_ZERO_DAMAGE */ /* ** Include code that is common to all os_*.c files @@ -3511,6 +3512,22 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){ return SQLITE_OK; } +/* +** If *pArg is inititially negative then this is a query. Set *pArg to +** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. +** +** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. +*/ +static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){ + if( *pArg<0 ){ + *pArg = (pFile->ctrlFlags & mask)!=0; + }else if( (*pArg)==0 ){ + pFile->ctrlFlags &= ~mask; + }else{ + pFile->ctrlFlags |= mask; + } +} + /* ** Information and control of an open file handle. */ @@ -3537,14 +3554,11 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ return rc; } case SQLITE_FCNTL_PERSIST_WAL: { - int bPersist = *(int*)pArg; - if( bPersist<0 ){ - *(int*)pArg = (pFile->ctrlFlags & UNIXFILE_PERSIST_WAL)!=0; - }else if( bPersist==0 ){ - pFile->ctrlFlags &= ~UNIXFILE_PERSIST_WAL; - }else{ - pFile->ctrlFlags |= UNIXFILE_PERSIST_WAL; - } + unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg); + return SQLITE_OK; + } + case SQLITE_FCNTL_ZERO_DAMAGE: { + unixModeBit(pFile, UNIXFILE_ZERO_DAMAGE, (int*)pArg); return SQLITE_OK; } case SQLITE_FCNTL_VFSNAME: { @@ -3589,27 +3603,37 @@ static int unixSectorSize(sqlite3_file *pFile){ unixFile *p = (unixFile*)pFile; if( p->szSector==0 ){ #ifdef MISSING_STATVFS - p->szSector = SQLITE_DEFAULT_SECTOR_SIZE; + p->szSector = SQLITE_DEFAULT_SECTOR_SIZE/512; #else struct statvfs x; int sz; memset(&x, 0, sizeof(x)); osStatvfs(p->zPath, &x); - p->szSector = sz = (int)x.f_frsize; + sz = (int)x.f_frsize; if( sz<512 || sz>65536 || (sz&(sz-1))!=0 ){ - p->szSector = SQLITE_DEFAULT_SECTOR_SIZE; + sz = SQLITE_DEFAULT_SECTOR_SIZE; } + p->szSector = sz/512; #endif } - return p->szSector; + return p->szSector*512; } /* -** Return the device characteristics for the file. This is always 0 for unix. +** Return the device characteristics for the file. +** +** This VFS is set up to return SQLITE_IOCAP_ZERO_DAMAGE by default. +** However, that choice is contraversial sicne technically the underlying +** file system does not always provide ZERO_DAMAGE. (In other words, after +** a power-loss event, parts of the file that were never written might end +** up being altered.) However, non-ZERO-DAMAGE behavior is very, very rare. +** And asserting ZERO_DAMAGE makes a large reduction in the amount of required +** I/O. Hence, while ZERO_DAMAGE is on by default, there is a file-control +** available to turn it off. */ -static int unixDeviceCharacteristics(sqlite3_file *NotUsed){ - UNUSED_PARAMETER(NotUsed); - return SQLITE_IOCAP_ZERO_DAMAGE; +static int unixDeviceCharacteristics(sqlite3_file *id){ + unixFile *p = (unixFile*)id; + return (p->ctrlFlags & UNIXFILE_ZERO_DAMAGE) ? SQLITE_IOCAP_ZERO_DAMAGE : 0; } #ifndef SQLITE_OMIT_WAL @@ -4568,6 +4592,7 @@ static int fillInUnixFile( const sqlite3_io_methods *pLockingStyle; unixFile *pNew = (unixFile *)pId; int rc = SQLITE_OK; + const char *zZeroDam; /* Value of the zero_damage query parameter */ assert( pNew->pInode==NULL ); @@ -4594,10 +4619,11 @@ static int fillInUnixFile( pNew->h = h; pNew->pVfs = pVfs; pNew->zPath = zFilename; + zZeroDam = sqlite3_uri_parameter(zFilename, "zero_damage"); + if( zZeroDam==0 ) zZeroDam = "1"; + pNew->ctrlFlags = atoi(zZeroDam) ? UNIXFILE_ZERO_DAMAGE : 1; if( memcmp(pVfs->zName,"unix-excl",10)==0 ){ - pNew->ctrlFlags = UNIXFILE_EXCL; - }else{ - pNew->ctrlFlags = 0; + pNew->ctrlFlags |= UNIXFILE_EXCL; } if( isReadOnly ){ pNew->ctrlFlags |= UNIXFILE_RDONLY; diff --git a/src/os_win.c b/src/os_win.c index 5e0667d188..ec4d062f9b 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -59,7 +59,7 @@ struct winFile { HANDLE h; /* Handle for accessing the file */ u8 locktype; /* Type of lock currently held on this file */ short sharedLockByte; /* Randomly chosen byte used as a shared lock */ - u8 bPersistWal; /* True to persist WAL files */ + u8 ctrlFlags; /* Flags. See WINFILE_* below */ DWORD lastErrno; /* The Windows errno from the last I/O error */ DWORD sectorSize; /* Sector size of the device file is on */ winShm *pShm; /* Instance of shared memory on this file */ @@ -74,6 +74,12 @@ struct winFile { #endif }; +/* +** Allowed values for winFile.ctrlFlags +*/ +#define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ +#define WINFILE_ZERO_DAMAGE 0x10 /* True if SQLITE_IOCAP_ZERO_DAMAGE */ + /* * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the * various Win32 API heap functions instead of our own. @@ -2125,6 +2131,22 @@ static int winUnlock(sqlite3_file *id, int locktype){ return rc; } +/* +** If *pArg is inititially negative then this is a query. Set *pArg to +** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. +** +** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. +*/ +static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){ + if( *pArg<0 ){ + *pArg = (pFile->ctrlFlags & mask)!=0; + }else if( (*pArg)==0 ){ + pFile->ctrlFlags &= ~mask; + }else{ + pFile->ctrlFlags |= mask; + } +} + /* ** Control and query of the open file handle. */ @@ -2160,12 +2182,11 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ return SQLITE_OK; } case SQLITE_FCNTL_PERSIST_WAL: { - int bPersist = *(int*)pArg; - if( bPersist<0 ){ - *(int*)pArg = pFile->bPersistWal; - }else{ - pFile->bPersistWal = bPersist!=0; - } + winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg); + return SQLITE_OK; + } + case SQLITE_FCNTL_ZERO_DAMAGE: { + winModeBit(pFile, WINFILE_ZERO_DAMAGE, (int*)pArg); return SQLITE_OK; } case SQLITE_FCNTL_VFSNAME: { @@ -2212,9 +2233,9 @@ static int winSectorSize(sqlite3_file *id){ ** Return a vector of device characteristics. */ static int winDeviceCharacteristics(sqlite3_file *id){ - UNUSED_PARAMETER(id); + winFile *p = (winFile*)id; return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | - SQLITE_IOCAP_ZERO_DAMAGE; + ((p->ctrlFlags & WINFILE_ZERO_DAMAGE)?SQLITE_IOCAP_ZERO_DAMAGE:0); } #ifndef SQLITE_OMIT_WAL @@ -3004,6 +3025,7 @@ static int winOpen( void *zConverted; /* Filename in OS encoding */ const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ int cnt = 0; + const char *zZeroDam; /* Value of zero_damage query parameter */ /* If argument zPath is a NULL pointer, this function is required to open ** a temporary file. Use this buffer to store the file name in. @@ -3179,6 +3201,9 @@ static int winOpen( pFile->pVfs = pVfs; pFile->pShm = 0; pFile->zPath = zName; + zZeroDam = sqlite3_uri_parameter(zName, "zero_damage"); + if( zZeroDam==0 ) zZeroDam = "1"; + pFile->ctrlFlags = atoi(zZeroDam) ? WINFILE_ZERO_DAMAGE : 1; pFile->sectorSize = getSectorSize(pVfs, zUtf8Name); #if SQLITE_OS_WINCE diff --git a/src/sqlite.h.in b/src/sqlite.h.in index f7a2616baa..e036449d02 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -774,6 +774,15 @@ struct sqlite3_io_methods { ** WAL mode. If the integer is -1, then it is overwritten with the current ** WAL persistence setting. ** +** ^The [SQLITE_FCNTL_ZERO_DAMAGE] opcode is used to set or query the +** persistent zero-damage setting. The zero-damage setting determines +** the [SQLITE_IOCAP_ZERO_DAMAGE] bit of the xDeviceCharacteristics methods. +** The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage +** mode. If the integer is -1, then it is overwritten with the current +** zero-damage mode setting. +** ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening ** a write transaction to indicate that, unless it is rolled back for some ** reason, the entire database file will be overwritten by the current @@ -802,6 +811,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_PERSIST_WAL 10 #define SQLITE_FCNTL_OVERWRITE 11 #define SQLITE_FCNTL_VFSNAME 12 +#define SQLITE_FCNTL_ZERO_DAMAGE 13 /* ** CAPI3REF: Mutex Handle diff --git a/src/tclsqlite.c b/src/tclsqlite.c index c8f0fbd31b..3692bef9ca 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -3001,6 +3001,14 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ }else{ flags &= ~SQLITE_OPEN_FULLMUTEX; } + }else if( strcmp(zArg, "-uri")==0 ){ + int b; + if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; + if( b ){ + flags |= SQLITE_OPEN_URI; + }else{ + flags &= ~SQLITE_OPEN_URI; + } }else{ Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0); return TCL_ERROR; diff --git a/src/test1.c b/src/test1.c index 798366a8c7..b96b99ce8d 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5235,6 +5235,38 @@ static int file_control_persist_wal( return TCL_OK; } +/* +** tclcmd: file_control_zero_damage DB ZERO-DAMAGE-FLAG +** +** This TCL command runs the sqlite3_file_control interface with +** the SQLITE_FCNTL_ZERO_DAMAGE opcode. +*/ +static int file_control_zero_damage( + ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + sqlite3 *db; + int rc; + int bDamage; + char z[100]; + + if( objc!=3 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_GetStringFromObj(objv[0], 0), " DB FLAG", 0); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ + return TCL_ERROR; + } + if( Tcl_GetIntFromObj(interp, objv[2], &bDamage) ) return TCL_ERROR; + rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_ZERO_DAMAGE,(void*)&bDamage); + sqlite3_snprintf(sizeof(z), z, "%d %d", rc, bDamage); + Tcl_AppendResult(interp, z, (char*)0); + return TCL_OK; +} + /* ** tclcmd: file_control_vfsname DB ?AUXDB? @@ -6093,6 +6125,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "file_control_sizehint_test", file_control_sizehint_test, 0 }, { "file_control_win32_av_retry", file_control_win32_av_retry, 0 }, { "file_control_persist_wal", file_control_persist_wal, 0 }, + { "file_control_zero_damage", file_control_zero_damage, 0 }, { "file_control_vfsname", file_control_vfsname, 0 }, { "sqlite3_vfs_list", vfs_list, 0 }, { "sqlite3_create_function_v2", test_create_function_v2, 0 }, diff --git a/test/zerodamage.test b/test/zerodamage.test new file mode 100644 index 0000000000..bef82b2eda --- /dev/null +++ b/test/zerodamage.test @@ -0,0 +1,109 @@ +# 2011 December 21 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file implements tests of the SQLITE_IOCAP_ZERO_DAMAGE property +# and the SQLITE_FCNTL_ZERO_DAMAGE file-control for manipulating it. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix wal5 + +# ZERO_DAMAGE defaults to true +# +do_test zerodamage-1.0 { + file_control_zero_damage db -1 +} {0 1} + +# Check the ability to turn zero-damage on and off. +# +do_test zerodamage-1.1 { + file_control_zero_damage db 0 + file_control_zero_damage db -1 +} {0 0} +do_test zerodamage-1.2 { + file_control_zero_damage db 1 + file_control_zero_damage db -1 +} {0 1} + +# Run a transaction with zero-damage on, a small page size and a much larger +# sectorsize. Verify that the maximum journal size is small - that the +# rollback journal is not being padded. +# +do_test zerodamage-2.0 { + db close + testvfs tv -default 1 + tv sectorsize 8192 + sqlite3 db file:test.db?zero_damage=1 -uri 1 + unset -nocomplain ::max_journal_size + set ::max_journal_size 0 + proc xDeleteCallback {method file args} { + set sz [file size $file] + if {$sz>$::max_journal_size} {set ::max_journal_size $sz} + } + tv filter xDelete + tv script xDeleteCallback + register_wholenumber_module db + db eval { + PRAGMA page_size=1024; + PRAGMA journal_mode=DELETE; + PRAGMA cache_size=5; + CREATE VIRTUAL TABLE nums USING wholenumber; + CREATE TABLE t1(x, y); + INSERT INTO t1 SELECT value, randomblob(100) FROM nums + WHERE value BETWEEN 1 AND 400; + } + set ::max_journal_size 0 + db eval { + UPDATE t1 SET y=randomblob(50) WHERE x=123; + } + concat [file_control_zero_damage db -1] [set ::max_journal_size] +} {0 1 2576} + +# Repeat the previous step with zero-damage turned off. This time the +# maximum rollback journal size should be much larger. +# +do_test zerodamage-2.1 { + set ::max_journal_size 0 + db close + sqlite3 db file:test.db?zero_damage=0 -uri 1 + db eval { + UPDATE t1 SET y=randomblob(50) WHERE x=124; + } + concat [file_control_zero_damage db -1] [set ::max_journal_size] +} {0 0 24704} + +# Run a WAL-mode transaction with ZERO_DAMAGE on to verify that the +# WAL file does not get too big. +# +do_test zerodamage-3.0 { + db eval { + PRAGMA journal_mode=WAL; + } + db close + sqlite3 db file:test.db?zero_damage=1 -uri 1 + db eval { + UPDATE t1 SET y=randomblob(50) WHERE x=124; + } + file size test.db-wal +} {1080} + +# Repeat the previous with ZERO_DAMAGE off. Verify that the WAL file +# is padded. +# +do_test zerodamage-3.1 { + db close + sqlite3 db file:test.db?zero_damage=0 -uri 1 + db eval { + UPDATE t1 SET y=randomblob(50) WHERE x=124; + } + file size test.db-wal +} {8416} From 27d47fbe6e5d77798c88564ad6bbaf647702e149 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Dec 2011 17:00:16 +0000 Subject: [PATCH 130/161] Avoid 32-bit overflow when calculating the byte offset of an overflow page in SQLITE_DIRECT_OVERFLOW_READ code. Fix for [ac0ff496b7]. FossilOrigin-Name: c5256b59ad70104c1e181b9f49d1d712cf4cc9f6 --- manifest | 15 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- test/bigfile2.test | 59 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 9 deletions(-) create mode 100644 test/bigfile2.test diff --git a/manifest b/manifest index e6573ae9e2..4f3ee6af22 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Assert\sthat\sthe\sisCommit\sparameter\sto\ssqlite3WalFrames()\sis\szero\sif\sand\nonly\sif\sthe\snTruncate\sparameter\sis\szero. -D 2011-12-20T13:13:09.326 +C Avoid\s32-bit\soverflow\swhen\scalculating\sthe\sbyte\soffset\sof\san\soverflow\spage\sin\sSQLITE_DIRECT_OVERFLOW_READ\scode.\sFix\sfor\s[ac0ff496b7]. +D 2011-12-21T17:00:16.841 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -125,7 +125,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 4368158da74d4711888e03264105c5c527d76caf F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 80ea65224512884bb72976c93810d2dcaecc1353 +F src/btree.c 2fdde7d16c80bd4e8a0913038e766c4297818f6f F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h ea863a819224d3e6845ad1e39954d41558b8cd8b F src/build.c 8915bb6d72ead998f94c2756ea8d143c77709b70 @@ -297,6 +297,7 @@ F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f F test/between.test 16b1776c6323faadb097a52d673e8e3d8be7d070 F test/bigfile.test a8ec8073a20207456dab01a29ad9cde42b0dd103 +F test/bigfile2.test f8e83eca9abef60692a34255a2ebcb96aff897fc F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747 F test/bind.test 3c7b320969000c441a70952b0b15938fbb66237c F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0 @@ -984,7 +985,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 4d518bd4801c31bb1e4fb0329ad057e549035237 -R b6fa212f141f93e02b36860230812df1 -U drh -Z ec529eca7ddb3f43acff46ddca1c2443 +P 979daf92e09305665d943e197b93b81139197c5b +R 3ca2d5c9a0922c80f51a136db15c2655 +U dan +Z 686f6e4400cb272609dcad0347caf0ec diff --git a/manifest.uuid b/manifest.uuid index 6ec54257b9..b8f0351d86 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -979daf92e09305665d943e197b93b81139197c5b \ No newline at end of file +c5256b59ad70104c1e181b9f49d1d712cf4cc9f6 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 713016e756..ad011608bf 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3979,7 +3979,7 @@ static int accessPayload( u8 aSave[4]; u8 *aWrite = &pBuf[-4]; memcpy(aSave, aWrite, 4); - rc = sqlite3OsRead(fd, aWrite, a+4, pBt->pageSize * (nextPage-1)); + rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); nextPage = get4byte(aWrite); memcpy(aWrite, aSave, 4); }else diff --git a/test/bigfile2.test b/test/bigfile2.test new file mode 100644 index 0000000000..9810d3a0f3 --- /dev/null +++ b/test/bigfile2.test @@ -0,0 +1,59 @@ +# 2011 December 20 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this script testing the ability of SQLite to handle database +# files larger than 4GB. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix bigfile2 + +# Create a small database. +# +do_execsql_test 1.1 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); +} + +# Pad the file out to 4GB in size. Then clear the file-size field in the +# db header. This will cause SQLite to assume that the first 4GB of pages +# are actually in use and new pages will be appended to the file. +# +db close +if {[catch {fake_big_file 4096 [pwd]/test.db} msg]} { + puts "**** Unable to create a file larger than 4096 MB. *****" + finish_test + return +} +hexio_write test.db 28 00000000 + +do_test 1.2 { + file size test.db +} [expr 14 + 4096 * (1<<20)] + +# Now insert a large row. The overflow pages will be located past the 4GB +# boundary. Then, after opening and closing the database, test that the row +# can be read back in. +# +set str [string repeat k 30000] +do_test 1.3 { + sqlite3 db test.db + execsql { INSERT INTO t1 VALUES(3, $str) } + db close + sqlite3 db test.db + db one { SELECT b FROM t1 WHERE a = 3 } +} $str + +db close +file delete test.db + +finish_test From 7c3210e641ac445048385ff0fe82096a2f4945d7 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Dec 2011 18:04:41 +0000 Subject: [PATCH 131/161] Fix other problems where 32-bit integer overflow may cause a problem. Two that require an improbably large sub-journal and two in test harness code. FossilOrigin-Name: c723e3e18a008922281d8d6e8e3aba07941eb173 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/pager.c | 6 +++--- src/test_journal.c | 2 +- src/test_stat.c | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 4f3ee6af22..bbe5f09d73 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\s32-bit\soverflow\swhen\scalculating\sthe\sbyte\soffset\sof\san\soverflow\spage\sin\sSQLITE_DIRECT_OVERFLOW_READ\scode.\sFix\sfor\s[ac0ff496b7]. -D 2011-12-21T17:00:16.841 +C Fix\sother\sproblems\swhere\s32-bit\sinteger\soverflow\smay\scause\sa\sproblem.\sTwo\sthat\srequire\san\simprobably\slarge\ssub-journal\sand\stwo\sin\stest\sharness\scode. +D 2011-12-21T18:04:41.417 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -168,7 +168,7 @@ F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 7dc7df10331942b139032328449a3723e051979e F src/os_win.c 197d23ce8a0dff748e766e034bf95ff756dd3884 -F src/pager.c c7c32a1c279e0bbbde3578172985c41d4c5efc35 +F src/pager.c 523c64f6ca707e820d5cf10ed8371238ecac8333 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba F src/pcache.c 1fdd77978c1525d1ca4b9ef48eb80abca710cb4c @@ -211,7 +211,7 @@ F src/test_hexio.c c4773049603151704a6ab25ac5e936b5109caf5a F src/test_init.c 3cbad7ce525aec925f8fda2192d576d47f0d478a F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99 F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 -F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff +F src/test_journal.c 2c06e4be6584d51b935dc8b353980a9388de62ef F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 F src/test_multiplex.c 6e07b94e2fe430f7f4f0d7d67b5e58f504dea655 @@ -225,7 +225,7 @@ F src/test_quota.h 9ffa1d3ad6d0a6a24e8670ea64b909c717ec3358 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f -F src/test_stat.c 69de4361c7a69fc1136d31ab7144408cd00805c7 +F src/test_stat.c 80271ad7d776a79babe0e025bb3a1bfcd3a3cfb1 F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa @@ -985,7 +985,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 979daf92e09305665d943e197b93b81139197c5b -R 3ca2d5c9a0922c80f51a136db15c2655 +P c5256b59ad70104c1e181b9f49d1d712cf4cc9f6 +R 67d063070f0e350ae5f59b7b697ace26 U dan -Z 686f6e4400cb272609dcad0347caf0ec +Z bef61bfcf61cf3a9e556e6b3194dc0ce diff --git a/manifest.uuid b/manifest.uuid index b8f0351d86..0d2903da39 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c5256b59ad70104c1e181b9f49d1d712cf4cc9f6 \ No newline at end of file +c723e3e18a008922281d8d6e8e3aba07941eb173 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 9db6ebd3f4..4f8473e735 100644 --- a/src/pager.c +++ b/src/pager.c @@ -3267,13 +3267,13 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ */ if( pSavepoint ){ u32 ii; /* Loop counter */ - i64 offset = pSavepoint->iSubRec*(4+pPager->pageSize); + i64 offset = (i64)pSavepoint->iSubRec*(4+pPager->pageSize); if( pagerUseWal(pPager) ){ rc = sqlite3WalSavepointUndo(pPager->pWal, pSavepoint->aWalData); } for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && iinSubRec; ii++){ - assert( offset==ii*(4+pPager->pageSize) ); + assert( offset==(i64)ii*(4+pPager->pageSize) ); rc = pager_playback_one_page(pPager, &offset, pDone, 0, 1); } assert( rc!=SQLITE_DONE ); @@ -4125,7 +4125,7 @@ static int subjournalPage(PgHdr *pPg){ ** write the journal record into the file. */ if( rc==SQLITE_OK ){ void *pData = pPg->pData; - i64 offset = pPager->nSubRec*(4+pPager->pageSize); + i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize); char *pData2; CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2); diff --git a/src/test_journal.c b/src/test_journal.c index 68869723b3..ef82070320 100644 --- a/src/test_journal.c +++ b/src/test_journal.c @@ -391,7 +391,7 @@ static int openTransaction(jt_file *pMain, jt_file *pJournal){ while( rc==SQLITE_OK && iTrunk>0 ){ u32 nLeaf; u32 iLeaf; - sqlite3_int64 iOff = (iTrunk-1)*pMain->nPagesize; + sqlite3_int64 iOff = (i64)(iTrunk-1)*pMain->nPagesize; rc = sqlite3OsRead(p, aData, pMain->nPagesize, iOff); nLeaf = decodeUint32(&aData[4]); for(iLeaf=0; rc==SQLITE_OK && iLeafszPage = sqlite3BtreeGetPageSize(pBt); - pCsr->iOffset = pCsr->szPage * (pCsr->iPageno - 1); + pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1); /* If connected to a ZIPVFS backend, override the page size and ** offset with actual values obtained from ZIPVFS. From 3b5b351b656050b2f8411e4ecbd7ede68523ec5c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 22 Dec 2011 01:46:04 +0000 Subject: [PATCH 132/161] Remove a redundant assignment operator. FossilOrigin-Name: 19a6852a1e5905b35bc69b309951c5ec8ecd0bef --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wal.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9b902fbbaf..d75a9a88ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sability\sto\senable\sor\sdisable\sSQLITE_IOCAP_ZERO_DAMAGE\susing\sa\sURI\nparameter\sfor\sboth\sunix\sand\swindows.\s\sAdd\sa\sfile-control\sto\squery\sor\sdisable\nthe\sZERO_DAMAGE\ssetting.\s\sAdd\sthe\s-uri\soption\sto\sthe\s"sqlite3"\sTCL\scommand\nin\stclsqlite3.c.\s\sAllow\sthe\ssqlite3_uri_parameter()\sinterface\sto\saccept\sa\nNULL\spointer\sfor\sits\sfirst\sparameter. -D 2011-12-21T14:42:29.520 +C Remove\sa\sredundant\sassignment\soperator. +D 2011-12-22T01:46:04.520 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -250,7 +250,7 @@ F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a -F src/wal.c 86193db30a696ee46a0a0ee052e0cbb9aa6802cb +F src/wal.c 842901b44832474b0f77f9a031455af3787ae277 F src/wal.h 42f8313f7aaf8913e2d1fdf7b47025c23491ea1d F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 @@ -985,7 +985,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 7ac713a14e24c48651c2a97acc9839850fa7f3c3 -R 8d88cdfbb2218ba883425a8ad72e347f +P c83627b73285f883719845c1b9fe85f378f28dd2 +R f1e5c3d8040d152c5fcb2f4a7615b662 U drh -Z 6c0db6cbcd8026c224cda9667bf4cff6 +Z 2c78a3c6c37d41190b48f488942db024 diff --git a/manifest.uuid b/manifest.uuid index 074245c6ae..6760521fcc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c83627b73285f883719845c1b9fe85f378f28dd2 \ No newline at end of file +19a6852a1e5905b35bc69b309951c5ec8ecd0bef \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index ff33d5f30d..d3b66b5b9f 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1154,7 +1154,6 @@ static int walIndexRecover(Wal *pWal){ /* Read all frames from the log file. */ iFrame = 0; - isValid = 1; for(iOffset=WAL_HDRSIZE; (iOffset+szFrame)<=nSize; iOffset+=szFrame){ u32 pgno; /* Database page number for frame */ u32 nTruncate; /* dbsize field from frame header */ From 0c8cda6e0dcb1c9173710ac060b69fdbfb9c1a27 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 22 Dec 2011 15:30:46 +0000 Subject: [PATCH 133/161] Fix a problem in fts3_write.c causing stack memory to be referenced after it is out of scope. FossilOrigin-Name: f9c4a7c8f4e5821b47c1393d6272e32416d8886c --- ext/fts3/fts3_write.c | 11 ++++++++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index 2904a9acaa..fe9f26cf3e 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -1470,6 +1470,7 @@ int sqlite3Fts3SegReaderPending( Fts3SegReader **ppReader /* OUT: SegReader for pending-terms */ ){ Fts3SegReader *pReader = 0; /* Fts3SegReader object to return */ + Fts3HashElem *pE; /* Iterator variable */ Fts3HashElem **aElem = 0; /* Array of term hash entries to scan */ int nElem = 0; /* Size of array at aElem */ int rc = SQLITE_OK; /* Return Code */ @@ -1478,7 +1479,6 @@ int sqlite3Fts3SegReaderPending( pHash = &p->aIndex[iIndex].hPending; if( bPrefix ){ int nAlloc = 0; /* Size of allocated array at aElem */ - Fts3HashElem *pE = 0; /* Iterator variable */ for(pE=fts3HashFirst(pHash); pE; pE=fts3HashNext(pE)){ char *zKey = (char *)fts3HashKey(pE); @@ -1512,8 +1512,13 @@ int sqlite3Fts3SegReaderPending( }else{ /* The query is a simple term lookup that matches at most one term in - ** the index. All that is required is a straight hash-lookup. */ - Fts3HashElem *pE = fts3HashFindElem(pHash, zTerm, nTerm); + ** the index. All that is required is a straight hash-lookup. + ** + ** Because the stack address of pE may be accessed via the aElem pointer + ** below, the "Fts3HashElem *pE" must be declared so that it is valid + ** within this entire function, not just this "else{...}" block. + */ + pE = fts3HashFindElem(pHash, zTerm, nTerm); if( pE ){ aElem = &pE; nElem = 1; diff --git a/manifest b/manifest index bbe5f09d73..bcb25f1287 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sother\sproblems\swhere\s32-bit\sinteger\soverflow\smay\scause\sa\sproblem.\sTwo\sthat\srequire\san\simprobably\slarge\ssub-journal\sand\stwo\sin\stest\sharness\scode. -D 2011-12-21T18:04:41.417 +C Fix\sa\sproblem\sin\sfts3_write.c\scausing\sstack\smemory\sto\sbe\sreferenced\safter\sit\sis\sout\sof\sscope. +D 2011-12-22T15:30:46.102 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -78,7 +78,7 @@ F ext/fts3/fts3_test.c 24fa13f330db011500acb95590da9eee24951894 F ext/fts3/fts3_tokenizer.c 9ff7ec66ae3c5c0340fa081958e64f395c71a106 F ext/fts3/fts3_tokenizer.h 13ffd9fcb397fec32a05ef5cd9e0fa659bf3dbd3 F ext/fts3/fts3_tokenizer1.c 0dde8f307b8045565cf63797ba9acfaff1c50c68 -F ext/fts3/fts3_write.c c097228bff4d33c6b8a270c9717b9f8339068776 +F ext/fts3/fts3_write.c fb1998be659ff85b7045513ab625bbdcf9b804d8 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9 @@ -985,7 +985,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P c5256b59ad70104c1e181b9f49d1d712cf4cc9f6 -R 67d063070f0e350ae5f59b7b697ace26 +P c723e3e18a008922281d8d6e8e3aba07941eb173 +R a473dabc4c74a83ea005d83d596de923 U dan -Z bef61bfcf61cf3a9e556e6b3194dc0ce +Z 9db758f12d3cf045a211ef0d51186bd2 diff --git a/manifest.uuid b/manifest.uuid index 0d2903da39..0edb2fd4a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c723e3e18a008922281d8d6e8e3aba07941eb173 \ No newline at end of file +f9c4a7c8f4e5821b47c1393d6272e32416d8886c \ No newline at end of file From de0f18154e0a1b71740eb67298442cb5b9805484 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 22 Dec 2011 17:10:35 +0000 Subject: [PATCH 134/161] Check the return code from sqlite3_initialize() called from within sqlite3_soft_heap_limit64() and return an error from sqlite3_soft_heap_limit64() if sqlite3_initialize() fails. FossilOrigin-Name: 676acce274fec692a1eb34d27ee4b1327b4b3334 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/malloc.c | 3 ++- src/sqlite.h.in | 3 ++- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index bcb25f1287..384275d8e0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sfts3_write.c\scausing\sstack\smemory\sto\sbe\sreferenced\safter\sit\sis\sout\sof\sscope. -D 2011-12-22T15:30:46.102 +C Check\sthe\sreturn\scode\sfrom\ssqlite3_initialize()\scalled\sfrom\swithin\nsqlite3_soft_heap_limit64()\sand\sreturn\san\serror\sfrom\ssqlite3_soft_heap_limit64()\nif\ssqlite3_initialize()\sfails. +D 2011-12-22T17:10:35.691 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -148,7 +148,7 @@ F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d F src/main.c c837e24182e8ec7121c61e44f547b59cbe413e7f -F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 +F src/malloc.c 15afac5e59b6584efe072e9933aefb4230e74f97 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 7998e7003a3047e323c849a26dda004debc04d03 F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf @@ -182,7 +182,7 @@ F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c a1d075db66a0ea42807353501b62997969e5be79 F src/shell.c aa4183d4a5243d8110b1d3d77faa4aea7e9c9c2d -F src/sqlite.h.in e3e45b5c69ab3236c7ec4591a5858221863cecd4 +F src/sqlite.h.in e884dffa91721080e1792e73a2260485c9d2ffc1 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h 165409fa8adc8701148830804febeded3f2e4448 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -985,7 +985,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P c723e3e18a008922281d8d6e8e3aba07941eb173 -R a473dabc4c74a83ea005d83d596de923 -U dan -Z 9db758f12d3cf045a211ef0d51186bd2 +P f9c4a7c8f4e5821b47c1393d6272e32416d8886c +R 362f49b95b21624f3aae30c0009ec92f +U drh +Z 1c719257426fd1979e90548de4947ab1 diff --git a/manifest.uuid b/manifest.uuid index 0edb2fd4a3..1abc503440 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f9c4a7c8f4e5821b47c1393d6272e32416d8886c \ No newline at end of file +676acce274fec692a1eb34d27ee4b1327b4b3334 \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index 3e38d1df9f..29c6b0dcd0 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -130,7 +130,8 @@ sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){ sqlite3_int64 priorLimit; sqlite3_int64 excess; #ifndef SQLITE_OMIT_AUTOINIT - sqlite3_initialize(); + int rc = sqlite3_initialize(); + if( rc ) return -1; #endif sqlite3_mutex_enter(mem0.mutex); priorLimit = mem0.alarmThreshold; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 0e0e3af6b6..5bb1cb5323 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4608,7 +4608,8 @@ int sqlite3_db_release_memory(sqlite3*); ** is advisory only. ** ** ^The return value from sqlite3_soft_heap_limit64() is the size of -** the soft heap limit prior to the call. ^If the argument N is negative +** the soft heap limit prior to the call, or negative in the case of an +** error. ^If the argument N is negative ** then no change is made to the soft heap limit. Hence, the current ** size of the soft heap limit can be determined by invoking ** sqlite3_soft_heap_limit64() with a negative argument. From 64803bd2fabfb0316577dee1f2173e5baba19879 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 22 Dec 2011 17:31:17 +0000 Subject: [PATCH 135/161] Fix minor issues with FTS and RTREE discovered by coverity. FossilOrigin-Name: 1c27d842163e27c39bbe9409f50657b9de9ade6e --- ext/fts3/fts3_write.c | 10 ++-------- ext/rtree/rtree.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 11 insertions(+), 17 deletions(-) diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index fe9f26cf3e..0ee7ea81f1 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -1386,7 +1386,6 @@ int sqlite3Fts3SegReaderNew( int nRoot, /* Size of buffer containing root node */ Fts3SegReader **ppReader /* OUT: Allocated Fts3SegReader */ ){ - int rc = SQLITE_OK; /* Return code */ Fts3SegReader *pReader; /* Newly allocated SegReader object */ int nExtra = 0; /* Bytes to allocate segment root node */ @@ -1414,13 +1413,8 @@ int sqlite3Fts3SegReaderNew( }else{ pReader->iCurrentBlock = iStartLeaf-1; } - - if( rc==SQLITE_OK ){ - *ppReader = pReader; - }else{ - sqlite3Fts3SegReaderFree(pReader); - } - return rc; + *ppReader = pReader; + return SQLITE_OK; } /* diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 884482ea66..4c36f26171 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -1193,7 +1193,7 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ int nBlob; /* Check that value is actually a blob. */ - if( !sqlite3_value_type(pValue)==SQLITE_BLOB ) return SQLITE_ERROR; + if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR; /* Check that the blob is roughly the right size. */ nBlob = sqlite3_value_bytes(pValue); diff --git a/manifest b/manifest index 384275d8e0..1d52fc8814 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Check\sthe\sreturn\scode\sfrom\ssqlite3_initialize()\scalled\sfrom\swithin\nsqlite3_soft_heap_limit64()\sand\sreturn\san\serror\sfrom\ssqlite3_soft_heap_limit64()\nif\ssqlite3_initialize()\sfails. -D 2011-12-22T17:10:35.691 +C Fix\sminor\sissues\swith\sFTS\sand\sRTREE\sdiscovered\sby\scoverity. +D 2011-12-22T17:31:17.125 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -78,14 +78,14 @@ F ext/fts3/fts3_test.c 24fa13f330db011500acb95590da9eee24951894 F ext/fts3/fts3_tokenizer.c 9ff7ec66ae3c5c0340fa081958e64f395c71a106 F ext/fts3/fts3_tokenizer.h 13ffd9fcb397fec32a05ef5cd9e0fa659bf3dbd3 F ext/fts3/fts3_tokenizer1.c 0dde8f307b8045565cf63797ba9acfaff1c50c68 -F ext/fts3/fts3_write.c fb1998be659ff85b7045513ab625bbdcf9b804d8 +F ext/fts3/fts3_write.c fdf0c99830360146ec7128150271c8c014a8fef7 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 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 692e9192d148f318b3dca9f744600346a175eedd +F ext/rtree/rtree.c b92ab2e91e35c4964644647322813419c65fe1ce F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 28e1b8da4da98093ce3210187434dd760a8d89d8 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -985,7 +985,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P f9c4a7c8f4e5821b47c1393d6272e32416d8886c -R 362f49b95b21624f3aae30c0009ec92f +P 676acce274fec692a1eb34d27ee4b1327b4b3334 +R 8a1d21156d0abc4e02d468720492bfd4 U drh -Z 1c719257426fd1979e90548de4947ab1 +Z d6b64802c9259af408f51c1ca44ff382 diff --git a/manifest.uuid b/manifest.uuid index 1abc503440..fbfcdbf0a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -676acce274fec692a1eb34d27ee4b1327b4b3334 \ No newline at end of file +1c27d842163e27c39bbe9409f50657b9de9ade6e \ No newline at end of file From 9291372094ec5dfa66fb9ca67171a7d9c7b4ceba Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Dec 2011 00:07:33 +0000 Subject: [PATCH 136/161] Add interfaces sqlite3_uri_boolean() and sqlite3_uri_int64() which are wrappers around sqlite3_uri_parameter() combined with internal routines for converting strings to booleans and 64-bit integers. FossilOrigin-Name: 83d26b9a9115eadac9e59a33d608bca0ab2519e3 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/main.c | 25 +++++++++++++++++++++++++ src/os_unix.c | 4 +--- src/sqlite.h.in | 36 ++++++++++++++++++++++++++---------- src/test_multiplex.c | 28 ++++++---------------------- src/util.c | 4 +--- 7 files changed, 70 insertions(+), 49 deletions(-) diff --git a/manifest b/manifest index 1d52fc8814..2f08ae4c31 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sminor\sissues\swith\sFTS\sand\sRTREE\sdiscovered\sby\scoverity. -D 2011-12-22T17:31:17.125 +C Add\sinterfaces\ssqlite3_uri_boolean()\sand\ssqlite3_uri_int64()\swhich\sare\nwrappers\saround\ssqlite3_uri_parameter()\scombined\swith\sinternal\sroutines\sfor\nconverting\sstrings\sto\sbooleans\sand\s64-bit\sintegers. +D 2011-12-23T00:07:33.075 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d -F src/main.c c837e24182e8ec7121c61e44f547b59cbe413e7f +F src/main.c e2e3fb34be05658f41ac65ee5d9a44e00a358b48 F src/malloc.c 15afac5e59b6584efe072e9933aefb4230e74f97 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 7998e7003a3047e323c849a26dda004debc04d03 @@ -166,7 +166,7 @@ F src/os.c 28bbdab2170dfce84d86c45456a18eab1d0f99a9 F src/os.h 549b1a2e5e0ed1e1499f252dac126c4973e7379c F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c 7dc7df10331942b139032328449a3723e051979e +F src/os_unix.c ee4ea557de196798bafba1ac69f76a755035ebbb F src/os_win.c 197d23ce8a0dff748e766e034bf95ff756dd3884 F src/pager.c 523c64f6ca707e820d5cf10ed8371238ecac8333 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 @@ -182,7 +182,7 @@ F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c a1d075db66a0ea42807353501b62997969e5be79 F src/shell.c aa4183d4a5243d8110b1d3d77faa4aea7e9c9c2d -F src/sqlite.h.in e884dffa91721080e1792e73a2260485c9d2ffc1 +F src/sqlite.h.in db834f87316a1422051a97cba5beac31c0cb1b2d F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h 165409fa8adc8701148830804febeded3f2e4448 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 2c06e4be6584d51b935dc8b353980a9388de62ef F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c 6e07b94e2fe430f7f4f0d7d67b5e58f504dea655 +F src/test_multiplex.c 7a41891cda4c6b43298656d88e37e3c6244a90ff F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -238,7 +238,7 @@ F src/tokenize.c c819d9f72168a035d545a5bdafe9b085b20df705 F src/trigger.c ee7e178fb9188f44b532cebd449a7c1df90fb684 F src/update.c d3076782c887c10e882996550345da9c4c9f9dea F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 -F src/util.c 343508d359df65685b62e63964a40e7af4cfbe05 +F src/util.c 19ae3ee0dfa88e6054838afc5920327c5918fa2b F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa F src/vdbe.c 029add0c5197a61db588824a58570547330b9d8f F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb @@ -985,7 +985,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 676acce274fec692a1eb34d27ee4b1327b4b3334 -R 8a1d21156d0abc4e02d468720492bfd4 +P 1c27d842163e27c39bbe9409f50657b9de9ade6e +R 712ad6ea662046687d3fa2e6906d477a U drh -Z d6b64802c9259af408f51c1ca44ff382 +Z dfef488f9835a38d5955098b906ef223 diff --git a/manifest.uuid b/manifest.uuid index fbfcdbf0a5..0daedf9dab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1c27d842163e27c39bbe9409f50657b9de9ade6e \ No newline at end of file +83d26b9a9115eadac9e59a33d608bca0ab2519e3 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 690b73c2e7..94ea2fa2e5 100644 --- a/src/main.c +++ b/src/main.c @@ -2977,6 +2977,7 @@ int sqlite3_test_control(int op, ...){ ** returns a NULL pointer. */ const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){ + if( zFilename==0 ) return 0; zFilename += sqlite3Strlen30(zFilename) + 1; while( zFilename[0] ){ int x = strcmp(zFilename, zParam); @@ -2987,6 +2988,30 @@ const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){ return 0; } +/* +** Return a boolean value for a query parameter. +*/ +int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){ + const char *z = sqlite3_uri_parameter(zFilename, zParam); + return z ? sqlite3GetBoolean(z) : (bDflt!=0); +} + +/* +** Return a 64-bit integer value for a query parameter. +*/ +sqlite3_int64 sqlite3_uri_int64( + const char *zFilename, /* Filename as passed to xOpen */ + const char *zParam, /* URI parameter sought */ + sqlite3_int64 bDflt /* return if parameter is missing */ +){ + const char *z = sqlite3_uri_parameter(zFilename, zParam); + sqlite3_int64 v; + if( z && sqlite3Atoi64(z, &v, sqlite3Strlen30(z), SQLITE_UTF8)==SQLITE_OK ){ + bDflt = v; + } + return bDflt; +} + /* ** Return the filename of the database associated with a database ** connection. diff --git a/src/os_unix.c b/src/os_unix.c index ee5971f10e..5f26017b02 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3866,10 +3866,8 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ } if( pInode->bProcessLock==0 ){ - const char *zRO; int openFlags = O_RDWR | O_CREAT; - zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm"); - if( zRO && sqlite3GetBoolean(zRO) ){ + if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ openFlags = O_RDONLY; pShmNode->isReadonly = 1; } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 5bb1cb5323..ca0d7e3208 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2608,21 +2608,37 @@ int sqlite3_open_v2( /* ** CAPI3REF: Obtain Values For URI Parameters ** -** This is a utility routine, useful to VFS implementations, that checks +** These are utility routines, useful to VFS implementations, that check ** to see if a database file was a URI that contained a specific query -** parameter, and if so obtains the value of the query parameter. +** parameter, and if so obtains the value of that query parameter. ** -** The zFilename argument is the filename pointer passed into the xOpen() -** method of a VFS implementation. The zParam argument is the name of the -** query parameter we seek. This routine returns the value of the zParam -** parameter if it exists. If the parameter does not exist, this routine -** returns a NULL pointer. +** If F is the filename pointer passed into the xOpen() method of a VFS +** implementation and P is the name of the query parameter, then +** sqlite3_uri_parameter(F,P) returns the value of the P +** parameter if it exists or a NULL pointer if P does not appear as a +** query parameter on F. If P is a query parameter of F +** has no explicit value, then sqlite3_uri_parameter(F,P) returns +** a pointer to an empty string. ** -** If the zFilename argument to this function is not a pointer that SQLite -** passed into the xOpen VFS method, then the behavior of this routine -** is undefined and probably undesirable. +** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean +** parameter and returns true (1) or false (0) according to the value +** of P. The value of P is true if it is "yes" or "true" or "on" or +** a non-zero number and is false otherwise. If P is not a query parameter +** on F then sqlite3_uri_boolean(F,P,B) returns (B!=0). +** +** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a +** 64-bit signed integer and returns that integer, or D if P does not +** exist. If the value of P is something other than an integer, then +** zero is returned. +** +** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and +** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and +** is not a pathname pointer that SQLite passed into the xOpen VFS method, +** then the behavior of this routine is undefined and probably undesirable. */ const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); +int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); +sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); /* diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 25bfcdddd2..45f7310361 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -495,35 +495,19 @@ static int multiplexOpen( memset(pGroup, 0, sz); pMultiplexOpen->pGroup = pGroup; pGroup->bEnabled = -1; - pGroup->bTruncate = (flags & SQLITE_OPEN_MAIN_DB)==0; - pGroup->szChunk = SQLITE_MULTIPLEX_CHUNK_SIZE; - + pGroup->bTruncate = sqlite3_uri_boolean(zName, "truncate", + (flags & SQLITE_OPEN_MAIN_DB)==0); + pGroup->szChunk = sqlite3_uri_int64(zName, "chunksize", + SQLITE_MULTIPLEX_CHUNK_SIZE); + pGroup->szChunk = (pGroup->szChunk+0xffff)&~0xffff; if( zName ){ char *p = (char *)&pGroup[1]; - if( flags & SQLITE_OPEN_URI ){ - const char *zChunkSize; - zChunkSize = sqlite3_uri_parameter(zName, "chunksize"); - if( zChunkSize ){ - unsigned int n = 0; - int i; - for(i=0; zChunkSize[i]>='0' && zChunkSize[i]<='9'; i++){ - n = n*10 + zChunkSize[i] - '0'; - } - if( n>0 ){ - pGroup->szChunk = (n+0xffff)&~0xffff; - }else{ - /* A zero or negative chunksize disabled the multiplexor */ - pGroup->bEnabled = 0; - } - } - if( sqlite3_uri_parameter(zName, "truncate") ) pGroup->bTruncate = 1; - } pGroup->zName = p; memcpy(pGroup->zName, zName, nName+1); pGroup->nName = nName; } if( pGroup->bEnabled ){ - /* Make sure that the chunksize is not such that the pending byte + /* Make sure that the chunksize is such that the pending byte does not ** falls at the end of a chunk. A region of up to 64K following ** the pending byte is never written, so if the pending byte occurs ** near the end of a chunk, that chunk will be too small. */ diff --git a/src/util.c b/src/util.c index d27f6fdf26..a80b89a4ad 100644 --- a/src/util.c +++ b/src/util.c @@ -1173,9 +1173,7 @@ int sqlite3AbsInt32(int x){ */ void sqlite3FileSuffix3(const char *zBaseFilename, char *z){ #if SQLITE_ENABLE_8_3_NAMES<2 - const char *zOk; - zOk = sqlite3_uri_parameter(zBaseFilename, "8_3_names"); - if( zOk && sqlite3GetBoolean(zOk) ) + if( sqlite3_uri_boolean(zBaseFilename, "8_3_names") ) #endif { int i, sz; From cb15f35f3bcfe0ba3635ce1becc41c133838ceba Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Dec 2011 01:04:17 +0000 Subject: [PATCH 137/161] Change the name ZERO_DAMAGE to the more descriptive POWERSAFE_OVERWRITE. The query parameter used to control this device characteristic is now "psow". FossilOrigin-Name: 6191c5e45175f5c6040e891843b0725a929d6dd7 --- manifest | 32 ++++++++++++++++---------------- manifest.uuid | 2 +- src/os_unix.c | 33 +++++++++++++++++++-------------- src/os_win.c | 12 ++++++------ src/pager.c | 15 ++++++++------- src/sqlite.h.in | 41 +++++++++++++++++++++-------------------- src/sqliteInt.h | 8 ++++++++ src/test1.c | 16 ++++++++-------- src/test6.c | 24 ++++++++++++------------ src/test_vfs.c | 24 ++++++++++++------------ src/wal.c | 10 ++++++---- test/journal2.test | 2 +- test/zerodamage.test | 35 +++++++++++++++++++---------------- 13 files changed, 137 insertions(+), 117 deletions(-) diff --git a/manifest b/manifest index eaeb4c6775..5fe186261d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\strunk\schanges\sinto\sthe\sstatvfs\sbranch. -D 2011-12-23T00:25:02.544 +C Change\sthe\sname\sZERO_DAMAGE\sto\sthe\smore\sdescriptive\sPOWERSAFE_OVERWRITE.\nThe\squery\sparameter\sused\sto\scontrol\sthis\sdevice\scharacteristic\sis\snow\s"psow". +D 2011-12-23T01:04:17.601 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,9 +166,9 @@ F src/os.c 28bbdab2170dfce84d86c45456a18eab1d0f99a9 F src/os.h 549b1a2e5e0ed1e1499f252dac126c4973e7379c F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c ac21edf9794591badec31070a932845ef81f088e -F src/os_win.c f45f03e4585c31b5124771eb07ecce5b37a5c30a -F src/pager.c fb35a2c33667dd568b8df30fc11a4516e9889057 +F src/os_unix.c 3a441671f35569df4b72641e928fdb1ab5cd8576 +F src/os_win.c 569fe7448e781bfb8116aa79081df0eadf576fc6 +F src/pager.c d03fb1de7bd724f0cdcae0aab0a733d89c94ac2f F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba F src/pcache.c 1fdd77978c1525d1ca4b9ef48eb80abca710cb4c @@ -182,19 +182,19 @@ F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c a1d075db66a0ea42807353501b62997969e5be79 F src/shell.c aa4183d4a5243d8110b1d3d77faa4aea7e9c9c2d -F src/sqlite.h.in f414e44e9eb1d13804b9da0123ac082b0604bebf +F src/sqlite.h.in 3d1a77e27b9d9979fb7ec84834a8423602d29dc5 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 165409fa8adc8701148830804febeded3f2e4448 +F src/sqliteInt.h b8fdd9c39c8d7f5c794f4ea917293d9c75b9aff2 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c bd86070f52ae3f77a2e6b3b065ff03adb9140bfa -F src/test1.c 4cbabeb8b2c487f67d724e2ea03841b69fa640c4 +F src/test1.c 1b1e514e85ffe7152b02cba38bd0a1ce8cd56113 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7 F src/test5.c e1a19845625144caf038031234a12185e40d315c -F src/test6.c ffcc25c9b32e08e40754d85adb0a5d289721974a +F src/test6.c cf6ab27a59e1ab64b011bb251ba600131e803e59 F src/test7.c 2e0781754905c8adc3268d8f0967e7633af58843 F src/test8.c 99f70341d6ec480313775127f4cd14b4a47db557 F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60 @@ -230,7 +230,7 @@ F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_thread.c 35022393dd54d147b998b6b7f7e945b01114d666 -F src/test_vfs.c b241a08b5fa5bfec22983eba323e0ca621d3cea6 +F src/test_vfs.c 07157a0bbfe161cb5e32cad2079abd26cd611c4b F src/test_vfstrace.c 065c7270a614254b2c68fbc7ba8d1fb1d5cbc823 F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 @@ -250,7 +250,7 @@ F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a -F src/wal.c 842901b44832474b0f77f9a031455af3787ae277 +F src/wal.c 13c34ed72fd3a0cb81b3addbc901b3be60430cca F src/wal.h 42f8313f7aaf8913e2d1fdf7b47025c23491ea1d F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 @@ -545,7 +545,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe F test/join6.test bf82cf3f979e9eade83ad0d056a66c5ed71d1901 F test/journal1.test 8b71ef1ed5798bdc0e6eb616d8694e2c2c188d4d -F test/journal2.test 81f51a9f3e9b67c0efd4cdbb93752e064027ad96 +F test/journal2.test ae06f566c28552c313ded3fee79a6c69e6d049b1 F test/journal3.test 6fd28532c88b447db844186bc190523108b6dbb4 F test/jrnlmode.test 9ee3a78f53d52cca737db69293d15dc41c0cbd36 F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d @@ -941,7 +941,7 @@ F test/whereC.test 13ff5ec0dba407c0e0c075980c75b3275a6774e5 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 -F test/zerodamage.test 0e12b2d7343f1fbb015e56a4a2a6074336ff46cf +F test/zerodamage.test 7ef0680559163118705975be132933898d349674 F tool/build-shell.sh 12aa4391073a777fcb6dcc490b219a018ae98bac F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 995ec8a41a7d091d9d87cb8f18f62102c8fda7d7 83d26b9a9115eadac9e59a33d608bca0ab2519e3 -R 260e1493aa81c50b80cb4676fbf8b938 +P d5e36327c12f264429eb079bddbb71a310f76389 +R d510fa35ee7302e7724e03225e057408 U drh -Z de070232ec96f7f04c9c57b396f63bcc +Z cc6357a73838dede95445f3f634219d1 diff --git a/manifest.uuid b/manifest.uuid index cc4ba47667..7bfda38bdc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d5e36327c12f264429eb079bddbb71a310f76389 \ No newline at end of file +6191c5e45175f5c6040e891843b0725a929d6dd7 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 5378f862e9..adf11541ff 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -263,7 +263,7 @@ struct unixFile { #else # define UNIXFILE_DIRSYNC 0x00 #endif -#define UNIXFILE_ZERO_DAMAGE 0x10 /* True if SQLITE_IOCAP_ZERO_DAMAGE */ +#define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ /* ** Include code that is common to all os_*.c files @@ -3557,8 +3557,8 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg); return SQLITE_OK; } - case SQLITE_FCNTL_ZERO_DAMAGE: { - unixModeBit(pFile, UNIXFILE_ZERO_DAMAGE, (int*)pArg); + case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { + unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg); return SQLITE_OK; } case SQLITE_FCNTL_VFSNAME: { @@ -3622,18 +3622,23 @@ static int unixSectorSize(sqlite3_file *pFile){ /* ** Return the device characteristics for the file. ** -** This VFS is set up to return SQLITE_IOCAP_ZERO_DAMAGE by default. -** However, that choice is contraversial sicne technically the underlying -** file system does not always provide ZERO_DAMAGE. (In other words, after -** a power-loss event, parts of the file that were never written might end -** up being altered.) However, non-ZERO-DAMAGE behavior is very, very rare. -** And asserting ZERO_DAMAGE makes a large reduction in the amount of required -** I/O. Hence, while ZERO_DAMAGE is on by default, there is a file-control -** available to turn it off. +** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default. +** However, that choice is contraversial since technically the underlying +** file system does not always provide powersafe overwrites. (In other +** words, after a power-loss event, parts of the file that were never +** written might end up being altered.) However, non-PSOW behavior is very, +** very rare. And asserting PSOW makes a large reduction in the amount +** of required I/O for journaling, since a lot of padding is eliminated. +** Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control +** available to turn it off and URI query parameter available to turn it off. */ static int unixDeviceCharacteristics(sqlite3_file *id){ unixFile *p = (unixFile*)id; - return (p->ctrlFlags & UNIXFILE_ZERO_DAMAGE) ? SQLITE_IOCAP_ZERO_DAMAGE : 0; + if( p->ctrlFlags & UNIXFILE_PSOW ){ + return SQLITE_IOCAP_POWERSAFE_OVERWRITE; + }else{ + return 0; + } } #ifndef SQLITE_OMIT_WAL @@ -4617,8 +4622,8 @@ static int fillInUnixFile( pNew->pVfs = pVfs; pNew->zPath = zFilename; pNew->ctrlFlags = 0; - if( sqlite3_uri_boolean(zFilename, "zero_damage", 1) ){ - pNew->ctrlFlags |= UNIXFILE_ZERO_DAMAGE; + if( sqlite3_uri_boolean(zFilename, "psow", SQLITE_POWERSAFE_OVERWRITE) ){ + pNew->ctrlFlags |= UNIXFILE_PSOW; } if( memcmp(pVfs->zName,"unix-excl",10)==0 ){ pNew->ctrlFlags |= UNIXFILE_EXCL; diff --git a/src/os_win.c b/src/os_win.c index 85bf9d89bb..18fdd93933 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -78,7 +78,7 @@ struct winFile { ** Allowed values for winFile.ctrlFlags */ #define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ -#define WINFILE_ZERO_DAMAGE 0x10 /* True if SQLITE_IOCAP_ZERO_DAMAGE */ +#define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ /* * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the @@ -2185,8 +2185,8 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg); return SQLITE_OK; } - case SQLITE_FCNTL_ZERO_DAMAGE: { - winModeBit(pFile, WINFILE_ZERO_DAMAGE, (int*)pArg); + case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { + winModeBit(pFile, WINFILE_PSOW, (int*)pArg); return SQLITE_OK; } case SQLITE_FCNTL_VFSNAME: { @@ -2235,7 +2235,7 @@ static int winSectorSize(sqlite3_file *id){ static int winDeviceCharacteristics(sqlite3_file *id){ winFile *p = (winFile*)id; return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | - ((p->ctrlFlags & WINFILE_ZERO_DAMAGE)?SQLITE_IOCAP_ZERO_DAMAGE:0); + ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); } #ifndef SQLITE_OMIT_WAL @@ -3200,8 +3200,8 @@ static int winOpen( pFile->pVfs = pVfs; pFile->pShm = 0; pFile->zPath = zName; - if( sqlite3_uri_boolean(zName, "zero_damage", 1) ){ - pFile->ctrlFlags |= WINFILE_ZERO_DAMAGE; + if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){ + pFile->ctrlFlags |= WINFILE_PSOW; } pFile->sectorSize = getSectorSize(pVfs, zUtf8Name); diff --git a/src/pager.c b/src/pager.c index f6c8f2fa53..892c245b44 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2516,20 +2516,21 @@ static int pager_truncate(Pager *pPager, Pgno nPage){ ** it is less than 32, or rounded down to MAX_SECTOR_SIZE if it ** is greater than MAX_SECTOR_SIZE. ** -** If the file has the SQLITE_IOCAP_ZERO_DAMAGE property, then set the -** effective sector size to its minimum value (512). The purpose of +** If the file has the SQLITE_IOCAP_POWERSAFE_OVERWRITE property, then set +** the effective sector size to its minimum value (512). The purpose of ** pPager->sectorSize is to define the "blast radius" of bytes that ** might change if a crash occurs while writing to a single byte in -** that range. But with ZERO_DAMAGE, the blast radius is zero, so -** we minimize the sector size. For backwards compatibility of the -** rollback journal file format, we cannot reduce the effective sector -** size below 512. +** that range. But with POWERSAFE_OVERWRITE, the blast radius is zero +** (that is what POWERSAFE_OVERWRITE means), so we minimize the sector +** size. For backwards compatibility of the rollback journal file format, +** we cannot reduce the effective sector size below 512. */ static void setSectorSize(Pager *pPager){ assert( isOpen(pPager->fd) || pPager->tempFile ); if( pPager->tempFile - || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_ZERO_DAMAGE)!=0 + || (sqlite3OsDeviceCharacteristics(pPager->fd) & + SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0 ){ /* Sector size doesn't matter for temporary files. Also, the file ** may not have been opened yet, in which case the OsSectorSize() diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 3748aada25..85ebd67a9f 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -504,11 +504,12 @@ int sqlite3_exec( ** first then the size of the file is extended, never the other ** way around. The SQLITE_IOCAP_SEQUENTIAL property means that ** information is written to disk in the same order as calls -** to xWrite(). The SQLITE_IOCAP_ZERO_DAMAGE property means that +** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that ** after reboot following a crash or power loss, the value of ** each byte in a file is a value that was actually written ** into that byte at some point. In other words, a crash will -** not introduce garbage or randomness into a file, and byte of +** not cause unwritten bytes of the file to change nor introduce +** randomness into a file nor zero out parts of the file, and any byte of ** a file that are never written will not change values due to ** writes to nearby bytes. */ @@ -524,7 +525,7 @@ int sqlite3_exec( #define SQLITE_IOCAP_SAFE_APPEND 0x00000200 #define SQLITE_IOCAP_SEQUENTIAL 0x00000400 #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 -#define SQLITE_IOCAP_ZERO_DAMAGE 0x00001000 +#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 /* ** CAPI3REF: File Locking Levels @@ -774,10 +775,10 @@ struct sqlite3_io_methods { ** WAL mode. If the integer is -1, then it is overwritten with the current ** WAL persistence setting. ** -** ^The [SQLITE_FCNTL_ZERO_DAMAGE] opcode is used to set or query the -** persistent zero-damage setting. The zero-damage setting determines -** the [SQLITE_IOCAP_ZERO_DAMAGE] bit of the xDeviceCharacteristics methods. -** The fourth parameter to +** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the +** persistent "powersafe-overwrite" or "PSOW" setting. The PSOW setting +** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the +** xDeviceCharacteristics methods. The fourth parameter to ** [sqlite3_file_control()] for this opcode should be a pointer to an integer. ** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage ** mode. If the integer is -1, then it is overwritten with the current @@ -799,19 +800,19 @@ struct sqlite3_io_methods { ** pointer in case this file-control is not implemented. This file-control ** is intended for diagnostic use only. */ -#define SQLITE_FCNTL_LOCKSTATE 1 -#define SQLITE_GET_LOCKPROXYFILE 2 -#define SQLITE_SET_LOCKPROXYFILE 3 -#define SQLITE_LAST_ERRNO 4 -#define SQLITE_FCNTL_SIZE_HINT 5 -#define SQLITE_FCNTL_CHUNK_SIZE 6 -#define SQLITE_FCNTL_FILE_POINTER 7 -#define SQLITE_FCNTL_SYNC_OMITTED 8 -#define SQLITE_FCNTL_WIN32_AV_RETRY 9 -#define SQLITE_FCNTL_PERSIST_WAL 10 -#define SQLITE_FCNTL_OVERWRITE 11 -#define SQLITE_FCNTL_VFSNAME 12 -#define SQLITE_FCNTL_ZERO_DAMAGE 13 +#define SQLITE_FCNTL_LOCKSTATE 1 +#define SQLITE_GET_LOCKPROXYFILE 2 +#define SQLITE_SET_LOCKPROXYFILE 3 +#define SQLITE_LAST_ERRNO 4 +#define SQLITE_FCNTL_SIZE_HINT 5 +#define SQLITE_FCNTL_CHUNK_SIZE 6 +#define SQLITE_FCNTL_FILE_POINTER 7 +#define SQLITE_FCNTL_SYNC_OMITTED 8 +#define SQLITE_FCNTL_WIN32_AV_RETRY 9 +#define SQLITE_FCNTL_PERSIST_WAL 10 +#define SQLITE_FCNTL_OVERWRITE 11 +#define SQLITE_FCNTL_VFSNAME 12 +#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 /* ** CAPI3REF: Mutex Handle diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8613d865aa..6e48b1c4f2 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -125,6 +125,14 @@ #endif #endif +/* +** Powersafe overwrite is on by default. But can be turned off using +** the -DSQLITE_POWERSAFE_OVERWRITE=0 command-line option. +*/ +#ifndef SQLITE_POWERSAFE_OVERWRITE +# define SQLITE_POWERSAFE_OVERWRITE 1 +#endif + /* ** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1. ** It determines whether or not the features related to diff --git a/src/test1.c b/src/test1.c index b96b99ce8d..9cc5d6347c 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5236,12 +5236,12 @@ static int file_control_persist_wal( } /* -** tclcmd: file_control_zero_damage DB ZERO-DAMAGE-FLAG +** tclcmd: file_control_powersafe_overwrite DB PSOW-FLAG ** ** This TCL command runs the sqlite3_file_control interface with -** the SQLITE_FCNTL_ZERO_DAMAGE opcode. +** the SQLITE_FCNTL_POWERSAFE_OVERWRITE opcode. */ -static int file_control_zero_damage( +static int file_control_powersafe_overwrite( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5249,7 +5249,7 @@ static int file_control_zero_damage( ){ sqlite3 *db; int rc; - int bDamage; + int b; char z[100]; if( objc!=3 ){ @@ -5260,9 +5260,9 @@ static int file_control_zero_damage( if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ return TCL_ERROR; } - if( Tcl_GetIntFromObj(interp, objv[2], &bDamage) ) return TCL_ERROR; - rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_ZERO_DAMAGE,(void*)&bDamage); - sqlite3_snprintf(sizeof(z), z, "%d %d", rc, bDamage); + if( Tcl_GetIntFromObj(interp, objv[2], &b) ) return TCL_ERROR; + rc = sqlite3_file_control(db,NULL,SQLITE_FCNTL_POWERSAFE_OVERWRITE,(void*)&b); + sqlite3_snprintf(sizeof(z), z, "%d %d", rc, b); Tcl_AppendResult(interp, z, (char*)0); return TCL_OK; } @@ -6125,7 +6125,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "file_control_sizehint_test", file_control_sizehint_test, 0 }, { "file_control_win32_av_retry", file_control_win32_av_retry, 0 }, { "file_control_persist_wal", file_control_persist_wal, 0 }, - { "file_control_zero_damage", file_control_zero_damage, 0 }, + { "file_control_powersafe_overwrite",file_control_powersafe_overwrite,0}, { "file_control_vfsname", file_control_vfsname, 0 }, { "sqlite3_vfs_list", vfs_list, 0 }, { "sqlite3_create_function_v2", test_create_function_v2, 0 }, diff --git a/src/test6.c b/src/test6.c index 1bb9c65f05..89f4a090b0 100644 --- a/src/test6.c +++ b/src/test6.c @@ -705,18 +705,18 @@ static int processDevSymArgs( char *zName; int iValue; } aFlag[] = { - { "atomic", SQLITE_IOCAP_ATOMIC }, - { "atomic512", SQLITE_IOCAP_ATOMIC512 }, - { "atomic1k", SQLITE_IOCAP_ATOMIC1K }, - { "atomic2k", SQLITE_IOCAP_ATOMIC2K }, - { "atomic4k", SQLITE_IOCAP_ATOMIC4K }, - { "atomic8k", SQLITE_IOCAP_ATOMIC8K }, - { "atomic16k", SQLITE_IOCAP_ATOMIC16K }, - { "atomic32k", SQLITE_IOCAP_ATOMIC32K }, - { "atomic64k", SQLITE_IOCAP_ATOMIC64K }, - { "sequential", SQLITE_IOCAP_SEQUENTIAL }, - { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, - { "zero_damage", SQLITE_IOCAP_ZERO_DAMAGE }, + { "atomic", SQLITE_IOCAP_ATOMIC }, + { "atomic512", SQLITE_IOCAP_ATOMIC512 }, + { "atomic1k", SQLITE_IOCAP_ATOMIC1K }, + { "atomic2k", SQLITE_IOCAP_ATOMIC2K }, + { "atomic4k", SQLITE_IOCAP_ATOMIC4K }, + { "atomic8k", SQLITE_IOCAP_ATOMIC8K }, + { "atomic16k", SQLITE_IOCAP_ATOMIC16K }, + { "atomic32k", SQLITE_IOCAP_ATOMIC32K }, + { "atomic64k", SQLITE_IOCAP_ATOMIC64K }, + { "sequential", SQLITE_IOCAP_SEQUENTIAL }, + { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, + { "powersafe_overwrite", SQLITE_IOCAP_POWERSAFE_OVERWRITE }, { 0, 0 } }; diff --git a/src/test_vfs.c b/src/test_vfs.c index 2c985a7db7..a79407b57f 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -1162,19 +1162,19 @@ static int testvfs_obj_cmd( int iValue; } aFlag[] = { { "default", -1 }, - { "atomic", SQLITE_IOCAP_ATOMIC }, - { "atomic512", SQLITE_IOCAP_ATOMIC512 }, - { "atomic1k", SQLITE_IOCAP_ATOMIC1K }, - { "atomic2k", SQLITE_IOCAP_ATOMIC2K }, - { "atomic4k", SQLITE_IOCAP_ATOMIC4K }, - { "atomic8k", SQLITE_IOCAP_ATOMIC8K }, - { "atomic16k", SQLITE_IOCAP_ATOMIC16K }, - { "atomic32k", SQLITE_IOCAP_ATOMIC32K }, - { "atomic64k", SQLITE_IOCAP_ATOMIC64K }, - { "sequential", SQLITE_IOCAP_SEQUENTIAL }, - { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, + { "atomic", SQLITE_IOCAP_ATOMIC }, + { "atomic512", SQLITE_IOCAP_ATOMIC512 }, + { "atomic1k", SQLITE_IOCAP_ATOMIC1K }, + { "atomic2k", SQLITE_IOCAP_ATOMIC2K }, + { "atomic4k", SQLITE_IOCAP_ATOMIC4K }, + { "atomic8k", SQLITE_IOCAP_ATOMIC8K }, + { "atomic16k", SQLITE_IOCAP_ATOMIC16K }, + { "atomic32k", SQLITE_IOCAP_ATOMIC32K }, + { "atomic64k", SQLITE_IOCAP_ATOMIC64K }, + { "sequential", SQLITE_IOCAP_SEQUENTIAL }, + { "safe_append", SQLITE_IOCAP_SAFE_APPEND }, { "undeletable_when_open", SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN }, - { "zero_damage", SQLITE_IOCAP_ZERO_DAMAGE }, + { "powersafe_overwrite", SQLITE_IOCAP_POWERSAFE_OVERWRITE }, { 0, 0 } }; Tcl_Obj *pRet; diff --git a/src/wal.c b/src/wal.c index d3b66b5b9f..904138723d 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1305,7 +1305,9 @@ int sqlite3WalOpen( }else{ int iDC = sqlite3OsDeviceCharacteristics(pRet->pWalFd); if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; } - if( iDC & SQLITE_IOCAP_ZERO_DAMAGE ){ pRet->padToSectorBoundary = 0; } + if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){ + pRet->padToSectorBoundary = 0; + } *ppWal = pRet; WALTRACE(("WAL%d: opened\n", pRet)); } @@ -2810,9 +2812,9 @@ int sqlite3WalFrames( ** transaction and if PRAGMA synchronous=FULL. If synchronous==NORMAL ** or synchonous==OFF, then no padding or syncing are needed. ** - ** If SQLITE_IOCAP_ZERO_DAMAGE is defined, then padding is not needed - ** and only the sync is done. If padding is needed, then the final - ** frame is repeated (with its commit mark) until the next sector + ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not + ** needed and only the sync is done. If padding is needed, then the + ** final frame is repeated (with its commit mark) until the next sector ** boundary is crossed. Only the part of the WAL prior to the last ** sector boundary is synced; the part of the last frame that extends ** past the sector boundary is written after the sync. diff --git a/test/journal2.test b/test/journal2.test index 2272f139f4..8f9b4d0b71 100644 --- a/test/journal2.test +++ b/test/journal2.test @@ -34,7 +34,7 @@ proc a_string {n} { # characteristics flags to "SAFE_DELETE". # testvfs tvfs -default 1 -tvfs devchar {undeletable_when_open zero_damage} +tvfs devchar {undeletable_when_open powersafe_overwrite} # Set up a hook so that each time a journal file is opened, closed or # deleted, the method name ("xOpen", "xClose" or "xDelete") and the final diff --git a/test/zerodamage.test b/test/zerodamage.test index bef82b2eda..0e82ce3505 100644 --- a/test/zerodamage.test +++ b/test/zerodamage.test @@ -9,29 +9,32 @@ # #*********************************************************************** # -# This file implements tests of the SQLITE_IOCAP_ZERO_DAMAGE property -# and the SQLITE_FCNTL_ZERO_DAMAGE file-control for manipulating it. +# This file implements tests of the SQLITE_IOCAP_POWERSAFE_OVERWRITE property +# and the SQLITE_FCNTL_POWERSAFE_OVERWRITE file-control for manipulating it. +# +# The name of this file comes from the fact that we used to call the +# POWERSAFE_OVERWRITE property ZERO_DAMAGE. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix wal5 -# ZERO_DAMAGE defaults to true +# POWERSAFE_OVERWRITE defaults to true # do_test zerodamage-1.0 { - file_control_zero_damage db -1 + file_control_powersafe_overwrite db -1 } {0 1} # Check the ability to turn zero-damage on and off. # do_test zerodamage-1.1 { - file_control_zero_damage db 0 - file_control_zero_damage db -1 + file_control_powersafe_overwrite db 0 + file_control_powersafe_overwrite db -1 } {0 0} do_test zerodamage-1.2 { - file_control_zero_damage db 1 - file_control_zero_damage db -1 + file_control_powersafe_overwrite db 1 + file_control_powersafe_overwrite db -1 } {0 1} # Run a transaction with zero-damage on, a small page size and a much larger @@ -42,7 +45,7 @@ do_test zerodamage-2.0 { db close testvfs tv -default 1 tv sectorsize 8192 - sqlite3 db file:test.db?zero_damage=1 -uri 1 + sqlite3 db file:test.db?psow=TRUE -uri 1 unset -nocomplain ::max_journal_size set ::max_journal_size 0 proc xDeleteCallback {method file args} { @@ -65,7 +68,7 @@ do_test zerodamage-2.0 { db eval { UPDATE t1 SET y=randomblob(50) WHERE x=123; } - concat [file_control_zero_damage db -1] [set ::max_journal_size] + concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size] } {0 1 2576} # Repeat the previous step with zero-damage turned off. This time the @@ -74,14 +77,14 @@ do_test zerodamage-2.0 { do_test zerodamage-2.1 { set ::max_journal_size 0 db close - sqlite3 db file:test.db?zero_damage=0 -uri 1 + sqlite3 db file:test.db?psow=FALSE -uri 1 db eval { UPDATE t1 SET y=randomblob(50) WHERE x=124; } - concat [file_control_zero_damage db -1] [set ::max_journal_size] + concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size] } {0 0 24704} -# Run a WAL-mode transaction with ZERO_DAMAGE on to verify that the +# Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the # WAL file does not get too big. # do_test zerodamage-3.0 { @@ -89,19 +92,19 @@ do_test zerodamage-3.0 { PRAGMA journal_mode=WAL; } db close - sqlite3 db file:test.db?zero_damage=1 -uri 1 + sqlite3 db file:test.db?psow=TRUE -uri 1 db eval { UPDATE t1 SET y=randomblob(50) WHERE x=124; } file size test.db-wal } {1080} -# Repeat the previous with ZERO_DAMAGE off. Verify that the WAL file +# Repeat the previous with POWERSAFE_OVERWRITE off. Verify that the WAL file # is padded. # do_test zerodamage-3.1 { db close - sqlite3 db file:test.db?zero_damage=0 -uri 1 + sqlite3 db file:test.db?psow=FALSE -uri 1 db eval { UPDATE t1 SET y=randomblob(50) WHERE x=124; } From 4e5e108e83ee917a6a425e1bc8a18a4aa2d7b196 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Dec 2011 13:32:07 +0000 Subject: [PATCH 138/161] Avoid excess syncs when padding a transaction in a WAL. FossilOrigin-Name: 1f24ae716df6232de768e245ea990049deee3c22 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wal.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 1aebed56f7..4d1c60afe0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sPOWERSAFE_OVERWRITE\sfeatures\sand\sthe\suse\sof\sstatvfs()\sfrom\sthe\nstatvfs\sbranch\sinto\strunk. -D 2011-12-23T02:07:10.640 +C Avoid\sexcess\ssyncs\swhen\spadding\sa\stransaction\sin\sa\sWAL. +D 2011-12-23T13:32:07.917 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -250,7 +250,7 @@ F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a -F src/wal.c 66e2afeec77933f80c8098cfb3c0b29bc875de0f +F src/wal.c 4800adb021db953138eafdda825f95bc050e5b98 F src/wal.h 42f8313f7aaf8913e2d1fdf7b47025c23491ea1d F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 83d26b9a9115eadac9e59a33d608bca0ab2519e3 6191c5e45175f5c6040e891843b0725a929d6dd7 -R 9e1524ff0804966ed866a28455ef991b +P 2370d70eb51d2259aaa8073d861ab79d6637cbd9 +R 070cfae8b4f17992d010f84eb7fc87cd U drh -Z 88029f358469c654bea2978d031e29f2 +Z ce9eb9870fa6375b9586d00c63492f9d diff --git a/manifest.uuid b/manifest.uuid index 18ed65b934..e351e25035 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2370d70eb51d2259aaa8073d861ab79d6637cbd9 \ No newline at end of file +1f24ae716df6232de768e245ea990049deee3c22 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 657d59d527..076ba9633d 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2829,8 +2829,9 @@ int sqlite3WalFrames( iOffset += szFrame; nExtra++; } + }else{ + rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK); } - rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK); } /* If this frame set completes the first transaction in the WAL and From 4eaff93e4b215e9e6de218d308c1543495c9271a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Dec 2011 20:49:26 +0000 Subject: [PATCH 139/161] Documentation updates. No changes to code. FossilOrigin-Name: a8a1a639fe441a533b11ada7368b2200edea7a05 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 11 ++++------- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 4d1c60afe0..4180f9892f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sexcess\ssyncs\swhen\spadding\sa\stransaction\sin\sa\sWAL. -D 2011-12-23T13:32:07.917 +C Documentation\supdates.\s\sNo\schanges\sto\scode. +D 2011-12-23T20:49:26.881 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -182,7 +182,7 @@ F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c a1d075db66a0ea42807353501b62997969e5be79 F src/shell.c aa4183d4a5243d8110b1d3d77faa4aea7e9c9c2d -F src/sqlite.h.in 3d1a77e27b9d9979fb7ec84834a8423602d29dc5 +F src/sqlite.h.in c78aa4b9e0eba0e671fdbef13d8d07125c504a32 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h b8fdd9c39c8d7f5c794f4ea917293d9c75b9aff2 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 2370d70eb51d2259aaa8073d861ab79d6637cbd9 -R 070cfae8b4f17992d010f84eb7fc87cd +P 1f24ae716df6232de768e245ea990049deee3c22 +R 3f80d501a005f63063af2f8ab95e37cd U drh -Z ce9eb9870fa6375b9586d00c63492f9d +Z 04aada2484a2858d2fcd0e96317998a2 diff --git a/manifest.uuid b/manifest.uuid index e351e25035..7e8c84c7be 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1f24ae716df6232de768e245ea990049deee3c22 \ No newline at end of file +a8a1a639fe441a533b11ada7368b2200edea7a05 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 85ebd67a9f..9f47366cb3 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -505,13 +505,10 @@ int sqlite3_exec( ** way around. The SQLITE_IOCAP_SEQUENTIAL property means that ** information is written to disk in the same order as calls ** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that -** after reboot following a crash or power loss, the value of -** each byte in a file is a value that was actually written -** into that byte at some point. In other words, a crash will -** not cause unwritten bytes of the file to change nor introduce -** randomness into a file nor zero out parts of the file, and any byte of -** a file that are never written will not change values due to -** writes to nearby bytes. +** after reboot following a crash or power loss, the only bytes in a +** file that were written at the application level might have changed +** and that adjacent bytes, even bytes within the same sector are +** guaranteed to be unchanged. */ #define SQLITE_IOCAP_ATOMIC 0x00000001 #define SQLITE_IOCAP_ATOMIC512 0x00000002 From 44659c941781fbd61d636c055c06843f9a23f575 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 Dec 2011 05:08:41 +0000 Subject: [PATCH 140/161] Fix some typos in comments. No code changes. FossilOrigin-Name: 4edc5994b26e1fd3245572cb80242d07ba20a475 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/os.c | 2 +- src/sqlite.h.in | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 4180f9892f..392de553ec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Documentation\supdates.\s\sNo\schanges\sto\scode. -D 2011-12-23T20:49:26.881 +C Fix\ssome\stypos\sin\scomments.\sNo\scode\schanges. +D 2011-12-30T05:08:41.951 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -162,7 +162,7 @@ F src/mutex_os2.c 882d735098c07c8c6a5472b8dd66e19675fe117f F src/mutex_unix.c b4f4e923bb8de93ec3f251fadb50855f23df9579 F src/mutex_w32.c 5e54f3ba275bcb5d00248b8c23107df2e2f73e33 F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 -F src/os.c 28bbdab2170dfce84d86c45456a18eab1d0f99a9 +F src/os.c 519bdf7c608c4848024e1d87934f9305454145f4 F src/os.h 549b1a2e5e0ed1e1499f252dac126c4973e7379c F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 @@ -182,7 +182,7 @@ F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c a1d075db66a0ea42807353501b62997969e5be79 F src/shell.c aa4183d4a5243d8110b1d3d77faa4aea7e9c9c2d -F src/sqlite.h.in c78aa4b9e0eba0e671fdbef13d8d07125c504a32 +F src/sqlite.h.in 5d2d6c3f542ec484e769784014ef659b86e30aaa F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h b8fdd9c39c8d7f5c794f4ea917293d9c75b9aff2 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 1f24ae716df6232de768e245ea990049deee3c22 -R 3f80d501a005f63063af2f8ab95e37cd -U drh -Z 04aada2484a2858d2fcd0e96317998a2 +P a8a1a639fe441a533b11ada7368b2200edea7a05 +R 543342ae679dc2b9a76e5d06ebe795fb +U dan +Z cff3fff2b321de20b23137e8553f1cda diff --git a/manifest.uuid b/manifest.uuid index 7e8c84c7be..edfd491f47 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a8a1a639fe441a533b11ada7368b2200edea7a05 \ No newline at end of file +4edc5994b26e1fd3245572cb80242d07ba20a475 \ No newline at end of file diff --git a/src/os.c b/src/os.c index a347ec1d02..c26429bf9a 100644 --- a/src/os.c +++ b/src/os.c @@ -141,7 +141,7 @@ int sqlite3OsOpen( ){ int rc; DO_OS_MALLOC_TEST(0); - /* 0x87f3f is a mask of SQLITE_OPEN_ flags that are valid to be passed + /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example, ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before ** reaching the VFS. */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 9f47366cb3..b4f8d56102 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -366,7 +366,7 @@ int sqlite3_exec( ** KEYWORDS: {result code} {result codes} ** ** Many SQLite functions return an integer result code from the set shown -** here in order to indicates success or failure. +** here in order to indicate success or failure. ** ** New error codes may be added in future versions of SQLite. ** @@ -744,12 +744,12 @@ struct sqlite3_io_methods { ** ** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic ** retry counts and intervals for certain disk I/O operations for the -** windows [VFS] in order to work to provide robustness against +** windows [VFS] in order to provide robustness in the presence of ** anti-virus programs. By default, the windows VFS will retry file read, ** file write, and file delete operations up to 10 times, with a delay ** of 25 milliseconds before the first retry and with the delay increasing ** by an additional 25 milliseconds with each subsequent retry. This -** opcode allows those to values (10 retries and 25 milliseconds of delay) +** opcode allows these two values (10 retries and 25 milliseconds of delay) ** to be adjusted. The values are changed for all database connections ** within the same process. The argument is a pointer to an array of two ** integers where the first integer i the new retry count and the second @@ -2015,7 +2015,7 @@ void sqlite3_free_table(char **result); ** All of the usual printf() formatting options apply. In addition, there ** is are "%q", "%Q", and "%z" options. ** -** ^(The %q option works like %s in that it substitutes a null-terminated +** ^(The %q option works like %s in that it substitutes a nul-terminated ** string from the argument list. But %q also doubles every '\'' character. ** %q is designed for use inside a string literal.)^ By doubling each '\'' ** character it escapes that character and allows it to be inserted into @@ -3535,7 +3535,7 @@ int sqlite3_data_count(sqlite3_stmt *pStmt); ** bytes in the string, not the number of characters. ** ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(), -** even empty strings, are always zero terminated. ^The return +** even empty strings, are always zero-terminated. ^The return ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. ** ** ^The object returned by [sqlite3_column_value()] is an @@ -5596,7 +5596,7 @@ struct sqlite3_mutex_methods { ** ^These routines should return true if the mutex in their argument ** is held or not held, respectively, by the calling thread. ** -** ^The implementation is not required to provided versions of these +** ^The implementation is not required to provide versions of these ** routines that actually work. If the implementation does not provide working ** versions of these routines, it should at least provide stubs that always ** return true so that one does not get spurious assertion failures. From 0e208252c92206760d2208603acf7d594f7489ce Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 Dec 2011 09:00:19 +0000 Subject: [PATCH 141/161] Change an implicit i64-to-int cast in pager.c to an explicit cast. FossilOrigin-Name: 6a71ba9ce930838d44ed8d399075ba0723c9132b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 392de553ec..47d18e93ef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\stypos\sin\scomments.\sNo\scode\schanges. -D 2011-12-30T05:08:41.951 +C Change\san\simplicit\si64-to-int\scast\sin\spager.c\sto\san\sexplicit\scast. +D 2011-12-30T09:00:19.278 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -168,7 +168,7 @@ F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 3a441671f35569df4b72641e928fdb1ab5cd8576 F src/os_win.c 569fe7448e781bfb8116aa79081df0eadf576fc6 -F src/pager.c d03fb1de7bd724f0cdcae0aab0a733d89c94ac2f +F src/pager.c 0ae6079dd6109d475e54ff2ce3131dd0a3fea24f F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba F src/pcache.c 1fdd77978c1525d1ca4b9ef48eb80abca710cb4c @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P a8a1a639fe441a533b11ada7368b2200edea7a05 -R 543342ae679dc2b9a76e5d06ebe795fb +P 4edc5994b26e1fd3245572cb80242d07ba20a475 +R 1bc770471ba89216f7a16ad43b7ad6d5 U dan -Z cff3fff2b321de20b23137e8553f1cda +Z 18d47a3b5d2edb28ffe71e9399d7b1d4 diff --git a/manifest.uuid b/manifest.uuid index edfd491f47..1bde373959 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4edc5994b26e1fd3245572cb80242d07ba20a475 \ No newline at end of file +6a71ba9ce930838d44ed8d399075ba0723c9132b \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 892c245b44..e1a3385b05 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4370,7 +4370,8 @@ int sqlite3PagerOpen( z += sqlite3Strlen30(z)+1; z += sqlite3Strlen30(z)+1; } - nUri = &z[1] - zUri; + nUri = (int)(&z[1] - zUri); + assert( nUri>=0 ); if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){ /* This branch is taken when the journal path required by ** the database being opened will be more than pVfs->mxPathname From 0420b74a94e3a040f568854038915fc94bff1370 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 Dec 2011 10:54:24 +0000 Subject: [PATCH 142/161] Minor changes to fix compilation with SQLITE_OMIT_WAL and SQLITE_OMIT_WSD defined. FossilOrigin-Name: 26a513a8d2dddfde82f5fd0a0e1cc186c9b0df94 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_multiplex.c | 4 ++++ src/wal.h | 12 ++++++------ 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 47d18e93ef..f98c6c5327 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\san\simplicit\si64-to-int\scast\sin\spager.c\sto\san\sexplicit\scast. -D 2011-12-30T09:00:19.278 +C Minor\schanges\sto\sfix\scompilation\swith\sSQLITE_OMIT_WAL\sand\sSQLITE_OMIT_WSD\sdefined. +D 2011-12-30T10:54:24.715 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 2c06e4be6584d51b935dc8b353980a9388de62ef F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 -F src/test_multiplex.c 7a41891cda4c6b43298656d88e37e3c6244a90ff +F src/test_multiplex.c 2bf2eb36c9eff73c808ba6d19388e2f577438d9e F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec @@ -251,7 +251,7 @@ F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a F src/wal.c 4800adb021db953138eafdda825f95bc050e5b98 -F src/wal.h 42f8313f7aaf8913e2d1fdf7b47025c23491ea1d +F src/wal.h eaa00b9a403ddda2b56d01b7afc19ef600f9363f F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 4edc5994b26e1fd3245572cb80242d07ba20a475 -R 1bc770471ba89216f7a16ad43b7ad6d5 +P 6a71ba9ce930838d44ed8d399075ba0723c9132b +R 579eb5da5cf1f5387840a047b3fbeef2 U dan -Z 18d47a3b5d2edb28ffe71e9399d7b1d4 +Z 6dd1d82cc9bb099d02383a4750cf40f4 diff --git a/manifest.uuid b/manifest.uuid index 1bde373959..22d07c070d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6a71ba9ce930838d44ed8d399075ba0723c9132b \ No newline at end of file +26a513a8d2dddfde82f5fd0a0e1cc186c9b0df94 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 45f7310361..eceb8d74ab 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -511,7 +511,11 @@ static int multiplexOpen( ** falls at the end of a chunk. A region of up to 64K following ** the pending byte is never written, so if the pending byte occurs ** near the end of a chunk, that chunk will be too small. */ +#ifndef SQLITE_OMIT_WSD extern int sqlite3PendingByte; +#else + int sqlite3PendingByte = 0x40000000; +#endif while( (sqlite3PendingByte % pGroup->szChunk)>=(pGroup->szChunk-65536) ){ pGroup->szChunk += 65536; } diff --git a/src/wal.h b/src/wal.h index 7cd84be997..fac762e870 100644 --- a/src/wal.h +++ b/src/wal.h @@ -19,6 +19,12 @@ #include "sqliteInt.h" +/* Additional values that can be added to the sync_flags argument of +** sqlite3WalFrames(): +*/ +#define WAL_SYNC_TRANSACTIONS 0x20 /* Sync at the end of each transaction */ +#define SQLITE_SYNC_MASK 0x13 /* Mask off the SQLITE_SYNC_* values */ + #ifdef SQLITE_OMIT_WAL # define sqlite3WalOpen(x,y,z) 0 # define sqlite3WalLimit(x,y) @@ -87,12 +93,6 @@ int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData); /* Write a frame or frames to the log. */ int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int); -/* Additional values that can be added to the sync_flags argument of -** sqlite3WalFrames(): -*/ -#define WAL_SYNC_TRANSACTIONS 0x20 /* Sync at the end of each transaction */ -#define SQLITE_SYNC_MASK 0x13 /* Mask off the SQLITE_SYNC_* values */ - /* Copy pages from the log to the database file */ int sqlite3WalCheckpoint( Wal *pWal, /* Write-ahead log connection */ From d9bb3a974934e5f308e4a7e0c7c91a417d5983e6 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 Dec 2011 11:43:59 +0000 Subject: [PATCH 143/161] Hold the database handle mutex for the duration of sqlite3_db_release_memory(). FossilOrigin-Name: eeaf2988004ff5343be60ab4ba2f809f76c94b51 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/main.c | 2 ++ src/sqlite.h.in | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f98c6c5327..46bbd61bab 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\schanges\sto\sfix\scompilation\swith\sSQLITE_OMIT_WAL\sand\sSQLITE_OMIT_WSD\sdefined. -D 2011-12-30T10:54:24.715 +C Hold\sthe\sdatabase\shandle\smutex\sfor\sthe\sduration\sof\ssqlite3_db_release_memory(). +D 2011-12-30T11:43:59.164 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d -F src/main.c e2e3fb34be05658f41ac65ee5d9a44e00a358b48 +F src/main.c 34646375b3ee13918e7def246d2e8af31a8cca78 F src/malloc.c 15afac5e59b6584efe072e9933aefb4230e74f97 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 7998e7003a3047e323c849a26dda004debc04d03 @@ -182,7 +182,7 @@ F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c a1d075db66a0ea42807353501b62997969e5be79 F src/shell.c aa4183d4a5243d8110b1d3d77faa4aea7e9c9c2d -F src/sqlite.h.in 5d2d6c3f542ec484e769784014ef659b86e30aaa +F src/sqlite.h.in 49398dec1abb0a2caecff17da6202179ca487fe8 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h b8fdd9c39c8d7f5c794f4ea917293d9c75b9aff2 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 6a71ba9ce930838d44ed8d399075ba0723c9132b -R 579eb5da5cf1f5387840a047b3fbeef2 +P 26a513a8d2dddfde82f5fd0a0e1cc186c9b0df94 +R d333c596d678fa72a4469b4e5cebba2a U dan -Z 6dd1d82cc9bb099d02383a4750cf40f4 +Z ce6f0cbc05a184731b495119899185ea diff --git a/manifest.uuid b/manifest.uuid index 22d07c070d..890d31873c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -26a513a8d2dddfde82f5fd0a0e1cc186c9b0df94 \ No newline at end of file +eeaf2988004ff5343be60ab4ba2f809f76c94b51 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 94ea2fa2e5..785e50a19c 100644 --- a/src/main.c +++ b/src/main.c @@ -540,6 +540,7 @@ sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){ */ int sqlite3_db_release_memory(sqlite3 *db){ int i; + sqlite3_mutex_enter(db->mutex); sqlite3BtreeEnterAll(db); for(i=0; inDb; i++){ Btree *pBt = db->aDb[i].pBt; @@ -549,6 +550,7 @@ int sqlite3_db_release_memory(sqlite3 *db){ } } sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index b4f8d56102..d9c8346950 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4615,7 +4615,7 @@ int sqlite3_release_memory(int); /* ** CAPI3REF: Free Memory Used By A Database Connection ** -** ^The sqlite3_db_shrink(D) interface attempts to free as much heap +** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap ** memory as possible from database connection D. Unlike the ** [sqlite3_release_memory()] interface, this interface is effect even ** when then [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is From 2faf5f5e9e55f4b8b6778231266fd65787e70b98 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Dec 2011 15:17:47 +0000 Subject: [PATCH 144/161] Update the text of requirements associated with sqlite3_pcache_methods2. Update requirements marks embedded in code. All of the above are comment changes only; there are no changes to code in this check-in. FossilOrigin-Name: f945c41a72519d6bcfb478730ba0254bb24e5331 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/sqlite.h.in | 6 +++--- src/tokenize.c | 4 ++-- src/vdbemem.c | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 46bbd61bab..86a4848b48 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Hold\sthe\sdatabase\shandle\smutex\sfor\sthe\sduration\sof\ssqlite3_db_release_memory(). -D 2011-12-30T11:43:59.164 +C Update\sthe\stext\sof\srequirements\sassociated\swith\ssqlite3_pcache_methods2.\nUpdate\srequirements\smarks\sembedded\sin\scode.\s\sAll\sof\sthe\sabove\sare\scomment\nchanges\sonly;\sthere\sare\sno\schanges\sto\scode\sin\sthis\scheck-in. +D 2011-12-30T15:17:47.480 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -182,7 +182,7 @@ F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c a1d075db66a0ea42807353501b62997969e5be79 F src/shell.c aa4183d4a5243d8110b1d3d77faa4aea7e9c9c2d -F src/sqlite.h.in 49398dec1abb0a2caecff17da6202179ca487fe8 +F src/sqlite.h.in e6c0f4500a3264fff2cee2b2f4bad8a6cdc94e02 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h b8fdd9c39c8d7f5c794f4ea917293d9c75b9aff2 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -234,7 +234,7 @@ F src/test_vfs.c 07157a0bbfe161cb5e32cad2079abd26cd611c4b F src/test_vfstrace.c 065c7270a614254b2c68fbc7ba8d1fb1d5cbc823 F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 -F src/tokenize.c c819d9f72168a035d545a5bdafe9b085b20df705 +F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12 F src/trigger.c ee7e178fb9188f44b532cebd449a7c1df90fb684 F src/update.c d3076782c887c10e882996550345da9c4c9f9dea F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 @@ -246,7 +246,7 @@ F src/vdbeInt.h 48c158b2fceca9682d1577e61c62da3c58cf0748 F src/vdbeapi.c 86189ebba2c49791d75eaa12929f3ce6527596bd F src/vdbeaux.c 3015179b27672cb773d014495023eaa4a8cd8f9c F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb -F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 +F src/vdbemem.c 5e8c0831bd0a270ff81af385e891ff381dec900f F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 26a513a8d2dddfde82f5fd0a0e1cc186c9b0df94 -R d333c596d678fa72a4469b4e5cebba2a -U dan -Z ce6f0cbc05a184731b495119899185ea +P eeaf2988004ff5343be60ab4ba2f809f76c94b51 +R d7822a6c14ff22061dc2e151833db7d3 +U drh +Z e78d250a48fb9bb93570b28550168403 diff --git a/manifest.uuid b/manifest.uuid index 890d31873c..8028d698f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eeaf2988004ff5343be60ab4ba2f809f76c94b51 \ No newline at end of file +f945c41a72519d6bcfb478730ba0254bb24e5331 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d9c8346950..f8a410e1d4 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -864,7 +864,7 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** from xFullPathname() with an optional suffix added. ** ^If a suffix is added to the zFilename parameter, it will ** consist of a single "-" character followed by no more than -** 10 alphanumeric and/or "-" characters. +** 11 alphanumeric and/or "-" characters. ** ^SQLite further guarantees that ** the string will be valid and unchanged until xClose() is ** called. Because of the previous sentence, @@ -6078,7 +6078,7 @@ struct sqlite3_pcache_page { ** ^(The xInit() method is called once for each effective ** call to [sqlite3_initialize()])^ ** (usually only once during the lifetime of the process). ^(The xInit() -** method is passed a copy of the sqlite3_pcache_methods.pArg value.)^ +** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^ ** The intent of the xInit() method is to set up global data structures ** required by the custom page cache implementation. ** ^(If the xInit() method is NULL, then the @@ -6199,7 +6199,7 @@ struct sqlite3_pcache_page { ** ^The xDestroy() method is used to delete a cache allocated by xCreate(). ** All resources associated with the specified cache should be freed. ^After ** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*] -** handle invalid, and will not use it with any other sqlite3_pcache_methods +** handle invalid, and will not use it with any other sqlite3_pcache_methods2 ** functions. ** ** [[the xShrink() page cache method]] diff --git a/src/tokenize.c b/src/tokenize.c index b32989277e..faea5f26c7 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -123,7 +123,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ } case '-': { if( z[1]=='-' ){ - /* IMP: R-15891-05542 -- syntax diagram for comments */ + /* IMP: R-50417-27976 -- syntax diagram for comments */ for(i=2; (c=z[i])!=0 && c!='\n'; i++){} *tokenType = TK_SPACE; /* IMP: R-22934-25134 */ return i; @@ -156,7 +156,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ *tokenType = TK_SLASH; return 1; } - /* IMP: R-15891-05542 -- syntax diagram for comments */ + /* IMP: R-50417-27976 -- syntax diagram for comments */ for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){} if( c ) i++; *tokenType = TK_SPACE; /* IMP: R-22934-25134 */ diff --git a/src/vdbemem.c b/src/vdbemem.c index e6e9156272..423d17b15a 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -969,7 +969,7 @@ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ return 0; } } - sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-59893-45467 */ + sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-31275-44060 */ }else{ assert( (pVal->flags&MEM_Blob)==0 ); sqlite3VdbeMemStringify(pVal, enc); From f4692ccc79d314955139cfe80cc4f4153dcccd2a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Dec 2011 16:07:37 +0000 Subject: [PATCH 145/161] Fix up requirements marks for syntax diagrams to reflect the new and improved GIF renderings. FossilOrigin-Name: 1bb23a3b5297e07e08c26362f71aef0c5b978875 --- manifest | 30 +++++++++++++++--------------- manifest.uuid | 2 +- test/e_createtable.test | 17 ++++++----------- test/e_delete.test | 6 +++--- test/e_droptrigger.test | 2 +- test/e_dropview.test | 2 +- test/e_expr.test | 8 ++++---- test/e_insert.test | 2 +- test/e_reindex.test | 6 +++--- test/e_select.test | 16 ++++++++-------- test/e_update.test | 4 ++-- test/e_vacuum.test | 2 +- 12 files changed, 46 insertions(+), 51 deletions(-) diff --git a/manifest b/manifest index 86a4848b48..2e5cb60076 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\stext\sof\srequirements\sassociated\swith\ssqlite3_pcache_methods2.\nUpdate\srequirements\smarks\sembedded\sin\scode.\s\sAll\sof\sthe\sabove\sare\scomment\nchanges\sonly;\sthere\sare\sno\schanges\sto\scode\sin\sthis\scheck-in. -D 2011-12-30T15:17:47.480 +C Fix\sup\srequirements\smarks\sfor\ssyntax\sdiagrams\sto\sreflect\sthe\snew\sand\simproved\nGIF\srenderings. +D 2011-12-30T16:07:37.766 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -375,21 +375,21 @@ F test/descidx3.test fe720e8b37d59f4cef808b0bf4e1b391c2e56b6f F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e F test/distinct.test df5b11ad606439129c88720a86787bc9ca181f31 F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 -F test/e_createtable.test 4771686a586b6ae414f927c389b2c101cc05c028 -F test/e_delete.test e2ae0d3fce5efd70fef99025e932afffc5616fab -F test/e_droptrigger.test ddd4b28ed8a3d81bd5153fa0ab7559529a2ca03a -F test/e_dropview.test b347bab30fc8de67b131594b3cd6f3d3bdaa753d -F test/e_expr.test d93ccded2409c66637dc1649a02f169e041b63d8 +F test/e_createtable.test 48598b15e8fe6554d301e7b65a10c9851f177e84 +F test/e_delete.test ec168cd4b08d681e6d5847f462203755ad647532 +F test/e_droptrigger.test afd5c4d27dec607f5997a66bf7e2498a082cb235 +F test/e_dropview.test 583411e470458c5d76148542cfb5a5fa84c8f93e +F test/e_expr.test 4e4399006b3d1ab333721b8e386cabb9fb6d5a89 F test/e_fkey.test 38039b840ab19331000b0f0eb1d82baa7208a67a F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 -F test/e_insert.test 76d4bb5da9b28014d515d91ffe29a79a1e99f2bc -F test/e_reindex.test a064f0878b8f848fbca38f1f61f82f15a3000c64 +F test/e_insert.test 234242b71855af8e8a9b1e141c3533f6d43d8645 +F test/e_reindex.test dfedfc32c5a282b0596c6537cbcd4217fbb1a216 F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6 -F test/e_select.test 8d7fac7a268eaeb80b9a7ba7964505b9d30f5458 +F test/e_select.test 6f488c22851c1c280ed74e16a9a1430706a3a8cb F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92 -F test/e_update.test b926341a65955d69a6375c9eb4fd82e7089bc83a +F test/e_update.test dba988a4d079156549a40854074ba4890b0a4577 F test/e_uri.test 6f35b491f80dac005c8144f38b2dfb4d96483596 -F test/e_vacuum.test 6c09c2af7f2f140518f371c5342100118f779dcf +F test/e_vacuum.test 5296e25ef871965bac010b9da083dd7e4734526e F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc2.test 796c59832e2b9a52842f382ffda8f3e989db03ad F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40 @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P eeaf2988004ff5343be60ab4ba2f809f76c94b51 -R d7822a6c14ff22061dc2e151833db7d3 +P f945c41a72519d6bcfb478730ba0254bb24e5331 +R 083e04872607f66ed041353fe8d84c15 U drh -Z e78d250a48fb9bb93570b28550168403 +Z ee6ec02cb8c689b8dd9c361989e990ed diff --git a/manifest.uuid b/manifest.uuid index 8028d698f8..77ad2dab5b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f945c41a72519d6bcfb478730ba0254bb24e5331 \ No newline at end of file +1bb23a3b5297e07e08c26362f71aef0c5b978875 \ No newline at end of file diff --git a/test/e_createtable.test b/test/e_createtable.test index f61db1cd61..8221828153 100644 --- a/test/e_createtable.test +++ b/test/e_createtable.test @@ -58,7 +58,7 @@ proc table_list {} { } -# EVIDENCE-OF: R-25262-01881 -- syntax diagram type-name +# EVIDENCE-OF: R-47266-09114 -- syntax diagram type-name # do_createtable_tests 0.1.1 -repair { drop_all_tables @@ -79,12 +79,7 @@ do_createtable_tests 0.1.2 -error { } -# EVIDENCE-OF: R-18762-12428 -- syntax diagram column-constraint -# -# Note: Not shown in the syntax diagram is the "NULL" constraint. This -# is the opposite of "NOT NULL" - it implies that the column may -# take a NULL value. This is the default anyway, so this type of -# constraint is rarely used. +# EVIDENCE-OF: R-60689-48779 -- syntax diagram column-constraint # do_createtable_tests 0.2.1 -repair { drop_all_tables @@ -131,7 +126,7 @@ do_createtable_tests 0.2.1 -repair { } {} } -# EVIDENCE-OF: R-17905-31923 -- syntax diagram table-constraint +# EVIDENCE-OF: R-58169-51804 -- syntax diagram table-constraint # do_createtable_tests 0.3.1 -repair { drop_all_tables @@ -150,7 +145,7 @@ do_createtable_tests 0.3.1 -repair { 4.1 "CREATE TABLE t1(c1, c2, FOREIGN KEY(c1) REFERENCES t2)" {} } -# EVIDENCE-OF: R-18765-31171 -- syntax diagram column-def +# EVIDENCE-OF: R-44826-22243 -- syntax diagram column-def # do_createtable_tests 0.4.1 -repair { drop_all_tables @@ -165,7 +160,7 @@ do_createtable_tests 0.4.1 -repair { } {} } -# EVIDENCE-OF: R-59573-11075 -- syntax diagram create-table-stmt +# EVIDENCE-OF: R-45698-45677 -- syntax diagram create-table-stmt # do_createtable_tests 0.5.1 -repair { drop_all_tables @@ -190,7 +185,7 @@ do_createtable_tests 0.5.1 -repair { 15 "CREATE TABLE t1 AS SELECT count(*), max(b), min(a) FROM t2" {} } -# EVIDENCE-OF: R-32138-02228 -- syntax diagram foreign-key-clause +# EVIDENCE-OF: R-24369-11919 -- syntax diagram foreign-key-clause # # 1: Explicit parent-key columns. # 2: Implicit child-key columns. diff --git a/test/e_delete.test b/test/e_delete.test index c77d444226..91459810f9 100644 --- a/test/e_delete.test +++ b/test/e_delete.test @@ -24,9 +24,9 @@ do_execsql_test e_delete-0.0 { CREATE INDEX i1 ON t1(a); } {} -# EVIDENCE-OF: R-24177-52883 -- syntax diagram delete-stmt +# EVIDENCE-OF: R-62077-19799 -- syntax diagram delete-stmt # -# EVIDENCE-OF: R-12802-60464 -- syntax diagram qualified-table-name +# EVIDENCE-OF: R-60796-31013 -- syntax diagram qualified-table-name # do_delete_tests e_delete-0.1 { 1 "DELETE FROM t1" {} @@ -287,7 +287,7 @@ do_delete_tests e_delete-2.5 -error { near "%s": syntax error } { # of the DELETE statement is extended by the addition of optional ORDER # BY and LIMIT clauses: # -# EVIDENCE-OF: R-45897-01670 -- syntax diagram delete-stmt-limited +# EVIDENCE-OF: R-52694-53361 -- syntax diagram delete-stmt-limited # do_delete_tests e_delete-3.1 { 1 "DELETE FROM t1 LIMIT 5" {} diff --git a/test/e_droptrigger.test b/test/e_droptrigger.test index 0c1483176c..fe961048d9 100644 --- a/test/e_droptrigger.test +++ b/test/e_droptrigger.test @@ -69,7 +69,7 @@ proc droptrigger_reopen_db {{event INSERT}} { } -# EVIDENCE-OF: R-52650-16855 -- syntax diagram drop-trigger-stmt +# EVIDENCE-OF: R-27975-10951 -- syntax diagram drop-trigger-stmt # do_droptrigger_tests 1.1 -repair { droptrigger_reopen_db diff --git a/test/e_dropview.test b/test/e_dropview.test index 447e5c3592..4a4b9c345a 100644 --- a/test/e_dropview.test +++ b/test/e_dropview.test @@ -70,7 +70,7 @@ proc do_dropview_tests {nm args} { uplevel do_select_tests $nm $args } -# EVIDENCE-OF: R-21739-51207 -- syntax diagram drop-view-stmt +# EVIDENCE-OF: R-53136-36436 -- syntax diagram drop-view-stmt # # All paths in the syntax diagram for DROP VIEW are tested by tests 1.*. # diff --git a/test/e_expr.test b/test/e_expr.test index 3c9678c3cc..c770f1c410 100644 --- a/test/e_expr.test +++ b/test/e_expr.test @@ -627,7 +627,7 @@ do_test e_expr-11.7.1 { sqlite3_finalize $stmt } SQLITE_OK #------------------------------------------------------------------------- # "Test" the syntax diagrams in lang_expr.html. # -# EVIDENCE-OF: R-62067-43884 -- syntax diagram signed-number +# EVIDENCE-OF: R-02989-21050 -- syntax diagram signed-number # do_execsql_test e_expr-12.1.1 { SELECT 0, +0, -0 } {0 0 0} do_execsql_test e_expr-12.1.2 { SELECT 1, +1, -1 } {1 1 -1} @@ -642,7 +642,7 @@ do_execsql_test e_expr-12.1.6 { SELECT 0.0001, +0.0001, -0.0001 } {0.0001 0.0001 -0.0001} -# EVIDENCE-OF: R-21258-25489 -- syntax diagram literal-value +# EVIDENCE-OF: R-43188-60852 -- syntax diagram literal-value # set sqlite_current_time 1 do_execsql_test e_expr-12.2.1 {SELECT 123} {123} @@ -655,7 +655,7 @@ do_execsql_test e_expr-12.2.7 {SELECT CURRENT_DATE} {1970-01-01} do_execsql_test e_expr-12.2.8 {SELECT CURRENT_TIMESTAMP} {{1970-01-01 00:00:01}} set sqlite_current_time 0 -# EVIDENCE-OF: R-57598-59332 -- syntax diagram expr +# EVIDENCE-OF: R-50544-32159 -- syntax diagram expr # forcedelete test.db2 execsql { @@ -812,7 +812,7 @@ foreach {tn expr} { } } -# EVIDENCE-OF: R-49462-56079 -- syntax diagram raise-function +# EVIDENCE-OF: R-39820-63916 -- syntax diagram raise-function # foreach {tn raiseexpr} { 1 "RAISE(IGNORE)" diff --git a/test/e_insert.test b/test/e_insert.test index fe8bfcf8ef..e96b1a6f6e 100644 --- a/test/e_insert.test +++ b/test/e_insert.test @@ -45,7 +45,7 @@ proc do_insert_tests {args} { uplevel do_select_tests $args } -# EVIDENCE-OF: R-41448-54465 -- syntax diagram insert-stmt +# EVIDENCE-OF: R-55375-41353 -- syntax diagram insert-stmt # do_insert_tests e_insert-0 { 1 "INSERT INTO a1 DEFAULT VALUES" {} diff --git a/test/e_reindex.test b/test/e_reindex.test index e9419dff8a..b39f37e0de 100644 --- a/test/e_reindex.test +++ b/test/e_reindex.test @@ -26,7 +26,7 @@ do_execsql_test e_reindex-0.0 { CREATE INDEX i2 ON t1(b, a); } {} -# EVIDENCE-OF: R-57021-15304 -- syntax diagram reindex-stmt +# EVIDENCE-OF: R-51477-38549 -- syntax diagram reindex-stmt # do_reindex_tests e_reindex-0.1 { 1 "REINDEX" {} @@ -34,8 +34,8 @@ do_reindex_tests e_reindex-0.1 { 3 "REINDEX binary" {} 4 "REINDEX t1" {} 5 "REINDEX main.t1" {} - 4 "REINDEX i1" {} - 5 "REINDEX main.i1" {} + 6 "REINDEX i1" {} + 7 "REINDEX main.i1" {} } # EVIDENCE-OF: R-52173-44778 The REINDEX command is used to delete and diff --git a/test/e_select.test b/test/e_select.test index e0f5f0fb91..39a74cc8d7 100644 --- a/test/e_select.test +++ b/test/e_select.test @@ -78,7 +78,7 @@ proc do_join_test {tn select res} { # The following tests check that all paths on the syntax diagrams on # the lang_select.html page may be taken. # -# EVIDENCE-OF: R-18428-22111 -- syntax diagram join-constraint +# EVIDENCE-OF: R-11353-33501 -- syntax diagram join-constraint # do_join_test e_select-0.1.1 { SELECT count(*) FROM t1 %JOIN% t2 ON (t1.a=t2.a) @@ -96,7 +96,7 @@ do_catchsql_test e_select-0.1.5 { SELECT count(*) FROM t1, t2 USING (a) ON (t1.a=t2.a) } {1 {near "ON": syntax error}} -# EVIDENCE-OF: R-44854-11739 -- syntax diagram select-core +# EVIDENCE-OF: R-40919-40941 -- syntax diagram select-core # # 0: SELECT ... # 1: SELECT DISTINCT ... @@ -221,7 +221,7 @@ do_select_tests e_select-0.2 { } -# EVIDENCE-OF: R-23316-20169 -- syntax diagram result-column +# EVIDENCE-OF: R-41378-26734 -- syntax diagram result-column # do_select_tests e_select-0.3 { 1 "SELECT * FROM t1" {a one b two c three} @@ -231,9 +231,9 @@ do_select_tests e_select-0.3 { 5 "SELECT 'x'||a||'x' AS alias FROM t1" {xax xbx xcx} } -# EVIDENCE-OF: R-41233-21397 -- syntax diagram join-source +# EVIDENCE-OF: R-43129-35648 -- syntax diagram join-source # -# EVIDENCE-OF: R-45040-11121 -- syntax diagram join-op +# EVIDENCE-OF: R-36683-37460 -- syntax diagram join-op # do_select_tests e_select-0.4 { 1 "SELECT t1.rowid FROM t1" {1 2 3} @@ -258,7 +258,7 @@ do_select_tests e_select-0.4 { 16 "SELECT t1.rowid FROM t1 CROSS JOIN t3" {1 1 2 2 3 3} } -# EVIDENCE-OF: R-56911-63533 -- syntax diagram compound-operator +# EVIDENCE-OF: R-28308-37813 -- syntax diagram compound-operator # do_select_tests e_select-0.5 { 1 "SELECT rowid FROM t1 UNION ALL SELECT rowid+2 FROM t4" {1 2 3 3 4} @@ -267,7 +267,7 @@ do_select_tests e_select-0.5 { 4 "SELECT rowid FROM t1 EXCEPT SELECT rowid+2 FROM t4" {1 2} } -# EVIDENCE-OF: R-60388-27458 -- syntax diagram ordering-term +# EVIDENCE-OF: R-06480-34950 -- syntax diagram ordering-term # do_select_tests e_select-0.6 { 1 "SELECT b||a FROM t1 ORDER BY b||a" {onea threec twob} @@ -276,7 +276,7 @@ do_select_tests e_select-0.6 { 4 "SELECT b||a FROM t1 ORDER BY (b||a) DESC" {twob threec onea} } -# EVIDENCE-OF: R-36494-33519 -- syntax diagram select-stmt +# EVIDENCE-OF: R-23926-36668 -- syntax diagram select-stmt # do_select_tests e_select-0.7 { 1 "SELECT * FROM t1" {a one b two c three} diff --git a/test/e_update.test b/test/e_update.test index c14b8456f1..6c0e5f8aa6 100644 --- a/test/e_update.test +++ b/test/e_update.test @@ -49,7 +49,7 @@ proc do_update_tests {args} { uplevel do_select_tests $args } -# EVIDENCE-OF: R-05685-44205 -- syntax diagram update-stmt +# EVIDENCE-OF: R-62337-45828 -- syntax diagram update-stmt # do_update_tests e_update-0 { 1 "UPDATE t1 SET a=10" {} @@ -495,7 +495,7 @@ do_update_tests e_update-2.5 -error { # of the UPDATE statement is extended with optional ORDER BY and LIMIT # clauses # -# EVIDENCE-OF: R-08948-01887 -- syntax diagram update-stmt-limited +# EVIDENCE-OF: R-45169-39597 -- syntax diagram update-stmt-limited # do_update_tests e_update-3.0 { 1 "UPDATE t1 SET a=b LIMIT 5" {} diff --git a/test/e_vacuum.test b/test/e_vacuum.test index 414c854d11..aa7870fd10 100644 --- a/test/e_vacuum.test +++ b/test/e_vacuum.test @@ -65,7 +65,7 @@ proc fragment_count {name} { } -# EVIDENCE-OF: R-63707-33375 -- syntax diagram vacuum-stmt +# EVIDENCE-OF: R-45173-45977 -- syntax diagram vacuum-stmt # do_execsql_test e_vacuum-0.1 { VACUUM } {} From 4373bb880ce7d10862e3cd3bb9c26fa67a928517 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 Dec 2011 16:09:50 +0000 Subject: [PATCH 146/161] Change dbstatus.test to account for the fact that the value reported by DBSTATUS_SCHEMA_USED may be slightly lower than the actual memory used on osx FossilOrigin-Name: 6f2010c862105a113b55e90018b86a9ece298d4d --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/dbstatus.test | 7 ++++++- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 2e5cb60076..d753e29cce 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sup\srequirements\smarks\sfor\ssyntax\sdiagrams\sto\sreflect\sthe\snew\sand\simproved\nGIF\srenderings. -D 2011-12-30T16:07:37.766 +C Change\sdbstatus.test\sto\saccount\sfor\sthe\sfact\sthat\sthe\svalue\sreported\sby\sDBSTATUS_SCHEMA_USED\smay\sbe\sslightly\slower\sthan\sthe\sactual\smemory\sused\son\sosx +D 2011-12-30T16:09:50.209 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -363,7 +363,7 @@ F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/date.test a18a2ce81add84b17b06559e82ad7bb91bc6ddff -F test/dbstatus.test 179575499759241bf92ca2fb86bd3ccc8a562aac +F test/dbstatus.test 3e978f8bdb2362a36a4be63c36a59f542c4cc2a3 F test/dbstatus2.test dc57b0d9610851c0ff58a8e1b5b191678398b72a F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc F test/delete.test a065b05d2ebf60fd16639c579a4adfb7c381c701 @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P f945c41a72519d6bcfb478730ba0254bb24e5331 -R 083e04872607f66ed041353fe8d84c15 -U drh -Z ee6ec02cb8c689b8dd9c361989e990ed +P 1bb23a3b5297e07e08c26362f71aef0c5b978875 +R 5519d15ccab3182a8de12d0e5781f16b +U dan +Z 7cafc8456631d3e0c14ea4d8ad93c1b3 diff --git a/manifest.uuid b/manifest.uuid index 77ad2dab5b..45f9848222 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1bb23a3b5297e07e08c26362f71aef0c5b978875 \ No newline at end of file +6f2010c862105a113b55e90018b86a9ece298d4d \ No newline at end of file diff --git a/test/dbstatus.test b/test/dbstatus.test index 182f4ddbcd..5fc8be0426 100644 --- a/test/dbstatus.test +++ b/test/dbstatus.test @@ -212,8 +212,13 @@ foreach ::lookaside_buffer_size {0 64 120} { # Some of the memory used for sqlite_stat3 is unaccounted for by # dbstatus. # + # Finally, on osx the estimate of memory used by the schema may be + # slightly low. + # if {[string match *x $tn] || $AUTOVACUUM - || ([string match *y $tn] && $STAT3)} { + || ([string match *y $tn] && $STAT3) + || ($::tcl_platform(os) == "Darwin") + } { do_test dbstatus-2.$tn.ax { expr {($nSchema1-$nSchema2)<=$nFree} } 1 } else { do_test dbstatus-2.$tn.a { expr {$nSchema1-$nSchema2} } $nFree From 50cc5c278928ae39e12cf65f496621215ef1219e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Dec 2011 16:16:56 +0000 Subject: [PATCH 147/161] Fix a typo in the documentation for PCACHE2. No changes to code. FossilOrigin-Name: 46e7903ab993b08251c87239bd4a7320e6781cee --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d753e29cce..f6dfbff750 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sdbstatus.test\sto\saccount\sfor\sthe\sfact\sthat\sthe\svalue\sreported\sby\sDBSTATUS_SCHEMA_USED\smay\sbe\sslightly\slower\sthan\sthe\sactual\smemory\sused\son\sosx -D 2011-12-30T16:09:50.209 +C Fix\sa\stypo\sin\sthe\sdocumentation\sfor\sPCACHE2.\s\sNo\schanges\sto\scode. +D 2011-12-30T16:16:56.830 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -182,7 +182,7 @@ F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c a1d075db66a0ea42807353501b62997969e5be79 F src/shell.c aa4183d4a5243d8110b1d3d77faa4aea7e9c9c2d -F src/sqlite.h.in e6c0f4500a3264fff2cee2b2f4bad8a6cdc94e02 +F src/sqlite.h.in f3e91b55ddd62f99677c9e8391e53bd755f476ac F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h b8fdd9c39c8d7f5c794f4ea917293d9c75b9aff2 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 1bb23a3b5297e07e08c26362f71aef0c5b978875 -R 5519d15ccab3182a8de12d0e5781f16b -U dan -Z 7cafc8456631d3e0c14ea4d8ad93c1b3 +P 6f2010c862105a113b55e90018b86a9ece298d4d +R 7e79df782114fbf75cf072c51937066b +U drh +Z 49ff10403d9172f7b7e8e3deec0c0e68 diff --git a/manifest.uuid b/manifest.uuid index 45f9848222..0f38ab599c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6f2010c862105a113b55e90018b86a9ece298d4d \ No newline at end of file +46e7903ab993b08251c87239bd4a7320e6781cee \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index f8a410e1d4..17b352ed75 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6104,7 +6104,7 @@ struct sqlite3_pcache_page { ** ^SQLite invokes the xCreate() method to construct a new cache instance. ** SQLite will typically create one cache instance for each open database file, ** though this is not guaranteed. ^The -** parameter parameter, szPage, is the size in bytes of the pages that must +** first parameter, szPage, is the size in bytes of the pages that must ** be allocated by the cache. ^szPage will always a power of two. ^The ** second parameter szExtra is a number of bytes of extra storage ** associated with each page cache entry. ^The szExtra parameter will From b3ce3d6d92c28daacbbb2645d2f83edcf2b1045a Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 Dec 2011 18:16:02 +0000 Subject: [PATCH 148/161] Add calls to the BenignMalloc() functions around the SQLITE_FCNTL_SIZE_HINT call in pager.c. FossilOrigin-Name: c17a3f5e5d72187c06b598ef071d43ef89328e19 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pager.c | 2 ++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f6dfbff750..1765dba345 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sthe\sdocumentation\sfor\sPCACHE2.\s\sNo\schanges\sto\scode. -D 2011-12-30T16:16:56.830 +C Add\scalls\sto\sthe\sBenignMalloc()\sfunctions\saround\sthe\sSQLITE_FCNTL_SIZE_HINT\scall\sin\spager.c. +D 2011-12-30T18:16:02.598 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -168,7 +168,7 @@ F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 3a441671f35569df4b72641e928fdb1ab5cd8576 F src/os_win.c 569fe7448e781bfb8116aa79081df0eadf576fc6 -F src/pager.c 0ae6079dd6109d475e54ff2ce3131dd0a3fea24f +F src/pager.c 4ee26909f1092239ed39e50d4f4438de11f32275 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba F src/pcache.c 1fdd77978c1525d1ca4b9ef48eb80abca710cb4c @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 6f2010c862105a113b55e90018b86a9ece298d4d -R 7e79df782114fbf75cf072c51937066b -U drh -Z 49ff10403d9172f7b7e8e3deec0c0e68 +P 46e7903ab993b08251c87239bd4a7320e6781cee +R f1370d9592311ee925b065af7c5e925d +U dan +Z 7b10c47157901b03eeddf5ba0f182b05 diff --git a/manifest.uuid b/manifest.uuid index 0f38ab599c..d74ef398bd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -46e7903ab993b08251c87239bd4a7320e6781cee \ No newline at end of file +c17a3f5e5d72187c06b598ef071d43ef89328e19 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index e1a3385b05..7e7240f248 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4029,7 +4029,9 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ assert( rc!=SQLITE_OK || isOpen(pPager->fd) ); if( rc==SQLITE_OK && pPager->dbSize>pPager->dbHintSize ){ sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize; + sqlite3BeginBenignMalloc(); sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile); + sqlite3EndBenignMalloc(); pPager->dbHintSize = pPager->dbSize; } From 23a3de398e2a816a402a603532edb3da42026f1d Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 31 Dec 2011 10:18:00 +0000 Subject: [PATCH 149/161] Add calls to the BenignMalloc() functions around the SQLITE_FCNTL_OVERWRITE call in backup.c. FossilOrigin-Name: 3e0833dbb736a1aca08d17941d6d33901b15a03b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/backup.c | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 1765dba345..24265fbbb2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\scalls\sto\sthe\sBenignMalloc()\sfunctions\saround\sthe\sSQLITE_FCNTL_SIZE_HINT\scall\sin\spager.c. -D 2011-12-30T18:16:02.598 +C Add\scalls\sto\sthe\sBenignMalloc()\sfunctions\saround\sthe\sSQLITE_FCNTL_OVERWRITE\scall\sin\sbackup.c. +D 2011-12-31T10:18:00.048 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -122,7 +122,7 @@ F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 F src/analyze.c f32ff304da413851eefa562b04e61ff6cb88248b F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 -F src/backup.c 4368158da74d4711888e03264105c5c527d76caf +F src/backup.c 80d713109d295cc3a674f55cfe6446afb9b024ad F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 2fdde7d16c80bd4e8a0913038e766c4297818f6f @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 46e7903ab993b08251c87239bd4a7320e6781cee -R f1370d9592311ee925b065af7c5e925d +P c17a3f5e5d72187c06b598ef071d43ef89328e19 +R 11347eca51418811296406b6ca6391d4 U dan -Z 7b10c47157901b03eeddf5ba0f182b05 +Z e290df4c733c56ee941822f3e8c85381 diff --git a/manifest.uuid b/manifest.uuid index d74ef398bd..8ffd3352f9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c17a3f5e5d72187c06b598ef071d43ef89328e19 \ No newline at end of file +3e0833dbb736a1aca08d17941d6d33901b15a03b \ No newline at end of file diff --git a/src/backup.c b/src/backup.c index bdf96bd8e1..f3b952bf0d 100644 --- a/src/backup.c +++ b/src/backup.c @@ -678,7 +678,9 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ pFd = sqlite3PagerFile(sqlite3BtreePager(pTo)); if( pFd->pMethods ){ i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom); + sqlite3BeginBenignMalloc(); sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte); + sqlite3EndBenignMalloc(); } /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set From b8a45bbdb8bd753750558fe32ea2f4405787b469 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 31 Dec 2011 21:51:55 +0000 Subject: [PATCH 150/161] Fix typos in comments. No changes to code. FossilOrigin-Name: 6827338ecbe43e28da88d919851ebffde9f6d398 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/btreeInt.h | 6 +++--- src/main.c | 2 +- src/sqlite.h.in | 2 +- src/vdbe.c | 2 +- src/vdbeapi.c | 8 ++++---- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 24265fbbb2..d8b0034c18 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\scalls\sto\sthe\sBenignMalloc()\sfunctions\saround\sthe\sSQLITE_FCNTL_OVERWRITE\scall\sin\sbackup.c. -D 2011-12-31T10:18:00.048 +C Fix\stypos\sin\scomments.\s\sNo\schanges\sto\scode. +D 2011-12-31T21:51:55.629 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -127,7 +127,7 @@ F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 2fdde7d16c80bd4e8a0913038e766c4297818f6f F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce -F src/btreeInt.h ea863a819224d3e6845ad1e39954d41558b8cd8b +F src/btreeInt.h 6e57bacaa4feb7dd56719678133e63a7c289c6e7 F src/build.c 8915bb6d72ead998f94c2756ea8d143c77709b70 F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac @@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d -F src/main.c 34646375b3ee13918e7def246d2e8af31a8cca78 +F src/main.c bcf8cd3036122b64586b65c4db0c5f339ede4a8f F src/malloc.c 15afac5e59b6584efe072e9933aefb4230e74f97 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 7998e7003a3047e323c849a26dda004debc04d03 @@ -182,7 +182,7 @@ F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c a1d075db66a0ea42807353501b62997969e5be79 F src/shell.c aa4183d4a5243d8110b1d3d77faa4aea7e9c9c2d -F src/sqlite.h.in f3e91b55ddd62f99677c9e8391e53bd755f476ac +F src/sqlite.h.in 80115fdec17acf32f93adbf950960b889de98b79 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h b8fdd9c39c8d7f5c794f4ea917293d9c75b9aff2 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -240,10 +240,10 @@ F src/update.c d3076782c887c10e882996550345da9c4c9f9dea F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 F src/util.c 19ae3ee0dfa88e6054838afc5920327c5918fa2b F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa -F src/vdbe.c 029add0c5197a61db588824a58570547330b9d8f +F src/vdbe.c 50f0cf69eb64e11185042d15062bec8a1373a8a2 F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb F src/vdbeInt.h 48c158b2fceca9682d1577e61c62da3c58cf0748 -F src/vdbeapi.c 86189ebba2c49791d75eaa12929f3ce6527596bd +F src/vdbeapi.c 3662b6a468a2a4605a15dfab313baa6dff81ad91 F src/vdbeaux.c 3015179b27672cb773d014495023eaa4a8cd8f9c F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 5e8c0831bd0a270ff81af385e891ff381dec900f @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P c17a3f5e5d72187c06b598ef071d43ef89328e19 -R 11347eca51418811296406b6ca6391d4 -U dan -Z e290df4c733c56ee941822f3e8c85381 +P 3e0833dbb736a1aca08d17941d6d33901b15a03b +R ace5a10cf9ac7f9252c85c4d0ddd28cb +U drh +Z cb1b01f06ed7e6e96727a1a0146b31c3 diff --git a/manifest.uuid b/manifest.uuid index 8ffd3352f9..c2efca8bed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e0833dbb736a1aca08d17941d6d33901b15a03b \ No newline at end of file +6827338ecbe43e28da88d919851ebffde9f6d398 \ No newline at end of file diff --git a/src/btreeInt.h b/src/btreeInt.h index d3117ad9fa..1535350a3e 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -370,7 +370,7 @@ struct Btree { /* ** An instance of this object represents a single database file. ** -** A single database file can be in use as the same time by two +** A single database file can be in use at the same time by two ** or more database connections. When two or more connections are ** sharing the same database file, each connection has it own ** private Btree object for the file and each of those Btrees points @@ -476,7 +476,7 @@ struct CellInfo { ** The entry is identified by its MemPage and the index in ** MemPage.aCell[] of the entry. ** -** A single database file can shared by two more database connections, +** A single database file can be shared by two more database connections, ** but cursors cannot be shared. Each cursor is associated with a ** particular database connection identified BtCursor.pBtree.db. ** @@ -637,7 +637,7 @@ struct IntegrityCk { }; /* -** Read or write a two- and four-byte big-endian integer values. +** Routines to read or write a two- and four-byte big-endian integer values. */ #define get2byte(x) ((x)[0]<<8 | (x)[1]) #define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v)) diff --git a/src/main.c b/src/main.c index 785e50a19c..7da925c2e5 100644 --- a/src/main.c +++ b/src/main.c @@ -50,7 +50,7 @@ const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } /* IMPLEMENTATION-OF: R-54823-41343 The sqlite3_threadsafe() function returns -** zero if and only if SQLite was compiled mutexing code omitted due to +** zero if and only if SQLite was compiled with mutexing code omitted due to ** the SQLITE_THREADSAFE compile-time option being set to 0. */ int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 17b352ed75..029a10dd74 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -172,7 +172,7 @@ const char *sqlite3_compileoption_get(int N); ** CAPI3REF: Test To See If The Library Is Threadsafe ** ** ^The sqlite3_threadsafe() function returns zero if and only if -** SQLite was compiled mutexing code omitted due to the +** SQLite was compiled with mutexing code omitted due to the ** [SQLITE_THREADSAFE] compile-time option being set to 0. ** ** SQLite can be compiled with or without mutexes. When diff --git a/src/vdbe.c b/src/vdbe.c index 64ae54e3db..4cc5627382 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1152,7 +1152,7 @@ case OP_ResultRow: { /* Make sure the results of the current row are \000 terminated ** and have an assigned type. The results are de-ephemeralized as - ** as side effect. + ** a side effect. */ pMem = p->pResultSet = &aMem[pOp->p1]; for(i=0; ip2; i++){ diff --git a/src/vdbeapi.c b/src/vdbeapi.c index c6c54854f3..94db205e1f 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -354,7 +354,7 @@ static int sqlite3Step(Vdbe *p){ ** ** Nevertheless, some published applications that were originally written ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE - ** returns, and the so were broken by the automatic-reset change. As a + ** returns, and those were broken by the automatic-reset change. As a ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the ** legacy behavior of returning SQLITE_MISUSE for cases where the ** previous sqlite3_step() returned something other than a SQLITE_LOCKED @@ -700,13 +700,13 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ /* If the value passed as the second argument is out of range, return ** a pointer to the following static Mem object which contains the ** value SQL NULL. Even though the Mem structure contains an element - ** of type i64, on certain architecture (x86) with certain compiler + ** of type i64, on certain architectures (x86) with certain compiler ** switches (-Os), gcc may align this Mem object on a 4-byte boundary ** instead of an 8-byte one. This all works fine, except that when ** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s ** that a Mem structure is located on an 8-byte boundary. To prevent - ** this assert() from failing, when building with SQLITE_DEBUG defined - ** using gcc, force nullMem to be 8-byte aligned using the magical + ** these assert()s from failing, when building with SQLITE_DEBUG defined + ** using gcc, we force nullMem to be 8-byte aligned using the magical ** __attribute__((aligned(8))) macro. */ static const Mem nullMem #if defined(SQLITE_DEBUG) && defined(__GNUC__) From 20e226d97997702d58c3112a71d85c372a49d8d1 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 1 Jan 2012 13:58:53 +0000 Subject: [PATCH 151/161] Tweaks to improve testability. FossilOrigin-Name: e3a929e43180f41095cc2cd00c6b0781856a4474 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeaux.c | 1 + src/wal.c | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d8b0034c18..431e37efbd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypos\sin\scomments.\s\sNo\schanges\sto\scode. -D 2011-12-31T21:51:55.629 +C Tweaks\sto\simprove\stestability. +D 2012-01-01T13:58:53.511 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -244,13 +244,13 @@ F src/vdbe.c 50f0cf69eb64e11185042d15062bec8a1373a8a2 F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb F src/vdbeInt.h 48c158b2fceca9682d1577e61c62da3c58cf0748 F src/vdbeapi.c 3662b6a468a2a4605a15dfab313baa6dff81ad91 -F src/vdbeaux.c 3015179b27672cb773d014495023eaa4a8cd8f9c +F src/vdbeaux.c 6b6c7acacdb47af51853b1f2a19a9b755ffe2aba F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 5e8c0831bd0a270ff81af385e891ff381dec900f F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a -F src/wal.c 4800adb021db953138eafdda825f95bc050e5b98 +F src/wal.c 932f09509d70fc115a7cc3d494d6fdcb825099ed F src/wal.h eaa00b9a403ddda2b56d01b7afc19ef600f9363f F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c af623942514571895818b9b7ae11db95ae3b3d88 @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 3e0833dbb736a1aca08d17941d6d33901b15a03b -R ace5a10cf9ac7f9252c85c4d0ddd28cb +P 6827338ecbe43e28da88d919851ebffde9f6d398 +R c2dd931589fd30a5a91f7fea2672cfd8 U drh -Z cb1b01f06ed7e6e96727a1a0146b31c3 +Z 649f8c400641c466a926a4b1d755f8fd diff --git a/manifest.uuid b/manifest.uuid index c2efca8bed..83908620fa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6827338ecbe43e28da88d919851ebffde9f6d398 \ No newline at end of file +e3a929e43180f41095cc2cd00c6b0781856a4474 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index c7d46a1bc1..9e3a493283 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1487,6 +1487,7 @@ void sqlite3VdbeMakeReady( nCursor = pParse->nTab; nArg = pParse->nMaxArg; nOnce = pParse->nOnce; + if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */ /* For each cursor required, also allocate a memory cell. Memory ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by diff --git a/src/wal.c b/src/wal.c index 076ba9633d..b9d3532204 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2857,7 +2857,7 @@ int sqlite3WalFrames( iFrame++; rc = walIndexAppend(pWal, iFrame, p->pgno); } - while( nExtra>0 && rc==SQLITE_OK ){ + while( rc==SQLITE_OK && nExtra>0 ){ iFrame++; nExtra--; rc = walIndexAppend(pWal, iFrame, pLast->pgno); From 7d39e17eefda200d71a32e145b0313d77e2e0c5e Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Jan 2012 12:41:53 +0000 Subject: [PATCH 152/161] Fix the build so that it works when SQLITE_ENABLE_8_3_NAMES=1. FossilOrigin-Name: d9761f15a175724c6c28a52335c979304737b188 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/util.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 431e37efbd..58f818265e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Tweaks\sto\simprove\stestability. -D 2012-01-01T13:58:53.511 +C Fix\sthe\sbuild\sso\sthat\sit\sworks\swhen\sSQLITE_ENABLE_8_3_NAMES=1. +D 2012-01-02T12:41:53.461 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -238,7 +238,7 @@ F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12 F src/trigger.c ee7e178fb9188f44b532cebd449a7c1df90fb684 F src/update.c d3076782c887c10e882996550345da9c4c9f9dea F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 -F src/util.c 19ae3ee0dfa88e6054838afc5920327c5918fa2b +F src/util.c 9e07bd67dfafe9c75b1da78c87ba030cebbb5388 F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa F src/vdbe.c 50f0cf69eb64e11185042d15062bec8a1373a8a2 F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 6827338ecbe43e28da88d919851ebffde9f6d398 -R c2dd931589fd30a5a91f7fea2672cfd8 +P e3a929e43180f41095cc2cd00c6b0781856a4474 +R ebe54cc51516118d00ec9f963dc0c725 U drh -Z 649f8c400641c466a926a4b1d755f8fd +Z f0855acf7bf6b1fdb217f7703ac74727 diff --git a/manifest.uuid b/manifest.uuid index 83908620fa..51641940c0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e3a929e43180f41095cc2cd00c6b0781856a4474 \ No newline at end of file +d9761f15a175724c6c28a52335c979304737b188 \ No newline at end of file diff --git a/src/util.c b/src/util.c index a80b89a4ad..fd3c858ab7 100644 --- a/src/util.c +++ b/src/util.c @@ -1173,7 +1173,7 @@ int sqlite3AbsInt32(int x){ */ void sqlite3FileSuffix3(const char *zBaseFilename, char *z){ #if SQLITE_ENABLE_8_3_NAMES<2 - if( sqlite3_uri_boolean(zBaseFilename, "8_3_names") ) + if( sqlite3_uri_boolean(zBaseFilename, "8_3_names", 0) ) #endif { int i, sz; From aa584af08837c6d8cca9f112777632b95d30c74f Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 2 Jan 2012 14:50:12 +0000 Subject: [PATCH 153/161] Have SQLITE_FCNTL_SYNC_OMITTED use the normal method of returning an error code. FossilOrigin-Name: fd3822f1f2e6ea181f663e99bfe788d8404176ee --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pager.c | 5 ++++- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 58f818265e..b03f7e9842 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sbuild\sso\sthat\sit\sworks\swhen\sSQLITE_ENABLE_8_3_NAMES=1. -D 2012-01-02T12:41:53.461 +C Have\sSQLITE_FCNTL_SYNC_OMITTED\suse\sthe\snormal\smethod\sof\sreturning\san\serror\scode. +D 2012-01-02T14:50:12.973 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -168,7 +168,7 @@ F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 3a441671f35569df4b72641e928fdb1ab5cd8576 F src/os_win.c 569fe7448e781bfb8116aa79081df0eadf576fc6 -F src/pager.c 4ee26909f1092239ed39e50d4f4438de11f32275 +F src/pager.c a21a3191ab75310ea75bb61149e63b835f77f5f0 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba F src/pcache.c 1fdd77978c1525d1ca4b9ef48eb80abca710cb4c @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P e3a929e43180f41095cc2cd00c6b0781856a4474 -R ebe54cc51516118d00ec9f963dc0c725 -U drh -Z f0855acf7bf6b1fdb217f7703ac74727 +P d9761f15a175724c6c28a52335c979304737b188 +R 82d9c69c5da42ef30dc006ee831a69fd +U dan +Z 8ee537d5237b81fef6f749f1defb7865 diff --git a/manifest.uuid b/manifest.uuid index 51641940c0..e2fb77c0ef 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d9761f15a175724c6c28a52335c979304737b188 \ No newline at end of file +fd3822f1f2e6ea181f663e99bfe788d8404176ee \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 7e7240f248..3640d462bb 100644 --- a/src/pager.c +++ b/src/pager.c @@ -5696,7 +5696,10 @@ int sqlite3PagerSync(Pager *pPager){ rc = sqlite3OsSync(pPager->fd, pPager->syncFlags); }else if( isOpen(pPager->fd) ){ assert( !MEMDB ); - sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC_OMITTED, (void *)&rc); + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC_OMITTED, 0); + if( rc==SQLITE_NOTFOUND ){ + rc = SQLITE_OK; + } } return rc; } From 5dc2bcda7e49ff18c7b2204579f166aad088289e Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Jan 2012 15:45:12 +0000 Subject: [PATCH 154/161] Make sure large negative arguments to PRAGMA cache_size do not cause 32-bit signed integer overflow. Also correct a requirements mark. FossilOrigin-Name: 17c30634a71051158f8d37fd51b3c2a125ad8bd2 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/main.c | 2 +- src/pcache.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index b03f7e9842..47ea98d771 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sSQLITE_FCNTL_SYNC_OMITTED\suse\sthe\snormal\smethod\sof\sreturning\san\serror\scode. -D 2012-01-02T14:50:12.973 +C Make\ssure\slarge\snegative\sarguments\sto\sPRAGMA\scache_size\sdo\snot\scause\n32-bit\ssigned\sinteger\soverflow.\s\sAlso\scorrect\sa\srequirements\smark. +D 2012-01-02T15:45:12.548 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -147,7 +147,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d -F src/main.c bcf8cd3036122b64586b65c4db0c5f339ede4a8f +F src/main.c e60abee4a7ca3da31b67745ccf02b8d29f138614 F src/malloc.c 15afac5e59b6584efe072e9933aefb4230e74f97 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 7998e7003a3047e323c849a26dda004debc04d03 @@ -171,7 +171,7 @@ F src/os_win.c 569fe7448e781bfb8116aa79081df0eadf576fc6 F src/pager.c a21a3191ab75310ea75bb61149e63b835f77f5f0 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba -F src/pcache.c 1fdd77978c1525d1ca4b9ef48eb80abca710cb4c +F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h b1d8775a9bddf44e65edb0d20bfc57a4982f840f F src/pcache1.c 9d735349ac87ef08076c6b1230f04cd83b15c6da F src/pragma.c dd66f21fafe7be40e1a48ad4195764cc191cf583 @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P d9761f15a175724c6c28a52335c979304737b188 -R 82d9c69c5da42ef30dc006ee831a69fd -U dan -Z 8ee537d5237b81fef6f749f1defb7865 +P fd3822f1f2e6ea181f663e99bfe788d8404176ee +R 6a506042b7b9b54c17254c10f96e54fb +U drh +Z c1922e4cc60e8bf7e7f5fefa3fe55bc1 diff --git a/manifest.uuid b/manifest.uuid index e2fb77c0ef..2ce2d010a1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fd3822f1f2e6ea181f663e99bfe788d8404176ee \ No newline at end of file +17c30634a71051158f8d37fd51b3c2a125ad8bd2 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 7da925c2e5..524b710263 100644 --- a/src/main.c +++ b/src/main.c @@ -49,7 +49,7 @@ const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } */ int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } -/* IMPLEMENTATION-OF: R-54823-41343 The sqlite3_threadsafe() function returns +/* IMPLEMENTATION-OF: R-20790-14025 The sqlite3_threadsafe() function returns ** zero if and only if SQLite was compiled with mutexing code omitted due to ** the SQLITE_THREADSAFE compile-time option being set to 0. */ diff --git a/src/pcache.c b/src/pcache.c index 0c3e9ee0a2..482a188bee 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -205,7 +205,7 @@ static int numberOfCachePages(PCache *p){ if( p->szCache>=0 ){ return p->szCache; }else{ - return (-1024*p->szCache)/(p->szPage+p->szExtra); + return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra)); } } From 2f32fbae31854f04a922127af1c9bf1b4878d98b Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Jan 2012 16:38:57 +0000 Subject: [PATCH 155/161] Remove an incorrect assert() in btree.c. FossilOrigin-Name: c1691d998a03fee3bef137ccf2e8ca45acac2df4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 6 ++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 47ea98d771..153ec82af8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\slarge\snegative\sarguments\sto\sPRAGMA\scache_size\sdo\snot\scause\n32-bit\ssigned\sinteger\soverflow.\s\sAlso\scorrect\sa\srequirements\smark. -D 2012-01-02T15:45:12.548 +C Remove\san\sincorrect\sassert()\sin\sbtree.c. +D 2012-01-02T16:38:57.512 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -125,7 +125,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 80d713109d295cc3a674f55cfe6446afb9b024ad F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 2fdde7d16c80bd4e8a0913038e766c4297818f6f +F src/btree.c 8f683b1fcfd9ac92efa781c9c56c537e080a7117 F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 6e57bacaa4feb7dd56719678133e63a7c289c6e7 F src/build.c 8915bb6d72ead998f94c2756ea8d143c77709b70 @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P fd3822f1f2e6ea181f663e99bfe788d8404176ee -R 6a506042b7b9b54c17254c10f96e54fb +P 17c30634a71051158f8d37fd51b3c2a125ad8bd2 +R 6c012a7774ed9e5a330a66726436b4a2 U drh -Z c1922e4cc60e8bf7e7f5fefa3fe55bc1 +Z fcdcf01f58c77f738eb120329f0033fc diff --git a/manifest.uuid b/manifest.uuid index 2ce2d010a1..1269d5372f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -17c30634a71051158f8d37fd51b3c2a125ad8bd2 \ No newline at end of file +c1691d998a03fee3bef137ccf2e8ca45acac2df4 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index ad011608bf..7c043ccf75 100644 --- a/src/btree.c +++ b/src/btree.c @@ -6203,8 +6203,14 @@ static int balance_nonroot( /* Either we found one or more cells (cntnew[0])>0) or pPage is ** a virtual root page. A virtual root page is when the real root ** page is page 1 and we are the only child of that page. + ** + ** UPDATE: The assert() below is not necessarily true if the database + ** file is corrupt. The corruption will be detected and reported later + ** in this procedure so there is no need to act upon it now. */ +#if 0 assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) ); +#endif TRACE(("BALANCE: old: %d %d %d ", apOld[0]->pgno, From a69085cf5fadc0f462cc9d60eade7a7b471a93c1 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Jan 2012 18:00:55 +0000 Subject: [PATCH 156/161] Change page quantities in pcache1.c to unsigned. FossilOrigin-Name: da52e6e8b490508bc1ee4700aa45a79f398363da --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pcache1.c | 20 +++++++++++--------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 153ec82af8..b5bf9bdea3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sincorrect\sassert()\sin\sbtree.c. -D 2012-01-02T16:38:57.512 +C Change\spage\squantities\sin\spcache1.c\sto\sunsigned. +D 2012-01-02T18:00:55.564 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -173,7 +173,7 @@ F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h b1d8775a9bddf44e65edb0d20bfc57a4982f840f -F src/pcache1.c 9d735349ac87ef08076c6b1230f04cd83b15c6da +F src/pcache1.c e1aaa3bc9bbfd8b0bc391ca731f5f8185467375d F src/pragma.c dd66f21fafe7be40e1a48ad4195764cc191cf583 F src/prepare.c ec4989f7f480544bdc4192fe663470d2a2d7d61e F src/printf.c 7ffb4ebb8b341f67e049695ba031da717b3d2699 @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 17c30634a71051158f8d37fd51b3c2a125ad8bd2 -R 6c012a7774ed9e5a330a66726436b4a2 +P c1691d998a03fee3bef137ccf2e8ca45acac2df4 +R 84be2ca283aa4d12d0883d5cb3ef90ca U drh -Z fcdcf01f58c77f738eb120329f0033fc +Z 981c2603df115cccf0c78e5588d3bb18 diff --git a/manifest.uuid b/manifest.uuid index 1269d5372f..1b3a2f307c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c1691d998a03fee3bef137ccf2e8ca45acac2df4 \ No newline at end of file +da52e6e8b490508bc1ee4700aa45a79f398363da \ No newline at end of file diff --git a/src/pcache1.c b/src/pcache1.c index 505941a3a7..405ae5aec8 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -48,10 +48,10 @@ typedef struct PGroup PGroup; */ struct PGroup { sqlite3_mutex *mutex; /* MUTEX_STATIC_LRU or NULL */ - int nMaxPage; /* Sum of nMax for purgeable caches */ - int nMinPage; /* Sum of nMin for purgeable caches */ - int mxPinned; /* nMaxpage + 10 - nMinPage */ - int nCurrentPage; /* Number of purgeable pages allocated */ + unsigned int nMaxPage; /* Sum of nMax for purgeable caches */ + unsigned int nMinPage; /* Sum of nMin for purgeable caches */ + unsigned int mxPinned; /* nMaxpage + 10 - nMinPage */ + unsigned int nCurrentPage; /* Number of purgeable pages allocated */ PgHdr1 *pLruHead, *pLruTail; /* LRU list of unpinned pages */ }; @@ -714,7 +714,7 @@ static sqlite3_pcache_page *pcache1Fetch( unsigned int iKey, int createFlag ){ - int nPinned; + unsigned int nPinned; PCache1 *pCache = (PCache1 *)p; PGroup *pGroup; PgHdr1 *pPage = 0; @@ -749,13 +749,13 @@ static sqlite3_pcache_page *pcache1Fetch( #endif /* Step 3: Abort if createFlag is 1 but the cache is nearly full */ + assert( pCache->nPage >= pCache->nRecyclable ); nPinned = pCache->nPage - pCache->nRecyclable; - assert( nPinned>=0 ); assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage ); assert( pCache->n90pct == pCache->nMax*9/10 ); if( createFlag==1 && ( nPinned>=pGroup->mxPinned - || nPinned>=(int)pCache->n90pct + || nPinned>=pCache->n90pct || pcache1UnderMemoryPressure(pCache) )){ goto fetch_out; @@ -928,7 +928,9 @@ static void pcache1Destroy(sqlite3_pcache *p){ assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) ); pcache1EnterMutex(pGroup); pcache1TruncateUnsafe(pCache, 0); + assert( pGroup->nMaxPage >= pCache->nMax ); pGroup->nMaxPage -= pCache->nMax; + assert( pGroup->nMinPage >= pCache->nMin ); pGroup->nMinPage -= pCache->nMin; pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; pcache1EnforceMaxPage(pGroup); @@ -1010,8 +1012,8 @@ void sqlite3PcacheStats( nRecyclable++; } *pnCurrent = pcache1.grp.nCurrentPage; - *pnMax = pcache1.grp.nMaxPage; - *pnMin = pcache1.grp.nMinPage; + *pnMax = (int)pcache1.grp.nMaxPage; + *pnMin = (int)pcache1.grp.nMinPage; *pnRecyclable = nRecyclable; } #endif From 8942d4125ea63c485d0252eebab31e38003607eb Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Jan 2012 18:20:14 +0000 Subject: [PATCH 157/161] Remove the code that attempts to find the sector size from the OS and hardcode the xSectorSize methods of the unix and windows VFSes to return SQLITE_DEFAULT_SECTOR_SIZE, which is now set to 4096 unless overridden. FossilOrigin-Name: 03d8362cd2cadab8e1cc5b18a3194152f2bd0a84 --- manifest | 16 ++++----- manifest.uuid | 2 +- src/os.h | 2 +- src/os_unix.c | 33 ++----------------- src/os_win.c | 89 ++------------------------------------------------- 5 files changed, 15 insertions(+), 127 deletions(-) diff --git a/manifest b/manifest index b5bf9bdea3..182ee59812 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\spage\squantities\sin\spcache1.c\sto\sunsigned. -D 2012-01-02T18:00:55.564 +C Remove\sthe\scode\sthat\sattempts\sto\sfind\sthe\ssector\ssize\sfrom\sthe\sOS\sand\nhardcode\sthe\sxSectorSize\smethods\sof\sthe\sunix\sand\swindows\sVFSes\sto\sreturn\nSQLITE_DEFAULT_SECTOR_SIZE,\swhich\sis\snow\sset\sto\s4096\sunless\soverridden. +D 2012-01-02T18:20:14.209 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -163,11 +163,11 @@ F src/mutex_unix.c b4f4e923bb8de93ec3f251fadb50855f23df9579 F src/mutex_w32.c 5e54f3ba275bcb5d00248b8c23107df2e2f73e33 F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 F src/os.c 519bdf7c608c4848024e1d87934f9305454145f4 -F src/os.h 549b1a2e5e0ed1e1499f252dac126c4973e7379c +F src/os.h c7d888830f168a9b681b3aec30789f4ad2445c17 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c 3a441671f35569df4b72641e928fdb1ab5cd8576 -F src/os_win.c 569fe7448e781bfb8116aa79081df0eadf576fc6 +F src/os_unix.c 51acd5477f7c92321bbc665282a710556f19b4a7 +F src/os_win.c 0d3522dd0ad82b615748d4d391211af62b57ae03 F src/pager.c a21a3191ab75310ea75bb61149e63b835f77f5f0 F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P c1691d998a03fee3bef137ccf2e8ca45acac2df4 -R 84be2ca283aa4d12d0883d5cb3ef90ca +P da52e6e8b490508bc1ee4700aa45a79f398363da +R a0b8de10aeee04558967b4b25ead4061 U drh -Z 981c2603df115cccf0c78e5588d3bb18 +Z d686dcd0a4de73c84f2800d730af321e diff --git a/manifest.uuid b/manifest.uuid index 1b3a2f307c..44d9031030 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -da52e6e8b490508bc1ee4700aa45a79f398363da \ No newline at end of file +03d8362cd2cadab8e1cc5b18a3194152f2bd0a84 \ No newline at end of file diff --git a/src/os.h b/src/os.h index 80afc516ff..52ac4b0cbc 100644 --- a/src/os.h +++ b/src/os.h @@ -119,7 +119,7 @@ ** The default size of a disk sector */ #ifndef SQLITE_DEFAULT_SECTOR_SIZE -# define SQLITE_DEFAULT_SECTOR_SIZE 512 +# define SQLITE_DEFAULT_SECTOR_SIZE 4096 #endif /* diff --git a/src/os_unix.c b/src/os_unix.c index adf11541ff..6542c0e66c 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -122,9 +122,6 @@ #ifndef SQLITE_OMIT_WAL #include #endif -#ifndef MISSING_STATVFS -#include -#endif #if SQLITE_ENABLE_LOCKING_STYLE @@ -215,7 +212,6 @@ struct unixFile { int h; /* The file descriptor */ unsigned char eFileLock; /* The type of lock held on this fd */ unsigned char ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ - unsigned char szSector; /* Sectorsize/512 */ int lastErrno; /* The unix errno from last I/O error */ void *lockingContext; /* Locking style specific state */ UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ @@ -420,14 +416,6 @@ static struct unix_syscall { { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 }, #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) -#if defined(MISSING_STATVFS) - { "statvfs", (sqlite3_syscall_ptr)0, 0 }, -#define osStatvfs ((int(*)(const char*,void*))aSyscall[20].pCurrent) -#else - { "statvfs", (sqlite3_syscall_ptr)statvfs, 0 }, -#define osStatvfs ((int(*)(const char*,struct statvfs*))aSyscall[20].pCurrent) -#endif - }; /* End of the overrideable system calls */ /* @@ -3600,23 +3588,8 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ ** same for both. */ static int unixSectorSize(sqlite3_file *pFile){ - unixFile *p = (unixFile*)pFile; - if( p->szSector==0 ){ -#ifdef MISSING_STATVFS - p->szSector = SQLITE_DEFAULT_SECTOR_SIZE/512; -#else - struct statvfs x; - int sz; - memset(&x, 0, sizeof(x)); - osStatvfs(p->zPath, &x); - sz = (int)x.f_frsize; - if( sz<512 || sz>65536 || (sz&(sz-1))!=0 ){ - sz = SQLITE_DEFAULT_SECTOR_SIZE; - } - p->szSector = sz/512; -#endif - } - return p->szSector*512; + (void)pFile; + return SQLITE_DEFAULT_SECTOR_SIZE; } /* @@ -6833,7 +6806,7 @@ int sqlite3_os_init(void){ /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ - assert( ArraySize(aSyscall)==21 ); + assert( ArraySize(aSyscall)==20 ); /* Register all VFSes defined in the aVfs[] array */ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ diff --git a/src/os_win.c b/src/os_win.c index 18fdd93933..9ced7baaf0 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -61,7 +61,6 @@ struct winFile { short sharedLockByte; /* Randomly chosen byte used as a shared lock */ u8 ctrlFlags; /* Flags. See WINFILE_* below */ DWORD lastErrno; /* The Windows errno from the last I/O error */ - DWORD sectorSize; /* Sector size of the device file is on */ winShm *pShm; /* Instance of shared memory on this file */ const char *zPath; /* Full pathname of this file */ int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */ @@ -151,14 +150,6 @@ static void winMemShutdown(void *pAppData); const sqlite3_mem_methods *sqlite3MemGetWin32(void); #endif /* SQLITE_WIN32_MALLOC */ -/* -** Forward prototypes. -*/ -static int getSectorSize( - sqlite3_vfs *pVfs, - const char *zRelative /* UTF-8 file name */ -); - /* ** The following variable is (normally) set once and never changes ** thereafter. It records whether the operating system is Win9x @@ -2225,8 +2216,8 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ ** same for both. */ static int winSectorSize(sqlite3_file *id){ - assert( id!=0 ); - return (int)(((winFile*)id)->sectorSize); + (void)id; + return SQLITE_DEFAULT_SECTOR_SIZE; } /* @@ -3203,7 +3194,6 @@ static int winOpen( if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){ pFile->ctrlFlags |= WINFILE_PSOW; } - pFile->sectorSize = getSectorSize(pVfs, zUtf8Name); #if SQLITE_OS_WINCE if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB @@ -3448,81 +3438,6 @@ static int winFullPathname( #endif } -/* -** Get the sector size of the device used to store -** file. -*/ -static int getSectorSize( - sqlite3_vfs *pVfs, - const char *zRelative /* UTF-8 file name */ -){ - DWORD bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE; - /* GetDiskFreeSpace is not supported under WINCE */ -#if SQLITE_OS_WINCE - UNUSED_PARAMETER(pVfs); - UNUSED_PARAMETER(zRelative); -#else - char zFullpath[MAX_PATH+1]; - int rc; - DWORD dwRet = 0; - DWORD dwDummy; - - /* - ** We need to get the full path name of the file - ** to get the drive letter to look up the sector - ** size. - */ - SimulateIOErrorBenign(1); - sqlite3BeginBenignMalloc(); - rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath); - sqlite3EndBenignMalloc(); - SimulateIOErrorBenign(0); - if( rc == SQLITE_OK ) - { - void *zConverted; - sqlite3BeginBenignMalloc(); - zConverted = convertUtf8Filename(zFullpath); - sqlite3EndBenignMalloc(); - if( zConverted ){ - if( isNT() ){ - /* trim path to just drive reference */ - LPWSTR p = zConverted; - for(;*p;p++){ - if( *p == '\\' ){ - *p = '\0'; - break; - } - } - dwRet = osGetDiskFreeSpaceW((LPCWSTR)zConverted, - &dwDummy, - &bytesPerSector, - &dwDummy, - &dwDummy); - }else{ - /* trim path to just drive reference */ - char *p = (char *)zConverted; - for(;*p;p++){ - if( *p == '\\' ){ - *p = '\0'; - break; - } - } - dwRet = osGetDiskFreeSpaceA((char*)zConverted, - &dwDummy, - &bytesPerSector, - &dwDummy, - &dwDummy); - } - sqlite3_free(zConverted); - } - if( !dwRet ){ - bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE; - } - } -#endif - return (int) bytesPerSector; -} - #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** Interfaces for opening a shared library, finding entry points From 52bcde0e2d73c73a16a05b8e6a637b60034e9b48 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Jan 2012 14:50:45 +0000 Subject: [PATCH 158/161] Make sure filenames passed into sqlite3OsOpen() always have the extra zero-terminators needed by sqlite3_uri_parameter(). FossilOrigin-Name: d73e93cfdc9441ade77b796dcdcf6eeb753cb398 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/os_unix.c | 4 ++-- src/os_win.c | 2 +- src/pager.c | 8 ++++---- src/util.c | 7 ++++++- src/vdbeaux.c | 2 +- 7 files changed, 25 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 182ee59812..10533ad79f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\scode\sthat\sattempts\sto\sfind\sthe\ssector\ssize\sfrom\sthe\sOS\sand\nhardcode\sthe\sxSectorSize\smethods\sof\sthe\sunix\sand\swindows\sVFSes\sto\sreturn\nSQLITE_DEFAULT_SECTOR_SIZE,\swhich\sis\snow\sset\sto\s4096\sunless\soverridden. -D 2012-01-02T18:20:14.209 +C Make\ssure\sfilenames\spassed\sinto\ssqlite3OsOpen()\salways\shave\sthe\sextra\nzero-terminators\sneeded\sby\ssqlite3_uri_parameter(). +D 2012-01-03T14:50:45.695 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,9 +166,9 @@ F src/os.c 519bdf7c608c4848024e1d87934f9305454145f4 F src/os.h c7d888830f168a9b681b3aec30789f4ad2445c17 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c 51acd5477f7c92321bbc665282a710556f19b4a7 -F src/os_win.c 0d3522dd0ad82b615748d4d391211af62b57ae03 -F src/pager.c a21a3191ab75310ea75bb61149e63b835f77f5f0 +F src/os_unix.c aff2f5e6632065dec09a53af1daf1e75fe12dce5 +F src/os_win.c f1057db64d481dffb15776147b06b15f4f8d7b87 +F src/pager.c 5b89ab92631a8fc488b87cc663ab064802173fec F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 @@ -238,13 +238,13 @@ F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12 F src/trigger.c ee7e178fb9188f44b532cebd449a7c1df90fb684 F src/update.c d3076782c887c10e882996550345da9c4c9f9dea F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 -F src/util.c 9e07bd67dfafe9c75b1da78c87ba030cebbb5388 +F src/util.c ad06374bc92b98071f221f00d553daea514f2b60 F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa F src/vdbe.c 50f0cf69eb64e11185042d15062bec8a1373a8a2 F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb F src/vdbeInt.h 48c158b2fceca9682d1577e61c62da3c58cf0748 F src/vdbeapi.c 3662b6a468a2a4605a15dfab313baa6dff81ad91 -F src/vdbeaux.c 6b6c7acacdb47af51853b1f2a19a9b755ffe2aba +F src/vdbeaux.c 01fe6e35e5923c401a912b4662f0909d62453a1d F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 5e8c0831bd0a270ff81af385e891ff381dec900f F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P da52e6e8b490508bc1ee4700aa45a79f398363da -R a0b8de10aeee04558967b4b25ead4061 +P 03d8362cd2cadab8e1cc5b18a3194152f2bd0a84 +R bab430cac57fc8357d76990e6c780f64 U drh -Z d686dcd0a4de73c84f2800d730af321e +Z 242be7d816ac09f954d1b623be157dd8 diff --git a/manifest.uuid b/manifest.uuid index 44d9031030..9f17d9d5af 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -03d8362cd2cadab8e1cc5b18a3194152f2bd0a84 \ No newline at end of file +d73e93cfdc9441ade77b796dcdcf6eeb753cb398 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 6542c0e66c..e0a39882e1 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3866,9 +3866,9 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ } #ifdef SQLITE_SHM_DIRECTORY - nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 30; + nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31; #else - nShmFilename = 5 + (int)strlen(pDbFd->zPath); + nShmFilename = 6 + (int)strlen(pDbFd->zPath); #endif pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename ); if( pShmNode==0 ){ diff --git a/src/os_win.c b/src/os_win.c index 9ced7baaf0..e570d7fba6 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -2466,7 +2466,7 @@ static int winOpenSharedMemory(winFile *pDbFd){ if( p==0 ) return SQLITE_IOERR_NOMEM; memset(p, 0, sizeof(*p)); nName = sqlite3Strlen30(pDbFd->zPath); - pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 15 ); + pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 16 ); if( pNew==0 ){ sqlite3_free(p); return SQLITE_IOERR_NOMEM; diff --git a/src/pager.c b/src/pager.c index 3640d462bb..c57fe18745 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4407,9 +4407,9 @@ int sqlite3PagerOpen( ROUND8(pVfs->szOsFile) + /* The main db file */ journalFileSize * 2 + /* The two journal files */ nPathname + 1 + nUri + /* zFilename */ - nPathname + 8 + 1 /* zJournal */ + nPathname + 8 + 2 /* zJournal */ #ifndef SQLITE_OMIT_WAL - + nPathname + 4 + 1 /* zWal */ + + nPathname + 4 + 2 /* zWal */ #endif ); assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); @@ -4432,12 +4432,12 @@ int sqlite3PagerOpen( memcpy(pPager->zFilename, zPathname, nPathname); memcpy(&pPager->zFilename[nPathname+1], zUri, nUri); memcpy(pPager->zJournal, zPathname, nPathname); - memcpy(&pPager->zJournal[nPathname], "-journal", 8); + memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+1); sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal); #ifndef SQLITE_OMIT_WAL pPager->zWal = &pPager->zJournal[nPathname+8+1]; memcpy(pPager->zWal, zPathname, nPathname); - memcpy(&pPager->zWal[nPathname], "-wal", 4); + memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1); sqlite3FileSuffix3(pPager->zFilename, pPager->zWal); #endif sqlite3_free(zPathname); diff --git a/src/util.c b/src/util.c index fd3c858ab7..4a332a5e98 100644 --- a/src/util.c +++ b/src/util.c @@ -1164,6 +1164,10 @@ int sqlite3AbsInt32(int x){ ** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always ** do the suffix shortening regardless of URI parameter. ** +** Assume that zBaseFilename contains two \000 terminator bytes (so that +** it can be harmlessly passed into sqlite3_uri_parameter()) and copy both +** zero terminator bytes into the end of the revised name. +** ** Examples: ** ** test.db-journal => test.nal @@ -1172,6 +1176,7 @@ int sqlite3AbsInt32(int x){ ** test.db-mj7f3319fa => test.9fa */ void sqlite3FileSuffix3(const char *zBaseFilename, char *z){ + assert( zBaseFilename[strlen(zBaseFilename)+1]==0 ); #if SQLITE_ENABLE_8_3_NAMES<2 if( sqlite3_uri_boolean(zBaseFilename, "8_3_names", 0) ) #endif @@ -1179,7 +1184,7 @@ void sqlite3FileSuffix3(const char *zBaseFilename, char *z){ int i, sz; sz = sqlite3Strlen30(z); for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} - if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4); + if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 5); } } #endif diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 9e3a493283..d5d27fd557 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1839,7 +1839,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ /* Select a master journal file name */ nMainFile = sqlite3Strlen30(zMainFile); - zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XX", zMainFile); + zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz", zMainFile); if( zMaster==0 ) return SQLITE_NOMEM; do { u32 iRandom; From e4c88c0c384f681374a51983f90398e4d5cb1825 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 4 Jan 2012 12:57:45 +0000 Subject: [PATCH 159/161] Fix typos and comments and make minor changes to a few function names, as suggested by readership. FossilOrigin-Name: e9d05cbb7676cbda83f1b3b71447404d7edde898 --- manifest | 30 +++++++++++++++--------------- manifest.uuid | 2 +- src/insert.c | 2 +- src/mutex.c | 2 +- src/mutex_noop.c | 4 ++-- src/mutex_unix.c | 2 +- src/sqlite.h.in | 4 ++-- src/test_func.c | 10 +++++----- src/vdbe.c | 16 ++++++++-------- src/vdbeInt.h | 4 ++-- src/vdbeaux.c | 8 +++++--- src/vdbemem.c | 8 ++++---- 12 files changed, 47 insertions(+), 45 deletions(-) diff --git a/manifest b/manifest index 10533ad79f..4c82af5a04 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sfilenames\spassed\sinto\ssqlite3OsOpen()\salways\shave\sthe\sextra\nzero-terminators\sneeded\sby\ssqlite3_uri_parameter(). -D 2012-01-03T14:50:45.695 +C Fix\stypos\sand\scomments\sand\smake\sminor\schanges\sto\sa\sfew\sfunction\snames,\nas\ssuggested\sby\sreadership. +D 2012-01-04T12:57:45.610 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -142,7 +142,7 @@ F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c ea820fe9af748075b3b6827fb6f23f25079bf1f7 +F src/insert.c d7c69718acbb92e10e4b121da7bed13903342962 F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 @@ -155,11 +155,11 @@ F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534 F src/mem5.c c2c63b7067570b00bf33d751c39af24182316f7f F src/memjournal.c 0ebce851677a7ac035ba1512a7e65851b34530c6 -F src/mutex.c 6949180803ff05a7d0e2b9334a95b4fb5a00e23f +F src/mutex.c d3b66a569368015e0fcb1ac15f81c119f504d3bc F src/mutex.h 2a79e0c10c26412546b501ee0f3d92b42decf63e -F src/mutex_noop.c d5cfbca87168c661a0b118cd8e329a908e453151 +F src/mutex_noop.c 7682796b7d8d39bf1c138248858efcd10c9e1553 F src/mutex_os2.c 882d735098c07c8c6a5472b8dd66e19675fe117f -F src/mutex_unix.c b4f4e923bb8de93ec3f251fadb50855f23df9579 +F src/mutex_unix.c c3a4e00f96ba068a8dbef34084465979aaf369cc F src/mutex_w32.c 5e54f3ba275bcb5d00248b8c23107df2e2f73e33 F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 F src/os.c 519bdf7c608c4848024e1d87934f9305454145f4 @@ -182,7 +182,7 @@ F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c a1d075db66a0ea42807353501b62997969e5be79 F src/shell.c aa4183d4a5243d8110b1d3d77faa4aea7e9c9c2d -F src/sqlite.h.in 80115fdec17acf32f93adbf950960b889de98b79 +F src/sqlite.h.in 02352d9488394a3489b2d153360da58a7c392070 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h b8fdd9c39c8d7f5c794f4ea917293d9c75b9aff2 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -205,7 +205,7 @@ F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2 F src/test_config.c a036a69b550ebc477ab9ca2b37269201f888436e F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc -F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 +F src/test_func.c 6232d722a4ddb193035aa13a03796bf57d6c12fd F src/test_fuzzer.c f884f6f32e8513d34248d6e1ac8a32047fead254 F src/test_hexio.c c4773049603151704a6ab25ac5e936b5109caf5a F src/test_init.c 3cbad7ce525aec925f8fda2192d576d47f0d478a @@ -240,13 +240,13 @@ F src/update.c d3076782c887c10e882996550345da9c4c9f9dea F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 F src/util.c ad06374bc92b98071f221f00d553daea514f2b60 F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa -F src/vdbe.c 50f0cf69eb64e11185042d15062bec8a1373a8a2 +F src/vdbe.c d5062ca4c623b92cecbfa005458a9a4b92f162cf F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb -F src/vdbeInt.h 48c158b2fceca9682d1577e61c62da3c58cf0748 +F src/vdbeInt.h 88e4d5d717946bfed800a6383c53883484f1a35e F src/vdbeapi.c 3662b6a468a2a4605a15dfab313baa6dff81ad91 -F src/vdbeaux.c 01fe6e35e5923c401a912b4662f0909d62453a1d +F src/vdbeaux.c eb13a6917ed7455b5b49236fe5cfb3d3c3e4c57b F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb -F src/vdbemem.c 5e8c0831bd0a270ff81af385e891ff381dec900f +F src/vdbemem.c dadc7465860ad2e980f01c9b0b1ba44903249257 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 03d8362cd2cadab8e1cc5b18a3194152f2bd0a84 -R bab430cac57fc8357d76990e6c780f64 +P d73e93cfdc9441ade77b796dcdcf6eeb753cb398 +R 393cb6b00a2ad516972e1693f3526c0a U drh -Z 242be7d816ac09f954d1b623be157dd8 +Z b9855855a204c8fcbbc8d1530cb14b4f diff --git a/manifest.uuid b/manifest.uuid index 9f17d9d5af..508fdfe7f0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d73e93cfdc9441ade77b796dcdcf6eeb753cb398 \ No newline at end of file +e9d05cbb7676cbda83f1b3b71447404d7edde898 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index dadb10acdb..6b31e24f2c 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1107,7 +1107,7 @@ insert_cleanup: ** cause sqlite3_exec() to return immediately ** with SQLITE_CONSTRAINT. ** -** any FAIL Sqlite_exec() returns immediately with a +** any FAIL Sqlite3_exec() returns immediately with a ** return code of SQLITE_CONSTRAINT. The ** transaction is not rolled back and any ** prior changes are retained. diff --git a/src/mutex.c b/src/mutex.c index 869a4aeb08..b567e7c27e 100644 --- a/src/mutex.c +++ b/src/mutex.c @@ -150,4 +150,4 @@ int sqlite3_mutex_notheld(sqlite3_mutex *p){ } #endif -#endif /* SQLITE_MUTEX_OMIT */ +#endif /* !defined(SQLITE_MUTEX_OMIT) */ diff --git a/src/mutex_noop.c b/src/mutex_noop.c index c5fd5202c2..456e82a25e 100644 --- a/src/mutex_noop.c +++ b/src/mutex_noop.c @@ -202,5 +202,5 @@ sqlite3_mutex_methods const *sqlite3NoopMutex(void){ sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ return sqlite3NoopMutex(); } -#endif /* SQLITE_MUTEX_NOOP */ -#endif /* SQLITE_MUTEX_OMIT */ +#endif /* defined(SQLITE_MUTEX_NOOP) */ +#endif /* !defined(SQLITE_MUTEX_OMIT) */ diff --git a/src/mutex_unix.c b/src/mutex_unix.c index aa9a8cf265..eca7295831 100644 --- a/src/mutex_unix.c +++ b/src/mutex_unix.c @@ -348,4 +348,4 @@ sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ return &sMutex; } -#endif /* SQLITE_MUTEX_PTHREAD */ +#endif /* SQLITE_MUTEX_PTHREADS */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 029a10dd74..2ce3a6ff5b 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5398,7 +5398,7 @@ int sqlite3_vfs_unregister(sqlite3_vfs*); ** **
      **
    • SQLITE_MUTEX_OS2 -**
    • SQLITE_MUTEX_PTHREAD +**
    • SQLITE_MUTEX_PTHREADS **
    • SQLITE_MUTEX_W32 **
    • SQLITE_MUTEX_NOOP **
    )^ @@ -5406,7 +5406,7 @@ int sqlite3_vfs_unregister(sqlite3_vfs*); ** ^The SQLITE_MUTEX_NOOP implementation is a set of routines ** that does no real locking and is appropriate for use in ** a single-threaded application. ^The SQLITE_MUTEX_OS2, -** SQLITE_MUTEX_PTHREAD, and SQLITE_MUTEX_W32 implementations +** SQLITE_MUTEX_PTHREADS, and SQLITE_MUTEX_W32 implementations ** are appropriate for use on OS/2, Unix, and Windows. ** ** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor diff --git a/src/test_func.c b/src/test_func.c index a123943425..fff070e7ee 100644 --- a/src/test_func.c +++ b/src/test_func.c @@ -149,13 +149,13 @@ static void test_destructor_count( ** arguments. It returns the text value returned by the sqlite3_errmsg16() ** API function. */ -#ifndef SQLITE_OMIT_BUILTIN_TEST +#ifndef SQLITE_OMIT_BUILTIN_TEST void sqlite3BeginBenignMalloc(void); void sqlite3EndBenignMalloc(void); -#else - #define sqlite3BeginBenignMalloc() - #define sqlite3EndBenignMalloc() -#endif +#else + #define sqlite3BeginBenignMalloc() + #define sqlite3EndBenignMalloc() +#endif static void test_agg_errmsg16_step(sqlite3_context *a, int b,sqlite3_value **c){ } static void test_agg_errmsg16_final(sqlite3_context *ctx){ diff --git a/src/vdbe.c b/src/vdbe.c index 4cc5627382..5696d1f010 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -52,7 +52,7 @@ ** not misused. */ #ifdef SQLITE_DEBUG -# define memAboutToChange(P,M) sqlite3VdbeMemPrepareToChange(P,M) +# define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M) #else # define memAboutToChange(P,M) #endif @@ -70,8 +70,8 @@ int sqlite3_search_count = 0; /* ** When this global variable is positive, it gets decremented once before -** each instruction in the VDBE. When reaches zero, the u1.isInterrupted -** field of the sqlite3 structure is set in order to simulate and interrupt. +** each instruction in the VDBE. When it reaches zero, the u1.isInterrupted +** field of the sqlite3 structure is set in order to simulate an interrupt. ** ** This facility is used for testing purposes only. It does not function ** in an ordinary build. @@ -196,7 +196,7 @@ static VdbeCursor *allocateCursor( Vdbe *p, /* The virtual machine */ int iCur, /* Index of the new VdbeCursor */ int nField, /* Number of fields in the table or index */ - int iDb, /* When database the cursor belongs to, or -1 */ + int iDb, /* Database the cursor belongs to, or -1 */ int isBtreeCursor /* True for B-Tree. False for pseudo-table or vtab */ ){ /* Find the memory cell that will be used to store the blob of memory @@ -478,7 +478,7 @@ static void registerTrace(FILE *out, int iReg, Mem *p){ ** ** This macro added to every instruction that does a jump in order to ** implement a loop. This test used to be on every single instruction, -** but that meant we more testing that we needed. By only testing the +** but that meant we more testing than we needed. By only testing the ** flag on jump instructions, we get a (small) speed improvement. */ #define CHECK_FOR_INTERRUPT \ @@ -673,7 +673,7 @@ int sqlite3VdbeExec( assert( pOp->p2<=p->nMem ); pOut = &aMem[pOp->p2]; memAboutToChange(p, pOut); - MemReleaseExt(pOut); + VdbeMemRelease(pOut); pOut->flags = MEM_Int; } @@ -977,7 +977,7 @@ case OP_Null: { /* out2-prerelease */ while( cnt>0 ){ pOut++; memAboutToChange(p, pOut); - MemReleaseExt(pOut); + VdbeMemRelease(pOut); pOut->flags = MEM_Null; cnt--; } @@ -2375,7 +2375,7 @@ case OP_Column: { if( aOffset[p2] ){ assert( rc==SQLITE_OK ); if( zRec ){ - MemReleaseExt(pDest); + VdbeMemRelease(pDest); sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], pDest); }else{ len = sqlite3VdbeSerialTypeLen(aType[p2]); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index a56dedf6af..e3687cf14d 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -408,7 +408,7 @@ int sqlite3VdbeMemNumerify(Mem*); int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*); void sqlite3VdbeMemRelease(Mem *p); void sqlite3VdbeMemReleaseExternal(Mem *p); -#define MemReleaseExt(X) \ +#define VdbeMemRelease(X) \ if((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame)) \ sqlite3VdbeMemReleaseExternal(X); int sqlite3VdbeMemFinalize(Mem*, FuncDef*); @@ -447,7 +447,7 @@ int sqlite3VdbeSorterCompare(VdbeCursor *, Mem *, int *); #endif #ifdef SQLITE_DEBUG -void sqlite3VdbeMemPrepareToChange(Vdbe*,Mem*); +void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*); #endif #ifndef SQLITE_OMIT_FOREIGN_KEY diff --git a/src/vdbeaux.c b/src/vdbeaux.c index d5d27fd557..c1566f37d8 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -196,7 +196,8 @@ int sqlite3VdbeAddOp4( /* ** Add an OP_ParseSchema opcode. This routine is broken out from -** sqlite3VdbeAddOp4() since it needs to also local all btrees. +** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees +** as having been used. ** ** The zWhere string must have been obtained from sqlite3_malloc(). ** This routine will take ownership of the allocated memory. @@ -963,8 +964,9 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ ** Declare to the Vdbe that the BTree object at db->aDb[i] is used. ** ** The prepared statements need to know in advance the complete set of -** attached databases that they will be using. A mask of these databases -** is maintained in p->btreeMask and is used for locking and other purposes. +** attached databases that will be use. A mask of these databases +** is maintained in p->btreeMask. The p->lockMask value is the subset of +** p->btreeMask of databases that will require a lock. */ void sqlite3VdbeUsesBtree(Vdbe *p, int i){ assert( i>=0 && idb->nDb && i<(int)sizeof(yDbMask)*8 ); diff --git a/src/vdbemem.c b/src/vdbemem.c index 423d17b15a..0c78594319 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -292,7 +292,7 @@ void sqlite3VdbeMemReleaseExternal(Mem *p){ ** (Mem.type==SQLITE_TEXT). */ void sqlite3VdbeMemRelease(Mem *p){ - MemReleaseExt(p); + VdbeMemRelease(p); sqlite3DbFree(p->db, p->zMalloc); p->z = 0; p->zMalloc = 0; @@ -588,7 +588,7 @@ int sqlite3VdbeMemTooBig(Mem *p){ ** This is used for testing and debugging only - to make sure shallow ** copies are not misused. */ -void sqlite3VdbeMemPrepareToChange(Vdbe *pVdbe, Mem *pMem){ +void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ int i; Mem *pX; for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){ @@ -614,7 +614,7 @@ void sqlite3VdbeMemPrepareToChange(Vdbe *pVdbe, Mem *pMem){ */ void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ assert( (pFrom->flags & MEM_RowSet)==0 ); - MemReleaseExt(pTo); + VdbeMemRelease(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); pTo->xDel = 0; if( (pFrom->flags&MEM_Static)==0 ){ @@ -632,7 +632,7 @@ int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ int rc = SQLITE_OK; assert( (pFrom->flags & MEM_RowSet)==0 ); - MemReleaseExt(pTo); + VdbeMemRelease(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); pTo->flags &= ~MEM_Dyn; From bce51350d68e183ff7dd15f7f2f36020a4adec5c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 5 Jan 2012 11:43:10 +0000 Subject: [PATCH 160/161] Remove the SQLITE_FCNTL_SYNC_OMITTED cases from the unix and windows VFSes as they are no longer needed because of check-in [fd3822f1f2]. FossilOrigin-Name: 7cf568a101cda20ab6005bd250154b7f6960193a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_unix.c | 3 --- src/os_win.c | 3 --- 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 4c82af5a04..9cb80d72cd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypos\sand\scomments\sand\smake\sminor\schanges\sto\sa\sfew\sfunction\snames,\nas\ssuggested\sby\sreadership. -D 2012-01-04T12:57:45.610 +C Remove\sthe\sSQLITE_FCNTL_SYNC_OMITTED\scases\sfrom\sthe\sunix\sand\swindows\sVFSes\nas\sthey\sare\sno\slonger\sneeded\sbecause\sof\scheck-in\s[fd3822f1f2]. +D 2012-01-05T11:43:10.883 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,8 +166,8 @@ F src/os.c 519bdf7c608c4848024e1d87934f9305454145f4 F src/os.h c7d888830f168a9b681b3aec30789f4ad2445c17 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c aff2f5e6632065dec09a53af1daf1e75fe12dce5 -F src/os_win.c f1057db64d481dffb15776147b06b15f4f8d7b87 +F src/os_unix.c f19ca2ef603e4f6510f3daf206e244476a68413d +F src/os_win.c 88b35c8fe7b32c7398ceace727ea01120cb21989 F src/pager.c 5b89ab92631a8fc488b87cc663ab064802173fec F src/pager.h 5cd760857707529b403837d813d86b68938d6183 F src/parse.y fabb2e7047417d840e6fdb3ef0988a86849a08ba @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P d73e93cfdc9441ade77b796dcdcf6eeb753cb398 -R 393cb6b00a2ad516972e1693f3526c0a +P e9d05cbb7676cbda83f1b3b71447404d7edde898 +R 6615d318658492419d159ab8371d00f5 U drh -Z b9855855a204c8fcbbc8d1530cb14b4f +Z cda129bb9172ce6754b58d4da58725d3 diff --git a/manifest.uuid b/manifest.uuid index 508fdfe7f0..e17fa003e3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e9d05cbb7676cbda83f1b3b71447404d7edde898 \ No newline at end of file +7cf568a101cda20ab6005bd250154b7f6960193a \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index e0a39882e1..4f263bcdd0 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3570,9 +3570,6 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ return proxyFileControl(id,op,pArg); } #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ - case SQLITE_FCNTL_SYNC_OMITTED: { - return SQLITE_OK; /* A no-op */ - } } return SQLITE_NOTFOUND; } diff --git a/src/os_win.c b/src/os_win.c index e570d7fba6..7269f436d7 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -2184,9 +2184,6 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ *(char**)pArg = sqlite3_mprintf("win32"); return SQLITE_OK; } - case SQLITE_FCNTL_SYNC_OMITTED: { - return SQLITE_OK; - } case SQLITE_FCNTL_WIN32_AV_RETRY: { int *a = (int*)pArg; if( a[0]>0 ){ From e0711b47b12cf0312690c7240d6ee09b67ce4822 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 5 Jan 2012 12:38:02 +0000 Subject: [PATCH 161/161] Ensure 8-byte alignment of Index.aiRowEst[] elements even if the size of an Index object is not a multiple of 8 bytes. FossilOrigin-Name: 1378f905d37544701776d38987fe7a312b255983 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 9cb80d72cd..bd8f246a59 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sSQLITE_FCNTL_SYNC_OMITTED\scases\sfrom\sthe\sunix\sand\swindows\sVFSes\nas\sthey\sare\sno\slonger\sneeded\sbecause\sof\scheck-in\s[fd3822f1f2]. -D 2012-01-05T11:43:10.883 +C Ensure\s8-byte\salignment\sof\sIndex.aiRowEst[]\selements\seven\sif\sthe\ssize\sof\nan\sIndex\sobject\sis\snot\sa\smultiple\sof\s8\sbytes. +D 2012-01-05T12:38:02.435 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -128,7 +128,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 8f683b1fcfd9ac92efa781c9c56c537e080a7117 F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 6e57bacaa4feb7dd56719678133e63a7c289c6e7 -F src/build.c 8915bb6d72ead998f94c2756ea8d143c77709b70 +F src/build.c 8e2a4dedad860fed982270ef43968505f35ec57f F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33 @@ -986,7 +986,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P e9d05cbb7676cbda83f1b3b71447404d7edde898 -R 6615d318658492419d159ab8371d00f5 +P 7cf568a101cda20ab6005bd250154b7f6960193a +R 17a54c6dc9279f1461f74799fcc0456e U drh -Z cda129bb9172ce6754b58d4da58725d3 +Z e2b3f0a5a9dd1fb18b07ce4e17a75f03 diff --git a/manifest.uuid b/manifest.uuid index e17fa003e3..e41b002552 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7cf568a101cda20ab6005bd250154b7f6960193a \ No newline at end of file +1378f905d37544701776d38987fe7a312b255983 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 46512f8e38..5798e7322e 100644 --- a/src/build.c +++ b/src/build.c @@ -2661,7 +2661,7 @@ Index *sqlite3CreateIndex( nName = sqlite3Strlen30(zName); nCol = pList->nExpr; pIndex = sqlite3DbMallocZero(db, - sizeof(Index) + /* Index structure */ + ROUND8(sizeof(Index)) + /* Index structure */ ROUND8(sizeof(tRowcnt)*(nCol+1)) + /* Index.aiRowEst */ sizeof(char *)*nCol + /* Index.azColl */ sizeof(int)*nCol + /* Index.aiColumn */ @@ -2672,7 +2672,8 @@ Index *sqlite3CreateIndex( if( db->mallocFailed ){ goto exit_create_index; } - pIndex->aiRowEst = (tRowcnt*)(&pIndex[1]); + zExtra = (char*)pIndex; + pIndex->aiRowEst = (tRowcnt*)&zExtra[ROUND8(sizeof(Index))]; pIndex->azColl = (char**) ((char*)pIndex->aiRowEst + ROUND8(sizeof(tRowcnt)*nCol+1)); assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) );