Compare commits

...

91 Commits

Author SHA1 Message Date
mistachkin 7547f78889 Expand scope of the SQLITE_DISABLE_MMAP define for the Win32 VFS.
FossilOrigin-Name: daa168f3dad995c4b7dd60e7717db90639e167c2
2013-04-11 22:52:44 +00:00
mistachkin fdd72c9a2f For the multi-process tester on Win32, make use of the GetCurrentProcessId API.
FossilOrigin-Name: f1b524b9d9ea3db96d54ac55c39f15e6879085bd
2013-04-11 21:13:10 +00:00
drh e82c6c39f4 Fix the xCheckReservedLock() method on the windows VFS so that it cannot
return a false positive when two or more processes use it at the same time
on the same file.  Ticket [7ff3120e4fa54abb55]

FossilOrigin-Name: dd3510bb20ade173c81c9874c05466011c8a249d
2013-04-11 18:28:55 +00:00
drh ef8e986bde Fix pragma code generation so that it always outputs an OP_Trace opcode so
that pragmas are shown in sqlite3_trace() output.

FossilOrigin-Name: 663f04bd48bc6f302230a22bd22b82bde2353943
2013-04-11 13:26:18 +00:00
drh e3be8c8627 Show the process-id on log messages from mptester.
FossilOrigin-Name: 6748a83dc5c02db37ecd963e678c5c69db142cac
2013-04-11 11:53:45 +00:00
drh fbc7e8845d Have the UNIX VFS issue warnings via sqlite3_log() if a database file is
renamed or unlinked or linked to more than one name while the file is open.

FossilOrigin-Name: e238dcf9189c029fbdcf89339e21d9cdd8fbf2c5
2013-04-11 01:16:15 +00:00
mistachkin 08d418904a Enhance multi-process tester integration with the Win32 API.
FossilOrigin-Name: 0fdc743583c67a3a017b9ad812c62a5104b9aee7
2013-04-11 00:09:44 +00:00
drh d040e76442 Add new primary error codes SQLITE_NOTICE and SQLITE_WARNING for use with
sqlite3_log().  Add new extended error codes SQLITE_NOTICE_RECOVER_WAL and
SQLITE_NOTICE_RECOVER_ROLLBACK to use with sqlite3_log() messages that occur
on each recovery.

FossilOrigin-Name: be7d2c5482c41baf000d7fb5dccc31b974e91064
2013-04-10 23:48:37 +00:00
drh 56282a5bc7 Add the sqlite3_strglob() interface.
FossilOrigin-Name: 41d6ff32a6dd1311dc3aabe5156335a64a886919
2013-04-10 16:13:38 +00:00
drh 4c5298f352 Use symbolic names for tasks in mptester.
FossilOrigin-Name: f0d95afc73f8dbce8943dceb4a14b7de650c8823
2013-04-10 12:01:21 +00:00
mistachkin 21c9b6bdc9 Fix typo in name of mptest executable files in clean targets.
FossilOrigin-Name: 4c7d9e1ed8722e0c75b5fdbeffb9030ccef0bd64
2013-04-10 03:06:43 +00:00
mistachkin 65eb64765c Correct test numbering on several rtree tests.
FossilOrigin-Name: 0adf8a3a4f2ca370568b35c9e8ce0e18f18701a2
2013-04-10 02:56:24 +00:00
drh 7de96f7fc1 Limit integrity_check output to 10 lines in mptester scripts.
FossilOrigin-Name: 67ee0dc0f4de5dc2ae92fb98932f1fdda3e76bdf
2013-04-09 20:04:09 +00:00
drh ab755ac81a Change the rollback journal so that it invokes sqlite3_log() make a record
of a recovery, just as the WAL journal does.

FossilOrigin-Name: 7cd3f6cd3a39ed1c4bbf9e3508824150632c5bd9
2013-04-09 18:36:36 +00:00
drh 6e0b6d52da Add extra #ifndef statements in os_unix.c and os_win.c to make sure the
memory mapped I/O really is disabled when SQLITE_DISABLE_MMAP is set.

FossilOrigin-Name: c1e2523c9051782569291fff998140f7e0b70b6d
2013-04-09 16:19:20 +00:00
drh 188d488409 Disable the use of memory-mapped I/O if the SQLITE_DISABLE_MMAP macro is
defined.  Automatically define this macro for OpenBSD and QNX.  Other
systems are likely to be added to the disabled list over time.

FossilOrigin-Name: 8a4314a398c6c6efb25e6993c826b7e60d9bb1f9
2013-04-08 20:47:49 +00:00
drh f90e50f60b In mptester, handle startScript no-change commits using a retry rather
than grabbing an exclusive transaction.

FossilOrigin-Name: ae8bb24bfb014bdcb8aaa8159ddae0cd376afe99
2013-04-08 19:13:48 +00:00
drh 6adab7a1a8 Still more tests using mptester. Added test cases that leave rollback
journals that must be recovered by other threads.

FossilOrigin-Name: 437b674f00610e2b925dc00ca27b5022e3858994
2013-04-08 18:58:00 +00:00
drh 023dd903cc Adding tests to the mptester scripts.
FossilOrigin-Name: e121adceb1e267e032dcbadb74eaa692a12a65bb
2013-04-08 17:57:26 +00:00
drh e5ebd22d99 Change mptester to avoid reporting SQLITE_BUSY errors if the busy handler
is turned off and the tracing level is set low.

FossilOrigin-Name: d77407ae6a9e09dea124dd59b14fdbbc36ed3d4e
2013-04-08 15:36:51 +00:00
dan bcb8a868ce Handle the case in os_unix.c where SQLITE_FCNTL_MMAP_LIMIT requests that the mmap limit be set to a value smaller than the current mapping.
FossilOrigin-Name: 360473493ec1a7094a2b1c5436f3b70914a6dfdd
2013-04-08 15:30:41 +00:00
drh 554052c600 Merge the multi-process tester into trunk.
FossilOrigin-Name: ea53c45d79772986d2ad289f4f56f333541747e7
2013-04-08 14:41:34 +00:00
drh bc94dbb661 Add the "mptester" target to the makefiles. Make mptester run with
synchronous off by default.

FossilOrigin-Name: 1397830bfead3699a7e6b1858ae67ae15259b89e
2013-04-08 14:28:33 +00:00
drh 841810cef6 Fix harmless compiler warnings in mptest.c.
FossilOrigin-Name: 59bdbb10ed67bf79e0991e2ad58a28321dedb959
2013-04-08 13:59:11 +00:00
drh 1bf44c7acb Add the vfsname() and eval() SQL functions to mptest.c.
Enhancements to the test/config01.test script.

FossilOrigin-Name: 91397a147ce4f67a7ea1182f06a7dda3a96ec465
2013-04-08 13:48:29 +00:00
drh 7dfe8e2bde Add --if, --else, --endif processing to mptest.c.
FossilOrigin-Name: 51265acae3088a51ac0ce6ab8731e6e15a48d4ae
2013-04-08 13:13:43 +00:00
dan fbfe388d31 Fix an incorrect type cast in an assignment in vdbe.c.
FossilOrigin-Name: 320b5295da57023399c7b9eed82eae40cf619803
2013-04-08 10:38:57 +00:00
drh e348fc7fe8 Fix the --source command so that its argument is relative to the script.
Verify that the SQLite header and library match.  Print SQLite version
and compile-time configuration information on startup.

FossilOrigin-Name: 15cb0db7583c3a24cbea0c72576047a93fba0801
2013-04-06 18:35:07 +00:00
drh 8f35eb024e Merge trunk changes into the mptest branch. The mptest needs the
SQLITE_MAX_SCHEMA_RETRY fix in particular.

FossilOrigin-Name: fb7a7773965697855c12193408cb75300decc23c
2013-04-06 18:10:27 +00:00
drh 60625313b0 Increase the default SQLITE_MAX_SCHEMA_RETRY to 50. Make sure that macro
covers every case where a prepared statement might need to be reprepared due
to a schema change.  The sqlite3_exec() interface now uses 
sqlite3_prepare_v2().

FossilOrigin-Name: c1d7304c80c4a6244c8a9f6fad1eebd0f339c724
2013-04-06 18:06:51 +00:00
drh 1790bb36c5 Add SQLITE_CONFIG_LOG error logging to the mptest program.
FossilOrigin-Name: 716c25bd125c8934499c1fb59a60d7e844c0691c
2013-04-06 14:30:29 +00:00
drh 896be7d93a Get the build of mptest working on mac.
FossilOrigin-Name: a0bae686c9d7f08afac00f66067f5147be6231e0
2013-04-06 14:16:41 +00:00
drh f012ae0759 Get the mptest program running on windows.
FossilOrigin-Name: 3966b33284355325afda627ed6f4e26f967438f8
2013-04-06 14:04:22 +00:00
drh 3f5bc38037 Many improvements to the mptest program. Added a simple test script.
FossilOrigin-Name: 07b0401a9b61b1664fc6dcddac3b5969fc0f481a
2013-04-06 13:09:11 +00:00
dan abd6d84a11 Add tests to "permutations.test coverage-pager" to cover uncovered branches.
FossilOrigin-Name: 07a0e4e9820a85bf1690214fef3577866c763f92
2013-04-06 11:03:09 +00:00
drh 27338e6ed7 Add a prototype TH3-script-style test harness that starts multiple processes
operating on the same database file at the same time.

FossilOrigin-Name: c318fafe686120d7fb8e487eb3bb4942d497665c
2013-04-06 00:19:37 +00:00
dan d7a558a9fb Improve the code coverage of "permutations.test coverage-pager".
FossilOrigin-Name: b095e2cdb61ca8487255687f58fb1024d40f3986
2013-04-05 20:40:43 +00:00
dan ced9813b12 Add further multi-client tests to mmap1.test.
FossilOrigin-Name: a107f75d93b8acd3403d8473a75137378041a833
2013-04-04 19:32:53 +00:00
drh 75f2d540ac Disable memory-mapped I/O for the win32lock.test module
FossilOrigin-Name: 2b3d9805a28e51f646113e22c2dff2272342306e
2013-04-04 17:28:11 +00:00
drh 67f7c780f3 Updates to the file-control documentation. No changes to code.
FossilOrigin-Name: 51fab480d0487107709e6c9e00bc0512b82ef1aa
2013-04-04 01:54:10 +00:00
drh 6109e50f87 Increase the version number to 3.7.17.
FossilOrigin-Name: 5c8c5a2a12f3f5e29c91c4d16e8b4afd4307354e
2013-04-04 00:51:14 +00:00
drh a478b3fa80 Try to use mmap() to speed access to the database file on windows, linux,
and mac.

FossilOrigin-Name: fff2be60779571c8fb89158db976ec3755e9a223
2013-04-04 00:40:17 +00:00
drh b0a8ea046a Release resources prior to bailing out of the btreeCreateTable() routine
following an OOM error.

FossilOrigin-Name: b2a72be9bab77f050bef75477a278a6294d3e854
2013-04-03 21:23:28 +00:00
drh 370c9f498d Remove an unreachable branch in the direct blob I/O logic of btree.c.
FossilOrigin-Name: f97d7274f48e3bb98ed17eae11abb55064134874
2013-04-03 20:04:04 +00:00
drh 716d6d2da7 Fix a bug in the detection of iOS when setting the default mmap_limit.
FossilOrigin-Name: ac1432b3a8e968be4cbc138b4a35f34187c0c36f
2013-04-03 13:38:46 +00:00
drh 34f7490311 Change the mmap_limit pragma to report the new limit, or to report the
existing limit if called with no arguments.  Report the default mmap_limit
as part of PRAGMA compile_options.  Set the default mmmap_limit to 0 for
all systems other than linux, mac, windows, and solaris.

FossilOrigin-Name: 2d9f1327fe79e40435ce1e2594d7cd9a5aea0ef2
2013-04-03 13:09:18 +00:00
dan 6c96946475 Remove the restriction on using xFetch to load the root pages of tables and indexes. It appears to have been based on a misconception.
FossilOrigin-Name: 5b082efead488a2fccc18171e640e0aa5252d1d0
2013-04-03 11:52:16 +00:00
dan f7679ad19e When moving a page to make way for the root page of a new table or index in an auto-vacuum database, save the positions of any cursors that may be holding xFetch references to the page being moved.
FossilOrigin-Name: 9d9b1da54a555e8fb6037d63d1952458c12956d2
2013-04-03 11:38:36 +00:00
dan 227a1c482c In btree.c, save the positions of other cursors open on the same table when writing via an incremental blob handle. Otherwise, they may be left holding an out-of-date xFetch page reference.
FossilOrigin-Name: 3f09fba18f7e61e21381ffea13c31b968efd7d77
2013-04-03 11:17:39 +00:00
drh 2b8246e3e2 Initialize the mmap_limit of temporary files to the configured mmap_limit.
FossilOrigin-Name: 24bab7596bb7385981a5d331df5eeb05353547f7
2013-04-03 10:50:02 +00:00
drh 7e36962e6c Make use of xFetch, if it is available when doing a VACUUM or a backup.
FossilOrigin-Name: 83bc37af07857960c11275891f853a358dcbbf05
2013-04-03 03:53:15 +00:00
drh 7d9f3943ba Add the -mmap option to the command-line shell, for setting the default
mmap_limit.

FossilOrigin-Name: fc30d06c94c8212abb0477fb4cec4520d05bea34
2013-04-03 01:26:54 +00:00
drh 85830a70c2 Fix the unix driver to check defined(_BSD_SOURCE) rather than just the plain
_BSD_SOURCE macro.  This fixes the build for OpenBSD.

FossilOrigin-Name: 1dd42ef4144ee08fb4ee1676d934a56a0e34bac2
2013-04-03 00:42:01 +00:00
dan 48ccef8059 Fix a resource leak in os_unix.c.
FossilOrigin-Name: b29cda03fe4e8d8f5b5acbbea2d69f284a2bdf23
2013-04-02 20:55:01 +00:00
drh c3d53189fc Adjustments to mmap1.test so that it works better on windows. It still gets
some answers wrong, but it no longer crashes.

FossilOrigin-Name: ee8d3ceeec40d84adb8798f084b6f1215ab56d92
2013-04-02 20:29:33 +00:00
dan 81d1765ad8 Fix a bug in mmap2.test that was leaving an invalid sqlite3_log() callback installed, causing a crash.
FossilOrigin-Name: c0cdaa07355f51bd217881b5b91ec2a609fa56f4
2013-04-02 20:19:22 +00:00
mistachkin a9d79ae95d Add assert to the Windows VFS pertaining to the size of the SIZE_T type.
FossilOrigin-Name: 4eeea58354e21797ca1f4dc4ea785d0330381f0b
2013-04-02 20:13:04 +00:00
dan db082408c6 Add test cases to mmap1.test and pagerfault.test.
FossilOrigin-Name: 3050136be962427cc4dcced6077ef29b2a941405
2013-04-02 18:33:55 +00:00
dan d409792838 Change an assert in pager.c to acknowledge that it is possible for sqlite3PagerRollback() to return SQLITE_CORRUPT.
FossilOrigin-Name: d641d3d20d80fdb86d91de31fcf2eb5ca3c5c715
2013-04-02 18:31:29 +00:00
drh a2c16c084a Fix the build for Mac.
FossilOrigin-Name: d36ce0bbad58445c983597ee93438fe07b659cdc
2013-04-02 18:25:04 +00:00
dan f6653871b2 Add new test file btreefault.test.
FossilOrigin-Name: 7fe908afeba16f64edc16824c67b396138581a8f
2013-04-02 15:37:30 +00:00
drh 07fa864d15 Fix a faulty assert() in the os_win.c VFS.
FossilOrigin-Name: fd6ee54969322203c02ce9bd8744e095faf6a69c
2013-04-02 14:37:40 +00:00
drh 936c6d7e9e If the SQLITE_TRACE_SIZE_LIMIT compile-time parameter is set to a positive
integer then limit the expansion of strings and blobs in trace output to
approximately that many bytes.

FossilOrigin-Name: e5b710849dd66673ba0e0d935b103cb29abfcc4b
2013-04-02 13:56:53 +00:00
dan 4ff7bc45c6 Add test cases for errors in mmap() or mremap() is os_unix.c.
FossilOrigin-Name: 3098a3c1e7305033904a496ef534cb312a876fab
2013-04-02 12:04:09 +00:00
drh a3a2b3bdc0 Proposed template preprocessor magic for activating mmap only on platforms
where we know it works.

FossilOrigin-Name: d96272f031102514b02bd839aac9e37618872200
2013-04-02 10:29:13 +00:00
drh 6d81449fc6 Reorder two conditions to make coverage testing easier.
FossilOrigin-Name: 793ba4e996426522eeaa86589a9e974fa1fc1522
2013-04-02 01:45:10 +00:00
drh 092d993cb7 Remove an unreachable condition from pager.c.
FossilOrigin-Name: 3628e86bf131cb205f08a4b299d84007cd6b25c3
2013-04-02 00:41:18 +00:00
drh 98d2038fc2 Always send the SQLITE_FCNTL_MMAP_LIMIT pragma to the VFS, even if the limit
is zero and even if the VFS does not support xFetch().

FossilOrigin-Name: 01ffdabbad30f1c157f2b33b1e85ee4d6c4632dd
2013-04-02 00:15:23 +00:00
drh 3861f546e3 Remove a debugging printf() accidently left in the previous check-in.
FossilOrigin-Name: 8198cdd8ac5dcc1c677fffa869ac965186b96abf
2013-04-01 22:42:48 +00:00
drh a1f42c7c32 Add the SQLITE_CONFIG_MMAP_LIMIT configuration option for overriding the
SQLITE_DEFAULT_MMAP_LIMIT compile-time setting.  Enhance "PRAGMA mmap_limit"
so that without a specific database name, it sets the limit on all database
files and changes the default for any future databases that might be added
using ATTACH.

FossilOrigin-Name: 78141d0a16dd1d56b575fccd149de7fa789cb06c
2013-04-01 22:38:06 +00:00
drh a539c8a464 Add a comment to xUnfetch on windows to say that the call to winUnmapfile()
might be unnecessary.

FossilOrigin-Name: e3c63c31a21b27806592d066a013a111b280c61f
2013-04-01 18:25:48 +00:00
drh db56bcbe42 In windows, round down the size of the memory mapped region to the next
smaller multiple of the page size.

FossilOrigin-Name: 0e44ed1badde6d766f18d1373d968e5b286b15bd
2013-04-01 18:15:50 +00:00
dan 57d6b25ec9 Merge accidental fork.
FossilOrigin-Name: 5f4437c0e35c8aa740515aac3e81e0146716d2bb
2013-04-01 17:58:10 +00:00
dan e6ecd6630d Attempt to emulate mremap() on non-Linux systems by allocating a second mapping immediately following the first in virtual memory.
FossilOrigin-Name: 4d67433db8fb4754ae6b192945e479f3d7bad579
2013-04-01 17:56:59 +00:00
drh f9d18e472b Bug fix in the winMapfile() subroutine: Be sure to record the map object
handle in the sqlite3_file object.

FossilOrigin-Name: ee4d188e207efa24a26776fa4f025c6ac39cce73
2013-04-01 17:56:28 +00:00
drh 5175b324b8 Add xFetch and xUnfetch methods to the os_win.c VFS.
FossilOrigin-Name: a1653a257d6af6e8b10c819e68b12f6c2f485811
2013-04-01 17:22:51 +00:00
dan f55a4cf80c Ensure that a checkpoint does not use an out-of-date mapping.
FossilOrigin-Name: a1040f0397d57855500926494c978623286ddc77
2013-04-01 16:56:41 +00:00
dan 0943f0bdc8 Fix a typo in a log message in wal.c.
FossilOrigin-Name: 83fc48d16572443373e5de62adbd4cd53c2f7786
2013-04-01 14:35:01 +00:00
dan 71be5c5c87 Fix a problem in btree.c that could cause a crash following an OOM.
FossilOrigin-Name: b724aa5889f2e09cf0cbef133a672e6486755104
2013-04-01 14:29:33 +00:00
mistachkin fde3b1c715 For the clean target, tidy up a couple more generated (or copied) source files.
FossilOrigin-Name: 5687e5ee7bafa00d2b353c3eda1e5dfb219cb185
2013-03-29 19:52:04 +00:00
drh 50126644a5 Version 3.7.16.1
FossilOrigin-Name: 527231bc67285f01fb18d4451b28f61da3c4e39d
2013-03-29 13:44:34 +00:00
drh 12886632c6 Adjustment to an extreme corner case in the sqlite3Atoi64() routine.
FossilOrigin-Name: 39534b4baa53b9360696a9d5ee8cc2108af34592
2013-03-28 11:40:14 +00:00
drh 4b11bad358 Fix harmless compiler warnings coming from MSVC64 in test code. No
changes to the core.

FossilOrigin-Name: 274d2a22660c7b34b8bbd85f3c29cbafbcb1b4e7
2013-03-27 20:41:15 +00:00
drh ab5190a46c Increment the version number to 3.7.16.1.
FossilOrigin-Name: 7e32eb7b66290ba7323520f7ea92ffa584ee7193
2013-03-27 19:46:33 +00:00
drh d9883570f5 In order to optimize out the ORDER BY clause,
outer loops must generate values for ORDER BY terms that are unique or else
the inner loops must generate no more than a single row.
Fix for ticket [a179fe7465].

FossilOrigin-Name: 2936f7466e162dfb003bda26d35358d1b3063112
2013-03-27 17:20:10 +00:00
drh e6a8bbbb62 Restore additional ORDER BY optimizations that where broken by the
recent ORDER BY fix.

FossilOrigin-Name: c77ee6e20d3a8c91a8bf4c9063c36a95c70e17cf
2013-03-27 16:42:21 +00:00
drh 2b6c874b13 Improved optimization of ORDER BY.
FossilOrigin-Name: 97e5c70f2f19a1bca70dd2221b757b9e5418fce0
2013-03-27 16:05:30 +00:00
drh 8a1b87cb97 A fix an test-case for the ORDER BY problem identified by ticket [a179fe7465].
This change causes sorting to occur in some cases where it is not strictly
necessary.  Further work is needed to avoid those extra sorts.

FossilOrigin-Name: 488089e615e375c01b31544f06e801af950ae3db
2013-03-27 15:04:28 +00:00
drh 138eeeb1b0 Candidate fix for ticket [6bfb98dfc0c]: Make sure invalid cursors drop all
references to database pages prior to doing any insert or update.

