Compare commits

..

93 Commits

Author SHA1 Message Date
mistachkin 7f61e13f72 Fix several harmless compiler warnings.
FossilOrigin-Name: 360c0fd1cf9db5f1e4f670a4b95971daaeaa5879
2014-05-09 00:36:06 +00:00
mistachkin 5c8b293c75 Fix typos in logging code.
FossilOrigin-Name: dc7f84dfcc8415fad4af041fd30c20b3fd91be45
2014-05-08 22:15:13 +00:00
mistachkin df5e9e977b Fix a memory leak of the temporary read buffer.
FossilOrigin-Name: 37e60d211f70d12eda6d8b63da5e5e307e9d1748
2014-05-08 22:08:22 +00:00
mistachkin 04de790b09 Update comments and only include the thread routine when required.
FossilOrigin-Name: a60c545f255f7da53e0ebcde8743532b54bafdb6
2014-05-08 22:05:30 +00:00
mistachkin 83dca19e9f Experimental changes to pre-cache a database file prior to it being fully opened.
FossilOrigin-Name: 38cbcedbb6e57dc3c2d452a0eb573cabc7df0c75
2014-05-08 22:01:26 +00:00
mistachkin df24cf81a6 Fix static variable declaration issue on Windows.
FossilOrigin-Name: a41d29691307067523c8637b486941c5f7c33775
2014-05-08 22:01:08 +00:00
dan 5a7dbc70ea Add a little extra variety to the tests in sort4.test.
FossilOrigin-Name: 7de6aee6a5cb5c7f89dced89f2ebf38f8be7a4fa
2014-05-06 16:21:30 +00:00
dan dfea45330e Re-implement the core of the multi-threaded sorter tests in sort4.test using C. Run each test in sort4.test ten times, or repeat all tests for 300 seconds as part of the "multithread" permutation test.
FossilOrigin-Name: 208b2b04d4d282bec4424ea7160a123ba549d118
2014-05-06 15:38:07 +00:00
dan 449cb9a5af Add test file sort4.test, containing brute force tests for the multi-theaded sorter.
FossilOrigin-Name: 9cc364c42cc64ab7b55b5c55e303fb63a456cf00
2014-05-05 20:03:50 +00:00
dan 0d3a4085e5 Fix a race condition in the sorter code.
FossilOrigin-Name: 2d2edfe58db101d42a96772b856e6e55b401aab6
2014-05-05 15:58:40 +00:00
dan d94d4ee7bd Add tests so that the "coverage-sorter" test permutation covers all branches in vdbesort.c. Fix a few minor problems in the same file.
FossilOrigin-Name: bde28b702dabd02269e333535cc41481351c5efc
2014-05-05 09:08:54 +00:00
dan f7f425d600 Add an extra fault-injection test to sortfault.test. Remove an unreachable branch from vdbesort.c.
FossilOrigin-Name: a33a366ba8a0da81ddd895d552a348441ef8529a
2014-05-03 20:43:13 +00:00
dan e18e90ebaf Fix a race condition in the sorter.
FossilOrigin-Name: 32ccf3ae18531682dfd039fa8df6ad9a907ac455
2014-05-03 19:33:00 +00:00
dan 0d51def29e Fix a problem in the sorter causing it to return spurious SQLITE_NOMEM errors when configured to use memsys3 or memsys5.
FossilOrigin-Name: 3a66c4e1bf311d38668dfcdcd77867feff6db7bd
2014-05-03 14:28:14 +00:00
drh 2fc7bc08bd Get SQLITE_MUTEX_STATIC_APP1 and _APP2 working for the debugMutex
implementation.

FossilOrigin-Name: f49ba1c926c63ee1c4609930138389fca182c845
2014-05-03 13:53:37 +00:00
drh 7bd3c89114 Add two new static mutexes, SQLITE_MUTEX_STATIC_APP1 and _APP2, for use by
the application program.  First intended use is in test programs for the
memory allocation logic where one does not want to allocating a _FAST
or _RECURSIVE mutex since that would involve using the memory allocation
system under test.

FossilOrigin-Name: 13686035dd1cf67ad9c6d282ab13c3259e7273d1
2014-05-03 12:00:01 +00:00
drh a09c8855b7 Add the SQLITE_DEFAULT_WORKER_THREADS compile-time option.
Fix a NULL-pointer dereference that can occur following OOM.

FossilOrigin-Name: e0dea89b3e9f295f80210fcca007681bf1b08692
2014-05-03 11:22:09 +00:00
mistachkin e500747cfe Fix typo in Windows makefile. Make sure the WaitForSingleObjectEx system call is always available.
FossilOrigin-Name: d7ed529fa2aa5cb13edaabca2acaad06dffef569
2014-05-02 19:12:37 +00:00
drh 84de690b4f Do not run the vdbeRecordCompareDebug() assert if pKeyInfo->db is NULL since
in that case there would be no way to check for a memory allocation failure.

FossilOrigin-Name: 63ed2d6acb82be8a74dbf6a61388be6da6113985
2014-05-02 18:46:52 +00:00
dan 2ae56f50ce Merge orderby-planning with this branch.
FossilOrigin-Name: d9549de31741239ece060e448b592ce8fc5b8042
2014-05-02 18:05:38 +00:00
drh 79211e194d Simplify assert() statements used to verify correct operation of
record comparison routines.

FossilOrigin-Name: 3300d62dcbe74842cf86ca436959fe4e77a89f84
2014-05-02 17:33:16 +00:00
dan a7bf23c6b5 Fix some broken asserts in btree.c and vdbeaux.c that may fail following an OOM error.
FossilOrigin-Name: e15f47064bef431c0afd8bf93eb4e160c23ad562
2014-05-02 17:12:41 +00:00
drh c7f6c148d9 Failure to extend a temp file for use with mmap() in vdbesort.c is benign.
FossilOrigin-Name: d4d396387d373bd1e82eda2c7c2e7ca35ec099c4
2014-05-02 16:22:55 +00:00
dan 012e133772 Remove a faulty assert() from vdbesort.c.
FossilOrigin-Name: d95d68aa1d14b750888d50068380cc107f9070df
2014-05-02 16:03:57 +00:00
drh 7a0fd192cc Fix a faulty assert() statement.
FossilOrigin-Name: 9196ce407379ca3b151b601b98848771e5cb4e8f
2014-05-02 15:25:24 +00:00
drh fb0d6e56d6 Merge latest trunk enhancements and fixes into the orderby-planning branch.
FossilOrigin-Name: 84862d3a095629d20c8e7b8a16f4dc26cd41ab6d
2014-05-02 13:09:06 +00:00
drh f690c14280 Improved header comment on the vdbesort.c module. No changes to code.
FossilOrigin-Name: bf09ce24d054bc68c226064f5f28d97e0e648a13
2014-04-24 16:25:25 +00:00
drh 0ff435a782 Reopen the orderby-planning branch and merge in the latest trunk enhancements
and fixes.

FossilOrigin-Name: 6077ddcd93318e24b9756adaaf293ba9fb3cedf7
2014-04-24 15:06:25 +00:00
drh 3de4df27dd Improvements to comments. Store some extra information in SqliteThread that
is useful for debugging.

FossilOrigin-Name: 9fb5e212089d85cdd3b4787dd69c72e6d84560b6
2014-04-24 12:28:28 +00:00
drh 9e0ed8d4ec Merge all recent trunk changes into the threads branch.
FossilOrigin-Name: e2c9f71a451e44040624b9f255b4510743513019
2014-04-23 12:57:55 +00:00
drh 46a06bbe47 Add to speedtest1.c the --threads option for setting the
SQLITE_CONFIG_WORKER_THREADS configuration.

FossilOrigin-Name: 5fce40c44aacf883df2e8e9472c399a6e92197b3
2014-04-18 13:57:39 +00:00
drh 958d261bb8 Fix harmless compiler warnings.
FossilOrigin-Name: f8f72ecb9052a4cace1db75879fb8b5131ea4f50
2014-04-18 13:40:07 +00:00
drh e9af1894e3 Merge recent trunk changes into the threads branch.
FossilOrigin-Name: 8729aa3e3ed1da2e15408ef8705cbe185cd2a5ac
2014-04-18 12:38:54 +00:00
dan a9f43d735b Fix build problems in vdbesort.c. Add further comments and changes to make things easier to understand.
FossilOrigin-Name: 12b190db1d20c34390c768614b40ff58a9d3b74c
2014-04-17 08:57:17 +00:00
dan 31a0bfde9b Clarify the purpose of the nField argument passed to sqlite3VdbeSorterInit().
FossilOrigin-Name: c0c8cff17b7311bbc4fd081313a5552f927c3833
2014-04-16 19:04:23 +00:00
dan db30fc4ff2 Change the name of vdbeIncrInit2 to vdbePmaReaderIncrInit. Add a header comment to the same function.
FossilOrigin-Name: 6622d87675c1d7992b1e6d52ae7da1007a1568a4
2014-04-16 17:41:22 +00:00
dan 7f0a24b7bf Rework the way trees of MergeEngine objects are built in vdbesort.c to make it easier to follow. Fix memory leaks that could follow an OOM or IO error. Add various comments to explain functions in vdbesort.c.
FossilOrigin-Name: 69026ec7dc3bd3e33bbe17c221a53cf1dd0f8945
2014-04-16 16:43:05 +00:00
dan 22ace89179 Fix some problems to do with OOM conditions in vdbesort.c. Some problems remain.
FossilOrigin-Name: 2f94f9ce9bf11f1599bbc640b3fc8c15da588416
2014-04-15 20:52:27 +00:00
dan 1a088a8ef5 Fix further code and documentation issues in vdbesort.c.
FossilOrigin-Name: d03f5b8622d304f029f73c7cd0bee3182a81d081
2014-04-15 19:52:34 +00:00
dan 9c1586ec7c Allow the sorter to begin returning data to the VDBE as soon as it is available, instead of waiting until all keys have been sorted.
FossilOrigin-Name: cb0ab20c48962cdee03115efa93d7d501780ac73
2014-04-14 19:23:18 +00:00
dan f77ceba594 Improve performance in single-threaded mode by having the final merge pass keys directly to the VDBE, instead of going via a final PMA.
FossilOrigin-Name: 02610cd9b77caa2c181210056088beb3ad6ce30f
2014-04-14 18:41:21 +00:00
dan 92a20dde1f Minor fixes so that builds with SQLITE_MAX_WORKER_THREADS=0 work.
FossilOrigin-Name: e400bbbf26cdfe88f6cb231e96cdcddb9a6bcc0f
2014-04-14 08:45:32 +00:00
dan be3018c18f Improve use of multiple threads in sqlite3VdbeSorterRewind().
FossilOrigin-Name: e1bdc4b810907cc0e55e0c923c8ebc777068cfe0
2014-04-14 07:30:39 +00:00
dan 82a8a9f120 Fix many issues with new code.
FossilOrigin-Name: 62c406a042d7246f6df6b943421182a88483b2e3
2014-04-12 19:34:44 +00:00
dan 4be4c406fa Avoid having the sorter merge too many PMAs at a time when incrementally merging data following a SorterRewind().
FossilOrigin-Name: 98bf0307b121b0776a7170108cc8d3f948a7ebfe
2014-04-11 19:43:07 +00:00
dan d30ab3d9dd Experimental multi-threaded sorting changes to allow the sorter to begin returning items to the VDBE before all data is sorted.
FossilOrigin-Name: f9d5e09afaf64d68a0e461c1c2f38179bcea4b1f
2014-04-09 20:04:17 +00:00
drh bf20a35d5f Fix harmless compiler warnings.
FossilOrigin-Name: e54dded2012f0ab486ee138e9bd57c528af33980
2014-04-04 22:44:59 +00:00
mistachkin f7da5555da Fix typo in a Windows threading support routine.
FossilOrigin-Name: 5e3dfa27c71a666e122e3cf64897038ff8424800
2014-04-04 21:40:38 +00:00
drh 85462ed939 Merge the latest trunk changes into the threads branch.
FossilOrigin-Name: 39ac79cffe716f88af0871bdd206231b6a6511ff
2014-04-04 18:37:36 +00:00
dan 8daefc2af0 Add test file sort3.test, which should have been part of commit [9d3351b8d7].
FossilOrigin-Name: dceed2c803fca23c83c02c448d5ae7c4698efee1
2014-04-04 07:52:44 +00:00
drh 6b5d4759ce Change vdbeSorterExtendFile() so that it makes a best effort to create the
PMA file of the desired size, but does not return an error if unable.

FossilOrigin-Name: 217814bc4b53fab7bdad433e24e8aef8998c38fe
2014-04-04 02:13:26 +00:00
drh 1aca5caa88 Merge all recent changes from trunk.
FossilOrigin-Name: a0910079adde95245680dee59b43613b60903f10
2014-04-03 16:42:21 +00:00
dan 8930c2ab0c Fix an integer overflow problem in the sorter.
FossilOrigin-Name: 9d3351b8d713232133dad149c73fb2a27c72abb1
2014-04-03 16:25:29 +00:00
dan 6e4cc55e1f Fix minor errors causing compilation to fail with SQLITE_MAX_WORKER_THREADS set to a value greater than zero.
FossilOrigin-Name: 0561272abf357a2f4709f6c02866e570d19cd344
2014-04-03 14:29:08 +00:00
drh a634fb1577 Refactor local object and method names in vdbesort.c so that their names
more closely reflect their actual use.

FossilOrigin-Name: d284e30eb1db144965fa85566e4234e30464350b
2014-04-03 02:54:27 +00:00
drh ac4f0039c0 Add a big introductory comment to vdbesort.c explaining its operation at a
high level.  Also adjust some symbolic names and fix other comment issues in
that file.

FossilOrigin-Name: eef60f1bf54fcdc7b32f96ebb87a9a0bf0776e8b
2014-04-02 18:58:49 +00:00
dan dd95d30f82 Fix some problems with OOM handling in vdbesort.c.
FossilOrigin-Name: 47e702bd8392bc50c4edaf6a2c8c499af87b520e
2014-04-02 15:15:25 +00:00
drh 8d8f56296b Change the name of the SorterThread object to "SortSubtask" to avoid confusion
with the SQLiteThread object.

FossilOrigin-Name: 4ee2d910fbbed8d4def15e4e99ee225839f3a739
2014-04-02 14:38:14 +00:00
dan fad9f9a8a6 When sorting data for a CREATE INDEX statement in single-threaded mode, assume that keys are delivered to the sorter in primary key order. Also fix various comments that had fallen out of date.
FossilOrigin-Name: 821d1ac4504243fa13b9e3c0d56361ad9fb80d78
2014-04-01 18:41:51 +00:00
dan 578e1ca8d7 Even if compile time option SQLITE_MAX_WORKER_THREADS is set to one or greater, set the default number of worker threads to zero. Distribute data more evenly between threads in sqlite3VdbeSorterWrite() to improve performance when sorting large amounts of data. Add new test file sort2.test.
FossilOrigin-Name: 643c86a056168e39fcb7f39b8a72731f1eb246db
2014-04-01 15:38:44 +00:00
dan 38fdead890 Fix a problem with OOM handling in the sorter code.
FossilOrigin-Name: 59cd5229e2b5be5272cf57c7e7d09e97d16a5425
2014-04-01 10:19:02 +00:00
dan b3f56fdb69 Add the SQLITE_MAX_WORKER_THREADS compile time option. And the SQLITE_CONFIG_WORKER_THREADS sqlite3_config() switch.
FossilOrigin-Name: 2774710df8cd2bfaca49888c69f1b01c0ddadf9a
2014-03-31 19:57:34 +00:00
dan 853c4a7621 Fix a broken assert() in vdbesort.c.
FossilOrigin-Name: 18d1b402f2dbe78f1a1113bb356b710e348365ef
2014-03-29 10:01:58 +00:00
dan e7c84cc7e3 Fix a problem in vdbesort.c causing spurious SQLITE_NOMEM errors when using memsys3 or memsys5.
FossilOrigin-Name: a683c05f6250389e84b980b16559e162ba1a27c2
2014-03-29 09:34:45 +00:00
dan ff9fce4d60 Add the optimization to avoid some unnecessary calls to sqlite3VdbeRecordUnpack() added to the trunk by [707ea170b3].
FossilOrigin-Name: fc4d04e6b039ea5aeb47739e38c5926e63a4b01b
2014-03-29 06:27:35 +00:00
drh 73e7d8b2bb Fix a compiler warning and an after-OOM memory leak.
FossilOrigin-Name: 58f7ca29303c280229f86d01f418e1de5f5aebba
2014-03-28 19:47:19 +00:00
dan 2f17001521 Merge latest changes from orderby-planning branch.
FossilOrigin-Name: 4c7fb5423430f3b936befaa7c309f8e1968ee7d8
2014-03-28 19:18:16 +00:00
drh 7c8e9c78c8 Merge the latest changes from trunk.
FossilOrigin-Name: 3047a25f1c41e83f0b4772f7c36fbfec0f12dc7e
2014-03-28 18:35:39 +00:00
dan 6971952c65 Instead of allocating a single large buffer at the beginning of each sort operation, start with a small buffer and extend it using realloc() as required.
FossilOrigin-Name: 81987c8ceb64f051528a6ca42673821d9ab7c0ff
2014-03-27 19:25:02 +00:00
dan face087212 Use xFetch() to access temporary files in vdbesort.c. Use a single large allocation instead of many small allocations when accumulating records in vdbesort.c. This is an interim commit - it allocates a buffer the size of the page-cache every time data is sorted.
FossilOrigin-Name: f4ac1bf28c4ba395ccab8f1c9df72614a61095a7
2014-03-27 17:23:41 +00:00
drh bfa463696b Merge the latest trunk changes and the fix for the crash on a corrupt
database.