FossilOrigin-Name: 322a5f086d9ee46017f750df81527799a54ae258
2013-03-27 03:15:23 +00:00
drh 6c5696381e Fix a comment in os_unix.c. No code changes.
FossilOrigin-Name: 72813b8ec924b91583c679668f7c4561dff82a02
2013-03-26 18:48:11 +00:00
drh c86e51358b Change the name of the Pager.pFree field to Pager.pMmapFreelist.
FossilOrigin-Name: 611bd824c24a60d298f28705de323fa2e813a308
2013-03-26 14:36:11 +00:00
65 changed files with 4137 additions and 569 deletions
+8
View File
@@ -502,6 +502,11 @@ sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h
-o $@ $(TOP)/src/shell.c libsqlite3.la \
$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"
mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
$(TLIBS) -rpath "$(libdir)"
# This target creates a directory named "tsrc" and fills it with
# copies of all of the C source code and header files needed to
# build on the target system. Some of the C source code and header
@@ -946,8 +951,11 @@ clean:
rm -f testfixture$(TEXE) test.db
rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
rm -f sqlite3.c
rm -f sqlite3rc.h
rm -f shell.c sqlite3ext.h
rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
rm -f sqlite-*-output.vsix
rm -f mptester mptester.exe
distclean: clean
rm -f config.log config.status libtool Makefile sqlite3.pc
+6
View File
@@ -813,6 +813,10 @@ sqlite3.exe: $(TOP)\src\shell.c libsqlite3.lib $(LIBRESOBJS) sqlite3.h
$(TOP)\src\shell.c \
/link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
mptester.exe: $(TOP)\mptest\mptest.c libsqlite3.lib $(LIBRESOBJS) sqlite3.h
$(LTLINK) $(TOP)\mptest\mptest.c \
/link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
# This target creates a directory named "tsrc" and fills it with
# copies of all of the C source code and header files needed to
# build on the target system. Some of the C source code and header
@@ -1250,8 +1254,10 @@ clean:
del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
del /Q sqlite3.c
del /Q sqlite3rc.h
del /Q shell.c sqlite3ext.h
del /Q sqlite3_analyzer.exe sqlite3_analyzer.exp sqlite3_analyzer.c
del /Q sqlite-*-output.vsix
del /Q mptester.exe
# Dynamic link library section.
#
+2
View File
@@ -662,4 +662,6 @@ clean:
rm -rf tsrc target_source
rm -f testloadext.dll libtestloadext.so
rm -f sqlite3.c fts?amal.c tclsqlite3.c
rm -f sqlite3rc.h
rm -f shell.c sqlite3ext.h
rm -f $(SHPREFIX)sqlite3.$(SO)
+1 -1
View File
@@ -1 +1 @@
3.7.16
3.7.17
Vendored
+9 -9
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.62 for sqlite 3.7.16.
# Generated by GNU Autoconf 2.62 for sqlite 3.7.17.
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
@@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.7.16'
PACKAGE_STRING='sqlite 3.7.16'
PACKAGE_VERSION='3.7.17'
PACKAGE_STRING='sqlite 3.7.17'
PACKAGE_BUGREPORT=''
# Factoring default headers for most tests.
@@ -1484,7 +1484,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.16 to adapt to many kinds of systems.
\`configure' configures sqlite 3.7.17 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1549,7 +1549,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.7.16:";;
short | recursive ) echo "Configuration of sqlite 3.7.17:";;
esac
cat <<\_ACEOF
@@ -1665,7 +1665,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.7.16
sqlite configure 3.7.17
generated by GNU Autoconf 2.62
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1679,7 +1679,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.16, which was
It was created by sqlite $as_me 3.7.17, which was
generated by GNU Autoconf 2.62. Invocation command line was
$ $0 $@
@@ -14032,7 +14032,7 @@ exec 6>&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.16, which was
This file was extended by sqlite $as_me 3.7.17, which was
generated by GNU Autoconf 2.62. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -14085,7 +14085,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
sqlite config.status 3.7.16
sqlite config.status 3.7.17
configured by $0, generated by GNU Autoconf 2.62,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+1
View File
@@ -17,6 +17,7 @@ if {![info exists testdir]} {
}
source [file join [file dirname [info script]] rtree_util.tcl]
source $testdir/tester.tcl
set testprefix rtree1
# Test plan:
#
+1 -1
View File
@@ -61,7 +61,7 @@ do_test rtree5-1.9 {
do_test rtree5-1.10 {
execsql { SELECT (1<<31)-5, (1<<31)-1, -1*(1<<31), -1*(1<<31)+5 }
} {2147483643 2147483647 -2147483648 -2147483643}
do_test rtree5-1.10 {
do_test rtree5-1.11 {
execsql {
INSERT INTO t1 VALUES(2, (1<<31)-5, (1<<31)-1, -1*(1<<31), -1*(1<<31)+5)
}
+7
View File
@@ -365,6 +365,10 @@ sqlite3$(EXE): $(TOP)/src/shell.c libsqlite3.a sqlite3.h
$(TOP)/src/shell.c \
libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB)
mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
$(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
$(TLIBS) $(THREADLIB)
sqlite3.o: sqlite3.c
$(TCCX) -c sqlite3.c
@@ -622,5 +626,8 @@ clean:
rm -f testfixture testfixture.exe
rm -f threadtest3 threadtest3.exe
rm -f sqlite3.c fts?amal.c tclsqlite3.c
rm -f sqlite3rc.h
rm -f shell.c sqlite3ext.h
rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
rm -f sqlite-*-output.vsix
rm -f mptester mptester.exe
+72 -59
View File
@@ -1,12 +1,12 @@
C In\sbtree.c,\ssave\sthe\spositions\sof\sany\sopen\scursors\sbefore\smoving\sany\spages\saround\sto\sauto-vacuum\sthe\sdatabase\son\scommit.
D 2013-03-26T14:16:20.450
C Expand\sscope\sof\sthe\sSQLITE_DISABLE_MMAP\sdefine\sfor\sthe\sWin32\sVFS.
D 2013-04-11T22:52:44.089
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in df3e48659d80e1b7765785d8d66c86b320f72cc7
F Makefile.in 3dd3fcb87b70c78d99b2c8a03e44ec86d6ca9ce2
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc 0c1abc21c8deefc88e8a32ad6a07e5f96e158761
F Makefile.vxworks b18ad88e9a8c6a001f5cf4a389116a4f1a7ab45f
F Makefile.msc a244e5b5ba2493625db95b4d46b79201ea868bfe
F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
F VERSION 6d4f66eaebabc42ef8c2a4d2d0caf4ce7ee81137
F VERSION 05c7bd63b96f31cfdef5c766ed91307ac121f5aa
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
@@ -15,7 +15,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure 00d3a5fda47ee7dd3e68dc9dad7eeb439cd1ffea x
F configure 8bb8bd13d3c918c4c1c73480930e81f955ac298a x
F configure.ac 81c43d151d0b0e406be056394cc9ff4cb3fd0444
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
@@ -85,11 +85,11 @@ F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/rtree.c 757abea591d4ff67c0ff4e8f9776aeda86b18c14
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
F ext/rtree/rtree1.test e474a2b5eff231496dbd073fe67e5fbaf7f444c9
F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
F ext/rtree/rtree3.test a494da55c30ee0bc9b01a91c80c81b387b22d2dc
F ext/rtree/rtree4.test c8fe384f60ebd49540a5fecc990041bf452eb6e0
F ext/rtree/rtree5.test 9a229678a00f40e6aedb40cb3a07ec5444af892c
F ext/rtree/rtree5.test 6a510494f12454bf57ef28f45bc7764ea279431e
F ext/rtree/rtree6.test 3ff9113b4a872fa935309e3511cd9b7cdb4d2472
F ext/rtree/rtree7.test 1fa710b9e6bf997a0c1a537b81be7bb6fded1971
F ext/rtree/rtree8.test 9772e16da71e17e02bdebf0a5188590f289ab37d
@@ -103,13 +103,19 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F main.mk c5437f64aad34844d18efe7b2d2adaa36efca49c
F main.mk dcb05737414488383369b93e33cf1a1484c4b6e6
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
F mkopcodec.awk f6fccee29e68493bfd90a2e0466ede5fa94dd2fc
F mkopcodeh.awk 29b84656502eee5f444c3147f331ee686956ab0e
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3f4ddeb152a4f83872f0fa7fcb48d9fd609893da
F mptest/config02.test 962913ed2b537d60de4126db7fe54716865cdd22
F mptest/crash01.test a5f31998ed48de8267d6620e8af107ec148e5f12
F mptest/crash02.subtest f4ef05adcd15d60e5d2bd654204f2c008b519df8
F mptest/mptest.c 53066ffe4ae6f0c4de451cc77985b88d0fee2aec
F mptest/multiwrite01.test 81fbc17657964889b60750bd7bbb1deffe8f4d42
F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
@@ -118,32 +124,32 @@ F src/alter.c f8db986c03eb0bfb221523fc9bbb9d0b70de3168
F src/analyze.c d5f895810e8ff9737c9ec7b76abc3dcff5860335
F src/attach.c 1816f5a9eea8d2010fc2b22b44f0f63eb3a62704
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c b2cac9f7993f3f9588827b824b1501d0c820fa68
F src/backup.c b266767351ae2d847716c56fcb2a1fea7c761c03
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 19b587b32569d4b92651b5eaa9de2e59c6f8f704
F src/btree.c 5f2c4fe72f663bba837c5d01a732799c1d1c93f8
F src/btree.h d9490cd37aaeb530a41b07f06e1262950b1be916
F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2
F src/build.c 083da8466fd7e481cb8bd5264398f537507f6176
F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 2a5f251fcd7393808df77ccfc817e7058df08c4c
F src/ctime.c 61a53c7e0db5e7ba60cf23b73deaf6779aa715d3
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
F src/delete.c aeabdabeeeaa0584127f291baa9617153d334778
F src/expr.c 48048fca951eedbc74aa32262154410d56c83812
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c e16942bd5c8a868ac53287886464a5ed0e72b179
F src/func.c 48987c025d69399f59a1c2a553cea5da41bf105d
F src/global.c e59ecd2c553ad0d4bfbc84ca71231336f8993a7a
F src/func.c d3fdcff9274bc161152e67ed3f626841c247f4b9
F src/global.c d2494a1cea8f66a2cab8258449df07f8f0ae6330
F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c f7cb141e8ce257cb6b15c497f09e4e23d6055599
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
F src/loadext.c 1422eba4aa2b1fb5f7b3aef574752272477d21e2
F src/main.c 379160ec3680e3009aa4978eac47027c3ef27ac5
F src/main.c 54a841854734b6731c4d026834788cac6a19f3d1
F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa
@@ -157,50 +163,50 @@ F src/mutex_noop.c 7682796b7d8d39bf1c138248858efcd10c9e1553
F src/mutex_unix.c c3a4e00f96ba068a8dbef34084465979aaf369cc
F src/mutex_w32.c 32a9b3841e2d757355f0012b860b1bc5e01eafa0
F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
F src/os.c 809d0707cec693e1b9b376ab229271ad74c3d35d
F src/os.c ca679b293a6233327e418fd1dde2cd5db3e90932
F src/os.h ae08bcc5f6ec6b339f4a2adf3931bb88cc14c3e4
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_unix.c 57306f1d2a2d783dae4365446b9f9a5da8958559
F src/os_win.c e4f17ddf79f2a9373e33ed70565e765d65324589
F src/pager.c 8ac98fd95106e759870e92ff316b188e78f469cf
F src/os_unix.c 5707fcb125f043e2d3376ea862e8ec83633c5e0e
F src/os_win.c 190be0e689be61b3dcb8c1d253bc967e09c1866e
F src/pager.c 28f45e60d9a173368872d6e688e7a848c3926344
F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1
F src/parse.y 5d5e12772845805fdfeb889163516b84fbb9ae95
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9
F src/pragma.c 8875d32d54530300e6aa31a9d5426b2088a69b12
F src/prepare.c 310eaff1ee5f3c700b3545afb095cfe9346efc3a
F src/pragma.c 216d6c24520f7b2e267a2356e5d3269d28690f49
F src/prepare.c 743e484233c51109666d402f470523553b41797c
F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/resolve.c 9079da7d59aed2bb14ec8315bc7f720dd85b5b65
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
F src/select.c 01540bcd3df3c8f1187158e77986028b1c667258
F src/shell.c 7c41bfcd9e5bf9d96b9215f79b03a5b2b44a3bca
F src/sqlite.h.in 921ba42ec3531fe8cf021492ffd781b161383f1b
F src/shell.c 319b7791cee6c763b60fde1b590bfaf62613cf37
F src/sqlite.h.in f606903594d314d1b63e677affb1a03e3c9a49c7
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
F src/sqlite3ext.h 7183ab832e23db0f934494f16928da127a571d75
F src/sqliteInt.h 0f8f05ee4db4ba9120b38f7a3992b325698f6e8a
F src/sqliteLimit.h 83d0cd0ce3050a80930406d3c7aecb48c1ccdfc5
F src/sqliteInt.h 1c517a89cfdba28084093607ec79af70359c7f9b
F src/sqliteLimit.h 3ea5c07b370b8033c30f66515ccf4e875c252429
F src/status.c bedc37ec1a6bb9399944024d63f4c769971955a9
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c 9a716c737590d2f129d71c8fc7065e5aba0e7222
F src/test1.c 26e66b839f42c2eed6833f9023e0098f0d863f35
F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf
F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d
F src/test4.c bf9fa9bece01de08e6f5e02314e4af5c13590dfa
F src/test1.c 6784fdacb35c33ba564ef749b62c4718fe515484
F src/test2.c 29e7154112f7448d64204e8d31179cf497ecf425
F src/test3.c 96aed72a8e1d542fed127e3e8350ae357712fa82
F src/test4.c cea2c55110241e4674e66d476d29c914627999f5
F src/test5.c a6d1ac55ac054d0b2b8f37b5e655b6c92645a013
F src/test6.c a437f76f9874d2563352a7e6cd0d43217663c220
F src/test7.c 2e0781754905c8adc3268d8f0967e7633af58843
F src/test7.c f4b894b7931f8cf9f5cbf37cfa0727703f526a40
F src/test8.c 58ea1d9698f3947e4662107ef98f429e84ae20e0
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad
F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e
F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de
F src/test_btree.c 5b89601dcb42a33ba8b820a6b763cc9cb48bac16
F src/test_config.c ab6605a41f2020912d5e44b8dd4b9fb21bd75ac0
F src/test_config.c b6f5d680f0cf03d0ae9d6165bd2e447d9b356e4a
F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_fs.c 1c51e203b2c20235d8c3739f8c1fb13a7502915b
F src/test_fs.c 8f786bfd0ad48030cf2a06fb1f050e9c60a150d7
F src/test_func.c 3a8dd37c08ab43b76d38eea2836e34a3897bf170
F src/test_fuzzer.c 1d26aa965120420bc14807da29d4d4541bfa6148
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
@@ -218,7 +224,7 @@ F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
F src/test_quota.c 1ec82e02fd3643899e9a5de9684515e84641c91f
F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
F src/test_regexp.c 5ff0eafd66c9a209417142fa319006f7028fbda8
F src/test_regexp.c 06ae8138d41a793330f62351283dd6f6f21104f4
F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f
@@ -226,10 +232,10 @@ F src/test_spellfix.c 56dfa6d583ac34f61af0834d7b58d674e7e18e13
F src/test_sqllog.c bc50e5afeb7fb50e77b4594e42302df9d05446aa
F src/test_stat.c d1569c7a4839f13e80187e2c26b2ab4da2d03935
F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
F src/test_syscall.c fe018f95049d4f24e036d1d649516b60689b4e57
F src/test_syscall.c 7e8293e4e6971b0f44c7f7f37b1315a8cc9f6018
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
F src/test_thread.c e286f2173563f2a1747c24bcda6b9d030bf4f4e4
F src/test_vfs.c fb16b2d9938cf0c1afc5a423b55b952fcc024275
F src/test_vfs.c 8e6087a8b3dcc260282074b0efba14b76311120c
F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
F src/test_wholenumber.c 3d2b9ed1505c40ad5c5ca2ad16ae7a289d6cc251
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
@@ -237,22 +243,22 @@ F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12
F src/trigger.c cd95ac64efa60e39faf9b5597443192ff27a22fa
F src/update.c a2a5631d618cbe240fc83725fa9e95c56ae0084c
F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f
F src/util.c 550f2b6a5c0085153a4d00462719fb17ee242792
F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9
F src/vacuum.c 2727bdd08847fcb6b2d2da6d14f018910e8645d3
F src/vdbe.c 1d56617d816098a41bdbe73536a67dcdefad52bd
F src/vdbe.c 5f0047130f80c7fd0bc41bc51a653b5542c4fbd5
F src/vdbe.h b52887278cb173e66188da84dfab216bea61119d
F src/vdbeInt.h 3bb8531d6768379f086e1576b31d52331f6eb982
F src/vdbeapi.c 56f9ad6329d093f54b5dd321a2b4a643f89a6cb6
F src/vdbeInt.h c1e830268b75f04a2901dd895b51a637a26c7045
F src/vdbeapi.c 085cf9bf169b859a6c8fa43791702bac805cb7aa
F src/vdbeaux.c ecb43014bcd3019e5aa2b5561e5c3a447f007a08
F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb
F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69
F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab
F src/vdbesort.c 4fad64071ae120c25f39dcac572d716b9cadeb7f
F src/vdbetrace.c 8bd5da325fc90f28464335e4cc4ad1407fe30835
F src/vdbetrace.c a22263ab47f6ba4fcd176515cec1e732866b25f0
F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83
F src/wal.c e84eff498c57ec2d79ca4496a3f4a638af378fb3
F src/wal.c 436bfceb141b9423c45119e68e444358ee0ed35d
F src/wal.h a4d3da523d55a226a0b28e9058ef88d0a8051887
F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b
F src/where.c 9a16c0b84bbeb054d11fda96e9e037ae310bd54e
F src/where.c 4ad2329c439a30ddb915a780f6f80bdffafe3a64
F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@@ -314,6 +320,7 @@ F test/boundary3.tcl 8901d6a503d0bf64251dd81cc74e5ad3add4b119
F test/boundary3.test 56ef82096b4329aca2be74fa1e2b0f762ea0eb45
F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983
F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b
F test/btreefault.test 06899a377f31a8c1a3048ec69831522d4e5c6045
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
F test/capi2.test e8b18cc61090b6e5e388f54d6b125d711d1b265a
@@ -630,7 +637,8 @@ F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
F test/misc7.test dd82ec9250b89178b96cd28b2aca70639d21e5b3
F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054
F test/mmap1.test 9fb71daaca72f66fcc7a3b3a37fc3db99988b57a
F test/mmap1.test f064a9025136cd688c982ccdae81c7b4fac95724
F test/mmap2.test a5ba639f90b5fc487400a49e158e14e465943e98
F test/multiplex.test e08cc7177bd6d85990ee1d71100bb6c684c02256
F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a
F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101
@@ -647,14 +655,15 @@ F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
F test/orderby1.test f33968647da5c546528fe4d2bf86c6a6a2e5a7ae
F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04
F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99
F test/orderby4.test 4d39bfbaaa3ae64d026ca2ff166353d2edca4ba4
F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
F test/pager1.test 31c04bec797dda1bde337810b52efa08d1f1f08e
F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1
F test/pager1.test 134144862f6a98f862dc2edda1b10ff499141bfa
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
F test/pagerfault.test 452f2cc23e3bfcfa935f4442aec1da4fe1dc0442
F test/pagerfault.test bba948be0564254b823ec6ca1fd95fbbfb0839a3
F test/pagerfault2.test 1f79ea40d1133b2683a2f811b00f2399f7ec2401
F test/pagerfault3.test f16e2efcb5fc9996d1356f7cbc44c998318ae1d7
F test/pageropt.test 32cb5a6ed7ccddf8e8c842cb44240bd9340223ce
F test/pageropt.test d6b695e6c12290c406150fc51eec32878d48df4c
F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
@@ -731,7 +740,7 @@ F test/softheap1.test c16709a16ad79fa43b32929b2e623d1d117ccf53
F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5
F test/speed1.test f2974a91d79f58507ada01864c0e323093065452
F test/speed1p.explain d841e650a04728b39e6740296b852dccdca9b2cb
F test/speed1p.test c4a469f29f135f4d76c55b1f2a52f36e209466cc
F test/speed1p.test b180e98609c7677382cf618c0ec9b69f789033a8
F test/speed2.test 53177056baf6556dcbdcf032bbdfc41c1aa74ded
F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
@@ -785,6 +794,7 @@ F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894
F test/tkt-5d863f876e.test c9f36ca503fa154a3655f92a69d2c30da1747bfa
F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84
F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f
F test/tkt-6bfb98dfc0.test 24780633627b5cfc0635a5500c2389ebfb563336
F test/tkt-752e1646fc.test ea78d88d14fe9866bdd991c634483334639e13bf
F test/tkt-78e04e52ea.test 703e0bfb23d543edf0426a97e3bbd0ca346508ec
F test/tkt-7a31705a7e6.test 5a7889fdb095ffbe1622413e0145de1637d421bd
@@ -951,11 +961,11 @@ F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
F test/vtab_shared.test 82f463886e18d7f8395a4b6167c91815efe54839
F test/wal.test bbd98ac09d8fbcaa80ec233757056eb1bbb7cd95
F test/wal.test 20fb8d0f8e65e50eb675994cc3a4f0e692fd4faf
F test/wal2.test d4b470f13c87f6d8268b004380afa04c3c67cb90
F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
F test/wal5.test f4d0aee6a2cf09e326ed2459011d396b4fdf661a
F test/wal5.test 13c980d4d8d2d6b558361f19bed4ab31d41a2c7c
F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
F test/wal8.test b3ee739fe8f7586aaebdc2367f477ebcf3e3b034
@@ -967,7 +977,7 @@ F test/walcksum.test f5447800a157c9e2234fbb8e80243f0813941bde
F test/walcrash.test 4457436593be8c136f9148487c7dccd5e9013af2
F test/walcrash2.test 019d60b89d96c1937adb2b30b850ac7e86e5a142
F test/walcrash3.test 595e44c6197f0d0aa509fc135be2fd0209d11a2c
F test/walfault.test 97394d8de82a99f7abf1c12ed229640607fd0ad2
F test/walfault.test 54ad6e849c727f4da463964b9eb8c8e8e155cf82
F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c
F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496
@@ -993,7 +1003,7 @@ F test/whereD.test 3f3ee93825c94804f1fc91eef2de0d365981759a
F test/whereE.test 7bd34945797efef15819368479bacc34215e4e1d
F test/whereF.test a0e296643cabe5278379bc1a0aa158cf3c54a1c9
F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9
F test/win32lock.test 21810396eee150680cc398970839e6abdcb807b9
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
F test/zerodamage.test e7f77fded01dfcdf92ac2c5400f1e35d7a21463c
F tool/build-all-msvc.bat 74fb6e5cca66ebdb6c9bbafb2f8b802f08146d38 x
@@ -1040,7 +1050,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
P a850c7319c20b5757983443df05cf2aa4250053b
R 211ffabed726a7468ad9f8d3eeabe8a8
U dan
Z 3ec7da7f1db0278991c8541b22037fbf
P f1b524b9d9ea3db96d54ac55c39f15e6879085bd
R 81fda886c4b87168bc8522f21db6569f
T *branch * winDisableMmap
T *sym-winDisableMmap *
T -sym-trunk *
U mistachkin
Z d00cd2eed7d26c94b83b76365b3988fe
+1 -1
View File
@@ -1 +1 @@
30c0a69363931a72d1c34e5be71646932398d172
daa168f3dad995c4b7dd60e7717db90639e167c2
+43
View File
@@ -0,0 +1,43 @@
/*
** Configure five tasks in different ways, then run tests.
*/
--if vfsname() GLOB 'unix'
PRAGMA page_size=8192;
--task 1
PRAGMA journal_mode=PERSIST;
PRAGMA mmap_limit=0;
--end
--task 2
PRAGMA journal_mode=TRUNCATE;
PRAGMA mmap_limit=28672;
--end
--task 3
PRAGMA journal_mode=MEMORY;
--end
--task 4
PRAGMA journal_mode=OFF;
--end
--source multiwrite01.test
--wait all
PRAGMA page_size=16384;
VACUUM;
CREATE TABLE pgsz(taskid, sz INTEGER);
--task 1
INSERT INTO pgsz VALUES(1, eval('PRAGMA page_size'));
--end
--task 2
INSERT INTO pgsz VALUES(2, eval('PRAGMA page_size'));
--end
--task 3
INSERT INTO pgsz VALUES(3, eval('PRAGMA page_size'));
--end
--task 4
INSERT INTO pgsz VALUES(4, eval('PRAGMA page_size'));
--end
--task 5
INSERT INTO pgsz VALUES(5, eval('PRAGMA page_size'));
--end
--source multiwrite01.test
--wait all
SELECT sz FROM pgsz;
--match 16384 16384 16384 16384 16384
+120
View File
@@ -0,0 +1,120 @@
/*
** Configure five tasks in different ways, then run tests.
*/
PRAGMA page_size=512;
--task 1
PRAGMA mmap_limit=0;
--end
--task 2
PRAGMA mmap_limit=28672;
--end
--task 3
PRAGMA mmap_limit=8192;
--end
--task 4
PRAGMA mmap_limit=65536;
--end
--source multiwrite01.test
--source crash02.subtest
PRAGMA page_size=1024;
VACUUM;
CREATE TABLE pgsz(taskid, sz INTEGER);
--task 1
INSERT INTO pgsz VALUES(1, eval('PRAGMA page_size'));
--end
--task 2
INSERT INTO pgsz VALUES(2, eval('PRAGMA page_size'));
--end
--task 3
INSERT INTO pgsz VALUES(3, eval('PRAGMA page_size'));
--end
--task 4
INSERT INTO pgsz VALUES(4, eval('PRAGMA page_size'));
--end
--task 5
INSERT INTO pgsz VALUES(5, eval('PRAGMA page_size'));
--end
--source multiwrite01.test
--source crash02.subtest
--wait all
SELECT sz FROM pgsz;
--match 1024 1024 1024 1024 1024
PRAGMA page_size=2048;
VACUUM;
DELETE FROM pgsz;
--task 1
INSERT INTO pgsz VALUES(1, eval('PRAGMA page_size'));
--end
--task 2
INSERT INTO pgsz VALUES(2, eval('PRAGMA page_size'));
--end
--task 3
INSERT INTO pgsz VALUES(3, eval('PRAGMA page_size'));
--end
--task 4
INSERT INTO pgsz VALUES(4, eval('PRAGMA page_size'));
--end
--task 5
INSERT INTO pgsz VALUES(5, eval('PRAGMA page_size'));
--end
--source multiwrite01.test
--source crash02.subtest
--wait all
SELECT sz FROM pgsz;
--match 2048 2048 2048 2048 2048
PRAGMA page_size=8192;
VACUUM;
DELETE FROM pgsz;
--task 1
INSERT INTO pgsz VALUES(1, eval('PRAGMA page_size'));
--end
--task 2
INSERT INTO pgsz VALUES(2, eval('PRAGMA page_size'));
--end
--task 3
INSERT INTO pgsz VALUES(3, eval('PRAGMA page_size'));
--end
--task 4
INSERT INTO pgsz VALUES(4, eval('PRAGMA page_size'));
--end
--task 5
INSERT INTO pgsz VALUES(5, eval('PRAGMA page_size'));
--end
--source multiwrite01.test
--source crash02.subtest
--wait all
SELECT sz FROM pgsz;
--match 8192 8192 8192 8192 8192
PRAGMA page_size=16384;
VACUUM;
DELETE FROM pgsz;
--task 1
INSERT INTO pgsz VALUES(1, eval('PRAGMA page_size'));
--end
--task 2
INSERT INTO pgsz VALUES(2, eval('PRAGMA page_size'));
--end
--task 3
INSERT INTO pgsz VALUES(3, eval('PRAGMA page_size'));
--end
--task 4
INSERT INTO pgsz VALUES(4, eval('PRAGMA page_size'));
--end
--task 5
INSERT INTO pgsz VALUES(5, eval('PRAGMA page_size'));
--end
--source multiwrite01.test
--source crash02.subtest
--wait all
SELECT sz FROM pgsz;
--match 16384 16384 16384 16384 16384
PRAGMA auto_vacuum=FULL;
VACUUM;
--source multiwrite01.test
--source crash02.subtest
--wait all
PRAGMA auto_vacuum=FULL;
PRAGMA page_size=512;
VACUUM;
--source multiwrite01.test
--source crash02.subtest
+102
View File
@@ -0,0 +1,102 @@
/* Test cases involving incomplete transactions that must be rolled back.
*/
--task 1
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
--sleep 1
INSERT INTO t1 VALUES(1, randomblob(2000));
INSERT INTO t1 VALUES(2, randomblob(1000));
--sleep 1
INSERT INTO t1 SELECT a+2, randomblob(1500) FROM t1;
INSERT INTO t1 SELECT a+4, randomblob(1500) FROM t1;
INSERT INTO t1 SELECT a+8, randomblob(1500) FROM t1;
--sleep 1
INSERT INTO t1 SELECT a+16, randomblob(1500) FROM t1;
--sleep 1
INSERT INTO t1 SELECT a+32, randomblob(1500) FROM t1;
SELECT count(*) FROM t1;
--match 64
SELECT avg(length(b)) FROM t1;
--match 1500.0
--sleep 2
UPDATE t1 SET b='x'||a||'y';
SELECT total(length(b)) FROM t1;
--match 247
SELECT a FROM t1 WHERE b='x17y';
--match 17
CREATE INDEX t1b ON t1(b);
SELECT a FROM t1 WHERE b='x17y';
--match 17
SELECT a FROM t1 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
--match 29 28 27 26 25
--end
--wait 1
--task 2
CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
INSERT INTO t2 SELECT a, b FROM t1;
UPDATE t1 SET b='x'||a||'y';
SELECT total(length(b)) FROM t2;
--match 247
SELECT a FROM t2 WHERE b='x17y';
--match 17
CREATE INDEX t2b ON t2(b);
SELECT a FROM t2 WHERE b='x17y';
--match 17
SELECT a FROM t2 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
--match 29 28 27 26 25
--end
--task 3
CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
INSERT INTO t3 SELECT a, b FROM t1;
UPDATE t1 SET b='x'||a||'y';
SELECT total(length(b)) FROM t3;
--match 247
SELECT a FROM t3 WHERE b='x17y';
--match 17
CREATE INDEX t3b ON t3(b);
SELECT a FROM t3 WHERE b='x17y';
--match 17
SELECT a FROM t3 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
--match 29 28 27 26 25
--end
--task 4
CREATE TABLE t4(a INTEGER PRIMARY KEY, b);
INSERT INTO t4 SELECT a, b FROM t1;
UPDATE t1 SET b='x'||a||'y';
SELECT total(length(b)) FROM t4;
--match 247
SELECT a FROM t4 WHERE b='x17y';
--match 17
CREATE INDEX t4b ON t4(b);
SELECT a FROM t4 WHERE b='x17y';
--match 17
SELECT a FROM t4 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
--match 29 28 27 26 25
--end
--task 5
CREATE TABLE t5(a INTEGER PRIMARY KEY, b);
INSERT INTO t5 SELECT a, b FROM t1;
UPDATE t1 SET b='x'||a||'y';
SELECT total(length(b)) FROM t5;
--match 247
SELECT a FROM t5 WHERE b='x17y';
--match 17
CREATE INDEX t5b ON t5(b);
SELECT a FROM t5 WHERE b='x17y';
--match 17
SELECT a FROM t5 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
--match 29 28 27 26 25
--end
--wait all
/* After the database file has been set up, run the crash2 subscript
** multiple times. */
--source crash02.subtest
--source crash02.subtest
--source crash02.subtest
--source crash02.subtest
--source crash02.subtest
--source crash02.subtest
--source crash02.subtest
--source crash02.subtest
--source crash02.subtest
+53
View File
@@ -0,0 +1,53 @@
/*
** This script is called from crash01.test and config02.test and perhaps other
** script. After the database file has been set up, make a big rollback
** journal in client 1, then crash client 1.
** Then in the other clients, do an integrity check.
*/
--task 1 leave-hot-journal
--sleep 5
--finish
PRAGMA cache_size=10;
BEGIN;
UPDATE t1 SET b=randomblob(20000);
UPDATE t2 SET b=randomblob(20000);
UPDATE t3 SET b=randomblob(20000);
UPDATE t4 SET b=randomblob(20000);
UPDATE t5 SET b=randomblob(20000);
UPDATE t1 SET b=NULL;
UPDATE t2 SET b=NULL;
UPDATE t3 SET b=NULL;
UPDATE t4 SET b=NULL;
UPDATE t5 SET b=NULL;
--print Task one crashing an incomplete transaction
--exit 1
--end
--task 2 integrity_check-2
SELECT count(*) FROM t1;
--match 64
--sleep 100
PRAGMA integrity_check(10);
--match ok
--end
--task 3 integrity_check-3
SELECT count(*) FROM t1;
--match 64
--sleep 100
PRAGMA integrity_check(10);
--match ok
--end
--task 4 integrity_check-4
SELECT count(*) FROM t1;
--match 64
--sleep 100
PRAGMA integrity_check(10);
--match ok
--end
--task 5 integrity_check-5
SELECT count(*) FROM t1;
--match 64
--sleep 100
PRAGMA integrity_check(10);
--match ok
--end
--wait all
+1315
View File
File diff suppressed because it is too large Load Diff
+405
View File
@@ -0,0 +1,405 @@
/*
** This script sets up five different tasks all writing and updating
** the database at the same time, but each in its own table.
*/
--task 1 build-t1
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
--sleep 1
INSERT INTO t1 VALUES(1, randomblob(2000));
INSERT INTO t1 VALUES(2, randomblob(1000));
--sleep 1
INSERT INTO t1 SELECT a+2, randomblob(1500) FROM t1;
INSERT INTO t1 SELECT a+4, randomblob(1500) FROM t1;
INSERT INTO t1 SELECT a+8, randomblob(1500) FROM t1;
--sleep 1
INSERT INTO t1 SELECT a+16, randomblob(1500) FROM t1;
--sleep 1
INSERT INTO t1 SELECT a+32, randomblob(1500) FROM t1;
SELECT count(*) FROM t1;
--match 64
SELECT avg(length(b)) FROM t1;
--match 1500.0
--sleep 2
UPDATE t1 SET b='x'||a||'y';
SELECT total(length(b)) FROM t1;
--match 247
SELECT a FROM t1 WHERE b='x17y';
--match 17
CREATE INDEX t1b ON t1(b);
SELECT a FROM t1 WHERE b='x17y';
--match 17
SELECT a FROM t1 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
--match 29 28 27 26 25
--end
--task 2 build-t2
DROP TABLE IF EXISTS t2;
CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
--sleep 1
INSERT INTO t2 VALUES(1, randomblob(2000));
INSERT INTO t2 VALUES(2, randomblob(1000));
--sleep 1
INSERT INTO t2 SELECT a+2, randomblob(1500) FROM t2;
INSERT INTO t2 SELECT a+4, randomblob(1500) FROM t2;
INSERT INTO t2 SELECT a+8, randomblob(1500) FROM t2;
--sleep 1
INSERT INTO t2 SELECT a+16, randomblob(1500) FROM t2;
--sleep 1
INSERT INTO t2 SELECT a+32, randomblob(1500) FROM t2;
SELECT count(*) FROM t2;
--match 64
SELECT avg(length(b)) FROM t2;
--match 1500.0
--sleep 2
UPDATE t2 SET b='x'||a||'y';
SELECT total(length(b)) FROM t2;
--match 247
SELECT a FROM t2 WHERE b='x17y';
--match 17
CREATE INDEX t2b ON t2(b);
SELECT a FROM t2 WHERE b='x17y';
--match 17
SELECT a FROM t2 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
--match 29 28 27 26 25
--end
--task 3 build-t3
DROP TABLE IF EXISTS t3;
CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
--sleep 1
INSERT INTO t3 VALUES(1, randomblob(2000));
INSERT INTO t3 VALUES(2, randomblob(1000));
--sleep 1
INSERT INTO t3 SELECT a+2, randomblob(1500) FROM t3;
INSERT INTO t3 SELECT a+4, randomblob(1500) FROM t3;
INSERT INTO t3 SELECT a+8, randomblob(1500) FROM t3;
--sleep 1
INSERT INTO t3 SELECT a+16, randomblob(1500) FROM t3;
--sleep 1
INSERT INTO t3 SELECT a+32, randomblob(1500) FROM t3;
SELECT count(*) FROM t3;
--match 64
SELECT avg(length(b)) FROM t3;
--match 1500.0
--sleep 2
UPDATE t3 SET b='x'||a||'y';
SELECT total(length(b)) FROM t3;
--match 247
SELECT a FROM t3 WHERE b='x17y';
--match 17
CREATE INDEX t3b ON t3(b);
SELECT a FROM t3 WHERE b='x17y';
--match 17
SELECT a FROM t3 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
--match 29 28 27 26 25
--end
--task 4 build-t4
DROP TABLE IF EXISTS t4;
CREATE TABLE t4(a INTEGER PRIMARY KEY, b);
--sleep 1
INSERT INTO t4 VALUES(1, randomblob(2000));
INSERT INTO t4 VALUES(2, randomblob(1000));
--sleep 1
INSERT INTO t4 SELECT a+2, randomblob(1500) FROM t4;
INSERT INTO t4 SELECT a+4, randomblob(1500) FROM t4;
INSERT INTO t4 SELECT a+8, randomblob(1500) FROM t4;
--sleep 1
INSERT INTO t4 SELECT a+16, randomblob(1500) FROM t4;
--sleep 1
INSERT INTO t4 SELECT a+32, randomblob(1500) FROM t4;
SELECT count(*) FROM t4;
--match 64
SELECT avg(length(b)) FROM t4;
--match 1500.0
--sleep 2
UPDATE t4 SET b='x'||a||'y';
SELECT total(length(b)) FROM t4;
--match 247
SELECT a FROM t4 WHERE b='x17y';
--match 17
CREATE INDEX t4b ON t4(b);
SELECT a FROM t4 WHERE b='x17y';
--match 17
SELECT a FROM t4 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
--match 29 28 27 26 25
--end
--task 5 build-t5
DROP TABLE IF EXISTS t5;
CREATE TABLE t5(a INTEGER PRIMARY KEY, b);
--sleep 1
INSERT INTO t5 VALUES(1, randomblob(2000));
INSERT INTO t5 VALUES(2, randomblob(1000));
--sleep 1
INSERT INTO t5 SELECT a+2, randomblob(1500) FROM t5;
INSERT INTO t5 SELECT a+4, randomblob(1500) FROM t5;
INSERT INTO t5 SELECT a+8, randomblob(1500) FROM t5;
--sleep 1
INSERT INTO t5 SELECT a+16, randomblob(1500) FROM t5;
--sleep 1
INSERT INTO t5 SELECT a+32, randomblob(1500) FROM t5;
SELECT count(*) FROM t5;
--match 64
SELECT avg(length(b)) FROM t5;
--match 1500.0
--sleep 2
UPDATE t5 SET b='x'||a||'y';
SELECT total(length(b)) FROM t5;
--match 247
SELECT a FROM t5 WHERE b='x17y';
--match 17
CREATE INDEX t5b ON t5(b);
SELECT a FROM t5 WHERE b='x17y';
--match 17
SELECT a FROM t5 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
--match 29 28 27 26 25
--end
--wait all
SELECT count(*), total(length(b)) FROM t1;
--match 64 247
SELECT count(*), total(length(b)) FROM t2;
--match 64 247
SELECT count(*), total(length(b)) FROM t3;
--match 64 247
SELECT count(*), total(length(b)) FROM t4;
--match 64 247
SELECT count(*), total(length(b)) FROM t5;
--match 64 247
--task 1
SELECT t1.a FROM t1, t2
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
ORDER BY t1.a LIMIT 4
--match 33 34 35 36
SELECT t3.a FROM t3, t4
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
ORDER BY t3.a LIMIT 7
--match 45 46 47 48 49 50 51
--end
--task 5
SELECT t1.a FROM t1, t2
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
ORDER BY t1.a LIMIT 4
--match 33 34 35 36
SELECT t3.a FROM t3, t4
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
ORDER BY t3.a LIMIT 7
--match 45 46 47 48 49 50 51
--end
--task 3
SELECT t1.a FROM t1, t2
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
ORDER BY t1.a LIMIT 4
--match 33 34 35 36
SELECT t3.a FROM t3, t4
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
ORDER BY t3.a LIMIT 7
--match 45 46 47 48 49 50 51
--end
--task 2
SELECT t1.a FROM t1, t2
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
ORDER BY t1.a LIMIT 4
--match 33 34 35 36
SELECT t3.a FROM t3, t4
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
ORDER BY t3.a LIMIT 7
--match 45 46 47 48 49 50 51
--end
--task 4
SELECT t1.a FROM t1, t2
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
ORDER BY t1.a LIMIT 4
--match 33 34 35 36
SELECT t3.a FROM t3, t4
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
ORDER BY t3.a LIMIT 7
--match 45 46 47 48 49 50 51
--end
--wait all
--task 5
DROP INDEX t5b;
--sleep 5
PRAGMA integrity_check(10);
--match ok
CREATE INDEX t5b ON t5(b DESC);
--end
--task 3
DROP INDEX t3b;
--sleep 5
PRAGMA integrity_check(10);
--match ok
CREATE INDEX t3b ON t3(b DESC);
--end
--task 1
DROP INDEX t1b;
--sleep 5
PRAGMA integrity_check(10);
--match ok
CREATE INDEX t1b ON t1(b DESC);
--end
--task 2
DROP INDEX t2b;
--sleep 5
PRAGMA integrity_check(10);
--match ok
CREATE INDEX t2b ON t2(b DESC);
--end
--task 4
DROP INDEX t4b;
--sleep 5
PRAGMA integrity_check(10);
--match ok
CREATE INDEX t4b ON t4(b DESC);
--end
--wait all
--task 1
SELECT t1.a FROM t1, t2
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
ORDER BY t1.a LIMIT 4
--match 33 34 35 36
SELECT t3.a FROM t3, t4
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
ORDER BY t3.a LIMIT 7
--match 45 46 47 48 49 50 51
--end
--task 5
SELECT t1.a FROM t1, t2
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
ORDER BY t1.a LIMIT 4
--match 33 34 35 36
SELECT t3.a FROM t3, t4
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
ORDER BY t3.a LIMIT 7
--match 45 46 47 48 49 50 51
--end
--task 3
SELECT t1.a FROM t1, t2
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
ORDER BY t1.a LIMIT 4
--match 33 34 35 36
SELECT t3.a FROM t3, t4
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
ORDER BY t3.a LIMIT 7
--match 45 46 47 48 49 50 51
--end
--task 2
SELECT t1.a FROM t1, t2
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
ORDER BY t1.a LIMIT 4
--match 33 34 35 36
SELECT t3.a FROM t3, t4
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
ORDER BY t3.a LIMIT 7
--match 45 46 47 48 49 50 51
--end
--task 4
SELECT t1.a FROM t1, t2
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
ORDER BY t1.a LIMIT 4
--match 33 34 35 36
SELECT t3.a FROM t3, t4
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
ORDER BY t3.a LIMIT 7
--match 45 46 47 48 49 50 51
--end
--wait all
VACUUM;
PRAGMA integrity_check(10);
--match ok
--task 1
UPDATE t1 SET b=randomblob(20000);
--sleep 5
UPDATE t1 SET b='x'||a||'y';
SELECT a FROM t1 WHERE b='x63y';
--match 63
--end
--task 2
UPDATE t2 SET b=randomblob(20000);
--sleep 5
UPDATE t2 SET b='x'||a||'y';
SELECT a FROM t2 WHERE b='x63y';
--match 63
--end
--task 3
UPDATE t3 SET b=randomblob(20000);
--sleep 5
UPDATE t3 SET b='x'||a||'y';
SELECT a FROM t3 WHERE b='x63y';
--match 63
--end
--task 4
UPDATE t4 SET b=randomblob(20000);
--sleep 5
UPDATE t4 SET b='x'||a||'y';
SELECT a FROM t4 WHERE b='x63y';
--match 63
--end
--task 5
UPDATE t5 SET b=randomblob(20000);
--sleep 5
UPDATE t5 SET b='x'||a||'y';
SELECT a FROM t5 WHERE b='x63y';
--match 63
--end
--wait all
--task 1
SELECT t1.a FROM t1, t2
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
ORDER BY t1.a LIMIT 4
--match 33 34 35 36
SELECT t3.a FROM t3, t4
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
ORDER BY t3.a LIMIT 7
--match 45 46 47 48 49 50 51
--end
--task 5
SELECT t1.a FROM t1, t2
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
ORDER BY t1.a LIMIT 4
--match 33 34 35 36
SELECT t3.a FROM t3, t4
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
ORDER BY t3.a LIMIT 7
--match 45 46 47 48 49 50 51
--end
--task 3
SELECT t1.a FROM t1, t2
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
ORDER BY t1.a LIMIT 4
--match 33 34 35 36
SELECT t3.a FROM t3, t4
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
ORDER BY t3.a LIMIT 7
--match 45 46 47 48 49 50 51
--end
--task 2
SELECT t1.a FROM t1, t2
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
ORDER BY t1.a LIMIT 4
--match 33 34 35 36
SELECT t3.a FROM t3, t4
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
ORDER BY t3.a LIMIT 7
--match 45 46 47 48 49 50 51
--end
--task 4
SELECT t1.a FROM t1, t2
WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
ORDER BY t1.a LIMIT 4
--match 33 34 35 36
SELECT t3.a FROM t3, t4
WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
ORDER BY t3.a LIMIT 7
--match 45 46 47 48 49 50 51
--end
--wait all
+2 -1
View File
@@ -397,7 +397,8 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
const Pgno iSrcPg = p->iNext; /* Source page number */
if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
DbPage *pSrcPg; /* Source page object */
rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
rc = sqlite3PagerAcquire(pSrcPager, iSrcPg, &pSrcPg,
PAGER_ACQUIRE_READONLY);
if( rc==SQLITE_OK ){
rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
sqlite3PagerUnref(pSrcPg);
+43 -42
View File
@@ -575,6 +575,19 @@ static void btreeClearHasContent(BtShared *pBt){
pBt->pHasContent = 0;
}
/*
** Release all of the apPage[] pages for a cursor.
*/
static void btreeReleaseAllCursorPages(BtCursor *pCur){
int i;
for(i=0; i<=pCur->iPage; i++){
releasePage(pCur->apPage[i]);
pCur->apPage[i] = 0;
}
pCur->iPage = -1;
}
/*
** Save the current cursor position in the variables BtCursor.nKey
** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
@@ -614,12 +627,7 @@ static int saveCursorPosition(BtCursor *pCur){
assert( !pCur->apPage[0]->intKey || !pCur->pKey );
if( rc==SQLITE_OK ){
int i;
for(i=0; i<=pCur->iPage; i++){
releasePage(pCur->apPage[i]);
pCur->apPage[i] = 0;
}
pCur->iPage = -1;
btreeReleaseAllCursorPages(pCur);
pCur->eState = CURSOR_REQUIRESEEK;
}
@@ -637,11 +645,15 @@ static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
assert( sqlite3_mutex_held(pBt->mutex) );
assert( pExcept==0 || pExcept->pBt==pBt );
for(p=pBt->pCursor; p; p=p->pNext){
if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) &&
p->eState==CURSOR_VALID ){
int rc = saveCursorPosition(p);
if( SQLITE_OK!=rc ){
return rc;
if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){
if( p->eState==CURSOR_VALID ){
int rc = saveCursorPosition(p);
if( SQLITE_OK!=rc ){
return rc;
}
}else{
testcase( p->iPage>0 );
btreeReleaseAllCursorPages(p);
}
}
}
@@ -1864,6 +1876,7 @@ int sqlite3BtreeOpen(
rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
EXTRA_SIZE, flags, vfsFlags, pageReinit);
if( rc==SQLITE_OK ){
sqlite3PagerSetMmapLimit(pBt->pPager, db->mxMmap);
rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
}
if( rc!=SQLITE_OK ){
@@ -2582,33 +2595,6 @@ int sqlite3BtreeNewDb(Btree *p){
return rc;
}
/*
** Ensure that any root page references held by open cursors are not
** mmap pages.
*/
static int btreeSwapOutMmap(BtShared *pBt){
int rc = SQLITE_OK; /* Return code */
BtCursor *pCsr; /* Used to iterate through all open cursors */
for(pCsr=pBt->pCursor; pCsr && rc==SQLITE_OK; pCsr=pCsr->pNext){
if( pCsr->iPage>=0 ){
MemPage *pPg = pCsr->apPage[0];
if( pPg && pPg->pDbPage->flags & PGHDR_MMAP ){
MemPage *pNew = 0;
rc = getAndInitPage(pBt, pPg->pgno, &pNew, 0);
if( rc==SQLITE_OK && pCsr->iPage==0 ){
pCsr->info.pCell = pNew->aData + (pCsr->info.pCell - pPg->aData);
}
pCsr->apPage[0] = pNew;
releasePage(pPg);
if( rc!=SQLITE_OK ) return rc;
}
}
}
return rc;
}
/*
** Attempt to start a new transaction. A write-transaction
** is started if the second argument is nonzero, otherwise a read-
@@ -2715,9 +2701,6 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
rc = SQLITE_READONLY;
}else{
rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db));
if( rc==SQLITE_OK ){
rc = btreeSwapOutMmap(pBt);
}
if( rc==SQLITE_OK ){
rc = newDatabase(pBt);
}
@@ -4417,7 +4400,7 @@ static int moveToRoot(BtCursor *pCur){
pCur->eState = CURSOR_INVALID;
return SQLITE_OK;
}else{
rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0], 0);
rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0], pCur->wrFlag==0);
if( rc!=SQLITE_OK ){
pCur->eState = CURSOR_INVALID;
return rc;
@@ -7267,7 +7250,14 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
u8 eType = 0;
Pgno iPtrPage = 0;
/* Save the positions of any open cursors. This is required in
** case they are holding a reference to an xFetch reference
** corresponding to page pgnoRoot. */
rc = saveAllCursors(pBt, 0, 0);
releasePage(pPageMove);
if( rc!=SQLITE_OK ){
return rc;
}
/* Move the page currently at pgnoRoot to pgnoMove. */
rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0);
@@ -8398,6 +8388,17 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
return SQLITE_ABORT;
}
/* Save the positions of all other cursors open on this table. This is
** required in case any of them are holding references to an xFetch
** version of the b-tree page modified by the accessPayload call below.
**
** Note that pCsr must be open on a BTREE_INTKEY table and saveCursorPosition()
** and hence saveAllCursors() cannot fail on a BTREE_INTKEY table, hence
** saveAllCursors can only return SQLITE_OK.
*/
VVA_ONLY(rc =) saveAllCursors(pCsr->pBt, pCsr->pgnoRoot, pCsr);
assert( rc==SQLITE_OK );
/* Check some assumptions:
** (a) the cursor is open for writing,
** (b) there is a read/write transaction open,
+6
View File
@@ -57,12 +57,18 @@ static const char * const azCompileOpt[] = {
#ifdef SQLITE_DEFAULT_LOCKING_MODE
"DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
#endif
#ifdef SQLITE_DEFAULT_MMAP_LIMIT
"DEFAULT_MMAP_LIMIT=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_LIMIT),
#endif
#ifdef SQLITE_DISABLE_DIRSYNC
"DISABLE_DIRSYNC",
#endif
#ifdef SQLITE_DISABLE_LFS
"DISABLE_LFS",
#endif
#ifdef SQLITE_DISABLE_MMAP
"DISABLE_MMAP",
#endif
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
"ENABLE_ATOMIC_WRITE",
#endif
+7
View File
@@ -693,6 +693,13 @@ static int patternCompare(
return *zString==0;
}
/*
** The sqlite3_strglob() interface.
*/
int sqlite3_strglob(const char *zGlobPattern, const char *zString){
return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, 0)==0;
}
/*
** Count the number of times that the LIKE operator (or GLOB which is
** just a variation of LIKE) gets called. This is used for testing
+1
View File
@@ -156,6 +156,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
(void*)0, /* pHeap */
0, /* nHeap */
0, 0, /* mnHeap, mxHeap */
SQLITE_DEFAULT_MMAP_LIMIT, /* mxMmap */
(void*)0, /* pScratch */
0, /* szScratch */
0, /* nScratch */
+4 -8
View File
@@ -38,7 +38,6 @@ int sqlite3_exec(
const char *zLeftover; /* Tail of unprocessed SQL */
sqlite3_stmt *pStmt = 0; /* The current SQL statement */
char **azCols = 0; /* Names of result columns */
int nRetry = 0; /* Number of retry attempts */
int callbackIsInit; /* True if callback data is initialized */
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
@@ -46,12 +45,12 @@ int sqlite3_exec(
sqlite3_mutex_enter(db->mutex);
sqlite3Error(db, SQLITE_OK, 0);
while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){
while( rc==SQLITE_OK && zSql[0] ){
int nCol;
char **azVals = 0;
pStmt = 0;
rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover);
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
assert( rc==SQLITE_OK || pStmt==0 );
if( rc!=SQLITE_OK ){
continue;
@@ -108,11 +107,8 @@ int sqlite3_exec(
if( rc!=SQLITE_ROW ){
rc = sqlite3VdbeFinalize((Vdbe *)pStmt);
pStmt = 0;
if( rc!=SQLITE_SCHEMA ){
nRetry = 0;
zSql = zLeftover;
while( sqlite3Isspace(zSql[0]) ) zSql++;
}
zSql = zLeftover;
while( sqlite3Isspace(zSql[0]) ) zSql++;
break;
}
}
+8
View File
@@ -496,6 +496,13 @@ int sqlite3_config(int op, ...){
}
#endif
case SQLITE_CONFIG_MMAP_LIMIT: {
sqlite3_int64 mxMmap = va_arg(ap, sqlite3_int64);
if( mxMmap<0 ) mxMmap = SQLITE_DEFAULT_MMAP_LIMIT;
sqlite3GlobalConfig.mxMmap = mxMmap;
break;
}
default: {
rc = SQLITE_ERROR;
break;
@@ -2316,6 +2323,7 @@ static int openDatabase(
memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
db->autoCommit = 1;
db->nextAutovac = -1;
db->mxMmap = sqlite3GlobalConfig.mxMmap;
db->nextPagesize = 0;
db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger
#if SQLITE_DEFAULT_FILE_FORMAT<4
+12
View File
@@ -141,6 +141,8 @@ int sqlite3OsShmMap(
return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
}
#if !defined(SQLITE_DISABLE_MMAP)
/* The real implementation of xFetch and xUnfetch */
int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
DO_OS_MALLOC_TEST(id);
return id->pMethods->xFetch(id, iOff, iAmt, pp);
@@ -148,6 +150,16 @@ int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
return id->pMethods->xUnfetch(id, iOff, p);
}
#else
/* No-op stubs to use when memory-mapped I/O is disabled */
int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
*pp = 0;
return SQLITE_OK;
}
int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
return SQLITE_OK;
}
#endif
/*
** The next group of routines are convenience wrappers around the
+186 -28
View File
@@ -280,6 +280,7 @@ struct unixFile {
#define UNIXFILE_DELETE 0x20 /* Delete on close */
#define UNIXFILE_URI 0x40 /* Filename might have query parameters */
#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */
#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings have been issued */
/*
** Include code that is common to all os_*.c files
@@ -313,6 +314,17 @@ struct unixFile {
#define threadid 0
#endif
/*
** HAVE_MREMAP defaults to true on Linux and false everywhere else.
*/
#if !defined(HAVE_MREMAP)
# if defined(__linux__) && defined(_GNU_SOURCE)
# define HAVE_MREMAP 1
# else
# define HAVE_MREMAP 0
# endif
#endif
/*
** Different Unix systems declare open() in different ways. Same use
** open(const char*,int,mode_t). Others use open(const char*,int,...).
@@ -450,7 +462,7 @@ static struct unix_syscall {
{ "munmap", (sqlite3_syscall_ptr)munmap, 0 },
#define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent)
#if defined(__linux__) && defined(_GNU_SOURCE)
#if HAVE_MREMAP
{ "mremap", (sqlite3_syscall_ptr)mremap, 0 },
#else
{ "mremap", (sqlite3_syscall_ptr)0, 0 },
@@ -788,7 +800,6 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
}
/******************************************************************************
****************** Begin Unique File ID Utility Used By VxWorks ***************
**
@@ -1124,7 +1135,6 @@ static int unixLogErrorAtLine(
zErr = strerror(iErrno);
#endif
assert( errcode!=SQLITE_OK );
if( zPath==0 ) zPath = "";
sqlite3_log(errcode,
"os_unix.c:%d: (%d) %s(%s) - %s",
@@ -1290,6 +1300,50 @@ static int findInodeInfo(
}
/*
** Check a unixFile that is a database. Verify the following:
**
** (1) There is exactly one hard link on the file
** (2) The file is not a symbolic link
** (3) The file has not been renamed or unlinked
**
** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right.
*/
static void verifyDbFile(unixFile *pFile){
struct stat buf;
int rc;
if( pFile->ctrlFlags & UNIXFILE_WARNED ){
/* One or more of the following warnings have already been issued. Do not
** repeat them so as not to clutter the error log */
return;
}
rc = osFstat(pFile->h, &buf);
if( rc!=0 ){
sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath);
pFile->ctrlFlags |= UNIXFILE_WARNED;
return;
}
if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
pFile->ctrlFlags |= UNIXFILE_WARNED;
return;
}
if( buf.st_nlink>1 ){
sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath);
pFile->ctrlFlags |= UNIXFILE_WARNED;
return;
}
if( pFile->pInode!=0
&& ((rc = osStat(pFile->zPath, &buf))!=0
|| buf.st_ino!=pFile->pInode->fileId.ino)
){
sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath);
pFile->ctrlFlags |= UNIXFILE_WARNED;
return;
}
}
/*
** This routine checks if there is a RESERVED lock held on the specified
** file by this or any other process. If such a lock is held, set *pResOut
@@ -1866,6 +1920,7 @@ static int closeUnixFile(sqlite3_file *id){
static int unixClose(sqlite3_file *id){
int rc = SQLITE_OK;
unixFile *pFile = (unixFile *)id;
verifyDbFile(pFile);
unixUnlock(id, NO_LOCK);
unixEnterMutex();
@@ -3107,8 +3162,9 @@ static int unixRead(
);
#endif
/* Deal with as much of this write request as possible by transfering
** data to the memory mapping using memcpy(). */
#if !defined(SQLITE_DISABLE_MMAP)
/* Deal with as much of this read request as possible by transfering
** data from the memory mapping using memcpy(). */
if( offset<pFile->mmapSize ){
if( offset+amt <= pFile->mmapSize ){
memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
@@ -3121,6 +3177,7 @@ static int unixRead(
offset += nCopy;
}
}
#endif
got = seekAndRead(pFile, offset, pBuf, amt);
if( got==amt ){
@@ -3226,6 +3283,7 @@ static int unixWrite(
}
#endif
#if !defined(SQLITE_DISABLE_MMAP)
/* Deal with as much of this write request as possible by transfering
** data from the memory mapping using memcpy(). */
if( offset<pFile->mmapSize ){
@@ -3240,6 +3298,7 @@ static int unixWrite(
offset += nCopy;
}
}
#endif
while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){
amt -= wrote;
@@ -3619,7 +3678,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
}
}
if( pFile->mmapLimit>0 ){
if( pFile->mmapLimit>0 && nByte>pFile->mmapSize ){
int rc;
if( pFile->szChunk<=0 ){
if( robust_ftruncate(pFile->h, nByte) ){
@@ -3700,7 +3759,12 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
return SQLITE_OK;
}
case SQLITE_FCNTL_MMAP_LIMIT: {
pFile->mmapLimit = *(i64*)pArg;
i64 newLimit = *(i64*)pArg;
*(i64*)pArg = pFile->mmapLimit;
if( newLimit>=0 ){
pFile->mmapLimit = newLimit;
if( newLimit<pFile->mmapSize ) pFile->mmapSize = newLimit;
}
return SQLITE_OK;
}
#ifdef SQLITE_DEBUG
@@ -4510,14 +4574,118 @@ static int unixShmUnmap(
*/
static void unixUnmapfile(unixFile *pFd){
assert( pFd->nFetchOut==0 );
#ifndef SQLITE_DISABLE_MMAP
if( pFd->pMapRegion ){
osMunmap(pFd->pMapRegion, pFd->mmapOrigsize);
pFd->pMapRegion = 0;
pFd->mmapSize = 0;
pFd->mmapOrigsize = 0;
}
#endif
}
#ifndef SQLITE_DISABLE_MMAP
/*
** Return the system page size.
*/
static int unixGetPagesize(void){
#if HAVE_MREMAP
return 512;
#elif defined(_BSD_SOURCE)
return getpagesize();
#else
return (int)sysconf(_SC_PAGESIZE);
#endif
}
#endif /* SQLITE_DISABLE_MMAP */
#ifndef SQLITE_DISABLE_MMAP
/*
** Attempt to set the size of the memory mapping maintained by file
** descriptor pFd to nNew bytes. Any existing mapping is discarded.
**
** If successful, this function sets the following variables:
**
** unixFile.pMapRegion
** unixFile.mmapSize
** unixFile.mmapOrigsize
**
** If unsuccessful, an error message is logged via sqlite3_log() and
** the three variables above are zeroed. In this case SQLite should
** continue accessing the database using the xRead() and xWrite()
** methods.
*/
static void unixRemapfile(
unixFile *pFd, /* File descriptor object */
i64 nNew /* Required mapping size */
){
const char *zErr = "mmap";
int h = pFd->h; /* File descriptor open on db file */
u8 *pOrig = (u8 *)pFd->pMapRegion; /* Pointer to current file mapping */
i64 nOrig = pFd->mmapOrigsize; /* Size of pOrig region in bytes */
u8 *pNew = 0; /* Location of new mapping */
int flags = PROT_READ; /* Flags to pass to mmap() */
assert( pFd->nFetchOut==0 );
assert( nNew>pFd->mmapSize );
assert( nNew<=pFd->mmapLimit );
assert( nNew>0 );
assert( pFd->mmapOrigsize>=pFd->mmapSize );
assert( MAP_FAILED!=0 );
if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
if( pOrig ){
const int szSyspage = unixGetPagesize();
i64 nReuse = (pFd->mmapSize & ~(szSyspage-1));
u8 *pReq = &pOrig[nReuse];
/* Unmap any pages of the existing mapping that cannot be reused. */
if( nReuse!=nOrig ){
osMunmap(pReq, nOrig-nReuse);
}
#if HAVE_MREMAP
pNew = osMremap(pOrig, nReuse, nNew, MREMAP_MAYMOVE);
zErr = "mremap";
#else
pNew = osMmap(pReq, nNew-nReuse, flags, MAP_SHARED, h, nReuse);
if( pNew!=MAP_FAILED ){
if( pNew!=pReq ){
osMunmap(pNew, nNew - nReuse);
pNew = 0;
}else{
pNew = pOrig;
}
}
#endif
/* The attempt to extend the existing mapping failed. Free it. */
if( pNew==MAP_FAILED || pNew==0 ){
osMunmap(pOrig, nReuse);
}
}
/* If pNew is still NULL, try to create an entirely new mapping. */
if( pNew==0 ){
pNew = osMmap(0, nNew, flags, MAP_SHARED, h, 0);
}
if( pNew==MAP_FAILED ){
pNew = 0;
nNew = 0;
unixLogError(SQLITE_OK, zErr, pFd->zPath);
/* If the mmap() above failed, assume that all subsequent mmap() calls
** will probably fail too. Fall back to using xRead/xWrite exclusively
** in this case. */
pFd->mmapLimit = 0;
}
pFd->pMapRegion = (void *)pNew;
pFd->mmapSize = pFd->mmapOrigsize = nNew;
}
#endif
/*
** Memory map or remap the file opened by file-descriptor pFd (if the file
** is already mapped, the existing mapping is replaced by the new). Or, if
@@ -4535,6 +4703,7 @@ static void unixUnmapfile(unixFile *pFd){
** code otherwise.
*/
static int unixMapfile(unixFile *pFd, i64 nByte){
#ifndef SQLITE_DISABLE_MMAP
i64 nMap = nByte;
int rc;
@@ -4554,29 +4723,13 @@ static int unixMapfile(unixFile *pFd, i64 nByte){
}
if( nMap!=pFd->mmapSize ){
void *pNew = 0;
#if defined(__linux__) && defined(_GNU_SOURCE)
if( pFd->pMapRegion && nMap>0 ){
pNew = osMremap(pFd->pMapRegion, pFd->mmapOrigsize, nMap, MREMAP_MAYMOVE);
}else
#endif
{
if( nMap>0 ){
unixRemapfile(pFd, nMap);
}else{
unixUnmapfile(pFd);
if( nMap>0 ){
int flags = PROT_READ;
if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
pNew = osMmap(0, nMap, flags, MAP_SHARED, pFd->h, 0);
}
}
if( pNew==MAP_FAILED ){
return SQLITE_IOERR_MMAP;
}
pFd->pMapRegion = pNew;
pFd->mmapSize = nMap;
pFd->mmapOrigsize = nMap;
}
#endif
return SQLITE_OK;
}
@@ -4594,9 +4747,12 @@ static int unixMapfile(unixFile *pFd, i64 nByte){
** release the reference by calling unixUnfetch().
*/
static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
#ifndef SQLITE_DISABLE_MMAP
unixFile *pFd = (unixFile *)fd; /* The underlying database file */
#endif
*pp = 0;
#ifndef SQLITE_DISABLE_MMAP
if( pFd->mmapLimit>0 ){
if( pFd->pMapRegion==0 ){
int rc = unixMapfile(pFd, -1);
@@ -4607,6 +4763,7 @@ static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
pFd->nFetchOut++;
}
}
#endif
return SQLITE_OK;
}
@@ -4969,7 +5126,7 @@ static int fillInUnixFile(
pNew->pVfs = pVfs;
pNew->zPath = zFilename;
pNew->ctrlFlags = (u8)ctrlFlags;
pNew->mmapLimit = SQLITE_DEFAULT_MMAP_LIMIT;
pNew->mmapLimit = sqlite3GlobalConfig.mxMmap;
if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
"psow", SQLITE_POWERSAFE_OVERWRITE) ){
pNew->ctrlFlags |= UNIXFILE_PSOW;
@@ -5114,6 +5271,7 @@ static int fillInUnixFile(
}else{
pNew->pMethod = pLockingStyle;
OpenCounter(+1);
verifyDbFile(pNew);
}
return rc;
}
+209 -120
View File
@@ -150,9 +150,14 @@ struct winFile {
winceLock local; /* Locks obtained by this instance of winFile */
winceLock *shared; /* Global shared lock memory for the file */
#endif
HANDLE hMap; /* Handle for accessing memory mapping */
void *pMapRegion; /* Area memory mapped */
sqlite3_int64 mmapSize; /* Size of xMremap() */
#if !defined(SQLITE_DISABLE_MMAP)
int nFetchOut; /* Number of outstanding xFetch references */
HANDLE hMap; /* Handle for accessing memory mapping */
void *pMapRegion; /* Area memory mapped */
sqlite3_int64 mmapSize; /* Usable size of mapped region */
sqlite3_int64 mmapOrigsize; /* Actual size of mapped region */
sqlite3_int64 mmapLimit; /* Configured FCNTL_MMAP_LIMIT value */
#endif
};
/*
@@ -2066,7 +2071,7 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
}
/* Forward references to VFS methods */
static int winUnmap(sqlite3_file *);
static int winUnmapfile(winFile*);
/*
** Close a file.
@@ -2090,8 +2095,10 @@ static int winClose(sqlite3_file *id){
OSTRACE(("CLOSE %d\n", pFile->h));
assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
rc = winUnmap(id);
#if !defined(SQLITE_DISABLE_MMAP)
rc = winUnmapfile(pFile);
if( rc!=SQLITE_OK ) return rc;
#endif
do{
rc = osCloseHandle(pFile->h);
@@ -2142,10 +2149,26 @@ static int winRead(
assert( id!=0 );
assert( amt>0 );
assert( offset>=pFile->mmapSize ); /* Never read from the mmapped region */
SimulateIOError(return SQLITE_IOERR_READ);
OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype));
#if !defined(SQLITE_DISABLE_MMAP)
/* Deal with as much of this read request as possible by transfering
** data from the memory mapping using memcpy(). */
if( offset<pFile->mmapSize ){
if( offset+amt <= pFile->mmapSize ){
memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
return SQLITE_OK;
}else{
int nCopy = (int)(pFile->mmapSize - offset);
memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy);
pBuf = &((u8 *)pBuf)[nCopy];
amt -= nCopy;
offset += nCopy;
}
}
#endif
#if SQLITE_OS_WINCE
if( seekWinFile(pFile, offset) ){
return SQLITE_FULL;
@@ -2189,13 +2212,29 @@ static int winWrite(
int nRetry = 0; /* Number of retries */
assert( amt>0 );
assert( offset>=pFile->mmapSize ); /* Never write into the mmapped region */
assert( pFile );
SimulateIOError(return SQLITE_IOERR_WRITE);
SimulateDiskfullError(return SQLITE_FULL);
OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype));
#if !defined(SQLITE_DISABLE_MMAP)
/* Deal with as much of this write request as possible by transfering
** data from the memory mapping using memcpy(). */
if( offset<pFile->mmapSize ){
if( offset+amt <= pFile->mmapSize ){
memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt);
return SQLITE_OK;
}else{
int nCopy = (int)(pFile->mmapSize - offset);
memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy);
pBuf = &((u8 *)pBuf)[nCopy];
amt -= nCopy;
offset += nCopy;
}
}
#endif
#if SQLITE_OS_WINCE
rc = seekWinFile(pFile, offset);
if( rc==0 ){
@@ -2288,16 +2327,18 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
pFile->lastErrno = lastErrno;
rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
"winTruncate2", pFile->zPath);
}else{
/* If the file was just truncated to a size smaller than the currently
** mapped region, reduce the effective mapping size as well. SQLite will
** use read() and write() to access data beyond this point from now on.
*/
if( pFile->pMapRegion && nByte<pFile->mmapSize ){
pFile->mmapSize = nByte;
}
}
#if !defined(SQLITE_DISABLE_MMAP)
/* If the file was truncated to a size smaller than the currently
** mapped region, reduce the effective mapping size as well. SQLite will
** use read() and write() to access data beyond this point from now on.
*/
if( pFile->pMapRegion && nByte<pFile->mmapSize ){
pFile->mmapSize = nByte;
}
#endif
OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok"));
return rc;
}
@@ -2665,7 +2706,7 @@ static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
rc = 1;
OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc));
}else{
rc = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
rc = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0);
if( rc ){
winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
}
@@ -2805,6 +2846,14 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
}
return SQLITE_OK;
}
#if !defined(SQLITE_DISABLE_MMAP)
case SQLITE_FCNTL_MMAP_LIMIT: {
i64 newLimit = *(i64*)pArg;
*(i64*)pArg = pFile->mmapLimit;
if( newLimit>=0 ) pFile->mmapLimit = newLimit;
return SQLITE_OK;
}
#endif
}
return SQLITE_NOTFOUND;
}
@@ -3475,37 +3524,26 @@ shmpage_out:
# define winShmUnmap 0
#endif /* #ifndef SQLITE_OMIT_WAL */
/*
** Arguments x and y are both integers. Argument y must be a power of 2.
** Round x up to the nearest integer multiple of y. For example:
**
** ROUNDUP(0, 8) -> 0
** ROUNDUP(13, 8) -> 16
** ROUNDUP(32, 8) -> 32
*/
#define ROUNDUP(x,y) (((x)+y-1)&~(y-1))
/*
** Cleans up the mapped region of the specified file, if any.
*/
static int winUnmap(
sqlite3_file *id
){
winFile *pFile = (winFile*)id;
#if !defined(SQLITE_DISABLE_MMAP)
static int winUnmapfile(winFile *pFile){
assert( pFile!=0 );
if( pFile->pMapRegion ){
if( !osUnmapViewOfFile(pFile->pMapRegion) ){
pFile->lastErrno = osGetLastError();
return winLogError(SQLITE_IOERR_MREMAP, pFile->lastErrno,
return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
"winUnmap1", pFile->zPath);
}
pFile->pMapRegion = 0;
pFile->mmapSize = 0;
pFile->mmapOrigsize = 0;
}
if( pFile->hMap!=NULL ){
if( !osCloseHandle(pFile->hMap) ){
pFile->lastErrno = osGetLastError();
return winLogError(SQLITE_IOERR_MREMAP, pFile->lastErrno,
return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
"winUnmap2", pFile->zPath);
}
pFile->hMap = NULL;
@@ -3514,116 +3552,162 @@ static int winUnmap(
}
/*
** Map, remap or unmap part of the database file.
** Memory map or remap the file opened by file-descriptor pFd (if the file
** is already mapped, the existing mapping is replaced by the new). Or, if
** there already exists a mapping for this file, and there are still
** outstanding xFetch() references to it, this function is a no-op.
**
** If parameter nByte is non-negative, then it is the requested size of
** the mapping to create. Otherwise, if nByte is less than zero, then the
** requested size is the size of the file on disk. The actual size of the
** created mapping is either the requested size or the value configured
** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller.
**
** SQLITE_OK is returned if no error occurs (even if the mapping is not
** recreated as a result of outstanding references) or an SQLite error
** code otherwise.
*/
static int winMremap(
sqlite3_file *id, /* Main database file */
int flags, /* Mask of SQLITE_MREMAP_XXX flags */
sqlite3_int64 iOff, /* Offset to start mapping at */
sqlite3_int64 nOld, /* Size of old mapping, or zero */
sqlite3_int64 nNew, /* Size of new mapping, or zero */
void **ppMap /* IN/OUT: Old/new mappings */
){
winFile *pFile = (winFile*)id; /* The underlying database file */
int rc = SQLITE_OK; /* Return code */
HANDLE hMap = NULL; /* New mapping handle */
void *pNew = 0; /* New mapping */
i64 nNewRnd; /* nNew rounded up */
i64 nOldRnd; /* nOld rounded up */
static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
sqlite3_int64 nMap = nByte;
int rc;
assert( pFile!=0 );
assert( iOff==0 );
assert( nOld>=0 );
assert( nOld==0 || pFile->pMapRegion==(*ppMap) );
assert( nNew>=0 );
assert( ppMap );
assert( pFile->hMap==NULL || pFile->pMapRegion==(*ppMap) );
assert( pFile->pMapRegion==0 || pFile->pMapRegion==(*ppMap) );
/* assert( pFile->mmapSize==nOld ); */
assert( nMap>=0 || pFd->nFetchOut==0 );
if( pFd->nFetchOut>0 ) return SQLITE_OK;
assert( winSysInfo.dwPageSize>0 );
nNewRnd = ROUNDUP(nNew, winSysInfo.dwPageSize*1);
assert( nNewRnd>=0 );
nOldRnd = ROUNDUP(nOld, winSysInfo.dwPageSize*1);
assert( nOldRnd>=0 );
if( nNewRnd==nOldRnd ){
pFile->mmapSize = nNew;
return SQLITE_OK;
}
/* If the SQLITE_MREMAP_EXTEND flag is set, then the size of the requested
** mapping (nNew bytes) may be greater than the size of the database file.
** If this is the case, extend the file on disk using ftruncate(). */
assert( nNewRnd>0 || (flags & SQLITE_MREMAP_EXTEND)==0 );
if( flags & SQLITE_MREMAP_EXTEND ){
sqlite3_int64 oldSz;
rc = winFileSize(id, &oldSz);
if( rc==SQLITE_OK && nNewRnd>oldSz ){
rc = winUnmap(id); /* Cannot truncate the file with an open mapping. */
if( rc==SQLITE_OK ){
rc = winTruncate(id, nNewRnd);
}
if( nMap<0 ){
rc = winFileSize((sqlite3_file*)pFd, &nMap);
if( rc ){
return SQLITE_IOERR_FSTAT;
}
if( rc!=SQLITE_OK ) return rc;
}
/* If we get this far, unmap any old mapping. */
rc = winUnmap(id);
if( rc!=SQLITE_OK ) return rc;
/* And, if required, create a new mapping. */
if( nNewRnd>0 ){
i64 offset = ((iOff / winSysInfo.dwAllocationGranularity) *
(winSysInfo.dwAllocationGranularity));
if( nMap>pFd->mmapLimit ){
nMap = pFd->mmapLimit;
}
nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1);
if( nMap==0 && pFd->mmapSize>0 ){
winUnmapfile(pFd);
}
if( nMap!=pFd->mmapSize ){
void *pNew = 0;
DWORD protect = PAGE_READONLY;
DWORD flags = FILE_MAP_READ;
if( (pFile->ctrlFlags & WINFILE_RDONLY)==0 ){
winUnmapfile(pFd);
if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){
protect = PAGE_READWRITE;
flags |= FILE_MAP_WRITE;
}
#if SQLITE_OS_WINRT
hMap = osCreateFileMappingFromApp(pFile->h, NULL, protect, nNewRnd, NULL);
pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL);
#elif defined(SQLITE_WIN32_HAS_WIDE)
hMap = osCreateFileMappingW(pFile->h, NULL, protect,
(DWORD)((nNewRnd>>32) & 0xffffffff),
(DWORD)(nNewRnd & 0xffffffff), NULL);
pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect,
(DWORD)((nMap>>32) & 0xffffffff),
(DWORD)(nMap & 0xffffffff), NULL);
#elif defined(SQLITE_WIN32_HAS_ANSI)
hMap = osCreateFileMappingA(pFile->h, NULL, protect,
(DWORD)((nNewRnd>>32) & 0xffffffff),
(DWORD)(nNewRnd & 0xffffffff), NULL);
pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect,
(DWORD)((nMap>>32) & 0xffffffff),
(DWORD)(nMap & 0xffffffff), NULL);
#endif
if( hMap==NULL ){
pFile->lastErrno = osGetLastError();
rc = winLogError(SQLITE_IOERR_MREMAP, pFile->lastErrno,
"winMremap1", pFile->zPath);
return rc;
if( pFd->hMap==NULL ){
pFd->lastErrno = osGetLastError();
rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
"winMapfile", pFd->zPath);
/* Log the error, but continue normal operation using xRead/xWrite */
return SQLITE_OK;
}
assert( (nNewRnd % winSysInfo.dwPageSize)==0 );
assert( (nMap % winSysInfo.dwPageSize)==0 );
#if SQLITE_OS_WINRT
pNew = osMapViewOfFileFromApp(hMap, flags, offset, nNewRnd);
pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, nMap);
#else
assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nNewRnd<=0xffffffff );
pNew = osMapViewOfFile(hMap, flags,
(DWORD)((offset>>32) & 0xffffffff),
(DWORD)(offset & 0xffffffff),
(SIZE_T)nNewRnd);
assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
#endif
if( pNew==NULL ){
osCloseHandle(hMap);
hMap = NULL;
pFile->lastErrno = osGetLastError();
rc = winLogError(SQLITE_IOERR_MREMAP, pFile->lastErrno,
"winMremap2", pFile->zPath);
osCloseHandle(pFd->hMap);
pFd->hMap = NULL;
pFd->lastErrno = osGetLastError();
winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
"winMapfile", pFd->zPath);
return SQLITE_OK;
}
pFd->pMapRegion = pNew;
pFd->mmapSize = nMap;
pFd->mmapOrigsize = nMap;
}
pFile->hMap = hMap;
pFile->pMapRegion = pNew;
pFile->mmapSize = nNew;
return SQLITE_OK;
}
#endif /* !defined(SQLITE_DISABLE_MMAP) */
*ppMap = pNew;
return rc;
/*
** If possible, return a pointer to a mapping of file fd starting at offset
** iOff. The mapping must be valid for at least nAmt bytes.
**
** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.
** Finally, if an error does occur, return an SQLite error code. The final
** value of *pp is undefined in this case.
**
** If this function does return a pointer, the caller must eventually
** release the reference by calling unixUnfetch().
*/
static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
#if !defined(SQLITE_DISABLE_MMAP)
winFile *pFd = (winFile*)fd; /* The underlying database file */
#endif
*pp = 0;
#if !defined(SQLITE_DISABLE_MMAP)
if( pFd->mmapLimit>0 ){
if( pFd->pMapRegion==0 ){
int rc = winMapfile(pFd, -1);
if( rc!=SQLITE_OK ) return rc;
}
if( pFd->mmapSize >= iOff+nAmt ){
*pp = &((u8 *)pFd->pMapRegion)[iOff];
pFd->nFetchOut++;
}
}
#endif
return SQLITE_OK;
}
/*
** If the third argument is non-NULL, then this function releases a
** reference obtained by an earlier call to unixFetch(). The second
** argument passed to this function must be the same as the corresponding
** argument that was passed to the unixFetch() invocation.
**
** Or, if the third argument is NULL, then this function is being called
** to inform the VFS layer that, according to POSIX, any existing mapping
** may now be invalid and should be unmapped.
*/
static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){
#if !defined(SQLITE_DISABLE_MMAP)
winFile *pFd = (winFile*)fd; /* The underlying database file */
/* If p==0 (unmap the entire file) then there must be no outstanding
** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
** then there must be at least one outstanding. */
assert( (p==0)==(pFd->nFetchOut==0) );
/* If p!=0, it must match the iOff value. */
assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] );
if( p ){
pFd->nFetchOut--;
}else{
/* FIXME: If Windows truly always prevents truncating or deleting a
** file while a mapping is held, then the following winUnmapfile() call
** is unnecessary can can be omitted - potentially improving
** performance. */
winUnmapfile(pFd);
}
assert( pFd->nFetchOut>=0 );
#endif
return SQLITE_OK;
}
/*
@@ -3654,7 +3738,8 @@ static const sqlite3_io_methods winIoMethod = {
winShmLock, /* xShmLock */
winShmBarrier, /* xShmBarrier */
winShmUnmap, /* xShmUnmap */
winMremap, /* xMremap */
winFetch, /* xFetch */
winUnfetch /* xUnfetch */
};
/****************************************************************************
@@ -4049,9 +4134,13 @@ static int winOpen(
}
pFile->lastErrno = NO_ERROR;
pFile->zPath = zName;
#if !defined(SQLITE_DISABLE_MMAP)
pFile->hMap = NULL;
pFile->pMapRegion = 0;
pFile->mmapSize = 0;
pFile->mmapOrigsize = 0;
pFile->mmapLimit = sqlite3GlobalConfig.mxMmap;
#endif
OpenCounter(+1);
return rc;
+40 -23
View File
@@ -659,7 +659,7 @@ struct Pager {
u8 bUseFetch; /* True to use xFetch() */
int nMmapOut; /* Number of mmap pages currently outstanding */
sqlite3_int64 mxMmap; /* Desired maximum mmap size */
PgHdr *pFree; /* List of free mmap page headers (pDirty) */
PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */
/*
** End of the routinely-changing class members
***************************************************************************/
@@ -770,6 +770,16 @@ static const unsigned char aJournalMagic[] = {
# define MEMDB pPager->memDb
#endif
/*
** The macro USEFETCH is true if we are allowed to use the xFetch and xUnfetch
** interfaces to access the database using memory-mapped I/O.
*/
#ifdef SQLITE_DISABLE_MMAP
# define USEFETCH(x) 0
#else
# define USEFETCH(x) ((x)->bUseFetch)
#endif
/*
** The maximum legal page number is (2^31 - 1).
*/
@@ -2648,6 +2658,7 @@ static int pager_playback(Pager *pPager, int isHot){
int res = 1; /* Value returned by sqlite3OsAccess() */
char *zMaster = 0; /* Name of master journal file if any */
int needPagerReset; /* True to reset page prior to first page rollback */
int nPlayback = 0; /* Total number of pages restored from journal */
/* Figure out how many records are in the journal. Abort early if
** the journal is empty.
@@ -2748,7 +2759,9 @@ static int pager_playback(Pager *pPager, int isHot){
needPagerReset = 0;
}
rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_OK ){
nPlayback++;
}else{
if( rc==SQLITE_DONE ){
pPager->journalOff = szJ;
break;
@@ -2818,6 +2831,10 @@ end_playback:
rc = pager_delmaster(pPager, zMaster);
testcase( rc!=SQLITE_OK );
}
if( isHot && nPlayback ){
sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s",
nPlayback, pPager->zJournal);
}
/* The Pager.sectorSize variable may have been updated while rolling
** back a journal created by a process with a different sector size
@@ -2936,15 +2953,14 @@ static int pagerUndoCallback(void *pCtx, Pgno iPg){
Pager *pPager = (Pager *)pCtx;
PgHdr *pPg;
assert( pagerUseWal(pPager) );
pPg = sqlite3PagerLookup(pPager, iPg);
if( pPg ){
if( sqlite3PcachePageRefcount(pPg)==1 ){
sqlite3PcacheDrop(pPg);
}else{
u32 iFrame = 0;
if( pagerUseWal(pPager) ){
rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame);
}
rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame);
if( rc==SQLITE_OK ){
rc = readDbPage(pPg, iFrame);
}
@@ -3091,7 +3107,7 @@ static int pagerBeginReadTransaction(Pager *pPager){
rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed);
if( rc!=SQLITE_OK || changed ){
pager_reset(pPager);
if( pPager->bUseFetch ) sqlite3OsUnfetch(pPager->fd, 0, 0);
if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
}
return rc;
@@ -3357,14 +3373,15 @@ void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
** Invoke SQLITE_FCNTL_MMAP_LIMIT based on the current value of mxMmap.
*/
static void pagerFixMaplimit(Pager *pPager){
#if !defined(SQLITE_DISABLE_MMAP)
sqlite3_file *fd = pPager->fd;
if( isOpen(fd) ){
sqlite3_int64 mx;
pPager->bUseFetch = (fd->pMethods->iVersion>=3) && pPager->mxMmap>0;
if( pPager->bUseFetch ){
sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_LIMIT,
(void*)&pPager->mxMmap);
}
mx = pPager->mxMmap;
sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_LIMIT, &mx);
}
#endif
}
/*
@@ -3854,9 +3871,9 @@ static int pagerAcquireMapPage(
){
PgHdr *p; /* Memory mapped page to return */
if( pPager->pFree ){
*ppPage = p = pPager->pFree;
pPager->pFree = p->pDirty;
if( pPager->pMmapFreelist ){
*ppPage = p = pPager->pMmapFreelist;
pPager->pMmapFreelist = p->pDirty;
p->pDirty = 0;
memset(p->pExtra, 0, pPager->nExtra);
}else{
@@ -3891,20 +3908,20 @@ static int pagerAcquireMapPage(
static void pagerReleaseMapPage(PgHdr *pPg){
Pager *pPager = pPg->pPager;
pPager->nMmapOut--;
pPg->pDirty = pPager->pFree;
pPager->pFree = pPg;
pPg->pDirty = pPager->pMmapFreelist;
pPager->pMmapFreelist = pPg;
assert( pPager->fd->pMethods->iVersion>=3 );
sqlite3OsUnfetch(pPager->fd, (i64)(pPg->pgno-1)*pPager->pageSize, pPg->pData);
}
/*
** Free all PgHdr objects stored in the Pager.pFree list.
** Free all PgHdr objects stored in the Pager.pMmapFreelist list.
*/
static void pagerFreeMapHdrs(Pager *pPager){
PgHdr *p;
PgHdr *pNext;
for(p=pPager->pFree; p; p=pNext){
for(p=pPager->pMmapFreelist; p; p=pNext){
pNext = p->pDirty;
sqlite3_free(p);
}
@@ -4749,7 +4766,7 @@ int sqlite3PagerOpen(
/* pPager->pBusyHandlerArg = 0; */
pPager->xReiniter = xReinit;
/* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
pPager->mxMmap = SQLITE_DEFAULT_MMAP_LIMIT;
/* pPager->mxMmap = SQLITE_DEFAULT_MMAP_LIMIT // will be set by btree.c */
*ppPager = pPager;
return SQLITE_OK;
@@ -5044,7 +5061,7 @@ int sqlite3PagerSharedLock(Pager *pPager){
if( !pPager->tempFile && (
pPager->pBackup
|| sqlite3PcachePagecount(pPager->pPCache)>0
|| pPager->bUseFetch
|| USEFETCH(pPager)
)){
/* The shared-lock has just been acquired on the database file
** and there are already pages in the cache (from a previous
@@ -5087,7 +5104,7 @@ int sqlite3PagerSharedLock(Pager *pPager){
** In this case there may exist a Pager.pMap mapping that appears
** to be the right size but is not actually valid. Avoid this
** possibility by unmapping the db here. */
if( pPager->bUseFetch ){
if( USEFETCH(pPager) ){
sqlite3OsUnfetch(pPager->fd, 0, 0);
}
}
@@ -5131,7 +5148,7 @@ int sqlite3PagerSharedLock(Pager *pPager){
** nothing to rollback, so this routine is a no-op.
*/
static void pagerUnlockIfUnused(Pager *pPager){
if( (sqlite3PcacheRefCount(pPager->pPCache)==0) && pPager->nMmapOut==0 ){
if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){
pagerUnlockAndRollback(pPager);
}
}
@@ -5201,7 +5218,7 @@ int sqlite3PagerAcquire(
** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
** flag was specified by the caller. And so long as the db is not a
** temporary or in-memory database. */
const int bMmapOk = (pgno!=1 && pPager->bUseFetch
const int bMmapOk = (pgno!=1 && USEFETCH(pPager)
&& (pPager->eState==PAGER_READER || (flags & PAGER_ACQUIRE_READONLY))
);
@@ -6264,7 +6281,7 @@ int sqlite3PagerRollback(Pager *pPager){
}
assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK );
assert( rc==SQLITE_OK || rc==SQLITE_FULL
assert( rc==SQLITE_OK || rc==SQLITE_FULL || rc==SQLITE_CORRUPT
|| rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR );
/* If an error occurs during a ROLLBACK, we can no longer trust the pager
+24 -7
View File
@@ -319,7 +319,7 @@ void sqlite3Pragma(
int rc; /* return value form SQLITE_FCNTL_PRAGMA */
sqlite3 *db = pParse->db; /* The database connection */
Db *pDb; /* The specific database being pragmaed */
Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(db); /* Prepared statement */
Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */
if( v==0 ) return;
sqlite3VdbeRunOnlyOnce(v);
@@ -402,11 +402,12 @@ void sqlite3Pragma(
static const VdbeOpList getCacheSize[] = {
{ OP_Transaction, 0, 0, 0}, /* 0 */
{ OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */
{ OP_IfPos, 1, 7, 0},
{ OP_IfPos, 1, 8, 0},
{ OP_Integer, 0, 2, 0},
{ OP_Subtract, 1, 2, 1},
{ OP_IfPos, 1, 7, 0},
{ OP_IfPos, 1, 8, 0},
{ OP_Integer, 0, 1, 0}, /* 6 */
{ OP_Noop, 0, 0, 0},
{ OP_ResultRow, 1, 1, 0},
};
int addr;
@@ -750,18 +751,34 @@ void sqlite3Pragma(
** Used to set mapping size limit. The mapping size limit is
** used to limit the aggregate size of all memory mapped regions of the
** database file. If this parameter is set to zero, then memory mapping
** is not used at all. The parameter N is measured in bytes.
** is not used at all. If N is negative, then the default memory map
** limit determined by sqlite3_config(SQLITE_CONFIG_MMAP_LIMIT) is set.
** The parameter N is measured in bytes.
**
** This value is advisory. The underlying VFS is free to memory map
** as little or as much as it wants. Except, if N is set to 0 then the
** upper layers will never invoke the xFetch interfaces to the VFS.
*/
if( sqlite3StrICmp(zLeft,"mmap_limit")==0 ){
sqlite3_int64 mx;
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( zRight ){
sqlite3_int64 size;
sqlite3Atoi64(zRight, &size, 1000, SQLITE_UTF8);
sqlite3BtreeSetMmapLimit(pDb->pBt, size);
int ii;
sqlite3Atoi64(zRight, &mx, 1000, SQLITE_UTF8);
if( mx<0 ) mx = sqlite3GlobalConfig.mxMmap;
if( pId2->n==0 ) db->mxMmap = mx;
for(ii=db->nDb-1; ii>=0; ii--){
if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){
sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, mx);
}
}
}
mx = -1;
if( sqlite3_file_control(db,zDb,SQLITE_FCNTL_MMAP_LIMIT,&mx)==SQLITE_OK ){
#if defined(SQLITE_DISABLE_MMAP)
mx = 0;
#endif
returnSingleInt(pParse, "mmap_limit", mx);
}
}else
-1
View File
@@ -654,7 +654,6 @@ static int sqlite3Prepare(
}
#endif
assert( db->init.busy==0 || saveSqlFlag==0 );
if( db->init.busy==0 ){
Vdbe *pVdbe = pParse->pVdbe;
sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag);
+45 -8
View File
@@ -1552,6 +1552,43 @@ static int booleanValue(char *zArg){
return 0;
}
/*
** Interpret zArg as an integer value, possibly with suffixes.
*/
static sqlite3_int64 integerValue(const char *zArg){
sqlite3_int64 v = 0;
static const struct { char *zSuffix; int iMult; } aMult[] = {
{ "KiB", 1024 },
{ "MiB", 1024*1024 },
{ "GiB", 1024*1024*1024 },
{ "KB", 1000 },
{ "MB", 1000000 },
{ "GB", 1000000000 },
{ "K", 1000 },
{ "M", 1000000 },
{ "G", 1000000000 },
};
int i;
int isNeg = 0;
if( zArg[0]=='-' ){
isNeg = 1;
zArg++;
}else if( zArg[0]=='+' ){
zArg++;
}
while( isdigit(zArg[0]) ){
v = v*10 + zArg[0] - '0';
zArg++;
}
for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++){
if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
v *= aMult[i].iMult;
break;
}
}
return isNeg? -v : v;
}
/*
** Close an output file, assuming it is not stderr or stdout
*/
@@ -2469,7 +2506,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
/* sqlite3_test_control(int, uint) */
case SQLITE_TESTCTRL_PENDING_BYTE:
if( nArg==3 ){
unsigned int opt = (unsigned int)atoi(azArg[2]);
unsigned int opt = (unsigned int)integerValue(azArg[2]);
rc = sqlite3_test_control(testctrl, opt);
printf("%d (0x%08x)\n", rc, rc);
} else {
@@ -2561,7 +2598,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
extern int sqlite3WhereTrace;
sqlite3WhereTrace = atoi(azArg[1]);
sqlite3WhereTrace = booleanValue(azArg[1]);
}else
#endif
@@ -2882,6 +2919,7 @@ static const char zOptions[] =
" -interactive force interactive I/O\n"
" -line set output mode to 'line'\n"
" -list set output mode to 'list'\n"
" -mmap N default mmap size set to N\n"
#ifdef SQLITE_ENABLE_MULTIPLEX
" -multiplex enable the multiplexor VFS\n"
#endif
@@ -3001,12 +3039,7 @@ int main(int argc, char **argv){
sqlite3_int64 szHeap;
zSize = cmdline_option_value(argc, argv, ++i);
szHeap = atoi(zSize);
for(j=0; (c = zSize[j])!=0; j++){
if( c=='M' ){ szHeap *= 1000000; break; }
if( c=='K' ){ szHeap *= 1000; break; }
if( c=='G' ){ szHeap *= 1000000000; break; }
}
szHeap = integerValue(zSize);
if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
#endif
@@ -3026,6 +3059,8 @@ int main(int argc, char **argv){
extern int sqlite3_multiple_initialize(const char*,int);
sqlite3_multiplex_initialize(0, 1);
#endif
}else if( strcmp(z,"-mmap")==0 ){
sqlite3_config(SQLITE_CONFIG_MMAP_LIMIT, integerValue(cmdline_option_value(argc,argv,++i)));
}else if( strcmp(z,"-vfs")==0 ){
sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
if( pVfs ){
@@ -3111,6 +3146,8 @@ int main(int argc, char **argv){
stdin_is_interactive = 0;
}else if( strcmp(z,"-heap")==0 ){
i++;
}else if( strcmp(z,"-mmap")==0 ){
i++;
}else if( strcmp(z,"-vfs")==0 ){
i++;
#ifdef SQLITE_ENABLE_VFSTRACE
+44 -4
View File
@@ -420,6 +420,8 @@ int sqlite3_exec(
#define SQLITE_FORMAT 24 /* Auxiliary database format error */
#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */
#define SQLITE_NOTADB 26 /* File opened that is not a database file */
#define SQLITE_NOTICE 27 /* Notifications from sqlite3_log() */
#define SQLITE_WARNING 28 /* Warnings from sqlite3_log() */
#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */
#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */
/* end-of-error-codes */
@@ -490,6 +492,8 @@ int sqlite3_exec(
#define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8))
#define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8))
#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8))
#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
/*
** CAPI3REF: Flags For File Open Operations
@@ -868,7 +872,8 @@ struct sqlite3_io_methods {
** it is able to override built-in [PRAGMA] statements.
**
** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
** ^This file-control may be invoked by SQLite on the database file handle
** ^The [SQLITE_FCNTL_BUSYHANDLER]
** file-control may be invoked by SQLite on the database file handle
** shortly after it is opened in order to provide a custom VFS with access
** to the connections busy-handler callback. The argument is of type (void **)
** - an array of two (void *) values. The first (void *) actually points
@@ -879,7 +884,8 @@ struct sqlite3_io_methods {
** current operation.
**
** <li>[[SQLITE_FCNTL_TEMPFILENAME]]
** ^Application can invoke this file-control to have SQLite generate a
** ^Application can invoke the [SQLITE_FCNTL_TEMPFILENAME] file-control
** to have SQLite generate a
** temporary filename using the same algorithm that is followed to generate
** temporary filenames for TEMP tables and other internal uses. The
** argument should be a char** which will be filled with the filename
@@ -887,8 +893,14 @@ struct sqlite3_io_methods {
** invoke [sqlite3_free()] on the result to avoid a memory leak.
**
** <li>[[SQLITE_FCNTL_MMAP_LIMIT]]
** The argument is assumed to pointer to a value of type sqlite3_int64 that
** is an advisory maximum number of bytes in the file to memory map.
** The [SQLITE_FCNTL_MMAP_LIMIT] file control is used to query or set the
** maximum number of bytes that will be used for memory-mapped I/O.
** The argument is a pointer to a value of type sqlite3_int64 that
** is an advisory maximum number of bytes in the file to memory map. The
** pointer is overwritten with the old value. The limit is not changed if
** the originally pointed to is negative, and so the current limit can be
** queried by passing in a pointer to a negative number. This file-control
** is used internally to implement [PRAGMA mmap_limit].
**
** </ul>
*/
@@ -1637,6 +1649,18 @@ struct sqlite3_mem_methods {
** points to has just been executed. Or, if the fourth parameter is 2, then
** the connection being passed as the second parameter is being closed. The
** third parameter is passed NULL In this case.
**
** [[SQLITE_CONFIG_MMAP_LIMIT]]
** <dt>SQLITE_CONFIG_MMAP_LIMIT
** <dd>The sole argument should be a 64-bit integer (an sqlite3_int64) that
** is the default maximum number of bytes of process address space that
** should be used for accessing each database file using memory mapping.
** The default setting can be overridden by each database connection using
** either the [PRAGMA mmap_limit] command, or by using the
** [SQLITE_FCNTL_MMAP_LIMIT] file control. The value set here overrides the
** compile-time default that is set using [SQLITE_DEFAULT_MMAP_LIMIT].
** If the argument to this option is negative, then
** the memory map limit is set to the compile-time default.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
@@ -1660,6 +1684,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
#define SQLITE_CONFIG_MMAP_LIMIT 22 /* sqlite3_int64 */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -6816,6 +6841,21 @@ int sqlite3_unlock_notify(
int sqlite3_stricmp(const char *, const char *);
int sqlite3_strnicmp(const char *, const char *, int);
/*
** CAPI3REF: String Globbing
*
** ^The [sqlite3_strglob(P,X)] interface returns zero if string X matches
** the glob pattern P, and it returns non-zero if string X does not match
** the glob pattern P. ^The definition of glob pattern matching used in
** [sqlite3_strglob(P,X) is the same as for the "X GLOB P" operator in the
** SQL dialect used by SQLite. ^The sqlite3_strglob(P,X) function is case
** sensitive.
**
** Note that this routine returns zero on a match and non-zero if the strings
** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
*/
int sqlite3_strglob(const char *zGlob, const char *zStr);
/*
** CAPI3REF: Error Logging Interface
**
+10
View File
@@ -539,6 +539,14 @@ extern const int sqlite3one;
# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0)
#endif
/*
** Disable MMAP on platforms where it is not supported
*/
#if defined(__OpenBSD__) || defined(__QNXNTO__)
# undef SQLITE_DISABLE_MMAP
# define SQLITE_DISABLE_MMAP 1
#endif
/*
** An instance of the following structure is used to store the busy-handler
@@ -834,6 +842,7 @@ struct sqlite3 {
int nDb; /* Number of backends currently in use */
int flags; /* Miscellaneous flags. See below */
i64 lastRowid; /* ROWID of most recent insert (see above) */
i64 mxMmap; /* Default mmap_limit setting */
unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
int errCode; /* Most recent error code (SQLITE_*) */
int errMask; /* & result codes with this before returning */
@@ -2505,6 +2514,7 @@ struct Sqlite3Config {
void *pHeap; /* Heap storage space */
int nHeap; /* Size of pHeap[] */
int mnReq, mxReq; /* Min and max heap requests sizes */
sqlite3_int64 mxMmap; /* Maximum mmap() space per open file */
void *pScratch; /* Scratch memory */
int szScratch; /* Size of each scratch buffer */
int nScratch; /* Number of scratch buffers */
+19 -2
View File
@@ -210,6 +210,23 @@
/*
** Default maximum size of memory used by xFetch in the VFS.
*/
#ifndef SQLITE_DEFAULT_MMAP_LIMIT
# define SQLITE_DEFAULT_MMAP_LIMIT (256*1024*1024)
#ifdef SQLITE_DISABLE_MMAP
# undef SQLITE_DEFAULT_MMAP_LIMIT
# define SQLITE_DEFAULT_MMAP_LIMIT 0
#endif
#ifdef __APPLE__
# include <TargetConditionals.h>
# if TARGET_OS_IPHONE
# define SQLITE_DEFAULT_MMAP_LIMIT 0
# endif
#endif
#ifndef SQLITE_DEFAULT_MMAP_LIMIT
# if defined(__linux__) \
|| defined(_WIN32) \
|| (defined(__APPLE__) && defined(__MACH__)) \
|| defined(__sun)
# define SQLITE_DEFAULT_MMAP_LIMIT 268435456 /* = 256*1024*1024 */
# else
# define SQLITE_DEFAULT_MMAP_LIMIT 0
# endif
#endif
+69 -64
View File
@@ -116,71 +116,76 @@ int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){
const char *sqlite3TestErrorName(int rc){
const char *zName = 0;
switch( rc ){
case SQLITE_OK: zName = "SQLITE_OK"; break;
case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break;
case SQLITE_PERM: zName = "SQLITE_PERM"; break;
case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break;
case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break;
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break;
case SQLITE_FULL: zName = "SQLITE_FULL"; break;
case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break;
case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break;
case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break;
case SQLITE_CONSTRAINT_UNIQUE: zName = "SQLITE_CONSTRAINT_UNIQUE"; break;
case SQLITE_CONSTRAINT_TRIGGER: zName = "SQLITE_CONSTRAINT_TRIGGER";break;
case SQLITE_CONSTRAINT_FOREIGNKEY:
zName = "SQLITE_CONSTRAINT_FOREIGNKEY"; break;
case SQLITE_CONSTRAINT_CHECK: zName = "SQLITE_CONSTRAINT_CHECK"; break;
case SQLITE_CONSTRAINT_PRIMARYKEY:
zName = "SQLITE_CONSTRAINT_PRIMARYKEY"; break;
case SQLITE_CONSTRAINT_NOTNULL: zName = "SQLITE_CONSTRAINT_NOTNULL";break;
case SQLITE_CONSTRAINT_COMMITHOOK:
zName = "SQLITE_CONSTRAINT_COMMITHOOK"; break;
case SQLITE_CONSTRAINT_VTAB: zName = "SQLITE_CONSTRAINT_VTAB"; break;
case SQLITE_CONSTRAINT_FUNCTION: zName = "SQLITE_CONSTRAINT_FUNCTION";break;
case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break;
case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break;
case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break;
case SQLITE_AUTH: zName = "SQLITE_AUTH"; break;
case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break;
case SQLITE_RANGE: zName = "SQLITE_RANGE"; break;
case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break;
case SQLITE_ROW: zName = "SQLITE_ROW"; break;
case SQLITE_DONE: zName = "SQLITE_DONE"; break;
case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break;
case SQLITE_IOERR_SHORT_READ: zName = "SQLITE_IOERR_SHORT_READ"; break;
case SQLITE_IOERR_WRITE: zName = "SQLITE_IOERR_WRITE"; break;
case SQLITE_IOERR_FSYNC: zName = "SQLITE_IOERR_FSYNC"; break;
case SQLITE_IOERR_DIR_FSYNC: zName = "SQLITE_IOERR_DIR_FSYNC"; break;
case SQLITE_IOERR_TRUNCATE: zName = "SQLITE_IOERR_TRUNCATE"; break;
case SQLITE_IOERR_FSTAT: zName = "SQLITE_IOERR_FSTAT"; break;
case SQLITE_IOERR_UNLOCK: zName = "SQLITE_IOERR_UNLOCK"; break;
case SQLITE_IOERR_RDLOCK: zName = "SQLITE_IOERR_RDLOCK"; break;
case SQLITE_IOERR_DELETE: zName = "SQLITE_IOERR_DELETE"; break;
case SQLITE_IOERR_BLOCKED: zName = "SQLITE_IOERR_BLOCKED"; break;
case SQLITE_IOERR_NOMEM: zName = "SQLITE_IOERR_NOMEM"; break;
case SQLITE_IOERR_ACCESS: zName = "SQLITE_IOERR_ACCESS"; break;
case SQLITE_IOERR_CHECKRESERVEDLOCK:
zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break;
case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break;
case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break;
case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break;
case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break;
case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break;
default: zName = "SQLITE_Unknown"; break;
int i;
for(i=0; i<2 && zName==0; i++, rc &= 0xff){
switch( rc ){
case SQLITE_OK: zName = "SQLITE_OK"; break;
case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break;
case SQLITE_PERM: zName = "SQLITE_PERM"; break;
case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break;
case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break;
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break;
case SQLITE_FULL: zName = "SQLITE_FULL"; break;
case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break;
case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break;
case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break;
case SQLITE_CONSTRAINT_UNIQUE: zName = "SQLITE_CONSTRAINT_UNIQUE"; break;
case SQLITE_CONSTRAINT_TRIGGER: zName = "SQLITE_CONSTRAINT_TRIGGER";break;
case SQLITE_CONSTRAINT_FOREIGNKEY:
zName = "SQLITE_CONSTRAINT_FOREIGNKEY"; break;
case SQLITE_CONSTRAINT_CHECK: zName = "SQLITE_CONSTRAINT_CHECK"; break;
case SQLITE_CONSTRAINT_PRIMARYKEY:
zName = "SQLITE_CONSTRAINT_PRIMARYKEY"; break;
case SQLITE_CONSTRAINT_NOTNULL: zName = "SQLITE_CONSTRAINT_NOTNULL";break;
case SQLITE_CONSTRAINT_COMMITHOOK:
zName = "SQLITE_CONSTRAINT_COMMITHOOK"; break;
case SQLITE_CONSTRAINT_VTAB: zName = "SQLITE_CONSTRAINT_VTAB"; break;
case SQLITE_CONSTRAINT_FUNCTION: zName = "SQLITE_CONSTRAINT_FUNCTION";break;
case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break;
case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break;
case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break;
case SQLITE_AUTH: zName = "SQLITE_AUTH"; break;
case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break;
case SQLITE_RANGE: zName = "SQLITE_RANGE"; break;
case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break;
case SQLITE_ROW: zName = "SQLITE_ROW"; break;
case SQLITE_NOTICE: zName = "SQLITE_NOTICE"; break;
case SQLITE_WARNING: zName = "SQLITE_WARNING"; break;
case SQLITE_DONE: zName = "SQLITE_DONE"; break;
case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break;
case SQLITE_IOERR_SHORT_READ: zName = "SQLITE_IOERR_SHORT_READ"; break;
case SQLITE_IOERR_WRITE: zName = "SQLITE_IOERR_WRITE"; break;
case SQLITE_IOERR_FSYNC: zName = "SQLITE_IOERR_FSYNC"; break;
case SQLITE_IOERR_DIR_FSYNC: zName = "SQLITE_IOERR_DIR_FSYNC"; break;
case SQLITE_IOERR_TRUNCATE: zName = "SQLITE_IOERR_TRUNCATE"; break;
case SQLITE_IOERR_FSTAT: zName = "SQLITE_IOERR_FSTAT"; break;
case SQLITE_IOERR_UNLOCK: zName = "SQLITE_IOERR_UNLOCK"; break;
case SQLITE_IOERR_RDLOCK: zName = "SQLITE_IOERR_RDLOCK"; break;
case SQLITE_IOERR_DELETE: zName = "SQLITE_IOERR_DELETE"; break;
case SQLITE_IOERR_BLOCKED: zName = "SQLITE_IOERR_BLOCKED"; break;
case SQLITE_IOERR_NOMEM: zName = "SQLITE_IOERR_NOMEM"; break;
case SQLITE_IOERR_ACCESS: zName = "SQLITE_IOERR_ACCESS"; break;
case SQLITE_IOERR_CHECKRESERVEDLOCK:
zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break;
case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break;
case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break;
case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break;
case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break;
case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break;
}
}
if( zName==0 ) zName = "SQLITE_Unknown";
return zName;
}
#define t1ErrorName sqlite3TestErrorName
+13 -41
View File
@@ -19,35 +19,7 @@
#include <string.h>
#include <ctype.h>
/*
** Interpret an SQLite error number
*/
static char *errorName(int rc){
char *zName;
switch( rc ){
case SQLITE_OK: zName = "SQLITE_OK"; break;
case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
case SQLITE_PERM: zName = "SQLITE_PERM"; break;
case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
case SQLITE_FULL: zName = "SQLITE_FULL"; break;
case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break;
case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break;
case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break;
case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break;
case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break;
default: zName = "SQLITE_Unknown"; break;
}
return zName;
}
extern const char *sqlite3TestErrorName(int rc);
/*
** Page size and reserved size used for testing.
@@ -87,7 +59,7 @@ static int pager_open(
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB,
pager_test_reiniter);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
sqlite3PagerSetCachesize(pPager, nPage);
@@ -119,7 +91,7 @@ static int pager_close(
pPager = sqlite3TestTextToPtr(argv[1]);
rc = sqlite3PagerClose(pPager);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
return TCL_OK;
@@ -146,7 +118,7 @@ static int pager_rollback(
pPager = sqlite3TestTextToPtr(argv[1]);
rc = sqlite3PagerRollback(pPager);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
return TCL_OK;
@@ -173,12 +145,12 @@ static int pager_commit(
pPager = sqlite3TestTextToPtr(argv[1]);
rc = sqlite3PagerCommitPhaseOne(pPager, 0, 0);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
rc = sqlite3PagerCommitPhaseTwo(pPager);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
return TCL_OK;
@@ -205,7 +177,7 @@ static int pager_stmt_begin(
pPager = sqlite3TestTextToPtr(argv[1]);
rc = sqlite3PagerOpenSavepoint(pPager, 1);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
return TCL_OK;
@@ -233,7 +205,7 @@ static int pager_stmt_rollback(
rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, 0);
sqlite3PagerSavepoint(pPager, SAVEPOINT_RELEASE, 0);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
return TCL_OK;
@@ -260,7 +232,7 @@ static int pager_stmt_commit(
pPager = sqlite3TestTextToPtr(argv[1]);
rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_RELEASE, 0);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
return TCL_OK;
@@ -353,7 +325,7 @@ static int page_get(
rc = sqlite3PagerGet(pPager, pgno, &pPage);
}
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage);
@@ -507,7 +479,7 @@ static int page_write(
pPage = (DbPage *)sqlite3TestTextToPtr(argv[1]);
rc = sqlite3PagerWrite(pPage);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
pData = sqlite3PagerGetData(pPage);
@@ -556,7 +528,7 @@ static int fake_big_file(
(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB), 0
);
if( rc ){
Tcl_AppendResult(interp, "open failed: ", errorName(rc), 0);
Tcl_AppendResult(interp, "open failed: ", sqlite3TestErrorName(rc), 0);
sqlite3_free(zFile);
return TCL_ERROR;
}
@@ -566,7 +538,7 @@ static int fake_big_file(
sqlite3OsCloseFree(fd);
sqlite3_free(zFile);
if( rc ){
Tcl_AppendResult(interp, "write failed: ", errorName(rc), 0);
Tcl_AppendResult(interp, "write failed: ", sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
return TCL_OK;
+8 -32
View File
@@ -19,31 +19,7 @@
#include <stdlib.h>
#include <string.h>
/*
** Interpret an SQLite error number
*/
static char *errorName(int rc){
char *zName;
switch( rc ){
case SQLITE_OK: zName = "SQLITE_OK"; break;
case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
case SQLITE_PERM: zName = "SQLITE_PERM"; break;
case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
case SQLITE_FULL: zName = "SQLITE_FULL"; break;
case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break;
default: zName = "SQLITE_Unknown"; break;
}
return zName;
}
extern const char *sqlite3TestErrorName(int rc);
/*
** A bogus sqlite3 connection structure for use in the btree
@@ -89,7 +65,7 @@ static int btree_open(
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB);
sqlite3_free(zFilename);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
sqlite3BtreeSetCacheSize(pBt, nCache);
@@ -119,7 +95,7 @@ static int btree_close(
pBt = sqlite3TestTextToPtr(argv[1]);
rc = sqlite3BtreeClose(pBt);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
nRefSqlite3--;
@@ -156,7 +132,7 @@ static int btree_begin_transaction(
rc = sqlite3BtreeBeginTrans(pBt, 1);
sqlite3BtreeLeave(pBt);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
return TCL_OK;
@@ -250,7 +226,7 @@ static int btree_cursor(
sqlite3BtreeLeave(pBt);
if( rc ){
ckfree((char *)pCur);
Tcl_AppendResult(interp, errorName(rc), 0);
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
sqlite3_snprintf(sizeof(zBuf), zBuf,"%p", pCur);
@@ -285,7 +261,7 @@ static int btree_close_cursor(
sqlite3BtreeLeave(pBt);
ckfree((char *)pCur);
if( rc ){
Tcl_AppendResult(interp, errorName(rc), 0);
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
return SQLITE_OK;
@@ -319,7 +295,7 @@ static int btree_next(
rc = sqlite3BtreeNext(pCur, &res);
sqlite3BtreeLeave(pCur->pBtree);
if( rc ){
Tcl_AppendResult(interp, errorName(rc), 0);
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res);
@@ -354,7 +330,7 @@ static int btree_first(
rc = sqlite3BtreeFirst(pCur, &res);
sqlite3BtreeLeave(pCur->pBtree);
if( rc ){
Tcl_AppendResult(interp, errorName(rc), 0);
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
return TCL_ERROR;
}
sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res);
+3 -28
View File
@@ -20,6 +20,8 @@
#include <sched.h>
#include <ctype.h>
extern const char *sqlite3TestErrorName(int rc);
/*
** Each thread is controlled by an instance of the following
** structure.
@@ -372,34 +374,7 @@ static int tcl_thread_result(
return TCL_ERROR;
}
thread_wait(&threadset[i]);
switch( threadset[i].rc ){
case SQLITE_OK: zName = "SQLITE_OK"; break;
case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
case SQLITE_PERM: zName = "SQLITE_PERM"; break;
case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break;
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
case SQLITE_FULL: zName = "SQLITE_FULL"; break;
case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break;
case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break;
case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break;
case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break;
case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break;
case SQLITE_AUTH: zName = "SQLITE_AUTH"; break;
case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break;
case SQLITE_RANGE: zName = "SQLITE_RANGE"; break;
case SQLITE_ROW: zName = "SQLITE_ROW"; break;
case SQLITE_DONE: zName = "SQLITE_DONE"; break;
default: zName = "SQLITE_Unknown"; break;
}
zName = sqlite3TestErrorName(threadset[i].rc);
Tcl_AppendResult(interp, zName, 0);
return TCL_OK;
}
+3 -28
View File
@@ -376,6 +376,8 @@ static int tcl_client_colname(
return TCL_OK;
}
extern const char *sqlite3TestErrorName(int rc);
/*
** Usage: client_result ID
**
@@ -403,34 +405,7 @@ static int tcl_client_result(
return TCL_ERROR;
}
client_wait(&threadset[i]);
switch( threadset[i].rc ){
case SQLITE_OK: zName = "SQLITE_OK"; break;
case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
case SQLITE_PERM: zName = "SQLITE_PERM"; break;
case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break;
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
case SQLITE_FULL: zName = "SQLITE_FULL"; break;
case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break;
case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break;
case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break;
case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break;
case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break;
case SQLITE_AUTH: zName = "SQLITE_AUTH"; break;
case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break;
case SQLITE_RANGE: zName = "SQLITE_RANGE"; break;
case SQLITE_ROW: zName = "SQLITE_ROW"; break;
case SQLITE_DONE: zName = "SQLITE_DONE"; break;
default: zName = "SQLITE_Unknown"; break;
}
zName = sqlite3TestErrorName(threadset[i].rc);
Tcl_AppendResult(interp, zName, 0);
return TCL_OK;
}
+6
View File
@@ -87,6 +87,12 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "lfs", "1", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_DISABLE_MMAP
Tcl_SetVar2(interp, "sqlite_options", "mmap", "0", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "mmap", "1", TCL_GLOBAL_ONLY);
#endif
#if 1 /* def SQLITE_MEMDEBUG */
Tcl_SetVar2(interp, "sqlite_options", "memdebug", "1", TCL_GLOBAL_ONLY);
#else
+1 -1
View File
@@ -99,7 +99,7 @@ static int fsConnect(
}
zTbl = argv[3];
nByte = sizeof(fs_vtab) + strlen(zTbl) + 1 + strlen(zDb) + 1;
nByte = sizeof(fs_vtab) + (int)strlen(zTbl) + 1 + (int)strlen(zDb) + 1;
pVtab = (fs_vtab *)sqlite3MallocZero( nByte );
if( !pVtab ) return SQLITE_NOMEM;
+2 -2
View File
@@ -188,7 +188,7 @@ int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
in.z = zIn;
in.i = 0;
in.mx = nIn>=0 ? nIn : strlen((char const*)zIn);
in.mx = nIn>=0 ? nIn : (int)strlen((char const*)zIn);
/* Look for the initial prefix match, if there is one. */
if( pRe->nInit ){
@@ -628,7 +628,7 @@ const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
}
pRe->sIn.z = (unsigned char*)zIn;
pRe->sIn.i = 0;
pRe->sIn.mx = strlen(zIn);
pRe->sIn.mx = (int)strlen(zIn);
zErr = re_subcompile_re(pRe);
if( zErr ){
re_free(pRe);
+14 -1
View File
@@ -108,7 +108,7 @@ static int ts_pwrite64(int fd, const void *aBuf, size_t nBuf, off_t off);
static int ts_fchmod(int fd, mode_t mode);
static int ts_fallocate(int fd, off_t off, off_t len);
static void *ts_mmap(void *, size_t, int, int, int, off_t);
static void *ts_mremap(void*, size_t, size_t, int, ...);
struct TestSyscallArray {
const char *zName;
@@ -134,6 +134,7 @@ struct TestSyscallArray {
/* 14 */ { "fchmod", (sqlite3_syscall_ptr)ts_fchmod, 0, 0, 0 },
/* 15 */ { "fallocate", (sqlite3_syscall_ptr)ts_fallocate, 0, 0, 0 },
/* 16 */ { "mmap", (sqlite3_syscall_ptr)ts_mmap, 0, 0, 0 },
/* 17 */ { "mremap", (sqlite3_syscall_ptr)ts_mremap, 0, 0, 0 },
{ 0, 0, 0, 0, 0 }
};
@@ -156,6 +157,7 @@ struct TestSyscallArray {
#define orig_fchmod ((int(*)(int,mode_t))aSyscall[14].xOrig)
#define orig_fallocate ((int(*)(int,off_t,off_t))aSyscall[15].xOrig)
#define orig_mmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[16].xOrig)
#define orig_mremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[17].xOrig)
/*
** This function is called exactly once from within each invocation of a
@@ -395,6 +397,17 @@ static void *ts_mmap(
return orig_mmap(pAddr, nByte, prot, flags, fd, iOff);
}
static void *ts_mremap(void *a, size_t b, size_t c, int d, ...){
va_list ap;
void *pArg;
if( tsIsFailErrno("mremap") ){
return MAP_FAILED;
}
va_start(ap, d);
pArg = va_arg(ap, void *);
return orig_mremap(a, b, c, d, pArg);
}
static int test_syscall_install(
void * clientData,
Tcl_Interp *interp,
+9 -3
View File
@@ -125,8 +125,9 @@ struct Testvfs {
#define TESTVFS_ACCESS_MASK 0x00004000
#define TESTVFS_FULLPATHNAME_MASK 0x00008000
#define TESTVFS_READ_MASK 0x00010000
#define TESTVFS_UNLOCK_MASK 0x00020000
#define TESTVFS_ALL_MASK 0x0001FFFF
#define TESTVFS_ALL_MASK 0x0003FFFF
#define TESTVFS_MAX_PAGES 1024
@@ -467,8 +468,12 @@ static int tvfsLock(sqlite3_file *pFile, int eLock){
** Unlock an tvfs-file.
*/
static int tvfsUnlock(sqlite3_file *pFile, int eLock){
TestvfsFd *p = tvfsGetFd(pFile);
return sqlite3OsUnlock(p->pReal, eLock);
TestvfsFd *pFd = tvfsGetFd(pFile);
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
if( p->mask&TESTVFS_WRITE_MASK && tvfsInjectIoerr(p) ){
return SQLITE_IOERR_UNLOCK;
}
return sqlite3OsUnlock(pFd->pReal, eLock);
}
/*
@@ -1101,6 +1106,7 @@ static int testvfs_obj_cmd(
{ "xClose", TESTVFS_CLOSE_MASK },
{ "xAccess", TESTVFS_ACCESS_MASK },
{ "xFullPathname", TESTVFS_FULLPATHNAME_MASK },
{ "xUnlock", TESTVFS_UNLOCK_MASK },
};
Tcl_Obj **apElem = 0;
int nElem = 0;
+1 -1
View File
@@ -520,7 +520,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
testcase( i==18 );
testcase( i==19 );
testcase( i==20 );
if( (c+nonNum!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr ){
if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr || nonNum ){
/* zNum is empty or contains non-numeric text or is longer
** than 19 digits (thus guaranteeing that it is too large) */
return 1;
+1 -1
View File
@@ -3515,7 +3515,7 @@ case OP_SeekGt: { /* jump, in3 */
** r.flags = 0;
** }
*/
r.flags = (u16)(UNPACKED_INCRKEY * (1 & (oc - OP_SeekLt)));
r.flags = (u8)(UNPACKED_INCRKEY * (1 & (oc - OP_SeekLt)));
assert( oc!=OP_SeekGt || r.flags==UNPACKED_INCRKEY );
assert( oc!=OP_SeekLe || r.flags==UNPACKED_INCRKEY );
assert( oc!=OP_SeekGe || r.flags==0 );
+8
View File
@@ -18,6 +18,14 @@
#ifndef _VDBEINT_H_
#define _VDBEINT_H_
/*
** The maximum number of times that a statement will try to reparse
** itself before giving up and returning SQLITE_SCHEMA.
*/
#ifndef SQLITE_MAX_SCHEMA_RETRY
# define SQLITE_MAX_SCHEMA_RETRY 50
#endif
/*
** SQL is translated into a sequence of instructions to be
** executed by a virtual machine. Each instruction is an instance
-8
View File
@@ -453,14 +453,6 @@ end_of_step:
return (rc&db->errMask);
}
/*
** The maximum number of times that a statement will try to reparse
** itself before giving up and returning SQLITE_SCHEMA.
*/
#ifndef SQLITE_MAX_SCHEMA_RETRY
# define SQLITE_MAX_SCHEMA_RETRY 5
#endif
/*
** This is the top-level implementation of sqlite3_step(). Call
** sqlite3Step() to do most of the work. If a schema error occurs,
+1 -1
View File
@@ -313,7 +313,7 @@ int sqlite3_blob_open(
}
sqlite3_bind_int64(pBlob->pStmt, 1, iRow);
rc = blobSeekToRow(pBlob, iRow, &zErr);
} while( (++nAttempt)<5 && rc==SQLITE_SCHEMA );
} while( (++nAttempt)<SQLITE_MAX_SCHEMA_RETRY && rc==SQLITE_SCHEMA );
blob_open_out:
if( rc==SQLITE_OK && db->mallocFailed==0 ){
+32 -8
View File
@@ -53,6 +53,11 @@ static int findNextHostParameter(const char *zSql, int *pnToken){
** then the returned string holds a copy of zRawSql with "-- " prepended
** to each line of text.
**
** If the SQLITE_TRACE_SIZE_LIMIT macro is defined to an integer, then
** then long strings and blobs are truncated to that many bytes. This
** can be used to prevent unreasonably large trace strings when dealing
** with large (multi-megabyte) strings and blobs.
**
** The calling function is responsible for making sure the memory returned
** is eventually freed.
**
@@ -123,30 +128,49 @@ char *sqlite3VdbeExpandSql(
}else if( pVar->flags & MEM_Real ){
sqlite3XPrintf(&out, "%!.15g", pVar->r);
}else if( pVar->flags & MEM_Str ){
int n; /* Number of bytes of the string text to include in output */
#ifndef SQLITE_OMIT_UTF16
u8 enc = ENC(db);
Mem utf8;
if( enc!=SQLITE_UTF8 ){
Mem utf8;
memset(&utf8, 0, sizeof(utf8));
utf8.db = db;
sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8);
sqlite3XPrintf(&out, "'%.*q'", utf8.n, utf8.z);
sqlite3VdbeMemRelease(&utf8);
}else
#endif
{
sqlite3XPrintf(&out, "'%.*q'", pVar->n, pVar->z);
pVar = &utf8;
}
#endif
n = pVar->n;
#ifdef SQLITE_TRACE_SIZE_LIMIT
if( n>SQLITE_TRACE_SIZE_LIMIT ){
n = SQLITE_TRACE_SIZE_LIMIT;
while( n<pVar->n && (pVar->z[n]&0xc0)==0x80 ){ n++; }
}
#endif
sqlite3XPrintf(&out, "'%.*q'", n, pVar->z);
#ifdef SQLITE_TRACE_SIZE_LIMIT
if( n<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-n);
#endif
#ifndef SQLITE_OMIT_UTF16
if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8);
#endif
}else if( pVar->flags & MEM_Zero ){
sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
}else{
int n; /* Number of bytes of the blob to include in output */
assert( pVar->flags & MEM_Blob );
sqlite3StrAccumAppend(&out, "x'", 2);
for(i=0; i<pVar->n; i++){
n = pVar->n;
#ifdef SQLITE_TRACE_SIZE_LIMIT
if( n>SQLITE_TRACE_SIZE_LIMIT ) n = SQLITE_TRACE_SIZE_LIMIT;
#endif
for(i=0; i<n; i++){
sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
}
sqlite3StrAccumAppend(&out, "'", 1);
#ifdef SQLITE_TRACE_SIZE_LIMIT
if( n<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-n);
#endif
}
}
}
+6 -2
View File
@@ -1207,8 +1207,9 @@ finished:
** checkpointing the log file.
*/
if( pWal->hdr.nPage ){
sqlite3_log(SQLITE_OK, "Recovered %d frames from WAL file %s",
pWal->hdr.nPage, pWal->zWalName
sqlite3_log(SQLITE_NOTICE_RECOVER_WAL,
"recovered %d frames from WAL file %s",
pWal->hdr.mxFrame, pWal->zWalName
);
}
}
@@ -2956,6 +2957,9 @@ int sqlite3WalCheckpoint(
/* Read the wal-index header. */
if( rc==SQLITE_OK ){
rc = walIndexReadHdr(pWal, &isChanged);
if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
}
}
/* Copy data from the log to the database file. */
+36 -8
View File
@@ -262,6 +262,8 @@ struct WhereCost {
#define WHERE_REVERSE 0x01000000 /* Scan in reverse order */
#define WHERE_UNIQUE 0x02000000 /* Selects no more than one row */
#define WHERE_ALL_UNIQUE 0x04000000 /* This and all prior have one row */
#define WHERE_OB_UNIQUE 0x00004000 /* Values in ORDER BY columns are
** different for every output row */
#define WHERE_VIRTUALTABLE 0x08000000 /* Use virtual-table processing */
#define WHERE_MULTI_OR 0x10000000 /* OR using multiple indices */
#define WHERE_TEMP_INDEX 0x20000000 /* Uses an ephemeral index */
@@ -2903,7 +2905,8 @@ static int isSortingIndex(
WhereBestIdx *p, /* Best index search context */
Index *pIdx, /* The index we are testing */
int base, /* Cursor number for the table to be sorted */
int *pbRev /* Set to 1 for reverse-order scan of pIdx */
int *pbRev, /* Set to 1 for reverse-order scan of pIdx */
int *pbObUnique /* ORDER BY column values will different in every row */
){
int i; /* Number of pIdx terms used */
int j; /* Number of ORDER BY terms satisfied */
@@ -2917,12 +2920,16 @@ static int isSortingIndex(
int nPriorSat; /* ORDER BY terms satisfied by outer loops */
int seenRowid = 0; /* True if an ORDER BY rowid term is seen */
int uniqueNotNull; /* pIdx is UNIQUE with all terms are NOT NULL */
int outerObUnique; /* Outer loops generate different values in
** every row for the ORDER BY columns */
if( p->i==0 ){
nPriorSat = 0;
outerObUnique = 1;
}else{
u32 wsFlags = p->aLevel[p->i-1].plan.wsFlags;
nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
if( (p->aLevel[p->i-1].plan.wsFlags & WHERE_ORDERED)==0 ){
if( (wsFlags & WHERE_ORDERED)==0 ){
/* This loop cannot be ordered unless the next outer loop is
** also ordered */
return nPriorSat;
@@ -2932,6 +2939,9 @@ static int isSortingIndex(
** optimization is disabled */
return nPriorSat;
}
testcase( wsFlags & WHERE_OB_UNIQUE );
testcase( wsFlags & WHERE_ALL_UNIQUE );
outerObUnique = (wsFlags & (WHERE_OB_UNIQUE|WHERE_ALL_UNIQUE))!=0;
}
pOrderBy = p->pOrderBy;
assert( pOrderBy!=0 );
@@ -3073,11 +3083,26 @@ static int isSortingIndex(
uniqueNotNull = 0;
}
}
if( seenRowid ){
uniqueNotNull = 1;
}else if( uniqueNotNull==0 || i<pIdx->nColumn ){
uniqueNotNull = 0;
}
/* If we have not found at least one ORDER BY term that matches the
** index, then show no progress. */
if( pOBItem==&pOrderBy->a[nPriorSat] ) return nPriorSat;
/* Either the outer queries must generate rows where there are no two
** rows with the same values in all ORDER BY columns, or else this
** loop must generate just a single row of output. Example: Suppose
** the outer loops generate A=1 and A=1, and this loop generates B=3
** and B=4. Then without the following test, ORDER BY A,B would
** generate the wrong order output: 1,3 1,4 1,3 1,4
*/
if( outerObUnique==0 && uniqueNotNull==0 ) return nPriorSat;
*pbObUnique = uniqueNotNull;
/* Return the necessary scan order back to the caller */
*pbRev = sortOrder & 1;
@@ -3085,7 +3110,7 @@ static int isSortingIndex(
** possible for a single row from this table to match, then skip over
** any additional ORDER BY terms dealing with this table.
*/
if( seenRowid || (uniqueNotNull && i>=pIdx->nColumn) ){
if( uniqueNotNull ){
/* Advance j over additional ORDER BY terms associated with base */
WhereMaskSet *pMS = p->pWC->pMaskSet;
Bitmask m = ~getMask(pMS, base);
@@ -3369,12 +3394,14 @@ static void bestBtreeIndex(WhereBestIdx *p){
** variable. */
if( bSort && (pSrc->jointype & JT_LEFT)==0 ){
int bRev = 2;
WHERETRACE((" --> before isSortingIndex: nPriorSat=%d\n",nPriorSat));
pc.plan.nOBSat = isSortingIndex(p, pProbe, iCur, &bRev);
WHERETRACE((" --> after isSortingIndex: bRev=%d nOBSat=%d\n",
bRev, pc.plan.nOBSat));
int bObUnique = 0;
WHERETRACE((" --> before isSortIndex: nPriorSat=%d\n",nPriorSat));
pc.plan.nOBSat = isSortingIndex(p, pProbe, iCur, &bRev, &bObUnique);
WHERETRACE((" --> after isSortIndex: bRev=%d bObU=%d nOBSat=%d\n",
bRev, bObUnique, pc.plan.nOBSat));
if( nPriorSat<pc.plan.nOBSat || (pc.plan.wsFlags & WHERE_ALL_UNIQUE)!=0 ){
pc.plan.wsFlags |= WHERE_ORDERED;
if( bObUnique ) pc.plan.wsFlags |= WHERE_OB_UNIQUE;
}
if( nOrderBy==pc.plan.nOBSat ){
bSort = 0;
@@ -3468,7 +3495,8 @@ static void bestBtreeIndex(WhereBestIdx *p){
** So this computation assumes table records are about twice as big
** as index records
*/
if( (pc.plan.wsFlags&~(WHERE_REVERSE|WHERE_ORDERED))==WHERE_IDX_ONLY
if( (pc.plan.wsFlags&~(WHERE_REVERSE|WHERE_ORDERED|WHERE_OB_UNIQUE))
==WHERE_IDX_ONLY
&& (pWC->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
&& sqlite3GlobalConfig.bUseCis
&& OptimizationEnabled(pParse->db, SQLITE_CoverIdxScan)
+50
View File
@@ -0,0 +1,50 @@
# 2013 April 02
#
# 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 fault injection tests designed to test the btree.c
# module.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
set testprefix btreefault
do_test 1-pre1 {
execsql {
PRAGMA auto_vacuum = incremental;
PRAGMA journal_mode = DELETE;
CREATE TABLE t1(a PRIMARY KEY, b);
INSERT INTO t1 VALUES(randomblob(1000), randomblob(100));
INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
DELETE FROM t1 WHERE rowid%2;
}
faultsim_save_and_close
} {}
do_faultsim_test 1 -prep {
faultsim_restore_and_reopen
set ::STMT [sqlite3_prepare db "SELECT * FROM t1 ORDER BY a" -1 DUMMY]
sqlite3_step $::STMT
sqlite3_step $::STMT
} -body {
execsql { PRAGMA incremental_vacuum = 10 }
} -test {
sqlite3_finalize $::STMT
faultsim_test_result {0 {}}
faultsim_integrity_check
}
finish_test
+203 -18
View File
@@ -12,6 +12,10 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !mmap {
finish_test
return
}
source $testdir/lock_common.tcl
set testprefix mmap1
@@ -20,32 +24,39 @@ proc nRead {db} {
db_enter $db
array set stats [btree_pager_stats $bt]
db_leave $db
# puts [array get stats]
return $stats(read)
}
proc register_rblob_code {dbname seed} {
return [subst -nocommands {
set ::rcnt $seed
proc rblob {n} {
set ::rcnt [expr (([set ::rcnt] << 3) + [set ::rcnt] + 456) & 0xFFFFFFFF]
set str [format %.8x [expr [set ::rcnt] ^ 0xbdf20da3]]
string range [string repeat [set str] [expr [set n]/4]] 1 [set n]
}
$dbname func rblob rblob
}]
}
foreach {t mmap_limit nRead c2init} {
1.1 { PRAGMA mmap_limit = 70000000 } 4 {}
1.2 { PRAGMA mmap_limit = 51200 } 156 {}
1.3 { PRAGMA mmap_limit = 0 } 344 {}
1.4 { PRAGMA mmap_limit = 70000000 } 4 {PRAGMA mmap_limit = 70000000 }
1.5 { PRAGMA mmap_limit = 51200 } 156 {PRAGMA mmap_limit = 70000000 }
1.6 { PRAGMA mmap_limit = 0 } 344 {PRAGMA mmap_limit = 70000000 }
1.1 { PRAGMA mmap_limit = 67108864 } 4 {PRAGMA mmap_limit = 0}
1.2 { PRAGMA mmap_limit = 53248 } 150 {PRAGMA mmap_limit = 0}
1.3 { PRAGMA mmap_limit = 0 } 344 {PRAGMA mmap_limit = 0}
1.4 { PRAGMA mmap_limit = 67108864 } 4 {PRAGMA mmap_limit = 67108864 }
1.5 { PRAGMA mmap_limit = 53248 } 150 {PRAGMA mmap_limit = 67108864 }
1.6 { PRAGMA mmap_limit = 0 } 344 {PRAGMA mmap_limit = 67108864 }
} {
do_multiclient_test tn {
sql1 {PRAGMA page_size=1024}
sql1 $mmap_limit
sql2 $c2init
code2 {
set ::rcnt 0
proc rblob {n} {
set ::rcnt [expr (($::rcnt << 3) + $::rcnt + 456) & 0xFFFFFFFF]
set str [format %.8x [expr $::rcnt ^ 0xbdf20da3]]
string range [string repeat $str [expr $n/4]] 1 $n
}
db2 func rblob rblob
}
code2 [register_rblob_code db2 0]
sql2 {
sql2 {
PRAGMA page_size=1024;
PRAGMA auto_vacuum = 1;
CREATE TABLE t1(a, b, UNIQUE(a, b));
INSERT INTO t1 VALUES(rblob(500), rblob(500));
@@ -95,7 +106,7 @@ db func rblob rblob
do_execsql_test 2.1 {
PRAGMA auto_vacuum = 1;
PRAGMA mmap_limit = 70000000;
PRAGMA mmap_limit = 67108864;
PRAGMA journal_mode = wal;
CREATE TABLE t1(a, b, UNIQUE(a, b));
INSERT INTO t1 VALUES(rblob(500), rblob(500));
@@ -105,7 +116,7 @@ do_execsql_test 2.1 {
INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 16
INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 32
PRAGMA wal_checkpoint;
} {wal 0 103 103}
} {67108864 wal 0 103 103}
do_execsql_test 2.2 {
PRAGMA auto_vacuum;
@@ -129,4 +140,178 @@ do_execsql_test 2.4 {
PRAGMA wal_checkpoint;
} {0 24 24}
db2 close
reset_db
db func rblob rblob
do_execsql_test 3.1 {
PRAGMA auto_vacuum = 1;
CREATE TABLE t1(a, b, UNIQUE(a, b));
INSERT INTO t1 VALUES(rblob(500), rblob(500));
INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 2
INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 4
INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 8
CREATE TABLE t2(a, b, UNIQUE(a, b));
INSERT INTO t2 SELECT * FROM t1;
} {}
do_test 3.2 {
set nRow 0
db eval {SELECT * FROM t2 ORDER BY a, b} {
if {$nRow==4} { db eval { DELETE FROM t1 } }
incr nRow
}
set nRow
} {8}
#-------------------------------------------------------------------------
# Ensure that existing cursors using xFetch() pages see changes made
# to rows using the incrblob API.
#
reset_db
set aaa [string repeat a 400]
set bbb [string repeat b 400]
set ccc [string repeat c 400]
set ddd [string repeat d 400]
set eee [string repeat e 400]
do_execsql_test 4.1 {
PRAGMA page_size = 1024;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES($aaa);
INSERT INTO t1 VALUES($bbb);
INSERT INTO t1 VALUES($ccc);
INSERT INTO t1 VALUES($ddd);
SELECT * FROM t1;
BEGIN;
} [list $aaa $bbb $ccc $ddd]
do_test 4.2 {
set ::STMT [sqlite3_prepare db "SELECT * FROM t1 ORDER BY rowid" -1 dummy]
sqlite3_step $::STMT
sqlite3_column_text $::STMT 0
} $aaa
do_test 4.3 {
foreach r {2 3 4} {
set fd [db incrblob t1 x $r]
puts -nonewline $fd $eee
close $fd
}
set res [list]
while {"SQLITE_ROW" == [sqlite3_step $::STMT]} {
lappend res [sqlite3_column_text $::STMT 0]
}
set res
} [list $eee $eee $eee]
do_test 4.4 {
sqlite3_finalize $::STMT
} SQLITE_OK
do_execsql_test 4.5 { COMMIT }
#-------------------------------------------------------------------------
# Ensure that existing cursors holding xFetch() references are not
# confused if those pages are moved to make way for the root page of a
# new table or index.
#
reset_db
do_execsql_test 5.1 {
PRAGMA auto_vacuum = 2;
PRAGMA page_size = 1024;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES($aaa);
INSERT INTO t1 VALUES($bbb);
INSERT INTO t1 VALUES($ccc);
INSERT INTO t1 VALUES($ddd);
PRAGMA auto_vacuum;
SELECT * FROM t1;
} [list 2 $aaa $bbb $ccc $ddd]
do_test 5.2 {
set ::STMT [sqlite3_prepare db "SELECT * FROM t1 ORDER BY rowid" -1 dummy]
sqlite3_step $::STMT
sqlite3_column_text $::STMT 0
} $aaa
do_execsql_test 5.3 {
CREATE TABLE t2(x);
INSERT INTO t2 VALUES('tricked you!');
INSERT INTO t2 VALUES('tricked you!');
}
do_test 5.4 {
sqlite3_step $::STMT
sqlite3_column_text $::STMT 0
} $bbb
do_test 5.5 {
sqlite3_finalize $::STMT
} SQLITE_OK
#-------------------------------------------------------------------------
# Test various mmap_limit settings.
#
foreach {tn1 mmap1 mmap2} {
1 6144 167773
2 18432 140399
3 43008 401302
4 92160 253899
5 190464 2
6 387072 752431
7 780288 291143
8 1566720 594306
9 3139584 829137
10 6285312 793963
11 12576768 1015590
} {
do_multiclient_test tn {
sql1 {
CREATE TABLE t1(a PRIMARY KEY);
CREATE TABLE t2(x);
INSERT INTO t2 VALUES('');
}
code1 [register_rblob_code db 0]
code2 [register_rblob_code db2 444]
sql1 "PRAGMA mmap_limit = $mmap1"
sql2 "PRAGMA mmap_limit = $mmap2"
do_test $tn1.$tn {
for {set i 1} {$i <= 100} {incr i} {
if {$i % 2} {
set c1 sql1
set c2 sql2
} else {
set c1 sql2
set c2 sql1
}
$c1 {
INSERT INTO t1 VALUES( rblob(5000) );
UPDATE t2 SET x = (SELECT md5sum(a) FROM t1);
}
set res [$c2 {
SELECT count(*) FROM t1;
SELECT x == (SELECT md5sum(a) FROM t1) FROM t2;
PRAGMA integrity_check;
}]
if {$res != [list $i 1 ok]} {
do_test $tn1.$tn.$i {
set ::res
} [list $i 1 ok]
}
}
set res 1
} {1}
}
}
finish_test
+86
View File
@@ -0,0 +1,86 @@
# 2013 March 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 tests the effect of the mmap() or mremap() system calls
# returning an error on the library.
#
# If either mmap() or mremap() fails, SQLite should log an error
# message, then continue accessing the database using read() and
# write() exclusively.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix mmap2
if {$::tcl_platform(platform)!="unix" || [test_syscall defaultvfs] != "unix"} {
finish_test
return
}
ifcapable !mmap {
finish_test
return
}
db close
sqlite3_shutdown
test_sqlite3_log xLog
proc xLog {error_code msg} {
if {[string match os_unix.c* $msg]} {
lappend ::log $msg
}
}
foreach syscall {mmap mremap} {
test_syscall uninstall
if {[catch {test_syscall install $syscall}]} continue
for {set i 1} {$i < 20} {incr i} {
reset_db
test_syscall fault $i 1
test_syscall errno $syscall ENOMEM
set ::log ""
do_execsql_test 1.$syscall.$i.1 {
CREATE TABLE t1(a, b, UNIQUE(a, b));
INSERT INTO t1 VALUES(randomblob(1000), randomblob(1000));
INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
}
set nFail [test_syscall fault 0 0]
do_execsql_test 1.$syscall.$i.2 {
SELECT count(*) FROM t1;
PRAGMA integrity_check;
} {64 ok}
do_test 1.$syscall.$i.3 {
expr {$nFail==0 || $nFail==1}
} {1}
do_test 1.$syscall.$i.4.nFail=$nFail {
regexp ".*${syscall}.*" $::log
} [expr $nFail>0]
}
}
db close
test_syscall uninstall
sqlite3_shutdown
test_sqlite3_log
sqlite3_initialize
finish_test
+56
View File
@@ -0,0 +1,56 @@
# 2013 March 26
#
# 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 file is testing that the optimizations that disable
# ORDER BY clauses work correctly on multi-value primary keys and
# unique indices when only some prefix of the terms in the key are
# used. See ticket http://www.sqlite.org/src/info/a179fe74659
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix orderby4
# Generate test data for a join. Verify that the join gets the
# correct answer.
#
do_execsql_test 1.1 {
CREATE TABLE t1(a, b, PRIMARY KEY(a,b));
INSERT INTO t1 VALUES(1,1),(1,2);
CREATE TABLE t2(x, y, PRIMARY KEY(x,y));
INSERT INTO t2 VALUES(3,3),(4,4);
SELECT a, x FROM t1, t2 ORDER BY 1, 2;
} {1 3 1 3 1 4 1 4}
do_execsql_test 1.2 {
SELECT a, x FROM t1 CROSS JOIN t2 ORDER BY 1, 2;
} {1 3 1 3 1 4 1 4}
do_execsql_test 1.3 {
SELECT a, x FROM t2 CROSS JOIN t1 ORDER BY 1, 2;
} {1 3 1 3 1 4 1 4}
do_execsql_test 2.1 {
CREATE TABLE t3(a);
INSERT INTO t3 VALUES(1),(1);
CREATE INDEX t3a ON t3(a);
CREATE TABLE t4(x);
INSERT INTO t4 VALUES(3),(4);
CREATE INDEX t4x ON t4(x);
SELECT a, x FROM t3, t4 ORDER BY 1, 2;
} {1 3 1 3 1 4 1 4}
do_execsql_test 2.2 {
SELECT a, x FROM t3 CROSS JOIN t4 ORDER BY 1, 2;
} {1 3 1 3 1 4 1 4}
do_execsql_test 2.3 {
SELECT a, x FROM t4 CROSS JOIN t3 ORDER BY 1, 2;
} {1 3 1 3 1 4 1 4}
finish_test
+294 -2
View File
@@ -15,6 +15,7 @@ source $testdir/tester.tcl
source $testdir/lock_common.tcl
source $testdir/malloc_common.tcl
source $testdir/wal_common.tcl
set testprefix pager1
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
@@ -1382,6 +1383,7 @@ db2 close
#
testvfs tv -default 1
foreach sectorsize {
16
32 64 128 256 512 1024 2048
4096 8192 16384 32768 65536 131072 262144
} {
@@ -1404,7 +1406,7 @@ foreach sectorsize {
COMMIT;
}
file size test.db-journal
} [expr $sectorsize > 65536 ? 65536 : $sectorsize]
} [expr $sectorsize > 65536 ? 65536 : ($sectorsize<32 ? 512 : $sectorsize)]
do_test pager1-10.$sectorsize.2 {
execsql {
@@ -2243,7 +2245,6 @@ do_test pager1-25-1 {
}
db close
} {}
breakpoint
do_test pager1-25-2 {
faultsim_delete_and_reopen
execsql {
@@ -2523,4 +2524,295 @@ if {$::tcl_platform(platform)=="unix"} {
} {one two}
}
#-------------------------------------------------------------------------
# Test that appending pages to the database file then moving those pages
# to the free-list before the transaction is committed does not cause
# an error.
#
foreach {tn pragma strsize} {
1 { PRAGMA mmap_limit = 0 } 2400
2 { } 2400
3 { PRAGMA mmap_limit = 0 } 4400
4 { } 4400
} {
reset_db
db func a_string a_string
db eval $pragma
do_execsql_test 34.$tn.1 {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 2);
}
do_execsql_test 34.$tn.2 {
BEGIN;
INSERT INTO t1 VALUES(2, a_string($strsize));
DELETE FROM t1 WHERE oid=2;
COMMIT;
PRAGMA integrity_check;
} {ok}
}
#-------------------------------------------------------------------------
#
reset_db
do_test 35 {
sqlite3 db test.db
execsql {
CREATE TABLE t1(x, y);
PRAGMA journal_mode = WAL;
INSERT INTO t1 VALUES(1, 2);
}
execsql {
BEGIN;
CREATE TABLE t2(a, b);
}
hexio_write test.db-shm [expr 16*1024] [string repeat 0055 8192]
catchsql ROLLBACK
} {0 {}}
do_multiclient_test tn {
sql1 {
PRAGMA auto_vacuum = 0;
CREATE TABLE t1(x, y);
INSERT INTO t1 VALUES(1, 2);
}
do_test 36.$tn.1 {
sql2 { PRAGMA max_page_count = 2 }
list [catch { sql2 { CREATE TABLE t2(x) } } msg] $msg
} {1 {database or disk is full}}
sql1 { PRAGMA checkpoint_fullfsync = 1 }
sql1 { CREATE TABLE t2(x) }
do_test 36.$tn.2 {
sql2 { INSERT INTO t2 VALUES('xyz') }
list [catch { sql2 { CREATE TABLE t3(x) } } msg] $msg
} {1 {database or disk is full}}
}
forcedelete test1 test2
foreach {tn uri} {
1 {file:?mode=memory&cache=shared}
2 {file:one?mode=memory&cache=shared}
3 {file:test1?cache=shared}
4 {file:test2?another=parameter&yet=anotherone}
} {
do_test 37.$tn {
catch { db close }
sqlite3_shutdown
sqlite3_config_uri 1
sqlite3 db $uri
db eval {
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(1);
SELECT * FROM t1;
}
} {1}
do_execsql_test 37.$tn.2 {
VACUUM;
SELECT * FROM t1;
} {1}
db close
sqlite3_shutdown
sqlite3_config_uri 0
}
do_test 38.1 {
catch { db close }
forcedelete test.db
set fd [open test.db w]
puts $fd "hello world"
close $fd
sqlite3 db test.db
catchsql { CREATE TABLE t1(x) }
} {1 {file is encrypted or is not a database}}
do_test 38.2 {
catch { db close }
forcedelete test.db
} {}
do_test 39.1 {
sqlite3 db test.db
execsql {
PRAGMA auto_vacuum = 1;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES('xxx');
INSERT INTO t1 VALUES('two');
INSERT INTO t1 VALUES(randomblob(400));
INSERT INTO t1 VALUES(randomblob(400));
INSERT INTO t1 VALUES(randomblob(400));
INSERT INTO t1 VALUES(randomblob(400));
BEGIN;
UPDATE t1 SET x = 'one' WHERE rowid=1;
}
set ::stmt [sqlite3_prepare db "SELECT * FROM t1 ORDER BY rowid" -1 dummy]
sqlite3_step $::stmt
sqlite3_column_text $::stmt 0
} {one}
do_test 39.2 {
execsql { CREATE TABLE t2(x) }
sqlite3_step $::stmt
sqlite3_column_text $::stmt 0
} {two}
do_test 39.3 {
sqlite3_finalize $::stmt
execsql COMMIT
} {}
do_execsql_test 39.4 {
PRAGMA auto_vacuum = 2;
CREATE TABLE t3(x);
CREATE TABLE t4(x);
DROP TABLE t2;
DROP TABLE t3;
DROP TABLE t4;
}
do_test 39.5 {
db close
sqlite3 db test.db
execsql {
PRAGMA cache_size = 1;
PRAGMA incremental_vacuum;
PRAGMA integrity_check;
}
} {ok}
do_test 40.1 {
reset_db
execsql {
PRAGMA auto_vacuum = 1;
CREATE TABLE t1(x PRIMARY KEY);
INSERT INTO t1 VALUES(randomblob(1200));
PRAGMA page_count;
}
} {6}
do_test 40.2 {
execsql {
INSERT INTO t1 VALUES(randomblob(1200));
INSERT INTO t1 VALUES(randomblob(1200));
INSERT INTO t1 VALUES(randomblob(1200));
}
} {}
do_test 40.3 {
db close
sqlite3 db test.db
execsql {
PRAGMA cache_size = 1;
CREATE TABLE t2(x);
PRAGMA integrity_check;
}
} {ok}
do_test 41.1 {
reset_db
execsql {
CREATE TABLE t1(x PRIMARY KEY);
INSERT INTO t1 VALUES(randomblob(200));
INSERT INTO t1 SELECT randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200) FROM t1;
}
} {}
do_test 41.2 {
testvfs tv -default 1
tv sectorsize 16384;
tv devchar [list]
db close
sqlite3 db test.db
execsql {
PRAGMA cache_size = 1;
DELETE FROM t1 WHERE rowid%4;
PRAGMA integrity_check;
}
} {ok}
db close
tv delete
set pending_prev [sqlite3_test_control_pending_byte 0x1000000]
do_test 42.1 {
reset_db
execsql {
CREATE TABLE t1(x, y);
INSERT INTO t1 VALUES(randomblob(200), randomblob(200));
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
}
db close
sqlite3_test_control_pending_byte 0x0010000
sqlite3 db test.db
db eval { PRAGMA mmap_limit = 0 }
catchsql { SELECT sum(length(y)) FROM t1 }
} {1 {database disk image is malformed}}
do_test 42.2 {
reset_db
execsql {
CREATE TABLE t1(x, y);
INSERT INTO t1 VALUES(randomblob(200), randomblob(200));
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
}
db close
testvfs tv -default 1
tv sectorsize 16384;
tv devchar [list]
sqlite3 db test.db -vfs tv
execsql { UPDATE t1 SET x = randomblob(200) }
} {}
db close
tv delete
sqlite3_test_control_pending_byte $pending_prev
do_test 43.1 {
reset_db
execsql {
CREATE TABLE t1(x, y);
INSERT INTO t1 VALUES(1, 2);
CREATE TABLE t2(x, y);
INSERT INTO t2 VALUES(1, 2);
CREATE TABLE t3(x, y);
INSERT INTO t3 VALUES(1, 2);
}
db close
sqlite3 db test.db
db eval { PRAGMA mmap_limit = 0 }
db eval { SELECT * FROM t1 }
sqlite3_db_status db CACHE_MISS 0
} {0 2 0}
do_test 43.2 {
db eval { SELECT * FROM t2 }
sqlite3_db_status db CACHE_MISS 1
} {0 3 0}
do_test 43.3 {
db eval { SELECT * FROM t3 }
sqlite3_db_status db CACHE_MISS 0
} {0 1 0}
finish_test
+18 -1
View File
@@ -118,7 +118,6 @@ tv delete
#-------------------------------------------------------------------------
#
# pager2-2.1: Test a ROLLBACK with journal_mode=off.
# pager2-2.2: Test shrinking the database (auto-vacuum) with
# journal_mode=off
@@ -148,4 +147,22 @@ do_test pager2-2.2 {
file size test.db
} {3072}
#-------------------------------------------------------------------------
# Test that shared in-memory databases seem to work.
#
db close
do_test pager2-3.1 {
forcedelete test.db
sqlite3_shutdown
sqlite3_config_uri 1
sqlite3 db1 {file:test.db?mode=memory&cache=shared}
sqlite3 db2 {file:test.db?mode=memory&cache=shared}
sqlite3 db3 test.db
db1 eval { CREATE TABLE t1(a, b) }
db2 eval { INSERT INTO t1 VALUES(1, 2) }
list [catch { db3 eval { INSERT INTO t1 VALUES(3, 4) } } msg] $msg
} {1 {no such table: t1}}
finish_test
+299
View File
@@ -1246,5 +1246,304 @@ do_faultsim_test pagerfault-27 -faults ioerr-persistent -prep {
faultsim_integrity_check
}
#-------------------------------------------------------------------------
#
do_test pagerfault-28-pre {
faultsim_delete_and_reopen
db func a_string a_string
execsql {
PRAGMA page_size = 512;
PRAGMA journal_mode = wal;
PRAGMA wal_autocheckpoint = 0;
PRAGMA cache_size = 100000;
BEGIN;
CREATE TABLE t2(a UNIQUE, b UNIQUE);
INSERT INTO t2 VALUES( a_string(800), a_string(800) );
INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
COMMIT;
CREATE TABLE t1(a PRIMARY KEY, b);
}
expr {[file size test.db-shm] >= 96*1024}
} {1}
faultsim_save_and_close
do_faultsim_test pagerfault-28a -faults oom* -prep {
faultsim_restore_and_reopen
execsql { PRAGMA mmap_limit=0 }
sqlite3 db2 test.db
db2 eval { SELECT count(*) FROM t2 }
db func a_string a_string
execsql {
BEGIN;
INSERT INTO t1 VALUES(a_string(2000), a_string(2000));
INSERT INTO t1 VALUES(a_string(2000), a_string(2000));
}
set ::STMT [sqlite3_prepare db "SELECT * FROM t1 ORDER BY a" -1 DUMMY]
sqlite3_step $::STMT
} -body {
execsql { ROLLBACK }
} -test {
db2 close
sqlite3_finalize $::STMT
catchsql { ROLLBACK }
faultsim_integrity_check
}
faultsim_restore_and_reopen
sqlite3 db2 test.db
db2 eval {SELECT count(*) FROM t2}
db close
do_faultsim_test pagerfault-28b -faults oom* -prep {
sqlite3 db test.db
} -body {
execsql { SELECT count(*) FROM t2 }
} -test {
faultsim_test_result {0 2048}
db close
}
db2 close
#-------------------------------------------------------------------------
# Try this:
#
# 1) Put the pager in ERROR state (error during rollback)
#
# 2) Next time the connection is used inject errors into all xWrite() and
# xUnlock() calls. This causes the hot-journal rollback to fail and
# the pager to declare its locking state UNKNOWN.
#
# 3) Same again.
#
# 4a) Stop injecting errors. Allow the rollback to succeed. Check that
# the database is Ok. Or,
#
# 4b) Close and reopen the db. Check that the db is Ok.
#
proc custom_injectinstall {} {
testvfs custom -default true
custom filter {xWrite xUnlock}
}
proc custom_injectuninstall {} {
catch {db close}
catch {db2 close}
custom delete
}
proc custom_injectstart {iFail} {
custom ioerr $iFail 1
}
proc custom_injectstop {} {
custom ioerr
}
set ::FAULTSIM(custom) [list \
-injectinstall custom_injectinstall \
-injectstart custom_injectstart \
-injectstop custom_injectstop \
-injecterrlist {{1 {disk I/O error}}} \
-injectuninstall custom_injectuninstall \
]
do_test pagerfault-29-pre {
faultsim_delete_and_reopen
db func a_string a_string
execsql {
PRAGMA page_size = 1024;
PRAGMA cache_size = 5;
BEGIN;
CREATE TABLE t2(a UNIQUE, b UNIQUE);
INSERT INTO t2 VALUES( a_string(800), a_string(800) );
INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
COMMIT;
}
expr {[file size test.db] >= 50*1024}
} {1}
faultsim_save_and_close
foreach {tn tt} {
29 { catchsql ROLLBACK }
30 { db close ; sqlite3 db test.db }
} {
do_faultsim_test pagerfault-$tn -faults custom -prep {
faultsim_restore_and_reopen
db func a_string a_string
execsql {
PRAGMA cache_size = 5;
BEGIN;
UPDATE t2 SET a = a_string(799);
}
} -body {
catchsql ROLLBACK
catchsql ROLLBACK
catchsql ROLLBACK
} -test {
eval $::tt
if {"ok" != [db one {PRAGMA integrity_check}]} {
error "integrity check failed"
}
}
}
do_test pagerfault-31-pre {
sqlite3_shutdown
sqlite3_config_uri 1
} {SQLITE_OK}
do_faultsim_test pagerfault-31 -faults oom* -body {
sqlite3 db {file:one?mode=memory&cache=shared}
db eval {
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(1);
SELECT * FROM t1;
}
} -test {
faultsim_test_result {0 1} {1 {}}
catch { db close }
}
sqlite3_shutdown
sqlite3_config_uri 0
do_test pagerfault-32-pre {
reset_db
execsql {
CREATE TABLE t1(x);
INSERT INTO t1 VALUES('one');
}
} {}
faultsim_save_and_close
do_faultsim_test pagerfault-32 -prep {
faultsim_restore_and_reopen
db eval { SELECT * FROM t1; }
} -body {
execsql { SELECT * FROM t1; }
} -test {
faultsim_test_result {0 one}
}
sqlite3_shutdown
sqlite3_config_uri 0
do_faultsim_test pagerfault-33a -prep {
sqlite3 db :memory:
execsql {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 2);
}
} -body {
execsql { VACUUM }
} -test {
faultsim_test_result {0 {}}
}
do_faultsim_test pagerfault-33b -prep {
sqlite3 db ""
execsql {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 2);
}
} -body {
execsql { VACUUM }
} -test {
faultsim_test_result {0 {}}
}
do_test pagerfault-34-pre {
reset_db
execsql {
CREATE TABLE t1(x PRIMARY KEY);
}
} {}
faultsim_save_and_close
do_faultsim_test pagerfault-34 -prep {
faultsim_restore_and_reopen
execsql {
BEGIN;
INSERT INTO t1 VALUES( randomblob(4000) );
DELETE FROM t1;
}
} -body {
execsql COMMIT
} -test {
faultsim_test_result {0 {}}
}
do_test pagerfault-35-pre {
faultsim_delete_and_reopen
execsql {
CREATE TABLE t1(x PRIMARY KEY, y);
INSERT INTO t1 VALUES(randomblob(200), randomblob(200));
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
}
faultsim_save_and_close
} {}
testvfs tv -default 1
tv sectorsize 8192;
tv devchar [list]
do_faultsim_test pagerfault-35 -prep {
faultsim_restore_and_reopen
} -body {
execsql { UPDATE t1 SET x=randomblob(200) }
} -test {
faultsim_test_result {0 {}}
}
catch {db close}
tv delete
sqlite3_shutdown
sqlite3_config_uri 1
do_test pagerfault-36-pre {
faultsim_delete_and_reopen
execsql {
CREATE TABLE t1(x PRIMARY KEY, y);
INSERT INTO t1 VALUES(randomblob(200), randomblob(200));
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
}
faultsim_save_and_close
} {}
do_faultsim_test pagerfault-36 -prep {
faultsim_restore
sqlite3 db file:test.db?cache=shared
sqlite3 db2 file:test.db?cache=shared
db2 eval {
BEGIN;
SELECT count(*) FROM sqlite_master;
}
db eval {
PRAGMA cache_size = 1;
BEGIN;
UPDATE t1 SET x = randomblob(200);
}
} -body {
execsql ROLLBACK db
} -test {
catch { db eval {UPDATE t1 SET x = randomblob(200)} }
faultsim_test_result {0 {}}
catch { db close }
catch { db2 close }
}
sqlite3_shutdown
sqlite3_config_uri 0
finish_test
+6 -1
View File
@@ -87,12 +87,17 @@ do_test pageropt-1.4 {
# But if the other thread modifies the database, then the cache
# must refill.
#
ifcapable mmap {
set x [expr {[permutation]=="nommap" ? 6 : 1}]
} else {
set x 6
}
do_test pageropt-1.5 {
db2 eval {CREATE TABLE t2(y)}
pagercount_sql {
SELECT hex(x) FROM t1
}
} [list [expr {[permutation]=="nommap" ? 6 : 1}] 0 0 $blobcontent]
} [list $x 0 0 $blobcontent]
do_test pageropt-1.6 {
pagercount_sql {
SELECT hex(x) FROM t1
+2 -1
View File
@@ -24,6 +24,8 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
speed_trial_init speed1
sqlite3_memdebug_vfs_oom_test 0
# Set a uniform random seed
expr srand(0)
@@ -78,7 +80,6 @@ do_test speed1p-1.0 {
}
} {i2a i2b t1 t2}
# 50000 INSERTs on an unindexed table
#
set list {}
+61
View File
@@ -0,0 +1,61 @@
# 2013 March 27
#
# 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. Specifically,
# it tests that ticket [6bfb98dfc0]
#
# The final INSERT in the script below reports that the database is
# corrupt (SQLITE_CORRUPT) and aborts even though the database is not
# corrupt.
#
# PRAGMA page_size=512;
# CREATE TABLE t1(x INTEGER PRIMARY KEY, y);
# INSERT INTO t1 VALUES(1,randomblob(400));
# INSERT INTO t1 VALUES(2,randomblob(400));
# INSERT INTO t1 SELECT x+2, randomblob(400) FROM t1;
# INSERT INTO t1 SELECT x+4, randomblob(400) FROM t1;
# INSERT INTO t1 SELECT x+8, randomblob(400) FROM t1;
# INSERT INTO t1 SELECT x+16, randomblob(400) FROM t1;
# INSERT INTO t1 SELECT x+32, randomblob(400) FROM t1;
# INSERT INTO t1 SELECT x+64, randomblob(400) FROM t1 WHERE x<10;
# CREATE TRIGGER r1 AFTER INSERT ON t1 WHEN new.x=74 BEGIN
# DELETE FROM t1;
# INSERT INTO t1 VALUES(75, randomblob(400));
# INSERT INTO t1 VALUES(76, randomblob(400));
# END;
# INSERT INTO t1 VALUES(74, randomblob(400));
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_test tkt-6bfb98dfc0.100 {
db eval {
PRAGMA page_size=512;
CREATE TABLE t1(x INTEGER PRIMARY KEY, y);
INSERT INTO t1 VALUES(1,randomblob(400));
INSERT INTO t1 VALUES(2,randomblob(400));
INSERT INTO t1 SELECT x+2, randomblob(400) FROM t1;
INSERT INTO t1 SELECT x+4, randomblob(400) FROM t1;
INSERT INTO t1 SELECT x+8, randomblob(400) FROM t1;
INSERT INTO t1 SELECT x+16, randomblob(400) FROM t1;
INSERT INTO t1 SELECT x+32, randomblob(400) FROM t1;
INSERT INTO t1 SELECT x+64, randomblob(400) FROM t1 WHERE x<10;
CREATE TRIGGER r1 AFTER INSERT ON t1 WHEN new.x=74 BEGIN
DELETE FROM t1;
INSERT INTO t1 VALUES(75, randomblob(400));
INSERT INTO t1 VALUES(76, randomblob(400));
END;
INSERT INTO t1 VALUES(74, randomblob(400));
SELECT x, length(y) FROM t1 ORDER BY x;
}
} {75 400 76 400}
finish_test
+2 -1
View File
@@ -729,6 +729,7 @@ do_test wal-11.9 {
sqlite3_wal db test.db
set nWal 39
if {[permutation]=="nommap"} {set nWal 37}
ifcapable !mmap {set nWal 37}
do_test wal-11.10 {
execsql {
PRAGMA cache_size = 10;
@@ -1514,7 +1515,7 @@ do_test wal-23.3 {
set nPage [expr 2+$AUTOVACUUM]
do_test wal-23.4 {
set ::log
} [list SQLITE_OK "Recovered $nPage frames from WAL file $walfile"]
} [list SQLITE_NOTICE "recovered $nPage frames from WAL file $walfile"]
ifcapable autovacuum {
+1
View File
@@ -243,6 +243,7 @@ foreach {testprefix do_wal_checkpoint} {
# start of the checkpoint, even though page 2 cannot be written.
set nDb 2
if {[permutation]=="no-mmap"} {set nDb 1}
ifcapable !mmap {set nDb 1}
do_test 2.3.$tn.8 { file_page_counts } [list $nDb 4 2 4]
}
+39 -1
View File
@@ -548,6 +548,44 @@ do_faultsim_test walfault-14 -prep {
set nRow [db eval {SELECT count(*) FROM abc}]
if {!(($nRow==2 && $testrc) || $nRow==3)} { error "Bad db content" }
}
finish_test
#-------------------------------------------------------------------------
# Test fault-handling when switching out of exclusive-locking mode.
#
do_test walfault-14-pre {
faultsim_delete_and_reopen
execsql {
PRAGMA auto_vacuum = 0;
PRAGMA journal_mode = WAL;
BEGIN;
CREATE TABLE abc(a PRIMARY KEY);
INSERT INTO abc VALUES(randomblob(1500));
INSERT INTO abc VALUES(randomblob(1500));
COMMIT;
}
faultsim_save_and_close
} {}
do_faultsim_test walfault-14 -prep {
faultsim_restore_and_reopen
breakpoint
execsql {
SELECT count(*) FROM abc;
PRAGMA locking_mode = exclusive;
BEGIN;
INSERT INTO abc VALUES(randomblob(1500));
COMMIT;
}
} -body {
db eval {
PRAGMA locking_mode = normal;
BEGIN;
INSERT INTO abc VALUES(randomblob(1500));
COMMIT;
}
} -test {
faultsim_integrity_check
set nRow [db eval {SELECT count(*) FROM abc}]
if {$nRow!=3 && $nRow!=4} { error "Bad db content" }
}
finish_test
+1
View File
@@ -27,6 +27,7 @@ proc xLog {error_code msg} {
lappend ::log $msg
}
sqlite3 db test.db
db eval {PRAGMA mmap_limit=0}
do_test win32lock-1.1 {
db eval {