FossilOrigin-Name: 0b35346c32dba14963c85ec178f2b46aa2bbf6dc
2014-03-27 00:09:00 +00:00
drh 664eb14d8e Merge from trunk the fix for the crash on a corrupt database.
FossilOrigin-Name: 8cb2b02baa7ef9aa96319e977f0315328f944237
2014-03-26 19:45:01 +00:00
drh e6c7b09df6 Merge enhancements and fixes from trunk.
FossilOrigin-Name: e005f2d6dd9faf38cc8fdb9428b5aa6192a6adae
2014-03-25 18:29:12 +00:00
dan ab1dcc1a4b Fix a problem in the code added by [707ea170b3] causing vdbesort.c to sort unstably.
FossilOrigin-Name: d3e640afe611b6ae0b7f2cff5b00900d7e4d5ee3
2014-03-25 17:07:48 +00:00
dan 78d5843245 Remove the sequence values from sorter records used by ORDER BY as well.
FossilOrigin-Name: c3ae3697832a00d4d5758988a8766bdbb691e6b8
2014-03-25 15:04:07 +00:00
drh 3c863634ef Enable four sorting threads by default in the command-line shell.
FossilOrigin-Name: 1cab83577c814feb35b4fb91af0d52a9751d99bc
2014-03-25 14:12:16 +00:00
drh 5c2b314222 Merge all fixes and enhancements from trunk.
FossilOrigin-Name: b415dfb6cb0df0c69992ca2bb700c15664f158e6
2014-03-25 13:17:41 +00:00
dan dd23c6bfb4 Omit the sequence value from sorter records used by GROUP BY queries that cannot use an index.
FossilOrigin-Name: 3f90abddc31ac20739778c235a834c33f7057997
2014-03-24 20:19:07 +00:00
drh fd0a2f9756 Avoid unnecessary moving of content between registers during an ORDER BY.
FossilOrigin-Name: 4f472accf072d9cb64f209923924b26f21b13d27
2014-03-24 18:08:15 +00:00
dan 3f802ebce2 Remove an unnecessary temporary register allocation.
FossilOrigin-Name: 5d506743f541b022cde04a9606baa4680cdfd70b
2014-03-24 09:34:58 +00:00
drh 83553eefaf Remove a pointless OP_Once operation in ORDER BY clauses with LIMIT.
FossilOrigin-Name: e6c59d23316c83b318b1a94d9b28a5d321737fa5
2014-03-24 02:20:53 +00:00
drh 70f624c3a9 Further enhancements to geneverated VDBE code for ORDER BY.
FossilOrigin-Name: e7188fad87ec82d36a39b80ccaf8006bf45a9bcd
2014-03-24 01:43:50 +00:00
drh d345a66428 merge fixes from trunk
FossilOrigin-Name: faf7f9caf526ab33a6fdb9c89b45a0483510db21
2014-03-23 18:47:00 +00:00
drh f45f2326a2 Use only a single OP_MakeRecord instead of two when constructing entries
to go onto a sorter.

FossilOrigin-Name: d696cdedacd39075aa7fc407ab7c7e50f01d9f39
2014-03-23 17:45:03 +00:00
dan f87684189d Add an experimental multi-threaded capability to vdbesorter.c.
FossilOrigin-Name: ff0b5c851ba7d04d1836d7c6a3222713e7d8d357
2014-03-17 15:43:05 +00:00
dan c625ba7f4f Merge latest trunk changes into this branch.
FossilOrigin-Name: d17231b63d48c1f9c4dee109c90cec112e2f0fd4
2014-03-13 15:41:09 +00:00
drh 6ddecb753a Cherry-pick [555fc07]:
Changes to the thread routines to disable them when threading is turned
off using sqlite3_config().  Also merge all recent trunk changes.

FossilOrigin-Name: c92b0fe1371e7c20a5fbdf5fa96e30da14c40880
2012-08-21 17:36:44 +00:00
drh daa3ce4b08 Update the spellfix virtual table so that all OOM errors are reported out
to the application.

FossilOrigin-Name: c2cf498513c2633bd2b08372772eaa0f3b3ab25f
2012-08-21 13:08:15 +00:00
drh e22724ee54 Update the threads branch to include all the latest trunk changes.
FossilOrigin-Name: f4125771e21f1ca29d5442b5441dacfc06b8032b
2012-08-16 11:24:22 +00:00
mistachkin a806475f86 Add an assert() to help verify the return code from the Win32 thread wait function.
FossilOrigin-Name: ed3dc7a89f3416622fcd741ae5fba437929d06d6
2012-07-23 06:47:30 +00:00
mistachkin 572df3b1e4 Enhance implementation of the Win32 thread wait function.
FossilOrigin-Name: 049b04117353c3e163ffc87916cbe121403a2821
2012-07-23 02:00:38 +00:00
mistachkin da0e47109e Add Win32 support to the internal threads interface. Also, add several asserts and fix a few typos.
FossilOrigin-Name: 793195d37109c75eba84f7190c8fe0b8722f76f7
2012-07-21 22:49:08 +00:00
drh f51446a38c Add an internal interface that allows the code to take advantage of multiple
cores by pushing subcomputations off into separate threads.  The interface
is not currently used.

FossilOrigin-Name: 0e4d977a4a07d6de50acbf022c7dd947998b8d96
2012-07-21 19:40:42 +00:00
47 changed files with 3579 additions and 886 deletions
+5 -5
View File
@@ -177,7 +177,7 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
random.lo resolve.lo rowset.lo rtree.lo select.lo status.lo \
table.lo tokenize.lo trigger.lo \
table.lo threads.lo tokenize.lo trigger.lo \
update.lo util.lo vacuum.lo \
vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
vdbetrace.lo wal.lo walker.lo where.lo utf.lo vtab.lo
@@ -239,10 +239,8 @@ SRC = \
$(TOP)/src/os.c \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_setup.h \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/os_win.h \
$(TOP)/src/pager.c \
$(TOP)/src/pager.h \
$(TOP)/src/parse.y \
@@ -263,6 +261,7 @@ SRC = \
$(TOP)/src/sqliteInt.h \
$(TOP)/src/sqliteLimit.h \
$(TOP)/src/table.c \
$(TOP)/src/threads.c \
$(TOP)/src/tclsqlite.c \
$(TOP)/src/tokenize.c \
$(TOP)/src/trigger.c \
@@ -459,8 +458,6 @@ HDR = \
opcodes.h \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_setup.h \
$(TOP)/src/os_win.h \
$(TOP)/src/pager.h \
$(TOP)/src/pcache.h \
parse.h \
@@ -736,6 +733,9 @@ status.lo: $(TOP)/src/status.c $(HDR)
table.lo: $(TOP)/src/table.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/table.c
threads.lo: $(TOP)/src/threads.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/threads.c
tokenize.lo: $(TOP)/src/tokenize.c keywordhash.h $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/tokenize.c
+5 -5
View File
@@ -564,7 +564,7 @@ LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
pager.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
random.lo resolve.lo rowset.lo rtree.lo select.lo status.lo \
table.lo tokenize.lo trigger.lo \
table.lo threads.lo tokenize.lo trigger.lo \
update.lo util.lo vacuum.lo \
vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
vdbetrace.lo wal.lo walker.lo where.lo utf.lo vtab.lo
@@ -637,10 +637,8 @@ SRC = \
$(TOP)\src\os.c \
$(TOP)\src\os.h \
$(TOP)\src\os_common.h \
$(TOP)\src\os_setup.h \
$(TOP)\src\os_unix.c \
$(TOP)\src\os_win.c \
$(TOP)\src\os_win.h \
$(TOP)\src\pager.c \
$(TOP)\src\pager.h \
$(TOP)\src\parse.y \
@@ -661,6 +659,7 @@ SRC = \
$(TOP)\src\sqliteInt.h \
$(TOP)\src\sqliteLimit.h \
$(TOP)\src\table.c \
$(TOP)\src\threads.c \
$(TOP)\src\tclsqlite.c \
$(TOP)\src\tokenize.c \
$(TOP)\src\trigger.c \
@@ -860,8 +859,6 @@ HDR = \
opcodes.h \
$(TOP)\src\os.h \
$(TOP)\src\os_common.h \
$(TOP)\src\os_setup.h \
$(TOP)\src\os_win.h \
$(TOP)\src\pager.h \
$(TOP)\src\pcache.h \
parse.h \
@@ -1143,6 +1140,9 @@ status.lo: $(TOP)\src\status.c $(HDR)
table.lo: $(TOP)\src\table.c $(HDR)
$(LTCOMPILE) -c $(TOP)\src\table.c
threads.lo: $(TOP)\src\threads.c $(HDR)
$(LTCOMPILE) -c $(TOP)\src\threads.c
tokenize.lo: $(TOP)\src\tokenize.c keywordhash.h $(HDR)
$(LTCOMPILE) -c $(TOP)\src\tokenize.c
-4
View File
@@ -262,10 +262,8 @@ SRC = \
$(TOP)/src/os.c \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_setup.h \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/os_win.h \
$(TOP)/src/pager.c \
$(TOP)/src/pager.h \
$(TOP)/src/parse.y \
@@ -418,8 +416,6 @@ HDR = \
opcodes.h \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_setup.h \
$(TOP)/src/os_win.h \
$(TOP)/src/pager.h \
$(TOP)/src/pcache.h \
parse.h \
+3 -5
View File
@@ -66,7 +66,7 @@ LIBOBJ+= vdbe.o parse.o \
notify.o opcodes.o os.o os_unix.o os_win.o \
pager.o pcache.o pcache1.o pragma.o prepare.o printf.o \
random.o resolve.o rowset.o rtree.o select.o status.o \
table.o tokenize.o trigger.o \
table.o threads.o tokenize.o trigger.o \
update.o util.o vacuum.o \
vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \
vdbetrace.o wal.o walker.o where.o utf.o vtab.o
@@ -121,10 +121,8 @@ SRC = \
$(TOP)/src/os.c \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_setup.h \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/os_win.h \
$(TOP)/src/pager.c \
$(TOP)/src/pager.h \
$(TOP)/src/parse.y \
@@ -146,6 +144,7 @@ SRC = \
$(TOP)/src/sqliteLimit.h \
$(TOP)/src/table.c \
$(TOP)/src/tclsqlite.c \
$(TOP)/src/threads.c \
$(TOP)/src/tokenize.c \
$(TOP)/src/trigger.c \
$(TOP)/src/utf.c \
@@ -313,6 +312,7 @@ TESTSRC2 = \
$(TOP)/src/pcache.c \
$(TOP)/src/pcache1.c \
$(TOP)/src/select.c \
$(TOP)/src/threads.c \
$(TOP)/src/tokenize.c \
$(TOP)/src/utf.c \
$(TOP)/src/util.c \
@@ -341,8 +341,6 @@ HDR = \
opcodes.h \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_setup.h \
$(TOP)/src/os_win.h \
$(TOP)/src/pager.h \
$(TOP)/src/pcache.h \
parse.h \
+49 -46
View File
@@ -1,10 +1,10 @@
C Attempt\sto\sfix\sthe\sbuild\son\sbeagleboard.
D 2014-05-05T20:21:52.937
C Fix\sseveral\sharmless\scompiler\swarnings.
D 2014-05-09T00:36:06.204
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670
F Makefile.in ad0921c4b2780d01868cf69b419a4f102308d125
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc d1d9474b660e87a0134acd33693281883cb328b1
F Makefile.vxworks 034289efa9d591b04b1a73598623119c306cbba0
F Makefile.msc 7d6981e8e14d8189a2a2f9b4a485f40b2032cb2e
F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315
F README.md 64f270c43c38c46de749e419c22f0ae2f4499fe8
F VERSION 9f823c026c6a32fc5f84d212a8aae0a221dba45c
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
@@ -144,7 +144,7 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt f439556c5ce01ced70987e5ee86549a45165d9ff
F main.mk 601f43d91e6c7043127ec192bf85c9a1ae940621
F main.mk f51f401a87fd07be255bcecae8b03105ca2024e8
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
@@ -165,10 +165,10 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 6c9b51abd404ce5b78b173b6f2248e8cb824758c
F src/btree.c e14daeed62b5b1499835a6523f9a47d660c297c8
F src/btree.h d79306df4ed9181b48916737fe8871a4392c4594
F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3
F src/build.c 02665ca158431a0926b10cbd7d8178a4c9fc4a22
F src/build.c 9c522b6e5af1485c38b12a55f9d946e66fca61b6
F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a
@@ -178,7 +178,7 @@ F src/expr.c 4f9e497c66e2f25a4d139357a778c84d5713207c
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 5269ef07b100763134f71b889327c333bd0989cf
F src/func.c 2945bb2c4cdc0ac43733046285a4434310be1811
F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486
F src/global.c b7943ff485c31660ec0b17c68467034804df01b1
F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
@@ -187,7 +187,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303
F src/main.c 0a8cfb6b2899649880e5874ac9bfd1c6f7c6a4a3
F src/main.c 2ba4f6eeb84cf8efd8bb632c1abe203dc86adcac
F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b
@@ -195,19 +195,17 @@ F src/mem2.c dce31758da87ec2cfa52ba4c5df1aed6e07d8e8f
F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534
F src/mem5.c 74670012946c4adc8a6ad84d03acc80959c3e529
F src/memjournal.c 0683aac6cab6ec2b5374c0db37c0deb2436a3785
F src/mutex.c d3b66a569368015e0fcb1ac15f81c119f504d3bc
F src/mutex.c 84a073c9a23a8d7bdd2ea832522d1730df18812c
F src/mutex.h 5bc526e19dccc412b7ff04642f6fdad3fdfdabea
F src/mutex_noop.c 7682796b7d8d39bf1c138248858efcd10c9e1553
F src/mutex_unix.c c3a4e00f96ba068a8dbef34084465979aaf369cc
F src/mutex_w32.c ab08c0fc54b71979370ca7c8f42fc64a9f211ebb
F src/mutex_noop.c 4222773e5f61e506f232aedc9ad9e16ca00c1399
F src/mutex_unix.c 56e22c1bc6aabfa2f9736317a8f56acd5d0c5f7c
F src/mutex_w32.c c4726d3bfe80996665a39d27598ebd056e2d6b89
F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace
F src/os.h 60d419395e32a8029fa380a80a3da2e9030f635e
F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
F src/os_unix.c ae4b5240af4619d711301d7992396e182585269f
F src/os_win.c 485d06a93965f306c7281fca0937829292367234
F src/os_win.h 057344a6720b4c8405d9bd98f58cb37a6ee46c25
F src/os_win.c 5024065c68c50739aeef6d490db88e5b682fcc30
F src/pager.c ab62a24218d87dda1be641f6c5ad291bff78fd94
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0
@@ -220,17 +218,17 @@ F src/printf.c e5a0005f8b3de21f85da6a709d2fbee76775bf4b
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66
F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be
F src/select.c 089c4d46f067a5cccae93524c6377f981ba99bd9
F src/shell.c 2afe7a7154e97be0c74c5feacf09626bda8493be
F src/sqlite.h.in bde98816e1ba0c9ffef50afe7b32f4e5a8f54fe0
F src/select.c a5ed3fdc82ebab5b9b095ea1971515a7f8a303d2
F src/shell.c 6946aea9f21af551fa84bc6b2a8de55d93bf0004
F src/sqlite.h.in ed6d0cc90da850340c3863c84351e6e164c0ef00
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h b2947801eccefd7ba3e5f14e1353289351a83cf3
F src/sqliteInt.h 851003126071d4a3bac86a0db75c48197fbd0ff0
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c e87c99e28a145943666b51b212dacae35fcea0bd
F src/test1.c 899bddeb0c7fb2b8062de6f03af4a4e4f48f9df5
F src/test1.c a0e59104fec5626bb1d1bd746157f43e85245e4b
F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
@@ -243,7 +241,7 @@ F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8
F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
F src/test_config.c dabaa32868974e1ae39770cc17d7e066a9c38e6d
F src/test_config.c bf2e0bf49ebd8fe3dccabb4542157f9571fe48fa
F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
@@ -254,15 +252,15 @@ F src/test_intarray.c 87847c71c3c36889c0bcc9c4baf9d31881665d61
F src/test_intarray.h 2ece66438cfd177b78d1bfda7a4180cd3a10844d
F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64
F src/test_loadext.c a5251f956ab6af21e138dc1f9c0399394a510cb4
F src/test_malloc.c 1ff5b1243d96124c9a180f3b89424820a1f337f3
F src/test_malloc.c 27047a841f5bff1cb638123806a2c30714771307
F src/test_multiplex.c 9f304bf04170c91c0318238d512df2da039eb1c8
F src/test_multiplex.h 110a8c4d356e0aa464ca8730375608a9a0b61ae1
F src/test_mutex.c 293042d623ebba969160f471a82aa1551626454f
F src/test_onefile.c 0396f220561f3b4eedc450cef26d40c593c69a25
F src/test_osinst.c 3d0340bc31a9f3d8a3547e0272373e80f78dde25
F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
F src/test_quota.c 65f6348fec0f2b3020c907247fb47556b214abb9
F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d
F src/test_quota.c 30c64f0ef84734f2231a686df41ed882b0c59bc0
F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
F src/test_rtree.c fdd8d29ca5165c7857987a2ba263fac5c69e231f
F src/test_schema.c cd12a2223c3a394f4d07bb93bdf6d344c5c121b6
F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
@@ -275,20 +273,21 @@ F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb
F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c b9daffcb6ae3a9c080da37b905e790d45a8f99db
F src/tokenize.c 6da2de6e12218ccb0aea5184b56727d011f4bee7
F src/trigger.c 66f3470b03b52b395e839155786966e3e037fddb
F src/update.c 5b3e74a03b3811e586b4f2b4cbd7c49f01c93115
F src/utf.c 6dc9ec9f1b3db43ae8ba0365377f11df1ee4c01c
F src/util.c 2b5fb283a190aacdb286f7835a447c45b345b83c
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
F src/vdbe.c 7f359193bf2366cc914a9ece093ebf284e56acdc
F src/vdbe.c 89ab2ded5123e823b47293aedd7931a4742fb6bd
F src/vdbe.h 394464909ed682334aa3d5831aae0c2fe2abef94
F src/vdbeInt.h e6d83e5bfd62fc6685ba1ed6153f7099f82de9f7
F src/vdbeInt.h c78ace64dc37495806dd50596eded1f6cd2b5a64
F src/vdbeapi.c 0ed6053f947edd0b30f64ce5aeb811872a3450a4
F src/vdbeaux.c e493f38758c4b8f4ca2007cf6a700bd405d192f3
F src/vdbeaux.c 44d4d1f5711f71eaf0d624de5c3e4976fe4e180b
F src/vdbeblob.c 9205ce9d3b064d9600f8418a897fc88b5687d9ac
F src/vdbemem.c 6fc77594c60f6155404f3f8d71bf36d1fdeb4447
F src/vdbesort.c 4abb7c0f8f19b7d7d82f4558d5da1a30fdf9ea38
F src/vdbesort.c b36070436d33372237541e9eaa6068e1a61bc402
F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767
F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
@@ -584,7 +583,7 @@ F test/func3.test dbccee9133cfef1473c59ec07b5f0262b9d72f9a
F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f
F test/func5.test cdd224400bc3e48d891827cc913a57051a426fa4
F test/fuzz-oss1.test 4912e528ec9cf2f42134456933659d371c9e0d74
F test/fuzz.test 96083052bf5765e4518c1ba686ce2bab785670d1
F test/fuzz.test 77fd50afc12847af50fcf1941679d90adebadde6
F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167
F test/fuzz3.test efd384b896c647b61a2c1848ba70d42aad60a7b3
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
@@ -666,7 +665,7 @@ F test/lock_common.tcl 0c270b121d40959fa2f3add382200c27045b3d95
F test/lookaside.test 93f07bac140c5bb1d49f3892d2684decafdc7af2
F test/main.test 39c4bb8a157f57298ed1659d6df89d9f35aaf2c8
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
F test/malloc.test fd368e31fe98d4779ed80442f311ed9f03bcd1f7
F test/malloc.test ada8ae15193ffc6415bf431a6db31d4ec507dbfe
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
F test/malloc5.test fafce0aa9157060445cd1a56ad50fc79d82f28c3
@@ -674,7 +673,7 @@ F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a
F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d
F test/malloc9.test 2307c6ee3703b0a21391f3ea92388b4b73f9105e
F test/mallocA.test 1ba0367fb5434e7bc2fa4afcb30b14174d91b160
F test/mallocA.test c049224adeb0244b8f6eb770c1fa6ac40f9b3518
F test/mallocAll.test 98f1be74bc9f49a858bc4f361fc58e26486798be
F test/mallocB.test bc475ab850cda896142ab935bbfbc74c24e51ed6
F test/mallocC.test 3dffe16532f109293ce1ccecd0c31dca55ef08c4
@@ -742,7 +741,7 @@ F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54
F test/permutations.test 40add071ba71aefe1c04f5845308cf46f7de8d04
F test/permutations.test 33e7e239ba494fdb30e2f4ffc64c508b145ff42f
F test/pragma.test adb21a90875bc54a880fa939c4d7c46598905aa0
F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
@@ -822,7 +821,11 @@ F test/skipscan1.test bed8cbe9d554c8c27afb6c88500f704c86a9196f
F test/skipscan2.test d77f79cdbba25f0f6f35298136cff21a7d7a553a
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24
F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5
F test/sort.test 688468cef8c9a66fcc1d54235de8e4deac745690
F test/sort2.test c5e25eb674689e291d06b5209fe8d337ae0ec010
F test/sort3.test 6178ade30810ac9166fcdf14b7065e49c0f534e2
F test/sort4.test 971452fd4e2928e6fc05c3868396ad7d5f9ce2ad
F test/sortfault.test 1a12b6e27d475f50658a8164aaa34f0080a86b36
F test/speed1.test f2974a91d79f58507ada01864c0e323093065452
F test/speed1p.explain d841e650a04728b39e6740296b852dccdca9b2cb
F test/speed1p.test b180e98609c7677382cf618c0ec9b69f789033a8
@@ -831,7 +834,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/speedtest1.c d29c8048beb7ea9254191f3fde9414709166a920
F test/speedtest1.c f452891e50571627f7060c0e1262359127055717
F test/spellfix.test 61309f5efbec53603b3f86457d34a504f80abafe
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de
@@ -851,7 +854,7 @@ F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
F test/tester.tcl f31bea1483ea1d39620f982130026e76f872d744
F test/tester.tcl bc0889a2f86d9c17307992ca1e70391794780265
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@@ -1136,10 +1139,10 @@ F tool/mkkeywordhash.c c9e05e4a7bcab8fab9f583d5b321fb72f565ad97
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkpragmatab.tcl 78a77b2c554d534c6f2dc903130186ed15715460
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c-noext.tcl 1712d3d71256ca1f297046619c89e77a4d7c8f6d
F tool/mksqlite3c.tcl ba274df71f5e6534b0a913c7c48eabfcbd0934b6
F tool/mksqlite3c-noext.tcl 752f1a9d3287f6c0ef5738b1c4add0b96fbe0854
F tool/mksqlite3c.tcl 8da823522f27608494997e1dba19cd426572ba80
F tool/mksqlite3h.tcl ba24038056f51fde07c0079c41885ab85e2cff12
F tool/mksqlite3internalh.tcl b6514145a7d5321b47e64e19b8116cc44f973eb1
F tool/mksqlite3internalh.tcl 3dca7bb5374cee003379b8cbac73714f610ef795
F tool/mkvsix.tcl 6477fb9dab838b7eea1eed50658ff1cda04850b5
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
F tool/omittest.tcl 34d7ac01fe4fd18e3637f64abe12c40eca0f6b97
@@ -1168,7 +1171,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P 857f2baf9b722e4eb1ac0d50fe03e32d5176185b
R 13f47e22fa817432bd25922bb1ff1b2f
U drh
Z 55108ca91e730f32aa309dbf16d83499
P dc7f84dfcc8415fad4af041fd30c20b3fd91be45
R dab57784c4183d6467c4fe813ebf5ee5
U mistachkin
Z bd4d9a5acb160a48faa7ad2a8521ce0e
+1 -1
View File
@@ -1 +1 @@
3ac75725a66730566105ad184a988a8f80f51055
360c0fd1cf9db5f1e4f670a4b95971daaeaa5879
+6 -3
View File
@@ -4609,7 +4609,7 @@ int sqlite3BtreeMovetoUnpacked(
if( pIdxKey ){
xRecordCompare = sqlite3VdbeFindCompare(pIdxKey);
pIdxKey->isCorrupt = 0;
pIdxKey->errCode = 0;
assert( pIdxKey->default_rc==1
|| pIdxKey->default_rc==0
|| pIdxKey->default_rc==-1
@@ -4733,7 +4733,10 @@ int sqlite3BtreeMovetoUnpacked(
c = xRecordCompare(nCell, pCellKey, pIdxKey, 0);
sqlite3_free(pCellKey);
}
assert( pIdxKey->isCorrupt==0 || c==0 );
assert(
(pIdxKey->errCode!=SQLITE_CORRUPT || c==0)
&& (pIdxKey->errCode!=SQLITE_NOMEM || pCur->pBtree->db->mallocFailed)
);
if( c<0 ){
lwr = idx+1;
}else if( c>0 ){
@@ -4743,7 +4746,7 @@ int sqlite3BtreeMovetoUnpacked(
*pRes = 0;
rc = SQLITE_OK;
pCur->aiIdx[pCur->iPage] = (u16)idx;
if( pIdxKey->isCorrupt ) rc = SQLITE_CORRUPT;
if( pIdxKey->errCode ) rc = SQLITE_CORRUPT;
goto moveto_finish;
}
if( lwr>upr ) break;
+2 -2
View File
@@ -2669,7 +2669,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
/* Open the sorter cursor if we are to use one. */
iSorter = pParse->nTab++;
sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)
sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, pIndex->nKeyCol, (char*)
sqlite3KeyInfoRef(pKey), P4_KEYINFO);
/* Open the table. Loop through all rows of the table, inserting index
@@ -3018,7 +3018,7 @@ Index *sqlite3CreateIndex(
pParse->checkSchema = 1;
goto exit_create_index;
}
assert( pTab->nCol<=0x7fff && j<=0x7fff );
assert( j<=0x7fff );
pIndex->aiColumn[i] = (i16)j;
if( pListItem->pExpr ){
int nColl;
+1
View File
@@ -167,6 +167,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
0, /* nPage */
0, /* mxParserStack */
0, /* sharedCacheEnabled */
SQLITE_DEFAULT_WORKER_THREADS, /* nWorker */
/* All the rest should always be initialized to zero */
0, /* isInit */
0, /* inProgress */
+15
View File
@@ -515,6 +515,13 @@ int sqlite3_config(int op, ...){
}
#endif
case SQLITE_CONFIG_WORKER_THREADS: {
int n = va_arg(ap, int);
if( n>SQLITE_MAX_WORKER_THREADS ) n = SQLITE_MAX_WORKER_THREADS;
if( n>=0 ) sqlite3GlobalConfig.nWorker = n;
break;
}
default: {
rc = SQLITE_ERROR;
break;
@@ -2497,6 +2504,7 @@ static int openDatabase(
db->nextAutovac = -1;
db->szMmap = sqlite3GlobalConfig.szMmap;
db->nextPagesize = 0;
db->nMaxSorterMmap = 0x7FFFFFFF;
db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
| SQLITE_AutoIndex
@@ -3339,6 +3347,13 @@ int sqlite3_test_control(int op, ...){
break;
}
/* sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, nMax); */
case SQLITE_TESTCTRL_SORTER_MMAP: {
sqlite3 *db = va_arg(ap, sqlite3*);
db->nMaxSorterMmap = va_arg(ap, int);
break;
}
}
va_end(ap);
#endif /* SQLITE_OMIT_BUILTIN_TEST */
+1 -1
View File
@@ -81,7 +81,7 @@ int sqlite3MutexEnd(void){
*/
sqlite3_mutex *sqlite3_mutex_alloc(int id){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0;
#endif
return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
}
+1 -1
View File
@@ -107,7 +107,7 @@ static int debugMutexEnd(void){ return SQLITE_OK; }
** that means that a mutex could not be allocated.
*/
static sqlite3_mutex *debugMutexAlloc(int id){
static sqlite3_debug_mutex aStatic[6];
static sqlite3_debug_mutex aStatic[8];
sqlite3_debug_mutex *pNew = 0;
switch( id ){
case SQLITE_MUTEX_FAST:
+5 -1
View File
@@ -96,10 +96,12 @@ static int pthreadMutexEnd(void){ return SQLITE_OK; }
** <li> SQLITE_MUTEX_RECURSIVE
** <li> SQLITE_MUTEX_STATIC_MASTER
** <li> SQLITE_MUTEX_STATIC_MEM
** <li> SQLITE_MUTEX_STATIC_MEM2
** <li> SQLITE_MUTEX_STATIC_OPEN
** <li> SQLITE_MUTEX_STATIC_PRNG
** <li> SQLITE_MUTEX_STATIC_LRU
** <li> SQLITE_MUTEX_STATIC_PMEM
** <li> SQLITE_MUTEX_STATIC_APP1
** <li> SQLITE_MUTEX_STATIC_APP2
** </ul>
**
** The first two constants cause sqlite3_mutex_alloc() to create
@@ -133,6 +135,8 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER
};
sqlite3_mutex *p;
+6 -7
View File
@@ -19,11 +19,6 @@
*/
#ifdef SQLITE_MUTEX_W32
/*
** Include the header file for the Windows VFS.
*/
#include "os_win.h"
/*
** Each recursive mutex is an instance of the following structure.
*/
@@ -98,7 +93,9 @@ static int winMutexNotheld(sqlite3_mutex *p){
/*
** Initialize and deinitialize the mutex subsystem.
*/
static sqlite3_mutex winMutex_staticMutexes[6] = {
static sqlite3_mutex winMutex_staticMutexes[] = {
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
@@ -164,10 +161,12 @@ static int winMutexEnd(void){
** <li> SQLITE_MUTEX_RECURSIVE
** <li> SQLITE_MUTEX_STATIC_MASTER
** <li> SQLITE_MUTEX_STATIC_MEM
** <li> SQLITE_MUTEX_STATIC_MEM2
** <li> SQLITE_MUTEX_STATIC_OPEN
** <li> SQLITE_MUTEX_STATIC_PRNG
** <li> SQLITE_MUTEX_STATIC_LRU
** <li> SQLITE_MUTEX_STATIC_PMEM
** <li> SQLITE_MUTEX_STATIC_APP1
** <li> SQLITE_MUTEX_STATIC_APP2
** </ul>
**
** The first two constants cause sqlite3_mutex_alloc() to create
+76 -3
View File
@@ -21,10 +21,83 @@
#define _SQLITE_OS_H_
/*
** Attempt to automatically detect the operating system and setup the
** necessary pre-processor macros for it.
** Figure out if we are dealing with Unix, Windows, or some other
** operating system. After the following block of preprocess macros,
** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, and SQLITE_OS_OTHER
** will defined to either 1 or 0. One of the four will be 1. The other
** three will be 0.
*/
#include "os_setup.h"
#if defined(SQLITE_OS_OTHER)
# if SQLITE_OS_OTHER==1
# undef SQLITE_OS_UNIX
# define SQLITE_OS_UNIX 0
# undef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
# else
# undef SQLITE_OS_OTHER
# endif
#endif
#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER)
# define SQLITE_OS_OTHER 0
# ifndef SQLITE_OS_WIN
# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
# define SQLITE_OS_WIN 1
# define SQLITE_OS_UNIX 0
# else
# define SQLITE_OS_WIN 0
# define SQLITE_OS_UNIX 1
# endif
# else
# define SQLITE_OS_UNIX 0
# endif
#else
# ifndef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
# endif
#endif
#if SQLITE_OS_WIN
# include <windows.h>
#endif
/*
** Determine if we are dealing with Windows NT.
**
** We ought to be able to determine if we are compiling for win98 or winNT
** using the _WIN32_WINNT macro as follows:
**
** #if defined(_WIN32_WINNT)
** # define SQLITE_OS_WINNT 1
** #else
** # define SQLITE_OS_WINNT 0
** #endif
**
** However, vs2005 does not set _WIN32_WINNT by default, as it ought to,
** so the above test does not work. We'll just assume that everything is
** winNT unless the programmer explicitly says otherwise by setting
** SQLITE_OS_WINNT to 0.
*/
#if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT)
# define SQLITE_OS_WINNT 1
#endif
/*
** Determine if we are dealing with WindowsCE - which has a much
** reduced API.
*/
#if defined(_WIN32_WCE)
# define SQLITE_OS_WINCE 1
#else
# define SQLITE_OS_WINCE 0
#endif
/*
** Determine if we are dealing with WinRT, which provides only a subset of
** the full Win32 API.
*/
#if !defined(SQLITE_OS_WINRT)
# define SQLITE_OS_WINRT 0
#endif
/* If the SET_FULLSYNC macro is not defined above, then make it
** a no-op
-57
View File
@@ -1,57 +0,0 @@
/*
** 2013 November 25
**
** 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 pre-processor directives related to operating system
** detection and/or setup.
*/
#ifndef _OS_SETUP_H_
#define _OS_SETUP_H_
/*
** Figure out if we are dealing with Unix, Windows, or some other operating
** system.
**
** After the following block of preprocess macros, all of SQLITE_OS_UNIX,
** SQLITE_OS_WIN, and SQLITE_OS_OTHER will defined to either 1 or 0. One of
** the three will be 1. The other two will be 0.
*/
#if defined(SQLITE_OS_OTHER)
# if SQLITE_OS_OTHER==1
# undef SQLITE_OS_UNIX
# define SQLITE_OS_UNIX 0
# undef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
# else
# undef SQLITE_OS_OTHER
# endif
#endif
#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER)
# define SQLITE_OS_OTHER 0
# ifndef SQLITE_OS_WIN
# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \
defined(__MINGW32__) || defined(__BORLANDC__)
# define SQLITE_OS_WIN 1
# define SQLITE_OS_UNIX 0
# else
# define SQLITE_OS_WIN 0
# define SQLITE_OS_UNIX 1
# endif
# else
# define SQLITE_OS_UNIX 0
# endif
#else
# ifndef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
# endif
#endif
#endif /* _OS_SETUP_H_ */
+116 -44
View File
@@ -15,16 +15,16 @@
#include "sqliteInt.h"
#if SQLITE_OS_WIN /* This file is used for Windows only */
#ifdef __CYGWIN__
# include <sys/cygwin.h>
# include <errno.h> /* amalgamator: keep */
#endif
/*
** Include code that is common to all os_*.c files
*/
#include "os_common.h"
/*
** Include the header file for the Windows VFS.
*/
#include "os_win.h"
/*
** Compiling and using WAL mode requires several APIs that are only
** available in Windows platforms based on the NT kernel.
@@ -267,6 +267,7 @@ struct winFile {
sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */
sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */
#endif
SQLiteThread *preCacheThread; /* Thread used to pre-cache file contents */
};
/*
@@ -948,11 +949,7 @@ static struct win_syscall {
#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
DWORD))aSyscall[63].pCurrent)
#if SQLITE_OS_WINRT
{ "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
#else
{ "WaitForSingleObjectEx", (SYSCALL)0, 0 },
#endif
#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
BOOL))aSyscall[64].pCurrent)
@@ -1048,6 +1045,11 @@ static struct win_syscall {
#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)
{ "DuplicateHandle", (SYSCALL)DuplicateHandle, 0 },
#define osDuplicateHandle ((BOOL(WINAPI*)(HANDLE, \
HANDLE,HANDLE,LPHANDLE,DWORD,BOOL,DWORD))aSyscall[76].pCurrent)
}; /* End of the overrideable system calls */
/*
@@ -1279,6 +1281,13 @@ void sqlite3_win32_sleep(DWORD milliseconds){
#endif
}
DWORD sqlite3Win32Wait(HANDLE hObject){
DWORD rc;
while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
TRUE))==WAIT_IO_COMPLETION ){}
return rc;
}
/*
** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
** or WinCE. Return false (zero) for Win95, Win98, or WinME.
@@ -1836,32 +1845,6 @@ static int winLogErrorAtLine(
static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY;
static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
/*
** The "winIoerrCanRetry1" macro is used to determine if a particular I/O
** error code obtained via GetLastError() is eligible to be retried. It
** must accept the error code DWORD as its only argument and should return
** non-zero if the error code is transient in nature and the operation
** responsible for generating the original error might succeed upon being
** retried. The argument to this macro should be a variable.
**
** Additionally, a macro named "winIoerrCanRetry2" may be defined. If it
** is defined, it will be consulted only when the macro "winIoerrCanRetry1"
** returns zero. The "winIoerrCanRetry2" macro is completely optional and
** may be used to include additional error codes in the set that should
** result in the failing I/O operation being retried by the caller. If
** defined, the "winIoerrCanRetry2" macro must exhibit external semantics
** identical to those of the "winIoerrCanRetry1" macro.
*/
#if !defined(winIoerrCanRetry1)
#define winIoerrCanRetry1(a) (((a)==ERROR_ACCESS_DENIED) || \
((a)==ERROR_SHARING_VIOLATION) || \
((a)==ERROR_LOCK_VIOLATION) || \
((a)==ERROR_DEV_NOT_EXIST) || \
((a)==ERROR_NETNAME_DELETED) || \
((a)==ERROR_SEM_TIMEOUT) || \
((a)==ERROR_NETWORK_UNREACHABLE))
#endif
/*
** If a ReadFile() or WriteFile() error occurs, invoke this routine
** to see if it should be retried. Return TRUE to retry. Return FALSE
@@ -1875,18 +1858,13 @@ static int winRetryIoerr(int *pnRetry, DWORD *pError){
}
return 0;
}
if( winIoerrCanRetry1(e) ){
if( e==ERROR_ACCESS_DENIED ||
e==ERROR_LOCK_VIOLATION ||
e==ERROR_SHARING_VIOLATION ){
sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
++*pnRetry;
return 1;
}
#if defined(winIoerrCanRetry2)
else if( winIoerrCanRetry2(e) ){
sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
++*pnRetry;
return 1;
}
#endif
if( pError ){
*pError = e;
}
@@ -2382,6 +2360,13 @@ static int winClose(sqlite3_file *id){
assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
OSTRACE(("CLOSE file=%p\n", pFile->h));
#if SQLITE_MAX_WORKER_THREADS>0
if( pFile->preCacheThread ){
void *pOut = 0;
sqlite3ThreadJoin(pFile->preCacheThread, &pOut);
}
#endif
#if SQLITE_MAX_MMAP_SIZE>0
winUnmapfile(pFile);
#endif
@@ -3226,6 +3211,84 @@ static int winDeviceCharacteristics(sqlite3_file *id){
((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0);
}
#if SQLITE_MAX_WORKER_THREADS>0
/*
** Thread routine that attempts to read the entire file. This is used to
** provide a hint to the operating system that the entire file should be held
** in the cache.
*/
static void *winPreCacheThread(void *pCtx){
winFile *pFile = (winFile*)pCtx;
void *pBuf = 0;
DWORD lastErrno;
HANDLE dupHandle = NULL;
DWORD dwSize, dwRet;
DWORD dwAmt;
DWORD nRead;
if( !osDuplicateHandle(GetCurrentProcess(), pFile->h, GetCurrentProcess(),
&dupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS) ){
pFile->lastErrno = osGetLastError();
OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR\n", dupHandle));
return SQLITE_INT_TO_PTR(winLogError(SQLITE_IOERR, pFile->lastErrno,
"winPreCacheThread1", pFile->zPath));
}
dwSize = osSetFilePointer(dupHandle, 0, 0, FILE_END);
if( (dwSize==INVALID_SET_FILE_POINTER
&& ((lastErrno = osGetLastError())!=NO_ERROR)) ){
pFile->lastErrno = lastErrno;
osCloseHandle(dupHandle);
OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR_SEEK\n", dupHandle));
return SQLITE_INT_TO_PTR(winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
"winPreCacheThread2", pFile->zPath));
}
dwRet = osSetFilePointer(dupHandle, 0, 0, FILE_BEGIN);
if( (dwRet==INVALID_SET_FILE_POINTER
&& ((lastErrno = osGetLastError())!=NO_ERROR)) ){
pFile->lastErrno = lastErrno;
osCloseHandle(dupHandle);
OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR_SEEK\n", dupHandle));
return SQLITE_INT_TO_PTR(winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
"winPreCacheThread3", pFile->zPath));
}
dwAmt = 4194304; /* TODO: Tuning. */
if( dwSize<dwAmt ){
dwAmt = dwSize;
}
pBuf = sqlite3MallocZero( dwAmt );
if( pBuf==0 ){
osCloseHandle(dupHandle);
OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR_NOMEM\n", dupHandle));
return SQLITE_INT_TO_PTR(SQLITE_IOERR_NOMEM);
}
while( 1 ){
if( !osReadFile(dupHandle, pBuf, dwAmt, &nRead, 0) ){
pFile->lastErrno = osGetLastError();
sqlite3_free(pBuf);
osCloseHandle(dupHandle);
OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR_READ\n", dupHandle));
return SQLITE_INT_TO_PTR(winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
"winPreCacheThread4", pFile->zPath));
}
if( nRead<dwAmt ){
sqlite3_free(pBuf);
osCloseHandle(dupHandle);
OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR_SHORT_READ\n", dupHandle));
return SQLITE_INT_TO_PTR(winLogError(SQLITE_IOERR_SHORT_READ,
pFile->lastErrno,
"winPreCacheThread5", pFile->zPath));
}
dwSize -= dwAmt;
if( dwSize==0 ){
break;
}
}
sqlite3_free(pBuf);
osCloseHandle(dupHandle);
return SQLITE_INT_TO_PTR(SQLITE_OK);
}
#endif
/*
** Windows will only let you create file view mappings
** on allocation size granularity boundaries.
@@ -4732,6 +4795,15 @@ static int winOpen(
pFile->mmapSizeActual = 0;
pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap;
#endif
#if SQLITE_MAX_WORKER_THREADS>0
sqlite3ThreadCreate(&pFile->preCacheThread, winPreCacheThread, pFile);
{
void *pOut = 0;
sqlite3ThreadJoin(pFile->preCacheThread, &pOut);
pFile->preCacheThread = 0;
}
#endif
OpenCounter(+1);
return rc;
@@ -5450,7 +5522,7 @@ int sqlite3_os_init(void){
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
assert( ArraySize(aSyscall)==76 );
assert( ArraySize(aSyscall)==77 );
/* get memory map allocation granularity */
memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
-67
View File
@@ -1,67 +0,0 @@
/*
** 2013 November 25
**
** 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 code that is specific to Windows.
*/
#ifndef _OS_WIN_H_
#define _OS_WIN_H_
/*
** Include the primary Windows SDK header file.
*/
#include "windows.h"
#ifdef __CYGWIN__
# include <sys/cygwin.h>
# include <errno.h> /* amalgamator: dontcache */
#endif
/*
** Determine if we are dealing with Windows NT.
**
** We ought to be able to determine if we are compiling for Windows 9x or
** Windows NT using the _WIN32_WINNT macro as follows:
**
** #if defined(_WIN32_WINNT)
** # define SQLITE_OS_WINNT 1
** #else
** # define SQLITE_OS_WINNT 0
** #endif
**
** However, Visual Studio 2005 does not set _WIN32_WINNT by default, as
** it ought to, so the above test does not work. We'll just assume that
** everything is Windows NT unless the programmer explicitly says otherwise
** by setting SQLITE_OS_WINNT to 0.
*/
#if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT)
# define SQLITE_OS_WINNT 1
#endif
/*
** Determine if we are dealing with Windows CE - which has a much reduced
** API.
*/
#if defined(_WIN32_WCE)
# define SQLITE_OS_WINCE 1
#else
# define SQLITE_OS_WINCE 0
#endif
/*
** Determine if we are dealing with WinRT, which provides only a subset of
** the full Win32 API.
*/
#if !defined(SQLITE_OS_WINRT)
# define SQLITE_OS_WINRT 0
#endif
#endif /* _OS_WIN_H_ */
+89 -60
View File
@@ -455,28 +455,43 @@ static KeyInfo *keyInfoFromExprList(
);
/*
** Insert code into "v" that will push the record in register regData
** into the sorter.
** Generate code that will push the record in registers regData
** through regData+nData-1 onto the sorter.
*/
static void pushOntoSorter(
Parse *pParse, /* Parser context */
SortCtx *pSort, /* Information about the ORDER BY clause */
Select *pSelect, /* The whole SELECT statement */
int regData /* Register holding data to be sorted */
int regData, /* First register holding data to be sorted */
int nData, /* Number of elements in the data array */
int nPrefixReg /* No. of reg prior to regData available for use */
){
Vdbe *v = pParse->pVdbe;
int nExpr = pSort->pOrderBy->nExpr;
int regRecord = ++pParse->nMem;
int regBase = pParse->nMem+1;
int nOBSat = pSort->nOBSat;
int op;
Vdbe *v = pParse->pVdbe; /* Stmt under construction */
int bSeq = ((pSort->sortFlags & SORTFLAG_UseSorter)==0);
int nExpr = pSort->pOrderBy->nExpr; /* No. of ORDER BY terms */
int nBase = nExpr + bSeq + nData; /* Fields in sorter record */
int regBase; /* Regs for sorter record */
int regRecord = ++pParse->nMem; /* Assembled sorter record */
int nOBSat = pSort->nOBSat; /* ORDER BY terms to skip */
int op; /* Opcode to add sorter record to sorter */
pParse->nMem += nExpr+2; /* nExpr+2 registers allocated at regBase */
sqlite3ExprCacheClear(pParse);
sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, 0);
sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nExpr+2-nOBSat,regRecord);
assert( bSeq==0 || bSeq==1 );
if( nPrefixReg ){
assert( nPrefixReg==nExpr+bSeq );
regBase = regData - nExpr - bSeq;
}else{
regBase = pParse->nMem + 1;
pParse->nMem += nBase;
}
sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, SQLITE_ECEL_DUP);
if( bSeq ){
sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
}
if( nPrefixReg==0 ){
sqlite3VdbeAddOp3(v, OP_Move, regData, regBase+nExpr+bSeq, nData);
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord);
if( nOBSat>0 ){
int regPrevKey; /* The first nOBSat columns of the previous row */
int addrFirst; /* Address of the OP_IfNot opcode */
@@ -487,12 +502,17 @@ static void pushOntoSorter(
regPrevKey = pParse->nMem+1;
pParse->nMem += pSort->nOBSat;
nKey = nExpr - pSort->nOBSat + 1;
addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr); VdbeCoverage(v);
nKey = nExpr - pSort->nOBSat + bSeq;
if( bSeq ){
addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr);
}else{
addrFirst = sqlite3VdbeAddOp1(v, OP_SequenceTest, pSort->iECursor);
}
VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat);
pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex);
if( pParse->db->mallocFailed ) return;
pOp->p2 = nKey + 1;
pOp->p2 = nKey + nData;
pKI = pOp->p4.pKeyInfo;
memset(pKI->aSortOrder, 0, pKI->nField); /* Makes OP_Jump below testable */
sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
@@ -627,6 +647,7 @@ static void selectInnerLoop(
int eDest = pDest->eDest; /* How to dispose of results */
int iParm = pDest->iSDParm; /* First argument to disposal method */
int nResultCol; /* Number of result columns */
int nPrefixReg = 0; /* Number of extra registers before regResult */
assert( v );
assert( pEList!=0 );
@@ -642,6 +663,11 @@ static void selectInnerLoop(
nResultCol = pEList->nExpr;
if( pDest->iSdst==0 ){
if( pSort ){
nPrefixReg = pSort->pOrderBy->nExpr;
if( !(pSort->sortFlags & SORTFLAG_UseSorter) ) nPrefixReg++;
pParse->nMem += nPrefixReg;
}
pDest->iSdst = pParse->nMem+1;
pParse->nMem += nResultCol;
}else if( pDest->iSdst+nResultCol > pParse->nMem ){
@@ -758,10 +784,10 @@ static void selectInnerLoop(
case SRT_DistFifo:
case SRT_Table:
case SRT_EphemTab: {
int r1 = sqlite3GetTempReg(pParse);
int r1 = sqlite3GetTempRange(pParse, nPrefixReg+1);
testcase( eDest==SRT_Table );
testcase( eDest==SRT_EphemTab );
sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg);
#ifndef SQLITE_OMIT_CTE
if( eDest==SRT_DistFifo ){
/* If the destination is DistFifo, then cursor (iParm+1) is open
@@ -776,7 +802,7 @@ static void selectInnerLoop(
}
#endif
if( pSort ){
pushOntoSorter(pParse, pSort, p, r1);
pushOntoSorter(pParse, pSort, p, r1+nPrefixReg, 1, nPrefixReg);
}else{
int r2 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2);
@@ -784,7 +810,7 @@ static void selectInnerLoop(
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
sqlite3ReleaseTempReg(pParse, r2);
}
sqlite3ReleaseTempReg(pParse, r1);
sqlite3ReleaseTempRange(pParse, r1, nPrefixReg+1);
break;
}
@@ -802,7 +828,7 @@ static void selectInnerLoop(
** ORDER BY in this case since the order of entries in the set
** does not matter. But there might be a LIMIT clause, in which
** case the order does matter */
pushOntoSorter(pParse, pSort, p, regResult);
pushOntoSorter(pParse, pSort, p, regResult, 1, nPrefixReg);
}else{
int r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1);
@@ -828,7 +854,7 @@ static void selectInnerLoop(
case SRT_Mem: {
assert( nResultCol==1 );
if( pSort ){
pushOntoSorter(pParse, pSort, p, regResult);
pushOntoSorter(pParse, pSort, p, regResult, 1, nPrefixReg);
}else{
sqlite3ExprCodeMove(pParse, regResult, iParm, 1);
/* The LIMIT clause will jump out of the loop for us */
@@ -842,10 +868,7 @@ static void selectInnerLoop(
testcase( eDest==SRT_Coroutine );
testcase( eDest==SRT_Output );
if( pSort ){
int r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1);
pushOntoSorter(pParse, pSort, p, r1);
sqlite3ReleaseTempReg(pParse, r1);
pushOntoSorter(pParse, pSort, p, regResult, nResultCol, nPrefixReg);
}else if( eDest==SRT_Coroutine ){
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
}else{
@@ -1125,46 +1148,62 @@ static void generateSortTail(
int addr;
int addrOnce = 0;
int iTab;
int pseudoTab = 0;
ExprList *pOrderBy = pSort->pOrderBy;
int eDest = pDest->eDest;
int iParm = pDest->iSDParm;
int regRow;
int regRowid;
int nKey;
int iSortTab; /* Sorter cursor to read from */
int nSortData; /* Trailing values to read from sorter */
u8 p5; /* p5 parameter for 1st OP_Column */
int i;
int bSeq; /* True if sorter record includes seq. no. */
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
struct ExprList_item *aOutEx = p->pEList->a;
#endif
if( pSort->labelBkOut ){
sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBreak);
sqlite3VdbeResolveLabel(v, pSort->labelBkOut);
addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
}
iTab = pSort->iECursor;
regRow = sqlite3GetTempReg(pParse);
if( eDest==SRT_Output || eDest==SRT_Coroutine ){
pseudoTab = pParse->nTab++;
sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn);
regRowid = 0;
regRow = pDest->iSdst;
nSortData = nColumn;
}else{
regRowid = sqlite3GetTempReg(pParse);
regRow = sqlite3GetTempReg(pParse);
nSortData = 1;
}
nKey = pOrderBy->nExpr - pSort->nOBSat;
if( pSort->sortFlags & SORTFLAG_UseSorter ){
int regSortOut = ++pParse->nMem;
int ptab2 = pParse->nTab++;
sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, nKey+2);
iSortTab = pParse->nTab++;
if( pSort->labelBkOut ){
addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
}
sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
VdbeCoverage(v);
codeOffset(v, p->iOffset, addrContinue);
sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
sqlite3VdbeAddOp3(v, OP_Column, ptab2, nKey+1, regRow);
sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
p5 = OPFLAG_CLEARCACHE;
bSeq = 0;
}else{
if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
codeOffset(v, p->iOffset, addrContinue);
sqlite3VdbeAddOp3(v, OP_Column, iTab, nKey+1, regRow);
iSortTab = iTab;
p5 = 0;
bSeq = 1;
}
for(i=0; i<nSortData; i++){
sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
if( i==0 ) sqlite3VdbeChangeP5(v, p5);
VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
}
switch( eDest ){
case SRT_Table:
@@ -1193,17 +1232,9 @@ static void generateSortTail(
}
#endif
default: {
int i;
assert( eDest==SRT_Output || eDest==SRT_Coroutine );
testcase( eDest==SRT_Output );
testcase( eDest==SRT_Coroutine );
for(i=0; i<nColumn; i++){
assert( regRow!=pDest->iSdst+i );
sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iSdst+i);
if( i==0 ){
sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
}
}
if( eDest==SRT_Output ){
sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn);
sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn);
@@ -1213,9 +1244,10 @@ static void generateSortTail(
break;
}
}
sqlite3ReleaseTempReg(pParse, regRow);
sqlite3ReleaseTempReg(pParse, regRowid);
if( regRowid ){
sqlite3ReleaseTempReg(pParse, regRow);
sqlite3ReleaseTempReg(pParse, regRowid);
}
/* The bottom of the loop
*/
sqlite3VdbeResolveLabel(v, addrContinue);
@@ -1226,9 +1258,6 @@ static void generateSortTail(
}
if( pSort->regReturn ) sqlite3VdbeAddOp1(v, OP_Return, pSort->regReturn);
sqlite3VdbeResolveLabel(v, addrBreak);
if( eDest==SRT_Output || eDest==SRT_Coroutine ){
sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0);
}
}
/*
@@ -4758,8 +4787,9 @@ int sqlite3Select(
sSort.iECursor = pParse->nTab++;
sSort.addrSortIndex =
sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
sSort.iECursor, sSort.pOrderBy->nExpr+2, 0,
(char*)pKeyInfo, P4_KEYINFO);
sSort.iECursor, sSort.pOrderBy->nExpr+1+pEList->nExpr, 0,
(char*)pKeyInfo, P4_KEYINFO
);
}else{
sSort.addrSortIndex = -1;
}
@@ -4890,7 +4920,7 @@ int sqlite3Select(
sNC.pSrcList = pTabList;
sNC.pAggInfo = &sAggInfo;
sAggInfo.mnReg = pParse->nMem+1;
sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0;
sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0;
sAggInfo.pGroupBy = pGroupBy;
sqlite3ExprAnalyzeAggList(&sNC, pEList);
sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy);
@@ -4983,8 +5013,8 @@ int sqlite3Select(
groupBySort = 1;
nGroupBy = pGroupBy->nExpr;
nCol = nGroupBy + 1;
j = nGroupBy+1;
nCol = nGroupBy;
j = nGroupBy;
for(i=0; i<sAggInfo.nColumn; i++){
if( sAggInfo.aCol[i].iSorterColumn>=j ){
nCol++;
@@ -4994,8 +5024,7 @@ int sqlite3Select(
regBase = sqlite3GetTempRange(pParse, nCol);
sqlite3ExprCacheClear(pParse);
sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0);
sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx,regBase+nGroupBy);
j = nGroupBy+1;
j = nGroupBy;
for(i=0; i<sAggInfo.nColumn; i++){
struct AggInfo_col *pCol = &sAggInfo.aCol[i];
if( pCol->iSorterColumn>=j ){
+2 -1
View File
@@ -3536,7 +3536,8 @@ static void main_init(struct callback_data *data) {
sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
sqlite3_config(SQLITE_CONFIG_WORKER_THREADS, 4);
}
/*
+19 -3
View File
@@ -1715,6 +1715,16 @@ struct sqlite3_mem_methods {
** SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
** that specifies the maximum size of the created heap.
** </dl>
**
** [[SQLITE_CONFIG_WORKER_THREADS]]
** <dt>SQLITE_CONFIG_WORKER_THREADS
** <dd>^SQLITE_CONFIG_WORKER_THREADS takes a single argument of type int.
** It is used to set the number of background worker threads that may be
** launched when sorting large amounts of data. A value of 0 means launch
** no background threads at all. The maximum number of background threads
** allowed is configured at build-time by the SQLITE_MAX_WORKER_THREADS
** pre-processor option.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
@@ -1739,6 +1749,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */
#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
#define SQLITE_CONFIG_WORKER_THREADS 24 /* int nWorker */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -5817,10 +5828,12 @@ int sqlite3_vfs_unregister(sqlite3_vfs*);
** <li> SQLITE_MUTEX_RECURSIVE
** <li> SQLITE_MUTEX_STATIC_MASTER
** <li> SQLITE_MUTEX_STATIC_MEM
** <li> SQLITE_MUTEX_STATIC_MEM2
** <li> SQLITE_MUTEX_STATIC_OPEN
** <li> SQLITE_MUTEX_STATIC_PRNG
** <li> SQLITE_MUTEX_STATIC_LRU
** <li> SQLITE_MUTEX_STATIC_LRU2
** <li> SQLITE_MUTEX_STATIC_PMEM
** <li> SQLITE_MUTEX_STATIC_APP1
** <li> SQLITE_MUTEX_STATIC_APP2
** </ul>)^
**
** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
@@ -6024,6 +6037,8 @@ int sqlite3_mutex_notheld(sqlite3_mutex*);
#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */
#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */
#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */
#define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */
#define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */
/*
** CAPI3REF: Retrieve the mutex for a database connection
@@ -6119,7 +6134,8 @@ int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
#define SQLITE_TESTCTRL_BYTEORDER 22
#define SQLITE_TESTCTRL_LAST 22
#define SQLITE_TESTCTRL_SORTER_MMAP 23
#define SQLITE_TESTCTRL_LAST 23
/*
** CAPI3REF: SQLite Runtime Status
+39 -1
View File
@@ -422,6 +422,26 @@
# define SQLITE_TEMP_STORE_xc 1 /* Exclude from ctime.c */
#endif
/*
** If no value has been provided for SQLITE_MAX_WORKER_THREADS, or if
** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it
** to zero.
*/
#if SQLITE_TEMP_STORE==3
# undef SQLITE_MAX_WORKER_THREADS
#endif
#ifndef SQLITE_MAX_WORKER_THREADS
# define SQLITE_MAX_WORKER_THREADS 0
#endif
#ifndef SQLITE_DEFAULT_WORKER_THREADS
# define SQLITE_DEFAULT_WORKER_THREADS 0
#endif
#if SQLITE_DEFAULT_WORKER_THREADS>SQLITE_MAX_WORKER_THREADS
# undef SQLITE_MAX_WORKER_THREADS
# define SQLITE_MAX_WORKER_THREADS SQLITE_DEFAULT_WORKER_THREADS
#endif
/*
** GCC does not define the offsetof() macro so we'll have to do it
** ourselves.
@@ -805,6 +825,7 @@ typedef struct PrintfArguments PrintfArguments;
typedef struct RowSet RowSet;
typedef struct Savepoint Savepoint;
typedef struct Select Select;
typedef struct SQLiteThread SQLiteThread;
typedef struct SelectDest SelectDest;
typedef struct SrcList SrcList;
typedef struct StrAccum StrAccum;
@@ -984,6 +1005,7 @@ struct sqlite3 {
int nChange; /* Value returned by sqlite3_changes() */
int nTotalChange; /* Value returned by sqlite3_total_changes() */
int aLimit[SQLITE_N_LIMIT]; /* Limits */
int nMaxSorterMmap; /* Maximum size of regions mapped by sorter */
struct sqlite3InitInfo { /* Information used during initialization */
int newTnum; /* Rootpage of table being initialized */
u8 iDb; /* Which db file is being initialized */
@@ -1644,7 +1666,7 @@ struct UnpackedRecord {
KeyInfo *pKeyInfo; /* Collation and sort-order information */
u16 nField; /* Number of entries in apMem[] */
i8 default_rc; /* Comparison result if keys are equal */
u8 isCorrupt; /* Corruption detected by xRecordCompare() */
u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
Mem *aMem; /* Values */
int r1; /* Value to return if (lhs > rhs) */
int r2; /* Value to return if (rhs < lhs) */
@@ -2702,6 +2724,7 @@ struct Sqlite3Config {
int nPage; /* Number of pages in pPage[] */
int mxParserStack; /* maximum depth of the parser stack */
int sharedCacheEnabled; /* true if shared-cache mode enabled */
int nWorker; /* Number of worker threads to use */
/* The above might be initialized to non-zero. The following need to always
** initially be zero, however. */
int isInit; /* True after initialization has finished */
@@ -3653,4 +3676,19 @@ SQLITE_EXTERN void (*sqlite3IoTrace)(const char*,...);
#define MEMTYPE_PCACHE 0x08 /* Page cache allocations */
#define MEMTYPE_DB 0x10 /* Uses sqlite3DbMalloc, not sqlite_malloc */
/*
** Threading interface
*/
#if SQLITE_MAX_WORKER_THREADS>0
int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*);
int sqlite3ThreadJoin(SQLiteThread*, void**);
#endif
/*
** Win32 interface
*/
#if SQLITE_OS_WIN
DWORD sqlite3Win32Wait(HANDLE hObject);
#endif
#endif /* _SQLITEINT_H_ */
+164 -4
View File
@@ -14,10 +14,6 @@
** testing of the SQLite library.
*/
#include "sqliteInt.h"
#if SQLITE_OS_WIN
# include "os_win.h"
#endif
#include "vdbeInt.h"
#include "tcl.h"
#include <stdlib.h>
@@ -2707,6 +2703,46 @@ bad_args:
return TCL_ERROR;
}
/*
** Usage: add_test_utf16bin_collate <db ptr>
**
** Add a utf-16 collation sequence named "utf16bin" to the database
** handle. This collation sequence compares arguments in the same way as the
** built-in collation "binary".
*/
static int test_utf16bin_collate_func(
void *pCtx,
int nA, const void *zA,
int nB, const void *zB
){
int nCmp = (nA>nB ? nB : nA);
int res = memcmp(zA, zB, nCmp);
if( res==0 ) res = nA - nB;
return res;
}
static int test_utf16bin_collate(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3 *db;
int rc;
if( objc!=2 ) goto bad_args;
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
rc = sqlite3_create_collation(db, "utf16bin", SQLITE_UTF16, 0,
test_utf16bin_collate_func
);
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
return TCL_OK;
bad_args:
Tcl_WrongNumArgs(interp, 1, objv, "DB");
return TCL_ERROR;
}
/*
** When the collation needed callback is invoked, record the name of
** the requested collating function here. The recorded name is linked
@@ -5848,6 +5884,7 @@ static int test_test_control(
int i;
} aVerb[] = {
{ "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT },
{ "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP },
};
int iVerb;
int iFlag;
@@ -5875,6 +5912,19 @@ static int test_test_control(
sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, val);
break;
}
case SQLITE_TESTCTRL_SORTER_MMAP: {
int val;
sqlite3 *db;
if( objc!=4 ){
Tcl_WrongNumArgs(interp, 2, objv, "DB LIMIT");
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR;
if( Tcl_GetIntFromObj(interp, objv[3], &val) ) return TCL_ERROR;
sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, val);
break;
}
}
Tcl_ResetResult(interp);
@@ -6286,6 +6336,113 @@ static int tclLoadStaticExtensionCmd(
return TCL_OK;
}
/*
** sorter_test_fakeheap BOOL
**
*/
static int sorter_test_fakeheap(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int bArg;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "BOOL");
return TCL_ERROR;
}
if( Tcl_GetBooleanFromObj(interp, objv[1], &bArg) ){
return TCL_ERROR;
}
if( bArg ){
if( sqlite3GlobalConfig.pHeap==0 ){
sqlite3GlobalConfig.pHeap = SQLITE_INT_TO_PTR(-1);
}
}else{
if( sqlite3GlobalConfig.pHeap==SQLITE_INT_TO_PTR(-1) ){
sqlite3GlobalConfig.pHeap = 0;
}
}
Tcl_ResetResult(interp);
return TCL_OK;
}
/*
** sorter_test_sort4_helper DB SQL1 NSTEP SQL2
**
** Compile SQL statement $SQL1 and step it $NSTEP times. For each row,
** check that the leftmost and rightmost columns returned are both integers,
** and that both contain the same value.
**
** Then execute statement $SQL2. Check that the statement returns the same
** set of integers in the same order as in the previous step (using $SQL1).
*/
static int sorter_test_sort4_helper(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
const char *zSql1;
const char *zSql2;
int nStep;
int iStep;
int iCksum1 = 0;
int iCksum2 = 0;
int rc;
int iB;
sqlite3 *db;
sqlite3_stmt *pStmt;
if( objc!=5 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB SQL1 NSTEP SQL2");
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
zSql1 = Tcl_GetString(objv[2]);
if( Tcl_GetIntFromObj(interp, objv[3], &nStep) ) return TCL_ERROR;
zSql2 = Tcl_GetString(objv[4]);
rc = sqlite3_prepare_v2(db, zSql1, -1, &pStmt, 0);
if( rc!=SQLITE_OK ) goto sql_error;
iB = sqlite3_column_count(pStmt)-1;
for(iStep=0; iStep<nStep && SQLITE_ROW==sqlite3_step(pStmt); iStep++){
int a = sqlite3_column_int(pStmt, 0);
if( a!=sqlite3_column_int(pStmt, iB) ){
Tcl_AppendResult(interp, "data error: (a!=b)", 0);
return TCL_ERROR;
}
iCksum1 += (iCksum1 << 3) + a;
}
rc = sqlite3_finalize(pStmt);
if( rc!=SQLITE_OK ) goto sql_error;
rc = sqlite3_prepare_v2(db, zSql2, -1, &pStmt, 0);
if( rc!=SQLITE_OK ) goto sql_error;
for(iStep=0; SQLITE_ROW==sqlite3_step(pStmt); iStep++){
int a = sqlite3_column_int(pStmt, 0);
iCksum2 += (iCksum2 << 3) + a;
}
rc = sqlite3_finalize(pStmt);
if( rc!=SQLITE_OK ) goto sql_error;
if( iCksum1!=iCksum2 ){
Tcl_AppendResult(interp, "checksum mismatch", 0);
return TCL_ERROR;
}
return TCL_OK;
sql_error:
Tcl_AppendResult(interp, "sql error: ", sqlite3_errmsg(db), 0);
return TCL_ERROR;
}
/*
** Register commands with the TCL interpreter.
@@ -6485,6 +6642,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "add_test_collate", test_collate, 0 },
{ "add_test_collate_needed", test_collate_needed, 0 },
{ "add_test_function", test_function, 0 },
{ "add_test_utf16bin_collate", test_utf16bin_collate, 0 },
#endif
{ "sqlite3_test_errstr", test_errstr, 0 },
{ "tcl_variable_type", tcl_variable_type, 0 },
@@ -6518,6 +6676,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "getrusage", test_getrusage },
#endif
{ "load_static_extension", tclLoadStaticExtensionCmd },
{ "sorter_test_fakeheap", sorter_test_fakeheap },
{ "sorter_test_sort4_helper", sorter_test_sort4_helper },
};
static int bitmask_size = sizeof(Bitmask)*8;
int i;
+4 -4
View File
@@ -20,10 +20,6 @@
#include "sqliteLimit.h"
#include "sqliteInt.h"
#if SQLITE_OS_WIN
# include "os_win.h"
#endif
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
@@ -103,6 +99,10 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "mmap", "0", TCL_GLOBAL_ONLY);
#endif
Tcl_SetVar2(interp, "sqlite_options", "worker_threads",
STRINGVALUE(SQLITE_MAX_WORKER_THREADS), TCL_GLOBAL_ONLY
);
#if 1 /* def SQLITE_MEMDEBUG */
Tcl_SetVar2(interp, "sqlite_options", "memdebug", "1", TCL_GLOBAL_ONLY);
#else
+27
View File
@@ -1253,6 +1253,32 @@ static int test_config_cis(
return TCL_OK;
}
/*
** Usage: sqlite3_config_worker_threads N
*/
static int test_config_worker_threads(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int rc;
int nThread;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "N");
return TCL_ERROR;
}
if( Tcl_GetIntFromObj(interp, objv[1], &nThread) ){
return TCL_ERROR;
}
rc = sqlite3_config(SQLITE_CONFIG_WORKER_THREADS, nThread);
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
return TCL_OK;
}
/*
** Usage: sqlite3_dump_memsys3 FILENAME
** sqlite3_dump_memsys5 FILENAME
@@ -1506,6 +1532,7 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){
{ "sqlite3_config_error", test_config_error ,0 },
{ "sqlite3_config_uri", test_config_uri ,0 },
{ "sqlite3_config_cis", test_config_cis ,0 },
{ "sqlite3_config_worker_threads", test_config_worker_threads ,0 },
{ "sqlite3_db_config_lookaside",test_db_config_lookaside ,0 },
{ "sqlite3_dump_memsys3", test_dump_memsys3 ,3 },
{ "sqlite3_dump_memsys5", test_dump_memsys3 ,5 },
+1 -6
View File
@@ -70,12 +70,6 @@
*/
#include "sqlite3.h"
#include "os_setup.h"
#if SQLITE_OS_WIN
# include "os_win.h"
#endif
#include <string.h>
#include <assert.h>
@@ -227,6 +221,7 @@ static sqlite3_uint64 vfslog_time(){
return sTime.tv_usec + (sqlite3_uint64)sTime.tv_sec * 1000000;
}
#elif SQLITE_OS_WIN
#include <windows.h>
#include <time.h>
static sqlite3_uint64 vfslog_time(){
FILETIME ft;
+38 -2
View File
@@ -44,13 +44,49 @@
#define sqlite3_mutex_notheld(X) ((void)(X),1)
#endif /* SQLITE_THREADSAFE==0 */
#include "os_setup.h"
/*
** Figure out if we are dealing with Unix, Windows, or some other
** operating system. After the following block of preprocess macros,
** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, and SQLITE_OS_OTHER
** will defined to either 1 or 0. One of the four will be 1. The other
** three will be 0.
*/
#if defined(SQLITE_OS_OTHER)
# if SQLITE_OS_OTHER==1
# undef SQLITE_OS_UNIX
# define SQLITE_OS_UNIX 0
# undef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
# else
# undef SQLITE_OS_OTHER
# endif
#endif
#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER)
# define SQLITE_OS_OTHER 0
# ifndef SQLITE_OS_WIN
# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) \
|| defined(__MINGW32__) || defined(__BORLANDC__)
# define SQLITE_OS_WIN 1
# define SQLITE_OS_UNIX 0
# else
# define SQLITE_OS_WIN 0
# define SQLITE_OS_UNIX 1
# endif
# else
# define SQLITE_OS_UNIX 0
# endif
#else
# ifndef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
# endif
#endif
#if SQLITE_OS_UNIX
# include <unistd.h>
#endif
#if SQLITE_OS_WIN
# include "os_win.h"
# include <windows.h>
# include <io.h>
#endif
+6
View File
@@ -31,6 +31,12 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#if SQLITE_OS_UNIX
# include <unistd.h>
#endif
#if SQLITE_OS_WIN
# include <windows.h>
#endif
/* Make this callable from C++ */
#ifdef __cplusplus
+234
View File
@@ -0,0 +1,234 @@
/*
** 2012 July 21
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file presents a simple cross-platform threading interface for
** use internally by SQLite.
**
** A "thread" can be created using sqlite3ThreadCreate(). This thread
** runs independently of its creator until it is joined using
** sqlite3ThreadJoin(), at which point it terminates.
**
** Threads do not have to be real. It could be that the work of the
** "thread" is done by the main thread at either the sqlite3ThreadCreate()
** or sqlite3ThreadJoin() call. This is, in fact, what happens in
** single threaded systems. Nothing in SQLite requires multiple threads.
** This interface exists so that applications that want to take advantage
** of multiple cores can do so, while also allowing applications to stay
** single-threaded if desired.
*/
#include "sqliteInt.h"
#if SQLITE_MAX_WORKER_THREADS>0
/********************************* Unix Pthreads ****************************/
#if SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) && SQLITE_THREADSAFE>0
#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */
#include <pthread.h>
/* A running thread */
struct SQLiteThread {
pthread_t tid; /* Thread ID */
int done; /* Set to true when thread finishes */
void *pOut; /* Result returned by the thread */
void *(*xTask)(void*); /* The thread routine */
void *pIn; /* Argument to the thread */
};
/* Create a new thread */
int sqlite3ThreadCreate(
SQLiteThread **ppThread, /* OUT: Write the thread object here */
void *(*xTask)(void*), /* Routine to run in a separate thread */
void *pIn /* Argument passed into xTask() */
){
SQLiteThread *p;
assert( ppThread!=0 );
assert( xTask!=0 );
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
if( p==0 ) return SQLITE_NOMEM;
memset(p, 0, sizeof(*p));
p->xTask = xTask;
p->pIn = pIn;
if( sqlite3GlobalConfig.bCoreMutex==0
|| pthread_create(&p->tid, 0, xTask, pIn)!=0
){
p->done = 1;
p->pOut = xTask(pIn);
}
*ppThread = p;
return SQLITE_OK;
}
/* Get the results of the thread */
int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
int rc;
assert( ppOut!=0 );
if( p==0 ) return SQLITE_NOMEM;
if( p->done ){
*ppOut = p->pOut;
rc = SQLITE_OK;
}else{
rc = pthread_join(p->tid, ppOut);
}
sqlite3_free(p);
return rc ? SQLITE_ERROR : SQLITE_OK;
}
#endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */
/******************************** End Unix Pthreads *************************/
/********************************* Win32 Threads ****************************/
#if SQLITE_OS_WIN && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0
#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */
#include <process.h>
/* A running thread */
struct SQLiteThread {
uintptr_t tid; /* The thread handle */
void *(*xTask)(void*); /* The routine to run as a thread */
void *pIn; /* Argument to xTask */
void *pResult; /* Result of xTask */
};
/* Thread procedure Win32 compatibility shim */
static void sqlite3ThreadProc(
void *pArg /* IN: Pointer to the SQLiteThread structure */
){
SQLiteThread *p = (SQLiteThread *)pArg;
assert( p!=0 );
assert( p->xTask!=0 );
p->pResult = p->xTask(p->pIn);
_endthread();
}
/* Create a new thread */
int sqlite3ThreadCreate(
SQLiteThread **ppThread, /* OUT: Write the thread object here */
void *(*xTask)(void*), /* Routine to run in a separate thread */
void *pIn /* Argument passed into xTask() */
){
SQLiteThread *p;
assert( ppThread!=0 );
assert( xTask!=0 );
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
if( p==0 ) return SQLITE_NOMEM;
if( sqlite3GlobalConfig.bCoreMutex==0 ){
memset(p, 0, sizeof(*p));
}else{
p->xTask = xTask;
p->pIn = pIn;
p->tid = _beginthread(sqlite3ThreadProc, 0, p);
if( p->tid==(uintptr_t)-1 ){
memset(p, 0, sizeof(*p));
}
}
if( p->xTask==0 ){
p->pResult = xTask(pIn);
}
*ppThread = p;
return SQLITE_OK;
}
/* Get the results of the thread */
int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
DWORD rc;
assert( ppOut!=0 );
if( p==0 ) return SQLITE_NOMEM;
if( p->xTask==0 ){
rc = WAIT_OBJECT_0;
}else{
rc = sqlite3Win32Wait((HANDLE)p->tid);
assert( rc!=WAIT_IO_COMPLETION );
}
if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult;
sqlite3_free(p);
return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR;
}
#endif /* SQLITE_OS_WIN && !SQLITE_OS_WINRT */
/******************************** End Win32 Threads *************************/
/********************************* Single-Threaded **************************/
#ifndef SQLITE_THREADS_IMPLEMENTED
/*
** This implementation does not actually create a new thread. It does the
** work of the thread in the main thread, when either the thread is created
** or when it is joined
*/
/* A running thread */
struct SQLiteThread {
void *(*xTask)(void*); /* The routine to run as a thread */
void *pIn; /* Argument to xTask */
void *pResult; /* Result of xTask */
};
/* Create a new thread */
int sqlite3ThreadCreate(
SQLiteThread **ppThread, /* OUT: Write the thread object here */
void *(*xTask)(void*), /* Routine to run in a separate thread */
void *pIn /* Argument passed into xTask() */
){
SQLiteThread *p;
assert( ppThread!=0 );
assert( xTask!=0 );
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
if( p==0 ) return SQLITE_NOMEM;
if( (SQLITE_PTR_TO_INT(p)/17)&1 ){
p->xTask = xTask;
p->pIn = pIn;
}else{
p->xTask = 0;
p->pResult = xTask(pIn);
}
*ppThread = p;
return SQLITE_OK;
}
/* Get the results of the thread */
int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
assert( ppOut!=0 );
if( p==0 ) return SQLITE_NOMEM;
if( p->xTask ){
*ppOut = p->xTask(p->pIn);
}else{
*ppOut = p->pResult;
}
sqlite3_free(p);
#if defined(SQLITE_TEST)
{
void *pTstAlloc = sqlite3Malloc(10);
if (!pTstAlloc) return SQLITE_NOMEM;
sqlite3_free(pTstAlloc);
}
#endif
return SQLITE_OK;
}
#endif /* !defined(SQLITE_THREADS_IMPLEMENTED) */
/****************************** End Single-Threaded *************************/
#endif /* SQLITE_MAX_WORKER_THREADS>0 */
+27 -4
View File
@@ -3390,11 +3390,15 @@ case OP_OpenEphemeral: {
break;
}
/* Opcode: SorterOpen P1 P2 * P4 *
/* Opcode: SorterOpen P1 P2 P3 P4 *
**
** This opcode works like OP_OpenEphemeral except that it opens
** a transient index that is specifically designed to sort large
** tables using an external merge-sort algorithm.
**
** If argument P3 is non-zero, then it indicates that the sorter may
** assume that a stable sort considering the first P3 fields of each
** key is sufficient to produce the required results.
*/
case OP_SorterOpen: {
VdbeCursor *pCx;
@@ -3406,7 +3410,25 @@ case OP_SorterOpen: {
pCx->pKeyInfo = pOp->p4.pKeyInfo;
assert( pCx->pKeyInfo->db==db );
assert( pCx->pKeyInfo->enc==ENC(db) );
rc = sqlite3VdbeSorterInit(db, pCx);
rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx);
break;
}
/* Opcode: SequenceTest P1 P2 * * *
** Synopsis: if( cursor[P1].ctr++ ) pc = P2
**
** P1 is a sorter cursor. If the sequence counter is currently zero, jump
** to P2. Regardless of whether or not the jump is taken, increment the
** the sequence value.
*/
case OP_SequenceTest: {
VdbeCursor *pC;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC->pSorter );
if( (pC->seqCount++)==0 ){
pc = pOp->p2 - 1;
}
break;
}
@@ -4212,6 +4234,7 @@ case OP_SorterCompare: {
assert( pOp->p4type==P4_INT32 );
pIn3 = &aMem[pOp->p3];
nIgnore = pOp->p4.i;
res = 0;
rc = sqlite3VdbeSorterCompare(pC, pIn3, nIgnore, &res);
VdbeBranchTaken(res!=0,2);
if( res ){
@@ -4462,7 +4485,7 @@ case OP_Rewind: { /* jump */
assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) );
res = 1;
if( isSorter(pC) ){
rc = sqlite3VdbeSorterRewind(db, pC, &res);
rc = sqlite3VdbeSorterRewind(pC, &res);
}else{
pCrsr = pC->pCursor;
assert( pCrsr );
@@ -4621,7 +4644,7 @@ case OP_IdxInsert: { /* in2 */
rc = ExpandBlob(pIn2);
if( rc==SQLITE_OK ){
if( isSorter(pC) ){
rc = sqlite3VdbeSorterWrite(db, pC, pIn2);
rc = sqlite3VdbeSorterWrite(pC, pIn2);
}else{
nKey = pIn2->n;
zKey = pIn2->z;
+3 -3
View File
@@ -437,13 +437,13 @@ void sqlite3VdbeFrameDelete(VdbeFrame*);
int sqlite3VdbeFrameRestore(VdbeFrame *);
int sqlite3VdbeTransferError(Vdbe *p);
int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *);
int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *);
void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *);
void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *);
int sqlite3VdbeSorterWrite(sqlite3 *, const VdbeCursor *, Mem *);
int sqlite3VdbeSorterRewind(const VdbeCursor *, int *);
int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *);
int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
+35 -30
View File
@@ -3137,10 +3137,14 @@ void sqlite3VdbeRecordUnpack(
** sqlite3VdbeSerialGet() and sqlite3MemCompare() functions. It is used
** in assert() statements to ensure that the optimized code in
** sqlite3VdbeRecordCompare() returns results with these two primitives.
**
** Return true if the result of comparison is equivalent to desiredResult.
** Return false if there is a disagreement.
*/
static int vdbeRecordCompareDebug(
int nKey1, const void *pKey1, /* Left key */
const UnpackedRecord *pPKey2 /* Right key */
const UnpackedRecord *pPKey2, /* Right key */
int desiredResult /* Correct answer */
){
u32 d1; /* Offset into aKey[] of next data element */
u32 idx1; /* Offset into aKey[] of next header element */
@@ -3152,6 +3156,7 @@ static int vdbeRecordCompareDebug(
Mem mem1;
pKeyInfo = pPKey2->pKeyInfo;
if( pKeyInfo->db==0 ) return 1;
mem1.enc = pKeyInfo->enc;
mem1.db = pKeyInfo->db;
/* mem1.flags = 0; // Will be initialized by sqlite3VdbeSerialGet() */
@@ -3202,7 +3207,7 @@ static int vdbeRecordCompareDebug(
if( pKeyInfo->aSortOrder[i] ){
rc = -rc; /* Invert the result for DESC sort order. */
}
return rc;
goto debugCompareEnd;
}
i++;
}while( idx1<szHdr1 && i<pPKey2->nField );
@@ -3216,7 +3221,15 @@ static int vdbeRecordCompareDebug(
/* rc==0 here means that one of the keys ran out of fields and
** all the fields up to that point were equal. Return the the default_rc
** value. */
return pPKey2->default_rc;
rc = pPKey2->default_rc;
debugCompareEnd:
if( desiredResult==0 && rc==0 ) return 1;
if( desiredResult<0 && rc<0 ) return 1;
if( desiredResult>0 && rc>0 ) return 1;
if( CORRUPT_DB ) return 1;
if( pKeyInfo->db->mallocFailed ) return 1;
return 0;
}
#endif
@@ -3229,7 +3242,8 @@ static int vdbeRecordCompareDebug(
static int vdbeCompareMemString(
const Mem *pMem1,
const Mem *pMem2,
const CollSeq *pColl
const CollSeq *pColl,
u8 *prcErr /* If an OOM occurs, set to SQLITE_NOMEM */
){
if( pMem1->enc==pColl->enc ){
/* The strings are already in the correct encoding. Call the
@@ -3252,6 +3266,7 @@ static int vdbeCompareMemString(
rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
sqlite3VdbeMemRelease(&c1);
sqlite3VdbeMemRelease(&c2);
if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM;
return rc;
}
}
@@ -3334,7 +3349,7 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
assert( !pColl || pColl->xCmp );
if( pColl ){
return vdbeCompareMemString(pMem1, pMem2, pColl);
return vdbeCompareMemString(pMem1, pMem2, pColl, 0);
}
/* If a NULL pointer was passed as the collate function, fall through
** to the blob case and use memcmp(). */
@@ -3406,8 +3421,10 @@ static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){
** fields that appear in both keys are equal, then pPKey2->default_rc is
** returned.
**
** If database corruption is discovered, set pPKey2->isCorrupt to non-zero
** and return 0.
** If database corruption is discovered, set pPKey2->errCode to
** SQLITE_CORRUPT and return 0. If an OOM error is encountered,
** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the
** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db).
*/
int sqlite3VdbeRecordCompare(
int nKey1, const void *pKey1, /* Left key */
@@ -3438,7 +3455,7 @@ int sqlite3VdbeRecordCompare(
idx1 = getVarint32(aKey1, szHdr1);
d1 = szHdr1;
if( d1>(unsigned)nKey1 ){
pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT;
pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
return 0; /* Corruption */
}
i = 0;
@@ -3517,14 +3534,16 @@ int sqlite3VdbeRecordCompare(
testcase( (d1+mem1.n)==(unsigned)nKey1 );
testcase( (d1+mem1.n+1)==(unsigned)nKey1 );
if( (d1+mem1.n) > (unsigned)nKey1 ){
pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT;
pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
return 0; /* Corruption */
}else if( pKeyInfo->aColl[i] ){
mem1.enc = pKeyInfo->enc;
mem1.db = pKeyInfo->db;
mem1.flags = MEM_Str;
mem1.z = (char*)&aKey1[d1];
rc = vdbeCompareMemString(&mem1, pRhs, pKeyInfo->aColl[i]);
rc = vdbeCompareMemString(
&mem1, pRhs, pKeyInfo->aColl[i], &pPKey2->errCode
);
}else{
int nCmp = MIN(mem1.n, pRhs->n);
rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
@@ -3544,7 +3563,7 @@ int sqlite3VdbeRecordCompare(
testcase( (d1+nStr)==(unsigned)nKey1 );
testcase( (d1+nStr+1)==(unsigned)nKey1 );
if( (d1+nStr) > (unsigned)nKey1 ){
pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT;
pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
return 0; /* Corruption */
}else{
int nCmp = MIN(nStr, pRhs->n);
@@ -3564,11 +3583,7 @@ int sqlite3VdbeRecordCompare(
if( pKeyInfo->aSortOrder[i] ){
rc = -rc;
}
assert( CORRUPT_DB
|| (rc<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
|| (rc>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
|| pKeyInfo->db->mallocFailed
);
assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) );
assert( mem1.zMalloc==0 ); /* See comment below */
return rc;
}
@@ -3587,9 +3602,7 @@ int sqlite3VdbeRecordCompare(
/* rc==0 here means that one or both of the keys ran out of fields and
** all the fields up to that point were equal. Return the the default_rc
** value. */
assert( CORRUPT_DB
|| pPKey2->default_rc==vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)
);
assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) );
return pPKey2->default_rc;
}
@@ -3686,11 +3699,7 @@ static int vdbeRecordCompareInt(
res = pPKey2->default_rc;
}
assert( (res==0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)==0)
|| (res<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
|| (res>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
|| CORRUPT_DB
);
assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) );
return res;
}
@@ -3724,7 +3733,7 @@ static int vdbeRecordCompareString(
nStr = (serial_type-12) / 2;
if( (szHdr + nStr) > nKey1 ){
pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT;
pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
return 0; /* Corruption */
}
nCmp = MIN( pPKey2->aMem[0].n, nStr );
@@ -3750,11 +3759,7 @@ static int vdbeRecordCompareString(
}
}
assert( (res==0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)==0)
|| (res<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
|| (res>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
|| CORRUPT_DB
);
assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) );
return res;
}
+1813 -501
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -285,7 +285,7 @@ do_test fuzz-1.18 {
)
))
}
} {0 {{}}}
} {0 -4294967298}
# At one point the following INSERT statement caused an assert() to fail.
#
+42
View File
@@ -880,6 +880,48 @@ do_malloc_test 39 -tclprep {
db close
}
reset_db
add_test_utf16bin_collate db
do_execsql_test 40.1 {
CREATE TABLE t1(a);
INSERT INTO t1 VALUES('fghij');
INSERT INTO t1 VALUES('pqrst');
INSERT INTO t1 VALUES('abcde');
INSERT INTO t1 VALUES('uvwxy');
INSERT INTO t1 VALUES('klmno');
}
do_execsql_test 40.2 {
SELECT * FROM t1 ORDER BY 1 COLLATE utf16bin;
} {abcde fghij klmno pqrst uvwxy}
do_faultsim_test 40.3 -faults oom-trans* -body {
execsql {
SELECT * FROM t1 ORDER BY 1 COLLATE utf16bin;
}
} -test {
faultsim_test_result {0 {abcde fghij klmno pqrst uvwxy}}
faultsim_integrity_check
}
reset_db
add_test_utf16bin_collate db
set big [string repeat x 200]
do_execsql_test 41.1 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a COLLATE utf16bin);
INSERT INTO t1 VALUES('fghij' || $::big);
INSERT INTO t1 VALUES('pqrst' || $::big);
INSERT INTO t1 VALUES('abcde' || $::big);
INSERT INTO t1 VALUES('uvwxy' || $::big);
INSERT INTO t1 VALUES('klmno' || $::big);
CREATE INDEX i1 ON t1(a);
}
do_faultsim_test 41.2 -faults oom* -body {
execsql { SELECT * FROM t1 WHERE a = ('abcde' || $::big)}
} -test {
faultsim_test_result [list 0 "abcde$::big"]
faultsim_integrity_check
}
# Ensure that no file descriptors were leaked.
do_test malloc-99.X {
catch {db close}
+22 -1
View File
@@ -25,7 +25,6 @@ if {!$MEMDEBUG} {
return
}
# Construct a test database
#
forcedelete test.db.bu
@@ -116,6 +115,28 @@ ifcapable stat3 {
}
}
do_execsql_test 7.0 {
PRAGMA cache_size = 5;
}
do_faultsim_test 7 -faults oom-trans* -prep {
if {$iFail < 500} { set iFail 2000 }
if {$iFail > 1215} { set iFail 2000 }
} -body {
execsql {
WITH r(x,y) AS (
SELECT 1, randomblob(100)
UNION ALL
SELECT x+1, randomblob(100) FROM r
LIMIT 1000
)
SELECT count(x), length(y) FROM r GROUP BY (x%5)
}
} -test {
set res [list 200 100 200 100 200 100 200 100 200 100]
faultsim_test_result [list 0 $res]
}
# Ensure that no file descriptors were leaked.
do_test malloc-99.X {
catch {db close}
+8 -1
View File
@@ -112,6 +112,7 @@ set allquicktests [test_set $alltests -exclude {
incrvacuum_ioerr.test autovacuum_crash.test btree8.test shared_err.test
vtab_err.test walslow.test walcrash.test walcrash3.test
walthread.test rtree3.test indexfault.test securedel2.test
sort3.test sort4.test
}]
if {[info exists ::env(QUICKTEST_INCLUDE)]} {
set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)]
@@ -331,6 +332,12 @@ test_suite "coverage-analyze" -description {
analyze.test analyzeB.test mallocA.test
}
test_suite "coverage-sorter" -description {
Coverage tests for file vdbesort.c.
} -files {
sort.test sortfault.test
}
lappend ::testsuitelist xxx
#-------------------------------------------------------------------------
@@ -462,7 +469,7 @@ test_suite "multithread" -description {
} -files {
delete.test delete2.test insert.test rollback.test select1.test
select2.test trans.test update.test vacuum.test types.test
types2.test types3.test
types2.test types3.test sort4.test
} -shutdown {
catch {db close}
sqlite3_shutdown
+176 -3
View File
@@ -8,10 +8,10 @@
# 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 the CREATE TABLE statement.
#
# $Id: sort.test,v 1.25 2005/11/14 22:29:06 drh Exp $
# This file implements regression tests for SQLite library. The
# focus of this file is testing the sorter (code in vdbesort.c).
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -464,4 +464,177 @@ do_test sort-12.1 {
}
} {1 2 xxx 1 3 yyy 1 1 zzz}
#-------------------------------------------------------------------------
# Check that the sorter in vdbesort.c sorts in a stable fashion.
#
do_execsql_test sort-13.0 {
CREATE TABLE t10(a, b);
}
do_test sort-13.1 {
db transaction {
for {set i 0} {$i < 100000} {incr i} {
execsql { INSERT INTO t10 VALUES( $i/10, $i%10 ) }
}
}
} {}
do_execsql_test sort-13.2 {
SELECT a, b FROM t10 ORDER BY a;
} [db eval {SELECT a, b FROM t10 ORDER BY a, b}]
do_execsql_test sort-13.3 {
PRAGMA cache_size = 5;
SELECT a, b FROM t10 ORDER BY a;
} [db eval {SELECT a, b FROM t10 ORDER BY a, b}]
#-------------------------------------------------------------------------
# Sort some large ( > 4KiB) records.
#
proc cksum {x} {
set i1 1
set i2 2
binary scan $x c* L
foreach {a b} $L {
set i1 [expr (($i2<<3) + $a) & 0x7FFFFFFF]
set i2 [expr (($i1<<3) + $b) & 0x7FFFFFFF]
}
list $i1 $i2
}
db func cksum cksum
do_execsql_test sort-14.0 {
PRAGMA cache_size = 5;
CREATE TABLE t11(a, b);
INSERT INTO t11 VALUES(randomblob(5000), NULL);
INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --2
INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --3
INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --4
INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --5
INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --6
INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --7
INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --8
INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --9
UPDATE t11 SET b = cksum(a);
}
foreach {tn mmap_limit} {
1 0
2 1000000
} {
do_test sort-14.$tn {
sqlite3_test_control SQLITE_TESTCTRL_SORTER_MMAP db $mmap_limit
set prev ""
db eval { SELECT * FROM t11 ORDER BY b } {
if {$b != [cksum $a]} {error "checksum failed"}
if {[string compare $b $prev] < 0} {error "sort failed"}
set prev $b
}
set {} {}
} {}
}
#-------------------------------------------------------------------------
#
foreach {tn mmap_limit nWorker tmpstore coremutex fakeheap softheaplimit} {
1 0 3 file true false 0
2 0 3 file true true 0
3 0 0 file true false 0
4 1000000 3 file true false 0
5 0 0 memory false true 0
6 0 0 file false true 1000000
7 0 0 file false true 10000
} {
db close
sqlite3_shutdown
sqlite3_config_worker_threads $nWorker
if {$coremutex} {
sqlite3_config multithread
} else {
sqlite3_config singlethread
}
sqlite3_initialize
sorter_test_fakeheap $fakeheap
sqlite3_soft_heap_limit $softheaplimit
reset_db
sqlite3_test_control SQLITE_TESTCTRL_SORTER_MMAP db $mmap_limit
execsql "PRAGMA temp_store = $tmpstore"
set ten [string repeat X 10300]
set one [string repeat y 200]
if {$softheaplimit} {
execsql { PRAGMA cache_size = 20 };
} else {
execsql { PRAGMA cache_size = 5 };
}
do_execsql_test 15.$tn.1 {
WITH rr AS (
SELECT 4, $ten UNION ALL
SELECT 2, $one UNION ALL
SELECT 1, $ten UNION ALL
SELECT 3, $one
)
SELECT * FROM rr ORDER BY 1;
} [list 1 $ten 2 $one 3 $one 4 $ten]
do_execsql_test 15.$tn.2 {
CREATE TABLE t1(a);
INSERT INTO t1 VALUES(4);
INSERT INTO t1 VALUES(5);
INSERT INTO t1 VALUES(3);
INSERT INTO t1 VALUES(2);
INSERT INTO t1 VALUES(6);
INSERT INTO t1 VALUES(1);
CREATE INDEX i1 ON t1(a);
SELECT * FROM t1 ORDER BY a;
} {1 2 3 4 5 6}
do_execsql_test 15.$tn.3 {
WITH rr AS (
SELECT 4, $ten UNION ALL
SELECT 2, $one
)
SELECT * FROM rr ORDER BY 1;
} [list 2 $one 4 $ten]
sorter_test_fakeheap 0
}
db close
sqlite3_shutdown
sqlite3_config_worker_threads 0
set t(0) singlethread
set t(1) multithread
set t(2) serialized
sqlite3_config $t($sqlite_options(threadsafe))
sqlite3_initialize
sqlite3_soft_heap_limit 0
reset_db
do_catchsql_test 16.1 {
CREATE TABLE t1(a, b, c);
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(1, NULL, 3);
INSERT INTO t1 VALUES(NULL, 2, 3);
INSERT INTO t1 VALUES(1, 2, NULL);
INSERT INTO t1 VALUES(4, 5, 6);
CREATE UNIQUE INDEX i1 ON t1(b, a, c);
} {0 {}}
reset_db
do_catchsql_test 16.2 {
CREATE TABLE t1(a, b, c);
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(1, NULL, 3);
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(1, 2, NULL);
INSERT INTO t1 VALUES(4, 5, 6);
CREATE UNIQUE INDEX i1 ON t1(b, a, c);
} {1 {UNIQUE constraint failed: t1.b, t1.a, t1.c}}
reset_db
do_execsql_test 17.1 {
SELECT * FROM sqlite_master ORDER BY sql;
} {}
finish_test
+88
View File
@@ -0,0 +1,88 @@
# 2014 March 25.
#
# 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, the tests in this file attempt to verify that
# multi-threaded sorting works.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix sort2
foreach {tn script} {
1 { }
2 {
catch { db close }
sqlite3_shutdown
sqlite3_config_worker_threads 7
reset_db
}
} {
eval $script
do_execsql_test $tn.1 {
PRAGMA cache_size = 5;
WITH r(x,y) AS (
SELECT 1, randomblob(100)
UNION ALL
SELECT x+1, randomblob(100) FROM r
LIMIT 100000
)
SELECT count(x), length(y) FROM r GROUP BY (x%5)
} {
20000 100 20000 100 20000 100 20000 100 20000 100
}
do_execsql_test $tn.2.1 {
CREATE TABLE t1(a, b);
WITH r(x,y) AS (
SELECT 1, randomblob(100)
UNION ALL
SELECT x+1, randomblob(100) FROM r
LIMIT 10000
) INSERT INTO t1 SELECT * FROM r;
}
do_execsql_test $tn.2.2 {
CREATE UNIQUE INDEX i1 ON t1(b, a);
}
do_execsql_test $tn.2.3 {
CREATE UNIQUE INDEX i2 ON t1(a);
}
do_execsql_test $tn.2.4 { PRAGMA integrity_check } {ok}
breakpoint
do_execsql_test $tn.3 {
PRAGMA cache_size = 5;
WITH r(x,y) AS (
SELECT 1, randomblob(100)
UNION ALL
SELECT x+1, randomblob(100) FROM r
LIMIT 1000000
)
SELECT count(x), length(y) FROM r GROUP BY (x%5)
} {
200000 100 200000 100 200000 100 200000 100 200000 100
}
db close
sqlite3_shutdown
sqlite3_config_worker_threads 0
sqlite3_initialize
}
finish_test
+67
View File
@@ -0,0 +1,67 @@
# 2014 March 25.
#
# 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 tests in this file verify that sorting works when the library is
# configured to use mmap(), but the temporary files generated by the
# sorter are too large to be completely mapped.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix sort3
# Sort roughly 20MB of data. Once with a mmap limit of 5MB and once without.
#
foreach {itest limit} {
1 5000000
2 0x7FFFFFFF
} {
sqlite3_test_control SQLITE_TESTCTRL_SORTER_MMAP db $limit
do_execsql_test 1.$itest {
WITH r(x,y) AS (
SELECT 1, randomblob(1000)
UNION ALL
SELECT x+1, randomblob(1000) FROM r
LIMIT 20000
)
SELECT count(*), sum(length(y)) FROM r GROUP BY (x%5);
} {
4000 4000000
4000 4000000
4000 4000000
4000 4000000
4000 4000000
}
}
# Sort more than 2GB of data. At one point this was causing a problem.
# This test might take one minute or more to run.
#
do_execsql_test 2 {
PRAGMA cache_size = 20000;
WITH r(x,y) AS (
SELECT 1, randomblob(1000)
UNION ALL
SELECT x+1, randomblob(1000) FROM r
LIMIT 2200000
)
SELECT count(*), sum(length(y)) FROM r GROUP BY (x%5);
} {
440000 440000000
440000 440000000
440000 440000000
440000 440000000
440000 440000000
}
finish_test
+198
View File
@@ -0,0 +1,198 @@
# 2014 May 6.
#
# 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 tests in this file are brute force tests of the multi-threaded
# sorter.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix sort4
# Configure the sorter to use 3 background threads.
catch { db close }
sqlite3_shutdown
sqlite3_config_worker_threads 3
sqlite3_initialize
reset_db
# Minimum number of seconds to run for. If the value is 0, each test
# is run exactly once. Otherwise, tests are repeated until the timeout
# expires.
set SORT4TIMEOUT 0
if {[permutation] == "multithread"} { set SORT4TIMEOUT 300 }
#--------------------------------------------------------------------
# Set up a table "t1" containing $nRow rows. Each row contains also
# contains blob fields that collectively contain at least $nPayload
# bytes of content. The table schema is as follows:
#
# CREATE TABLE t1(a INTEGER, <extra-columns>, b INTEGER);
#
# For each row, the values of columns "a" and "b" are set to the same
# pseudo-randomly selected integer. The "extra-columns", of which there
# are at most eight, are named c0, c1, c2 etc. Column c0 contains a 4
# byte string. Column c1 an 8 byte string. Field c2 16 bytes, and so on.
#
# This table is intended to be used for testing queries of the form:
#
# SELECT a, <cols>, b FROM t1 ORDER BY a;
#
# The test code checks that rows are returned in order, and that the
# values of "a" and "b" are the same for each row (the idea being that
# if field "b" at the end of the sorter record has not been corrupted,
# the rest of the record is probably Ok as well).
#
proc populate_table {nRow nPayload} {
set nCol 0
set n 0
for {set nCol 0} {$n < $nPayload} {incr nCol} {
incr n [expr (4 << $nCol)]
}
set cols [lrange [list xxx c0 c1 c2 c3 c4 c5 c6 c7] 1 $nCol]
set data [lrange [list xxx \
randomblob(4) randomblob(8) randomblob(16) randomblob(32) \
randomblob(64) randomblob(128) randomblob(256) randomblob(512) \
] 1 $nCol]
execsql { DROP TABLE IF EXISTS t1 }
db transaction {
execsql "CREATE TABLE t1(a, [join $cols ,], b);"
set insert "INSERT INTO t1 VALUES(:k, [join $data ,], :k)"
for {set i 0} {$i < $nRow} {incr i} {
set k [expr int(rand()*1000000000)]
execsql $insert
}
}
}
# Helper for [do_sorter_test]
#
proc sorter_test {nRow nRead nPayload} {
set res [list]
set nLoad [expr ($nRow > $nRead) ? $nRead : $nRow]
set nPayload [expr (($nPayload+3)/4) * 4]
set cols [list]
foreach {mask col} {
0x04 c0 0x08 c1 0x10 c2 0x20 c3
0x40 c4 0x80 c5 0x100 c6 0x200 c7
} {
if {$nPayload & $mask} { lappend cols $col }
}
# Create two SELECT statements. Statement $sql1 uses the sorter to sort
# $nRow records of a bit over $nPayload bytes each read from the "t1"
# table created by [populate_table] proc above. Rows are sorted in order
# of the integer field in each "t1" record.
#
# The second SQL statement sorts the same set of rows as the first, but
# uses a LIMIT clause, causing SQLite to use a temp table instead of the
# sorter for sorting.
#
set sql1 "SELECT a, [join $cols ,], b FROM t1 WHERE rowid<=$nRow ORDER BY a"
set sql2 "SELECT a FROM t1 WHERE rowid<=$nRow ORDER BY a LIMIT $nRead"
# Pass the two SQL statements to a helper command written in C. This
# command steps statement $sql1 $nRead times and compares the integer
# values in the rows returned with the results of executing $sql2. If
# the comparison fails (indicating some bug in the sorter), a Tcl
# exception is thrown.
#
sorter_test_sort4_helper db $sql1 $nRead $sql2
set {} {}
}
# Usage:
#
# do_sorter_test <testname> <args>...
#
# where <args> are any of the following switches:
#
# -rows N (number of rows to have sorter sort)
# -read N (number of rows to read out of sorter)
# -payload N (bytes of payload to read with each row)
# -cachesize N (Value for "PRAGMA cache_size = ?")
# -repeats N (number of times to repeat test)
# -fakeheap BOOL (true to use separate allocations for in-memory records)
#
proc do_sorter_test {tn args} {
set a(-rows) 1000
set a(-repeats) 1
set a(-read) 100
set a(-payload) 100
set a(-cachesize) 100
set a(-fakeheap) 0
foreach {s val} $args {
if {[info exists a($s)]==0} {
unset a(-cachesize)
set optlist "[join [array names a] ,] or -cachesize"
error "Unknown option $s, expected $optlist"
}
set a($s) $val
}
if {[permutation] == "memsys3" || [permutation] == "memsys5"} {
set a(-fakeheap) 0
}
if {$a(-fakeheap)} { sorter_test_fakeheap 1 }
db eval "PRAGMA cache_size = $a(-cachesize)"
do_test $tn [subst -nocommands {
for {set i 0} {[set i] < $a(-repeats)} {incr i} {
sorter_test $a(-rows) $a(-read) $a(-payload)
}
}] {}
if {$a(-fakeheap)} { sorter_test_fakeheap 0 }
}
proc clock_seconds {} {
db one {SELECT strftime('%s')}
}
#-------------------------------------------------------------------------
# Begin tests here.
# Create a test database.
do_test 1 {
execsql "PRAGMA page_size = 4096"
populate_table 100000 500
} {}
set iTimeLimit [expr [clock_seconds] + $SORT4TIMEOUT]
for {set t 2} {1} {incr tn} {
do_sorter_test $t.2 -repeats 10 -rows 1000 -read 100
do_sorter_test $t.3 -repeats 10 -rows 100000 -read 1000
do_sorter_test $t.4 -repeats 10 -rows 100000 -read 1000 -payload 500
do_sorter_test $t.5 -repeats 10 -rows 100000 -read 100000 -payload 8
do_sorter_test $t.6 -repeats 10 -rows 100000 -read 10 -payload 8
do_sorter_test $t.7 -repeats 10 -rows 10000 -read 10000 -payload 8 -fakeheap 1
do_sorter_test $t.8 -repeats 10 -rows 100000 -read 10000 -cachesize 250
set iNow [clock_seconds]
if {$iNow>=$iTimeLimit} break
do_test "$testprefix-([expr $iTimeLimit-$iNow] seconds remain)" {} {}
}
catch { db close }
sqlite3_shutdown
sqlite3_config_worker_threads 0
sqlite3_initialize
finish_test
+169
View File
@@ -0,0 +1,169 @@
# 2014 March 25.
#
# 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 the effects of fault injection on the sorter
# module (code in vdbesort.c).
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix sortfault
do_execsql_test 1.0 {
PRAGMA cache_size = 5;
}
foreach {tn mmap_limit nWorker tmpstore threadsmode fakeheap lookaside} {
1 0 0 file multithread false false
2 100000 0 file multithread false false
3 100000 1 file multithread false false
4 2000000 0 file singlethread false true
} {
if {$sqlite_options(threadsafe)} { set threadsmode singlethread }
catch { db close }
sqlite3_shutdown
sqlite3_config_worker_threads $nWorker
sqlite3_config $threadsmode
if { $lookaside } {
sqlite3_config_lookaside 100 500
} else {
sqlite3_config_lookaside 0 0
}
sqlite3_initialize
sorter_test_fakeheap $fakeheap
set str [string repeat a 1000]
puts $threadsmode
do_faultsim_test 1.$tn -prep {
sqlite3 db test.db
sqlite3_test_control SQLITE_TESTCTRL_SORTER_MMAP db $::mmap_limit
execsql { PRAGMA cache_size = 5 }
} -body {
execsql {
WITH r(x,y) AS (
SELECT 1, $::str
UNION ALL
SELECT x+1, $::str FROM r
LIMIT 200
)
SELECT count(x), length(y) FROM r GROUP BY (x%5)
}
} -test {
faultsim_test_result {0 {40 1000 40 1000 40 1000 40 1000 40 1000}}
}
do_faultsim_test 2.$tn -faults oom* -prep {
sqlite3 db test.db
sqlite3_test_control SQLITE_TESTCTRL_SORTER_MMAP db $::mmap_limit
add_test_utf16bin_collate db
execsql { PRAGMA cache_size = 5 }
} -body {
execsql {
WITH r(x,y) AS (
SELECT 100, $::str
UNION ALL
SELECT x-1, $::str FROM r
LIMIT 100
)
SELECT count(x), length(y) FROM r GROUP BY y COLLATE utf16bin, (x%5)
}
} -test {
faultsim_test_result {0 {20 1000 20 1000 20 1000 20 1000 20 1000}}
}
if {$mmap_limit > 1000000} {
set str2 [string repeat $str 10]
sqlite3_memdebug_vfs_oom_test 0
sqlite3 db test.db
sqlite3_test_control SQLITE_TESTCTRL_SORTER_MMAP db $::mmap_limit
execsql { PRAGMA cache_size = 5 }
do_faultsim_test 3.$tn -faults oom-trans* -body {
execsql {
WITH r(x,y) AS (
SELECT 300, $::str2
UNION ALL
SELECT x-1, $::str2 FROM r
LIMIT 300
)
SELECT count(x), length(y) FROM r GROUP BY y, (x%5)
}
} -test {
faultsim_test_result {0 {60 10000 60 10000 60 10000 60 10000 60 10000}}
}
sqlite3_memdebug_vfs_oom_test 1
}
}
catch { db close }
sqlite3_shutdown
sqlite3_config_worker_threads 0
set t(0) singlethread
set t(1) multithread
set t(2) serialized
sqlite3_config $t($sqlite_options(threadsafe))
sqlite3_config_lookaside 100 500
sqlite3_initialize
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 4.0 {
CREATE TABLE t1(a, b, c);
INSERT INTO t1 VALUES(1, 2, 3);
}
do_test 4.1 {
for {set i 0} {$i < 256} {incr i} {
execsql {
INSERT INTO t1 SELECT
((a<<3) + b) & 2147483647,
((b<<3) + c) & 2147483647,
((c<<3) + a) & 2147483647
FROM t1 ORDER BY rowid DESC LIMIT 1;
}
}
} {}
faultsim_save_and_close
do_faultsim_test 4.2 -faults oom* -prep {
faultsim_restore_and_reopen
} -body {
execsql { CREATE UNIQUE INDEX i1 ON t1(a,b,c) }
} -test {
faultsim_test_result {0 {}}
}
#-------------------------------------------------------------------------
#
reset_db
set a [string repeat a 500]
set b [string repeat b 500]
set c [string repeat c 500]
do_execsql_test 5.0 {
CREATE TABLE t1(a, b, c);
INSERT INTO t1 VALUES($a, $b, $c);
INSERT INTO t1 VALUES($c, $b, $a);
}
do_faultsim_test 5.1 -faults oom* -body {
execsql { SELECT * FROM t1 ORDER BY a }
} -test {
faultsim_test_result [list 0 [list $::a $::b $::c $::c $::b $::a]]
}
finish_test
+10
View File
@@ -27,6 +27,7 @@ static const char zHelp[] =
" --stats Show statistics at the end\n"
" --testset T Run test-set T\n"
" --trace Turn on SQL tracing\n"
" --threads N Use up to N threads for sorting\n"
" --utf16be Set text encoding to UTF-16BE\n"
" --utf16le Set text encoding to UTF-16LE\n"
" --verify Run additional verification steps.\n"
@@ -1141,6 +1142,7 @@ int main(int argc, char **argv){
int nPCache = 0, szPCache = 0;/* --pcache configuration */
int nScratch = 0, szScratch=0;/* --scratch configuration */
int showStats = 0; /* True for --stats */
int nThread = 0; /* --threads value */
const char *zTSet = "main"; /* Which --testset torun */
int doTrace = 0; /* True for --trace */
const char *zEncoding = 0; /* --utf16be or --utf16le */
@@ -1225,6 +1227,9 @@ int main(int argc, char **argv){
zTSet = argv[++i];
}else if( strcmp(z,"trace")==0 ){
doTrace = 1;
}else if( strcmp(z,"threads")==0 ){
if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
nThread = integerValue(argv[++i]);
}else if( strcmp(z,"utf16le")==0 ){
zEncoding = "utf16le";
}else if( strcmp(z,"utf16be")==0 ){
@@ -1273,6 +1278,11 @@ int main(int argc, char **argv){
rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, pScratch, szScratch, nScratch);
if( rc ) fatal_error("scratch configuration failed: %d\n", rc);
}
#ifdef SQLITE_CONFIG_WORKER_THREADS
if( nThread>0 ){
sqlite3_config(SQLITE_CONFIG_WORKER_THREADS, nThread);
}
#endif
if( nLook>0 ){
sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);
}
+2
View File
@@ -1076,6 +1076,7 @@ proc explain_i {sql {db db}} {
foreach opcode {
Seek SeekGe SeekGt SeekLe SeekLt NotFound Last Rewind
NoConflict Next Prev VNext VPrev VFilter
SorterSort SorterNext
} {
set color($opcode) $B
}
@@ -1098,6 +1099,7 @@ proc explain_i {sql {db db}} {
if {$opcode=="Next" || $opcode=="Prev"
|| $opcode=="VNext" || $opcode=="VPrev"
|| $opcode=="SorterNext"
} {
for {set i $p2} {$i<$addr} {incr i} {
incr x($i) 2
+1 -2
View File
@@ -99,8 +99,6 @@ foreach hdr {
mutex.h
opcodes.h
os_common.h
os_setup.h
os_win.h
os.h
pager.h
parse.h
@@ -239,6 +237,7 @@ foreach file {
malloc.c
printf.c
random.c
threads.c
utf.c
util.c
hash.c
+2 -5
View File
@@ -103,8 +103,6 @@ foreach hdr {
mutex.h
opcodes.h
os_common.h
os_setup.h
os_win.h
os.h
pager.h
parse.h
@@ -170,9 +168,7 @@ proc copy_file {filename} {
if {$linemacros} {puts $out "#line [expr {$ln+1}] \"$filename\""}
}
} elseif {![info exists seen_hdr($hdr)]} {
if {![regexp {/\*\s+amalgamator:\s+dontcache\s+\*/} $line]} {
set seen_hdr($hdr) 1
}
set seen_hdr($hdr) 1
puts $out $line
} elseif {[regexp {/\*\s+amalgamator:\s+keep\s+\*/} $line]} {
# This include file must be kept because there was a "keep"
@@ -253,6 +249,7 @@ foreach file {
malloc.c
printf.c
random.c
threads.c
utf.c
util.c
hash.c
-2
View File
@@ -60,8 +60,6 @@ foreach hdr {
keywordhash.h
opcodes.h
os_common.h
os_setup.h
os_win.h
os.h
pager.h
parse.h